mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-06 23:10:00 +01:00
Compare commits
664 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
028a032a31 | ||
|
|
124a3ddc4b | ||
|
|
fc7e3955ae | ||
|
|
acf1316167 | ||
|
|
24c49e0b42 | ||
|
|
4fb5f391ae | ||
|
|
4fb4a642c6 | ||
|
|
adfefc9c9a | ||
|
|
1ab3e34cb4 | ||
|
|
a9fb75893b | ||
|
|
c28752f03a | ||
|
|
d89941aa89 | ||
|
|
3f86cc0680 | ||
|
|
c4ead1ab27 | ||
|
|
6d654eb036 | ||
|
|
439f3564fa | ||
|
|
ab0e4b5b51 | ||
|
|
34a9bef0c9 | ||
|
|
4be2a19822 | ||
|
|
954c2b07b6 | ||
|
|
2c60731777 | ||
|
|
8bd6bf8214 | ||
|
|
9ad735588c | ||
|
|
34cad2f0e2 | ||
|
|
ce28047755 | ||
|
|
235a55700b | ||
|
|
1a6f38b31b | ||
|
|
969485aace | ||
|
|
49efdb1e77 | ||
|
|
17b3485a67 | ||
|
|
91c7cc9726 | ||
|
|
32d1657192 | ||
|
|
e1a854da2d | ||
|
|
fc3e4c9ab3 | ||
|
|
50dd0e43af | ||
|
|
e8a3b17dd4 | ||
|
|
5ee4c376d0 | ||
|
|
857c5fa976 | ||
|
|
42b9df5a98 | ||
|
|
b48a36e773 | ||
|
|
02d11e616a | ||
|
|
13763f7192 | ||
|
|
380515e5b9 | ||
|
|
a03d488ae2 | ||
|
|
c09c0ce374 | ||
|
|
81bf24a827 | ||
|
|
d6ff6dc56b | ||
|
|
37a14a3d83 | ||
|
|
5fdc679561 | ||
|
|
b24b316e30 | ||
|
|
3e3e42dbc4 | ||
|
|
7d14046740 | ||
|
|
e69edb7aef | ||
|
|
cbc839681b | ||
|
|
b51f515c5c | ||
|
|
4654cc8cee | ||
|
|
1fc3ebbcd9 | ||
|
|
314d78992c | ||
|
|
5f58877bd9 | ||
|
|
d857f1035b | ||
|
|
4730046891 | ||
|
|
4e87ab803a | ||
|
|
4d9f669a9f | ||
|
|
7a8b61357c | ||
|
|
d7c29005a4 | ||
|
|
8b8502a66f | ||
|
|
d6ecc61db8 | ||
|
|
0bd6717c0f | ||
|
|
8bd2ba44a1 | ||
|
|
fcfa854abd | ||
|
|
7373064247 | ||
|
|
374a2d2250 | ||
|
|
519a54cc19 | ||
|
|
4b1e87dc32 | ||
|
|
b76dcd0786 | ||
|
|
70d0cc8221 | ||
|
|
1959c0f9f9 | ||
|
|
f052d1df3e | ||
|
|
11f5a13196 | ||
|
|
b2c9771dd4 | ||
|
|
16b07d59de | ||
|
|
0eb0b21c7f | ||
|
|
2db9b31996 | ||
|
|
d9630deca4 | ||
|
|
79bec49315 | ||
|
|
2293e5a78a | ||
|
|
74b28c54d9 | ||
|
|
04be199f8e | ||
|
|
9e8a636551 | ||
|
|
397674a3fb | ||
|
|
720a44f3a3 | ||
|
|
5cf5a1034c | ||
|
|
6b66cd8c40 | ||
|
|
ab2d991382 | ||
|
|
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
|
||||
|
||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -18,13 +18,6 @@
|
||||
*.so.*
|
||||
*.swp
|
||||
*.ver
|
||||
*.version
|
||||
*.metal.air
|
||||
*.metallib
|
||||
*.metallib.c
|
||||
*.ptx
|
||||
*.ptx.c
|
||||
*.ptx.gz
|
||||
*_g
|
||||
\#*
|
||||
.\#*
|
||||
@@ -33,11 +26,10 @@
|
||||
/ffmpeg
|
||||
/ffplay
|
||||
/ffprobe
|
||||
/config.asm
|
||||
/config.h
|
||||
/ffserver
|
||||
/config.*
|
||||
/coverage.info
|
||||
/avversion.h
|
||||
/lcov/
|
||||
/src
|
||||
/mapfile
|
||||
/tools/python/__pycache__/
|
||||
|
||||
25
.mailmap
25
.mailmap
@@ -1,25 +0,0 @@
|
||||
<james.darnley@gmail.com> <jdarnley@obe.tv>
|
||||
<jeebjp@gmail.com> <jan.ekstrom@aminocom.com>
|
||||
<sw@jkqxz.net> <mrt@jkqxz.net>
|
||||
<u@pkh.me> <cboesch@gopro.com>
|
||||
<zhilizhao@tencent.com> <quinkblack@foxmail.com>
|
||||
<zhilizhao@tencent.com> <wantlamy@gmail.com>
|
||||
<modmaker@google.com> <modmaker-at-google.com@ffmpeg.org>
|
||||
<stebbins@jetheaddev.com> <jstebbins@jetheaddev.com>
|
||||
<barryjzhao@tencent.com> <mypopydev@gmail.com>
|
||||
<barryjzhao@tencent.com> <jun.zhao@intel.com>
|
||||
<josh@itanimul.li> <joshdk@obe.tv>
|
||||
<michael@niedermayer.cc> <michaelni@gmx.at>
|
||||
<linjie.justin.fu@gmail.com> <linjie.fu@intel.com>
|
||||
<linjie.justin.fu@gmail.com> <fulinjie@zju.edu.cn>
|
||||
<ceffmpeg@gmail.com> <cehoyos@ag.or.at>
|
||||
<ceffmpeg@gmail.com> <cehoyos@rainbow.studorg.tuwien.ac.at>
|
||||
<ffmpeg@gyani.pro> <gyandoshi@gmail.com>
|
||||
<atomnuker@gmail.com> <rpehlivanov@obe.tv>
|
||||
<lizhong1008@gmail.com> <zhong.li@intel.com>
|
||||
<lizhong1008@gmail.com> <zhongli_dev@126.com>
|
||||
<andreas.rheinhardt@gmail.com> <andreas.rheinhardt@googlemail.com>
|
||||
rcombs <rcombs@rcombs.me> <rodger.combs@gmail.com>
|
||||
<thilo.borgmann@mail.de> <thilo.borgmann@googlemail.com>
|
||||
<liuqi05@kuaishou.com> <lq@chinaffmpeg.org>
|
||||
<ruiling.song83@gmail.com> <ruiling.song@intel.com>
|
||||
10
.travis.yml
10
.travis.yml
@@ -6,22 +6,18 @@ os:
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- nasm
|
||||
- yasm
|
||||
- diffutils
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
matrix:
|
||||
exclude:
|
||||
- os: osx
|
||||
compiler: gcc
|
||||
cache:
|
||||
directories:
|
||||
- ffmpeg-samples
|
||||
before_install:
|
||||
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update; fi
|
||||
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update --all; fi
|
||||
install:
|
||||
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install nasm; fi
|
||||
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install yasm; fi
|
||||
script:
|
||||
- mkdir -p ffmpeg-samples
|
||||
- ./configure --samples=ffmpeg-samples --cc=$CC
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## Installing FFmpeg
|
||||
#Installing FFmpeg:
|
||||
|
||||
1. Type `./configure` to create the configuration. A list of configure
|
||||
options is printed by running `configure --help`.
|
||||
|
||||
43
LICENSE.md
43
LICENSE.md
@@ -17,15 +17,16 @@ 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`
|
||||
- `doc/texi2pod.pl`
|
||||
- `libswresample/tests/swresample.c`
|
||||
- `libswresample/swresample-test.c`
|
||||
- `tests/checkasm/*`
|
||||
- `tests/tiny_ssim.c`
|
||||
- the following filters in libavfilter:
|
||||
- `signature_lookup.c`
|
||||
- `f_ebur128.c`
|
||||
- `vf_blackframe.c`
|
||||
- `vf_boxblur.c`
|
||||
- `vf_colormatrix.c`
|
||||
@@ -35,13 +36,13 @@ Specifically, the GPL parts of FFmpeg are:
|
||||
- `vf_eq.c`
|
||||
- `vf_find_rect.c`
|
||||
- `vf_fspp.c`
|
||||
- `vf_geq.c`
|
||||
- `vf_histeq.c`
|
||||
- `vf_hqdn3d.c`
|
||||
- `vf_interlace.c`
|
||||
- `vf_kerndeint.c`
|
||||
- `vf_lensfun.c` (GPL version 3 or later)
|
||||
- `vf_mcdeint.c`
|
||||
- `vf_mpdecimate.c`
|
||||
- `vf_nnedi.c`
|
||||
- `vf_owdenoise.c`
|
||||
- `vf_perspective.c`
|
||||
- `vf_phase.c`
|
||||
@@ -50,14 +51,12 @@ Specifically, the GPL parts of FFmpeg are:
|
||||
- `vf_pullup.c`
|
||||
- `vf_repeatfields.c`
|
||||
- `vf_sab.c`
|
||||
- `vf_signature.c`
|
||||
- `vf_smartblur.c`
|
||||
- `vf_spp.c`
|
||||
- `vf_stereo3d.c`
|
||||
- `vf_super2xsai.c`
|
||||
- `vf_tinterlace.c`
|
||||
- `vf_uspp.c`
|
||||
- `vf_vaguedenoiser.c`
|
||||
- `vsrc_mptestsrc.c`
|
||||
|
||||
Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then
|
||||
@@ -83,47 +82,41 @@ affect the licensing of binaries resulting from the combination.
|
||||
|
||||
### Compatible libraries
|
||||
|
||||
The following libraries are under GPL version 2:
|
||||
- avisynth
|
||||
The following libraries are under GPL:
|
||||
- frei0r
|
||||
- libcdio
|
||||
- libdavs2
|
||||
- librubberband
|
||||
- libvidstab
|
||||
- libx264
|
||||
- libx265
|
||||
- libxavs
|
||||
- libxavs2
|
||||
- libxvid
|
||||
|
||||
When combining them with FFmpeg, FFmpeg needs to be licensed as GPL as well by
|
||||
passing `--enable-gpl` to configure.
|
||||
|
||||
The following libraries are under LGPL version 3:
|
||||
- gmp
|
||||
- libaribb24
|
||||
- liblensfun
|
||||
|
||||
When combining them with FFmpeg, use the configure option `--enable-version3` to
|
||||
upgrade FFmpeg to the LGPL v3.
|
||||
|
||||
The VMAF, mbedTLS, RK MPI, OpenCORE and VisualOn libraries are under the Apache License
|
||||
2.0. That license is incompatible with the LGPL v2.1 and the GPL v2, but not with
|
||||
The OpenCORE and VisualOn libraries are under the Apache License 2.0. That
|
||||
license is incompatible with the LGPL v2.1 and the GPL v2, but not with
|
||||
version 3 of those licenses. So to combine these libraries with FFmpeg, the
|
||||
license version needs to be upgraded by passing `--enable-version3` to configure.
|
||||
|
||||
The smbclient library is under the GPL v3, to combine it with FFmpeg,
|
||||
the options `--enable-gpl` and `--enable-version3` have to be passed to
|
||||
configure to upgrade FFmpeg to the GPL v3.
|
||||
|
||||
### Incompatible libraries
|
||||
|
||||
There are certain libraries you can combine with FFmpeg whose licenses are not
|
||||
compatible with the GPL and/or the LGPL. If you wish to enable these
|
||||
libraries, even in circumstances that their license may be incompatible, pass
|
||||
`--enable-nonfree` to configure. This will cause the resulting binary to be
|
||||
`--enable-nonfree` to configure. But note that if you enable any of these
|
||||
libraries the resulting binary will be under a complex license mix that is
|
||||
more restrictive than the LGPL and that may result in additional obligations.
|
||||
It is possible that these restrictions cause the resulting binary to be
|
||||
unredistributable.
|
||||
|
||||
The Fraunhofer FDK AAC and OpenSSL libraries are under licenses which are
|
||||
incompatible with the GPLv2 and v3. To the best of our knowledge, they are
|
||||
compatible with the LGPL.
|
||||
|
||||
The NVENC library, while its header file is licensed under the compatible MIT
|
||||
license, requires a proprietary binary blob at run time, and is deemed to be
|
||||
incompatible with the GPL. We are not certain if it is compatible with the
|
||||
LGPL, but we require `--enable-nonfree` even with LGPL configurations in case
|
||||
it is not.
|
||||
|
||||
152
MAINTAINERS
152
MAINTAINERS
@@ -29,6 +29,9 @@ ffplay:
|
||||
ffprobe:
|
||||
ffprobe.c Stefano Sabatini
|
||||
|
||||
ffserver:
|
||||
ffserver.c Reynaldo H. Verdejo Pinochet
|
||||
|
||||
Commandline utility code:
|
||||
cmdutils.c, cmdutils.h Michael Niedermayer
|
||||
|
||||
@@ -39,12 +42,11 @@ QuickTime faststart:
|
||||
Miscellaneous Areas
|
||||
===================
|
||||
|
||||
documentation Stefano Sabatini, Mike Melanson, Timothy Gu, Gyan Doshi
|
||||
documentation Stefano Sabatini, Mike Melanson, Timothy Gu, Lou Logan
|
||||
project server Árpád Gereöffy, Michael Niedermayer, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov
|
||||
presets Robert Swain
|
||||
metadata subsystem Aurelien Jacobs
|
||||
release management Michael Niedermayer
|
||||
API tests Ludmila Glinskih
|
||||
|
||||
|
||||
Communication
|
||||
@@ -52,12 +54,11 @@ Communication
|
||||
|
||||
website Deby Barbara Lepage
|
||||
fate.ffmpeg.org Timothy Gu
|
||||
Trac bug tracker Alexander Strasser, Michael Niedermayer, Carl Eugen Hoyos
|
||||
Patchwork Andriy Gelman
|
||||
mailing lists Baptiste Coudurier
|
||||
Twitter Reynaldo H. Verdejo Pinochet
|
||||
Trac bug tracker Alexander Strasser, Michael Niedermayer, Carl Eugen Hoyos, Lou Logan
|
||||
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, rcombs, wm4
|
||||
|
||||
|
||||
libavutil
|
||||
@@ -78,7 +79,6 @@ Other:
|
||||
float_dsp Loren Merritt
|
||||
hash Reimar Doeffinger
|
||||
hwcontext_cuda* Timo Rothenpieler
|
||||
hwcontext_vulkan* Lynne
|
||||
intfloat* Michael Niedermayer
|
||||
integer.c, integer.h Michael Niedermayer
|
||||
lzo Reimar Doeffinger
|
||||
@@ -89,7 +89,6 @@ Other:
|
||||
rational.c, rational.h Michael Niedermayer
|
||||
rc4 Reimar Doeffinger
|
||||
ripemd.c, ripemd.h James Almer
|
||||
tx* Lynne
|
||||
|
||||
|
||||
libavcodec
|
||||
@@ -115,14 +114,13 @@ 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:
|
||||
motion* Michael Niedermayer
|
||||
rate control:
|
||||
ratecontrol.c Michael Niedermayer
|
||||
libxvid_rc.c Michael Niedermayer
|
||||
simple IDCT:
|
||||
simple_idct.c, simple_idct.h Michael Niedermayer
|
||||
postprocessing:
|
||||
@@ -138,15 +136,12 @@ Codecs:
|
||||
8bps.c Roberto Togni
|
||||
8svx.c Jaikrishnan Menon
|
||||
aacenc*, aaccoder.c Rostislav Pehlivanov
|
||||
adpcm.c Zane van Iperen
|
||||
alacenc.c Jaikrishnan Menon
|
||||
alsdec.c Thilo Borgmann, Umair Khan
|
||||
aptx.c Aurelien Jacobs
|
||||
ass* Aurelien Jacobs
|
||||
asv* Michael Niedermayer
|
||||
atrac3plus* Maxim Poliakovski
|
||||
audiotoolbox* rcombs
|
||||
avs2* Huiwen Ren
|
||||
audiotoolbox* Rodger Combs
|
||||
bgmc.c, bgmc.h Thilo Borgmann
|
||||
binkaudio.c Peter Ross
|
||||
cavs* Stefan Gehrer
|
||||
@@ -159,11 +154,9 @@ Codecs:
|
||||
cpia.c Stephan Hilb
|
||||
crystalhd.c Philip Langdale
|
||||
cscd.c Reimar Doeffinger
|
||||
cuviddec.c Timo Rothenpieler
|
||||
dca* foo86
|
||||
cuvid.c Timo Rothenpieler
|
||||
dirac* Rostislav Pehlivanov
|
||||
dnxhd* Baptiste Coudurier
|
||||
dolby_e* foo86
|
||||
dpcm.c Mike Melanson
|
||||
dss_sp.c Oleksij Rempel
|
||||
dv.c Roman Shaposhnik
|
||||
@@ -182,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
|
||||
@@ -190,19 +183,16 @@ Codecs:
|
||||
jvdec.c Peter Ross
|
||||
lcl*.c Roberto Togni, Reimar Doeffinger
|
||||
libcelt_dec.c Nicolas George
|
||||
libcodec2.c Tomas Härdin
|
||||
libdirac* David Conrad
|
||||
libdavs2.c Huiwen Ren
|
||||
libgsm.c Michel Bardiaux
|
||||
libkvazaar.c Arttu Ylä-Outinen
|
||||
libopenh264enc.c Martin Storsjo, Linjie Fu
|
||||
libopenjpeg.c Jaikrishnan Menon
|
||||
libopenjpegenc.c Michael Bradshaw
|
||||
libschroedinger* David Conrad
|
||||
libtheoraenc.c David Conrad
|
||||
libvorbis.c David Conrad
|
||||
libvpx* James Zern
|
||||
libxavs.c Stefan Gehrer
|
||||
libxavs2.c Huiwen Ren
|
||||
libzvbi-teletextdec.c Marton Balint
|
||||
lzo.h, lzo.c Reimar Doeffinger
|
||||
mdec.c Michael Niedermayer
|
||||
@@ -217,16 +207,14 @@ Codecs:
|
||||
msrle.c Mike Melanson
|
||||
msvideo1.c Mike Melanson
|
||||
nuv.c Reimar Doeffinger
|
||||
nvdec*, nvenc* Timo Rothenpieler
|
||||
omx.c Martin Storsjo, Aman Gupta
|
||||
opus* Rostislav Pehlivanov
|
||||
nvenc* Timo Rothenpieler
|
||||
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, Zhong Li, Haihao Xiang
|
||||
qsv* Ivan Uskov
|
||||
qtrle.c Mike Melanson
|
||||
ra144.c, ra144.h, ra288.c, ra288.h Roberto Togni
|
||||
resample2.c Michael Niedermayer
|
||||
@@ -234,11 +222,12 @@ 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
|
||||
snow* Michael Niedermayer, Loren Merritt
|
||||
sonic.c Alex Beregszaszi
|
||||
speedhq.c Steinar H. Gunderson
|
||||
srt* Aurelien Jacobs
|
||||
sunrast.c Ivo van Poorten
|
||||
svq3.c Michael Niedermayer
|
||||
@@ -247,10 +236,11 @@ Codecs:
|
||||
tta.c Alex Beregszaszi, Jaikrishnan Menon
|
||||
ttaenc.c Paul B Mahol
|
||||
txd.c Ivo van Poorten
|
||||
v4l2_* Jorge Ramirez-Ortiz
|
||||
vc1* Christophe Gisquet
|
||||
vc2* Rostislav Pehlivanov
|
||||
vcr1.c Michael Niedermayer
|
||||
videotoolboxenc.c Rick Kern, Aman Gupta
|
||||
vda_h264_dec.c Xidorn Quan
|
||||
videotoolboxenc.c Rick Kern
|
||||
vima.c Paul B Mahol
|
||||
vorbisdec.c Denes Balatoni, David Conrad
|
||||
vorbisenc.c Oded Shimon
|
||||
@@ -271,13 +261,12 @@ Codecs:
|
||||
|
||||
Hardware acceleration:
|
||||
crystalhd.c Philip Langdale
|
||||
dxva2* Hendrik Leppkes, Laurent Aimar, Steve Lhomme
|
||||
d3d11va* Steve Lhomme
|
||||
mediacodec* Matthieu Bouron, Aman Gupta
|
||||
vaapi* Haihao Xiang
|
||||
vaapi_encode* Mark Thompson, Haihao Xiang
|
||||
dxva2* Hendrik Leppkes, Laurent Aimar
|
||||
mediacodec* Matthieu Bouron
|
||||
vaapi* Gwenole Beauchesne
|
||||
vaapi_encode* Mark Thompson
|
||||
vdpau* Philip Langdale, Carl Eugen Hoyos
|
||||
videotoolbox* Rick Kern, Aman Gupta
|
||||
videotoolbox* Rick Kern
|
||||
|
||||
|
||||
libavdevice
|
||||
@@ -287,8 +276,7 @@ libavdevice
|
||||
|
||||
|
||||
avfoundation.m Thilo Borgmann
|
||||
android_camera.c Felix Matouschek
|
||||
decklink* Marton Balint
|
||||
decklink* Deti Fliegl
|
||||
dshow.c Roger Pack (CC rogerdpack@gmail.com)
|
||||
fbdev_enc.c Lukasz Marek
|
||||
gdigrab.c Roger Pack (CC rogerdpack@gmail.com)
|
||||
@@ -297,6 +285,7 @@ libavdevice
|
||||
libdc1394.c Roman Shaposhnik
|
||||
opengl_enc.c Lukasz Marek
|
||||
pulse_audio_enc.c Lukasz Marek
|
||||
qtkit.m Thilo Borgmann
|
||||
sdl Stefano Sabatini
|
||||
sdl2.c Josh de Kock
|
||||
v4l2.c Giorgio Vazzana
|
||||
@@ -335,10 +324,8 @@ Filters:
|
||||
avf_avectorscope.c Paul B Mahol
|
||||
avf_showcqt.c Muhammad Faiz
|
||||
vf_blend.c Paul B Mahol
|
||||
vf_bwdif Thomas Mundt (CC <thomas.mundt@hr.de>)
|
||||
vf_chromakey.c Timo Rothenpieler
|
||||
vf_colorchannelmixer.c Paul B Mahol
|
||||
vf_colorconstancy.c Mina Sami (CC <minas.gorgy@gmail.com>)
|
||||
vf_colorbalance.c Paul B Mahol
|
||||
vf_colorkey.c Timo Rothenpieler
|
||||
vf_colorlevels.c Paul B Mahol
|
||||
@@ -352,7 +339,6 @@ Filters:
|
||||
vf_hqx.c Clément Bœsch
|
||||
vf_idet.c Pascal Massimino
|
||||
vf_il.c Paul B Mahol
|
||||
vf_(t)interlace Thomas Mundt (CC <thomas.mundt@hr.de>)
|
||||
vf_lenscorrection.c Daniel Oberhoff
|
||||
vf_mergeplanes.c Paul B Mahol
|
||||
vf_mestimate.c Davinder Singh
|
||||
@@ -366,15 +352,12 @@ Filters:
|
||||
vf_ssim.c Paul B Mahol
|
||||
vf_stereo3d.c Paul B Mahol
|
||||
vf_telecine.c Paul B Mahol
|
||||
vf_tonemap_opencl.c Ruiling Song
|
||||
vf_yadif.c Michael Niedermayer
|
||||
vf_zoompan.c Paul B Mahol
|
||||
|
||||
Sources:
|
||||
vsrc_mandelbrot.c Michael Niedermayer
|
||||
|
||||
dnn Yejun Guo
|
||||
|
||||
libavformat
|
||||
===========
|
||||
|
||||
@@ -393,13 +376,7 @@ Muxers/Demuxers:
|
||||
afc.c Paul B Mahol
|
||||
aiffdec.c Baptiste Coudurier, Matthieu Bouron
|
||||
aiffenc.c Baptiste Coudurier, Matthieu Bouron
|
||||
alp.c Zane van Iperen
|
||||
amvenc.c Zane van Iperen
|
||||
apm.c Zane van Iperen
|
||||
apngdec.c Benoit Fouet
|
||||
argo_asf.c Zane van Iperen
|
||||
argo_brp.c Zane van Iperen
|
||||
argo_cvg.c Zane van Iperen
|
||||
ass* Aurelien Jacobs
|
||||
astdec.c Paul B Mahol
|
||||
astenc.c James Almer
|
||||
@@ -407,28 +384,23 @@ 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
|
||||
codec2.c Tomas Härdin
|
||||
crc.c Michael Niedermayer
|
||||
dashdec.c Steven Liu
|
||||
dashenc.c Karthick Jeyapal
|
||||
daud.c Reimar Doeffinger
|
||||
dss.c Oleksij Rempel
|
||||
dtsdec.c foo86
|
||||
dtshddec.c Paul B Mahol
|
||||
dv.c Roman Shaposhnik
|
||||
electronicarts.c Peter Ross
|
||||
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
|
||||
hlsenc.c Christian Suloway, Steven Liu
|
||||
hls.c Anssi Hannula
|
||||
hls encryption (hlsenc.c) Christian Suloway, Steven Liu
|
||||
idcin.c Mike Melanson
|
||||
idroqdec.c Mike Melanson
|
||||
iff.c Jaikrishnan Menon
|
||||
@@ -437,15 +409,15 @@ Muxers/Demuxers:
|
||||
ircam* Paul B Mahol
|
||||
iss.c Stefan Gehrer
|
||||
jvdec.c Peter Ross
|
||||
kvag.c Zane van Iperen
|
||||
libmodplug.c Clément Bœsch
|
||||
libnut.c Oded Shimon
|
||||
libopenmpt.c Josh de Kock
|
||||
lmlm4.c Ivo van Poorten
|
||||
lvfdec.c Paul B Mahol
|
||||
lxfdec.c Tomas Härdin
|
||||
matroska.c Aurelien Jacobs, Andreas Rheinhardt
|
||||
matroskadec.c Aurelien Jacobs, Andreas Rheinhardt
|
||||
matroskaenc.c David Conrad, Andreas Rheinhardt
|
||||
matroska.c Aurelien Jacobs
|
||||
matroskadec.c Aurelien Jacobs
|
||||
matroskaenc.c David Conrad
|
||||
matroska subtitles (matroskaenc.c) John Peebles
|
||||
metadata* Aurelien Jacobs
|
||||
mgsts.c Paul B Mahol
|
||||
@@ -460,7 +432,8 @@ Muxers/Demuxers:
|
||||
mpegtsenc.c Baptiste Coudurier
|
||||
msnwc_tcp.c Ramiro Polla
|
||||
mtv.c Reynaldo H. Verdejo Pinochet
|
||||
mxf* Baptiste Coudurier, Tomas Härdin
|
||||
mxf* Baptiste Coudurier
|
||||
mxfdec.c Tomas Härdin
|
||||
nistspheredec.c Paul B Mahol
|
||||
nsvdec.c Francois Revol
|
||||
nut* Michael Niedermayer
|
||||
@@ -468,9 +441,9 @@ Muxers/Demuxers:
|
||||
oggdec.c, oggdec.h David Conrad
|
||||
oggenc.c Baptiste Coudurier
|
||||
oggparse*.c David Conrad
|
||||
oggparsedaala* Rostislav Pehlivanov
|
||||
oma.c Maxim Poliakovski
|
||||
paf.c Paul B Mahol
|
||||
pp_bnk.c Zane van Iperen
|
||||
psxstr.c Mike Melanson
|
||||
pva.c Ivo van Poorten
|
||||
pvfdec.c Paul B Mahol
|
||||
@@ -489,7 +462,6 @@ Muxers/Demuxers:
|
||||
rtpdec_vc2hq.*, rtpenc_vc2hq.* Thomas Volkert
|
||||
rtpdec_vp9.c Thomas Volkert
|
||||
rtpenc_mpv.*, rtpenc_aac.* Martin Storsjo
|
||||
s337m.c foo86
|
||||
sbgdec.c Nicolas George
|
||||
sdp.c Martin Storsjo
|
||||
segafilm.c Mike Melanson
|
||||
@@ -516,7 +488,6 @@ Protocols:
|
||||
ftp.c Lukasz Marek
|
||||
http.c Ronald S. Bultje
|
||||
libssh.c Lukasz Marek
|
||||
libzmq.c Andriy Gelman
|
||||
mms*.c Ronald S. Bultje
|
||||
udp.c Luca Abeni
|
||||
icecast.c Marvin Scholz
|
||||
@@ -540,10 +511,9 @@ Operating systems / CPU architectures
|
||||
=====================================
|
||||
|
||||
Alpha Falk Hueffner
|
||||
MIPS Manojkumar Bhosale, Shiyou Yin
|
||||
MIPS Nedeljko Babic
|
||||
Mac OS X / PowerPC Romain Dolbeau, Guillaume Poirier
|
||||
Amiga / PowerPC Colin Ward
|
||||
Linux / PowerPC Lauri Kasanen
|
||||
Windows MinGW Alex Beregszaszi, Ramiro Polla
|
||||
Windows Cygwin Victor Paesa
|
||||
Windows MSVC Matthew Oliver, Hendrik Leppkes
|
||||
@@ -553,35 +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
|
||||
Jan Ekström
|
||||
Joakim Plate
|
||||
Jun Zhao
|
||||
Kieran Kunhya
|
||||
Kirill Gavrilov
|
||||
Limin Wang
|
||||
Martin Storsjö
|
||||
Panagiotis Issaris
|
||||
Pedro Arthur
|
||||
Sebastien Zwickert
|
||||
Vittorio Giovara
|
||||
wm4
|
||||
(this list is incomplete)
|
||||
|
||||
|
||||
Releases
|
||||
========
|
||||
|
||||
@@ -593,11 +534,8 @@ Releases
|
||||
If you want to maintain an older release, please contact us
|
||||
|
||||
|
||||
GnuPG Fingerprints and IRC nicknames of maintainers and contributors
|
||||
====================================================================
|
||||
|
||||
IRC nicknames are in parentheses. These apply
|
||||
to the IRC channels listed on the website.
|
||||
GnuPG Fingerprints of maintainers and contributors
|
||||
==================================================
|
||||
|
||||
Alexander Strasser 1C96 78B7 83CB 8AA7 9AF5 D1EB A7D8 A57B A876 E58F
|
||||
Anssi Hannula 1A92 FF42 2DD9 8D2E 8AF7 65A9 4278 C520 513D F3CB
|
||||
@@ -611,30 +549,24 @@ Daniel Verkamp 78A6 07ED 782C 653E C628 B8B9 F0EB 8DD8 2F0E 21C7
|
||||
FFmpeg release signing key FCF9 86EA 15E6 E293 A564 4F10 B432 2F04 D676 58D8
|
||||
Ganesh Ajjanagadde C96A 848E 97C3 CEA2 AB72 5CE4 45F9 6A2D 3C36 FB1B
|
||||
Gwenole Beauchesne 2E63 B3A6 3E44 37E2 017D 2704 53C7 6266 B153 99C4
|
||||
Haihao Xiang (haihao) 1F0C 31E8 B4FE F7A4 4DC1 DC99 E0F5 76D4 76FC 437F
|
||||
Jaikrishnan Menon 61A1 F09F 01C9 2D45 78E1 C862 25DC 8831 AF70 D368
|
||||
James Almer 7751 2E8C FD94 A169 57E6 9A7A 1463 01AD 7376 59E0
|
||||
Jean Delvare 7CA6 9F44 60F1 BDC4 1FD2 C858 A552 6B9B B3CD 4E6A
|
||||
Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE
|
||||
Lynne FE50 139C 6805 72CA FD52 1F8D A2FE A5F0 3F03 4464
|
||||
Lou Logan 7D68 DC73 CBEF EABB 671A B6CF 621C 2E28 82F8 DC3A
|
||||
Michael Niedermayer 9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB
|
||||
Nicolas George 24CE 01CE 9ACC 5CEB 74D8 8D9D B063 D997 36E5 4C93
|
||||
Nikolay Aleksandrov 8978 1D8C FB71 588E 4B27 EAA8 C4F0 B5FC E011 13B1
|
||||
Panagiotis Issaris 6571 13A3 33D9 3726 F728 AA98 F643 B12E ECF3 E029
|
||||
Peter Ross A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B
|
||||
Philip Langdale 5DC5 8D66 5FBA 3A43 18EC 045E F8D6 B194 6A75 682E
|
||||
Ramiro Polla 7859 C65B 751B 1179 792E DAE8 8E95 8B2F 9B6C 5700
|
||||
Reimar Doeffinger C61D 16E5 9E2C D10C 8958 38A4 0899 A2B9 06D4 D9C7
|
||||
Reinhard Tartler 9300 5DC2 7E87 6C37 ED7B CA9A 9808 3544 9453 48A4
|
||||
Reynaldo H. Verdejo Pinochet 6E27 CD34 170C C78E 4D4F 5F40 C18E 077F 3114 452A
|
||||
Robert Swain EE7A 56EA 4A81 A7B5 2001 A521 67FA 362D A2FC 3E71
|
||||
Sascha Sommer 38A0 F88B 868E 9D3A 97D4 D6A0 E823 706F 1E07 0D3C
|
||||
Stefano Sabatini 0D0B AD6B 5330 BBAD D3D6 6A0C 719C 2839 FC43 2D5F
|
||||
Steinar H. Gunderson C2E9 004F F028 C18E 4EAD DB83 7F61 7561 7797 8F76
|
||||
Stephan Hilb 4F38 0B3A 5F39 B99B F505 E562 8D5C 5554 4E17 8863
|
||||
Thilo Borgmann (thilo) CE1D B7F4 4D20 FC3A DD9F FE5A 257C 5B8F 1D20 B92F
|
||||
Tiancheng "Timothy" Gu 9456 AFC0 814A 8139 E994 8351 7FE6 B095 B582 B0D4
|
||||
Tim Nicholson 38CF DB09 3ED0 F607 8B67 6CED 0C0B FC44 8B0B FC83
|
||||
Tomas Härdin (thardin) A79D 4E3D F38F 763F 91F5 8B33 A01E 8AE0 41BB 2551
|
||||
Tomas Härdin A79D 4E3D F38F 763F 91F5 8B33 A01E 8AE0 41BB 2551
|
||||
Wei Gao 4269 7741 857A 0E60 9EC5 08D2 4744 4EFA 62C1 87B9
|
||||
Zane van Iperen (zane) 61AE D40F 368B 6F26 9DAE 3892 6861 6B2D 8AC4 DCC5
|
||||
|
||||
168
Makefile
168
Makefile
@@ -1,5 +1,5 @@
|
||||
MAIN_MAKEFILE=1
|
||||
include ffbuild/config.mak
|
||||
include config.mak
|
||||
|
||||
vpath %.c $(SRC_PATH)
|
||||
vpath %.cpp $(SRC_PATH)
|
||||
@@ -11,19 +11,47 @@ vpath %.asm $(SRC_PATH)
|
||||
vpath %.rc $(SRC_PATH)
|
||||
vpath %.v $(SRC_PATH)
|
||||
vpath %.texi $(SRC_PATH)
|
||||
vpath %.cu $(SRC_PATH)
|
||||
vpath %.ptx $(SRC_PATH)
|
||||
vpath %.metal $(SRC_PATH)
|
||||
vpath %/fate_config.sh.template $(SRC_PATH)
|
||||
|
||||
AVPROGS-$(CONFIG_FFMPEG) += ffmpeg
|
||||
AVPROGS-$(CONFIG_FFPLAY) += ffplay
|
||||
AVPROGS-$(CONFIG_FFPROBE) += ffprobe
|
||||
AVPROGS-$(CONFIG_FFSERVER) += ffserver
|
||||
|
||||
AVPROGS := $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
|
||||
INSTPROGS = $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
|
||||
PROGS += $(AVPROGS)
|
||||
|
||||
AVBASENAMES = ffmpeg ffplay ffprobe ffserver
|
||||
ALLAVPROGS = $(AVBASENAMES:%=%$(PROGSSUF)$(EXESUF))
|
||||
ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
|
||||
|
||||
$(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog) += cmdutils.o))
|
||||
$(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog)-$(CONFIG_OPENCL) += cmdutils_opencl.o))
|
||||
|
||||
OBJS-ffmpeg += ffmpeg_opt.o ffmpeg_filter.o
|
||||
OBJS-ffmpeg-$(CONFIG_VIDEOTOOLBOX) += ffmpeg_videotoolbox.o
|
||||
OBJS-ffmpeg-$(CONFIG_LIBMFX) += ffmpeg_qsv.o
|
||||
OBJS-ffmpeg-$(CONFIG_VAAPI) += ffmpeg_vaapi.o
|
||||
ifndef CONFIG_VIDEOTOOLBOX
|
||||
OBJS-ffmpeg-$(CONFIG_VDA) += ffmpeg_videotoolbox.o
|
||||
endif
|
||||
OBJS-ffmpeg-$(CONFIG_CUVID) += ffmpeg_cuvid.o
|
||||
OBJS-ffmpeg-$(HAVE_DXVA2_LIB) += ffmpeg_dxva2.o
|
||||
OBJS-ffmpeg-$(HAVE_VDPAU_X11) += ffmpeg_vdpau.o
|
||||
OBJS-ffserver += ffserver_config.o
|
||||
|
||||
TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64 audiomatch
|
||||
HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options
|
||||
TOOLS = qt-faststart trasher uncoded_frame
|
||||
TOOLS-$(CONFIG_ZLIB) += cws2fws
|
||||
|
||||
# $(FFLIBS-yes) needs to be in linking order
|
||||
FFLIBS-$(CONFIG_AVDEVICE) += avdevice
|
||||
FFLIBS-$(CONFIG_AVFILTER) += avfilter
|
||||
FFLIBS-$(CONFIG_AVFORMAT) += avformat
|
||||
FFLIBS-$(CONFIG_AVCODEC) += avcodec
|
||||
FFLIBS-$(CONFIG_AVRESAMPLE) += avresample
|
||||
FFLIBS-$(CONFIG_POSTPROC) += postproc
|
||||
FFLIBS-$(CONFIG_SWRESAMPLE) += swresample
|
||||
FFLIBS-$(CONFIG_SWSCALE) += swscale
|
||||
@@ -31,67 +59,38 @@ FFLIBS-$(CONFIG_SWSCALE) += swscale
|
||||
FFLIBS := avutil
|
||||
|
||||
DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.ffpreset) $(SRC_PATH)/doc/ffprobe.xsd
|
||||
EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/Makefile $(SRC_PATH)/doc/examples/README
|
||||
|
||||
SKIPHEADERS = compat/w32pthreads.h
|
||||
SKIPHEADERS = cmdutils_common_opts.h \
|
||||
compat/w32pthreads.h
|
||||
|
||||
# first so "all" becomes default target
|
||||
all: all-yes
|
||||
|
||||
include $(SRC_PATH)/tools/Makefile
|
||||
include $(SRC_PATH)/ffbuild/common.mak
|
||||
include $(SRC_PATH)/common.mak
|
||||
|
||||
FF_EXTRALIBS := $(FFEXTRALIBS)
|
||||
FF_DEP_LIBS := $(DEP_LIBS)
|
||||
FF_STATIC_DEP_LIBS := $(STATIC_DEP_LIBS)
|
||||
|
||||
$(TOOLS): %$(EXESUF): %.o
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(EXTRALIBS-$(*F)) $(EXTRALIBS) $(ELIBS)
|
||||
all: $(AVPROGS)
|
||||
|
||||
target_dec_%_fuzzer$(EXESUF): target_dec_%_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
$(TOOLS): %$(EXESUF): %.o $(EXEOBJS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS)
|
||||
|
||||
tools/target_bsf_%_fuzzer$(EXESUF): tools/target_bsf_%_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
|
||||
target_dem_%_fuzzer$(EXESUF): target_dem_%_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
|
||||
tools/target_dem_fuzzer$(EXESUF): tools/target_dem_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
|
||||
tools/target_io_dem_fuzzer$(EXESUF): tools/target_io_dem_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
|
||||
|
||||
tools/enum_options$(EXESUF): ELIBS = $(FF_EXTRALIBS)
|
||||
tools/enum_options$(EXESUF): $(FF_DEP_LIBS)
|
||||
tools/scale_slice_test$(EXESUF): $(FF_DEP_LIBS)
|
||||
tools/scale_slice_test$(EXESUF): ELIBS = $(FF_EXTRALIBS)
|
||||
tools/sofa2wavs$(EXESUF): ELIBS = $(FF_EXTRALIBS)
|
||||
tools/cws2fws$(EXESUF): ELIBS = $(ZLIB)
|
||||
tools/uncoded_frame$(EXESUF): $(FF_DEP_LIBS)
|
||||
tools/uncoded_frame$(EXESUF): ELIBS = $(FF_EXTRALIBS)
|
||||
tools/target_dec_%_fuzzer$(EXESUF): $(FF_DEP_LIBS)
|
||||
tools/target_dem_%_fuzzer$(EXESUF): $(FF_DEP_LIBS)
|
||||
|
||||
CONFIGURABLE_COMPONENTS = \
|
||||
$(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c)) \
|
||||
$(SRC_PATH)/libavcodec/bitstream_filters.c \
|
||||
$(SRC_PATH)/libavcodec/parsers.c \
|
||||
$(SRC_PATH)/libavformat/protocols.c \
|
||||
|
||||
config.h: ffbuild/.config
|
||||
ffbuild/.config: $(CONFIGURABLE_COMPONENTS)
|
||||
config.h: .config
|
||||
.config: $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c))
|
||||
@-tput bold 2>/dev/null
|
||||
@-printf '\nWARNING: $(?) newer than config.h, rerun configure\n\n'
|
||||
@-printf '\nWARNING: $(?F) newer than config.h, rerun configure\n\n'
|
||||
@-tput sgr0 2>/dev/null
|
||||
|
||||
SUBDIR_VARS := CLEANFILES FFLIBS HOSTPROGS TESTPROGS TOOLS \
|
||||
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 X86ASM-OBJS \
|
||||
ALTIVEC-OBJS MMX-OBJS YASM-OBJS \
|
||||
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSP-OBJS MSA-OBJS \
|
||||
MMI-OBJS LSX-OBJS LASX-OBJS OBJS SLIBOBJS SHLIBOBJS \
|
||||
STLIBOBJS HOSTOBJS TESTOBJS
|
||||
MMI-OBJS OBJS SLIBOBJS HOSTOBJS TESTOBJS
|
||||
|
||||
define RESET
|
||||
$(1) :=
|
||||
@@ -104,32 +103,41 @@ SUBDIR := $(1)/
|
||||
include $(SRC_PATH)/$(1)/Makefile
|
||||
-include $(SRC_PATH)/$(1)/$(ARCH)/Makefile
|
||||
-include $(SRC_PATH)/$(1)/$(INTRINSICS)/Makefile
|
||||
include $(SRC_PATH)/ffbuild/library.mak
|
||||
include $(SRC_PATH)/library.mak
|
||||
endef
|
||||
|
||||
$(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D))))
|
||||
|
||||
include $(SRC_PATH)/fftools/Makefile
|
||||
include $(SRC_PATH)/doc/Makefile
|
||||
include $(SRC_PATH)/doc/examples/Makefile
|
||||
|
||||
libavcodec/avcodec.o libavformat/utils.o libavdevice/avdevice.o libavfilter/avfilter.o libavutil/utils.o libpostproc/postprocess.o libswresample/swresample.o libswscale/utils.o : libavutil/ffversion.h
|
||||
define DOPROG
|
||||
OBJS-$(1) += $(1).o $(EXEOBJS) $(OBJS-$(1)-yes)
|
||||
$(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1))
|
||||
$$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1))
|
||||
$(1)$(PROGSSUF)_g$(EXESUF): LDFLAGS += $(LDFLAGS-$(1))
|
||||
$(1)$(PROGSSUF)_g$(EXESUF): FF_EXTRALIBS += $(LIBS-$(1))
|
||||
-include $$(OBJS-$(1):.o=.d)
|
||||
endef
|
||||
|
||||
$(foreach P,$(PROGS),$(eval $(call DOPROG,$(P:$(PROGSSUF)$(EXESUF)=))))
|
||||
|
||||
ffprobe.o cmdutils.o libavcodec/utils.o libavformat/utils.o libavdevice/avdevice.o libavfilter/avfilter.o libavutil/utils.o libpostproc/postprocess.o libswresample/swresample.o libswscale/utils.o : libavutil/ffversion.h
|
||||
|
||||
$(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF)
|
||||
ifeq ($(STRIPTYPE),direct)
|
||||
$(STRIP) -o $@ $<
|
||||
else
|
||||
$(CP) $< $@
|
||||
$(STRIP) $@
|
||||
endif
|
||||
|
||||
%$(PROGSSUF)_g$(EXESUF): $(FF_DEP_LIBS)
|
||||
%$(PROGSSUF)_g$(EXESUF): %.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS)
|
||||
|
||||
VERSION_SH = $(SRC_PATH)/ffbuild/version.sh
|
||||
OBJDIRS += tools
|
||||
|
||||
-include $(wildcard tools/*.d)
|
||||
|
||||
VERSION_SH = $(SRC_PATH)/version.sh
|
||||
GIT_LOG = $(SRC_PATH)/.git/logs/HEAD
|
||||
|
||||
.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) ffbuild/config.mak
|
||||
.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) config.mak
|
||||
.version: M=@
|
||||
|
||||
libavutil/ffversion.h .version:
|
||||
@@ -139,33 +147,44 @@ libavutil/ffversion.h .version:
|
||||
# force version.sh to run whenever version might have changed
|
||||
-include .version
|
||||
|
||||
ifdef AVPROGS
|
||||
install: install-progs install-data
|
||||
endif
|
||||
|
||||
install: install-libs install-headers
|
||||
|
||||
install-libs: install-libs-yes
|
||||
|
||||
install-data: $(DATA_FILES)
|
||||
$(Q)mkdir -p "$(DATADIR)"
|
||||
$(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)"
|
||||
install-progs-yes:
|
||||
install-progs-$(CONFIG_SHARED): install-libs
|
||||
|
||||
uninstall: uninstall-data uninstall-headers uninstall-libs uninstall-pkgconfig
|
||||
install-progs: install-progs-yes $(AVPROGS)
|
||||
$(Q)mkdir -p "$(BINDIR)"
|
||||
$(INSTALL) -c -m 755 $(INSTPROGS) "$(BINDIR)"
|
||||
|
||||
install-data: $(DATA_FILES) $(EXAMPLES_FILES)
|
||||
$(Q)mkdir -p "$(DATADIR)/examples"
|
||||
$(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)"
|
||||
$(INSTALL) -m 644 $(EXAMPLES_FILES) "$(DATADIR)/examples"
|
||||
|
||||
uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data
|
||||
|
||||
uninstall-progs:
|
||||
$(RM) $(addprefix "$(BINDIR)/", $(ALLAVPROGS))
|
||||
|
||||
uninstall-data:
|
||||
$(RM) -r "$(DATADIR)"
|
||||
|
||||
clean::
|
||||
$(RM) $(ALLAVPROGS) $(ALLAVPROGS_G)
|
||||
$(RM) $(CLEANSUFFIXES)
|
||||
$(RM) $(addprefix compat/,$(CLEANSUFFIXES)) $(addprefix compat/*/,$(CLEANSUFFIXES)) $(addprefix compat/*/*/,$(CLEANSUFFIXES))
|
||||
$(RM) $(CLEANSUFFIXES:%=tools/%)
|
||||
$(RM) -r coverage-html
|
||||
$(RM) -rf coverage.info coverage.info.in lcov
|
||||
|
||||
distclean:: clean
|
||||
$(RM) .version avversion.h config.asm config.h mapfile \
|
||||
ffbuild/.config ffbuild/config.* libavutil/avconfig.h \
|
||||
version.h libavutil/ffversion.h libavcodec/codec_names.h \
|
||||
libavcodec/bsf_list.c libavformat/protocol_list.c \
|
||||
libavcodec/codec_list.c libavcodec/parser_list.c \
|
||||
libavfilter/filter_list.c libavdevice/indev_list.c libavdevice/outdev_list.c \
|
||||
libavformat/muxer_list.c libavformat/demuxer_list.c
|
||||
distclean::
|
||||
$(RM) $(DISTCLEANSUFFIXES)
|
||||
$(RM) config.* .config libavutil/avconfig.h .version mapfile avversion.h version.h libavutil/ffversion.h libavcodec/codec_names.h libavcodec/bsf_list.c libavformat/protocol_list.c
|
||||
ifeq ($(SRC_LINK),src)
|
||||
$(RM) src
|
||||
endif
|
||||
@@ -174,12 +193,11 @@ endif
|
||||
config:
|
||||
$(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION)
|
||||
|
||||
build: all alltools examples testprogs
|
||||
check: all alltools examples testprogs fate
|
||||
|
||||
include $(SRC_PATH)/tests/Makefile
|
||||
|
||||
$(sort $(OUTDIRS)):
|
||||
$(sort $(OBJDIRS)):
|
||||
$(Q)mkdir -p $@
|
||||
|
||||
# Dummy rule to stop make trying to rebuild removed or renamed headers
|
||||
@@ -190,5 +208,5 @@ $(sort $(OUTDIRS)):
|
||||
# so this saves some time on slow systems.
|
||||
.SUFFIXES:
|
||||
|
||||
.PHONY: all all-yes alltools build check config testprogs
|
||||
.PHONY: *clean install* uninstall*
|
||||
.PHONY: all all-yes alltools check *clean config install*
|
||||
.PHONY: testprogs uninstall*
|
||||
|
||||
@@ -9,7 +9,7 @@ such as audio, video, subtitles and related metadata.
|
||||
* `libavcodec` provides implementation of a wider range of codecs.
|
||||
* `libavformat` implements streaming protocols, container formats and basic I/O access.
|
||||
* `libavutil` includes hashers, decompressors and miscellaneous utility functions.
|
||||
* `libavfilter` provides means to alter decoded audio and video through a directed graph of connected filters.
|
||||
* `libavfilter` provides a mean to alter decoded Audio and Video through chain of filters.
|
||||
* `libavdevice` provides an abstraction to access capture and playback devices.
|
||||
* `libswresample` implements audio mixing and resampling routines.
|
||||
* `libswscale` implements color conversion and scaling routines.
|
||||
@@ -21,6 +21,8 @@ such as audio, video, subtitles and related metadata.
|
||||
* [ffplay](https://ffmpeg.org/ffplay.html) is a minimalistic multimedia player.
|
||||
* [ffprobe](https://ffmpeg.org/ffprobe.html) is a simple analysis tool to inspect
|
||||
multimedia content.
|
||||
* [ffserver](https://ffmpeg.org/ffserver.html) is a multimedia streaming server
|
||||
for live broadcasts.
|
||||
* Additional small tools such as `aviocat`, `ismindex` and `qt-faststart`.
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
|
||||
┌────────────────────────────────────────┐
|
||||
│ RELEASE NOTES for FFmpeg 5.0 "Lorentz" │
|
||||
│ RELEASE NOTES for FFmpeg 3.2 "Hypatia" │
|
||||
└────────────────────────────────────────┘
|
||||
|
||||
The FFmpeg Project proudly presents FFmpeg 5.0 "Lorentz", about 9
|
||||
months after the release of FFmpeg 4.4.
|
||||
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 https://git.ffmpeg.org/gitweb/ffmpeg.git
|
||||
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.libera.chat) or ask
|
||||
feel free to join us on the #ffmpeg IRC channel (on irc.freenode.net) or ask
|
||||
on the mailing-lists.
|
||||
|
||||
@@ -8,12 +8,10 @@ OBJS-$(HAVE_MIPSFPU) += $(MIPSFPU-OBJS) $(MIPSFPU-OBJS-yes)
|
||||
OBJS-$(HAVE_MIPSDSP) += $(MIPSDSP-OBJS) $(MIPSDSP-OBJS-yes)
|
||||
OBJS-$(HAVE_MIPSDSPR2) += $(MIPSDSPR2-OBJS) $(MIPSDSPR2-OBJS-yes)
|
||||
OBJS-$(HAVE_MSA) += $(MSA-OBJS) $(MSA-OBJS-yes)
|
||||
OBJS-$(HAVE_MMI) += $(MMI-OBJS) $(MMI-OBJS-yes)
|
||||
OBJS-$(HAVE_LSX) += $(LSX-OBJS) $(LSX-OBJS-yes)
|
||||
OBJS-$(HAVE_LASX) += $(LASX-OBJS) $(LASX-OBJS-yes)
|
||||
OBJS-$(HAVE_MMI) += $(MMI-OBJS) $(MMI-OBJS-yes)
|
||||
|
||||
OBJS-$(HAVE_ALTIVEC) += $(ALTIVEC-OBJS) $(ALTIVEC-OBJS-yes)
|
||||
OBJS-$(HAVE_VSX) += $(VSX-OBJS) $(VSX-OBJS-yes)
|
||||
|
||||
OBJS-$(HAVE_MMX) += $(MMX-OBJS) $(MMX-OBJS-yes)
|
||||
OBJS-$(HAVE_X86ASM) += $(X86ASM-OBJS) $(X86ASM-OBJS-yes)
|
||||
OBJS-$(HAVE_YASM) += $(YASM-OBJS) $(YASM-OBJS-yes)
|
||||
@@ -34,14 +34,13 @@
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavfilter/avfilter.h"
|
||||
#include "libavdevice/avdevice.h"
|
||||
#include "libavresample/avresample.h"
|
||||
#include "libswscale/swscale.h"
|
||||
#include "libswresample/swresample.h"
|
||||
#include "libpostproc/postprocess.h"
|
||||
#include "libavutil/attributes.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/bprint.h"
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/display.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
@@ -54,8 +53,10 @@
|
||||
#include "libavutil/cpu.h"
|
||||
#include "libavutil/ffversion.h"
|
||||
#include "libavutil/version.h"
|
||||
#include "libavcodec/bsf.h"
|
||||
#include "cmdutils.h"
|
||||
#if CONFIG_NETWORK
|
||||
#include "libavformat/network.h"
|
||||
#endif
|
||||
#if HAVE_SYS_RESOURCE_H
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
@@ -68,17 +69,16 @@ static int init_report(const char *env);
|
||||
|
||||
AVDictionary *sws_dict;
|
||||
AVDictionary *swr_opts;
|
||||
AVDictionary *format_opts, *codec_opts;
|
||||
AVDictionary *format_opts, *codec_opts, *resample_opts;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void uninit_opts(void)
|
||||
{
|
||||
@@ -86,6 +86,7 @@ void uninit_opts(void)
|
||||
av_dict_free(&sws_dict);
|
||||
av_dict_free(&format_opts);
|
||||
av_dict_free(&codec_opts);
|
||||
av_dict_free(&resample_opts);
|
||||
}
|
||||
|
||||
void log_callback_help(void *ptr, int level, const char *fmt, va_list vl)
|
||||
@@ -111,7 +112,7 @@ static void log_callback_report(void *ptr, int level, const char *fmt, va_list v
|
||||
|
||||
void init_dynload(void)
|
||||
{
|
||||
#if HAVE_SETDLLDIRECTORY && defined(_WIN32)
|
||||
#ifdef _WIN32
|
||||
/* Calling SetDllDirectory with the empty string (but not NULL) removes the
|
||||
* current working directory from the DLL search path as a security pre-caution. */
|
||||
SetDllDirectory("");
|
||||
@@ -174,7 +175,7 @@ void show_help_options(const OptionDef *options, const char *msg, int req_flags,
|
||||
|
||||
first = 1;
|
||||
for (po = options; po->name; po++) {
|
||||
char buf[128];
|
||||
char buf[64];
|
||||
|
||||
if (((po->flags & req_flags) != req_flags) ||
|
||||
(alt_flags && !(po->flags & alt_flags)) ||
|
||||
@@ -197,22 +198,23 @@ void show_help_options(const OptionDef *options, const char *msg, int req_flags,
|
||||
|
||||
void show_help_children(const AVClass *class, int flags)
|
||||
{
|
||||
void *iter = NULL;
|
||||
const AVClass *child;
|
||||
const AVClass *child = NULL;
|
||||
if (class->option) {
|
||||
av_opt_show2(&class, NULL, flags, 0);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
while (child = av_opt_child_class_iterate(class, &iter))
|
||||
while (child = av_opt_child_class_next(class, child))
|
||||
show_help_children(child, flags);
|
||||
}
|
||||
|
||||
static const OptionDef *find_option(const OptionDef *po, const char *name)
|
||||
{
|
||||
const char *p = strchr(name, ':');
|
||||
int len = p ? p - name : strlen(name);
|
||||
|
||||
while (po->name) {
|
||||
const char *end;
|
||||
if (av_strstart(name, po->name, &end) && (!*end || *end == ':'))
|
||||
if (!strncmp(name, po->name, len) && strlen(po->name) == len)
|
||||
break;
|
||||
po++;
|
||||
}
|
||||
@@ -223,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;
|
||||
@@ -540,6 +543,9 @@ int opt_default(void *optctx, const char *opt, const char *arg)
|
||||
char opt_stripped[128];
|
||||
const char *p;
|
||||
const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class();
|
||||
#if CONFIG_AVRESAMPLE
|
||||
const AVClass *rc = avresample_get_class();
|
||||
#endif
|
||||
#if CONFIG_SWSCALE
|
||||
const AVClass *sc = sws_get_class();
|
||||
#endif
|
||||
@@ -609,6 +615,13 @@ int opt_default(void *optctx, const char *opt, const char *arg)
|
||||
consumed = 1;
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_AVRESAMPLE
|
||||
if ((o=opt_find(&rc, opt, NULL, 0,
|
||||
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
|
||||
av_dict_set(&resample_opts, opt, arg, FLAGS);
|
||||
consumed = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (consumed)
|
||||
return 0;
|
||||
@@ -656,11 +669,14 @@ static void finish_group(OptionParseContext *octx, int group_idx,
|
||||
g->swr_opts = swr_opts;
|
||||
g->codec_opts = codec_opts;
|
||||
g->format_opts = format_opts;
|
||||
g->resample_opts = resample_opts;
|
||||
|
||||
codec_opts = NULL;
|
||||
format_opts = NULL;
|
||||
resample_opts = NULL;
|
||||
sws_dict = NULL;
|
||||
swr_opts = NULL;
|
||||
init_opts();
|
||||
|
||||
memset(&octx->cur_group, 0, sizeof(octx->cur_group));
|
||||
}
|
||||
@@ -689,7 +705,7 @@ static void init_parse_context(OptionParseContext *octx,
|
||||
memset(octx, 0, sizeof(*octx));
|
||||
|
||||
octx->nb_groups = nb_groups;
|
||||
octx->groups = av_calloc(octx->nb_groups, sizeof(*octx->groups));
|
||||
octx->groups = av_mallocz_array(octx->nb_groups, sizeof(*octx->groups));
|
||||
if (!octx->groups)
|
||||
exit_program(1);
|
||||
|
||||
@@ -698,6 +714,8 @@ static void init_parse_context(OptionParseContext *octx,
|
||||
|
||||
octx->global_opts.group_def = &global_group;
|
||||
octx->global_opts.arg = "";
|
||||
|
||||
init_opts();
|
||||
}
|
||||
|
||||
void uninit_parse_context(OptionParseContext *octx)
|
||||
@@ -711,6 +729,7 @@ void uninit_parse_context(OptionParseContext *octx)
|
||||
av_freep(&l->groups[j].opts);
|
||||
av_dict_free(&l->groups[j].codec_opts);
|
||||
av_dict_free(&l->groups[j].format_opts);
|
||||
av_dict_free(&l->groups[j].resample_opts);
|
||||
|
||||
av_dict_free(&l->groups[j].sws_dict);
|
||||
av_dict_free(&l->groups[j].swr_opts);
|
||||
@@ -822,9 +841,9 @@ do { \
|
||||
return AVERROR_OPTION_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (octx->cur_group.nb_opts || codec_opts || format_opts)
|
||||
av_log(NULL, AV_LOG_WARNING, "Trailing option(s) found in the "
|
||||
"command: may be ignored.\n");
|
||||
if (octx->cur_group.nb_opts || codec_opts || format_opts || resample_opts)
|
||||
av_log(NULL, AV_LOG_WARNING, "Trailing options were found on the "
|
||||
"commandline.\n");
|
||||
|
||||
av_log(NULL, AV_LOG_DEBUG, "Finished splitting the commandline.\n");
|
||||
|
||||
@@ -843,32 +862,6 @@ int opt_cpuflags(void *optctx, const char *opt, const char *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opt_cpucount(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
int ret;
|
||||
int count;
|
||||
|
||||
static const AVOption opts[] = {
|
||||
{"count", NULL, 0, AV_OPT_TYPE_INT, { .i64 = -1}, -1, INT_MAX},
|
||||
{NULL},
|
||||
};
|
||||
static const AVClass class = {
|
||||
.class_name = "cpucount",
|
||||
.item_name = av_default_item_name,
|
||||
.option = opts,
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
};
|
||||
const AVClass *pclass = &class;
|
||||
|
||||
ret = av_opt_eval_int(&pclass, opts, arg, &count);
|
||||
|
||||
if (!ret) {
|
||||
av_cpu_force_count(count);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int opt_loglevel(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
const struct { const char *name; int level; } log_levels[] = {
|
||||
@@ -882,52 +875,28 @@ int opt_loglevel(void *optctx, const char *opt, const char *arg)
|
||||
{ "debug" , AV_LOG_DEBUG },
|
||||
{ "trace" , AV_LOG_TRACE },
|
||||
};
|
||||
const char *token;
|
||||
char *tail;
|
||||
int flags = av_log_get_flags();
|
||||
int level = av_log_get_level();
|
||||
int cmd, i = 0;
|
||||
int level;
|
||||
int flags;
|
||||
int i;
|
||||
|
||||
av_assert0(arg);
|
||||
while (*arg) {
|
||||
token = arg;
|
||||
if (*token == '+' || *token == '-') {
|
||||
cmd = *token++;
|
||||
} else {
|
||||
cmd = 0;
|
||||
}
|
||||
if (!i && !cmd) {
|
||||
flags = 0; /* missing relative prefix, build absolute value */
|
||||
}
|
||||
if (av_strstart(token, "repeat", &arg)) {
|
||||
if (cmd == '-') {
|
||||
flags |= AV_LOG_SKIP_REPEATED;
|
||||
} else {
|
||||
flags &= ~AV_LOG_SKIP_REPEATED;
|
||||
}
|
||||
} else if (av_strstart(token, "level", &arg)) {
|
||||
if (cmd == '-') {
|
||||
flags &= ~AV_LOG_PRINT_LEVEL;
|
||||
} else {
|
||||
flags |= AV_LOG_PRINT_LEVEL;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (!*arg) {
|
||||
goto end;
|
||||
} else if (*arg == '+') {
|
||||
arg++;
|
||||
} else if (!i) {
|
||||
flags = av_log_get_flags(); /* level value without prefix, reset flags */
|
||||
}
|
||||
flags = av_log_get_flags();
|
||||
tail = strstr(arg, "repeat");
|
||||
if (tail)
|
||||
flags &= ~AV_LOG_SKIP_REPEATED;
|
||||
else
|
||||
flags |= AV_LOG_SKIP_REPEATED;
|
||||
|
||||
av_log_set_flags(flags);
|
||||
if (tail == arg)
|
||||
arg += 6 + (arg[6]=='+');
|
||||
if(tail && !*arg)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
|
||||
if (!strcmp(log_levels[i].name, arg)) {
|
||||
level = log_levels[i].level;
|
||||
goto end;
|
||||
av_log_set_level(log_levels[i].level);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -939,9 +908,6 @@ int opt_loglevel(void *optctx, const char *opt, const char *arg)
|
||||
av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
end:
|
||||
av_log_set_flags(flags);
|
||||
av_log_set_level(level);
|
||||
return 0;
|
||||
}
|
||||
@@ -979,7 +945,6 @@ static int init_report(const char *env)
|
||||
char *filename_template = NULL;
|
||||
char *key, *val;
|
||||
int ret, count = 0;
|
||||
int prog_loglevel, envlevel = 0;
|
||||
time_t now;
|
||||
struct tm *tm;
|
||||
AVBPrint filename;
|
||||
@@ -1011,7 +976,6 @@ static int init_report(const char *env)
|
||||
av_log(NULL, AV_LOG_FATAL, "Invalid report file level\n");
|
||||
exit_program(1);
|
||||
}
|
||||
envlevel = 1;
|
||||
} else {
|
||||
av_log(NULL, AV_LOG_ERROR, "Unknown key '%s' in FFREPORT\n", key);
|
||||
}
|
||||
@@ -1019,7 +983,7 @@ static int init_report(const char *env)
|
||||
av_free(key);
|
||||
}
|
||||
|
||||
av_bprint_init(&filename, 0, AV_BPRINT_SIZE_AUTOMATIC);
|
||||
av_bprint_init(&filename, 0, 1);
|
||||
expand_filename_template(&filename,
|
||||
av_x_if_null(filename_template, "%p-%t.log"), tm);
|
||||
av_free(filename_template);
|
||||
@@ -1028,10 +992,6 @@ static int init_report(const char *env)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
prog_loglevel = av_log_get_level();
|
||||
if (!envlevel)
|
||||
report_file_level = FFMAX(report_file_level, prog_loglevel);
|
||||
|
||||
report_file = fopen(filename.str, "w");
|
||||
if (!report_file) {
|
||||
int ret = AVERROR(errno);
|
||||
@@ -1042,17 +1002,16 @@ static int init_report(const char *env)
|
||||
av_log_set_callback(log_callback_report);
|
||||
av_log(NULL, AV_LOG_INFO,
|
||||
"%s started on %04d-%02d-%02d at %02d:%02d:%02d\n"
|
||||
"Report written to \"%s\"\n"
|
||||
"Log level: %d\n",
|
||||
"Report written to \"%s\"\n",
|
||||
program_name,
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec,
|
||||
filename.str, report_file_level);
|
||||
filename.str);
|
||||
av_bprint_finalize(&filename, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opt_report(void *optctx, const char *opt, const char *arg)
|
||||
int opt_report(const char *opt)
|
||||
{
|
||||
return init_report(NULL);
|
||||
}
|
||||
@@ -1137,6 +1096,7 @@ static void print_all_libs_info(int flags, int level)
|
||||
PRINT_LIB_INFO(avformat, AVFORMAT, flags, level);
|
||||
PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
|
||||
PRINT_LIB_INFO(avfilter, AVFILTER, flags, level);
|
||||
PRINT_LIB_INFO(avresample, AVRESAMPLE, flags, level);
|
||||
PRINT_LIB_INFO(swscale, SWSCALE, flags, level);
|
||||
PRINT_LIB_INFO(swresample, SWRESAMPLE, flags, level);
|
||||
PRINT_LIB_INFO(postproc, POSTPROC, flags, level);
|
||||
@@ -1165,13 +1125,13 @@ static void print_buildconf(int flags, int level)
|
||||
// Change all the ' --' strings to '~--' so that
|
||||
// they can be identified as tokens.
|
||||
while ((conflist = strstr(str, " --")) != NULL) {
|
||||
conflist[0] = '~';
|
||||
strncpy(conflist, "~--", 3);
|
||||
}
|
||||
|
||||
// Compensate for the weirdness this would cause
|
||||
// when passing 'pkg-config --static'.
|
||||
while ((remove_tilde = strstr(str, "pkg-config~")) != NULL) {
|
||||
remove_tilde[sizeof("pkg-config~") - 2] = ' ';
|
||||
strncpy(remove_tilde, "pkg-config ", 11);
|
||||
}
|
||||
|
||||
splitconf = strtok(str, "~");
|
||||
@@ -1291,12 +1251,10 @@ 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)
|
||||
{
|
||||
void *ifmt_opaque = NULL;
|
||||
const AVInputFormat *ifmt = NULL;
|
||||
void *ofmt_opaque = NULL;
|
||||
const AVOutputFormat *ofmt = NULL;
|
||||
AVInputFormat *ifmt = NULL;
|
||||
AVOutputFormat *ofmt = NULL;
|
||||
const char *last_name;
|
||||
int is_dev;
|
||||
|
||||
@@ -1311,43 +1269,37 @@ 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) {
|
||||
ofmt_opaque = NULL;
|
||||
while ((ofmt = av_muxer_iterate(&ofmt_opaque))) {
|
||||
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) {
|
||||
ifmt_opaque = NULL;
|
||||
while ((ifmt = av_demuxer_iterate(&ifmt_opaque))) {
|
||||
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;
|
||||
last_name = name;
|
||||
|
||||
printf(" %c%c %-15s %s\n",
|
||||
decode ? 'D' : ' ',
|
||||
encode ? 'E' : ' ',
|
||||
printf(" %s%s %-15s %s\n",
|
||||
decode ? "D" : " ",
|
||||
encode ? "E" : " ",
|
||||
name,
|
||||
long_name ? long_name:" ");
|
||||
}
|
||||
@@ -1356,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) \
|
||||
@@ -1399,6 +1341,8 @@ static void print_codec(const AVCodec *c)
|
||||
printf("horizband ");
|
||||
if (c->capabilities & AV_CODEC_CAP_DR1)
|
||||
printf("dr1 ");
|
||||
if (c->capabilities & AV_CODEC_CAP_TRUNCATED)
|
||||
printf("trunc ");
|
||||
if (c->capabilities & AV_CODEC_CAP_DELAY)
|
||||
printf("delay ");
|
||||
if (c->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME)
|
||||
@@ -1415,14 +1359,8 @@ static void print_codec(const AVCodec *c)
|
||||
printf("variable ");
|
||||
if (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
|
||||
AV_CODEC_CAP_SLICE_THREADS |
|
||||
AV_CODEC_CAP_OTHER_THREADS))
|
||||
AV_CODEC_CAP_AUTO_THREADS))
|
||||
printf("threads ");
|
||||
if (c->capabilities & AV_CODEC_CAP_AVOID_PROBING)
|
||||
printf("avoidprobe ");
|
||||
if (c->capabilities & AV_CODEC_CAP_HARDWARE)
|
||||
printf("hardware ");
|
||||
if (c->capabilities & AV_CODEC_CAP_HYBRID)
|
||||
printf("hybrid ");
|
||||
if (!c->capabilities)
|
||||
printf("none");
|
||||
printf("\n");
|
||||
@@ -1432,28 +1370,17 @@ static void print_codec(const AVCodec *c)
|
||||
printf(" Threading capabilities: ");
|
||||
switch (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
|
||||
AV_CODEC_CAP_SLICE_THREADS |
|
||||
AV_CODEC_CAP_OTHER_THREADS)) {
|
||||
AV_CODEC_CAP_AUTO_THREADS)) {
|
||||
case AV_CODEC_CAP_FRAME_THREADS |
|
||||
AV_CODEC_CAP_SLICE_THREADS: printf("frame and slice"); break;
|
||||
case AV_CODEC_CAP_FRAME_THREADS: printf("frame"); break;
|
||||
case AV_CODEC_CAP_SLICE_THREADS: printf("slice"); break;
|
||||
case AV_CODEC_CAP_OTHER_THREADS: printf("other"); break;
|
||||
case AV_CODEC_CAP_AUTO_THREADS : printf("auto"); break;
|
||||
default: printf("none"); break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (avcodec_get_hw_config(c, 0)) {
|
||||
printf(" Supported hardware devices: ");
|
||||
for (int i = 0;; i++) {
|
||||
const AVCodecHWConfig *config = avcodec_get_hw_config(c, i);
|
||||
if (!config)
|
||||
break;
|
||||
printf("%s ", av_hwdevice_get_type_name(config->device_type));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (c->supported_framerates) {
|
||||
const AVRational *fps = c->supported_framerates;
|
||||
|
||||
@@ -1492,14 +1419,13 @@ static char get_media_type_char(enum AVMediaType type)
|
||||
}
|
||||
}
|
||||
|
||||
static const AVCodec *next_codec_for_id(enum AVCodecID id, void **iter,
|
||||
static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev,
|
||||
int encoder)
|
||||
{
|
||||
const AVCodec *c;
|
||||
while ((c = av_codec_iterate(iter))) {
|
||||
if (c->id == id &&
|
||||
(encoder ? av_codec_is_encoder(c) : av_codec_is_decoder(c)))
|
||||
return c;
|
||||
while ((prev = av_codec_next(prev))) {
|
||||
if (prev->id == id &&
|
||||
(encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev)))
|
||||
return prev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -1536,12 +1462,11 @@ static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
|
||||
|
||||
static void print_codecs_for_id(enum AVCodecID id, int encoder)
|
||||
{
|
||||
void *iter = NULL;
|
||||
const AVCodec *codec;
|
||||
const AVCodec *codec = NULL;
|
||||
|
||||
printf(" (%s: ", encoder ? "encoders" : "decoders");
|
||||
|
||||
while ((codec = next_codec_for_id(id, &iter, encoder)))
|
||||
while ((codec = next_codec_for_id(id, codec, encoder)))
|
||||
printf("%s ", codec->name);
|
||||
|
||||
printf(")");
|
||||
@@ -1564,8 +1489,7 @@ int show_codecs(void *optctx, const char *opt, const char *arg)
|
||||
" -------\n");
|
||||
for (i = 0; i < nb_codecs; i++) {
|
||||
const AVCodecDescriptor *desc = codecs[i];
|
||||
const AVCodec *codec;
|
||||
void *iter = NULL;
|
||||
const AVCodec *codec = NULL;
|
||||
|
||||
if (strstr(desc->name, "_deprecated"))
|
||||
continue;
|
||||
@@ -1583,14 +1507,14 @@ int show_codecs(void *optctx, const char *opt, const char *arg)
|
||||
|
||||
/* print decoders/encoders when there's more than one or their
|
||||
* names are different from codec name */
|
||||
while ((codec = next_codec_for_id(desc->id, &iter, 0))) {
|
||||
while ((codec = next_codec_for_id(desc->id, codec, 0))) {
|
||||
if (strcmp(codec->name, desc->name)) {
|
||||
print_codecs_for_id(desc->id, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
iter = NULL;
|
||||
while ((codec = next_codec_for_id(desc->id, &iter, 1))) {
|
||||
codec = NULL;
|
||||
while ((codec = next_codec_for_id(desc->id, codec, 1))) {
|
||||
if (strcmp(codec->name, desc->name)) {
|
||||
print_codecs_for_id(desc->id, 1);
|
||||
break;
|
||||
@@ -1621,10 +1545,9 @@ static void print_codecs(int encoder)
|
||||
encoder ? "Encoders" : "Decoders");
|
||||
for (i = 0; i < nb_codecs; i++) {
|
||||
const AVCodecDescriptor *desc = codecs[i];
|
||||
const AVCodec *codec;
|
||||
void *iter = NULL;
|
||||
const AVCodec *codec = NULL;
|
||||
|
||||
while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
|
||||
while ((codec = next_codec_for_id(desc->id, codec, encoder))) {
|
||||
printf(" %c", get_media_type_char(desc->type));
|
||||
printf((codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? "F" : ".");
|
||||
printf((codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : ".");
|
||||
@@ -1660,7 +1583,7 @@ int show_bsfs(void *optctx, const char *opt, const char *arg)
|
||||
void *opaque = NULL;
|
||||
|
||||
printf("Bitstream filters:\n");
|
||||
while ((bsf = av_bsf_iterate(&opaque)))
|
||||
while ((bsf = av_bsf_next(&opaque)))
|
||||
printf("%s\n", bsf->name);
|
||||
printf("\n");
|
||||
return 0;
|
||||
@@ -1686,7 +1609,6 @@ int show_filters(void *optctx, const char *opt, const char *arg)
|
||||
#if CONFIG_AVFILTER
|
||||
const AVFilter *filter = NULL;
|
||||
char descr[64], *descr_cur;
|
||||
void *opaque = NULL;
|
||||
int i, j;
|
||||
const AVFilterPad *pad;
|
||||
|
||||
@@ -1698,17 +1620,15 @@ int show_filters(void *optctx, const char *opt, const char *arg)
|
||||
" V = Video input/output\n"
|
||||
" N = Dynamic number and/or type of input/output\n"
|
||||
" | = Source or sink filter\n");
|
||||
while ((filter = av_filter_iterate(&opaque))) {
|
||||
while ((filter = avfilter_next(filter))) {
|
||||
descr_cur = descr;
|
||||
for (i = 0; i < 2; i++) {
|
||||
unsigned nb_pads;
|
||||
if (i) {
|
||||
*(descr_cur++) = '-';
|
||||
*(descr_cur++) = '>';
|
||||
}
|
||||
pad = i ? filter->outputs : filter->inputs;
|
||||
nb_pads = avfilter_filter_pad_count(filter, i);
|
||||
for (j = 0; j < nb_pads; j++) {
|
||||
for (j = 0; pad && avfilter_pad_get_name(pad, j); j++) {
|
||||
if (descr_cur >= descr + sizeof(descr) - 4)
|
||||
break;
|
||||
*(descr_cur++) = get_media_type_char(avfilter_pad_get_type(pad, j));
|
||||
@@ -1754,7 +1674,7 @@ int show_pix_fmts(void *optctx, const char *opt, const char *arg)
|
||||
"..H.. = Hardware accelerated format\n"
|
||||
"...P. = Paletted format\n"
|
||||
"....B = Bitstream format\n"
|
||||
"FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL BIT_DEPTHS\n"
|
||||
"FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
|
||||
"-----\n");
|
||||
|
||||
#if !CONFIG_SWSCALE
|
||||
@@ -1763,8 +1683,8 @@ int show_pix_fmts(void *optctx, const char *opt, const char *arg)
|
||||
#endif
|
||||
|
||||
while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) {
|
||||
enum AVPixelFormat av_unused pix_fmt = av_pix_fmt_desc_get_id(pix_desc);
|
||||
printf("%c%c%c%c%c %-16s %d %3d %d",
|
||||
enum AVPixelFormat pix_fmt = av_pix_fmt_desc_get_id(pix_desc);
|
||||
printf("%c%c%c%c%c %-16s %d %2d\n",
|
||||
sws_isSupportedInput (pix_fmt) ? 'I' : '.',
|
||||
sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
|
||||
pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL ? 'H' : '.',
|
||||
@@ -1772,12 +1692,7 @@ int show_pix_fmts(void *optctx, const char *opt, const char *arg)
|
||||
pix_desc->flags & AV_PIX_FMT_FLAG_BITSTREAM ? 'B' : '.',
|
||||
pix_desc->name,
|
||||
pix_desc->nb_components,
|
||||
av_get_bits_per_pixel(pix_desc),
|
||||
pix_desc->comp[0].depth);
|
||||
|
||||
for (unsigned i = 1; i < pix_desc->nb_components; i++)
|
||||
printf("-%d", pix_desc->comp[i].depth);
|
||||
printf("\n");
|
||||
av_get_bits_per_pixel(pix_desc));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1820,16 +1735,6 @@ int show_sample_fmts(void *optctx, const char *opt, const char *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int show_dispositions(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
for (int i = 0; i < 32; i++) {
|
||||
const char *str = av_disposition_to_string(1U << i);
|
||||
if (str)
|
||||
printf("%s\n", str);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void show_help_codec(const char *name, int encoder)
|
||||
{
|
||||
const AVCodecDescriptor *desc;
|
||||
@@ -1846,10 +1751,9 @@ static void show_help_codec(const char *name, int encoder)
|
||||
if (codec)
|
||||
print_codec(codec);
|
||||
else if ((desc = avcodec_descriptor_get_by_name(name))) {
|
||||
void *iter = NULL;
|
||||
int printed = 0;
|
||||
|
||||
while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
|
||||
while ((codec = next_codec_for_id(desc->id, codec, encoder))) {
|
||||
printed = 1;
|
||||
print_codec(codec);
|
||||
}
|
||||
@@ -1884,24 +1788,6 @@ static void show_help_demuxer(const char *name)
|
||||
show_help_children(fmt->priv_class, AV_OPT_FLAG_DECODING_PARAM);
|
||||
}
|
||||
|
||||
static void show_help_protocol(const char *name)
|
||||
{
|
||||
const AVClass *proto_class;
|
||||
|
||||
if (!name) {
|
||||
av_log(NULL, AV_LOG_ERROR, "No protocol name specified.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
proto_class = avio_protocol_get_class(name);
|
||||
if (!proto_class) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Unknown protocol '%s'.\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
show_help_children(proto_class, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
|
||||
}
|
||||
|
||||
static void show_help_muxer(const char *name)
|
||||
{
|
||||
const AVCodecDescriptor *desc;
|
||||
@@ -1958,7 +1844,7 @@ static void show_help_filter(const char *name)
|
||||
printf(" slice threading supported\n");
|
||||
|
||||
printf(" Inputs:\n");
|
||||
count = avfilter_filter_pad_count(f, 0);
|
||||
count = avfilter_pad_count(f->inputs);
|
||||
for (i = 0; i < count; i++) {
|
||||
printf(" #%d: %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i),
|
||||
media_type_string(avfilter_pad_get_type(f->inputs, i)));
|
||||
@@ -1969,7 +1855,7 @@ static void show_help_filter(const char *name)
|
||||
printf(" none (source filter)\n");
|
||||
|
||||
printf(" Outputs:\n");
|
||||
count = avfilter_filter_pad_count(f, 1);
|
||||
count = avfilter_pad_count(f->outputs);
|
||||
for (i = 0; i < count; i++) {
|
||||
printf(" #%d: %s (%s)\n", i, avfilter_pad_get_name(f->outputs, i),
|
||||
media_type_string(avfilter_pad_get_type(f->outputs, i)));
|
||||
@@ -1991,25 +1877,6 @@ static void show_help_filter(const char *name)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void show_help_bsf(const char *name)
|
||||
{
|
||||
const AVBitStreamFilter *bsf = av_bsf_get_by_name(name);
|
||||
|
||||
if (!name) {
|
||||
av_log(NULL, AV_LOG_ERROR, "No bitstream filter name specified.\n");
|
||||
return;
|
||||
} else if (!bsf) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Unknown bit stream filter '%s'.\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Bit stream filter %s\n", bsf->name);
|
||||
PRINT_CODEC_SUPPORTED(bsf, codec_ids, enum AVCodecID, "codecs",
|
||||
AV_CODEC_ID_NONE, GET_CODEC_NAME);
|
||||
if (bsf->priv_class)
|
||||
show_help_children(bsf->priv_class, AV_OPT_FLAG_BSF_PARAM);
|
||||
}
|
||||
|
||||
int show_help(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
char *topic, *par;
|
||||
@@ -2032,14 +1899,10 @@ int show_help(void *optctx, const char *opt, const char *arg)
|
||||
show_help_demuxer(par);
|
||||
} else if (!strcmp(topic, "muxer")) {
|
||||
show_help_muxer(par);
|
||||
} else if (!strcmp(topic, "protocol")) {
|
||||
show_help_protocol(par);
|
||||
#if CONFIG_AVFILTER
|
||||
} else if (!strcmp(topic, "filter")) {
|
||||
show_help_filter(par);
|
||||
#endif
|
||||
} else if (!strcmp(topic, "bsf")) {
|
||||
show_help_bsf(par);
|
||||
} else {
|
||||
show_help_default(topic, par);
|
||||
}
|
||||
@@ -2073,7 +1936,7 @@ FILE *get_preset_file(char *filename, size_t filename_size,
|
||||
av_strlcpy(filename, preset_name, filename_size);
|
||||
f = fopen(filename, "r");
|
||||
} else {
|
||||
#if HAVE_GETMODULEHANDLE && defined(_WIN32)
|
||||
#ifdef _WIN32
|
||||
char datadir[MAX_PATH], *ls;
|
||||
base[2] = NULL;
|
||||
|
||||
@@ -2118,10 +1981,10 @@ int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
|
||||
}
|
||||
|
||||
AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
|
||||
AVFormatContext *s, AVStream *st, const AVCodec *codec)
|
||||
AVFormatContext *s, AVStream *st, AVCodec *codec)
|
||||
{
|
||||
AVDictionary *ret = NULL;
|
||||
const AVDictionaryEntry *t = NULL;
|
||||
AVDictionaryEntry *t = NULL;
|
||||
int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM
|
||||
: AV_OPT_FLAG_DECODING_PARAM;
|
||||
char prefix = 0;
|
||||
@@ -2147,7 +2010,6 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
|
||||
}
|
||||
|
||||
while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
|
||||
const AVClass *priv_class;
|
||||
char *p = strchr(t->key, ':');
|
||||
|
||||
/* check stream specification in opt name */
|
||||
@@ -2160,8 +2022,8 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
|
||||
|
||||
if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
|
||||
!codec ||
|
||||
((priv_class = codec->priv_class) &&
|
||||
av_opt_find(&priv_class, t->key, NULL, flags,
|
||||
(codec->priv_class &&
|
||||
av_opt_find(&codec->priv_class, t->key, NULL, flags,
|
||||
AV_OPT_SEARCH_FAKE_OBJ)))
|
||||
av_dict_set(&ret, t->key, t->value, 0);
|
||||
else if (t->key[0] == prefix &&
|
||||
@@ -2183,11 +2045,11 @@ AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
|
||||
|
||||
if (!s->nb_streams)
|
||||
return NULL;
|
||||
opts = av_calloc(s->nb_streams, sizeof(*opts));
|
||||
opts = av_mallocz_array(s->nb_streams, sizeof(*opts));
|
||||
if (!opts) {
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"Could not alloc memory for stream options.\n");
|
||||
exit_program(1);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < s->nb_streams; i++)
|
||||
opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codecpar->codec_id,
|
||||
@@ -2214,92 +2076,88 @@ void *grow_array(void *array, int elem_size, int *size, int new_size)
|
||||
return array;
|
||||
}
|
||||
|
||||
void *allocate_array_elem(void *ptr, size_t elem_size, int *nb_elems)
|
||||
{
|
||||
void *new_elem;
|
||||
|
||||
if (!(new_elem = av_mallocz(elem_size)) ||
|
||||
av_dynarray_add_nofree(ptr, nb_elems, new_elem) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
|
||||
exit_program(1);
|
||||
}
|
||||
return new_elem;
|
||||
}
|
||||
|
||||
double get_rotation(int32_t *displaymatrix)
|
||||
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)
|
||||
theta = -round(av_display_rotation_get((int32_t*) 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);
|
||||
|
||||
if (fabs(theta - 90*round(theta/90)) > 2)
|
||||
av_log(NULL, AV_LOG_WARNING, "Odd rotation angle.\n"
|
||||
"If you want to help, upload a sample "
|
||||
"of this file to https://streams.videolan.org/upload/ "
|
||||
"of this file to ftp://upload.ffmpeg.org/incoming/ "
|
||||
"and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)");
|
||||
|
||||
return theta;
|
||||
}
|
||||
|
||||
#if CONFIG_AVDEVICE
|
||||
static void print_device_list(const AVDeviceInfoList *device_list)
|
||||
static int print_device_sources(AVInputFormat *fmt, AVDictionary *opts)
|
||||
{
|
||||
// print devices
|
||||
for (int i = 0; i < device_list->nb_devices; i++) {
|
||||
const AVDeviceInfo *device = device_list->devices[i];
|
||||
printf("%c %s [%s] (", device_list->default_device == i ? '*' : ' ',
|
||||
device->device_name, device->device_description);
|
||||
if (device->nb_media_types > 0) {
|
||||
for (int j = 0; j < device->nb_media_types; ++j) {
|
||||
const char* media_type = av_get_media_type_string(device->media_types[j]);
|
||||
if (j > 0)
|
||||
printf(", ");
|
||||
printf("%s", media_type ? media_type : "unknown");
|
||||
}
|
||||
} else {
|
||||
printf("none");
|
||||
}
|
||||
printf(")\n");
|
||||
}
|
||||
}
|
||||
static int print_device_sources(const AVInputFormat *fmt, AVDictionary *opts)
|
||||
{
|
||||
int ret;
|
||||
int ret, i;
|
||||
AVDeviceInfoList *device_list = NULL;
|
||||
|
||||
if (!fmt || !fmt->priv_class || !AV_IS_INPUT_DEVICE(fmt->priv_class->category))
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
printf("Auto-detected sources for %s:\n", fmt->name);
|
||||
if ((ret = avdevice_list_input_sources(fmt, NULL, opts, &device_list)) < 0) {
|
||||
printf("Cannot list sources: %s\n", av_err2str(ret));
|
||||
if (!fmt->get_device_list) {
|
||||
ret = AVERROR(ENOSYS);
|
||||
printf("Cannot list sources. Not implemented.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
print_device_list(device_list);
|
||||
if ((ret = avdevice_list_input_sources(fmt, NULL, opts, &device_list)) < 0) {
|
||||
printf("Cannot list sources.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < device_list->nb_devices; i++) {
|
||||
printf("%s %s [%s]\n", device_list->default_device == i ? "*" : " ",
|
||||
device_list->devices[i]->device_name, device_list->devices[i]->device_description);
|
||||
}
|
||||
|
||||
fail:
|
||||
avdevice_free_list_devices(&device_list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int print_device_sinks(const AVOutputFormat *fmt, AVDictionary *opts)
|
||||
static int print_device_sinks(AVOutputFormat *fmt, AVDictionary *opts)
|
||||
{
|
||||
int ret;
|
||||
int ret, i;
|
||||
AVDeviceInfoList *device_list = NULL;
|
||||
|
||||
if (!fmt || !fmt->priv_class || !AV_IS_OUTPUT_DEVICE(fmt->priv_class->category))
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
printf("Auto-detected sinks for %s:\n", fmt->name);
|
||||
if ((ret = avdevice_list_output_sinks(fmt, NULL, opts, &device_list)) < 0) {
|
||||
printf("Cannot list sinks: %s\n", av_err2str(ret));
|
||||
if (!fmt->get_device_list) {
|
||||
ret = AVERROR(ENOSYS);
|
||||
printf("Cannot list sinks. Not implemented.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
print_device_list(device_list);
|
||||
if ((ret = avdevice_list_output_sinks(fmt, NULL, opts, &device_list)) < 0) {
|
||||
printf("Cannot list sinks.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < device_list->nb_devices; i++) {
|
||||
printf("%s %s [%s]\n", device_list->default_device == i ? "*" : " ",
|
||||
device_list->devices[i]->device_name, device_list->devices[i]->device_description);
|
||||
}
|
||||
|
||||
fail:
|
||||
avdevice_free_list_devices(&device_list);
|
||||
@@ -2330,13 +2188,13 @@ static int show_sinks_sources_parse_arg(const char *arg, char **dev, AVDictionar
|
||||
|
||||
int show_sources(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
const AVInputFormat *fmt = NULL;
|
||||
AVInputFormat *fmt = NULL;
|
||||
char *dev = NULL;
|
||||
AVDictionary *opts = NULL;
|
||||
int ret = 0;
|
||||
int error_level = av_log_get_level();
|
||||
|
||||
av_log_set_level(AV_LOG_WARNING);
|
||||
av_log_set_level(AV_LOG_ERROR);
|
||||
|
||||
if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
|
||||
goto fail;
|
||||
@@ -2368,13 +2226,13 @@ int show_sources(void *optctx, const char *opt, const char *arg)
|
||||
|
||||
int show_sinks(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
const AVOutputFormat *fmt = NULL;
|
||||
AVOutputFormat *fmt = NULL;
|
||||
char *dev = NULL;
|
||||
AVDictionary *opts = NULL;
|
||||
int ret = 0;
|
||||
int error_level = av_log_get_level();
|
||||
|
||||
av_log_set_level(AV_LOG_WARNING);
|
||||
av_log_set_level(AV_LOG_ERROR);
|
||||
|
||||
if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
|
||||
goto fail;
|
||||
@@ -19,8 +19,8 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef FFTOOLS_CMDUTILS_H
|
||||
#define FFTOOLS_CMDUTILS_H
|
||||
#ifndef CMDUTILS_H
|
||||
#define CMDUTILS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -48,7 +48,7 @@ extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
|
||||
extern AVFormatContext *avformat_opts;
|
||||
extern AVDictionary *sws_dict;
|
||||
extern AVDictionary *swr_opts;
|
||||
extern AVDictionary *format_opts, *codec_opts;
|
||||
extern AVDictionary *format_opts, *codec_opts, *resample_opts;
|
||||
extern int hide_banner;
|
||||
|
||||
/**
|
||||
@@ -88,11 +88,6 @@ void log_callback_help(void* ptr, int level, const char* fmt, va_list vl);
|
||||
*/
|
||||
int opt_cpuflags(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Override the cpucount.
|
||||
*/
|
||||
int opt_cpucount(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Fallback for options that are not explicitly handled, these will be
|
||||
* parsed through AVOptions.
|
||||
@@ -104,12 +99,18 @@ int opt_default(void *optctx, const char *opt, const char *arg);
|
||||
*/
|
||||
int opt_loglevel(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
int opt_report(void *optctx, const char *opt, const char *arg);
|
||||
int opt_report(const char *opt);
|
||||
|
||||
int opt_max_alloc(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
int opt_codec_debug(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
#if CONFIG_OPENCL
|
||||
int opt_opencl(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
int opt_opencl_bench(void *optctx, const char *opt, const char *arg);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Limit the execution time.
|
||||
*/
|
||||
@@ -154,7 +155,6 @@ typedef struct SpecifierOpt {
|
||||
uint8_t *str;
|
||||
int i;
|
||||
int64_t i64;
|
||||
uint64_t ui64;
|
||||
float f;
|
||||
double dbl;
|
||||
} u;
|
||||
@@ -206,49 +206,6 @@ typedef struct OptionDef {
|
||||
void show_help_options(const OptionDef *options, const char *msg, int req_flags,
|
||||
int rej_flags, int alt_flags);
|
||||
|
||||
#if CONFIG_AVDEVICE
|
||||
#define CMDUTILS_COMMON_OPTIONS_AVDEVICE \
|
||||
{ "sources" , OPT_EXIT | HAS_ARG, { .func_arg = show_sources }, \
|
||||
"list sources of the input device", "device" }, \
|
||||
{ "sinks" , OPT_EXIT | HAS_ARG, { .func_arg = show_sinks }, \
|
||||
"list sinks of the output device", "device" }, \
|
||||
|
||||
#else
|
||||
#define CMDUTILS_COMMON_OPTIONS_AVDEVICE
|
||||
#endif
|
||||
|
||||
#define CMDUTILS_COMMON_OPTIONS \
|
||||
{ "L", OPT_EXIT, { .func_arg = show_license }, "show license" }, \
|
||||
{ "h", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" }, \
|
||||
{ "?", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" }, \
|
||||
{ "help", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" }, \
|
||||
{ "-help", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" }, \
|
||||
{ "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" }, \
|
||||
{ "encoders", OPT_EXIT, { .func_arg = show_encoders }, "show available encoders" }, \
|
||||
{ "bsfs", OPT_EXIT, { .func_arg = show_bsfs }, "show available bit stream filters" }, \
|
||||
{ "protocols", OPT_EXIT, { .func_arg = show_protocols }, "show available protocols" }, \
|
||||
{ "filters", OPT_EXIT, { .func_arg = show_filters }, "show available filters" }, \
|
||||
{ "pix_fmts", OPT_EXIT, { .func_arg = show_pix_fmts }, "show available pixel formats" }, \
|
||||
{ "layouts", OPT_EXIT, { .func_arg = show_layouts }, "show standard channel layouts" }, \
|
||||
{ "sample_fmts", OPT_EXIT, { .func_arg = show_sample_fmts }, "show available audio sample formats" }, \
|
||||
{ "dispositions", OPT_EXIT, { .func_arg = show_dispositions}, "show available stream dispositions" }, \
|
||||
{ "colors", OPT_EXIT, { .func_arg = show_colors }, "show available color names" }, \
|
||||
{ "loglevel", HAS_ARG, { .func_arg = opt_loglevel }, "set logging level", "loglevel" }, \
|
||||
{ "v", HAS_ARG, { .func_arg = opt_loglevel }, "set logging level", "loglevel" }, \
|
||||
{ "report", 0, { .func_arg = opt_report }, "generate a report" }, \
|
||||
{ "max_alloc", HAS_ARG, { .func_arg = opt_max_alloc }, "set maximum size of a single allocated block", "bytes" }, \
|
||||
{ "cpuflags", HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpuflags }, "force specific cpu flags", "flags" }, \
|
||||
{ "cpucount", HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpucount }, "force specific cpu count", "count" }, \
|
||||
{ "hide_banner", OPT_BOOL | OPT_EXPERT, {&hide_banner}, "do not show program banner", "hide_banner" }, \
|
||||
CMDUTILS_COMMON_OPTIONS_AVDEVICE \
|
||||
|
||||
/**
|
||||
* Show help for all options with given flags in class and all its
|
||||
* children.
|
||||
@@ -324,6 +281,7 @@ typedef struct OptionGroup {
|
||||
|
||||
AVDictionary *codec_opts;
|
||||
AVDictionary *format_opts;
|
||||
AVDictionary *resample_opts;
|
||||
AVDictionary *sws_dict;
|
||||
AVDictionary *swr_opts;
|
||||
} OptionGroup;
|
||||
@@ -420,7 +378,7 @@ int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec);
|
||||
* @return a pointer to the created dictionary
|
||||
*/
|
||||
AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
|
||||
AVFormatContext *s, AVStream *st, const AVCodec *codec);
|
||||
AVFormatContext *s, AVStream *st, AVCodec *codec);
|
||||
|
||||
/**
|
||||
* Setup AVCodecContext options for avformat_find_stream_info().
|
||||
@@ -430,8 +388,8 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
|
||||
* Each dictionary will contain the options from codec_opts which can
|
||||
* be applied to the corresponding stream codec context.
|
||||
*
|
||||
* @return pointer to the created array of dictionaries.
|
||||
* Calls exit() on failure.
|
||||
* @return pointer to the created array of dictionaries, NULL if it
|
||||
* cannot be created
|
||||
*/
|
||||
AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
|
||||
AVDictionary *codec_opts);
|
||||
@@ -483,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.
|
||||
@@ -578,11 +522,6 @@ int show_layouts(void *optctx, const char *opt, const char *arg);
|
||||
*/
|
||||
int show_sample_fmts(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Print a listing containing all supported stream dispositions.
|
||||
*/
|
||||
int show_dispositions(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Print a listing containing all the color names and values recognized
|
||||
* by the program.
|
||||
@@ -628,34 +567,14 @@ FILE *get_preset_file(char *filename, size_t filename_size,
|
||||
*/
|
||||
void *grow_array(void *array, int elem_size, int *size, int new_size);
|
||||
|
||||
/**
|
||||
* Atomically add a new element to an array of pointers, i.e. allocate
|
||||
* a new entry, reallocate the array of pointers and make the new last
|
||||
* member of this array point to the newly allocated buffer.
|
||||
* Calls exit() on failure.
|
||||
*
|
||||
* @param array array of pointers to reallocate
|
||||
* @param elem_size size of the new element to allocate
|
||||
* @param nb_elems pointer to the number of elements of the array array;
|
||||
* *nb_elems will be incremented by one by this function.
|
||||
* @return pointer to the newly allocated entry
|
||||
*/
|
||||
void *allocate_array_elem(void *array, size_t elem_size, int *nb_elems);
|
||||
|
||||
#define media_type_string av_get_media_type_string
|
||||
|
||||
#define GROW_ARRAY(array, nb_elems)\
|
||||
array = grow_array(array, sizeof(*array), &nb_elems, nb_elems + 1)
|
||||
|
||||
#define ALLOC_ARRAY_ELEM(array, nb_elems)\
|
||||
allocate_array_elem(&array, sizeof(*array[0]), &nb_elems)
|
||||
|
||||
#define GET_PIX_FMT_NAME(pix_fmt)\
|
||||
const char *name = av_get_pix_fmt_name(pix_fmt);
|
||||
|
||||
#define GET_CODEC_NAME(id)\
|
||||
const char *name = avcodec_descriptor_get(id)->name;
|
||||
|
||||
#define GET_SAMPLE_FMT_NAME(sample_fmt)\
|
||||
const char *name = av_get_sample_fmt_name(sample_fmt)
|
||||
|
||||
@@ -671,6 +590,6 @@ void *allocate_array_elem(void *array, size_t elem_size, int *nb_elems);
|
||||
char name[128];\
|
||||
av_get_channel_layout_string(name, sizeof(name), 0, ch_layout);
|
||||
|
||||
double get_rotation(int32_t *displaymatrix);
|
||||
double get_rotation(AVStream *st);
|
||||
|
||||
#endif /* FFTOOLS_CMDUTILS_H */
|
||||
#endif /* CMDUTILS_H */
|
||||
35
cmdutils_common_opts.h
Normal file
35
cmdutils_common_opts.h
Normal file
@@ -0,0 +1,35 @@
|
||||
{ "L" , OPT_EXIT, {.func_arg = show_license}, "show license" },
|
||||
{ "h" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" },
|
||||
{ "?" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" },
|
||||
{ "help" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" },
|
||||
{ "-help" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" },
|
||||
{ "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" },
|
||||
{ "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" },
|
||||
{ "encoders" , OPT_EXIT, {.func_arg = show_encoders }, "show available encoders" },
|
||||
{ "bsfs" , OPT_EXIT, {.func_arg = show_bsfs }, "show available bit stream filters" },
|
||||
{ "protocols" , OPT_EXIT, {.func_arg = show_protocols}, "show available protocols" },
|
||||
{ "filters" , OPT_EXIT, {.func_arg = show_filters }, "show available filters" },
|
||||
{ "pix_fmts" , OPT_EXIT, {.func_arg = show_pix_fmts }, "show available pixel formats" },
|
||||
{ "layouts" , OPT_EXIT, {.func_arg = show_layouts }, "show standard channel layouts" },
|
||||
{ "sample_fmts", OPT_EXIT, {.func_arg = show_sample_fmts }, "show available audio sample formats" },
|
||||
{ "colors" , OPT_EXIT, {.func_arg = show_colors }, "show available color names" },
|
||||
{ "loglevel" , HAS_ARG, {.func_arg = opt_loglevel}, "set logging level", "loglevel" },
|
||||
{ "v", HAS_ARG, {.func_arg = opt_loglevel}, "set logging level", "loglevel" },
|
||||
{ "report" , 0, {(void*)opt_report}, "generate a report" },
|
||||
{ "max_alloc" , HAS_ARG, {.func_arg = opt_max_alloc}, "set maximum size of a single allocated block", "bytes" },
|
||||
{ "cpuflags" , HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpuflags }, "force specific cpu flags", "flags" },
|
||||
{ "hide_banner", OPT_BOOL | OPT_EXPERT, {&hide_banner}, "do not show program banner", "hide_banner" },
|
||||
#if CONFIG_OPENCL
|
||||
{ "opencl_bench", OPT_EXIT, {.func_arg = opt_opencl_bench}, "run benchmark on all OpenCL devices and show results" },
|
||||
{ "opencl_options", HAS_ARG, {.func_arg = opt_opencl}, "set OpenCL environment options" },
|
||||
#endif
|
||||
#if CONFIG_AVDEVICE
|
||||
{ "sources" , OPT_EXIT | HAS_ARG, { .func_arg = show_sources },
|
||||
"list sources of the input device", "device" },
|
||||
{ "sinks" , OPT_EXIT | HAS_ARG, { .func_arg = show_sinks },
|
||||
"list sinks of the output device", "device" },
|
||||
#endif
|
||||
278
cmdutils_opencl.c
Normal file
278
cmdutils_opencl.c
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Lenny Wang
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/time.h"
|
||||
#include "libavutil/log.h"
|
||||
#include "libavutil/opencl.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "cmdutils.h"
|
||||
|
||||
typedef struct {
|
||||
int platform_idx;
|
||||
int device_idx;
|
||||
char device_name[64];
|
||||
int64_t runtime;
|
||||
} OpenCLDeviceBenchmark;
|
||||
|
||||
const char *ocl_bench_source = AV_OPENCL_KERNEL(
|
||||
inline unsigned char clip_uint8(int a)
|
||||
{
|
||||
if (a & (~0xFF))
|
||||
return (-a)>>31;
|
||||
else
|
||||
return a;
|
||||
}
|
||||
|
||||
kernel void unsharp_bench(
|
||||
global unsigned char *src,
|
||||
global unsigned char *dst,
|
||||
global int *mask,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
int i, j, local_idx, lc_idx, sum = 0;
|
||||
int2 thread_idx, block_idx, global_idx, lm_idx;
|
||||
thread_idx.x = get_local_id(0);
|
||||
thread_idx.y = get_local_id(1);
|
||||
block_idx.x = get_group_id(0);
|
||||
block_idx.y = get_group_id(1);
|
||||
global_idx.x = get_global_id(0);
|
||||
global_idx.y = get_global_id(1);
|
||||
local uchar data[32][32];
|
||||
local int lc[128];
|
||||
|
||||
for (i = 0; i <= 1; i++) {
|
||||
lm_idx.y = -8 + (block_idx.y + i) * 16 + thread_idx.y;
|
||||
lm_idx.y = lm_idx.y < 0 ? 0 : lm_idx.y;
|
||||
lm_idx.y = lm_idx.y >= height ? height - 1: lm_idx.y;
|
||||
for (j = 0; j <= 1; j++) {
|
||||
lm_idx.x = -8 + (block_idx.x + j) * 16 + thread_idx.x;
|
||||
lm_idx.x = lm_idx.x < 0 ? 0 : lm_idx.x;
|
||||
lm_idx.x = lm_idx.x >= width ? width - 1: lm_idx.x;
|
||||
data[i*16 + thread_idx.y][j*16 + thread_idx.x] = src[lm_idx.y*width + lm_idx.x];
|
||||
}
|
||||
}
|
||||
local_idx = thread_idx.y*16 + thread_idx.x;
|
||||
if (local_idx < 128)
|
||||
lc[local_idx] = mask[local_idx];
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
\n#pragma unroll\n
|
||||
for (i = -4; i <= 4; i++) {
|
||||
lm_idx.y = 8 + i + thread_idx.y;
|
||||
\n#pragma unroll\n
|
||||
for (j = -4; j <= 4; j++) {
|
||||
lm_idx.x = 8 + j + thread_idx.x;
|
||||
lc_idx = (i + 4)*8 + j + 4;
|
||||
sum += (int)data[lm_idx.y][lm_idx.x] * lc[lc_idx];
|
||||
}
|
||||
}
|
||||
int temp = (int)data[thread_idx.y + 8][thread_idx.x + 8];
|
||||
int res = temp + (((temp - (int)((sum + 1<<15) >> 16))) >> 16);
|
||||
if (global_idx.x < width && global_idx.y < height)
|
||||
dst[global_idx.x + global_idx.y*width] = clip_uint8(res);
|
||||
}
|
||||
);
|
||||
|
||||
#define OCLCHECK(method, ... ) \
|
||||
do { \
|
||||
status = method(__VA_ARGS__); \
|
||||
if (status != CL_SUCCESS) { \
|
||||
av_log(NULL, AV_LOG_ERROR, # method " error '%s'\n", \
|
||||
av_opencl_errstr(status)); \
|
||||
ret = AVERROR_EXTERNAL; \
|
||||
goto end; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CREATEBUF(out, flags, size) \
|
||||
do { \
|
||||
out = clCreateBuffer(ext_opencl_env->context, flags, size, NULL, &status); \
|
||||
if (status != CL_SUCCESS) { \
|
||||
av_log(NULL, AV_LOG_ERROR, "Could not create OpenCL buffer\n"); \
|
||||
ret = AVERROR_EXTERNAL; \
|
||||
goto end; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static void fill_rand_int(int *data, int n)
|
||||
{
|
||||
int i;
|
||||
srand(av_gettime());
|
||||
for (i = 0; i < n; i++)
|
||||
data[i] = rand();
|
||||
}
|
||||
|
||||
#define OPENCL_NB_ITER 5
|
||||
static int64_t run_opencl_bench(AVOpenCLExternalEnv *ext_opencl_env)
|
||||
{
|
||||
int i, arg = 0, width = 1920, height = 1088;
|
||||
int64_t start, ret = 0;
|
||||
cl_int status;
|
||||
size_t kernel_len;
|
||||
char *inbuf;
|
||||
int *mask;
|
||||
int buf_size = width * height * sizeof(char);
|
||||
int mask_size = sizeof(uint32_t) * 128;
|
||||
|
||||
cl_mem cl_mask, cl_inbuf, cl_outbuf;
|
||||
cl_kernel kernel = NULL;
|
||||
cl_program program = NULL;
|
||||
size_t local_work_size_2d[2] = {16, 16};
|
||||
size_t global_work_size_2d[2] = {(size_t)width, (size_t)height};
|
||||
|
||||
if (!(inbuf = av_malloc(buf_size)) || !(mask = av_malloc(mask_size))) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
fill_rand_int((int*)inbuf, buf_size/4);
|
||||
fill_rand_int(mask, mask_size/4);
|
||||
|
||||
CREATEBUF(cl_mask, CL_MEM_READ_ONLY, mask_size);
|
||||
CREATEBUF(cl_inbuf, CL_MEM_READ_ONLY, buf_size);
|
||||
CREATEBUF(cl_outbuf, CL_MEM_READ_WRITE, buf_size);
|
||||
|
||||
kernel_len = strlen(ocl_bench_source);
|
||||
program = clCreateProgramWithSource(ext_opencl_env->context, 1, &ocl_bench_source,
|
||||
&kernel_len, &status);
|
||||
if (status != CL_SUCCESS || !program) {
|
||||
av_log(NULL, AV_LOG_ERROR, "OpenCL unable to create benchmark program\n");
|
||||
ret = AVERROR_EXTERNAL;
|
||||
goto end;
|
||||
}
|
||||
status = clBuildProgram(program, 1, &(ext_opencl_env->device_id), NULL, NULL, NULL);
|
||||
if (status != CL_SUCCESS) {
|
||||
av_log(NULL, AV_LOG_ERROR, "OpenCL unable to build benchmark program\n");
|
||||
ret = AVERROR_EXTERNAL;
|
||||
goto end;
|
||||
}
|
||||
kernel = clCreateKernel(program, "unsharp_bench", &status);
|
||||
if (status != CL_SUCCESS) {
|
||||
av_log(NULL, AV_LOG_ERROR, "OpenCL unable to create benchmark kernel\n");
|
||||
ret = AVERROR_EXTERNAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
OCLCHECK(clEnqueueWriteBuffer, ext_opencl_env->command_queue, cl_inbuf, CL_TRUE, 0,
|
||||
buf_size, inbuf, 0, NULL, NULL);
|
||||
OCLCHECK(clEnqueueWriteBuffer, ext_opencl_env->command_queue, cl_mask, CL_TRUE, 0,
|
||||
mask_size, mask, 0, NULL, NULL);
|
||||
OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &cl_inbuf);
|
||||
OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &cl_outbuf);
|
||||
OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &cl_mask);
|
||||
OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_int), &width);
|
||||
OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_int), &height);
|
||||
|
||||
start = av_gettime_relative();
|
||||
for (i = 0; i < OPENCL_NB_ITER; i++)
|
||||
OCLCHECK(clEnqueueNDRangeKernel, ext_opencl_env->command_queue, kernel, 2, NULL,
|
||||
global_work_size_2d, local_work_size_2d, 0, NULL, NULL);
|
||||
clFinish(ext_opencl_env->command_queue);
|
||||
ret = (av_gettime_relative() - start)/OPENCL_NB_ITER;
|
||||
end:
|
||||
if (kernel)
|
||||
clReleaseKernel(kernel);
|
||||
if (program)
|
||||
clReleaseProgram(program);
|
||||
if (cl_inbuf)
|
||||
clReleaseMemObject(cl_inbuf);
|
||||
if (cl_outbuf)
|
||||
clReleaseMemObject(cl_outbuf);
|
||||
if (cl_mask)
|
||||
clReleaseMemObject(cl_mask);
|
||||
av_free(inbuf);
|
||||
av_free(mask);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int compare_ocl_device_desc(const void *a, const void *b)
|
||||
{
|
||||
const OpenCLDeviceBenchmark* va = (const OpenCLDeviceBenchmark*)a;
|
||||
const OpenCLDeviceBenchmark* vb = (const OpenCLDeviceBenchmark*)b;
|
||||
return FFDIFFSIGN(va->runtime , vb->runtime);
|
||||
}
|
||||
|
||||
int opt_opencl_bench(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
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;
|
||||
|
||||
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");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if (!(devices = av_malloc_array(nb_devices, sizeof(OpenCLDeviceBenchmark)))) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Could not allocate buffer\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
for (i = 0; i < device_list->platform_num; i++) {
|
||||
for (j = 0; j < device_list->platform_node[i]->device_num; j++) {
|
||||
device_node = device_list->platform_node[i]->device_node[j];
|
||||
platform = device_list->platform_node[i]->platform_id;
|
||||
score = av_opencl_benchmark(device_node, platform, run_opencl_bench);
|
||||
if (score > 0) {
|
||||
devices[count].platform_idx = i;
|
||||
devices[count].device_idx = j;
|
||||
devices[count].runtime = score;
|
||||
av_strlcpy(devices[count].device_name, device_node->device_name,
|
||||
sizeof(devices[count].device_name));
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
qsort(devices, count, sizeof(OpenCLDeviceBenchmark), compare_ocl_device_desc);
|
||||
fprintf(stderr, "platform_idx\tdevice_idx\tdevice_name\truntime\n");
|
||||
for (i = 0; i < count; i++)
|
||||
fprintf(stdout, "%d\t%d\t%s\t%"PRId64"\n",
|
||||
devices[i].platform_idx, devices[i].device_idx,
|
||||
devices[i].device_name, devices[i].runtime);
|
||||
|
||||
av_opencl_free_device_list(&device_list);
|
||||
av_free(devices);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opt_opencl(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
char *key, *value;
|
||||
const char *opts = arg;
|
||||
int ret = 0;
|
||||
while (*opts) {
|
||||
ret = av_opt_get_key_value(&opts, "=", ":", 0, &key, &value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = av_opencl_set_option(key, value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (*opts)
|
||||
opts++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -2,24 +2,24 @@
|
||||
# common bits used by all libraries
|
||||
#
|
||||
|
||||
DEFAULT_X86ASMD=.dbg
|
||||
# first so "all" becomes default target
|
||||
all: all-yes
|
||||
|
||||
DEFAULT_YASMD=.dbg
|
||||
|
||||
ifeq ($(DBG),1)
|
||||
X86ASMD=$(DEFAULT_X86ASMD)
|
||||
YASMD=$(DEFAULT_YASMD)
|
||||
else
|
||||
X86ASMD=
|
||||
YASMD=
|
||||
endif
|
||||
|
||||
ifndef SUBDIR
|
||||
|
||||
BIN2CEXE = ffbuild/bin2c$(HOSTEXESUF)
|
||||
BIN2C = $(BIN2CEXE)
|
||||
|
||||
ifndef V
|
||||
Q = @
|
||||
ECHO = printf "$(1)\t%s\n" $(2)
|
||||
BRIEF = CC CXX OBJCC HOSTCC HOSTLD AS X86ASM AR LD STRIP CP WINDRES NVCC BIN2C
|
||||
SILENT = DEPCC DEPHOSTCC DEPAS DEPX86ASM RANLIB RM
|
||||
BRIEF = CC CXX OBJCC HOSTCC HOSTLD AS YASM AR LD STRIP CP WINDRES
|
||||
SILENT = DEPCC DEPHOSTCC DEPAS DEPYASM RANLIB RM
|
||||
|
||||
MSG = $@
|
||||
M = @$(call ECHO,$(TAG),$@);
|
||||
@@ -29,7 +29,7 @@ $(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR))))
|
||||
$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL))
|
||||
endif
|
||||
|
||||
ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale swresample
|
||||
ALLFFLIBS = avcodec avdevice avfilter avformat avresample avutil postproc swscale swresample
|
||||
|
||||
# NASM requires -I path terminated with /
|
||||
IFLAGS := -I. -I$(SRC_LINK)/
|
||||
@@ -40,39 +40,21 @@ OBJCFLAGS += $(EOBJCFLAGS)
|
||||
OBJCCFLAGS = $(CPPFLAGS) $(CFLAGS) $(OBJCFLAGS)
|
||||
ASFLAGS := $(CPPFLAGS) $(ASFLAGS)
|
||||
CXXFLAGS := $(CPPFLAGS) $(CFLAGS) $(CXXFLAGS)
|
||||
X86ASMFLAGS += $(IFLAGS:%=%/) -I$(<D)/ -Pconfig.asm
|
||||
YASMFLAGS += $(IFLAGS:%=%/) -Pconfig.asm
|
||||
|
||||
HOSTCCFLAGS = $(IFLAGS) $(HOSTCPPFLAGS) $(HOSTCFLAGS)
|
||||
LDFLAGS := $(ALLFFLIBS:%=$(LD_PATH)lib%) $(LDFLAGS)
|
||||
|
||||
define COMPILE
|
||||
$(call $(1)DEP,$(1))
|
||||
$($(1)) $($(1)FLAGS) $($(2)) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<)
|
||||
$($(1)) $($(1)FLAGS) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<)
|
||||
endef
|
||||
|
||||
COMPILE_C = $(call COMPILE,CC)
|
||||
COMPILE_CXX = $(call COMPILE,CXX)
|
||||
COMPILE_S = $(call COMPILE,AS)
|
||||
COMPILE_M = $(call COMPILE,OBJCC)
|
||||
COMPILE_X86ASM = $(call COMPILE,X86ASM)
|
||||
COMPILE_HOSTC = $(call COMPILE,HOSTCC)
|
||||
COMPILE_NVCC = $(call COMPILE,NVCC)
|
||||
COMPILE_MMI = $(call COMPILE,CC,MMIFLAGS)
|
||||
COMPILE_MSA = $(call COMPILE,CC,MSAFLAGS)
|
||||
COMPILE_LSX = $(call COMPILE,CC,LSXFLAGS)
|
||||
COMPILE_LASX = $(call COMPILE,CC,LASXFLAGS)
|
||||
|
||||
%_mmi.o: %_mmi.c
|
||||
$(COMPILE_MMI)
|
||||
|
||||
%_msa.o: %_msa.c
|
||||
$(COMPILE_MSA)
|
||||
|
||||
%_lsx.o: %_lsx.c
|
||||
$(COMPILE_LSX)
|
||||
|
||||
%_lasx.o: %_lasx.c
|
||||
$(COMPILE_LASX)
|
||||
|
||||
%.o: %.c
|
||||
$(COMPILE_C)
|
||||
@@ -92,16 +74,8 @@ COMPILE_LASX = $(call COMPILE,CC,LASXFLAGS)
|
||||
%_host.o: %.c
|
||||
$(COMPILE_HOSTC)
|
||||
|
||||
%$(DEFAULT_X86ASMD).asm: %.asm
|
||||
$(DEPX86ASM) $(X86ASMFLAGS) -M -o $@ $< > $(@:.asm=.d)
|
||||
$(X86ASM) $(X86ASMFLAGS) -e $< | sed '/^%/d;/^$$/d;' > $@
|
||||
|
||||
%.o: %.asm
|
||||
$(COMPILE_X86ASM)
|
||||
-$(if $(ASMSTRIPFLAGS), $(STRIP) $(ASMSTRIPFLAGS) $@)
|
||||
|
||||
%.o: %.rc
|
||||
$(WINDRES) $(IFLAGS) $(foreach ARG,$(CC_DEPFLAGS),--preprocessor-arg "$(ARG)") -o $@ $<
|
||||
$(WINDRES) $(IFLAGS) --preprocessor "$(DEPWINDRES) -E -xc-header -DRC_INVOKED $(CC_DEPFLAGS)" -o $@ $<
|
||||
|
||||
%.i: %.c
|
||||
$(CC) $(CCFLAGS) $(CC_E) $<
|
||||
@@ -109,40 +83,10 @@ COMPILE_LASX = $(call COMPILE,CC,LASXFLAGS)
|
||||
%.h.c:
|
||||
$(Q)echo '#include "$*.h"' >$@
|
||||
|
||||
$(BIN2CEXE): ffbuild/bin2c_host.o
|
||||
$(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTEXTRALIBS)
|
||||
|
||||
%.metal.air: %.metal
|
||||
$(METALCC) $< -o $@
|
||||
|
||||
%.metallib: %.metal.air
|
||||
$(METALLIB) --split-module-without-linking $< -o $@
|
||||
|
||||
%.metallib.c: %.metallib $(BIN2CEXE)
|
||||
$(BIN2C) $< $@ $(subst .,_,$(basename $(notdir $@)))
|
||||
|
||||
%.ptx: %.cu $(SRC_PATH)/compat/cuda/cuda_runtime.h
|
||||
$(COMPILE_NVCC)
|
||||
|
||||
ifdef CONFIG_PTX_COMPRESSION
|
||||
%.ptx.gz: TAG = GZIP
|
||||
%.ptx.gz: %.ptx
|
||||
$(M)gzip -c9 $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) >$@
|
||||
|
||||
%.ptx.c: %.ptx.gz $(BIN2CEXE)
|
||||
$(BIN2C) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) $@ $(subst .,_,$(basename $(notdir $@)))
|
||||
else
|
||||
%.ptx.c: %.ptx $(BIN2CEXE)
|
||||
$(BIN2C) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) $@ $(subst .,_,$(basename $(notdir $@)))
|
||||
endif
|
||||
|
||||
clean::
|
||||
$(RM) $(BIN2CEXE)
|
||||
|
||||
%.c %.h %.pc %.ver %.version: TAG = GEN
|
||||
%.c %.h %.ver: TAG = GEN
|
||||
|
||||
# Dummy rule to stop make trying to rebuild removed or renamed headers
|
||||
%.h %_template.c:
|
||||
%.h:
|
||||
@:
|
||||
|
||||
# Disable suffix rules. Most of the builtin rules are suffix rules,
|
||||
@@ -153,22 +97,18 @@ clean::
|
||||
$(OBJS):
|
||||
endif
|
||||
|
||||
include $(SRC_PATH)/ffbuild/arch.mak
|
||||
include $(SRC_PATH)/arch.mak
|
||||
|
||||
OBJS += $(OBJS-yes)
|
||||
SLIBOBJS += $(SLIBOBJS-yes)
|
||||
SHLIBOBJS += $(SHLIBOBJS-yes)
|
||||
STLIBOBJS += $(STLIBOBJS-yes)
|
||||
FFLIBS := $($(NAME)_FFLIBS) $(FFLIBS-yes) $(FFLIBS)
|
||||
TESTPROGS += $(TESTPROGS-yes)
|
||||
|
||||
LDLIBS = $(FFLIBS:%=%$(BUILDSUF))
|
||||
FFEXTRALIBS := $(LDLIBS:%=$(LD_LIB)) $(foreach lib,EXTRALIBS-$(NAME) $(FFLIBS:%=EXTRALIBS-%),$($(lib))) $(EXTRALIBS)
|
||||
FFEXTRALIBS := $(LDLIBS:%=$(LD_LIB)) $(EXTRALIBS)
|
||||
|
||||
OBJS := $(sort $(OBJS:%=$(SUBDIR)%))
|
||||
SLIBOBJS := $(sort $(SLIBOBJS:%=$(SUBDIR)%))
|
||||
SHLIBOBJS := $(sort $(SHLIBOBJS:%=$(SUBDIR)%))
|
||||
STLIBOBJS := $(sort $(STLIBOBJS:%=$(SUBDIR)%))
|
||||
TESTOBJS := $(TESTOBJS:%=$(SUBDIR)tests/%) $(TESTPROGS:%=$(SUBDIR)tests/%.o)
|
||||
TESTPROGS := $(TESTPROGS:%=$(SUBDIR)tests/%$(EXESUF))
|
||||
HOSTOBJS := $(HOSTPROGS:%=$(SUBDIR)%.o)
|
||||
@@ -187,10 +127,8 @@ ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)
|
||||
SKIPHEADERS += $(ARCH_HEADERS:%=$(ARCH)/%) $(SKIPHEADERS-)
|
||||
SKIPHEADERS := $(SKIPHEADERS:%=$(SUBDIR)%)
|
||||
HOBJS = $(filter-out $(SKIPHEADERS:.h=.h.o),$(ALLHEADERS:.h=.h.o))
|
||||
PTXOBJS = $(filter %.ptx.o,$(OBJS))
|
||||
$(HOBJS): CCFLAGS += $(CFLAGS_HEADERS)
|
||||
checkheaders: $(HOBJS)
|
||||
.SECONDARY: $(HOBJS:.o=.c) $(PTXOBJS:.o=.c) $(PTXOBJS:.o=.gz) $(PTXOBJS:.o=)
|
||||
.SECONDARY: $(HOBJS:.o=.c)
|
||||
|
||||
alltools: $(TOOLS)
|
||||
|
||||
@@ -198,20 +136,19 @@ $(HOSTOBJS): %.o: %.c
|
||||
$(COMPILE_HOSTC)
|
||||
|
||||
$(HOSTPROGS): %$(HOSTEXESUF): %.o
|
||||
$(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTEXTRALIBS)
|
||||
$(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTLIBS)
|
||||
|
||||
$(OBJS): | $(sort $(dir $(OBJS)))
|
||||
$(HOBJS): | $(sort $(dir $(HOBJS)))
|
||||
$(HOSTOBJS): | $(sort $(dir $(HOSTOBJS)))
|
||||
$(SLIBOBJS): | $(sort $(dir $(SLIBOBJS)))
|
||||
$(SHLIBOBJS): | $(sort $(dir $(SHLIBOBJS)))
|
||||
$(STLIBOBJS): | $(sort $(dir $(STLIBOBJS)))
|
||||
$(TESTOBJS): | $(sort $(dir $(TESTOBJS)))
|
||||
$(TOOLOBJS): | tools
|
||||
|
||||
OUTDIRS := $(OUTDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(SLIBOBJS) $(SHLIBOBJS) $(STLIBOBJS) $(TESTOBJS))
|
||||
OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(SLIBOBJS) $(TESTOBJS))
|
||||
|
||||
CLEANSUFFIXES = *.d *.gcda *.gcno *.h.c *.ho *.map *.o *.pc *.ptx *.ptx.gz *.ptx.c *.ver *.version *$(DEFAULT_X86ASMD).asm *~ *.ilk *.pdb
|
||||
CLEANSUFFIXES = *.d *.o *~ *.h.c *.gcda *.gcno *.map *.ver *.ho *$(DEFAULT_YASMD).asm
|
||||
DISTCLEANSUFFIXES = *.pc
|
||||
LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a
|
||||
|
||||
define RULES
|
||||
@@ -221,4 +158,4 @@ endef
|
||||
|
||||
$(eval $(RULES))
|
||||
|
||||
-include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d) $(SHLIBOBJS:.o=.d) $(STLIBOBJS:.o=.d) $(SLIBOBJS:.o=.d)) $(OBJS:.o=$(DEFAULT_X86ASMD).d)
|
||||
-include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d) $(SLIBOBJS:.o=.d)) $(OBJS:.o=$(DEFAULT_YASMD).d)
|
||||
@@ -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,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 = (intptr_t)atomic_cas_ptr(object, (void *)old, (void *)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,181 +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
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#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((PVOID volatile *)object, (PVOID)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 = (intptr_t)InterlockedCompareExchangePointer(
|
||||
(PVOID *)object, (PVOID)desired, (PVOID)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 */
|
||||
1064
compat/avisynth/avisynth_c.h
Normal file
1064
compat/avisynth/avisynth_c.h
Normal file
File diff suppressed because it is too large
Load Diff
62
compat/avisynth/avs/capi.h
Normal file
62
compat/avisynth/avs/capi.h
Normal file
@@ -0,0 +1,62 @@
|
||||
// Avisynth C Interface Version 0.20
|
||||
// Copyright 2003 Kevin Atkinson
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
|
||||
// http://www.gnu.org/copyleft/gpl.html .
|
||||
//
|
||||
// As a special exception, I give you permission to link to the
|
||||
// Avisynth C interface with independent modules that communicate with
|
||||
// the Avisynth C interface solely through the interfaces defined in
|
||||
// avisynth_c.h, regardless of the license terms of these independent
|
||||
// modules, and to copy and distribute the resulting combined work
|
||||
// under terms of your choice, provided that every copy of the
|
||||
// combined work is accompanied by a complete copy of the source code
|
||||
// of the Avisynth C interface and Avisynth itself (with the version
|
||||
// used to produce the combined work), being distributed under the
|
||||
// terms of the GNU General Public License plus this exception. An
|
||||
// independent module is a module which is not derived from or based
|
||||
// on Avisynth C Interface, such as 3rd-party filters, import and
|
||||
// export plugins, or graphical user interfaces.
|
||||
|
||||
#ifndef AVS_CAPI_H
|
||||
#define AVS_CAPI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define EXTERN_C extern "C"
|
||||
#else
|
||||
# define EXTERN_C
|
||||
#endif
|
||||
|
||||
#ifndef AVSC_USE_STDCALL
|
||||
# define AVSC_CC __cdecl
|
||||
#else
|
||||
# define AVSC_CC __stdcall
|
||||
#endif
|
||||
|
||||
#define AVSC_INLINE static __inline
|
||||
|
||||
#ifdef BUILDING_AVSCORE
|
||||
# define AVSC_EXPORT EXTERN_C
|
||||
# define AVSC_API(ret, name) EXTERN_C __declspec(dllexport) ret AVSC_CC name
|
||||
#else
|
||||
# define AVSC_EXPORT EXTERN_C __declspec(dllexport)
|
||||
# ifndef AVSC_NO_DECLSPEC
|
||||
# define AVSC_API(ret, name) EXTERN_C __declspec(dllimport) ret AVSC_CC name
|
||||
# else
|
||||
# define AVSC_API(ret, name) typedef ret (AVSC_CC *name##_func)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif //AVS_CAPI_H
|
||||
55
compat/avisynth/avs/config.h
Normal file
55
compat/avisynth/avs/config.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// Avisynth C Interface Version 0.20
|
||||
// Copyright 2003 Kevin Atkinson
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
|
||||
// http://www.gnu.org/copyleft/gpl.html .
|
||||
//
|
||||
// As a special exception, I give you permission to link to the
|
||||
// Avisynth C interface with independent modules that communicate with
|
||||
// the Avisynth C interface solely through the interfaces defined in
|
||||
// avisynth_c.h, regardless of the license terms of these independent
|
||||
// modules, and to copy and distribute the resulting combined work
|
||||
// under terms of your choice, provided that every copy of the
|
||||
// combined work is accompanied by a complete copy of the source code
|
||||
// of the Avisynth C interface and Avisynth itself (with the version
|
||||
// used to produce the combined work), being distributed under the
|
||||
// terms of the GNU General Public License plus this exception. An
|
||||
// independent module is a module which is not derived from or based
|
||||
// on Avisynth C Interface, such as 3rd-party filters, import and
|
||||
// export plugins, or graphical user interfaces.
|
||||
|
||||
#ifndef AVS_CONFIG_H
|
||||
#define AVS_CONFIG_H
|
||||
|
||||
// Undefine this to get cdecl calling convention
|
||||
#define AVSC_USE_STDCALL 1
|
||||
|
||||
// NOTE TO PLUGIN AUTHORS:
|
||||
// Because FRAME_ALIGN can be substantially higher than the alignment
|
||||
// a plugin actually needs, plugins should not use FRAME_ALIGN to check for
|
||||
// alignment. They should always request the exact alignment value they need.
|
||||
// This is to make sure that plugins work over the widest range of AviSynth
|
||||
// builds possible.
|
||||
#define FRAME_ALIGN 32
|
||||
|
||||
#if defined(_M_AMD64) || defined(__x86_64)
|
||||
# define X86_64
|
||||
#elif defined(_M_IX86) || defined(__i386__)
|
||||
# define X86_32
|
||||
#else
|
||||
# error Unsupported CPU architecture.
|
||||
#endif
|
||||
|
||||
#endif //AVS_CONFIG_H
|
||||
51
compat/avisynth/avs/types.h
Normal file
51
compat/avisynth/avs/types.h
Normal file
@@ -0,0 +1,51 @@
|
||||
// Avisynth C Interface Version 0.20
|
||||
// Copyright 2003 Kevin Atkinson
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
|
||||
// http://www.gnu.org/copyleft/gpl.html .
|
||||
//
|
||||
// As a special exception, I give you permission to link to the
|
||||
// Avisynth C interface with independent modules that communicate with
|
||||
// the Avisynth C interface solely through the interfaces defined in
|
||||
// avisynth_c.h, regardless of the license terms of these independent
|
||||
// modules, and to copy and distribute the resulting combined work
|
||||
// under terms of your choice, provided that every copy of the
|
||||
// combined work is accompanied by a complete copy of the source code
|
||||
// of the Avisynth C interface and Avisynth itself (with the version
|
||||
// used to produce the combined work), being distributed under the
|
||||
// terms of the GNU General Public License plus this exception. An
|
||||
// independent module is a module which is not derived from or based
|
||||
// on Avisynth C Interface, such as 3rd-party filters, import and
|
||||
// export plugins, or graphical user interfaces.
|
||||
|
||||
#ifndef AVS_TYPES_H
|
||||
#define AVS_TYPES_H
|
||||
|
||||
// Define all types necessary for interfacing with avisynth.dll
|
||||
|
||||
// Raster types used by VirtualDub & Avisynth
|
||||
typedef unsigned int Pixel32;
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
// Audio Sample information
|
||||
typedef float SFLOAT;
|
||||
|
||||
#ifdef __GNUC__
|
||||
typedef long long int INT64;
|
||||
#else
|
||||
typedef __int64 INT64;
|
||||
#endif
|
||||
|
||||
#endif //AVS_TYPES_H
|
||||
728
compat/avisynth/avxsynth_c.h
Normal file
728
compat/avisynth/avxsynth_c.h
Normal file
@@ -0,0 +1,728 @@
|
||||
// Avisynth C Interface Version 0.20
|
||||
// Copyright 2003 Kevin Atkinson
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
// MA 02110-1301 USA, or visit
|
||||
// http://www.gnu.org/copyleft/gpl.html .
|
||||
//
|
||||
// As a special exception, I give you permission to link to the
|
||||
// Avisynth C interface with independent modules that communicate with
|
||||
// the Avisynth C interface solely through the interfaces defined in
|
||||
// avisynth_c.h, regardless of the license terms of these independent
|
||||
// modules, and to copy and distribute the resulting combined work
|
||||
// under terms of your choice, provided that every copy of the
|
||||
// combined work is accompanied by a complete copy of the source code
|
||||
// of the Avisynth C interface and Avisynth itself (with the version
|
||||
// used to produce the combined work), being distributed under the
|
||||
// terms of the GNU General Public License plus this exception. An
|
||||
// independent module is a module which is not derived from or based
|
||||
// on Avisynth C Interface, such as 3rd-party filters, import and
|
||||
// export plugins, or graphical user interfaces.
|
||||
|
||||
#ifndef __AVXSYNTH_C__
|
||||
#define __AVXSYNTH_C__
|
||||
|
||||
#include "windowsPorts/windows2linux.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define EXTERN_C extern "C"
|
||||
#else
|
||||
# define EXTERN_C
|
||||
#endif
|
||||
|
||||
#define AVSC_USE_STDCALL 1
|
||||
|
||||
#ifndef AVSC_USE_STDCALL
|
||||
# define AVSC_CC __cdecl
|
||||
#else
|
||||
# define AVSC_CC __stdcall
|
||||
#endif
|
||||
|
||||
#define AVSC_INLINE static __inline
|
||||
|
||||
#ifdef AVISYNTH_C_EXPORTS
|
||||
# define AVSC_EXPORT EXTERN_C
|
||||
# define AVSC_API(ret, name) EXTERN_C __declspec(dllexport) ret AVSC_CC name
|
||||
#else
|
||||
# define AVSC_EXPORT EXTERN_C __declspec(dllexport)
|
||||
# ifndef AVSC_NO_DECLSPEC
|
||||
# define AVSC_API(ret, name) EXTERN_C __declspec(dllimport) ret AVSC_CC name
|
||||
# else
|
||||
# define AVSC_API(ret, name) typedef ret (AVSC_CC *name##_func)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
typedef long long int INT64;
|
||||
#else
|
||||
typedef __int64 INT64;
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
|
||||
#ifndef __AVXSYNTH_H__
|
||||
enum { AVISYNTH_INTERFACE_VERSION = 3 };
|
||||
#endif
|
||||
|
||||
enum {AVS_SAMPLE_INT8 = 1<<0,
|
||||
AVS_SAMPLE_INT16 = 1<<1,
|
||||
AVS_SAMPLE_INT24 = 1<<2,
|
||||
AVS_SAMPLE_INT32 = 1<<3,
|
||||
AVS_SAMPLE_FLOAT = 1<<4};
|
||||
|
||||
enum {AVS_PLANAR_Y=1<<0,
|
||||
AVS_PLANAR_U=1<<1,
|
||||
AVS_PLANAR_V=1<<2,
|
||||
AVS_PLANAR_ALIGNED=1<<3,
|
||||
AVS_PLANAR_Y_ALIGNED=AVS_PLANAR_Y|AVS_PLANAR_ALIGNED,
|
||||
AVS_PLANAR_U_ALIGNED=AVS_PLANAR_U|AVS_PLANAR_ALIGNED,
|
||||
AVS_PLANAR_V_ALIGNED=AVS_PLANAR_V|AVS_PLANAR_ALIGNED};
|
||||
|
||||
// Colorspace properties.
|
||||
enum {AVS_CS_BGR = 1<<28,
|
||||
AVS_CS_YUV = 1<<29,
|
||||
AVS_CS_INTERLEAVED = 1<<30,
|
||||
AVS_CS_PLANAR = 1<<31};
|
||||
|
||||
// Specific colorformats
|
||||
enum {
|
||||
AVS_CS_UNKNOWN = 0,
|
||||
AVS_CS_BGR24 = 1<<0 | AVS_CS_BGR | AVS_CS_INTERLEAVED,
|
||||
AVS_CS_BGR32 = 1<<1 | AVS_CS_BGR | AVS_CS_INTERLEAVED,
|
||||
AVS_CS_YUY2 = 1<<2 | AVS_CS_YUV | AVS_CS_INTERLEAVED,
|
||||
AVS_CS_YV12 = 1<<3 | AVS_CS_YUV | AVS_CS_PLANAR, // y-v-u, planar
|
||||
AVS_CS_I420 = 1<<4 | AVS_CS_YUV | AVS_CS_PLANAR, // y-u-v, planar
|
||||
AVS_CS_IYUV = 1<<4 | AVS_CS_YUV | AVS_CS_PLANAR // same as above
|
||||
};
|
||||
|
||||
enum {
|
||||
AVS_IT_BFF = 1<<0,
|
||||
AVS_IT_TFF = 1<<1,
|
||||
AVS_IT_FIELDBASED = 1<<2};
|
||||
|
||||
enum {
|
||||
AVS_FILTER_TYPE=1,
|
||||
AVS_FILTER_INPUT_COLORSPACE=2,
|
||||
AVS_FILTER_OUTPUT_TYPE=9,
|
||||
AVS_FILTER_NAME=4,
|
||||
AVS_FILTER_AUTHOR=5,
|
||||
AVS_FILTER_VERSION=6,
|
||||
AVS_FILTER_ARGS=7,
|
||||
AVS_FILTER_ARGS_INFO=8,
|
||||
AVS_FILTER_ARGS_DESCRIPTION=10,
|
||||
AVS_FILTER_DESCRIPTION=11};
|
||||
|
||||
enum { //SUBTYPES
|
||||
AVS_FILTER_TYPE_AUDIO=1,
|
||||
AVS_FILTER_TYPE_VIDEO=2,
|
||||
AVS_FILTER_OUTPUT_TYPE_SAME=3,
|
||||
AVS_FILTER_OUTPUT_TYPE_DIFFERENT=4};
|
||||
|
||||
enum {
|
||||
AVS_CACHE_NOTHING=0,
|
||||
AVS_CACHE_RANGE=1,
|
||||
AVS_CACHE_ALL=2,
|
||||
AVS_CACHE_AUDIO=3,
|
||||
AVS_CACHE_AUDIO_NONE=4,
|
||||
AVS_CACHE_AUDIO_AUTO=5
|
||||
};
|
||||
|
||||
#define AVS_FRAME_ALIGN 16
|
||||
|
||||
typedef struct AVS_Clip AVS_Clip;
|
||||
typedef struct AVS_ScriptEnvironment AVS_ScriptEnvironment;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AVS_VideoInfo
|
||||
//
|
||||
|
||||
// AVS_VideoInfo is layed out identicly to VideoInfo
|
||||
typedef struct AVS_VideoInfo {
|
||||
int width, height; // width=0 means no video
|
||||
unsigned fps_numerator, fps_denominator;
|
||||
int num_frames;
|
||||
|
||||
int pixel_type;
|
||||
|
||||
int audio_samples_per_second; // 0 means no audio
|
||||
int sample_type;
|
||||
INT64 num_audio_samples;
|
||||
int nchannels;
|
||||
|
||||
// Imagetype properties
|
||||
|
||||
int image_type;
|
||||
} AVS_VideoInfo;
|
||||
|
||||
// useful functions of the above
|
||||
AVSC_INLINE int avs_has_video(const AVS_VideoInfo * p)
|
||||
{ return (p->width!=0); }
|
||||
|
||||
AVSC_INLINE int avs_has_audio(const AVS_VideoInfo * p)
|
||||
{ return (p->audio_samples_per_second!=0); }
|
||||
|
||||
AVSC_INLINE int avs_is_rgb(const AVS_VideoInfo * p)
|
||||
{ return !!(p->pixel_type&AVS_CS_BGR); }
|
||||
|
||||
AVSC_INLINE int avs_is_rgb24(const AVS_VideoInfo * p)
|
||||
{ return (p->pixel_type&AVS_CS_BGR24)==AVS_CS_BGR24; } // Clear out additional properties
|
||||
|
||||
AVSC_INLINE int avs_is_rgb32(const AVS_VideoInfo * p)
|
||||
{ return (p->pixel_type & AVS_CS_BGR32) == AVS_CS_BGR32 ; }
|
||||
|
||||
AVSC_INLINE int avs_is_yuv(const AVS_VideoInfo * p)
|
||||
{ return !!(p->pixel_type&AVS_CS_YUV ); }
|
||||
|
||||
AVSC_INLINE int avs_is_yuy2(const AVS_VideoInfo * p)
|
||||
{ return (p->pixel_type & AVS_CS_YUY2) == AVS_CS_YUY2; }
|
||||
|
||||
AVSC_INLINE int avs_is_yv12(const AVS_VideoInfo * p)
|
||||
{ return ((p->pixel_type & AVS_CS_YV12) == AVS_CS_YV12)||((p->pixel_type & AVS_CS_I420) == AVS_CS_I420); }
|
||||
|
||||
AVSC_INLINE int avs_is_color_space(const AVS_VideoInfo * p, int c_space)
|
||||
{ return ((p->pixel_type & c_space) == c_space); }
|
||||
|
||||
AVSC_INLINE int avs_is_property(const AVS_VideoInfo * p, int property)
|
||||
{ return ((p->pixel_type & property)==property ); }
|
||||
|
||||
AVSC_INLINE int avs_is_planar(const AVS_VideoInfo * p)
|
||||
{ return !!(p->pixel_type & AVS_CS_PLANAR); }
|
||||
|
||||
AVSC_INLINE int avs_is_field_based(const AVS_VideoInfo * p)
|
||||
{ return !!(p->image_type & AVS_IT_FIELDBASED); }
|
||||
|
||||
AVSC_INLINE int avs_is_parity_known(const AVS_VideoInfo * p)
|
||||
{ return ((p->image_type & AVS_IT_FIELDBASED)&&(p->image_type & (AVS_IT_BFF | AVS_IT_TFF))); }
|
||||
|
||||
AVSC_INLINE int avs_is_bff(const AVS_VideoInfo * p)
|
||||
{ return !!(p->image_type & AVS_IT_BFF); }
|
||||
|
||||
AVSC_INLINE int avs_is_tff(const AVS_VideoInfo * p)
|
||||
{ return !!(p->image_type & AVS_IT_TFF); }
|
||||
|
||||
AVSC_INLINE int avs_bits_per_pixel(const AVS_VideoInfo * p)
|
||||
{
|
||||
switch (p->pixel_type) {
|
||||
case AVS_CS_BGR24: return 24;
|
||||
case AVS_CS_BGR32: return 32;
|
||||
case AVS_CS_YUY2: return 16;
|
||||
case AVS_CS_YV12:
|
||||
case AVS_CS_I420: return 12;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
AVSC_INLINE int avs_bytes_from_pixels(const AVS_VideoInfo * p, int pixels)
|
||||
{ return pixels * (avs_bits_per_pixel(p)>>3); } // Will work on planar images, but will return only luma planes
|
||||
|
||||
AVSC_INLINE int avs_row_size(const AVS_VideoInfo * p)
|
||||
{ return avs_bytes_from_pixels(p,p->width); } // Also only returns first plane on planar images
|
||||
|
||||
AVSC_INLINE int avs_bmp_size(const AVS_VideoInfo * vi)
|
||||
{ if (avs_is_planar(vi)) {int p = vi->height * ((avs_row_size(vi)+3) & ~3); p+=p>>1; return p; } return vi->height * ((avs_row_size(vi)+3) & ~3); }
|
||||
|
||||
AVSC_INLINE int avs_samples_per_second(const AVS_VideoInfo * p)
|
||||
{ return p->audio_samples_per_second; }
|
||||
|
||||
|
||||
AVSC_INLINE int avs_bytes_per_channel_sample(const AVS_VideoInfo * p)
|
||||
{
|
||||
switch (p->sample_type) {
|
||||
case AVS_SAMPLE_INT8: return sizeof(signed char);
|
||||
case AVS_SAMPLE_INT16: return sizeof(signed short);
|
||||
case AVS_SAMPLE_INT24: return 3;
|
||||
case AVS_SAMPLE_INT32: return sizeof(signed int);
|
||||
case AVS_SAMPLE_FLOAT: return sizeof(float);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
AVSC_INLINE int avs_bytes_per_audio_sample(const AVS_VideoInfo * p)
|
||||
{ return p->nchannels*avs_bytes_per_channel_sample(p);}
|
||||
|
||||
AVSC_INLINE INT64 avs_audio_samples_from_frames(const AVS_VideoInfo * p, INT64 frames)
|
||||
{ return ((INT64)(frames) * p->audio_samples_per_second * p->fps_denominator / p->fps_numerator); }
|
||||
|
||||
AVSC_INLINE int avs_frames_from_audio_samples(const AVS_VideoInfo * p, INT64 samples)
|
||||
{ return (int)(samples * (INT64)p->fps_numerator / (INT64)p->fps_denominator / (INT64)p->audio_samples_per_second); }
|
||||
|
||||
AVSC_INLINE INT64 avs_audio_samples_from_bytes(const AVS_VideoInfo * p, INT64 bytes)
|
||||
{ return bytes / avs_bytes_per_audio_sample(p); }
|
||||
|
||||
AVSC_INLINE INT64 avs_bytes_from_audio_samples(const AVS_VideoInfo * p, INT64 samples)
|
||||
{ return samples * avs_bytes_per_audio_sample(p); }
|
||||
|
||||
AVSC_INLINE int avs_audio_channels(const AVS_VideoInfo * p)
|
||||
{ return p->nchannels; }
|
||||
|
||||
AVSC_INLINE int avs_sample_type(const AVS_VideoInfo * p)
|
||||
{ return p->sample_type;}
|
||||
|
||||
// useful mutator
|
||||
AVSC_INLINE void avs_set_property(AVS_VideoInfo * p, int property)
|
||||
{ p->image_type|=property; }
|
||||
|
||||
AVSC_INLINE void avs_clear_property(AVS_VideoInfo * p, int property)
|
||||
{ p->image_type&=~property; }
|
||||
|
||||
AVSC_INLINE void avs_set_field_based(AVS_VideoInfo * p, int isfieldbased)
|
||||
{ if (isfieldbased) p->image_type|=AVS_IT_FIELDBASED; else p->image_type&=~AVS_IT_FIELDBASED; }
|
||||
|
||||
AVSC_INLINE void avs_set_fps(AVS_VideoInfo * p, unsigned numerator, unsigned denominator)
|
||||
{
|
||||
unsigned x=numerator, y=denominator;
|
||||
while (y) { // find gcd
|
||||
unsigned t = x%y; x = y; y = t;
|
||||
}
|
||||
p->fps_numerator = numerator/x;
|
||||
p->fps_denominator = denominator/x;
|
||||
}
|
||||
|
||||
AVSC_INLINE int avs_is_same_colorspace(AVS_VideoInfo * x, AVS_VideoInfo * y)
|
||||
{
|
||||
return (x->pixel_type == y->pixel_type)
|
||||
|| (avs_is_yv12(x) && avs_is_yv12(y));
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AVS_VideoFrame
|
||||
//
|
||||
|
||||
// VideoFrameBuffer holds information about a memory block which is used
|
||||
// for video data. For efficiency, instances of this class are not deleted
|
||||
// when the refcount reaches zero; instead they're stored in a linked list
|
||||
// to be reused. The instances are deleted when the corresponding AVS
|
||||
// file is closed.
|
||||
|
||||
// AVS_VideoFrameBuffer is layed out identicly to VideoFrameBuffer
|
||||
// DO NOT USE THIS STRUCTURE DIRECTLY
|
||||
typedef struct AVS_VideoFrameBuffer {
|
||||
unsigned char * data;
|
||||
int data_size;
|
||||
// sequence_number is incremented every time the buffer is changed, so
|
||||
// that stale views can tell they're no longer valid.
|
||||
long sequence_number;
|
||||
|
||||
long refcount;
|
||||
} AVS_VideoFrameBuffer;
|
||||
|
||||
// VideoFrame holds a "window" into a VideoFrameBuffer.
|
||||
|
||||
// AVS_VideoFrame is layed out identicly to IVideoFrame
|
||||
// DO NOT USE THIS STRUCTURE DIRECTLY
|
||||
typedef struct AVS_VideoFrame {
|
||||
int refcount;
|
||||
AVS_VideoFrameBuffer * vfb;
|
||||
int offset, pitch, row_size, height, offsetU, offsetV, pitchUV; // U&V offsets are from top of picture.
|
||||
} AVS_VideoFrame;
|
||||
|
||||
// Access functions for AVS_VideoFrame
|
||||
AVSC_INLINE int avs_get_pitch(const AVS_VideoFrame * p) {
|
||||
return p->pitch;}
|
||||
|
||||
AVSC_INLINE int avs_get_pitch_p(const AVS_VideoFrame * p, int plane) {
|
||||
switch (plane) {
|
||||
case AVS_PLANAR_U: case AVS_PLANAR_V: return p->pitchUV;}
|
||||
return p->pitch;}
|
||||
|
||||
AVSC_INLINE int avs_get_row_size(const AVS_VideoFrame * p) {
|
||||
return p->row_size; }
|
||||
|
||||
AVSC_INLINE int avs_get_row_size_p(const AVS_VideoFrame * p, int plane) {
|
||||
int r;
|
||||
switch (plane) {
|
||||
case AVS_PLANAR_U: case AVS_PLANAR_V:
|
||||
if (p->pitchUV) return p->row_size>>1;
|
||||
else return 0;
|
||||
case AVS_PLANAR_U_ALIGNED: case AVS_PLANAR_V_ALIGNED:
|
||||
if (p->pitchUV) {
|
||||
r = ((p->row_size+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)) )>>1; // Aligned rowsize
|
||||
if (r < p->pitchUV)
|
||||
return r;
|
||||
return p->row_size>>1;
|
||||
} else return 0;
|
||||
case AVS_PLANAR_Y_ALIGNED:
|
||||
r = (p->row_size+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)); // Aligned rowsize
|
||||
if (r <= p->pitch)
|
||||
return r;
|
||||
return p->row_size;
|
||||
}
|
||||
return p->row_size;
|
||||
}
|
||||
|
||||
AVSC_INLINE int avs_get_height(const AVS_VideoFrame * p) {
|
||||
return p->height;}
|
||||
|
||||
AVSC_INLINE int avs_get_height_p(const AVS_VideoFrame * p, int plane) {
|
||||
switch (plane) {
|
||||
case AVS_PLANAR_U: case AVS_PLANAR_V:
|
||||
if (p->pitchUV) return p->height>>1;
|
||||
return 0;
|
||||
}
|
||||
return p->height;}
|
||||
|
||||
AVSC_INLINE const unsigned char* avs_get_read_ptr(const AVS_VideoFrame * p) {
|
||||
return p->vfb->data + p->offset;}
|
||||
|
||||
AVSC_INLINE const unsigned char* avs_get_read_ptr_p(const AVS_VideoFrame * p, int plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case AVS_PLANAR_U: return p->vfb->data + p->offsetU;
|
||||
case AVS_PLANAR_V: return p->vfb->data + p->offsetV;
|
||||
default: return p->vfb->data + p->offset;}
|
||||
}
|
||||
|
||||
AVSC_INLINE int avs_is_writable(const AVS_VideoFrame * p) {
|
||||
return (p->refcount == 1 && p->vfb->refcount == 1);}
|
||||
|
||||
AVSC_INLINE unsigned char* avs_get_write_ptr(const AVS_VideoFrame * p)
|
||||
{
|
||||
if (avs_is_writable(p)) {
|
||||
++p->vfb->sequence_number;
|
||||
return p->vfb->data + p->offset;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVSC_INLINE unsigned char* avs_get_write_ptr_p(const AVS_VideoFrame * p, int plane)
|
||||
{
|
||||
if (plane==AVS_PLANAR_Y && avs_is_writable(p)) {
|
||||
++p->vfb->sequence_number;
|
||||
return p->vfb->data + p->offset;
|
||||
} else if (plane==AVS_PLANAR_Y) {
|
||||
return 0;
|
||||
} else {
|
||||
switch (plane) {
|
||||
case AVS_PLANAR_U: return p->vfb->data + p->offsetU;
|
||||
case AVS_PLANAR_V: return p->vfb->data + p->offsetV;
|
||||
default: return p->vfb->data + p->offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
AVSC_API(void, avs_release_video_frame)(AVS_VideoFrame *);
|
||||
// makes a shallow copy of a video frame
|
||||
AVSC_API(AVS_VideoFrame *, avs_copy_video_frame)(AVS_VideoFrame *);
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifndef AVSC_NO_DECLSPEC
|
||||
AVSC_INLINE void avs_release_frame(AVS_VideoFrame * f)
|
||||
{avs_release_video_frame(f);}
|
||||
AVSC_INLINE AVS_VideoFrame * avs_copy_frame(AVS_VideoFrame * f)
|
||||
{return avs_copy_video_frame(f);}
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AVS_Value
|
||||
//
|
||||
|
||||
// Treat AVS_Value as a fat pointer. That is use avs_copy_value
|
||||
// and avs_release_value appropiaty as you would if AVS_Value was
|
||||
// a pointer.
|
||||
|
||||
// To maintain source code compatibility with future versions of the
|
||||
// avisynth_c API don't use the AVS_Value directly. Use the helper
|
||||
// functions below.
|
||||
|
||||
// AVS_Value is layed out identicly to AVSValue
|
||||
typedef struct AVS_Value AVS_Value;
|
||||
struct AVS_Value {
|
||||
short type; // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, or 'l'ong
|
||||
// for some function e'rror
|
||||
short array_size;
|
||||
union {
|
||||
void * clip; // do not use directly, use avs_take_clip
|
||||
char boolean;
|
||||
int integer;
|
||||
INT64 integer64; // match addition of __int64 to avxplugin.h
|
||||
float floating_pt;
|
||||
const char * string;
|
||||
const AVS_Value * array;
|
||||
} d;
|
||||
};
|
||||
|
||||
// AVS_Value should be initilized with avs_void.
|
||||
// Should also set to avs_void after the value is released
|
||||
// with avs_copy_value. Consider it the equalvent of setting
|
||||
// a pointer to NULL
|
||||
static const AVS_Value avs_void = {'v'};
|
||||
|
||||
AVSC_API(void, avs_copy_value)(AVS_Value * dest, AVS_Value src);
|
||||
AVSC_API(void, avs_release_value)(AVS_Value);
|
||||
|
||||
AVSC_INLINE int avs_defined(AVS_Value v) { return v.type != 'v'; }
|
||||
AVSC_INLINE int avs_is_clip(AVS_Value v) { return v.type == 'c'; }
|
||||
AVSC_INLINE int avs_is_bool(AVS_Value v) { return v.type == 'b'; }
|
||||
AVSC_INLINE int avs_is_int(AVS_Value v) { return v.type == 'i'; }
|
||||
AVSC_INLINE int avs_is_float(AVS_Value v) { return v.type == 'f' || v.type == 'i'; }
|
||||
AVSC_INLINE int avs_is_string(AVS_Value v) { return v.type == 's'; }
|
||||
AVSC_INLINE int avs_is_array(AVS_Value v) { return v.type == 'a'; }
|
||||
AVSC_INLINE int avs_is_error(AVS_Value v) { return v.type == 'e'; }
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
AVSC_API(AVS_Clip *, avs_take_clip)(AVS_Value, AVS_ScriptEnvironment *);
|
||||
AVSC_API(void, avs_set_to_clip)(AVS_Value *, AVS_Clip *);
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
AVSC_INLINE int avs_as_bool(AVS_Value v)
|
||||
{ return v.d.boolean; }
|
||||
AVSC_INLINE int avs_as_int(AVS_Value v)
|
||||
{ return v.d.integer; }
|
||||
AVSC_INLINE const char * avs_as_string(AVS_Value v)
|
||||
{ return avs_is_error(v) || avs_is_string(v) ? v.d.string : 0; }
|
||||
AVSC_INLINE double avs_as_float(AVS_Value v)
|
||||
{ return avs_is_int(v) ? v.d.integer : v.d.floating_pt; }
|
||||
AVSC_INLINE const char * avs_as_error(AVS_Value v)
|
||||
{ return avs_is_error(v) ? v.d.string : 0; }
|
||||
AVSC_INLINE const AVS_Value * avs_as_array(AVS_Value v)
|
||||
{ return v.d.array; }
|
||||
AVSC_INLINE int avs_array_size(AVS_Value v)
|
||||
{ return avs_is_array(v) ? v.array_size : 1; }
|
||||
AVSC_INLINE AVS_Value avs_array_elt(AVS_Value v, int index)
|
||||
{ return avs_is_array(v) ? v.d.array[index] : v; }
|
||||
|
||||
// only use these functions on am AVS_Value that does not already have
|
||||
// an active value. Remember, treat AVS_Value as a fat pointer.
|
||||
AVSC_INLINE AVS_Value avs_new_value_bool(int v0)
|
||||
{ AVS_Value v = {0}; v.type = 'b'; v.d.boolean = v0 == 0 ? 0 : 1; return v; }
|
||||
AVSC_INLINE AVS_Value avs_new_value_int(int v0)
|
||||
{ AVS_Value v = {0}; v.type = 'i'; v.d.integer = v0; return v; }
|
||||
AVSC_INLINE AVS_Value avs_new_value_string(const char * v0)
|
||||
{ AVS_Value v = {0}; v.type = 's'; v.d.string = v0; return v; }
|
||||
AVSC_INLINE AVS_Value avs_new_value_float(float v0)
|
||||
{ AVS_Value v = {0}; v.type = 'f'; v.d.floating_pt = v0; return v;}
|
||||
AVSC_INLINE AVS_Value avs_new_value_error(const char * v0)
|
||||
{ AVS_Value v = {0}; v.type = 'e'; v.d.string = v0; return v; }
|
||||
#ifndef AVSC_NO_DECLSPEC
|
||||
AVSC_INLINE AVS_Value avs_new_value_clip(AVS_Clip * v0)
|
||||
{ AVS_Value v = {0}; avs_set_to_clip(&v, v0); return v; }
|
||||
#endif
|
||||
AVSC_INLINE AVS_Value avs_new_value_array(AVS_Value * v0, int size)
|
||||
{ AVS_Value v = {0}; v.type = 'a'; v.d.array = v0; v.array_size = size; return v; }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AVS_Clip
|
||||
//
|
||||
#if defined __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
AVSC_API(void, avs_release_clip)(AVS_Clip *);
|
||||
AVSC_API(AVS_Clip *, avs_copy_clip)(AVS_Clip *);
|
||||
|
||||
AVSC_API(const char *, avs_clip_get_error)(AVS_Clip *); // return 0 if no error
|
||||
|
||||
AVSC_API(const AVS_VideoInfo *, avs_get_video_info)(AVS_Clip *);
|
||||
|
||||
AVSC_API(int, avs_get_version)(AVS_Clip *);
|
||||
|
||||
AVSC_API(AVS_VideoFrame *, avs_get_frame)(AVS_Clip *, int n);
|
||||
// The returned video frame must be released with avs_release_video_frame
|
||||
|
||||
AVSC_API(int, avs_get_parity)(AVS_Clip *, int n);
|
||||
// return field parity if field_based, else parity of first field in frame
|
||||
|
||||
AVSC_API(int, avs_get_audio)(AVS_Clip *, void * buf,
|
||||
INT64 start, INT64 count);
|
||||
// start and count are in samples
|
||||
|
||||
AVSC_API(int, avs_set_cache_hints)(AVS_Clip *,
|
||||
int cachehints, size_t frame_range);
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
// This is the callback type used by avs_add_function
|
||||
typedef AVS_Value (AVSC_CC * AVS_ApplyFunc)
|
||||
(AVS_ScriptEnvironment *, AVS_Value args, void * user_data);
|
||||
|
||||
typedef struct AVS_FilterInfo AVS_FilterInfo;
|
||||
struct AVS_FilterInfo
|
||||
{
|
||||
// these members should not be modified outside of the AVS_ApplyFunc callback
|
||||
AVS_Clip * child;
|
||||
AVS_VideoInfo vi;
|
||||
AVS_ScriptEnvironment * env;
|
||||
AVS_VideoFrame * (AVSC_CC * get_frame)(AVS_FilterInfo *, int n);
|
||||
int (AVSC_CC * get_parity)(AVS_FilterInfo *, int n);
|
||||
int (AVSC_CC * get_audio)(AVS_FilterInfo *, void * buf,
|
||||
INT64 start, INT64 count);
|
||||
int (AVSC_CC * set_cache_hints)(AVS_FilterInfo *, int cachehints,
|
||||
int frame_range);
|
||||
void (AVSC_CC * free_filter)(AVS_FilterInfo *);
|
||||
|
||||
// Should be set when ever there is an error to report.
|
||||
// It is cleared before any of the above methods are called
|
||||
const char * error;
|
||||
// this is to store whatever and may be modified at will
|
||||
void * user_data;
|
||||
};
|
||||
|
||||
// Create a new filter
|
||||
// fi is set to point to the AVS_FilterInfo so that you can
|
||||
// modify it once it is initilized.
|
||||
// store_child should generally be set to true. If it is not
|
||||
// set than ALL methods (the function pointers) must be defined
|
||||
// If it is set than you do not need to worry about freeing the child
|
||||
// clip.
|
||||
#if defined __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
AVSC_API(AVS_Clip *, avs_new_c_filter)(AVS_ScriptEnvironment * e,
|
||||
AVS_FilterInfo * * fi,
|
||||
AVS_Value child, int store_child);
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AVS_ScriptEnvironment
|
||||
//
|
||||
|
||||
// For GetCPUFlags. These are backwards-compatible with those in VirtualDub.
|
||||
enum {
|
||||
/* slowest CPU to support extension */
|
||||
AVS_CPU_FORCE = 0x01, // N/A
|
||||
AVS_CPU_FPU = 0x02, // 386/486DX
|
||||
AVS_CPU_MMX = 0x04, // P55C, K6, PII
|
||||
AVS_CPU_INTEGER_SSE = 0x08, // PIII, Athlon
|
||||
AVS_CPU_SSE = 0x10, // PIII, Athlon XP/MP
|
||||
AVS_CPU_SSE2 = 0x20, // PIV, Hammer
|
||||
AVS_CPU_3DNOW = 0x40, // K6-2
|
||||
AVS_CPU_3DNOW_EXT = 0x80, // Athlon
|
||||
AVS_CPU_X86_64 = 0xA0, // Hammer (note: equiv. to 3DNow + SSE2,
|
||||
// which only Hammer will have anyway)
|
||||
};
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
AVSC_API(const char *, avs_get_error)(AVS_ScriptEnvironment *); // return 0 if no error
|
||||
|
||||
AVSC_API(long, avs_get_cpu_flags)(AVS_ScriptEnvironment *);
|
||||
AVSC_API(int, avs_check_version)(AVS_ScriptEnvironment *, int version);
|
||||
|
||||
AVSC_API(char *, avs_save_string)(AVS_ScriptEnvironment *, const char* s, int length);
|
||||
AVSC_API(char *, avs_sprintf)(AVS_ScriptEnvironment *, const char * fmt, ...);
|
||||
|
||||
AVSC_API(char *, avs_vsprintf)(AVS_ScriptEnvironment *, const char * fmt, va_list val);
|
||||
// note: val is really a va_list; I hope everyone typedefs va_list to a pointer
|
||||
|
||||
AVSC_API(int, avs_add_function)(AVS_ScriptEnvironment *,
|
||||
const char * name, const char * params,
|
||||
AVS_ApplyFunc apply, void * user_data);
|
||||
|
||||
AVSC_API(int, avs_function_exists)(AVS_ScriptEnvironment *, const char * name);
|
||||
|
||||
AVSC_API(AVS_Value, avs_invoke)(AVS_ScriptEnvironment *, const char * name,
|
||||
AVS_Value args, const char** arg_names);
|
||||
// The returned value must be be released with avs_release_value
|
||||
|
||||
AVSC_API(AVS_Value, avs_get_var)(AVS_ScriptEnvironment *, const char* name);
|
||||
// The returned value must be be released with avs_release_value
|
||||
|
||||
AVSC_API(int, avs_set_var)(AVS_ScriptEnvironment *, const char* name, AVS_Value val);
|
||||
|
||||
AVSC_API(int, avs_set_global_var)(AVS_ScriptEnvironment *, const char* name, const AVS_Value val);
|
||||
|
||||
//void avs_push_context(AVS_ScriptEnvironment *, int level=0);
|
||||
//void avs_pop_context(AVS_ScriptEnvironment *);
|
||||
|
||||
AVSC_API(AVS_VideoFrame *, avs_new_video_frame_a)(AVS_ScriptEnvironment *,
|
||||
const AVS_VideoInfo * vi, int align);
|
||||
// align should be at least 16
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifndef AVSC_NO_DECLSPEC
|
||||
AVSC_INLINE
|
||||
AVS_VideoFrame * avs_new_video_frame(AVS_ScriptEnvironment * env,
|
||||
const AVS_VideoInfo * vi)
|
||||
{return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);}
|
||||
|
||||
AVSC_INLINE
|
||||
AVS_VideoFrame * avs_new_frame(AVS_ScriptEnvironment * env,
|
||||
const AVS_VideoInfo * vi)
|
||||
{return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);}
|
||||
#endif
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
AVSC_API(int, avs_make_writable)(AVS_ScriptEnvironment *, AVS_VideoFrame * * pvf);
|
||||
|
||||
AVSC_API(void, avs_bit_blt)(AVS_ScriptEnvironment *, unsigned char* dstp, int dst_pitch, const unsigned char* srcp, int src_pitch, int row_size, int height);
|
||||
|
||||
typedef void (AVSC_CC *AVS_ShutdownFunc)(void* user_data, AVS_ScriptEnvironment * env);
|
||||
AVSC_API(void, avs_at_exit)(AVS_ScriptEnvironment *, AVS_ShutdownFunc function, void * user_data);
|
||||
|
||||
AVSC_API(AVS_VideoFrame *, avs_subframe)(AVS_ScriptEnvironment *, AVS_VideoFrame * src, int rel_offset, int new_pitch, int new_row_size, int new_height);
|
||||
// The returned video frame must be be released
|
||||
|
||||
AVSC_API(int, avs_set_memory_max)(AVS_ScriptEnvironment *, int mem);
|
||||
|
||||
AVSC_API(int, avs_set_working_dir)(AVS_ScriptEnvironment *, const char * newdir);
|
||||
|
||||
// avisynth.dll exports this; it's a way to use it as a library, without
|
||||
// writing an AVS script or without going through AVIFile.
|
||||
AVSC_API(AVS_ScriptEnvironment *, avs_create_script_environment)(int version);
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
// this symbol is the entry point for the plugin and must
|
||||
// be defined
|
||||
AVSC_EXPORT
|
||||
const char * AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env);
|
||||
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
AVSC_API(void, avs_delete_script_environment)(AVS_ScriptEnvironment *);
|
||||
|
||||
|
||||
AVSC_API(AVS_VideoFrame *, avs_subframe_planar)(AVS_ScriptEnvironment *, AVS_VideoFrame * src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV);
|
||||
// The returned video frame must be be released
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif //__AVXSYNTH_C__
|
||||
85
compat/avisynth/windowsPorts/basicDataTypeConversions.h
Normal file
85
compat/avisynth/windowsPorts/basicDataTypeConversions.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef __DATA_TYPE_CONVERSIONS_H__
|
||||
#define __DATA_TYPE_CONVERSIONS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace avxsynth {
|
||||
#endif // __cplusplus
|
||||
|
||||
typedef int64_t __int64;
|
||||
typedef int32_t __int32;
|
||||
#ifdef __cplusplus
|
||||
typedef bool BOOL;
|
||||
#else
|
||||
typedef uint32_t BOOL;
|
||||
#endif // __cplusplus
|
||||
typedef void* HMODULE;
|
||||
typedef void* LPVOID;
|
||||
typedef void* PVOID;
|
||||
typedef PVOID HANDLE;
|
||||
typedef HANDLE HWND;
|
||||
typedef HANDLE HINSTANCE;
|
||||
typedef void* HDC;
|
||||
typedef void* HBITMAP;
|
||||
typedef void* HICON;
|
||||
typedef void* HFONT;
|
||||
typedef void* HGDIOBJ;
|
||||
typedef void* HBRUSH;
|
||||
typedef void* HMMIO;
|
||||
typedef void* HACMSTREAM;
|
||||
typedef void* HACMDRIVER;
|
||||
typedef void* HIC;
|
||||
typedef void* HACMOBJ;
|
||||
typedef HACMSTREAM* LPHACMSTREAM;
|
||||
typedef void* HACMDRIVERID;
|
||||
typedef void* LPHACMDRIVER;
|
||||
typedef unsigned char BYTE;
|
||||
typedef BYTE* LPBYTE;
|
||||
typedef char TCHAR;
|
||||
typedef TCHAR* LPTSTR;
|
||||
typedef const TCHAR* LPCTSTR;
|
||||
typedef char* LPSTR;
|
||||
typedef LPSTR LPOLESTR;
|
||||
typedef const char* LPCSTR;
|
||||
typedef LPCSTR LPCOLESTR;
|
||||
typedef wchar_t WCHAR;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned int UINT;
|
||||
typedef UINT MMRESULT;
|
||||
typedef uint32_t DWORD;
|
||||
typedef DWORD COLORREF;
|
||||
typedef DWORD FOURCC;
|
||||
typedef DWORD HRESULT;
|
||||
typedef DWORD* LPDWORD;
|
||||
typedef DWORD* DWORD_PTR;
|
||||
typedef int32_t LONG;
|
||||
typedef int32_t* LONG_PTR;
|
||||
typedef LONG_PTR LRESULT;
|
||||
typedef uint32_t ULONG;
|
||||
typedef uint32_t* ULONG_PTR;
|
||||
//typedef __int64_t intptr_t;
|
||||
typedef uint64_t _fsize_t;
|
||||
|
||||
|
||||
//
|
||||
// Structures
|
||||
//
|
||||
|
||||
typedef struct _GUID {
|
||||
DWORD Data1;
|
||||
WORD Data2;
|
||||
WORD Data3;
|
||||
BYTE Data4[8];
|
||||
} GUID;
|
||||
|
||||
typedef GUID REFIID;
|
||||
typedef GUID CLSID;
|
||||
typedef CLSID* LPCLSID;
|
||||
typedef GUID IID;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; // namespace avxsynth
|
||||
#endif // __cplusplus
|
||||
#endif // __DATA_TYPE_CONVERSIONS_H__
|
||||
77
compat/avisynth/windowsPorts/windows2linux.h
Normal file
77
compat/avisynth/windowsPorts/windows2linux.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#ifndef __WINDOWS2LINUX_H__
|
||||
#define __WINDOWS2LINUX_H__
|
||||
|
||||
/*
|
||||
* LINUX SPECIFIC DEFINITIONS
|
||||
*/
|
||||
//
|
||||
// Data types conversions
|
||||
//
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "basicDataTypeConversions.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace avxsynth {
|
||||
#endif // __cplusplus
|
||||
//
|
||||
// purposefully define the following MSFT definitions
|
||||
// to mean nothing (as they do not mean anything on Linux)
|
||||
//
|
||||
#define __stdcall
|
||||
#define __cdecl
|
||||
#define noreturn
|
||||
#define __declspec(x)
|
||||
#define STDAPI extern "C" HRESULT
|
||||
#define STDMETHODIMP HRESULT __stdcall
|
||||
#define STDMETHODIMP_(x) x __stdcall
|
||||
|
||||
#define STDMETHOD(x) virtual HRESULT x
|
||||
#define STDMETHOD_(a, x) virtual a x
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE true
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE false
|
||||
#endif
|
||||
|
||||
#define S_OK (0x00000000)
|
||||
#define S_FALSE (0x00000001)
|
||||
#define E_NOINTERFACE (0X80004002)
|
||||
#define E_POINTER (0x80004003)
|
||||
#define E_FAIL (0x80004005)
|
||||
#define E_OUTOFMEMORY (0x8007000E)
|
||||
|
||||
#define INVALID_HANDLE_VALUE ((HANDLE)((LONG_PTR)-1))
|
||||
#define FAILED(hr) ((hr) & 0x80000000)
|
||||
#define SUCCEEDED(hr) (!FAILED(hr))
|
||||
|
||||
|
||||
//
|
||||
// Functions
|
||||
//
|
||||
#define MAKEDWORD(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
|
||||
#define MAKEWORD(a,b) (((a) << 8) | (b))
|
||||
|
||||
#define lstrlen strlen
|
||||
#define lstrcpy strcpy
|
||||
#define lstrcmpi strcasecmp
|
||||
#define _stricmp strcasecmp
|
||||
#define InterlockedIncrement(x) __sync_fetch_and_add((x), 1)
|
||||
#define InterlockedDecrement(x) __sync_fetch_and_sub((x), 1)
|
||||
// Windows uses (new, old) ordering but GCC has (old, new)
|
||||
#define InterlockedCompareExchange(x,y,z) __sync_val_compare_and_swap(x,z,y)
|
||||
|
||||
#define UInt32x32To64(a, b) ( (uint64_t) ( ((uint64_t)((uint32_t)(a))) * ((uint32_t)(b)) ) )
|
||||
#define Int64ShrlMod32(a, b) ( (uint64_t) ( (uint64_t)(a) >> (b) ) )
|
||||
#define Int32x32To64(a, b) ((__int64)(((__int64)((long)(a))) * ((long)(b))))
|
||||
|
||||
#define MulDiv(nNumber, nNumerator, nDenominator) (int32_t) (((int64_t) (nNumber) * (int64_t) (nNumerator) + (int64_t) ((nDenominator)/2)) / (int64_t) (nDenominator))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; // namespace avxsynth
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __WINDOWS2LINUX_H__
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* Minimum CUDA compatibility definitions header
|
||||
*
|
||||
* Copyright (c) 2019 rcombs
|
||||
*
|
||||
* 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_CUDA_CUDA_RUNTIME_H
|
||||
#define COMPAT_CUDA_CUDA_RUNTIME_H
|
||||
|
||||
// Common macros
|
||||
#define __global__ __attribute__((global))
|
||||
#define __device__ __attribute__((device))
|
||||
#define __device_builtin__ __attribute__((device_builtin))
|
||||
#define __align__(N) __attribute__((aligned(N)))
|
||||
#define __inline__ __inline__ __attribute__((always_inline))
|
||||
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define abs(x) ((x) < 0 ? -(x) : (x))
|
||||
|
||||
#define atomicAdd(a, b) (__atomic_fetch_add(a, b, __ATOMIC_SEQ_CST))
|
||||
|
||||
// Basic typedefs
|
||||
typedef __device_builtin__ unsigned long long cudaTextureObject_t;
|
||||
|
||||
typedef struct __device_builtin__ __align__(2) uchar2
|
||||
{
|
||||
unsigned char x, y;
|
||||
} uchar2;
|
||||
|
||||
typedef struct __device_builtin__ __align__(4) ushort2
|
||||
{
|
||||
unsigned short x, y;
|
||||
} ushort2;
|
||||
|
||||
typedef struct __device_builtin__ __align__(8) float2
|
||||
{
|
||||
float x, y;
|
||||
} float2;
|
||||
|
||||
typedef struct __device_builtin__ __align__(8) int2
|
||||
{
|
||||
int x, y;
|
||||
} int2;
|
||||
|
||||
typedef struct __device_builtin__ uint3
|
||||
{
|
||||
unsigned int x, y, z;
|
||||
} uint3;
|
||||
|
||||
typedef struct uint3 dim3;
|
||||
|
||||
typedef struct __device_builtin__ __align__(4) uchar4
|
||||
{
|
||||
unsigned char x, y, z, w;
|
||||
} uchar4;
|
||||
|
||||
typedef struct __device_builtin__ __align__(8) ushort4
|
||||
{
|
||||
unsigned short x, y, z, w;
|
||||
} ushort4;
|
||||
|
||||
typedef struct __device_builtin__ __align__(16) int4
|
||||
{
|
||||
int x, y, z, w;
|
||||
} int4;
|
||||
|
||||
typedef struct __device_builtin__ __align__(16) float4
|
||||
{
|
||||
float x, y, z, w;
|
||||
} float4;
|
||||
|
||||
// Accessors for special registers
|
||||
#define GETCOMP(reg, comp) \
|
||||
asm("mov.u32 %0, %%" #reg "." #comp ";" : "=r"(tmp)); \
|
||||
ret.comp = tmp;
|
||||
|
||||
#define GET(name, reg) static inline __device__ uint3 name() {\
|
||||
uint3 ret; \
|
||||
unsigned tmp; \
|
||||
GETCOMP(reg, x) \
|
||||
GETCOMP(reg, y) \
|
||||
GETCOMP(reg, z) \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
GET(getBlockIdx, ctaid)
|
||||
GET(getBlockDim, ntid)
|
||||
GET(getThreadIdx, tid)
|
||||
|
||||
// Instead of externs for these registers, we turn access to them into calls into trivial ASM
|
||||
#define blockIdx (getBlockIdx())
|
||||
#define blockDim (getBlockDim())
|
||||
#define threadIdx (getThreadIdx())
|
||||
|
||||
// Basic initializers (simple macros rather than inline functions)
|
||||
#define make_int2(a, b) ((int2){.x = a, .y = b})
|
||||
#define make_uchar2(a, b) ((uchar2){.x = a, .y = b})
|
||||
#define make_ushort2(a, b) ((ushort2){.x = a, .y = b})
|
||||
#define make_float2(a, b) ((float2){.x = a, .y = b})
|
||||
#define make_int4(a, b, c, d) ((int4){.x = a, .y = b, .z = c, .w = d})
|
||||
#define make_uchar4(a, b, c, d) ((uchar4){.x = a, .y = b, .z = c, .w = d})
|
||||
#define make_ushort4(a, b, c, d) ((ushort4){.x = a, .y = b, .z = c, .w = d})
|
||||
#define make_float4(a, b, c, d) ((float4){.x = a, .y = b, .z = c, .w = d})
|
||||
|
||||
// Conversions from the tex instruction's 4-register output to various types
|
||||
#define TEX2D(type, ret) static inline __device__ void conv(type* out, unsigned a, unsigned b, unsigned c, unsigned d) {*out = (ret);}
|
||||
|
||||
TEX2D(unsigned char, a & 0xFF)
|
||||
TEX2D(unsigned short, a & 0xFFFF)
|
||||
TEX2D(float, a)
|
||||
TEX2D(uchar2, make_uchar2(a & 0xFF, b & 0xFF))
|
||||
TEX2D(ushort2, make_ushort2(a & 0xFFFF, b & 0xFFFF))
|
||||
TEX2D(float2, make_float2(a, b))
|
||||
TEX2D(uchar4, make_uchar4(a & 0xFF, b & 0xFF, c & 0xFF, d & 0xFF))
|
||||
TEX2D(ushort4, make_ushort4(a & 0xFFFF, b & 0xFFFF, c & 0xFFFF, d & 0xFFFF))
|
||||
TEX2D(float4, make_float4(a, b, c, d))
|
||||
|
||||
// Template calling tex instruction and converting the output to the selected type
|
||||
template<typename T>
|
||||
inline __device__ T tex2D(cudaTextureObject_t texObject, float x, float y)
|
||||
{
|
||||
T ret;
|
||||
unsigned ret1, ret2, ret3, ret4;
|
||||
asm("tex.2d.v4.u32.f32 {%0, %1, %2, %3}, [%4, {%5, %6}];" :
|
||||
"=r"(ret1), "=r"(ret2), "=r"(ret3), "=r"(ret4) :
|
||||
"l"(texObject), "f"(x), "f"(y));
|
||||
conv(&ret, ret1, ret2, ret3, ret4);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline __device__ float4 tex2D<float4>(cudaTextureObject_t texObject, float x, float y)
|
||||
{
|
||||
float4 ret;
|
||||
asm("tex.2d.v4.f32.f32 {%0, %1, %2, %3}, [%4, {%5, %6}];" :
|
||||
"=r"(ret.x), "=r"(ret.y), "=r"(ret.z), "=r"(ret.w) :
|
||||
"l"(texObject), "f"(x), "f"(y));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline __device__ float tex2D<float>(cudaTextureObject_t texObject, float x, float y)
|
||||
{
|
||||
return tex2D<float4>(texObject, x, y).x;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline __device__ float2 tex2D<float2>(cudaTextureObject_t texObject, float x, float y)
|
||||
{
|
||||
float4 ret = tex2D<float4>(texObject, x, y);
|
||||
return make_float2(ret.x, ret.y);
|
||||
}
|
||||
|
||||
// Math helper functions
|
||||
static inline __device__ float floorf(float a) { return __builtin_floorf(a); }
|
||||
static inline __device__ float floor(float a) { return __builtin_floorf(a); }
|
||||
static inline __device__ double floor(double a) { return __builtin_floor(a); }
|
||||
static inline __device__ float ceilf(float a) { return __builtin_ceilf(a); }
|
||||
static inline __device__ float ceil(float a) { return __builtin_ceilf(a); }
|
||||
static inline __device__ double ceil(double a) { return __builtin_ceil(a); }
|
||||
static inline __device__ float truncf(float a) { return __builtin_truncf(a); }
|
||||
static inline __device__ float trunc(float a) { return __builtin_truncf(a); }
|
||||
static inline __device__ double trunc(double a) { return __builtin_trunc(a); }
|
||||
static inline __device__ float fabsf(float a) { return __builtin_fabsf(a); }
|
||||
static inline __device__ float fabs(float a) { return __builtin_fabsf(a); }
|
||||
static inline __device__ double fabs(double a) { return __builtin_fabs(a); }
|
||||
|
||||
static inline __device__ float __sinf(float a) { return __nvvm_sin_approx_f(a); }
|
||||
static inline __device__ float __cosf(float a) { return __nvvm_cos_approx_f(a); }
|
||||
static inline __device__ float __expf(float a) { return __nvvm_ex2_approx_f(a * (float)__builtin_log2(__builtin_exp(1))); }
|
||||
|
||||
#endif /* COMPAT_CUDA_CUDA_RUNTIME_H */
|
||||
827
compat/cuda/cuviddec.h
Normal file
827
compat/cuda/cuviddec.h
Normal file
@@ -0,0 +1,827 @@
|
||||
/*
|
||||
* This copyright notice applies to this header file only:
|
||||
*
|
||||
* Copyright (c) 2010-2016 NVIDIA Corporation
|
||||
*
|
||||
* 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 cuviddec.h
|
||||
* NvCuvid API provides Video Decoding interface to NVIDIA GPU devices.
|
||||
* \date 2015-2016
|
||||
* This file contains constants, structure definitions and function prototypes used for decoding.
|
||||
*/
|
||||
|
||||
#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
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef void *CUvideodecoder;
|
||||
typedef struct _CUcontextlock_st *CUvideoctxlock;
|
||||
|
||||
/**
|
||||
* \addtogroup VIDEO_DECODER Video Decoder
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \enum cudaVideoCodec
|
||||
* Video Codec Enums
|
||||
*/
|
||||
typedef enum cudaVideoCodec_enum {
|
||||
cudaVideoCodec_MPEG1=0, /**< MPEG1 */
|
||||
cudaVideoCodec_MPEG2, /**< MPEG2 */
|
||||
cudaVideoCodec_MPEG4, /**< MPEG4 */
|
||||
cudaVideoCodec_VC1, /**< VC1 */
|
||||
cudaVideoCodec_H264, /**< H264 */
|
||||
cudaVideoCodec_JPEG, /**< JPEG */
|
||||
cudaVideoCodec_H264_SVC, /**< H264-SVC */
|
||||
cudaVideoCodec_H264_MVC, /**< H264-MVC */
|
||||
cudaVideoCodec_HEVC, /**< HEVC */
|
||||
cudaVideoCodec_VP8, /**< VP8 */
|
||||
cudaVideoCodec_VP9, /**< VP9 */
|
||||
cudaVideoCodec_NumCodecs, /**< Max COdecs */
|
||||
// Uncompressed YUV
|
||||
cudaVideoCodec_YUV420 = (('I'<<24)|('Y'<<16)|('U'<<8)|('V')), /**< Y,U,V (4:2:0) */
|
||||
cudaVideoCodec_YV12 = (('Y'<<24)|('V'<<16)|('1'<<8)|('2')), /**< Y,V,U (4:2:0) */
|
||||
cudaVideoCodec_NV12 = (('N'<<24)|('V'<<16)|('1'<<8)|('2')), /**< Y,UV (4:2:0) */
|
||||
cudaVideoCodec_YUYV = (('Y'<<24)|('U'<<16)|('Y'<<8)|('V')), /**< YUYV/YUY2 (4:2:2) */
|
||||
cudaVideoCodec_UYVY = (('U'<<24)|('Y'<<16)|('V'<<8)|('Y')) /**< UYVY (4:2:2) */
|
||||
} cudaVideoCodec;
|
||||
|
||||
/*!
|
||||
* \enum cudaVideoSurfaceFormat
|
||||
* Video Surface Formats Enums
|
||||
*/
|
||||
typedef enum cudaVideoSurfaceFormat_enum {
|
||||
cudaVideoSurfaceFormat_NV12=0 /**< NV12 (currently the only supported output format) */
|
||||
} cudaVideoSurfaceFormat;
|
||||
|
||||
/*!
|
||||
* \enum cudaVideoDeinterlaceMode
|
||||
* Deinterlacing Modes Enums
|
||||
*/
|
||||
typedef enum cudaVideoDeinterlaceMode_enum {
|
||||
cudaVideoDeinterlaceMode_Weave=0, /**< Weave both fields (no deinterlacing) */
|
||||
cudaVideoDeinterlaceMode_Bob, /**< Drop one field */
|
||||
cudaVideoDeinterlaceMode_Adaptive /**< Adaptive deinterlacing */
|
||||
} cudaVideoDeinterlaceMode;
|
||||
|
||||
/*!
|
||||
* \enum cudaVideoChromaFormat
|
||||
* Chroma Formats Enums
|
||||
*/
|
||||
typedef enum cudaVideoChromaFormat_enum {
|
||||
cudaVideoChromaFormat_Monochrome=0, /**< MonoChrome */
|
||||
cudaVideoChromaFormat_420, /**< 4:2:0 */
|
||||
cudaVideoChromaFormat_422, /**< 4:2:2 */
|
||||
cudaVideoChromaFormat_444 /**< 4:4:4 */
|
||||
} cudaVideoChromaFormat;
|
||||
|
||||
/*!
|
||||
* \enum cudaVideoCreateFlags
|
||||
* Decoder Flags Enums
|
||||
*/
|
||||
typedef enum cudaVideoCreateFlags_enum {
|
||||
cudaVideoCreate_Default = 0x00, /**< Default operation mode: use dedicated video engines */
|
||||
cudaVideoCreate_PreferCUDA = 0x01, /**< Use a CUDA-based decoder if faster than dedicated engines (requires a valid vidLock object for multi-threading) */
|
||||
cudaVideoCreate_PreferDXVA = 0x02, /**< Go through DXVA internally if possible (requires D3D9 interop) */
|
||||
cudaVideoCreate_PreferCUVID = 0x04 /**< Use dedicated video engines directly */
|
||||
} cudaVideoCreateFlags;
|
||||
|
||||
/*!
|
||||
* \struct CUVIDDECODECREATEINFO
|
||||
* Struct used in create decoder
|
||||
*/
|
||||
typedef struct _CUVIDDECODECREATEINFO
|
||||
{
|
||||
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) */
|
||||
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
|
||||
*/
|
||||
struct {
|
||||
short left;
|
||||
short top;
|
||||
short right;
|
||||
short bottom;
|
||||
} display_area;
|
||||
|
||||
cudaVideoSurfaceFormat OutputFormat; /**< cudaVideoSurfaceFormat_XXX */
|
||||
cudaVideoDeinterlaceMode DeinterlaceMode; /**< cudaVideoDeinterlaceMode_XXX */
|
||||
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)
|
||||
* if a null rectangle is specified, {0,0,ulTargetWidth,ulTargetHeight} will be used
|
||||
*/
|
||||
struct {
|
||||
short left;
|
||||
short top;
|
||||
short right;
|
||||
short bottom;
|
||||
} target_rect;
|
||||
unsigned long Reserved2[5]; /**< Reserved for future use - set to zero */
|
||||
} CUVIDDECODECREATEINFO;
|
||||
|
||||
/*!
|
||||
* \struct CUVIDH264DPBENTRY
|
||||
* H.264 DPB Entry
|
||||
*/
|
||||
typedef struct _CUVIDH264DPBENTRY
|
||||
{
|
||||
int PicIdx; /**< picture index of reference frame */
|
||||
int FrameIdx; /**< frame_num(short-term) or LongTermFrameIdx(long-term) */
|
||||
int is_long_term; /**< 0=short term reference, 1=long term reference */
|
||||
int not_existing; /**< non-existing reference frame (corresponding PicIdx should be set to -1) */
|
||||
int used_for_reference; /**< 0=unused, 1=top_field, 2=bottom_field, 3=both_fields */
|
||||
int FieldOrderCnt[2]; /**< field order count of top and bottom fields */
|
||||
} CUVIDH264DPBENTRY;
|
||||
|
||||
/*!
|
||||
* \struct CUVIDH264MVCEXT
|
||||
* H.264 MVC Picture Parameters Ext
|
||||
*/
|
||||
typedef struct _CUVIDH264MVCEXT
|
||||
{
|
||||
int num_views_minus1;
|
||||
int view_id;
|
||||
unsigned char inter_view_flag;
|
||||
unsigned char num_inter_view_refs_l0;
|
||||
unsigned char num_inter_view_refs_l1;
|
||||
unsigned char MVCReserved8Bits;
|
||||
int InterViewRefsL0[16];
|
||||
int InterViewRefsL1[16];
|
||||
} CUVIDH264MVCEXT;
|
||||
|
||||
/*!
|
||||
* \struct CUVIDH264SVCEXT
|
||||
* H.264 SVC Picture Parameters Ext
|
||||
*/
|
||||
typedef struct _CUVIDH264SVCEXT
|
||||
{
|
||||
unsigned char profile_idc;
|
||||
unsigned char level_idc;
|
||||
unsigned char DQId;
|
||||
unsigned char DQIdMax;
|
||||
unsigned char disable_inter_layer_deblocking_filter_idc;
|
||||
unsigned char ref_layer_chroma_phase_y_plus1;
|
||||
signed char inter_layer_slice_alpha_c0_offset_div2;
|
||||
signed char inter_layer_slice_beta_offset_div2;
|
||||
|
||||
unsigned short DPBEntryValidFlag;
|
||||
unsigned char inter_layer_deblocking_filter_control_present_flag;
|
||||
unsigned char extended_spatial_scalability_idc;
|
||||
unsigned char adaptive_tcoeff_level_prediction_flag;
|
||||
unsigned char slice_header_restriction_flag;
|
||||
unsigned char chroma_phase_x_plus1_flag;
|
||||
unsigned char chroma_phase_y_plus1;
|
||||
|
||||
unsigned char tcoeff_level_prediction_flag;
|
||||
unsigned char constrained_intra_resampling_flag;
|
||||
unsigned char ref_layer_chroma_phase_x_plus1_flag;
|
||||
unsigned char store_ref_base_pic_flag;
|
||||
unsigned char Reserved8BitsA;
|
||||
unsigned char Reserved8BitsB;
|
||||
// For the 4 scaled_ref_layer_XX fields below,
|
||||
// if (extended_spatial_scalability_idc == 1), SPS field, G.7.3.2.1.4, add prefix "seq_"
|
||||
// if (extended_spatial_scalability_idc == 2), SLH field, G.7.3.3.4,
|
||||
short scaled_ref_layer_left_offset;
|
||||
short scaled_ref_layer_top_offset;
|
||||
short scaled_ref_layer_right_offset;
|
||||
short scaled_ref_layer_bottom_offset;
|
||||
unsigned short Reserved16Bits;
|
||||
struct _CUVIDPICPARAMS *pNextLayer; /**< Points to the picparams for the next layer to be decoded. Linked list ends at the target layer. */
|
||||
int bRefBaseLayer; /**< whether to store ref base pic */
|
||||
} CUVIDH264SVCEXT;
|
||||
|
||||
/*!
|
||||
* \struct CUVIDH264PICPARAMS
|
||||
* H.264 Picture Parameters
|
||||
*/
|
||||
typedef struct _CUVIDH264PICPARAMS
|
||||
{
|
||||
// SPS
|
||||
int log2_max_frame_num_minus4;
|
||||
int pic_order_cnt_type;
|
||||
int log2_max_pic_order_cnt_lsb_minus4;
|
||||
int delta_pic_order_always_zero_flag;
|
||||
int frame_mbs_only_flag;
|
||||
int direct_8x8_inference_flag;
|
||||
int num_ref_frames; // NOTE: shall meet level 4.1 restrictions
|
||||
unsigned char residual_colour_transform_flag;
|
||||
unsigned char bit_depth_luma_minus8; // Must be 0 (only 8-bit supported)
|
||||
unsigned char bit_depth_chroma_minus8; // Must be 0 (only 8-bit supported)
|
||||
unsigned char qpprime_y_zero_transform_bypass_flag;
|
||||
// PPS
|
||||
int entropy_coding_mode_flag;
|
||||
int pic_order_present_flag;
|
||||
int num_ref_idx_l0_active_minus1;
|
||||
int num_ref_idx_l1_active_minus1;
|
||||
int weighted_pred_flag;
|
||||
int weighted_bipred_idc;
|
||||
int pic_init_qp_minus26;
|
||||
int deblocking_filter_control_present_flag;
|
||||
int redundant_pic_cnt_present_flag;
|
||||
int transform_8x8_mode_flag;
|
||||
int MbaffFrameFlag;
|
||||
int constrained_intra_pred_flag;
|
||||
int chroma_qp_index_offset;
|
||||
int second_chroma_qp_index_offset;
|
||||
int ref_pic_flag;
|
||||
int frame_num;
|
||||
int CurrFieldOrderCnt[2];
|
||||
// DPB
|
||||
CUVIDH264DPBENTRY dpb[16]; // List of reference frames within the DPB
|
||||
// Quantization Matrices (raster-order)
|
||||
unsigned char WeightScale4x4[6][16];
|
||||
unsigned char WeightScale8x8[2][64];
|
||||
// FMO/ASO
|
||||
unsigned char fmo_aso_enable;
|
||||
unsigned char num_slice_groups_minus1;
|
||||
unsigned char slice_group_map_type;
|
||||
signed char pic_init_qs_minus26;
|
||||
unsigned int slice_group_change_rate_minus1;
|
||||
union
|
||||
{
|
||||
unsigned long long slice_group_map_addr;
|
||||
const unsigned char *pMb2SliceGroupMap;
|
||||
} fmo;
|
||||
unsigned int Reserved[12];
|
||||
// SVC/MVC
|
||||
union
|
||||
{
|
||||
CUVIDH264MVCEXT mvcext;
|
||||
CUVIDH264SVCEXT svcext;
|
||||
};
|
||||
} CUVIDH264PICPARAMS;
|
||||
|
||||
|
||||
/*!
|
||||
* \struct CUVIDMPEG2PICPARAMS
|
||||
* MPEG-2 Picture Parameters
|
||||
*/
|
||||
typedef struct _CUVIDMPEG2PICPARAMS
|
||||
{
|
||||
int ForwardRefIdx; // Picture index of forward reference (P/B-frames)
|
||||
int BackwardRefIdx; // Picture index of backward reference (B-frames)
|
||||
int picture_coding_type;
|
||||
int full_pel_forward_vector;
|
||||
int full_pel_backward_vector;
|
||||
int f_code[2][2];
|
||||
int intra_dc_precision;
|
||||
int frame_pred_frame_dct;
|
||||
int concealment_motion_vectors;
|
||||
int q_scale_type;
|
||||
int intra_vlc_format;
|
||||
int alternate_scan;
|
||||
int top_field_first;
|
||||
// Quantization matrices (raster order)
|
||||
unsigned char QuantMatrixIntra[64];
|
||||
unsigned char QuantMatrixInter[64];
|
||||
} CUVIDMPEG2PICPARAMS;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MPEG-4 Picture Parameters
|
||||
//
|
||||
|
||||
// MPEG-4 has VOP types instead of Picture types
|
||||
#define I_VOP 0
|
||||
#define P_VOP 1
|
||||
#define B_VOP 2
|
||||
#define S_VOP 3
|
||||
|
||||
/*!
|
||||
* \struct CUVIDMPEG4PICPARAMS
|
||||
* MPEG-4 Picture Parameters
|
||||
*/
|
||||
typedef struct _CUVIDMPEG4PICPARAMS
|
||||
{
|
||||
int ForwardRefIdx; // Picture index of forward reference (P/B-frames)
|
||||
int BackwardRefIdx; // Picture index of backward reference (B-frames)
|
||||
// VOL
|
||||
int video_object_layer_width;
|
||||
int video_object_layer_height;
|
||||
int vop_time_increment_bitcount;
|
||||
int top_field_first;
|
||||
int resync_marker_disable;
|
||||
int quant_type;
|
||||
int quarter_sample;
|
||||
int short_video_header;
|
||||
int divx_flags;
|
||||
// VOP
|
||||
int vop_coding_type;
|
||||
int vop_coded;
|
||||
int vop_rounding_type;
|
||||
int alternate_vertical_scan_flag;
|
||||
int interlaced;
|
||||
int vop_fcode_forward;
|
||||
int vop_fcode_backward;
|
||||
int trd[2];
|
||||
int trb[2];
|
||||
// Quantization matrices (raster order)
|
||||
unsigned char QuantMatrixIntra[64];
|
||||
unsigned char QuantMatrixInter[64];
|
||||
int gmc_enabled;
|
||||
} CUVIDMPEG4PICPARAMS;
|
||||
|
||||
/*!
|
||||
* \struct CUVIDVC1PICPARAMS
|
||||
* VC1 Picture Parameters
|
||||
*/
|
||||
typedef struct _CUVIDVC1PICPARAMS
|
||||
{
|
||||
int ForwardRefIdx; /**< Picture index of forward reference (P/B-frames) */
|
||||
int BackwardRefIdx; /**< Picture index of backward reference (B-frames) */
|
||||
int FrameWidth; /**< Actual frame width */
|
||||
int FrameHeight; /**< Actual frame height */
|
||||
// PICTURE
|
||||
int intra_pic_flag; /**< Set to 1 for I,BI frames */
|
||||
int ref_pic_flag; /**< Set to 1 for I,P frames */
|
||||
int progressive_fcm; /**< Progressive frame */
|
||||
// SEQUENCE
|
||||
int profile;
|
||||
int postprocflag;
|
||||
int pulldown;
|
||||
int interlace;
|
||||
int tfcntrflag;
|
||||
int finterpflag;
|
||||
int psf;
|
||||
int multires;
|
||||
int syncmarker;
|
||||
int rangered;
|
||||
int maxbframes;
|
||||
// ENTRYPOINT
|
||||
int panscan_flag;
|
||||
int refdist_flag;
|
||||
int extended_mv;
|
||||
int dquant;
|
||||
int vstransform;
|
||||
int loopfilter;
|
||||
int fastuvmc;
|
||||
int overlap;
|
||||
int quantizer;
|
||||
int extended_dmv;
|
||||
int range_mapy_flag;
|
||||
int range_mapy;
|
||||
int range_mapuv_flag;
|
||||
int range_mapuv;
|
||||
int rangeredfrm; // range reduction state
|
||||
} CUVIDVC1PICPARAMS;
|
||||
|
||||
/*!
|
||||
* \struct CUVIDJPEGPICPARAMS
|
||||
* JPEG Picture Parameters
|
||||
*/
|
||||
typedef struct _CUVIDJPEGPICPARAMS
|
||||
{
|
||||
int Reserved;
|
||||
} CUVIDJPEGPICPARAMS;
|
||||
|
||||
|
||||
/*!
|
||||
* \struct CUVIDHEVCPICPARAMS
|
||||
* HEVC Picture Parameters
|
||||
*/
|
||||
typedef struct _CUVIDHEVCPICPARAMS
|
||||
{
|
||||
// sps
|
||||
int pic_width_in_luma_samples;
|
||||
int pic_height_in_luma_samples;
|
||||
unsigned char log2_min_luma_coding_block_size_minus3;
|
||||
unsigned char log2_diff_max_min_luma_coding_block_size;
|
||||
unsigned char log2_min_transform_block_size_minus2;
|
||||
unsigned char log2_diff_max_min_transform_block_size;
|
||||
unsigned char pcm_enabled_flag;
|
||||
unsigned char log2_min_pcm_luma_coding_block_size_minus3;
|
||||
unsigned char log2_diff_max_min_pcm_luma_coding_block_size;
|
||||
unsigned char pcm_sample_bit_depth_luma_minus1;
|
||||
|
||||
unsigned char pcm_sample_bit_depth_chroma_minus1;
|
||||
unsigned char pcm_loop_filter_disabled_flag;
|
||||
unsigned char strong_intra_smoothing_enabled_flag;
|
||||
unsigned char max_transform_hierarchy_depth_intra;
|
||||
unsigned char max_transform_hierarchy_depth_inter;
|
||||
unsigned char amp_enabled_flag;
|
||||
unsigned char separate_colour_plane_flag;
|
||||
unsigned char log2_max_pic_order_cnt_lsb_minus4;
|
||||
|
||||
unsigned char num_short_term_ref_pic_sets;
|
||||
unsigned char long_term_ref_pics_present_flag;
|
||||
unsigned char num_long_term_ref_pics_sps;
|
||||
unsigned char sps_temporal_mvp_enabled_flag;
|
||||
unsigned char sample_adaptive_offset_enabled_flag;
|
||||
unsigned char scaling_list_enable_flag;
|
||||
unsigned char IrapPicFlag;
|
||||
unsigned char IdrPicFlag;
|
||||
|
||||
unsigned char bit_depth_luma_minus8;
|
||||
unsigned char bit_depth_chroma_minus8;
|
||||
unsigned char reserved1[14];
|
||||
|
||||
// pps
|
||||
unsigned char dependent_slice_segments_enabled_flag;
|
||||
unsigned char slice_segment_header_extension_present_flag;
|
||||
unsigned char sign_data_hiding_enabled_flag;
|
||||
unsigned char cu_qp_delta_enabled_flag;
|
||||
unsigned char diff_cu_qp_delta_depth;
|
||||
signed char init_qp_minus26;
|
||||
signed char pps_cb_qp_offset;
|
||||
signed char pps_cr_qp_offset;
|
||||
|
||||
unsigned char constrained_intra_pred_flag;
|
||||
unsigned char weighted_pred_flag;
|
||||
unsigned char weighted_bipred_flag;
|
||||
unsigned char transform_skip_enabled_flag;
|
||||
unsigned char transquant_bypass_enabled_flag;
|
||||
unsigned char entropy_coding_sync_enabled_flag;
|
||||
unsigned char log2_parallel_merge_level_minus2;
|
||||
unsigned char num_extra_slice_header_bits;
|
||||
|
||||
unsigned char loop_filter_across_tiles_enabled_flag;
|
||||
unsigned char loop_filter_across_slices_enabled_flag;
|
||||
unsigned char output_flag_present_flag;
|
||||
unsigned char num_ref_idx_l0_default_active_minus1;
|
||||
unsigned char num_ref_idx_l1_default_active_minus1;
|
||||
unsigned char lists_modification_present_flag;
|
||||
unsigned char cabac_init_present_flag;
|
||||
unsigned char pps_slice_chroma_qp_offsets_present_flag;
|
||||
|
||||
unsigned char deblocking_filter_override_enabled_flag;
|
||||
unsigned char pps_deblocking_filter_disabled_flag;
|
||||
signed char pps_beta_offset_div2;
|
||||
signed char pps_tc_offset_div2;
|
||||
unsigned char tiles_enabled_flag;
|
||||
unsigned char uniform_spacing_flag;
|
||||
unsigned char num_tile_columns_minus1;
|
||||
unsigned char num_tile_rows_minus1;
|
||||
|
||||
unsigned short column_width_minus1[21];
|
||||
unsigned short row_height_minus1[21];
|
||||
unsigned int reserved3[15];
|
||||
|
||||
// RefPicSets
|
||||
int NumBitsForShortTermRPSInSlice;
|
||||
int NumDeltaPocsOfRefRpsIdx;
|
||||
int NumPocTotalCurr;
|
||||
int NumPocStCurrBefore;
|
||||
int NumPocStCurrAfter;
|
||||
int NumPocLtCurr;
|
||||
int CurrPicOrderCntVal;
|
||||
int RefPicIdx[16]; // [refpic] Indices of valid reference pictures (-1 if unused for reference)
|
||||
int PicOrderCntVal[16]; // [refpic]
|
||||
unsigned char IsLongTerm[16]; // [refpic] 0=not a long-term reference, 1=long-term reference
|
||||
unsigned char RefPicSetStCurrBefore[8]; // [0..NumPocStCurrBefore-1] -> refpic (0..15)
|
||||
unsigned char RefPicSetStCurrAfter[8]; // [0..NumPocStCurrAfter-1] -> refpic (0..15)
|
||||
unsigned char RefPicSetLtCurr[8]; // [0..NumPocLtCurr-1] -> refpic (0..15)
|
||||
unsigned char RefPicSetInterLayer0[8];
|
||||
unsigned char RefPicSetInterLayer1[8];
|
||||
unsigned int reserved4[12];
|
||||
|
||||
// scaling lists (diag order)
|
||||
unsigned char ScalingList4x4[6][16]; // [matrixId][i]
|
||||
unsigned char ScalingList8x8[6][64]; // [matrixId][i]
|
||||
unsigned char ScalingList16x16[6][64]; // [matrixId][i]
|
||||
unsigned char ScalingList32x32[2][64]; // [matrixId][i]
|
||||
unsigned char ScalingListDCCoeff16x16[6]; // [matrixId]
|
||||
unsigned char ScalingListDCCoeff32x32[2]; // [matrixId]
|
||||
} CUVIDHEVCPICPARAMS;
|
||||
|
||||
|
||||
/*!
|
||||
* \struct CUVIDVP8PICPARAMS
|
||||
* VP8 Picture Parameters
|
||||
*/
|
||||
typedef struct _CUVIDVP8PICPARAMS
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
unsigned int first_partition_size;
|
||||
//Frame Indexes
|
||||
unsigned char LastRefIdx;
|
||||
unsigned char GoldenRefIdx;
|
||||
unsigned char AltRefIdx;
|
||||
union {
|
||||
struct {
|
||||
unsigned char frame_type : 1; /**< 0 = KEYFRAME, 1 = INTERFRAME */
|
||||
unsigned char version : 3;
|
||||
unsigned char show_frame : 1;
|
||||
unsigned char update_mb_segmentation_data : 1; /**< Must be 0 if segmentation is not enabled */
|
||||
unsigned char Reserved2Bits : 2;
|
||||
};
|
||||
unsigned char wFrameTagFlags;
|
||||
};
|
||||
unsigned char Reserved1[4];
|
||||
unsigned int Reserved2[3];
|
||||
} CUVIDVP8PICPARAMS;
|
||||
|
||||
/*!
|
||||
* \struct CUVIDVP9PICPARAMS
|
||||
* VP9 Picture Parameters
|
||||
*/
|
||||
typedef struct _CUVIDVP9PICPARAMS
|
||||
{
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
|
||||
//Frame Indices
|
||||
unsigned char LastRefIdx;
|
||||
unsigned char GoldenRefIdx;
|
||||
unsigned char AltRefIdx;
|
||||
unsigned char colorSpace;
|
||||
|
||||
unsigned short profile : 3;
|
||||
unsigned short frameContextIdx : 2;
|
||||
unsigned short frameType : 1;
|
||||
unsigned short showFrame : 1;
|
||||
unsigned short errorResilient : 1;
|
||||
unsigned short frameParallelDecoding : 1;
|
||||
unsigned short subSamplingX : 1;
|
||||
unsigned short subSamplingY : 1;
|
||||
unsigned short intraOnly : 1;
|
||||
unsigned short allow_high_precision_mv : 1;
|
||||
unsigned short refreshEntropyProbs : 1;
|
||||
unsigned short reserved2Bits : 2;
|
||||
|
||||
unsigned short reserved16Bits;
|
||||
|
||||
unsigned char refFrameSignBias[4];
|
||||
|
||||
unsigned char bitDepthMinus8Luma;
|
||||
unsigned char bitDepthMinus8Chroma;
|
||||
unsigned char loopFilterLevel;
|
||||
unsigned char loopFilterSharpness;
|
||||
|
||||
unsigned char modeRefLfEnabled;
|
||||
unsigned char log2_tile_columns;
|
||||
unsigned char log2_tile_rows;
|
||||
|
||||
unsigned char segmentEnabled : 1;
|
||||
unsigned char segmentMapUpdate : 1;
|
||||
unsigned char segmentMapTemporalUpdate : 1;
|
||||
unsigned char segmentFeatureMode : 1;
|
||||
unsigned char reserved4Bits : 4;
|
||||
|
||||
|
||||
unsigned char segmentFeatureEnable[8][4];
|
||||
short segmentFeatureData[8][4];
|
||||
unsigned char mb_segment_tree_probs[7];
|
||||
unsigned char segment_pred_probs[3];
|
||||
unsigned char reservedSegment16Bits[2];
|
||||
|
||||
int qpYAc;
|
||||
int qpYDc;
|
||||
int qpChDc;
|
||||
int qpChAc;
|
||||
|
||||
unsigned int activeRefIdx[3];
|
||||
unsigned int resetFrameContext;
|
||||
unsigned int mcomp_filter_type;
|
||||
unsigned int mbRefLfDelta[4];
|
||||
unsigned int mbModeLfDelta[2];
|
||||
unsigned int frameTagSize;
|
||||
unsigned int offsetToDctParts;
|
||||
unsigned int reserved128Bits[4];
|
||||
|
||||
} CUVIDVP9PICPARAMS;
|
||||
|
||||
|
||||
/*!
|
||||
* \struct CUVIDPICPARAMS
|
||||
* Picture Parameters for Decoding
|
||||
*/
|
||||
typedef struct _CUVIDPICPARAMS
|
||||
{
|
||||
int PicWidthInMbs; /**< Coded Frame Size */
|
||||
int FrameHeightInMbs; /**< Coded Frame Height */
|
||||
int CurrPicIdx; /**< Output index of the current picture */
|
||||
int field_pic_flag; /**< 0=frame picture, 1=field picture */
|
||||
int bottom_field_flag; /**< 0=top field, 1=bottom field (ignored if field_pic_flag=0) */
|
||||
int second_field; /**< Second field of a complementary field pair */
|
||||
// Bitstream data
|
||||
unsigned int nBitstreamDataLen; /**< Number of bytes in bitstream data buffer */
|
||||
const unsigned char *pBitstreamData; /**< Ptr to bitstream data for this picture (slice-layer) */
|
||||
unsigned int nNumSlices; /**< Number of slices in this picture */
|
||||
const unsigned int *pSliceDataOffsets; /**< nNumSlices entries, contains offset of each slice within the bitstream data buffer */
|
||||
int ref_pic_flag; /**< This picture is a reference picture */
|
||||
int intra_pic_flag; /**< This picture is entirely intra coded */
|
||||
unsigned int Reserved[30]; /**< Reserved for future use */
|
||||
// Codec-specific data
|
||||
union {
|
||||
CUVIDMPEG2PICPARAMS mpeg2; /**< Also used for MPEG-1 */
|
||||
CUVIDH264PICPARAMS h264;
|
||||
CUVIDVC1PICPARAMS vc1;
|
||||
CUVIDMPEG4PICPARAMS mpeg4;
|
||||
CUVIDJPEGPICPARAMS jpeg;
|
||||
CUVIDHEVCPICPARAMS hevc;
|
||||
CUVIDVP8PICPARAMS vp8;
|
||||
CUVIDVP9PICPARAMS vp9;
|
||||
unsigned int CodecReserved[1024];
|
||||
} CodecSpecific;
|
||||
} CUVIDPICPARAMS;
|
||||
|
||||
|
||||
/*!
|
||||
* \struct CUVIDPROCPARAMS
|
||||
* Picture Parameters for Postprocessing
|
||||
*/
|
||||
typedef struct _CUVIDPROCPARAMS
|
||||
{
|
||||
int progressive_frame; /**< Input is progressive (deinterlace_mode will be ignored) */
|
||||
int second_field; /**< Output the second field (ignored if deinterlace mode is Weave) */
|
||||
int top_field_first; /**< Input frame is top field first (1st field is top, 2nd field is bottom) */
|
||||
int unpaired_field; /**< Input only contains one field (2nd field is invalid) */
|
||||
// The fields below are used for raw YUV input
|
||||
unsigned int reserved_flags; /**< Reserved for future use (set to zero) */
|
||||
unsigned int reserved_zero; /**< Reserved (set to zero) */
|
||||
unsigned long long raw_input_dptr; /**< Input CUdeviceptr for raw YUV extensions */
|
||||
unsigned int raw_input_pitch; /**< pitch in bytes of raw YUV input (should be aligned appropriately) */
|
||||
unsigned int raw_input_format; /**< Reserved for future use (set to zero) */
|
||||
unsigned long long raw_output_dptr; /**< Reserved for future use (set to zero) */
|
||||
unsigned int raw_output_pitch; /**< Reserved for future use (set to zero) */
|
||||
unsigned int Reserved[48];
|
||||
void *Reserved3[3];
|
||||
} CUVIDPROCPARAMS;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* In order to minimize decode latencies, there should be always at least 2 pictures in the decode
|
||||
* queue at any time, in order to make sure that all decode engines are always busy.
|
||||
*
|
||||
* Overall data flow:
|
||||
* - cuvidCreateDecoder(...)
|
||||
* For each picture:
|
||||
* - cuvidDecodePicture(N)
|
||||
* - cuvidMapVideoFrame(N-4)
|
||||
* - do some processing in cuda
|
||||
* - cuvidUnmapVideoFrame(N-4)
|
||||
* - cuvidDecodePicture(N+1)
|
||||
* - cuvidMapVideoFrame(N-3)
|
||||
* ...
|
||||
* - cuvidDestroyDecoder(...)
|
||||
*
|
||||
* NOTE:
|
||||
* - When the cuda context is created from a D3D device, the D3D device must also be created
|
||||
* with the D3DCREATE_MULTITHREADED flag.
|
||||
* - There is a limit to how many pictures can be mapped simultaneously (ulNumOutputSurfaces)
|
||||
* - cuVidDecodePicture may block the calling thread if there are too many pictures pending
|
||||
* in the decode queue
|
||||
*/
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidCreateDecoder(CUvideodecoder *phDecoder, CUVIDDECODECREATEINFO *pdci)
|
||||
* Create the decoder object
|
||||
*/
|
||||
CUresult CUDAAPI cuvidCreateDecoder(CUvideodecoder *phDecoder, CUVIDDECODECREATEINFO *pdci);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidDestroyDecoder(CUvideodecoder hDecoder)
|
||||
* Destroy the decoder object
|
||||
*/
|
||||
CUresult CUDAAPI cuvidDestroyDecoder(CUvideodecoder hDecoder);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidDecodePicture(CUvideodecoder hDecoder, CUVIDPICPARAMS *pPicParams)
|
||||
* Decode a single picture (field or frame)
|
||||
*/
|
||||
CUresult CUDAAPI cuvidDecodePicture(CUvideodecoder hDecoder, CUVIDPICPARAMS *pPicParams);
|
||||
|
||||
|
||||
#if !defined(__CUVID_DEVPTR64) || defined(__CUVID_INTERNAL)
|
||||
/**
|
||||
* \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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
CUresult CUDAAPI cuvidUnmapVideoFrame(CUvideodecoder hDecoder, unsigned int DevPtr);
|
||||
#endif
|
||||
|
||||
#if defined(WIN64) || defined(_WIN64) || defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidMapVideoFrame64(CUvideodecoder hDecoder, int nPicIdx, unsigned long long *pDevPtr, unsigned int *pPitch, CUVIDPROCPARAMS *pVPP);
|
||||
* map a video frame
|
||||
*/
|
||||
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
|
||||
*/
|
||||
CUresult CUDAAPI cuvidUnmapVideoFrame64(CUvideodecoder hDecoder, unsigned long long DevPtr);
|
||||
|
||||
#if defined(__CUVID_DEVPTR64) && !defined(__CUVID_INTERNAL)
|
||||
#define cuvidMapVideoFrame cuvidMapVideoFrame64
|
||||
#define cuvidUnmapVideoFrame cuvidUnmapVideoFrame64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Context-locking: to facilitate multi-threaded implementations, the following 4 functions
|
||||
* provide a simple mutex-style host synchronization. If a non-NULL context is specified
|
||||
* in CUVIDDECODECREATEINFO, the codec library will acquire the mutex associated with the given
|
||||
* context before making any cuda calls.
|
||||
* A multi-threaded application could create a lock associated with a context handle so that
|
||||
* multiple threads can safely share the same cuda context:
|
||||
* - use cuCtxPopCurrent immediately after context creation in order to create a 'floating' context
|
||||
* that can be passed to cuvidCtxLockCreate.
|
||||
* - When using a floating context, all cuda calls should only be made within a cuvidCtxLock/cuvidCtxUnlock section.
|
||||
*
|
||||
* NOTE: This is a safer alternative to cuCtxPushCurrent and cuCtxPopCurrent, and is not related to video
|
||||
* decoder in any way (implemented as a critical section associated with cuCtx{Push|Pop}Current calls).
|
||||
*/
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidCtxLockCreate(CUvideoctxlock *pLock, CUcontext ctx)
|
||||
*/
|
||||
CUresult CUDAAPI cuvidCtxLockCreate(CUvideoctxlock *pLock, CUcontext ctx);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidCtxLockDestroy(CUvideoctxlock lck)
|
||||
*/
|
||||
CUresult CUDAAPI cuvidCtxLockDestroy(CUvideoctxlock lck);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidCtxLock(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)
|
||||
*/
|
||||
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,33 +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_CUDA_DYNLINK_LOADER_H
|
||||
#define COMPAT_CUDA_DYNLINK_LOADER_H
|
||||
|
||||
#include "libavutil/log.h"
|
||||
#include "compat/w32dlfcn.h"
|
||||
|
||||
#define FFNV_LOAD_FUNC(path) dlopen((path), RTLD_LAZY)
|
||||
#define FFNV_SYM_FUNC(lib, sym) dlsym((lib), (sym))
|
||||
#define FFNV_FREE_FUNC(lib) dlclose(lib)
|
||||
#define FFNV_LOG_FUNC(logctx, msg, ...) av_log(logctx, AV_LOG_ERROR, msg, __VA_ARGS__)
|
||||
#define FFNV_DEBUG_LOG_FUNC(logctx, msg, ...) av_log(logctx, AV_LOG_DEBUG, msg, __VA_ARGS__)
|
||||
|
||||
#include <ffnvcodec/dynlink_loader.h>
|
||||
|
||||
#endif /* COMPAT_CUDA_DYNLINK_LOADER_H */
|
||||
321
compat/cuda/nvcuvid.h
Normal file
321
compat/cuda/nvcuvid.h
Normal file
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* This copyright notice applies to this header file only:
|
||||
*
|
||||
* Copyright (c) 2010-2016 NVIDIA Corporation
|
||||
*
|
||||
* 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 nvcuvid.h
|
||||
* NvCuvid API provides Video Decoding interface to NVIDIA GPU devices.
|
||||
* \date 2015-2015
|
||||
* This file contains the interface constants, structure definitions and function prototypes.
|
||||
*/
|
||||
|
||||
#if !defined(__NVCUVID_H__)
|
||||
#define __NVCUVID_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
|
||||
//
|
||||
|
||||
typedef void *CUvideosource;
|
||||
typedef void *CUvideoparser;
|
||||
typedef long long CUvideotimestamp;
|
||||
|
||||
/**
|
||||
* \addtogroup VIDEO_PARSER Video Parser
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \enum cudaVideoState
|
||||
* Video Source State
|
||||
*/
|
||||
typedef enum {
|
||||
cudaVideoState_Error = -1, /**< Error state (invalid source) */
|
||||
cudaVideoState_Stopped = 0, /**< Source is stopped (or reached end-of-stream) */
|
||||
cudaVideoState_Started = 1 /**< Source is running and delivering data */
|
||||
} cudaVideoState;
|
||||
|
||||
/*!
|
||||
* \enum cudaAudioCodec
|
||||
* Audio compression
|
||||
*/
|
||||
typedef enum {
|
||||
cudaAudioCodec_MPEG1=0, /**< MPEG-1 Audio */
|
||||
cudaAudioCodec_MPEG2, /**< MPEG-2 Audio */
|
||||
cudaAudioCodec_MP3, /**< MPEG-1 Layer III Audio */
|
||||
cudaAudioCodec_AC3, /**< Dolby Digital (AC3) Audio */
|
||||
cudaAudioCodec_LPCM /**< PCM Audio */
|
||||
} cudaAudioCodec;
|
||||
|
||||
/*!
|
||||
* \struct CUVIDEOFORMAT
|
||||
* Video format
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
cudaVideoCodec codec; /**< Compression format */
|
||||
/**
|
||||
* frame rate = numerator / denominator (for example: 30000/1001)
|
||||
*/
|
||||
struct {
|
||||
unsigned int numerator; /**< frame rate numerator (0 = unspecified or variable frame rate) */
|
||||
unsigned int denominator; /**< frame rate denominator (0 = unspecified or variable frame rate) */
|
||||
} frame_rate;
|
||||
unsigned char progressive_sequence; /**< 0=interlaced, 1=progressive */
|
||||
unsigned char bit_depth_luma_minus8; /**< high bit depth Luma */
|
||||
unsigned char bit_depth_chroma_minus8; /**< high bit depth Chroma */
|
||||
unsigned char reserved1; /**< Reserved for future use */
|
||||
unsigned int coded_width; /**< coded frame width */
|
||||
unsigned int coded_height; /**< coded frame height */
|
||||
/**
|
||||
* area of the frame that should be displayed
|
||||
* typical example:
|
||||
* coded_width = 1920, coded_height = 1088
|
||||
* display_area = { 0,0,1920,1080 }
|
||||
*/
|
||||
struct {
|
||||
int left; /**< left position of display rect */
|
||||
int top; /**< top position of display rect */
|
||||
int right; /**< right position of display rect */
|
||||
int bottom; /**< bottom position of display rect */
|
||||
} display_area;
|
||||
cudaVideoChromaFormat chroma_format; /**< Chroma format */
|
||||
unsigned int bitrate; /**< video bitrate (bps, 0=unknown) */
|
||||
/**
|
||||
* Display Aspect Ratio = x:y (4:3, 16:9, etc)
|
||||
*/
|
||||
struct {
|
||||
int x;
|
||||
int y;
|
||||
} display_aspect_ratio;
|
||||
/**
|
||||
* Video Signal Description
|
||||
*/
|
||||
struct {
|
||||
unsigned char video_format : 3;
|
||||
unsigned char video_full_range_flag : 1;
|
||||
unsigned char reserved_zero_bits : 4;
|
||||
unsigned char color_primaries;
|
||||
unsigned char transfer_characteristics;
|
||||
unsigned char matrix_coefficients;
|
||||
} video_signal_description;
|
||||
unsigned int seqhdr_data_length; /**< Additional bytes following (CUVIDEOFORMATEX) */
|
||||
} CUVIDEOFORMAT;
|
||||
|
||||
/*!
|
||||
* \struct CUVIDEOFORMATEX
|
||||
* Video format including raw sequence header information
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
CUVIDEOFORMAT format;
|
||||
unsigned char raw_seqhdr_data[1024];
|
||||
} CUVIDEOFORMATEX;
|
||||
|
||||
/*!
|
||||
* \struct CUAUDIOFORMAT
|
||||
* Audio Formats
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
cudaAudioCodec codec; /**< Compression format */
|
||||
unsigned int channels; /**< number of audio channels */
|
||||
unsigned int samplespersec; /**< sampling frequency */
|
||||
unsigned int bitrate; /**< For uncompressed, can also be used to determine bits per sample */
|
||||
unsigned int reserved1; /**< Reserved for future use */
|
||||
unsigned int reserved2; /**< Reserved for future use */
|
||||
} CUAUDIOFORMAT;
|
||||
|
||||
|
||||
/*!
|
||||
* \enum CUvideopacketflags
|
||||
* Data packet flags
|
||||
*/
|
||||
typedef enum {
|
||||
CUVID_PKT_ENDOFSTREAM = 0x01, /**< Set when this is the last packet for this stream */
|
||||
CUVID_PKT_TIMESTAMP = 0x02, /**< Timestamp is valid */
|
||||
CUVID_PKT_DISCONTINUITY = 0x04 /**< Set when a discontinuity has to be signalled */
|
||||
} CUvideopacketflags;
|
||||
|
||||
/*!
|
||||
* \struct CUVIDSOURCEDATAPACKET
|
||||
* Data Packet
|
||||
*/
|
||||
typedef struct _CUVIDSOURCEDATAPACKET
|
||||
{
|
||||
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;
|
||||
|
||||
// Callback for packet delivery
|
||||
typedef int (CUDAAPI *PFNVIDSOURCECALLBACK)(void *, CUVIDSOURCEDATAPACKET *);
|
||||
|
||||
/*!
|
||||
* \struct CUVIDSOURCEPARAMS
|
||||
* Source Params
|
||||
*/
|
||||
typedef struct _CUVIDSOURCEPARAMS
|
||||
{
|
||||
unsigned int ulClockRate; /**< Timestamp units in Hz (0=default=10000000Hz) */
|
||||
unsigned int uReserved1[7]; /**< Reserved for future use - set to zero */
|
||||
void *pUserData; /**< Parameter passed in to the data handlers */
|
||||
PFNVIDSOURCECALLBACK pfnVideoDataHandler; /**< Called to deliver audio packets */
|
||||
PFNVIDSOURCECALLBACK pfnAudioDataHandler; /**< Called to deliver video packets */
|
||||
void *pvReserved2[8]; /**< Reserved for future use - set to NULL */
|
||||
} CUVIDSOURCEPARAMS;
|
||||
|
||||
/*!
|
||||
* \enum CUvideosourceformat_flags
|
||||
* CUvideosourceformat_flags
|
||||
*/
|
||||
typedef enum {
|
||||
CUVID_FMT_EXTFORMATINFO = 0x100 /**< Return extended format structure (CUVIDEOFORMATEX) */
|
||||
} CUvideosourceformat_flags;
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidCreateVideoSource(CUvideosource *pObj, const char *pszFileName, CUVIDSOURCEPARAMS *pParams)
|
||||
* Create Video Source
|
||||
*/
|
||||
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
|
||||
*/
|
||||
CUresult CUDAAPI cuvidCreateVideoSourceW(CUvideosource *pObj, const wchar_t *pwszFileName, CUVIDSOURCEPARAMS *pParams);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidDestroyVideoSource(CUvideosource obj)
|
||||
* Destroy Video Source
|
||||
*/
|
||||
CUresult CUDAAPI cuvidDestroyVideoSource(CUvideosource obj);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidSetVideoSourceState(CUvideosource obj, cudaVideoState state)
|
||||
* Set Video Source state
|
||||
*/
|
||||
CUresult CUDAAPI cuvidSetVideoSourceState(CUvideosource obj, cudaVideoState state);
|
||||
|
||||
/**
|
||||
* \fn cudaVideoState CUDAAPI cuvidGetVideoSourceState(CUvideosource obj)
|
||||
* Get Video Source state
|
||||
*/
|
||||
cudaVideoState CUDAAPI cuvidGetVideoSourceState(CUvideosource obj);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidGetSourceVideoFormat(CUvideosource obj, CUVIDEOFORMAT *pvidfmt, unsigned int flags)
|
||||
* Get Video Source Format
|
||||
*/
|
||||
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
|
||||
*/
|
||||
CUresult CUDAAPI cuvidGetSourceAudioFormat(CUvideosource obj, CUAUDIOFORMAT *paudfmt, unsigned int flags);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \struct CUVIDPARSERDISPINFO
|
||||
*/
|
||||
typedef struct _CUVIDPARSERDISPINFO
|
||||
{
|
||||
int picture_index; /**< */
|
||||
int progressive_frame; /**< */
|
||||
int top_field_first; /**< */
|
||||
int repeat_first_field; /**< Number of additional fields (1=ivtc, 2=frame doubling, 4=frame tripling, -1=unpaired field) */
|
||||
CUvideotimestamp timestamp; /**< */
|
||||
} CUVIDPARSERDISPINFO;
|
||||
|
||||
//
|
||||
// Parser callbacks
|
||||
// The parser will call these synchronously from within cuvidParseVideoData(), whenever a picture is ready to
|
||||
// be decoded and/or displayed.
|
||||
//
|
||||
typedef int (CUDAAPI *PFNVIDSEQUENCECALLBACK)(void *, CUVIDEOFORMAT *);
|
||||
typedef int (CUDAAPI *PFNVIDDECODECALLBACK)(void *, CUVIDPICPARAMS *);
|
||||
typedef int (CUDAAPI *PFNVIDDISPLAYCALLBACK)(void *, CUVIDPARSERDISPINFO *);
|
||||
|
||||
/**
|
||||
* \struct CUVIDPARSERPARAMS
|
||||
*/
|
||||
typedef struct _CUVIDPARSERPARAMS
|
||||
{
|
||||
cudaVideoCodec CodecType; /**< cudaVideoCodec_XXX */
|
||||
unsigned int ulMaxNumDecodeSurfaces; /**< Max # of decode surfaces (parser will cycle through these) */
|
||||
unsigned int ulClockRate; /**< Timestamp units in Hz (0=default=10000000Hz) */
|
||||
unsigned int ulErrorThreshold; /**< % Error threshold (0-100) for calling pfnDecodePicture (100=always call pfnDecodePicture even if picture bitstream is fully corrupted) */
|
||||
unsigned int ulMaxDisplayDelay; /**< Max display queue delay (improves pipelining of decode with display) - 0=no delay (recommended values: 2..4) */
|
||||
unsigned int uReserved1[5]; /**< Reserved for future use - set to 0 */
|
||||
void *pUserData; /**< User data for callbacks */
|
||||
PFNVIDSEQUENCECALLBACK pfnSequenceCallback; /**< Called before decoding frames and/or whenever there is a format change */
|
||||
PFNVIDDECODECALLBACK pfnDecodePicture; /**< Called when a picture is ready to be decoded (decode order) */
|
||||
PFNVIDDISPLAYCALLBACK pfnDisplayPicture; /**< Called whenever a picture is ready to be displayed (display order) */
|
||||
void *pvReserved2[7]; /**< Reserved for future use - set to NULL */
|
||||
CUVIDEOFORMATEX *pExtVideoInfo; /**< [Optional] sequence header data from system layer */
|
||||
} CUVIDPARSERPARAMS;
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidCreateVideoParser(CUvideoparser *pObj, CUVIDPARSERPARAMS *pParams)
|
||||
*/
|
||||
CUresult CUDAAPI cuvidCreateVideoParser(CUvideoparser *pObj, CUVIDPARSERPARAMS *pParams);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidParseVideoData(CUvideoparser obj, CUVIDSOURCEDATAPACKET *pPacket)
|
||||
*/
|
||||
CUresult CUDAAPI cuvidParseVideoData(CUvideoparser obj, CUVIDSOURCEDATAPACKET *pPacket);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidDestroyVideoParser(CUvideoparser obj)
|
||||
*/
|
||||
CUresult CUDAAPI cuvidDestroyVideoParser(CUvideoparser obj);
|
||||
|
||||
/** @} */ /* END VIDEO_PARSER */
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif // __NVCUVID_H__
|
||||
|
||||
|
||||
@@ -1,47 +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
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define FUN(name, type, op) \
|
||||
type name(type x, type y) \
|
||||
{ \
|
||||
if (fpclassify(x) == FP_NAN) return y; \
|
||||
if (fpclassify(y) == FP_NAN) return x; \
|
||||
return x op y ? x : y; \
|
||||
}
|
||||
|
||||
FUN(fmin, double, <)
|
||||
FUN(fmax, double, >)
|
||||
FUN(fminf, float, <)
|
||||
FUN(fmaxf, float, >)
|
||||
|
||||
long double fmodl(long double x, long double y)
|
||||
{
|
||||
return fmod(x, y);
|
||||
}
|
||||
|
||||
long double scalbnl(long double x, int exp)
|
||||
{
|
||||
return scalbn(x, exp);
|
||||
}
|
||||
|
||||
long double copysignl(long double x, long double y)
|
||||
{
|
||||
return copysign(x, y);
|
||||
}
|
||||
@@ -1,25 +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
|
||||
*/
|
||||
|
||||
double fmin(double, double);
|
||||
double fmax(double, double);
|
||||
float fminf(float, float);
|
||||
float fmaxf(float, float);
|
||||
long double fmodl(long double, long double);
|
||||
long double scalbnl(long double, int);
|
||||
long double copysignl(long double, long double);
|
||||
@@ -59,7 +59,7 @@ int avpriv_vsnprintf(char *s, size_t n, const char *fmt,
|
||||
* recommends to provide _snprintf/_vsnprintf() a buffer size that
|
||||
* is one less than the actual buffer, and zero it before calling
|
||||
* _snprintf/_vsnprintf() to workaround this problem.
|
||||
* See https://web.archive.org/web/20151214111935/http://msdn.microsoft.com/en-us/library/1kt27hek(v=vs.80).aspx */
|
||||
* See http://msdn.microsoft.com/en-us/library/1kt27hek(v=vs.80).aspx */
|
||||
memset(s, 0, n);
|
||||
va_copy(ap_copy, ap);
|
||||
ret = _vsnprintf(s, n - 1, fmt, ap_copy);
|
||||
|
||||
3219
compat/nvenc/nvEncodeAPI.h
Normal file
3219
compat/nvenc/nvEncodeAPI.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2017 KO Myung-Hun <komh@chollian.net>
|
||||
* Copyright (c) 2011 KO Myung-Hun <komh@chollian.net>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
@@ -27,19 +27,15 @@
|
||||
#define COMPAT_OS2THREADS_H
|
||||
|
||||
#define INCL_DOS
|
||||
#define INCL_DOSERRORS
|
||||
#include <os2.h>
|
||||
|
||||
#undef __STRICT_ANSI__ /* for _beginthread() */
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/builtin.h>
|
||||
#include <sys/fmutex.h>
|
||||
|
||||
#include "libavutil/attributes.h"
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/time.h"
|
||||
|
||||
typedef struct {
|
||||
TID tid;
|
||||
@@ -50,11 +46,9 @@ typedef struct {
|
||||
|
||||
typedef void pthread_attr_t;
|
||||
|
||||
typedef _fmutex pthread_mutex_t;
|
||||
typedef HMTX pthread_mutex_t;
|
||||
typedef void pthread_mutexattr_t;
|
||||
|
||||
#define PTHREAD_MUTEX_INITIALIZER _FMUTEX_INITIALIZER
|
||||
|
||||
typedef struct {
|
||||
HEV event_sem;
|
||||
HEV ack_sem;
|
||||
@@ -104,28 +98,28 @@ static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
|
||||
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex,
|
||||
const pthread_mutexattr_t *attr)
|
||||
{
|
||||
_fmutex_create(mutex, 0);
|
||||
DosCreateMutexSem(NULL, (PHMTX)mutex, 0, FALSE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
|
||||
{
|
||||
_fmutex_close(mutex);
|
||||
DosCloseMutexSem(*(PHMTX)mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
|
||||
{
|
||||
_fmutex_request(mutex, 0);
|
||||
DosRequestMutexSem(*(PHMTX)mutex, SEM_INDEFINITE_WAIT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
|
||||
{
|
||||
_fmutex_release(mutex);
|
||||
DosReleaseMutexSem(*(PHMTX)mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -167,28 +161,6 @@ static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_cond_timedwait(pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
int64_t abs_milli = abstime->tv_sec * 1000LL + abstime->tv_nsec / 1000000;
|
||||
ULONG t = av_clip64(abs_milli - av_gettime() / 1000, 0, ULONG_MAX);
|
||||
|
||||
__atomic_increment(&cond->wait_count);
|
||||
|
||||
pthread_mutex_unlock(mutex);
|
||||
|
||||
APIRET ret = DosWaitEventSem(cond->event_sem, t);
|
||||
|
||||
__atomic_decrement(&cond->wait_count);
|
||||
|
||||
DosPostEventSem(cond->ack_sem);
|
||||
|
||||
pthread_mutex_lock(mutex);
|
||||
|
||||
return (ret == ERROR_TIMEOUT) ? ETIMEDOUT : 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex)
|
||||
{
|
||||
|
||||
10
compat/plan9/head
Executable file
10
compat/plan9/head
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
n=10
|
||||
|
||||
case "$1" in
|
||||
-n) n=$2; shift 2 ;;
|
||||
-n*) n=${1#-n}; shift ;;
|
||||
esac
|
||||
|
||||
exec sed ${n}q "$@"
|
||||
@@ -16,24 +16,19 @@
|
||||
* 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
|
||||
*/
|
||||
int plan9_main(int argc, char **argv);
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "stdatomic.h"
|
||||
|
||||
static pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
void avpriv_atomic_lock(void)
|
||||
#undef main
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
pthread_mutex_lock(&atomic_lock);
|
||||
}
|
||||
/* The setfcr() function in lib9 is broken, must use asm. */
|
||||
#ifdef __i386
|
||||
short fcr;
|
||||
__asm__ volatile ("fstcw %0 \n"
|
||||
"or $63, %0 \n"
|
||||
"fldcw %0 \n"
|
||||
: "=m"(fcr));
|
||||
#endif
|
||||
|
||||
void avpriv_atomic_unlock(void)
|
||||
{
|
||||
pthread_mutex_unlock(&atomic_lock);
|
||||
return plan9_main(argc, argv);
|
||||
}
|
||||
2
compat/plan9/printf
Executable file
2
compat/plan9/printf
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
exec awk "BEGIN { for (i = 2; i < ARGC; i++) printf \"$1\", ARGV[i] }" "$@"
|
||||
@@ -25,9 +25,9 @@
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
|
||||
static const char *check_nan_suffix(const char *s)
|
||||
static char *check_nan_suffix(char *s)
|
||||
{
|
||||
const char *start = s;
|
||||
char *start = s;
|
||||
|
||||
if (*s++ != '(')
|
||||
return start;
|
||||
@@ -44,7 +44,7 @@ double strtod(const char *, char **);
|
||||
|
||||
double avpriv_strtod(const char *nptr, char **endptr)
|
||||
{
|
||||
const char *end;
|
||||
char *end;
|
||||
double res;
|
||||
|
||||
/* Skip leading spaces */
|
||||
@@ -81,13 +81,13 @@ double avpriv_strtod(const char *nptr, char **endptr)
|
||||
!av_strncasecmp(nptr, "+0x", 3)) {
|
||||
/* FIXME this doesn't handle exponents, non-integers (float/double)
|
||||
* and numbers too large for long long */
|
||||
res = strtoll(nptr, (char **)&end, 16);
|
||||
res = strtoll(nptr, &end, 16);
|
||||
} else {
|
||||
res = strtod(nptr, (char **)&end);
|
||||
res = strtod(nptr, &end);
|
||||
}
|
||||
|
||||
if (endptr)
|
||||
*endptr = (char *)end;
|
||||
*endptr = end;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -16,13 +16,15 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVUTIL_MIPS_CPU_H
|
||||
#define AVUTIL_MIPS_CPU_H
|
||||
#ifndef COMPAT_TMS470_MATH_H
|
||||
#define COMPAT_TMS470_MATH_H
|
||||
|
||||
#include "libavutil/cpu.h"
|
||||
#include "libavutil/cpu_internal.h"
|
||||
#include_next <math.h>
|
||||
|
||||
#define have_mmi(flags) CPUEXT(flags, MMI)
|
||||
#define have_msa(flags) CPUEXT(flags, MSA)
|
||||
#undef INFINITY
|
||||
#undef NAN
|
||||
|
||||
#endif /* AVUTIL_MIPS_CPU_H */
|
||||
#define INFINITY (*(const float*)((const unsigned []){ 0x7f800000 }))
|
||||
#define NAN (*(const float*)((const unsigned []){ 0x7fc00000 }))
|
||||
|
||||
#endif /* COMPAT_TMS470_MATH_H */
|
||||
@@ -1,94 +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>
|
||||
#include "config.h"
|
||||
#if (_WIN32_WINNT < 0x0602) || HAVE_WINRT
|
||||
#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_calloc(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
|
||||
#if HAVE_WINRT
|
||||
wchar_t *name_w = NULL;
|
||||
int ret;
|
||||
if (utf8towchar(name, &name_w))
|
||||
return NULL;
|
||||
ret = LoadPackagedLibrary(name_w, 0);
|
||||
av_free(name_w);
|
||||
return ret;
|
||||
#else
|
||||
return LoadLibraryExA(name, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
#endif
|
||||
}
|
||||
#define dlopen(name, flags) win32_dlopen(name)
|
||||
#define dlclose FreeLibrary
|
||||
#define dlsym GetProcAddress
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#endif /* COMPAT_W32DLFCN_H */
|
||||
@@ -38,13 +38,16 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#include <time.h>
|
||||
|
||||
#if _WIN32_WINNT < 0x0600 && defined(__MINGW32__)
|
||||
#undef MemoryBarrier
|
||||
#define MemoryBarrier __sync_synchronize
|
||||
#endif
|
||||
|
||||
#include "libavutil/attributes.h"
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/internal.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/time.h"
|
||||
|
||||
typedef struct pthread_t {
|
||||
void *handle;
|
||||
@@ -53,22 +56,28 @@ typedef struct pthread_t {
|
||||
void *ret;
|
||||
} pthread_t;
|
||||
|
||||
/* use light weight mutex/condition variable API for Windows Vista and later */
|
||||
typedef SRWLOCK pthread_mutex_t;
|
||||
/* the conditional variable api for windows 6.0+ uses critical sections and
|
||||
* not mutexes */
|
||||
typedef CRITICAL_SECTION pthread_mutex_t;
|
||||
|
||||
/* This is the CONDITION_VARIABLE typedef for using Windows' native
|
||||
* conditional variables on kernels 6.0+. */
|
||||
#if HAVE_CONDITION_VARIABLE_PTR
|
||||
typedef CONDITION_VARIABLE pthread_cond_t;
|
||||
#else
|
||||
typedef struct pthread_cond_t {
|
||||
void *Ptr;
|
||||
} pthread_cond_t;
|
||||
#endif
|
||||
|
||||
#define PTHREAD_MUTEX_INITIALIZER SRWLOCK_INIT
|
||||
#define PTHREAD_COND_INITIALIZER CONDITION_VARIABLE_INIT
|
||||
|
||||
#if _WIN32_WINNT >= 0x0600
|
||||
#define InitializeCriticalSection(x) InitializeCriticalSectionEx(x, 0, 0)
|
||||
#define WaitForSingleObject(a, b) WaitForSingleObjectEx(a, b, FALSE)
|
||||
|
||||
#define PTHREAD_CANCEL_ENABLE 1
|
||||
#define PTHREAD_CANCEL_DISABLE 0
|
||||
#endif
|
||||
|
||||
static av_unused unsigned __stdcall attribute_align_arg win32thread_worker(void *arg)
|
||||
{
|
||||
pthread_t *h = (pthread_t*)arg;
|
||||
pthread_t *h = arg;
|
||||
h->ret = h->func(h->arg);
|
||||
return 0;
|
||||
}
|
||||
@@ -105,25 +114,26 @@ static av_unused int pthread_join(pthread_t thread, void **value_ptr)
|
||||
|
||||
static inline int pthread_mutex_init(pthread_mutex_t *m, void* attr)
|
||||
{
|
||||
InitializeSRWLock(m);
|
||||
InitializeCriticalSection(m);
|
||||
return 0;
|
||||
}
|
||||
static inline int pthread_mutex_destroy(pthread_mutex_t *m)
|
||||
{
|
||||
/* Unlocked SWR locks use no resources */
|
||||
DeleteCriticalSection(m);
|
||||
return 0;
|
||||
}
|
||||
static inline int pthread_mutex_lock(pthread_mutex_t *m)
|
||||
{
|
||||
AcquireSRWLockExclusive(m);
|
||||
EnterCriticalSection(m);
|
||||
return 0;
|
||||
}
|
||||
static inline int pthread_mutex_unlock(pthread_mutex_t *m)
|
||||
{
|
||||
ReleaseSRWLockExclusive(m);
|
||||
LeaveCriticalSection(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if _WIN32_WINNT >= 0x0600
|
||||
typedef INIT_ONCE pthread_once_t;
|
||||
#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
|
||||
|
||||
@@ -157,23 +167,7 @@ static inline int pthread_cond_broadcast(pthread_cond_t *cond)
|
||||
|
||||
static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
SleepConditionVariableSRW(cond, mutex, INFINITE, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
int64_t abs_milli = abstime->tv_sec * 1000LL + abstime->tv_nsec / 1000000;
|
||||
DWORD t = av_clip64(abs_milli - av_gettime() / 1000, 0, UINT32_MAX);
|
||||
|
||||
if (!SleepConditionVariableSRW(cond, mutex, t, 0)) {
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_TIMEOUT)
|
||||
return ETIMEDOUT;
|
||||
else
|
||||
return EINVAL;
|
||||
}
|
||||
SleepConditionVariableCS(cond, mutex, INFINITE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -183,9 +177,242 @@ static inline int pthread_cond_signal(pthread_cond_t *cond)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_setcancelstate(int state, int *oldstate)
|
||||
#else // _WIN32_WINNT < 0x0600
|
||||
|
||||
/* atomic init state of dynamically loaded functions */
|
||||
static LONG w32thread_init_state = 0;
|
||||
static av_unused void w32thread_init(void);
|
||||
|
||||
/* for pre-Windows 6.0 platforms, define INIT_ONCE struct,
|
||||
* compatible to the one used in the native API */
|
||||
|
||||
typedef union pthread_once_t {
|
||||
void * Ptr; ///< For the Windows 6.0+ native functions
|
||||
LONG state; ///< For the pre-Windows 6.0 compat code
|
||||
} pthread_once_t;
|
||||
|
||||
#define PTHREAD_ONCE_INIT {0}
|
||||
|
||||
/* function pointers to init once API on windows 6.0+ kernels */
|
||||
static BOOL (WINAPI *initonce_begin)(pthread_once_t *lpInitOnce, DWORD dwFlags, BOOL *fPending, void **lpContext);
|
||||
static BOOL (WINAPI *initonce_complete)(pthread_once_t *lpInitOnce, DWORD dwFlags, void *lpContext);
|
||||
|
||||
/* pre-Windows 6.0 compat using a spin-lock */
|
||||
static inline void w32thread_once_fallback(LONG volatile *state, void (*init_routine)(void))
|
||||
{
|
||||
switch (InterlockedCompareExchange(state, 1, 0)) {
|
||||
/* Initial run */
|
||||
case 0:
|
||||
init_routine();
|
||||
InterlockedExchange(state, 2);
|
||||
break;
|
||||
/* Another thread is running init */
|
||||
case 1:
|
||||
while (1) {
|
||||
MemoryBarrier();
|
||||
if (*state == 2)
|
||||
break;
|
||||
Sleep(0);
|
||||
}
|
||||
break;
|
||||
/* Initialization complete */
|
||||
case 2:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static av_unused int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
|
||||
{
|
||||
w32thread_once_fallback(&w32thread_init_state, w32thread_init);
|
||||
|
||||
/* Use native functions on Windows 6.0+ */
|
||||
if (initonce_begin && initonce_complete) {
|
||||
BOOL pending = FALSE;
|
||||
initonce_begin(once_control, 0, &pending, NULL);
|
||||
if (pending)
|
||||
init_routine();
|
||||
initonce_complete(once_control, 0, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
w32thread_once_fallback(&once_control->state, init_routine);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* for pre-Windows 6.0 platforms we need to define and use our own condition
|
||||
* variable and api */
|
||||
|
||||
typedef struct win32_cond_t {
|
||||
pthread_mutex_t mtx_broadcast;
|
||||
pthread_mutex_t mtx_waiter_count;
|
||||
volatile int waiter_count;
|
||||
HANDLE semaphore;
|
||||
HANDLE waiters_done;
|
||||
volatile int is_broadcast;
|
||||
} win32_cond_t;
|
||||
|
||||
/* function pointers to conditional variable API on windows 6.0+ kernels */
|
||||
static void (WINAPI *cond_broadcast)(pthread_cond_t *cond);
|
||||
static void (WINAPI *cond_init)(pthread_cond_t *cond);
|
||||
static void (WINAPI *cond_signal)(pthread_cond_t *cond);
|
||||
static BOOL (WINAPI *cond_wait)(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
DWORD milliseconds);
|
||||
|
||||
static av_unused int pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
|
||||
{
|
||||
win32_cond_t *win32_cond = NULL;
|
||||
|
||||
w32thread_once_fallback(&w32thread_init_state, w32thread_init);
|
||||
|
||||
if (cond_init) {
|
||||
cond_init(cond);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* non native condition variables */
|
||||
win32_cond = av_mallocz(sizeof(win32_cond_t));
|
||||
if (!win32_cond)
|
||||
return ENOMEM;
|
||||
cond->Ptr = win32_cond;
|
||||
win32_cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
|
||||
if (!win32_cond->semaphore)
|
||||
return ENOMEM;
|
||||
win32_cond->waiters_done = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!win32_cond->waiters_done)
|
||||
return ENOMEM;
|
||||
|
||||
pthread_mutex_init(&win32_cond->mtx_waiter_count, NULL);
|
||||
pthread_mutex_init(&win32_cond->mtx_broadcast, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_unused int pthread_cond_destroy(pthread_cond_t *cond)
|
||||
{
|
||||
win32_cond_t *win32_cond = cond->Ptr;
|
||||
/* native condition variables do not destroy */
|
||||
if (cond_init)
|
||||
return 0;
|
||||
|
||||
/* non native condition variables */
|
||||
CloseHandle(win32_cond->semaphore);
|
||||
CloseHandle(win32_cond->waiters_done);
|
||||
pthread_mutex_destroy(&win32_cond->mtx_waiter_count);
|
||||
pthread_mutex_destroy(&win32_cond->mtx_broadcast);
|
||||
av_freep(&win32_cond);
|
||||
cond->Ptr = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_unused int pthread_cond_broadcast(pthread_cond_t *cond)
|
||||
{
|
||||
win32_cond_t *win32_cond = cond->Ptr;
|
||||
int have_waiter;
|
||||
|
||||
if (cond_broadcast) {
|
||||
cond_broadcast(cond);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* non native condition variables */
|
||||
pthread_mutex_lock(&win32_cond->mtx_broadcast);
|
||||
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
|
||||
have_waiter = 0;
|
||||
|
||||
if (win32_cond->waiter_count) {
|
||||
win32_cond->is_broadcast = 1;
|
||||
have_waiter = 1;
|
||||
}
|
||||
|
||||
if (have_waiter) {
|
||||
ReleaseSemaphore(win32_cond->semaphore, win32_cond->waiter_count, NULL);
|
||||
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||
WaitForSingleObject(win32_cond->waiters_done, INFINITE);
|
||||
ResetEvent(win32_cond->waiters_done);
|
||||
win32_cond->is_broadcast = 0;
|
||||
} else
|
||||
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_unused int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
win32_cond_t *win32_cond = cond->Ptr;
|
||||
int last_waiter;
|
||||
if (cond_wait) {
|
||||
cond_wait(cond, mutex, INFINITE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* non native condition variables */
|
||||
pthread_mutex_lock(&win32_cond->mtx_broadcast);
|
||||
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
|
||||
win32_cond->waiter_count++;
|
||||
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
|
||||
|
||||
// unlock the external mutex
|
||||
pthread_mutex_unlock(mutex);
|
||||
WaitForSingleObject(win32_cond->semaphore, INFINITE);
|
||||
|
||||
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
|
||||
win32_cond->waiter_count--;
|
||||
last_waiter = !win32_cond->waiter_count || !win32_cond->is_broadcast;
|
||||
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||
|
||||
if (last_waiter)
|
||||
SetEvent(win32_cond->waiters_done);
|
||||
|
||||
// lock the external mutex
|
||||
return pthread_mutex_lock(mutex);
|
||||
}
|
||||
|
||||
static av_unused int pthread_cond_signal(pthread_cond_t *cond)
|
||||
{
|
||||
win32_cond_t *win32_cond = cond->Ptr;
|
||||
int have_waiter;
|
||||
if (cond_signal) {
|
||||
cond_signal(cond);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&win32_cond->mtx_broadcast);
|
||||
|
||||
/* non-native condition variables */
|
||||
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
|
||||
have_waiter = win32_cond->waiter_count;
|
||||
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||
|
||||
if (have_waiter) {
|
||||
ReleaseSemaphore(win32_cond->semaphore, 1, NULL);
|
||||
WaitForSingleObject(win32_cond->waiters_done, INFINITE);
|
||||
ResetEvent(win32_cond->waiters_done);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static av_unused void w32thread_init(void)
|
||||
{
|
||||
#if _WIN32_WINNT < 0x0600
|
||||
HANDLE kernel_dll = GetModuleHandle(TEXT("kernel32.dll"));
|
||||
/* if one is available, then they should all be available */
|
||||
cond_init =
|
||||
(void*)GetProcAddress(kernel_dll, "InitializeConditionVariable");
|
||||
cond_broadcast =
|
||||
(void*)GetProcAddress(kernel_dll, "WakeAllConditionVariable");
|
||||
cond_signal =
|
||||
(void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
|
||||
cond_wait =
|
||||
(void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
|
||||
initonce_begin =
|
||||
(void*)GetProcAddress(kernel_dll, "InitOnceBeginInitialize");
|
||||
initonce_complete =
|
||||
(void*)GetProcAddress(kernel_dll, "InitOnceComplete");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif /* COMPAT_W32PTHREADS_H */
|
||||
|
||||
@@ -45,11 +45,7 @@ libname=$(mktemp -u "library").lib
|
||||
|
||||
trap 'rm -f -- $libname' EXIT
|
||||
|
||||
if [ -n "$AR" ]; then
|
||||
$AR rcs ${libname} $@ >/dev/null
|
||||
else
|
||||
lib.exe -out:${libname} $@ >/dev/null
|
||||
fi
|
||||
lib -out:${libname} $@ >/dev/null
|
||||
if [ $? != 0 ]; then
|
||||
echo "Could not create temporary library." >&2
|
||||
exit 1
|
||||
@@ -58,7 +54,23 @@ fi
|
||||
IFS='
|
||||
'
|
||||
|
||||
prefix="$EXTERN_PREFIX"
|
||||
# Determine if we're building for x86 or x86_64 and
|
||||
# set the symbol prefix accordingly.
|
||||
prefix=""
|
||||
arch=$(dumpbin -headers ${libname} |
|
||||
tr '\t' ' ' |
|
||||
grep '^ \+.\+machine \+(.\+)' |
|
||||
head -1 |
|
||||
sed -e 's/^ \{1,\}.\{1,\} \{1,\}machine \{1,\}(\(...\)).*/\1/')
|
||||
|
||||
if [ "${arch}" = "x86" ]; then
|
||||
prefix="_"
|
||||
else
|
||||
if [ "${arch}" != "ARM" ] && [ "${arch}" != "x64" ]; then
|
||||
echo "Unknown machine type." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
started=0
|
||||
regex="none"
|
||||
@@ -100,19 +112,7 @@ for line in $(cat ${vscript} | tr '\t' ' '); do
|
||||
'
|
||||
done
|
||||
|
||||
if [ -n "$NM" ]; then
|
||||
# Use eval, since NM="nm -g"
|
||||
dump=$(eval "$NM --defined-only -g ${libname}" |
|
||||
grep -v : |
|
||||
grep -v ^$ |
|
||||
cut -d' ' -f3 |
|
||||
sed -e "s/^${prefix}//")
|
||||
else
|
||||
dump=$(dumpbin.exe -linkermember:1 ${libname} |
|
||||
sed -e '/public symbols/,$!d' -e '/^ \{1,\}Summary/,$d' -e "s/ \{1,\}${prefix}/ /" -e 's/ \{1,\}/ /g' |
|
||||
tail -n +2 |
|
||||
cut -d' ' -f3)
|
||||
fi
|
||||
dump=$(dumpbin -linkermember:1 ${libname})
|
||||
|
||||
rm ${libname}
|
||||
|
||||
@@ -121,6 +121,9 @@ list=""
|
||||
for exp in ${regex}; do
|
||||
list="${list}"'
|
||||
'$(echo "${dump}" |
|
||||
sed -e '/public symbols/,$!d' -e '/^ \{1,\}Summary/,$d' -e "s/ \{1,\}${prefix}/ /" -e 's/ \{1,\}/ /g' |
|
||||
tail -n +2 |
|
||||
cut -d' ' -f3 |
|
||||
grep "^${exp}" |
|
||||
sed -e 's/^/ /')
|
||||
done
|
||||
|
||||
@@ -4,6 +4,6 @@ LINK_EXE_PATH=$(dirname "$(command -v cl)")/link
|
||||
if [ -x "$LINK_EXE_PATH" ]; then
|
||||
"$LINK_EXE_PATH" $@
|
||||
else
|
||||
link.exe $@
|
||||
link $@
|
||||
fi
|
||||
exit $?
|
||||
|
||||
897
doc/APIchanges
897
doc/APIchanges
@@ -2,894 +2,19 @@ Never assume the API of libav* to be stable unless at least 1 month has passed
|
||||
since the last major version increase or the API was added.
|
||||
|
||||
The last version increases were:
|
||||
libavcodec: 2021-04-27
|
||||
libavdevice: 2021-04-27
|
||||
libavfilter: 2021-04-27
|
||||
libavformat: 2021-04-27
|
||||
libpostproc: 2021-04-27
|
||||
libswresample: 2021-04-27
|
||||
libswscale: 2021-04-27
|
||||
libavutil: 2021-04-27
|
||||
libavcodec: 2015-08-28
|
||||
libavdevice: 2015-08-28
|
||||
libavfilter: 2015-08-28
|
||||
libavformat: 2015-08-28
|
||||
libavresample: 2015-08-28
|
||||
libpostproc: 2015-08-28
|
||||
libswresample: 2015-08-28
|
||||
libswscale: 2015-08-28
|
||||
libavutil: 2015-08-28
|
||||
|
||||
|
||||
API changes, most recent first:
|
||||
|
||||
2022-01-04 - 78dc21b123e - lavu 57.16.100 - frame.h
|
||||
Add AV_FRAME_DATA_DOVI_METADATA.
|
||||
|
||||
2022-01-03 - 70f318e6b6c - lavf 59.13.100 - avformat.h
|
||||
Add AVFMT_EXPERIMENTAL flag.
|
||||
|
||||
2021-12-22 - b7e1ec7bda9 - lavu 57.13.100 - hwcontext_videotoolbox.h
|
||||
Add av_vt_pixbuf_set_attachments
|
||||
|
||||
2021-12-22 - 69bd95dcd8d - lavu 57.13.100 - hwcontext_videotoolbox.h
|
||||
Add av_map_videotoolbox_chroma_loc_from_av
|
||||
Add av_map_videotoolbox_color_matrix_from_av
|
||||
Add av_map_videotoolbox_color_primaries_from_av
|
||||
Add av_map_videotoolbox_color_trc_from_av
|
||||
|
||||
2021-12-21 - ffbab99f2c2 - lavu 57.12.100 - cpu.h
|
||||
Add AV_CPU_FLAG_SLOW_GATHER.
|
||||
|
||||
2021-12-20 - 278068dc60d - lavu 57.11.101 - display.h
|
||||
Modified the documentation of av_display_rotation_set()
|
||||
to match its longstanding actual behaviour of treating
|
||||
the angle as directed clockwise.
|
||||
|
||||
2021-12-12 - 64834bb86a1 - lavf 59.10.100 - avformat.h
|
||||
Add AVFormatContext io_close2 which returns an int
|
||||
|
||||
2021-12-10 - f45cbb775e4 - lavu 57.11.100 - hwcontext_vulkan.h
|
||||
Add AVVkFrame.offset and AVVulkanFramesContext.flags.
|
||||
|
||||
2021-12-04 - b9c928a486f - lavfi 8.19.100 - avfilter.h
|
||||
Add AVFILTER_FLAG_METADATA_ONLY.
|
||||
|
||||
2021-12-03 - b236ef0a594 - lavu 57.10.100 - frame.h
|
||||
Add AVFrame.time_base
|
||||
|
||||
2021-11-22 - b2cd1fb2ec6 - lavu 57.9.100 - pixfmt.h
|
||||
Add AV_PIX_FMT_P210, AV_PIX_FMT_P410, AV_PIX_FMT_P216, and AV_PIX_FMT_P416.
|
||||
|
||||
2021-11-17 - 54e65aa38ab - lavf 57.9.100 - frame.h
|
||||
Add AV_FRAME_DATA_DOVI_RPU_BUFFER.
|
||||
|
||||
2021-11-16 - ed75a08d36c - lavf 59.9.100 - avformat.h
|
||||
Add av_stream_get_class(). Schedule adding AVStream.av_class at libavformat
|
||||
major version 60.
|
||||
Add av_disposition_to_string() and av_disposition_from_string().
|
||||
Add "disposition" AVOption to AVStream's class.
|
||||
|
||||
2021-11-12 - 8478d60d5b5 - lavu 57.8.100 - hwcontext_vulkan.h
|
||||
Added AVVkFrame.sem_value, AVVulkanDeviceContext.queue_family_encode_index,
|
||||
nb_encode_queues, queue_family_decode_index, and nb_decode_queues.
|
||||
|
||||
2021-10-18 - 682bafdb125 - lavf 59.8.100 - avio.h
|
||||
Introduce public bytes_{read,written} statistic fields to AVIOContext.
|
||||
|
||||
2021-10-13 - a5622ed16f8 - lavf 59.7.100 - avio.h
|
||||
Deprecate AVIOContext.written. Originally added as a private entry in
|
||||
commit 3f75e5116b900f1428aa13041fc7d6301bf1988a, its grouping with
|
||||
the comment noting its private state was missed during merging of the field
|
||||
from Libav (most likely due to an already existing field in between).
|
||||
|
||||
2021-09-21 - 0760d9153c3 - lavu 57.7.100 - pixfmt.h
|
||||
Add AV_PIX_FMT_X2BGR10.
|
||||
|
||||
2021-09-20 - 8d5de914d31 - lavu 57.6.100 - mem.h
|
||||
Deprecate av_mallocz_array() as it is identical to av_calloc().
|
||||
|
||||
2021-09-20 - 176b8d785bf - lavc 59.9.100 - avcodec.h
|
||||
Deprecate AVCodecContext.sub_text_format and the corresponding
|
||||
AVOptions. It is unused since the last major bump.
|
||||
|
||||
2021-09-20 - dd846bc4a91 - lavc 59.8.100 - avcodec.h codec.h
|
||||
Deprecate AV_CODEC_FLAG_TRUNCATED and AV_CODEC_CAP_TRUNCATED,
|
||||
as they are redundant with parsers.
|
||||
|
||||
2021-09-17 - ccfdef79b13 - lavu 57.5.101 - buffer.h
|
||||
Constified the input parameters in av_buffer_replace(), av_buffer_ref(),
|
||||
and av_buffer_pool_buffer_get_opaque().
|
||||
|
||||
2021-09-08 - 4f78711f9c2 - lavu 57.5.100 - hwcontext_d3d11va.h
|
||||
Add AVD3D11VAFramesContext.texture_infos
|
||||
|
||||
2021-09-06 - 42cd64c1826 - lsws 6.1.100 - swscale.h
|
||||
Add AVFrame-based scaling API:
|
||||
- sws_scale_frame()
|
||||
- sws_frame_start()
|
||||
- sws_frame_end()
|
||||
- sws_send_slice()
|
||||
- sws_receive_slice()
|
||||
- sws_receive_slice_alignment()
|
||||
|
||||
2021-09-02 - cbf111059d2 - lavc 59.7.100 - avcodec.h
|
||||
Incremented the number of elements of AVCodecParser.codec_ids to seven.
|
||||
|
||||
2021-08-24 - 590a7e02f04 - lavc 59.6.100 - avcodec.h
|
||||
Add FF_CODEC_PROPERTY_FILM_GRAIN
|
||||
|
||||
2021-08-20 - 7c5f998196d - lavfi 8.3.100 - avfilter.H
|
||||
Add avfilter_filter_pad_count() as a replacement for avfilter_pad_count().
|
||||
Deprecate avfilter_pad_count().
|
||||
|
||||
2021-08-17 - 8c53b145993 - lavu 57.4.101 - opt.h
|
||||
av_opt_copy() now guarantees that allocated src and dst options
|
||||
don't alias each other even on error.
|
||||
|
||||
2021-08-14 - d5de9965ef6 - lavu 57.4.100 - imgutils.h
|
||||
Add av_image_copy_plane_uc_from()
|
||||
|
||||
2021-08-02 - a1a0fddfd05 - lavc 59.4.100 - packet.h
|
||||
Add AVPacket.opaque, AVPacket.opaque_ref, AVPacket.time_base.
|
||||
|
||||
2021-07-23 - 2dd8acbe800 - lavu 57.3.100 - common.h macros.h
|
||||
Move several macros (AV_NE, FFDIFFSIGN, FFMAX, FFMAX3, FFMIN, FFMIN3,
|
||||
FFSWAP, FF_ARRAY_ELEMS, MKTAG, MKBETAG) from common.h to macros.h.
|
||||
|
||||
2021-07-22 - e3b5ff17c2e - lavu 57.2.100 - film_grain_params.h
|
||||
Add AV_FILM_GRAIN_PARAMS_H274, AVFilmGrainH274Params
|
||||
|
||||
2021-07-19 - c1bf56a526f - lavu 57.1.100 - cpu.h
|
||||
Add av_cpu_force_count()
|
||||
|
||||
2021-06-17 - aca923b3653 - lavc 59.2.100 - packet.h
|
||||
Add AV_PKT_DATA_DYNAMIC_HDR10_PLUS
|
||||
|
||||
2021-06-09 - 2cccab96f6f - lavf 59.3.100 - avformat.h
|
||||
Add pts_wrap_bits to AVStream
|
||||
|
||||
2021-06-10 - 7c9763070d9 - lavc 59.1.100 - avcodec.h codec.h
|
||||
Move av_get_profile_name() from avcodec.h to codec.h.
|
||||
|
||||
2021-06-10 - bb3648e6766 - lavc 59.1.100 - avcodec.h codec_par.h
|
||||
Move av_get_audio_frame_duration2() from avcodec.h to codec_par.h.
|
||||
|
||||
2021-06-10 - 881db34f6a0 - lavc 59.1.100 - avcodec.h codec_id.h
|
||||
Move av_get_bits_per_sample(), av_get_exact_bits_per_sample(),
|
||||
avcodec_profile_name(), and av_get_pcm_codec() from avcodec.h
|
||||
to codec_id.h.
|
||||
|
||||
2021-06-10 - ff0a96046d8 - lavc 59.1.100 - avcodec.h defs.h
|
||||
Add new installed header defs.h. The following definitions are moved
|
||||
into it from avcodec.h:
|
||||
- AVDiscard
|
||||
- AVAudioServiceType
|
||||
- AVPanScan
|
||||
- AVCPBProperties and av_cpb_properties_alloc()
|
||||
- AVProducerReferenceTime
|
||||
- av_xiphlacing()
|
||||
|
||||
2021-04-27 - cb3ac722f4 - lavc 59.0.100 - avcodec.h
|
||||
Constified AVCodecParserContext.parser.
|
||||
|
||||
2021-04-27 - 8b3e6ce5f4 - lavd 59.0.100 - avdevice.h
|
||||
The av_*_device_next API functions now accept and return
|
||||
pointers to const AVInputFormat resp. AVOutputFormat.
|
||||
|
||||
2021-04-27 - d7e0d428fa - lavd 59.0.100 - avdevice.h
|
||||
avdevice_list_input_sources and avdevice_list_output_sinks now accept
|
||||
pointers to const AVInputFormat resp. const AVOutputFormat.
|
||||
|
||||
2021-04-27 - 46dac8cf3d - lavf 59.0.100 - avformat.h
|
||||
av_find_best_stream now uses a const AVCodec ** parameter
|
||||
for the returned decoder.
|
||||
|
||||
2021-04-27 - 626535f6a1 - lavc 59.0.100 - codec.h
|
||||
avcodec_find_encoder_by_name(), avcodec_find_encoder(),
|
||||
avcodec_find_decoder_by_name() and avcodec_find_decoder()
|
||||
now return a pointer to const AVCodec.
|
||||
|
||||
2021-04-27 - 14fa0a4efb - lavf 59.0.100 - avformat.h
|
||||
Constified AVFormatContext.*_codec.
|
||||
|
||||
2021-04-27 - 56450a0ee4 - lavf 59.0.100 - avformat.h
|
||||
Constified the pointers to AVInputFormats and AVOutputFormats
|
||||
in AVFormatContext, avformat_alloc_output_context2(),
|
||||
av_find_input_format(), av_probe_input_format(),
|
||||
av_probe_input_format2(), av_probe_input_format3(),
|
||||
av_probe_input_buffer2(), av_probe_input_buffer(),
|
||||
avformat_open_input(), av_guess_format() and av_guess_codec().
|
||||
Furthermore, constified the AVProbeData in av_probe_input_format(),
|
||||
av_probe_input_format2() and av_probe_input_format3().
|
||||
|
||||
2021-04-19 - 18af1ea8d1 - lavu 56.74.100 - tx.h
|
||||
Add AV_TX_FULL_IMDCT and AV_TX_UNALIGNED.
|
||||
|
||||
2021-04-17 - f1bf465aa0 - lavu 56.73.100 - frame.h detection_bbox.h
|
||||
Add AV_FRAME_DATA_DETECTION_BBOXES
|
||||
|
||||
2021-04-06 - 557953a397 - lavf 58.78.100 - avformat.h
|
||||
Add avformat_index_get_entries_count(), avformat_index_get_entry(),
|
||||
and avformat_index_get_entry_from_timestamp().
|
||||
|
||||
2021-03-21 - a77beea6c8 - lavu 56.72.100 - frame.h
|
||||
Deprecated av_get_colorspace_name().
|
||||
Use av_color_space_name() instead.
|
||||
|
||||
-------- 8< --------- FFmpeg 4.4 was cut here -------- 8< ---------
|
||||
|
||||
2021-03-19 - e8c0bca6bd - lavu 56.69.100 - adler32.h
|
||||
Added a typedef for the type of the Adler-32 checksums
|
||||
used by av_adler32_update(). It will be changed to uint32_t
|
||||
at the next major bump.
|
||||
The type of the parameter for the length of the input buffer
|
||||
will also be changed to size_t at the next major bump.
|
||||
|
||||
2021-03-19 - e318438f2f - lavf 58.75.100 - avformat.h
|
||||
AVChapter.id will be changed from int to int64_t
|
||||
on the next major version bump.
|
||||
|
||||
2021-03-17 - f7db77bd87 - lavc 58.133.100 - codec.h
|
||||
Deprecated av_init_packet(). Once removed, sizeof(AVPacket) will
|
||||
no longer be a part of the public ABI.
|
||||
Deprecated AVPacketList.
|
||||
|
||||
2021-03-16 - 7d09579190 - lavc 58.132.100 - codec.h
|
||||
Add AV_CODEC_CAP_OTHER_THREADS as a new name for
|
||||
AV_CODEC_CAP_AUTO_THREADS. AV_CODEC_CAP_AUTO_THREADS
|
||||
is now deprecated.
|
||||
|
||||
2021-03-12 - 6e7e3a3820 - lavc 58.131.100 - avcodec.h codec.h
|
||||
Add a get_encode_buffer callback to AVCodecContext, similar to
|
||||
get_buffer2 but for encoders.
|
||||
Add avcodec_default_get_encode_buffer().
|
||||
Add AV_GET_ENCODE_BUFFER_FLAG_REF.
|
||||
Encoders may now be flagged as AV_CODEC_CAP_DR1 capable.
|
||||
|
||||
2021-03-10 - 42e68fe015 - lavf 58.72.100 - avformat.h
|
||||
Change AVBufferRef related AVStream function and struct size
|
||||
parameter and fields type to size_t at next major bump.
|
||||
|
||||
2021-03-10 - d79e0fe65c - lavc 58.130.100 - packet.h
|
||||
Change AVBufferRef related AVPacket function and struct size
|
||||
parameter and fields type to size_t at next major bump.
|
||||
|
||||
2021-03-10 - 14040a1d91 - lavu 56.68.100 - buffer.h frame.h
|
||||
Change AVBufferRef and relevant AVFrame function and struct size
|
||||
parameter and fields type to size_t at next major bump.
|
||||
|
||||
2021-03-04 - a0eec776b6 - lavc 58.128.101 - avcodec.h
|
||||
Enable err_recognition to be set for encoders.
|
||||
|
||||
2021-03-03 - 2ff40b98ec - lavf 58.70.100 - avformat.h
|
||||
Deprecate AVFMT_FLAG_PRIV_OPT. It will do nothing
|
||||
as soon as av_demuxer_open() is removed.
|
||||
|
||||
2021-02-27 - dd9227e48f - lavc 58.126.100 - avcodec.h
|
||||
Deprecated avcodec_get_frame_class().
|
||||
|
||||
2021-02-21 - 5ca40d6d94 - lavu 56.66.100 - tx.h
|
||||
Add enum AVTXFlags and AVTXFlags.AV_TX_INPLACE
|
||||
|
||||
2021-02-14 - 4f49ca7bbc - lavd 58.12.100 - avdevice.h
|
||||
Deprecated avdevice_capabilities_create() and
|
||||
avdevice_capabilities_free().
|
||||
|
||||
2021-02-10 - 1bda9bb68a - lavu 56.65.100 - common.h
|
||||
Add FFABS64U()
|
||||
|
||||
2021-01-26 - 5dd9567080 - lavu 56.64.100 - common.h
|
||||
Add FFABSU()
|
||||
|
||||
2021-01-25 - 56709ca8aa - lavc 58.119.100 - avcodec.h
|
||||
Deprecate AVCodecContext.debug_mv, FF_DEBUG_VIS_MV_P_FOR, FF_DEBUG_VIS_MV_B_FOR,
|
||||
FF_DEBUG_VIS_MV_B_BACK
|
||||
|
||||
2021-01-11 - ebdd33086a - lavc 58.116.100 - avcodec.h
|
||||
Add FF_PROFILE_VVC_MAIN_10 and FF_PROFILE_VVC_MAIN_10_444.
|
||||
|
||||
2020-01-01 - baecaa16c1 - lavu 56.63.100 - video_enc_params.h
|
||||
Add AV_VIDEO_ENC_PARAMS_MPEG2
|
||||
|
||||
2020-12-03 - eca12f4d5a - lavu 56.62.100 - timecode.h
|
||||
Add av_timecode_init_from_components.
|
||||
|
||||
2020-11-27 - a83098ab03 - lavc 58.114.100 - avcodec.h
|
||||
Deprecate AVCodecContext.thread_safe_callbacks. Starting with
|
||||
LIBAVCODEC_VERSION_MAJOR=60, user callbacks must always be
|
||||
thread-safe when frame threading is used.
|
||||
|
||||
2020-11-25 - d243dd540a - lavc 58.113.100 - avcodec.h
|
||||
Adds a new flag AV_CODEC_EXPORT_DATA_FILM_GRAIN for export_side_data.
|
||||
|
||||
2020-11-25 - 4f9ee87253 - lavu 56.61.100 - film_grain_params.h
|
||||
Adds a new API for extracting codec film grain parameters as side data.
|
||||
Adds a new AVFrameSideDataType entry AV_FRAME_DATA_FILM_GRAIN_PARAMS for it.
|
||||
|
||||
2020-10-28 - f95d9510ff - lavf 58.64.100 - avformat.h
|
||||
Add AVSTREAM_EVENT_FLAG_NEW_PACKETS.
|
||||
|
||||
2020-09-28 - 68918d3b7f - lavu 56.60.100 - buffer.h
|
||||
Add a av_buffer_replace() convenience function.
|
||||
|
||||
2020-09-13 - 837b6eb90e - lavu 56.59.100 - timecode.h
|
||||
Add av_timecode_make_smpte_tc_string2.
|
||||
|
||||
2020-08-21 - 06f2651204 - lavu 56.58.100 - avstring.h
|
||||
Deprecate av_d2str(). Use av_asprintf() instead.
|
||||
|
||||
2020-08-04 - 34de0abbe7 - lavu 56.58.100 - channel_layout.h
|
||||
Add AV_CH_LAYOUT_22POINT2 together with its newly required pieces:
|
||||
AV_CH_TOP_SIDE_LEFT, AV_CH_TOP_SIDE_RIGHT, AV_CH_BOTTOM_FRONT_CENTER,
|
||||
AV_CH_BOTTOM_FRONT_LEFT, AV_CH_BOTTOM_FRONT_RIGHT.
|
||||
|
||||
2020-07-23 - 84655b7101 - lavu 56.57.100 - cpu.h
|
||||
Add AV_CPU_FLAG_MMI and AV_CPU_FLAG_MSA.
|
||||
|
||||
2020-07-22 - 3a8e927176 - lavu 56.56.100 - imgutils.h
|
||||
Add av_image_fill_plane_sizes().
|
||||
|
||||
2020-07-15 - 448a9aaa78 - lavc 58.96.100 - packet.h
|
||||
Add AV_PKT_DATA_S12M_TIMECODE.
|
||||
|
||||
2020-06-12 - b09fb030c1 - lavu 56.55.100 - pixdesc.h
|
||||
Add AV_PIX_FMT_X2RGB10.
|
||||
|
||||
2020-06-11 - bc8ab084fb - lavu 56.54.100 - frame.h
|
||||
Add AV_FRAME_DATA_SEI_UNREGISTERED.
|
||||
|
||||
2020-06-10 - 1b4a98b029 - lavu 56.53.100 - log.h opt.h
|
||||
Add av_opt_child_class_iterate() and AVClass.child_class_iterate().
|
||||
Deprecate av_opt_child_class_next() and AVClass.child_class_next().
|
||||
|
||||
-------- 8< --------- FFmpeg 4.3 was cut here -------- 8< ---------
|
||||
|
||||
2020-06-05 - ec39c2276a - lavu 56.50.100 - buffer.h
|
||||
Passing NULL as alloc argument to av_buffer_pool_init2() is now allowed.
|
||||
|
||||
2020-05-27 - ba6cada92e - lavc 58.88.100 - avcodec.h codec.h
|
||||
Move AVCodec-related public API to new header codec.h.
|
||||
|
||||
2020-05-23 - 064b875e89 - lavu 56.49.100 - video_enc_params.h
|
||||
Add AV_VIDEO_ENC_PARAMS_H264.
|
||||
|
||||
2020-05-23 - 2e08b39444 - lavu 56.48.100 - hwcontext.h
|
||||
Add av_hwdevice_ctx_create_derived_opts.
|
||||
|
||||
2020-05-23 - 6b65c4ec54 - lavu 56.47.100 - rational.h
|
||||
Add av_gcd_q().
|
||||
|
||||
2020-05-22 - af9e622776 - lavu 56.46.101 - opt.h
|
||||
Add AV_OPT_FLAG_CHILD_CONSTS.
|
||||
|
||||
2020-05-22 - 9d443c3e68 - lavc 58.87.100 - avcodec.h codec_par.h
|
||||
Move AVBitstreamFilter-related public API to new header bsf.h.
|
||||
Move AVCodecParameters-related public API to new header codec_par.h.
|
||||
|
||||
2020-05-21 - 13b1bbff0b - lavc 58.86.101 - avcodec.h
|
||||
Deprecated AV_CODEC_CAP_INTRA_ONLY and AV_CODEC_CAP_LOSSLESS.
|
||||
|
||||
2020-05-17 - 84af196c65 - lavu 56.46.100 - common.h
|
||||
Add av_sat_add64() and av_sat_sub64()
|
||||
|
||||
2020-05-12 - 991d417692 - lavu 56.45.100 - video_enc_params.h
|
||||
lavc 58.84.100 - avcodec.h
|
||||
Add a new API for exporting video encoding information.
|
||||
Replaces the deprecated API for exporting QP tables from decoders.
|
||||
Add AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS to request this information from
|
||||
decoders.
|
||||
|
||||
2020-05-10 - dccd07f66d - lavu 56.44.100 - hwcontext_vulkan.h
|
||||
Add enabled_inst_extensions, num_enabled_inst_extensions, enabled_dev_extensions
|
||||
and num_enabled_dev_extensions fields to AVVulkanDeviceContext
|
||||
|
||||
2020-04-22 - 0e1db79e37 - lavc 58.81.100 - packet.h
|
||||
- lavu 56.43.100 - dovi_meta.h
|
||||
Add AV_PKT_DATA_DOVI_CONF and AVDOVIDecoderConfigurationRecord.
|
||||
|
||||
2020-04-15 - 22b25b3ea5 - lavc 58.79.100 - avcodec.h
|
||||
Add formal support for calling avcodec_flush_buffers() on encoders.
|
||||
Encoders that set the cap AV_CODEC_CAP_ENCODER_FLUSH will be flushed.
|
||||
For all other encoders, the call is now a no-op rather than undefined
|
||||
behaviour.
|
||||
|
||||
2020-04-10 - 672946c7fe - lavc 58.78.100 - avcodec.h codec_desc.h codec_id.h packet.h
|
||||
Move AVCodecDesc-related public API to new header codec_desc.h.
|
||||
Move AVCodecID enum to new header codec_id.h.
|
||||
Move AVPacket-related public API to new header packet.h.
|
||||
|
||||
2020-03-29 - 4cb0dda555 - lavf 58.42.100 - avformat.h
|
||||
av_read_frame() now guarantees to handle uninitialized input packets
|
||||
and to return refcounted packets on success.
|
||||
|
||||
2020-03-27 - c52ec0367d - lavc 58.77.100 - avcodec.h
|
||||
av_packet_ref() now guarantees to return the destination packet
|
||||
in a blank state on error.
|
||||
|
||||
2020-03-10 - 05d27f342b - lavc 58.75.100 - avcodec.h
|
||||
Add AV_PKT_DATA_ICC_PROFILE.
|
||||
|
||||
2020-02-21 - d005a7cdfd - lavc 58.73.101 - avcodec.h
|
||||
Add AV_CODEC_EXPORT_DATA_PRFT.
|
||||
|
||||
2020-02-21 - c666689491 - lavc 58.73.100 - avcodec.h
|
||||
Add AVCodecContext.export_side_data and AV_CODEC_EXPORT_DATA_MVS.
|
||||
|
||||
2020-02-13 - e8f054b095 - lavu 56.41.100 - tx.h
|
||||
Add AV_TX_INT32_FFT and AV_TX_INT32_MDCT
|
||||
|
||||
2020-02-12 - 3182114f88 - lavu 56.40.100 - log.h
|
||||
Add av_log_once().
|
||||
|
||||
2020-02-04 - a88449ffb2 - lavu 56.39.100 - hwcontext.h
|
||||
Add AV_PIX_FMT_VULKAN
|
||||
Add AV_HWDEVICE_TYPE_VULKAN and implementation.
|
||||
|
||||
2020-01-30 - 27529eeb27 - lavf 58.37.100 - avio.h
|
||||
Add avio_protocol_get_class().
|
||||
|
||||
2020-01-15 - 717b2074ec - lavc 58.66.100 - avcodec.h
|
||||
Add AV_PKT_DATA_PRFT and AVProducerReferenceTime.
|
||||
|
||||
2019-12-27 - 45259a0ee4 - lavu 56.38.100 - eval.h
|
||||
Add av_expr_count_func().
|
||||
|
||||
2019-12-26 - 16685114d5 - lavu 56.37.100 - buffer.h
|
||||
Add av_buffer_pool_buffer_get_opaque().
|
||||
|
||||
2019-11-17 - 1c23abc88f - lavu 56.36.100 - eval API
|
||||
Add av_expr_count_vars().
|
||||
|
||||
2019-10-14 - f3746d31f9 - lavu 56.35.101 - opt.h
|
||||
Add AV_OPT_FLAG_RUNTIME_PARAM.
|
||||
|
||||
2019-09-25 - f8406ab4b9 - lavc 58.59.100 - avcodec.h
|
||||
Add max_samples
|
||||
|
||||
2019-09-04 - 2a9d461abc - lavu 56.35.100 - hwcontext_videotoolbox.h
|
||||
Add av_map_videotoolbox_format_from_pixfmt2() for full range pixfmt
|
||||
|
||||
2019-09-01 - 8821d1f56e - lavu 56.34.100 - pixfmt.h
|
||||
Add EBU Tech. 3213-E AVColorPrimaries value
|
||||
|
||||
2019-08-17 - 95fa73a2b4 - lavf 58.31.101 - avio.h
|
||||
4K limit removed from avio_printf.
|
||||
|
||||
2019-08-17 - a82f8f2f10 - lavf 58.31.100 - avio.h
|
||||
Add avio_print_string_array and avio_print.
|
||||
|
||||
2019-07-27 - 42e2319ba9 - lavu 56.33.100 - tx.h
|
||||
Add AV_TX_DOUBLE_FFT and AV_TX_DOUBLE_MDCT
|
||||
|
||||
-------- 8< --------- FFmpeg 4.2 was cut here -------- 8< ---------
|
||||
|
||||
2019-06-21 - a30e44098a - lavu 56.30.100 - frame.h
|
||||
Add FF_DECODE_ERROR_DECODE_SLICES
|
||||
|
||||
2019-06-14 - edfced8c04 - lavu 56.29.100 - frame.h
|
||||
Add FF_DECODE_ERROR_CONCEALMENT_ACTIVE
|
||||
|
||||
2019-05-15 - b79b29ddb1 - lavu 56.28.100 - tx.h
|
||||
Add av_tx_init(), av_tx_uninit() and related definitions.
|
||||
|
||||
2019-04-20 - 3153a6502a - lavc 58.52.100 - avcodec.h
|
||||
Add AV_CODEC_FLAG_DROPCHANGED to allow avcodec_receive_frame to drop
|
||||
frames whose parameters differ from first decoded frame in stream.
|
||||
|
||||
2019-04-12 - abfeba9724 - lavf 58.27.102
|
||||
Rename hls,applehttp demuxer to hls
|
||||
|
||||
2019-01-27 - 5bcefceec8 - lavc 58.46.100 - avcodec.h
|
||||
Add discard_damaged_percentage
|
||||
|
||||
2019-01-08 - 1ef4828276 - lavu 56.26.100 - frame.h
|
||||
Add AV_FRAME_DATA_REGIONS_OF_INTEREST
|
||||
|
||||
2018-12-21 - 2744d6b364 - lavu 56.25.100 - hdr_dynamic_metadata.h
|
||||
Add AV_FRAME_DATA_DYNAMIC_HDR_PLUS enum value, av_dynamic_hdr_plus_alloc(),
|
||||
av_dynamic_hdr_plus_create_side_data() functions, and related structs.
|
||||
|
||||
-------- 8< --------- FFmpeg 4.1 was cut here -------- 8< ---------
|
||||
|
||||
2018-10-27 - 718044dc19 - lavu 56.21.100 - pixdesc.h
|
||||
Add av_read_image_line2(), av_write_image_line2()
|
||||
|
||||
2018-10-24 - f9d4126f28 - lavu 56.20.100 - frame.h
|
||||
Add AV_FRAME_DATA_S12M_TIMECODE
|
||||
|
||||
2018-10-11 - f6d48b618a - lavc 58.33.100 - mediacodec.h
|
||||
Add av_mediacodec_render_buffer_at_time().
|
||||
|
||||
2018-09-09 - 35498c124a - lavc 58.29.100 - avcodec.h
|
||||
Add AV_PKT_DATA_AFD
|
||||
|
||||
2018-08-16 - b33f5299a5 - lavc 58.23.100 - avcodec.h
|
||||
Add av_bsf_flush().
|
||||
|
||||
2018-05-18 - 2b2f2f65f3 - lavf 58.15.100 - avformat.h
|
||||
Add pmt_version field to AVProgram
|
||||
|
||||
2018-05-17 - 5dfeb7f081 - lavf 58.14.100 - avformat.h
|
||||
Add AV_DISPOSITION_STILL_IMAGE
|
||||
|
||||
2018-05-10 - c855683427 - lavu 56.18.101 - hwcontext_cuda.h
|
||||
Add AVCUDADeviceContext.stream.
|
||||
|
||||
2018-04-30 - 56b081da57 - lavu 56.18.100 - pixdesc.h
|
||||
Add AV_PIX_FMT_FLAG_ALPHA to AV_PIX_FMT_PAL8.
|
||||
|
||||
2018-04-26 - 5be0410cb3 - lavu 56.17.100 - opt.h
|
||||
Add AV_OPT_FLAG_DEPRECATED.
|
||||
|
||||
2018-04-26 - 71fa82bed6 - lavu 56.16.100 - threadmessage.h
|
||||
Add av_thread_message_queue_nb_elems().
|
||||
|
||||
-------- 8< --------- FFmpeg 4.0 was cut here -------- 8< ---------
|
||||
|
||||
2018-04-03 - d6fc031caf - lavu 56.13.100 - pixdesc.h
|
||||
Deprecate AV_PIX_FMT_FLAG_PSEUDOPAL and make allocating a pseudo palette
|
||||
optional for API users (see AV_PIX_FMT_FLAG_PSEUDOPAL doxygen for details).
|
||||
|
||||
2018-04-01 - 860086ee16 - lavc 58.17.100 - avcodec.h
|
||||
Add av_packet_make_refcounted().
|
||||
|
||||
2018-04-01 - f1805d160d - lavfi 7.14.100 - avfilter.h
|
||||
Deprecate use of avfilter_register(), avfilter_register_all(),
|
||||
avfilter_next(). Add av_filter_iterate().
|
||||
|
||||
2018-03-25 - b7d0d912ef - lavc 58.16.100 - avcodec.h
|
||||
Add FF_SUB_CHARENC_MODE_IGNORE.
|
||||
|
||||
2018-03-23 - db2a7c947e - lavu 56.12.100 - encryption_info.h
|
||||
Add AVEncryptionInitInfo and AVEncryptionInfo structures to hold new side-data
|
||||
for encryption info.
|
||||
|
||||
2018-03-21 - f14ca60001 - lavc 58.15.100 - avcodec.h
|
||||
Add av_packet_make_writable().
|
||||
|
||||
2018-03-18 - 4b86ac27a0 - lavu 56.11.100 - frame.h
|
||||
Add AV_FRAME_DATA_QP_TABLE_PROPERTIES and AV_FRAME_DATA_QP_TABLE_DATA.
|
||||
|
||||
2018-03-15 - e0e72539cf - lavu 56.10.100 - opt.h
|
||||
Add AV_OPT_FLAG_BSF_PARAM
|
||||
|
||||
2018-03-07 - 950170bd3b - lavu 56.9.100 - crc.h
|
||||
Add AV_CRC_8_EBU crc variant.
|
||||
|
||||
2018-03-07 - 2a0eb86857 - lavc 58.14.100 - mediacodec.h
|
||||
Change the default behavior of avcodec_flush() on mediacodec
|
||||
video decoders. To restore the previous behavior, use the new
|
||||
delay_flush=1 option.
|
||||
|
||||
2018-03-01 - 6731f60598 - lavu 56.8.100 - frame.h
|
||||
Add av_frame_new_side_data_from_buf().
|
||||
|
||||
2018-02-15 - 8a8d0b319a
|
||||
Change av_ripemd_update(), av_murmur3_update() and av_hash_update() length
|
||||
parameter type to size_t at next major bump.
|
||||
|
||||
2018-02-12 - bcab11a1a2 - lavfi 7.12.100 - avfilter.h
|
||||
Add AVFilterContext.extra_hw_frames.
|
||||
|
||||
2018-02-12 - d23fff0d8a - lavc 58.11.100 - avcodec.h
|
||||
Add AVCodecContext.extra_hw_frames.
|
||||
|
||||
2018-02-06 - 0694d87024 - lavf 58.9.100 - avformat.h
|
||||
Deprecate use of av_register_input_format(), av_register_output_format(),
|
||||
av_register_all(), av_iformat_next(), av_oformat_next().
|
||||
Add av_demuxer_iterate(), and av_muxer_iterate().
|
||||
|
||||
2018-02-06 - 36c85d6e77 - lavc 58.10.100 - avcodec.h
|
||||
Deprecate use of avcodec_register(), avcodec_register_all(),
|
||||
av_codec_next(), av_register_codec_parser(), and av_parser_next().
|
||||
Add av_codec_iterate() and av_parser_iterate().
|
||||
|
||||
2018-02-04 - ff46124b0d - lavf 58.8.100 - avformat.h
|
||||
Deprecate the current names of the RTSP "timeout", "stimeout", "user-agent"
|
||||
options. Introduce "listen_timeout" as replacement for the current "timeout"
|
||||
option, and "user_agent" as replacement for "user-agent". Once the deprecation
|
||||
is over, the old "timeout" option will be removed, and "stimeout" will be
|
||||
renamed to "stimeout" (the "timeout" option will essentially change semantics).
|
||||
|
||||
2018-01-28 - ea3672b7d6 - lavf 58.7.100 - avformat.h
|
||||
Deprecate AVFormatContext filename field which had limited length, use the
|
||||
new dynamically allocated url field instead.
|
||||
|
||||
2018-01-28 - ea3672b7d6 - lavf 58.7.100 - avformat.h
|
||||
Add url field to AVFormatContext and add ff_format_set_url helper function.
|
||||
|
||||
2018-01-27 - 6194d7e564 - lavf 58.6.100 - avformat.h
|
||||
Add AVFMTCTX_UNSEEKABLE (for HLS demuxer).
|
||||
|
||||
2018-01-23 - 9f07cf7c00 - lavu 56.9.100 - aes_ctr.h
|
||||
Add method to set the 16-byte IV.
|
||||
|
||||
2018-01-16 - 631c56a8e4 - lavf 58.5.100 - avformat.h
|
||||
Explicitly make avformat_network_init() and avformat_network_deinit() optional.
|
||||
If these are not called, network initialization and deinitialization is
|
||||
automatic, and unlike in older versions, fully supported, unless libavformat
|
||||
is linked to ancient GnuTLS and OpenSSL.
|
||||
|
||||
2018-01-16 - 6512ff72f9 - lavf 58.4.100 - avformat.h
|
||||
Deprecate AVStream.recommended_encoder_configuration. It was useful only for
|
||||
FFserver, which has been removed.
|
||||
|
||||
2018-01-05 - 798dcf2432 - lavfi 7.11.101 - avfilter.h
|
||||
Deprecate avfilter_link_get_channels(). Use av_buffersink_get_channels().
|
||||
|
||||
2017-01-04 - c29038f304 - lavr 4.0.0 - avresample.h
|
||||
Deprecate the entire library. Merged years ago to provide compatibility
|
||||
with Libav, it remained unmaintained by the FFmpeg project and duplicated
|
||||
functionality provided by libswresample.
|
||||
|
||||
In order to improve consistency and reduce attack surface, it has been deprecated.
|
||||
Users of this library are asked to migrate to libswresample, which, as well as
|
||||
providing more functionality, is faster and has higher accuracy.
|
||||
|
||||
2017-12-26 - a04c2c707d - lavc 58.9.100 - avcodec.h
|
||||
Deprecate av_lockmgr_register(). You need to build FFmpeg with threading
|
||||
support enabled to get basic thread-safety (which is the default build
|
||||
configuration).
|
||||
|
||||
2017-12-24 - 8b81eabe57 - lavu 56.7.100 - cpu.h
|
||||
AVX-512 flags added.
|
||||
|
||||
2017-12-16 - 8bf4e6d3ce - lavc 58.8.100 - avcodec.h
|
||||
The MediaCodec decoders now support AVCodecContext.hw_device_ctx.
|
||||
|
||||
2017-12-16 - e4d9f05ca7 - lavu 56.6.100 - hwcontext.h hwcontext_mediacodec.h
|
||||
Add AV_HWDEVICE_TYPE_MEDIACODEC and a new installed header with
|
||||
MediaCodec-specific hwcontext definitions.
|
||||
|
||||
2017-12-14 - b945fed629 - lavc 58.7.100 - avcodec.h
|
||||
Add AV_CODEC_CAP_HARDWARE, AV_CODEC_CAP_HYBRID, and AVCodec.wrapper_name,
|
||||
and mark all AVCodecs accordingly.
|
||||
|
||||
2017-11-29 - d268094f88 - lavu 56.4.100 / 56.7.0 - stereo3d.h
|
||||
Add view field to AVStereo3D structure and AVStereo3DView enum.
|
||||
|
||||
2017-11-26 - 3a71bcc213 - lavc 58.6.100 - avcodec.h
|
||||
Add const to AVCodecContext.hwaccel.
|
||||
|
||||
2017-11-26 - 3536a3efb9 - lavc 58.5.100 - avcodec.h
|
||||
Deprecate user visibility of the AVHWAccel structure and the functions
|
||||
av_register_hwaccel() and av_hwaccel_next().
|
||||
|
||||
2017-11-26 - 24cc0a53e9 - lavc 58.4.100 - avcodec.h
|
||||
Add AVCodecHWConfig and avcodec_get_hw_config().
|
||||
|
||||
2017-11-22 - 3650cb2dfa - lavu 56.3.100 - opencl.h
|
||||
Remove experimental OpenCL API (av_opencl_*).
|
||||
|
||||
2017-11-22 - b25d8ef0a7 - lavu 56.2.100 - hwcontext.h hwcontext_opencl.h
|
||||
Add AV_HWDEVICE_TYPE_OPENCL and a new installed header with
|
||||
OpenCL-specific hwcontext definitions.
|
||||
|
||||
2017-11-22 - a050f56c09 - lavu 56.1.100 - pixfmt.h
|
||||
Add AV_PIX_FMT_OPENCL.
|
||||
|
||||
2017-11-11 - 48e4eda11d - lavc 58.3.100 - avcodec.h
|
||||
Add avcodec_get_hw_frames_parameters().
|
||||
|
||||
-------- 8< --------- FFmpeg 3.4 was cut here -------- 8< ---------
|
||||
|
||||
2017-09-28 - b6cf66ae1c - lavc 57.106.104 - avcodec.h
|
||||
Add AV_PKT_DATA_A53_CC packet side data, to export closed captions
|
||||
|
||||
2017-09-27 - 7aa6b8a68f - lavu 55.77.101 / lavu 55.31.1 - frame.h
|
||||
Allow passing the value of 0 (meaning "automatic") as the required alignment
|
||||
to av_frame_get_buffer().
|
||||
|
||||
2017-09-27 - 522f877086 - lavu 55.77.100 / lavu 55.31.0 - cpu.h
|
||||
Add av_cpu_max_align() for querying maximum required data alignment.
|
||||
|
||||
2017-09-26 - b1cf151c4d - lavc 57.106.102 - avcodec.h
|
||||
Deprecate AVCodecContext.refcounted_frames. This was useful for deprecated
|
||||
API only (avcodec_decode_video2/avcodec_decode_audio4). The new decode APIs
|
||||
(avcodec_send_packet/avcodec_receive_frame) always work with reference
|
||||
counted frames.
|
||||
|
||||
2017-09-21 - 6f15f1cdc8 - lavu 55.76.100 / 56.6.0 - pixdesc.h
|
||||
Add av_color_range_from_name(), av_color_primaries_from_name(),
|
||||
av_color_transfer_from_name(), av_color_space_from_name(), and
|
||||
av_chroma_location_from_name().
|
||||
|
||||
2017-09-13 - 82342cead1 - lavc 57.106.100 - avcodec.h
|
||||
Add AV_PKT_FLAG_TRUSTED.
|
||||
|
||||
2017-09-13 - 9cb23cd9fe - lavu 55.75.100 - hwcontext.h hwcontext_drm.h
|
||||
Add AV_HWDEVICE_TYPE_DRM and implementation.
|
||||
|
||||
2017-09-08 - 5ba2aef6ec - lavfi 6.103.100 - buffersrc.h
|
||||
Add av_buffersrc_close().
|
||||
|
||||
2017-09-04 - 6cadbb16e9 - lavc 57.105.100 - avcodec.h
|
||||
Add AV_HWACCEL_CODEC_CAP_EXPERIMENTAL, replacing the deprecated
|
||||
HWACCEL_CODEC_CAP_EXPERIMENTAL flag.
|
||||
|
||||
2017-09-01 - 5d76674756 - lavf 57.81.100 - avio.h
|
||||
Add avio_read_partial().
|
||||
|
||||
2017-09-01 - xxxxxxx - lavf 57.80.100 / 57.11.0 - avio.h
|
||||
Add avio_context_free(). From now on it must be used for freeing AVIOContext.
|
||||
|
||||
2017-08-08 - 1460408703 - lavu 55.74.100 - pixdesc.h
|
||||
Add AV_PIX_FMT_FLAG_FLOAT pixel format flag.
|
||||
|
||||
2017-08-08 - 463b81de2b - lavu 55.72.100 - imgutils.h
|
||||
Add av_image_fill_black().
|
||||
|
||||
2017-08-08 - caa12027ba - lavu 55.71.100 - frame.h
|
||||
Add av_frame_apply_cropping().
|
||||
|
||||
2017-07-25 - 24de4fddca - lavu 55.69.100 - frame.h
|
||||
Add AV_FRAME_DATA_ICC_PROFILE side data type.
|
||||
|
||||
2017-06-27 - 70143a3954 - lavc 57.100.100 - avcodec.h
|
||||
DXVA2 and D3D11 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. For D3D11,
|
||||
the new AV_PIX_FMT_D3D11 pixfmt must be used with the new API.
|
||||
|
||||
2017-06-27 - 3303511f33 - lavu 56.67.100 - hwcontext.h
|
||||
Add AV_HWDEVICE_TYPE_D3D11VA and AV_PIX_FMT_D3D11.
|
||||
|
||||
2017-06-24 - 09891c5391 - lavf 57.75.100 - avio.h
|
||||
Add AVIO_DATA_MARKER_FLUSH_POINT to signal preferred flush points to aviobuf.
|
||||
|
||||
2017-06-14 - d59c6a3aeb - lavu 55.66.100 - hwcontext.h
|
||||
av_hwframe_ctx_create_derived() now takes some AV_HWFRAME_MAP_* combination
|
||||
as its flags argument (which was previously unused).
|
||||
|
||||
2017-06-14 - 49ae8a5e87 - lavc 57.99.100 - avcodec.h
|
||||
Add AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH.
|
||||
|
||||
2017-06-14 - 0b1794a43e - lavu 55.65.100 - hwcontext.h
|
||||
Add AV_HWDEVICE_TYPE_NONE, av_hwdevice_find_type_by_name(),
|
||||
av_hwdevice_get_type_name() and av_hwdevice_iterate_types().
|
||||
|
||||
2017-06-14 - b22172f6f3 - lavu 55.64.100 - hwcontext.h
|
||||
Add av_hwdevice_ctx_create_derived().
|
||||
|
||||
2017-05-15 - 532b23f079 - lavc 57.96.100 - avcodec.h
|
||||
VideoToolbox hardware-accelerated decoding now supports the new hwaccel API,
|
||||
which can create the decoder context and allocate hardware frames automatically.
|
||||
See AVCodecContext.hw_device_ctx and AVCodecContext.hw_frames_ctx.
|
||||
|
||||
2017-05-15 - 532b23f079 - lavu 57.63.100 - hwcontext.h
|
||||
Add AV_HWDEVICE_TYPE_VIDEOTOOLBOX and implementation.
|
||||
|
||||
2017-05-08 - f089e02fa2 - lavc 57.95.100 / 57.31.0 - avcodec.h
|
||||
Add AVCodecContext.apply_cropping to control whether cropping
|
||||
is handled by libavcodec or the caller.
|
||||
|
||||
2017-05-08 - a47bd5d77e - lavu 55.62.100 / 55.30.0 - frame.h
|
||||
Add AVFrame.crop_left/right/top/bottom fields for attaching cropping
|
||||
information to video frames.
|
||||
|
||||
2017-xx-xx - xxxxxxxxxx
|
||||
Change av_sha_update(), av_sha512_update() and av_md5_sum()/av_md5_update() length
|
||||
parameter type to size_t at next major bump.
|
||||
|
||||
2017-05-05 - c0f17a905f - lavc 57.94.100 - avcodec.h
|
||||
The cuvid decoders now support AVCodecContext.hw_device_ctx, which removes
|
||||
the requirement to set an incomplete AVCodecContext.hw_frames_ctx only to
|
||||
set the Cuda device handle.
|
||||
|
||||
2017-04-11 - 8378466507 - lavu 55.61.100 - avstring.h
|
||||
Add av_strireplace().
|
||||
|
||||
2016-04-06 - 157e57a181 - lavc 57.92.100 - avcodec.h
|
||||
Add AV_PKT_DATA_CONTENT_LIGHT_LEVEL packet side data.
|
||||
|
||||
2016-04-06 - b378f5bd64 - lavu 55.60.100 - mastering_display_metadata.h
|
||||
Add AV_FRAME_DATA_CONTENT_LIGHT_LEVEL value, av_content_light_metadata_alloc()
|
||||
and av_content_light_metadata_create_side_data() API, and AVContentLightMetadata
|
||||
type to export content light level video properties.
|
||||
|
||||
2017-03-31 - 9033e8723c - lavu 55.57.100 - spherical.h
|
||||
Add av_spherical_projection_name().
|
||||
Add av_spherical_from_name().
|
||||
|
||||
2017-03-30 - 4cda23f1f1 - 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 - fc9f14c7de - 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 - 8200b16a9c - 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 - 1b7ffddb3a - 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 - 2eab48177d - 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 - f542b152aa - lavu 55.43.100 - imgutils.h
|
||||
Add av_image_check_size2()
|
||||
|
||||
2016-12-07 - e7a6f8c972 - lavc 57.67.100 / 57.29.0 - avcodec.h
|
||||
Add AV_PKT_DATA_SPHERICAL packet side data to export AVSphericalMapping
|
||||
information from containers.
|
||||
|
||||
2016-12-07 - 8f58ecc344 - 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
|
||||
@@ -1390,7 +515,7 @@ API changes, most recent first:
|
||||
Add av_opt_get_dict_val/set_dict_val with AV_OPT_TYPE_DICT to support
|
||||
dictionary types being set as options.
|
||||
|
||||
2014-08-13 - afbd4b7e09 - lavf 56.01.0 - avformat.h
|
||||
2014-08-13 - afbd4b8 - lavf 56.01.0 - avformat.h
|
||||
Add AVFormatContext.event_flags and AVStream.event_flags for signaling to
|
||||
the user when events happen in the file/stream.
|
||||
|
||||
@@ -1407,7 +532,7 @@ API changes, most recent first:
|
||||
2014-08-08 - 5c3c671 - lavf 55.53.100 - avio.h
|
||||
Add avio_feof() and deprecate url_feof().
|
||||
|
||||
2014-08-07 - bb789016d4 - lsws 2.1.3 - swscale.h
|
||||
2014-08-07 - bb78903 - lsws 2.1.3 - swscale.h
|
||||
sws_getContext is not going to be removed in the future.
|
||||
|
||||
2014-08-07 - a561662 / ad1ee5f - lavc 55.73.101 / 55.57.3 - avcodec.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 = 5.0.1
|
||||
PROJECT_NUMBER = 3.2.10
|
||||
|
||||
# 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
|
||||
|
||||
41
doc/Makefile
41
doc/Makefile
@@ -24,7 +24,6 @@ HTMLPAGES = $(AVPROGS-yes:%=doc/%.html) $(AVPROGS-yes:%=doc/%-all.html) $(COMP
|
||||
doc/fate.html \
|
||||
doc/general.html \
|
||||
doc/git-howto.html \
|
||||
doc/mailing-list-faq.html \
|
||||
doc/nut.html \
|
||||
doc/platform.html \
|
||||
|
||||
@@ -37,6 +36,30 @@ DOCS-$(CONFIG_MANPAGES) += $(MANPAGES)
|
||||
DOCS-$(CONFIG_TXTPAGES) += $(TXTPAGES)
|
||||
DOCS = $(DOCS-yes)
|
||||
|
||||
DOC_EXAMPLES-$(CONFIG_AVIO_DIR_CMD_EXAMPLE) += avio_dir_cmd
|
||||
DOC_EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading
|
||||
DOC_EXAMPLES-$(CONFIG_DECODING_ENCODING_EXAMPLE) += decoding_encoding
|
||||
DOC_EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
|
||||
DOC_EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE) += extract_mvs
|
||||
DOC_EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio
|
||||
DOC_EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE) += filtering_audio
|
||||
DOC_EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE) += filtering_video
|
||||
DOC_EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE) += http_multiclient
|
||||
DOC_EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata
|
||||
DOC_EXAMPLES-$(CONFIG_MUXING_EXAMPLE) += muxing
|
||||
DOC_EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec
|
||||
DOC_EXAMPLES-$(CONFIG_REMUXING_EXAMPLE) += remuxing
|
||||
DOC_EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio
|
||||
DOC_EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
|
||||
DOC_EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
|
||||
DOC_EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE) += transcoding
|
||||
ALL_DOC_EXAMPLES_LIST = $(DOC_EXAMPLES-) $(DOC_EXAMPLES-yes)
|
||||
|
||||
DOC_EXAMPLES := $(DOC_EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
|
||||
ALL_DOC_EXAMPLES := $(ALL_DOC_EXAMPLES_LIST:%=doc/examples/%$(PROGSSUF)$(EXESUF))
|
||||
ALL_DOC_EXAMPLES_G := $(ALL_DOC_EXAMPLES_LIST:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
|
||||
PROGS += $(DOC_EXAMPLES)
|
||||
|
||||
all-$(CONFIG_DOC): doc
|
||||
|
||||
doc: documentation
|
||||
@@ -44,6 +67,8 @@ doc: documentation
|
||||
apidoc: doc/doxy/html
|
||||
documentation: $(DOCS)
|
||||
|
||||
examples: $(DOC_EXAMPLES)
|
||||
|
||||
TEXIDEP = perl $(SRC_PATH)/doc/texidep.pl $(SRC_PATH) $< $@ >$(@:%=%.d)
|
||||
|
||||
doc/%.txt: TAG = TXT
|
||||
@@ -96,13 +121,15 @@ doc/%.3: doc/%.pod $(GENTEXI)
|
||||
$(M)pod2man --section=3 --center=" " --release=" " --date=" " $< > $@
|
||||
|
||||
$(DOCS) doc/doxy/html: | doc/
|
||||
$(DOC_EXAMPLES:%$(EXESUF)=%.o): | doc/examples
|
||||
OBJDIRS += doc/examples
|
||||
|
||||
DOXY_INPUT = $(INSTHEADERS)
|
||||
DOXY_INPUT_DEPS = $(addprefix $(SRC_PATH)/, $(DOXY_INPUT)) ffbuild/config.mak
|
||||
DOXY_INPUT = $(INSTHEADERS) $(DOC_EXAMPLES:%$(EXESUF)=%.c) $(LIB_EXAMPLES:%$(EXESUF)=%.c)
|
||||
DOXY_INPUT_DEPS = $(addprefix $(SRC_PATH)/, $(DOXY_INPUT)) config.mak
|
||||
|
||||
doc/doxy/html: TAG = DOXY
|
||||
doc/doxy/html: $(SRC_PATH)/doc/Doxyfile $(SRC_PATH)/doc/doxy-wrapper.sh $(DOXY_INPUT_DEPS)
|
||||
$(M)$(SRC_PATH)/doc/doxy-wrapper.sh $$PWD/doc/doxy $(SRC_PATH) doc/Doxyfile $(DOXYGEN) $(DOXY_INPUT);
|
||||
$(M)OUT_DIR=$$PWD/doc/doxy; cd $(SRC_PATH); ./doc/doxy-wrapper.sh $$OUT_DIR $< $(DOXYGEN) $(DOXY_INPUT);
|
||||
|
||||
install-doc: install-html install-man
|
||||
|
||||
@@ -144,7 +171,11 @@ clean:: docclean
|
||||
distclean:: docclean
|
||||
$(RM) doc/config.texi
|
||||
|
||||
docclean::
|
||||
examplesclean:
|
||||
$(RM) $(ALL_DOC_EXAMPLES) $(ALL_DOC_EXAMPLES_G)
|
||||
$(RM) $(CLEANSUFFIXES:%=doc/examples/%)
|
||||
|
||||
docclean: examplesclean
|
||||
$(RM) $(CLEANSUFFIXES:%=doc/%)
|
||||
$(RM) $(TXTPAGES) doc/*.html doc/*.pod doc/*.1 doc/*.3 doc/avoptions_*.texi
|
||||
$(RM) -r doc/doxy/html
|
||||
|
||||
@@ -26,101 +26,36 @@ 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.
|
||||
|
||||
@section av1_metadata
|
||||
|
||||
Modify metadata embedded in an AV1 stream.
|
||||
|
||||
@table @option
|
||||
@item td
|
||||
Insert or remove temporal delimiter OBUs in all temporal units of the
|
||||
stream.
|
||||
|
||||
@table @samp
|
||||
@item insert
|
||||
Insert a TD at the beginning of every TU which does not already have one.
|
||||
@item remove
|
||||
Remove the TD from the beginning of every TU which has one.
|
||||
@end table
|
||||
|
||||
@item color_primaries
|
||||
@item transfer_characteristics
|
||||
@item matrix_coefficients
|
||||
Set the color description fields in the stream (see AV1 section 6.4.2).
|
||||
|
||||
@item color_range
|
||||
Set the color range in the stream (see AV1 section 6.4.2; note that
|
||||
this cannot be set for streams using BT.709 primaries, sRGB transfer
|
||||
characteristic and identity (RGB) matrix coefficients).
|
||||
@table @samp
|
||||
@item tv
|
||||
Limited range.
|
||||
@item pc
|
||||
Full range.
|
||||
@end table
|
||||
|
||||
@item chroma_sample_position
|
||||
Set the chroma sample location in the stream (see AV1 section 6.4.2).
|
||||
This can only be set for 4:2:0 streams.
|
||||
|
||||
@table @samp
|
||||
@item vertical
|
||||
Left position (matching the default in MPEG-2 and H.264).
|
||||
@item colocated
|
||||
Top-left position.
|
||||
@end table
|
||||
|
||||
@item tick_rate
|
||||
Set the tick rate (@emph{time_scale / num_units_in_display_tick}) in
|
||||
the timing info in the sequence header.
|
||||
@item num_ticks_per_picture
|
||||
Set the number of ticks in each picture, to indicate that the stream
|
||||
has a fixed framerate. Ignored if @option{tick_rate} is not also set.
|
||||
|
||||
@item delete_padding
|
||||
Deletes Padding OBUs.
|
||||
|
||||
@end table
|
||||
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 except when
|
||||
said packets already exactly begin with the extradata that is intended
|
||||
to be added.
|
||||
Add extradata to the beginning of the filtered packets.
|
||||
|
||||
@table @option
|
||||
@item freq
|
||||
The additional argument specifies which packets should be filtered.
|
||||
It accepts the values:
|
||||
@table @samp
|
||||
@item a
|
||||
add extradata to all key packets, but only if @var{local_header} is
|
||||
set in the @option{flags2} codec context field
|
||||
|
||||
@item k
|
||||
@item keyframe
|
||||
add extradata to all key packets
|
||||
|
||||
@item e
|
||||
@item all
|
||||
add extradata to all packets
|
||||
@end table
|
||||
@end table
|
||||
|
||||
If not specified it is assumed @samp{k}.
|
||||
|
||||
@@ -132,165 +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 eac3_core
|
||||
@section dca_core
|
||||
|
||||
Extract the core from a E-AC-3 stream, dropping extra channels.
|
||||
|
||||
@section extract_extradata
|
||||
|
||||
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
|
||||
|
||||
@section filter_units
|
||||
|
||||
Remove units with types in or not in a given set from the stream.
|
||||
|
||||
@table @option
|
||||
@item pass_types
|
||||
List of unit types or ranges of unit types to pass through while removing
|
||||
all others. This is specified as a '|'-separated list of unit type values
|
||||
or ranges of values with '-'.
|
||||
|
||||
@item remove_types
|
||||
Identical to @option{pass_types}, except the units in the given set
|
||||
removed and all others passed through.
|
||||
@end table
|
||||
|
||||
Extradata is unchanged by this transformation, but note that if the stream
|
||||
contains inline parameter sets then the output may be unusable if they are
|
||||
removed.
|
||||
|
||||
For example, to remove all non-VCL NAL units from an H.264 stream:
|
||||
@example
|
||||
ffmpeg -i INPUT -c:v copy -bsf:v 'filter_units=pass_types=1-5' OUTPUT
|
||||
@end example
|
||||
|
||||
To remove all AUDs, SEI and filler from an H.265 stream:
|
||||
@example
|
||||
ffmpeg -i INPUT -c:v copy -bsf:v 'filter_units=remove_types=35|38-40' OUTPUT
|
||||
@end example
|
||||
|
||||
@section hapqa_extract
|
||||
|
||||
Extract Rgb or Alpha part of an HAPQA file, without recompression, in order to create an HAPQ or an HAPAlphaOnly file.
|
||||
|
||||
@table @option
|
||||
@item texture
|
||||
Specifies the texture to keep.
|
||||
|
||||
@table @option
|
||||
@item color
|
||||
@item alpha
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
Convert HAPQA to HAPQ
|
||||
@example
|
||||
ffmpeg -i hapqa_inputfile.mov -c copy -bsf:v hapqa_extract=texture=color -tag:v HapY -metadata:s:v:0 encoder="HAPQ" hapq_file.mov
|
||||
@end example
|
||||
|
||||
Convert HAPQA to HAPAlphaOnly
|
||||
@example
|
||||
ffmpeg -i hapqa_inputfile.mov -c copy -bsf:v hapqa_extract=texture=alpha -tag:v HapA -metadata:s:v:0 encoder="HAPAlpha Only" hapalphaonly_file.mov
|
||||
@end example
|
||||
|
||||
@section h264_metadata
|
||||
|
||||
Modify metadata embedded in an H.264 stream.
|
||||
|
||||
@table @option
|
||||
@item aud
|
||||
Insert or remove AUD NAL units in all access units of the stream.
|
||||
|
||||
@table @samp
|
||||
@item insert
|
||||
@item remove
|
||||
@end table
|
||||
|
||||
@item sample_aspect_ratio
|
||||
Set the sample aspect ratio of the stream in the VUI parameters.
|
||||
|
||||
@item overscan_appropriate_flag
|
||||
Set whether the stream is suitable for display using overscan
|
||||
or not (see H.264 section E.2.1).
|
||||
|
||||
@item video_format
|
||||
@item video_full_range_flag
|
||||
Set the video format in the stream (see H.264 section E.2.1 and
|
||||
table E-2).
|
||||
|
||||
@item colour_primaries
|
||||
@item transfer_characteristics
|
||||
@item matrix_coefficients
|
||||
Set the colour description in the stream (see H.264 section E.2.1
|
||||
and tables E-3, E-4 and E-5).
|
||||
|
||||
@item chroma_sample_loc_type
|
||||
Set the chroma sample location in the stream (see H.264 section
|
||||
E.2.1 and figure E-1).
|
||||
|
||||
@item tick_rate
|
||||
Set the tick rate (time_scale / num_units_in_tick) in the VUI
|
||||
parameters. This is the smallest time unit representable in the
|
||||
stream, and in many cases represents the field rate of the stream
|
||||
(double the frame rate).
|
||||
@item fixed_frame_rate_flag
|
||||
Set whether the stream has fixed framerate - typically this indicates
|
||||
that the framerate is exactly half the tick rate, but the exact
|
||||
meaning is dependent on interlacing and the picture structure (see
|
||||
H.264 section E.2.1 and table E-6).
|
||||
@item zero_new_constraint_set_flags
|
||||
Zero constraint_set4_flag and constraint_set5_flag in the SPS. These
|
||||
bits were reserved in a previous version of the H.264 spec, and thus
|
||||
some hardware decoders require these to be zero. The result of zeroing
|
||||
this is still a valid bitstream.
|
||||
|
||||
@item crop_left
|
||||
@item crop_right
|
||||
@item crop_top
|
||||
@item crop_bottom
|
||||
Set the frame cropping offsets in the SPS. These values will replace
|
||||
the current ones if the stream is already cropped.
|
||||
|
||||
These fields are set in pixels. Note that some sizes may not be
|
||||
representable if the chroma is subsampled or the stream is interlaced
|
||||
(see H.264 section 7.4.2.1.1).
|
||||
|
||||
@item sei_user_data
|
||||
Insert a string as SEI unregistered user data. The argument must
|
||||
be of the form @emph{UUID+string}, where the UUID is as hex digits
|
||||
possibly separated by hyphens, and the string can be anything.
|
||||
|
||||
For example, @samp{086f3693-b7b3-4f2c-9653-21492feee5b8+hello} will
|
||||
insert the string ``hello'' associated with the given UUID.
|
||||
|
||||
@item delete_filler
|
||||
Deletes both filler NAL units and filler SEI messages.
|
||||
|
||||
@item level
|
||||
Set the level in the SPS. Refer to H.264 section A.3 and tables A-1
|
||||
to A-5.
|
||||
|
||||
The argument must be the name of a level (for example, @samp{4.2}), a
|
||||
level_idc value (for example, @samp{42}), or the special name @samp{auto}
|
||||
indicating that the filter should attempt to guess the level from the
|
||||
input stream properties.
|
||||
|
||||
@end table
|
||||
Extract DCA core from DTS-HD streams.
|
||||
|
||||
@section h264_mp4toannexb
|
||||
|
||||
@@ -299,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:
|
||||
@@ -308,101 +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 h264_redundant_pps
|
||||
|
||||
This applies a specific fixup to some Blu-ray streams which contain
|
||||
redundant PPSs modifying irrelevant parameters of the stream which
|
||||
confuse other transformations which require correct extradata.
|
||||
|
||||
A new single global PPS is created, and all of the redundant PPSs
|
||||
within the stream are removed.
|
||||
|
||||
@section hevc_metadata
|
||||
|
||||
Modify metadata embedded in an HEVC stream.
|
||||
|
||||
@table @option
|
||||
@item aud
|
||||
Insert or remove AUD NAL units in all access units of the stream.
|
||||
|
||||
@table @samp
|
||||
@item insert
|
||||
@item remove
|
||||
@end table
|
||||
|
||||
@item sample_aspect_ratio
|
||||
Set the sample aspect ratio in the stream in the VUI parameters.
|
||||
|
||||
@item video_format
|
||||
@item video_full_range_flag
|
||||
Set the video format in the stream (see H.265 section E.3.1 and
|
||||
table E.2).
|
||||
|
||||
@item colour_primaries
|
||||
@item transfer_characteristics
|
||||
@item matrix_coefficients
|
||||
Set the colour description in the stream (see H.265 section E.3.1
|
||||
and tables E.3, E.4 and E.5).
|
||||
|
||||
@item chroma_sample_loc_type
|
||||
Set the chroma sample location in the stream (see H.265 section
|
||||
E.3.1 and figure E.1).
|
||||
|
||||
@item tick_rate
|
||||
Set the tick rate in the VPS and VUI parameters (time_scale /
|
||||
num_units_in_tick). Combined with @option{num_ticks_poc_diff_one}, this can
|
||||
set a constant framerate in the stream. Note that it is likely to be
|
||||
overridden by container parameters when the stream is in a container.
|
||||
|
||||
@item num_ticks_poc_diff_one
|
||||
Set poc_proportional_to_timing_flag in VPS and VUI and use this value
|
||||
to set num_ticks_poc_diff_one_minus1 (see H.265 sections 7.4.3.1 and
|
||||
E.3.1). Ignored if @option{tick_rate} is not also set.
|
||||
|
||||
@item crop_left
|
||||
@item crop_right
|
||||
@item crop_top
|
||||
@item crop_bottom
|
||||
Set the conformance window cropping offsets in the SPS. These values
|
||||
will replace the current ones if the stream is already cropped.
|
||||
|
||||
These fields are set in pixels. Note that some sizes may not be
|
||||
representable if the chroma is subsampled (H.265 section 7.4.3.2.1).
|
||||
|
||||
@item level
|
||||
Set the level in the VPS and SPS. See H.265 section A.4 and tables
|
||||
A.6 and A.7.
|
||||
|
||||
The argument must be the name of a level (for example, @samp{5.1}), a
|
||||
@emph{general_level_idc} value (for example, @samp{153} for level 5.1),
|
||||
or the special name @samp{auto} indicating that the filter should
|
||||
attempt to guess the level from the input stream properties.
|
||||
|
||||
@end table
|
||||
|
||||
@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
|
||||
@@ -453,58 +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 mpeg2_metadata
|
||||
|
||||
Modify metadata embedded in an MPEG-2 stream.
|
||||
|
||||
@table @option
|
||||
@item display_aspect_ratio
|
||||
Set the display aspect ratio in the stream.
|
||||
|
||||
The following fixed values are supported:
|
||||
@table @option
|
||||
@item 4/3
|
||||
@item 16/9
|
||||
@item 221/100
|
||||
@end table
|
||||
Any other value will result in square pixels being signalled instead
|
||||
(see H.262 section 6.3.3 and table 6-3).
|
||||
|
||||
@item frame_rate
|
||||
Set the frame rate in the stream. This is constructed from a table
|
||||
of known values combined with a small multiplier and divisor - if
|
||||
the supplied value is not exactly representable, the nearest
|
||||
representable value will be used instead (see H.262 section 6.3.3
|
||||
and table 6-4).
|
||||
|
||||
@item video_format
|
||||
Set the video format in the stream (see H.262 section 6.3.6 and
|
||||
table 6-6).
|
||||
|
||||
@item colour_primaries
|
||||
@item transfer_characteristics
|
||||
@item matrix_coefficients
|
||||
Set the colour description in the stream (see H.262 section 6.3.6
|
||||
and tables 6-7, 6-8 and 6-9).
|
||||
|
||||
@end table
|
||||
@section mp3_header_decompress
|
||||
|
||||
@section mpeg4_unpack_bframes
|
||||
|
||||
@@ -528,327 +165,20 @@ ffmpeg -i INPUT.avi -codec copy -bsf:v mpeg4_unpack_bframes OUTPUT.avi
|
||||
|
||||
@section noise
|
||||
|
||||
Damages the contents of packets or simply drops them without damaging the
|
||||
container. Can be used for fuzzing or testing error resilience/concealment.
|
||||
Damages the contents of packets without damaging the container. Can be
|
||||
used for fuzzing or testing error resilience/concealment.
|
||||
|
||||
Parameters:
|
||||
@table @option
|
||||
@item amount
|
||||
Accepts an expression whose evaluation per-packet determines how often bytes in that
|
||||
packet will be modified. A value below 0 will result in a variable frequency.
|
||||
Default is 0 which results in no modification. However, if neither amount nor drop is specified,
|
||||
amount will be set to @var{-1}. See below for accepted variables.
|
||||
@item drop
|
||||
Accepts an expression evaluated per-packet whose value determines whether that packet is dropped.
|
||||
Evaluation to a positive value results in the packet being dropped. Evaluation to a negative
|
||||
value results in a variable chance of it being dropped, roughly inverse in proportion to the magnitude
|
||||
of the value. Default is 0 which results in no drops. See below for accepted variables.
|
||||
@item dropamount
|
||||
Accepts a non-negative integer, which assigns a variable chance of it being dropped, roughly inverse
|
||||
in proportion to the value. Default is 0 which results in no drops. This option is kept for backwards
|
||||
compatibility and is equivalent to setting drop to a negative value with the same magnitude
|
||||
i.e. @code{dropamount=4} is the same as @code{drop=-4}. Ignored if drop is also specified.
|
||||
@end table
|
||||
A numeral string, whose value is related to how often output bytes will
|
||||
be modified. Therefore, values below or equal to 0 are forbidden, and
|
||||
the lower the more frequent bytes will be modified, with 1 meaning
|
||||
every byte is modified.
|
||||
|
||||
Both @code{amount} and @code{drop} accept expressions containing the following variables:
|
||||
|
||||
@table @samp
|
||||
@item n
|
||||
The index of the packet, starting from zero.
|
||||
@item tb
|
||||
The timebase for packet timestamps.
|
||||
@item pts
|
||||
Packet presentation timestamp.
|
||||
@item dts
|
||||
Packet decoding timestamp.
|
||||
@item nopts
|
||||
Constant representing AV_NOPTS_VALUE.
|
||||
@item startpts
|
||||
First non-AV_NOPTS_VALUE PTS seen in the stream.
|
||||
@item startdts
|
||||
First non-AV_NOPTS_VALUE DTS seen in the stream.
|
||||
@item duration
|
||||
@itemx d
|
||||
Packet duration, in timebase units.
|
||||
@item pos
|
||||
Packet position in input; may be -1 when unknown or not set.
|
||||
@item size
|
||||
Packet size, in bytes.
|
||||
@item key
|
||||
Whether packet is marked as a keyframe.
|
||||
@item state
|
||||
A pseudo random integer, primarily derived from the content of packet payload.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
Apply modification to every byte but don't drop any packets.
|
||||
@example
|
||||
ffmpeg -i INPUT -c copy -bsf noise=1 output.mkv
|
||||
@end example
|
||||
|
||||
Drop every video packet not marked as a keyframe after timestamp 30s but do not
|
||||
modify any of the remaining packets.
|
||||
@example
|
||||
ffmpeg -i INPUT -c copy -bsf:v noise=drop='gt(t\,30)*not(key)' output.mkv
|
||||
@end example
|
||||
|
||||
Drop one second of audio every 10 seconds and add some random noise to the rest.
|
||||
@example
|
||||
ffmpeg -i INPUT -c copy -bsf:a noise=amount=-1:drop='between(mod(t\,10)\,9\,10)' output.mkv
|
||||
@end example
|
||||
|
||||
@section null
|
||||
This bitstream filter passes the packets through unchanged.
|
||||
|
||||
@section pcm_rechunk
|
||||
|
||||
Repacketize PCM audio to a fixed number of samples per packet or a fixed packet
|
||||
rate per second. This is similar to the @ref{asetnsamples,,asetnsamples audio
|
||||
filter,ffmpeg-filters} but works on audio packets instead of audio frames.
|
||||
|
||||
@table @option
|
||||
@item nb_out_samples, n
|
||||
Set the number of samples per each output audio packet. The number is intended
|
||||
as the number of samples @emph{per each channel}. Default value is 1024.
|
||||
|
||||
@item pad, p
|
||||
If set to 1, the filter will pad the last audio packet with silence, so that it
|
||||
will contain the same number of samples (or roughly the same number of samples,
|
||||
see @option{frame_rate}) as the previous ones. Default value is 1.
|
||||
|
||||
@item frame_rate, r
|
||||
This option makes the filter output a fixed number of packets per second instead
|
||||
of a fixed number of samples per packet. If the audio sample rate is not
|
||||
divisible by the frame rate then the number of samples will not be constant but
|
||||
will vary slightly so that each packet will start as close to the frame
|
||||
boundary as possible. Using this option has precedence over @option{nb_out_samples}.
|
||||
@end table
|
||||
|
||||
You can generate the well known 1602-1601-1602-1601-1602 pattern of 48kHz audio
|
||||
for NTSC frame rate using the @option{frame_rate} option.
|
||||
@example
|
||||
ffmpeg -f lavfi -i sine=r=48000:d=1 -c pcm_s16le -bsf pcm_rechunk=r=30000/1001 -f framecrc -
|
||||
@end example
|
||||
|
||||
@section prores_metadata
|
||||
|
||||
Modify color property metadata embedded in prores stream.
|
||||
|
||||
@table @option
|
||||
@item color_primaries
|
||||
Set the color primaries.
|
||||
Available values are:
|
||||
|
||||
@table @samp
|
||||
@item auto
|
||||
Keep the same color primaries property (default).
|
||||
|
||||
@item unknown
|
||||
@item bt709
|
||||
@item bt470bg
|
||||
BT601 625
|
||||
|
||||
@item smpte170m
|
||||
BT601 525
|
||||
|
||||
@item bt2020
|
||||
@item smpte431
|
||||
DCI P3
|
||||
|
||||
@item smpte432
|
||||
P3 D65
|
||||
|
||||
@end table
|
||||
|
||||
@item transfer_characteristics
|
||||
Set the color transfer.
|
||||
Available values are:
|
||||
|
||||
@table @samp
|
||||
@item auto
|
||||
Keep the same transfer characteristics property (default).
|
||||
|
||||
@item unknown
|
||||
@item bt709
|
||||
BT 601, BT 709, BT 2020
|
||||
@item smpte2084
|
||||
SMPTE ST 2084
|
||||
@item arib-std-b67
|
||||
ARIB STD-B67
|
||||
@end table
|
||||
|
||||
|
||||
@item matrix_coefficients
|
||||
Set the matrix coefficient.
|
||||
Available values are:
|
||||
|
||||
@table @samp
|
||||
@item auto
|
||||
Keep the same colorspace property (default).
|
||||
|
||||
@item unknown
|
||||
@item bt709
|
||||
@item smpte170m
|
||||
BT 601
|
||||
|
||||
@item bt2020nc
|
||||
@end table
|
||||
@end table
|
||||
|
||||
Set Rec709 colorspace for each frame of the file
|
||||
@example
|
||||
ffmpeg -i INPUT -c copy -bsf:v prores_metadata=color_primaries=bt709:color_trc=bt709:colorspace=bt709 output.mov
|
||||
@end example
|
||||
|
||||
Set Hybrid Log-Gamma parameters for each frame of the file
|
||||
@example
|
||||
ffmpeg -i INPUT -c copy -bsf:v prores_metadata=color_primaries=bt2020:color_trc=arib-std-b67:colorspace=bt2020nc output.mov
|
||||
ffmpeg -i INPUT -c copy -bsf noise[=1] output.mkv
|
||||
@end example
|
||||
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
|
||||
|
||||
@section setts
|
||||
Set PTS and DTS in packets.
|
||||
|
||||
It accepts the following parameters:
|
||||
@table @option
|
||||
@item ts
|
||||
@item pts
|
||||
@item dts
|
||||
Set expressions for PTS, DTS or both.
|
||||
@end table
|
||||
|
||||
The expressions are evaluated through the eval API and can contain the following
|
||||
constants:
|
||||
|
||||
@table @option
|
||||
@item N
|
||||
The count of the input packet. Starting from 0.
|
||||
|
||||
@item TS
|
||||
The demux timestamp in input in case of @code{ts} or @code{dts} option or presentation
|
||||
timestamp in case of @code{pts} option.
|
||||
|
||||
@item POS
|
||||
The original position in the file of the packet, or undefined if undefined
|
||||
for the current packet
|
||||
|
||||
@item DTS
|
||||
The demux timestamp in input.
|
||||
|
||||
@item PTS
|
||||
The presentation timestamp in input.
|
||||
|
||||
@item STARTDTS
|
||||
The DTS of the first packet.
|
||||
|
||||
@item STARTPTS
|
||||
The PTS of the first packet.
|
||||
|
||||
@item PREV_INDTS
|
||||
The previous input DTS.
|
||||
|
||||
@item PREV_INPTS
|
||||
The previous input PTS.
|
||||
|
||||
@item PREV_OUTDTS
|
||||
The previous output DTS.
|
||||
|
||||
@item PREV_OUTPTS
|
||||
The previous output PTS.
|
||||
|
||||
@item TB
|
||||
The timebase of stream packet belongs.
|
||||
|
||||
@item SR
|
||||
The sample rate of stream packet belongs.
|
||||
|
||||
@item NOPTS
|
||||
The AV_NOPTS_VALUE constant.
|
||||
@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 trace_headers
|
||||
|
||||
Log trace output containing all syntax elements in the coded stream
|
||||
headers (everything above the level of individual coded blocks).
|
||||
This can be useful for debugging low-level stream issues.
|
||||
|
||||
Supports AV1, H.264, H.265, (M)JPEG, MPEG-2 and VP9, but depending
|
||||
on the build only a subset of these may be available.
|
||||
|
||||
@section truehd_core
|
||||
|
||||
Extract the core from a TrueHD stream, dropping ATMOS data.
|
||||
|
||||
@section vp9_metadata
|
||||
|
||||
Modify metadata embedded in a VP9 stream.
|
||||
|
||||
@table @option
|
||||
@item color_space
|
||||
Set the color space value in the frame header. Note that any frame
|
||||
set to RGB will be implicitly set to PC range and that RGB is
|
||||
incompatible with profiles 0 and 2.
|
||||
@table @samp
|
||||
@item unknown
|
||||
@item bt601
|
||||
@item bt709
|
||||
@item smpte170
|
||||
@item smpte240
|
||||
@item bt2020
|
||||
@item rgb
|
||||
@end table
|
||||
|
||||
@item color_range
|
||||
Set the color range value in the frame header. Note that any value
|
||||
imposed by the color space will take precedence over this value.
|
||||
@table @samp
|
||||
@item tv
|
||||
@item pc
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@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.
|
||||
|
||||
@section vp9_superframe_split
|
||||
|
||||
Split VP9 superframes into single frames.
|
||||
|
||||
@section vp9_raw_reorder
|
||||
|
||||
Given a VP9 stream with correct timestamps but possibly out of order,
|
||||
insert additional show-existing-frame packets to correct the ordering.
|
||||
|
||||
@c man end BITSTREAM FILTERS
|
||||
|
||||
@@ -36,20 +36,15 @@ install
|
||||
examples
|
||||
Build all examples located in doc/examples.
|
||||
|
||||
checkheaders
|
||||
Check headers dependencies.
|
||||
libavformat/output-example
|
||||
Build the libavformat basic example.
|
||||
|
||||
alltools
|
||||
Build all tools in tools directory.
|
||||
libswscale/swscale-test
|
||||
Build the swscale self-test (useful also as an example).
|
||||
|
||||
config
|
||||
Reconfigure the project with the current configuration.
|
||||
|
||||
tools/target_dec_<decoder>_fuzzer
|
||||
Build fuzzer to fuzz the specified decoder.
|
||||
|
||||
tools/target_bsf_<filter>_fuzzer
|
||||
Build fuzzer to fuzz the specified bitstream filter.
|
||||
|
||||
Useful standard make commands:
|
||||
make -t <target>
|
||||
|
||||
442
doc/codecs.texi
442
doc/codecs.texi
@@ -44,20 +44,26 @@ Use 1/4 pel motion compensation.
|
||||
Use loop filter.
|
||||
@item qscale
|
||||
Use fixed qscale.
|
||||
@item gmc
|
||||
Use gmc.
|
||||
@item mv0
|
||||
Always try a mb with mv=<0,0>.
|
||||
@item input_preserved
|
||||
|
||||
@item pass1
|
||||
Use internal 2pass ratecontrol in first pass mode.
|
||||
@item pass2
|
||||
Use internal 2pass ratecontrol in second pass mode.
|
||||
@item gray
|
||||
Only decode/encode grayscale.
|
||||
@item emu_edge
|
||||
Do not draw edges.
|
||||
@item psnr
|
||||
Set error[?] variables during encoding.
|
||||
@item truncated
|
||||
Input bitstream might be randomly truncated.
|
||||
@item drop_changed
|
||||
Don't output frames whose parameters differ from first decoded frame in stream.
|
||||
Error AVERROR_INPUT_CHANGED is returned when a frame is dropped.
|
||||
|
||||
@item naq
|
||||
Normalize adaptive quantization.
|
||||
@item ildct
|
||||
Use interlaced DCT.
|
||||
@item low_delay
|
||||
@@ -70,14 +76,50 @@ This ensures that file and data checksums are reproducible and match between
|
||||
platforms. Its primary use is for regression testing.
|
||||
@item aic
|
||||
Apply H263 advanced intra coding / mpeg4 ac prediction.
|
||||
@item cbp
|
||||
Deprecated, use mpegvideo private options instead.
|
||||
@item qprd
|
||||
Deprecated, use mpegvideo private options instead.
|
||||
@item ilme
|
||||
Apply interlaced motion estimation.
|
||||
@item cgop
|
||||
Use closed gop.
|
||||
@item output_corrupt
|
||||
Output even potentially corrupted frames.
|
||||
@end table
|
||||
|
||||
@item me_method @var{integer} (@emph{encoding,video})
|
||||
Set motion estimation method.
|
||||
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item zero
|
||||
zero motion estimation (fastest)
|
||||
@item full
|
||||
full motion estimation (slowest)
|
||||
@item epzs
|
||||
EPZS motion estimation (default)
|
||||
@item esa
|
||||
esa motion estimation (alias for full)
|
||||
@item tesa
|
||||
tesa motion estimation
|
||||
@item dia
|
||||
dia motion estimation (alias for epzs)
|
||||
@item log
|
||||
log motion estimation
|
||||
@item phods
|
||||
phods motion estimation
|
||||
@item x1
|
||||
X1 motion estimation
|
||||
@item hex
|
||||
hex motion estimation
|
||||
@item umh
|
||||
umh motion estimation
|
||||
@item iter
|
||||
iter motion estimation
|
||||
@end table
|
||||
|
||||
@item extradata_size @var{integer}
|
||||
Set extradata size.
|
||||
|
||||
@item time_base @var{rational number}
|
||||
Set codec time base.
|
||||
|
||||
@@ -96,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.
|
||||
@@ -144,6 +185,24 @@ Default value is 0.
|
||||
@item b_qfactor @var{float} (@emph{encoding,video})
|
||||
Set qp factor between P and B frames.
|
||||
|
||||
@item rc_strategy @var{integer} (@emph{encoding,video})
|
||||
Set ratecontrol method.
|
||||
|
||||
@item b_strategy @var{integer} (@emph{encoding,video})
|
||||
Set strategy to choose between I/P/B-frames.
|
||||
|
||||
@item ps @var{integer} (@emph{encoding,video})
|
||||
Set RTP payload size in bytes.
|
||||
|
||||
@item mv_bits @var{integer}
|
||||
@item header_bits @var{integer}
|
||||
@item i_tex_bits @var{integer}
|
||||
@item p_tex_bits @var{integer}
|
||||
@item i_count @var{integer}
|
||||
@item p_count @var{integer}
|
||||
@item skip_count @var{integer}
|
||||
@item misc_bits @var{integer}
|
||||
@item frame_bits @var{integer}
|
||||
@item codec_tag @var{integer}
|
||||
@item bug @var{flags} (@emph{decoding,video})
|
||||
Workaround not auto detected encoder bugs.
|
||||
@@ -152,6 +211,8 @@ Possible values:
|
||||
@table @samp
|
||||
@item autodetect
|
||||
|
||||
@item old_msmpeg4
|
||||
some old lavc generated msmpeg4v3 files (no autodetection)
|
||||
@item xvid_ilace
|
||||
Xvid interlacing bug (autodetected if fourcc==XVIX)
|
||||
@item ump4
|
||||
@@ -160,6 +221,8 @@ Xvid interlacing bug (autodetected if fourcc==XVIX)
|
||||
padding bug (autodetected)
|
||||
@item amv
|
||||
|
||||
@item ac_vlc
|
||||
illegal vlc bug (autodetected per fourcc)
|
||||
@item qpel_chroma
|
||||
|
||||
@item std_qpel
|
||||
@@ -180,6 +243,14 @@ Workaround various bugs in microsoft broken decoders.
|
||||
trancated frames
|
||||
@end table
|
||||
|
||||
@item lelim @var{integer} (@emph{encoding,video})
|
||||
Set single coefficient elimination threshold for luminance (negative
|
||||
values also consider DC coefficient).
|
||||
|
||||
@item celim @var{integer} (@emph{encoding,video})
|
||||
Set single coefficient elimination threshold for chrominance (negative
|
||||
values also consider dc coefficient)
|
||||
|
||||
@item strict @var{integer} (@emph{decoding/encoding,audio,video})
|
||||
Specify how strictly to follow the standards.
|
||||
|
||||
@@ -233,8 +304,29 @@ consider things that a sane encoder should not do as an error
|
||||
|
||||
@item block_align @var{integer}
|
||||
|
||||
@item mpeg_quant @var{integer} (@emph{encoding,video})
|
||||
Use MPEG quantizers instead of H.263.
|
||||
|
||||
@item qsquish @var{float} (@emph{encoding,video})
|
||||
How to keep quantizer between qmin and qmax (0 = clip, 1 = use
|
||||
differentiable function).
|
||||
|
||||
@item rc_qmod_amp @var{float} (@emph{encoding,video})
|
||||
Set experimental quantizer modulation.
|
||||
|
||||
@item rc_qmod_freq @var{integer} (@emph{encoding,video})
|
||||
Set experimental quantizer modulation.
|
||||
|
||||
@item rc_override_count @var{integer}
|
||||
|
||||
@item rc_eq @var{string} (@emph{encoding,video})
|
||||
Set rate control equation. When computing the expression, besides the
|
||||
standard functions defined in the section 'Expression Evaluation', the
|
||||
following functions are available: bits2qp(bits), qp2bits(qp). Also
|
||||
the following constants are available: iTex pTex tex mv fCode iCount
|
||||
mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex
|
||||
avgTex.
|
||||
|
||||
@item maxrate @var{integer} (@emph{encoding,audio,video})
|
||||
Set max bitrate tolerance (in bits/s). Requires bufsize to be set.
|
||||
|
||||
@@ -245,12 +337,18 @@ encode. It is of little use elsewise.
|
||||
@item bufsize @var{integer} (@emph{encoding,audio,video})
|
||||
Set ratecontrol buffer size (in bits).
|
||||
|
||||
@item rc_buf_aggressivity @var{float} (@emph{encoding,video})
|
||||
Currently useless.
|
||||
|
||||
@item i_qfactor @var{float} (@emph{encoding,video})
|
||||
Set QP factor between P and I frames.
|
||||
|
||||
@item i_qoffset @var{float} (@emph{encoding,video})
|
||||
Set QP offset between P and I frames.
|
||||
|
||||
@item rc_init_cplx @var{float} (@emph{encoding,video})
|
||||
Set initial complexity for 1-pass encoding.
|
||||
|
||||
@item dct @var{integer} (@emph{encoding,video})
|
||||
Set DCT algorithm.
|
||||
|
||||
@@ -315,7 +413,11 @@ Automatically pick a IDCT compatible with the simple one
|
||||
|
||||
@item simpleneon
|
||||
|
||||
@item xvid
|
||||
@item simplealpha
|
||||
|
||||
@item ipp
|
||||
|
||||
@item xvidmmx
|
||||
|
||||
@item faani
|
||||
floating point AAN IDCT
|
||||
@@ -338,6 +440,19 @@ favor predicting from the previous frame instead of the current
|
||||
|
||||
@item bits_per_coded_sample @var{integer}
|
||||
|
||||
@item pred @var{integer} (@emph{encoding,video})
|
||||
Set prediction method.
|
||||
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item left
|
||||
|
||||
@item plane
|
||||
|
||||
@item median
|
||||
|
||||
@end table
|
||||
|
||||
@item aspect @var{rational number} (@emph{encoding,video})
|
||||
Set sample aspect ratio.
|
||||
|
||||
@@ -359,6 +474,8 @@ rate control
|
||||
macroblock (MB) type
|
||||
@item qp
|
||||
per-block quantization parameter (QP)
|
||||
@item mv
|
||||
motion vector
|
||||
@item dct_coeff
|
||||
|
||||
@item green_metadata
|
||||
@@ -368,12 +485,18 @@ display complexity metadata for the upcoming frame, GoP or for a given duration.
|
||||
|
||||
@item startcode
|
||||
|
||||
@item pts
|
||||
|
||||
@item er
|
||||
error recognition
|
||||
@item mmco
|
||||
memory management control operations (H.264)
|
||||
@item bugs
|
||||
|
||||
@item vis_qp
|
||||
visualize quantization parameter (QP), lower QP are tinted greener
|
||||
@item vis_mb_type
|
||||
visualize block types
|
||||
@item buffers
|
||||
picture buffer allocations
|
||||
@item thread_ops
|
||||
@@ -382,6 +505,21 @@ threading operations
|
||||
skip motion compensation
|
||||
@end table
|
||||
|
||||
@item vismv @var{integer} (@emph{decoding,video})
|
||||
Visualize motion vectors (MVs).
|
||||
|
||||
This option is deprecated, see the codecview filter instead.
|
||||
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item pf
|
||||
forward predicted MVs of P-frames
|
||||
@item bf
|
||||
forward predicted MVs of B-frames
|
||||
@item bb
|
||||
backward predicted MVs of B-frames
|
||||
@end table
|
||||
|
||||
@item cmp @var{integer} (@emph{encoding,video})
|
||||
Set full pel me compare function.
|
||||
|
||||
@@ -532,28 +670,13 @@ noise preserving sum of squared differences
|
||||
|
||||
@item dia_size @var{integer} (@emph{encoding,video})
|
||||
Set diamond type & size for motion estimation.
|
||||
@table @samp
|
||||
@item (1024, INT_MAX)
|
||||
full motion estimation(slowest)
|
||||
@item (768, 1024]
|
||||
umh motion estimation
|
||||
@item (512, 768]
|
||||
hex motion estimation
|
||||
@item (256, 512]
|
||||
l2s diamond motion estimation
|
||||
@item [2,256]
|
||||
var diamond motion estimation
|
||||
@item (-1, 2)
|
||||
small diamond motion estimation
|
||||
@item -1
|
||||
funny diamond motion estimation
|
||||
@item (INT_MIN, -1)
|
||||
sab diamond motion estimation
|
||||
@end table
|
||||
|
||||
@item last_pred @var{integer} (@emph{encoding,video})
|
||||
Set amount of motion predictors from the previous frame.
|
||||
|
||||
@item preme @var{integer} (@emph{encoding,video})
|
||||
Set pre motion estimation.
|
||||
|
||||
@item precmp @var{integer} (@emph{encoding,video})
|
||||
Set pre motion estimation compare function.
|
||||
|
||||
@@ -597,13 +720,44 @@ Set diamond type & size for motion estimation pre-pass.
|
||||
@item subq @var{integer} (@emph{encoding,video})
|
||||
Set sub pel motion estimation quality.
|
||||
|
||||
@item dtg_active_format @var{integer}
|
||||
|
||||
@item me_range @var{integer} (@emph{encoding,video})
|
||||
Set limit motion vectors range (1023 for DivX player).
|
||||
|
||||
@item ibias @var{integer} (@emph{encoding,video})
|
||||
Set intra quant bias.
|
||||
|
||||
@item pbias @var{integer} (@emph{encoding,video})
|
||||
Set inter quant bias.
|
||||
|
||||
@item color_table_id @var{integer}
|
||||
|
||||
@item global_quality @var{integer} (@emph{encoding,audio,video})
|
||||
|
||||
@item coder @var{integer} (@emph{encoding,video})
|
||||
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item vlc
|
||||
variable length coder / huffman coder
|
||||
@item ac
|
||||
arithmetic coder
|
||||
@item raw
|
||||
raw (no encoding)
|
||||
@item rle
|
||||
run-length coder
|
||||
@item deflate
|
||||
deflate-based coder
|
||||
@end table
|
||||
|
||||
@item context @var{integer} (@emph{encoding,video})
|
||||
Set context model.
|
||||
|
||||
@item slice_flags @var{integer}
|
||||
|
||||
@item xvmc_acceleration @var{integer}
|
||||
|
||||
@item mbd @var{integer} (@emph{encoding,video})
|
||||
Set macroblock decision algorithm (high quality mode).
|
||||
|
||||
@@ -617,16 +771,32 @@ use fewest bits
|
||||
use best rate distortion
|
||||
@end table
|
||||
|
||||
@item stream_codec_tag @var{integer}
|
||||
|
||||
@item sc_threshold @var{integer} (@emph{encoding,video})
|
||||
Set scene change threshold.
|
||||
|
||||
@item lmin @var{integer} (@emph{encoding,video})
|
||||
Set min lagrange factor (VBR).
|
||||
|
||||
@item lmax @var{integer} (@emph{encoding,video})
|
||||
Set max lagrange factor (VBR).
|
||||
|
||||
@item nr @var{integer} (@emph{encoding,video})
|
||||
Set noise reduction.
|
||||
|
||||
@item rc_init_occupancy @var{integer} (@emph{encoding,video})
|
||||
Set number of bits which should be loaded into the rc buffer before
|
||||
decoding starts.
|
||||
|
||||
@item flags2 @var{flags} (@emph{decoding/encoding,audio,video,subtitles})
|
||||
@item flags2 @var{flags} (@emph{decoding/encoding,audio,video})
|
||||
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item fast
|
||||
Allow non spec compliant speedup tricks.
|
||||
@item sgop
|
||||
Deprecated, use mpegvideo private options instead.
|
||||
@item noout
|
||||
Skip bitstream encoding.
|
||||
@item ignorecrop
|
||||
@@ -637,32 +807,17 @@ Place global headers at every keyframe instead of in extradata.
|
||||
Frame data might be split into multiple chunks.
|
||||
@item showall
|
||||
Show all frames before the first keyframe.
|
||||
@item skiprd
|
||||
Deprecated, use mpegvideo private options instead.
|
||||
@item export_mvs
|
||||
Export motion vectors into frame side-data (see @code{AV_FRAME_DATA_MOTION_VECTORS})
|
||||
for codecs that support it. See also @file{doc/examples/export_mvs.c}.
|
||||
@item skip_manual
|
||||
Do not skip samples and export skip information as frame side data.
|
||||
@item ass_ro_flush_noop
|
||||
Do not reset ASS ReadOrder field on flush.
|
||||
@end table
|
||||
|
||||
@item export_side_data @var{flags} (@emph{decoding/encoding,audio,video,subtitles})
|
||||
@item error @var{integer} (@emph{encoding,video})
|
||||
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item mvs
|
||||
Export motion vectors into frame side-data (see @code{AV_FRAME_DATA_MOTION_VECTORS})
|
||||
for codecs that support it. See also @file{doc/examples/export_mvs.c}.
|
||||
@item prft
|
||||
Export encoder Producer Reference Time into packet side-data (see @code{AV_PKT_DATA_PRFT})
|
||||
for codecs that support it.
|
||||
@item venc_params
|
||||
Export video encoding parameters through frame side data (see @code{AV_FRAME_DATA_VIDEO_ENC_PARAMS})
|
||||
for codecs that support it. At present, those are H.264 and VP9.
|
||||
@item film_grain
|
||||
Export film grain parameters through frame side data (see @code{AV_FRAME_DATA_FILM_GRAIN_PARAMS}).
|
||||
Supported at present by AV1 decoders.
|
||||
@end table
|
||||
@item qns @var{integer} (@emph{encoding,video})
|
||||
Deprecated, use mpegvideo private options instead.
|
||||
|
||||
@item threads @var{integer} (@emph{decoding/encoding,video})
|
||||
Set the number of threads to be used, in case the selected codec
|
||||
@@ -676,6 +831,12 @@ automatically select the number of threads to set
|
||||
|
||||
Default value is @samp{auto}.
|
||||
|
||||
@item me_threshold @var{integer} (@emph{encoding,video})
|
||||
Set motion estimation threshold.
|
||||
|
||||
@item mb_threshold @var{integer} (@emph{encoding,video})
|
||||
Set macroblock threshold.
|
||||
|
||||
@item dc @var{integer} (@emph{encoding,video})
|
||||
Set intra_dc_precision.
|
||||
|
||||
@@ -690,8 +851,49 @@ Set number of macroblock rows at the bottom which are skipped.
|
||||
|
||||
@item profile @var{integer} (@emph{encoding,audio,video})
|
||||
|
||||
Set encoder codec profile. Default value is @samp{unknown}. Encoder specific
|
||||
profiles are documented in the relevant encoder documentation.
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item unknown
|
||||
|
||||
@item aac_main
|
||||
|
||||
@item aac_low
|
||||
|
||||
@item aac_ssr
|
||||
|
||||
@item aac_ltp
|
||||
|
||||
@item aac_he
|
||||
|
||||
@item aac_he_v2
|
||||
|
||||
@item aac_ld
|
||||
|
||||
@item aac_eld
|
||||
|
||||
@item mpeg2_aac_low
|
||||
|
||||
@item mpeg2_aac_he
|
||||
|
||||
@item mpeg4_sp
|
||||
|
||||
@item mpeg4_core
|
||||
|
||||
@item mpeg4_main
|
||||
|
||||
@item mpeg4_asp
|
||||
|
||||
@item dts
|
||||
|
||||
@item dts_es
|
||||
|
||||
@item dts_96_24
|
||||
|
||||
@item dts_hd_hra
|
||||
|
||||
@item dts_hd_ma
|
||||
|
||||
@end table
|
||||
|
||||
@item level @var{integer} (@emph{encoding,audio,video})
|
||||
|
||||
@@ -704,12 +906,67 @@ Possible values:
|
||||
@item lowres @var{integer} (@emph{decoding,audio,video})
|
||||
Decode at 1= 1/2, 2=1/4, 3=1/8 resolutions.
|
||||
|
||||
@item skip_threshold @var{integer} (@emph{encoding,video})
|
||||
Set frame skip threshold.
|
||||
|
||||
@item skip_factor @var{integer} (@emph{encoding,video})
|
||||
Set frame skip factor.
|
||||
|
||||
@item skip_exp @var{integer} (@emph{encoding,video})
|
||||
Set frame skip exponent.
|
||||
Negative values behave identical to the corresponding positive ones, except
|
||||
that the score is normalized.
|
||||
Positive values exist primarily for compatibility reasons and are not so useful.
|
||||
|
||||
@item skipcmp @var{integer} (@emph{encoding,video})
|
||||
Set frame skip compare function.
|
||||
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item sad
|
||||
sum of absolute differences, fast (default)
|
||||
@item sse
|
||||
sum of squared errors
|
||||
@item satd
|
||||
sum of absolute Hadamard transformed differences
|
||||
@item dct
|
||||
sum of absolute DCT transformed differences
|
||||
@item psnr
|
||||
sum of squared quantization errors (avoid, low quality)
|
||||
@item bit
|
||||
number of bits needed for the block
|
||||
@item rd
|
||||
rate distortion optimal, slow
|
||||
@item zero
|
||||
0
|
||||
@item vsad
|
||||
sum of absolute vertical differences
|
||||
@item vsse
|
||||
sum of squared vertical differences
|
||||
@item nsse
|
||||
noise preserving sum of squared differences
|
||||
@item w53
|
||||
5/3 wavelet, only used in snow
|
||||
@item w97
|
||||
9/7 wavelet, only used in snow
|
||||
@item dctmax
|
||||
|
||||
@item chroma
|
||||
|
||||
@end table
|
||||
|
||||
@item border_mask @var{float} (@emph{encoding,video})
|
||||
Increase the quantizer for macroblocks close to borders.
|
||||
|
||||
@item mblmin @var{integer} (@emph{encoding,video})
|
||||
Set min macroblock lagrange factor (VBR).
|
||||
|
||||
@item mblmax @var{integer} (@emph{encoding,video})
|
||||
Set max macroblock lagrange factor (VBR).
|
||||
|
||||
@item mepc @var{integer} (@emph{encoding,video})
|
||||
Set motion estimation bitrate penalty compensation (1.0 = 256).
|
||||
|
||||
@item skip_loop_filter @var{integer} (@emph{decoding,video})
|
||||
@item skip_idct @var{integer} (@emph{decoding,video})
|
||||
@item skip_frame @var{integer} (@emph{decoding,video})
|
||||
@@ -737,9 +994,6 @@ Discard all bidirectional frames.
|
||||
@item nokey
|
||||
Discard all frames excepts keyframes.
|
||||
|
||||
@item nointra
|
||||
Discard all frames except I frames.
|
||||
|
||||
@item all
|
||||
Discard all frames.
|
||||
@end table
|
||||
@@ -749,17 +1003,38 @@ Default value is @samp{default}.
|
||||
@item bidir_refine @var{integer} (@emph{encoding,video})
|
||||
Refine the two motion vectors used in bidirectional macroblocks.
|
||||
|
||||
@item brd_scale @var{integer} (@emph{encoding,video})
|
||||
Downscale frames for dynamic B-frame decision.
|
||||
|
||||
@item keyint_min @var{integer} (@emph{encoding,video})
|
||||
Set minimum interval between IDR-frames.
|
||||
|
||||
@item refs @var{integer} (@emph{encoding,video})
|
||||
Set reference frames to consider for motion compensation.
|
||||
|
||||
@item chromaoffset @var{integer} (@emph{encoding,video})
|
||||
Set chroma qp offset from luma.
|
||||
|
||||
@item trellis @var{integer} (@emph{encoding,audio,video})
|
||||
Set rate-distortion optimal quantization.
|
||||
|
||||
@item sc_factor @var{integer} (@emph{encoding,video})
|
||||
Set value multiplied by qscale for each frame and added to
|
||||
scene_change_score.
|
||||
|
||||
@item mv0_threshold @var{integer} (@emph{encoding,video})
|
||||
@item b_sensitivity @var{integer} (@emph{encoding,video})
|
||||
Adjust sensitivity of b_frame_strategy 1.
|
||||
|
||||
@item compression_level @var{integer} (@emph{encoding,audio,video})
|
||||
@item min_prediction_order @var{integer} (@emph{encoding,audio})
|
||||
@item max_prediction_order @var{integer} (@emph{encoding,audio})
|
||||
@item timecode_frame_start @var{integer} (@emph{encoding,video})
|
||||
Set GOP timecode frame start number, in non drop frame format.
|
||||
|
||||
@item request_channels @var{integer} (@emph{decoding,audio})
|
||||
Set desired number of audio channels.
|
||||
|
||||
@item bits_per_raw_sample @var{integer}
|
||||
@item channel_layout @var{integer} (@emph{decoding/encoding,audio})
|
||||
|
||||
@@ -792,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})
|
||||
@@ -819,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
|
||||
@@ -865,51 +1129,19 @@ 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
|
||||
SMPTE 2085
|
||||
@item chroma-derived-nc
|
||||
Chroma-derived NCL
|
||||
@item chroma-derived-c
|
||||
Chroma-derived CL
|
||||
@item ictcp
|
||||
ICtCp
|
||||
@end table
|
||||
|
||||
@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.
|
||||
@@ -988,7 +1220,7 @@ Interlaced video, top coded first, bottom displayed first
|
||||
Interlaced video, bottom coded first, top displayed first
|
||||
@end table
|
||||
|
||||
@item skip_alpha @var{bool} (@emph{decoding,video})
|
||||
@item skip_alpha @var{integer} (@emph{decoding,video})
|
||||
Set to 1 to disable processing alpha (transparency). This works like the
|
||||
@samp{gray} flag in the @option{flags} option which skips chroma information
|
||||
instead of alpha. Default is 0.
|
||||
@@ -999,26 +1231,12 @@ instead of alpha. Default is 0.
|
||||
@item dump_separator @var{string} (@emph{input})
|
||||
Separator used to separate the fields printed on the command line about the
|
||||
Stream parameters.
|
||||
For example, to separate the fields with newlines and indentation:
|
||||
For example to separate the fields with newlines and indention:
|
||||
@example
|
||||
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.
|
||||
|
||||
@item apply_cropping @var{bool} (@emph{decoding,video})
|
||||
Enable cropping if cropping parameters are multiples of the required
|
||||
alignment for the left and top parameters. If the alignment is not met the
|
||||
cropping will be partially applied to maintain alignment.
|
||||
Default is 1 (enabled).
|
||||
Note: The required alignment depends on if @code{AV_CODEC_FLAG_UNALIGNED} is set and the
|
||||
CPU. @code{AV_CODEC_FLAG_UNALIGNED} cannot be changed from the command line. Also hardware
|
||||
decoders will not apply left/top Cropping.
|
||||
|
||||
|
||||
@end table
|
||||
|
||||
@c man end CODEC OPTIONS
|
||||
|
||||
@@ -25,18 +25,12 @@ enabled decoders.
|
||||
A description of some of the currently available video decoders
|
||||
follows.
|
||||
|
||||
@section av1
|
||||
@section hevc
|
||||
|
||||
AOMedia Video 1 (AV1) decoder.
|
||||
HEVC / H.265 decoder.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item operating_point
|
||||
Select an operating point of a scalable AV1 bitstream (0 - 31). Default is 0.
|
||||
|
||||
@end table
|
||||
Note: the @option{skip_loop_filter} option has effect only at level
|
||||
@code{all}.
|
||||
|
||||
@section rawvideo
|
||||
|
||||
@@ -60,72 +54,6 @@ top-field-first is assumed
|
||||
|
||||
@end table
|
||||
|
||||
@section libdav1d
|
||||
|
||||
dav1d AV1 decoder.
|
||||
|
||||
libdav1d allows libavcodec to decode the AOMedia Video 1 (AV1) codec.
|
||||
Requires the presence of the libdav1d headers and library during configuration.
|
||||
You need to explicitly configure the build with @code{--enable-libdav1d}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following options are supported by the libdav1d wrapper.
|
||||
|
||||
@table @option
|
||||
|
||||
@item framethreads
|
||||
Set amount of frame threads to use during decoding. The default value is 0 (autodetect).
|
||||
This option is deprecated for libdav1d >= 1.0 and will be removed in the future. Use the
|
||||
global option @code{threads} instead.
|
||||
|
||||
@item tilethreads
|
||||
Set amount of tile threads to use during decoding. The default value is 0 (autodetect).
|
||||
This option is deprecated for libdav1d >= 1.0 and will be removed in the future. Use the
|
||||
global option @code{threads} instead.
|
||||
|
||||
@item filmgrain
|
||||
Apply film grain to the decoded video if present in the bitstream. Defaults to the
|
||||
internal default of the library.
|
||||
This option is deprecated and will be removed in the future. See the global option
|
||||
@code{export_side_data} to export Film Grain parameters instead of applying it.
|
||||
|
||||
@item oppoint
|
||||
Select an operating point of a scalable AV1 bitstream (0 - 31). Defaults to the
|
||||
internal default of the library.
|
||||
|
||||
@item alllayers
|
||||
Output all spatial layers of a scalable AV1 bitstream. The default value is false.
|
||||
|
||||
@end table
|
||||
|
||||
@section libdavs2
|
||||
|
||||
AVS2-P2/IEEE1857.4 video decoder wrapper.
|
||||
|
||||
This decoder allows libavcodec to decode AVS2 streams with davs2 library.
|
||||
|
||||
@c man end VIDEO DECODERS
|
||||
|
||||
@section libuavs3d
|
||||
|
||||
AVS3-P2/IEEE1857.10 video decoder.
|
||||
|
||||
libuavs3d allows libavcodec to decode AVS3 streams.
|
||||
Requires the presence of the libuavs3d headers and library during configuration.
|
||||
You need to explicitly configure the build with @code{--enable-libuavs3d}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following option is supported by the libuavs3d wrapper.
|
||||
|
||||
@table @option
|
||||
|
||||
@item frame_threads
|
||||
Set amount of frame threads to use during decoding. The default value is 0 (autodetect).
|
||||
|
||||
@end table
|
||||
|
||||
@c man end VIDEO DECODERS
|
||||
|
||||
@chapter Audio Decoders
|
||||
@@ -147,7 +75,7 @@ the undocumented RealAudio 3 (a.k.a. dnet).
|
||||
|
||||
@item -drc_scale @var{value}
|
||||
Dynamic Range Scale Factor. The factor to apply to dynamic range values
|
||||
from the AC-3 stream. This factor is applied exponentially. The default value is 1.
|
||||
from the AC-3 stream. This factor is applied exponentially.
|
||||
There are 3 notable scale factor ranges:
|
||||
@table @option
|
||||
@item drc_scale == 0
|
||||
@@ -181,7 +109,7 @@ correctly by using lavc's old buggy lpc logic for decoding.
|
||||
|
||||
@section ffwavesynth
|
||||
|
||||
Internal wave synthesizer.
|
||||
Internal wave synthetizer.
|
||||
|
||||
This decoder generates wave patterns according to predefined sequences. Its
|
||||
use is purely internal and the format of the data it accepts is not publicly
|
||||
@@ -267,31 +195,6 @@ without this library.
|
||||
@chapter Subtitles Decoders
|
||||
@c man begin SUBTILES DECODERS
|
||||
|
||||
@section libaribb24
|
||||
|
||||
ARIB STD-B24 caption decoder.
|
||||
|
||||
Implements profiles A and C of the ARIB STD-B24 standard.
|
||||
|
||||
@subsection libaribb24 Decoder Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item -aribb24-base-path @var{path}
|
||||
Sets the base path for the libaribb24 library. This is utilized for reading of
|
||||
configuration files (for custom unicode conversions), and for dumping of
|
||||
non-text symbols as images under that location.
|
||||
|
||||
Unset by default.
|
||||
|
||||
@item -aribb24-skip-ruby-text @var{boolean}
|
||||
Tells the decoder wrapper to skip text blocks that contain half-height ruby
|
||||
text.
|
||||
|
||||
Enabled by default.
|
||||
|
||||
@end table
|
||||
|
||||
@section dvbsub
|
||||
|
||||
@subsection Options
|
||||
@@ -299,8 +202,6 @@ Enabled by default.
|
||||
@table @option
|
||||
@item compute_clut
|
||||
@table @option
|
||||
@item -2
|
||||
Compute clut once if no matching CLUT is in the stream.
|
||||
@item -1
|
||||
Compute clut if no matching CLUT is in the stream.
|
||||
@item 0
|
||||
@@ -329,7 +230,7 @@ palette is stored in the IFO file, and therefore not available when reading
|
||||
from dumped VOB files.
|
||||
|
||||
The format for this option is a string containing 16 24-bits hexadecimal
|
||||
numbers (without 0x prefix) separated by commas, for example @code{0d00ee,
|
||||
numbers (without 0x prefix) separated by comas, for example @code{0d00ee,
|
||||
ee450d, 101010, eaeaea, 0ce60b, ec14ed, ebff0b, 0d617a, 7b7b7b, d1d1d1,
|
||||
7b2a0e, 0d950c, 0f007b, cf0dec, cfa80c, 7c127b}.
|
||||
|
||||
@@ -354,30 +255,18 @@ configuration. You need to explicitly configure the build with
|
||||
|
||||
@table @option
|
||||
@item txt_page
|
||||
List of teletext page numbers to decode. Pages that do not match the specified
|
||||
list are dropped. You may use the special @code{*} string to match all pages,
|
||||
or @code{subtitle} to match all subtitle pages.
|
||||
List of teletext page numbers to decode. You may use the special * string to
|
||||
match all pages. Pages that do not match the specified list are dropped.
|
||||
Default value is *.
|
||||
@item txt_default_region
|
||||
Set default character set used for decoding, a value between 0 and 87 (see
|
||||
ETS 300 706, Section 15, Table 32). Default value is -1, which does not
|
||||
override the libzvbi default. This option is needed for some legacy level 1.0
|
||||
transmissions which cannot signal the proper charset.
|
||||
@item txt_chop_top
|
||||
Discards the top teletext line. Default value is 1.
|
||||
@item txt_format
|
||||
Specifies the format of the decoded subtitles.
|
||||
@table @option
|
||||
@item bitmap
|
||||
The default format, you should use this for teletext pages, because certain
|
||||
graphics and colors cannot be expressed in simple text or even ASS.
|
||||
@item text
|
||||
Simple text based output without formatting.
|
||||
@item ass
|
||||
Formatted ASS output, subtitle pages and teletext pages are returned in
|
||||
different styles, subtitle pages are stripped down to text, but an effort is
|
||||
made to keep the text alignment and the formatting.
|
||||
@end table
|
||||
Specifies the format of the decoded subtitles. The teletext decoder is capable
|
||||
of decoding the teletext pages to bitmaps or to simple text, you should use
|
||||
"bitmap" for teletext pages, because certain graphics and colors cannot be
|
||||
expressed in simple text. You might use "text" for teletext based subtitles if
|
||||
your application can handle simple text based subtitles. Default value is
|
||||
bitmap.
|
||||
@item txt_left
|
||||
X offset of generated bitmaps, default is 0.
|
||||
@item txt_top
|
||||
@@ -386,12 +275,11 @@ Y offset of generated bitmaps, default is 0.
|
||||
Chops leading and trailing spaces and removes empty lines from the generated
|
||||
text. This option is useful for teletext based subtitles where empty spaces may
|
||||
be present at the start or at the end of the lines or empty lines may be
|
||||
present between the subtitle lines because of double-sized teletext characters.
|
||||
present between the subtitle lines because of double-sized teletext charactes.
|
||||
Default value is 1.
|
||||
@item txt_duration
|
||||
Sets the display duration of the decoded teletext pages or subtitles in
|
||||
milliseconds. Default value is -1 which means infinity or until the next
|
||||
subtitle event comes.
|
||||
milliseconds. Default value is 30000 which is 30 seconds.
|
||||
@item txt_transparent
|
||||
Force transparent background of the generated teletext bitmaps. Default value
|
||||
is 0 which means an opaque background.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -25,12 +24,16 @@ Audible Format 2, 3, and 4 demuxer.
|
||||
|
||||
This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files.
|
||||
|
||||
@section aac
|
||||
@section applehttp
|
||||
|
||||
Raw Audio Data Transport Stream AAC demuxer.
|
||||
Apple HTTP Live Streaming demuxer.
|
||||
|
||||
This demuxer is used to demux an ADTS input containing a single AAC stream
|
||||
alongwith any ID3v1/2 or APE tags in it.
|
||||
This demuxer presents all AVStreams from all variant streams.
|
||||
The id field is set to the bitrate variant index number. By setting
|
||||
the discard flags on AVStreams (by pressing 'a' or 'v' in ffplay),
|
||||
the caller can decide which variant streams to actually receive.
|
||||
The total bitrate of the variant that the stream belongs to is
|
||||
available in a metadata key named "variant_bitrate".
|
||||
|
||||
@section apng
|
||||
|
||||
@@ -44,15 +47,12 @@ between the last fcTL and IEND chunks.
|
||||
|
||||
@table @option
|
||||
@item -ignore_loop @var{bool}
|
||||
Ignore the loop variable in the file if set. Default is enabled.
|
||||
|
||||
Ignore the loop variable in the file if set.
|
||||
@item -max_fps @var{int}
|
||||
Maximum framerate in frames per second. Default of 0 imposes no limit.
|
||||
|
||||
Maximum framerate in frames per second (0 for no limit).
|
||||
@item -default_fps @var{int}
|
||||
Default framerate in frames per second when none is specified in the file
|
||||
(0 meaning as fast as possible). Default is 15.
|
||||
|
||||
(0 meaning as fast as possible).
|
||||
@end table
|
||||
|
||||
@section asf
|
||||
@@ -103,7 +103,8 @@ backslash or single quotes.
|
||||
All subsequent file-related directives apply to that file.
|
||||
|
||||
@item @code{ffconcat version 1.0}
|
||||
Identify the script type and version.
|
||||
Identify the script type and version. It also sets the @option{safe} option
|
||||
to 1 if it was -1.
|
||||
|
||||
To make FFmpeg recognize the format automatically, this directive must
|
||||
appear exactly as is (no extra space or byte-order-mark) on the very first
|
||||
@@ -157,16 +158,6 @@ directive) will be reduced based on their specified Out point.
|
||||
Metadata of the packets of the file. The specified metadata will be set for
|
||||
each file packet. You can specify this directive multiple times to add multiple
|
||||
metadata entries.
|
||||
This directive is deprecated, use @code{file_packet_meta} instead.
|
||||
|
||||
@item @code{file_packet_meta @var{key} @var{value}}
|
||||
Metadata of the packets of the file. The specified metadata will be set for
|
||||
each file packet. You can specify this directive multiple times to add multiple
|
||||
metadata entries.
|
||||
|
||||
@item @code{option @var{key} @var{value}}
|
||||
Option to access, open and probe the file.
|
||||
Can be present multiple times.
|
||||
|
||||
@item @code{stream}
|
||||
Introduce a stream in the virtual file.
|
||||
@@ -184,20 +175,6 @@ subfiles will be used.
|
||||
This is especially useful for MPEG-PS (VOB) files, where the order of the
|
||||
streams is not reliable.
|
||||
|
||||
@item @code{stream_meta @var{key} @var{value}}
|
||||
Metadata for the stream.
|
||||
Can be present multiple times.
|
||||
|
||||
@item @code{stream_codec @var{value}}
|
||||
Codec for the stream.
|
||||
|
||||
@item @code{stream_extradata @var{hex_string}}
|
||||
Extradata for the string, encoded in hexadecimal.
|
||||
|
||||
@item @code{chapter @var{id} @var{start} @var{end}}
|
||||
Add a chapter. @var{id} is an unique identifier, possibly small and
|
||||
consecutive.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Options
|
||||
@@ -207,8 +184,7 @@ This demuxer accepts the following option:
|
||||
@table @option
|
||||
|
||||
@item safe
|
||||
If set to 1, reject unsafe file paths and directives.
|
||||
A file path is considered safe if it
|
||||
If set to 1, reject unsafe file paths. A file path is considered safe if it
|
||||
does not contain a protocol specification and is relative and all components
|
||||
only contain characters from the portable character set (letters, digits,
|
||||
period, underscore and hyphen) and have no period at the beginning of a
|
||||
@@ -218,6 +194,9 @@ If set to 0, any file name is accepted.
|
||||
|
||||
The default is 1.
|
||||
|
||||
-1 is equivalent to 1 if the format was automatically
|
||||
probed and 0 otherwise.
|
||||
|
||||
@item auto_convert
|
||||
If set to 1, try to perform automatic conversions on packet data to make the
|
||||
streams concatenable.
|
||||
@@ -264,44 +243,15 @@ file subdir/file-2.wav
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@section dash
|
||||
|
||||
Dynamic Adaptive Streaming over HTTP demuxer.
|
||||
|
||||
This demuxer presents all AVStreams found in the manifest.
|
||||
By setting the discard flags on AVStreams the caller can decide
|
||||
which streams to actually receive.
|
||||
Each stream mirrors the @code{id} and @code{bandwidth} properties from the
|
||||
@code{<Representation>} as metadata keys named "id" and "variant_bitrate" respectively.
|
||||
|
||||
@section imf
|
||||
|
||||
Interoperable Master Format demuxer.
|
||||
|
||||
This demuxer presents audio and video streams found in an IMF Composition.
|
||||
|
||||
@section flv, live_flv, kux
|
||||
@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.
|
||||
KUX is a flv variant used on the Youku platform.
|
||||
|
||||
@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}
|
||||
Allocate the streams according to the onMetaData array content.
|
||||
|
||||
@item -flv_ignore_prevtag @var{bool}
|
||||
Ignore the size of previous tag value.
|
||||
|
||||
@item -flv_full_metadata @var{bool}
|
||||
Output all context of the onMetadata.
|
||||
@end table
|
||||
|
||||
@section gif
|
||||
@@ -347,15 +297,6 @@ infinitely.
|
||||
|
||||
HLS demuxer
|
||||
|
||||
Apple HTTP Live Streaming demuxer.
|
||||
|
||||
This demuxer presents all AVStreams from all variant streams.
|
||||
The id field is set to the bitrate variant index number. By setting
|
||||
the discard flags on AVStreams (by pressing 'a' or 'v' in ffplay),
|
||||
the caller can decide which variant streams to actually receive.
|
||||
The total bitrate of the variant that the stream belongs to is
|
||||
available in a metadata key named "variant_bitrate".
|
||||
|
||||
It accepts the following options:
|
||||
|
||||
@table @option
|
||||
@@ -368,25 +309,6 @@ segment index to start live streams at (negative values are from the end).
|
||||
@item max_reload
|
||||
Maximum number of times a insufficient list is attempted to be reloaded.
|
||||
Default value is 1000.
|
||||
|
||||
@item m3u8_hold_counters
|
||||
The maximum number of times to load m3u8 when it refreshes without new segments.
|
||||
Default value is 1000.
|
||||
|
||||
@item http_persistent
|
||||
Use persistent HTTP connections. Applicable only for HTTP streams.
|
||||
Enabled by default.
|
||||
|
||||
@item http_multiple
|
||||
Use multiple HTTP connections for downloading HTTP segments.
|
||||
Enabled by default for HTTP/1.1 servers.
|
||||
|
||||
@item http_seekable
|
||||
Use HTTP partial requests for downloading HTTP segments.
|
||||
0 = disable, 1 = enable, -1 = auto, Default is auto.
|
||||
|
||||
@item seg_format_options
|
||||
Set options for the demuxer of media segments using a list of key=value pairs separated by @code{:}.
|
||||
@end table
|
||||
|
||||
@section image2
|
||||
@@ -497,17 +419,6 @@ nanosecond precision.
|
||||
@item video_size
|
||||
Set the video size of the images to read. If not specified the video
|
||||
size is guessed from the first image file in the sequence.
|
||||
@item export_path_metadata
|
||||
If set to 1, will add two extra fields to the metadata found in input, making them
|
||||
also available for other filters (see @var{drawtext} filter for examples). Default
|
||||
value is 0. The extra fields are described below:
|
||||
@table @option
|
||||
@item lavf.image2dec.source_path
|
||||
Corresponds to the full path to the input file being read.
|
||||
@item lavf.image2dec.source_basename
|
||||
Corresponds to the name of the file being read.
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
@@ -539,84 +450,14 @@ ffmpeg -framerate 10 -pattern_type glob -i "*.png" out.mkv
|
||||
|
||||
The Game Music Emu library is a collection of video game music file emulators.
|
||||
|
||||
See @url{https://bitbucket.org/mpyne/game-music-emu/overview} for more information.
|
||||
See @url{http://code.google.com/p/game-music-emu/} for more information.
|
||||
|
||||
It accepts the following options:
|
||||
Some files have multiple tracks. The demuxer will pick the first track by
|
||||
default. The @option{track_index} option can be used to select a different
|
||||
track. Track indexes start at 0. The demuxer exports the number of tracks as
|
||||
@var{tracks} meta data entry.
|
||||
|
||||
@table @option
|
||||
|
||||
@item track_index
|
||||
Set the index of which track to demux. The demuxer can only export one track.
|
||||
Track indexes start at 0. Default is to pick the first track. Number of tracks
|
||||
is exported as @var{tracks} metadata entry.
|
||||
|
||||
@item sample_rate
|
||||
Set the sampling rate of the exported track. Range is 1000 to 999999. Default is 44100.
|
||||
|
||||
@item max_size @emph{(bytes)}
|
||||
The demuxer buffers the entire file into memory. Adjust this value to set the maximum buffer size,
|
||||
which in turn, acts as a ceiling for the size of files that can be read.
|
||||
Default is 50 MiB.
|
||||
|
||||
@end table
|
||||
|
||||
@section libmodplug
|
||||
|
||||
ModPlug based module demuxer
|
||||
|
||||
See @url{https://github.com/Konstanty/libmodplug}
|
||||
|
||||
It will export one 2-channel 16-bit 44.1 kHz audio stream.
|
||||
Optionally, a @code{pal8} 16-color video stream can be exported with or without printed metadata.
|
||||
|
||||
It accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item noise_reduction
|
||||
Apply a simple low-pass filter. Can be 1 (on) or 0 (off). Default is 0.
|
||||
|
||||
@item reverb_depth
|
||||
Set amount of reverb. Range 0-100. Default is 0.
|
||||
|
||||
@item reverb_delay
|
||||
Set delay in ms, clamped to 40-250 ms. Default is 0.
|
||||
|
||||
@item bass_amount
|
||||
Apply bass expansion a.k.a. XBass or megabass. Range is 0 (quiet) to 100 (loud). Default is 0.
|
||||
|
||||
@item bass_range
|
||||
Set cutoff i.e. upper-bound for bass frequencies. Range is 10-100 Hz. Default is 0.
|
||||
|
||||
@item surround_depth
|
||||
Apply a Dolby Pro-Logic surround effect. Range is 0 (quiet) to 100 (heavy). Default is 0.
|
||||
|
||||
@item surround_delay
|
||||
Set surround delay in ms, clamped to 5-40 ms. Default is 0.
|
||||
|
||||
@item max_size
|
||||
The demuxer buffers the entire file into memory. Adjust this value to set the maximum buffer size,
|
||||
which in turn, acts as a ceiling for the size of files that can be read. Range is 0 to 100 MiB.
|
||||
0 removes buffer size limit (not recommended). Default is 5 MiB.
|
||||
|
||||
@item video_stream_expr
|
||||
String which is evaluated using the eval API to assign colors to the generated video stream.
|
||||
Variables which can be used are @code{x}, @code{y}, @code{w}, @code{h}, @code{t}, @code{speed},
|
||||
@code{tempo}, @code{order}, @code{pattern} and @code{row}.
|
||||
|
||||
@item video_stream
|
||||
Generate video stream. Can be 1 (on) or 0 (off). Default is 0.
|
||||
|
||||
@item video_stream_w
|
||||
Set video frame width in 'chars' where one char indicates 8 pixels. Range is 20-512. Default is 30.
|
||||
|
||||
@item video_stream_h
|
||||
Set video frame height in 'chars' where one char indicates 8 pixels. Range is 20-512. Default is 30.
|
||||
|
||||
@item video_stream_ptxt
|
||||
Print metadata on video stream. Includes @code{speed}, @code{tempo}, @code{order}, @code{pattern},
|
||||
@code{row} and @code{ts} (time in ms). Can be 1 (on) or 0 (off). Default is 1.
|
||||
|
||||
@end table
|
||||
For very large files, the @option{max_size} option may have to be adjusted.
|
||||
|
||||
@section libopenmpt
|
||||
|
||||
@@ -645,13 +486,9 @@ Set the sample rate for libopenmpt to output.
|
||||
Range is from 1000 to INT_MAX. The value default is 48000.
|
||||
@end table
|
||||
|
||||
@section mov/mp4/3gp
|
||||
@section mov/mp4/3gp/QuickTime
|
||||
|
||||
Demuxer for Quicktime File Format & ISO/IEC Base Media File Format (ISO/IEC 14496-12 or MPEG-4 Part 12, ISO/IEC 15444-12 or JPEG 2000 Part 12).
|
||||
|
||||
Registered extensions: mov, mp4, m4a, 3gp, 3g2, mj2, psp, m4b, ism, ismv, isma, f4v
|
||||
|
||||
@subsection Options
|
||||
QuickTime / MP4 demuxer.
|
||||
|
||||
This demuxer accepts the following options:
|
||||
@table @option
|
||||
@@ -662,88 +499,10 @@ Enabling this can theoretically leak information in some use cases.
|
||||
@item use_absolute_path
|
||||
Allows loading of external tracks via absolute paths, disabled by default.
|
||||
Enabling this poses a security risk. It should only be enabled if the source
|
||||
is known to be non-malicious.
|
||||
is known to be non malicious.
|
||||
|
||||
@item seek_streams_individually
|
||||
When seeking, identify the closest point in each stream individually and demux packets in
|
||||
that stream from identified point. This can lead to a different sequence of packets compared
|
||||
to demuxing linearly from the beginning. Default is true.
|
||||
|
||||
@item ignore_editlist
|
||||
Ignore any edit list atoms. The demuxer, by default, modifies the stream index to reflect the
|
||||
timeline described by the edit list. Default is false.
|
||||
|
||||
@item advanced_editlist
|
||||
Modify the stream index to reflect the timeline described by the edit list. @code{ignore_editlist}
|
||||
must be set to false for this option to be effective.
|
||||
If both @code{ignore_editlist} and this option are set to false, then only the
|
||||
start of the stream index is modified to reflect initial dwell time or starting timestamp
|
||||
described by the edit list. Default is true.
|
||||
|
||||
@item ignore_chapters
|
||||
Don't parse chapters. This includes GoPro 'HiLight' tags/moments. Note that chapters are
|
||||
only parsed when input is seekable. Default is false.
|
||||
|
||||
@item use_mfra_for
|
||||
For seekable fragmented input, set fragment's starting timestamp from media fragment random access box, if present.
|
||||
|
||||
Following options are available:
|
||||
@table @samp
|
||||
@item auto
|
||||
Auto-detect whether to set mfra timestamps as PTS or DTS @emph{(default)}
|
||||
|
||||
@item dts
|
||||
Set mfra timestamps as DTS
|
||||
|
||||
@item pts
|
||||
Set mfra timestamps as PTS
|
||||
|
||||
@item 0
|
||||
Don't use mfra box to set timestamps
|
||||
@end table
|
||||
|
||||
@item use_tfdt
|
||||
For fragmented input, set fragment's starting timestamp to @code{baseMediaDecodeTime} from the @code{tfdt} box.
|
||||
Default is enabled, which will prefer to use the @code{tfdt} box to set DTS. Disable to use the @code{earliest_presentation_time} from the @code{sidx} box.
|
||||
In either case, the timestamp from the @code{mfra} box will be used if it's available and @code{use_mfra_for} is
|
||||
set to pts or dts.
|
||||
|
||||
@item export_all
|
||||
Export unrecognized boxes within the @var{udta} box as metadata entries. The first four
|
||||
characters of the box type are set as the key. Default is false.
|
||||
|
||||
@item export_xmp
|
||||
Export entire contents of @var{XMP_} box and @var{uuid} box as a string with key @code{xmp}. Note that
|
||||
if @code{export_all} is set and this option isn't, the contents of @var{XMP_} box are still exported
|
||||
but with key @code{XMP_}. Default is false.
|
||||
|
||||
@item activation_bytes
|
||||
4-byte key required to decrypt Audible AAX and AAX+ files. See Audible AAX subsection below.
|
||||
|
||||
@item audible_fixed_key
|
||||
Fixed key used for handling Audible AAX/AAX+ files. It has been pre-set so should not be necessary to
|
||||
specify.
|
||||
|
||||
@item decryption_key
|
||||
16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
|
||||
|
||||
@item max_stts_delta
|
||||
Very high sample deltas written in a trak's stts box may occasionally be intended but usually they are written in
|
||||
error or used to store a negative value for dts correction when treated as signed 32-bit integers. This option lets
|
||||
the user set an upper limit, beyond which the delta is clamped to 1. Values greater than the limit if negative when
|
||||
cast to int32 are used to adjust onward dts.
|
||||
|
||||
Unit is the track time scale. Range is 0 to UINT_MAX. Default is @code{UINT_MAX - 48000*10} which allows upto
|
||||
a 10 second dts correction for 48 kHz audio streams while accommodating 99.9% of @code{uint32} range.
|
||||
@end table
|
||||
|
||||
@subsection Audible AAX
|
||||
|
||||
Audible AAX files are encrypted M4B files, and they can be decrypted by specifying a 4 byte activation secret.
|
||||
@example
|
||||
ffmpeg -activation_bytes 1CEB00DA -i test.aax -vn -c:a copy output.mp4
|
||||
@end example
|
||||
|
||||
@section mpegts
|
||||
|
||||
MPEG-2 transport stream demuxer.
|
||||
@@ -754,9 +513,6 @@ This demuxer accepts the following options:
|
||||
Set size limit for looking up a new synchronization. Default value is
|
||||
65536.
|
||||
|
||||
@item skip_unknown_pmt
|
||||
Skip PMTs for programs not defined in the PAT. Default value is 0.
|
||||
|
||||
@item fix_teletext_pts
|
||||
Override teletext packet PTS and DTS values with the timestamps calculated
|
||||
from the PCR of the first program which the teletext stream is part of and is
|
||||
@@ -771,10 +527,6 @@ Show the detected raw packet size, cannot be set by the user.
|
||||
Scan and combine all PMTs. The value is an integer with value from -1
|
||||
to 1 (-1 means automatic setting, 1 means enabled, 0 means
|
||||
disabled). Default value is -1.
|
||||
|
||||
@item merge_pmt_versions
|
||||
Re-use existing streams when a PMT's version is updated and elementary
|
||||
streams move to different PIDs. Default value is 0.
|
||||
@end table
|
||||
|
||||
@section mpjpeg
|
||||
@@ -872,20 +624,4 @@ Example: convert the captions to a format most players understand:
|
||||
ffmpeg -i http://www.ted.com/talks/subtitles/id/1/lang/en talk1-en.srt
|
||||
@end example
|
||||
|
||||
@section vapoursynth
|
||||
|
||||
Vapoursynth wrapper.
|
||||
|
||||
Due to security concerns, Vapoursynth scripts will not
|
||||
be autodetected so the input format has to be forced. For ff* CLI tools,
|
||||
add @code{-f vapoursynth} before the input @code{-i yourscript.vpy}.
|
||||
|
||||
This demuxer accepts the following option:
|
||||
@table @option
|
||||
@item max_script_size
|
||||
The demuxer buffers the entire script into memory. Adjust this value to set the maximum buffer size,
|
||||
which in turn, acts as a ceiling for the size of scripts that can be read.
|
||||
Default is 1 MiB.
|
||||
@end table
|
||||
|
||||
@c man end DEMUXERS
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
# FFmpeg project
|
||||
|
||||
## Organisation
|
||||
|
||||
The FFmpeg project is organized through a community working on global consensus.
|
||||
|
||||
Decisions are taken by the ensemble of active members, through voting and
|
||||
are aided by two committees.
|
||||
|
||||
## General Assembly
|
||||
|
||||
The ensemble of active members is called the General Assembly (GA).
|
||||
|
||||
The General Assembly is sovereign and legitimate for all its decisions
|
||||
regarding the FFmpeg project.
|
||||
|
||||
The General Assembly is made up of active contributors.
|
||||
|
||||
Contributors are considered "active contributors" if they have pushed more
|
||||
than 20 patches in the last 36 months in the main FFmpeg repository, or
|
||||
if they have been voted in by the GA.
|
||||
|
||||
Additional members are added to the General Assembly through a vote after
|
||||
proposal by a member of the General Assembly.
|
||||
They are part of the GA for two years, after which they need a confirmation by
|
||||
the GA.
|
||||
|
||||
## Voting
|
||||
|
||||
Voting is done using a ranked voting system, currently running on https://vote.ffmpeg.org/ .
|
||||
|
||||
Majority vote means more than 50% of the expressed ballots.
|
||||
|
||||
## Technical Committee
|
||||
|
||||
The Technical Committee (TC) is here to arbitrate and make decisions when
|
||||
technical conflicts occur in the project.
|
||||
They will consider the merits of all the positions, judge them and make a
|
||||
decision.
|
||||
|
||||
The TC resolves technical conflicts but is not a technical steering committee.
|
||||
|
||||
Decisions by the TC are binding for all the contributors.
|
||||
|
||||
Decisions made by the TC can be re-opened after 1 year or by a majority vote
|
||||
of the General Assembly, requested by one of the member of the GA.
|
||||
|
||||
The TC is elected by the General Assembly for a duration of 1 year, and
|
||||
is composed of 5 members.
|
||||
Members can be re-elected if they wish. A majority vote in the General Assembly
|
||||
can trigger a new election of the TC.
|
||||
|
||||
The members of the TC can be elected from outside of the GA.
|
||||
Candidates for election can either be suggested or self-nominated.
|
||||
|
||||
The conflict resolution process is detailed in the [resolution process](resolution_process.md) document.
|
||||
|
||||
## Community committee
|
||||
|
||||
The Community Committee (CC) is here to arbitrage and make decisions when
|
||||
inter-personal conflicts occur in the project. It will decide quickly and
|
||||
take actions, for the sake of the project.
|
||||
|
||||
The CC can remove privileges of offending members, including removal of
|
||||
commit access and temporary ban from the community.
|
||||
|
||||
Decisions made by the CC can be re-opened after 1 year or by a majority vote
|
||||
of the General Assembly. Indefinite bans from the community must be confirmed
|
||||
by the General Assembly, in a majority vote.
|
||||
|
||||
The CC is elected by the General Assembly for a duration of 1 year, and is
|
||||
composed of 5 members.
|
||||
Members can be re-elected if they wish. A majority vote in the General Assembly
|
||||
can trigger a new election of the CC.
|
||||
|
||||
The members of the CC can be elected from outside of the GA.
|
||||
Candidates for election can either be suggested or self-nominated.
|
||||
|
||||
The CC is governed by and responsible for enforcing the Code of Conduct.
|
||||
@@ -1,91 +0,0 @@
|
||||
# Technical Committee
|
||||
|
||||
_This document only makes sense with the rules from [the community document](community)_.
|
||||
|
||||
The Technical Committee (**TC**) is here to arbitrate and make decisions when
|
||||
technical conflicts occur in the project.
|
||||
|
||||
The TC main role is to resolve technical conflicts.
|
||||
It is therefore not a technical steering committee, but it is understood that
|
||||
some decisions might impact the future of the project.
|
||||
|
||||
# Process
|
||||
|
||||
## Seizing
|
||||
|
||||
The TC can take possession of any technical matter that it sees fit.
|
||||
|
||||
To involve the TC in a matter, email tc@ or CC them on an ongoing discussion.
|
||||
|
||||
As members of TC are developers, they also can email tc@ to raise an issue.
|
||||
|
||||
## Announcement
|
||||
|
||||
The TC, once seized, must announce itself on the main mailing list, with a _[TC]_ tag.
|
||||
|
||||
The TC has 2 modes of operation: a RFC one and an internal one.
|
||||
|
||||
If the TC thinks it needs the input from the larger community, the TC can call
|
||||
for a RFC. Else, it can decide by itself.
|
||||
|
||||
If the disagreement involves a member of the TC, that member should recuse
|
||||
themselves from the decision.
|
||||
|
||||
The decision to use a RFC process or an internal discussion is a discretionary
|
||||
decision of the TC.
|
||||
|
||||
The TC can also reject a seizure for a few reasons such as:
|
||||
the matter was not discussed enough previously; it lacks expertise to reach a
|
||||
beneficial decision on the matter; or the matter is too trivial.
|
||||
|
||||
### RFC call
|
||||
|
||||
In the RFC mode, one person from the TC posts on the mailing list the
|
||||
technical question and will request input from the community.
|
||||
|
||||
The mail will have the following specification:
|
||||
* a precise title
|
||||
* a specific tag [TC RFC]
|
||||
* a top-level email
|
||||
* contain a precise question that does not exceed 100 words and that is answerable by developers
|
||||
* may have an extra description, or a link to a previous discussion, if deemed necessary,
|
||||
* contain a precise end date for the answers.
|
||||
|
||||
The answers from the community must be on the main mailing list and must have
|
||||
the following specification:
|
||||
* keep the tag and the title unchanged
|
||||
* limited to 400 words
|
||||
* a first-level, answering directly to the main email
|
||||
* answering to the question.
|
||||
|
||||
Further replies to answers are permitted, as long as they conform to the
|
||||
community standards of politeness, they are limited to 100 words, and are not
|
||||
nested more than once. (max-depth=2)
|
||||
|
||||
After the end-date, mails on the thread will be ignored.
|
||||
|
||||
Violations of those rules will be escalated through the Community Committee.
|
||||
|
||||
After all the emails are in, the TC has 96 hours to give its final decision.
|
||||
Exceptionally, the TC can request an extra delay, that will be notified on the
|
||||
mailing list.
|
||||
|
||||
### Within TC
|
||||
|
||||
In the internal case, the TC has 96 hours to give its final decision.
|
||||
Exceptionally, the TC can request an extra delay.
|
||||
|
||||
|
||||
## Decisions
|
||||
|
||||
The decisions from the TC will be sent on the mailing list, with the _[TC]_ tag.
|
||||
|
||||
Internally, the TC should take decisions with a majority, or using
|
||||
ranked-choice voting.
|
||||
|
||||
The decision from the TC should be published with a summary of the reasons that
|
||||
lead to this decision.
|
||||
|
||||
The decisions from the TC are final, until the matters are reopened after
|
||||
no less than one year.
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Notes for external developers
|
||||
@chapter Developers Guide
|
||||
|
||||
@section Notes for external developers
|
||||
|
||||
This document is mostly useful for internal FFmpeg developers.
|
||||
External developers who need to use the API in their application should
|
||||
@@ -28,13 +30,15 @@ For more detailed legal information about the use of FFmpeg in
|
||||
external programs read the @file{LICENSE} file in the source tree and
|
||||
consult @url{https://ffmpeg.org/legal.html}.
|
||||
|
||||
@chapter Contributing
|
||||
@section Contributing
|
||||
|
||||
There are 2 ways by which code gets into FFmpeg:
|
||||
There are 3 ways by which code gets into FFmpeg.
|
||||
@itemize @bullet
|
||||
@item Submitting patches to the ffmpeg-devel mailing list.
|
||||
@item Submitting patches to the main developer mailing list.
|
||||
See @ref{Submitting patches} for details.
|
||||
@item Directly committing changes to the main tree.
|
||||
@item Committing changes to a git clone, for example on github.com or
|
||||
gitorious.org. And asking us to merge these changes.
|
||||
@end itemize
|
||||
|
||||
Whichever way, changes should be reviewed by the maintainer of the code
|
||||
@@ -43,9 +47,9 @@ The developer making the commit and the author are responsible for their changes
|
||||
and should try to fix issues their commit causes.
|
||||
|
||||
@anchor{Coding Rules}
|
||||
@chapter Coding Rules
|
||||
@section Coding Rules
|
||||
|
||||
@section Code formatting conventions
|
||||
@subsection Code formatting conventions
|
||||
|
||||
There are the following guidelines regarding the indentation in files:
|
||||
|
||||
@@ -70,7 +74,7 @@ The presentation is one inspired by 'indent -i4 -kr -nut'.
|
||||
The main priority in FFmpeg is simplicity and small code size in order to
|
||||
minimize the bug count.
|
||||
|
||||
@section Comments
|
||||
@subsection Comments
|
||||
Use the JavaDoc/Doxygen format (see examples below) so that code documentation
|
||||
can be generated automatically. All nontrivial functions should have a comment
|
||||
above them explaining what the function does, even if it is just one sentence.
|
||||
@@ -110,7 +114,7 @@ int myfunc(int my_parameter)
|
||||
...
|
||||
@end example
|
||||
|
||||
@section C language features
|
||||
@subsection C language features
|
||||
|
||||
FFmpeg is programmed in the ISO C90 language with a few additional
|
||||
features from ISO C99, namely:
|
||||
@@ -128,12 +132,6 @@ designated struct initializers (@samp{struct s x = @{ .i = 17 @};});
|
||||
@item
|
||||
compound literals (@samp{x = (struct s) @{ 17, 23 @};}).
|
||||
|
||||
@item
|
||||
for loops with variable definition (@samp{for (int i = 0; i < 8; i++)});
|
||||
|
||||
@item
|
||||
Variadic macros (@samp{#define ARRAY(nb, ...) (int[nb + 1])@{ nb, __VA_ARGS__ @}});
|
||||
|
||||
@item
|
||||
Implementation defined behavior for signed integers is assumed to match the
|
||||
expected behavior for two's complement. Non representable values in integer
|
||||
@@ -162,7 +160,7 @@ mixing statements and declarations;
|
||||
GCC statement expressions (@samp{(x = (@{ int y = 4; y; @})}).
|
||||
@end itemize
|
||||
|
||||
@section Naming conventions
|
||||
@subsection Naming conventions
|
||||
All names should be composed with underscores (_), not CamelCase. For example,
|
||||
@samp{avfilter_get_video_buffer} is an acceptable function name and
|
||||
@samp{AVFilterGetVideo} is not. The exception from this are type names, like
|
||||
@@ -186,7 +184,7 @@ e.g. @samp{ff_w64_demuxer}.
|
||||
@item
|
||||
For variables and functions visible outside of file scope, used internally
|
||||
across multiple libraries, use @code{avpriv_} as prefix, for example,
|
||||
@samp{avpriv_report_missing_feature}.
|
||||
@samp{avpriv_aac_parse_header}.
|
||||
|
||||
@item
|
||||
Each library has its own prefix for public symbols, in addition to the
|
||||
@@ -206,7 +204,7 @@ letter as they are reserved by the C standard. Names starting with @code{_}
|
||||
are reserved at the file level and may not be used for externally visible
|
||||
symbols. If in doubt, just avoid names starting with @code{_} altogether.
|
||||
|
||||
@section Miscellaneous conventions
|
||||
@subsection Miscellaneous conventions
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
@@ -218,7 +216,7 @@ Casts should be used only when necessary. Unneeded parentheses
|
||||
should also be avoided if they don't make the code easier to understand.
|
||||
@end itemize
|
||||
|
||||
@section Editor configuration
|
||||
@subsection Editor configuration
|
||||
In order to configure Vim to follow FFmpeg formatting conventions, paste
|
||||
the following snippet into your @file{.vimrc}:
|
||||
@example
|
||||
@@ -251,9 +249,9 @@ For Emacs, add these roughly equivalent lines to your @file{.emacs.d/init.el}:
|
||||
(setq c-default-style "ffmpeg")
|
||||
@end lisp
|
||||
|
||||
@chapter Development Policy
|
||||
@section Development Policy
|
||||
|
||||
@section Patches/Committing
|
||||
@subsection Patches/Committing
|
||||
@subheading Licenses for patches must be compatible with FFmpeg.
|
||||
Contributions should be licensed under the
|
||||
@uref{http://www.gnu.org/licenses/lgpl-2.1.html, LGPL 2.1},
|
||||
@@ -352,7 +350,7 @@ time-frame (12h for build failures and security fixes, 3 days small changes,
|
||||
1 week for big patches) then commit your patch if you think it is OK.
|
||||
Also note, the maintainer can simply ask for more time to review!
|
||||
|
||||
@section Code
|
||||
@subsection Code
|
||||
@subheading API/ABI changes should be discussed before they are made.
|
||||
Do not change behavior of the programs (renaming options etc) or public
|
||||
API or ABI without first discussing it on the ffmpeg-devel mailing list.
|
||||
@@ -383,29 +381,12 @@ Never write to unallocated memory, never write over the end of arrays,
|
||||
always check values read from some untrusted source before using them
|
||||
as array index or other risky things.
|
||||
|
||||
@section Documentation/Other
|
||||
@subheading Subscribe to the ffmpeg-devel mailing list.
|
||||
It is important to be subscribed to the
|
||||
@uref{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel, ffmpeg-devel}
|
||||
mailing list. Almost any non-trivial patch is to be sent there for review.
|
||||
Other developers may have comments about your contribution. We expect you see
|
||||
those comments, and to improve it if requested. (N.B. Experienced committers
|
||||
have other channels, and may sometimes skip review for trivial fixes.) Also,
|
||||
discussion here about bug fixes and FFmpeg improvements by other developers may
|
||||
be helpful information for you. Finally, by being a list subscriber, your
|
||||
contribution will be posted immediately to the list, without the moderation
|
||||
hold which messages from non-subscribers experience.
|
||||
|
||||
However, it is more important to the project that we receive your patch than
|
||||
that you be subscribed to the ffmpeg-devel list. If you have a patch, and don't
|
||||
want to subscribe and discuss the patch, then please do send it to the list
|
||||
anyway.
|
||||
|
||||
@subsection Documentation/Other
|
||||
@subheading Subscribe to the ffmpeg-cvslog mailing list.
|
||||
Diffs of all commits are sent to the
|
||||
@uref{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-cvslog, ffmpeg-cvslog}
|
||||
mailing list. Some developers read this list to review all code base changes
|
||||
from all sources. Subscribing to this list is not mandatory.
|
||||
It is important to do this as the diffs of all commits are sent there and
|
||||
reviewed by all the other developers. Bugs and possible improvements or
|
||||
general questions regarding commits are discussed there. We expect you to
|
||||
react if problems with your code are uncovered.
|
||||
|
||||
@subheading Keep the documentation up to date.
|
||||
Update the documentation if you change behavior or add features. If you are
|
||||
@@ -425,7 +406,7 @@ finding a new maintainer and also don't forget to update the @file{MAINTAINERS}
|
||||
|
||||
We think our rules are not too hard. If you have comments, contact us.
|
||||
|
||||
@chapter Code of conduct
|
||||
@section Code of conduct
|
||||
|
||||
Be friendly and respectful towards others and third parties.
|
||||
Treat others the way you yourself want to be treated.
|
||||
@@ -455,7 +436,7 @@ Finally, keep in mind the immortal words of Bill and Ted,
|
||||
"Be excellent to each other."
|
||||
|
||||
@anchor{Submitting patches}
|
||||
@chapter Submitting patches
|
||||
@section Submitting patches
|
||||
|
||||
First, read the @ref{Coding Rules} above if you did not yet, in particular
|
||||
the rules regarding patch submission.
|
||||
@@ -494,22 +475,6 @@ patch is inline or attached per mail.
|
||||
You can check @url{https://patchwork.ffmpeg.org}, if your patch does not show up, its mime type
|
||||
likely was wrong.
|
||||
|
||||
@subheading Sending patches from email clients
|
||||
Using @code{git send-email} might not be desirable for everyone. The
|
||||
following trick allows to send patches via email clients in a safe
|
||||
way. It has been tested with Outlook and Thunderbird (with X-Unsent
|
||||
extension) and might work with other applications.
|
||||
|
||||
Create your patch like this:
|
||||
|
||||
@verbatim
|
||||
git format-patch -s -o "outputfolder" --add-header "X-Unsent: 1" --suffix .eml --to ffmpeg-devel@ffmpeg.org -1 1a2b3c4d
|
||||
@end verbatim
|
||||
|
||||
Now you'll just need to open the eml file with the email application
|
||||
and execute 'Send'.
|
||||
|
||||
@subheading Reviews
|
||||
Your patch will be reviewed on the mailing list. You will likely be asked
|
||||
to make some changes and are expected to send in an improved version that
|
||||
incorporates the requests from the review. This process may go through
|
||||
@@ -520,7 +485,7 @@ Give us a few days to react. But if some time passes without reaction,
|
||||
send a reminder by email. Your patch should eventually be dealt with.
|
||||
|
||||
|
||||
@chapter New codecs or formats checklist
|
||||
@section New codecs or formats checklist
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
@@ -572,7 +537,7 @@ Did you make sure it compiles standalone, i.e. with
|
||||
@end enumerate
|
||||
|
||||
|
||||
@chapter Patch submission checklist
|
||||
@section patch submission checklist
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
@@ -582,9 +547,9 @@ Does @code{make fate} pass with the patch applied?
|
||||
Was the patch generated with git format-patch or send-email?
|
||||
|
||||
@item
|
||||
Did you sign-off your patch? (@code{git commit -s})
|
||||
See @uref{https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/process/submitting-patches.rst, Sign your work} for the meaning
|
||||
of @dfn{sign-off}.
|
||||
Did you sign off your patch? (git commit -s)
|
||||
See @url{http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob_plain;f=Documentation/SubmittingPatches} for the meaning
|
||||
of sign off.
|
||||
|
||||
@item
|
||||
Did you provide a clear git commit log message?
|
||||
@@ -641,7 +606,7 @@ If the patch fixes a bug, did you provide a verbose analysis of the bug?
|
||||
If the patch fixes a bug, did you provide enough information, including
|
||||
a sample, so the bug can be reproduced and the fix can be verified?
|
||||
Note please do not attach samples >100k to mails but rather provide a
|
||||
URL, you can upload to @url{https://streams.videolan.org/upload/}.
|
||||
URL, you can upload to ftp://upload.ffmpeg.org.
|
||||
|
||||
@item
|
||||
Did you provide a verbose summary about what the patch does change?
|
||||
@@ -685,7 +650,7 @@ Test your code with valgrind and or Address Sanitizer to ensure it's free
|
||||
of leaks, out of array accesses, etc.
|
||||
@end enumerate
|
||||
|
||||
@chapter Patch review process
|
||||
@section Patch review process
|
||||
|
||||
All patches posted to ffmpeg-devel will be reviewed, unless they contain a
|
||||
clear note that the patch is not for the git master branch.
|
||||
@@ -716,7 +681,7 @@ to be reviewed, please consider helping to review other patches, that is a great
|
||||
way to get everyone's patches reviewed sooner.
|
||||
|
||||
@anchor{Regression tests}
|
||||
@chapter Regression tests
|
||||
@section Regression tests
|
||||
|
||||
Before submitting a patch (or committing to the repository), you should at least
|
||||
test that you did not break anything.
|
||||
@@ -727,7 +692,7 @@ Running 'make fate' accomplishes this, please see @url{fate.html} for details.
|
||||
this case, the reference results of the regression tests shall be modified
|
||||
accordingly].
|
||||
|
||||
@section Adding files to the fate-suite dataset
|
||||
@subsection Adding files to the fate-suite dataset
|
||||
|
||||
When there is no muxer or encoder available to generate test media for a
|
||||
specific test then the media has to be included in the fate-suite.
|
||||
@@ -738,7 +703,7 @@ Once you have a working fate test and fate sample, provide in the commit
|
||||
message or introductory message for the patch series that you post to
|
||||
the ffmpeg-devel mailing list, a direct link to download the sample media.
|
||||
|
||||
@section Visualizing Test Coverage
|
||||
@subsection Visualizing Test Coverage
|
||||
|
||||
The FFmpeg build system allows visualizing the test coverage in an easy
|
||||
manner with the coverage tools @code{gcov}/@code{lcov}. This involves
|
||||
@@ -765,7 +730,7 @@ You can use the command @code{make lcov-reset} to reset the coverage
|
||||
measurements. You will need to rerun @code{make lcov} after running a
|
||||
new test.
|
||||
|
||||
@section Using Valgrind
|
||||
@subsection Using Valgrind
|
||||
|
||||
The configure script provides a shortcut for using valgrind to spot bugs
|
||||
related to memory handling. Just add the option
|
||||
@@ -779,7 +744,7 @@ In case you need finer control over how valgrind is invoked, use the
|
||||
your configure line instead.
|
||||
|
||||
@anchor{Release process}
|
||||
@chapter Release process
|
||||
@section Release process
|
||||
|
||||
FFmpeg maintains a set of @strong{release branches}, which are the
|
||||
recommended deliverable for system integrators and distributors (such as
|
||||
@@ -811,7 +776,7 @@ adjustments to the symbol versioning file. Please discuss such changes
|
||||
on the @strong{ffmpeg-devel} mailing list in time to allow forward planning.
|
||||
|
||||
@anchor{Criteria for Point Releases}
|
||||
@section Criteria for Point Releases
|
||||
@subsection Criteria for Point Releases
|
||||
|
||||
Changes that match the following criteria are valid candidates for
|
||||
inclusion into a point release:
|
||||
@@ -835,7 +800,7 @@ point releases of the same release branch.
|
||||
The order for checking the rules is (1 OR 2 OR 3) AND 4.
|
||||
|
||||
|
||||
@section Release Checklist
|
||||
@subsection Release Checklist
|
||||
|
||||
The release process involves the following steps:
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
OUT_DIR="${1}"
|
||||
SRC_DIR="${2}"
|
||||
DOXYFILE="${3}"
|
||||
DOXYGEN="${4}"
|
||||
DOXYFILE="${2}"
|
||||
DOXYGEN="${3}"
|
||||
|
||||
shift 4
|
||||
|
||||
cd ${SRC_DIR}
|
||||
shift 3
|
||||
|
||||
if [ -e "VERSION" ]; then
|
||||
VERSION=`cat "VERSION"`
|
||||
|
||||
1421
doc/encoders.texi
1421
doc/encoders.texi
File diff suppressed because it is too large
Load Diff
10
doc/examples/.gitignore
vendored
10
doc/examples/.gitignore
vendored
@@ -1,16 +1,12 @@
|
||||
/avio_list_dir
|
||||
/avio_dir_cmd
|
||||
/avio_reading
|
||||
/decode_audio
|
||||
/decode_video
|
||||
/decoding_encoding
|
||||
/demuxing_decoding
|
||||
/encode_audio
|
||||
/encode_video
|
||||
/extract_mvs
|
||||
/filter_audio
|
||||
/filtering_audio
|
||||
/filtering_video
|
||||
/http_multiclient
|
||||
/hw_decode
|
||||
/metadata
|
||||
/muxing
|
||||
/pc-uninstalled
|
||||
@@ -20,5 +16,3 @@
|
||||
/scaling_video
|
||||
/transcode_aac
|
||||
/transcoding
|
||||
/vaapi_encode
|
||||
/vaapi_transcode
|
||||
|
||||
@@ -1,64 +1,46 @@
|
||||
EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir
|
||||
EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading
|
||||
EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio
|
||||
EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video
|
||||
EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
|
||||
EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio
|
||||
EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video
|
||||
EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE) += extract_mvs
|
||||
EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio
|
||||
EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE) += filtering_audio
|
||||
EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE) += filtering_video
|
||||
EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE) += http_multiclient
|
||||
EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode
|
||||
EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata
|
||||
EXAMPLES-$(CONFIG_MUXING_EXAMPLE) += muxing
|
||||
EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec
|
||||
EXAMPLES-$(CONFIG_REMUXING_EXAMPLE) += remuxing
|
||||
EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio
|
||||
EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
|
||||
EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
|
||||
EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE) += transcoding
|
||||
EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE) += vaapi_encode
|
||||
EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE) += vaapi_transcode
|
||||
# use pkg-config for getting CFLAGS and LDLIBS
|
||||
FFMPEG_LIBS= libavdevice \
|
||||
libavformat \
|
||||
libavfilter \
|
||||
libavcodec \
|
||||
libswresample \
|
||||
libswscale \
|
||||
libavutil \
|
||||
|
||||
EXAMPLES := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
|
||||
EXAMPLES_G := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
|
||||
ALL_EXAMPLES := $(EXAMPLES) $(EXAMPLES-:%=doc/examples/%$(PROGSSUF)$(EXESUF))
|
||||
ALL_EXAMPLES_G := $(EXAMPLES_G) $(EXAMPLES-:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
|
||||
PROGS += $(EXAMPLES)
|
||||
CFLAGS += -Wall -g
|
||||
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
|
||||
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
|
||||
|
||||
EXAMPLE_MAKEFILE := $(SRC_PATH)/doc/examples/Makefile
|
||||
EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/README $(EXAMPLE_MAKEFILE)
|
||||
EXAMPLES= avio_dir_cmd \
|
||||
avio_reading \
|
||||
decoding_encoding \
|
||||
demuxing_decoding \
|
||||
extract_mvs \
|
||||
filtering_video \
|
||||
filtering_audio \
|
||||
http_multiclient \
|
||||
metadata \
|
||||
muxing \
|
||||
remuxing \
|
||||
resampling_audio \
|
||||
scaling_video \
|
||||
transcode_aac \
|
||||
transcoding \
|
||||
|
||||
$(foreach P,$(EXAMPLES),$(eval OBJS-$(P:%$(PROGSSUF)$(EXESUF)=%) = $(P:%$(PROGSSUF)$(EXESUF)=%).o))
|
||||
$(EXAMPLES_G): %$(PROGSSUF)_g$(EXESUF): %.o
|
||||
OBJS=$(addsuffix .o,$(EXAMPLES))
|
||||
|
||||
examples: $(EXAMPLES)
|
||||
# the following examples make explicit use of the math library
|
||||
avcodec: LDLIBS += -lm
|
||||
decoding_encoding: LDLIBS += -lm
|
||||
muxing: LDLIBS += -lm
|
||||
resampling_audio: LDLIBS += -lm
|
||||
|
||||
$(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.o): | doc/examples
|
||||
OUTDIRS += doc/examples
|
||||
.phony: all clean-test clean
|
||||
|
||||
DOXY_INPUT += $(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.c)
|
||||
all: $(OBJS) $(EXAMPLES)
|
||||
|
||||
install: install-examples
|
||||
clean-test:
|
||||
$(RM) test*.pgm test.h264 test.mp2 test.sw test.mpg
|
||||
|
||||
install-examples: $(EXAMPLES_FILES)
|
||||
$(Q)mkdir -p "$(DATADIR)/examples"
|
||||
$(INSTALL) -m 644 $(EXAMPLES_FILES) "$(DATADIR)/examples"
|
||||
$(INSTALL) -m 644 $(EXAMPLE_MAKEFILE:%=%.example) "$(DATADIR)/examples/Makefile"
|
||||
|
||||
uninstall: uninstall-examples
|
||||
|
||||
uninstall-examples:
|
||||
$(RM) -r "$(DATADIR)/examples"
|
||||
|
||||
examplesclean:
|
||||
$(RM) $(ALL_EXAMPLES) $(ALL_EXAMPLES_G)
|
||||
$(RM) $(CLEANSUFFIXES:%=doc/examples/%)
|
||||
|
||||
docclean:: examplesclean
|
||||
|
||||
-include $(wildcard $(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.d))
|
||||
|
||||
.PHONY: examples
|
||||
clean: clean-test
|
||||
$(RM) $(EXAMPLES) $(OBJS)
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# use pkg-config for getting CFLAGS and LDLIBS
|
||||
FFMPEG_LIBS= libavdevice \
|
||||
libavformat \
|
||||
libavfilter \
|
||||
libavcodec \
|
||||
libswresample \
|
||||
libswscale \
|
||||
libavutil \
|
||||
|
||||
CFLAGS += -Wall -g
|
||||
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
|
||||
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
|
||||
|
||||
EXAMPLES= avio_list_dir \
|
||||
avio_reading \
|
||||
decode_audio \
|
||||
decode_video \
|
||||
demuxing_decoding \
|
||||
encode_audio \
|
||||
encode_video \
|
||||
extract_mvs \
|
||||
filtering_video \
|
||||
filtering_audio \
|
||||
http_multiclient \
|
||||
hw_decode \
|
||||
metadata \
|
||||
muxing \
|
||||
remuxing \
|
||||
resampling_audio \
|
||||
scaling_video \
|
||||
transcode_aac \
|
||||
transcoding \
|
||||
|
||||
OBJS=$(addsuffix .o,$(EXAMPLES))
|
||||
|
||||
# the following examples make explicit use of the math library
|
||||
avcodec: LDLIBS += -lm
|
||||
encode_audio: LDLIBS += -lm
|
||||
muxing: LDLIBS += -lm
|
||||
resampling_audio: LDLIBS += -lm
|
||||
|
||||
.phony: all clean-test clean
|
||||
|
||||
all: $(OBJS) $(EXAMPLES)
|
||||
|
||||
clean-test:
|
||||
$(RM) test*.pgm test.h264 test.mp2 test.sw test.mpg
|
||||
|
||||
clean: clean-test
|
||||
$(RM) $(EXAMPLES) $(OBJS)
|
||||
@@ -102,15 +102,38 @@ static int list_op(const char *input_dir)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int del_op(const char *url)
|
||||
{
|
||||
int ret = avpriv_io_delete(url);
|
||||
if (ret < 0)
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot delete '%s': %s.\n", url, av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int move_op(const char *src, const char *dst)
|
||||
{
|
||||
int ret = avpriv_io_move(src, dst);
|
||||
if (ret < 0)
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot move '%s' into '%s': %s.\n", src, dst, av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void usage(const char *program_name)
|
||||
{
|
||||
fprintf(stderr, "usage: %s input_dir\n"
|
||||
"API example program to show how to list files in directory "
|
||||
"accessed through AVIOContext.\n", program_name);
|
||||
fprintf(stderr, "usage: %s OPERATION entry1 [entry2]\n"
|
||||
"API example program to show how to manipulate resources "
|
||||
"accessed through AVIOContext.\n"
|
||||
"OPERATIONS:\n"
|
||||
"list list content of the directory\n"
|
||||
"move rename content in directory\n"
|
||||
"del delete content in directory\n",
|
||||
program_name);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *op = NULL;
|
||||
int ret;
|
||||
|
||||
av_log_set_level(AV_LOG_DEBUG);
|
||||
@@ -120,9 +143,36 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* register codecs and formats and other lavf/lavc components*/
|
||||
av_register_all();
|
||||
avformat_network_init();
|
||||
|
||||
ret = list_op(argv[1]);
|
||||
op = argv[1];
|
||||
if (strcmp(op, "list") == 0) {
|
||||
if (argc < 3) {
|
||||
av_log(NULL, AV_LOG_INFO, "Missing argument for list operation.\n");
|
||||
ret = AVERROR(EINVAL);
|
||||
} else {
|
||||
ret = list_op(argv[2]);
|
||||
}
|
||||
} else if (strcmp(op, "del") == 0) {
|
||||
if (argc < 3) {
|
||||
av_log(NULL, AV_LOG_INFO, "Missing argument for del operation.\n");
|
||||
ret = AVERROR(EINVAL);
|
||||
} else {
|
||||
ret = del_op(argv[2]);
|
||||
}
|
||||
} else if (strcmp(op, "move") == 0) {
|
||||
if (argc < 4) {
|
||||
av_log(NULL, AV_LOG_INFO, "Missing argument for move operation.\n");
|
||||
ret = AVERROR(EINVAL);
|
||||
} else {
|
||||
ret = move_op(argv[2], argv[3]);
|
||||
}
|
||||
} else {
|
||||
av_log(NULL, AV_LOG_INFO, "Invalid operation %s\n", op);
|
||||
ret = AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
avformat_network_deinit();
|
||||
|
||||
@@ -44,8 +44,6 @@ static int read_packet(void *opaque, uint8_t *buf, int buf_size)
|
||||
struct buffer_data *bd = (struct buffer_data *)opaque;
|
||||
buf_size = FFMIN(buf_size, bd->size);
|
||||
|
||||
if (!buf_size)
|
||||
return AVERROR_EOF;
|
||||
printf("ptr:%p size:%zu\n", bd->ptr, bd->size);
|
||||
|
||||
/* copy internal buffer data to buf */
|
||||
@@ -74,6 +72,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
input_filename = argv[1];
|
||||
|
||||
/* register codecs and formats and other lavf/lavc components*/
|
||||
av_register_all();
|
||||
|
||||
/* slurp file content into buffer */
|
||||
ret = av_file_map(input_filename, &buffer, &buffer_size, 0, NULL);
|
||||
if (ret < 0)
|
||||
@@ -117,12 +118,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
end:
|
||||
avformat_close_input(&fmt_ctx);
|
||||
|
||||
/* note: the internal buffer could have changed, and be != avio_ctx_buffer */
|
||||
if (avio_ctx)
|
||||
if (avio_ctx) {
|
||||
av_freep(&avio_ctx->buffer);
|
||||
avio_context_free(&avio_ctx);
|
||||
|
||||
av_freep(&avio_ctx);
|
||||
}
|
||||
av_file_unmap(buffer, buffer_size);
|
||||
|
||||
if (ret < 0) {
|
||||
|
||||
@@ -1,236 +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
|
||||
|
||||
static int get_format_from_sample_fmt(const char **fmt,
|
||||
enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
int i;
|
||||
struct sample_fmt_entry {
|
||||
enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
|
||||
} sample_fmt_entries[] = {
|
||||
{ AV_SAMPLE_FMT_U8, "u8", "u8" },
|
||||
{ AV_SAMPLE_FMT_S16, "s16be", "s16le" },
|
||||
{ AV_SAMPLE_FMT_S32, "s32be", "s32le" },
|
||||
{ AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
|
||||
{ AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
|
||||
};
|
||||
*fmt = NULL;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
|
||||
struct sample_fmt_entry *entry = &sample_fmt_entries[i];
|
||||
if (sample_fmt == entry->sample_fmt) {
|
||||
*fmt = AV_NE(entry->fmt_be, entry->fmt_le);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"sample format %s is not supported as output format\n",
|
||||
av_get_sample_fmt_name(sample_fmt));
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame,
|
||||
FILE *outfile)
|
||||
{
|
||||
int i, ch;
|
||||
int ret, data_size;
|
||||
|
||||
/* send the packet with the compressed data to the decoder */
|
||||
ret = avcodec_send_packet(dec_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error submitting the packet to the decoder\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* read all the output frames (in general there may be any number of them */
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
return;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
exit(1);
|
||||
}
|
||||
data_size = av_get_bytes_per_sample(dec_ctx->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 < frame->nb_samples; i++)
|
||||
for (ch = 0; ch < dec_ctx->channels; ch++)
|
||||
fwrite(frame->data[ch] + data_size*i, 1, data_size, outfile);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *outfilename, *filename;
|
||||
const AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
AVCodecParserContext *parser = NULL;
|
||||
int len, ret;
|
||||
FILE *f, *outfile;
|
||||
uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
uint8_t *data;
|
||||
size_t data_size;
|
||||
AVPacket *pkt;
|
||||
AVFrame *decoded_frame = NULL;
|
||||
enum AVSampleFormat sfmt;
|
||||
int n_channels = 0;
|
||||
const char *fmt;
|
||||
|
||||
if (argc <= 2) {
|
||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
filename = argv[1];
|
||||
outfilename = argv[2];
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
|
||||
/* find the MPEG audio decoder */
|
||||
codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
parser = av_parser_init(codec->id);
|
||||
if (!parser) {
|
||||
fprintf(stderr, "Parser 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 */
|
||||
data = inbuf;
|
||||
data_size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
|
||||
|
||||
while (data_size > 0) {
|
||||
if (!decoded_frame) {
|
||||
if (!(decoded_frame = av_frame_alloc())) {
|
||||
fprintf(stderr, "Could not allocate audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
|
||||
data, data_size,
|
||||
AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while parsing\n");
|
||||
exit(1);
|
||||
}
|
||||
data += ret;
|
||||
data_size -= ret;
|
||||
|
||||
if (pkt->size)
|
||||
decode(c, pkt, decoded_frame, outfile);
|
||||
|
||||
if (data_size < AUDIO_REFILL_THRESH) {
|
||||
memmove(inbuf, data, data_size);
|
||||
data = inbuf;
|
||||
len = fread(data + data_size, 1,
|
||||
AUDIO_INBUF_SIZE - data_size, f);
|
||||
if (len > 0)
|
||||
data_size += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* flush the decoder */
|
||||
pkt->data = NULL;
|
||||
pkt->size = 0;
|
||||
decode(c, pkt, decoded_frame, outfile);
|
||||
|
||||
/* print output pcm infomations, because there have no metadata of pcm */
|
||||
sfmt = c->sample_fmt;
|
||||
|
||||
if (av_sample_fmt_is_planar(sfmt)) {
|
||||
const char *packed = av_get_sample_fmt_name(sfmt);
|
||||
printf("Warning: the sample format the decoder produced is planar "
|
||||
"(%s). This example will output the first channel only.\n",
|
||||
packed ? packed : "?");
|
||||
sfmt = av_get_packed_sample_fmt(sfmt);
|
||||
}
|
||||
|
||||
n_channels = c->channels;
|
||||
if ((ret = get_format_from_sample_fmt(&fmt, sfmt)) < 0)
|
||||
goto end;
|
||||
|
||||
printf("Play the output audio file with the command:\n"
|
||||
"ffplay -f %s -ac %d -ar %d %s\n",
|
||||
fmt, n_channels, c->sample_rate,
|
||||
outfilename);
|
||||
end:
|
||||
fclose(outfile);
|
||||
fclose(f);
|
||||
|
||||
avcodec_free_context(&c);
|
||||
av_parser_close(parser);
|
||||
av_frame_free(&decoded_frame);
|
||||
av_packet_free(&pkt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,187 +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,"wb");
|
||||
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 void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
|
||||
const char *filename)
|
||||
{
|
||||
char buf[1024];
|
||||
int ret;
|
||||
|
||||
ret = avcodec_send_packet(dec_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error sending a packet for decoding\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
return;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("saving frame %3d\n", dec_ctx->frame_number);
|
||||
fflush(stdout);
|
||||
|
||||
/* the picture is allocated by the decoder. no need to
|
||||
free it */
|
||||
snprintf(buf, sizeof(buf), "%s-%d", filename, dec_ctx->frame_number);
|
||||
pgm_save(frame->data[0], frame->linesize[0],
|
||||
frame->width, frame->height, buf);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *filename, *outfilename;
|
||||
const AVCodec *codec;
|
||||
AVCodecParserContext *parser;
|
||||
AVCodecContext *c= NULL;
|
||||
FILE *f;
|
||||
AVFrame *frame;
|
||||
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
uint8_t *data;
|
||||
size_t data_size;
|
||||
int ret;
|
||||
AVPacket *pkt;
|
||||
|
||||
if (argc <= 2) {
|
||||
fprintf(stderr, "Usage: %s <input file> <output file>\n"
|
||||
"And check your input file is encoded by mpeg1video please.\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
filename = argv[1];
|
||||
outfilename = argv[2];
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt)
|
||||
exit(1);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
parser = av_parser_init(codec->id);
|
||||
if (!parser) {
|
||||
fprintf(stderr, "parser not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate video codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
while (!feof(f)) {
|
||||
/* read raw data from the input file */
|
||||
data_size = fread(inbuf, 1, INBUF_SIZE, f);
|
||||
if (!data_size)
|
||||
break;
|
||||
|
||||
/* use the parser to split the data into frames */
|
||||
data = inbuf;
|
||||
while (data_size > 0) {
|
||||
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
|
||||
data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while parsing\n");
|
||||
exit(1);
|
||||
}
|
||||
data += ret;
|
||||
data_size -= ret;
|
||||
|
||||
if (pkt->size)
|
||||
decode(c, frame, pkt, outfilename);
|
||||
}
|
||||
}
|
||||
|
||||
/* flush the decoder */
|
||||
decode(c, frame, NULL, outfilename);
|
||||
|
||||
fclose(f);
|
||||
|
||||
av_parser_close(parser);
|
||||
avcodec_free_context(&c);
|
||||
av_frame_free(&frame);
|
||||
av_packet_free(&pkt);
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <libavutil/imgutils.h>
|
||||
#include <libavutil/samplefmt.h>
|
||||
#include <libavutil/timestamp.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
static AVFormatContext *fmt_ctx = NULL;
|
||||
@@ -52,97 +51,99 @@ static int video_dst_bufsize;
|
||||
|
||||
static int video_stream_idx = -1, audio_stream_idx = -1;
|
||||
static AVFrame *frame = NULL;
|
||||
static AVPacket *pkt = NULL;
|
||||
static AVPacket pkt;
|
||||
static int video_frame_count = 0;
|
||||
static int audio_frame_count = 0;
|
||||
|
||||
static int output_video_frame(AVFrame *frame)
|
||||
{
|
||||
if (frame->width != width || frame->height != height ||
|
||||
frame->format != pix_fmt) {
|
||||
/* To handle this change, one could call av_image_alloc again and
|
||||
* decode the following frames into another rawvideo file. */
|
||||
fprintf(stderr, "Error: Width, height and pixel format have to be "
|
||||
"constant in a rawvideo file, but the width, height or "
|
||||
"pixel format of the input video changed:\n"
|
||||
"old: width = %d, height = %d, format = %s\n"
|
||||
"new: width = %d, height = %d, format = %s\n",
|
||||
width, height, av_get_pix_fmt_name(pix_fmt),
|
||||
frame->width, frame->height,
|
||||
av_get_pix_fmt_name(frame->format));
|
||||
return -1;
|
||||
}
|
||||
/* Enable or disable frame reference counting. You are not supposed to support
|
||||
* both paths in your application but pick the one most appropriate to your
|
||||
* needs. Look for the use of refcount in this example to see what are the
|
||||
* differences of API usage between them. */
|
||||
static int refcount = 0;
|
||||
|
||||
printf("video_frame n:%d coded_n:%d\n",
|
||||
video_frame_count++, frame->coded_picture_number);
|
||||
|
||||
/* copy decoded frame to destination buffer:
|
||||
* this is required since rawvideo expects non aligned data */
|
||||
av_image_copy(video_dst_data, video_dst_linesize,
|
||||
(const uint8_t **)(frame->data), frame->linesize,
|
||||
pix_fmt, width, height);
|
||||
|
||||
/* write to rawvideo file */
|
||||
fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int output_audio_frame(AVFrame *frame)
|
||||
{
|
||||
size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(frame->format);
|
||||
printf("audio_frame n:%d nb_samples:%d pts:%s\n",
|
||||
audio_frame_count++, frame->nb_samples,
|
||||
av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));
|
||||
|
||||
/* Write the raw audio data samples of the first plane. This works
|
||||
* fine for packed formats (e.g. AV_SAMPLE_FMT_S16). However,
|
||||
* most audio decoders output planar audio, which uses a separate
|
||||
* plane of audio samples for each channel (e.g. AV_SAMPLE_FMT_S16P).
|
||||
* In other words, this code will write only the first audio channel
|
||||
* in these cases.
|
||||
* You should use libswresample or libavfilter to convert the frame
|
||||
* to packed data. */
|
||||
fwrite(frame->extended_data[0], 1, unpadded_linesize, audio_dst_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_packet(AVCodecContext *dec, const AVPacket *pkt)
|
||||
static int decode_packet(int *got_frame, int cached)
|
||||
{
|
||||
int ret = 0;
|
||||
int decoded = pkt.size;
|
||||
|
||||
// submit the packet to the decoder
|
||||
ret = avcodec_send_packet(dec, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error submitting a packet for decoding (%s)\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
*got_frame = 0;
|
||||
|
||||
// get all the available frames from the decoder
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec, frame);
|
||||
if (pkt.stream_index == video_stream_idx) {
|
||||
/* decode video frame */
|
||||
ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
|
||||
if (ret < 0) {
|
||||
// those two return values are special and mean there is no output
|
||||
// frame available, but there were no errors during decoding
|
||||
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
|
||||
return 0;
|
||||
|
||||
fprintf(stderr, "Error during decoding (%s)\n", av_err2str(ret));
|
||||
fprintf(stderr, "Error decoding video frame (%s)\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
// write the frame data to output file
|
||||
if (dec->codec->type == AVMEDIA_TYPE_VIDEO)
|
||||
ret = output_video_frame(frame);
|
||||
else
|
||||
ret = output_audio_frame(frame);
|
||||
if (*got_frame) {
|
||||
|
||||
av_frame_unref(frame);
|
||||
if (ret < 0)
|
||||
if (frame->width != width || frame->height != height ||
|
||||
frame->format != pix_fmt) {
|
||||
/* To handle this change, one could call av_image_alloc again and
|
||||
* decode the following frames into another rawvideo file. */
|
||||
fprintf(stderr, "Error: Width, height and pixel format have to be "
|
||||
"constant in a rawvideo file, but the width, height or "
|
||||
"pixel format of the input video changed:\n"
|
||||
"old: width = %d, height = %d, format = %s\n"
|
||||
"new: width = %d, height = %d, format = %s\n",
|
||||
width, height, av_get_pix_fmt_name(pix_fmt),
|
||||
frame->width, frame->height,
|
||||
av_get_pix_fmt_name(frame->format));
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("video_frame%s n:%d coded_n:%d\n",
|
||||
cached ? "(cached)" : "",
|
||||
video_frame_count++, frame->coded_picture_number);
|
||||
|
||||
/* copy decoded frame to destination buffer:
|
||||
* this is required since rawvideo expects non aligned data */
|
||||
av_image_copy(video_dst_data, video_dst_linesize,
|
||||
(const uint8_t **)(frame->data), frame->linesize,
|
||||
pix_fmt, width, height);
|
||||
|
||||
/* write to rawvideo file */
|
||||
fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);
|
||||
}
|
||||
} else if (pkt.stream_index == audio_stream_idx) {
|
||||
/* decode audio frame */
|
||||
ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error decoding audio frame (%s)\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
/* Some audio decoders decode only part of the packet, and have to be
|
||||
* called again with the remainder of the packet data.
|
||||
* Sample: fate-suite/lossless-audio/luckynight-partial.shn
|
||||
* Also, some decoders might over-read the packet. */
|
||||
decoded = FFMIN(ret, pkt.size);
|
||||
|
||||
if (*got_frame) {
|
||||
size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(frame->format);
|
||||
printf("audio_frame%s n:%d nb_samples:%d pts:%s\n",
|
||||
cached ? "(cached)" : "",
|
||||
audio_frame_count++, frame->nb_samples,
|
||||
av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));
|
||||
|
||||
/* Write the raw audio data samples of the first plane. This works
|
||||
* fine for packed formats (e.g. AV_SAMPLE_FMT_S16). However,
|
||||
* most audio decoders output planar audio, which uses a separate
|
||||
* plane of audio samples for each channel (e.g. AV_SAMPLE_FMT_S16P).
|
||||
* In other words, this code will write only the first audio channel
|
||||
* in these cases.
|
||||
* You should use libswresample or libavfilter to convert the frame
|
||||
* to packed data. */
|
||||
fwrite(frame->extended_data[0], 1, unpadded_linesize, audio_dst_file);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* If we use frame reference counting, we own the data and need
|
||||
* to de-reference it when we don't use it anymore */
|
||||
if (*got_frame && refcount)
|
||||
av_frame_unref(frame);
|
||||
|
||||
return decoded;
|
||||
}
|
||||
|
||||
static int open_codec_context(int *stream_idx,
|
||||
@@ -150,7 +151,8 @@ static int open_codec_context(int *stream_idx,
|
||||
{
|
||||
int ret, stream_index;
|
||||
AVStream *st;
|
||||
const AVCodec *dec = NULL;
|
||||
AVCodec *dec = NULL;
|
||||
AVDictionary *opts = NULL;
|
||||
|
||||
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
|
||||
if (ret < 0) {
|
||||
@@ -184,8 +186,9 @@ static int open_codec_context(int *stream_idx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Init the decoders */
|
||||
if ((ret = avcodec_open2(*dec_ctx, dec, NULL)) < 0) {
|
||||
/* Init the decoders, with or without reference counting */
|
||||
av_dict_set(&opts, "refcounted_frames", refcount ? "1" : "0", 0);
|
||||
if ((ret = avcodec_open2(*dec_ctx, dec, &opts)) < 0) {
|
||||
fprintf(stderr, "Failed to open %s codec\n",
|
||||
av_get_media_type_string(type));
|
||||
return ret;
|
||||
@@ -227,21 +230,31 @@ static int get_format_from_sample_fmt(const char **fmt,
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = 0, got_frame;
|
||||
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"
|
||||
if (argc != 4 && argc != 5) {
|
||||
fprintf(stderr, "usage: %s [-refcount] input_file video_output_file audio_output_file\n"
|
||||
"API example program to show how to read frames from an input file.\n"
|
||||
"This program reads frames from a file, decodes them, and writes decoded\n"
|
||||
"video frames to a rawvideo file named video_output_file, and decoded\n"
|
||||
"audio frames to a rawaudio file named audio_output_file.\n",
|
||||
argv[0]);
|
||||
"audio frames to a rawaudio file named audio_output_file.\n\n"
|
||||
"If the -refcount option is specified, the program use the\n"
|
||||
"reference counting frame system which allows keeping a copy of\n"
|
||||
"the data for longer than one decode call.\n"
|
||||
"\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if (argc == 5 && !strcmp(argv[1], "-refcount")) {
|
||||
refcount = 1;
|
||||
argv++;
|
||||
}
|
||||
src_filename = argv[1];
|
||||
video_dst_filename = argv[2];
|
||||
audio_dst_filename = argv[3];
|
||||
|
||||
/* register all formats and codecs */
|
||||
av_register_all();
|
||||
|
||||
/* open input file, and allocate format context */
|
||||
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open source file %s\n", src_filename);
|
||||
@@ -303,12 +316,10 @@ int main (int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
fprintf(stderr, "Could not allocate packet\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
/* initialize packet, set data to NULL, let the demuxer fill it */
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL;
|
||||
pkt.size = 0;
|
||||
|
||||
if (video_stream)
|
||||
printf("Demuxing video from file '%s' into '%s'\n", src_filename, video_dst_filename);
|
||||
@@ -316,23 +327,24 @@ int main (int argc, char **argv)
|
||||
printf("Demuxing audio from file '%s' into '%s'\n", src_filename, audio_dst_filename);
|
||||
|
||||
/* read frames from the file */
|
||||
while (av_read_frame(fmt_ctx, pkt) >= 0) {
|
||||
// check if the packet belongs to a stream we are interested in, otherwise
|
||||
// skip it
|
||||
if (pkt->stream_index == video_stream_idx)
|
||||
ret = decode_packet(video_dec_ctx, pkt);
|
||||
else if (pkt->stream_index == audio_stream_idx)
|
||||
ret = decode_packet(audio_dec_ctx, pkt);
|
||||
av_packet_unref(pkt);
|
||||
if (ret < 0)
|
||||
break;
|
||||
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
|
||||
AVPacket orig_pkt = pkt;
|
||||
do {
|
||||
ret = decode_packet(&got_frame, 0);
|
||||
if (ret < 0)
|
||||
break;
|
||||
pkt.data += ret;
|
||||
pkt.size -= ret;
|
||||
} while (pkt.size > 0);
|
||||
av_packet_unref(&orig_pkt);
|
||||
}
|
||||
|
||||
/* flush the decoders */
|
||||
if (video_dec_ctx)
|
||||
decode_packet(video_dec_ctx, NULL);
|
||||
if (audio_dec_ctx)
|
||||
decode_packet(audio_dec_ctx, NULL);
|
||||
/* flush cached frames */
|
||||
pkt.data = NULL;
|
||||
pkt.size = 0;
|
||||
do {
|
||||
decode_packet(&got_frame, 1);
|
||||
} while (got_frame);
|
||||
|
||||
printf("Demuxing succeeded.\n");
|
||||
|
||||
@@ -374,7 +386,6 @@ end:
|
||||
fclose(video_dst_file);
|
||||
if (audio_dst_file)
|
||||
fclose(audio_dst_file);
|
||||
av_packet_free(&pkt);
|
||||
av_frame_free(&frame);
|
||||
av_free(video_dst_data[0]);
|
||||
|
||||
|
||||
@@ -1,238 +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;
|
||||
}
|
||||
|
||||
static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt,
|
||||
FILE *output)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* send the frame for encoding */
|
||||
ret = avcodec_send_frame(ctx, frame);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error sending the frame to the encoder\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* read all the available output packets (in general there may be any
|
||||
* number of them */
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_packet(ctx, pkt);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
return;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fwrite(pkt->data, 1, pkt->size, output);
|
||||
av_packet_unref(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *filename;
|
||||
const AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
AVFrame *frame;
|
||||
AVPacket *pkt;
|
||||
int i, j, k, ret;
|
||||
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];
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* packet for holding encoded output */
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
fprintf(stderr, "could not allocate the packet\n");
|
||||
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++) {
|
||||
/* 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(c, frame, pkt, f);
|
||||
}
|
||||
|
||||
/* flush the encoder */
|
||||
encode(c, NULL, pkt, f);
|
||||
|
||||
fclose(f);
|
||||
|
||||
av_frame_free(&frame);
|
||||
av_packet_free(&pkt);
|
||||
avcodec_free_context(&c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,216 +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>
|
||||
|
||||
static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,
|
||||
FILE *outfile)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* send the frame to the encoder */
|
||||
if (frame)
|
||||
printf("Send frame %3"PRId64"\n", frame->pts);
|
||||
|
||||
ret = avcodec_send_frame(enc_ctx, frame);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error sending a frame for encoding\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_packet(enc_ctx, pkt);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
return;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error during encoding\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size);
|
||||
fwrite(pkt->data, 1, pkt->size, outfile);
|
||||
av_packet_unref(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *filename, *codec_name;
|
||||
const AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
int i, ret, x, y;
|
||||
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];
|
||||
|
||||
/* find the mpeg1video encoder */
|
||||
codec = avcodec_find_encoder_by_name(codec_name);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec '%s' not found\n", codec_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate video codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt)
|
||||
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 */
|
||||
ret = avcodec_open2(c, codec, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
|
||||
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, 0);
|
||||
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++) {
|
||||
fflush(stdout);
|
||||
|
||||
/* Make sure the frame data is writable.
|
||||
On the first round, the frame is fresh from av_frame_get_buffer()
|
||||
and therefore we know it is writable.
|
||||
But on the next rounds, encode() will have called
|
||||
avcodec_send_frame(), and the codec may have kept a reference to
|
||||
the frame in its internal structures, that makes the frame
|
||||
unwritable.
|
||||
av_frame_make_writable() checks that and allocates a new buffer
|
||||
for the frame only if necessary.
|
||||
*/
|
||||
ret = av_frame_make_writable(frame);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
|
||||
/* Prepare a dummy image.
|
||||
In real code, this is where you would have your own logic for
|
||||
filling the frame. FFmpeg does not care what you put in the
|
||||
frame.
|
||||
*/
|
||||
/* 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 */
|
||||
encode(c, frame, pkt, f);
|
||||
}
|
||||
|
||||
/* flush the encoder */
|
||||
encode(c, NULL, pkt, f);
|
||||
|
||||
/* Add sequence end code to have a real MPEG file.
|
||||
It makes only sense because this tiny examples writes packets
|
||||
directly. This is called "elementary stream" and only works for some
|
||||
codecs. To create a valid file, you usually need to write packets
|
||||
into a proper file format or protocol; see muxing.c.
|
||||
*/
|
||||
if (codec->id == AV_CODEC_ID_MPEG1VIDEO || codec->id == AV_CODEC_ID_MPEG2VIDEO)
|
||||
fwrite(endcode, 1, sizeof(endcode), f);
|
||||
fclose(f);
|
||||
|
||||
avcodec_free_context(&c);
|
||||
av_frame_free(&frame);
|
||||
av_packet_free(&pkt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -22,7 +22,6 @@
|
||||
*/
|
||||
|
||||
#include <libavutil/motion_vector.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
static AVFormatContext *fmt_ctx = NULL;
|
||||
@@ -32,26 +31,23 @@ static const char *src_filename = NULL;
|
||||
|
||||
static int video_stream_idx = -1;
|
||||
static AVFrame *frame = NULL;
|
||||
static AVPacket pkt;
|
||||
static int video_frame_count = 0;
|
||||
|
||||
static int decode_packet(const AVPacket *pkt)
|
||||
static int decode_packet(int *got_frame, int cached)
|
||||
{
|
||||
int ret = avcodec_send_packet(video_dec_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while sending a packet to the decoder: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
int decoded = pkt.size;
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(video_dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
break;
|
||||
} else if (ret < 0) {
|
||||
fprintf(stderr, "Error while receiving a frame from the decoder: %s\n", av_err2str(ret));
|
||||
*got_frame = 0;
|
||||
|
||||
if (pkt.stream_index == video_stream_idx) {
|
||||
int ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error decoding video frame (%s)\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret >= 0) {
|
||||
if (*got_frame) {
|
||||
int i;
|
||||
AVFrameSideData *sd;
|
||||
|
||||
@@ -62,60 +58,51 @@ static int decode_packet(const AVPacket *pkt)
|
||||
for (i = 0; i < sd->size / sizeof(*mvs); i++) {
|
||||
const AVMotionVector *mv = &mvs[i];
|
||||
printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64"\n",
|
||||
video_frame_count, mv->source,
|
||||
mv->w, mv->h, mv->src_x, mv->src_y,
|
||||
mv->dst_x, mv->dst_y, mv->flags);
|
||||
video_frame_count, mv->source,
|
||||
mv->w, mv->h, mv->src_x, mv->src_y,
|
||||
mv->dst_x, mv->dst_y, mv->flags);
|
||||
}
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
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;
|
||||
AVCodecContext *dec_ctx = NULL;
|
||||
const AVCodec *dec = NULL;
|
||||
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);
|
||||
ret = avcodec_open2(dec_ctx, dec, &opts);
|
||||
av_dict_free(&opts);
|
||||
if (ret < 0) {
|
||||
if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) {
|
||||
fprintf(stderr, "Failed to open %s codec\n",
|
||||
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;
|
||||
@@ -123,8 +110,7 @@ static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
AVPacket *pkt = NULL;
|
||||
int ret = 0, got_frame;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s <video>\n", argv[0]);
|
||||
@@ -132,6 +118,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
src_filename = argv[1];
|
||||
|
||||
av_register_all();
|
||||
|
||||
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open source file %s\n", src_filename);
|
||||
exit(1);
|
||||
@@ -142,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);
|
||||
|
||||
@@ -159,31 +150,36 @@ int main(int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
fprintf(stderr, "Could not allocate AVPacket\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
printf("framenum,source,blockw,blockh,srcx,srcy,dstx,dsty,flags\n");
|
||||
|
||||
/* initialize packet, set data to NULL, let the demuxer fill it */
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL;
|
||||
pkt.size = 0;
|
||||
|
||||
/* read frames from the file */
|
||||
while (av_read_frame(fmt_ctx, pkt) >= 0) {
|
||||
if (pkt->stream_index == video_stream_idx)
|
||||
ret = decode_packet(pkt);
|
||||
av_packet_unref(pkt);
|
||||
if (ret < 0)
|
||||
break;
|
||||
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
|
||||
AVPacket orig_pkt = pkt;
|
||||
do {
|
||||
ret = decode_packet(&got_frame, 0);
|
||||
if (ret < 0)
|
||||
break;
|
||||
pkt.data += ret;
|
||||
pkt.size -= ret;
|
||||
} while (pkt.size > 0);
|
||||
av_packet_unref(&orig_pkt);
|
||||
}
|
||||
|
||||
/* flush cached frames */
|
||||
decode_packet(NULL);
|
||||
pkt.data = NULL;
|
||||
pkt.size = 0;
|
||||
do {
|
||||
decode_packet(&got_frame, 1);
|
||||
} while (got_frame);
|
||||
|
||||
end:
|
||||
avcodec_free_context(&video_dec_ctx);
|
||||
avcodec_close(video_dec_ctx);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
av_frame_free(&frame);
|
||||
av_packet_free(&pkt);
|
||||
return ret < 0;
|
||||
}
|
||||
|
||||
@@ -64,13 +64,13 @@ static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src,
|
||||
{
|
||||
AVFilterGraph *filter_graph;
|
||||
AVFilterContext *abuffer_ctx;
|
||||
const AVFilter *abuffer;
|
||||
AVFilter *abuffer;
|
||||
AVFilterContext *volume_ctx;
|
||||
const AVFilter *volume;
|
||||
AVFilter *volume;
|
||||
AVFilterContext *aformat_ctx;
|
||||
const AVFilter *aformat;
|
||||
AVFilter *aformat;
|
||||
AVFilterContext *abuffersink_ctx;
|
||||
const AVFilter *abuffersink;
|
||||
AVFilter *abuffersink;
|
||||
|
||||
AVDictionary *options_dict = NULL;
|
||||
uint8_t options_str[1024];
|
||||
@@ -289,6 +289,8 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
avfilter_register_all();
|
||||
|
||||
/* Allocate the frame we will be using to store the data. */
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavfilter/avfiltergraph.h>
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/opt.h>
|
||||
|
||||
static const char *filter_descr = "aresample=8000,aformat=sample_fmts=s16:channel_layouts=mono";
|
||||
@@ -49,8 +49,8 @@ static int audio_stream_index = -1;
|
||||
|
||||
static int open_input_file(const char *filename)
|
||||
{
|
||||
const AVCodec *dec;
|
||||
int ret;
|
||||
AVCodec *dec;
|
||||
|
||||
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
|
||||
@@ -69,12 +69,8 @@ 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 */
|
||||
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
||||
@@ -89,8 +85,8 @@ static int init_filters(const char *filters_descr)
|
||||
{
|
||||
char args[512];
|
||||
int ret = 0;
|
||||
const AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
|
||||
const AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
|
||||
AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
|
||||
AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
|
||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||
AVFilterInOut *inputs = avfilter_inout_alloc();
|
||||
static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 };
|
||||
@@ -200,7 +196,7 @@ end:
|
||||
|
||||
static void print_frame(const AVFrame *frame)
|
||||
{
|
||||
const int n = frame->nb_samples * av_get_channel_layout_nb_channels(frame->channel_layout);
|
||||
const int n = frame->nb_samples * av_get_channel_layout_nb_channels(av_frame_get_channel_layout(frame));
|
||||
const uint16_t *p = (uint16_t*)frame->data[0];
|
||||
const uint16_t *p_end = p + n;
|
||||
|
||||
@@ -215,12 +211,13 @@ static void print_frame(const AVFrame *frame)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
AVPacket *packet = av_packet_alloc();
|
||||
AVPacket packet0, packet;
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
AVFrame *filt_frame = av_frame_alloc();
|
||||
int got_frame;
|
||||
|
||||
if (!packet || !frame || !filt_frame) {
|
||||
fprintf(stderr, "Could not allocate frame or packet\n");
|
||||
if (!frame || !filt_frame) {
|
||||
perror("Could not allocate frame");
|
||||
exit(1);
|
||||
}
|
||||
if (argc != 2) {
|
||||
@@ -228,60 +225,64 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
av_register_all();
|
||||
avfilter_register_all();
|
||||
|
||||
if ((ret = open_input_file(argv[1])) < 0)
|
||||
goto end;
|
||||
if ((ret = init_filters(filter_descr)) < 0)
|
||||
goto end;
|
||||
|
||||
/* read all packets */
|
||||
packet0.data = NULL;
|
||||
packet.data = NULL;
|
||||
while (1) {
|
||||
if ((ret = av_read_frame(fmt_ctx, packet)) < 0)
|
||||
break;
|
||||
|
||||
if (packet->stream_index == audio_stream_index) {
|
||||
ret = avcodec_send_packet(dec_ctx, packet);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");
|
||||
if (!packet0.data) {
|
||||
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
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");
|
||||
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);
|
||||
}
|
||||
}
|
||||
packet0 = packet;
|
||||
}
|
||||
|
||||
if (packet.stream_index == audio_stream_index) {
|
||||
got_frame = 0;
|
||||
ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, &packet);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error decoding audio\n");
|
||||
continue;
|
||||
}
|
||||
packet.size -= ret;
|
||||
packet.data += ret;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
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_packet_free(&packet);
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&filt_frame);
|
||||
|
||||
|
||||
@@ -29,11 +29,10 @@
|
||||
|
||||
#define _XOPEN_SOURCE 600 /* for usleep */
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavfilter/avfiltergraph.h>
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavutil/opt.h>
|
||||
@@ -53,8 +52,8 @@ static int64_t last_pts = AV_NOPTS_VALUE;
|
||||
|
||||
static int open_input_file(const char *filename)
|
||||
{
|
||||
const AVCodec *dec;
|
||||
int ret;
|
||||
AVCodec *dec;
|
||||
|
||||
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
|
||||
@@ -73,12 +72,8 @@ 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 */
|
||||
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
||||
@@ -93,8 +88,8 @@ static int init_filters(const char *filters_descr)
|
||||
{
|
||||
char args[512];
|
||||
int ret = 0;
|
||||
const AVFilter *buffersrc = avfilter_get_by_name("buffer");
|
||||
const AVFilter *buffersink = avfilter_get_by_name("buffersink");
|
||||
AVFilter *buffersrc = avfilter_get_by_name("buffer");
|
||||
AVFilter *buffersink = avfilter_get_by_name("buffersink");
|
||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||
AVFilterInOut *inputs = avfilter_inout_alloc();
|
||||
AVRational time_base = fmt_ctx->streams[video_stream_index]->time_base;
|
||||
@@ -210,22 +205,22 @@ static void display_frame(const AVFrame *frame, AVRational time_base)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
AVPacket *packet;
|
||||
AVFrame *frame;
|
||||
AVFrame *filt_frame;
|
||||
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");
|
||||
exit(1);
|
||||
}
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s file\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
filt_frame = av_frame_alloc();
|
||||
packet = av_packet_alloc();
|
||||
if (!frame || !filt_frame || !packet) {
|
||||
fprintf(stderr, "Could not allocate frame or packet\n");
|
||||
exit(1);
|
||||
}
|
||||
av_register_all();
|
||||
avfilter_register_all();
|
||||
|
||||
if ((ret = open_input_file(argv[1])) < 0)
|
||||
goto end;
|
||||
@@ -234,26 +229,19 @@ int main(int argc, char **argv)
|
||||
|
||||
/* read all packets */
|
||||
while (1) {
|
||||
if ((ret = av_read_frame(fmt_ctx, packet)) < 0)
|
||||
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
|
||||
break;
|
||||
|
||||
if (packet->stream_index == video_stream_index) {
|
||||
ret = avcodec_send_packet(dec_ctx, packet);
|
||||
if (packet.stream_index == video_stream_index) {
|
||||
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) {
|
||||
break;
|
||||
} else if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
frame->pts = frame->best_effort_timestamp;
|
||||
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) {
|
||||
@@ -274,15 +262,14 @@ int main(int argc, char **argv)
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
}
|
||||
av_packet_unref(packet);
|
||||
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);
|
||||
av_packet_free(&packet);
|
||||
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
|
||||
@@ -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)
|
||||
@@ -114,6 +112,7 @@ int main(int argc, char **argv)
|
||||
in_uri = argv[1];
|
||||
out_uri = argv[2];
|
||||
|
||||
av_register_all();
|
||||
avformat_network_init();
|
||||
|
||||
if ((ret = av_dict_set(&options, "listen", "2", 0)) < 0) {
|
||||
|
||||
@@ -1,256 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Jun Zhao
|
||||
* Copyright (c) 2017 Kaixuan Liu
|
||||
*
|
||||
* HW Acceleration API (video decoding) decode sample
|
||||
*
|
||||
* 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
|
||||
* HW-Accelerated decoding example.
|
||||
*
|
||||
* @example hw_decode.c
|
||||
* This example shows how to do HW-accelerated decoding with output
|
||||
* frames from the HW video surfaces.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/avassert.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
|
||||
static AVBufferRef *hw_device_ctx = NULL;
|
||||
static enum AVPixelFormat hw_pix_fmt;
|
||||
static FILE *output_file = NULL;
|
||||
|
||||
static int hw_decoder_init(AVCodecContext *ctx, const enum AVHWDeviceType type)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if ((err = av_hwdevice_ctx_create(&hw_device_ctx, type,
|
||||
NULL, NULL, 0)) < 0) {
|
||||
fprintf(stderr, "Failed to create specified HW device.\n");
|
||||
return err;
|
||||
}
|
||||
ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static enum AVPixelFormat get_hw_format(AVCodecContext *ctx,
|
||||
const enum AVPixelFormat *pix_fmts)
|
||||
{
|
||||
const enum AVPixelFormat *p;
|
||||
|
||||
for (p = pix_fmts; *p != -1; p++) {
|
||||
if (*p == hw_pix_fmt)
|
||||
return *p;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Failed to get HW surface format.\n");
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
static int decode_write(AVCodecContext *avctx, AVPacket *packet)
|
||||
{
|
||||
AVFrame *frame = NULL, *sw_frame = NULL;
|
||||
AVFrame *tmp_frame = NULL;
|
||||
uint8_t *buffer = NULL;
|
||||
int size;
|
||||
int ret = 0;
|
||||
|
||||
ret = avcodec_send_packet(avctx, packet);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (!(frame = av_frame_alloc()) || !(sw_frame = av_frame_alloc())) {
|
||||
fprintf(stderr, "Can not alloc frame\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = avcodec_receive_frame(avctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&sw_frame);
|
||||
return 0;
|
||||
} else if (ret < 0) {
|
||||
fprintf(stderr, "Error while decoding\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (frame->format == hw_pix_fmt) {
|
||||
/* retrieve data from GPU to CPU */
|
||||
if ((ret = av_hwframe_transfer_data(sw_frame, frame, 0)) < 0) {
|
||||
fprintf(stderr, "Error transferring the data to system memory\n");
|
||||
goto fail;
|
||||
}
|
||||
tmp_frame = sw_frame;
|
||||
} else
|
||||
tmp_frame = frame;
|
||||
|
||||
size = av_image_get_buffer_size(tmp_frame->format, tmp_frame->width,
|
||||
tmp_frame->height, 1);
|
||||
buffer = av_malloc(size);
|
||||
if (!buffer) {
|
||||
fprintf(stderr, "Can not alloc buffer\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
ret = av_image_copy_to_buffer(buffer, size,
|
||||
(const uint8_t * const *)tmp_frame->data,
|
||||
(const int *)tmp_frame->linesize, tmp_frame->format,
|
||||
tmp_frame->width, tmp_frame->height, 1);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Can not copy image to buffer\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((ret = fwrite(buffer, 1, size, output_file)) < 0) {
|
||||
fprintf(stderr, "Failed to dump raw data.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&sw_frame);
|
||||
av_freep(&buffer);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
AVFormatContext *input_ctx = NULL;
|
||||
int video_stream, ret;
|
||||
AVStream *video = NULL;
|
||||
AVCodecContext *decoder_ctx = NULL;
|
||||
const AVCodec *decoder = NULL;
|
||||
AVPacket *packet = NULL;
|
||||
enum AVHWDeviceType type;
|
||||
int i;
|
||||
|
||||
if (argc < 4) {
|
||||
fprintf(stderr, "Usage: %s <device type> <input file> <output file>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
type = av_hwdevice_find_type_by_name(argv[1]);
|
||||
if (type == AV_HWDEVICE_TYPE_NONE) {
|
||||
fprintf(stderr, "Device type %s is not supported.\n", argv[1]);
|
||||
fprintf(stderr, "Available device types:");
|
||||
while((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE)
|
||||
fprintf(stderr, " %s", av_hwdevice_get_type_name(type));
|
||||
fprintf(stderr, "\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
packet = av_packet_alloc();
|
||||
if (!packet) {
|
||||
fprintf(stderr, "Failed to allocate AVPacket\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open the input file */
|
||||
if (avformat_open_input(&input_ctx, argv[2], NULL, NULL) != 0) {
|
||||
fprintf(stderr, "Cannot open input file '%s'\n", argv[2]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (avformat_find_stream_info(input_ctx, NULL) < 0) {
|
||||
fprintf(stderr, "Cannot find input stream information.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* find the video stream information */
|
||||
ret = av_find_best_stream(input_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot find a video stream in the input file\n");
|
||||
return -1;
|
||||
}
|
||||
video_stream = ret;
|
||||
|
||||
for (i = 0;; i++) {
|
||||
const AVCodecHWConfig *config = avcodec_get_hw_config(decoder, i);
|
||||
if (!config) {
|
||||
fprintf(stderr, "Decoder %s does not support device type %s.\n",
|
||||
decoder->name, av_hwdevice_get_type_name(type));
|
||||
return -1;
|
||||
}
|
||||
if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
|
||||
config->device_type == type) {
|
||||
hw_pix_fmt = config->pix_fmt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(decoder_ctx = avcodec_alloc_context3(decoder)))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
video = input_ctx->streams[video_stream];
|
||||
if (avcodec_parameters_to_context(decoder_ctx, video->codecpar) < 0)
|
||||
return -1;
|
||||
|
||||
decoder_ctx->get_format = get_hw_format;
|
||||
|
||||
if (hw_decoder_init(decoder_ctx, type) < 0)
|
||||
return -1;
|
||||
|
||||
if ((ret = avcodec_open2(decoder_ctx, decoder, NULL)) < 0) {
|
||||
fprintf(stderr, "Failed to open codec for stream #%u\n", video_stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open the file to dump raw data */
|
||||
output_file = fopen(argv[3], "w+b");
|
||||
|
||||
/* actual decoding and dump the raw data */
|
||||
while (ret >= 0) {
|
||||
if ((ret = av_read_frame(input_ctx, packet)) < 0)
|
||||
break;
|
||||
|
||||
if (video_stream == packet->stream_index)
|
||||
ret = decode_write(decoder_ctx, packet);
|
||||
|
||||
av_packet_unref(packet);
|
||||
}
|
||||
|
||||
/* flush the decoder */
|
||||
ret = decode_write(decoder_ctx, NULL);
|
||||
|
||||
if (output_file)
|
||||
fclose(output_file);
|
||||
av_packet_free(&packet);
|
||||
avcodec_free_context(&decoder_ctx);
|
||||
avformat_close_input(&input_ctx);
|
||||
av_buffer_unref(&hw_device_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -34,7 +34,7 @@
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
AVFormatContext *fmt_ctx = NULL;
|
||||
const AVDictionaryEntry *tag = NULL;
|
||||
AVDictionaryEntry *tag = NULL;
|
||||
int ret;
|
||||
|
||||
if (argc != 2) {
|
||||
@@ -44,14 +44,10 @@ int main (int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
av_register_all();
|
||||
if ((ret = avformat_open_input(&fmt_ctx, argv[1], NULL, NULL)))
|
||||
return ret;
|
||||
|
||||
if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
|
||||
printf("%s=%s\n", tag->key, tag->value);
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/mathematics.h>
|
||||
#include <libavutil/timestamp.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libswscale/swscale.h>
|
||||
#include <libswresample/swresample.h>
|
||||
@@ -62,8 +61,6 @@ typedef struct OutputStream {
|
||||
AVFrame *frame;
|
||||
AVFrame *tmp_frame;
|
||||
|
||||
AVPacket *tmp_pkt;
|
||||
|
||||
float t, tincr, tincr2;
|
||||
|
||||
struct SwsContext *sws_ctx;
|
||||
@@ -81,50 +78,20 @@ static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)
|
||||
pkt->stream_index);
|
||||
}
|
||||
|
||||
static int write_frame(AVFormatContext *fmt_ctx, AVCodecContext *c,
|
||||
AVStream *st, AVFrame *frame, AVPacket *pkt)
|
||||
static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
|
||||
{
|
||||
int ret;
|
||||
/* rescale output packet timestamp values from codec to stream timebase */
|
||||
av_packet_rescale_ts(pkt, *time_base, st->time_base);
|
||||
pkt->stream_index = st->index;
|
||||
|
||||
// send the frame to the encoder
|
||||
ret = avcodec_send_frame(c, frame);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error sending a frame to the encoder: %s\n",
|
||||
av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_packet(c, pkt);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
break;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding a frame: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* rescale output packet timestamp values from codec to stream timebase */
|
||||
av_packet_rescale_ts(pkt, c->time_base, st->time_base);
|
||||
pkt->stream_index = st->index;
|
||||
|
||||
/* Write the compressed frame to the media file. */
|
||||
log_packet(fmt_ctx, pkt);
|
||||
ret = av_interleaved_write_frame(fmt_ctx, pkt);
|
||||
/* pkt is now blank (av_interleaved_write_frame() takes ownership of
|
||||
* its contents and resets pkt), so that no unreferencing is necessary.
|
||||
* This would be different if one used av_write_frame(). */
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while writing output packet: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return ret == AVERROR_EOF ? 1 : 0;
|
||||
/* Write the compressed frame to the media file. */
|
||||
log_packet(fmt_ctx, pkt);
|
||||
return av_interleaved_write_frame(fmt_ctx, pkt);
|
||||
}
|
||||
|
||||
/* Add an output stream. */
|
||||
static void add_stream(OutputStream *ost, AVFormatContext *oc,
|
||||
const AVCodec **codec,
|
||||
AVCodec **codec,
|
||||
enum AVCodecID codec_id)
|
||||
{
|
||||
AVCodecContext *c;
|
||||
@@ -138,12 +105,6 @@ static void add_stream(OutputStream *ost, AVFormatContext *oc,
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ost->tmp_pkt = av_packet_alloc();
|
||||
if (!ost->tmp_pkt) {
|
||||
fprintf(stderr, "Could not allocate AVPacket\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ost->st = avformat_new_stream(oc, NULL);
|
||||
if (!ost->st) {
|
||||
fprintf(stderr, "Could not allocate stream\n");
|
||||
@@ -209,7 +170,7 @@ static void add_stream(OutputStream *ost, AVFormatContext *oc,
|
||||
* the motion of the chroma plane does not match the luma plane. */
|
||||
c->mb_decision = 2;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -251,8 +212,7 @@ static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
|
||||
return frame;
|
||||
}
|
||||
|
||||
static void open_audio(AVFormatContext *oc, const AVCodec *codec,
|
||||
OutputStream *ost, AVDictionary *opt_arg)
|
||||
static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg)
|
||||
{
|
||||
AVCodecContext *c;
|
||||
int nb_samples;
|
||||
@@ -294,25 +254,25 @@ static void open_audio(AVFormatContext *oc, const AVCodec *codec,
|
||||
}
|
||||
|
||||
/* create resampler context */
|
||||
ost->swr_ctx = swr_alloc();
|
||||
if (!ost->swr_ctx) {
|
||||
fprintf(stderr, "Could not allocate resampler context\n");
|
||||
exit(1);
|
||||
}
|
||||
ost->swr_ctx = swr_alloc();
|
||||
if (!ost->swr_ctx) {
|
||||
fprintf(stderr, "Could not allocate resampler context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* set options */
|
||||
av_opt_set_int (ost->swr_ctx, "in_channel_count", c->channels, 0);
|
||||
av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0);
|
||||
av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
||||
av_opt_set_int (ost->swr_ctx, "out_channel_count", c->channels, 0);
|
||||
av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0);
|
||||
av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
|
||||
/* set options */
|
||||
av_opt_set_int (ost->swr_ctx, "in_channel_count", c->channels, 0);
|
||||
av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0);
|
||||
av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
||||
av_opt_set_int (ost->swr_ctx, "out_channel_count", c->channels, 0);
|
||||
av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0);
|
||||
av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
|
||||
|
||||
/* initialize the resampling context */
|
||||
if ((ret = swr_init(ost->swr_ctx)) < 0) {
|
||||
fprintf(stderr, "Failed to initialize the resampling context\n");
|
||||
exit(1);
|
||||
}
|
||||
/* initialize the resampling context */
|
||||
if ((ret = swr_init(ost->swr_ctx)) < 0) {
|
||||
fprintf(stderr, "Failed to initialize the resampling context\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
|
||||
@@ -325,7 +285,7 @@ static AVFrame *get_audio_frame(OutputStream *ost)
|
||||
|
||||
/* check if we want to generate more frames */
|
||||
if (av_compare_ts(ost->next_pts, ost->enc->time_base,
|
||||
STREAM_DURATION, (AVRational){ 1, 1 }) > 0)
|
||||
STREAM_DURATION, (AVRational){ 1, 1 }) >= 0)
|
||||
return NULL;
|
||||
|
||||
for (j = 0; j <frame->nb_samples; j++) {
|
||||
@@ -349,20 +309,23 @@ static AVFrame *get_audio_frame(OutputStream *ost)
|
||||
static int write_audio_frame(AVFormatContext *oc, OutputStream *ost)
|
||||
{
|
||||
AVCodecContext *c;
|
||||
AVPacket pkt = { 0 }; // data and size must be 0;
|
||||
AVFrame *frame;
|
||||
int ret;
|
||||
int got_packet;
|
||||
int dst_nb_samples;
|
||||
|
||||
av_init_packet(&pkt);
|
||||
c = ost->enc;
|
||||
|
||||
frame = get_audio_frame(ost);
|
||||
|
||||
if (frame) {
|
||||
/* convert samples from native format to destination codec format, using the resampler */
|
||||
/* compute destination number of samples */
|
||||
dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples,
|
||||
c->sample_rate, c->sample_rate, AV_ROUND_UP);
|
||||
av_assert0(dst_nb_samples == frame->nb_samples);
|
||||
/* compute destination number of samples */
|
||||
dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples,
|
||||
c->sample_rate, c->sample_rate, AV_ROUND_UP);
|
||||
av_assert0(dst_nb_samples == frame->nb_samples);
|
||||
|
||||
/* when we pass a frame to the encoder, it may keep a reference to it
|
||||
* internally;
|
||||
@@ -372,21 +335,36 @@ 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;
|
||||
}
|
||||
|
||||
return write_frame(oc, c, ost->st, frame, ost->tmp_pkt);
|
||||
ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding audio frame: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (got_packet) {
|
||||
ret = write_frame(oc, &c->time_base, ost->st, &pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while writing audio frame: %s\n",
|
||||
av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return (frame || got_packet) ? 0 : 1;
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
@@ -406,7 +384,7 @@ static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
|
||||
picture->height = height;
|
||||
|
||||
/* allocate the buffers for the frame data */
|
||||
ret = av_frame_get_buffer(picture, 0);
|
||||
ret = av_frame_get_buffer(picture, 32);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate frame data.\n");
|
||||
exit(1);
|
||||
@@ -415,8 +393,7 @@ static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
|
||||
return picture;
|
||||
}
|
||||
|
||||
static void open_video(AVFormatContext *oc, const AVCodec *codec,
|
||||
OutputStream *ost, AVDictionary *opt_arg)
|
||||
static void open_video(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg)
|
||||
{
|
||||
int ret;
|
||||
AVCodecContext *c = ost->enc;
|
||||
@@ -463,7 +440,15 @@ static void open_video(AVFormatContext *oc, const AVCodec *codec,
|
||||
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;
|
||||
|
||||
@@ -487,14 +472,9 @@ static AVFrame *get_video_frame(OutputStream *ost)
|
||||
|
||||
/* check if we want to generate more frames */
|
||||
if (av_compare_ts(ost->next_pts, c->time_base,
|
||||
STREAM_DURATION, (AVRational){ 1, 1 }) > 0)
|
||||
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 */
|
||||
@@ -511,9 +491,9 @@ static AVFrame *get_video_frame(OutputStream *ost)
|
||||
}
|
||||
}
|
||||
fill_yuv_image(ost->tmp_frame, ost->next_pts, c->width, c->height);
|
||||
sws_scale(ost->sws_ctx, (const uint8_t * const *) ost->tmp_frame->data,
|
||||
ost->tmp_frame->linesize, 0, c->height, ost->frame->data,
|
||||
ost->frame->linesize);
|
||||
sws_scale(ost->sws_ctx,
|
||||
(const uint8_t * const *)ost->tmp_frame->data, ost->tmp_frame->linesize,
|
||||
0, c->height, ost->frame->data, ost->frame->linesize);
|
||||
} else {
|
||||
fill_yuv_image(ost->frame, ost->next_pts, c->width, c->height);
|
||||
}
|
||||
@@ -529,7 +509,37 @@ static AVFrame *get_video_frame(OutputStream *ost)
|
||||
*/
|
||||
static int write_video_frame(AVFormatContext *oc, OutputStream *ost)
|
||||
{
|
||||
return write_frame(oc, ost->enc, ost->st, get_video_frame(ost), ost->tmp_pkt);
|
||||
int ret;
|
||||
AVCodecContext *c;
|
||||
AVFrame *frame;
|
||||
int got_packet = 0;
|
||||
AVPacket pkt = { 0 };
|
||||
|
||||
c = ost->enc;
|
||||
|
||||
frame = get_video_frame(ost);
|
||||
|
||||
av_init_packet(&pkt);
|
||||
|
||||
/* encode the image */
|
||||
ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (got_packet) {
|
||||
ret = write_frame(oc, &c->time_base, ost->st, &pkt);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return (frame || got_packet) ? 0 : 1;
|
||||
}
|
||||
|
||||
static void close_stream(AVFormatContext *oc, OutputStream *ost)
|
||||
@@ -537,7 +547,6 @@ static void close_stream(AVFormatContext *oc, OutputStream *ost)
|
||||
avcodec_free_context(&ost->enc);
|
||||
av_frame_free(&ost->frame);
|
||||
av_frame_free(&ost->tmp_frame);
|
||||
av_packet_free(&ost->tmp_pkt);
|
||||
sws_freeContext(ost->sws_ctx);
|
||||
swr_free(&ost->swr_ctx);
|
||||
}
|
||||
@@ -548,16 +557,19 @@ static void close_stream(AVFormatContext *oc, OutputStream *ost)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
OutputStream video_st = { 0 }, audio_st = { 0 };
|
||||
const AVOutputFormat *fmt;
|
||||
const char *filename;
|
||||
AVOutputFormat *fmt;
|
||||
AVFormatContext *oc;
|
||||
const AVCodec *audio_codec, *video_codec;
|
||||
AVCodec *audio_codec, *video_codec;
|
||||
int ret;
|
||||
int have_video = 0, have_audio = 0;
|
||||
int encode_video = 0, encode_audio = 0;
|
||||
AVDictionary *opt = NULL;
|
||||
int i;
|
||||
|
||||
/* Initialize libavcodec, and register all codecs and formats. */
|
||||
av_register_all();
|
||||
|
||||
if (argc < 2) {
|
||||
printf("usage: %s output_file\n"
|
||||
"API example program to output a media file with libavformat.\n"
|
||||
|
||||
@@ -26,28 +26,186 @@
|
||||
*
|
||||
* @example qsvdec.c
|
||||
* This example shows how to do QSV-accelerated H.264 decoding with output
|
||||
* frames in the GPU video surfaces.
|
||||
* frames in the VA-API video surfaces.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <mfx/mfxvideo.h>
|
||||
|
||||
#include <va/va.h>
|
||||
#include <va/va_x11.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavformat/avio.h"
|
||||
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavcodec/qsv.h"
|
||||
|
||||
#include "libavutil/buffer.h"
|
||||
#include "libavutil/error.h"
|
||||
#include "libavutil/hwcontext.h"
|
||||
#include "libavutil/hwcontext_qsv.h"
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
typedef struct DecodeContext {
|
||||
mfxSession mfx_session;
|
||||
VADisplay va_dpy;
|
||||
|
||||
VASurfaceID *surfaces;
|
||||
mfxMemId *surface_ids;
|
||||
int *surface_used;
|
||||
int nb_surfaces;
|
||||
|
||||
mfxFrameInfo frame_info;
|
||||
} DecodeContext;
|
||||
|
||||
static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
|
||||
mfxFrameAllocResponse *resp)
|
||||
{
|
||||
DecodeContext *decode = pthis;
|
||||
int err, i;
|
||||
|
||||
if (decode->surfaces) {
|
||||
fprintf(stderr, "Multiple allocation requests.\n");
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
}
|
||||
if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)) {
|
||||
fprintf(stderr, "Unsupported surface type: %d\n", req->Type);
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
}
|
||||
if (req->Info.BitDepthLuma != 8 || req->Info.BitDepthChroma != 8 ||
|
||||
req->Info.Shift || req->Info.FourCC != MFX_FOURCC_NV12 ||
|
||||
req->Info.ChromaFormat != MFX_CHROMAFORMAT_YUV420) {
|
||||
fprintf(stderr, "Unsupported surface properties.\n");
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
decode->surfaces = av_malloc_array (req->NumFrameSuggested, sizeof(*decode->surfaces));
|
||||
decode->surface_ids = av_malloc_array (req->NumFrameSuggested, sizeof(*decode->surface_ids));
|
||||
decode->surface_used = av_mallocz_array(req->NumFrameSuggested, sizeof(*decode->surface_used));
|
||||
if (!decode->surfaces || !decode->surface_ids || !decode->surface_used)
|
||||
goto fail;
|
||||
|
||||
err = vaCreateSurfaces(decode->va_dpy, VA_RT_FORMAT_YUV420,
|
||||
req->Info.Width, req->Info.Height,
|
||||
decode->surfaces, req->NumFrameSuggested,
|
||||
NULL, 0);
|
||||
if (err != VA_STATUS_SUCCESS) {
|
||||
fprintf(stderr, "Error allocating VA surfaces\n");
|
||||
goto fail;
|
||||
}
|
||||
decode->nb_surfaces = req->NumFrameSuggested;
|
||||
|
||||
for (i = 0; i < decode->nb_surfaces; i++)
|
||||
decode->surface_ids[i] = &decode->surfaces[i];
|
||||
|
||||
resp->mids = decode->surface_ids;
|
||||
resp->NumFrameActual = decode->nb_surfaces;
|
||||
|
||||
decode->frame_info = req->Info;
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
fail:
|
||||
av_freep(&decode->surfaces);
|
||||
av_freep(&decode->surface_ids);
|
||||
av_freep(&decode->surface_used);
|
||||
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
}
|
||||
|
||||
static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
|
||||
{
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
|
||||
{
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
|
||||
{
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
|
||||
{
|
||||
*hdl = mid;
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
static void free_surfaces(DecodeContext *decode)
|
||||
{
|
||||
if (decode->surfaces)
|
||||
vaDestroySurfaces(decode->va_dpy, decode->surfaces, decode->nb_surfaces);
|
||||
av_freep(&decode->surfaces);
|
||||
av_freep(&decode->surface_ids);
|
||||
av_freep(&decode->surface_used);
|
||||
decode->nb_surfaces = 0;
|
||||
}
|
||||
|
||||
static void free_buffer(void *opaque, uint8_t *data)
|
||||
{
|
||||
int *used = opaque;
|
||||
*used = 0;
|
||||
av_freep(&data);
|
||||
}
|
||||
|
||||
static int get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
|
||||
{
|
||||
DecodeContext *decode = avctx->opaque;
|
||||
|
||||
mfxFrameSurface1 *surf;
|
||||
AVBufferRef *surf_buf;
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < decode->nb_surfaces; idx++) {
|
||||
if (!decode->surface_used[idx])
|
||||
break;
|
||||
}
|
||||
if (idx == decode->nb_surfaces) {
|
||||
fprintf(stderr, "No free surfaces\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
surf = av_mallocz(sizeof(*surf));
|
||||
if (!surf)
|
||||
return AVERROR(ENOMEM);
|
||||
surf_buf = av_buffer_create((uint8_t*)surf, sizeof(*surf), free_buffer,
|
||||
&decode->surface_used[idx], AV_BUFFER_FLAG_READONLY);
|
||||
if (!surf_buf) {
|
||||
av_freep(&surf);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
surf->Info = decode->frame_info;
|
||||
surf->Data.MemId = &decode->surfaces[idx];
|
||||
|
||||
frame->buf[0] = surf_buf;
|
||||
frame->data[3] = (uint8_t*)surf;
|
||||
|
||||
decode->surface_used[idx] = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
|
||||
{
|
||||
while (*pix_fmts != AV_PIX_FMT_NONE) {
|
||||
if (*pix_fmts == AV_PIX_FMT_QSV) {
|
||||
if (!avctx->hwaccel_context) {
|
||||
DecodeContext *decode = avctx->opaque;
|
||||
AVQSVContext *qsv = av_qsv_alloc_context();
|
||||
if (!qsv)
|
||||
return AV_PIX_FMT_NONE;
|
||||
|
||||
qsv->session = decode->mfx_session;
|
||||
qsv->iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
|
||||
|
||||
avctx->hwaccel_context = qsv;
|
||||
}
|
||||
|
||||
return AV_PIX_FMT_QSV;
|
||||
}
|
||||
|
||||
@@ -59,48 +217,87 @@ static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
static int decode_packet(AVCodecContext *decoder_ctx,
|
||||
AVFrame *frame, AVFrame *sw_frame,
|
||||
AVPacket *pkt, AVIOContext *output_ctx)
|
||||
static int decode_packet(DecodeContext *decode, AVCodecContext *decoder_ctx,
|
||||
AVFrame *frame, AVPacket *pkt,
|
||||
AVIOContext *output_ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
int got_frame = 1;
|
||||
|
||||
ret = avcodec_send_packet(decoder_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
int i, j;
|
||||
|
||||
ret = avcodec_receive_frame(decoder_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
break;
|
||||
else if (ret < 0) {
|
||||
while (pkt->size > 0 || (!pkt->data && got_frame)) {
|
||||
ret = avcodec_decode_video2(decoder_ctx, frame, &got_frame, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pkt->data += ret;
|
||||
pkt->size -= ret;
|
||||
|
||||
/* A real program would do something useful with the decoded frame here.
|
||||
* We just retrieve the raw data and write it to a file, which is rather
|
||||
* useless but pedagogic. */
|
||||
ret = av_hwframe_transfer_data(sw_frame, frame, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error transferring the data to system memory\n");
|
||||
goto fail;
|
||||
}
|
||||
if (got_frame) {
|
||||
mfxFrameSurface1 *surf = (mfxFrameSurface1*)frame->data[3];
|
||||
VASurfaceID surface = *(VASurfaceID*)surf->Data.MemId;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(sw_frame->data) && sw_frame->data[i]; i++)
|
||||
for (j = 0; j < (sw_frame->height >> (i > 0)); j++)
|
||||
avio_write(output_ctx, sw_frame->data[i] + j * sw_frame->linesize[i], sw_frame->width);
|
||||
VAImageFormat img_fmt = {
|
||||
.fourcc = VA_FOURCC_NV12,
|
||||
.byte_order = VA_LSB_FIRST,
|
||||
.bits_per_pixel = 8,
|
||||
.depth = 8,
|
||||
};
|
||||
|
||||
VAImage img;
|
||||
|
||||
VAStatus err;
|
||||
uint8_t *data;
|
||||
int i, j;
|
||||
|
||||
img.buf = VA_INVALID_ID;
|
||||
img.image_id = VA_INVALID_ID;
|
||||
|
||||
err = vaCreateImage(decode->va_dpy, &img_fmt,
|
||||
frame->width, frame->height, &img);
|
||||
if (err != VA_STATUS_SUCCESS) {
|
||||
fprintf(stderr, "Error creating an image: %s\n",
|
||||
vaErrorStr(err));
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = vaGetImage(decode->va_dpy, surface, 0, 0,
|
||||
frame->width, frame->height,
|
||||
img.image_id);
|
||||
if (err != VA_STATUS_SUCCESS) {
|
||||
fprintf(stderr, "Error getting an image: %s\n",
|
||||
vaErrorStr(err));
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = vaMapBuffer(decode->va_dpy, img.buf, (void**)&data);
|
||||
if (err != VA_STATUS_SUCCESS) {
|
||||
fprintf(stderr, "Error mapping the image buffer: %s\n",
|
||||
vaErrorStr(err));
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < img.num_planes; i++)
|
||||
for (j = 0; j < (img.height >> (i > 0)); j++)
|
||||
avio_write(output_ctx, data + img.offsets[i] + j * img.pitches[i], img.width);
|
||||
|
||||
fail:
|
||||
av_frame_unref(sw_frame);
|
||||
av_frame_unref(frame);
|
||||
if (img.buf != VA_INVALID_ID)
|
||||
vaUnmapBuffer(decode->va_dpy, img.buf);
|
||||
if (img.image_id != VA_INVALID_ID)
|
||||
vaDestroyImage(decode->va_dpy, img.image_id);
|
||||
av_frame_unref(frame);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -113,14 +310,31 @@ int main(int argc, char **argv)
|
||||
AVCodecContext *decoder_ctx = NULL;
|
||||
const AVCodec *decoder;
|
||||
|
||||
AVPacket *pkt = NULL;
|
||||
AVFrame *frame = NULL, *sw_frame = NULL;
|
||||
AVPacket pkt = { 0 };
|
||||
AVFrame *frame = NULL;
|
||||
|
||||
DecodeContext decode = { NULL };
|
||||
|
||||
Display *dpy = NULL;
|
||||
int va_ver_major, va_ver_minor;
|
||||
|
||||
mfxIMPL mfx_impl = MFX_IMPL_AUTO_ANY;
|
||||
mfxVersion mfx_ver = { { 1, 1 } };
|
||||
|
||||
mfxFrameAllocator frame_allocator = {
|
||||
.pthis = &decode,
|
||||
.Alloc = frame_alloc,
|
||||
.Lock = frame_lock,
|
||||
.Unlock = frame_unlock,
|
||||
.GetHDL = frame_get_hdl,
|
||||
.Free = frame_free,
|
||||
};
|
||||
|
||||
AVIOContext *output_ctx = NULL;
|
||||
|
||||
int ret, i;
|
||||
int ret, i, err;
|
||||
|
||||
AVBufferRef *device_ref = NULL;
|
||||
av_register_all();
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||
@@ -148,13 +362,34 @@ int main(int argc, char **argv)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* open the hardware device */
|
||||
ret = av_hwdevice_ctx_create(&device_ref, AV_HWDEVICE_TYPE_QSV,
|
||||
"auto", NULL, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot open the hardware device\n");
|
||||
/* initialize VA-API */
|
||||
dpy = XOpenDisplay(NULL);
|
||||
if (!dpy) {
|
||||
fprintf(stderr, "Cannot open the X display\n");
|
||||
goto finish;
|
||||
}
|
||||
decode.va_dpy = vaGetDisplay(dpy);
|
||||
if (!decode.va_dpy) {
|
||||
fprintf(stderr, "Cannot open the VA display\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
err = vaInitialize(decode.va_dpy, &va_ver_major, &va_ver_minor);
|
||||
if (err != VA_STATUS_SUCCESS) {
|
||||
fprintf(stderr, "Cannot initialize VA: %s\n", vaErrorStr(err));
|
||||
goto finish;
|
||||
}
|
||||
fprintf(stderr, "Initialized VA v%d.%d\n", va_ver_major, va_ver_minor);
|
||||
|
||||
/* initialize an MFX session */
|
||||
err = MFXInit(mfx_impl, &mfx_ver, &decode.mfx_session);
|
||||
if (err != MFX_ERR_NONE) {
|
||||
fprintf(stderr, "Error initializing an MFX session\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
MFXVideoCORE_SetHandle(decode.mfx_session, MFX_HANDLE_VA_DISPLAY, decode.va_dpy);
|
||||
MFXVideoCORE_SetFrameAllocator(decode.mfx_session, &frame_allocator);
|
||||
|
||||
/* initialize the decoder */
|
||||
decoder = avcodec_find_decoder_by_name("h264_qsv");
|
||||
@@ -180,9 +415,10 @@ int main(int argc, char **argv)
|
||||
video_st->codecpar->extradata_size);
|
||||
decoder_ctx->extradata_size = video_st->codecpar->extradata_size;
|
||||
}
|
||||
decoder_ctx->refcounted_frames = 1;
|
||||
|
||||
|
||||
decoder_ctx->hw_device_ctx = av_buffer_ref(device_ref);
|
||||
decoder_ctx->opaque = &decode;
|
||||
decoder_ctx->get_buffer2 = get_buffer;
|
||||
decoder_ctx->get_format = get_format;
|
||||
|
||||
ret = avcodec_open2(decoder_ctx, NULL, NULL);
|
||||
@@ -198,28 +434,28 @@ int main(int argc, char **argv)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
sw_frame = av_frame_alloc();
|
||||
pkt = av_packet_alloc();
|
||||
if (!frame || !sw_frame || !pkt) {
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* actual decoding */
|
||||
while (ret >= 0) {
|
||||
ret = av_read_frame(input_ctx, pkt);
|
||||
ret = av_read_frame(input_ctx, &pkt);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
if (pkt->stream_index == video_st->index)
|
||||
ret = decode_packet(decoder_ctx, frame, sw_frame, pkt, output_ctx);
|
||||
if (pkt.stream_index == video_st->index)
|
||||
ret = decode_packet(&decode, decoder_ctx, frame, &pkt, output_ctx);
|
||||
|
||||
av_packet_unref(pkt);
|
||||
av_packet_unref(&pkt);
|
||||
}
|
||||
|
||||
/* flush the decoder */
|
||||
ret = decode_packet(decoder_ctx, frame, sw_frame, NULL, output_ctx);
|
||||
pkt.data = NULL;
|
||||
pkt.size = 0;
|
||||
ret = decode_packet(&decode, decoder_ctx, frame, &pkt, output_ctx);
|
||||
|
||||
finish:
|
||||
if (ret < 0) {
|
||||
@@ -231,12 +467,19 @@ finish:
|
||||
avformat_close_input(&input_ctx);
|
||||
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&sw_frame);
|
||||
av_packet_free(&pkt);
|
||||
|
||||
if (decoder_ctx)
|
||||
av_freep(&decoder_ctx->hwaccel_context);
|
||||
avcodec_free_context(&decoder_ctx);
|
||||
|
||||
av_buffer_unref(&device_ref);
|
||||
free_surfaces(&decode);
|
||||
|
||||
if (decode.mfx_session)
|
||||
MFXClose(decode.mfx_session);
|
||||
if (decode.va_dpy)
|
||||
vaTerminate(decode.va_dpy);
|
||||
if (dpy)
|
||||
XCloseDisplay(dpy);
|
||||
|
||||
avio_close(output_ctx);
|
||||
|
||||
|
||||
@@ -45,14 +45,11 @@ static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt, cons
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const AVOutputFormat *ofmt = NULL;
|
||||
AVOutputFormat *ofmt = NULL;
|
||||
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
|
||||
AVPacket *pkt = NULL;
|
||||
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"
|
||||
@@ -65,11 +62,7 @@ int main(int argc, char **argv)
|
||||
in_filename = argv[1];
|
||||
out_filename = argv[2];
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
fprintf(stderr, "Could not allocate AVPacket\n");
|
||||
return 1;
|
||||
}
|
||||
av_register_all();
|
||||
|
||||
if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
|
||||
fprintf(stderr, "Could not open input file '%s'", in_filename);
|
||||
@@ -90,42 +83,25 @@ int main(int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
stream_mapping_size = ifmt_ctx->nb_streams;
|
||||
stream_mapping = av_calloc(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);
|
||||
|
||||
@@ -146,39 +122,32 @@ int main(int argc, char **argv)
|
||||
while (1) {
|
||||
AVStream *in_stream, *out_stream;
|
||||
|
||||
ret = av_read_frame(ifmt_ctx, pkt);
|
||||
ret = av_read_frame(ifmt_ctx, &pkt);
|
||||
if (ret < 0)
|
||||
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;
|
||||
}
|
||||
in_stream = ifmt_ctx->streams[pkt.stream_index];
|
||||
out_stream = ofmt_ctx->streams[pkt.stream_index];
|
||||
|
||||
pkt->stream_index = stream_mapping[pkt->stream_index];
|
||||
out_stream = ofmt_ctx->streams[pkt->stream_index];
|
||||
log_packet(ifmt_ctx, pkt, "in");
|
||||
log_packet(ifmt_ctx, &pkt, "in");
|
||||
|
||||
/* copy packet */
|
||||
av_packet_rescale_ts(pkt, in_stream->time_base, out_stream->time_base);
|
||||
pkt->pos = -1;
|
||||
log_packet(ofmt_ctx, pkt, "out");
|
||||
pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
|
||||
pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
|
||||
pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
|
||||
pkt.pos = -1;
|
||||
log_packet(ofmt_ctx, &pkt, "out");
|
||||
|
||||
ret = av_interleaved_write_frame(ofmt_ctx, pkt);
|
||||
/* pkt is now blank (av_interleaved_write_frame() takes ownership of
|
||||
* its contents and resets pkt), so that no unreferencing is necessary.
|
||||
* This would be different if one used av_write_frame(). */
|
||||
ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error muxing packet\n");
|
||||
break;
|
||||
}
|
||||
av_packet_unref(&pkt);
|
||||
}
|
||||
|
||||
av_write_trailer(ofmt_ctx);
|
||||
end:
|
||||
av_packet_free(&pkt);
|
||||
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
|
||||
@@ -187,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;
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Andreas Unterweger
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
@@ -10,7 +8,7 @@
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
@@ -20,11 +18,10 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Simple audio converter
|
||||
* simple audio converter
|
||||
*
|
||||
* @example transcode_aac.c
|
||||
* Convert an input audio file to AAC in an MP4 container using FFmpeg.
|
||||
* Formats other than MP4 are supported based on the output file extension.
|
||||
* @author Andreas Unterweger (dustsigns@gmail.com)
|
||||
*/
|
||||
|
||||
@@ -38,50 +35,55 @@
|
||||
#include "libavutil/audio_fifo.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/frame.h"
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
#include "libswresample/swresample.h"
|
||||
|
||||
/* The output bit rate in bit/s */
|
||||
/** The output bit rate in kbit/s */
|
||||
#define OUTPUT_BIT_RATE 96000
|
||||
/* The number of output channels */
|
||||
/** The number of output channels */
|
||||
#define OUTPUT_CHANNELS 2
|
||||
|
||||
/**
|
||||
* Open an input file and the required decoder.
|
||||
* @param filename File to be opened
|
||||
* @param[out] input_format_context Format context of opened file
|
||||
* @param[out] input_codec_context Codec context of opened file
|
||||
* @return Error code (0 if successful)
|
||||
* 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,
|
||||
AVCodecContext **input_codec_context)
|
||||
{
|
||||
AVCodecContext *avctx;
|
||||
const AVCodec *input_codec;
|
||||
AVCodec *input_codec;
|
||||
int error;
|
||||
|
||||
/* Open the input file to read from it. */
|
||||
/** Open the input file to read from it. */
|
||||
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;
|
||||
}
|
||||
|
||||
/* Get information on the input file (number of streams etc.). */
|
||||
/** 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;
|
||||
}
|
||||
|
||||
/* Make sure that there is only one stream in the input file. */
|
||||
/** Make sure that there is only one stream in the input file. */
|
||||
if ((*input_format_context)->nb_streams != 1) {
|
||||
fprintf(stderr, "Expected one audio input stream, but found %d\n",
|
||||
(*input_format_context)->nb_streams);
|
||||
@@ -89,14 +91,14 @@ static int open_input_file(const char *filename,
|
||||
return AVERROR_EXIT;
|
||||
}
|
||||
|
||||
/* Find a decoder for the audio stream. */
|
||||
/** Find a decoder for the audio stream. */
|
||||
if (!(input_codec = avcodec_find_decoder((*input_format_context)->streams[0]->codecpar->codec_id))) {
|
||||
fprintf(stderr, "Could not find input codec\n");
|
||||
avformat_close_input(input_format_context);
|
||||
return AVERROR_EXIT;
|
||||
}
|
||||
|
||||
/* Allocate a new decoding context. */
|
||||
/** allocate a new decoding context */
|
||||
avctx = avcodec_alloc_context3(input_codec);
|
||||
if (!avctx) {
|
||||
fprintf(stderr, "Could not allocate a decoding context\n");
|
||||
@@ -104,7 +106,7 @@ static int open_input_file(const char *filename,
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* Initialize the stream parameters with demuxer information. */
|
||||
/** initialize the stream parameters with demuxer information */
|
||||
error = avcodec_parameters_to_context(avctx, (*input_format_context)->streams[0]->codecpar);
|
||||
if (error < 0) {
|
||||
avformat_close_input(input_format_context);
|
||||
@@ -112,16 +114,16 @@ static int open_input_file(const char *filename,
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Open the decoder for the audio stream to use it later. */
|
||||
/** 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;
|
||||
}
|
||||
|
||||
/* Save the decoder context for easier access later. */
|
||||
/** Save the decoder context for easier access later. */
|
||||
*input_codec_context = avctx;
|
||||
|
||||
return 0;
|
||||
@@ -131,11 +133,6 @@ static int open_input_file(const char *filename,
|
||||
* Open an output file and the required encoder.
|
||||
* Also set some basic encoder parameters.
|
||||
* Some of these parameters are based on the input file's parameters.
|
||||
* @param filename File to be opened
|
||||
* @param input_codec_context Codec context of input file
|
||||
* @param[out] output_format_context Format context of output file
|
||||
* @param[out] output_codec_context Codec context of output file
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int open_output_file(const char *filename,
|
||||
AVCodecContext *input_codec_context,
|
||||
@@ -145,46 +142,43 @@ static int open_output_file(const char *filename,
|
||||
AVCodecContext *avctx = NULL;
|
||||
AVIOContext *output_io_context = NULL;
|
||||
AVStream *stream = NULL;
|
||||
const AVCodec *output_codec = NULL;
|
||||
AVCodec *output_codec = NULL;
|
||||
int error;
|
||||
|
||||
/* Open the output file to write to it. */
|
||||
/** Open the output file to write to it. */
|
||||
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;
|
||||
}
|
||||
|
||||
/* Create a new format context for the output container format. */
|
||||
/** Create a new format context for the output container format. */
|
||||
if (!(*output_format_context = avformat_alloc_context())) {
|
||||
fprintf(stderr, "Could not allocate output format context\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* Associate the output file (pointer) with the container format context. */
|
||||
/** Associate the output file (pointer) with the container format context. */
|
||||
(*output_format_context)->pb = output_io_context;
|
||||
|
||||
/* Guess the desired container format based on the file extension. */
|
||||
/** Guess the desired container format based on the file extension. */
|
||||
if (!((*output_format_context)->oformat = av_guess_format(NULL, filename,
|
||||
NULL))) {
|
||||
fprintf(stderr, "Could not find output file format\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!((*output_format_context)->url = av_strdup(filename))) {
|
||||
fprintf(stderr, "Could not allocate url.\n");
|
||||
error = AVERROR(ENOMEM);
|
||||
goto cleanup;
|
||||
}
|
||||
av_strlcpy((*output_format_context)->filename, filename,
|
||||
sizeof((*output_format_context)->filename));
|
||||
|
||||
/* Find the encoder to be used by its name. */
|
||||
/** Find the encoder to be used by its name. */
|
||||
if (!(output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC))) {
|
||||
fprintf(stderr, "Could not find an AAC encoder.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Create a new audio stream in the output file container. */
|
||||
/** Create a new audio stream in the output file container. */
|
||||
if (!(stream = avformat_new_stream(*output_format_context, NULL))) {
|
||||
fprintf(stderr, "Could not create new stream\n");
|
||||
error = AVERROR(ENOMEM);
|
||||
@@ -198,30 +192,34 @@ static int open_output_file(const char *filename,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Set the basic encoder parameters.
|
||||
* The input file's sample rate is used to avoid a sample rate conversion. */
|
||||
/**
|
||||
* Set the basic encoder parameters.
|
||||
* The input file's sample rate is used to avoid a sample rate conversion.
|
||||
*/
|
||||
avctx->channels = OUTPUT_CHANNELS;
|
||||
avctx->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS);
|
||||
avctx->sample_rate = input_codec_context->sample_rate;
|
||||
avctx->sample_fmt = output_codec->sample_fmts[0];
|
||||
avctx->bit_rate = OUTPUT_BIT_RATE;
|
||||
|
||||
/* Allow the use of the experimental AAC encoder. */
|
||||
/** Allow the use of the experimental AAC encoder */
|
||||
avctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
|
||||
|
||||
/* Set the sample rate for the container. */
|
||||
/** Set the sample rate for the container. */
|
||||
stream->time_base.den = input_codec_context->sample_rate;
|
||||
stream->time_base.num = 1;
|
||||
|
||||
/* Some container formats (like MP4) require global headers to be present.
|
||||
* Mark the encoder so that it behaves accordingly. */
|
||||
/**
|
||||
* Some container formats (like MP4) require global headers to be present
|
||||
* Mark the encoder so that it behaves accordingly.
|
||||
*/
|
||||
if ((*output_format_context)->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
avctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
/* Open the encoder for the audio stream to use it later. */
|
||||
/** 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;
|
||||
}
|
||||
|
||||
@@ -231,7 +229,7 @@ static int open_output_file(const char *filename,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Save the encoder context for easier access later. */
|
||||
/** Save the encoder context for easier access later. */
|
||||
*output_codec_context = avctx;
|
||||
|
||||
return 0;
|
||||
@@ -244,25 +242,16 @@ cleanup:
|
||||
return error < 0 ? error : AVERROR_EXIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize one data packet for reading or writing.
|
||||
* @param[out] packet Packet to be initialized
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int init_packet(AVPacket **packet)
|
||||
/** Initialize one data packet for reading or writing. */
|
||||
static void init_packet(AVPacket *packet)
|
||||
{
|
||||
if (!(*packet = av_packet_alloc())) {
|
||||
fprintf(stderr, "Could not allocate packet\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
return 0;
|
||||
av_init_packet(packet);
|
||||
/** Set the packet data and size so that it is recognized as being empty. */
|
||||
packet->data = NULL;
|
||||
packet->size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize one audio frame for reading from the input file.
|
||||
* @param[out] frame Frame to be initialized
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
/** Initialize one audio frame for reading from the input file */
|
||||
static int init_input_frame(AVFrame **frame)
|
||||
{
|
||||
if (!(*frame = av_frame_alloc())) {
|
||||
@@ -276,10 +265,6 @@ static int init_input_frame(AVFrame **frame)
|
||||
* Initialize the audio resampler based on the input and output codec settings.
|
||||
* If the input and output sample formats differ, a conversion is required
|
||||
* libswresample takes care of this, but requires initialization.
|
||||
* @param input_codec_context Codec context of the input file
|
||||
* @param output_codec_context Codec context of the output file
|
||||
* @param[out] resample_context Resample context for the required conversion
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int init_resampler(AVCodecContext *input_codec_context,
|
||||
AVCodecContext *output_codec_context,
|
||||
@@ -287,7 +272,7 @@ static int init_resampler(AVCodecContext *input_codec_context,
|
||||
{
|
||||
int error;
|
||||
|
||||
/*
|
||||
/**
|
||||
* Create a resampler context for the conversion.
|
||||
* Set the conversion parameters.
|
||||
* Default channel layouts based on the number of channels
|
||||
@@ -306,14 +291,14 @@ static int init_resampler(AVCodecContext *input_codec_context,
|
||||
fprintf(stderr, "Could not allocate resample context\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
/*
|
||||
/**
|
||||
* Perform a sanity check so that the number of converted samples is
|
||||
* not greater than the number of samples to be converted.
|
||||
* If the sample rates differ, this case has to be handled differently
|
||||
*/
|
||||
av_assert0(output_codec_context->sample_rate == input_codec_context->sample_rate);
|
||||
|
||||
/* Open the resampler with the specified parameters. */
|
||||
/** Open the resampler with the specified parameters. */
|
||||
if ((error = swr_init(*resample_context)) < 0) {
|
||||
fprintf(stderr, "Could not open resample context\n");
|
||||
swr_free(resample_context);
|
||||
@@ -322,15 +307,10 @@ static int init_resampler(AVCodecContext *input_codec_context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a FIFO buffer for the audio samples to be encoded.
|
||||
* @param[out] fifo Sample buffer
|
||||
* @param output_codec_context Codec context of the output file
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
/** Initialize a FIFO buffer for the audio samples to be encoded. */
|
||||
static int init_fifo(AVAudioFifo **fifo, AVCodecContext *output_codec_context)
|
||||
{
|
||||
/* Create the FIFO buffer based on the specified output sample format. */
|
||||
/** Create the FIFO buffer based on the specified output sample format. */
|
||||
if (!(*fifo = av_audio_fifo_alloc(output_codec_context->sample_fmt,
|
||||
output_codec_context->channels, 1))) {
|
||||
fprintf(stderr, "Could not allocate FIFO\n");
|
||||
@@ -339,106 +319,69 @@ static int init_fifo(AVAudioFifo **fifo, AVCodecContext *output_codec_context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the header of the output file container.
|
||||
* @param output_format_context Format context of the output file
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
/** Write the header of the output file container. */
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode one audio frame from the input file.
|
||||
* @param frame Audio frame to be decoded
|
||||
* @param input_format_context Format context of the input file
|
||||
* @param input_codec_context Codec context of the input file
|
||||
* @param[out] data_present Indicates whether data has been decoded
|
||||
* @param[out] finished Indicates whether the end of file has
|
||||
* been reached and all data has been
|
||||
* decoded. If this flag is false, there
|
||||
* is more data to be decoded, i.e., this
|
||||
* function has to be called again.
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
/** Decode one audio frame from the input file. */
|
||||
static int decode_audio_frame(AVFrame *frame,
|
||||
AVFormatContext *input_format_context,
|
||||
AVCodecContext *input_codec_context,
|
||||
int *data_present, int *finished)
|
||||
{
|
||||
/* Packet used for temporary storage. */
|
||||
AVPacket *input_packet;
|
||||
/** Packet used for temporary storage. */
|
||||
AVPacket input_packet;
|
||||
int error;
|
||||
init_packet(&input_packet);
|
||||
|
||||
error = init_packet(&input_packet);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
/* Read one audio frame from the input file into a temporary packet. */
|
||||
if ((error = av_read_frame(input_format_context, input_packet)) < 0) {
|
||||
/* If we are at the end of the file, flush the decoder below. */
|
||||
/** Read one audio frame from the input file into a temporary packet. */
|
||||
if ((error = av_read_frame(input_format_context, &input_packet)) < 0) {
|
||||
/** If we are at the end of the file, flush the decoder below. */
|
||||
if (error == AVERROR_EOF)
|
||||
*finished = 1;
|
||||
else {
|
||||
fprintf(stderr, "Could not read frame (error '%s')\n",
|
||||
av_err2str(error));
|
||||
goto cleanup;
|
||||
get_error_text(error));
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send the audio frame stored in the temporary packet to the decoder.
|
||||
* The input audio stream decoder is used to do this. */
|
||||
if ((error = avcodec_send_packet(input_codec_context, input_packet)) < 0) {
|
||||
fprintf(stderr, "Could not send packet for decoding (error '%s')\n",
|
||||
av_err2str(error));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Receive one frame from the decoder. */
|
||||
error = avcodec_receive_frame(input_codec_context, frame);
|
||||
/* If the decoder asks for more data to be able to decode a frame,
|
||||
* return indicating that no data is present. */
|
||||
if (error == AVERROR(EAGAIN)) {
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
/* If the end of the input file is reached, stop decoding. */
|
||||
} else if (error == AVERROR_EOF) {
|
||||
*finished = 1;
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
} else if (error < 0) {
|
||||
/**
|
||||
* Decode the audio frame stored in the temporary packet.
|
||||
* The input audio stream decoder is used to do this.
|
||||
* If we are at the end of the file, pass an empty packet to the decoder
|
||||
* to flush it.
|
||||
*/
|
||||
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));
|
||||
goto cleanup;
|
||||
/* Default case: Return decoded data. */
|
||||
} else {
|
||||
*data_present = 1;
|
||||
goto cleanup;
|
||||
get_error_text(error));
|
||||
av_packet_unref(&input_packet);
|
||||
return error;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
av_packet_free(&input_packet);
|
||||
return error;
|
||||
/**
|
||||
* If the decoder has not been flushed completely, we are not finished,
|
||||
* so that this function has to be called again.
|
||||
*/
|
||||
if (*finished && *data_present)
|
||||
*finished = 0;
|
||||
av_packet_unref(&input_packet);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a temporary storage for the specified number of audio samples.
|
||||
* The conversion requires temporary storage due to the different format.
|
||||
* The number of audio samples to be allocated is specified in frame_size.
|
||||
* @param[out] converted_input_samples Array of converted samples. The
|
||||
* dimensions are reference, channel
|
||||
* (for multi-channel audio), sample.
|
||||
* @param output_codec_context Codec context of the output file
|
||||
* @param frame_size Number of samples to be converted in
|
||||
* each round
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int init_converted_samples(uint8_t ***converted_input_samples,
|
||||
AVCodecContext *output_codec_context,
|
||||
@@ -446,7 +389,8 @@ static int init_converted_samples(uint8_t ***converted_input_samples,
|
||||
{
|
||||
int error;
|
||||
|
||||
/* Allocate as many pointers as there are audio channels.
|
||||
/**
|
||||
* Allocate as many pointers as there are audio channels.
|
||||
* Each pointer will later point to the audio samples of the corresponding
|
||||
* channels (although it may be NULL for interleaved formats).
|
||||
*/
|
||||
@@ -456,15 +400,17 @@ static int init_converted_samples(uint8_t ***converted_input_samples,
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* Allocate memory for the samples of all channels in one consecutive
|
||||
* block for convenience. */
|
||||
/**
|
||||
* Allocate memory for the samples of all channels in one consecutive
|
||||
* block for convenience.
|
||||
*/
|
||||
if ((error = av_samples_alloc(*converted_input_samples, NULL,
|
||||
output_codec_context->channels,
|
||||
frame_size,
|
||||
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;
|
||||
@@ -474,15 +420,8 @@ static int init_converted_samples(uint8_t ***converted_input_samples,
|
||||
|
||||
/**
|
||||
* Convert the input audio samples into the output sample format.
|
||||
* The conversion happens on a per-frame basis, the size of which is
|
||||
* specified by frame_size.
|
||||
* @param input_data Samples to be decoded. The dimensions are
|
||||
* channel (for multi-channel audio), sample.
|
||||
* @param[out] converted_data Converted samples. The dimensions are channel
|
||||
* (for multi-channel audio), sample.
|
||||
* @param frame_size Number of samples to be converted
|
||||
* @param resample_context Resample context for the conversion
|
||||
* @return Error code (0 if successful)
|
||||
* The conversion happens on a per-frame basis, the size of which is specified
|
||||
* by frame_size.
|
||||
*/
|
||||
static int convert_samples(const uint8_t **input_data,
|
||||
uint8_t **converted_data, const int frame_size,
|
||||
@@ -490,40 +429,35 @@ static int convert_samples(const uint8_t **input_data,
|
||||
{
|
||||
int error;
|
||||
|
||||
/* Convert the samples using the resampler. */
|
||||
/** Convert the samples using the resampler. */
|
||||
if ((error = swr_convert(resample_context,
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add converted input audio samples to the FIFO buffer for later processing.
|
||||
* @param fifo Buffer to add the samples to
|
||||
* @param converted_input_samples Samples to be added. The dimensions are channel
|
||||
* (for multi-channel audio), sample.
|
||||
* @param frame_size Number of samples to be converted
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
/** Add converted input audio samples to the FIFO buffer for later processing. */
|
||||
static int add_samples_to_fifo(AVAudioFifo *fifo,
|
||||
uint8_t **converted_input_samples,
|
||||
const int frame_size)
|
||||
{
|
||||
int error;
|
||||
|
||||
/* Make the FIFO as large as it needs to be to hold both,
|
||||
* the old and the new samples. */
|
||||
/**
|
||||
* Make the FIFO as large as it needs to be to hold both,
|
||||
* the old and the new samples.
|
||||
*/
|
||||
if ((error = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame_size)) < 0) {
|
||||
fprintf(stderr, "Could not reallocate FIFO\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Store the new samples in the FIFO buffer. */
|
||||
/** Store the new samples in the FIFO buffer. */
|
||||
if (av_audio_fifo_write(fifo, (void **)converted_input_samples,
|
||||
frame_size) < frame_size) {
|
||||
fprintf(stderr, "Could not write data to FIFO\n");
|
||||
@@ -533,20 +467,8 @@ static int add_samples_to_fifo(AVAudioFifo *fifo,
|
||||
}
|
||||
|
||||
/**
|
||||
* Read one audio frame from the input file, decode, convert and store
|
||||
* Read one audio frame from the input file, decodes, converts and stores
|
||||
* it in the FIFO buffer.
|
||||
* @param fifo Buffer used for temporary storage
|
||||
* @param input_format_context Format context of the input file
|
||||
* @param input_codec_context Codec context of the input file
|
||||
* @param output_codec_context Codec context of the output file
|
||||
* @param resampler_context Resample context for the conversion
|
||||
* @param[out] finished Indicates whether the end of file has
|
||||
* been reached and all data has been
|
||||
* decoded. If this flag is false,
|
||||
* there is more data to be decoded,
|
||||
* i.e., this function has to be called
|
||||
* again.
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int read_decode_convert_and_store(AVAudioFifo *fifo,
|
||||
AVFormatContext *input_format_context,
|
||||
@@ -555,41 +477,45 @@ static int read_decode_convert_and_store(AVAudioFifo *fifo,
|
||||
SwrContext *resampler_context,
|
||||
int *finished)
|
||||
{
|
||||
/* Temporary storage of the input samples of the frame read from the file. */
|
||||
/** Temporary storage of the input samples of the frame read from the file. */
|
||||
AVFrame *input_frame = NULL;
|
||||
/* Temporary storage for the converted input samples. */
|
||||
/** Temporary storage for the converted input samples. */
|
||||
uint8_t **converted_input_samples = NULL;
|
||||
int data_present = 0;
|
||||
int data_present;
|
||||
int ret = AVERROR_EXIT;
|
||||
|
||||
/* Initialize temporary storage for one input frame. */
|
||||
/** Initialize temporary storage for one input frame. */
|
||||
if (init_input_frame(&input_frame))
|
||||
goto cleanup;
|
||||
/* Decode one frame worth of audio samples. */
|
||||
/** Decode one frame worth of audio samples. */
|
||||
if (decode_audio_frame(input_frame, input_format_context,
|
||||
input_codec_context, &data_present, finished))
|
||||
goto cleanup;
|
||||
/* If we are at the end of the file and there are no more samples
|
||||
/**
|
||||
* If we are at the end of the file and there are no more samples
|
||||
* in the decoder which are delayed, we are actually finished.
|
||||
* This must not be treated as an error. */
|
||||
if (*finished) {
|
||||
* This must not be treated as an error.
|
||||
*/
|
||||
if (*finished && !data_present) {
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
/* If there is decoded data, convert and store it. */
|
||||
/** If there is decoded data, convert and store it */
|
||||
if (data_present) {
|
||||
/* Initialize the temporary storage for the converted input samples. */
|
||||
/** Initialize the temporary storage for the converted input samples. */
|
||||
if (init_converted_samples(&converted_input_samples, output_codec_context,
|
||||
input_frame->nb_samples))
|
||||
goto cleanup;
|
||||
|
||||
/* Convert the input samples to the desired output sample format.
|
||||
* This requires a temporary storage provided by converted_input_samples. */
|
||||
/**
|
||||
* Convert the input samples to the desired output sample format.
|
||||
* This requires a temporary storage provided by converted_input_samples.
|
||||
*/
|
||||
if (convert_samples((const uint8_t**)input_frame->extended_data, converted_input_samples,
|
||||
input_frame->nb_samples, resampler_context))
|
||||
goto cleanup;
|
||||
|
||||
/* Add the converted input samples to the FIFO buffer for later processing. */
|
||||
/** Add the converted input samples to the FIFO buffer for later processing. */
|
||||
if (add_samples_to_fifo(fifo, converted_input_samples,
|
||||
input_frame->nb_samples))
|
||||
goto cleanup;
|
||||
@@ -610,10 +536,6 @@ cleanup:
|
||||
/**
|
||||
* Initialize one input frame for writing to the output file.
|
||||
* The frame will be exactly frame_size samples large.
|
||||
* @param[out] frame Frame to be initialized
|
||||
* @param output_codec_context Codec context of the output file
|
||||
* @param frame_size Size of the frame
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int init_output_frame(AVFrame **frame,
|
||||
AVCodecContext *output_codec_context,
|
||||
@@ -621,27 +543,31 @@ static int init_output_frame(AVFrame **frame,
|
||||
{
|
||||
int error;
|
||||
|
||||
/* Create a new frame to store the audio samples. */
|
||||
/** Create a new frame to store the audio samples. */
|
||||
if (!(*frame = av_frame_alloc())) {
|
||||
fprintf(stderr, "Could not allocate output frame\n");
|
||||
return AVERROR_EXIT;
|
||||
}
|
||||
|
||||
/* Set the frame's parameters, especially its size and format.
|
||||
/**
|
||||
* Set the frame's parameters, especially its size and format.
|
||||
* av_frame_get_buffer needs this to allocate memory for the
|
||||
* audio samples of the frame.
|
||||
* Default channel layouts based on the number of channels
|
||||
* are assumed for simplicity. */
|
||||
* are assumed for simplicity.
|
||||
*/
|
||||
(*frame)->nb_samples = frame_size;
|
||||
(*frame)->channel_layout = output_codec_context->channel_layout;
|
||||
(*frame)->format = output_codec_context->sample_fmt;
|
||||
(*frame)->sample_rate = output_codec_context->sample_rate;
|
||||
|
||||
/* Allocate the samples of the created frame. This call will make
|
||||
* sure that the audio frame can hold as many samples as specified. */
|
||||
/**
|
||||
* Allocate the samples of the created frame. This call will make
|
||||
* 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;
|
||||
}
|
||||
@@ -649,117 +575,87 @@ static int init_output_frame(AVFrame **frame,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Global timestamp for the audio frames. */
|
||||
/** Global timestamp for the audio frames */
|
||||
static int64_t pts = 0;
|
||||
|
||||
/**
|
||||
* Encode one frame worth of audio to the output file.
|
||||
* @param frame Samples to be encoded
|
||||
* @param output_format_context Format context of the output file
|
||||
* @param output_codec_context Codec context of the output file
|
||||
* @param[out] data_present Indicates whether data has been
|
||||
* encoded
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
/** Encode one frame worth of audio to the output file. */
|
||||
static int encode_audio_frame(AVFrame *frame,
|
||||
AVFormatContext *output_format_context,
|
||||
AVCodecContext *output_codec_context,
|
||||
int *data_present)
|
||||
{
|
||||
/* Packet used for temporary storage. */
|
||||
AVPacket *output_packet;
|
||||
/** Packet used for temporary storage. */
|
||||
AVPacket output_packet;
|
||||
int error;
|
||||
init_packet(&output_packet);
|
||||
|
||||
error = init_packet(&output_packet);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
/* Set a timestamp based on the sample rate for the container. */
|
||||
/** Set a timestamp based on the sample rate for the container. */
|
||||
if (frame) {
|
||||
frame->pts = pts;
|
||||
pts += frame->nb_samples;
|
||||
}
|
||||
|
||||
/* Send the audio frame stored in the temporary packet to the encoder.
|
||||
* The output audio stream encoder is used to do this. */
|
||||
error = avcodec_send_frame(output_codec_context, frame);
|
||||
/* The encoder signals that it has nothing more to encode. */
|
||||
if (error == AVERROR_EOF) {
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
} else if (error < 0) {
|
||||
fprintf(stderr, "Could not send packet for encoding (error '%s')\n",
|
||||
av_err2str(error));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Receive one encoded frame from the encoder. */
|
||||
error = avcodec_receive_packet(output_codec_context, output_packet);
|
||||
/* If the encoder asks for more data to be able to provide an
|
||||
* encoded frame, return indicating that no data is present. */
|
||||
if (error == AVERROR(EAGAIN)) {
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
/* If the last frame has been encoded, stop encoding. */
|
||||
} else if (error == AVERROR_EOF) {
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
} else if (error < 0) {
|
||||
/**
|
||||
* Encode the audio frame and store it in the temporary packet.
|
||||
* The output audio stream encoder is used to do this.
|
||||
*/
|
||||
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));
|
||||
goto cleanup;
|
||||
/* Default case: Return encoded data. */
|
||||
} else {
|
||||
*data_present = 1;
|
||||
get_error_text(error));
|
||||
av_packet_unref(&output_packet);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Write one audio frame from the temporary packet to the output file. */
|
||||
if (*data_present &&
|
||||
(error = av_write_frame(output_format_context, output_packet)) < 0) {
|
||||
fprintf(stderr, "Could not write frame (error '%s')\n",
|
||||
av_err2str(error));
|
||||
goto cleanup;
|
||||
/** Write one audio frame from the temporary packet to the output file. */
|
||||
if (*data_present) {
|
||||
if ((error = av_write_frame(output_format_context, &output_packet)) < 0) {
|
||||
fprintf(stderr, "Could not write frame (error '%s')\n",
|
||||
get_error_text(error));
|
||||
av_packet_unref(&output_packet);
|
||||
return error;
|
||||
}
|
||||
|
||||
av_packet_unref(&output_packet);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
av_packet_free(&output_packet);
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load one audio frame from the FIFO buffer, encode and write it to the
|
||||
* output file.
|
||||
* @param fifo Buffer used for temporary storage
|
||||
* @param output_format_context Format context of the output file
|
||||
* @param output_codec_context Codec context of the output file
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
static int load_encode_and_write(AVAudioFifo *fifo,
|
||||
AVFormatContext *output_format_context,
|
||||
AVCodecContext *output_codec_context)
|
||||
{
|
||||
/* Temporary storage of the output samples of the frame written to the file. */
|
||||
/** Temporary storage of the output samples of the frame written to the file. */
|
||||
AVFrame *output_frame;
|
||||
/* Use the maximum number of possible samples per frame.
|
||||
/**
|
||||
* Use the maximum number of possible samples per frame.
|
||||
* If there is less than the maximum possible frame size in the FIFO
|
||||
* buffer use this number. Otherwise, use the maximum possible frame size. */
|
||||
* buffer use this number. Otherwise, use the maximum possible frame size
|
||||
*/
|
||||
const int frame_size = FFMIN(av_audio_fifo_size(fifo),
|
||||
output_codec_context->frame_size);
|
||||
int data_written;
|
||||
|
||||
/* Initialize temporary storage for one output frame. */
|
||||
/** Initialize temporary storage for one output frame. */
|
||||
if (init_output_frame(&output_frame, output_codec_context, frame_size))
|
||||
return AVERROR_EXIT;
|
||||
|
||||
/* Read as many samples from the FIFO buffer as required to fill the frame.
|
||||
* The samples are stored in the frame temporarily. */
|
||||
/**
|
||||
* Read as many samples from the FIFO buffer as required to fill the frame.
|
||||
* The samples are stored in the frame temporarily.
|
||||
*/
|
||||
if (av_audio_fifo_read(fifo, (void **)output_frame->data, frame_size) < frame_size) {
|
||||
fprintf(stderr, "Could not read data from FIFO\n");
|
||||
av_frame_free(&output_frame);
|
||||
return AVERROR_EXIT;
|
||||
}
|
||||
|
||||
/* Encode one frame worth of audio samples. */
|
||||
/** Encode one frame worth of audio samples. */
|
||||
if (encode_audio_frame(output_frame, output_format_context,
|
||||
output_codec_context, &data_written)) {
|
||||
av_frame_free(&output_frame);
|
||||
@@ -769,22 +665,19 @@ static int load_encode_and_write(AVAudioFifo *fifo,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the trailer of the output file container.
|
||||
* @param output_format_context Format context of the output file
|
||||
* @return Error code (0 if successful)
|
||||
*/
|
||||
/** Write the trailer of the output file container. */
|
||||
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;
|
||||
}
|
||||
|
||||
/** Convert an audio file to an AAC file in an MP4 container. */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
AVFormatContext *input_format_context = NULL, *output_format_context = NULL;
|
||||
@@ -793,75 +686,90 @@ int main(int argc, char **argv)
|
||||
AVAudioFifo *fifo = NULL;
|
||||
int ret = AVERROR_EXIT;
|
||||
|
||||
if (argc != 3) {
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Open the input file for reading. */
|
||||
/** Register all codecs and formats so that they can be used. */
|
||||
av_register_all();
|
||||
/** Open the input file for reading. */
|
||||
if (open_input_file(argv[1], &input_format_context,
|
||||
&input_codec_context))
|
||||
goto cleanup;
|
||||
/* Open the output file for writing. */
|
||||
/** Open the output file for writing. */
|
||||
if (open_output_file(argv[2], input_codec_context,
|
||||
&output_format_context, &output_codec_context))
|
||||
goto cleanup;
|
||||
/* Initialize the resampler to be able to convert audio sample formats. */
|
||||
/** Initialize the resampler to be able to convert audio sample formats. */
|
||||
if (init_resampler(input_codec_context, output_codec_context,
|
||||
&resample_context))
|
||||
goto cleanup;
|
||||
/* Initialize the FIFO buffer to store audio samples to be encoded. */
|
||||
/** Initialize the FIFO buffer to store audio samples to be encoded. */
|
||||
if (init_fifo(&fifo, output_codec_context))
|
||||
goto cleanup;
|
||||
/* Write the header of the output file container. */
|
||||
/** Write the header of the output file container. */
|
||||
if (write_output_file_header(output_format_context))
|
||||
goto cleanup;
|
||||
|
||||
/* Loop as long as we have input samples to read or output samples
|
||||
* to write; abort as soon as we have neither. */
|
||||
/**
|
||||
* Loop as long as we have input samples to read or output samples
|
||||
* to write; abort as soon as we have neither.
|
||||
*/
|
||||
while (1) {
|
||||
/* Use the encoder's desired frame size for processing. */
|
||||
/** Use the encoder's desired frame size for processing. */
|
||||
const int output_frame_size = output_codec_context->frame_size;
|
||||
int finished = 0;
|
||||
|
||||
/* Make sure that there is one frame worth of samples in the FIFO
|
||||
/**
|
||||
* Make sure that there is one frame worth of samples in the FIFO
|
||||
* buffer so that the encoder can do its work.
|
||||
* Since the decoder's and the encoder's frame size may differ, we
|
||||
* need to FIFO buffer to store as many frames worth of input samples
|
||||
* that they make up at least one frame worth of output samples. */
|
||||
* that they make up at least one frame worth of output samples.
|
||||
*/
|
||||
while (av_audio_fifo_size(fifo) < output_frame_size) {
|
||||
/* Decode one frame worth of audio samples, convert it to the
|
||||
* output sample format and put it into the FIFO buffer. */
|
||||
/**
|
||||
* Decode one frame worth of audio samples, convert it to the
|
||||
* output sample format and put it into the FIFO buffer.
|
||||
*/
|
||||
if (read_decode_convert_and_store(fifo, input_format_context,
|
||||
input_codec_context,
|
||||
output_codec_context,
|
||||
resample_context, &finished))
|
||||
goto cleanup;
|
||||
|
||||
/* If we are at the end of the input file, we continue
|
||||
* encoding the remaining audio samples to the output file. */
|
||||
/**
|
||||
* If we are at the end of the input file, we continue
|
||||
* encoding the remaining audio samples to the output file.
|
||||
*/
|
||||
if (finished)
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we have enough samples for the encoder, we encode them.
|
||||
/**
|
||||
* If we have enough samples for the encoder, we encode them.
|
||||
* At the end of the file, we pass the remaining samples to
|
||||
* the encoder. */
|
||||
* the encoder.
|
||||
*/
|
||||
while (av_audio_fifo_size(fifo) >= output_frame_size ||
|
||||
(finished && av_audio_fifo_size(fifo) > 0))
|
||||
/* Take one frame worth of audio samples from the FIFO buffer,
|
||||
* encode it and write it to the output file. */
|
||||
/**
|
||||
* Take one frame worth of audio samples from the FIFO buffer,
|
||||
* encode it and write it to the output file.
|
||||
*/
|
||||
if (load_encode_and_write(fifo, output_format_context,
|
||||
output_codec_context))
|
||||
goto cleanup;
|
||||
|
||||
/* If we are at the end of the input file and have encoded
|
||||
* all remaining samples, we can exit this loop and finish. */
|
||||
/**
|
||||
* If we are at the end of the input file and have encoded
|
||||
* all remaining samples, we can exit this loop and finish.
|
||||
*/
|
||||
if (finished) {
|
||||
int data_written;
|
||||
/* Flush the encoder as it may have delayed frames. */
|
||||
/** Flush the encoder as it may have delayed frames. */
|
||||
do {
|
||||
data_written = 0;
|
||||
if (encode_audio_frame(NULL, output_format_context,
|
||||
output_codec_context, &data_written))
|
||||
goto cleanup;
|
||||
@@ -870,7 +778,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the trailer of the output file container. */
|
||||
/** Write the trailer of the output file container. */
|
||||
if (write_output_file_trailer(output_format_context))
|
||||
goto cleanup;
|
||||
ret = 0;
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavfilter/avfiltergraph.h>
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
|
||||
@@ -42,20 +42,9 @@ typedef struct FilteringContext {
|
||||
AVFilterContext *buffersink_ctx;
|
||||
AVFilterContext *buffersrc_ctx;
|
||||
AVFilterGraph *filter_graph;
|
||||
|
||||
AVPacket *enc_pkt;
|
||||
AVFrame *filtered_frame;
|
||||
} FilteringContext;
|
||||
static FilteringContext *filter_ctx;
|
||||
|
||||
typedef struct StreamContext {
|
||||
AVCodecContext *dec_ctx;
|
||||
AVCodecContext *enc_ctx;
|
||||
|
||||
AVFrame *dec_frame;
|
||||
} StreamContext;
|
||||
static StreamContext *stream_ctx;
|
||||
|
||||
static int open_input_file(const char *filename)
|
||||
{
|
||||
int ret;
|
||||
@@ -72,46 +61,22 @@ static int open_input_file(const char *filename)
|
||||
return ret;
|
||||
}
|
||||
|
||||
stream_ctx = av_calloc(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];
|
||||
const 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;
|
||||
|
||||
stream_ctx[i].dec_frame = av_frame_alloc();
|
||||
if (!stream_ctx[i].dec_frame)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
av_dump_format(ifmt_ctx, 0, filename, 0);
|
||||
@@ -123,7 +88,7 @@ static int open_output_file(const char *filename)
|
||||
AVStream *out_stream;
|
||||
AVStream *in_stream;
|
||||
AVCodecContext *dec_ctx, *enc_ctx;
|
||||
const AVCodec *encoder;
|
||||
AVCodec *encoder;
|
||||
int ret;
|
||||
unsigned int i;
|
||||
|
||||
@@ -143,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) {
|
||||
@@ -153,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
|
||||
@@ -172,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;
|
||||
@@ -182,36 +143,28 @@ static int open_output_file(const char *filename)
|
||||
enc_ctx->time_base = (AVRational){1, enc_ctx->sample_rate};
|
||||
}
|
||||
|
||||
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
/* Third parameter can be used to pass settings to encoder */
|
||||
ret = avcodec_open2(enc_ctx, encoder, NULL);
|
||||
if (ret < 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -238,8 +191,8 @@ static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx,
|
||||
{
|
||||
char args[512];
|
||||
int ret = 0;
|
||||
const AVFilter *buffersrc = NULL;
|
||||
const AVFilter *buffersink = NULL;
|
||||
AVFilter *buffersrc = NULL;
|
||||
AVFilter *buffersink = NULL;
|
||||
AVFilterContext *buffersrc_ctx = NULL;
|
||||
AVFilterContext *buffersink_ctx = NULL;
|
||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||
@@ -395,76 +348,67 @@ 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;
|
||||
|
||||
filter_ctx[i].enc_pkt = av_packet_alloc();
|
||||
if (!filter_ctx[i].enc_pkt)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
filter_ctx[i].filtered_frame = av_frame_alloc();
|
||||
if (!filter_ctx[i].filtered_frame)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int encode_write_frame(unsigned int stream_index, int flush)
|
||||
{
|
||||
StreamContext *stream = &stream_ctx[stream_index];
|
||||
FilteringContext *filter = &filter_ctx[stream_index];
|
||||
AVFrame *filt_frame = flush ? NULL : filter->filtered_frame;
|
||||
AVPacket *enc_pkt = filter->enc_pkt;
|
||||
static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame) {
|
||||
int ret;
|
||||
int got_frame_local;
|
||||
AVPacket enc_pkt;
|
||||
int (*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int *) =
|
||||
(ifmt_ctx->streams[stream_index]->codec->codec_type ==
|
||||
AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2;
|
||||
|
||||
if (!got_frame)
|
||||
got_frame = &got_frame_local;
|
||||
|
||||
av_log(NULL, AV_LOG_INFO, "Encoding frame\n");
|
||||
/* encode filtered frame */
|
||||
av_packet_unref(enc_pkt);
|
||||
|
||||
ret = avcodec_send_frame(stream->enc_ctx, filt_frame);
|
||||
|
||||
enc_pkt.data = NULL;
|
||||
enc_pkt.size = 0;
|
||||
av_init_packet(&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)
|
||||
return ret;
|
||||
if (!(*got_frame))
|
||||
return 0;
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_packet(stream->enc_ctx, enc_pkt);
|
||||
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
return 0;
|
||||
|
||||
/* prepare packet for muxing */
|
||||
enc_pkt->stream_index = stream_index;
|
||||
av_packet_rescale_ts(enc_pkt,
|
||||
stream->enc_ctx->time_base,
|
||||
ofmt_ctx->streams[stream_index]->time_base);
|
||||
|
||||
av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");
|
||||
/* mux encoded frame */
|
||||
ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt);
|
||||
}
|
||||
/* prepare packet for muxing */
|
||||
enc_pkt.stream_index = stream_index;
|
||||
av_packet_rescale_ts(&enc_pkt,
|
||||
ofmt_ctx->streams[stream_index]->codec->time_base,
|
||||
ofmt_ctx->streams[stream_index]->time_base);
|
||||
|
||||
av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");
|
||||
/* mux encoded frame */
|
||||
ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
|
||||
{
|
||||
FilteringContext *filter = &filter_ctx[stream_index];
|
||||
int ret;
|
||||
AVFrame *filt_frame;
|
||||
|
||||
av_log(NULL, AV_LOG_INFO, "Pushing decoded frame to filters\n");
|
||||
/* push the decoded frame into the filtergraph */
|
||||
ret = av_buffersrc_add_frame_flags(filter->buffersrc_ctx,
|
||||
ret = av_buffersrc_add_frame_flags(filter_ctx[stream_index].buffersrc_ctx,
|
||||
frame, 0);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
|
||||
@@ -473,9 +417,14 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
|
||||
|
||||
/* pull filtered frames from the filtergraph */
|
||||
while (1) {
|
||||
filt_frame = av_frame_alloc();
|
||||
if (!filt_frame) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
break;
|
||||
}
|
||||
av_log(NULL, AV_LOG_INFO, "Pulling filtered frame from filters\n");
|
||||
ret = av_buffersink_get_frame(filter->buffersink_ctx,
|
||||
filter->filtered_frame);
|
||||
ret = av_buffersink_get_frame(filter_ctx[stream_index].buffersink_ctx,
|
||||
filt_frame);
|
||||
if (ret < 0) {
|
||||
/* if no more frames for output - returns AVERROR(EAGAIN)
|
||||
* if flushed and no more frames for output - returns AVERROR_EOF
|
||||
@@ -483,12 +432,12 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
|
||||
*/
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
ret = 0;
|
||||
av_frame_free(&filt_frame);
|
||||
break;
|
||||
}
|
||||
|
||||
filter->filtered_frame->pict_type = AV_PICTURE_TYPE_NONE;
|
||||
ret = encode_write_frame(stream_index, 0);
|
||||
av_frame_unref(filter->filtered_frame);
|
||||
filt_frame->pict_type = AV_PICTURE_TYPE_NONE;
|
||||
ret = encode_write_frame(filt_frame, stream_index, NULL);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
@@ -498,80 +447,99 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
|
||||
|
||||
static int flush_encoder(unsigned int stream_index)
|
||||
{
|
||||
if (!(stream_ctx[stream_index].enc_ctx->codec->capabilities &
|
||||
int ret;
|
||||
int got_frame;
|
||||
|
||||
if (!(ofmt_ctx->streams[stream_index]->codec->codec->capabilities &
|
||||
AV_CODEC_CAP_DELAY))
|
||||
return 0;
|
||||
|
||||
av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index);
|
||||
return encode_write_frame(stream_index, 1);
|
||||
while (1) {
|
||||
av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index);
|
||||
ret = encode_write_frame(NULL, stream_index, &got_frame);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (!got_frame)
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
AVPacket *packet = NULL;
|
||||
AVPacket packet = { .data = NULL, .size = 0 };
|
||||
AVFrame *frame = NULL;
|
||||
enum AVMediaType type;
|
||||
unsigned int stream_index;
|
||||
unsigned int i;
|
||||
int got_frame;
|
||||
int (*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket *);
|
||||
|
||||
if (argc != 3) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
av_register_all();
|
||||
avfilter_register_all();
|
||||
|
||||
if ((ret = open_input_file(argv[1])) < 0)
|
||||
goto end;
|
||||
if ((ret = open_output_file(argv[2])) < 0)
|
||||
goto end;
|
||||
if ((ret = init_filters()) < 0)
|
||||
goto end;
|
||||
if (!(packet = av_packet_alloc()))
|
||||
goto end;
|
||||
|
||||
/* read all packets */
|
||||
while (1) {
|
||||
if ((ret = av_read_frame(ifmt_ctx, packet)) < 0)
|
||||
if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0)
|
||||
break;
|
||||
stream_index = packet->stream_index;
|
||||
stream_index = packet.stream_index;
|
||||
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);
|
||||
|
||||
if (filter_ctx[stream_index].filter_graph) {
|
||||
StreamContext *stream = &stream_ctx[stream_index];
|
||||
|
||||
av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the frame\n");
|
||||
|
||||
av_packet_rescale_ts(packet,
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
break;
|
||||
}
|
||||
av_packet_rescale_ts(&packet,
|
||||
ifmt_ctx->streams[stream_index]->time_base,
|
||||
stream->dec_ctx->time_base);
|
||||
ret = avcodec_send_packet(stream->dec_ctx, packet);
|
||||
ifmt_ctx->streams[stream_index]->codec->time_base);
|
||||
dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :
|
||||
avcodec_decode_audio4;
|
||||
ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame,
|
||||
&got_frame, &packet);
|
||||
if (ret < 0) {
|
||||
av_frame_free(&frame);
|
||||
av_log(NULL, AV_LOG_ERROR, "Decoding failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(stream->dec_ctx, stream->dec_frame);
|
||||
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
|
||||
break;
|
||||
else if (ret < 0)
|
||||
goto end;
|
||||
|
||||
stream->dec_frame->pts = stream->dec_frame->best_effort_timestamp;
|
||||
ret = filter_encode_write_frame(stream->dec_frame, stream_index);
|
||||
if (got_frame) {
|
||||
frame->pts = av_frame_get_best_effort_timestamp(frame);
|
||||
ret = filter_encode_write_frame(frame, stream_index);
|
||||
av_frame_free(&frame);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
} else {
|
||||
av_frame_free(&frame);
|
||||
}
|
||||
} else {
|
||||
/* remux this frame without reencoding */
|
||||
av_packet_rescale_ts(packet,
|
||||
av_packet_rescale_ts(&packet,
|
||||
ifmt_ctx->streams[stream_index]->time_base,
|
||||
ofmt_ctx->streams[stream_index]->time_base);
|
||||
|
||||
ret = av_interleaved_write_frame(ofmt_ctx, packet);
|
||||
ret = av_interleaved_write_frame(ofmt_ctx, &packet);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
}
|
||||
av_packet_unref(packet);
|
||||
av_packet_unref(&packet);
|
||||
}
|
||||
|
||||
/* flush filters and encoders */
|
||||
@@ -595,21 +563,16 @@ int main(int argc, char **argv)
|
||||
|
||||
av_write_trailer(ofmt_ctx);
|
||||
end:
|
||||
av_packet_free(&packet);
|
||||
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);
|
||||
if (filter_ctx && filter_ctx[i].filter_graph) {
|
||||
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_packet_free(&filter_ctx[i].enc_pkt);
|
||||
av_frame_free(&filter_ctx[i].filtered_frame);
|
||||
}
|
||||
|
||||
av_frame_free(&stream_ctx[i].dec_frame);
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -1,224 +0,0 @@
|
||||
/*
|
||||
* Video Acceleration API (video encoding) encode sample
|
||||
*
|
||||
* 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
|
||||
* Intel VAAPI-accelerated encoding example.
|
||||
*
|
||||
* @example vaapi_encode.c
|
||||
* This example shows how to do VAAPI-accelerated encoding. now only support NV12
|
||||
* raw file, usage like: vaapi_encode 1920 1080 input.yuv output.h264
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
#include <libavutil/hwcontext.h>
|
||||
|
||||
static int width, height;
|
||||
static AVBufferRef *hw_device_ctx = NULL;
|
||||
|
||||
static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx)
|
||||
{
|
||||
AVBufferRef *hw_frames_ref;
|
||||
AVHWFramesContext *frames_ctx = NULL;
|
||||
int err = 0;
|
||||
|
||||
if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx))) {
|
||||
fprintf(stderr, "Failed to create VAAPI frame context.\n");
|
||||
return -1;
|
||||
}
|
||||
frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
|
||||
frames_ctx->format = AV_PIX_FMT_VAAPI;
|
||||
frames_ctx->sw_format = AV_PIX_FMT_NV12;
|
||||
frames_ctx->width = width;
|
||||
frames_ctx->height = height;
|
||||
frames_ctx->initial_pool_size = 20;
|
||||
if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0) {
|
||||
fprintf(stderr, "Failed to initialize VAAPI frame context."
|
||||
"Error code: %s\n",av_err2str(err));
|
||||
av_buffer_unref(&hw_frames_ref);
|
||||
return err;
|
||||
}
|
||||
ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ref);
|
||||
if (!ctx->hw_frames_ctx)
|
||||
err = AVERROR(ENOMEM);
|
||||
|
||||
av_buffer_unref(&hw_frames_ref);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int encode_write(AVCodecContext *avctx, AVFrame *frame, FILE *fout)
|
||||
{
|
||||
int ret = 0;
|
||||
AVPacket *enc_pkt;
|
||||
|
||||
if (!(enc_pkt = av_packet_alloc()))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if ((ret = avcodec_send_frame(avctx, frame)) < 0) {
|
||||
fprintf(stderr, "Error code: %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
while (1) {
|
||||
ret = avcodec_receive_packet(avctx, enc_pkt);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
enc_pkt->stream_index = 0;
|
||||
ret = fwrite(enc_pkt->data, enc_pkt->size, 1, fout);
|
||||
av_packet_unref(enc_pkt);
|
||||
}
|
||||
|
||||
end:
|
||||
av_packet_free(&enc_pkt);
|
||||
ret = ((ret == AVERROR(EAGAIN)) ? 0 : -1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int size, err;
|
||||
FILE *fin = NULL, *fout = NULL;
|
||||
AVFrame *sw_frame = NULL, *hw_frame = NULL;
|
||||
AVCodecContext *avctx = NULL;
|
||||
const AVCodec *codec = NULL;
|
||||
const char *enc_name = "h264_vaapi";
|
||||
|
||||
if (argc < 5) {
|
||||
fprintf(stderr, "Usage: %s <width> <height> <input file> <output file>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
width = atoi(argv[1]);
|
||||
height = atoi(argv[2]);
|
||||
size = width * height;
|
||||
|
||||
if (!(fin = fopen(argv[3], "r"))) {
|
||||
fprintf(stderr, "Fail to open input file : %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (!(fout = fopen(argv[4], "w+b"))) {
|
||||
fprintf(stderr, "Fail to open output file : %s\n", strerror(errno));
|
||||
err = -1;
|
||||
goto close;
|
||||
}
|
||||
|
||||
err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI,
|
||||
NULL, NULL, 0);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Failed to create a VAAPI device. Error code: %s\n", av_err2str(err));
|
||||
goto close;
|
||||
}
|
||||
|
||||
if (!(codec = avcodec_find_encoder_by_name(enc_name))) {
|
||||
fprintf(stderr, "Could not find encoder.\n");
|
||||
err = -1;
|
||||
goto close;
|
||||
}
|
||||
|
||||
if (!(avctx = avcodec_alloc_context3(codec))) {
|
||||
err = AVERROR(ENOMEM);
|
||||
goto close;
|
||||
}
|
||||
|
||||
avctx->width = width;
|
||||
avctx->height = height;
|
||||
avctx->time_base = (AVRational){1, 25};
|
||||
avctx->framerate = (AVRational){25, 1};
|
||||
avctx->sample_aspect_ratio = (AVRational){1, 1};
|
||||
avctx->pix_fmt = AV_PIX_FMT_VAAPI;
|
||||
|
||||
/* set hw_frames_ctx for encoder's AVCodecContext */
|
||||
if ((err = set_hwframe_ctx(avctx, hw_device_ctx)) < 0) {
|
||||
fprintf(stderr, "Failed to set hwframe context.\n");
|
||||
goto close;
|
||||
}
|
||||
|
||||
if ((err = avcodec_open2(avctx, codec, NULL)) < 0) {
|
||||
fprintf(stderr, "Cannot open video encoder codec. Error code: %s\n", av_err2str(err));
|
||||
goto close;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (!(sw_frame = av_frame_alloc())) {
|
||||
err = AVERROR(ENOMEM);
|
||||
goto close;
|
||||
}
|
||||
/* read data into software frame, and transfer them into hw frame */
|
||||
sw_frame->width = width;
|
||||
sw_frame->height = height;
|
||||
sw_frame->format = AV_PIX_FMT_NV12;
|
||||
if ((err = av_frame_get_buffer(sw_frame, 0)) < 0)
|
||||
goto close;
|
||||
if ((err = fread((uint8_t*)(sw_frame->data[0]), size, 1, fin)) <= 0)
|
||||
break;
|
||||
if ((err = fread((uint8_t*)(sw_frame->data[1]), size/2, 1, fin)) <= 0)
|
||||
break;
|
||||
|
||||
if (!(hw_frame = av_frame_alloc())) {
|
||||
err = AVERROR(ENOMEM);
|
||||
goto close;
|
||||
}
|
||||
if ((err = av_hwframe_get_buffer(avctx->hw_frames_ctx, hw_frame, 0)) < 0) {
|
||||
fprintf(stderr, "Error code: %s.\n", av_err2str(err));
|
||||
goto close;
|
||||
}
|
||||
if (!hw_frame->hw_frames_ctx) {
|
||||
err = AVERROR(ENOMEM);
|
||||
goto close;
|
||||
}
|
||||
if ((err = av_hwframe_transfer_data(hw_frame, sw_frame, 0)) < 0) {
|
||||
fprintf(stderr, "Error while transferring frame data to surface."
|
||||
"Error code: %s.\n", av_err2str(err));
|
||||
goto close;
|
||||
}
|
||||
|
||||
if ((err = (encode_write(avctx, hw_frame, fout))) < 0) {
|
||||
fprintf(stderr, "Failed to encode.\n");
|
||||
goto close;
|
||||
}
|
||||
av_frame_free(&hw_frame);
|
||||
av_frame_free(&sw_frame);
|
||||
}
|
||||
|
||||
/* flush encoder */
|
||||
err = encode_write(avctx, NULL, fout);
|
||||
if (err == AVERROR_EOF)
|
||||
err = 0;
|
||||
|
||||
close:
|
||||
if (fin)
|
||||
fclose(fin);
|
||||
if (fout)
|
||||
fclose(fout);
|
||||
av_frame_free(&sw_frame);
|
||||
av_frame_free(&hw_frame);
|
||||
avcodec_free_context(&avctx);
|
||||
av_buffer_unref(&hw_device_ctx);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -1,308 +0,0 @@
|
||||
/*
|
||||
* Video Acceleration API (video transcoding) transcode sample
|
||||
*
|
||||
* 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
|
||||
* Intel VAAPI-accelerated transcoding example.
|
||||
*
|
||||
* @example vaapi_transcode.c
|
||||
* This example shows how to do VAAPI-accelerated transcoding.
|
||||
* Usage: vaapi_transcode input_stream codec output_stream
|
||||
* e.g: - vaapi_transcode input.mp4 h264_vaapi output_h264.mp4
|
||||
* - vaapi_transcode input.mp4 vp9_vaapi output_vp9.ivf
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
static AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
|
||||
static AVBufferRef *hw_device_ctx = NULL;
|
||||
static AVCodecContext *decoder_ctx = NULL, *encoder_ctx = NULL;
|
||||
static int video_stream = -1;
|
||||
static AVStream *ost;
|
||||
static int initialized = 0;
|
||||
|
||||
static enum AVPixelFormat get_vaapi_format(AVCodecContext *ctx,
|
||||
const enum AVPixelFormat *pix_fmts)
|
||||
{
|
||||
const enum AVPixelFormat *p;
|
||||
|
||||
for (p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) {
|
||||
if (*p == AV_PIX_FMT_VAAPI)
|
||||
return *p;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Unable to decode this file using VA-API.\n");
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
static int open_input_file(const char *filename)
|
||||
{
|
||||
int ret;
|
||||
const AVCodec *decoder = NULL;
|
||||
AVStream *video = NULL;
|
||||
|
||||
if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {
|
||||
fprintf(stderr, "Cannot open input file '%s', Error code: %s\n",
|
||||
filename, av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
|
||||
fprintf(stderr, "Cannot find input stream information. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot find a video stream in the input file. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
video_stream = ret;
|
||||
|
||||
if (!(decoder_ctx = avcodec_alloc_context3(decoder)))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
video = ifmt_ctx->streams[video_stream];
|
||||
if ((ret = avcodec_parameters_to_context(decoder_ctx, video->codecpar)) < 0) {
|
||||
fprintf(stderr, "avcodec_parameters_to_context error. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
decoder_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
|
||||
if (!decoder_ctx->hw_device_ctx) {
|
||||
fprintf(stderr, "A hardware device reference create failed.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
decoder_ctx->get_format = get_vaapi_format;
|
||||
|
||||
if ((ret = avcodec_open2(decoder_ctx, decoder, NULL)) < 0)
|
||||
fprintf(stderr, "Failed to open codec for decoding. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int encode_write(AVPacket *enc_pkt, AVFrame *frame)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
av_packet_unref(enc_pkt);
|
||||
|
||||
if ((ret = avcodec_send_frame(encoder_ctx, frame)) < 0) {
|
||||
fprintf(stderr, "Error during encoding. Error code: %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
while (1) {
|
||||
ret = avcodec_receive_packet(encoder_ctx, enc_pkt);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
enc_pkt->stream_index = 0;
|
||||
av_packet_rescale_ts(enc_pkt, ifmt_ctx->streams[video_stream]->time_base,
|
||||
ofmt_ctx->streams[0]->time_base);
|
||||
ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error during writing data to output file. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (ret == AVERROR_EOF)
|
||||
return 0;
|
||||
ret = ((ret == AVERROR(EAGAIN)) ? 0:-1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dec_enc(AVPacket *pkt, const AVCodec *enc_codec)
|
||||
{
|
||||
AVFrame *frame;
|
||||
int ret = 0;
|
||||
|
||||
ret = avcodec_send_packet(decoder_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding. Error code: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
if (!(frame = av_frame_alloc()))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
ret = avcodec_receive_frame(decoder_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
av_frame_free(&frame);
|
||||
return 0;
|
||||
} else if (ret < 0) {
|
||||
fprintf(stderr, "Error while decoding. Error code: %s\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
/* we need to ref hw_frames_ctx of decoder to initialize encoder's codec.
|
||||
Only after we get a decoded frame, can we obtain its hw_frames_ctx */
|
||||
encoder_ctx->hw_frames_ctx = av_buffer_ref(decoder_ctx->hw_frames_ctx);
|
||||
if (!encoder_ctx->hw_frames_ctx) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
/* set AVCodecContext Parameters for encoder, here we keep them stay
|
||||
* the same as decoder.
|
||||
* xxx: now the sample can't handle resolution change case.
|
||||
*/
|
||||
encoder_ctx->time_base = av_inv_q(decoder_ctx->framerate);
|
||||
encoder_ctx->pix_fmt = AV_PIX_FMT_VAAPI;
|
||||
encoder_ctx->width = decoder_ctx->width;
|
||||
encoder_ctx->height = decoder_ctx->height;
|
||||
|
||||
if ((ret = avcodec_open2(encoder_ctx, enc_codec, NULL)) < 0) {
|
||||
fprintf(stderr, "Failed to open encode codec. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(ost = avformat_new_stream(ofmt_ctx, enc_codec))) {
|
||||
fprintf(stderr, "Failed to allocate stream for output format.\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ost->time_base = encoder_ctx->time_base;
|
||||
ret = avcodec_parameters_from_context(ost->codecpar, encoder_ctx);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to copy the stream parameters. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* write the stream header */
|
||||
if ((ret = avformat_write_header(ofmt_ctx, NULL)) < 0) {
|
||||
fprintf(stderr, "Error while writing stream header. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
if ((ret = encode_write(pkt, frame)) < 0)
|
||||
fprintf(stderr, "Error during encoding and writing.\n");
|
||||
|
||||
fail:
|
||||
av_frame_free(&frame);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const AVCodec *enc_codec;
|
||||
int ret = 0;
|
||||
AVPacket *dec_pkt;
|
||||
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "Usage: %s <input file> <encode codec> <output file>\n"
|
||||
"The output format is guessed according to the file extension.\n"
|
||||
"\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, NULL, NULL, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to create a VAAPI device. Error code: %s\n", av_err2str(ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
dec_pkt = av_packet_alloc();
|
||||
if (!dec_pkt) {
|
||||
fprintf(stderr, "Failed to allocate decode packet\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = open_input_file(argv[1])) < 0)
|
||||
goto end;
|
||||
|
||||
if (!(enc_codec = avcodec_find_encoder_by_name(argv[2]))) {
|
||||
fprintf(stderr, "Could not find encoder '%s'\n", argv[2]);
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = (avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, argv[3]))) < 0) {
|
||||
fprintf(stderr, "Failed to deduce output format from file extension. Error code: "
|
||||
"%s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!(encoder_ctx = avcodec_alloc_context3(enc_codec))) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avio_open(&ofmt_ctx->pb, argv[3], AVIO_FLAG_WRITE);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot open output file. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* read all packets and only transcoding video */
|
||||
while (ret >= 0) {
|
||||
if ((ret = av_read_frame(ifmt_ctx, dec_pkt)) < 0)
|
||||
break;
|
||||
|
||||
if (video_stream == dec_pkt->stream_index)
|
||||
ret = dec_enc(dec_pkt, enc_codec);
|
||||
|
||||
av_packet_unref(dec_pkt);
|
||||
}
|
||||
|
||||
/* flush decoder */
|
||||
av_packet_unref(dec_pkt);
|
||||
ret = dec_enc(dec_pkt, enc_codec);
|
||||
|
||||
/* flush encoder */
|
||||
ret = encode_write(dec_pkt, NULL);
|
||||
|
||||
/* write the trailer for output stream */
|
||||
av_write_trailer(ofmt_ctx);
|
||||
|
||||
end:
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
avformat_close_input(&ofmt_ctx);
|
||||
avcodec_free_context(&decoder_ctx);
|
||||
avcodec_free_context(&encoder_ctx);
|
||||
av_buffer_unref(&hw_device_ctx);
|
||||
av_packet_free(&dec_pkt);
|
||||
return ret;
|
||||
}
|
||||
81
doc/faq.texi
81
doc/faq.texi
@@ -76,7 +76,7 @@ the gcc developers. Note that we will not add workarounds for gcc bugs.
|
||||
|
||||
Also note that (some of) the gcc developers believe this is not a bug or
|
||||
not a bug they should fix:
|
||||
@url{https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11203}.
|
||||
@url{http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11203}.
|
||||
Then again, some of them do not know the difference between an undecidable
|
||||
problem and an NP-hard problem...
|
||||
|
||||
@@ -257,13 +257,13 @@ default.
|
||||
@section Which are good parameters for encoding high quality MPEG-4?
|
||||
|
||||
'-mbd rd -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -g 300 -pass 1/2',
|
||||
things to try: '-bf 2', '-mpv_flags qp_rd', '-mpv_flags mv0', '-mpv_flags skip_rd'.
|
||||
things to try: '-bf 2', '-flags qprd', '-flags mv0', '-flags skiprd'.
|
||||
|
||||
@section Which are good parameters for encoding high quality MPEG-1/MPEG-2?
|
||||
|
||||
'-mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -pass 1/2'
|
||||
but beware the '-g 100' might cause problems with some decoders.
|
||||
Things to try: '-bf 2', '-mpv_flags qp_rd', '-mpv_flags mv0', '-mpv_flags skip_rd'.
|
||||
Things to try: '-bf 2', '-flags qprd', '-flags mv0', '-flags skiprd.
|
||||
|
||||
@section Interlaced video looks very bad when encoded with ffmpeg, what is wrong?
|
||||
|
||||
@@ -385,7 +385,7 @@ mkfifo intermediate2.mpg
|
||||
ffmpeg -i input1.avi -qscale:v 1 -y intermediate1.mpg < /dev/null &
|
||||
ffmpeg -i input2.avi -qscale:v 1 -y intermediate2.mpg < /dev/null &
|
||||
cat intermediate1.mpg intermediate2.mpg |\
|
||||
ffmpeg -f mpeg -i - -c:v mpeg4 -c:a libmp3lame output.avi
|
||||
ffmpeg -f mpeg -i - -c:v mpeg4 -acodec libmp3lame output.avi
|
||||
@end example
|
||||
|
||||
@subsection Concatenating using raw audio and video
|
||||
@@ -407,13 +407,13 @@ mkfifo temp2.a
|
||||
mkfifo temp2.v
|
||||
mkfifo all.a
|
||||
mkfifo all.v
|
||||
ffmpeg -i input1.flv -vn -f u16le -c:a pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null &
|
||||
ffmpeg -i input2.flv -vn -f u16le -c:a pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null &
|
||||
ffmpeg -i input1.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null &
|
||||
ffmpeg -i input2.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null &
|
||||
ffmpeg -i input1.flv -an -f yuv4mpegpipe - > temp1.v < /dev/null &
|
||||
@{ ffmpeg -i input2.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v ; @} &
|
||||
cat temp1.a temp2.a > all.a &
|
||||
cat temp1.v temp2.v > all.v &
|
||||
ffmpeg -f u16le -c:a pcm_s16le -ac 2 -ar 44100 -i all.a \
|
||||
ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \
|
||||
-f yuv4mpegpipe -i all.v \
|
||||
-y output.flv
|
||||
rm temp[12].[av] all.[av]
|
||||
@@ -501,71 +501,6 @@ ffmpeg -i ega_screen.nut -vf setdar=4/3 ega_screen_anamorphic.nut
|
||||
ffmpeg -i ega_screen.nut -aspect 4/3 -c copy ega_screen_overridden.nut
|
||||
@end example
|
||||
|
||||
@anchor{background task}
|
||||
@section How do I run ffmpeg as a background task?
|
||||
|
||||
ffmpeg normally checks the console input, for entries like "q" to stop
|
||||
and "?" to give help, while performing operations. ffmpeg does not have a way of
|
||||
detecting when it is running as a background task.
|
||||
When it checks the console input, that can cause the process running ffmpeg
|
||||
in the background to suspend.
|
||||
|
||||
To prevent those input checks, allowing ffmpeg to run as a background task,
|
||||
use the @url{ffmpeg.html#stdin-option, @code{-nostdin} option}
|
||||
in the ffmpeg invocation. This is effective whether you run ffmpeg in a shell
|
||||
or invoke ffmpeg in its own process via an operating system API.
|
||||
|
||||
As an alternative, when you are running ffmpeg in a shell, you can redirect
|
||||
standard input to @code{/dev/null} (on Linux and macOS)
|
||||
or @code{NUL} (on Windows). You can do this redirect either
|
||||
on the ffmpeg invocation, or from a shell script which calls ffmpeg.
|
||||
|
||||
For example:
|
||||
|
||||
@example
|
||||
ffmpeg -nostdin -i INPUT OUTPUT
|
||||
@end example
|
||||
|
||||
or (on Linux, macOS, and other UNIX-like shells):
|
||||
|
||||
@example
|
||||
ffmpeg -i INPUT OUTPUT </dev/null
|
||||
@end example
|
||||
|
||||
or (on Windows):
|
||||
|
||||
@example
|
||||
ffmpeg -i INPUT OUTPUT <NUL
|
||||
@end example
|
||||
|
||||
@section How do I prevent ffmpeg from suspending with a message like @emph{suspended (tty output)}?
|
||||
|
||||
If you run ffmpeg in the background, you may find that its process suspends.
|
||||
There may be a message like @emph{suspended (tty output)}. The question is how
|
||||
to prevent the process from being suspended.
|
||||
|
||||
For example:
|
||||
|
||||
@example
|
||||
% ffmpeg -i INPUT OUTPUT &> ~/tmp/log.txt &
|
||||
[1] 93352
|
||||
%
|
||||
[1] + suspended (tty output) ffmpeg -i INPUT OUTPUT &>
|
||||
@end example
|
||||
|
||||
The message "tty output" notwithstanding, the problem here is that
|
||||
ffmpeg normally checks the console input when it runs. The operating system
|
||||
detects this, and suspends the process until you can bring it to the
|
||||
foreground and attend to it.
|
||||
|
||||
The solution is to use the right techniques to tell ffmpeg not to consult
|
||||
console input. You can use the
|
||||
@url{ffmpeg.html#stdin-option, @code{-nostdin} option},
|
||||
or redirect standard input with @code{< /dev/null}.
|
||||
See FAQ
|
||||
@ref{background task, @emph{How do I run ffmpeg as a background task?}}
|
||||
for details.
|
||||
|
||||
@chapter Development
|
||||
|
||||
@section Are there examples illustrating how to use the FFmpeg libraries, particularly libavcodec and libavformat?
|
||||
@@ -601,7 +536,7 @@ No. These tools are too bloated and they complicate the build.
|
||||
FFmpeg is already organized in a highly modular manner and does not need to
|
||||
be rewritten in a formal object language. Further, many of the developers
|
||||
favor straight C; it works for them. For more arguments on this matter,
|
||||
read @uref{https://web.archive.org/web/20111004021423/http://kernel.org/pub/linux/docs/lkml/#s15, "Programming Religion"}.
|
||||
read @uref{http://www.tux.org/lkml/#s15, "Programming Religion"}.
|
||||
|
||||
@section Why are the ffmpeg programs devoid of debugging symbols?
|
||||
|
||||
|
||||
@@ -147,32 +147,6 @@ process.
|
||||
The only thing left is to automate the execution of the fate.sh script and
|
||||
the synchronisation of the samples directory.
|
||||
|
||||
@chapter Uploading new samples to the fate suite
|
||||
|
||||
If you need a sample uploaded send a mail to samples-request.
|
||||
|
||||
This is for developers who have an account on the fate suite server.
|
||||
If you upload new samples, please make sure they are as small as possible,
|
||||
space on each client, network bandwidth and so on benefit from smaller test cases.
|
||||
Also keep in mind older checkouts use existing sample files, that means in
|
||||
practice generally do not replace, remove or overwrite files as it likely would
|
||||
break older checkouts or releases.
|
||||
Also all needed samples for a commit should be uploaded, ideally 24
|
||||
hours, before the push.
|
||||
If you need an account for frequently uploading samples or you wish to help
|
||||
others by doing that send a mail to ffmpeg-devel.
|
||||
|
||||
@example
|
||||
#First update your local samples copy:
|
||||
rsync -vauL --chmod=Dg+s,Duo+x,ug+rw,o+r,o-w,+X fate-suite.ffmpeg.org:/home/samples/fate-suite/ ~/fate-suite
|
||||
|
||||
#Then do a dry run checking what would be uploaded:
|
||||
rsync -vanL --no-g --chmod=Dg+s,Duo+x,ug+rw,o+r,o-w,+X ~/fate-suite/ fate-suite.ffmpeg.org:/home/samples/fate-suite
|
||||
|
||||
#Upload the files:
|
||||
rsync -vaL --no-g --chmod=Dg+s,Duo+x,ug+rw,o+r,o-w,+X ~/fate-suite/ fate-suite.ffmpeg.org:/home/samples/fate-suite
|
||||
@end example
|
||||
|
||||
|
||||
@chapter FATE makefile targets and variables
|
||||
|
||||
@@ -223,16 +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.
|
||||
|
||||
@item KEEP
|
||||
Set to @samp{1} to keep temp files generated by fate test(s) when test is successful.
|
||||
Default is @samp{0}, which removes these files. Files are always kept when a test
|
||||
fails.
|
||||
|
||||
@end table
|
||||
|
||||
@section Examples
|
||||
|
||||
@@ -6,7 +6,6 @@ workdir= # directory in which to do all the work
|
||||
#fate_recv="ssh -T fate@fate.ffmpeg.org" # command to submit report
|
||||
comment= # optional description
|
||||
build_only= # set to "yes" for a compile-only instance that skips tests
|
||||
ignore_tests=
|
||||
|
||||
# the following are optional and map to configure options
|
||||
arch=
|
||||
@@ -27,7 +26,5 @@ extra_conf= # extra configure options not covered above
|
||||
|
||||
#make= # name of GNU make if not 'make'
|
||||
makeopts= # extra options passed to 'make'
|
||||
#makeopts_fate= # extra options passed to 'make' when running tests,
|
||||
# defaulting to makeopts above if this is not set
|
||||
#tar= # command to create a tar archive from its arguments on stdout,
|
||||
# defaults to 'tar c'
|
||||
|
||||
@@ -26,12 +26,12 @@ bitstream level modifications without performing decoding.
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||
@url{libavcodec.html,libavcodec}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libavcodec(3)
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavcodec(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@@ -23,12 +23,12 @@ the libavcodec library.
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||
@url{libavcodec.html,libavcodec}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libavcodec(3)
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavcodec(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@@ -23,12 +23,12 @@ libavdevice library.
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||
@url{libavdevice.html,libavdevice}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libavdevice(3)
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavdevice(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@@ -23,12 +23,12 @@ libavfilter library.
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||
@url{libavfilter.html,libavfilter}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libavfilter(3)
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavfilter(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@@ -23,12 +23,12 @@ provided by the libavformat library.
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||
@url{libavformat.html,libavformat}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libavformat(3)
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavformat(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@@ -23,12 +23,12 @@ libavformat library.
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||
@url{libavformat.html,libavformat}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libavformat(3)
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavformat(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@@ -25,12 +25,12 @@ and convert audio format and packing layout.
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||
@url{libswresample.html,libswresample}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libswresample(3)
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libswresample(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@@ -24,12 +24,12 @@ image rescaling and pixel format conversion.
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||
@url{libswscale.html,libswscale}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libswscale(3)
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libswscale(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
@@ -23,12 +23,12 @@ by the libavutil library.
|
||||
@chapter See Also
|
||||
|
||||
@ifhtml
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||
@url{libavutil.html,libavutil}
|
||||
@end ifhtml
|
||||
|
||||
@ifnothtml
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), libavutil(3)
|
||||
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavutil(3)
|
||||
@end ifnothtml
|
||||
|
||||
@include authors.texi
|
||||
|
||||
926
doc/ffmpeg.texi
926
doc/ffmpeg.texi
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user