mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-06 14:59:59 +01:00
Compare commits
494 Commits
n2.2.2
...
release/2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72006016ae | ||
|
|
f23efdd240 | ||
|
|
2789b48b4e | ||
|
|
5628d62022 | ||
|
|
58986f0fa1 | ||
|
|
c513e721f3 | ||
|
|
087561a7dc | ||
|
|
0b0183c5b7 | ||
|
|
055c302a11 | ||
|
|
b44025a1d0 | ||
|
|
7fc8458beb | ||
|
|
9b493887d5 | ||
|
|
804b90a5f5 | ||
|
|
4a2be7027f | ||
|
|
0caff57c42 | ||
|
|
af79d964a7 | ||
|
|
8320aa7dc7 | ||
|
|
7a9f4f2816 | ||
|
|
1fe67c9472 | ||
|
|
6fd4b2b84f | ||
|
|
a3740b6a86 | ||
|
|
ff0e9060a5 | ||
|
|
6d7384bd73 | ||
|
|
9db97584ca | ||
|
|
04bb8cc842 | ||
|
|
03c80a7400 | ||
|
|
b6ae28c2e9 | ||
|
|
5123c8aa0b | ||
|
|
6cb8599bab | ||
|
|
00b8a9dd8d | ||
|
|
9dd9090b89 | ||
|
|
fd1be2bd87 | ||
|
|
ced57c6ef3 | ||
|
|
13b22617c1 | ||
|
|
c01f551728 | ||
|
|
a3d05bf6be | ||
|
|
025b38f3a6 | ||
|
|
41c81556a7 | ||
|
|
f58c9746c3 | ||
|
|
a7c8dc67e7 | ||
|
|
0888e7110e | ||
|
|
990c2ee3bd | ||
|
|
ffd894917f | ||
|
|
3fedff3985 | ||
|
|
c532c56e7b | ||
|
|
36bc9519b6 | ||
|
|
136bd71f69 | ||
|
|
c0726da933 | ||
|
|
32f568f82c | ||
|
|
0bf455c054 | ||
|
|
e553282860 | ||
|
|
8ad873ed4e | ||
|
|
b470e21d61 | ||
|
|
4a9ce87ef3 | ||
|
|
1dad249ae6 | ||
|
|
5399107682 | ||
|
|
c7b089b1ac | ||
|
|
93a04473fc | ||
|
|
db0c4d2e3c | ||
|
|
fdc62caf30 | ||
|
|
998d943cce | ||
|
|
bf66555769 | ||
|
|
9945382816 | ||
|
|
ebc768cfa1 | ||
|
|
869613728c | ||
|
|
4d27d864a6 | ||
|
|
35eabb85b2 | ||
|
|
68e1c80c67 | ||
|
|
d2142c3b3a | ||
|
|
ac7a211b3b | ||
|
|
9ac72b1dde | ||
|
|
9d5362a45c | ||
|
|
0691554e68 | ||
|
|
7f2b3c3bee | ||
|
|
35ca5eb11f | ||
|
|
e6cc6a08d9 | ||
|
|
57208a0999 | ||
|
|
9f665b0d6a | ||
|
|
2d204f313b | ||
|
|
c7e56b8b9c | ||
|
|
cf13885622 | ||
|
|
cee951b596 | ||
|
|
1303d8a204 | ||
|
|
1a87782c2e | ||
|
|
a1f0c1b6fe | ||
|
|
baa58c19c4 | ||
|
|
82e24ec792 | ||
|
|
997a997465 | ||
|
|
c962405c19 | ||
|
|
743973f56f | ||
|
|
97b137a640 | ||
|
|
a5e2f79317 | ||
|
|
feb869b682 | ||
|
|
b73e47a413 | ||
|
|
2f51865751 | ||
|
|
50e17cdc98 | ||
|
|
936554f1d7 | ||
|
|
81ba3b1b91 | ||
|
|
9c10ef55b0 | ||
|
|
dece653d0d | ||
|
|
a26a200b3f | ||
|
|
572cfee405 | ||
|
|
e5f7aeb46f | ||
|
|
ae14a444f2 | ||
|
|
b13cba3082 | ||
|
|
46ee330d3a | ||
|
|
c9edf502cd | ||
|
|
1c1574e377 | ||
|
|
0f2401e3cb | ||
|
|
9be586e166 | ||
|
|
3d11279745 | ||
|
|
63efad67ee | ||
|
|
27432f259d | ||
|
|
e69c430353 | ||
|
|
ff0985347c | ||
|
|
5f92a0d1e9 | ||
|
|
3bfaadfada | ||
|
|
852ef62b85 | ||
|
|
45432879ff | ||
|
|
77955dcabf | ||
|
|
15fc5263f9 | ||
|
|
5ae61395af | ||
|
|
1697813db8 | ||
|
|
22dc1fd166 | ||
|
|
bc0bf39e4c | ||
|
|
3cca4c770e | ||
|
|
1cba89a135 | ||
|
|
ffdfa80147 | ||
|
|
c4353d7ee2 | ||
|
|
24bb746194 | ||
|
|
e201e75368 | ||
|
|
79460c552f | ||
|
|
fc0d183729 | ||
|
|
052cd9e552 | ||
|
|
d20c761782 | ||
|
|
b4e4a5cbaa | ||
|
|
1081c9decc | ||
|
|
a22da15b0c | ||
|
|
11afd2e2dd | ||
|
|
0d728ed792 | ||
|
|
fe618beccf | ||
|
|
c6ef9ca971 | ||
|
|
2acdf29838 | ||
|
|
76d18b6e09 | ||
|
|
2e6b1915cb | ||
|
|
64857ecd68 | ||
|
|
904f75d3c4 | ||
|
|
89e08520fc | ||
|
|
6e4e32e759 | ||
|
|
5c36d0e1cd | ||
|
|
c21604b5e7 | ||
|
|
1a8f5c9e2d | ||
|
|
2324c67076 | ||
|
|
3d5c48937b | ||
|
|
61b31c6939 | ||
|
|
c2439cad51 | ||
|
|
59fc55b297 | ||
|
|
bda7aa7cb3 | ||
|
|
04e28b3b25 | ||
|
|
81a766e57a | ||
|
|
e148369df9 | ||
|
|
3e11a186fa | ||
|
|
227a26cd40 | ||
|
|
da29aadeb7 | ||
|
|
776c481eb9 | ||
|
|
9ac17454a9 | ||
|
|
b0369f3369 | ||
|
|
5426a36300 | ||
|
|
5ba020d648 | ||
|
|
43b601d36f | ||
|
|
ca39fbe14d | ||
|
|
932e5c374a | ||
|
|
1fa9b7feb6 | ||
|
|
ae19e19678 | ||
|
|
53dc6f6643 | ||
|
|
587cd92bd7 | ||
|
|
8b130c4aab | ||
|
|
22f8dfafa8 | ||
|
|
9a15f32682 | ||
|
|
87af5b3877 | ||
|
|
47b82e51be | ||
|
|
a54aaa822a | ||
|
|
4e6706f851 | ||
|
|
32d24c8c05 | ||
|
|
b9ab59a829 | ||
|
|
a0976c15e6 | ||
|
|
f43127a516 | ||
|
|
0c50e41d63 | ||
|
|
eeff4bdbb8 | ||
|
|
a0f1da9baa | ||
|
|
71ad971244 | ||
|
|
42b0ef9056 | ||
|
|
1e18ed781f | ||
|
|
ff6ee4571c | ||
|
|
3190acae6f | ||
|
|
ac81fbba74 | ||
|
|
8a35f24ca9 | ||
|
|
3d91569c5e | ||
|
|
0baeb59307 | ||
|
|
f8675743c4 | ||
|
|
05e5d785fa | ||
|
|
2389309d48 | ||
|
|
0140f11c3b | ||
|
|
694c3dab36 | ||
|
|
8efb06c873 | ||
|
|
e2865d9316 | ||
|
|
bde9e859b3 | ||
|
|
85cac770bd | ||
|
|
808b0ccc03 | ||
|
|
2cf83677b3 | ||
|
|
c0be9d7264 | ||
|
|
70402f6ee7 | ||
|
|
9b1673531c | ||
|
|
d7906baa85 | ||
|
|
322470e606 | ||
|
|
0e71738262 | ||
|
|
128b0510e1 | ||
|
|
ff59edb6dc | ||
|
|
b4e0acfa04 | ||
|
|
d36bb362a6 | ||
|
|
be7105dff6 | ||
|
|
97fdbd12f9 | ||
|
|
db48767d7c | ||
|
|
ae81d9a7da | ||
|
|
abbfc4d87e | ||
|
|
16775c7aaa | ||
|
|
ac82e318bb | ||
|
|
49d69844f5 | ||
|
|
3f9a148022 | ||
|
|
8622618839 | ||
|
|
52fd0cda2c | ||
|
|
2eda0e705a | ||
|
|
f238de1990 | ||
|
|
992ce9777c | ||
|
|
47fe68eec8 | ||
|
|
beb83f0a40 | ||
|
|
2b415192fd | ||
|
|
6e70816f71 | ||
|
|
2fdb02693b | ||
|
|
d7d29f0d43 | ||
|
|
d76c9b5665 | ||
|
|
d4253b3a5b | ||
|
|
9fc7de8d80 | ||
|
|
2958b8b86e | ||
|
|
caf08defa6 | ||
|
|
57a6cd8ab1 | ||
|
|
b469fce85d | ||
|
|
656f930160 | ||
|
|
c56d6f3552 | ||
|
|
04973b02c3 | ||
|
|
bcb10b99f4 | ||
|
|
65f581472c | ||
|
|
c7fac44ef8 | ||
|
|
8d48223a32 | ||
|
|
3d10235b83 | ||
|
|
2428b02bb4 | ||
|
|
c2af6b500b | ||
|
|
dd72df9845 | ||
|
|
205e2264c3 | ||
|
|
4a23765704 | ||
|
|
083d0b7b2d | ||
|
|
1e9ae5dbbd | ||
|
|
01e2dd53a0 | ||
|
|
b93659db5b | ||
|
|
b94621ac6b | ||
|
|
a2b4e38729 | ||
|
|
9fe7e45030 | ||
|
|
3c169251ee | ||
|
|
81a2740919 | ||
|
|
a144d305dd | ||
|
|
4965da92ef | ||
|
|
a83304814c | ||
|
|
db6f3be941 | ||
|
|
2f1f407044 | ||
|
|
bdd2f7c7a7 | ||
|
|
332777970c | ||
|
|
62b9c99aec | ||
|
|
0e18480fc3 | ||
|
|
99d4d3532f | ||
|
|
d9d66d2d16 | ||
|
|
db33fb1c48 | ||
|
|
0be9a2e9d9 | ||
|
|
ee282be99b | ||
|
|
d3bcc9cfa9 | ||
|
|
eaa6d79105 | ||
|
|
4d9aad95b5 | ||
|
|
6882a04706 | ||
|
|
98805cbac5 | ||
|
|
66ca450fcb | ||
|
|
8162b69091 | ||
|
|
ed38ed3b62 | ||
|
|
6f6f5f9c8b | ||
|
|
690a3c4fb7 | ||
|
|
2ca68b98ba | ||
|
|
853bbe1aed | ||
|
|
218c853774 | ||
|
|
e315549ffa | ||
|
|
c9ed7a4fc1 | ||
|
|
1c321b7c31 | ||
|
|
491e1ec95d | ||
|
|
5805c0c2b6 | ||
|
|
c61c66cfb1 | ||
|
|
5ac53d07a2 | ||
|
|
02055da69a | ||
|
|
c7f419efd1 | ||
|
|
b556432f5a | ||
|
|
102df43f49 | ||
|
|
36fc9bff08 | ||
|
|
3ae71dd33e | ||
|
|
673f679c8a | ||
|
|
f65501f80c | ||
|
|
6387aa94d6 | ||
|
|
d581567e09 | ||
|
|
9933e06595 | ||
|
|
91d024d75d | ||
|
|
5ee384c4eb | ||
|
|
9ecd0f34ad | ||
|
|
7de7bd4f56 | ||
|
|
e939c7b7f5 | ||
|
|
612ef09a18 | ||
|
|
f0ee0fcbfc | ||
|
|
d41f4e8dc8 | ||
|
|
bc1c8ec5e6 | ||
|
|
67b943ad66 | ||
|
|
5e7e43c33e | ||
|
|
13ce367368 | ||
|
|
0962c26b6b | ||
|
|
33c47d3976 | ||
|
|
d0d0924947 | ||
|
|
ca5d6c615e | ||
|
|
7c17207ab9 | ||
|
|
9847f02faf | ||
|
|
dfdeabadca | ||
|
|
33aa2c5d6b | ||
|
|
b4552cc9b8 | ||
|
|
172f929767 | ||
|
|
66a9edfcf6 | ||
|
|
a9382fc15c | ||
|
|
bd9dcb411d | ||
|
|
ae81a0e32d | ||
|
|
4f93400db1 | ||
|
|
0cd61c7f7d | ||
|
|
28ac4e91dc | ||
|
|
6b683be641 | ||
|
|
3a3b5ae4c0 | ||
|
|
70fcea3b77 | ||
|
|
b545d11d49 | ||
|
|
4324d7bade | ||
|
|
c88bdac460 | ||
|
|
bdf6e6fff4 | ||
|
|
83e4aa3e7c | ||
|
|
fce2cfbdcf | ||
|
|
72f1907c96 | ||
|
|
074ebfacf4 | ||
|
|
47f8497837 | ||
|
|
93f26b7992 | ||
|
|
f684bbf224 | ||
|
|
edca16f1af | ||
|
|
aeac212fda | ||
|
|
62f05d6309 | ||
|
|
bd339d4882 | ||
|
|
9de71b0eb2 | ||
|
|
7e73760950 | ||
|
|
0639e403be | ||
|
|
5c7d6be5f9 | ||
|
|
2005887707 | ||
|
|
cf8462ce00 | ||
|
|
02c8c064ea | ||
|
|
9a4acedf31 | ||
|
|
c2d37e7364 | ||
|
|
62baf22ec0 | ||
|
|
8f7d839e15 | ||
|
|
93716f7bea | ||
|
|
ff4c53e8b3 | ||
|
|
9a22d6dd63 | ||
|
|
beb28bc55d | ||
|
|
1fa7ad2e20 | ||
|
|
f514834917 | ||
|
|
1d0e583728 | ||
|
|
782331be1e | ||
|
|
94c7ee4d9e | ||
|
|
b7154758de | ||
|
|
cd7d575e90 | ||
|
|
17d169ce0f | ||
|
|
fb1fb462e5 | ||
|
|
7da810e68b | ||
|
|
6de6d9e2d3 | ||
|
|
736851264b | ||
|
|
59431fc841 | ||
|
|
f581e25a69 | ||
|
|
9d0bb7fc39 | ||
|
|
a53fd4b758 | ||
|
|
b4ccdf5e68 | ||
|
|
9b02aa2593 | ||
|
|
f089e67d51 | ||
|
|
842d7c9b3a | ||
|
|
187297b871 | ||
|
|
211ad5042a | ||
|
|
2b06f5f8f1 | ||
|
|
0a64b25c77 | ||
|
|
40e52bbb63 | ||
|
|
aeec1a6430 | ||
|
|
ef121a88d5 | ||
|
|
db99c41567 | ||
|
|
54bdb5fc86 | ||
|
|
2fd824b466 | ||
|
|
005b38f8f1 | ||
|
|
6911d9e1b0 | ||
|
|
cecb2b39ce | ||
|
|
9ebfee7ac0 | ||
|
|
01b39884c7 | ||
|
|
c08e8ab715 | ||
|
|
68ae344b5e | ||
|
|
5753d780b4 | ||
|
|
dbb534cea6 | ||
|
|
414d75b8bc | ||
|
|
c52a25e03b | ||
|
|
c7966bf795 | ||
|
|
0f429392cf | ||
|
|
2dc6c5d462 | ||
|
|
dc0403530e | ||
|
|
59147be24f | ||
|
|
09bc4be3db | ||
|
|
aaef59d535 | ||
|
|
283e070877 | ||
|
|
4e0c29451b | ||
|
|
f5ae34250a | ||
|
|
fc4c29bc6e | ||
|
|
6158eec53f | ||
|
|
6c0fef5762 | ||
|
|
f5a4bd23e9 | ||
|
|
8e1760f37f | ||
|
|
1da5ab751f | ||
|
|
237ef710a1 | ||
|
|
be47e93134 | ||
|
|
1821c849da | ||
|
|
a4522ae516 | ||
|
|
c7ee4bc016 | ||
|
|
0cabb95811 | ||
|
|
a1b32533aa | ||
|
|
e2eb0d2326 | ||
|
|
acac6b0d69 | ||
|
|
deb8d0d6a1 | ||
|
|
3e817d91ef | ||
|
|
e231f0fade | ||
|
|
f0f55e6726 | ||
|
|
61dc8494d7 | ||
|
|
423b87d621 | ||
|
|
8d9568b4a1 | ||
|
|
acf511de34 | ||
|
|
fd2951bb53 | ||
|
|
fa004f4854 | ||
|
|
1155bdb754 | ||
|
|
01838c5732 | ||
|
|
f09f33031b | ||
|
|
b2a9f64e1b | ||
|
|
15ea618ef6 | ||
|
|
ec33423273 | ||
|
|
d5dd54df69 | ||
|
|
e7a4c34e7c | ||
|
|
2881bfbfd6 | ||
|
|
80fb38153e | ||
|
|
b79f337f8a | ||
|
|
f593ac1c21 | ||
|
|
baf92305a6 | ||
|
|
d6d168e87b | ||
|
|
50f9c4acc3 | ||
|
|
211374e52a | ||
|
|
1bf2461765 | ||
|
|
64444cd578 | ||
|
|
0047a31090 | ||
|
|
d73ce6cb56 | ||
|
|
9a6d3eee59 | ||
|
|
8b221d60fa | ||
|
|
9da9b36435 | ||
|
|
09b33f9a82 | ||
|
|
fa6b6dad3d | ||
|
|
e0d88cfd18 | ||
|
|
18043e3d22 | ||
|
|
ccf470fdb6 | ||
|
|
8f9bc6f2ce | ||
|
|
fcab45f39b | ||
|
|
bc44d06c3d | ||
|
|
7740e36a89 | ||
|
|
6127f792f9 | ||
|
|
fd2cf9c45d | ||
|
|
fc3dec8b62 | ||
|
|
a7315116dd | ||
|
|
37268dcc86 | ||
|
|
ea28e74205 | ||
|
|
c1c84f0a55 | ||
|
|
56bf38859b | ||
|
|
1cda4aa1e0 | ||
|
|
9711b52739 |
13
.gitignore
vendored
13
.gitignore
vendored
@@ -27,6 +27,7 @@
|
||||
/ffserver
|
||||
/config.*
|
||||
/coverage.info
|
||||
/version.h
|
||||
/doc/*.1
|
||||
/doc/*.3
|
||||
/doc/*.html
|
||||
@@ -34,28 +35,23 @@
|
||||
/doc/config.texi
|
||||
/doc/avoptions_codec.texi
|
||||
/doc/avoptions_format.texi
|
||||
/doc/doxy/html/
|
||||
/doc/examples/avio_reading
|
||||
/doc/examples/avcodec
|
||||
/doc/examples/demuxing_decoding
|
||||
/doc/examples/filter_audio
|
||||
/doc/examples/decoding_encoding
|
||||
/doc/examples/demuxing
|
||||
/doc/examples/filtering_audio
|
||||
/doc/examples/filtering_video
|
||||
/doc/examples/metadata
|
||||
/doc/examples/muxing
|
||||
/doc/examples/pc-uninstalled
|
||||
/doc/examples/remuxing
|
||||
/doc/examples/resampling_audio
|
||||
/doc/examples/scaling_video
|
||||
/doc/examples/transcode_aac
|
||||
/doc/fate.txt
|
||||
/doc/doxy/html/
|
||||
/doc/print_options
|
||||
/lcov/
|
||||
/libavcodec/*_tablegen
|
||||
/libavcodec/*_tables.c
|
||||
/libavcodec/*_tables.h
|
||||
/libavutil/avconfig.h
|
||||
/libavutil/ffversion.h
|
||||
/tests/audiogen
|
||||
/tests/base64
|
||||
/tests/data/
|
||||
@@ -67,7 +63,6 @@
|
||||
/tools/aviocat
|
||||
/tools/ffbisect
|
||||
/tools/bisect.need
|
||||
/tools/crypto_bench
|
||||
/tools/cws2fws
|
||||
/tools/fourcc2pixfmt
|
||||
/tools/ffescape
|
||||
|
||||
87
Changelog
87
Changelog
@@ -1,83 +1,6 @@
|
||||
Entries are sorted chronologically from oldest to youngest within each release,
|
||||
releases are sorted from youngest to oldest.
|
||||
|
||||
version 2.2:
|
||||
|
||||
- HNM version 4 demuxer and video decoder
|
||||
- Live HDS muxer
|
||||
- setsar/setdar filters now support variables in ratio expressions
|
||||
- elbg filter
|
||||
- string validation in ffprobe
|
||||
- support for decoding through VDPAU in ffmpeg (the -hwaccel option)
|
||||
- complete Voxware MetaSound decoder
|
||||
- remove mp3_header_compress bitstream filter
|
||||
- Windows resource files for shared libraries
|
||||
- aeval filter
|
||||
- stereoscopic 3d metadata handling
|
||||
- WebP encoding via libwebp
|
||||
- ATRAC3+ decoder
|
||||
- VP8 in Ogg demuxing
|
||||
- side & metadata support in NUT
|
||||
- framepack filter
|
||||
- XYZ12 rawvideo support in NUT
|
||||
- Exif metadata support in WebP decoder
|
||||
- OpenGL device
|
||||
- Use metadata_header_padding to control padding in ID3 tags (currently used in
|
||||
MP3, AIFF, and OMA files), FLAC header, and the AVI "junk" block.
|
||||
- Mirillis FIC video decoder
|
||||
- Support DNx444
|
||||
- libx265 encoder
|
||||
- dejudder filter
|
||||
- Autodetect VDA like all other hardware accelerations
|
||||
|
||||
|
||||
version 2.1:
|
||||
|
||||
- aecho filter
|
||||
- perspective filter ported from libmpcodecs
|
||||
- ffprobe -show_programs option
|
||||
- compand filter
|
||||
- RTMP seek support
|
||||
- when transcoding with ffmpeg (i.e. not streamcopying), -ss is now accurate
|
||||
even when used as an input option. Previous behavior can be restored with
|
||||
the -noaccurate_seek option.
|
||||
- ffmpeg -t option can now be used for inputs, to limit the duration of
|
||||
data read from an input file
|
||||
- incomplete Voxware MetaSound decoder
|
||||
- read EXIF metadata from JPEG
|
||||
- DVB teletext decoder
|
||||
- phase filter ported from libmpcodecs
|
||||
- w3fdif filter
|
||||
- Opus support in Matroska
|
||||
- FFV1 version 1.3 is stable and no longer experimental
|
||||
- FFV1: YUVA(444,422,420) 9, 10 and 16 bit support
|
||||
- changed DTS stream id in lavf mpeg ps muxer from 0x8a to 0x88, to be
|
||||
more consistent with other muxers.
|
||||
- adelay filter
|
||||
- pullup filter ported from libmpcodecs
|
||||
- ffprobe -read_intervals option
|
||||
- Lossless and alpha support for WebP decoder
|
||||
- Error Resilient AAC syntax (ER AAC LC) decoding
|
||||
- Low Delay AAC (ER AAC LD) decoding
|
||||
- mux chapters in ASF files
|
||||
- SFTP protocol (via libssh)
|
||||
- libx264: add ability to encode in YUVJ422P and YUVJ444P
|
||||
- Fraps: use BT.709 colorspace by default for yuv, as reference fraps decoder does
|
||||
- make decoding alpha optional for prores, ffv1 and vp6 by setting
|
||||
the skip_alpha flag.
|
||||
- ladspa wrapper filter
|
||||
- native VP9 decoder
|
||||
- dpx parser
|
||||
- max_error_rate parameter in ffmpeg
|
||||
- PulseAudio output device
|
||||
- ReplayGain scanner
|
||||
- Enhanced Low Delay AAC (ER AAC ELD) decoding (no LD SBR support)
|
||||
- Linux framebuffer output device
|
||||
- HEVC decoder
|
||||
- raw HEVC, HEVC in MOV/MP4, HEVC in Matroska, HEVC in MPEG-TS demuxing
|
||||
- mergeplanes filter
|
||||
|
||||
|
||||
version 2.0:
|
||||
|
||||
- curves filter
|
||||
@@ -90,7 +13,7 @@ version 2.0:
|
||||
- 10% faster aac encoding on x86 and MIPS
|
||||
- sine audio filter source
|
||||
- WebP demuxing and decoding support
|
||||
- ffmpeg options -filter_script and -filter_complex_script, which allow a
|
||||
- new ffmpeg options -filter_script and -filter_complex_script, which allow a
|
||||
filtergraph description to be read from a file
|
||||
- OpenCL support
|
||||
- audio phaser filter
|
||||
@@ -98,7 +21,7 @@ version 2.0:
|
||||
- libquvi demuxer
|
||||
- uniform options syntax across all filters
|
||||
- telecine filter
|
||||
- interlace filter
|
||||
- new interlace filter
|
||||
- smptehdbars source
|
||||
- inverse telecine filters (fieldmatch and decimate)
|
||||
- colorbalance filter
|
||||
@@ -684,7 +607,7 @@ version 0.6:
|
||||
- LPCM support in MPEG-TS (HDMV RID as found on Blu-ray disks)
|
||||
- WMA Pro decoder
|
||||
- Core Audio Format demuxer
|
||||
- ATRAC1 decoder
|
||||
- Atrac1 decoder
|
||||
- MD STUDIO audio demuxer
|
||||
- RF64 support in WAV demuxer
|
||||
- MPEG-4 Audio Lossless Coding (ALS) decoder
|
||||
@@ -784,7 +707,7 @@ version 0.5:
|
||||
- MXF demuxer
|
||||
- VC-1/WMV3/WMV9 video decoder
|
||||
- MacIntel support
|
||||
- AviSynth support
|
||||
- AVISynth support
|
||||
- VMware video decoder
|
||||
- VP5 video decoder
|
||||
- VP6 video decoder
|
||||
@@ -812,7 +735,7 @@ version 0.5:
|
||||
- Interplay C93 demuxer and video decoder
|
||||
- Bethsoft VID demuxer and video decoder
|
||||
- CRYO APC demuxer
|
||||
- ATRAC3 decoder
|
||||
- Atrac3 decoder
|
||||
- V.Flash PTX decoder
|
||||
- RoQ muxer, RoQ audio encoder
|
||||
- Renderware TXD demuxer and decoder
|
||||
|
||||
7
LICENSE
7
LICENSE
@@ -33,20 +33,20 @@ Specifically, the GPL parts of FFmpeg are
|
||||
- vf_geq.c
|
||||
- vf_histeq.c
|
||||
- vf_hqdn3d.c
|
||||
- vf_hue.c
|
||||
- vf_kerndeint.c
|
||||
- vf_mcdeint.c
|
||||
- vf_mp.c
|
||||
- vf_noise.c
|
||||
- vf_owdenoise.c
|
||||
- vf_perspective.c
|
||||
- vf_phase.c
|
||||
- vf_pp.c
|
||||
- vf_pullup.c
|
||||
- vf_sab.c
|
||||
- vf_smartblur.c
|
||||
- vf_spp.c
|
||||
- vf_stereo3d.c
|
||||
- vf_super2xsai.c
|
||||
- vf_tinterlace.c
|
||||
- vf_yadif.c
|
||||
- vsrc_mptestsrc.c
|
||||
|
||||
Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then
|
||||
@@ -79,7 +79,6 @@ The following libraries are under GPL:
|
||||
- libutvideo
|
||||
- libvidstab
|
||||
- libx264
|
||||
- libx265
|
||||
- libxavs
|
||||
- libxvid
|
||||
When combining them with FFmpeg, FFmpeg needs to be licensed as GPL as well by
|
||||
|
||||
68
MAINTAINERS
68
MAINTAINERS
@@ -14,7 +14,6 @@ patches and related discussions.
|
||||
Project Leader
|
||||
==============
|
||||
|
||||
Michael Niedermayer
|
||||
final design decisions
|
||||
|
||||
|
||||
@@ -31,7 +30,7 @@ ffprobe:
|
||||
ffprobe.c Stefano Sabatini
|
||||
|
||||
ffserver:
|
||||
ffserver.c Reynaldo H. Verdejo Pinochet
|
||||
ffserver.c, ffserver.h Baptiste Coudurier
|
||||
|
||||
Commandline utility code:
|
||||
cmdutils.c, cmdutils.h Michael Niedermayer
|
||||
@@ -43,24 +42,16 @@ QuickTime faststart:
|
||||
Miscellaneous Areas
|
||||
===================
|
||||
|
||||
documentation Stefano Sabatini, Mike Melanson, Timothy Gu
|
||||
documentation Mike Melanson
|
||||
website Robert Swain, Lou Logan
|
||||
build system (configure,Makefiles) Diego Biurrun, Mans Rullgard
|
||||
project server Árpád Gereöffy, Michael Niedermayer, Reimar Döffinger, Alexander Strasser
|
||||
mailinglists Michael Niedermayer, Baptiste Coudurier, Lou Logan
|
||||
presets Robert Swain
|
||||
metadata subsystem Aurelien Jacobs
|
||||
release management Michael Niedermayer
|
||||
|
||||
|
||||
Communication
|
||||
=============
|
||||
|
||||
website Robert Swain, Lou Logan
|
||||
mailinglists Michael Niedermayer, Baptiste Coudurier, Lou Logan
|
||||
Google+ Paul B Mahol, Michael Niedermayer, Alexander Strasser
|
||||
Twitter Lou Logan
|
||||
Launchpad Timothy Gu
|
||||
|
||||
|
||||
libavutil
|
||||
=========
|
||||
|
||||
@@ -73,16 +64,13 @@ Other:
|
||||
bprint Nicolas George
|
||||
bswap.h
|
||||
des Reimar Doeffinger
|
||||
eval.c, eval.h Michael Niedermayer
|
||||
float_dsp Loren Merritt
|
||||
hash Reimar Doeffinger
|
||||
intfloat* Michael Niedermayer
|
||||
integer.c, integer.h Michael Niedermayer
|
||||
lzo Reimar Doeffinger
|
||||
mathematics.c, mathematics.h Michael Niedermayer
|
||||
mem.c, mem.h Michael Niedermayer
|
||||
opencl.c, opencl.h Wei Gao
|
||||
opt.c, opt.h Michael Niedermayer
|
||||
rational.c, rational.h Michael Niedermayer
|
||||
rc4 Reimar Doeffinger
|
||||
ripemd.c, ripemd.h James Almer
|
||||
@@ -97,6 +85,10 @@ Generic Parts:
|
||||
avcodec.h Michael Niedermayer
|
||||
utility code:
|
||||
utils.c Michael Niedermayer
|
||||
mem.c Michael Niedermayer
|
||||
opt.c, opt.h Michael Niedermayer
|
||||
arithmetic expression evaluator:
|
||||
eval.c Michael Niedermayer
|
||||
audio and video frame extraction:
|
||||
parser.c Michael Niedermayer
|
||||
bitstream reading:
|
||||
@@ -127,8 +119,6 @@ Generic Parts:
|
||||
libpostproc/* Michael Niedermayer
|
||||
table generation:
|
||||
tableprint.c, tableprint.h Reimar Doeffinger
|
||||
fixed point FFT:
|
||||
fft* Zeljko Lukac
|
||||
|
||||
Codecs:
|
||||
4xm.c Michael Niedermayer
|
||||
@@ -142,7 +132,6 @@ Codecs:
|
||||
ass* Aurelien Jacobs
|
||||
asv* Michael Niedermayer
|
||||
atrac3* Benjamin Larsson
|
||||
atrac3plus* Maxim Poliakovski
|
||||
bgmc.c, bgmc.h Thilo Borgmann
|
||||
bink.c Kostya Shishkov
|
||||
binkaudio.c Peter Ross
|
||||
@@ -151,7 +140,6 @@ Codecs:
|
||||
cdxl.c Paul B Mahol
|
||||
celp_filters.* Vitor Sessak
|
||||
cinepak.c Roberto Togni
|
||||
cinepakenc.c Rl / Aetey G.T. AB
|
||||
cljr Alex Beregszaszi
|
||||
cllc.c Derek Buitenhuis
|
||||
cook.c, cookdata.h Benjamin Larsson
|
||||
@@ -164,7 +152,6 @@ Codecs:
|
||||
dv.c Roman Shaposhnik
|
||||
dxa.c Kostya Shishkov
|
||||
eacmv*, eaidct*, eat* Peter Ross
|
||||
exif.c, exif.h Thilo Borgmann
|
||||
ffv1.c Michael Niedermayer
|
||||
ffwavesynth.c Nicolas George
|
||||
flac* Justin Ruggles
|
||||
@@ -199,11 +186,8 @@ Codecs:
|
||||
libtheoraenc.c David Conrad
|
||||
libutvideo* Derek Buitenhuis
|
||||
libvorbis.c David Conrad
|
||||
libvpx* James Zern
|
||||
libx264.c Mans Rullgard, Jason Garrett-Glaser
|
||||
libx265.c Derek Buitenhuis
|
||||
libxavs.c Stefan Gehrer
|
||||
libzvbi-teletextdec.c Marton Balint
|
||||
loco.c Kostya Shishkov
|
||||
lzo.h, lzo.c Reimar Doeffinger
|
||||
mdec.c Michael Niedermayer
|
||||
@@ -271,7 +255,6 @@ Codecs:
|
||||
vp5 Aurelien Jacobs
|
||||
vp6 Aurelien Jacobs
|
||||
vp8 David Conrad, Jason Garrett-Glaser, Ronald Bultje
|
||||
vp9 Ronald Bultje, Clément Bœsch
|
||||
vqavideo.c Mike Melanson
|
||||
wavpack.c Kostya Shishkov
|
||||
wmaprodec.c Sascha Sommer
|
||||
@@ -280,7 +263,6 @@ Codecs:
|
||||
wnv1.c Kostya Shishkov
|
||||
xan.c Mike Melanson
|
||||
xbm* Paul B Mahol
|
||||
xface Stefano Sabatini
|
||||
xl.c Kostya Shishkov
|
||||
xvmc.c Ivan Kalvachev
|
||||
xwd* Paul B Mahol
|
||||
@@ -303,13 +285,8 @@ libavdevice
|
||||
|
||||
|
||||
dshow.c Roger Pack
|
||||
fbdev_enc.c Lukasz Marek
|
||||
iec61883.c Georg Lippitsch
|
||||
lavfi Stefano Sabatini
|
||||
libdc1394.c Roman Shaposhnik
|
||||
opengl_enc.c Lukasz Marek
|
||||
pulse_audio_enc.c Lukasz Marek
|
||||
sdl Stefano Sabatini
|
||||
v4l2.c Luca Abeni
|
||||
vfwcap.c Ramiro Polla
|
||||
|
||||
@@ -320,34 +297,14 @@ Generic parts:
|
||||
graphdump.c Nicolas George
|
||||
|
||||
Filters:
|
||||
af_adelay.c Paul B Mahol
|
||||
af_aecho.c Paul B Mahol
|
||||
af_afade.c Paul B Mahol
|
||||
af_amerge.c Nicolas George
|
||||
af_aphaser.c Paul B Mahol
|
||||
af_aresample.c Michael Niedermayer
|
||||
af_astats.c Paul B Mahol
|
||||
af_astreamsync.c Nicolas George
|
||||
af_atempo.c Pavel Koshevoy
|
||||
af_biquads.c Paul B Mahol
|
||||
af_compand.c Paul B Mahol
|
||||
af_ladspa.c Paul B Mahol
|
||||
af_pan.c Nicolas George
|
||||
avf_avectorscope.c Paul B Mahol
|
||||
vf_blend.c Paul B Mahol
|
||||
vf_colorbalance.c Paul B Mahol
|
||||
vf_dejudder.c Nicholas Robbins
|
||||
vf_delogo.c Jean Delvare (CC <khali@linux-fr.org>)
|
||||
vf_drawbox.c/drawgrid Andrey Utkin
|
||||
vf_extractplanes.c Paul B Mahol
|
||||
vf_histogram.c Paul B Mahol
|
||||
vf_il.c Paul B Mahol
|
||||
vf_mergeplanes.c Paul B Mahol
|
||||
vf_psnr.c Paul B Mahol
|
||||
vf_scale.c Michael Niedermayer
|
||||
vf_separatefields.c Paul B Mahol
|
||||
vf_stereo3d.c Paul B Mahol
|
||||
vf_telecine.c Paul B Mahol
|
||||
vf_yadif.c Michael Niedermayer
|
||||
|
||||
Sources:
|
||||
@@ -393,7 +350,6 @@ Muxers/Demuxers:
|
||||
flvdec.c, flvenc.c Michael Niedermayer
|
||||
gxf.c Reimar Doeffinger
|
||||
gxfenc.c Baptiste Coudurier
|
||||
hls.c Anssi Hannula
|
||||
idcin.c Mike Melanson
|
||||
idroqdec.c Mike Melanson
|
||||
iff.c Jaikrishnan Menon
|
||||
@@ -453,7 +409,6 @@ Muxers/Demuxers:
|
||||
siff.c Kostya Shishkov
|
||||
smacker.c Kostya Shishkov
|
||||
smjpeg* Paul B Mahol
|
||||
spdif* Anssi Hannula
|
||||
srtdec.c Aurelien Jacobs
|
||||
swf.c Baptiste Coudurier
|
||||
takdec.c Paul B Mahol
|
||||
@@ -472,7 +427,6 @@ Protocols:
|
||||
bluray.c Petri Hintukainen
|
||||
ftp.c Lukasz Marek
|
||||
http.c Ronald S. Bultje
|
||||
libssh.c Lukasz Marek
|
||||
mms*.c Ronald S. Bultje
|
||||
udp.c Luca Abeni
|
||||
|
||||
@@ -497,7 +451,7 @@ Operating systems / CPU architectures
|
||||
Alpha Mans Rullgard, Falk Hueffner
|
||||
ARM Mans Rullgard
|
||||
AVR32 Mans Rullgard
|
||||
MIPS Mans Rullgard, Nedeljko Babic
|
||||
MIPS Mans Rullgard
|
||||
Mac OS X / PowerPC Romain Dolbeau, Guillaume Poirier
|
||||
Amiga / PowerPC Colin Ward
|
||||
Linux / PowerPC Luca Barbato
|
||||
@@ -511,8 +465,7 @@ x86 Michael Niedermayer
|
||||
Releases
|
||||
========
|
||||
|
||||
2.2 Michael Niedermayer
|
||||
2.1 Michael Niedermayer
|
||||
2.0 Michael Niedermayer
|
||||
1.2 Michael Niedermayer
|
||||
|
||||
If you want to maintain an older release, please contact us
|
||||
@@ -521,7 +474,6 @@ If you want to maintain an older release, please contact us
|
||||
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
|
||||
Anton Khirnov 6D0C 6625 56F8 65D1 E5F5 814B B50A 1241 C067 07AB
|
||||
Ash Hughes 694D 43D2 D180 C7C7 6421 ABD3 A641 D0B7 623D 6029
|
||||
|
||||
68
Makefile
68
Makefile
@@ -6,34 +6,29 @@ vpath %.cpp $(SRC_PATH)
|
||||
vpath %.h $(SRC_PATH)
|
||||
vpath %.S $(SRC_PATH)
|
||||
vpath %.asm $(SRC_PATH)
|
||||
vpath %.rc $(SRC_PATH)
|
||||
vpath %.v $(SRC_PATH)
|
||||
vpath %.texi $(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
|
||||
PROGS-$(CONFIG_FFMPEG) += ffmpeg
|
||||
PROGS-$(CONFIG_FFPLAY) += ffplay
|
||||
PROGS-$(CONFIG_FFPROBE) += ffprobe
|
||||
PROGS-$(CONFIG_FFSERVER) += ffserver
|
||||
|
||||
AVPROGS := $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
|
||||
INSTPROGS = $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
|
||||
PROGS += $(AVPROGS)
|
||||
PROGS := $(PROGS-yes:%=%$(PROGSSUF)$(EXESUF))
|
||||
INSTPROGS = $(PROGS-yes:%=%$(PROGSSUF)$(EXESUF))
|
||||
|
||||
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-$(HAVE_VDPAU_X11) += ffmpeg_vdpau.o
|
||||
OBJS = cmdutils.o $(EXEOBJS)
|
||||
OBJS-ffmpeg = ffmpeg_opt.o ffmpeg_filter.o
|
||||
TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64
|
||||
HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options
|
||||
TOOLS = qt-faststart trasher uncoded_frame
|
||||
TOOLS = qt-faststart trasher
|
||||
TOOLS-$(CONFIG_ZLIB) += cws2fws
|
||||
|
||||
BASENAMES = ffmpeg ffplay ffprobe ffserver
|
||||
ALLPROGS = $(BASENAMES:%=%$(PROGSSUF)$(EXESUF))
|
||||
ALLPROGS_G = $(BASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
|
||||
|
||||
FFLIBS-$(CONFIG_AVDEVICE) += avdevice
|
||||
FFLIBS-$(CONFIG_AVFILTER) += avfilter
|
||||
FFLIBS-$(CONFIG_AVFORMAT) += avformat
|
||||
@@ -55,14 +50,16 @@ include $(SRC_PATH)/common.mak
|
||||
FF_EXTRALIBS := $(FFEXTRALIBS)
|
||||
FF_DEP_LIBS := $(DEP_LIBS)
|
||||
|
||||
all: $(AVPROGS)
|
||||
all: $(PROGS)
|
||||
|
||||
$(PROGS): %$(EXESUF): %_g$(EXESUF)
|
||||
$(CP) $< $@
|
||||
$(STRIP) $@
|
||||
|
||||
$(TOOLS): %$(EXESUF): %.o $(EXEOBJS)
|
||||
$(LD) $(LDFLAGS) $(LD_O) $^ $(ELIBS)
|
||||
|
||||
tools/cws2fws$(EXESUF): ELIBS = $(ZLIB)
|
||||
tools/uncoded_frame$(EXESUF): $(FF_DEP_LIBS)
|
||||
tools/uncoded_frame$(EXESUF): ELIBS = $(FF_EXTRALIBS)
|
||||
|
||||
config.h: .config
|
||||
.config: $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c))
|
||||
@@ -76,7 +73,7 @@ SUBDIR_VARS := CLEANFILES EXAMPLES FFLIBS HOSTPROGS TESTPROGS TOOLS \
|
||||
ALTIVEC-OBJS VIS-OBJS \
|
||||
MMX-OBJS YASM-OBJS \
|
||||
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSPR1-OBJS MIPS32R2-OBJS \
|
||||
OBJS SLIBOBJS HOSTOBJS TESTOBJS
|
||||
OBJS HOSTOBJS TESTOBJS
|
||||
|
||||
define RESET
|
||||
$(1) :=
|
||||
@@ -93,10 +90,8 @@ endef
|
||||
|
||||
$(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D))))
|
||||
|
||||
include $(SRC_PATH)/doc/Makefile
|
||||
|
||||
define DOPROG
|
||||
OBJS-$(1) += $(1).o $(EXEOBJS) $(OBJS-$(1)-yes)
|
||||
OBJS-$(1) += $(1).o cmdutils.o $(EXEOBJS)
|
||||
$(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1))
|
||||
$$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1))
|
||||
$(1)$(PROGSSUF)_g$(EXESUF): LDFLAGS += $(LDFLAGS-$(1))
|
||||
@@ -104,13 +99,7 @@ $(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 : libavutil/ffversion.h
|
||||
|
||||
$(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF)
|
||||
$(CP) $< $@
|
||||
$(STRIP) $@
|
||||
$(foreach P,$(PROGS-yes),$(eval $(call DOPROG,$(P))))
|
||||
|
||||
%$(PROGSSUF)_g$(EXESUF): %.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS)
|
||||
@@ -125,14 +114,14 @@ GIT_LOG = $(SRC_PATH)/.git/logs/HEAD
|
||||
.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) config.mak
|
||||
.version: M=@
|
||||
|
||||
libavutil/ffversion.h .version:
|
||||
$(M)$(VERSION_SH) $(SRC_PATH) libavutil/ffversion.h $(EXTRA_VERSION)
|
||||
version.h .version:
|
||||
$(M)$(VERSION_SH) $(SRC_PATH) version.h $(EXTRA_VERSION)
|
||||
$(Q)touch .version
|
||||
|
||||
# force version.sh to run whenever version might have changed
|
||||
-include .version
|
||||
|
||||
ifdef AVPROGS
|
||||
ifdef PROGS
|
||||
install: install-progs install-data
|
||||
endif
|
||||
|
||||
@@ -143,7 +132,7 @@ install-libs: install-libs-yes
|
||||
install-progs-yes:
|
||||
install-progs-$(CONFIG_SHARED): install-libs
|
||||
|
||||
install-progs: install-progs-yes $(AVPROGS)
|
||||
install-progs: install-progs-yes $(PROGS)
|
||||
$(Q)mkdir -p "$(BINDIR)"
|
||||
$(INSTALL) -c -m 755 $(INSTPROGS) "$(BINDIR)"
|
||||
|
||||
@@ -155,13 +144,13 @@ install-data: $(DATA_FILES) $(EXAMPLES_FILES)
|
||||
uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data
|
||||
|
||||
uninstall-progs:
|
||||
$(RM) $(addprefix "$(BINDIR)/", $(ALLAVPROGS))
|
||||
$(RM) $(addprefix "$(BINDIR)/", $(ALLPROGS))
|
||||
|
||||
uninstall-data:
|
||||
$(RM) -r "$(DATADIR)"
|
||||
|
||||
clean::
|
||||
$(RM) $(ALLAVPROGS) $(ALLAVPROGS_G)
|
||||
$(RM) $(ALLPROGS) $(ALLPROGS_G)
|
||||
$(RM) $(CLEANSUFFIXES)
|
||||
$(RM) $(CLEANSUFFIXES:%=tools/%)
|
||||
$(RM) -r coverage-html
|
||||
@@ -169,13 +158,14 @@ clean::
|
||||
|
||||
distclean::
|
||||
$(RM) $(DISTCLEANSUFFIXES)
|
||||
$(RM) config.* .config libavutil/avconfig.h .version version.h libavutil/ffversion.h libavcodec/codec_names.h
|
||||
$(RM) config.* .config libavutil/avconfig.h .version version.h libavcodec/codec_names.h
|
||||
|
||||
config:
|
||||
$(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION)
|
||||
|
||||
check: all alltools examples testprogs fate
|
||||
|
||||
include $(SRC_PATH)/doc/Makefile
|
||||
include $(SRC_PATH)/tests/Makefile
|
||||
|
||||
$(sort $(OBJDIRS)):
|
||||
|
||||
146
cmdutils.c
146
cmdutils.c
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
@@ -48,9 +47,8 @@
|
||||
#include "libavutil/eval.h"
|
||||
#include "libavutil/dict.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/cpu.h"
|
||||
#include "libavutil/ffversion.h"
|
||||
#include "cmdutils.h"
|
||||
#include "version.h"
|
||||
#if CONFIG_NETWORK
|
||||
#include "libavformat/network.h"
|
||||
#endif
|
||||
@@ -58,6 +56,10 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#if CONFIG_OPENCL
|
||||
#include "libavutil/opencl.h"
|
||||
#endif
|
||||
|
||||
|
||||
static int init_report(const char *env);
|
||||
|
||||
@@ -65,8 +67,9 @@ struct SwsContext *sws_opts;
|
||||
AVDictionary *swr_opts;
|
||||
AVDictionary *format_opts, *codec_opts, *resample_opts;
|
||||
|
||||
const int this_year = 2015;
|
||||
|
||||
static FILE *report_file;
|
||||
int hide_banner = 0;
|
||||
|
||||
void init_opts(void)
|
||||
{
|
||||
@@ -210,10 +213,7 @@ static const OptionDef *find_option(const OptionDef *po, const char *name)
|
||||
return po;
|
||||
}
|
||||
|
||||
/* _WIN32 means using the windows libc - cygwin doesn't define that
|
||||
* by default. HAVE_COMMANDLINETOARGVW is true on cygwin, while
|
||||
* it doesn't provide the actual command line via GetCommandLineW(). */
|
||||
#if HAVE_COMMANDLINETOARGVW && defined(_WIN32)
|
||||
#if HAVE_COMMANDLINETOARGVW
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
/* Will be leaked on exit */
|
||||
@@ -492,18 +492,6 @@ void parse_loglevel(int argc, char **argv, const OptionDef *options)
|
||||
fflush(report_file);
|
||||
}
|
||||
}
|
||||
idx = locate_option(argc, argv, options, "hide_banner");
|
||||
if (idx)
|
||||
hide_banner = 1;
|
||||
}
|
||||
|
||||
static const AVOption *opt_find(void *obj, const char *name, const char *unit,
|
||||
int opt_flags, int search_flags)
|
||||
{
|
||||
const AVOption *o = av_opt_find(obj, name, unit, opt_flags, search_flags);
|
||||
if(o && !o->flags)
|
||||
return NULL;
|
||||
return o;
|
||||
}
|
||||
|
||||
#define FLAGS (o->type == AV_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
|
||||
@@ -526,14 +514,14 @@ int opt_default(void *optctx, const char *opt, const char *arg)
|
||||
p = opt + strlen(opt);
|
||||
av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
|
||||
|
||||
if ((o = opt_find(&cc, opt_stripped, NULL, 0,
|
||||
if ((o = av_opt_find(&cc, opt_stripped, NULL, 0,
|
||||
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) ||
|
||||
((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
|
||||
(o = opt_find(&cc, opt + 1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)))) {
|
||||
(o = av_opt_find(&cc, opt + 1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)))) {
|
||||
av_dict_set(&codec_opts, opt, arg, FLAGS);
|
||||
consumed = 1;
|
||||
}
|
||||
if ((o = opt_find(&fc, opt, NULL, 0,
|
||||
if ((o = av_opt_find(&fc, opt, NULL, 0,
|
||||
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
|
||||
av_dict_set(&format_opts, opt, arg, FLAGS);
|
||||
if (consumed)
|
||||
@@ -542,7 +530,7 @@ int opt_default(void *optctx, const char *opt, const char *arg)
|
||||
}
|
||||
#if CONFIG_SWSCALE
|
||||
sc = sws_get_class();
|
||||
if (!consumed && opt_find(&sc, opt, NULL, 0,
|
||||
if (!consumed && av_opt_find(&sc, opt, NULL, 0,
|
||||
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) {
|
||||
// XXX we only support sws_flags, not arbitrary sws options
|
||||
int ret = av_opt_set(sws_opts, opt, arg, 0);
|
||||
@@ -555,7 +543,7 @@ int opt_default(void *optctx, const char *opt, const char *arg)
|
||||
#endif
|
||||
#if CONFIG_SWRESAMPLE
|
||||
swr_class = swr_get_class();
|
||||
if (!consumed && (o=opt_find(&swr_class, opt, NULL, 0,
|
||||
if (!consumed && (o=av_opt_find(&swr_class, opt, NULL, 0,
|
||||
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
|
||||
struct SwrContext *swr = swr_alloc();
|
||||
int ret = av_opt_set(swr, opt, arg, 0);
|
||||
@@ -569,7 +557,7 @@ int opt_default(void *optctx, const char *opt, const char *arg)
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_AVRESAMPLE
|
||||
if ((o=opt_find(&rc, opt, NULL, 0,
|
||||
if ((o=av_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;
|
||||
@@ -808,18 +796,6 @@ do { \
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opt_cpuflags(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
int ret;
|
||||
unsigned flags = av_get_cpu_flags();
|
||||
|
||||
if ((ret = av_parse_cpu_caps(&flags, arg)) < 0)
|
||||
return ret;
|
||||
|
||||
av_force_cpu_flags(flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opt_loglevel(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
const struct { const char *name; int level; } log_levels[] = {
|
||||
@@ -972,6 +948,18 @@ int opt_max_alloc(void *optctx, const char *opt, const char *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opt_cpuflags(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
int ret;
|
||||
unsigned flags = av_get_cpu_flags();
|
||||
|
||||
if ((ret = av_parse_cpu_caps(&flags, arg)) < 0)
|
||||
return ret;
|
||||
|
||||
av_force_cpu_flags(flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opt_timelimit(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
#if HAVE_SETRLIMIT
|
||||
@@ -985,6 +973,26 @@ int opt_timelimit(void *optctx, const char *opt, const char *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_OPENCL
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
void print_error(const char *filename, int err)
|
||||
{
|
||||
char errbuf[128];
|
||||
@@ -1050,7 +1058,7 @@ static void print_program_info(int flags, int level)
|
||||
av_log(NULL, level, "%s version " FFMPEG_VERSION, program_name);
|
||||
if (flags & SHOW_COPYRIGHT)
|
||||
av_log(NULL, level, " Copyright (c) %d-%d the FFmpeg developers",
|
||||
program_birth_year, CONFIG_THIS_YEAR);
|
||||
program_birth_year, this_year);
|
||||
av_log(NULL, level, "\n");
|
||||
av_log(NULL, level, "%sbuilt on %s %s with %s\n",
|
||||
indent, __DATE__, __TIME__, CC_IDENT);
|
||||
@@ -1058,36 +1066,10 @@ static void print_program_info(int flags, int level)
|
||||
av_log(NULL, level, "%sconfiguration: " FFMPEG_CONFIGURATION "\n", indent);
|
||||
}
|
||||
|
||||
static void print_buildconf(int flags, int level)
|
||||
{
|
||||
const char *indent = flags & INDENT ? " " : "";
|
||||
char str[] = { FFMPEG_CONFIGURATION };
|
||||
char *conflist, *remove_tilde, *splitconf;
|
||||
|
||||
// Change all the ' --' strings to '~--' so that
|
||||
// they can be identified as tokens.
|
||||
while ((conflist = strstr(str, " --")) != NULL) {
|
||||
strncpy(conflist, "~--", 3);
|
||||
}
|
||||
|
||||
// Compensate for the weirdness this would cause
|
||||
// when passing 'pkg-config --static'.
|
||||
while ((remove_tilde = strstr(str, "pkg-config~")) != NULL) {
|
||||
strncpy(remove_tilde, "pkg-config ", 11);
|
||||
}
|
||||
|
||||
splitconf = strtok(str, "~");
|
||||
av_log(NULL, level, "\n%sconfiguration:\n", indent);
|
||||
while (splitconf != NULL) {
|
||||
av_log(NULL, level, "%s%s%s\n", indent, indent, splitconf);
|
||||
splitconf = strtok(NULL, "~");
|
||||
}
|
||||
}
|
||||
|
||||
void show_banner(int argc, char **argv, const OptionDef *options)
|
||||
{
|
||||
int idx = locate_option(argc, argv, options, "version");
|
||||
if (hide_banner || idx)
|
||||
if (idx)
|
||||
return;
|
||||
|
||||
print_program_info (INDENT|SHOW_COPYRIGHT, AV_LOG_INFO);
|
||||
@@ -1104,14 +1086,6 @@ int show_version(void *optctx, const char *opt, const char *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int show_buildconf(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
av_log_set_callback(log_callback_help);
|
||||
print_buildconf (INDENT|0, AV_LOG_INFO);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int show_license(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
#if CONFIG_NONFREE
|
||||
@@ -1495,9 +1469,8 @@ int show_filters(void *optctx, const char *opt, const char *arg)
|
||||
const AVFilterPad *pad;
|
||||
|
||||
printf("Filters:\n"
|
||||
" T.. = Timeline support\n"
|
||||
" .S. = Slice threading\n"
|
||||
" ..C = Commmand support\n"
|
||||
" T. = Timeline support\n"
|
||||
" .S = Slice threading\n"
|
||||
" A = Audio input/output\n"
|
||||
" V = Video input/output\n"
|
||||
" N = Dynamic number and/or type of input/output\n"
|
||||
@@ -1521,30 +1494,15 @@ int show_filters(void *optctx, const char *opt, const char *arg)
|
||||
( i && (filter->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS))) ? 'N' : '|';
|
||||
}
|
||||
*descr_cur = 0;
|
||||
printf(" %c%c%c %-16s %-10s %s\n",
|
||||
printf(" %c%c %-16s %-10s %s\n",
|
||||
filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE ? 'T' : '.',
|
||||
filter->flags & AVFILTER_FLAG_SLICE_THREADS ? 'S' : '.',
|
||||
filter->process_command ? 'C' : '.',
|
||||
filter->name, descr, filter->description);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int show_colors(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
const char *name;
|
||||
const uint8_t *rgb;
|
||||
int i;
|
||||
|
||||
printf("%-32s #RRGGBB\n", "name");
|
||||
|
||||
for (i = 0; name = av_get_known_color_name(i, &rgb); i++)
|
||||
printf("%-32s #%02x%02x%02x\n", name, rgb[0], rgb[1], rgb[2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int show_pix_fmts(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
const AVPixFmtDescriptor *pix_desc = NULL;
|
||||
@@ -1804,7 +1762,7 @@ int read_yesno(void)
|
||||
int cmdutils_read_file(const char *filename, char **bufptr, size_t *size)
|
||||
{
|
||||
int ret;
|
||||
FILE *f = av_fopen_utf8(filename, "rb");
|
||||
FILE *f = fopen(filename, "rb");
|
||||
|
||||
if (!f) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename,
|
||||
|
||||
32
cmdutils.h
32
cmdutils.h
@@ -43,12 +43,16 @@ extern const char program_name[];
|
||||
*/
|
||||
extern const int program_birth_year;
|
||||
|
||||
/**
|
||||
* this year, defined by the program for show_banner()
|
||||
*/
|
||||
extern const int this_year;
|
||||
|
||||
extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
|
||||
extern AVFormatContext *avformat_opts;
|
||||
extern struct SwsContext *sws_opts;
|
||||
extern AVDictionary *swr_opts;
|
||||
extern AVDictionary *format_opts, *codec_opts, *resample_opts;
|
||||
extern int hide_banner;
|
||||
|
||||
/**
|
||||
* Register a program-specific cleanup routine.
|
||||
@@ -77,11 +81,6 @@ void uninit_opts(void);
|
||||
*/
|
||||
void log_callback_help(void* ptr, int level, const char* fmt, va_list vl);
|
||||
|
||||
/**
|
||||
* Override the cpuflags.
|
||||
*/
|
||||
int opt_cpuflags(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Fallback for options that are not explicitly handled, these will be
|
||||
* parsed through AVOptions.
|
||||
@@ -97,14 +96,12 @@ int opt_report(const char *opt);
|
||||
|
||||
int opt_max_alloc(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
int opt_cpuflags(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.
|
||||
*/
|
||||
@@ -414,13 +411,6 @@ void show_banner(int argc, char **argv, const OptionDef *options);
|
||||
*/
|
||||
int show_version(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Print the build configuration of the program to stdout. The contents
|
||||
* depend on the definition of FFMPEG_CONFIGURATION.
|
||||
* This option processing function does not utilize the arguments.
|
||||
*/
|
||||
int show_buildconf(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Print the license of the program to stdout. The license depends on
|
||||
* the license of the libraries compiled into the program.
|
||||
@@ -495,12 +485,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 the color names and values recognized
|
||||
* by the program.
|
||||
*/
|
||||
int show_colors(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Return a positive value if a line read from standard input
|
||||
* starts with [yY], otherwise return 0.
|
||||
@@ -514,7 +498,7 @@ int read_yesno(void);
|
||||
* @param filename file to read from
|
||||
* @param bufptr location where pointer to buffer is returned
|
||||
* @param size location where size of buffer is returned
|
||||
* @return >= 0 in case of success, a negative value corresponding to an
|
||||
* @return 0 in case of success, a negative value corresponding to an
|
||||
* AVERROR error code in case of failure.
|
||||
*/
|
||||
int cmdutils_read_file(const char *filename, char **bufptr, size_t *size);
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
{ "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" },
|
||||
{ "codecs" , OPT_EXIT, {.func_arg = show_codecs }, "show available codecs" },
|
||||
{ "decoders" , OPT_EXIT, {.func_arg = show_decoders }, "show available decoders" },
|
||||
@@ -15,14 +14,11 @@
|
||||
{ "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" },
|
||||
{ "cpuflags" , HAS_ARG | OPT_EXPERT, {.func_arg = opt_cpuflags}, "force specific cpu flags", "flags" },
|
||||
#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
|
||||
|
||||
@@ -1,274 +0,0 @@
|
||||
/*
|
||||
* 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 "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();
|
||||
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() - 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)
|
||||
{
|
||||
return ((OpenCLDeviceBenchmark*)a)->runtime - ((OpenCLDeviceBenchmark*)b)->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(sizeof(OpenCLDeviceBenchmark) * nb_devices))) {
|
||||
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;
|
||||
strcpy(devices[count].device_name, device_node->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;
|
||||
}
|
||||
24
common.mak
24
common.mak
@@ -10,7 +10,7 @@ ifndef SUBDIR
|
||||
ifndef V
|
||||
Q = @
|
||||
ECHO = printf "$(1)\t%s\n" $(2)
|
||||
BRIEF = CC CXX HOSTCC HOSTLD AS YASM AR LD STRIP CP WINDRES
|
||||
BRIEF = CC CXX HOSTCC HOSTLD AS YASM AR LD STRIP CP
|
||||
SILENT = DEPCC DEPHOSTCC DEPAS DEPYASM RANLIB RM
|
||||
|
||||
MSG = $@
|
||||
@@ -43,7 +43,6 @@ endef
|
||||
COMPILE_C = $(call COMPILE,CC)
|
||||
COMPILE_CXX = $(call COMPILE,CXX)
|
||||
COMPILE_S = $(call COMPILE,AS)
|
||||
COMPILE_HOSTC = $(call COMPILE,HOSTCC)
|
||||
|
||||
%.o: %.c
|
||||
$(COMPILE_C)
|
||||
@@ -57,12 +56,6 @@ COMPILE_HOSTC = $(call COMPILE,HOSTCC)
|
||||
%.o: %.S
|
||||
$(COMPILE_S)
|
||||
|
||||
%_host.o: %.c
|
||||
$(COMPILE_HOSTC)
|
||||
|
||||
%.o: %.rc
|
||||
$(WINDRES) $(IFLAGS) --preprocessor "$(DEPWINDRES) -E -xc-header -DRC_INVOKED $(CC_DEPFLAGS)" -o $@ $<
|
||||
|
||||
%.i: %.c
|
||||
$(CC) $(CCFLAGS) $(CC_E) $<
|
||||
|
||||
@@ -89,15 +82,14 @@ endif
|
||||
include $(SRC_PATH)/arch.mak
|
||||
|
||||
OBJS += $(OBJS-yes)
|
||||
SLIBOBJS += $(SLIBOBJS-yes)
|
||||
FFLIBS := $(FFLIBS-yes) $(FFLIBS)
|
||||
TESTPROGS += $(TESTPROGS-yes)
|
||||
|
||||
LDLIBS = $(FFLIBS:%=%$(BUILDSUF))
|
||||
FFEXTRALIBS := $(LDLIBS:%=$(LD_LIB)) $(EXTRALIBS)
|
||||
|
||||
EXAMPLES := $(EXAMPLES:%=$(SUBDIR)%-example$(EXESUF))
|
||||
OBJS := $(sort $(OBJS:%=$(SUBDIR)%))
|
||||
SLIBOBJS := $(sort $(SLIBOBJS:%=$(SUBDIR)%))
|
||||
TESTOBJS := $(TESTOBJS:%=$(SUBDIR)%) $(TESTPROGS:%=$(SUBDIR)%-test.o)
|
||||
TESTPROGS := $(TESTPROGS:%=$(SUBDIR)%-test$(EXESUF))
|
||||
HOSTOBJS := $(HOSTPROGS:%=$(SUBDIR)%.o)
|
||||
@@ -107,8 +99,7 @@ TOOLOBJS := $(TOOLS:%=tools/%.o)
|
||||
TOOLS := $(TOOLS:%=tools/%$(EXESUF))
|
||||
HEADERS += $(HEADERS-yes)
|
||||
|
||||
PATH_LIBNAME = $(foreach NAME,$(1),lib$(NAME)/$($(CONFIG_SHARED:yes=S)LIBNAME))
|
||||
DEP_LIBS := $(foreach lib,$(FFLIBS),$(call PATH_LIBNAME,$(lib)))
|
||||
DEP_LIBS := $(foreach NAME,$(FFLIBS),lib$(NAME)/$($(CONFIG_SHARED:yes=S)LIBNAME))
|
||||
|
||||
SRC_DIR := $(SRC_PATH)/lib$(NAME)
|
||||
ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)/$(ARCH)/*.h))
|
||||
@@ -121,19 +112,18 @@ checkheaders: $(HOBJS)
|
||||
alltools: $(TOOLS)
|
||||
|
||||
$(HOSTOBJS): %.o: %.c
|
||||
$(COMPILE_HOSTC)
|
||||
$(call COMPILE,HOSTCC)
|
||||
|
||||
$(HOSTPROGS): %$(HOSTEXESUF): %.o
|
||||
$(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTLIBS)
|
||||
$(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $< $(HOSTLIBS)
|
||||
|
||||
$(OBJS): | $(sort $(dir $(OBJS)))
|
||||
$(HOBJS): | $(sort $(dir $(HOBJS)))
|
||||
$(HOSTOBJS): | $(sort $(dir $(HOSTOBJS)))
|
||||
$(SLIBOBJS): | $(sort $(dir $(SLIBOBJS)))
|
||||
$(TESTOBJS): | $(sort $(dir $(TESTOBJS)))
|
||||
$(TOOLOBJS): | tools
|
||||
|
||||
OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(SLIBOBJS) $(TESTOBJS))
|
||||
OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(TESTOBJS))
|
||||
|
||||
CLEANSUFFIXES = *.d *.o *~ *.h.c *.map *.ver *.ho *.gcno *.gcda
|
||||
DISTCLEANSUFFIXES = *.pc
|
||||
@@ -148,4 +138,4 @@ endef
|
||||
|
||||
$(eval $(RULES))
|
||||
|
||||
-include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d) $(SLIBOBJS:.o=.d))
|
||||
-include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d))
|
||||
|
||||
@@ -1,26 +1,9 @@
|
||||
/*
|
||||
* Work around the class() function in AIX math.h clashing with
|
||||
* identifiers named "class".
|
||||
*
|
||||
* 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
|
||||
* Workaround aix-specific class() function clashing with ffmpeg class usage
|
||||
*/
|
||||
|
||||
#ifndef FFMPEG_COMPAT_AIX_MATH_H
|
||||
#define FFMPEG_COMPAT_AIX_MATH_H
|
||||
#ifndef COMPAT_AIX_MATH_H
|
||||
#define COMPAT_AIX_MATH_H
|
||||
|
||||
#define class class_in_math_h_causes_problems
|
||||
|
||||
@@ -28,4 +11,4 @@
|
||||
|
||||
#undef class
|
||||
|
||||
#endif /* FFMPEG_COMPAT_AIX_MATH_H */
|
||||
#endif /* COMPAT_AIX_MATH_H */
|
||||
|
||||
@@ -38,6 +38,8 @@ static int optind = 1;
|
||||
static int optopt;
|
||||
static char *optarg;
|
||||
|
||||
#undef fprintf
|
||||
|
||||
static int getopt(int argc, char *argv[], char *opts)
|
||||
{
|
||||
static int sp = 1;
|
||||
|
||||
@@ -32,8 +32,6 @@
|
||||
#undef __STRICT_ANSI__ /* for _beginthread() */
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
typedef TID pthread_t;
|
||||
typedef void pthread_attr_t;
|
||||
|
||||
|
||||
@@ -1,24 +1,3 @@
|
||||
/*
|
||||
* 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 FFMPEG_COMPAT_TMS470_MATH_H
|
||||
#define FFMPEG_COMPAT_TMS470_MATH_H
|
||||
|
||||
#include_next <math.h>
|
||||
|
||||
#undef INFINITY
|
||||
@@ -26,5 +5,3 @@
|
||||
|
||||
#define INFINITY (*(const float*)((const unsigned []){ 0x7f800000 }))
|
||||
#define NAN (*(const float*)((const unsigned []){ 0x7fc00000 }))
|
||||
|
||||
#endif /* FFMPEG_COMPAT_TMS470_MATH_H */
|
||||
|
||||
@@ -24,6 +24,3 @@
|
||||
#if !defined(va_copy) && defined(_MSC_VER)
|
||||
#define va_copy(dst, src) ((dst) = (src))
|
||||
#endif
|
||||
#if !defined(va_copy) && defined(__GNUC__) && __GNUC__ < 3
|
||||
#define va_copy(dst, src) __va_copy(dst, src)
|
||||
#endif
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
* w32threads to pthreads wrapper
|
||||
*/
|
||||
|
||||
#ifndef FFMPEG_COMPAT_W32PTHREADS_H
|
||||
#define FFMPEG_COMPAT_W32PTHREADS_H
|
||||
#ifndef LIBAV_W32PTHREADS_H
|
||||
#define LIBAV_W32PTHREADS_H
|
||||
|
||||
/* Build up a pthread-like API using underlying Windows API. Have only static
|
||||
* methods so as to not conflict with a potentially linked in pthread-win32
|
||||
@@ -62,18 +62,11 @@ typedef struct pthread_cond_t {
|
||||
} pthread_cond_t;
|
||||
|
||||
/* function pointers to conditional variable API on windows 6.0+ kernels */
|
||||
#if _WIN32_WINNT < 0x0600
|
||||
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);
|
||||
#else
|
||||
#define cond_init InitializeConditionVariable
|
||||
#define cond_broadcast WakeAllConditionVariable
|
||||
#define cond_signal WakeConditionVariable
|
||||
#define cond_wait SleepConditionVariableCS
|
||||
#endif
|
||||
|
||||
static unsigned __stdcall attribute_align_arg win32thread_worker(void *arg)
|
||||
{
|
||||
@@ -275,8 +268,13 @@ static void w32thread_init(void)
|
||||
(void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
|
||||
cond_wait =
|
||||
(void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
|
||||
#else
|
||||
cond_init = InitializeConditionVariable;
|
||||
cond_broadcast = WakeAllConditionVariable;
|
||||
cond_signal = WakeConditionVariable;
|
||||
cond_wait = SleepConditionVariableCS;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif /* FFMPEG_COMPAT_W32PTHREADS_H */
|
||||
#endif /* LIBAV_W32PTHREADS_H */
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2013, Derek Buitenhuis
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# mktemp isn't POSIX, so supply an implementation
|
||||
mktemp() {
|
||||
echo "${2%%XXX*}.${HOSTNAME}.${UID}.$$"
|
||||
}
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
echo "Usage: makedef <version_script> <objects>" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
vscript=$1
|
||||
shift
|
||||
|
||||
if [ ! -f "$vscript" ]; then
|
||||
echo "Version script does not exist" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for object in "$@"; do
|
||||
if [ ! -f "$object" ]; then
|
||||
echo "Object does not exist: ${object}" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Create a lib temporarily to dump symbols from.
|
||||
# It's just much easier to do it this way
|
||||
libname=$(mktemp -u "library").lib
|
||||
|
||||
trap 'rm -f -- $libname' EXIT
|
||||
|
||||
lib -out:${libname} $@ >/dev/null
|
||||
if [ $? != 0 ]; then
|
||||
echo "Could not create temporary library." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
IFS='
|
||||
'
|
||||
|
||||
# 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"
|
||||
|
||||
for line in $(cat ${vscript} | tr '\t' ' '); do
|
||||
# We only care about global symbols
|
||||
echo "${line}" | grep -q '^ \+global:'
|
||||
if [ $? = 0 ]; then
|
||||
started=1
|
||||
line=$(echo "${line}" | sed -e 's/^ \{1,\}global: *//')
|
||||
else
|
||||
echo "${line}" | grep -q '^ \+local:'
|
||||
if [ $? = 0 ]; then
|
||||
started=0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ${started} = 0 ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Handle multiple symbols on one line
|
||||
IFS=';'
|
||||
|
||||
# Work around stupid expansion to filenames
|
||||
line=$(echo "${line}" | sed -e 's/\*/.\\+/g')
|
||||
for exp in ${line}; do
|
||||
# Remove leading and trailing whitespace
|
||||
exp=$(echo "${exp}" | sed -e 's/^ *//' -e 's/ *$//')
|
||||
|
||||
if [ "${regex}" = "none" ]; then
|
||||
regex="${exp}"
|
||||
else
|
||||
regex="${regex};${exp}"
|
||||
fi
|
||||
done
|
||||
|
||||
IFS='
|
||||
'
|
||||
done
|
||||
|
||||
dump=$(dumpbin -linkermember:1 ${libname})
|
||||
|
||||
rm ${libname}
|
||||
|
||||
IFS=';'
|
||||
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
|
||||
|
||||
echo "EXPORTS"
|
||||
echo "${list}" | sort | uniq | tail -n +2
|
||||
308
doc/APIchanges
308
doc/APIchanges
@@ -4,7 +4,7 @@ since the last major version increase or the API was added.
|
||||
The last version increases were:
|
||||
libavcodec: 2013-03-xx
|
||||
libavdevice: 2013-03-xx
|
||||
libavfilter: 2013-12-xx
|
||||
libavfilter: 2012-06-22
|
||||
libavformat: 2013-03-xx
|
||||
libavresample: 2012-10-05
|
||||
libpostproc: 2011-04-18
|
||||
@@ -15,226 +15,24 @@ libavutil: 2012-10-22
|
||||
|
||||
API changes, most recent first:
|
||||
|
||||
2014-03-18 - e9c8a9a - lsws 2.5.102
|
||||
Make gray16 full-scale.
|
||||
|
||||
2014-xx-xx - xxxxxxx - lavu 53.05.0 - frame.h
|
||||
Add av_frame_copy() for copying the frame data.
|
||||
|
||||
2014-02-xx - xxxxxxx - lswr 0.18.100 - swresample.h
|
||||
Add swr_is_initialized() for checking whether a resample context is initialized.
|
||||
|
||||
2014-02-xx - xxxxxxx - lavr 1.2.0 - avresample.h
|
||||
Add avresample_is_open() for checking whether a resample context is open.
|
||||
|
||||
2014-xx-xx - xxxxxxx - lavu 53.04.0 - opt.h
|
||||
Add AV_OPT_FLAG_EXPORT and AV_OPT_FLAG_READONLY to mark options meant (only)
|
||||
for reading.
|
||||
|
||||
2014-xx-xx - xxxxxxx - lavu 53.03.01 - opt.h
|
||||
Deprecate unused AV_OPT_FLAG_METADATA.
|
||||
|
||||
2014-02-xx - xxxxxxx - lavd 55.10.100 - avdevice.h
|
||||
Add avdevice_list_devices() and avdevice_free_list_devices()
|
||||
|
||||
2014-02-16 - db3c970 - lavf 55.33.100 - avio.h
|
||||
Add avio_find_protocol_name() to find out the name of the protocol that would
|
||||
be selected for a given URL.
|
||||
|
||||
2014-02-xx - xxxxxxx - lavu 53.3.0 - frame.h
|
||||
Add AV_FRAME_DATA_DOWNMIX_INFO value to the AVFrameSideDataType enum and
|
||||
downmix_info.h API, which identify downmix-related metadata.
|
||||
|
||||
2014-02-11 - 1b05ac2 - lavf 55.32.100 - avformat.h
|
||||
Add av_write_uncoded_frame() and av_interleaved_write_uncoded_frame().
|
||||
|
||||
2014-02-04 - 3adb5f8 / d9ae103 - lavf 55.30.100 / 55.11.0 - avformat.h
|
||||
Add AVFormatContext.max_interleave_delta for controlling amount of buffering
|
||||
when interleaving.
|
||||
|
||||
2014-02-02 - xxxxxxx - lavf 55.29.100 - avformat.h
|
||||
Add output_ts_offset muxing option to AVFormatContext.
|
||||
|
||||
2014-01-27 - 102bd64 - lavd 55.7.100 - avdevice.h
|
||||
lavf 55.28.100 - avformat.h
|
||||
Add avdevice_dev_to_app_control_message() function.
|
||||
|
||||
2014-01-27 - 7151411 - lavd 55.6.100 - avdevice.h
|
||||
lavf 55.27.100 - avformat.h
|
||||
Add avdevice_app_to_dev_control_message() function.
|
||||
|
||||
2014-01-24 - 86bee79 - lavf 55.26.100 - avformat.h
|
||||
Add AVFormatContext option metadata_header_padding to allow control over the
|
||||
amount of padding added.
|
||||
|
||||
2014-01-20 - eef74b2 / 93c553c - lavc 55.48.102 / 55.32.1 - avcodec.h
|
||||
Edges are not required anymore on video buffers allocated by get_buffer2()
|
||||
(i.e. as if the CODEC_FLAG_EMU_EDGE flag was always on). Deprecate
|
||||
CODEC_FLAG_EMU_EDGE and avcodec_get_edge_width().
|
||||
|
||||
2014-01-19 - xxxxxxx - lavf 55.25.100 - avformat.h
|
||||
Add avformat_get_mov_video_tags() and avformat_get_mov_audio_tags().
|
||||
|
||||
2014-01-19 - xxxxxxx - lavu 52.63.100 - rational.h
|
||||
Add av_make_q() function.
|
||||
|
||||
2014-01-05 - 4cf4da9 / 5b4797a - lavu 52.62.100 / 53.2.0 - frame.h
|
||||
Add AV_FRAME_DATA_MATRIXENCODING value to the AVFrameSideDataType enum, which
|
||||
identifies AVMatrixEncoding data.
|
||||
|
||||
2014-01-05 - 751385f / 5c437fb - lavu 52.61.100 / 53.1.0 - channel_layout.h
|
||||
Add values for various Dolby flags to the AVMatrixEncoding enum.
|
||||
|
||||
2014-01-04 - xxxxxxx - lavu 52.60.100 - mathematics.h
|
||||
Add av_add_stable() function.
|
||||
|
||||
2013-12-22 - xxxxxxx - lavu 52.59.100 - avstring.h
|
||||
Add av_strnlen() function.
|
||||
|
||||
2013-12-xx - xxxxxxx - lavu 52.57.100 - opencl.h
|
||||
Add av_opencl_benchmark() function.
|
||||
|
||||
2013-11-xx - xxxxxxx - lavu 52.56.100 - ffversion.h
|
||||
Moves version.h to libavutil/ffversion.h.
|
||||
Install ffversion.h and make it public.
|
||||
|
||||
2013-12-11 - 29c83d2 / b9fb59d,409a143 / 9431356,44967ab / d7b3ee9 - lavc 55.45.101 / 55.28.1 - avcodec.h
|
||||
av_frame_alloc(), av_frame_unref() and av_frame_free() now can and should be
|
||||
used instead of avcodec_alloc_frame(), avcodec_get_frame_defaults() and
|
||||
avcodec_free_frame() respectively. The latter three functions are deprecated.
|
||||
|
||||
2013-12-09 - 7a60348 / 7e244c6- - lavu 52.58.100 / 52.20.0 - frame.h
|
||||
Add AV_FRAME_DATA_STEREO3D value to the AVFrameSideDataType enum and
|
||||
stereo3d.h API, that identify codec-independent stereo3d information.
|
||||
|
||||
2013-11-26 - 625b290 / 1eaac1d- - lavu 52.55.100 / 52.19.0 - frame.h
|
||||
Add AV_FRAME_DATA_A53_CC value to the AVFrameSideDataType enum, which
|
||||
identifies ATSC A53 Part 4 Closed Captions data.
|
||||
|
||||
2013-11-XX - xxxxxxx - lavu 52.54.100 - avstring.h
|
||||
Add av_utf8_decode() function.
|
||||
|
||||
2013-11-22 - fb7d70c - lavc 55.44.100 - avcodec.h
|
||||
Add HEVC profiles
|
||||
|
||||
2013-11-xx - xxxxxxx - lavc 55.44.100 - avcodec.h
|
||||
Add av_packet_{un,}pack_dictionary()
|
||||
Add AV_PKT_METADATA_UPDATE side data type, used to transmit key/value
|
||||
strings between a stream and the application.
|
||||
|
||||
2013-11-14 - 7c888ae / cce3e0a - lavu 52.53.100 / 52.18.0 - mem.h
|
||||
Move av_fast_malloc() and av_fast_realloc() for libavcodec to libavutil.
|
||||
|
||||
2013-11-14 - b71e4d8 / 8941971 - lavc 55.43.100 / 55.27.0 - avcodec.h
|
||||
Deprecate AVCodecContext.error_rate, it is replaced by the 'error_rate'
|
||||
private option of the mpegvideo encoder family.
|
||||
|
||||
2013-11-14 - 31c09b7 / 728c465 - lavc 55.26.0 - vdpau.h
|
||||
Add av_vdpau_get_profile().
|
||||
Add av_vdpau_alloc_context(). This function must from now on be
|
||||
used for allocating AVVDPAUContext.
|
||||
|
||||
2013-11-04 - be41f21 / cd8f772 - lavc 55.41.100 / 55.25.0 - avcodec.h
|
||||
lavu 52.51.100 - frame.h
|
||||
Add ITU-R BT.2020 and other not yet included values to color primaries,
|
||||
transfer characteristics and colorspaces.
|
||||
|
||||
2013-11-04 - xxxxxxx - lavu 52.50.100 - avutil.h
|
||||
Add av_fopen_utf8()
|
||||
|
||||
2013-10-31 - 78265fc / 28096e0 - lavu 52.49.100 / 52.17.0 - frame.h
|
||||
Add AVFrame.flags and AV_FRAME_FLAG_CORRUPT.
|
||||
|
||||
2013-10-27 - xxxxxxx - lavc 55.39.100 - avcodec.h
|
||||
Add CODEC_CAP_DELAY support to avcodec_decode_subtitle2.
|
||||
|
||||
2013-10-27 - xxxxxxx - lavu 52.48.100 - parseutils.h
|
||||
Add av_get_known_color_name().
|
||||
|
||||
2013-10-17 - xxxxxxx - lavu 52.47.100 - opt.h
|
||||
Add AV_OPT_TYPE_CHANNEL_LAYOUT and channel layout option handlers
|
||||
av_opt_get_channel_layout() and av_opt_set_channel_layout().
|
||||
|
||||
2013-10-xx - xxxxxxx -libswscale 2.5.101 - options.c
|
||||
Change default scaler to bicubic
|
||||
|
||||
2013-10-03 - xxxxxxx - lavc 55.34.100 - avcodec.h
|
||||
Add av_codec_get_max_lowres()
|
||||
|
||||
2013-10-02 - xxxxxxx - lavf 55.19.100 - avformat.h
|
||||
Add audio/video/subtitle AVCodec fields to AVFormatContext to force specific
|
||||
decoders
|
||||
|
||||
2013-09-28 - 7381d31 / 0767bfd - lavfi 3.88.100 / 3.11.0 - avfilter.h
|
||||
Add AVFilterGraph.execute and AVFilterGraph.opaque for custom slice threading
|
||||
implementations.
|
||||
|
||||
2013-09-21 - 85f8a3c / e208e6d - lavu 52.46.100 / 52.16.0 - pixfmt.h
|
||||
Add interleaved 4:2:2 8/10-bit formats AV_PIX_FMT_NV16 and
|
||||
AV_PIX_FMT_NV20.
|
||||
|
||||
2013-09-16 - c74c3fb / 3feb3d6 - lavu 52.44.100 / 52.15.0 - mem.h
|
||||
Add av_reallocp.
|
||||
|
||||
2013-09-04 - 3e1f507 - lavc 55.31.101 - avcodec.h
|
||||
avcodec_close() argument can be NULL.
|
||||
|
||||
2013-09-04 - 36cd017 - lavf 55.16.101 - avformat.h
|
||||
avformat_close_input() argument can be NULL and point on NULL.
|
||||
|
||||
2013-08-29 - e31db62 - lavf 55.15.100 - avformat.h
|
||||
Add av_format_get_probe_score().
|
||||
|
||||
2013-08-15 - 1e0e193 - lsws 2.5.100 -
|
||||
Add a sws_dither AVOption, allowing to set the dither algorithm used
|
||||
|
||||
2013-08-xx - xxxxxxx - lavc 55.27.100 - vdpau.h
|
||||
Add a render2 alternative to the render callback function.
|
||||
|
||||
2013-08-xx - xxxxxxx - lavc 55.26.100 - vdpau.h
|
||||
Add allocation function for AVVDPAUContext, allowing
|
||||
to extend it in the future without breaking ABI/API.
|
||||
|
||||
2013-08-10 - 67a580f / 5a9a9d4 - lavc 55.25.100 / 55.16.0 - avcodec.h
|
||||
Extend AVPacket API with av_packet_unref, av_packet_ref,
|
||||
av_packet_move_ref, av_packet_copy_props, av_packet_free_side_data.
|
||||
|
||||
2013-08-05 - 9547e3e / f824535 - lavc 55.22.100 / 55.13.0 - avcodec.h
|
||||
Deprecate the bitstream-related members from struct AVVDPAUContext.
|
||||
The bistream buffers no longer need to be explicitly freed.
|
||||
|
||||
2013-08-05 - 3b805dc / 549294f - lavc 55.21.100 / 55.12.0 - avcodec.h
|
||||
Deprecate the CODEC_CAP_HWACCEL_VDPAU codec capability. Use CODEC_CAP_HWACCEL
|
||||
and select the AV_PIX_FMT_VDPAU format with get_format() instead.
|
||||
|
||||
2013-08-05 - 4ee0984 / a0ad5d0 - lavu 52.41.100 / 52.14.0 - pixfmt.h
|
||||
Deprecate AV_PIX_FMT_VDPAU_*. Use AV_PIX_FMT_VDPAU instead.
|
||||
|
||||
2013-08-02 - 82fdfe8 / a8b1927 - lavc 55.20.100 / 55.11.0 - avcodec.h
|
||||
Add output_picture_number to AVCodecParserContext.
|
||||
|
||||
2013-07-23 - abc8110 - lavc 55.19.100 - avcodec.h
|
||||
Add avcodec_chroma_pos_to_enum()
|
||||
Add avcodec_enum_to_chroma_pos()
|
||||
|
||||
2013-07-03 - 838bd73 - lavfi 3.78.100 - avfilter.h
|
||||
2013-07-03 - xxxxxxx - lavfi 3.78.100 - avfilter.h
|
||||
Deprecate avfilter_graph_parse() in favor of the equivalent
|
||||
avfilter_graph_parse_ptr().
|
||||
|
||||
2013-06-24 - af5f9c0 / 95d5246 - lavc 55.17.100 / 55.10.0 - avcodec.h
|
||||
2013-06-xx - xxxxxxx - lavc 55.10.0 - avcodec.h
|
||||
Add MPEG-2 AAC profiles
|
||||
|
||||
2013-06-25 - af5f9c0 / 95d5246 - lavf 55.10.100 - avformat.h
|
||||
2013-06-xx - xxxxxxx - lavf 55.10.100 - avformat.h
|
||||
Add AV_DISPOSITION_* flags to indicate text track kind.
|
||||
|
||||
2013-06-15 - 99b8cd0 - lavu 52.36.100
|
||||
2013-06-xx - xxxxxxx - lavu 52.36.100
|
||||
Add AVRIPEMD:
|
||||
av_ripemd_alloc()
|
||||
av_ripemd_init()
|
||||
av_ripemd_update()
|
||||
av_ripemd_final()
|
||||
|
||||
2013-06-04 - 30b491f / fc962d4 - lavu 52.35.100 / 52.13.0 - mem.h
|
||||
2013-06-05 - fc962d4 - lavu 52.13.0 - mem.h
|
||||
Add av_realloc_array and av_reallocp_array
|
||||
|
||||
2013-05-30 - 682b227 - lavu 52.35.100
|
||||
@@ -244,55 +42,55 @@ API changes, most recent first:
|
||||
av_sha512_update()
|
||||
av_sha512_final()
|
||||
|
||||
2013-05-24 - 8d4e969 / 129bb23 - lavfi 3.10.0 / 3.70.100 - avfilter.h
|
||||
2013-05-24 - xxxxxxx - lavfi 3.70.100 - avfilter.h
|
||||
Add support for slice multithreading to lavfi. Filters supporting threading
|
||||
are marked with AVFILTER_FLAG_SLICE_THREADS.
|
||||
New fields AVFilterContext.thread_type, AVFilterGraph.thread_type and
|
||||
AVFilterGraph.nb_threads (accessible directly or through AVOptions) may be
|
||||
used to configure multithreading.
|
||||
|
||||
2013-05-24 - fe40a9f / 2a6eaea - lavu 52.12.0 / 52.34.100 - cpu.h
|
||||
2013-05-24 - xxxxxxx - lavu 52.34.100 - cpu.h
|
||||
Add av_cpu_count() function for getting the number of logical CPUs.
|
||||
|
||||
2013-05-24 - 0c25c39 / b493847 - lavc 55.7.0 / 55.12.100 - avcodec.h
|
||||
2013-05-24 - xxxxxxx - lavc 55.12.100 - avcodec.h
|
||||
Add picture_structure to AVCodecParserContext.
|
||||
|
||||
2013-05-17 - 3a751ea - lavu 52.33.100 - opt.h
|
||||
2013-05-17 - xxxxxxx - lavu 52.33.100 - opt.h
|
||||
Add AV_OPT_TYPE_COLOR value to AVOptionType enum.
|
||||
|
||||
2013-05-13 - e398416 - lavu 52.31.100 - mem.h
|
||||
2013-05-13 - xxxxxxx - lavu 52.31.100 - mem.h
|
||||
Add av_dynarray2_add().
|
||||
|
||||
2013-05-12 - 1776177 - lavfi 3.65.100
|
||||
2013-05-12 - xxxxxxx - lavfi 3.65.100
|
||||
Add AVFILTER_FLAG_SUPPORT_TIMELINE* filter flags.
|
||||
|
||||
2013-04-19 - 380cfce - lavc 55.4.100
|
||||
2013-04-19 - xxxxxxx - lavc 55.4.100
|
||||
Add AV_CODEC_PROP_TEXT_SUB property for text based subtitles codec.
|
||||
|
||||
2013-04-18 - 7c1a002 - lavf 55.3.100
|
||||
2013-04-18 - xxxxxxx - lavf 55.3.100
|
||||
The matroska demuxer can now output proper verbatim ASS packets. It will
|
||||
become the default starting lavf 56.0.100.
|
||||
|
||||
2013-04-10 - af0d270 - lavu 25.26.100 - avutil.h,opt.h
|
||||
2013-04-10 - xxxxxxx - lavu 25.26.100 - avutil.h,opt.h
|
||||
Add av_int_list_length()
|
||||
and av_opt_set_int_list().
|
||||
|
||||
2013-03-30 - 5c73645 - lavu 52.24.100 - samplefmt.h
|
||||
2013-03-30 - xxxxxxx - lavu 52.24.100 - samplefmt.h
|
||||
Add av_samples_alloc_array_and_samples().
|
||||
|
||||
2013-03-29 - ef7b6b4 - lavf 55.1.100 - avformat.h
|
||||
2013-03-29 - xxxxxxx - lavf 55.1.100 - avformat.h
|
||||
Add av_guess_frame_rate()
|
||||
|
||||
2013-03-20 - 8d928a9 - lavu 52.22.100 - opt.h
|
||||
2013-03-20 - xxxxxxx - lavu 52.22.100 - opt.h
|
||||
Add AV_OPT_TYPE_DURATION value to AVOptionType enum.
|
||||
|
||||
2013-03-17 - 7aa9af5 - lavu 52.20.100 - opt.h
|
||||
2013-03-17 - xxxxxx - lavu 52.20.100 - opt.h
|
||||
Add AV_OPT_TYPE_VIDEO_RATE value to AVOptionType enum.
|
||||
|
||||
2013-03-07 - 9767ec6 - lavu 52.18.100 - avstring.h,bprint.h
|
||||
2013-03-07 - xxxxxx - lavu 52.18.100 - avstring.h,bprint.h
|
||||
Add av_escape() and av_bprint_escape() API.
|
||||
|
||||
2013-02-24 - b59cd08 - lavfi 3.41.100 - buffersink.h
|
||||
2013-02-24 - xxxxxx - lavfi 3.41.100 - buffersink.h
|
||||
Add sample_rates field to AVABufferSinkParams.
|
||||
|
||||
2013-01-17 - a1a707f - lavf 54.61.100
|
||||
@@ -305,7 +103,7 @@ API changes, most recent first:
|
||||
Add AVFilterLink.channels, avfilter_link_get_channels()
|
||||
and avfilter_ref_get_channels().
|
||||
|
||||
2012-12-15 - 96d815fc - lavc 54.80.100 - avcodec.h
|
||||
2012-12-15 - 2ada584d - lavc 54.80.100 - avcodec.h
|
||||
Add pkt_size field to AVFrame.
|
||||
|
||||
2012-11-25 - c70ec631 - lavu 52.9.100 - opt.h
|
||||
@@ -418,52 +216,52 @@ API changes, most recent first:
|
||||
2012-03-26 - a67d9cf - lavfi 2.66.100
|
||||
Add avfilter_fill_frame_from_{audio_,}buffer_ref() functions.
|
||||
|
||||
2013-05-15 - ff46809 / e6c4ac7 - lavu 52.32.100 / 52.11.0 - pixdesc.h
|
||||
2013-05-xx - xxxxxxx - lavu 52.11.0 - pixdesc.h
|
||||
Replace PIX_FMT_* flags with AV_PIX_FMT_FLAG_*.
|
||||
|
||||
2013-04-03 - 6fc58a8 / 507b1e4 - lavc 55.7.100 / 55.4.0 - avcodec.h
|
||||
2013-04-xx - xxxxxxx - lavc 55.4.0 - avcodec.h
|
||||
Add field_order to AVCodecParserContext.
|
||||
|
||||
2013-04-19 - f4b05cd / 5e83d9a - lavc 55.5.100 / 55.2.0 - avcodec.h
|
||||
2013-03-xx - xxxxxxx - lavc 55.2.0 - avcodec.h
|
||||
Add CODEC_FLAG_UNALIGNED to allow decoders to produce unaligned output.
|
||||
|
||||
2013-04-11 - lavfi 3.53.100 / 3.8.0
|
||||
231fd44 / 38f0c07 - Move all content from avfiltergraph.h to avfilter.h. Deprecate
|
||||
2013-04-11 - lavfi 3.8.0
|
||||
38f0c07 - Move all content from avfiltergraph.h to avfilter.h. Deprecate
|
||||
avfilterhraph.h, user applications should include just avfilter.h
|
||||
86070b8 / bc1a985 - Add avfilter_graph_alloc_filter(), deprecate avfilter_open() and
|
||||
bc1a985 - Add avfilter_graph_alloc_filter(), deprecate avfilter_open() and
|
||||
avfilter_graph_add_filter().
|
||||
4fde705 / 1113672 - Add AVFilterContext.graph pointing to the AVFilterGraph that contains the
|
||||
1113672 - Add AVFilterContext.graph pointing to the AVFilterGraph that contains the
|
||||
filter.
|
||||
710b0aa / 48a5ada - Add avfilter_init_str(), deprecate avfilter_init_filter().
|
||||
46de9ba / 1ba95a9 - Add avfilter_init_dict().
|
||||
16fc24b / 7cdd737 - Add AVFilter.flags field and AVFILTER_FLAG_DYNAMIC_{INPUTS,OUTPUTS} flags.
|
||||
f4db6bf / 7e8fe4b - Add avfilter_pad_count() for counting filter inputs/outputs.
|
||||
835cc0f / fa2a34c - Add avfilter_next(), deprecate av_filter_next().
|
||||
48a5ada - Add avfilter_init_str(), deprecate avfilter_init_filter().
|
||||
1ba95a9 - Add avfilter_init_dict().
|
||||
7cdd737 - Add AVFilter.flags field and AVFILTER_FLAG_DYNAMIC_{INPUTS,OUTPUTS} flags.
|
||||
7e8fe4b - Add avfilter_pad_count() for counting filter inputs/outputs.
|
||||
fa2a34c - Add avfilter_next(), deprecate av_filter_next().
|
||||
Deprecate avfilter_uninit().
|
||||
|
||||
2013-04-09 - lavfi 3.51.100 / 3.7.0 - avfilter.h
|
||||
0594ef0 / b439c99 - Add AVFilter.priv_class for exporting filter options through the
|
||||
2013-04-09 - lavfi 3.7.0 - avfilter.h
|
||||
b439c99 - Add AVFilter.priv_class for exporting filter options through the
|
||||
AVOptions API in the similar way private options work in lavc and lavf.
|
||||
44d4488 / 8114c10 - Add avfilter_get_class().
|
||||
8114c10 - Add avfilter_get_class().
|
||||
Switch all filters to use AVOptions.
|
||||
|
||||
2013-03-19 - 17ebef2 / 2c328a9 - lavu 52.20.100 / 52.9.0 - pixdesc.h
|
||||
2013-03-19 - 2c328a9 - lavu 52.9.0 - pixdesc.h
|
||||
Add av_pix_fmt_count_planes() function for counting planes in a pixel format.
|
||||
|
||||
2013-03-16 - ecade98 / 42c7c61 - lavfi 3.47.100 / 3.6.0
|
||||
2013-03-16 - 42c7c61 - lavfi 3.6.0
|
||||
Add AVFilterGraph.nb_filters, deprecate AVFilterGraph.filter_count.
|
||||
|
||||
2013-03-08 - Reference counted buffers - lavu 52.8.0, lavc 55.0.100 / 55.0.0, lavf 55.0.100 / 55.0.0,
|
||||
lavd 54.4.100 / 54.0.0, lavfi 3.5.0
|
||||
36099df / 8e401db, 532f31a / 1cec062 - add a new API for reference counted buffers and buffer
|
||||
2013-03-08 - Reference counted buffers - lavu 52.8.0, lavc 55.0.0, lavf 55.0.0,
|
||||
lavd 54.0.0, lavfi 3.5.0
|
||||
8e401db, 1cec062 - add a new API for reference counted buffers and buffer
|
||||
pools (new header libavutil/buffer.h).
|
||||
2653e12 / 1afddbe - add AVPacket.buf to allow reference counting for the AVPacket data.
|
||||
1afddbe - add AVPacket.buf to allow reference counting for the AVPacket data.
|
||||
Add av_packet_from_data() function for constructing packets from
|
||||
av_malloc()ed data.
|
||||
c4e8821 / 7ecc2d4 - move AVFrame from lavc to lavu (new header libavutil/frame.h), add
|
||||
7ecc2d4 - move AVFrame from lavc to lavu (new header libavutil/frame.h), add
|
||||
AVFrame.buf/extended_buf to allow reference counting for the AVFrame
|
||||
data. Add new API for working with reference-counted AVFrames.
|
||||
80e9e63 / 759001c - add the refcounted_frames field to AVCodecContext to make audio and
|
||||
759001c - add the refcounted_frames field to AVCodecContext to make audio and
|
||||
video decoders return reference-counted frames. Add get_buffer2()
|
||||
callback to AVCodecContext which allocates reference-counted frames.
|
||||
Add avcodec_default_get_buffer2() as the default get_buffer2()
|
||||
@@ -481,30 +279,30 @@ lavd 54.4.100 / 54.0.0, lavfi 3.5.0
|
||||
* qscale_table, qstride, qscale_type, mbskip_table, motion_val,
|
||||
mb_type, dct_coeff, ref_index -- mpegvideo-specific tables,
|
||||
which are not exported anymore.
|
||||
a05a44e / 7e35037 - switch libavfilter to use AVFrame instead of AVFilterBufferRef. Add
|
||||
7e35037 - switch libavfilter to use AVFrame instead of AVFilterBufferRef. Add
|
||||
av_buffersrc_add_frame(), deprecate av_buffersrc_buffer().
|
||||
Add av_buffersink_get_frame() and av_buffersink_get_samples(),
|
||||
deprecate av_buffersink_read() and av_buffersink_read_samples().
|
||||
Deprecate AVFilterBufferRef and all functions for working with it.
|
||||
|
||||
2013-03-17 - 6c17ff8 / 12c5c1d - lavu 52.19.100 / 52.8.0 - avstring.h
|
||||
2013-03-17 - 12c5c1d - lavu 52.8.0 - avstring.h
|
||||
Add av_isdigit, av_isgraph, av_isspace, av_isxdigit.
|
||||
|
||||
2013-02-23 - 71cf094 / 9f12235 - lavfi 3.40.100 / 3.4.0 - avfiltergraph.h
|
||||
2013-02-23 - 9f12235 - lavfi 3.4.0 - avfiltergraph.h
|
||||
Add resample_lavr_opts to AVFilterGraph for setting libavresample options
|
||||
for auto-inserted resample filters.
|
||||
|
||||
2013-01-25 - e7e14bc / 38c1466 - lavu 52.17.100 / 52.7.0 - dict.h
|
||||
2013-01-25 - 38c1466 - lavu 52.7.0 - dict.h
|
||||
Add av_dict_parse_string() to set multiple key/value pairs at once from a
|
||||
string.
|
||||
|
||||
2013-01-25 - 25be630 / b85a5e8 - lavu 52.16.100 / 52.6.0 - avstring.h
|
||||
2013-01-25 - b85a5e8 - lavu 52.6.0 - avstring.h
|
||||
Add av_strnstr()
|
||||
|
||||
2013-01-15 - e7e0186 / 8ee288d - lavu 52.15.100 / 52.5.0 - hmac.h
|
||||
2013-01-15 - 8ee288d - lavu 52.5.0 - hmac.h
|
||||
Add AVHMAC.
|
||||
|
||||
2013-01-13 - 8ee7b38 / 44e065d - lavc 54.87.100 / 54.36.0 - vdpau.h
|
||||
2013-01-13 - 44e065d - lavc 54.87.100 / 54.36.0 - vdpau.h
|
||||
Add AVVDPAUContext struct for VDPAU hardware-accelerated decoding.
|
||||
|
||||
2013-01-12 - dae382b / 169fb94 - lavu 52.14.100 / 52.4.0 - pixdesc.h
|
||||
@@ -592,7 +390,7 @@ lavd 54.4.100 / 54.0.0, lavfi 3.5.0
|
||||
2012-07-29 - 7c26761 / 681ed00 - lavf 54.22.100 / 54.13.0 - avformat.h
|
||||
Add AVFMT_FLAG_NOBUFFER for low latency use cases.
|
||||
|
||||
2012-07-10 - fbe0245 / f3e5e6f - lavu 51.65.100 / 51.37.0
|
||||
2012-07-10 - 5fade8a - lavu 51.37.0
|
||||
Add av_malloc_array() and av_mallocz_array()
|
||||
|
||||
2012-06-22 - e847f41 / d3d3a32 - lavu 51.61.100 / 51.34.0
|
||||
|
||||
10
doc/Doxyfile
10
doc/Doxyfile
@@ -31,9 +31,9 @@ PROJECT_NAME = FFmpeg
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 2.2.2
|
||||
PROJECT_NUMBER = 2.0.7
|
||||
|
||||
# With the PROJECT_LOGO tag one can specify a logo or icon that is included
|
||||
# With the PROJECT_LOGO tag one can specify an logo or icon that is included
|
||||
# in the documentation. The maximum height of the logo should not exceed 55
|
||||
# pixels and the maximum width should not exceed 200 pixels. Doxygen will
|
||||
# copy the logo to the output directory.
|
||||
@@ -793,13 +793,13 @@ HTML_FILE_EXTENSION = .html
|
||||
# each generated HTML page. If it is left blank doxygen will generate a
|
||||
# standard header.
|
||||
|
||||
HTML_HEADER =
|
||||
#HTML_HEADER = doc/doxy/header.html
|
||||
|
||||
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
|
||||
# each generated HTML page. If it is left blank doxygen will generate a
|
||||
# standard footer.
|
||||
|
||||
HTML_FOOTER =
|
||||
#HTML_FOOTER = doc/doxy/footer.html
|
||||
|
||||
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
|
||||
# style sheet that is used by each HTML page. It can be used to
|
||||
@@ -808,7 +808,7 @@ HTML_FOOTER =
|
||||
# the style sheet file to the HTML output directory, so don't put your own
|
||||
# stylesheet in the HTML output directory as well, or it will be erased!
|
||||
|
||||
HTML_STYLESHEET =
|
||||
#HTML_STYLESHEET = doc/doxy/doxy_stylesheet.css
|
||||
|
||||
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
|
||||
# Doxygen will adjust the colors in the stylesheet and background images
|
||||
|
||||
67
doc/Makefile
67
doc/Makefile
@@ -14,11 +14,11 @@ COMPONENTS-$(CONFIG_AVFORMAT) += ffmpeg-formats ffmpeg-protocols
|
||||
COMPONENTS-$(CONFIG_AVDEVICE) += ffmpeg-devices
|
||||
COMPONENTS-$(CONFIG_AVFILTER) += ffmpeg-filters
|
||||
|
||||
MANPAGES1 = $(AVPROGS-yes:%=doc/%.1) $(AVPROGS-yes:%=doc/%-all.1) $(COMPONENTS-yes:%=doc/%.1)
|
||||
MANPAGES1 = $(PROGS-yes:%=doc/%.1) $(PROGS-yes:%=doc/%-all.1) $(COMPONENTS-yes:%=doc/%.1)
|
||||
MANPAGES3 = $(LIBRARIES-yes:%=doc/%.3)
|
||||
MANPAGES = $(MANPAGES1) $(MANPAGES3)
|
||||
PODPAGES = $(AVPROGS-yes:%=doc/%.pod) $(AVPROGS-yes:%=doc/%-all.pod) $(COMPONENTS-yes:%=doc/%.pod) $(LIBRARIES-yes:%=doc/%.pod)
|
||||
HTMLPAGES = $(AVPROGS-yes:%=doc/%.html) $(AVPROGS-yes:%=doc/%-all.html) $(COMPONENTS-yes:%=doc/%.html) $(LIBRARIES-yes:%=doc/%.html) \
|
||||
PODPAGES = $(PROGS-yes:%=doc/%.pod) $(PROGS-yes:%=doc/%-all.pod) $(COMPONENTS-yes:%=doc/%.pod) $(LIBRARIES-yes:%=doc/%.pod)
|
||||
HTMLPAGES = $(PROGS-yes:%=doc/%.html) $(PROGS-yes:%=doc/%-all.html) $(COMPONENTS-yes:%=doc/%.html) $(LIBRARIES-yes:%=doc/%.html) \
|
||||
doc/developer.html \
|
||||
doc/faq.html \
|
||||
doc/fate.html \
|
||||
@@ -36,25 +36,6 @@ DOCS-$(CONFIG_MANPAGES) += $(MANPAGES)
|
||||
DOCS-$(CONFIG_TXTPAGES) += $(TXTPAGES)
|
||||
DOCS = $(DOCS-yes)
|
||||
|
||||
DOC_EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading
|
||||
DOC_EXAMPLES-$(CONFIG_AVCODEC_EXAMPLE) += avcodec
|
||||
DOC_EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
|
||||
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_METADATA_EXAMPLE) += metadata
|
||||
DOC_EXAMPLES-$(CONFIG_MUXING_EXAMPLE) += muxing
|
||||
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
|
||||
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
|
||||
@@ -62,9 +43,7 @@ doc: documentation
|
||||
apidoc: doc/doxy/html
|
||||
documentation: $(DOCS)
|
||||
|
||||
examples: $(DOC_EXAMPLES)
|
||||
|
||||
TEXIDEP = perl $(SRC_PATH)/doc/texidep.pl $(SRC_PATH) $< $@ >$(@:%=%.d)
|
||||
TEXIDEP = awk '/^@(verbatim)?include/ { printf "$@: $(@D)/%s\n", $$2 }' <$< >$(@:%=%.d)
|
||||
|
||||
doc/%.txt: TAG = TXT
|
||||
doc/%.txt: doc/%.texi
|
||||
@@ -105,28 +84,12 @@ doc/%.3: doc/%.pod $(GENTEXI)
|
||||
$(M)pod2man --section=3 --center=" " --release=" " $< > $@
|
||||
|
||||
$(DOCS) doc/doxy/html: | doc/
|
||||
$(DOC_EXAMPLES:%$(EXESUF)=%.o): | doc/examples
|
||||
OBJDIRS += doc/examples
|
||||
|
||||
DOXY_INPUT = $(addprefix $(SRC_PATH)/, $(INSTHEADERS) $(DOC_EXAMPLES:%$(EXESUF)=%.c) $(LIB_EXAMPLES:%$(EXESUF)=%.c))
|
||||
|
||||
doc/doxy/html: $(SRC_PATH)/doc/Doxyfile $(DOXY_INPUT)
|
||||
$(M)$(SRC_PATH)/doc/doxy-wrapper.sh $(SRC_PATH) $< $(DOXY_INPUT)
|
||||
|
||||
install-doc: install-html install-man
|
||||
|
||||
install-html:
|
||||
doc/doxy/html: $(SRC_PATH)/doc/Doxyfile $(INSTHEADERS)
|
||||
$(M)$(SRC_PATH)/doc/doxy-wrapper.sh $(SRC_PATH) $^
|
||||
|
||||
install-man:
|
||||
|
||||
ifdef CONFIG_HTMLPAGES
|
||||
install-progs-$(CONFIG_DOC): install-html
|
||||
|
||||
install-html: $(HTMLPAGES)
|
||||
$(Q)mkdir -p "$(DOCDIR)"
|
||||
$(INSTALL) -m 644 $(HTMLPAGES) "$(DOCDIR)"
|
||||
endif
|
||||
|
||||
ifdef CONFIG_MANPAGES
|
||||
install-progs-$(CONFIG_DOC): install-man
|
||||
|
||||
@@ -137,15 +100,10 @@ install-man: $(MANPAGES)
|
||||
$(INSTALL) -m 644 $(MANPAGES3) "$(MANDIR)/man3"
|
||||
endif
|
||||
|
||||
uninstall: uninstall-doc
|
||||
|
||||
uninstall-doc: uninstall-html uninstall-man
|
||||
|
||||
uninstall-html:
|
||||
$(RM) -r "$(DOCDIR)"
|
||||
uninstall: uninstall-man
|
||||
|
||||
uninstall-man:
|
||||
$(RM) $(addprefix "$(MANDIR)/man1/",$(AVPROGS-yes:%=%.1) $(AVPROGS-yes:%=%-all.1) $(COMPONENTS-yes:%=%.1))
|
||||
$(RM) $(addprefix "$(MANDIR)/man1/",$(PROGS-yes:%=%.1) $(PROGS-yes:%=%-all.1) $(COMPONENTS-yes:%=%.1))
|
||||
$(RM) $(addprefix "$(MANDIR)/man3/",$(LIBRARIES-yes:%=%.3))
|
||||
|
||||
clean:: docclean
|
||||
@@ -153,13 +111,8 @@ clean:: docclean
|
||||
distclean:: docclean
|
||||
$(RM) doc/config.texi
|
||||
|
||||
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
|
||||
docclean:
|
||||
$(RM) $(TXTPAGES) doc/*.html doc/*.pod doc/*.1 doc/*.3 $(CLEANSUFFIXES:%=doc/%) doc/avoptions_*.texi
|
||||
$(RM) -r doc/doxy/html
|
||||
|
||||
-include $(wildcard $(DOCS:%=%.d))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
* 2.2 "Muybridge" March, 2014
|
||||
* 2.0 "Nameless" July, 2013
|
||||
|
||||
|
||||
General notes
|
||||
|
||||
@@ -59,18 +59,10 @@ Show license.
|
||||
|
||||
@item -h, -?, -help, --help [@var{arg}]
|
||||
Show help. An optional parameter may be specified to print help about a specific
|
||||
item. If no argument is specified, only basic (non advanced) tool
|
||||
options are shown.
|
||||
item.
|
||||
|
||||
Possible values of @var{arg} are:
|
||||
@table @option
|
||||
@item long
|
||||
Print advanced tool options in addition to the basic tool options.
|
||||
|
||||
@item full
|
||||
Print complete list of options, including shared and private options
|
||||
for encoders, decoders, demuxers, muxers, filters, etc.
|
||||
|
||||
@item decoder=@var{decoder_name}
|
||||
Print detailed information about the decoder named @var{decoder_name}. Use the
|
||||
@option{-decoders} option to get a list of all decoders.
|
||||
@@ -90,6 +82,7 @@ Print detailed information about the muxer named @var{muxer_name}. Use the
|
||||
@item filter=@var{filter_name}
|
||||
Print detailed information about the filter name @var{filter_name}. Use the
|
||||
@option{-filters} option to get a list of all filters.
|
||||
|
||||
@end table
|
||||
|
||||
@item -version
|
||||
@@ -128,9 +121,6 @@ Show available sample formats.
|
||||
@item -layouts
|
||||
Show channel names and standard channel layouts.
|
||||
|
||||
@item -colors
|
||||
Show recognized color names.
|
||||
|
||||
@item -loglevel [repeat+]@var{loglevel} | -v [repeat+]@var{loglevel}
|
||||
Set the logging level used by the library.
|
||||
Adding "repeat+" indicates that repeated log output should not be compressed
|
||||
@@ -194,13 +184,6 @@ to a plain @code{%}
|
||||
Errors in parsing the environment variable are not fatal, and will not
|
||||
appear in the report.
|
||||
|
||||
@item -hide_banner
|
||||
Suppress printing banner.
|
||||
|
||||
All FFmpeg tools will normally show a copyright notice, build options
|
||||
and library versions. This option can be used to suppress printing
|
||||
this information.
|
||||
|
||||
@item -cpuflags flags (@emph{global})
|
||||
Allows setting and clearing cpu flags. This option is intended
|
||||
for testing. Do not use it unless you know what you're doing.
|
||||
@@ -257,10 +240,6 @@ Possible flags for this option are:
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@item -opencl_bench
|
||||
Benchmark all available OpenCL devices and show the results. This option
|
||||
is only available when FFmpeg has been compiled with @code{--enable-opencl}.
|
||||
|
||||
@item -opencl_options options (@emph{global})
|
||||
Set OpenCL environment options. This option is only available when
|
||||
FFmpeg has been compiled with @code{--enable-opencl}.
|
||||
@@ -292,12 +271,11 @@ muxer:
|
||||
ffmpeg -i input.flac -id3v2_version 3 out.mp3
|
||||
@end example
|
||||
|
||||
All codec AVOptions are per-stream, and thus a stream specifier
|
||||
should be attached to them.
|
||||
All codec AVOptions are obviously per-stream, so the chapter on stream
|
||||
specifiers applies to them
|
||||
|
||||
Note: the @option{-nooption} syntax cannot be used for boolean
|
||||
AVOptions, use @option{-option 0}/@option{-option 1}.
|
||||
Note @option{-nooption} syntax cannot be used for boolean AVOptions,
|
||||
use @option{-option 0}/@option{-option 1}.
|
||||
|
||||
Note: the old undocumented way of specifying per-stream AVOptions by
|
||||
prepending v/a/s to the options name is now obsolete and will be
|
||||
removed soon.
|
||||
Note2 old undocumented way of specifying per-stream AVOptions by prepending
|
||||
v/a/s to the options name is now obsolete and will be removed soon.
|
||||
36
doc/avutil.txt
Normal file
36
doc/avutil.txt
Normal file
@@ -0,0 +1,36 @@
|
||||
AVUtil
|
||||
======
|
||||
libavutil is a small lightweight library of generally useful functions.
|
||||
It is not a library for code needed by both libavcodec and libavformat.
|
||||
|
||||
|
||||
Overview:
|
||||
=========
|
||||
adler32.c adler32 checksum
|
||||
aes.c AES encryption and decryption
|
||||
fifo.c resizeable first in first out buffer
|
||||
intfloat_readwrite.c portable reading and writing of floating point values
|
||||
log.c "printf" with context and level
|
||||
md5.c MD5 Message-Digest Algorithm
|
||||
rational.c code to perform exact calculations with rational numbers
|
||||
tree.c generic AVL tree
|
||||
crc.c generic CRC checksumming code
|
||||
integer.c 128bit integer math
|
||||
lls.c
|
||||
mathematics.c greatest common divisor, integer sqrt, integer log2, ...
|
||||
mem.c memory allocation routines with guaranteed alignment
|
||||
|
||||
Headers:
|
||||
bswap.h big/little/native-endian conversion code
|
||||
x86_cpu.h a few useful macros for unifying x86-64 and x86-32 code
|
||||
avutil.h
|
||||
common.h
|
||||
intreadwrite.h reading and writing of unaligned big/little/native-endian integers
|
||||
|
||||
|
||||
Goals:
|
||||
======
|
||||
* Modular (few interdependencies and the possibility of disabling individual parts during ./configure)
|
||||
* Small (source and object)
|
||||
* Efficient (low CPU and memory usage)
|
||||
* Useful (avoid useless features almost no one needs)
|
||||
@@ -30,33 +30,7 @@ ADTS AAC container to a FLV or a MOV/MP4 file.
|
||||
|
||||
Remove zero padding at the end of a packet.
|
||||
|
||||
@section dump_extra
|
||||
|
||||
Add extradata to the beginning of the filtered packets.
|
||||
|
||||
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
|
||||
add extradata to all key packets
|
||||
|
||||
@item e
|
||||
add extradata to all packets
|
||||
@end table
|
||||
|
||||
If not specified it is assumed @samp{k}.
|
||||
|
||||
For example the following @command{ffmpeg} command forces a global
|
||||
header (thus disabling individual packet headers) in the H.264 packets
|
||||
generated by the @code{libx264} encoder, but corrects them by adding
|
||||
the header stored in extradata to the key packets:
|
||||
@example
|
||||
ffmpeg -i INPUT -map 0 -flags:v +global_header -c:v libx264 -bsf:v dump_extra out.ts
|
||||
@end example
|
||||
@section dump_extradata
|
||||
|
||||
@section h264_mp4toannexb
|
||||
|
||||
@@ -117,10 +91,12 @@ ffmpeg -i frame_%d.jpg -c:v copy rotated.avi
|
||||
|
||||
@section movsub
|
||||
|
||||
@section mp3_header_compress
|
||||
|
||||
@section mp3_header_decompress
|
||||
|
||||
@section noise
|
||||
|
||||
@section remove_extra
|
||||
@section remove_extradata
|
||||
|
||||
@c man end BITSTREAM FILTERS
|
||||
|
||||
@@ -84,6 +84,9 @@ Apply interlaced motion estimation.
|
||||
Use closed gop.
|
||||
@end table
|
||||
|
||||
@item sub_id @var{integer}
|
||||
Deprecated, currently unused.
|
||||
|
||||
@item me_method @var{integer} (@emph{encoding,video})
|
||||
Set motion estimation method.
|
||||
|
||||
@@ -172,13 +175,7 @@ Set max video quantizer scale (VBR). Must be included between -1 and
|
||||
Set max difference between the quantizer scale (VBR).
|
||||
|
||||
@item bf @var{integer} (@emph{encoding,video})
|
||||
Set max number of B frames between non-B-frames.
|
||||
|
||||
Must be an integer between -1 and 16. 0 means that B-frames are
|
||||
disabled. If a value of -1 is used, it will choose an automatic value
|
||||
depending on the encoder.
|
||||
|
||||
Default value is 0.
|
||||
Set max number of B frames.
|
||||
|
||||
@item b_qfactor @var{float} (@emph{encoding,video})
|
||||
Set qp factor between P and B frames.
|
||||
@@ -389,6 +386,10 @@ Possible values:
|
||||
|
||||
@item simplemmx
|
||||
|
||||
@item libmpeg2mmx
|
||||
|
||||
@item mmi
|
||||
|
||||
@item arm
|
||||
|
||||
@item altivec
|
||||
@@ -405,6 +406,10 @@ Possible values:
|
||||
|
||||
@item simplealpha
|
||||
|
||||
@item h264
|
||||
|
||||
@item vp3
|
||||
|
||||
@item ipp
|
||||
|
||||
@item xvidmmx
|
||||
@@ -767,26 +772,26 @@ Set noise reduction.
|
||||
Set number of bits which should be loaded into the rc buffer before
|
||||
decoding starts.
|
||||
|
||||
@item inter_threshold @var{integer} (@emph{encoding,video})
|
||||
|
||||
@item flags2 @var{flags} (@emph{decoding/encoding,audio,video})
|
||||
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item fast
|
||||
Allow non spec compliant speedup tricks.
|
||||
allow non spec compliant speedup tricks
|
||||
@item sgop
|
||||
Deprecated, use mpegvideo private options instead.
|
||||
Deprecated, use mpegvideo private options instead
|
||||
@item noout
|
||||
Skip bitstream encoding.
|
||||
@item ignorecrop
|
||||
Ignore cropping information from sps.
|
||||
skip bitstream encoding
|
||||
@item local_header
|
||||
Place global headers at every keyframe instead of in extradata.
|
||||
place global headers at every keyframe instead of in extradata
|
||||
@item chunks
|
||||
Frame data might be split into multiple chunks.
|
||||
Frame data might be split into multiple chunks
|
||||
@item showall
|
||||
Show all frames before the first keyframe.
|
||||
Show all frames before the first keyframe
|
||||
@item skiprd
|
||||
Deprecated, use mpegvideo private options instead.
|
||||
Deprecated, use mpegvideo private options instead
|
||||
@end table
|
||||
|
||||
@item error @var{integer} (@emph{encoding,video})
|
||||
@@ -842,10 +847,6 @@ Possible values:
|
||||
|
||||
@item aac_eld
|
||||
|
||||
@item mpeg2_aac_low
|
||||
|
||||
@item mpeg2_aac_he
|
||||
|
||||
@item dts
|
||||
|
||||
@item dts_es
|
||||
@@ -877,9 +878,6 @@ 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 primarly for compatibility reasons and are not so useful.
|
||||
|
||||
@item skipcmp @var{integer} (@emph{encoding,video})
|
||||
Set frame skip compare function.
|
||||
@@ -1067,34 +1065,9 @@ Set sample format audio decoders should prefer. Default value is
|
||||
|
||||
@item sub_charenc @var{encoding} (@emph{decoding,subtitles})
|
||||
Set the input subtitles character encoding.
|
||||
|
||||
@item field_order @var{field_order} (@emph{video})
|
||||
Set/override the field order of the video.
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item progressive
|
||||
Progressive video
|
||||
@item tt
|
||||
Interlaced video, top field coded and displayed first
|
||||
@item bb
|
||||
Interlaced video, bottom field coded and displayed first
|
||||
@item tb
|
||||
Interlaced video, top coded first, bottom displayed first
|
||||
@item bt
|
||||
Interlaced video, bottom coded first, top displayed first
|
||||
@end table
|
||||
|
||||
@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.
|
||||
@end table
|
||||
|
||||
@c man end CODEC OPTIONS
|
||||
|
||||
@ifclear config-writeonly
|
||||
@include decoders.texi
|
||||
@end ifclear
|
||||
@ifclear config-readonly
|
||||
@include encoders.texi
|
||||
@end ifclear
|
||||
|
||||
@@ -14,7 +14,7 @@ You can disable all the decoders with the configure option
|
||||
with the options @code{--enable-decoder=@var{DECODER}} /
|
||||
@code{--disable-decoder=@var{DECODER}}.
|
||||
|
||||
The option @code{-decoders} of the ff* tools will display the list of
|
||||
The option @code{-codecs} of the ff* tools will display the list of
|
||||
enabled decoders.
|
||||
|
||||
@c man end DECODERS
|
||||
@@ -52,37 +52,6 @@ top-field-first is assumed
|
||||
@chapter Audio Decoders
|
||||
@c man begin AUDIO DECODERS
|
||||
|
||||
A description of some of the currently available audio decoders
|
||||
follows.
|
||||
|
||||
@section ac3
|
||||
|
||||
AC-3 audio decoder.
|
||||
|
||||
This decoder implements part of ATSC A/52:2010 and ETSI TS 102 366, as well as
|
||||
the undocumented RealAudio 3 (a.k.a. dnet).
|
||||
|
||||
@subsection AC-3 Decoder Options
|
||||
|
||||
@table @option
|
||||
|
||||
@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.
|
||||
There are 3 notable scale factor ranges:
|
||||
@table @option
|
||||
@item drc_scale == 0
|
||||
DRC disabled. Produces full range audio.
|
||||
@item 0 < drc_scale <= 1
|
||||
DRC enabled. Applies a fraction of the stream DRC value.
|
||||
Audio reproduction is between full range and full compression.
|
||||
@item drc_scale > 1
|
||||
DRC enabled. Applies drc_scale asymmetrically.
|
||||
Loud sounds are fully compressed. Soft sounds are enhanced.
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@section ffwavesynth
|
||||
|
||||
Internal wave synthetizer.
|
||||
@@ -189,45 +158,4 @@ ee450d, 101010, eaeaea, 0ce60b, ec14ed, ebff0b, 0d617a, 7b7b7b, d1d1d1,
|
||||
7b2a0e, 0d950c, 0f007b, cf0dec, cfa80c, 7c127b}.
|
||||
@end table
|
||||
|
||||
@section libzvbi-teletext
|
||||
|
||||
Libzvbi allows libavcodec to decode DVB teletext pages and DVB teletext
|
||||
subtitles. Requires the presence of the libzvbi headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libzvbi}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item txt_page
|
||||
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_chop_top
|
||||
Discards the top teletext line. Default value is 1.
|
||||
@item txt_format
|
||||
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
|
||||
Y offset of generated bitmaps, default is 0.
|
||||
@item txt_chop_spaces
|
||||
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 charactes.
|
||||
Default value is 1.
|
||||
@item txt_duration
|
||||
Sets the display duration of the decoded teletext pages or subtitles in
|
||||
miliseconds. 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 (black) background.
|
||||
@end table
|
||||
|
||||
@c man end SUBTILES DECODERS
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
a.summary-letter {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #2D6198;
|
||||
}
|
||||
@@ -17,8 +13,8 @@ a:visited {
|
||||
}
|
||||
|
||||
#banner img {
|
||||
margin-bottom: 1px;
|
||||
margin-top: 5px;
|
||||
padding-bottom: 1px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
#body {
|
||||
@@ -49,16 +45,11 @@ body {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 a, h2 a, h3 a, h4 a {
|
||||
text-decoration: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
h1, h2, h3 {
|
||||
padding-left: 0.4em;
|
||||
border-radius: 4px;
|
||||
padding-bottom: 0.25em;
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0.2em;
|
||||
padding-top: 0.2em;
|
||||
border: 1px solid #6A996A;
|
||||
}
|
||||
|
||||
@@ -72,22 +63,15 @@ h1 {
|
||||
|
||||
h2 {
|
||||
color: #313131;
|
||||
font-size: 1.0em;
|
||||
font-size: 0.9em;
|
||||
background-color: #ABE3AB;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #313131;
|
||||
font-size: 0.9em;
|
||||
margin-bottom: -6px;
|
||||
background-color: #BBF3BB;
|
||||
}
|
||||
|
||||
h4 {
|
||||
color: #313131;
|
||||
font-size: 0.8em;
|
||||
margin-bottom: -8px;
|
||||
background-color: #D1FDD1;
|
||||
background-color: #BBF3BB;
|
||||
}
|
||||
|
||||
img {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@chapter Demuxers
|
||||
@c man begin DEMUXERS
|
||||
|
||||
Demuxers are configured elements in FFmpeg that can read the
|
||||
Demuxers are configured elements in FFmpeg which allow to read the
|
||||
multimedia streams from a particular type of file.
|
||||
|
||||
When you configure your FFmpeg build, all the supported demuxers
|
||||
@@ -29,17 +29,6 @@ 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 asf
|
||||
|
||||
Advanced Systems Format demuxer.
|
||||
|
||||
This demuxer is used to demux ASF files and MMS network streams.
|
||||
|
||||
@table @option
|
||||
@item -no_resync_search @var{bool}
|
||||
Do not try to resynchronize by looking for a certain optional start code.
|
||||
@end table
|
||||
|
||||
@anchor{concat}
|
||||
@section concat
|
||||
|
||||
@@ -114,17 +103,6 @@ probed and 0 otherwise.
|
||||
|
||||
@end table
|
||||
|
||||
@section flv
|
||||
|
||||
Adobe Flash Video Format demuxer.
|
||||
|
||||
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.
|
||||
@end table
|
||||
|
||||
@section libgme
|
||||
|
||||
The Game Music Emu library is a collection of video game music file emulators.
|
||||
@@ -262,36 +240,23 @@ Use @command{ffmpeg} for creating a video from the images in the file
|
||||
sequence @file{img-001.jpeg}, @file{img-002.jpeg}, ..., assuming an
|
||||
input frame rate of 10 frames per second:
|
||||
@example
|
||||
ffmpeg -framerate 10 -i 'img-%03d.jpeg' out.mkv
|
||||
ffmpeg -i 'img-%03d.jpeg' -r 10 out.mkv
|
||||
@end example
|
||||
|
||||
@item
|
||||
As above, but start by reading from a file with index 100 in the sequence:
|
||||
@example
|
||||
ffmpeg -framerate 10 -start_number 100 -i 'img-%03d.jpeg' out.mkv
|
||||
ffmpeg -start_number 100 -i 'img-%03d.jpeg' -r 10 out.mkv
|
||||
@end example
|
||||
|
||||
@item
|
||||
Read images matching the "*.png" glob pattern , that is all the files
|
||||
terminating with the ".png" suffix:
|
||||
@example
|
||||
ffmpeg -framerate 10 -pattern_type glob -i "*.png" out.mkv
|
||||
ffmpeg -pattern_type glob -i "*.png" -r 10 out.mkv
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@section mpegts
|
||||
|
||||
MPEG-2 transport stream demuxer.
|
||||
|
||||
@table @option
|
||||
|
||||
@item fix_teletext_pts
|
||||
Overrides 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
|
||||
not discarded. Default value is 1, set this option to 0 if you want your
|
||||
teletext packet PTS and DTS values untouched.
|
||||
@end table
|
||||
|
||||
@section rawvideo
|
||||
|
||||
Raw video demuxer.
|
||||
|
||||
@@ -11,23 +11,29 @@
|
||||
|
||||
@chapter Developers Guide
|
||||
|
||||
@section Notes for external developers
|
||||
@section API
|
||||
@itemize @bullet
|
||||
@item libavcodec is the library containing the codecs (both encoding and
|
||||
decoding). Look at @file{doc/examples/decoding_encoding.c} to see how to use
|
||||
it.
|
||||
|
||||
This document is mostly useful for internal FFmpeg developers.
|
||||
External developers who need to use the API in their application should
|
||||
refer to the API doxygen documentation in the public headers, and
|
||||
check the examples in @file{doc/examples} and in the source code to
|
||||
see how the public API is employed.
|
||||
@item libavformat is the library containing the file format handling (mux and
|
||||
demux code for several formats). Look at @file{ffplay.c} to use it in a
|
||||
player. See @file{doc/examples/muxing.c} to use it to generate audio or video
|
||||
streams.
|
||||
|
||||
You can use the FFmpeg libraries in your commercial program, but you
|
||||
are encouraged to @emph{publish any patch you make}. In this case the
|
||||
best way to proceed is to send your patches to the ffmpeg-devel
|
||||
mailing list following the guidelines illustrated in the remainder of
|
||||
this document.
|
||||
@end itemize
|
||||
|
||||
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{http://ffmpeg.org/legal.html}.
|
||||
@section Integrating libavcodec or libavformat in your program
|
||||
|
||||
You can integrate all the source code of the libraries to link them
|
||||
statically to avoid any version problem. All you need is to provide a
|
||||
'config.mak' and a 'config.h' in the parent directory. See the defines
|
||||
generated by ./configure to understand what is needed.
|
||||
|
||||
You can use libavcodec or libavformat in your commercial program, but
|
||||
@emph{any patch you make must be published}. The best way to proceed is
|
||||
to send your patches to the FFmpeg mailing list.
|
||||
|
||||
@section Contributing
|
||||
|
||||
@@ -51,16 +57,13 @@ and should try to fix issues their commit causes.
|
||||
@subsection Code formatting conventions
|
||||
|
||||
There are the following guidelines regarding the indentation in files:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Indent size is 4.
|
||||
|
||||
@item
|
||||
The TAB character is forbidden outside of Makefiles as is any
|
||||
form of trailing whitespace. Commits containing either will be
|
||||
rejected by the git repository.
|
||||
|
||||
@item
|
||||
You should try to limit your code lines to 80 characters; however, do so if
|
||||
and only if this improves readability.
|
||||
@@ -92,7 +95,7 @@ for markup commands, i.e. use @code{@@param} and not @code{\param}.
|
||||
* more text ...
|
||||
* ...
|
||||
*/
|
||||
typedef struct Foobar @{
|
||||
typedef struct Foobar@{
|
||||
int var1; /**< var1 description */
|
||||
int var2; ///< var2 description
|
||||
/** var3 description */
|
||||
@@ -114,17 +117,13 @@ int myfunc(int my_parameter)
|
||||
|
||||
FFmpeg is programmed in the ISO C90 language with a few additional
|
||||
features from ISO C99, namely:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
the @samp{inline} keyword;
|
||||
|
||||
@item
|
||||
@samp{//} comments;
|
||||
|
||||
@item
|
||||
designated struct initializers (@samp{struct s x = @{ .i = 17 @};})
|
||||
|
||||
@item
|
||||
compound literals (@samp{x = (struct s) @{ 17, 23 @};})
|
||||
@end itemize
|
||||
@@ -136,17 +135,13 @@ clarity and performance.
|
||||
All code must compile with recent versions of GCC and a number of other
|
||||
currently supported compilers. To ensure compatibility, please do not use
|
||||
additional C99 features or GCC extensions. Especially watch out for:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
mixing statements and declarations;
|
||||
|
||||
@item
|
||||
@samp{long long} (use @samp{int64_t} instead);
|
||||
|
||||
@item
|
||||
@samp{__attribute__} not protected by @samp{#ifdef __GNUC__} or similar;
|
||||
|
||||
@item
|
||||
GCC statement expressions (@samp{(x = (@{ int y = 4; y; @})}).
|
||||
@end itemize
|
||||
@@ -158,25 +153,20 @@ All names should be composed with underscores (_), not CamelCase. For example,
|
||||
for example structs and enums; they should always be in the CamelCase
|
||||
|
||||
There are the following conventions for naming variables and functions:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
For local variables no prefix is required.
|
||||
|
||||
@item
|
||||
For file-scope variables and functions declared as @code{static}, no prefix
|
||||
is required.
|
||||
|
||||
@item
|
||||
For variables and functions visible outside of file scope, but only used
|
||||
internally by a library, an @code{ff_} prefix should be used,
|
||||
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_aac_parse_header}.
|
||||
|
||||
@item
|
||||
Each library has its own prefix for public symbols, in addition to the
|
||||
commonly used @code{av_} (@code{avformat_} for libavformat,
|
||||
@@ -196,12 +186,10 @@ 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.
|
||||
|
||||
@subsection Miscellaneous conventions
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
fprintf and printf are forbidden in libavformat and libavcodec,
|
||||
please use av_log() instead.
|
||||
|
||||
@item
|
||||
Casts should be used only when necessary. Unneeded parentheses
|
||||
should also be avoided if they don't make the code easier to understand.
|
||||
@@ -244,154 +232,131 @@ For Emacs, add these roughly equivalent lines to your @file{.emacs.d/init.el}:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Contributions should be licensed under the
|
||||
@uref{http://www.gnu.org/licenses/lgpl-2.1.html, LGPL 2.1},
|
||||
including an "or any later version" clause, or, if you prefer
|
||||
a gift-style license, the
|
||||
@uref{http://opensource.org/licenses/isc-license.txt, ISC} or
|
||||
@uref{http://mit-license.org/, MIT} license.
|
||||
@uref{http://www.gnu.org/licenses/gpl-2.0.html, GPL 2} including
|
||||
an "or any later version" clause is also acceptable, but LGPL is
|
||||
preferred.
|
||||
If you add a new file, give it a proper license header. Do not copy and
|
||||
paste it from a random place, use an existing file as template.
|
||||
|
||||
Contributions should be licensed under the
|
||||
@uref{http://www.gnu.org/licenses/lgpl-2.1.html, LGPL 2.1},
|
||||
including an "or any later version" clause, or, if you prefer
|
||||
a gift-style license, the
|
||||
@uref{http://www.isc.org/software/license/, ISC} or
|
||||
@uref{http://mit-license.org/, MIT} license.
|
||||
@uref{http://www.gnu.org/licenses/gpl-2.0.html, GPL 2} including
|
||||
an "or any later version" clause is also acceptable, but LGPL is
|
||||
preferred.
|
||||
@item
|
||||
You must not commit code which breaks FFmpeg! (Meaning unfinished but
|
||||
enabled code which breaks compilation or compiles but does not work or
|
||||
breaks the regression tests)
|
||||
You can commit unfinished stuff (for testing etc), but it must be disabled
|
||||
(#ifdef etc) by default so it does not interfere with other developers'
|
||||
work.
|
||||
|
||||
You must not commit code which breaks FFmpeg! (Meaning unfinished but
|
||||
enabled code which breaks compilation or compiles but does not work or
|
||||
breaks the regression tests)
|
||||
You can commit unfinished stuff (for testing etc), but it must be disabled
|
||||
(#ifdef etc) by default so it does not interfere with other developers'
|
||||
work.
|
||||
@item
|
||||
The commit message should have a short first line in the form of
|
||||
a @samp{topic: short description} as a header, separated by a newline
|
||||
from the body consisting of an explanation of why the change is necessary.
|
||||
If the commit fixes a known bug on the bug tracker, the commit message
|
||||
should include its bug ID. Referring to the issue on the bug tracker does
|
||||
not exempt you from writing an excerpt of the bug in the commit message.
|
||||
|
||||
The commit message should have a short first line in the form of
|
||||
a @samp{topic: short description} as a header, separated by a newline
|
||||
from the body consisting of an explanation of why the change is necessary.
|
||||
If the commit fixes a known bug on the bug tracker, the commit message
|
||||
should include its bug ID. Referring to the issue on the bug tracker does
|
||||
not exempt you from writing an excerpt of the bug in the commit message.
|
||||
@item
|
||||
You do not have to over-test things. If it works for you, and you think it
|
||||
should work for others, then commit. If your code has problems
|
||||
(portability, triggers compiler bugs, unusual environment etc) they will be
|
||||
reported and eventually fixed.
|
||||
|
||||
You do not have to over-test things. If it works for you, and you think it
|
||||
should work for others, then commit. If your code has problems
|
||||
(portability, triggers compiler bugs, unusual environment etc) they will be
|
||||
reported and eventually fixed.
|
||||
@item
|
||||
Do not commit unrelated changes together, split them into self-contained
|
||||
pieces. Also do not forget that if part B depends on part A, but A does not
|
||||
depend on B, then A can and should be committed first and separate from B.
|
||||
Keeping changes well split into self-contained parts makes reviewing and
|
||||
understanding them on the commit log mailing list easier. This also helps
|
||||
in case of debugging later on.
|
||||
Also if you have doubts about splitting or not splitting, do not hesitate to
|
||||
ask/discuss it on the developer mailing list.
|
||||
|
||||
Do not commit unrelated changes together, split them into self-contained
|
||||
pieces. Also do not forget that if part B depends on part A, but A does not
|
||||
depend on B, then A can and should be committed first and separate from B.
|
||||
Keeping changes well split into self-contained parts makes reviewing and
|
||||
understanding them on the commit log mailing list easier. This also helps
|
||||
in case of debugging later on.
|
||||
Also if you have doubts about splitting or not splitting, do not hesitate to
|
||||
ask/discuss it on the developer mailing list.
|
||||
@item
|
||||
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.
|
||||
Do not remove functionality from the code. Just improve!
|
||||
|
||||
Note: Redundant code can be removed.
|
||||
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.
|
||||
Do not remove functionality from the code. Just improve!
|
||||
|
||||
Note: Redundant code can be removed.
|
||||
@item
|
||||
Do not commit changes to the build system (Makefiles, configure script)
|
||||
which change behavior, defaults etc, without asking first. The same
|
||||
applies to compiler warning fixes, trivial looking fixes and to code
|
||||
maintained by other developers. We usually have a reason for doing things
|
||||
the way we do. Send your changes as patches to the ffmpeg-devel mailing
|
||||
list, and if the code maintainers say OK, you may commit. This does not
|
||||
apply to files you wrote and/or maintain.
|
||||
|
||||
Do not commit changes to the build system (Makefiles, configure script)
|
||||
which change behavior, defaults etc, without asking first. The same
|
||||
applies to compiler warning fixes, trivial looking fixes and to code
|
||||
maintained by other developers. We usually have a reason for doing things
|
||||
the way we do. Send your changes as patches to the ffmpeg-devel mailing
|
||||
list, and if the code maintainers say OK, you may commit. This does not
|
||||
apply to files you wrote and/or maintain.
|
||||
@item
|
||||
We refuse source indentation and other cosmetic changes if they are mixed
|
||||
with functional changes, such commits will be rejected and removed. Every
|
||||
developer has his own indentation style, you should not change it. Of course
|
||||
if you (re)write something, you can use your own style, even though we would
|
||||
prefer if the indentation throughout FFmpeg was consistent (Many projects
|
||||
force a given indentation style - we do not.). If you really need to make
|
||||
indentation changes (try to avoid this), separate them strictly from real
|
||||
changes.
|
||||
|
||||
NOTE: If you had to put if()@{ .. @} over a large (> 5 lines) chunk of code,
|
||||
then either do NOT change the indentation of the inner part within (do not
|
||||
move it to the right)! or do so in a separate commit
|
||||
We refuse source indentation and other cosmetic changes if they are mixed
|
||||
with functional changes, such commits will be rejected and removed. Every
|
||||
developer has his own indentation style, you should not change it. Of course
|
||||
if you (re)write something, you can use your own style, even though we would
|
||||
prefer if the indentation throughout FFmpeg was consistent (Many projects
|
||||
force a given indentation style - we do not.). If you really need to make
|
||||
indentation changes (try to avoid this), separate them strictly from real
|
||||
changes.
|
||||
|
||||
NOTE: If you had to put if()@{ .. @} over a large (> 5 lines) chunk of code,
|
||||
then either do NOT change the indentation of the inner part within (do not
|
||||
move it to the right)! or do so in a separate commit
|
||||
@item
|
||||
Always fill out the commit log message. Describe in a few lines what you
|
||||
changed and why. You can refer to mailing list postings if you fix a
|
||||
particular bug. Comments such as "fixed!" or "Changed it." are unacceptable.
|
||||
Recommended format:
|
||||
area changed: Short 1 line description
|
||||
|
||||
details describing what and why and giving references.
|
||||
Always fill out the commit log message. Describe in a few lines what you
|
||||
changed and why. You can refer to mailing list postings if you fix a
|
||||
particular bug. Comments such as "fixed!" or "Changed it." are unacceptable.
|
||||
Recommended format:
|
||||
area changed: Short 1 line description
|
||||
|
||||
details describing what and why and giving references.
|
||||
@item
|
||||
Make sure the author of the commit is set correctly. (see git commit --author)
|
||||
If you apply a patch, send an
|
||||
answer to ffmpeg-devel (or wherever you got the patch from) saying that
|
||||
you applied the patch.
|
||||
|
||||
Make sure the author of the commit is set correctly. (see git commit --author)
|
||||
If you apply a patch, send an
|
||||
answer to ffmpeg-devel (or wherever you got the patch from) saying that
|
||||
you applied the patch.
|
||||
@item
|
||||
When applying patches that have been discussed (at length) on the mailing
|
||||
list, reference the thread in the log message.
|
||||
|
||||
When applying patches that have been discussed (at length) on the mailing
|
||||
list, reference the thread in the log message.
|
||||
@item
|
||||
Do NOT commit to code actively maintained by others without permission.
|
||||
Send a patch to ffmpeg-devel instead. If no one answers within a reasonable
|
||||
timeframe (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!
|
||||
|
||||
Do NOT commit to code actively maintained by others without permission.
|
||||
Send a patch to ffmpeg-devel instead. If no one answers within a reasonable
|
||||
timeframe (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!
|
||||
@item
|
||||
Subscribe to the ffmpeg-cvslog mailing list. 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.
|
||||
|
||||
Subscribe to the ffmpeg-cvslog mailing list. 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.
|
||||
@item
|
||||
Update the documentation if you change behavior or add features. If you are
|
||||
unsure how best to do this, send a patch to ffmpeg-devel, the documentation
|
||||
maintainer(s) will review and commit your stuff.
|
||||
|
||||
Update the documentation if you change behavior or add features. If you are
|
||||
unsure how best to do this, send a patch to ffmpeg-devel, the documentation
|
||||
maintainer(s) will review and commit your stuff.
|
||||
@item
|
||||
Try to keep important discussions and requests (also) on the public
|
||||
developer mailing list, so that all developers can benefit from them.
|
||||
|
||||
Try to keep important discussions and requests (also) on the public
|
||||
developer mailing list, so that all developers can benefit from them.
|
||||
@item
|
||||
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.
|
||||
|
||||
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.
|
||||
@item
|
||||
Remember to check if you need to bump versions for the specific libav*
|
||||
parts (libavutil, libavcodec, libavformat) you are changing. You need
|
||||
to change the version integer.
|
||||
Incrementing the first component means no backward compatibility to
|
||||
previous versions (e.g. removal of a function from the public API).
|
||||
Incrementing the second component means backward compatible change
|
||||
(e.g. addition of a function to the public API or extension of an
|
||||
existing data structure).
|
||||
Incrementing the third component means a noteworthy binary compatible
|
||||
change (e.g. encoder bug fix that matters for the decoder). The third
|
||||
component always starts at 100 to distinguish FFmpeg from Libav.
|
||||
|
||||
Remember to check if you need to bump versions for the specific libav*
|
||||
parts (libavutil, libavcodec, libavformat) you are changing. You need
|
||||
to change the version integer.
|
||||
Incrementing the first component means no backward compatibility to
|
||||
previous versions (e.g. removal of a function from the public API).
|
||||
Incrementing the second component means backward compatible change
|
||||
(e.g. addition of a function to the public API or extension of an
|
||||
existing data structure).
|
||||
Incrementing the third component means a noteworthy binary compatible
|
||||
change (e.g. encoder bug fix that matters for the decoder). The third
|
||||
component always starts at 100 to distinguish FFmpeg from Libav.
|
||||
@item
|
||||
Compiler warnings indicate potential bugs or code with bad style. If a type of
|
||||
warning always points to correct and clean code, that warning should
|
||||
be disabled, not the code changed.
|
||||
Thus the remaining warnings can either be bugs or correct code.
|
||||
If it is a bug, the bug has to be fixed. If it is not, the code should
|
||||
be changed to not generate a warning unless that causes a slowdown
|
||||
or obfuscates the code.
|
||||
|
||||
Compiler warnings indicate potential bugs or code with bad style. If a type of
|
||||
warning always points to correct and clean code, that warning should
|
||||
be disabled, not the code changed.
|
||||
Thus the remaining warnings can either be bugs or correct code.
|
||||
If it is a bug, the bug has to be fixed. If it is not, the code should
|
||||
be changed to not generate a warning unless that causes a slowdown
|
||||
or obfuscates the code.
|
||||
@item
|
||||
Make sure that no parts of the codebase that you maintain are missing from the
|
||||
@file{MAINTAINERS} file. If something that you want to maintain is missing add it with
|
||||
your name after it.
|
||||
If at some point you no longer want to maintain some code, then please help
|
||||
finding a new maintainer and also don't forget updating the @file{MAINTAINERS} file.
|
||||
If you add a new file, give it a proper license header. Do not copy and
|
||||
paste it from a random place, use an existing file as template.
|
||||
@end enumerate
|
||||
|
||||
We think our rules are not too hard. If you have comments, contact us.
|
||||
@@ -446,51 +411,40 @@ send a reminder by email. Your patch should eventually be dealt with.
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Did you use av_cold for codec initialization and close functions?
|
||||
|
||||
Did you use av_cold for codec initialization and close functions?
|
||||
@item
|
||||
Did you add a long_name under NULL_IF_CONFIG_SMALL to the AVCodec or
|
||||
AVInputFormat/AVOutputFormat struct?
|
||||
|
||||
Did you add a long_name under NULL_IF_CONFIG_SMALL to the AVCodec or
|
||||
AVInputFormat/AVOutputFormat struct?
|
||||
@item
|
||||
Did you bump the minor version number (and reset the micro version
|
||||
number) in @file{libavcodec/version.h} or @file{libavformat/version.h}?
|
||||
|
||||
Did you bump the minor version number (and reset the micro version
|
||||
number) in @file{libavcodec/version.h} or @file{libavformat/version.h}?
|
||||
@item
|
||||
Did you register it in @file{allcodecs.c} or @file{allformats.c}?
|
||||
|
||||
Did you register it in @file{allcodecs.c} or @file{allformats.c}?
|
||||
@item
|
||||
Did you add the AVCodecID to @file{avcodec.h}?
|
||||
When adding new codec IDs, also add an entry to the codec descriptor
|
||||
list in @file{libavcodec/codec_desc.c}.
|
||||
|
||||
Did you add the AVCodecID to @file{avcodec.h}?
|
||||
When adding new codec IDs, also add an entry to the codec descriptor
|
||||
list in @file{libavcodec/codec_desc.c}.
|
||||
@item
|
||||
If it has a FourCC, did you add it to @file{libavformat/riff.c},
|
||||
even if it is only a decoder?
|
||||
|
||||
If it has a FourCC, did you add it to @file{libavformat/riff.c},
|
||||
even if it is only a decoder?
|
||||
@item
|
||||
Did you add a rule to compile the appropriate files in the Makefile?
|
||||
Remember to do this even if you're just adding a format to a file that is
|
||||
already being compiled by some other rule, like a raw demuxer.
|
||||
|
||||
Did you add a rule to compile the appropriate files in the Makefile?
|
||||
Remember to do this even if you're just adding a format to a file that is
|
||||
already being compiled by some other rule, like a raw demuxer.
|
||||
@item
|
||||
Did you add an entry to the table of supported formats or codecs in
|
||||
@file{doc/general.texi}?
|
||||
|
||||
Did you add an entry to the table of supported formats or codecs in
|
||||
@file{doc/general.texi}?
|
||||
@item
|
||||
Did you add an entry in the Changelog?
|
||||
|
||||
Did you add an entry in the Changelog?
|
||||
@item
|
||||
If it depends on a parser or a library, did you add that dependency in
|
||||
configure?
|
||||
|
||||
If it depends on a parser or a library, did you add that dependency in
|
||||
configure?
|
||||
@item
|
||||
Did you @code{git add} the appropriate files before committing?
|
||||
|
||||
Did you @code{git add} the appropriate files before committing?
|
||||
@item
|
||||
Did you make sure it compiles standalone, i.e. with
|
||||
@code{configure --disable-everything --enable-decoder=foo}
|
||||
(or @code{--enable-demuxer} or whatever your component is)?
|
||||
Did you make sure it compiles standalone, i.e. with
|
||||
@code{configure --disable-everything --enable-decoder=foo}
|
||||
(or @code{--enable-demuxer} or whatever your component is)?
|
||||
@end enumerate
|
||||
|
||||
|
||||
@@ -498,109 +452,82 @@ Did you make sure it compiles standalone, i.e. with
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Does @code{make fate} pass with the patch applied?
|
||||
|
||||
Does @code{make fate} pass with the patch applied?
|
||||
@item
|
||||
Was the patch generated with git format-patch or send-email?
|
||||
|
||||
Was the patch generated with git format-patch or send-email?
|
||||
@item
|
||||
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.
|
||||
|
||||
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?
|
||||
|
||||
Did you provide a clear git commit log message?
|
||||
@item
|
||||
Is the patch against latest FFmpeg git master branch?
|
||||
|
||||
Is the patch against latest FFmpeg git master branch?
|
||||
@item
|
||||
Are you subscribed to ffmpeg-devel?
|
||||
(the list is subscribers only due to spam)
|
||||
|
||||
Are you subscribed to ffmpeg-devel?
|
||||
(the list is subscribers only due to spam)
|
||||
@item
|
||||
Have you checked that the changes are minimal, so that the same cannot be
|
||||
achieved with a smaller patch and/or simpler final code?
|
||||
|
||||
Have you checked that the changes are minimal, so that the same cannot be
|
||||
achieved with a smaller patch and/or simpler final code?
|
||||
@item
|
||||
If the change is to speed critical code, did you benchmark it?
|
||||
|
||||
If the change is to speed critical code, did you benchmark it?
|
||||
@item
|
||||
If you did any benchmarks, did you provide them in the mail?
|
||||
|
||||
If you did any benchmarks, did you provide them in the mail?
|
||||
@item
|
||||
Have you checked that the patch does not introduce buffer overflows or
|
||||
other security issues?
|
||||
|
||||
Have you checked that the patch does not introduce buffer overflows or
|
||||
other security issues?
|
||||
@item
|
||||
Did you test your decoder or demuxer against damaged data? If no, see
|
||||
tools/trasher, the noise bitstream filter, and
|
||||
@uref{http://caca.zoy.org/wiki/zzuf, zzuf}. Your decoder or demuxer
|
||||
should not crash, end in a (near) infinite loop, or allocate ridiculous
|
||||
amounts of memory when fed damaged data.
|
||||
|
||||
Did you test your decoder or demuxer against damaged data? If no, see
|
||||
tools/trasher, the noise bitstream filter, and
|
||||
@uref{http://caca.zoy.org/wiki/zzuf, zzuf}. Your decoder or demuxer
|
||||
should not crash, end in a (near) infinite loop, or allocate ridiculous
|
||||
amounts of memory when fed damaged data.
|
||||
@item
|
||||
Does the patch not mix functional and cosmetic changes?
|
||||
|
||||
Does the patch not mix functional and cosmetic changes?
|
||||
@item
|
||||
Did you add tabs or trailing whitespace to the code? Both are forbidden.
|
||||
|
||||
Did you add tabs or trailing whitespace to the code? Both are forbidden.
|
||||
@item
|
||||
Is the patch attached to the email you send?
|
||||
|
||||
Is the patch attached to the email you send?
|
||||
@item
|
||||
Is the mime type of the patch correct? It should be text/x-diff or
|
||||
text/x-patch or at least text/plain and not application/octet-stream.
|
||||
|
||||
Is the mime type of the patch correct? It should be text/x-diff or
|
||||
text/x-patch or at least text/plain and not application/octet-stream.
|
||||
@item
|
||||
If the patch fixes a bug, did you provide a verbose analysis of the bug?
|
||||
|
||||
If the patch fixes a bug, did you provide a verbose analysis of the bug?
|
||||
@item
|
||||
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 ftp://upload.ffmpeg.org
|
||||
|
||||
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 ftp://upload.ffmpeg.org
|
||||
@item
|
||||
Did you provide a verbose summary about what the patch does change?
|
||||
|
||||
Did you provide a verbose summary about what the patch does change?
|
||||
@item
|
||||
Did you provide a verbose explanation why it changes things like it does?
|
||||
|
||||
Did you provide a verbose explanation why it changes things like it does?
|
||||
@item
|
||||
Did you provide a verbose summary of the user visible advantages and
|
||||
disadvantages if the patch is applied?
|
||||
|
||||
Did you provide a verbose summary of the user visible advantages and
|
||||
disadvantages if the patch is applied?
|
||||
@item
|
||||
Did you provide an example so we can verify the new feature added by the
|
||||
patch easily?
|
||||
|
||||
Did you provide an example so we can verify the new feature added by the
|
||||
patch easily?
|
||||
@item
|
||||
If you added a new file, did you insert a license header? It should be
|
||||
taken from FFmpeg, not randomly copied and pasted from somewhere else.
|
||||
|
||||
If you added a new file, did you insert a license header? It should be
|
||||
taken from FFmpeg, not randomly copied and pasted from somewhere else.
|
||||
@item
|
||||
You should maintain alphabetical order in alphabetically ordered lists as
|
||||
long as doing so does not break API/ABI compatibility.
|
||||
|
||||
You should maintain alphabetical order in alphabetically ordered lists as
|
||||
long as doing so does not break API/ABI compatibility.
|
||||
@item
|
||||
Lines with similar content should be aligned vertically when doing so
|
||||
improves readability.
|
||||
|
||||
Lines with similar content should be aligned vertically when doing so
|
||||
improves readability.
|
||||
@item
|
||||
Consider to add a regression test for your code.
|
||||
|
||||
Consider to add a regression test for your code.
|
||||
@item
|
||||
If you added YASM code please check that things still work with --disable-yasm
|
||||
|
||||
If you added YASM code please check that things still work with --disable-yasm
|
||||
@item
|
||||
Make sure you check the return values of function and return appropriate
|
||||
error codes. Especially memory allocation functions like @code{av_malloc()}
|
||||
are notoriously left unchecked, which is a serious problem.
|
||||
|
||||
Make sure you check the return values of function and return appropriate
|
||||
error codes. Especially memory allocation functions like @code{av_malloc()}
|
||||
are notoriously left unchecked, which is a serious problem.
|
||||
@item
|
||||
Test your code with valgrind and or Address Sanitizer to ensure it's free
|
||||
of leaks, out of array accesses, etc.
|
||||
Test your code with valgrind and or Address Sanitizer to ensure it's free
|
||||
of leaks, out of array accesses, etc.
|
||||
@end enumerate
|
||||
|
||||
@section Patch review process
|
||||
@@ -663,15 +590,12 @@ the following steps:
|
||||
@item
|
||||
Configure to compile with instrumentation enabled:
|
||||
@code{configure --toolchain=gcov}.
|
||||
|
||||
@item
|
||||
Run your test case, either manually or via FATE. This can be either
|
||||
the full FATE regression suite, or any arbitrary invocation of any
|
||||
front-end tool provided by FFmpeg, in any combination.
|
||||
|
||||
@item
|
||||
Run @code{make lcov} to generate coverage data in HTML format.
|
||||
|
||||
@item
|
||||
View @code{lcov/index.html} in your preferred HTML viewer.
|
||||
@end enumerate
|
||||
@@ -706,13 +630,12 @@ There are two kinds of releases:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
@strong{Major releases} always include the latest and greatest
|
||||
features and functionality.
|
||||
|
||||
@strong{Major releases} always include the latest and greatest
|
||||
features and functionality.
|
||||
@item
|
||||
@strong{Point releases} are cut from @strong{release} branches,
|
||||
which are named @code{release/X}, with @code{X} being the release
|
||||
version number.
|
||||
@strong{Point releases} are cut from @strong{release} branches,
|
||||
which are named @code{release/X}, with @code{X} being the release
|
||||
version number.
|
||||
@end enumerate
|
||||
|
||||
Note that we promise to our users that shared libraries from any FFmpeg
|
||||
@@ -733,18 +656,15 @@ inclusion into a point release:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Fixes a security issue, preferably identified by a @strong{CVE
|
||||
number} issued by @url{http://cve.mitre.org/}.
|
||||
|
||||
Fixes a security issue, preferably identified by a @strong{CVE
|
||||
number} issued by @url{http://cve.mitre.org/}.
|
||||
@item
|
||||
Fixes a documented bug in @url{https://trac.ffmpeg.org}.
|
||||
|
||||
Fixes a documented bug in @url{https://trac.ffmpeg.org}.
|
||||
@item
|
||||
Improves the included documentation.
|
||||
|
||||
Improves the included documentation.
|
||||
@item
|
||||
Retains both source code and binary compatibility with previous
|
||||
point releases of the same release branch.
|
||||
Retains both source code and binary compatibility with previous
|
||||
point releases of the same release branch.
|
||||
@end enumerate
|
||||
|
||||
The order for checking the rules is (1 OR 2 OR 3) AND 4.
|
||||
@@ -756,42 +676,33 @@ The release process involves the following steps:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Ensure that the @file{RELEASE} file contains the version number for
|
||||
the upcoming release.
|
||||
|
||||
Ensure that the @file{RELEASE} file contains the version number for
|
||||
the upcoming release.
|
||||
@item
|
||||
Add the release at @url{https://trac.ffmpeg.org/admin/ticket/versions}.
|
||||
|
||||
Add the release at @url{https://trac.ffmpeg.org/admin/ticket/versions}.
|
||||
@item
|
||||
Announce the intent to do a release to the mailing list.
|
||||
|
||||
Announce the intent to do a release to the mailing list.
|
||||
@item
|
||||
Make sure all relevant security fixes have been backported. See
|
||||
@url{https://ffmpeg.org/security.html}.
|
||||
|
||||
Make sure all relevant security fixes have been backported. See
|
||||
@url{https://ffmpeg.org/security.html}.
|
||||
@item
|
||||
Ensure that the FATE regression suite still passes in the release
|
||||
branch on at least @strong{i386} and @strong{amd64}
|
||||
(cf. @ref{Regression tests}).
|
||||
|
||||
Ensure that the FATE regression suite still passes in the release
|
||||
branch on at least @strong{i386} and @strong{amd64}
|
||||
(cf. @ref{Regression tests}).
|
||||
@item
|
||||
Prepare the release tarballs in @code{bz2} and @code{gz} formats, and
|
||||
supplementing files that contain @code{gpg} signatures
|
||||
|
||||
Prepare the release tarballs in @code{bz2} and @code{gz} formats, and
|
||||
supplementing files that contain @code{gpg} signatures
|
||||
@item
|
||||
Publish the tarballs at @url{http://ffmpeg.org/releases}. Create and
|
||||
push an annotated tag in the form @code{nX}, with @code{X}
|
||||
containing the version number.
|
||||
|
||||
Publish the tarballs at @url{http://ffmpeg.org/releases}. Create and
|
||||
push an annotated tag in the form @code{nX}, with @code{X}
|
||||
containing the version number.
|
||||
@item
|
||||
Propose and send a patch to the @strong{ffmpeg-devel} mailing list
|
||||
with a news entry for the website.
|
||||
|
||||
Propose and send a patch to the @strong{ffmpeg-devel} mailing list
|
||||
with a news entry for the website.
|
||||
@item
|
||||
Publish the news entry.
|
||||
|
||||
Publish the news entry.
|
||||
@item
|
||||
Send announcement to the mailing list.
|
||||
Send announcement to the mailing list.
|
||||
@end enumerate
|
||||
|
||||
@bye
|
||||
|
||||
@@ -17,9 +17,5 @@ for programmatic use.
|
||||
|
||||
@c man end DEVICE OPTIONS
|
||||
|
||||
@ifclear config-writeonly
|
||||
@include indevs.texi
|
||||
@end ifclear
|
||||
@ifclear config-readonly
|
||||
@include outdevs.texi
|
||||
@end ifclear
|
||||
|
||||
@@ -8,5 +8,7 @@ shift 2
|
||||
doxygen - <<EOF
|
||||
@INCLUDE = ${DOXYFILE}
|
||||
INPUT = $@
|
||||
EXAMPLE_PATH = ${SRC_PATH}/doc/examples
|
||||
HTML_HEADER = ${SRC_PATH}/doc/doxy/header.html
|
||||
HTML_FOOTER = ${SRC_PATH}/doc/doxy/footer.html
|
||||
HTML_STYLESHEET = ${SRC_PATH}/doc/doxy/doxy_stylesheet.css
|
||||
EOF
|
||||
|
||||
2019
doc/doxy/doxy_stylesheet.css
Normal file
2019
doc/doxy/doxy_stylesheet.css
Normal file
File diff suppressed because it is too large
Load Diff
9
doc/doxy/footer.html
Normal file
9
doc/doxy/footer.html
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
<footer class="footer pagination-right">
|
||||
<span class="label label-info">
|
||||
Generated on $datetime for $projectname by <a href="http://www.doxygen.org/index.html">doxygen</a> $doxygenversion
|
||||
</span>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
16
doc/doxy/header.html
Normal file
16
doc/doxy/header.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
|
||||
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
|
||||
<link href="$relpath$doxy_stylesheet.css" rel="stylesheet" type="text/css" />
|
||||
<!--Header replace -->
|
||||
|
||||
</head>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<!--Header replace -->
|
||||
<div class="menu">
|
||||
@@ -14,7 +14,7 @@ You can disable all the encoders with the configure option
|
||||
with the options @code{--enable-encoder=@var{ENCODER}} /
|
||||
@code{--disable-encoder=@var{ENCODER}}.
|
||||
|
||||
The option @code{-encoders} of the ff* tools will display the list of
|
||||
The option @code{-codecs} of the ff* tools will display the list of
|
||||
enabled encoders.
|
||||
|
||||
@c man end ENCODERS
|
||||
@@ -38,8 +38,8 @@ As this encoder is experimental, unexpected behavior may exist from time to
|
||||
time. For a more stable AAC encoder, see @ref{libvo-aacenc}. However, be warned
|
||||
that it has a worse quality reported by some users.
|
||||
|
||||
@c todo @ref{libaacplus}
|
||||
See also @ref{libfdk-aac-enc,,libfdk_aac} and @ref{libfaac}.
|
||||
@c Comment this out until somebody writes the respective documentation.
|
||||
@c See also @ref{libfaac}, @ref{libaacplus}, and @ref{libfdk-aac-enc}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@@ -71,7 +71,7 @@ Force middle/side encoding.
|
||||
Set AAC encoder coding method. Possible values:
|
||||
|
||||
@table @samp
|
||||
@item faac
|
||||
@item 0
|
||||
FAAC-inspired method.
|
||||
|
||||
This method is a simplified reimplementation of the method used in FAAC, which
|
||||
@@ -82,13 +82,13 @@ distortion below threshold band by band.
|
||||
The quality of this method is comparable to the two loop searching method
|
||||
descibed below, but somewhat a little better and slower.
|
||||
|
||||
@item anmr
|
||||
@item 1
|
||||
Average noise to mask ratio (ANMR) trellis-based solution.
|
||||
|
||||
This has a theoretic best quality out of all the coding methods, but at the
|
||||
cost of the slowest speed.
|
||||
|
||||
@item twoloop
|
||||
@item 2
|
||||
Two loop searching (TLS) method.
|
||||
|
||||
This method first sets quantizers depending on band thresholds and then tries
|
||||
@@ -97,7 +97,7 @@ all quantizers and adjusting some individual quantizer a little.
|
||||
|
||||
This method produces similar quality with the FAAC method and is the default.
|
||||
|
||||
@item fast
|
||||
@item 3
|
||||
Constant quantizer method.
|
||||
|
||||
This method sets a constant quantizer for all bands. This is the fastest of all
|
||||
@@ -107,6 +107,13 @@ the methods, yet produces the worst quality.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Tips and Tricks
|
||||
|
||||
According to some reports
|
||||
(e.g. @url{http://d.hatena.ne.jp/kamedo2/20120729/1343545890}), setting the
|
||||
@option{cutoff} option to 15000 Hz greatly improves the quality of the output
|
||||
quality. As a result, we encourage you to do the same.
|
||||
|
||||
@section ac3 and ac3_fixed
|
||||
|
||||
AC-3 audio encoders.
|
||||
@@ -494,286 +501,6 @@ Selected by Encoder (default)
|
||||
|
||||
@end table
|
||||
|
||||
@anchor{libfaac}
|
||||
@section libfaac
|
||||
|
||||
libfaac AAC (Advanced Audio Coding) encoder wrapper.
|
||||
|
||||
Requires the presence of the libfaac headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libfaac --enable-nonfree}.
|
||||
|
||||
This encoder is considered to be of higher quality with respect to the
|
||||
@ref{aacenc,,the native experimental FFmpeg AAC encoder}.
|
||||
|
||||
For more information see the libfaac project at
|
||||
@url{http://www.audiocoding.com/faac.html/}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following shared FFmpeg codec options are recognized.
|
||||
|
||||
The following options are supported by the libfaac wrapper. The
|
||||
@command{faac}-equivalent of the options are listed in parentheses.
|
||||
|
||||
@table @option
|
||||
@item b (@emph{-b})
|
||||
Set bit rate in bits/s for ABR (Average Bit Rate) mode. If the bit rate
|
||||
is not explicitly specified, it is automatically set to a suitable
|
||||
value depending on the selected profile. @command{faac} bitrate is
|
||||
expressed in kilobits/s.
|
||||
|
||||
Note that libfaac does not support CBR (Constant Bit Rate) but only
|
||||
ABR (Average Bit Rate).
|
||||
|
||||
If VBR mode is enabled this option is ignored.
|
||||
|
||||
@item ar (@emph{-R})
|
||||
Set audio sampling rate (in Hz).
|
||||
|
||||
@item ac (@emph{-c})
|
||||
Set the number of audio channels.
|
||||
|
||||
@item cutoff (@emph{-C})
|
||||
Set cutoff frequency. If not specified (or explicitly set to 0) it
|
||||
will use a value automatically computed by the library. Default value
|
||||
is 0.
|
||||
|
||||
@item profile
|
||||
Set audio profile.
|
||||
|
||||
The following profiles are recognized:
|
||||
@table @samp
|
||||
@item aac_main
|
||||
Main AAC (Main)
|
||||
|
||||
@item aac_low
|
||||
Low Complexity AAC (LC)
|
||||
|
||||
@item aac_ssr
|
||||
Scalable Sample Rate (SSR)
|
||||
|
||||
@item aac_ltp
|
||||
Long Term Prediction (LTP)
|
||||
@end table
|
||||
|
||||
If not specified it is set to @samp{aac_low}.
|
||||
|
||||
@item flags +qscale
|
||||
Set constant quality VBR (Variable Bit Rate) mode.
|
||||
|
||||
@item global_quality
|
||||
Set quality in VBR mode as an integer number of lambda units.
|
||||
|
||||
Only relevant when VBR mode is enabled with @code{flags +qscale}. The
|
||||
value is converted to QP units by dividing it by @code{FF_QP2LAMBDA},
|
||||
and used to set the quality value used by libfaac. A reasonable range
|
||||
for the option value in QP units is [10-500], the higher the value the
|
||||
higher the quality.
|
||||
|
||||
@item q (@emph{-q})
|
||||
Enable VBR mode when set to a non-negative value, and set constant
|
||||
quality value as a double floating point value in QP units.
|
||||
|
||||
The value sets the quality value used by libfaac. A reasonable range
|
||||
for the option value is [10-500], the higher the value the higher the
|
||||
quality.
|
||||
|
||||
This option is valid only using the @command{ffmpeg} command-line
|
||||
tool. For library interface users, use @option{global_quality}.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Use @command{ffmpeg} to convert an audio file to ABR 128 kbps AAC in an M4A (MP4)
|
||||
container:
|
||||
@example
|
||||
ffmpeg -i input.wav -codec:a libfaac -b:a 128k -output.m4a
|
||||
@end example
|
||||
|
||||
@item
|
||||
Use @command{ffmpeg} to convert an audio file to VBR AAC, using the
|
||||
LTP AAC profile:
|
||||
@example
|
||||
ffmpeg -i input.wav -c:a libfaac -profile:a aac_ltp -q:a 100 output.m4a
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@anchor{libfdk-aac-enc}
|
||||
@section libfdk_aac
|
||||
|
||||
libfdk-aac AAC (Advanced Audio Coding) encoder wrapper.
|
||||
|
||||
The libfdk-aac library is based on the Fraunhofer FDK AAC code from
|
||||
the Android project.
|
||||
|
||||
Requires the presence of the libfdk-aac headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libfdk-aac}. The library is also incompatible with GPL,
|
||||
so if you allow the use of GPL, you should configure with
|
||||
@code{--enable-gpl --enable-nonfree --enable-libfdk-aac}.
|
||||
|
||||
This encoder is considered to be of higher quality with respect to
|
||||
both @ref{aacenc,,the native experimental FFmpeg AAC encoder} and
|
||||
@ref{libfaac}.
|
||||
|
||||
VBR encoding, enabled through the @option{vbr} or @option{flags
|
||||
+qscale} options, is experimental and only works with some
|
||||
combinations of parameters.
|
||||
|
||||
Support for encoding 7.1 audio is only available with libfdk-aac 0.1.3 or
|
||||
higher.
|
||||
|
||||
For more information see the fdk-aac project at
|
||||
@url{http://sourceforge.net/p/opencore-amr/fdk-aac/}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following options are mapped on the shared FFmpeg codec options.
|
||||
|
||||
@table @option
|
||||
@item b
|
||||
Set bit rate in bits/s. If the bitrate is not explicitly specified, it
|
||||
is automatically set to a suitable value depending on the selected
|
||||
profile.
|
||||
|
||||
In case VBR mode is enabled the option is ignored.
|
||||
|
||||
@item ar
|
||||
Set audio sampling rate (in Hz).
|
||||
|
||||
@item channels
|
||||
Set the number of audio channels.
|
||||
|
||||
@item flags +qscale
|
||||
Enable fixed quality, VBR (Variable Bit Rate) mode.
|
||||
Note that VBR is implicitly enabled when the @option{vbr} value is
|
||||
positive.
|
||||
|
||||
@item cutoff
|
||||
Set cutoff frequency. If not specified (or explicitly set to 0) it
|
||||
will use a value automatically computed by the library. Default value
|
||||
is 0.
|
||||
|
||||
@item profile
|
||||
Set audio profile.
|
||||
|
||||
The following profiles are recognized:
|
||||
@table @samp
|
||||
@item aac_low
|
||||
Low Complexity AAC (LC)
|
||||
|
||||
@item aac_he
|
||||
High Efficiency AAC (HE-AAC)
|
||||
|
||||
@item aac_he_v2
|
||||
High Efficiency AAC version 2 (HE-AACv2)
|
||||
|
||||
@item aac_ld
|
||||
Low Delay AAC (LD)
|
||||
|
||||
@item aac_eld
|
||||
Enhanced Low Delay AAC (ELD)
|
||||
@end table
|
||||
|
||||
If not specified it is set to @samp{aac_low}.
|
||||
@end table
|
||||
|
||||
The following are private options of the libfdk_aac encoder.
|
||||
|
||||
@table @option
|
||||
@item afterburner
|
||||
Enable afterburner feature if set to 1, disabled if set to 0. This
|
||||
improves the quality but also the required processing power.
|
||||
|
||||
Default value is 1.
|
||||
|
||||
@item eld_sbr
|
||||
Enable SBR (Spectral Band Replication) for ELD if set to 1, disabled
|
||||
if set to 0.
|
||||
|
||||
Default value is 0.
|
||||
|
||||
@item signaling
|
||||
Set SBR/PS signaling style.
|
||||
|
||||
It can assume one of the following values:
|
||||
@table @samp
|
||||
@item default
|
||||
choose signaling implicitly (explicit hierarchical by default,
|
||||
implicit if global header is disabled)
|
||||
|
||||
@item implicit
|
||||
implicit backwards compatible signaling
|
||||
|
||||
@item explicit_sbr
|
||||
explicit SBR, implicit PS signaling
|
||||
|
||||
@item explicit_hierarchical
|
||||
explicit hierarchical signaling
|
||||
@end table
|
||||
|
||||
Default value is @samp{default}.
|
||||
|
||||
@item latm
|
||||
Output LATM/LOAS encapsulated data if set to 1, disabled if set to 0.
|
||||
|
||||
Default value is 0.
|
||||
|
||||
@item header_period
|
||||
Set StreamMuxConfig and PCE repetition period (in frames) for sending
|
||||
in-band configuration buffers within LATM/LOAS transport layer.
|
||||
|
||||
Must be a 16-bits non-negative integer.
|
||||
|
||||
Default value is 0.
|
||||
|
||||
@item vbr
|
||||
Set VBR mode, from 1 to 5. 1 is lowest quality (though still pretty
|
||||
good) and 5 is highest quality. A value of 0 will disable VBR, and CBR
|
||||
(Constant Bit Rate) is enabled.
|
||||
|
||||
Currently only the @samp{aac_low} profile supports VBR encoding.
|
||||
|
||||
VBR modes 1-5 correspond to roughly the following average bit rates:
|
||||
|
||||
@table @samp
|
||||
@item 1
|
||||
32 kbps/channel
|
||||
@item 2
|
||||
40 kbps/channel
|
||||
@item 3
|
||||
48-56 kbps/channel
|
||||
@item 4
|
||||
64 kbps/channel
|
||||
@item 5
|
||||
about 80-96 kbps/channel
|
||||
@end table
|
||||
|
||||
Default value is 0.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Use @command{ffmpeg} to convert an audio file to VBR AAC in an M4A (MP4)
|
||||
container:
|
||||
@example
|
||||
ffmpeg -i input.wav -codec:a libfdk_aac -vbr 3 output.m4a
|
||||
@end example
|
||||
|
||||
@item
|
||||
Use @command{ffmpeg} to convert an audio file to CBR 64k kbps AAC, using the
|
||||
High-Efficiency AAC profile:
|
||||
@example
|
||||
ffmpeg -i input.wav -c:a libfdk_aac -profile:a aac_he -b:a 64k output.m4a
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@anchor{libmp3lame}
|
||||
@section libmp3lame
|
||||
|
||||
LAME (Lame Ain't an MP3 Encoder) MP3 encoder wrapper.
|
||||
@@ -782,9 +509,6 @@ Requires the presence of the libmp3lame headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libmp3lame}.
|
||||
|
||||
See @ref{libshine} for a fixed-point MP3 encoder, although with a
|
||||
lower quality.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following options are supported by the libmp3lame wrapper. The
|
||||
@@ -792,7 +516,7 @@ The following options are supported by the libmp3lame wrapper. The
|
||||
|
||||
@table @option
|
||||
@item b (@emph{-b})
|
||||
Set bitrate expressed in bits/s for CBR or ABR. LAME @code{bitrate} is
|
||||
Set bitrate expressed in bits/s for CBR. LAME @code{bitrate} is
|
||||
expressed in kilobits/s.
|
||||
|
||||
@item q (@emph{-V})
|
||||
@@ -814,11 +538,6 @@ has this enabled by default, but can be overriden by use
|
||||
Enable the encoder to use (on a frame by frame basis) either L/R
|
||||
stereo or mid/side stereo. Default value is 1.
|
||||
|
||||
@item abr (@emph{--abr})
|
||||
Enable the encoder to use ABR when set to 1. The @command{lame}
|
||||
@option{--abr} sets the target bitrate, while this options only
|
||||
tells FFmpeg to use ABR still relies on @option{b} to set bitrate.
|
||||
|
||||
@end table
|
||||
|
||||
@section libopencore-amrnb
|
||||
@@ -858,42 +577,6 @@ default value is 0 (disabled).
|
||||
|
||||
@end table
|
||||
|
||||
@anchor{libshine}
|
||||
@section libshine
|
||||
|
||||
Shine Fixed-Point MP3 encoder wrapper.
|
||||
|
||||
Shine is a fixed-point MP3 encoder. It has a far better performance on
|
||||
platforms without an FPU, e.g. armel CPUs, and some phones and tablets.
|
||||
However, as it is more targeted on performance than quality, it is not on par
|
||||
with LAME and other production-grade encoders quality-wise. Also, according to
|
||||
the project's homepage, this encoder may not be free of bugs as the code was
|
||||
written a long time ago and the project was dead for at least 5 years.
|
||||
|
||||
This encoder only supports stereo and mono input. This is also CBR-only.
|
||||
|
||||
The original project (last updated in early 2007) is at
|
||||
@url{http://sourceforge.net/projects/libshine-fxp/}. We only support the
|
||||
updated fork by the Savonet/Liquidsoap project at @url{https://github.com/savonet/shine}.
|
||||
|
||||
Requires the presence of the libshine headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libshine}.
|
||||
|
||||
See also @ref{libmp3lame}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following options are supported by the libshine wrapper. The
|
||||
@command{shineenc}-equivalent of the options are listed in parentheses.
|
||||
|
||||
@table @option
|
||||
@item b (@emph{-b})
|
||||
Set bitrate expressed in bits/s for CBR. @command{shineenc} @option{-b} option
|
||||
is expressed in kilobits/s.
|
||||
|
||||
@end table
|
||||
|
||||
@section libtwolame
|
||||
|
||||
TwoLAME MP2 encoder wrapper.
|
||||
@@ -1095,163 +778,32 @@ respectively. The default is 0 (cutoff disabled).
|
||||
|
||||
@end table
|
||||
|
||||
@section libvorbis
|
||||
|
||||
libvorbis encoder wrapper.
|
||||
|
||||
Requires the presence of the libvorbisenc headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libvorbis}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following options are supported by the libvorbis wrapper. The
|
||||
@command{oggenc}-equivalent of the options are listed in parentheses.
|
||||
|
||||
To get a more accurate and extensive documentation of the libvorbis
|
||||
options, consult the libvorbisenc's and @command{oggenc}'s documentations.
|
||||
See @url{http://xiph.org/vorbis/},
|
||||
@url{http://wiki.xiph.org/Vorbis-tools}, and oggenc(1).
|
||||
|
||||
@table @option
|
||||
@item b (@emph{-b})
|
||||
Set bitrate expressed in bits/s for ABR. @command{oggenc} @option{-b} is
|
||||
expressed in kilobits/s.
|
||||
|
||||
@item q (@emph{-q})
|
||||
Set constant quality setting for VBR. The value should be a float
|
||||
number in the range of -1.0 to 10.0. The higher the value, the better
|
||||
the quality. The default value is @samp{3.0}.
|
||||
|
||||
This option is valid only using the @command{ffmpeg} command-line tool.
|
||||
For library interface users, use @option{global_quality}.
|
||||
|
||||
@item cutoff (@emph{--advanced-encode-option lowpass_frequency=N})
|
||||
Set cutoff bandwidth in Hz, a value of 0 disables cutoff. @command{oggenc}'s
|
||||
related option is expressed in kHz. The default value is @samp{0} (cutoff
|
||||
disabled).
|
||||
|
||||
@item minrate (@emph{-m})
|
||||
Set minimum bitrate expressed in bits/s. @command{oggenc} @option{-m} is
|
||||
expressed in kilobits/s.
|
||||
|
||||
@item maxrate (@emph{-M})
|
||||
Set maximum bitrate expressed in bits/s. @command{oggenc} @option{-M} is
|
||||
expressed in kilobits/s. This only has effect on ABR mode.
|
||||
|
||||
@item iblock (@emph{--advanced-encode-option impulse_noisetune=N})
|
||||
Set noise floor bias for impulse blocks. The value is a float number from
|
||||
-15.0 to 0.0. A negative bias instructs the encoder to pay special attention
|
||||
to the crispness of transients in the encoded audio. The tradeoff for better
|
||||
transient response is a higher bitrate.
|
||||
|
||||
@end table
|
||||
|
||||
@anchor{libwavpack}
|
||||
@section libwavpack
|
||||
|
||||
A wrapper providing WavPack encoding through libwavpack.
|
||||
|
||||
Only lossless mode using 32-bit integer samples is supported currently.
|
||||
|
||||
Requires the presence of the libwavpack headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libwavpack}.
|
||||
|
||||
Note that a libavcodec-native encoder for the WavPack codec exists so users can
|
||||
encode audios with this codec without using this encoder. See @ref{wavpackenc}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@command{wavpack} command line utility's corresponding options are listed in
|
||||
parentheses, if any.
|
||||
The @option{compression_level} option can be used to control speed vs.
|
||||
compression tradeoff, with the values mapped to libwavpack as follows:
|
||||
|
||||
@table @option
|
||||
@item frame_size (@emph{--blocksize})
|
||||
Default is 32768.
|
||||
|
||||
@item compression_level
|
||||
Set speed vs. compression tradeoff. Acceptable arguments are listed below:
|
||||
|
||||
@table @samp
|
||||
@item 0 (@emph{-f})
|
||||
Fast mode.
|
||||
@item 0
|
||||
Fast mode - corresponding to the wavpack @option{-f} option.
|
||||
|
||||
@item 1
|
||||
Normal (default) settings.
|
||||
|
||||
@item 2 (@emph{-h})
|
||||
High quality.
|
||||
@item 2
|
||||
High quality - corresponding to the wavpack @option{-h} option.
|
||||
|
||||
@item 3 (@emph{-hh})
|
||||
Very high quality.
|
||||
@item 3
|
||||
Very high quality - corresponding to the wavpack @option{-hh} option.
|
||||
|
||||
@item 4-8 (@emph{-hh -x}@var{EXTRAPROC})
|
||||
Same as @samp{3}, but with extra processing enabled.
|
||||
|
||||
@samp{4} is the same as @option{-x2} and @samp{8} is the same as @option{-x6}.
|
||||
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@anchor{wavpackenc}
|
||||
@section wavpack
|
||||
|
||||
WavPack lossless audio encoder.
|
||||
|
||||
This is a libavcodec-native WavPack encoder. There is also an encoder based on
|
||||
libwavpack, but there is virtually no reason to use that encoder.
|
||||
|
||||
See also @ref{libwavpack}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The equivalent options for @command{wavpack} command line utility are listed in
|
||||
parentheses.
|
||||
|
||||
@subsubsection Shared options
|
||||
|
||||
The following shared options are effective for this encoder. Only special notes
|
||||
about this particular encoder will be documented here. For the general meaning
|
||||
of the options, see @ref{codec-options,,the Codec Options chapter}.
|
||||
|
||||
@table @option
|
||||
@item frame_size (@emph{--blocksize})
|
||||
For this encoder, the range for this option is between 128 and 131072. Default
|
||||
is automatically decided based on sample rate and number of channel.
|
||||
|
||||
For the complete formula of calculating default, see
|
||||
@file{libavcodec/wavpackenc.c}.
|
||||
|
||||
@item compression_level (@emph{-f}, @emph{-h}, @emph{-hh}, and @emph{-x})
|
||||
This option's syntax is consistent with @ref{libwavpack}'s.
|
||||
@end table
|
||||
|
||||
@subsubsection Private options
|
||||
|
||||
@table @option
|
||||
@item joint_stereo (@emph{-j})
|
||||
Set whether to enable joint stereo. Valid values are:
|
||||
|
||||
@table @samp
|
||||
@item on (@emph{1})
|
||||
Force mid/side audio encoding.
|
||||
@item off (@emph{0})
|
||||
Force left/right audio encoding.
|
||||
@item auto
|
||||
Let the encoder decide automatically.
|
||||
@end table
|
||||
|
||||
@item optimize_mono
|
||||
Set whether to enable optimization for mono. This option is only effective for
|
||||
non-mono streams. Available values:
|
||||
|
||||
@table @samp
|
||||
@item on
|
||||
enabled
|
||||
@item off
|
||||
disabled
|
||||
@end table
|
||||
@item 4-8
|
||||
Same as 3, but with extra processing enabled - corresponding to the wavpack
|
||||
@option{-x} option. I.e. 4 is the same as @option{-x2} and 8 is the same as
|
||||
@option{-x6}.
|
||||
|
||||
@end table
|
||||
|
||||
@@ -1265,15 +817,12 @@ follows.
|
||||
|
||||
@section libtheora
|
||||
|
||||
libtheora Theora encoder wrapper.
|
||||
Theora format supported through libtheora.
|
||||
|
||||
Requires the presence of the libtheora headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libtheora}.
|
||||
|
||||
For more information about the libtheora project see
|
||||
@url{http://www.theora.org/}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following global options are mapped to internal libtheora options
|
||||
@@ -1281,11 +830,11 @@ which affect the quality and the bitrate of the encoded stream.
|
||||
|
||||
@table @option
|
||||
@item b
|
||||
Set the video bitrate in bit/s for CBR (Constant Bit Rate) mode. In
|
||||
case VBR (Variable Bit Rate) mode is enabled this option is ignored.
|
||||
Set the video bitrate, only works if the @code{qscale} flag in
|
||||
@option{flags} is not enabled.
|
||||
|
||||
@item flags
|
||||
Used to enable constant quality mode (VBR) encoding through the
|
||||
Used to enable constant quality mode encoding through the
|
||||
@option{qscale} flag, and to enable the @code{pass1} and @code{pass2}
|
||||
modes.
|
||||
|
||||
@@ -1293,41 +842,19 @@ modes.
|
||||
Set the GOP size.
|
||||
|
||||
@item global_quality
|
||||
Set the global quality as an integer in lambda units.
|
||||
Set the global quality in lambda units, only works if the
|
||||
@code{qscale} flag in @option{flags} is enabled. The value is clipped
|
||||
in the [0 - 10*@code{FF_QP2LAMBDA}] range, and then multiplied for 6.3
|
||||
to get a value in the native libtheora range [0-63]. A higher value
|
||||
corresponds to a higher quality.
|
||||
|
||||
Only relevant when VBR mode is enabled with @code{flags +qscale}. The
|
||||
value is converted to QP units by dividing it by @code{FF_QP2LAMBDA},
|
||||
clipped in the [0 - 10] range, and then multiplied by 6.3 to get a
|
||||
value in the native libtheora range [0-63]. A higher value corresponds
|
||||
to a higher quality.
|
||||
|
||||
@item q
|
||||
Enable VBR mode when set to a non-negative value, and set constant
|
||||
quality value as a double floating point value in QP units.
|
||||
|
||||
The value is clipped in the [0-10] range, and then multiplied by 6.3
|
||||
to get a value in the native libtheora range [0-63].
|
||||
|
||||
This option is valid only using the @command{ffmpeg} command-line
|
||||
tool. For library interface users, use @option{global_quality}.
|
||||
For example, to set maximum constant quality encoding with
|
||||
@command{ffmpeg}:
|
||||
@example
|
||||
ffmpeg -i INPUT -flags:v qscale -global_quality:v "10*QP2LAMBDA" -codec:v libtheora OUTPUT.ogg
|
||||
@end example
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Set maximum constant quality (VBR) encoding with @command{ffmpeg}:
|
||||
@example
|
||||
ffmpeg -i INPUT -codec:v libtheora -q:v 10 OUTPUT.ogg
|
||||
@end example
|
||||
|
||||
@item
|
||||
Use @command{ffmpeg} to convert a CBR 1000 kbps Theora video stream:
|
||||
@example
|
||||
ffmpeg -i INPUT -codec:v libtheora -b:v 1000k OUTPUT.ogg
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@section libvpx
|
||||
|
||||
VP8 format supported through libvpx.
|
||||
@@ -1447,69 +974,7 @@ g_error_resilient
|
||||
For more information about libvpx see:
|
||||
@url{http://www.webmproject.org/}
|
||||
|
||||
|
||||
@section libwebp
|
||||
|
||||
libwebp WebP Image encoder wrapper
|
||||
|
||||
libwebp is Google's official encoder for WebP images. It can encode in either
|
||||
lossy or lossless mode. Lossy images are essentially a wrapper around a VP8
|
||||
frame. Lossless images are a separate codec developed by Google.
|
||||
|
||||
@subsection Pixel Format
|
||||
|
||||
Currently, libwebp only supports YUV420 for lossy and RGB for lossless due
|
||||
to limitations of the format and libwebp. Alpha is supported for either mode.
|
||||
Because of API limitations, if RGB is passed in when encoding lossy or YUV is
|
||||
passed in for encoding lossless, the pixel format will automatically be
|
||||
converted using functions from libwebp. This is not ideal and is done only for
|
||||
convenience.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item -lossless @var{boolean}
|
||||
Enables/Disables use of lossless mode. Default is 0.
|
||||
|
||||
@item -compression_level @var{integer}
|
||||
For lossy, this is a quality/speed tradeoff. Higher values give better quality
|
||||
for a given size at the cost of increased encoding time. For lossless, this is
|
||||
a size/speed tradeoff. Higher values give smaller size at the cost of increased
|
||||
encoding time. More specifically, it controls the number of extra algorithms
|
||||
and compression tools used, and varies the combination of these tools. This
|
||||
maps to the @var{method} option in libwebp. The valid range is 0 to 6.
|
||||
Default is 4.
|
||||
|
||||
@item -qscale @var{float}
|
||||
For lossy encoding, this controls image quality, 0 to 100. For lossless
|
||||
encoding, this controls the effort and time spent at compressing more. The
|
||||
default value is 75. Note that for usage via libavcodec, this option is called
|
||||
@var{global_quality} and must be multiplied by @var{FF_QP2LAMBDA}.
|
||||
|
||||
@item -preset @var{type}
|
||||
Configuration preset. This does some automatic settings based on the general
|
||||
type of the image.
|
||||
@table @option
|
||||
@item none
|
||||
Do not use a preset.
|
||||
@item default
|
||||
Use the encoder default.
|
||||
@item picture
|
||||
Digital picture, like portrait, inner shot
|
||||
@item photo
|
||||
Outdoor photograph, with natural lighting
|
||||
@item drawing
|
||||
Hand or line drawing, with high-contrast details
|
||||
@item icon
|
||||
Small-sized colorful images
|
||||
@item text
|
||||
Text-like
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@section libx264, libx264rgb
|
||||
@section libx264
|
||||
|
||||
x264 H.264/MPEG-4 AVC encoder wrapper.
|
||||
|
||||
@@ -1531,16 +996,6 @@ by the libx264 @code{x264_param_parse} function.
|
||||
The x264 project website is at
|
||||
@url{http://www.videolan.org/developers/x264.html}.
|
||||
|
||||
The libx264rgb encoder is the same as libx264, except it accepts packed RGB
|
||||
pixel formats as input instead of YUV.
|
||||
|
||||
@subsection Supported Pixel Formats
|
||||
|
||||
x264 supports 8- to 10-bit color spaces. The exact bit depth is controlled at
|
||||
x264's configure time. FFmpeg only supports one bit depth in one particular
|
||||
build. In other words, it is not possible to build one FFmpeg with multiple
|
||||
versions of x264 with different bit depths.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following options are supported by the libx264 wrapper. The
|
||||
@@ -1729,10 +1184,6 @@ Enable calculation and printing SSIM stats after the encoding.
|
||||
Enable the use of Periodic Intra Refresh instead of IDR frames when set
|
||||
to 1.
|
||||
|
||||
@item bluray-compat (@emph{bluray-compat})
|
||||
Configure the encoder to be compatible with the bluray standard.
|
||||
It is a shorthand for setting "bluray-compat=1 force-cfr=1".
|
||||
|
||||
@item b-bias (@emph{b-bias})
|
||||
Set the influence on how often B-frames are used.
|
||||
|
||||
@@ -1977,56 +1428,6 @@ half pixel and quarter pixel refinement for 8x8 blocks, and rate
|
||||
distortion-based search using square pattern.
|
||||
@end table
|
||||
|
||||
@item lumi_aq
|
||||
Enable lumi masking adaptive quantization when set to 1. Default is 0
|
||||
(disabled).
|
||||
|
||||
@item variance_aq
|
||||
Enable variance adaptive quantization when set to 1. Default is 0
|
||||
(disabled).
|
||||
|
||||
When combined with @option{lumi_aq}, the resulting quality will not
|
||||
be better than any of the two specified individually. In other
|
||||
words, the resulting quality will be the worse one of the two
|
||||
effects.
|
||||
|
||||
@item ssim
|
||||
Set structural similarity (SSIM) displaying method. Possible values:
|
||||
|
||||
@table @samp
|
||||
@item off
|
||||
Disable displaying of SSIM information.
|
||||
|
||||
@item avg
|
||||
Output average SSIM at the end of encoding to stdout. The format of
|
||||
showing the average SSIM is:
|
||||
|
||||
@example
|
||||
Average SSIM: %f
|
||||
@end example
|
||||
|
||||
For users who are not familiar with C, %f means a float number, or
|
||||
a decimal (e.g. 0.939232).
|
||||
|
||||
@item frame
|
||||
Output both per-frame SSIM data during encoding and average SSIM at
|
||||
the end of encoding to stdout. The format of per-frame information
|
||||
is:
|
||||
|
||||
@example
|
||||
SSIM: avg: %1.3f min: %1.3f max: %1.3f
|
||||
@end example
|
||||
|
||||
For users who are not familiar with C, %1.3f means a float number
|
||||
rounded to 3 digits after the dot (e.g. 0.932).
|
||||
|
||||
@end table
|
||||
|
||||
@item ssim_acc
|
||||
Set SSIM accuracy. Valid options are integers within the range of
|
||||
0-4, while 0 gives the most accurate result and 4 computes the
|
||||
fastest.
|
||||
|
||||
@end table
|
||||
|
||||
@section png
|
||||
|
||||
@@ -11,24 +11,20 @@ CFLAGS += -Wall -g
|
||||
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
|
||||
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
|
||||
|
||||
EXAMPLES= avio_reading \
|
||||
avcodec \
|
||||
demuxing_decoding \
|
||||
EXAMPLES= decoding_encoding \
|
||||
demuxing \
|
||||
filtering_video \
|
||||
filtering_audio \
|
||||
metadata \
|
||||
muxing \
|
||||
remuxing \
|
||||
resampling_audio \
|
||||
scaling_video \
|
||||
transcode_aac \
|
||||
|
||||
OBJS=$(addsuffix .o,$(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
|
||||
|
||||
.phony: all clean-test clean
|
||||
|
||||
|
||||
@@ -5,19 +5,14 @@ Both following use cases rely on pkg-config and make, thus make sure
|
||||
that you have them installed and working on your system.
|
||||
|
||||
|
||||
Method 1: build the installed examples in a generic read/write user directory
|
||||
1) Build the installed examples in a generic read/write user directory
|
||||
|
||||
Copy to a read/write user directory and just use "make", it will link
|
||||
to the libraries on your system, assuming the PKG_CONFIG_PATH is
|
||||
correctly configured.
|
||||
|
||||
Method 2: build the examples in-tree
|
||||
2) Build the examples in-tree
|
||||
|
||||
Assuming you are in the source FFmpeg checkout directory, you need to build
|
||||
FFmpeg (no need to make install in any prefix). Then just run "make examples".
|
||||
This will build the examples using the FFmpeg build system. You can clean those
|
||||
examples using "make examplesclean"
|
||||
|
||||
If you want to try the dedicated Makefile examples (to emulate the first
|
||||
method), go into doc/examples and run a command such as
|
||||
PKG_CONFIG_PATH=pc-uninstalled make.
|
||||
FFmpeg (no need to make install in any prefix). Then you can go into the
|
||||
doc/examples and run a command such as PKG_CONFIG_PATH=pc-uninstalled make.
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Stefano Sabatini
|
||||
*
|
||||
* 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
|
||||
* libavformat AVIOContext API example.
|
||||
*
|
||||
* Make libavformat demuxer access media content through a custom
|
||||
* AVIOContext read callback.
|
||||
* @example avio_reading.c
|
||||
*/
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavformat/avio.h>
|
||||
#include <libavutil/file.h>
|
||||
|
||||
struct buffer_data {
|
||||
uint8_t *ptr;
|
||||
size_t size; ///< size left in the buffer
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
printf("ptr:%p size:%zu\n", bd->ptr, bd->size);
|
||||
|
||||
/* copy internal buffer data to buf */
|
||||
memcpy(buf, bd->ptr, buf_size);
|
||||
bd->ptr += buf_size;
|
||||
bd->size -= buf_size;
|
||||
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
AVFormatContext *fmt_ctx = NULL;
|
||||
AVIOContext *avio_ctx = NULL;
|
||||
uint8_t *buffer = NULL, *avio_ctx_buffer = NULL;
|
||||
size_t buffer_size, avio_ctx_buffer_size = 4096;
|
||||
char *input_filename = NULL;
|
||||
int ret = 0;
|
||||
struct buffer_data bd = { 0 };
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s input_file\n"
|
||||
"API example program to show how to read from a custom buffer "
|
||||
"accessed through AVIOContext.\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
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)
|
||||
goto end;
|
||||
|
||||
/* fill opaque structure used by the AVIOContext read callback */
|
||||
bd.ptr = buffer;
|
||||
bd.size = buffer_size;
|
||||
|
||||
if (!(fmt_ctx = avformat_alloc_context())) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
avio_ctx_buffer = av_malloc(avio_ctx_buffer_size);
|
||||
if (!avio_ctx_buffer) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,
|
||||
0, &bd, &read_packet, NULL, NULL);
|
||||
if (!avio_ctx) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
fmt_ctx->pb = avio_ctx;
|
||||
|
||||
ret = avformat_open_input(&fmt_ctx, NULL, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open input\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avformat_find_stream_info(fmt_ctx, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not find stream information\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
av_dump_format(fmt_ctx, 0, input_filename, 0);
|
||||
|
||||
end:
|
||||
avformat_close_input(&fmt_ctx);
|
||||
/* note: the internal buffer could have changed, and be != avio_ctx_buffer */
|
||||
if (avio_ctx) {
|
||||
av_freep(&avio_ctx->buffer);
|
||||
av_freep(&avio_ctx);
|
||||
}
|
||||
av_file_unmap(buffer, buffer_size);
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -24,10 +24,10 @@
|
||||
* @file
|
||||
* libavcodec API use example.
|
||||
*
|
||||
* @example avcodec.c
|
||||
* Note that libavcodec only handles codecs (mpeg, mpeg4, etc...),
|
||||
* not file formats (avi, vob, mp4, mov, mkv, mxf, flv, mpegts, mpegps, etc...). See library 'libavformat' for the
|
||||
* format handling
|
||||
* @example doc/examples/decoding_encoding.c
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
@@ -156,7 +156,7 @@ static void audio_encode_example(const char *filename)
|
||||
}
|
||||
|
||||
/* frame containing input raw audio */
|
||||
frame = av_frame_alloc();
|
||||
frame = avcodec_alloc_frame();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate audio frame\n");
|
||||
exit(1);
|
||||
@@ -170,10 +170,6 @@ static void audio_encode_example(const char *filename)
|
||||
* 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",
|
||||
@@ -191,7 +187,7 @@ static void audio_encode_example(const char *filename)
|
||||
/* encode a single tone sound */
|
||||
t = 0;
|
||||
tincr = 2 * M_PI * 440.0 / c->sample_rate;
|
||||
for (i = 0; i < 200; i++) {
|
||||
for(i=0;i<200;i++) {
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL; // packet data will be allocated by the encoder
|
||||
pkt.size = 0;
|
||||
@@ -231,7 +227,7 @@ static void audio_encode_example(const char *filename)
|
||||
fclose(f);
|
||||
|
||||
av_freep(&samples);
|
||||
av_frame_free(&frame);
|
||||
avcodec_free_frame(&frame);
|
||||
avcodec_close(c);
|
||||
av_free(c);
|
||||
}
|
||||
@@ -291,11 +287,12 @@ static void audio_decode_example(const char *outfilename, const char *filename)
|
||||
int got_frame = 0;
|
||||
|
||||
if (!decoded_frame) {
|
||||
if (!(decoded_frame = av_frame_alloc())) {
|
||||
if (!(decoded_frame = avcodec_alloc_frame())) {
|
||||
fprintf(stderr, "Could not allocate audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} else
|
||||
avcodec_get_frame_defaults(decoded_frame);
|
||||
|
||||
len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
|
||||
if (len < 0) {
|
||||
@@ -307,11 +304,6 @@ static void audio_decode_example(const char *outfilename, const char *filename)
|
||||
int data_size = av_samples_get_buffer_size(NULL, c->channels,
|
||||
decoded_frame->nb_samples,
|
||||
c->sample_fmt, 1);
|
||||
if (data_size < 0) {
|
||||
/* This should not occur, checking just for paranoia */
|
||||
fprintf(stderr, "Failed to calculate data size\n");
|
||||
exit(1);
|
||||
}
|
||||
fwrite(decoded_frame->data[0], 1, data_size, outfile);
|
||||
}
|
||||
avpkt.size -= len;
|
||||
@@ -337,7 +329,7 @@ static void audio_decode_example(const char *outfilename, const char *filename)
|
||||
|
||||
avcodec_close(c);
|
||||
av_free(c);
|
||||
av_frame_free(&decoded_frame);
|
||||
avcodec_free_frame(&decoded_frame);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -374,12 +366,12 @@ static void video_encode_example(const char *filename, int codec_id)
|
||||
c->width = 352;
|
||||
c->height = 288;
|
||||
/* frames per second */
|
||||
c->time_base = (AVRational){1,25};
|
||||
c->time_base= (AVRational){1,25};
|
||||
c->gop_size = 10; /* emit one intra frame every ten frames */
|
||||
c->max_b_frames = 1;
|
||||
c->max_b_frames=1;
|
||||
c->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||
|
||||
if (codec_id == AV_CODEC_ID_H264)
|
||||
if(codec_id == AV_CODEC_ID_H264)
|
||||
av_opt_set(c->priv_data, "preset", "slow", 0);
|
||||
|
||||
/* open it */
|
||||
@@ -394,7 +386,7 @@ static void video_encode_example(const char *filename, int codec_id)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
frame = avcodec_alloc_frame();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate video frame\n");
|
||||
exit(1);
|
||||
@@ -413,7 +405,7 @@ static void video_encode_example(const char *filename, int codec_id)
|
||||
}
|
||||
|
||||
/* encode 1 second of video */
|
||||
for (i = 0; i < 25; i++) {
|
||||
for(i=0;i<25;i++) {
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL; // packet data will be allocated by the encoder
|
||||
pkt.size = 0;
|
||||
@@ -421,15 +413,15 @@ static void video_encode_example(const char *filename, int codec_id)
|
||||
fflush(stdout);
|
||||
/* prepare a dummy image */
|
||||
/* Y */
|
||||
for (y = 0; y < c->height; y++) {
|
||||
for (x = 0; x < c->width; x++) {
|
||||
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++) {
|
||||
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;
|
||||
}
|
||||
@@ -475,7 +467,7 @@ static void video_encode_example(const char *filename, int codec_id)
|
||||
avcodec_close(c);
|
||||
av_free(c);
|
||||
av_freep(&frame->data[0]);
|
||||
av_frame_free(&frame);
|
||||
avcodec_free_frame(&frame);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@@ -489,10 +481,10 @@ static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -573,14 +565,14 @@ static void video_decode_example(const char *outfilename, const char *filename)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
frame = avcodec_alloc_frame();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate video frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame_count = 0;
|
||||
for (;;) {
|
||||
for(;;) {
|
||||
avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
|
||||
if (avpkt.size == 0)
|
||||
break;
|
||||
@@ -617,7 +609,7 @@ static void video_decode_example(const char *outfilename, const char *filename)
|
||||
|
||||
avcodec_close(c);
|
||||
av_free(c);
|
||||
av_frame_free(&frame);
|
||||
avcodec_free_frame(&frame);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Demuxing and decoding example.
|
||||
* libavformat demuxing API use example.
|
||||
*
|
||||
* Show how to use the libavformat and libavcodec API to demux and
|
||||
* decode audio and video data.
|
||||
* @example demuxing_decoding.c
|
||||
* @example doc/examples/demuxing.c
|
||||
*/
|
||||
|
||||
#include <libavutil/imgutils.h>
|
||||
@@ -47,36 +47,25 @@ static uint8_t *video_dst_data[4] = {NULL};
|
||||
static int video_dst_linesize[4];
|
||||
static int video_dst_bufsize;
|
||||
|
||||
static uint8_t **audio_dst_data = NULL;
|
||||
static int audio_dst_linesize;
|
||||
static int audio_dst_bufsize;
|
||||
|
||||
static int video_stream_idx = -1, audio_stream_idx = -1;
|
||||
static AVFrame *frame = NULL;
|
||||
static AVPacket pkt;
|
||||
static int video_frame_count = 0;
|
||||
static int audio_frame_count = 0;
|
||||
|
||||
/* The different ways of decoding and managing data memory. You are not
|
||||
* supposed to support all the modes in your application but pick the one most
|
||||
* appropriate to your needs. Look for the use of api_mode in this example to
|
||||
* see what are the differences of API usage between them */
|
||||
enum {
|
||||
API_MODE_OLD = 0, /* old method, deprecated */
|
||||
API_MODE_NEW_API_REF_COUNT = 1, /* new method, using the frame reference counting */
|
||||
API_MODE_NEW_API_NO_REF_COUNT = 2, /* new method, without reference counting */
|
||||
};
|
||||
|
||||
static int api_mode = API_MODE_OLD;
|
||||
|
||||
static int decode_packet(int *got_frame, int cached)
|
||||
{
|
||||
int ret = 0;
|
||||
int decoded = pkt.size;
|
||||
|
||||
*got_frame = 0;
|
||||
|
||||
if (pkt.stream_index == video_stream_idx) {
|
||||
/* decode video frame */
|
||||
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));
|
||||
fprintf(stderr, "Error decoding video frame\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -99,40 +88,40 @@ static int decode_packet(int *got_frame, int cached)
|
||||
/* 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));
|
||||
fprintf(stderr, "Error decoding audio frame\n");
|
||||
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);
|
||||
ret = av_samples_alloc(audio_dst_data, &audio_dst_linesize, av_frame_get_channels(frame),
|
||||
frame->nb_samples, frame->format, 1);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate audio buffer\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* TODO: extend return code of the av_samples_* functions so that this call is not needed */
|
||||
audio_dst_bufsize =
|
||||
av_samples_get_buffer_size(NULL, av_frame_get_channels(frame),
|
||||
frame->nb_samples, frame->format, 1);
|
||||
|
||||
/* copy audio data to destination buffer:
|
||||
* this is required since rawaudio expects non aligned data */
|
||||
av_samples_copy(audio_dst_data, frame->data, 0, 0,
|
||||
frame->nb_samples, av_frame_get_channels(frame), frame->format);
|
||||
|
||||
/* write to rawaudio file */
|
||||
fwrite(audio_dst_data[0], 1, audio_dst_bufsize, audio_dst_file);
|
||||
av_freep(&audio_dst_data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we use the new API with reference counting, we own the data and need
|
||||
* to de-reference it when we don't use it anymore */
|
||||
if (*got_frame && api_mode == API_MODE_NEW_API_REF_COUNT)
|
||||
av_frame_unref(frame);
|
||||
|
||||
return decoded;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int open_codec_context(int *stream_idx,
|
||||
@@ -142,7 +131,6 @@ static int open_codec_context(int *stream_idx,
|
||||
AVStream *st;
|
||||
AVCodecContext *dec_ctx = NULL;
|
||||
AVCodec *dec = NULL;
|
||||
AVDictionary *opts = NULL;
|
||||
|
||||
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
|
||||
if (ret < 0) {
|
||||
@@ -159,13 +147,10 @@ static int open_codec_context(int *stream_idx,
|
||||
if (!dec) {
|
||||
fprintf(stderr, "Failed to find %s codec\n",
|
||||
av_get_media_type_string(type));
|
||||
return AVERROR(EINVAL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Init the decoders, with or without reference counting */
|
||||
if (api_mode == API_MODE_NEW_API_REF_COUNT)
|
||||
av_dict_set(&opts, "refcounted_frames", "1", 0);
|
||||
if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) {
|
||||
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
||||
fprintf(stderr, "Failed to open %s codec\n",
|
||||
av_get_media_type_string(type));
|
||||
return ret;
|
||||
@@ -208,31 +193,15 @@ int main (int argc, char **argv)
|
||||
{
|
||||
int ret = 0, got_frame;
|
||||
|
||||
if (argc != 4 && argc != 5) {
|
||||
fprintf(stderr, "usage: %s [-refcount=<old|new_norefcount|new_refcount>] "
|
||||
"input_file video_output_file audio_output_file\n"
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "usage: %s 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\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. If unset, it's using\n"
|
||||
"the classic old method.\n"
|
||||
"audio frames to a rawaudio file named audio_output_file.\n"
|
||||
"\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if (argc == 5) {
|
||||
const char *mode = argv[1] + strlen("-refcount=");
|
||||
if (!strcmp(mode, "old")) api_mode = API_MODE_OLD;
|
||||
else if (!strcmp(mode, "new_norefcount")) api_mode = API_MODE_NEW_API_NO_REF_COUNT;
|
||||
else if (!strcmp(mode, "new_refcount")) api_mode = API_MODE_NEW_API_REF_COUNT;
|
||||
else {
|
||||
fprintf(stderr, "unknow mode '%s'\n", mode);
|
||||
exit(1);
|
||||
}
|
||||
argv++;
|
||||
}
|
||||
src_filename = argv[1];
|
||||
video_dst_filename = argv[2];
|
||||
audio_dst_filename = argv[3];
|
||||
@@ -275,6 +244,8 @@ int main (int argc, char **argv)
|
||||
}
|
||||
|
||||
if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {
|
||||
int nb_planes;
|
||||
|
||||
audio_stream = fmt_ctx->streams[audio_stream_idx];
|
||||
audio_dec_ctx = audio_stream->codec;
|
||||
audio_dst_file = fopen(audio_dst_filename, "wb");
|
||||
@@ -283,6 +254,15 @@ int main (int argc, char **argv)
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
nb_planes = av_sample_fmt_is_planar(audio_dec_ctx->sample_fmt) ?
|
||||
audio_dec_ctx->channels : 1;
|
||||
audio_dst_data = av_mallocz(sizeof(uint8_t *) * nb_planes);
|
||||
if (!audio_dst_data) {
|
||||
fprintf(stderr, "Could not allocate audio data buffers\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* dump input information to stderr */
|
||||
@@ -294,12 +274,7 @@ int main (int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* When using the new API, you need to use the libavutil/frame.h API, while
|
||||
* the classic frame management is available in libavcodec */
|
||||
if (api_mode == API_MODE_OLD)
|
||||
frame = avcodec_alloc_frame();
|
||||
else
|
||||
frame = av_frame_alloc();
|
||||
frame = avcodec_alloc_frame();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate frame\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
@@ -318,15 +293,8 @@ int main (int argc, char **argv)
|
||||
|
||||
/* read frames from the file */
|
||||
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_free_packet(&orig_pkt);
|
||||
decode_packet(&got_frame, 0);
|
||||
av_free_packet(&pkt);
|
||||
}
|
||||
|
||||
/* flush cached frames */
|
||||
@@ -346,41 +314,29 @@ int main (int argc, char **argv)
|
||||
}
|
||||
|
||||
if (audio_stream) {
|
||||
enum AVSampleFormat sfmt = audio_dec_ctx->sample_fmt;
|
||||
int n_channels = audio_dec_ctx->channels;
|
||||
const char *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 = 1;
|
||||
}
|
||||
|
||||
if ((ret = get_format_from_sample_fmt(&fmt, sfmt)) < 0)
|
||||
if ((ret = get_format_from_sample_fmt(&fmt, audio_dec_ctx->sample_fmt)) < 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, audio_dec_ctx->sample_rate,
|
||||
fmt, audio_dec_ctx->channels, audio_dec_ctx->sample_rate,
|
||||
audio_dst_filename);
|
||||
}
|
||||
|
||||
end:
|
||||
avcodec_close(video_dec_ctx);
|
||||
avcodec_close(audio_dec_ctx);
|
||||
if (video_dec_ctx)
|
||||
avcodec_close(video_dec_ctx);
|
||||
if (audio_dec_ctx)
|
||||
avcodec_close(audio_dec_ctx);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
if (video_dst_file)
|
||||
fclose(video_dst_file);
|
||||
if (audio_dst_file)
|
||||
fclose(audio_dst_file);
|
||||
if (api_mode == API_MODE_OLD)
|
||||
avcodec_free_frame(&frame);
|
||||
else
|
||||
av_frame_free(&frame);
|
||||
av_free(frame);
|
||||
av_free(video_dst_data[0]);
|
||||
av_free(audio_dst_data);
|
||||
|
||||
return ret < 0;
|
||||
}
|
||||
@@ -1,364 +0,0 @@
|
||||
/*
|
||||
* copyright (c) 2013 Andrew Kelley
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* libavfilter API usage example.
|
||||
*
|
||||
* @example filter_audio.c
|
||||
* This example will generate a sine wave audio,
|
||||
* pass it through a simple filter chain, and then compute the MD5 checksum of
|
||||
* the output data.
|
||||
*
|
||||
* The filter chain it uses is:
|
||||
* (input) -> abuffer -> volume -> aformat -> abuffersink -> (output)
|
||||
*
|
||||
* abuffer: This provides the endpoint where you can feed the decoded samples.
|
||||
* volume: In this example we hardcode it to 0.90.
|
||||
* aformat: This converts the samples to the samplefreq, channel layout,
|
||||
* and sample format required by the audio device.
|
||||
* abuffersink: This provides the endpoint where you can read the samples after
|
||||
* they have passed through the filter chain.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/md5.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/samplefmt.h"
|
||||
|
||||
#include "libavfilter/avfilter.h"
|
||||
#include "libavfilter/buffersink.h"
|
||||
#include "libavfilter/buffersrc.h"
|
||||
|
||||
#define INPUT_SAMPLERATE 48000
|
||||
#define INPUT_FORMAT AV_SAMPLE_FMT_FLTP
|
||||
#define INPUT_CHANNEL_LAYOUT AV_CH_LAYOUT_5POINT0
|
||||
|
||||
#define VOLUME_VAL 0.90
|
||||
|
||||
static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src,
|
||||
AVFilterContext **sink)
|
||||
{
|
||||
AVFilterGraph *filter_graph;
|
||||
AVFilterContext *abuffer_ctx;
|
||||
AVFilter *abuffer;
|
||||
AVFilterContext *volume_ctx;
|
||||
AVFilter *volume;
|
||||
AVFilterContext *aformat_ctx;
|
||||
AVFilter *aformat;
|
||||
AVFilterContext *abuffersink_ctx;
|
||||
AVFilter *abuffersink;
|
||||
|
||||
AVDictionary *options_dict = NULL;
|
||||
uint8_t options_str[1024];
|
||||
uint8_t ch_layout[64];
|
||||
|
||||
int err;
|
||||
|
||||
/* Create a new filtergraph, which will contain all the filters. */
|
||||
filter_graph = avfilter_graph_alloc();
|
||||
if (!filter_graph) {
|
||||
fprintf(stderr, "Unable to create filter graph.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* Create the abuffer filter;
|
||||
* it will be used for feeding the data into the graph. */
|
||||
abuffer = avfilter_get_by_name("abuffer");
|
||||
if (!abuffer) {
|
||||
fprintf(stderr, "Could not find the abuffer filter.\n");
|
||||
return AVERROR_FILTER_NOT_FOUND;
|
||||
}
|
||||
|
||||
abuffer_ctx = avfilter_graph_alloc_filter(filter_graph, abuffer, "src");
|
||||
if (!abuffer_ctx) {
|
||||
fprintf(stderr, "Could not allocate the abuffer instance.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* Set the filter options through the AVOptions API. */
|
||||
av_get_channel_layout_string(ch_layout, sizeof(ch_layout), 0, INPUT_CHANNEL_LAYOUT);
|
||||
av_opt_set (abuffer_ctx, "channel_layout", ch_layout, AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set (abuffer_ctx, "sample_fmt", av_get_sample_fmt_name(INPUT_FORMAT), AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_q (abuffer_ctx, "time_base", (AVRational){ 1, INPUT_SAMPLERATE }, AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_int(abuffer_ctx, "sample_rate", INPUT_SAMPLERATE, AV_OPT_SEARCH_CHILDREN);
|
||||
|
||||
/* Now initialize the filter; we pass NULL options, since we have already
|
||||
* set all the options above. */
|
||||
err = avfilter_init_str(abuffer_ctx, NULL);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Could not initialize the abuffer filter.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Create volume filter. */
|
||||
volume = avfilter_get_by_name("volume");
|
||||
if (!volume) {
|
||||
fprintf(stderr, "Could not find the volume filter.\n");
|
||||
return AVERROR_FILTER_NOT_FOUND;
|
||||
}
|
||||
|
||||
volume_ctx = avfilter_graph_alloc_filter(filter_graph, volume, "volume");
|
||||
if (!volume_ctx) {
|
||||
fprintf(stderr, "Could not allocate the volume instance.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* A different way of passing the options is as key/value pairs in a
|
||||
* dictionary. */
|
||||
av_dict_set(&options_dict, "volume", AV_STRINGIFY(VOLUME_VAL), 0);
|
||||
err = avfilter_init_dict(volume_ctx, &options_dict);
|
||||
av_dict_free(&options_dict);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Could not initialize the volume filter.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Create the aformat filter;
|
||||
* it ensures that the output is of the format we want. */
|
||||
aformat = avfilter_get_by_name("aformat");
|
||||
if (!aformat) {
|
||||
fprintf(stderr, "Could not find the aformat filter.\n");
|
||||
return AVERROR_FILTER_NOT_FOUND;
|
||||
}
|
||||
|
||||
aformat_ctx = avfilter_graph_alloc_filter(filter_graph, aformat, "aformat");
|
||||
if (!aformat_ctx) {
|
||||
fprintf(stderr, "Could not allocate the aformat instance.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* A third way of passing the options is in a string of the form
|
||||
* key1=value1:key2=value2.... */
|
||||
snprintf(options_str, sizeof(options_str),
|
||||
"sample_fmts=%s:sample_rates=%d:channel_layouts=0x%"PRIx64,
|
||||
av_get_sample_fmt_name(AV_SAMPLE_FMT_S16), 44100,
|
||||
(uint64_t)AV_CH_LAYOUT_STEREO);
|
||||
err = avfilter_init_str(aformat_ctx, options_str);
|
||||
if (err < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Could not initialize the aformat filter.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Finally create the abuffersink filter;
|
||||
* it will be used to get the filtered data out of the graph. */
|
||||
abuffersink = avfilter_get_by_name("abuffersink");
|
||||
if (!abuffersink) {
|
||||
fprintf(stderr, "Could not find the abuffersink filter.\n");
|
||||
return AVERROR_FILTER_NOT_FOUND;
|
||||
}
|
||||
|
||||
abuffersink_ctx = avfilter_graph_alloc_filter(filter_graph, abuffersink, "sink");
|
||||
if (!abuffersink_ctx) {
|
||||
fprintf(stderr, "Could not allocate the abuffersink instance.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* This filter takes no options. */
|
||||
err = avfilter_init_str(abuffersink_ctx, NULL);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Could not initialize the abuffersink instance.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Connect the filters;
|
||||
* in this simple case the filters just form a linear chain. */
|
||||
err = avfilter_link(abuffer_ctx, 0, volume_ctx, 0);
|
||||
if (err >= 0)
|
||||
err = avfilter_link(volume_ctx, 0, aformat_ctx, 0);
|
||||
if (err >= 0)
|
||||
err = avfilter_link(aformat_ctx, 0, abuffersink_ctx, 0);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Error connecting filters\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Configure the graph. */
|
||||
err = avfilter_graph_config(filter_graph, NULL);
|
||||
if (err < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error configuring the filter graph\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
*graph = filter_graph;
|
||||
*src = abuffer_ctx;
|
||||
*sink = abuffersink_ctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do something useful with the filtered data: this simple
|
||||
* example just prints the MD5 checksum of each plane to stdout. */
|
||||
static int process_output(struct AVMD5 *md5, AVFrame *frame)
|
||||
{
|
||||
int planar = av_sample_fmt_is_planar(frame->format);
|
||||
int channels = av_get_channel_layout_nb_channels(frame->channel_layout);
|
||||
int planes = planar ? channels : 1;
|
||||
int bps = av_get_bytes_per_sample(frame->format);
|
||||
int plane_size = bps * frame->nb_samples * (planar ? 1 : channels);
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < planes; i++) {
|
||||
uint8_t checksum[16];
|
||||
|
||||
av_md5_init(md5);
|
||||
av_md5_sum(checksum, frame->extended_data[i], plane_size);
|
||||
|
||||
fprintf(stdout, "plane %d: 0x", i);
|
||||
for (j = 0; j < sizeof(checksum); j++)
|
||||
fprintf(stdout, "%02X", checksum[j]);
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Construct a frame of audio data to be filtered;
|
||||
* this simple example just synthesizes a sine wave. */
|
||||
static int get_input(AVFrame *frame, int frame_num)
|
||||
{
|
||||
int err, i, j;
|
||||
|
||||
#define FRAME_SIZE 1024
|
||||
|
||||
/* Set up the frame properties and allocate the buffer for the data. */
|
||||
frame->sample_rate = INPUT_SAMPLERATE;
|
||||
frame->format = INPUT_FORMAT;
|
||||
frame->channel_layout = INPUT_CHANNEL_LAYOUT;
|
||||
frame->nb_samples = FRAME_SIZE;
|
||||
frame->pts = frame_num * FRAME_SIZE;
|
||||
|
||||
err = av_frame_get_buffer(frame, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Fill the data for each channel. */
|
||||
for (i = 0; i < 5; i++) {
|
||||
float *data = (float*)frame->extended_data[i];
|
||||
|
||||
for (j = 0; j < frame->nb_samples; j++)
|
||||
data[j] = sin(2 * M_PI * (frame_num + j) * (i + 1) / FRAME_SIZE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct AVMD5 *md5;
|
||||
AVFilterGraph *graph;
|
||||
AVFilterContext *src, *sink;
|
||||
AVFrame *frame;
|
||||
uint8_t errstr[1024];
|
||||
float duration;
|
||||
int err, nb_frames, i;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s <duration>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
duration = atof(argv[1]);
|
||||
nb_frames = duration * INPUT_SAMPLERATE / FRAME_SIZE;
|
||||
if (nb_frames <= 0) {
|
||||
fprintf(stderr, "Invalid duration: %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
avfilter_register_all();
|
||||
|
||||
/* Allocate the frame we will be using to store the data. */
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Error allocating the frame\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
md5 = av_md5_alloc();
|
||||
if (!md5) {
|
||||
fprintf(stderr, "Error allocating the MD5 context\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set up the filtergraph. */
|
||||
err = init_filter_graph(&graph, &src, &sink);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Unable to init filter graph:");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* the main filtering loop */
|
||||
for (i = 0; i < nb_frames; i++) {
|
||||
/* get an input frame to be filtered */
|
||||
err = get_input(frame, i);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Error generating input frame:");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Send the frame to the input of the filtergraph. */
|
||||
err = av_buffersrc_add_frame(src, frame);
|
||||
if (err < 0) {
|
||||
av_frame_unref(frame);
|
||||
fprintf(stderr, "Error submitting the frame to the filtergraph:");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Get all the filtered output that is available. */
|
||||
while ((err = av_buffersink_get_frame(sink, frame)) >= 0) {
|
||||
/* now do something with our filtered frame */
|
||||
err = process_output(md5, frame);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Error processing the filtered frame:");
|
||||
goto fail;
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
|
||||
if (err == AVERROR(EAGAIN)) {
|
||||
/* Need to feed more frames in. */
|
||||
continue;
|
||||
} else if (err == AVERROR_EOF) {
|
||||
/* Nothing more to do, finish. */
|
||||
break;
|
||||
} else if (err < 0) {
|
||||
/* An error occurred. */
|
||||
fprintf(stderr, "Error filtering the data:");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
avfilter_graph_free(&graph);
|
||||
av_frame_free(&frame);
|
||||
av_freep(&md5);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
av_strerror(err, errstr, sizeof(errstr));
|
||||
fprintf(stderr, "%s\n", errstr);
|
||||
return 1;
|
||||
}
|
||||
@@ -25,7 +25,7 @@
|
||||
/**
|
||||
* @file
|
||||
* API example for audio decoding and filtering
|
||||
* @example filtering_audio.c
|
||||
* @example doc/examples/filtering_audio.c
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
@@ -38,8 +38,8 @@
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavutil/opt.h>
|
||||
|
||||
static const char *filter_descr = "aresample=8000,aformat=sample_fmts=s16:channel_layouts=mono";
|
||||
static const char *player = "ffplay -f s16le -ar 8000 -ac 1 -";
|
||||
const char *filter_descr = "aresample=8000,aformat=sample_fmts=s16:channel_layouts=mono";
|
||||
const char *player = "ffplay -f s16le -ar 8000 -ac 1 -";
|
||||
|
||||
static AVFormatContext *fmt_ctx;
|
||||
static AVCodecContext *dec_ctx;
|
||||
@@ -85,22 +85,18 @@ static int open_input_file(const char *filename)
|
||||
static int init_filters(const char *filters_descr)
|
||||
{
|
||||
char args[512];
|
||||
int ret = 0;
|
||||
int ret;
|
||||
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 };
|
||||
static const int64_t out_channel_layouts[] = { AV_CH_LAYOUT_MONO, -1 };
|
||||
static const int out_sample_rates[] = { 8000, -1 };
|
||||
const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 };
|
||||
const int64_t out_channel_layouts[] = { AV_CH_LAYOUT_MONO, -1 };
|
||||
const int out_sample_rates[] = { 8000, -1 };
|
||||
const AVFilterLink *outlink;
|
||||
AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base;
|
||||
|
||||
filter_graph = avfilter_graph_alloc();
|
||||
if (!outputs || !inputs || !filter_graph) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* buffer audio source: the decoded frames from the decoder will be inserted here. */
|
||||
if (!dec_ctx->channel_layout)
|
||||
@@ -113,7 +109,7 @@ static int init_filters(const char *filters_descr)
|
||||
args, NULL, filter_graph);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
|
||||
goto end;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* buffer audio sink: to terminate the filter chain. */
|
||||
@@ -121,28 +117,28 @@ static int init_filters(const char *filters_descr)
|
||||
NULL, NULL, filter_graph);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");
|
||||
goto end;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = av_opt_set_int_list(buffersink_ctx, "sample_fmts", out_sample_fmts, -1,
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n");
|
||||
goto end;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = av_opt_set_int_list(buffersink_ctx, "channel_layouts", out_channel_layouts, -1,
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
|
||||
goto end;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = av_opt_set_int_list(buffersink_ctx, "sample_rates", out_sample_rates, -1,
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");
|
||||
goto end;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Endpoints for the filter graph. */
|
||||
@@ -157,11 +153,11 @@ static int init_filters(const char *filters_descr)
|
||||
inputs->next = NULL;
|
||||
|
||||
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
|
||||
&inputs, &outputs, NULL)) < 0)
|
||||
goto end;
|
||||
&inputs, &outputs, NULL)) < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
|
||||
goto end;
|
||||
return ret;
|
||||
|
||||
/* Print summary of the sink buffer
|
||||
* Note: args buffer is reused to store channel layout string */
|
||||
@@ -172,11 +168,7 @@ static int init_filters(const char *filters_descr)
|
||||
(char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"),
|
||||
args);
|
||||
|
||||
end:
|
||||
avfilter_inout_free(&inputs);
|
||||
avfilter_inout_free(&outputs);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_frame(const AVFrame *frame)
|
||||
@@ -196,7 +188,7 @@ static void print_frame(const AVFrame *frame)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
AVPacket packet0, packet;
|
||||
AVPacket packet;
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
AVFrame *filt_frame = av_frame_alloc();
|
||||
int got_frame;
|
||||
@@ -210,6 +202,7 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
avcodec_register_all();
|
||||
av_register_all();
|
||||
avfilter_register_all();
|
||||
|
||||
@@ -219,24 +212,18 @@ int main(int argc, char **argv)
|
||||
goto end;
|
||||
|
||||
/* read all packets */
|
||||
packet0.data = NULL;
|
||||
packet.data = NULL;
|
||||
while (1) {
|
||||
if (!packet0.data) {
|
||||
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
|
||||
break;
|
||||
packet0 = packet;
|
||||
}
|
||||
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
|
||||
break;
|
||||
|
||||
if (packet.stream_index == audio_stream_index) {
|
||||
avcodec_get_frame_defaults(frame);
|
||||
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 */
|
||||
@@ -248,31 +235,29 @@ int main(int argc, char **argv)
|
||||
/* pull filtered audio from the filtergraph */
|
||||
while (1) {
|
||||
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
break;
|
||||
if (ret < 0)
|
||||
if(ret < 0)
|
||||
goto end;
|
||||
print_frame(filt_frame);
|
||||
av_frame_unref(filt_frame);
|
||||
}
|
||||
}
|
||||
|
||||
if (packet.size <= 0)
|
||||
av_free_packet(&packet0);
|
||||
} else {
|
||||
/* discard non-wanted packets */
|
||||
av_free_packet(&packet0);
|
||||
}
|
||||
av_free_packet(&packet);
|
||||
}
|
||||
end:
|
||||
avfilter_graph_free(&filter_graph);
|
||||
avcodec_close(dec_ctx);
|
||||
if (dec_ctx)
|
||||
avcodec_close(dec_ctx);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&filt_frame);
|
||||
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
char buf[1024];
|
||||
av_strerror(ret, buf, sizeof(buf));
|
||||
fprintf(stderr, "Error occurred: %s\n", buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
/**
|
||||
* @file
|
||||
* API example for decoding and filtering
|
||||
* @example filtering_video.c
|
||||
* @example doc/examples/filtering_video.c
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 600 /* for usleep */
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <libavfilter/avcodec.h>
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavutil/opt.h>
|
||||
|
||||
const char *filter_descr = "scale=78:24";
|
||||
|
||||
@@ -71,7 +70,6 @@ static int open_input_file(const char *filename)
|
||||
}
|
||||
video_stream_index = ret;
|
||||
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) {
|
||||
@@ -85,18 +83,15 @@ static int open_input_file(const char *filename)
|
||||
static int init_filters(const char *filters_descr)
|
||||
{
|
||||
char args[512];
|
||||
int ret = 0;
|
||||
int ret;
|
||||
AVFilter *buffersrc = avfilter_get_by_name("buffer");
|
||||
AVFilter *buffersink = avfilter_get_by_name("buffersink");
|
||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||
AVFilterInOut *inputs = avfilter_inout_alloc();
|
||||
enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };
|
||||
AVBufferSinkParams *buffersink_params;
|
||||
|
||||
filter_graph = avfilter_graph_alloc();
|
||||
if (!outputs || !inputs || !filter_graph) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* buffer video source: the decoded frames from the decoder will be inserted here. */
|
||||
snprintf(args, sizeof(args),
|
||||
@@ -109,22 +104,18 @@ static int init_filters(const char *filters_descr)
|
||||
args, NULL, filter_graph);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
|
||||
goto end;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* buffer video sink: to terminate the filter chain. */
|
||||
buffersink_params = av_buffersink_params_alloc();
|
||||
buffersink_params->pixel_fmts = pix_fmts;
|
||||
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
|
||||
NULL, NULL, filter_graph);
|
||||
NULL, buffersink_params, filter_graph);
|
||||
av_free(buffersink_params);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts,
|
||||
AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
|
||||
goto end;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Endpoints for the filter graph. */
|
||||
@@ -140,16 +131,11 @@ static int init_filters(const char *filters_descr)
|
||||
|
||||
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
|
||||
&inputs, &outputs, NULL)) < 0)
|
||||
goto end;
|
||||
return ret;
|
||||
|
||||
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
|
||||
goto end;
|
||||
|
||||
end:
|
||||
avfilter_inout_free(&inputs);
|
||||
avfilter_inout_free(&outputs);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void display_frame(const AVFrame *frame, AVRational time_base)
|
||||
@@ -200,6 +186,7 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
avcodec_register_all();
|
||||
av_register_all();
|
||||
avfilter_register_all();
|
||||
|
||||
@@ -214,6 +201,7 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
|
||||
if (packet.stream_index == video_stream_index) {
|
||||
avcodec_get_frame_defaults(frame);
|
||||
got_frame = 0;
|
||||
ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, &packet);
|
||||
if (ret < 0) {
|
||||
@@ -240,20 +228,22 @@ int main(int argc, char **argv)
|
||||
display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
|
||||
av_frame_unref(filt_frame);
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
}
|
||||
av_free_packet(&packet);
|
||||
}
|
||||
end:
|
||||
avfilter_graph_free(&filter_graph);
|
||||
avcodec_close(dec_ctx);
|
||||
if (dec_ctx)
|
||||
avcodec_close(dec_ctx);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&filt_frame);
|
||||
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
char buf[1024];
|
||||
av_strerror(ret, buf, sizeof(buf));
|
||||
fprintf(stderr, "Error occurred: %s\n", buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
/**
|
||||
* @file
|
||||
* Shows how the metadata API can be used in application programs.
|
||||
* @example metadata.c
|
||||
* @example doc/examples/metadata.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
* @file
|
||||
* libavformat API example.
|
||||
*
|
||||
* Output a media file in any supported libavformat format. The default
|
||||
* codecs are used.
|
||||
* @example muxing.c
|
||||
* Output a media file in any supported libavformat format.
|
||||
* The default codecs are used.
|
||||
* @example doc/examples/muxing.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -36,43 +36,18 @@
|
||||
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/mathematics.h>
|
||||
#include <libavutil/timestamp.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libswscale/swscale.h>
|
||||
#include <libswresample/swresample.h>
|
||||
|
||||
static int audio_is_eof, video_is_eof;
|
||||
|
||||
#define STREAM_DURATION 10.0
|
||||
/* 5 seconds stream duration */
|
||||
#define STREAM_DURATION 200.0
|
||||
#define STREAM_FRAME_RATE 25 /* 25 images/s */
|
||||
#define STREAM_NB_FRAMES ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
|
||||
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
|
||||
|
||||
static int sws_flags = SWS_BICUBIC;
|
||||
|
||||
static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)
|
||||
{
|
||||
AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
|
||||
|
||||
printf("pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
|
||||
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
|
||||
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
|
||||
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
|
||||
pkt->stream_index);
|
||||
}
|
||||
|
||||
static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
|
||||
{
|
||||
/* rescale output packet timestamp values from codec to stream timebase */
|
||||
pkt->pts = av_rescale_q_rnd(pkt->pts, *time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
|
||||
pkt->dts = av_rescale_q_rnd(pkt->dts, *time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
|
||||
pkt->duration = av_rescale_q(pkt->duration, *time_base, st->time_base);
|
||||
pkt->stream_index = st->index;
|
||||
|
||||
/* 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 AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,
|
||||
enum AVCodecID codec_id)
|
||||
@@ -98,8 +73,7 @@ static AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,
|
||||
|
||||
switch ((*codec)->type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
c->sample_fmt = (*codec)->sample_fmts ?
|
||||
(*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
|
||||
c->sample_fmt = AV_SAMPLE_FMT_FLTP;
|
||||
c->bit_rate = 64000;
|
||||
c->sample_rate = 44100;
|
||||
c->channels = 2;
|
||||
@@ -148,7 +122,6 @@ static AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,
|
||||
|
||||
static float t, tincr, tincr2;
|
||||
|
||||
AVFrame *audio_frame;
|
||||
static uint8_t **src_samples_data;
|
||||
static int src_samples_linesize;
|
||||
static int src_nb_samples;
|
||||
@@ -157,7 +130,6 @@ static int max_dst_nb_samples;
|
||||
uint8_t **dst_samples_data;
|
||||
int dst_samples_linesize;
|
||||
int dst_samples_size;
|
||||
int samples_count;
|
||||
|
||||
struct SwrContext *swr_ctx = NULL;
|
||||
|
||||
@@ -168,13 +140,6 @@ static void open_audio(AVFormatContext *oc, AVCodec *codec, AVStream *st)
|
||||
|
||||
c = st->codec;
|
||||
|
||||
/* allocate and init a re-usable frame */
|
||||
audio_frame = av_frame_alloc();
|
||||
if (!audio_frame) {
|
||||
fprintf(stderr, "Could not allocate audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* open it */
|
||||
ret = avcodec_open2(c, codec, NULL);
|
||||
if (ret < 0) {
|
||||
@@ -192,17 +157,12 @@ static void open_audio(AVFormatContext *oc, AVCodec *codec, AVStream *st)
|
||||
10000 : c->frame_size;
|
||||
|
||||
ret = av_samples_alloc_array_and_samples(&src_samples_data, &src_samples_linesize, c->channels,
|
||||
src_nb_samples, AV_SAMPLE_FMT_S16, 0);
|
||||
src_nb_samples, c->sample_fmt, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate source samples\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* compute the number of converted samples: buffering is avoided
|
||||
* ensuring that the output buffer will contain at least all the
|
||||
* converted input samples */
|
||||
max_dst_nb_samples = src_nb_samples;
|
||||
|
||||
/* create resampler context */
|
||||
if (c->sample_fmt != AV_SAMPLE_FMT_S16) {
|
||||
swr_ctx = swr_alloc();
|
||||
@@ -224,15 +184,17 @@ static void open_audio(AVFormatContext *oc, AVCodec *codec, AVStream *st)
|
||||
fprintf(stderr, "Failed to initialize the resampling context\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
ret = av_samples_alloc_array_and_samples(&dst_samples_data, &dst_samples_linesize, c->channels,
|
||||
max_dst_nb_samples, c->sample_fmt, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate destination samples\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
dst_samples_data = src_samples_data;
|
||||
/* compute the number of converted samples: buffering is avoided
|
||||
* ensuring that the output buffer will contain at least all the
|
||||
* converted input samples */
|
||||
max_dst_nb_samples = src_nb_samples;
|
||||
ret = av_samples_alloc_array_and_samples(&dst_samples_data, &dst_samples_linesize, c->channels,
|
||||
max_dst_nb_samples, c->sample_fmt, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate destination samples\n");
|
||||
exit(1);
|
||||
}
|
||||
dst_samples_size = av_samples_get_buffer_size(NULL, c->channels, max_dst_nb_samples,
|
||||
c->sample_fmt, 0);
|
||||
@@ -255,83 +217,77 @@ static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)
|
||||
}
|
||||
}
|
||||
|
||||
static void write_audio_frame(AVFormatContext *oc, AVStream *st, int flush)
|
||||
static void write_audio_frame(AVFormatContext *oc, AVStream *st)
|
||||
{
|
||||
AVCodecContext *c;
|
||||
AVPacket pkt = { 0 }; // data and size must be 0;
|
||||
AVFrame *frame = avcodec_alloc_frame();
|
||||
int got_packet, ret, dst_nb_samples;
|
||||
|
||||
av_init_packet(&pkt);
|
||||
c = st->codec;
|
||||
|
||||
if (!flush) {
|
||||
get_audio_frame((int16_t *)src_samples_data[0], src_nb_samples, c->channels);
|
||||
get_audio_frame((int16_t *)src_samples_data[0], src_nb_samples, c->channels);
|
||||
|
||||
/* convert samples from native format to destination codec format, using the resampler */
|
||||
if (swr_ctx) {
|
||||
/* compute destination number of samples */
|
||||
dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, c->sample_rate) + src_nb_samples,
|
||||
c->sample_rate, c->sample_rate, AV_ROUND_UP);
|
||||
if (dst_nb_samples > max_dst_nb_samples) {
|
||||
av_free(dst_samples_data[0]);
|
||||
ret = av_samples_alloc(dst_samples_data, &dst_samples_linesize, c->channels,
|
||||
dst_nb_samples, c->sample_fmt, 0);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
max_dst_nb_samples = dst_nb_samples;
|
||||
dst_samples_size = av_samples_get_buffer_size(NULL, c->channels, dst_nb_samples,
|
||||
c->sample_fmt, 0);
|
||||
}
|
||||
|
||||
/* convert to destination format */
|
||||
ret = swr_convert(swr_ctx,
|
||||
dst_samples_data, dst_nb_samples,
|
||||
(const uint8_t **)src_samples_data, src_nb_samples);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while converting\n");
|
||||
/* convert samples from native format to destination codec format, using the resampler */
|
||||
if (swr_ctx) {
|
||||
/* compute destination number of samples */
|
||||
dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, c->sample_rate) + src_nb_samples,
|
||||
c->sample_rate, c->sample_rate, AV_ROUND_UP);
|
||||
if (dst_nb_samples > max_dst_nb_samples) {
|
||||
av_free(dst_samples_data[0]);
|
||||
ret = av_samples_alloc(dst_samples_data, &dst_samples_linesize, c->channels,
|
||||
dst_nb_samples, c->sample_fmt, 0);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
dst_nb_samples = src_nb_samples;
|
||||
max_dst_nb_samples = dst_nb_samples;
|
||||
dst_samples_size = av_samples_get_buffer_size(NULL, c->channels, dst_nb_samples,
|
||||
c->sample_fmt, 0);
|
||||
}
|
||||
|
||||
audio_frame->nb_samples = dst_nb_samples;
|
||||
audio_frame->pts = av_rescale_q(samples_count, (AVRational){1, c->sample_rate}, c->time_base);
|
||||
avcodec_fill_audio_frame(audio_frame, c->channels, c->sample_fmt,
|
||||
dst_samples_data[0], dst_samples_size, 0);
|
||||
samples_count += dst_nb_samples;
|
||||
/* convert to destination format */
|
||||
ret = swr_convert(swr_ctx,
|
||||
dst_samples_data, dst_nb_samples,
|
||||
(const uint8_t **)src_samples_data, src_nb_samples);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while converting\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
dst_samples_data[0] = src_samples_data[0];
|
||||
dst_nb_samples = src_nb_samples;
|
||||
}
|
||||
|
||||
ret = avcodec_encode_audio2(c, &pkt, flush ? NULL : audio_frame, &got_packet);
|
||||
frame->nb_samples = dst_nb_samples;
|
||||
avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
|
||||
dst_samples_data[0], dst_samples_size, 0);
|
||||
|
||||
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) {
|
||||
if (flush)
|
||||
audio_is_eof = 1;
|
||||
if (!got_packet)
|
||||
return;
|
||||
}
|
||||
|
||||
ret = write_frame(oc, &c->time_base, st, &pkt);
|
||||
if (ret < 0) {
|
||||
pkt.stream_index = st->index;
|
||||
|
||||
/* Write the compressed frame to the media file. */
|
||||
ret = av_interleaved_write_frame(oc, &pkt);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Error while writing audio frame: %s\n",
|
||||
av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
avcodec_free_frame(&frame);
|
||||
}
|
||||
|
||||
static void close_audio(AVFormatContext *oc, AVStream *st)
|
||||
{
|
||||
avcodec_close(st->codec);
|
||||
if (dst_samples_data != src_samples_data) {
|
||||
av_free(dst_samples_data[0]);
|
||||
av_free(dst_samples_data);
|
||||
}
|
||||
av_free(src_samples_data[0]);
|
||||
av_free(src_samples_data);
|
||||
av_frame_free(&audio_frame);
|
||||
av_free(dst_samples_data[0]);
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
@@ -354,14 +310,11 @@ static void open_video(AVFormatContext *oc, AVCodec *codec, AVStream *st)
|
||||
}
|
||||
|
||||
/* allocate and init a re-usable frame */
|
||||
frame = av_frame_alloc();
|
||||
frame = avcodec_alloc_frame();
|
||||
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;
|
||||
|
||||
/* Allocate the encoded raw picture. */
|
||||
ret = avpicture_alloc(&dst_picture, c->pix_fmt, c->width, c->height);
|
||||
@@ -408,13 +361,17 @@ static void fill_yuv_image(AVPicture *pict, int frame_index,
|
||||
}
|
||||
}
|
||||
|
||||
static void write_video_frame(AVFormatContext *oc, AVStream *st, int flush)
|
||||
static void write_video_frame(AVFormatContext *oc, AVStream *st)
|
||||
{
|
||||
int ret;
|
||||
static struct SwsContext *sws_ctx;
|
||||
AVCodecContext *c = st->codec;
|
||||
|
||||
if (!flush) {
|
||||
if (frame_count >= STREAM_NB_FRAMES) {
|
||||
/* No more frames to compress. The codec has a latency of a few
|
||||
* frames if using B-frames, so we get the last frames by
|
||||
* passing the same picture again. */
|
||||
} else {
|
||||
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 */
|
||||
@@ -437,7 +394,7 @@ static void write_video_frame(AVFormatContext *oc, AVStream *st, int flush)
|
||||
}
|
||||
}
|
||||
|
||||
if (oc->oformat->flags & AVFMT_RAWPICTURE && !flush) {
|
||||
if (oc->oformat->flags & AVFMT_RAWPICTURE) {
|
||||
/* Raw video case - directly store the picture in the packet */
|
||||
AVPacket pkt;
|
||||
av_init_packet(&pkt);
|
||||
@@ -454,24 +411,23 @@ static void write_video_frame(AVFormatContext *oc, AVStream *st, int flush)
|
||||
av_init_packet(&pkt);
|
||||
|
||||
/* encode the image */
|
||||
frame->pts = frame_count;
|
||||
ret = avcodec_encode_video2(c, &pkt, flush ? NULL : frame, &got_packet);
|
||||
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 size is zero, it means the image was buffered. */
|
||||
|
||||
if (got_packet) {
|
||||
ret = write_frame(oc, &c->time_base, st, &pkt);
|
||||
if (!ret && got_packet && pkt.size) {
|
||||
pkt.stream_index = st->index;
|
||||
|
||||
/* Write the compressed frame to the media file. */
|
||||
ret = av_interleaved_write_frame(oc, &pkt);
|
||||
} else {
|
||||
if (flush)
|
||||
video_is_eof = 1;
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
@@ -483,7 +439,7 @@ static void close_video(AVFormatContext *oc, AVStream *st)
|
||||
avcodec_close(st->codec);
|
||||
av_free(src_picture.data[0]);
|
||||
av_free(dst_picture.data[0]);
|
||||
av_frame_free(&frame);
|
||||
av_free(frame);
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
@@ -497,7 +453,7 @@ int main(int argc, char **argv)
|
||||
AVStream *audio_st, *video_st;
|
||||
AVCodec *audio_codec, *video_codec;
|
||||
double audio_time, video_time;
|
||||
int flush, ret;
|
||||
int ret;
|
||||
|
||||
/* Initialize libavcodec, and register all codecs and formats. */
|
||||
av_register_all();
|
||||
@@ -521,9 +477,9 @@ int main(int argc, char **argv)
|
||||
printf("Could not deduce output format from file extension: using MPEG.\n");
|
||||
avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
|
||||
}
|
||||
if (!oc)
|
||||
if (!oc) {
|
||||
return 1;
|
||||
|
||||
}
|
||||
fmt = oc->oformat;
|
||||
|
||||
/* Add the audio and video streams using the default format codecs
|
||||
@@ -531,10 +487,12 @@ int main(int argc, char **argv)
|
||||
video_st = NULL;
|
||||
audio_st = NULL;
|
||||
|
||||
if (fmt->video_codec != AV_CODEC_ID_NONE)
|
||||
if (fmt->video_codec != AV_CODEC_ID_NONE) {
|
||||
video_st = add_stream(oc, &video_codec, fmt->video_codec);
|
||||
if (fmt->audio_codec != AV_CODEC_ID_NONE)
|
||||
}
|
||||
if (fmt->audio_codec != AV_CODEC_ID_NONE) {
|
||||
audio_st = add_stream(oc, &audio_codec, fmt->audio_codec);
|
||||
}
|
||||
|
||||
/* Now that all the parameters are set, we can open the audio and
|
||||
* video codecs and allocate the necessary encode buffers. */
|
||||
@@ -563,23 +521,23 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
flush = 0;
|
||||
while ((video_st && !video_is_eof) || (audio_st && !audio_is_eof)) {
|
||||
if (frame)
|
||||
frame->pts = 0;
|
||||
for (;;) {
|
||||
/* Compute current audio and video time. */
|
||||
audio_time = (audio_st && !audio_is_eof) ? audio_st->pts.val * av_q2d(audio_st->time_base) : INFINITY;
|
||||
video_time = (video_st && !video_is_eof) ? video_st->pts.val * av_q2d(video_st->time_base) : INFINITY;
|
||||
audio_time = audio_st ? audio_st->pts.val * av_q2d(audio_st->time_base) : 0.0;
|
||||
video_time = video_st ? video_st->pts.val * av_q2d(video_st->time_base) : 0.0;
|
||||
|
||||
if (!flush &&
|
||||
(!audio_st || audio_time >= STREAM_DURATION) &&
|
||||
(!video_st || video_time >= STREAM_DURATION)) {
|
||||
flush = 1;
|
||||
}
|
||||
if ((!audio_st || audio_time >= STREAM_DURATION) &&
|
||||
(!video_st || video_time >= STREAM_DURATION))
|
||||
break;
|
||||
|
||||
/* write interleaved audio and video frames */
|
||||
if (audio_st && !audio_is_eof && audio_time <= video_time) {
|
||||
write_audio_frame(oc, audio_st, flush);
|
||||
} else if (video_st && !video_is_eof && video_time < audio_time) {
|
||||
write_video_frame(oc, video_st, flush);
|
||||
if (!video_st || (video_st && audio_st && audio_time < video_time)) {
|
||||
write_audio_frame(oc, audio_st);
|
||||
} else {
|
||||
write_video_frame(oc, video_st);
|
||||
frame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Stefano Sabatini
|
||||
*
|
||||
* 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
|
||||
* libavformat/libavcodec demuxing and muxing API example.
|
||||
*
|
||||
* Remux streams from one container format to another.
|
||||
* @example remuxing.c
|
||||
*/
|
||||
|
||||
#include <libavutil/timestamp.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt, const char *tag)
|
||||
{
|
||||
AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
|
||||
|
||||
printf("%s: pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
|
||||
tag,
|
||||
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
|
||||
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
|
||||
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
|
||||
pkt->stream_index);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
AVOutputFormat *ofmt = NULL;
|
||||
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
|
||||
AVPacket pkt;
|
||||
const char *in_filename, *out_filename;
|
||||
int ret, i;
|
||||
|
||||
if (argc < 3) {
|
||||
printf("usage: %s input output\n"
|
||||
"API example program to remux a media file with libavformat and libavcodec.\n"
|
||||
"The output format is guessed according to the file extension.\n"
|
||||
"\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_filename = argv[1];
|
||||
out_filename = argv[2];
|
||||
|
||||
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);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
|
||||
fprintf(stderr, "Failed to retrieve input stream information");
|
||||
goto end;
|
||||
}
|
||||
|
||||
av_dump_format(ifmt_ctx, 0, in_filename, 0);
|
||||
|
||||
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
|
||||
if (!ofmt_ctx) {
|
||||
fprintf(stderr, "Could not create output context\n");
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ofmt = ofmt_ctx->oformat;
|
||||
|
||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||
AVStream *in_stream = ifmt_ctx->streams[i];
|
||||
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_copy_context(out_stream->codec, in_stream->codec);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to copy context from input to output stream codec context\n");
|
||||
goto end;
|
||||
}
|
||||
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
}
|
||||
av_dump_format(ofmt_ctx, 0, out_filename, 1);
|
||||
|
||||
if (!(ofmt->flags & AVFMT_NOFILE)) {
|
||||
ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open output file '%s'", out_filename);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
ret = avformat_write_header(ofmt_ctx, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error occurred when opening output file\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
AVStream *in_stream, *out_stream;
|
||||
|
||||
ret = av_read_frame(ifmt_ctx, &pkt);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
in_stream = ifmt_ctx->streams[pkt.stream_index];
|
||||
out_stream = ofmt_ctx->streams[pkt.stream_index];
|
||||
|
||||
log_packet(ifmt_ctx, &pkt, "in");
|
||||
|
||||
/* copy packet */
|
||||
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);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error muxing packet\n");
|
||||
break;
|
||||
}
|
||||
av_free_packet(&pkt);
|
||||
}
|
||||
|
||||
av_write_trailer(ofmt_ctx);
|
||||
end:
|
||||
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
|
||||
/* close output */
|
||||
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
|
||||
avio_close(ofmt_ctx->pb);
|
||||
avformat_free_context(ofmt_ctx);
|
||||
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example resampling_audio.c
|
||||
* @example doc/examples/resampling_audio.c
|
||||
* libswresample API use example.
|
||||
*/
|
||||
|
||||
@@ -62,7 +62,7 @@ static int get_format_from_sample_fmt(const char **fmt,
|
||||
/**
|
||||
* Fill dst buffer with nb_samples, generated starting from t.
|
||||
*/
|
||||
static void fill_samples(double *dst, int nb_samples, int nb_channels, int sample_rate, double *t)
|
||||
void fill_samples(double *dst, int nb_samples, int nb_channels, int sample_rate, double *t)
|
||||
{
|
||||
int i, j;
|
||||
double tincr = 1.0 / sample_rate, *dstp = dst;
|
||||
@@ -184,10 +184,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,
|
||||
ret, dst_sample_fmt, 1);
|
||||
if (dst_bufsize < 0) {
|
||||
fprintf(stderr, "Could not get sample buffer size\n");
|
||||
goto end;
|
||||
}
|
||||
printf("t:%f in:%d out:%d\n", t, src_nb_samples, ret);
|
||||
fwrite(dst_data[0], 1, dst_bufsize, dst_file);
|
||||
} while (t < 10);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
/**
|
||||
* @file
|
||||
* libswscale API use example.
|
||||
* @example scaling_video.c
|
||||
* @example doc/examples/scaling_video.c
|
||||
*/
|
||||
|
||||
#include <libavutil/imgutils.h>
|
||||
|
||||
@@ -1,755 +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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* simple audio converter
|
||||
*
|
||||
* @example transcode_aac.c
|
||||
* Convert an input audio file to AAC in an MP4 container using FFmpeg.
|
||||
* @author Andreas Unterweger (dustsigns@gmail.com)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavformat/avio.h"
|
||||
|
||||
#include "libavcodec/avcodec.h"
|
||||
|
||||
#include "libavutil/audio_fifo.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/frame.h"
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
#include "libswresample/swresample.h"
|
||||
|
||||
/** The output bit rate in kbit/s */
|
||||
#define OUTPUT_BIT_RATE 48000
|
||||
/** The number of output channels */
|
||||
#define OUTPUT_CHANNELS 2
|
||||
/** The audio sample output format */
|
||||
#define OUTPUT_SAMPLE_FORMAT AV_SAMPLE_FMT_S16
|
||||
|
||||
/**
|
||||
* Convert an error code into a text message.
|
||||
* @param error Error code to be converted
|
||||
* @return Corresponding error text (not thread-safe)
|
||||
*/
|
||||
static char *const 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)
|
||||
{
|
||||
AVCodec *input_codec;
|
||||
int error;
|
||||
|
||||
/** 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, get_error_text(error));
|
||||
*input_format_context = NULL;
|
||||
return error;
|
||||
}
|
||||
|
||||
/** 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",
|
||||
get_error_text(error));
|
||||
avformat_close_input(input_format_context);
|
||||
return error;
|
||||
}
|
||||
|
||||
/** 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);
|
||||
avformat_close_input(input_format_context);
|
||||
return AVERROR_EXIT;
|
||||
}
|
||||
|
||||
/** Find a decoder for the audio stream. */
|
||||
if (!(input_codec = avcodec_find_decoder((*input_format_context)->streams[0]->codec->codec_id))) {
|
||||
fprintf(stderr, "Could not find input codec\n");
|
||||
avformat_close_input(input_format_context);
|
||||
return AVERROR_EXIT;
|
||||
}
|
||||
|
||||
/** Open the decoder for the audio stream to use it later. */
|
||||
if ((error = avcodec_open2((*input_format_context)->streams[0]->codec,
|
||||
input_codec, NULL)) < 0) {
|
||||
fprintf(stderr, "Could not open input codec (error '%s')\n",
|
||||
get_error_text(error));
|
||||
avformat_close_input(input_format_context);
|
||||
return error;
|
||||
}
|
||||
|
||||
/** Save the decoder context for easier access later. */
|
||||
*input_codec_context = (*input_format_context)->streams[0]->codec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
static int open_output_file(const char *filename,
|
||||
AVCodecContext *input_codec_context,
|
||||
AVFormatContext **output_format_context,
|
||||
AVCodecContext **output_codec_context)
|
||||
{
|
||||
AVIOContext *output_io_context = NULL;
|
||||
AVStream *stream = NULL;
|
||||
AVCodec *output_codec = NULL;
|
||||
int error;
|
||||
|
||||
/** 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, get_error_text(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
/** 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. */
|
||||
(*output_format_context)->pb = output_io_context;
|
||||
|
||||
/** 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;
|
||||
}
|
||||
|
||||
av_strlcpy((*output_format_context)->filename, filename,
|
||||
sizeof((*output_format_context)->filename));
|
||||
|
||||
/** 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. */
|
||||
if (!(stream = avformat_new_stream(*output_format_context, output_codec))) {
|
||||
fprintf(stderr, "Could not create new stream\n");
|
||||
error = AVERROR(ENOMEM);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/** Save the encoder context for easiert access later. */
|
||||
*output_codec_context = stream->codec;
|
||||
|
||||
/**
|
||||
* Set the basic encoder parameters.
|
||||
* The input file's sample rate is used to avoid a sample rate conversion.
|
||||
*/
|
||||
(*output_codec_context)->channels = OUTPUT_CHANNELS;
|
||||
(*output_codec_context)->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS);
|
||||
(*output_codec_context)->sample_rate = input_codec_context->sample_rate;
|
||||
(*output_codec_context)->sample_fmt = AV_SAMPLE_FMT_S16;
|
||||
(*output_codec_context)->bit_rate = OUTPUT_BIT_RATE;
|
||||
|
||||
/**
|
||||
* 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)
|
||||
(*output_codec_context)->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
/** Open the encoder for the audio stream to use it later. */
|
||||
if ((error = avcodec_open2(*output_codec_context, output_codec, NULL)) < 0) {
|
||||
fprintf(stderr, "Could not open output codec (error '%s')\n",
|
||||
get_error_text(error));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
avio_close((*output_format_context)->pb);
|
||||
avformat_free_context(*output_format_context);
|
||||
*output_format_context = NULL;
|
||||
return error < 0 ? error : AVERROR_EXIT;
|
||||
}
|
||||
|
||||
/** Initialize one data packet for reading or writing. */
|
||||
static void init_packet(AVPacket *packet)
|
||||
{
|
||||
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 */
|
||||
static int init_input_frame(AVFrame **frame)
|
||||
{
|
||||
if (!(*frame = av_frame_alloc())) {
|
||||
fprintf(stderr, "Could not allocate input frame\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
static int init_resampler(AVCodecContext *input_codec_context,
|
||||
AVCodecContext *output_codec_context,
|
||||
SwrContext **resample_context)
|
||||
{
|
||||
int error;
|
||||
|
||||
/**
|
||||
* Create a resampler context for the conversion.
|
||||
* Set the conversion parameters.
|
||||
* Default channel layouts based on the number of channels
|
||||
* are assumed for simplicity (they are sometimes not detected
|
||||
* properly by the demuxer and/or decoder).
|
||||
*/
|
||||
*resample_context = swr_alloc_set_opts(NULL,
|
||||
av_get_default_channel_layout(output_codec_context->channels),
|
||||
output_codec_context->sample_fmt,
|
||||
output_codec_context->sample_rate,
|
||||
av_get_default_channel_layout(input_codec_context->channels),
|
||||
input_codec_context->sample_fmt,
|
||||
input_codec_context->sample_rate,
|
||||
0, NULL);
|
||||
if (!*resample_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. */
|
||||
if ((error = swr_init(*resample_context)) < 0) {
|
||||
fprintf(stderr, "Could not open resample context\n");
|
||||
swr_free(resample_context);
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Initialize a FIFO buffer for the audio samples to be encoded. */
|
||||
static int init_fifo(AVAudioFifo **fifo)
|
||||
{
|
||||
/** Create the FIFO buffer based on the specified output sample format. */
|
||||
if (!(*fifo = av_audio_fifo_alloc(OUTPUT_SAMPLE_FORMAT, OUTPUT_CHANNELS, 1))) {
|
||||
fprintf(stderr, "Could not allocate FIFO\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** 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",
|
||||
get_error_text(error));
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** 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;
|
||||
int error;
|
||||
init_packet(&input_packet);
|
||||
|
||||
/** 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 the 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",
|
||||
get_error_text(error));
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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",
|
||||
get_error_text(error));
|
||||
av_free_packet(&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_free_packet(&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.
|
||||
*/
|
||||
static int init_converted_samples(uint8_t ***converted_input_samples,
|
||||
AVCodecContext *output_codec_context,
|
||||
int frame_size)
|
||||
{
|
||||
int error;
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
if (!(*converted_input_samples = calloc(output_codec_context->channels,
|
||||
sizeof(**converted_input_samples)))) {
|
||||
fprintf(stderr, "Could not allocate converted input sample pointers\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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",
|
||||
get_error_text(error));
|
||||
av_freep(&(*converted_input_samples)[0]);
|
||||
free(*converted_input_samples);
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
static int convert_samples(const uint8_t **input_data,
|
||||
uint8_t **converted_data, const int frame_size,
|
||||
SwrContext *resample_context)
|
||||
{
|
||||
int error;
|
||||
|
||||
/** 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",
|
||||
get_error_text(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
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. */
|
||||
if (av_audio_fifo_write(fifo, (void **)converted_input_samples,
|
||||
frame_size) < frame_size) {
|
||||
fprintf(stderr, "Could not write data to FIFO\n");
|
||||
return AVERROR_EXIT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read one audio frame from the input file, decodes, converts and stores
|
||||
* it in the FIFO buffer.
|
||||
*/
|
||||
static int read_decode_convert_and_store(AVAudioFifo *fifo,
|
||||
AVFormatContext *input_format_context,
|
||||
AVCodecContext *input_codec_context,
|
||||
AVCodecContext *output_codec_context,
|
||||
SwrContext *resampler_context,
|
||||
int *finished)
|
||||
{
|
||||
/** Temporary storage of the input samples of the frame read from the file. */
|
||||
AVFrame *input_frame = NULL;
|
||||
/** Temporary storage for the converted input samples. */
|
||||
uint8_t **converted_input_samples = NULL;
|
||||
int data_present;
|
||||
int ret = AVERROR_EXIT;
|
||||
|
||||
/** Initialize temporary storage for one input frame. */
|
||||
if (init_input_frame(&input_frame))
|
||||
goto cleanup;
|
||||
/** 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
|
||||
* in the decoder which are delayed, we are actually 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 (data_present) {
|
||||
/** 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.
|
||||
*/
|
||||
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. */
|
||||
if (add_samples_to_fifo(fifo, converted_input_samples,
|
||||
input_frame->nb_samples))
|
||||
goto cleanup;
|
||||
ret = 0;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
if (converted_input_samples) {
|
||||
av_freep(&converted_input_samples[0]);
|
||||
free(converted_input_samples);
|
||||
}
|
||||
av_frame_free(&input_frame);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize one input frame for writing to the output file.
|
||||
* The frame will be exactly frame_size samples large.
|
||||
*/
|
||||
static int init_output_frame(AVFrame **frame,
|
||||
AVCodecContext *output_codec_context,
|
||||
int frame_size)
|
||||
{
|
||||
int error;
|
||||
|
||||
/** 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.
|
||||
* 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.
|
||||
*/
|
||||
(*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.
|
||||
*/
|
||||
if ((error = av_frame_get_buffer(*frame, 0)) < 0) {
|
||||
fprintf(stderr, "Could allocate output frame samples (error '%s')\n",
|
||||
get_error_text(error));
|
||||
av_frame_free(frame);
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** 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;
|
||||
int error;
|
||||
init_packet(&output_packet);
|
||||
|
||||
/**
|
||||
* 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",
|
||||
get_error_text(error));
|
||||
av_free_packet(&output_packet);
|
||||
return error;
|
||||
}
|
||||
|
||||
/** 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_free_packet(&output_packet);
|
||||
return error;
|
||||
}
|
||||
|
||||
av_free_packet(&output_packet);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load one audio frame from the FIFO buffer, encode and write it to the
|
||||
* output file.
|
||||
*/
|
||||
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. */
|
||||
AVFrame *output_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
|
||||
*/
|
||||
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. */
|
||||
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.
|
||||
*/
|
||||
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. */
|
||||
if (encode_audio_frame(output_frame, output_format_context,
|
||||
output_codec_context, &data_written)) {
|
||||
av_frame_free(&output_frame);
|
||||
return AVERROR_EXIT;
|
||||
}
|
||||
av_frame_free(&output_frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** 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",
|
||||
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;
|
||||
AVCodecContext *input_codec_context = NULL, *output_codec_context = NULL;
|
||||
SwrContext *resample_context = NULL;
|
||||
AVAudioFifo *fifo = NULL;
|
||||
int ret = AVERROR_EXIT;
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/** 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. */
|
||||
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. */
|
||||
if (init_resampler(input_codec_context, output_codec_context,
|
||||
&resample_context))
|
||||
goto cleanup;
|
||||
/** Initialize the FIFO buffer to store audio samples to be encoded. */
|
||||
if (init_fifo(&fifo))
|
||||
goto cleanup;
|
||||
/** 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.
|
||||
*/
|
||||
while (1) {
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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 (finished)
|
||||
break;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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 (finished) {
|
||||
int data_written;
|
||||
/** Flush the encoder as it may have delayed frames. */
|
||||
do {
|
||||
if (encode_audio_frame(NULL, output_format_context,
|
||||
output_codec_context, &data_written))
|
||||
goto cleanup;
|
||||
} while (data_written);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Write the trailer of the output file container. */
|
||||
if (write_output_file_trailer(output_format_context))
|
||||
goto cleanup;
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
if (fifo)
|
||||
av_audio_fifo_free(fifo);
|
||||
swr_free(&resample_context);
|
||||
if (output_codec_context)
|
||||
avcodec_close(output_codec_context);
|
||||
if (output_format_context) {
|
||||
avio_close(output_format_context->pb);
|
||||
avformat_free_context(output_format_context);
|
||||
}
|
||||
if (input_codec_context)
|
||||
avcodec_close(input_codec_context);
|
||||
if (input_format_context)
|
||||
avformat_close_input(&input_format_context);
|
||||
|
||||
return ret;
|
||||
}
|
||||
62
doc/faq.texi
62
doc/faq.texi
@@ -105,7 +105,7 @@ For example, img1.jpg, img2.jpg, img3.jpg,...
|
||||
Then you may run:
|
||||
|
||||
@example
|
||||
ffmpeg -f image2 -i img%d.jpg /tmp/a.mpg
|
||||
ffmpeg -f image2 -i img%d.jpg /tmp/a.mpg
|
||||
@end example
|
||||
|
||||
Notice that @samp{%d} is replaced by the image number.
|
||||
@@ -118,7 +118,7 @@ the sequence. This is useful if your sequence does not start with
|
||||
example will start with @file{img100.jpg}:
|
||||
|
||||
@example
|
||||
ffmpeg -f image2 -start_number 100 -i img%d.jpg /tmp/a.mpg
|
||||
ffmpeg -f image2 -start_number 100 -i img%d.jpg /tmp/a.mpg
|
||||
@end example
|
||||
|
||||
If you have large number of pictures to rename, you can use the
|
||||
@@ -128,7 +128,7 @@ that match @code{*jpg} to the @file{/tmp} directory in the sequence of
|
||||
@file{img001.jpg}, @file{img002.jpg} and so on.
|
||||
|
||||
@example
|
||||
x=1; for i in *jpg; do counter=$(printf %03d $x); ln -s "$i" /tmp/img"$counter".jpg; x=$(($x+1)); done
|
||||
x=1; for i in *jpg; do counter=$(printf %03d $x); ln -s "$i" /tmp/img"$counter".jpg; x=$(($x+1)); done
|
||||
@end example
|
||||
|
||||
If you want to sequence them by oldest modified first, substitute
|
||||
@@ -137,7 +137,7 @@ If you want to sequence them by oldest modified first, substitute
|
||||
Then run:
|
||||
|
||||
@example
|
||||
ffmpeg -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg
|
||||
ffmpeg -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg
|
||||
@end example
|
||||
|
||||
The same logic is used for any image format that ffmpeg reads.
|
||||
@@ -145,7 +145,7 @@ The same logic is used for any image format that ffmpeg reads.
|
||||
You can also use @command{cat} to pipe images to ffmpeg:
|
||||
|
||||
@example
|
||||
cat *.jpg | ffmpeg -f image2pipe -c:v mjpeg -i - output.mpg
|
||||
cat *.jpg | ffmpeg -f image2pipe -c:v mjpeg -i - output.mpg
|
||||
@end example
|
||||
|
||||
@section How do I encode movie to single pictures?
|
||||
@@ -153,7 +153,7 @@ cat *.jpg | ffmpeg -f image2pipe -c:v mjpeg -i - output.mpg
|
||||
Use:
|
||||
|
||||
@example
|
||||
ffmpeg -i movie.mpg movie%d.jpg
|
||||
ffmpeg -i movie.mpg movie%d.jpg
|
||||
@end example
|
||||
|
||||
The @file{movie.mpg} used as input will be converted to
|
||||
@@ -169,7 +169,7 @@ to force the encoding.
|
||||
|
||||
Applying that to the previous example:
|
||||
@example
|
||||
ffmpeg -i movie.mpg -f image2 -c:v mjpeg menu%d.jpg
|
||||
ffmpeg -i movie.mpg -f image2 -c:v mjpeg menu%d.jpg
|
||||
@end example
|
||||
|
||||
Beware that there is no "jpeg" codec. Use "mjpeg" instead.
|
||||
@@ -227,15 +227,15 @@ then you may use any file that DirectShow can read as input.
|
||||
|
||||
Just create an "input.avs" text file with this single line ...
|
||||
@example
|
||||
DirectShowSource("C:\path to your file\yourfile.asf")
|
||||
DirectShowSource("C:\path to your file\yourfile.asf")
|
||||
@end example
|
||||
... and then feed that text file to ffmpeg:
|
||||
@example
|
||||
ffmpeg -i input.avs
|
||||
ffmpeg -i input.avs
|
||||
@end example
|
||||
|
||||
For ANY other help on AviSynth, please visit the
|
||||
@uref{http://www.avisynth.org/, AviSynth homepage}.
|
||||
For ANY other help on Avisynth, please visit the
|
||||
@uref{http://www.avisynth.org/, Avisynth homepage}.
|
||||
|
||||
@section How can I join video files?
|
||||
|
||||
@@ -368,6 +368,26 @@ ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \
|
||||
rm temp[12].[av] all.[av]
|
||||
@end example
|
||||
|
||||
@section -profile option fails when encoding H.264 video with AAC audio
|
||||
|
||||
@command{ffmpeg} prints an error like
|
||||
|
||||
@example
|
||||
Undefined constant or missing '(' in 'baseline'
|
||||
Unable to parse option value "baseline"
|
||||
Error setting option profile to value baseline.
|
||||
@end example
|
||||
|
||||
Short answer: write @option{-profile:v} instead of @option{-profile}.
|
||||
|
||||
Long answer: this happens because the @option{-profile} option can apply to both
|
||||
video and audio. Specifically the AAC encoder also defines some profiles, none
|
||||
of which are named @var{baseline}.
|
||||
|
||||
The solution is to apply the @option{-profile} option to the video stream only
|
||||
by using @url{http://ffmpeg.org/ffmpeg.html#Stream-specifiers-1, Stream specifiers}.
|
||||
Appending @code{:v} to it will do exactly that.
|
||||
|
||||
@section Using @option{-f lavfi}, audio becomes mono for no apparent reason.
|
||||
|
||||
Use @option{-dumpgraph -} to find out exactly where the channel layout is
|
||||
@@ -455,10 +475,9 @@ read @uref{http://www.tux.org/lkml/#s15, "Programming Religion"}.
|
||||
|
||||
@section Why are the ffmpeg programs devoid of debugging symbols?
|
||||
|
||||
The build process creates @command{ffmpeg_g}, @command{ffplay_g}, etc. which
|
||||
contain full debug information. Those binaries are stripped to create
|
||||
@command{ffmpeg}, @command{ffplay}, etc. If you need the debug information, use
|
||||
the *_g versions.
|
||||
The build process creates ffmpeg_g, ffplay_g, etc. which contain full debug
|
||||
information. Those binaries are stripped to create ffmpeg, ffplay, etc. If
|
||||
you need the debug information, use the *_g versions.
|
||||
|
||||
@section I do not like the LGPL, can I contribute code under the GPL instead?
|
||||
|
||||
@@ -478,7 +497,7 @@ An easy way to get the full list of required libraries in dependency order
|
||||
is to use @code{pkg-config}.
|
||||
|
||||
@example
|
||||
c99 -o program program.c $(pkg-config --cflags --libs libavformat libavcodec)
|
||||
c99 -o program program.c $(pkg-config --cflags --libs libavformat libavcodec)
|
||||
@end example
|
||||
|
||||
See @file{doc/example/Makefile} and @file{doc/example/pc-uninstalled} for
|
||||
@@ -502,6 +521,10 @@ to use them you have to append -D__STDC_CONSTANT_MACROS to your CXXFLAGS
|
||||
You have to create a custom AVIOContext using @code{avio_alloc_context},
|
||||
see @file{libavformat/aviobuf.c} in FFmpeg and @file{libmpdemux/demux_lavf.c} in MPlayer or MPlayer2 sources.
|
||||
|
||||
@section Where can I find libav* headers for Pascal/Delphi?
|
||||
|
||||
see @url{http://www.iversenit.dk/dev/ffmpeg-headers/}
|
||||
|
||||
@section Where is the documentation about ffv1, msmpeg4, asv1, 4xm?
|
||||
|
||||
see @url{http://www.ffmpeg.org/~michael/}
|
||||
@@ -514,12 +537,11 @@ In this specific case please look at RFC 4629 to see how it should be done.
|
||||
|
||||
@section AVStream.r_frame_rate is wrong, it is much larger than the frame rate.
|
||||
|
||||
@code{r_frame_rate} is NOT the average frame rate, it is the smallest frame rate
|
||||
r_frame_rate is NOT the average frame rate, it is the smallest frame rate
|
||||
that can accurately represent all timestamps. So no, it is not
|
||||
wrong if it is larger than the average!
|
||||
For example, if you have mixed 25 and 30 fps content, then @code{r_frame_rate}
|
||||
will be 150 (it is the least common multiple).
|
||||
If you are looking for the average frame rate, see @code{AVStream.avg_frame_rate}.
|
||||
For example, if you have mixed 25 and 30 fps content, then r_frame_rate
|
||||
will be 150.
|
||||
|
||||
@section Why is @code{make fate} not running all tests?
|
||||
|
||||
|
||||
@@ -153,20 +153,20 @@ the synchronisation of the samples directory.
|
||||
|
||||
@table @option
|
||||
@item fate-rsync
|
||||
Download/synchronize sample files to the configured samples directory.
|
||||
Download/synchronize sample files to the configured samples directory.
|
||||
|
||||
@item fate-list
|
||||
Will list all fate/regression test targets.
|
||||
Will list all fate/regression test targets.
|
||||
|
||||
@item fate
|
||||
Run the FATE test suite (requires the fate-suite dataset).
|
||||
Run the FATE test suite (requires the fate-suite dataset).
|
||||
@end table
|
||||
|
||||
@section Makefile variables
|
||||
|
||||
@table @option
|
||||
@item V
|
||||
Verbosity level, can be set to 0, 1 or 2.
|
||||
Verbosity level, can be set to 0, 1 or 2.
|
||||
@itemize
|
||||
@item 0: show just the test arguments
|
||||
@item 1: show just the command used in the test
|
||||
@@ -174,26 +174,22 @@ Verbosity level, can be set to 0, 1 or 2.
|
||||
@end itemize
|
||||
|
||||
@item SAMPLES
|
||||
Specify or override the path to the FATE samples at make time, it has a
|
||||
meaning only while running the regression tests.
|
||||
Specify or override the path to the FATE samples at make time, it has a
|
||||
meaning only while running the regression tests.
|
||||
|
||||
@item THREADS
|
||||
Specify how many threads to use while running regression tests, it is
|
||||
quite useful to detect thread-related regressions.
|
||||
|
||||
Specify how many threads to use while running regression tests, it is
|
||||
quite useful to detect thread-related regressions.
|
||||
@item THREAD_TYPE
|
||||
Specify which threading strategy test, either @var{slice} or @var{frame},
|
||||
by default @var{slice+frame}
|
||||
|
||||
Specify which threading strategy test, either @var{slice} or @var{frame},
|
||||
by default @var{slice+frame}
|
||||
@item CPUFLAGS
|
||||
Specify CPU flags.
|
||||
|
||||
Specify CPU flags.
|
||||
@item TARGET_EXEC
|
||||
Specify or override the wrapper used to run the tests.
|
||||
The @var{TARGET_EXEC} option provides a way to run FATE wrapped in
|
||||
@command{valgrind}, @command{qemu-user} or @command{wine} or on remote targets
|
||||
through @command{ssh}.
|
||||
|
||||
Specify or override the wrapper used to run the tests.
|
||||
The @var{TARGET_EXEC} option provides a way to run FATE wrapped in
|
||||
@command{valgrind}, @command{qemu-user} or @command{wine} or on remote targets
|
||||
through @command{ssh}.
|
||||
@item GEN
|
||||
Set to @var{1} to generate the missing or mismatched references.
|
||||
@end table
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
The FFmpeg resampler provides a high-level interface to the
|
||||
The FFmpeg resampler provides an high-level interface to the
|
||||
libswresample library audio resampling utilities. In particular it
|
||||
allows to perform audio resampling, audio channel layout rematrixing,
|
||||
and convert audio format and packing layout.
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
The FFmpeg rescaler provides a high-level interface to the libswscale
|
||||
The FFmpeg rescaler provides an high-level interface to the libswscale
|
||||
library image conversion utilities. In particular it allows to perform
|
||||
image rescaling and pixel format conversion.
|
||||
|
||||
|
||||
163
doc/ffmpeg.texi
163
doc/ffmpeg.texi
@@ -80,22 +80,11 @@ The transcoding process in @command{ffmpeg} for each output can be described by
|
||||
the following diagram:
|
||||
|
||||
@example
|
||||
_______ ______________
|
||||
| | | |
|
||||
| input | demuxer | encoded data | decoder
|
||||
| file | ---------> | packets | -----+
|
||||
|_______| |______________| |
|
||||
v
|
||||
_________
|
||||
| |
|
||||
| decoded |
|
||||
| frames |
|
||||
________ ______________ |_________|
|
||||
| | | | |
|
||||
| output | <-------- | encoded data | <----+
|
||||
| file | muxer | packets | encoder
|
||||
|________| |______________|
|
||||
|
||||
_______ ______________ _________ ______________ ________
|
||||
| | | | | | | | | |
|
||||
| input | demuxer | encoded data | decoder | decoded | encoder | encoded data | muxer | output |
|
||||
| file | ---------> | packets | ---------> | frames | ---------> | packets | -------> | file |
|
||||
|_______| |______________| |_________| |______________| |________|
|
||||
|
||||
@end example
|
||||
|
||||
@@ -123,11 +112,11 @@ the same type. In the above diagram they can be represented by simply inserting
|
||||
an additional step between decoding and encoding:
|
||||
|
||||
@example
|
||||
_________ __________ ______________
|
||||
| | simple | | | |
|
||||
| decoded | fltrgrph | filtered | encoder | encoded data |
|
||||
| frames | ----------> | frames | ---------> | packets |
|
||||
|_________| |__________| |______________|
|
||||
_________ __________ ______________
|
||||
| | | | | |
|
||||
| decoded | simple filtergraph | filtered | encoder | encoded data |
|
||||
| frames | -------------------> | frames | ---------> | packets |
|
||||
|_________| |__________| |______________|
|
||||
|
||||
@end example
|
||||
|
||||
@@ -136,10 +125,10 @@ Simple filtergraphs are configured with the per-stream @option{-filter} option
|
||||
A simple filtergraph for video can look for example like this:
|
||||
|
||||
@example
|
||||
_______ _____________ _______ ________
|
||||
| | | | | | | |
|
||||
| input | ---> | deinterlace | ---> | scale | ---> | output |
|
||||
|_______| |_____________| |_______| |________|
|
||||
_______ _____________ _______ _____ ________
|
||||
| | | | | | | | | |
|
||||
| input | ---> | deinterlace | ---> | scale | ---> | fps | ---> | output |
|
||||
|_______| |_____________| |_______| |_____| |________|
|
||||
|
||||
@end example
|
||||
|
||||
@@ -225,7 +214,7 @@ described.
|
||||
@chapter Options
|
||||
@c man begin OPTIONS
|
||||
|
||||
@include fftools-common-opts.texi
|
||||
@include avtools-common-opts.texi
|
||||
|
||||
@section Main options
|
||||
|
||||
@@ -283,33 +272,30 @@ Set the file size limit, expressed in bytes.
|
||||
|
||||
@item -ss @var{position} (@emph{input/output})
|
||||
When used as an input option (before @code{-i}), seeks in this input file to
|
||||
@var{position}. Note the in most formats it is not possible to seek exactly, so
|
||||
@command{ffmpeg} will seek to the closest seek point before @var{position}.
|
||||
When transcoding and @option{-accurate_seek} is enabled (the default), this
|
||||
extra segment between the seek point and @var{position} will be decoded and
|
||||
discarded. When doing stream copy or when @option{-noaccurate_seek} is used, it
|
||||
will be preserved.
|
||||
|
||||
When used as an output option (before an output filename), decodes but discards
|
||||
input until the timestamps reach @var{position}.
|
||||
@var{position}. When used as an output option (before an output filename),
|
||||
decodes but discards input until the timestamps reach @var{position}. This is
|
||||
slower, but more accurate.
|
||||
|
||||
@var{position} may be either in seconds or in @code{hh:mm:ss[.xxx]} form.
|
||||
|
||||
@item -itsoffset @var{offset} (@emph{input})
|
||||
Set the input time offset.
|
||||
Set the input time offset in seconds.
|
||||
@code{[-]hh:mm:ss[.xxx]} syntax is also supported.
|
||||
The offset is added to the timestamps of the input files.
|
||||
Specifying a positive offset means that the corresponding
|
||||
streams are delayed by @var{offset} seconds.
|
||||
|
||||
@var{offset} must be a time duration specification,
|
||||
see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
|
||||
The offset is added to the timestamps of the input files. Specifying
|
||||
a positive offset means that the corresponding streams are delayed by
|
||||
the time duration specified in @var{offset}.
|
||||
|
||||
@item -timestamp @var{date} (@emph{output})
|
||||
@item -timestamp @var{time} (@emph{output})
|
||||
Set the recording timestamp in the container.
|
||||
|
||||
@var{date} must be a time duration specification,
|
||||
see @ref{date syntax,,the Date section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
The syntax for @var{time} is:
|
||||
@example
|
||||
now|([(YYYY-MM-DD|YYYYMMDD)[T|t| ]]((HH:MM:SS[.m...])|(HHMMSS[.m...]))[Z|z])
|
||||
@end example
|
||||
If the value is "now" it takes the current time.
|
||||
Time is local time unless 'Z' or 'z' is appended, in which case it is
|
||||
interpreted as UTC.
|
||||
If the year-month-day part is not specified it takes the current
|
||||
year-month-day.
|
||||
|
||||
@item -metadata[:metadata_specifier] @var{key}=@var{value} (@emph{output,per-metadata})
|
||||
Set a metadata key/value pair.
|
||||
@@ -356,13 +342,8 @@ Stop writing to the stream after @var{framecount} frames.
|
||||
|
||||
@item -q[:@var{stream_specifier}] @var{q} (@emph{output,per-stream})
|
||||
@itemx -qscale[:@var{stream_specifier}] @var{q} (@emph{output,per-stream})
|
||||
Use fixed quality scale (VBR). The meaning of @var{q}/@var{qscale} is
|
||||
Use fixed quality scale (VBR). The meaning of @var{q} is
|
||||
codec-dependent.
|
||||
If @var{qscale} is used without a @var{stream_specifier} then it applies only
|
||||
to the video stream, this is to maintain compatibility with previous behavior
|
||||
and as specifying the same codec specific value to 2 different codecs that is
|
||||
audio and video generally is not what is intended when no stream_specifier is
|
||||
used.
|
||||
|
||||
@anchor{filter_option}
|
||||
@item -filter[:@var{stream_specifier}] @var{filtergraph} (@emph{output,per-stream})
|
||||
@@ -516,6 +497,9 @@ prefix is ``ffmpeg2pass''. The complete file name will be
|
||||
@file{PREFIX-N.log}, where N is a number specific to the output
|
||||
stream
|
||||
|
||||
@item -vlang @var{code}
|
||||
Set the ISO 639 language code (3 letters) of the current video stream.
|
||||
|
||||
@item -vf @var{filtergraph} (@emph{output})
|
||||
Create the filtergraph specified by @var{filtergraph} and use it to
|
||||
filter the stream.
|
||||
@@ -626,42 +610,6 @@ would be more efficient.
|
||||
@item -copyinkf[:@var{stream_specifier}] (@emph{output,per-stream})
|
||||
When doing stream copy, copy also non-key frames found at the
|
||||
beginning.
|
||||
|
||||
@item -hwaccel[:@var{stream_specifier}] @var{hwaccel} (@emph{input,per-stream})
|
||||
Use hardware acceleration to decode the matching stream(s). The allowed values
|
||||
of @var{hwaccel} are:
|
||||
@table @option
|
||||
@item none
|
||||
Do not use any hardware acceleration (the default).
|
||||
|
||||
@item auto
|
||||
Automatically select the hardware acceleration method.
|
||||
|
||||
@item vdpau
|
||||
Use VDPAU (Video Decode and Presentation API for Unix) hardware acceleration.
|
||||
@end table
|
||||
|
||||
This option has no effect if the selected hwaccel is not available or not
|
||||
supported by the chosen decoder.
|
||||
|
||||
Note that most acceleration methods are intended for playback and will not be
|
||||
faster than software decoding on modern CPUs. Additionally, @command{ffmpeg}
|
||||
will usually need to copy the decoded frames from the GPU memory into the system
|
||||
memory, resulting in further performance loss. This option is thus mainly
|
||||
useful for testing.
|
||||
|
||||
@item -hwaccel_device[:@var{stream_specifier}] @var{hwaccel_device} (@emph{input,per-stream})
|
||||
Select a device to use for hardware acceleration.
|
||||
|
||||
This option only makes sense when the @option{-hwaccel} option is also
|
||||
specified. Its exact meaning depends on the specific hardware acceleration
|
||||
method chosen.
|
||||
|
||||
@table @option
|
||||
@item vdpau
|
||||
For VDPAU, this option specifies the X11 display/screen to use. If this option
|
||||
is not specified, the value of the @var{DISPLAY} environment variable is used
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@section Audio Options
|
||||
@@ -714,6 +662,8 @@ stereo but not 6 channels as 5.1. The default is to always try to guess. Use
|
||||
@section Subtitle options:
|
||||
|
||||
@table @option
|
||||
@item -slang @var{code}
|
||||
Set the ISO 639 language code (3 letters) of the current subtitle stream.
|
||||
@item -scodec @var{codec} (@emph{input/output})
|
||||
Set the subtitle codec. This is an alias for @code{-codec:s}.
|
||||
@item -sn (@emph{output})
|
||||
@@ -921,12 +871,13 @@ Dump each input packet to stderr.
|
||||
When dumping packets, also dump the payload.
|
||||
@item -re (@emph{input})
|
||||
Read input at native frame rate. Mainly used to simulate a grab device.
|
||||
or live input stream (e.g. when reading from a file). Should not be used
|
||||
with actual grab devices or live input streams (where it can cause packet
|
||||
loss).
|
||||
By default @command{ffmpeg} attempts to read the input(s) as fast as possible.
|
||||
This option will slow down the reading of the input(s) to the native frame rate
|
||||
of the input(s). It is useful for real-time output (e.g. live streaming).
|
||||
of the input(s). It is useful for real-time output (e.g. live streaming). If
|
||||
your input(s) is coming from some other live streaming source (through HTTP or
|
||||
UDP for example) the server might already be in real-time, thus the option will
|
||||
likely not be required. On the other hand, this is meaningful if your input(s)
|
||||
is a file you are trying to push in real-time.
|
||||
@item -loop_input
|
||||
Loop over the input stream. Currently it works only for image
|
||||
streams. This option is used for automatic FFserver testing.
|
||||
@@ -1042,7 +993,7 @@ ffmpeg -i h264.mp4 -c:v copy -bsf:v h264_mp4toannexb -an out.h264
|
||||
ffmpeg -i file.mov -an -vn -bsf:s mov2textsub -c:s copy -f rawvideo sub.txt
|
||||
@end example
|
||||
|
||||
@item -tag[:@var{stream_specifier}] @var{codec_tag} (@emph{input/output,per-stream})
|
||||
@item -tag[:@var{stream_specifier}] @var{codec_tag} (@emph{per-stream})
|
||||
Force a tag/fourcc for matching streams.
|
||||
|
||||
@item -timecode @var{hh}:@var{mm}:@var{ss}SEP@var{ff}
|
||||
@@ -1109,21 +1060,13 @@ This option is similar to @option{-filter_complex}, the only difference is that
|
||||
its argument is the name of the file from which a complex filtergraph
|
||||
description is to be read.
|
||||
|
||||
@item -accurate_seek (@emph{input})
|
||||
This option enables or disables accurate seeking in input files with the
|
||||
@option{-ss} option. It is enabled by default, so seeking is accurate when
|
||||
transcoding. Use @option{-noaccurate_seek} to disable it, which may be useful
|
||||
e.g. when copying some streams and transcoding the others.
|
||||
|
||||
@item -override_ffserver (@emph{global})
|
||||
Overrides the input specifications from @command{ffserver}. Using this
|
||||
option you can map any input stream to @command{ffserver} and control
|
||||
many aspects of the encoding from @command{ffmpeg}. Without this
|
||||
option @command{ffmpeg} will transmit to @command{ffserver} what is
|
||||
requested by @command{ffserver}.
|
||||
|
||||
Overrides the input specifications from ffserver. Using this option you can
|
||||
map any input stream to ffserver and control many aspects of the encoding from
|
||||
ffmpeg. Without this option ffmpeg will transmit to ffserver what is requested by
|
||||
ffserver.
|
||||
The option is intended for cases where features are needed that cannot be
|
||||
specified to @command{ffserver} but can be to @command{ffmpeg}.
|
||||
specified to ffserver but can be to ffmpeg.
|
||||
|
||||
@end table
|
||||
|
||||
@@ -1182,7 +1125,7 @@ then it will search for the file @file{libvpx-1080p.ffpreset}.
|
||||
|
||||
@itemize
|
||||
@item
|
||||
For streaming at very low bitrates, use a low frame rate
|
||||
For streaming at very low bitrate application, use a low frame rate
|
||||
and a small GOP size. This is especially true for RealVideo where
|
||||
the Linux player does not seem to be very fast, so it can miss
|
||||
frames. An example is:
|
||||
@@ -1261,14 +1204,14 @@ standard mixer.
|
||||
Grab the X11 display with ffmpeg via
|
||||
|
||||
@example
|
||||
ffmpeg -f x11grab -video_size cif -framerate 25 -i :0.0 /tmp/out.mpg
|
||||
ffmpeg -f x11grab -s cif -r 25 -i :0.0 /tmp/out.mpg
|
||||
@end example
|
||||
|
||||
0.0 is display.screen number of your X11 server, same as
|
||||
the DISPLAY environment variable.
|
||||
|
||||
@example
|
||||
ffmpeg -f x11grab -video_size cif -framerate 25 -i :0.0+10,20 /tmp/out.mpg
|
||||
ffmpeg -f x11grab -s cif -r 25 -i :0.0+10,20 /tmp/out.mpg
|
||||
@end example
|
||||
|
||||
0.0 is display.screen number of your X11 server, same as the DISPLAY environment
|
||||
|
||||
@@ -24,7 +24,7 @@ various FFmpeg APIs.
|
||||
@chapter Options
|
||||
@c man begin OPTIONS
|
||||
|
||||
@include fftools-common-opts.texi
|
||||
@include avtools-common-opts.texi
|
||||
|
||||
@section Main options
|
||||
|
||||
@@ -174,26 +174,17 @@ Toggle full screen.
|
||||
Pause.
|
||||
|
||||
@item a
|
||||
Cycle audio channel in the curret program.
|
||||
Cycle audio channel.
|
||||
|
||||
@item v
|
||||
Cycle video channel.
|
||||
|
||||
@item t
|
||||
Cycle subtitle channel in the current program.
|
||||
|
||||
@item c
|
||||
Cycle program.
|
||||
Cycle subtitle channel.
|
||||
|
||||
@item w
|
||||
Show audio waves.
|
||||
|
||||
@item s
|
||||
Step to the next frame.
|
||||
|
||||
Pause if the stream is not already paused, step to the next video
|
||||
frame, and pause.
|
||||
|
||||
@item left/right
|
||||
Seek backward/forward 10 seconds.
|
||||
|
||||
@@ -201,8 +192,6 @@ Seek backward/forward 10 seconds.
|
||||
Seek backward/forward 1 minute.
|
||||
|
||||
@item page down/page up
|
||||
Seek to the previous/next chapter.
|
||||
or if there are no chapters
|
||||
Seek backward/forward 10 minutes.
|
||||
|
||||
@item mouse click
|
||||
@@ -214,7 +203,6 @@ Seek to percentage in file corresponding to fraction of width.
|
||||
|
||||
@include config.texi
|
||||
@ifset config-all
|
||||
@set config-readonly
|
||||
@ifset config-avutil
|
||||
@include utils.texi
|
||||
@end ifset
|
||||
|
||||
122
doc/ffprobe.texi
122
doc/ffprobe.texi
@@ -44,15 +44,14 @@ name (which may be shared by other sections), and an unique
|
||||
name. See the output of @option{sections}.
|
||||
|
||||
Metadata tags stored in the container or in the streams are recognized
|
||||
and printed in the corresponding "FORMAT", "STREAM" or "PROGRAM_STREAM"
|
||||
section.
|
||||
and printed in the corresponding "FORMAT" or "STREAM" section.
|
||||
|
||||
@c man end
|
||||
|
||||
@chapter Options
|
||||
@c man begin OPTIONS
|
||||
|
||||
@include fftools-common-opts.texi
|
||||
@include avtools-common-opts.texi
|
||||
|
||||
@section Main options
|
||||
|
||||
@@ -113,7 +112,7 @@ ffprobe -show_packets -select_streams v:1 INPUT
|
||||
@end example
|
||||
|
||||
@item -show_data
|
||||
Show payload data, as a hexadecimal and ASCII dump. Coupled with
|
||||
Show payload data, as an hexadecimal and ASCII dump. Coupled with
|
||||
@option{-show_packets}, it will dump the packets' data. Coupled with
|
||||
@option{-show_streams}, it will dump the codec extradata.
|
||||
|
||||
@@ -197,11 +196,11 @@ The information for each single packet is printed within a dedicated
|
||||
section with name "PACKET".
|
||||
|
||||
@item -show_frames
|
||||
Show information about each frame and subtitle contained in the input
|
||||
multimedia stream.
|
||||
Show information about each frame contained in the input multimedia
|
||||
stream.
|
||||
|
||||
The information for each single frame is printed within a dedicated
|
||||
section with name "FRAME" or "SUBTITLE".
|
||||
section with name "FRAME".
|
||||
|
||||
@item -show_streams
|
||||
Show information about each media stream contained in the input
|
||||
@@ -210,13 +209,6 @@ multimedia stream.
|
||||
Each media stream information is printed within a dedicated section
|
||||
with name "STREAM".
|
||||
|
||||
@item -show_programs
|
||||
Show information about programs and their streams contained in the input
|
||||
multimedia stream.
|
||||
|
||||
Each media stream information is printed within a dedicated section
|
||||
with name "PROGRAM_STREAM".
|
||||
|
||||
@item -show_chapters
|
||||
Show information about chapters stored in the format.
|
||||
|
||||
@@ -230,70 +222,6 @@ corresponding stream section.
|
||||
Count the number of packets per stream and report it in the
|
||||
corresponding stream section.
|
||||
|
||||
@item -read_intervals @var{read_intervals}
|
||||
|
||||
Read only the specified intervals. @var{read_intervals} must be a
|
||||
sequence of interval specifications separated by ",".
|
||||
@command{ffprobe} will seek to the interval starting point, and will
|
||||
continue reading from that.
|
||||
|
||||
Each interval is specified by two optional parts, separated by "%".
|
||||
|
||||
The first part specifies the interval start position. It is
|
||||
interpreted as an abolute position, or as a relative offset from the
|
||||
current position if it is preceded by the "+" character. If this first
|
||||
part is not specified, no seeking will be performed when reading this
|
||||
interval.
|
||||
|
||||
The second part specifies the interval end position. It is interpreted
|
||||
as an absolute position, or as a relative offset from the current
|
||||
position if it is preceded by the "+" character. If the offset
|
||||
specification starts with "#", it is interpreted as the number of
|
||||
packets to read (not including the flushing packets) from the interval
|
||||
start. If no second part is specified, the program will read until the
|
||||
end of the input.
|
||||
|
||||
Note that seeking is not accurate, thus the actual interval start
|
||||
point may be different from the specified position. Also, when an
|
||||
interval duration is specified, the absolute end time will be computed
|
||||
by adding the duration to the interval start point found by seeking
|
||||
the file, rather than to the specified start value.
|
||||
|
||||
The formal syntax is given by:
|
||||
@example
|
||||
@var{INTERVAL} ::= [@var{START}|+@var{START_OFFSET}][%[@var{END}|+@var{END_OFFSET}]]
|
||||
@var{INTERVALS} ::= @var{INTERVAL}[,@var{INTERVALS}]
|
||||
@end example
|
||||
|
||||
A few examples follow.
|
||||
@itemize
|
||||
@item
|
||||
Seek to time 10, read packets until 20 seconds after the found seek
|
||||
point, then seek to position @code{01:30} (1 minute and thirty
|
||||
seconds) and read packets until position @code{01:45}.
|
||||
@example
|
||||
10%+20,01:30%01:45
|
||||
@end example
|
||||
|
||||
@item
|
||||
Read only 42 packets after seeking to position @code{01:23}:
|
||||
@example
|
||||
01:23%+#42
|
||||
@end example
|
||||
|
||||
@item
|
||||
Read only the first 20 seconds from the start:
|
||||
@example
|
||||
%+20
|
||||
@end example
|
||||
|
||||
@item
|
||||
Read from the start until position @code{02:30}:
|
||||
@example
|
||||
%02:30
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@item -show_private_data, -private
|
||||
Show private data, that is data depending on the format of the
|
||||
particular shown element.
|
||||
@@ -337,39 +265,6 @@ A writer may accept one or more arguments, which specify the options
|
||||
to adopt. The options are specified as a list of @var{key}=@var{value}
|
||||
pairs, separated by ":".
|
||||
|
||||
All writers support the following options:
|
||||
|
||||
@table @option
|
||||
@item string_validation, sv
|
||||
Set string validation mode.
|
||||
|
||||
The following values are accepted.
|
||||
@table @samp
|
||||
@item fail
|
||||
The writer will fail immediately in case an invalid string (UTF-8)
|
||||
sequence or code point is found in the input. This is especially
|
||||
useful to validate input metadata.
|
||||
|
||||
@item ignore
|
||||
Any validation error will be ignored. This will result in possibly
|
||||
broken output, especially with the json or xml writer.
|
||||
|
||||
@item replace
|
||||
The writer will substitute invalid UTF-8 sequences or code points with
|
||||
the string specified with the @option{string_validation_replacement}.
|
||||
@end table
|
||||
|
||||
Default value is @samp{replace}.
|
||||
|
||||
@item string_validation_replacement, svr
|
||||
Set replacement string to use in case @option{string_validation} is
|
||||
set to @samp{replace}.
|
||||
|
||||
In case the option is not specified, the writer will assume the empty
|
||||
string, that is it will remove the invalid sequences from the input
|
||||
strings.
|
||||
@end table
|
||||
|
||||
A description of the currently available writers follows.
|
||||
|
||||
@section default
|
||||
@@ -384,8 +279,8 @@ keyN=valN
|
||||
[/SECTION]
|
||||
@end example
|
||||
|
||||
Metadata tags are printed as a line in the corresponding FORMAT, STREAM or
|
||||
PROGRAM_STREAM section, and are prefixed by the string "TAG:".
|
||||
Metadata tags are printed as a line in the corresponding FORMAT or
|
||||
STREAM section, and are prefixed by the string "TAG:".
|
||||
|
||||
A description of the accepted options follows.
|
||||
|
||||
@@ -599,7 +494,6 @@ DV, GXF and AVI timecodes are available in format metadata
|
||||
|
||||
@include config.texi
|
||||
@ifset config-all
|
||||
@set config-readonly
|
||||
@ifset config-avutil
|
||||
@include utils.texi
|
||||
@end ifset
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
<xsd:element name="packets" type="ffprobe:packetsType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="frames" type="ffprobe:framesType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="streams" type="ffprobe:streamsType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="programs" type="ffprobe:programsType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="chapters" type="ffprobe:chaptersType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="format" type="ffprobe:formatType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="error" type="ffprobe:errorType" minOccurs="0" maxOccurs="1" />
|
||||
@@ -28,10 +27,7 @@
|
||||
|
||||
<xsd:complexType name="framesType">
|
||||
<xsd:sequence>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="frame" type="ffprobe:frameType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="subtitle" type="ffprobe:subtitleType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:choice>
|
||||
<xsd:element name="frame" type="ffprobe:frameType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
@@ -61,8 +57,6 @@
|
||||
<xsd:attribute name="pkt_pts_time" type="xsd:float"/>
|
||||
<xsd:attribute name="pkt_dts" type="xsd:long" />
|
||||
<xsd:attribute name="pkt_dts_time" type="xsd:float"/>
|
||||
<xsd:attribute name="best_effort_timestamp" type="xsd:long" />
|
||||
<xsd:attribute name="best_effort_timestamp_time" type="xsd:float" />
|
||||
<xsd:attribute name="pkt_duration" type="xsd:long" />
|
||||
<xsd:attribute name="pkt_duration_time" type="xsd:float"/>
|
||||
<xsd:attribute name="pkt_pos" type="xsd:long" />
|
||||
@@ -87,28 +81,12 @@
|
||||
<xsd:attribute name="repeat_pict" type="xsd:int" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="subtitleType">
|
||||
<xsd:attribute name="media_type" type="xsd:string" fixed="subtitle" use="required"/>
|
||||
<xsd:attribute name="pts" type="xsd:long" />
|
||||
<xsd:attribute name="pts_time" type="xsd:float"/>
|
||||
<xsd:attribute name="format" type="xsd:int" />
|
||||
<xsd:attribute name="start_display_time" type="xsd:int" />
|
||||
<xsd:attribute name="end_display_time" type="xsd:int" />
|
||||
<xsd:attribute name="num_rects" type="xsd:int" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="streamsType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="stream" type="ffprobe:streamType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="programsType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="program" type="ffprobe:programType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="streamDispositionType">
|
||||
<xsd:attribute name="default" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="dub" type="xsd:int" use="required" />
|
||||
@@ -125,8 +103,8 @@
|
||||
|
||||
<xsd:complexType name="streamType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="disposition" type="ffprobe:streamDispositionType" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="disposition" type="ffprobe:streamDispositionType" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="index" type="xsd:int" use="required"/>
|
||||
@@ -153,7 +131,6 @@
|
||||
<xsd:attribute name="sample_fmt" type="xsd:string"/>
|
||||
<xsd:attribute name="sample_rate" type="xsd:int"/>
|
||||
<xsd:attribute name="channels" type="xsd:int"/>
|
||||
<xsd:attribute name="channel_layout" type="xsd:string"/>
|
||||
<xsd:attribute name="bits_per_sample" type="xsd:int"/>
|
||||
|
||||
<xsd:attribute name="id" type="xsd:string"/>
|
||||
@@ -170,23 +147,6 @@
|
||||
<xsd:attribute name="nb_read_packets" type="xsd:int"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="programType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="streams" type="ffprobe:streamsType" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="program_id" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="program_num" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="nb_streams" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="start_time" type="xsd:float"/>
|
||||
<xsd:attribute name="start_pts" type="xsd:long"/>
|
||||
<xsd:attribute name="end_time" type="xsd:float"/>
|
||||
<xsd:attribute name="end_pts" type="xsd:long"/>
|
||||
<xsd:attribute name="pmt_pid" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="pcr_pid" type="xsd:int" use="required"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="formatType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
@@ -194,14 +154,12 @@
|
||||
|
||||
<xsd:attribute name="filename" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="nb_streams" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="nb_programs" type="xsd:int" use="required"/>
|
||||
<xsd:attribute name="format_name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="format_long_name" type="xsd:string"/>
|
||||
<xsd:attribute name="start_time" type="xsd:float"/>
|
||||
<xsd:attribute name="duration" type="xsd:float"/>
|
||||
<xsd:attribute name="size" type="xsd:long"/>
|
||||
<xsd:attribute name="bit_rate" type="xsd:long"/>
|
||||
<xsd:attribute name="probe_score" type="xsd:int"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="tagType">
|
||||
|
||||
@@ -235,7 +235,7 @@ StartSendOnKey
|
||||
|
||||
#<Stream test.ogg>
|
||||
#Feed feed1.ffm
|
||||
#Metadata title "Stream title"
|
||||
#Title "Stream title"
|
||||
#AudioBitRate 64
|
||||
#AudioChannels 2
|
||||
#AudioSampleRate 44100
|
||||
@@ -280,10 +280,10 @@ StartSendOnKey
|
||||
#<Stream file.asf>
|
||||
#File "/usr/local/httpd/htdocs/test.asf"
|
||||
#NoAudio
|
||||
#Metadata author "Me"
|
||||
#Metadata copyright "Super MegaCorp"
|
||||
#Metadata title "Test stream from disk"
|
||||
#Metadata comment "Test comment"
|
||||
#Author "Me"
|
||||
#Copyright "Super MegaCorp"
|
||||
#Title "Test stream from disk"
|
||||
#Comment "Test comment"
|
||||
#</Stream>
|
||||
|
||||
|
||||
|
||||
@@ -16,14 +16,11 @@ ffserver [@var{options}]
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
@command{ffserver} is a streaming server for both audio and video.
|
||||
It supports several live feeds, streaming from files and time shifting
|
||||
on live feeds. You can seek to positions in the past on each live
|
||||
feed, provided you specify a big enough feed storage.
|
||||
|
||||
@command{ffserver} is configured through a configuration file, which
|
||||
is read at startup. If not explicitly specified, it will read from
|
||||
@file{/etc/ffserver.conf}.
|
||||
@command{ffserver} is a streaming server for both audio and video. It
|
||||
supports several live feeds, streaming from files and time shifting on
|
||||
live feeds (you can seek to positions in the past on each live feed,
|
||||
provided you specify a big enough feed storage in
|
||||
@file{ffserver.conf}).
|
||||
|
||||
@command{ffserver} receives prerecorded files or FFM streams from some
|
||||
@command{ffmpeg} instance as input, then streams them over
|
||||
@@ -42,126 +39,10 @@ For each feed you can have different output streams in various
|
||||
formats, each one specified by a @code{<Stream>} section in the
|
||||
configuration file.
|
||||
|
||||
@chapter Detailed description
|
||||
|
||||
@command{ffserver} works by forwarding streams encoded by
|
||||
@command{ffmpeg}, or pre-recorded streams which are read from disk.
|
||||
|
||||
Precisely, @command{ffserver} acts as an HTTP server, accepting POST
|
||||
requests from @command{ffmpeg} to acquire the stream to publish, and
|
||||
serving RTSP clients or HTTP clients GET requests with the stream
|
||||
media content.
|
||||
|
||||
A feed is an @ref{FFM} stream created by @command{ffmpeg}, and sent to
|
||||
a port where @command{ffserver} is listening.
|
||||
|
||||
Each feed is identified by a unique name, corresponding to the name
|
||||
of the resource published on @command{ffserver}, and is configured by
|
||||
a dedicated @code{Feed} section in the configuration file.
|
||||
|
||||
The feed publish URL is given by:
|
||||
@example
|
||||
http://@var{ffserver_ip_address}:@var{http_port}/@var{feed_name}
|
||||
@end example
|
||||
|
||||
where @var{ffserver_ip_address} is the IP address of the machine where
|
||||
@command{ffserver} is installed, @var{http_port} is the port number of
|
||||
the HTTP server (configured through the @option{Port} option), and
|
||||
@var{feed_name} is the name of the corresponding feed defined in the
|
||||
configuration file.
|
||||
|
||||
Each feed is associated to a file which is stored on disk. This stored
|
||||
file is used to allow to send pre-recorded data to a player as fast as
|
||||
possible when new content is added in real-time to the stream.
|
||||
|
||||
A "live-stream" or "stream" is a resource published by
|
||||
@command{ffserver}, and made accessible through the HTTP protocol to
|
||||
clients.
|
||||
|
||||
A stream can be connected to a feed, or to a file. In the first case,
|
||||
the published stream is forwarded from the corresponding feed
|
||||
generated by a running instance of @command{ffmpeg}, in the second
|
||||
case the stream is read from a pre-recorded file.
|
||||
|
||||
Each stream is identified by a unique name, corresponding to the name
|
||||
of the resource served by @command{ffserver}, and is configured by
|
||||
a dedicated @code{Stream} section in the configuration file.
|
||||
|
||||
The stream access HTTP URL is given by:
|
||||
@example
|
||||
http://@var{ffserver_ip_address}:@var{http_port}/@var{stream_name}[@var{options}]
|
||||
@end example
|
||||
|
||||
The stream access RTSP URL is given by:
|
||||
@example
|
||||
http://@var{ffserver_ip_address}:@var{rtsp_port}/@var{stream_name}[@var{options}]
|
||||
@end example
|
||||
|
||||
@var{stream_name} is the name of the corresponding stream defined in
|
||||
the configuration file. @var{options} is a list of options specified
|
||||
after the URL which affects how the stream is served by
|
||||
@command{ffserver}. @var{http_port} and @var{rtsp_port} are the HTTP
|
||||
and RTSP ports configured with the options @var{Port} and
|
||||
@var{RTSPPort} respectively.
|
||||
|
||||
In case the stream is associated to a feed, the encoding parameters
|
||||
must be configured in the stream configuration. They are sent to
|
||||
@command{ffmpeg} when setting up the encoding. This allows
|
||||
@command{ffserver} to define the encoding parameters used by
|
||||
the @command{ffmpeg} encoders.
|
||||
|
||||
The @command{ffmpeg} @option{override_ffserver} commandline option
|
||||
allows one to override the encoding parameters set by the server.
|
||||
|
||||
Multiple streams can be connected to the same feed.
|
||||
|
||||
For example, you can have a situation described by the following
|
||||
graph:
|
||||
@example
|
||||
_________ __________
|
||||
| | | |
|
||||
ffmpeg 1 -----| feed 1 |-----| stream 1 |
|
||||
\ |_________|\ |__________|
|
||||
\ \
|
||||
\ \ __________
|
||||
\ \ | |
|
||||
\ \| stream 2 |
|
||||
\ |__________|
|
||||
\
|
||||
\ _________ __________
|
||||
\ | | | |
|
||||
\| feed 2 |-----| stream 3 |
|
||||
|_________| |__________|
|
||||
|
||||
_________ __________
|
||||
| | | |
|
||||
ffmpeg 2 -----| feed 3 |-----| stream 4 |
|
||||
|_________| |__________|
|
||||
|
||||
_________ __________
|
||||
| | | |
|
||||
| file 1 |-----| stream 5 |
|
||||
|_________| |__________|
|
||||
@end example
|
||||
|
||||
@anchor{FFM}
|
||||
@section FFM, FFM2 formats
|
||||
|
||||
FFM and FFM2 are formats used by ffserver. They allow storing a wide variety of
|
||||
video and audio streams and encoding options, and can store a moving time segment
|
||||
of an infinite movie or a whole movie.
|
||||
|
||||
FFM is version specific, and there is limited compatibility of FFM files
|
||||
generated by one version of ffmpeg/ffserver and another version of
|
||||
ffmpeg/ffserver. It may work but it is not guaranteed to work.
|
||||
|
||||
FFM2 is extensible while maintaining compatibility and should work between
|
||||
differing versions of tools. FFM2 is the default.
|
||||
|
||||
@section Status stream
|
||||
|
||||
@command{ffserver} supports an HTTP interface which exposes the
|
||||
current status of the server.
|
||||
ffserver supports an HTTP interface which exposes the current status
|
||||
of the server.
|
||||
|
||||
Simply point your browser to the address of the special status stream
|
||||
specified in the configuration file.
|
||||
@@ -180,8 +61,27 @@ ACL allow 192.168.0.0 192.168.255.255
|
||||
then the server will post a page with the status information when
|
||||
the special stream @file{status.html} is requested.
|
||||
|
||||
@section What can this do?
|
||||
|
||||
When properly configured and running, you can capture video and audio in real
|
||||
time from a suitable capture card, and stream it out over the Internet to
|
||||
either Windows Media Player or RealAudio player (with some restrictions).
|
||||
|
||||
It can also stream from files, though that is currently broken. Very often, a
|
||||
web server can be used to serve up the files just as well.
|
||||
|
||||
It can stream prerecorded video from .ffm files, though it is somewhat tricky
|
||||
to make it work correctly.
|
||||
|
||||
@section How do I make it work?
|
||||
|
||||
First, build the kit. It *really* helps to have installed LAME first. Then when
|
||||
you run the ffserver ./configure, make sure that you have the
|
||||
@code{--enable-libmp3lame} flag turned on.
|
||||
|
||||
LAME is important as it allows for streaming audio to Windows Media Player.
|
||||
Don't ask why the other audio types do not work.
|
||||
|
||||
As a simple test, just run the following two command lines where INPUTFILE
|
||||
is some file which you can decode with ffmpeg:
|
||||
|
||||
@@ -209,6 +109,35 @@ You should edit the ffserver.conf file to suit your needs (in terms of
|
||||
frame rates etc). Then install ffserver and ffmpeg, write a script to start
|
||||
them up, and off you go.
|
||||
|
||||
@section Troubleshooting
|
||||
|
||||
@subsection I don't hear any audio, but video is fine.
|
||||
|
||||
Maybe you didn't install LAME, or got your ./configure statement wrong. Check
|
||||
the ffmpeg output to see if a line referring to MP3 is present. If not, then
|
||||
your configuration was incorrect. If it is, then maybe your wiring is not
|
||||
set up correctly. Maybe the sound card is not getting data from the right
|
||||
input source. Maybe you have a really awful audio interface (like I do)
|
||||
that only captures in stereo and also requires that one channel be flipped.
|
||||
If you are one of these people, then export 'AUDIO_FLIP_LEFT=1' before
|
||||
starting ffmpeg.
|
||||
|
||||
@subsection The audio and video lose sync after a while.
|
||||
|
||||
Yes, they do.
|
||||
|
||||
@subsection After a long while, the video update rate goes way down in WMP.
|
||||
|
||||
Yes, it does. Who knows why?
|
||||
|
||||
@subsection WMP 6.4 behaves differently to WMP 7.
|
||||
|
||||
Yes, it does. Any thoughts on this would be gratefully received. These
|
||||
differences extend to embedding WMP into a web page. [There are two
|
||||
object IDs that you can use: The old one, which does not play well, and
|
||||
the new one, which does (both tested on the same system). However,
|
||||
I suspect that the new one is not available unless you have installed WMP 7].
|
||||
|
||||
@section What else can it do?
|
||||
|
||||
You can replay video from .ffm files that was recorded earlier.
|
||||
@@ -248,6 +177,9 @@ specify a time. In addition, ffserver will skip frames until a key_frame
|
||||
is found. This further reduces the startup delay by not transferring data
|
||||
that will be discarded.
|
||||
|
||||
* You may want to adjust the MaxBandwidth in the ffserver.conf to limit
|
||||
the amount of bandwidth consumed by live streams.
|
||||
|
||||
@section Why does the ?buffer / Preroll stop working after a time?
|
||||
|
||||
It turns out that (on my machine at least) the number of frames successfully
|
||||
@@ -281,549 +213,37 @@ You use this by adding the ?date= to the end of the URL for the stream.
|
||||
For example: @samp{http://localhost:8080/test.asf?date=2002-07-26T23:05:00}.
|
||||
@c man end
|
||||
|
||||
@section What is FFM, FFM2
|
||||
|
||||
FFM and FFM2 are formats used by ffserver. They allow storing a wide variety of
|
||||
video and audio streams and encoding options, and can store a moving time segment
|
||||
of an infinite movie or a whole movie.
|
||||
|
||||
FFM is version specific, and there is limited compatibility of FFM files
|
||||
generated by one version of ffmpeg/ffserver and another version of
|
||||
ffmpeg/ffserver. It may work but it is not guaranteed to work.
|
||||
|
||||
FFM2 is extensible while maintaining compatibility and should work between
|
||||
differing versions of tools. FFM2 is the default.
|
||||
|
||||
@chapter Options
|
||||
@c man begin OPTIONS
|
||||
|
||||
@include fftools-common-opts.texi
|
||||
@include avtools-common-opts.texi
|
||||
|
||||
@section Main options
|
||||
|
||||
@table @option
|
||||
@item -f @var{configfile}
|
||||
Read configuration file @file{configfile}. If not specified it will
|
||||
read by default from @file{/etc/ffserver.conf}.
|
||||
|
||||
Use @file{configfile} instead of @file{/etc/ffserver.conf}.
|
||||
@item -n
|
||||
Enable no-launch mode. This option disables all the @code{Launch}
|
||||
directives within the various @code{<Feed>} sections. Since
|
||||
@command{ffserver} will not launch any @command{ffmpeg} instances, you
|
||||
will have to launch them manually.
|
||||
|
||||
Enable no-launch mode. This option disables all the Launch directives
|
||||
within the various <Stream> sections. Since ffserver will not launch
|
||||
any ffmpeg instances, you will have to launch them manually.
|
||||
@item -d
|
||||
Enable debug mode. This option increases log verbosity, and directs
|
||||
log messages to stdout. When specified, the @option{CustomLog} option
|
||||
is ignored.
|
||||
Enable debug mode. This option increases log verbosity, directs log
|
||||
messages to stdout.
|
||||
@end table
|
||||
|
||||
@chapter Configuration file syntax
|
||||
|
||||
@command{ffserver} reads a configuration file containing global
|
||||
options and settings for each stream and feed.
|
||||
|
||||
The configuration file consists of global options and dedicated
|
||||
sections, which must be introduced by "<@var{SECTION_NAME}
|
||||
@var{ARGS}>" on a separate line and must be terminated by a line in
|
||||
the form "</@var{SECTION_NAME}>". @var{ARGS} is optional.
|
||||
|
||||
Currently the following sections are recognized: @samp{Feed},
|
||||
@samp{Stream}, @samp{Redirect}.
|
||||
|
||||
A line starting with @code{#} is ignored and treated as a comment.
|
||||
|
||||
Name of options and sections are case-insensitive.
|
||||
|
||||
@section ACL syntax
|
||||
An ACL (Access Control List) specifies the address which are allowed
|
||||
to access a given stream, or to write a given feed.
|
||||
|
||||
It accepts the folling forms
|
||||
@itemize
|
||||
@item
|
||||
Allow/deny access to @var{address}.
|
||||
@example
|
||||
ACL ALLOW <address>
|
||||
ACL DENY <address>
|
||||
@end example
|
||||
|
||||
@item
|
||||
Allow/deny access to ranges of addresses from @var{first_address} to
|
||||
@var{last_address}.
|
||||
@example
|
||||
ACL ALLOW <first_address> <last_address>
|
||||
ACL DENY <first_address> <last_address>
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
You can repeat the ACL allow/deny as often as you like. It is on a per
|
||||
stream basis. The first match defines the action. If there are no matches,
|
||||
then the default is the inverse of the last ACL statement.
|
||||
|
||||
Thus 'ACL allow localhost' only allows access from localhost.
|
||||
'ACL deny 1.0.0.0 1.255.255.255' would deny the whole of network 1 and
|
||||
allow everybody else.
|
||||
|
||||
@section Global options
|
||||
@table @option
|
||||
@item Port @var{port_number}
|
||||
@item RTSPPort @var{port_number}
|
||||
|
||||
Set TCP port number on which the HTTP/RTSP server is listening. You
|
||||
must select a different port from your standard HTTP web server if it
|
||||
is running on the same computer.
|
||||
|
||||
If not specified, no corresponding server will be created.
|
||||
|
||||
@item BindAddress @var{ip_address}
|
||||
@item RTSPBindAddress @var{ip_address}
|
||||
Set address on which the HTTP/RTSP server is bound. Only useful if you
|
||||
have several network interfaces.
|
||||
|
||||
@item MaxHTTPConnections @var{n}
|
||||
Set number of simultaneous HTTP connections that can be handled. It
|
||||
has to be defined @emph{before} the @option{MaxClients} parameter,
|
||||
since it defines the @option{MaxClients} maximum limit.
|
||||
|
||||
Default value is 2000.
|
||||
|
||||
@item MaxClients @var{n}
|
||||
Set number of simultaneous requests that can be handled. Since
|
||||
@command{ffserver} is very fast, it is more likely that you will want
|
||||
to leave this high and use @option{MaxBandwidth}.
|
||||
|
||||
Default value is 5.
|
||||
|
||||
@item MaxBandwidth @var{kbps}
|
||||
Set the maximum amount of kbit/sec that you are prepared to consume
|
||||
when streaming to clients.
|
||||
|
||||
Default value is 1000.
|
||||
|
||||
@item CustomLog @var{filename}
|
||||
Set access log file (uses standard Apache log file format). '-' is the
|
||||
standard output.
|
||||
|
||||
If not specified @command{ffserver} will produce no log.
|
||||
|
||||
In case the commandline option @option{-d} is specified this option is
|
||||
ignored, and the log is written to standard output.
|
||||
|
||||
@item NoDaemon
|
||||
Set no-daemon mode. This option is currently ignored since now
|
||||
@command{ffserver} will always work in no-daemon mode, and is
|
||||
deprecated.
|
||||
@end table
|
||||
|
||||
@section Feed section
|
||||
|
||||
A Feed section defines a feed provided to @command{ffserver}.
|
||||
|
||||
Each live feed contains one video and/or audio sequence coming from an
|
||||
@command{ffmpeg} encoder or another @command{ffserver}. This sequence
|
||||
may be encoded simultaneously with several codecs at several
|
||||
resolutions.
|
||||
|
||||
A feed instance specification is introduced by a line in the form:
|
||||
@example
|
||||
<Feed FEED_FILENAME>
|
||||
@end example
|
||||
|
||||
where @var{FEED_FILENAME} specifies the unique name of the FFM stream.
|
||||
|
||||
The following options are recognized within a Feed section.
|
||||
|
||||
@table @option
|
||||
@item File @var{filename}
|
||||
@item ReadOnlyFile @var{filename}
|
||||
Set the path where the feed file is stored on disk.
|
||||
|
||||
If not specified, the @file{/tmp/FEED.ffm} is assumed, where
|
||||
@var{FEED} is the feed name.
|
||||
|
||||
If @option{ReadOnlyFile} is used the file is marked as read-only and
|
||||
it will not be deleted or updated.
|
||||
|
||||
@item Truncate
|
||||
Truncate the feed file, rather than appending to it. By default
|
||||
@command{ffserver} will append data to the file, until the maximum
|
||||
file size value is reached (see @option{FileMaxSize} option).
|
||||
|
||||
@item FileMaxSize @var{size}
|
||||
Set maximum size of the feed file in bytes. 0 means unlimited. The
|
||||
postfixes @code{K} (2^10), @code{M} (2^20), and @code{G} (2^30) are
|
||||
recognized.
|
||||
|
||||
Default value is 5M.
|
||||
|
||||
@item Launch @var{args}
|
||||
Launch an @command{ffmpeg} command when creating @command{ffserver}.
|
||||
|
||||
@var{args} must be a sequence of arguments to be provided to an
|
||||
@command{ffmpeg} instance. The first provided argument is ignored, and
|
||||
it is replaced by a path with the same dirname of the @command{ffserver}
|
||||
instance, followed by the remaining argument and terminated with a
|
||||
path corresponding to the feed.
|
||||
|
||||
When the launched process exits, @command{ffserver} will launch
|
||||
another program instance.
|
||||
|
||||
In case you need a more complex @command{ffmpeg} configuration,
|
||||
e.g. if you need to generate multiple FFM feeds with a single
|
||||
@command{ffmpeg} instance, you should launch @command{ffmpeg} by hand.
|
||||
|
||||
This option is ignored in case the commandline option @option{-n} is
|
||||
specified.
|
||||
|
||||
@item ACL @var{spec}
|
||||
Specify the list of IP address which are allowed or denied to write
|
||||
the feed. Multiple ACL options can be specified.
|
||||
@end table
|
||||
|
||||
@section Stream section
|
||||
|
||||
A Stream section defines a stream provided by @command{ffserver}, and
|
||||
identified by a single name.
|
||||
|
||||
The stream is sent when answering a request containing the stream
|
||||
name.
|
||||
|
||||
A stream section must be introduced by the line:
|
||||
@example
|
||||
<Stream STREAM_NAME>
|
||||
@end example
|
||||
|
||||
where @var{STREAM_NAME} specifies the unique name of the stream.
|
||||
|
||||
The following options are recognized within a Stream section.
|
||||
|
||||
Encoding options are marked with the @emph{encoding} tag, and they are
|
||||
used to set the encoding parameters, and are mapped to libavcodec
|
||||
encoding options. Not all encoding options are supported, in
|
||||
particular it is not possible to set encoder private options. In order
|
||||
to override the encoding options specified by @command{ffserver}, you
|
||||
can use the @command{ffmpeg} @option{override_ffserver} commandline
|
||||
option.
|
||||
|
||||
Only one of the @option{Feed} and @option{File} options should be set.
|
||||
|
||||
@table @option
|
||||
@item Feed @var{feed_name}
|
||||
Set the input feed. @var{feed_name} must correspond to an existing
|
||||
feed defined in a @code{Feed} section.
|
||||
|
||||
When this option is set, encoding options are used to setup the
|
||||
encoding operated by the remote @command{ffmpeg} process.
|
||||
|
||||
@item File @var{filename}
|
||||
Set the filename of the pre-recorded input file to stream.
|
||||
|
||||
When this option is set, encoding options are ignored and the input
|
||||
file content is re-streamed as is.
|
||||
|
||||
@item Format @var{format_name}
|
||||
Set the format of the output stream.
|
||||
|
||||
Must be the name of a format recognized by FFmpeg. If set to
|
||||
@samp{status}, it is treated as a status stream.
|
||||
|
||||
@item InputFormat @var{format_name}
|
||||
Set input format. If not specified, it is automatically guessed.
|
||||
|
||||
@item Preroll @var{n}
|
||||
Set this to the number of seconds backwards in time to start. Note that
|
||||
most players will buffer 5-10 seconds of video, and also you need to allow
|
||||
for a keyframe to appear in the data stream.
|
||||
|
||||
Default value is 0.
|
||||
|
||||
@item StartSendOnKey
|
||||
Do not send stream until it gets the first key frame. By default
|
||||
@command{ffserver} will send data immediately.
|
||||
|
||||
@item MaxTime @var{n}
|
||||
Set the number of seconds to run. This value set the maximum duration
|
||||
of the stream a client will be able to receive.
|
||||
|
||||
A value of 0 means that no limit is set on the stream duration.
|
||||
|
||||
@item ACL @var{spec}
|
||||
Set ACL for the stream.
|
||||
|
||||
@item DynamicACL @var{spec}
|
||||
|
||||
@item RTSPOption @var{option}
|
||||
|
||||
@item MulticastAddress @var{address}
|
||||
|
||||
@item MulticastPort @var{port}
|
||||
|
||||
@item MulticastTTL @var{integer}
|
||||
|
||||
@item NoLoop
|
||||
|
||||
@item FaviconURL @var{url}
|
||||
Set favicon (favourite icon) for the server status page. It is ignored
|
||||
for regular streams.
|
||||
|
||||
@item Author @var{value}
|
||||
@item Comment @var{value}
|
||||
@item Copyright @var{value}
|
||||
@item Title @var{value}
|
||||
Set metadata corresponding to the option. All these options are
|
||||
deprecated in favor of @option{Metadata}.
|
||||
|
||||
@item Metadata @var{key} @var{value}
|
||||
Set metadata value on the output stream.
|
||||
|
||||
@item NoAudio
|
||||
@item NoVideo
|
||||
Suppress audio/video.
|
||||
|
||||
@item AudioCodec @var{codec_name} (@emph{encoding,audio})
|
||||
Set audio codec.
|
||||
|
||||
@item AudioBitRate @var{rate} (@emph{encoding,audio})
|
||||
Set bitrate for the audio stream in kbits per second.
|
||||
|
||||
@item AudioChannels @var{n} (@emph{encoding,audio})
|
||||
Set number of audio channels.
|
||||
|
||||
@item AudioSampleRate @var{n} (@emph{encoding,audio})
|
||||
Set sampling frequency for audio. When using low bitrates, you should
|
||||
lower this frequency to 22050 or 11025. The supported frequencies
|
||||
depend on the selected audio codec.
|
||||
|
||||
@item AVOptionAudio @var{option} @var{value} (@emph{encoding,audio})
|
||||
Set generic option for audio stream.
|
||||
|
||||
@item AVPresetAudio @var{preset} (@emph{encoding,audio})
|
||||
Set preset for audio stream.
|
||||
|
||||
@item VideoCodec @var{codec_name} (@emph{encoding,video})
|
||||
Set video codec.
|
||||
|
||||
@item VideoBitRate @var{n} (@emph{encoding,video})
|
||||
Set bitrate for the video stream in kbits per second.
|
||||
|
||||
@item VideoBitRateRange @var{range} (@emph{encoding,video})
|
||||
Set video bitrate range.
|
||||
|
||||
A range must be specified in the form @var{minrate}-@var{maxrate}, and
|
||||
specifies the @option{minrate} and @option{maxrate} encoding options
|
||||
expressed in kbits per second.
|
||||
|
||||
@item VideoBitRateRangeTolerance @var{n} (@emph{encoding,video})
|
||||
Set video bitrate tolerance in kbits per second.
|
||||
|
||||
@item PixelFormat @var{pixel_format} (@emph{encoding,video})
|
||||
Set video pixel format.
|
||||
|
||||
@item Debug @var{integer} (@emph{encoding,video})
|
||||
Set video @option{debug} encoding option.
|
||||
|
||||
@item Strict @var{integer} (@emph{encoding,video})
|
||||
Set video @option{strict} encoding option.
|
||||
|
||||
@item VideoBufferSize @var{n} (@emph{encoding,video})
|
||||
Set ratecontrol buffer size, expressed in KB.
|
||||
|
||||
@item VideoFrameRate @var{n} (@emph{encoding,video})
|
||||
Set number of video frames per second.
|
||||
|
||||
@item VideoSize (@emph{encoding,video})
|
||||
Set size of the video frame, must be an abbreviation or in the form
|
||||
@var{W}x@var{H}. See @ref{video size syntax,,the Video size section
|
||||
in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
|
||||
Default value is @code{160x128}.
|
||||
|
||||
@item VideoIntraOnly (@emph{encoding,video})
|
||||
Transmit only intra frames (useful for low bitrates, but kills frame rate).
|
||||
|
||||
@item VideoGopSize @var{n} (@emph{encoding,video})
|
||||
If non-intra only, an intra frame is transmitted every VideoGopSize
|
||||
frames. Video synchronization can only begin at an intra frame.
|
||||
|
||||
@item VideoTag @var{tag} (@emph{encoding,video})
|
||||
Set video tag.
|
||||
|
||||
@item VideoHighQuality (@emph{encoding,video})
|
||||
@item Video4MotionVector (@emph{encoding,video})
|
||||
|
||||
@item BitExact (@emph{encoding,video})
|
||||
Set bitexact encoding flag.
|
||||
|
||||
@item IdctSimple (@emph{encoding,video})
|
||||
Set simple IDCT algorithm.
|
||||
|
||||
@item Qscale @var{n} (@emph{encoding,video})
|
||||
Enable constant quality encoding, and set video qscale (quantization
|
||||
scale) value, expressed in @var{n} QP units.
|
||||
|
||||
@item VideoQMin @var{n} (@emph{encoding,video})
|
||||
@item VideoQMax @var{n} (@emph{encoding,video})
|
||||
Set video qmin/qmax.
|
||||
|
||||
@item VideoQDiff @var{integer} (@emph{encoding,video})
|
||||
Set video @option{qdiff} encoding option.
|
||||
|
||||
@item LumiMask @var{float} (@emph{encoding,video})
|
||||
@item DarkMask @var{float} (@emph{encoding,video})
|
||||
Set @option{lumi_mask}/@option{dark_mask} encoding options.
|
||||
|
||||
@item AVOptionVideo @var{option} @var{value} (@emph{encoding,video})
|
||||
Set generic option for video stream.
|
||||
|
||||
@item AVPresetVideo @var{preset} (@emph{encoding,video})
|
||||
Set preset for video stream.
|
||||
|
||||
@var{preset} must be the path of a preset file.
|
||||
@end table
|
||||
|
||||
@subsection Server status stream
|
||||
|
||||
A server status stream is a special stream which is used to show
|
||||
statistics about the @command{ffserver} operations.
|
||||
|
||||
It must be specified setting the option @option{Format} to
|
||||
@samp{status}.
|
||||
|
||||
@section Redirect section
|
||||
|
||||
A redirect section specifies where to redirect the requested URL to
|
||||
another page.
|
||||
|
||||
A redirect section must be introduced by the line:
|
||||
@example
|
||||
<Redirect NAME>
|
||||
@end example
|
||||
|
||||
where @var{NAME} is the name of the page which should be redirected.
|
||||
|
||||
It only accepts the option @option{URL}, which specify the redirection
|
||||
URL.
|
||||
|
||||
@chapter Stream examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Multipart JPEG
|
||||
@example
|
||||
<Stream test.mjpg>
|
||||
Feed feed1.ffm
|
||||
Format mpjpeg
|
||||
VideoFrameRate 2
|
||||
VideoIntraOnly
|
||||
NoAudio
|
||||
Strict -1
|
||||
</Stream>
|
||||
@end example
|
||||
|
||||
@item
|
||||
Single JPEG
|
||||
@example
|
||||
<Stream test.jpg>
|
||||
Feed feed1.ffm
|
||||
Format jpeg
|
||||
VideoFrameRate 2
|
||||
VideoIntraOnly
|
||||
VideoSize 352x240
|
||||
NoAudio
|
||||
Strict -1
|
||||
</Stream>
|
||||
@end example
|
||||
|
||||
@item
|
||||
Flash
|
||||
@example
|
||||
<Stream test.swf>
|
||||
Feed feed1.ffm
|
||||
Format swf
|
||||
VideoFrameRate 2
|
||||
VideoIntraOnly
|
||||
NoAudio
|
||||
</Stream>
|
||||
@end example
|
||||
|
||||
@item
|
||||
ASF compatible
|
||||
@example
|
||||
<Stream test.asf>
|
||||
Feed feed1.ffm
|
||||
Format asf
|
||||
VideoFrameRate 15
|
||||
VideoSize 352x240
|
||||
VideoBitRate 256
|
||||
VideoBufferSize 40
|
||||
VideoGopSize 30
|
||||
AudioBitRate 64
|
||||
StartSendOnKey
|
||||
</Stream>
|
||||
@end example
|
||||
|
||||
@item
|
||||
MP3 audio
|
||||
@example
|
||||
<Stream test.mp3>
|
||||
Feed feed1.ffm
|
||||
Format mp2
|
||||
AudioCodec mp3
|
||||
AudioBitRate 64
|
||||
AudioChannels 1
|
||||
AudioSampleRate 44100
|
||||
NoVideo
|
||||
</Stream>
|
||||
@end example
|
||||
|
||||
@item
|
||||
Ogg Vorbis audio
|
||||
@example
|
||||
<Stream test.ogg>
|
||||
Feed feed1.ffm
|
||||
Metadata title "Stream title"
|
||||
AudioBitRate 64
|
||||
AudioChannels 2
|
||||
AudioSampleRate 44100
|
||||
NoVideo
|
||||
</Stream>
|
||||
@end example
|
||||
|
||||
@item
|
||||
Real with audio only at 32 kbits
|
||||
@example
|
||||
<Stream test.ra>
|
||||
Feed feed1.ffm
|
||||
Format rm
|
||||
AudioBitRate 32
|
||||
NoVideo
|
||||
</Stream>
|
||||
@end example
|
||||
|
||||
@item
|
||||
Real with audio and video at 64 kbits
|
||||
@example
|
||||
<Stream test.rm>
|
||||
Feed feed1.ffm
|
||||
Format rm
|
||||
AudioBitRate 32
|
||||
VideoBitRate 128
|
||||
VideoFrameRate 25
|
||||
VideoGopSize 25
|
||||
</Stream>
|
||||
@end example
|
||||
|
||||
@item
|
||||
For stream coming from a file: you only need to set the input filename
|
||||
and optionally a new format.
|
||||
|
||||
@example
|
||||
<Stream file.rm>
|
||||
File "/usr/local/httpd/htdocs/tlive.rm"
|
||||
NoAudio
|
||||
</Stream>
|
||||
@end example
|
||||
|
||||
@example
|
||||
<Stream file.asf>
|
||||
File "/usr/local/httpd/htdocs/test.asf"
|
||||
NoAudio
|
||||
Metadata author "Me"
|
||||
Metadata copyright "Super MegaCorp"
|
||||
Metadata title "Test stream from disk"
|
||||
Metadata comment "Test comment"
|
||||
</Stream>
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@c man end
|
||||
|
||||
@include config.texi
|
||||
|
||||
@@ -166,7 +166,7 @@ Buffer references ownership and permissions
|
||||
WRITE permission.
|
||||
|
||||
* Filters that read their input to produce a new frame on output (like
|
||||
scale) need the READ permission on input and must request a buffer
|
||||
scale) need the READ permission on input and and must request a buffer
|
||||
with the WRITE permission.
|
||||
|
||||
* Filters that intend to keep a reference after the filtering process
|
||||
|
||||
1588
doc/filters.texi
1588
doc/filters.texi
File diff suppressed because it is too large
Load Diff
@@ -58,8 +58,7 @@ Reduce the latency introduced by optional buffering
|
||||
@end table
|
||||
|
||||
@item seek2any @var{integer} (@emph{input})
|
||||
Allow seeking to non-keyframes on demuxer level when supported if set to 1.
|
||||
Default is 0.
|
||||
Forces seeking to enable seek to any mode if set to 1. Default is 0.
|
||||
|
||||
@item analyzeduration @var{integer} (@emph{input})
|
||||
Specify how many microseconds are analyzed to probe the input. A
|
||||
@@ -125,29 +124,20 @@ Consider things that a sane encoder should not do as an error.
|
||||
Use wallclock as timestamps.
|
||||
|
||||
@item avoid_negative_ts @var{integer} (@emph{output})
|
||||
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item make_non_negative
|
||||
Shift timestamps to make them non-negative.
|
||||
Also note that this affects only leading negative timestamps, and not
|
||||
non-monotonic negative timestamps.
|
||||
@item make_zero
|
||||
Shift timestamps so that the first timestamp is 0.
|
||||
@item auto (default)
|
||||
Enables shifting when required by the target format.
|
||||
@item disabled
|
||||
Disables shifting of timestamp.
|
||||
@end table
|
||||
Shift timestamps to make them non-negative. A value of 1 enables shifting,
|
||||
a value of 0 disables it, the default value of -1 enables shifting
|
||||
when required by the target format.
|
||||
|
||||
When shifting is enabled, all output timestamps are shifted by the
|
||||
same amount. Audio, video, and subtitles desynching and relative
|
||||
timestamp differences are preserved compared to how they would have
|
||||
been without shifting.
|
||||
|
||||
Also note that this affects only leading negative timestamps, and not
|
||||
non-monotonic negative timestamps.
|
||||
|
||||
@item skip_initial_bytes @var{integer} (@emph{input})
|
||||
Set number of bytes to skip before reading header and frames if set to 1.
|
||||
Default is 0.
|
||||
Set number initial bytes to skip. Default is 0.
|
||||
|
||||
@item correct_ts_overflow @var{integer} (@emph{input})
|
||||
Correct single timestamp overflows if set to 1. Default is 1.
|
||||
@@ -156,57 +146,10 @@ Correct single timestamp overflows if set to 1. Default is 1.
|
||||
Flush the underlying I/O stream after each packet. Default 1 enables it, and
|
||||
has the effect of reducing the latency; 0 disables it and may slightly
|
||||
increase performance in some cases.
|
||||
|
||||
@item output_ts_offset @var{offset} (@emph{output})
|
||||
Set the output time offset.
|
||||
|
||||
@var{offset} must be a time duration specification,
|
||||
see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
|
||||
The offset is added by the muxer to the output timestamps.
|
||||
|
||||
Specifying a positive offset means that the corresponding streams are
|
||||
delayed bt the time duration specified in @var{offset}. Default value
|
||||
is @code{0} (meaning that no offset is applied).
|
||||
@end table
|
||||
|
||||
@c man end FORMAT OPTIONS
|
||||
|
||||
@anchor{Format stream specifiers}
|
||||
@section Format stream specifiers
|
||||
|
||||
Format stream specifiers allow selection of one or more streams that
|
||||
match specific properties.
|
||||
|
||||
Possible forms of stream specifiers are:
|
||||
@table @option
|
||||
@item @var{stream_index}
|
||||
Matches the stream with this index.
|
||||
|
||||
@item @var{stream_type}[:@var{stream_index}]
|
||||
@var{stream_type} is one of following: 'v' for video, 'a' for audio,
|
||||
's' for subtitle, 'd' for data, and 't' for attachments. If
|
||||
@var{stream_index} is given, then it matches the stream number
|
||||
@var{stream_index} of this type. Otherwise, it matches all streams of
|
||||
this type.
|
||||
|
||||
@item p:@var{program_id}[:@var{stream_index}]
|
||||
If @var{stream_index} is given, then it matches the stream with number
|
||||
@var{stream_index} in the program with the id
|
||||
@var{program_id}. Otherwise, it matches all streams in the program.
|
||||
|
||||
@item #@var{stream_id}
|
||||
Matches the stream by a format-specific ID.
|
||||
@end table
|
||||
|
||||
The exact semantics of stream specifiers is defined by the
|
||||
@code{avformat_match_stream_specifier()} function declared in the
|
||||
@file{libavformat/avformat.h} header.
|
||||
|
||||
@ifclear config-writeonly
|
||||
@include demuxers.texi
|
||||
@end ifclear
|
||||
@ifclear config-readonly
|
||||
@include muxers.texi
|
||||
@end ifclear
|
||||
@include metadata.texi
|
||||
|
||||
@@ -94,7 +94,7 @@ Then pass @code{--enable-libtwolame} to configure to enable it.
|
||||
|
||||
@section libvpx
|
||||
|
||||
FFmpeg can make use of the libvpx library for VP8/VP9 encoding.
|
||||
FFmpeg can make use of the libvpx library for VP8 encoding.
|
||||
|
||||
Go to @url{http://www.webmproject.org/} and follow the instructions for
|
||||
installing the library. Then pass @code{--enable-libvpx} to configure to
|
||||
@@ -122,20 +122,6 @@ x264 is under the GNU Public License Version 2 or later
|
||||
details), you must upgrade FFmpeg's license to GPL in order to use it.
|
||||
@end float
|
||||
|
||||
@section x265
|
||||
|
||||
FFmpeg can make use of the x265 library for HEVC encoding.
|
||||
|
||||
Go to @url{http://x265.org/developers.html} and follow the instructions
|
||||
for installing the library. Then pass @code{--enable-libx265} to configure
|
||||
to enable it.
|
||||
|
||||
@float note
|
||||
x265 is under the GNU Public License Version 2 or later
|
||||
(see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for
|
||||
details), you must upgrade FFmpeg's license to GPL in order to use it.
|
||||
@end float
|
||||
|
||||
@section libilbc
|
||||
|
||||
iLBC is a narrowband speech codec that has been made freely available
|
||||
@@ -147,41 +133,6 @@ Go to @url{https://github.com/dekkers/libilbc} and follow the instructions for
|
||||
installing the library. Then pass @code{--enable-libilbc} to configure to
|
||||
enable it.
|
||||
|
||||
@section libzvbi
|
||||
|
||||
libzvbi is a VBI decoding library which can be used by FFmpeg to decode DVB
|
||||
teletext pages and DVB teletext subtitles.
|
||||
|
||||
Go to @url{http://sourceforge.net/projects/zapping/} and follow the instructions for
|
||||
installing the library. Then pass @code{--enable-libzvbi} to configure to
|
||||
enable it.
|
||||
|
||||
@float NOTE
|
||||
libzvbi is licensed under the GNU General Public License Version 2 or later
|
||||
(see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for details),
|
||||
you must upgrade FFmpeg's license to GPL in order to use it.
|
||||
@end float
|
||||
|
||||
@section AviSynth
|
||||
|
||||
FFmpeg can read AviSynth scripts as input. To enable support, pass
|
||||
@code{--enable-avisynth} to configure. The correct headers are
|
||||
included in compat/avisynth/, which allows the user to enable support
|
||||
without needing to search for these headers themselves.
|
||||
|
||||
For Windows, supported AviSynth variants are
|
||||
@url{http://avisynth.nl, AviSynth 2.5 or 2.6} for 32-bit builds and
|
||||
@url{http://avs-plus.net, AviSynth+ 0.1} for 32-bit and 64-bit builds.
|
||||
|
||||
For Linux and OS X, the supported AviSynth variant is
|
||||
@url{https://github.com/avxsynth/avxsynth, AvxSynth}.
|
||||
|
||||
@float NOTE
|
||||
AviSynth and AvxSynth are loaded dynamically. Distributors can build FFmpeg
|
||||
with @code{--enable-avisynth}, and the binaries will work regardless of the
|
||||
end user having AviSynth or AvxSynth installed - they'll only need to be
|
||||
installed to use AviSynth scripts (obviously).
|
||||
@end float
|
||||
|
||||
|
||||
@chapter Supported File Formats, Codecs or Features
|
||||
@@ -217,7 +168,7 @@ library:
|
||||
@item AST @tab X @tab X
|
||||
@tab Audio format used on the Nintendo Wii.
|
||||
@item AVI @tab X @tab X
|
||||
@item AviSynth @tab @tab X
|
||||
@item AVISynth @tab @tab X
|
||||
@item AVR @tab @tab X
|
||||
@tab Audio format used on Mac.
|
||||
@item AVS @tab @tab X
|
||||
@@ -284,8 +235,6 @@ library:
|
||||
@item GXF @tab X @tab X
|
||||
@tab General eXchange Format SMPTE 360M, used by Thomson Grass Valley
|
||||
playout servers.
|
||||
@item HNM @tab @tab X
|
||||
@tab Only version 4 supported, used in some games from Cryo Interactive
|
||||
@item iCEDraw File @tab @tab X
|
||||
@item ICO @tab X @tab X
|
||||
@tab Microsoft Windows ICO
|
||||
@@ -336,8 +285,6 @@ library:
|
||||
@tab also known as DVB Transport Stream
|
||||
@item MPEG-4 @tab X @tab X
|
||||
@tab MPEG-4 is a variant of QuickTime.
|
||||
@item Mirillis FIC video @tab @tab X
|
||||
@tab No cursor rendering.
|
||||
@item MIME multipart JPEG @tab X @tab
|
||||
@item MSN TCP webcam @tab @tab X
|
||||
@tab Used by MSN Messenger webcam streams.
|
||||
@@ -377,7 +324,6 @@ library:
|
||||
@item raw H.261 @tab X @tab X
|
||||
@item raw H.263 @tab X @tab X
|
||||
@item raw H.264 @tab X @tab X
|
||||
@item raw HEVC @tab X @tab X
|
||||
@item raw Ingenient MJPEG @tab @tab X
|
||||
@item raw MJPEG @tab X @tab X
|
||||
@item raw MLP @tab @tab X
|
||||
@@ -528,8 +474,6 @@ following image formats are supported:
|
||||
@tab YUV, JPEG and some extension is not supported yet.
|
||||
@item Truevision Targa @tab X @tab X
|
||||
@tab Targa (.TGA) image format
|
||||
@item WebP @tab E @tab X
|
||||
@tab WebP image format, encoding supported through external library libwebp
|
||||
@item XBM @tab X @tab X
|
||||
@tab X BitMap image format
|
||||
@item XFace @tab X @tab X
|
||||
@@ -647,9 +591,7 @@ following image formats are supported:
|
||||
@item H.263+ / H.263-1998 / H.263 version 2 @tab X @tab X
|
||||
@item H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 @tab E @tab X
|
||||
@tab encoding supported through external library libx264
|
||||
@item HEVC @tab X @tab X
|
||||
@tab encoding supported through the external library libx265
|
||||
@item HNM version 4 @tab @tab X
|
||||
@item H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration) @tab E @tab X
|
||||
@item HuffYUV @tab X @tab X
|
||||
@item HuffYUV FFmpeg variant @tab X @tab X
|
||||
@item IBM Ultimotion @tab @tab X
|
||||
@@ -701,6 +643,8 @@ following image formats are supported:
|
||||
@item Mobotix MxPEG video @tab @tab X
|
||||
@item Motion Pixels video @tab @tab X
|
||||
@item MPEG-1 video @tab X @tab X
|
||||
@item MPEG-1/2 video XvMC (X-Video Motion Compensation) @tab @tab X
|
||||
@item MPEG-1/2 video (VDPAU acceleration) @tab @tab X
|
||||
@item MPEG-2 video @tab X @tab X
|
||||
@item MPEG-4 part 2 @tab X @tab X
|
||||
@tab libxvidcore can be used alternatively for encoding.
|
||||
@@ -718,8 +662,6 @@ following image formats are supported:
|
||||
@tab fourcc: VP60,VP61,VP62
|
||||
@item VP8 @tab E @tab X
|
||||
@tab fourcc: VP80, encoding supported through external library libvpx
|
||||
@item VP9 @tab E @tab X
|
||||
@tab encoding supported through external library libvpx
|
||||
@item Pinnacle TARGA CineWave YUV16 @tab @tab X
|
||||
@tab fourcc: Y216
|
||||
@item Prores @tab @tab X
|
||||
@@ -869,9 +811,8 @@ following image formats are supported:
|
||||
@item Amazing Studio PAF Audio @tab @tab X
|
||||
@item Apple lossless audio @tab X @tab X
|
||||
@tab QuickTime fourcc 'alac'
|
||||
@item ATRAC1 @tab @tab X
|
||||
@item ATRAC3 @tab @tab X
|
||||
@item ATRAC3+ @tab @tab X
|
||||
@item Atrac 1 @tab @tab X
|
||||
@item Atrac 3 @tab @tab X
|
||||
@item Bink Audio @tab @tab X
|
||||
@tab Used in Bink and Smacker files in many games.
|
||||
@item CELT @tab @tab E
|
||||
@@ -981,8 +922,8 @@ following image formats are supported:
|
||||
@tab Used in LucasArts SMUSH animations.
|
||||
@item Vorbis @tab E @tab X
|
||||
@tab A native but very primitive encoder exists.
|
||||
@item Voxware MetaSound @tab @tab X
|
||||
@item WavPack @tab X @tab X
|
||||
@item WavPack @tab E @tab X
|
||||
@tab supported through external library libwavpack
|
||||
@item Westwood Audio (SND1) @tab @tab X
|
||||
@item Windows Media Audio 1 @tab X @tab X
|
||||
@item Windows Media Audio 2 @tab X @tab X
|
||||
@@ -1005,7 +946,6 @@ performance on systems without hardware floating point support).
|
||||
@item 3GPP Timed Text @tab @tab @tab X @tab X
|
||||
@item AQTitle @tab @tab X @tab @tab X
|
||||
@item DVB @tab X @tab X @tab X @tab X
|
||||
@item DVB teletext @tab @tab X @tab @tab E
|
||||
@item DVD @tab X @tab X @tab X @tab X
|
||||
@item JACOsub @tab X @tab X @tab @tab X
|
||||
@item MicroDVD @tab X @tab X @tab @tab X
|
||||
@@ -1028,14 +968,11 @@ performance on systems without hardware floating point support).
|
||||
|
||||
@code{X} means that the feature is supported.
|
||||
|
||||
@code{E} means that support is provided through an external library.
|
||||
|
||||
@section Network Protocols
|
||||
|
||||
@multitable @columnfractions .4 .1
|
||||
@item Name @tab Support
|
||||
@item file @tab X
|
||||
@item FTP @tab X
|
||||
@item Gopher @tab X
|
||||
@item HLS @tab X
|
||||
@item HTTP @tab X
|
||||
@@ -1051,7 +988,6 @@ performance on systems without hardware floating point support).
|
||||
@item RTMPTS @tab X
|
||||
@item RTP @tab X
|
||||
@item SCTP @tab X
|
||||
@item SFTP @tab E
|
||||
@item TCP @tab X
|
||||
@item TLS @tab X
|
||||
@item UDP @tab X
|
||||
@@ -1071,14 +1007,13 @@ performance on systems without hardware floating point support).
|
||||
@item caca @tab @tab X
|
||||
@item DV1394 @tab X @tab
|
||||
@item Lavfi virtual device @tab X @tab
|
||||
@item Linux framebuffer @tab X @tab X
|
||||
@item Linux framebuffer @tab X @tab
|
||||
@item JACK @tab X @tab
|
||||
@item LIBCDIO @tab X
|
||||
@item LIBDC1394 @tab X @tab
|
||||
@item OpenAL @tab X
|
||||
@item OpenGL @tab @tab X
|
||||
@item OSS @tab X @tab X
|
||||
@item PulseAudio @tab X @tab X
|
||||
@item Pulseaudio @tab X @tab
|
||||
@item SDL @tab @tab X
|
||||
@item Video4Linux2 @tab X @tab X
|
||||
@item VfW capture @tab X @tab
|
||||
|
||||
273
doc/git-howto.txt
Normal file
273
doc/git-howto.txt
Normal file
@@ -0,0 +1,273 @@
|
||||
|
||||
About Git write access:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Before everything else, you should know how to use GIT properly.
|
||||
Luckily Git comes with excellent documentation.
|
||||
|
||||
git --help
|
||||
man git
|
||||
|
||||
shows you the available subcommands,
|
||||
|
||||
git <command> --help
|
||||
man git-<command>
|
||||
|
||||
shows information about the subcommand <command>.
|
||||
|
||||
The most comprehensive manual is the website Git Reference
|
||||
|
||||
http://gitref.org/
|
||||
|
||||
For more information about the Git project, visit
|
||||
|
||||
http://git-scm.com/
|
||||
|
||||
Consult these resources whenever you have problems, they are quite exhaustive.
|
||||
|
||||
You do not need a special username or password.
|
||||
All you need is to provide a ssh public key to the Git server admin.
|
||||
|
||||
What follows now is a basic introduction to Git and some FFmpeg-specific
|
||||
guidelines. Read it at least once, if you are granted commit privileges to the
|
||||
FFmpeg project you are expected to be familiar with these rules.
|
||||
|
||||
|
||||
|
||||
I. BASICS:
|
||||
==========
|
||||
|
||||
0. Get GIT:
|
||||
|
||||
Most distributions have a git package, if not
|
||||
You can get git from http://git-scm.com/
|
||||
|
||||
|
||||
1. Cloning the source tree:
|
||||
|
||||
git clone git://source.ffmpeg.org/ffmpeg <target>
|
||||
|
||||
This will put the FFmpeg sources into the directory <target>.
|
||||
|
||||
git clone git@source.ffmpeg.org:ffmpeg <target>
|
||||
|
||||
This will put the FFmpeg sources into the directory <target> and let
|
||||
you push back your changes to the remote repository.
|
||||
|
||||
|
||||
2. Updating the source tree to the latest revision:
|
||||
|
||||
git pull (--ff-only)
|
||||
|
||||
pulls in the latest changes from the tracked branch. The tracked branch
|
||||
can be remote. By default the master branch tracks the branch master in
|
||||
the remote origin.
|
||||
Caveat: Since merge commits are forbidden at least for the initial
|
||||
months of git --ff-only or --rebase (see below) are recommended.
|
||||
--ff-only will fail and not create merge commits if your branch
|
||||
has diverged (has a different history) from the tracked branch.
|
||||
|
||||
2.a Rebasing your local branches:
|
||||
|
||||
git pull --rebase
|
||||
|
||||
fetches the changes from the main repository and replays your local commits
|
||||
over it. This is required to keep all your local changes at the top of
|
||||
FFmpeg's master tree. The master tree will reject pushes with merge commits.
|
||||
|
||||
|
||||
3. Adding/removing files/directories:
|
||||
|
||||
git add [-A] <filename/dirname>
|
||||
git rm [-r] <filename/dirname>
|
||||
|
||||
GIT needs to get notified of all changes you make to your working
|
||||
directory that makes files appear or disappear.
|
||||
Line moves across files are automatically tracked.
|
||||
|
||||
|
||||
4. Showing modifications:
|
||||
|
||||
git diff <filename(s)>
|
||||
|
||||
will show all local modifications in your working directory as unified diff.
|
||||
|
||||
|
||||
5. Inspecting the changelog:
|
||||
|
||||
git log <filename(s)>
|
||||
|
||||
You may also use the graphical tools like gitview or gitk or the web
|
||||
interface available at http://source.ffmpeg.org
|
||||
|
||||
6. Checking source tree status:
|
||||
|
||||
git status
|
||||
|
||||
detects all the changes you made and lists what actions will be taken in case
|
||||
of a commit (additions, modifications, deletions, etc.).
|
||||
|
||||
|
||||
7. Committing:
|
||||
|
||||
git diff --check
|
||||
|
||||
to double check your changes before committing them to avoid trouble later
|
||||
on. All experienced developers do this on each and every commit, no matter
|
||||
how small.
|
||||
Every one of them has been saved from looking like a fool by this many times.
|
||||
It's very easy for stray debug output or cosmetic modifications to slip in,
|
||||
please avoid problems through this extra level of scrutiny.
|
||||
|
||||
For cosmetics-only commits you should get (almost) empty output from
|
||||
|
||||
git diff -w -b <filename(s)>
|
||||
|
||||
Also check the output of
|
||||
|
||||
git status
|
||||
|
||||
to make sure you don't have untracked files or deletions.
|
||||
|
||||
git add [-i|-p|-A] <filenames/dirnames>
|
||||
|
||||
Make sure you have told git your name and email address, e.g. by running
|
||||
git config --global user.name "My Name"
|
||||
git config --global user.email my@email.invalid
|
||||
(--global to set the global configuration for all your git checkouts).
|
||||
|
||||
Git will select the changes to the files for commit. Optionally you can use
|
||||
the interactive or the patch mode to select hunk by hunk what should be
|
||||
added to the commit.
|
||||
|
||||
git commit
|
||||
|
||||
Git will commit the selected changes to your current local branch.
|
||||
|
||||
You will be prompted for a log message in an editor, which is either
|
||||
set in your personal configuration file through
|
||||
|
||||
git config core.editor
|
||||
|
||||
or set by one of the following environment variables:
|
||||
GIT_EDITOR, VISUAL or EDITOR.
|
||||
|
||||
Log messages should be concise but descriptive. Explain why you made a change,
|
||||
what you did will be obvious from the changes themselves most of the time.
|
||||
Saying just "bug fix" or "10l" is bad. Remember that people of varying skill
|
||||
levels look at and educate themselves while reading through your code. Don't
|
||||
include filenames in log messages, Git provides that information.
|
||||
|
||||
Possibly make the commit message have a terse, descriptive first line, an
|
||||
empty line and then a full description. The first line will be used to name
|
||||
the patch by git format-patch.
|
||||
|
||||
|
||||
8. Renaming/moving/copying files or contents of files:
|
||||
|
||||
Git automatically tracks such changes, making those normal commits.
|
||||
|
||||
mv/cp path/file otherpath/otherfile
|
||||
|
||||
git add [-A] .
|
||||
|
||||
git commit
|
||||
|
||||
Do not move, rename or copy files of which you are not the maintainer without
|
||||
discussing it on the mailing list first!
|
||||
|
||||
9. Reverting broken commits
|
||||
|
||||
git revert <commit>
|
||||
|
||||
git revert will generate a revert commit. This will not make the faulty
|
||||
commit disappear from the history.
|
||||
|
||||
git reset <commit>
|
||||
|
||||
git reset will uncommit the changes till <commit> rewriting the current
|
||||
branch history.
|
||||
|
||||
git commit --amend
|
||||
|
||||
allows to amend the last commit details quickly.
|
||||
|
||||
git rebase -i origin/master
|
||||
|
||||
will replay local commits over the main repository allowing to edit,
|
||||
merge or remove some of them in the process.
|
||||
|
||||
Note that the reset, commit --amend and rebase rewrite history, so you
|
||||
should use them ONLY on your local or topic branches.
|
||||
|
||||
The main repository will reject those changes.
|
||||
|
||||
10. Preparing a patchset.
|
||||
|
||||
git format-patch <commit> [-o directory]
|
||||
|
||||
will generate a set of patches for each commit between <commit> and
|
||||
current HEAD. E.g.
|
||||
|
||||
git format-patch origin/master
|
||||
|
||||
will generate patches for all commits on current branch which are not
|
||||
present in upstream.
|
||||
A useful shortcut is also
|
||||
|
||||
git format-patch -n
|
||||
|
||||
which will generate patches from last n commits.
|
||||
By default the patches are created in the current directory.
|
||||
|
||||
11. Sending patches for review
|
||||
|
||||
git send-email <commit list|directory>
|
||||
|
||||
will send the patches created by git format-patch or directly generates
|
||||
them. All the email fields can be configured in the global/local
|
||||
configuration or overridden by command line.
|
||||
Note that this tool must often be installed separately (e.g. git-email
|
||||
package on Debian-based distros).
|
||||
|
||||
12. Pushing changes to remote trees
|
||||
|
||||
git push
|
||||
|
||||
Will push the changes to the default remote (origin).
|
||||
Git will prevent you from pushing changes if the local and remote trees are
|
||||
out of sync. Refer to 2 and 2.a to sync the local tree.
|
||||
|
||||
git remote add <name> <url>
|
||||
|
||||
Will add additional remote with a name reference, it is useful if you want
|
||||
to push your local branch for review on a remote host.
|
||||
|
||||
git push <remote> <refspec>
|
||||
|
||||
Will push the changes to the remote repository. Omitting refspec makes git
|
||||
push update all the remote branches matching the local ones.
|
||||
|
||||
13. Finding a specific svn revision
|
||||
|
||||
Since version 1.7.1 git supports ':/foo' syntax for specifying commits
|
||||
based on a regular expression. see man gitrevisions
|
||||
|
||||
git show :/'as revision 23456'
|
||||
|
||||
will show the svn changeset r23456. With older git versions searching in
|
||||
the git log output is the easiest option (especially if a pager with
|
||||
search capabilities is used).
|
||||
This commit can be checked out with
|
||||
|
||||
git checkout -b svn_23456 :/'as revision 23456'
|
||||
|
||||
or for git < 1.7.1 with
|
||||
|
||||
git checkout -b svn_23456 $SHA1
|
||||
|
||||
where $SHA1 is the commit SHA1 from the 'git log' output.
|
||||
|
||||
|
||||
Contact the project admins <root at ffmpeg dot org> if you have technical
|
||||
problems with the GIT server.
|
||||
117
doc/indevs.texi
117
doc/indevs.texi
@@ -485,52 +485,87 @@ For more information about OSS see:
|
||||
|
||||
@section pulse
|
||||
|
||||
PulseAudio input device.
|
||||
pulseaudio input device.
|
||||
|
||||
To enable this output device you need to configure FFmpeg with @code{--enable-libpulse}.
|
||||
To enable this input device during configuration you need libpulse-simple
|
||||
installed in your system.
|
||||
|
||||
The filename to provide to the input device is a source device or the
|
||||
string "default"
|
||||
|
||||
To list the PulseAudio source devices and their properties you can invoke
|
||||
To list the pulse source devices and their properties you can invoke
|
||||
the command @command{pactl list sources}.
|
||||
|
||||
More information about PulseAudio can be found on @url{http://www.pulseaudio.org}.
|
||||
|
||||
@subsection Options
|
||||
@table @option
|
||||
@item server
|
||||
Connect to a specific PulseAudio server, specified by an IP address.
|
||||
Default server is used when not provided.
|
||||
|
||||
@item name
|
||||
Specify the application name PulseAudio will use when showing active clients,
|
||||
by default it is the @code{LIBAVFORMAT_IDENT} string.
|
||||
|
||||
@item stream_name
|
||||
Specify the stream name PulseAudio will use when showing active streams,
|
||||
by default it is "record".
|
||||
|
||||
@item sample_rate
|
||||
Specify the samplerate in Hz, by default 48kHz is used.
|
||||
|
||||
@item channels
|
||||
Specify the channels in use, by default 2 (stereo) is set.
|
||||
|
||||
@item frame_size
|
||||
Specify the number of bytes per frame, by default it is set to 1024.
|
||||
|
||||
@item fragment_size
|
||||
Specify the minimal buffering fragment in PulseAudio, it will affect the
|
||||
audio latency. By default it is unset.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
Record a stream from default device:
|
||||
@example
|
||||
ffmpeg -f pulse -i default /tmp/pulse.wav
|
||||
@end example
|
||||
|
||||
@subsection @var{server} AVOption
|
||||
|
||||
The syntax is:
|
||||
@example
|
||||
-server @var{server name}
|
||||
@end example
|
||||
|
||||
Connects to a specific server.
|
||||
|
||||
@subsection @var{name} AVOption
|
||||
|
||||
The syntax is:
|
||||
@example
|
||||
-name @var{application name}
|
||||
@end example
|
||||
|
||||
Specify the application name pulse will use when showing active clients,
|
||||
by default it is the LIBAVFORMAT_IDENT string
|
||||
|
||||
@subsection @var{stream_name} AVOption
|
||||
|
||||
The syntax is:
|
||||
@example
|
||||
-stream_name @var{stream name}
|
||||
@end example
|
||||
|
||||
Specify the stream name pulse will use when showing active streams,
|
||||
by default it is "record"
|
||||
|
||||
@subsection @var{sample_rate} AVOption
|
||||
|
||||
The syntax is:
|
||||
@example
|
||||
-sample_rate @var{samplerate}
|
||||
@end example
|
||||
|
||||
Specify the samplerate in Hz, by default 48kHz is used.
|
||||
|
||||
@subsection @var{channels} AVOption
|
||||
|
||||
The syntax is:
|
||||
@example
|
||||
-channels @var{N}
|
||||
@end example
|
||||
|
||||
Specify the channels in use, by default 2 (stereo) is set.
|
||||
|
||||
@subsection @var{frame_size} AVOption
|
||||
|
||||
The syntax is:
|
||||
@example
|
||||
-frame_size @var{bytes}
|
||||
@end example
|
||||
|
||||
Specify the number of byte per frame, by default it is set to 1024.
|
||||
|
||||
@subsection @var{fragment_size} AVOption
|
||||
|
||||
The syntax is:
|
||||
@example
|
||||
-fragment_size @var{bytes}
|
||||
@end example
|
||||
|
||||
Specify the minimal buffering fragment in pulseaudio, it will affect the
|
||||
audio latency. By default it is unset.
|
||||
|
||||
@section sndio
|
||||
|
||||
sndio input device.
|
||||
@@ -701,12 +736,12 @@ properties of your X11 display (e.g. grep for "name" or "dimensions").
|
||||
|
||||
For example to grab from @file{:0.0} using @command{ffmpeg}:
|
||||
@example
|
||||
ffmpeg -f x11grab -framerate 25 -video_size cif -i :0.0 out.mpg
|
||||
ffmpeg -f x11grab -r 25 -s cif -i :0.0 out.mpg
|
||||
@end example
|
||||
|
||||
Grab at position @code{10,20}:
|
||||
@example
|
||||
ffmpeg -f x11grab -framerate 25 -video_size cif -i :0.0+10,20 out.mpg
|
||||
ffmpeg -f x11grab -r 25 -s cif -i :0.0+10,20 out.mpg
|
||||
@end example
|
||||
|
||||
@subsection Options
|
||||
@@ -727,12 +762,12 @@ zero) to the edge of region.
|
||||
|
||||
For example:
|
||||
@example
|
||||
ffmpeg -f x11grab -follow_mouse centered -framerate 25 -video_size cif -i :0.0 out.mpg
|
||||
ffmpeg -f x11grab -follow_mouse centered -r 25 -s cif -i :0.0 out.mpg
|
||||
@end example
|
||||
|
||||
To follow only when the mouse pointer reaches within 100 pixels to edge:
|
||||
@example
|
||||
ffmpeg -f x11grab -follow_mouse 100 -framerate 25 -video_size cif -i :0.0 out.mpg
|
||||
ffmpeg -f x11grab -follow_mouse 100 -r 25 -s cif -i :0.0 out.mpg
|
||||
@end example
|
||||
|
||||
@item framerate
|
||||
@@ -748,12 +783,12 @@ know what is being grabbed if only a portion of the screen is grabbed.
|
||||
|
||||
For example:
|
||||
@example
|
||||
ffmpeg -f x11grab -show_region 1 -framerate 25 -video_size cif -i :0.0+10,20 out.mpg
|
||||
ffmpeg -f x11grab -show_region 1 -r 25 -s cif -i :0.0+10,20 out.mpg
|
||||
@end example
|
||||
|
||||
With @var{follow_mouse}:
|
||||
@example
|
||||
ffmpeg -f x11grab -follow_mouse centered -show_region 1 -framerate 25 -video_size cif -i :0.0 out.mpg
|
||||
ffmpeg -f x11grab -follow_mouse centered -show_region 1 -r 25 -s cif -i :0.0 out.mpg
|
||||
@end example
|
||||
|
||||
@item video_size
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FFmpeg's bug/feature request tracker manual
|
||||
FFmpeg's bug/patch/feature request tracker manual
|
||||
=================================================
|
||||
|
||||
NOTE: This is a draft.
|
||||
@@ -11,7 +11,7 @@ existing issues can be done through a web interface.
|
||||
|
||||
Issues can be different kinds of things we want to keep track of
|
||||
but that do not belong into the source tree itself. This includes
|
||||
bug reports, feature requests and license violations. We
|
||||
bug reports, patches, feature requests and license violations. We
|
||||
might add more items to this list in the future, so feel free to
|
||||
propose a new `type of issue' on the ffmpeg-devel mailing list if
|
||||
you feel it is worth tracking.
|
||||
@@ -28,9 +28,6 @@ http(s)://trac.ffmpeg.org
|
||||
|
||||
Type:
|
||||
-----
|
||||
art
|
||||
Artwork such as photos, music, banners, and logos.
|
||||
|
||||
bug / defect
|
||||
An error, flaw, mistake, failure, or fault in FFmpeg or libav* that
|
||||
prevents it from behaving as intended.
|
||||
@@ -44,18 +41,20 @@ feature request / enhancement
|
||||
license violation
|
||||
ticket to keep track of (L)GPL violations of ffmpeg by others
|
||||
|
||||
sponsoring request
|
||||
Developer requests for hardware, software, specifications, money,
|
||||
refunds, etc.
|
||||
patch
|
||||
A patch as generated by diff which conforms to the patch submission and
|
||||
development policy.
|
||||
|
||||
|
||||
Priority:
|
||||
---------
|
||||
critical
|
||||
Bugs about data loss and security issues.
|
||||
Bugs and patches which deal with data loss and security issues.
|
||||
No feature request can be critical.
|
||||
|
||||
important
|
||||
Bugs which make FFmpeg unusable for a significant number of users.
|
||||
Bugs which make FFmpeg unusable for a significant number of users, and
|
||||
patches fixing them.
|
||||
Examples here might be completely broken MPEG-4 decoding or a build issue
|
||||
on Linux.
|
||||
While broken 4xm decoding or a broken OS/2 build would not be important,
|
||||
@@ -69,7 +68,7 @@ normal
|
||||
|
||||
|
||||
minor
|
||||
Bugs about things like spelling errors, "mp2" instead of
|
||||
Bugs and patches about things like spelling errors, "mp2" instead of
|
||||
"mp3" being shown and such.
|
||||
Feature requests about things few people want or which do not make a big
|
||||
difference.
|
||||
@@ -104,13 +103,13 @@ This state implicates that the bug either has been reproduced or that
|
||||
reproduction is not needed as the bug is already understood.
|
||||
|
||||
|
||||
Type/Status:
|
||||
Type/Status/Substatus:
|
||||
----------
|
||||
*/new
|
||||
Initial state of new bugs and feature requests submitted by
|
||||
*/new/new
|
||||
Initial state of new bugs, patches and feature requests submitted by
|
||||
users.
|
||||
|
||||
*/open
|
||||
*/open/open
|
||||
Issues which have been briefly looked at and which did not look outright
|
||||
invalid.
|
||||
This implicates that no real more detailed state applies yet. Conversely,
|
||||
@@ -118,7 +117,9 @@ Type/Status:
|
||||
looked at.
|
||||
|
||||
*/closed/duplicate
|
||||
Bugs or feature requests which are duplicates.
|
||||
Bugs, patches or feature requests which are duplicates.
|
||||
Note that patches dealing with the same thing in a different way are not
|
||||
duplicates.
|
||||
Note, if you mark something as duplicate, do not forget setting the
|
||||
superseder so bug reports are properly linked.
|
||||
|
||||
@@ -133,7 +134,7 @@ Type/Status:
|
||||
bug/closed/fixed
|
||||
Bugs which have to the best of our knowledge been fixed.
|
||||
|
||||
bug/closed/wontfix
|
||||
bug/closed/wont_fix
|
||||
Bugs which we will not fix. Possible reasons include legality, high
|
||||
complexity for the sake of supporting obscure corner cases, speed loss
|
||||
for similarly esoteric purposes, et cetera.
|
||||
@@ -147,15 +148,33 @@ bug/closed/works_for_me
|
||||
reproduction failed - that is the code seems to work correctly to the
|
||||
best of our knowledge.
|
||||
|
||||
feature_request/closed/fixed
|
||||
patch/open/approved
|
||||
Patches which have been reviewed and approved by a developer.
|
||||
Such patches can be applied anytime by any other developer after some
|
||||
reasonable testing (compile + regression tests + does the patch do
|
||||
what the author claimed).
|
||||
|
||||
patch/open/needs_changes
|
||||
Patches which have been reviewed and need changes to be accepted.
|
||||
|
||||
patch/closed/applied
|
||||
Patches which have been applied.
|
||||
|
||||
patch/closed/rejected
|
||||
Patches which have been rejected.
|
||||
|
||||
feature_request/closed/implemented
|
||||
Feature requests which have been implemented.
|
||||
|
||||
feature_request/closed/wontfix
|
||||
feature_request/closed/wont_implement
|
||||
Feature requests which will not be implemented. The reasons here could
|
||||
be legal, philosophical or others.
|
||||
|
||||
Note, please do not use type-status-substatus combinations other than the
|
||||
above without asking on ffmpeg-dev first!
|
||||
|
||||
Note2, if you provide the requested info do not forget to remove the
|
||||
needs_more_info resolution.
|
||||
needs_more_info substatus.
|
||||
|
||||
Component:
|
||||
----------
|
||||
|
||||
@@ -16,25 +16,7 @@ The libavutil library is a utility library to aid portable
|
||||
multimedia programming. It contains safe portable string functions,
|
||||
random number generators, data structures, additional mathematics
|
||||
functions, cryptography and multimedia related functionality (like
|
||||
enumerations for pixel and sample formats). It is not a library for
|
||||
code needed by both libavcodec and libavformat.
|
||||
|
||||
The goals for this library is to be:
|
||||
|
||||
@table @strong
|
||||
@item Modular
|
||||
It should have few interdependencies and the possibility of disabling individual
|
||||
parts during @command{./configure}.
|
||||
|
||||
@item Small
|
||||
Both sources and objects should be small.
|
||||
|
||||
@item Efficient
|
||||
It should have low CPU and memory usage.
|
||||
|
||||
@item Useful
|
||||
It should avoid useless features that almost no one needs.
|
||||
@end table
|
||||
enumerations for pixel and sample formats).
|
||||
|
||||
@c man end DESCRIPTION
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Specifically, this library performs the following conversions:
|
||||
@itemize
|
||||
@item
|
||||
@emph{Resampling}: is the process of changing the audio rate, for
|
||||
example from a high sample rate of 44100Hz to 8000Hz. Audio
|
||||
example from an high sample rate of 44100Hz to 8000Hz. Audio
|
||||
conversion from high to low sample rate is a lossy process. Several
|
||||
resampling options and algorithms are available.
|
||||
|
||||
|
||||
@@ -47,11 +47,6 @@ Files that have MIPS copyright notice in them:
|
||||
* libavutil/mips/
|
||||
float_dsp_mips.c
|
||||
libm_mips.h
|
||||
* libavcodec/
|
||||
fft_fixed_32.c
|
||||
fft_init_table.c
|
||||
fft_table.h
|
||||
mdct_fixed_32.c
|
||||
* libavcodec/mips/
|
||||
aaccoder_mips.c
|
||||
aacpsy_mips.h
|
||||
|
||||
310
doc/muxers.texi
310
doc/muxers.texi
@@ -23,8 +23,6 @@ A description of some of the currently available muxers follows.
|
||||
|
||||
Audio Interchange File Format muxer.
|
||||
|
||||
@subsection Options
|
||||
|
||||
It accepts the following options:
|
||||
|
||||
@table @option
|
||||
@@ -51,10 +49,6 @@ The output of the muxer consists of a single line of the form:
|
||||
CRC=0x@var{CRC}, where @var{CRC} is a hexadecimal number 0-padded to
|
||||
8 digits containing the CRC for all the decoded input frames.
|
||||
|
||||
See also the @ref{framecrc} muxer.
|
||||
|
||||
@subsection Examples
|
||||
|
||||
For example to compute the CRC of the input, and store it in the file
|
||||
@file{out.crc}:
|
||||
@example
|
||||
@@ -74,6 +68,8 @@ and the input video converted to MPEG-2 video, use the command:
|
||||
ffmpeg -i INPUT -c:a pcm_u8 -c:v mpeg2video -f crc -
|
||||
@end example
|
||||
|
||||
See also the @ref{framecrc} muxer.
|
||||
|
||||
@anchor{framecrc}
|
||||
@section framecrc
|
||||
|
||||
@@ -93,8 +89,6 @@ packet of the form:
|
||||
@var{CRC} is a hexadecimal number 0-padded to 8 digits containing the
|
||||
CRC of the packet.
|
||||
|
||||
@subsection Examples
|
||||
|
||||
For example to compute the CRC of the audio and video frames in
|
||||
@file{INPUT}, converted to raw audio and video packets, and store it
|
||||
in the file @file{out.crc}:
|
||||
@@ -138,8 +132,6 @@ packet of the form:
|
||||
@var{MD5} is a hexadecimal number representing the computed MD5 hash
|
||||
for the packet.
|
||||
|
||||
@subsection Examples
|
||||
|
||||
For example to compute the MD5 of the audio and video frames in
|
||||
@file{INPUT}, converted to raw audio and video packets, and store it
|
||||
in the file @file{out.md5}:
|
||||
@@ -154,89 +146,30 @@ ffmpeg -i INPUT -f framemd5 -
|
||||
|
||||
See also the @ref{md5} muxer.
|
||||
|
||||
@anchor{gif}
|
||||
@section gif
|
||||
|
||||
Animated GIF muxer.
|
||||
|
||||
It accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item loop
|
||||
Set the number of times to loop the output. Use @code{-1} for no loop, @code{0}
|
||||
for looping indefinitely (default).
|
||||
|
||||
@item final_delay
|
||||
Force the delay (expressed in centiseconds) after the last frame. Each frame
|
||||
ends with a delay until the next frame. The default is @code{-1}, which is a
|
||||
special value to tell the muxer to re-use the previous delay. In case of a
|
||||
loop, you might want to customize this value to mark a pause for instance.
|
||||
@end table
|
||||
|
||||
For example, to encode a gif looping 10 times, with a 5 seconds delay between
|
||||
the loops:
|
||||
@example
|
||||
ffmpeg -i INPUT -loop 10 -final_delay 500 out.gif
|
||||
@end example
|
||||
|
||||
Note 1: if you wish to extract the frames in separate GIF files, you need to
|
||||
force the @ref{image2} muxer:
|
||||
@example
|
||||
ffmpeg -i INPUT -c:v gif -f image2 "out%d.gif"
|
||||
@end example
|
||||
|
||||
Note 2: the GIF format has a very small time base: the delay between two frames
|
||||
can not be smaller than one centi second.
|
||||
|
||||
@anchor{hls}
|
||||
@section hls
|
||||
|
||||
Apple HTTP Live Streaming muxer that segments MPEG-TS according to
|
||||
the HTTP Live Streaming (HLS) specification.
|
||||
the HTTP Live Streaming specification.
|
||||
|
||||
It creates a playlist file and numbered segment files. The output
|
||||
filename specifies the playlist filename; the segment filenames
|
||||
receive the same basename as the playlist, a sequential number and
|
||||
a .ts extension.
|
||||
|
||||
For example, to convert an input file with @command{ffmpeg}:
|
||||
@example
|
||||
ffmpeg -i in.nut out.m3u8
|
||||
@end example
|
||||
|
||||
See also the @ref{segment} muxer, which provides a more generic and
|
||||
flexible implementation of a segmenter, and can be used to perform HLS
|
||||
segmentation.
|
||||
|
||||
@subsection Options
|
||||
|
||||
This muxer supports the following options:
|
||||
|
||||
@table @option
|
||||
@item hls_time @var{seconds}
|
||||
Set the segment length in seconds. Default value is 2.
|
||||
|
||||
@item hls_list_size @var{size}
|
||||
Set the maximum number of playlist entries. If set to 0 the list file
|
||||
will contain all the segments. Default value is 5.
|
||||
|
||||
@item hls_wrap @var{wrap}
|
||||
Set the number after which the segment filename number (the number
|
||||
specified in each segment file) wraps. If set to 0 the number will be
|
||||
never wrapped. Default value is 0.
|
||||
|
||||
This option is useful to avoid to fill the disk with many segment
|
||||
files, and limits the maximum number of segment files written to disk
|
||||
to @var{wrap}.
|
||||
|
||||
@item start_number @var{number}
|
||||
Start the playlist sequence number from @var{number}. Default value is
|
||||
0.
|
||||
|
||||
Note that the playlist sequence number must be unique for each segment
|
||||
and it is not to be confused with the segment filename sequence number
|
||||
which can be cyclic, for example if the @option{wrap} option is
|
||||
specified.
|
||||
@item -hls_time @var{seconds}
|
||||
Set the segment length in seconds.
|
||||
@item -hls_list_size @var{size}
|
||||
Set the maximum number of playlist entries.
|
||||
@item -hls_wrap @var{wrap}
|
||||
Set the number after which index wraps.
|
||||
@item -start_number @var{number}
|
||||
Start the sequence from @var{number}.
|
||||
@end table
|
||||
|
||||
@anchor{ico}
|
||||
@@ -302,8 +235,6 @@ The pattern "img%%-%d.jpg" will specify a sequence of filenames of the
|
||||
form @file{img%-1.jpg}, @file{img%-2.jpg}, ..., @file{img%-10.jpg},
|
||||
etc.
|
||||
|
||||
@subsection Examples
|
||||
|
||||
The following example shows how to use @command{ffmpeg} for creating a
|
||||
sequence of files @file{img-001.jpeg}, @file{img-002.jpeg}, ...,
|
||||
taking one image every second from the input video:
|
||||
@@ -326,32 +257,16 @@ Note also that the pattern must not necessarily contain "%d" or
|
||||
ffmpeg -i in.avi -f image2 -frames:v 1 img.jpeg
|
||||
@end example
|
||||
|
||||
The @option{strftime} option allows you to expand the filename with
|
||||
date and time information. Check the documentation of
|
||||
the @code{strftime()} function for the syntax.
|
||||
|
||||
For example to generate image files from the @code{strftime()}
|
||||
"%Y-%m-%d_%H-%M-%S" pattern, the following @command{ffmpeg} command
|
||||
can be used:
|
||||
@example
|
||||
ffmpeg -f v4l2 -r 1 -i /dev/video0 -f image2 -strftime 1 "%Y-%m-%d_%H-%M-%S.jpg"
|
||||
@end example
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item start_number
|
||||
Start the sequence from the specified number. Default value is 1. Must
|
||||
be a non-negative number.
|
||||
@item start_number @var{number}
|
||||
Start the sequence from @var{number}. Default value is 1. Must be a
|
||||
positive number.
|
||||
|
||||
@item update
|
||||
If set to 1, the filename will always be interpreted as just a
|
||||
filename, not a pattern, and the corresponding file will be continuously
|
||||
overwritten with new images. Default value is 0.
|
||||
@item -update @var{number}
|
||||
If @var{number} is nonzero, the filename will always be interpreted as just a
|
||||
filename, not a pattern, and this file will be continuously overwritten with new
|
||||
images.
|
||||
|
||||
@item strftime
|
||||
If set to 1, expand the filename with date and time information from
|
||||
@code{strftime()}. Default value is 0.
|
||||
@end table
|
||||
|
||||
The image muxer supports the .Y.U.V image file format. This format is
|
||||
@@ -366,27 +281,25 @@ Matroska container muxer.
|
||||
|
||||
This muxer implements the matroska and webm container specs.
|
||||
|
||||
@subsection Metadata
|
||||
|
||||
The recognized metadata settings in this muxer are:
|
||||
|
||||
@table @option
|
||||
@item title
|
||||
Set title name provided to a single track.
|
||||
|
||||
@item language
|
||||
Specify the language of the track in the Matroska languages form.
|
||||
@item title=@var{title name}
|
||||
Name provided to a single track
|
||||
@end table
|
||||
|
||||
The language can be either the 3 letters bibliographic ISO-639-2 (ISO
|
||||
639-2/B) form (like "fre" for French), or a language code mixed with a
|
||||
country code for specialities in languages (like "fre-ca" for Canadian
|
||||
French).
|
||||
@table @option
|
||||
|
||||
@item stereo_mode
|
||||
Set stereo 3D video layout of two views in a single video track.
|
||||
@item language=@var{language name}
|
||||
Specifies the language of the track in the Matroska languages form
|
||||
@end table
|
||||
|
||||
The following values are recognized:
|
||||
@table @samp
|
||||
@table @option
|
||||
|
||||
@item stereo_mode=@var{mode}
|
||||
Stereo 3D video layout of two views in a single video track
|
||||
@table @option
|
||||
@item mono
|
||||
video is not stereo
|
||||
@item left_right
|
||||
@@ -425,11 +338,10 @@ For example a 3D WebM clip can be created using the following command line:
|
||||
ffmpeg -i sample_left_right_clip.mpg -an -c:v libvpx -metadata stereo_mode=left_right -y stereo_clip.webm
|
||||
@end example
|
||||
|
||||
@subsection Options
|
||||
|
||||
This muxer supports the following options:
|
||||
|
||||
@table @option
|
||||
|
||||
@item reserve_index_space
|
||||
By default, this muxer writes the index for seeking (called cues in Matroska
|
||||
terms) at the end of the file, because it cannot know in advance how much space
|
||||
@@ -444,6 +356,7 @@ for most use cases should be about 50kB per hour of video.
|
||||
|
||||
Note that cues are only written if the output is seekable and this option will
|
||||
have no effect if it is not.
|
||||
|
||||
@end table
|
||||
|
||||
@anchor{md5}
|
||||
@@ -473,9 +386,7 @@ ffmpeg -i INPUT -f md5 -
|
||||
|
||||
See also the @ref{framemd5} muxer.
|
||||
|
||||
@section mov, mp4, ismv
|
||||
|
||||
MOV/MP4/ISMV (Smooth Streaming) muxer.
|
||||
@section MOV/MP4/ISMV
|
||||
|
||||
The mov/mp4/ismv muxer supports fragmentation. Normally, a MOV/MP4
|
||||
file has all the metadata about all packets stored in one location
|
||||
@@ -491,8 +402,6 @@ very long files (since writing normal MOV/MP4 files stores info about
|
||||
every single packet in memory until the file is closed). The downside
|
||||
is that it is less compatible with other applications.
|
||||
|
||||
@subsection Options
|
||||
|
||||
Fragmentation is enabled by setting one of the AVOptions that define
|
||||
how to cut the file into fragments:
|
||||
|
||||
@@ -542,15 +451,13 @@ pair for each track, making it easier to separate tracks.
|
||||
|
||||
This option is implicitly set when writing ismv (Smooth Streaming) files.
|
||||
@item -movflags faststart
|
||||
Run a second pass moving the index (moov atom) to the beginning of the file.
|
||||
This operation can take a while, and will not work in various situations such
|
||||
Run a second pass moving the moov atom on top of the file. This
|
||||
operation can take a while, and will not work in various situations such
|
||||
as fragmented output, thus it is not enabled by default.
|
||||
@item -movflags rtphint
|
||||
Add RTP hinting tracks to the output file.
|
||||
@end table
|
||||
|
||||
@subsection Example
|
||||
|
||||
Smooth Streaming content can be pushed in real time to a publishing
|
||||
point on IIS with this muxer. Example:
|
||||
@example
|
||||
@@ -561,15 +468,12 @@ ffmpeg -re @var{<normal input/transcoding options>} -movflags isml+frag_keyframe
|
||||
|
||||
The MP3 muxer writes a raw MP3 stream with an ID3v2 header at the beginning and
|
||||
optionally an ID3v1 tag at the end. ID3v2.3 and ID3v2.4 are supported, the
|
||||
@code{id3v2_version} option controls which one is used. Setting
|
||||
@code{id3v2_version} to 0 will disable the ID3v2 header completely. The legacy
|
||||
ID3v1 tag is not written by default, but may be enabled with the
|
||||
@code{write_id3v1} option.
|
||||
@code{id3v2_version} option controls which one is used. The legacy ID3v1 tag is
|
||||
not written by default, but may be enabled with the @code{write_id3v1} option.
|
||||
|
||||
The muxer may also write a Xing frame at the beginning, which contains the
|
||||
number of frames in the file. It is useful for computing duration of VBR files.
|
||||
The Xing frame is written if the output stream is seekable and if the
|
||||
@code{write_xing} option is set to 1 (the default).
|
||||
For seekable output the muxer also writes a Xing frame at the beginning, which
|
||||
contains the number of frames in the file. It is useful for computing duration
|
||||
of VBR files.
|
||||
|
||||
The muxer supports writing ID3v2 attached pictures (APIC frames). The pictures
|
||||
are supplied to the muxer in form of a video stream with a single packet. There
|
||||
@@ -596,24 +500,12 @@ ffmpeg -i input.mp3 -i cover.png -c copy -map 0 -map 1
|
||||
-metadata:s:v title="Album cover" -metadata:s:v comment="Cover (Front)" out.mp3
|
||||
@end example
|
||||
|
||||
Write a "clean" MP3 without any extra features:
|
||||
@example
|
||||
ffmpeg -i input.wav -write_xing 0 -id3v2_version 0 out.mp3
|
||||
@end example
|
||||
|
||||
@section mpegts
|
||||
|
||||
MPEG transport stream muxer.
|
||||
|
||||
This muxer implements ISO 13818-1 and part of ETSI EN 300 468.
|
||||
|
||||
The recognized metadata settings in mpegts muxer are @code{service_provider}
|
||||
and @code{service_name}. If they are not set the default for
|
||||
@code{service_provider} is "FFmpeg" and the default for
|
||||
@code{service_name} is "Service01".
|
||||
|
||||
@subsection Options
|
||||
|
||||
The muxer options are:
|
||||
|
||||
@table @option
|
||||
@@ -630,43 +522,12 @@ Set the service_id (default 0x0001) also known as program in DVB.
|
||||
Set the first PID for PMT (default 0x1000, max 0x1f00).
|
||||
@item -mpegts_start_pid @var{number}
|
||||
Set the first PID for data packets (default 0x0100, max 0x0f00).
|
||||
@item -mpegts_m2ts_mode @var{number}
|
||||
Enable m2ts mode if set to 1. Default value is -1 which disables m2ts mode.
|
||||
@item -muxrate @var{number}
|
||||
Set muxrate.
|
||||
@item -pes_payload_size @var{number}
|
||||
Set minimum PES packet payload in bytes.
|
||||
@item -mpegts_flags @var{flags}
|
||||
Set flags (see below).
|
||||
@item -mpegts_copyts @var{number}
|
||||
Preserve original timestamps, if value is set to 1. Default value is -1, which
|
||||
results in shifting timestamps so that they start from 0.
|
||||
@item -tables_version @var{number}
|
||||
Set PAT, PMT and SDT version (default 0, valid values are from 0 to 31, inclusively).
|
||||
This option allows updating stream structure so that standard consumer may
|
||||
detect the change. To do so, reopen output AVFormatContext (in case of API
|
||||
usage) or restart ffmpeg instance, cyclically changing tables_version value:
|
||||
@example
|
||||
ffmpeg -i source1.ts -codec copy -f mpegts -tables_version 0 udp://1.1.1.1:1111
|
||||
ffmpeg -i source2.ts -codec copy -f mpegts -tables_version 1 udp://1.1.1.1:1111
|
||||
...
|
||||
ffmpeg -i source3.ts -codec copy -f mpegts -tables_version 31 udp://1.1.1.1:1111
|
||||
ffmpeg -i source1.ts -codec copy -f mpegts -tables_version 0 udp://1.1.1.1:1111
|
||||
ffmpeg -i source2.ts -codec copy -f mpegts -tables_version 1 udp://1.1.1.1:1111
|
||||
...
|
||||
@end example
|
||||
@end table
|
||||
|
||||
Option mpegts_flags may take a set of such flags:
|
||||
|
||||
@table @option
|
||||
@item resend_headers
|
||||
Reemit PAT/PMT before writing the next packet.
|
||||
@item latm
|
||||
Use LATM packetization for AAC.
|
||||
@end table
|
||||
|
||||
@subsection Example
|
||||
The recognized metadata settings in mpegts muxer are @code{service_provider}
|
||||
and @code{service_name}. If they are not set the default for
|
||||
@code{service_provider} is "FFmpeg" and the default for
|
||||
@code{service_name} is "Service01".
|
||||
|
||||
@example
|
||||
ffmpeg -i file.mpg -c copy \
|
||||
@@ -717,12 +578,11 @@ situations, giving a small seek granularity at the cost of additional container
|
||||
overhead.
|
||||
@end table
|
||||
|
||||
@anchor{segment}
|
||||
@section segment, stream_segment, ssegment
|
||||
|
||||
Basic stream segmenter.
|
||||
|
||||
This muxer outputs streams to a number of separate files of nearly
|
||||
The segmenter muxer outputs streams to a number of separate files of nearly
|
||||
fixed duration. Output filename pattern can be set in a fashion similar to
|
||||
@ref{image2}.
|
||||
|
||||
@@ -744,14 +604,7 @@ The segment muxer works best with a single constant frame rate video.
|
||||
|
||||
Optionally it can generate a list of the created segments, by setting
|
||||
the option @var{segment_list}. The list type is specified by the
|
||||
@var{segment_list_type} option. The entry filenames in the segment
|
||||
list are set by default to the basename of the corresponding segment
|
||||
files.
|
||||
|
||||
See also the @ref{hls} muxer, which provides a more specific
|
||||
implementation for HLS segmentation.
|
||||
|
||||
@subsection Options
|
||||
@var{segment_list_type} option.
|
||||
|
||||
The segment muxer supports the following options:
|
||||
|
||||
@@ -783,15 +636,13 @@ Allow caching (only affects M3U8 list files).
|
||||
Allow live-friendly file generation.
|
||||
@end table
|
||||
|
||||
Default value is @code{samp}.
|
||||
|
||||
@item segment_list_size @var{size}
|
||||
Update the list file so that it contains at most the last @var{size}
|
||||
segments. If 0 the list file will contain all the segments. Default
|
||||
value is 0.
|
||||
|
||||
@item segment_list_entry_prefix @var{prefix}
|
||||
Set @var{prefix} to prepend to the name of each entry filename. By
|
||||
default no prefix is applied.
|
||||
|
||||
@item segment_list_type @var{type}
|
||||
Specify the format for the segment list file.
|
||||
|
||||
@@ -863,7 +714,7 @@ In particular may be used in combination with the @file{ffmpeg} option
|
||||
@var{force_key_frames} may not be set accurately because of rounding
|
||||
issues, with the consequence that a key frame time may result set just
|
||||
before the specified time. For constant frame rate videos a value of
|
||||
1/(2*@var{frame_rate}) should address the worst case mismatch between
|
||||
1/2*@var{frame_rate} should address the worst case mismatch between
|
||||
the specified time and the time set by @var{force_key_frames}.
|
||||
|
||||
@item segment_times @var{times}
|
||||
@@ -890,10 +741,6 @@ Reset timestamps at the begin of each segment, so that each segment
|
||||
will start with near-zero timestamps. It is meant to ease the playback
|
||||
of the generated segments. May not work with some combinations of
|
||||
muxers/codecs. It is set to @code{0} by default.
|
||||
|
||||
@item initial_offset @var{offset}
|
||||
Specify timestamp offset to apply to the output packet timestamps. The
|
||||
argument must be a time duration specification, and defaults to 0.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
@@ -964,71 +811,22 @@ to feed the same packets to several muxers directly.
|
||||
The slave outputs are specified in the file name given to the muxer,
|
||||
separated by '|'. If any of the slave name contains the '|' separator,
|
||||
leading or trailing spaces or any special character, it must be
|
||||
escaped (see @ref{quoting_and_escaping,,the "Quoting and escaping"
|
||||
section in the ffmpeg-utils(1) manual,ffmpeg-utils}).
|
||||
escaped (see the ``Quoting and escaping'' section in the ffmpeg-utils
|
||||
manual).
|
||||
|
||||
Muxer options can be specified for each slave by prepending them as a list of
|
||||
Options can be specified for each slave by prepending them as a list of
|
||||
@var{key}=@var{value} pairs separated by ':', between square brackets. If
|
||||
the options values contain a special character or the ':' separator, they
|
||||
must be escaped; note that this is a second level escaping.
|
||||
|
||||
The following special options are also recognized:
|
||||
@table @option
|
||||
@item f
|
||||
Specify the format name. Useful if it cannot be guessed from the
|
||||
output name suffix.
|
||||
|
||||
@item bsfs[/@var{spec}]
|
||||
Specify a list of bitstream filters to apply to the specified
|
||||
output.
|
||||
|
||||
It is possible to specify to which streams a given bitstream filter
|
||||
applies, by appending a stream specifier to the option separated by
|
||||
@code{/}. @var{spec} must be a stream specifier (see @ref{Format
|
||||
stream specifiers}). If the stream specifier is not specified, the
|
||||
bistream filters will be applied to all streams in the output.
|
||||
|
||||
Several bitstream filters can be specified, separated by ",".
|
||||
|
||||
@item select
|
||||
Select the streams that should be mapped to the slave output,
|
||||
specified by a stream specifier. If not specified, this defaults to
|
||||
all the input streams.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Encode something and both archive it in a WebM file and stream it
|
||||
Example: encode something and both archive it in a WebM file and stream it
|
||||
as MPEG-TS over UDP (the streams need to be explicitly mapped):
|
||||
|
||||
@example
|
||||
ffmpeg -i ... -c:v libx264 -c:a mp2 -f tee -map 0:v -map 0:a
|
||||
"archive-20121107.mkv|[f=mpegts]udp://10.0.1.255:1234/"
|
||||
@end example
|
||||
|
||||
@item
|
||||
Use @command{ffmpeg} to encode the input, and send the output
|
||||
to three different destinations. The @code{dump_extra} bitstream
|
||||
filter is used to add extradata information to all the output video
|
||||
keyframes packets, as requested by the MPEG-TS format. The select
|
||||
option is applied to @file{out.aac} in order to make it contain only
|
||||
audio packets.
|
||||
@example
|
||||
ffmpeg -i ... -map 0 -flags +global_header -c:v libx264 -c:a aac -strict experimental
|
||||
-f tee "[bsfs/v=dump_extra]out.ts|[movflags=+faststart]out.mp4|[select=a]out.aac"
|
||||
@end example
|
||||
|
||||
@item
|
||||
As below, but select only stream @code{a:1} for the audio output. Note
|
||||
that a second level escaping must be performed, as ":" is a special
|
||||
character used to separate options.
|
||||
@example
|
||||
ffmpeg -i ... -map 0 -flags +global_header -c:v libx264 -c:a aac -strict experimental
|
||||
-f tee "[bsfs/v=dump_extra]out.ts|[movflags=+faststart]out.mp4|[select=\'a:1\']out.aac"
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
Note: some codecs may need different options depending on the output format;
|
||||
the auto-detection of this can not work with the tee muxer. The main example
|
||||
is the @option{global_header} flag.
|
||||
|
||||
206
doc/outdevs.texi
206
doc/outdevs.texi
@@ -1,7 +1,7 @@
|
||||
@chapter Output Devices
|
||||
@c man begin OUTPUT DEVICES
|
||||
|
||||
Output devices are configured elements in FFmpeg that can write
|
||||
Output devices are configured elements in FFmpeg which allow to write
|
||||
multimedia data to an output device attached to your system.
|
||||
|
||||
When you configure your FFmpeg build, all the supported output devices
|
||||
@@ -22,22 +22,6 @@ A description of the currently available output devices follows.
|
||||
|
||||
ALSA (Advanced Linux Sound Architecture) output device.
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Play a file on default ALSA device:
|
||||
@example
|
||||
ffmpeg -i INPUT -f alsa default
|
||||
@end example
|
||||
|
||||
@item
|
||||
Play a file on soundcard 1, audio device 7:
|
||||
@example
|
||||
ffmpeg -i INPUT -f alsa hw:1,7
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@section caca
|
||||
|
||||
CACA output device.
|
||||
@@ -120,184 +104,10 @@ ffmpeg -i INPUT -pix_fmt rgb24 -f caca -list_dither colors -
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@section decklink
|
||||
|
||||
The decklink output device provides playback capabilities for Blackmagic
|
||||
DeckLink devices.
|
||||
|
||||
To enable this output device, you need the Blackmagic DeckLink SDK and you
|
||||
need to configure with the appropriate @code{--extra-cflags}
|
||||
and @code{--extra-ldflags}.
|
||||
On Windows, you need to run the IDL files through @command{widl}.
|
||||
|
||||
DeckLink is very picky about the formats it supports. Pixel format is always
|
||||
uyvy422, framerate and video size must be determined for your device with
|
||||
@command{-list_formats 1}. Audio sample rate is always 48 kHz.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item list_devices
|
||||
If set to @option{true}, print a list of devices and exit.
|
||||
Defaults to @option{false}.
|
||||
|
||||
@item list_formats
|
||||
If set to @option{true}, print a list of supported formats and exit.
|
||||
Defaults to @option{false}.
|
||||
|
||||
@item preroll
|
||||
Amount of time to preroll video in seconds.
|
||||
Defaults to @option{0.5}.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
|
||||
@item
|
||||
List output devices:
|
||||
@example
|
||||
ffmpeg -i test.avi -f decklink -list_devices 1 dummy
|
||||
@end example
|
||||
|
||||
@item
|
||||
List supported formats:
|
||||
@example
|
||||
ffmpeg -i test.avi -f decklink -list_formats 1 'DeckLink Mini Monitor'
|
||||
@end example
|
||||
|
||||
@item
|
||||
Play video clip:
|
||||
@example
|
||||
ffmpeg -i test.avi -f decklink -pix_fmt uyvy422 'DeckLink Mini Monitor'
|
||||
@end example
|
||||
|
||||
@item
|
||||
Play video clip with non-standard framerate or video size:
|
||||
@example
|
||||
ffmpeg -i test.avi -f decklink -pix_fmt uyvy422 -s 720x486 -r 24000/1001 'DeckLink Mini Monitor'
|
||||
@end example
|
||||
|
||||
@end itemize
|
||||
|
||||
@section fbdev
|
||||
|
||||
Linux framebuffer output device.
|
||||
|
||||
The Linux framebuffer is a graphic hardware-independent abstraction
|
||||
layer to show graphics on a computer monitor, typically on the
|
||||
console. It is accessed through a file device node, usually
|
||||
@file{/dev/fb0}.
|
||||
|
||||
For more detailed information read the file
|
||||
@file{Documentation/fb/framebuffer.txt} included in the Linux source tree.
|
||||
|
||||
@subsection Options
|
||||
@table @option
|
||||
|
||||
@item xoffset
|
||||
@item yoffset
|
||||
Set x/y coordinate of top left corner. Default is 0.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
Play a file on framebuffer device @file{/dev/fb0}.
|
||||
Required pixel format depends on current framebuffer settings.
|
||||
@example
|
||||
ffmpeg -re -i INPUT -vcodec rawvideo -pix_fmt bgra -f fbdev /dev/fb0
|
||||
@end example
|
||||
|
||||
See also @url{http://linux-fbdev.sourceforge.net/}, and fbset(1).
|
||||
|
||||
@section opengl
|
||||
OpenGL output device.
|
||||
|
||||
To enable this output device you need to configure FFmpeg with @code{--enable-opengl}.
|
||||
|
||||
This output device allows one to render to OpenGL context.
|
||||
Context may be provided by application or default SDL window is created.
|
||||
|
||||
When device renders to external context, application must implement handlers for following messages:
|
||||
@code{AV_CTL_MESSAGE_CREATE_WINDOW_BUFFER} - create OpenGL context on current thread.
|
||||
@code{AV_CTL_MESSAGE_PREPARE_WINDOW_BUFFER} - make OpenGL context current.
|
||||
@code{AV_CTL_MESSAGE_DISPLAY_WINDOW_BUFFER} - swap buffers.
|
||||
@code{AV_CTL_MESSAGE_DESTROY_WINDOW_BUFFER} - destroy OpenGL context.
|
||||
Application is also required to inform a device about current resolution by sending @code{AV_DEVICE_WINDOW_RESIZED} message.
|
||||
|
||||
@subsection Options
|
||||
@table @option
|
||||
|
||||
@item background
|
||||
Set background color. Black is a default.
|
||||
@item no_window
|
||||
Disables default SDL window when set to non-zero value.
|
||||
Application must provide OpenGL context and both @code{window_size_cb} and @code{window_swap_buffers_cb} callbacks when set.
|
||||
@item window_title
|
||||
Set the SDL window title, if not specified default to the filename specified for the output device.
|
||||
Ignored when @option{no_window} is set.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
Play a file on SDL window using OpenGL rendering:
|
||||
@example
|
||||
ffmpeg -i INPUT -f opengl "window title"
|
||||
@end example
|
||||
|
||||
@section oss
|
||||
|
||||
OSS (Open Sound System) output device.
|
||||
|
||||
@section pulse
|
||||
|
||||
PulseAudio output device.
|
||||
|
||||
To enable this output device you need to configure FFmpeg with @code{--enable-libpulse}.
|
||||
|
||||
More information about PulseAudio can be found on @url{http://www.pulseaudio.org}
|
||||
|
||||
@subsection Options
|
||||
@table @option
|
||||
|
||||
@item server
|
||||
Connect to a specific PulseAudio server, specified by an IP address.
|
||||
Default server is used when not provided.
|
||||
|
||||
@item name
|
||||
Specify the application name PulseAudio will use when showing active clients,
|
||||
by default it is the @code{LIBAVFORMAT_IDENT} string.
|
||||
|
||||
@item stream_name
|
||||
Specify the stream name PulseAudio will use when showing active streams,
|
||||
by default it is set to the specified output name.
|
||||
|
||||
@item device
|
||||
Specify the device to use. Default device is used when not provided.
|
||||
List of output devices can be obtained with command @command{pactl list sinks}.
|
||||
|
||||
@item buffer_size
|
||||
@item buffer_duration
|
||||
Control the size and duration of the PulseAudio buffer. A small buffer
|
||||
gives more control, but requires more frequent updates.
|
||||
|
||||
@option{buffer_size} specifies size in bytes while
|
||||
@option{buffer_duration} specifies duration in milliseconds.
|
||||
|
||||
When both options are provided then the highest value is used
|
||||
(duration is recalculated to bytes using stream parameters). If they
|
||||
are set to 0 (which is default), the device will use the default
|
||||
PulseAudio duration value. By default PulseAudio set buffer duration
|
||||
to around 2 seconds.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
Play a file on default device on default server:
|
||||
@example
|
||||
ffmpeg -i INPUT -f pulse "stream name"
|
||||
@end example
|
||||
|
||||
@section sdl
|
||||
|
||||
SDL (Simple DirectMedia Layer) output device.
|
||||
@@ -329,20 +139,6 @@ Set the SDL window size, can be a string of the form
|
||||
@var{width}x@var{height} or a video size abbreviation.
|
||||
If not specified it defaults to the size of the input video,
|
||||
downscaled according to the aspect ratio.
|
||||
|
||||
@item window_fullscreen
|
||||
Set fullscreen mode when non-zero value is provided.
|
||||
Default value is zero.
|
||||
@end table
|
||||
|
||||
@subsection Interactive commands
|
||||
|
||||
The window created by the device can be controlled through the
|
||||
following interactive commands.
|
||||
|
||||
@table @key
|
||||
@item q, ESC
|
||||
Quit the device immediately.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@@ -51,9 +51,8 @@ The toolchain provided with Xcode is sufficient to build the basic
|
||||
unacelerated code.
|
||||
|
||||
Mac OS X on PowerPC or ARM (iPhone) requires a preprocessor from
|
||||
@url{https://github.com/FFmpeg/gas-preprocessor} or
|
||||
@url{http://github.com/yuvi/gas-preprocessor} to build the optimized
|
||||
assembler functions. Put the Perl script somewhere
|
||||
assembler functions. Just download the Perl script and put it somewhere
|
||||
in your PATH, FFmpeg's configure will pick it up automatically.
|
||||
|
||||
Mac OS X on amd64 and x86 requires @command{yasm} to build most of the
|
||||
@@ -109,16 +108,14 @@ libavformat) as DLLs.
|
||||
|
||||
@section Microsoft Visual C++ or Intel C++ Compiler for Windows
|
||||
|
||||
FFmpeg can be built with MSVC 2012 or earlier using a C99-to-C89 conversion utility
|
||||
and wrapper, or with MSVC 2013 and ICL natively.
|
||||
FFmpeg can be built with MSVC or ICL using a C99-to-C89 conversion utility and
|
||||
wrapper. For ICL, only the wrapper is used, since ICL supports C99.
|
||||
|
||||
You will need the following prerequisites:
|
||||
|
||||
@itemize
|
||||
@item @uref{https://github.com/libav/c99-to-c89/, C99-to-C89 Converter & Wrapper}
|
||||
(if using MSVC 2012 or earlier)
|
||||
@item @uref{http://download.videolan.org/pub/contrib/c99-to-c89/, C99-to-C89 Converter & Wrapper}
|
||||
@item @uref{http://code.google.com/p/msinttypes/, msinttypes}
|
||||
(if using MSVC 2012 or earlier)
|
||||
@item @uref{http://www.mingw.org/, MSYS}
|
||||
@item @uref{http://yasm.tortall.net/, YASM}
|
||||
@item @uref{http://gnuwin32.sourceforge.net/packages/bc.htm, bc for Windows} if
|
||||
@@ -128,16 +125,14 @@ you want to run @uref{fate.html, FATE}.
|
||||
To set up a proper environment in MSYS, you need to run @code{msys.bat} from
|
||||
the Visual Studio or Intel Compiler command prompt.
|
||||
|
||||
Place @code{yasm.exe} somewhere in your @code{PATH}. If using MSVC 2012 or
|
||||
earlier, place @code{c99wrap.exe} and @code{c99conv.exe} somewhere in your
|
||||
@code{PATH} as well.
|
||||
Place @code{makedef}, @code{c99wrap.exe}, @code{c99conv.exe}, and @code{yasm.exe}
|
||||
somewhere in your @code{PATH}.
|
||||
|
||||
Next, make sure any other headers and libs you want to use, such as zlib, are
|
||||
located in a spot that the compiler can see. Do so by modifying the @code{LIB}
|
||||
and @code{INCLUDE} environment variables to include the @strong{Windows-style}
|
||||
paths to these directories. Alternatively, you can try and use the
|
||||
@code{--extra-cflags}/@code{--extra-ldflags} configure options. If using MSVC
|
||||
2012 or earlier, place @code{inttypes.h} somewhere the compiler can see too.
|
||||
Next, make sure @code{inttypes.h} and any other headers and libs you want to use
|
||||
are located in a spot that the compiler can see. Do so by modifying the @code{LIB}
|
||||
and @code{INCLUDE} environment variables to include the @strong{Windows} paths to
|
||||
these directories. Alternatively, you can try and use the
|
||||
@code{--extra-cflags}/@code{--extra-ldflags} configure options.
|
||||
|
||||
Finally, run:
|
||||
|
||||
@@ -187,9 +182,7 @@ can see.
|
||||
@itemize
|
||||
@item Visual Studio 2010 Pro and Express
|
||||
@item Visual Studio 2012 Pro and Express
|
||||
@item Visual Studio 2013 Pro and Express
|
||||
@item Intel Composer XE 2013
|
||||
@item Intel Composer XE 2013 SP1
|
||||
@end itemize
|
||||
Anything else is not officially supported.
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Anton Khirnov
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
* This file is part of Libav.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* Libav 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,
|
||||
* Libav 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
|
||||
* License along with Libav; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
@@ -27,9 +27,7 @@
|
||||
#include <float.h>
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavformat/options_table.h"
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavcodec/options_table.h"
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
static void print_usage(void)
|
||||
@@ -98,14 +96,18 @@ static void show_opts(const AVOption *opts, int per_stream)
|
||||
|
||||
static void show_format_opts(void)
|
||||
{
|
||||
#include "libavformat/options_table.h"
|
||||
|
||||
printf("@section Format AVOptions\n");
|
||||
show_opts(avformat_options, 0);
|
||||
show_opts(options, 0);
|
||||
}
|
||||
|
||||
static void show_codec_opts(void)
|
||||
{
|
||||
#include "libavcodec/options_table.h"
|
||||
|
||||
printf("@section Codec AVOptions\n");
|
||||
show_opts(avcodec_options, 1);
|
||||
show_opts(options, 1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
@chapter Protocols
|
||||
@c man begin PROTOCOLS
|
||||
|
||||
Protocols are configured elements in FFmpeg that enable access to
|
||||
resources that require specific protocols.
|
||||
Protocols are configured elements in FFmpeg which allow to access
|
||||
resources which require the use of a particular protocol.
|
||||
|
||||
When you configure your FFmpeg build, all the supported protocols are
|
||||
enabled by default. You can list all available ones using the
|
||||
@@ -117,19 +117,7 @@ ffmpeg -i "data:image/gif;base64,R0lGODdhCAAIAMIEAAAAAAAA//8AAP//AP/////////////
|
||||
|
||||
File access protocol.
|
||||
|
||||
Allow to read from or write to a file.
|
||||
|
||||
A file URL can have the form:
|
||||
@example
|
||||
file:@var{filename}
|
||||
@end example
|
||||
|
||||
where @var{filename} is the path of the file to read.
|
||||
|
||||
An URL that does not have a protocol prefix will be assumed to be a
|
||||
file URL. Depending on the build, an URL that looks like a Windows
|
||||
path with the drive letter at the beginning will also be assumed to be
|
||||
a file URL (usually not the case in builds for unix-like systems).
|
||||
Allow to read from or read to a file.
|
||||
|
||||
For example to read from a file @file{input.mpeg} with @command{ffmpeg}
|
||||
use the command:
|
||||
@@ -137,19 +125,9 @@ use the command:
|
||||
ffmpeg -i file:input.mpeg output.mpeg
|
||||
@end example
|
||||
|
||||
This protocol accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item truncate
|
||||
Truncate existing files on write, if set to 1. A value of 0 prevents
|
||||
truncating. Default value is 1.
|
||||
|
||||
@item blocksize
|
||||
Set I/O operation maximum block size, in bytes. Default value is
|
||||
@code{INT_MAX}, which results in not limiting the requested block size.
|
||||
Setting this value reasonably low improves user termination request reaction
|
||||
time, which is valuable for files on slow medium.
|
||||
@end table
|
||||
The ff* tools default to the file protocol, that is a resource
|
||||
specified with the name "FILE.mpeg" is interpreted as the URL
|
||||
"file:FILE.mpeg".
|
||||
|
||||
@section ftp
|
||||
|
||||
@@ -213,7 +191,7 @@ m3u8 files.
|
||||
|
||||
HTTP (Hyper Text Transfer Protocol).
|
||||
|
||||
This protocol accepts the following options:
|
||||
This protocol accepts the following options.
|
||||
|
||||
@table @option
|
||||
@item seekable
|
||||
@@ -223,33 +201,32 @@ if set to -1 it will try to autodetect if it is seekable. Default
|
||||
value is -1.
|
||||
|
||||
@item chunked_post
|
||||
If set to 1 use chunked Transfer-Encoding for posts, default is 1.
|
||||
|
||||
@item content_type
|
||||
Set a specific content type for the POST messages.
|
||||
If set to 1 use chunked transfer-encoding for posts, default is 1.
|
||||
|
||||
@item headers
|
||||
Set custom HTTP headers, can override built in default headers. The
|
||||
value must be a string encoding the headers.
|
||||
|
||||
@item content_type
|
||||
Force a content type.
|
||||
|
||||
@item user-agent
|
||||
Override User-Agent header. If not specified the protocol will use a
|
||||
string describing the libavformat build.
|
||||
|
||||
@item multiple_requests
|
||||
Use persistent connections if set to 1, default is 0.
|
||||
Use persistent connections if set to 1. By default it is 0.
|
||||
|
||||
@item post_data
|
||||
Set custom HTTP post data.
|
||||
|
||||
@item user-agent
|
||||
@item user_agent
|
||||
Override the User-Agent header. If not specified the protocol will use a
|
||||
string describing the libavformat build. ("Lavf/<version>")
|
||||
|
||||
@item timeout
|
||||
Set timeout of socket I/O operations used by the underlying low level
|
||||
operation. By default it is set to -1, which means that the timeout is
|
||||
not specified.
|
||||
|
||||
@item mime_type
|
||||
Export the MIME type.
|
||||
Set MIME type.
|
||||
|
||||
@item icy
|
||||
If set to 1 request ICY (SHOUTcast) metadata from the server. If the server
|
||||
@@ -258,25 +235,17 @@ the @option{icy_metadata_headers} and @option{icy_metadata_packet} options.
|
||||
The default is 0.
|
||||
|
||||
@item icy_metadata_headers
|
||||
If the server supports ICY metadata, this contains the ICY-specific HTTP reply
|
||||
headers, separated by newline characters.
|
||||
If the server supports ICY metadata, this contains the ICY specific HTTP reply
|
||||
headers, separated with newline characters.
|
||||
|
||||
@item icy_metadata_packet
|
||||
If the server supports ICY metadata, and @option{icy} was set to 1, this
|
||||
contains the last non-empty metadata packet sent by the server. It should be
|
||||
polled in regular intervals by applications interested in mid-stream metadata
|
||||
updates.
|
||||
contains the last non-empty metadata packet sent by the server.
|
||||
|
||||
@item cookies
|
||||
Set the cookies to be sent in future requests. The format of each cookie is the
|
||||
same as the value of a Set-Cookie HTTP response field. Multiple cookies can be
|
||||
delimited by a newline character.
|
||||
|
||||
@item offset
|
||||
Set initial byte offset.
|
||||
|
||||
@item end_offset
|
||||
Try to limit the request to bytes preceding this offset.
|
||||
@end table
|
||||
|
||||
@subsection HTTP Cookies
|
||||
@@ -356,16 +325,6 @@ ffmpeg -i test.wav -f avi pipe:1 | cat > test.avi
|
||||
ffmpeg -i test.wav -f avi pipe: | cat > test.avi
|
||||
@end example
|
||||
|
||||
This protocol accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item blocksize
|
||||
Set I/O operation maximum block size, in bytes. Default value is
|
||||
@code{INT_MAX}, which results in not limiting the requested block size.
|
||||
Setting this value reasonably low improves user termination request reaction
|
||||
time, which is valuable if data transmission is slow.
|
||||
@end table
|
||||
|
||||
Note that some formats (typically MOV), require the output protocol to
|
||||
be seekable, so they will fail with the pipe output protocol.
|
||||
|
||||
@@ -378,18 +337,12 @@ content across a TCP/IP network.
|
||||
|
||||
The required syntax is:
|
||||
@example
|
||||
rtmp://[@var{username}:@var{password}@@]@var{server}[:@var{port}][/@var{app}][/@var{instance}][/@var{playpath}]
|
||||
rtmp://@var{server}[:@var{port}][/@var{app}][/@var{instance}][/@var{playpath}]
|
||||
@end example
|
||||
|
||||
The accepted parameters are:
|
||||
@table @option
|
||||
|
||||
@item username
|
||||
An optional username (mostly for publishing).
|
||||
|
||||
@item password
|
||||
An optional password (mostly for publishing).
|
||||
|
||||
@item server
|
||||
The address of the RTMP server.
|
||||
|
||||
@@ -440,8 +393,7 @@ times to construct arbitrary AMF sequences.
|
||||
|
||||
@item rtmp_flashver
|
||||
Version of the Flash plugin used to run the SWF player. The default
|
||||
is LNX 9,0,124,2. (When publishing, the default is FMLE/3.0 (compatible;
|
||||
<libavformat version>).)
|
||||
is LNX 9,0,124,2.
|
||||
|
||||
@item rtmp_flush_interval
|
||||
Number of packets flushed in the same request (RTMPT only). The default
|
||||
@@ -491,12 +443,6 @@ For example to read with @command{ffplay} a multimedia resource named
|
||||
ffplay rtmp://myserver/vod/sample
|
||||
@end example
|
||||
|
||||
To publish to a password protected server, passing the playpath and
|
||||
app names separately:
|
||||
@example
|
||||
ffmpeg -re -i <input> -f flv -rtmp_playpath some/long/path -rtmp_app long/app/name rtmp://username:password@@myserver/
|
||||
@end example
|
||||
|
||||
@section rtmpe
|
||||
|
||||
Encrypted Real-Time Messaging Protocol.
|
||||
@@ -537,43 +483,7 @@ The Real-Time Messaging Protocol tunneled through HTTPS (RTMPTS) is used
|
||||
for streaming multimedia content within HTTPS requests to traverse
|
||||
firewalls.
|
||||
|
||||
@section libssh
|
||||
|
||||
Secure File Transfer Protocol via libssh
|
||||
|
||||
Allow to read from or write to remote resources using SFTP protocol.
|
||||
|
||||
Following syntax is required.
|
||||
|
||||
@example
|
||||
sftp://[user[:password]@@]server[:port]/path/to/remote/resource.mpeg
|
||||
@end example
|
||||
|
||||
This protocol accepts the following options.
|
||||
|
||||
@table @option
|
||||
@item timeout
|
||||
Set timeout of socket I/O operations used by the underlying low level
|
||||
operation. By default it is set to -1, which means that the timeout
|
||||
is not specified.
|
||||
|
||||
@item truncate
|
||||
Truncate existing files on write, if set to 1. A value of 0 prevents
|
||||
truncating. Default value is 1.
|
||||
|
||||
@item private_key
|
||||
Specify the path of the file containing private key to use during authorization.
|
||||
By default libssh searches for keys in the @file{~/.ssh/} directory.
|
||||
|
||||
@end table
|
||||
|
||||
Example: Play a file stored on remote server.
|
||||
|
||||
@example
|
||||
ffplay sftp://user:password@@server_address:22/home/user/resource.mpeg
|
||||
@end example
|
||||
|
||||
@section librtmp rtmp, rtmpe, rtmps, rtmpt, rtmpte
|
||||
@section rtmp, rtmpe, rtmps, rtmpt, rtmpte
|
||||
|
||||
Real-Time Messaging Protocol and its variants supported through
|
||||
librtmp.
|
||||
@@ -615,75 +525,10 @@ ffplay "rtmp://myserver/live/mystream live=1"
|
||||
|
||||
@section rtp
|
||||
|
||||
Real-time Transport Protocol.
|
||||
|
||||
The required syntax for an RTP URL is:
|
||||
rtp://@var{hostname}[:@var{port}][?@var{option}=@var{val}...]
|
||||
|
||||
@var{port} specifies the RTP port to use.
|
||||
|
||||
The following URL options are supported:
|
||||
|
||||
@table @option
|
||||
|
||||
@item ttl=@var{n}
|
||||
Set the TTL (Time-To-Live) value (for multicast only).
|
||||
|
||||
@item rtcpport=@var{n}
|
||||
Set the remote RTCP port to @var{n}.
|
||||
|
||||
@item localrtpport=@var{n}
|
||||
Set the local RTP port to @var{n}.
|
||||
|
||||
@item localrtcpport=@var{n}'
|
||||
Set the local RTCP port to @var{n}.
|
||||
|
||||
@item pkt_size=@var{n}
|
||||
Set max packet size (in bytes) to @var{n}.
|
||||
|
||||
@item connect=0|1
|
||||
Do a @code{connect()} on the UDP socket (if set to 1) or not (if set
|
||||
to 0).
|
||||
|
||||
@item sources=@var{ip}[,@var{ip}]
|
||||
List allowed source IP addresses.
|
||||
|
||||
@item block=@var{ip}[,@var{ip}]
|
||||
List disallowed (blocked) source IP addresses.
|
||||
|
||||
@item write_to_source=0|1
|
||||
Send packets to the source address of the latest received packet (if
|
||||
set to 1) or to a default remote address (if set to 0).
|
||||
|
||||
@item localport=@var{n}
|
||||
Set the local RTP port to @var{n}.
|
||||
|
||||
This is a deprecated option. Instead, @option{localrtpport} should be
|
||||
used.
|
||||
|
||||
@end table
|
||||
|
||||
Important notes:
|
||||
|
||||
@enumerate
|
||||
|
||||
@item
|
||||
If @option{rtcpport} is not set the RTCP port will be set to the RTP
|
||||
port value plus 1.
|
||||
|
||||
@item
|
||||
If @option{localrtpport} (the local RTP port) is not set any available
|
||||
port will be used for the local RTP and RTCP ports.
|
||||
|
||||
@item
|
||||
If @option{localrtcpport} (the local RTCP port) is not set it will be
|
||||
set to the the local RTP port value plus 1.
|
||||
@end enumerate
|
||||
Real-Time Protocol.
|
||||
|
||||
@section rtsp
|
||||
|
||||
Real-Time Streaming Protocol.
|
||||
|
||||
RTSP is not technically a protocol handler in libavformat, it is a demuxer
|
||||
and muxer. The demuxer supports both normal RTSP (with data transferred
|
||||
over RTP; this is used by e.g. Apple and Microsoft) and Real-RTSP (with
|
||||
@@ -698,22 +543,14 @@ The required syntax for a RTSP url is:
|
||||
rtsp://@var{hostname}[:@var{port}]/@var{path}
|
||||
@end example
|
||||
|
||||
Options can be set on the @command{ffmpeg}/@command{ffplay} command
|
||||
line, or set in code via @code{AVOption}s or in
|
||||
@code{avformat_open_input}.
|
||||
The following options (set on the @command{ffmpeg}/@command{ffplay} command
|
||||
line, or set in code via @code{AVOption}s or in @code{avformat_open_input}),
|
||||
are supported:
|
||||
|
||||
The following options are supported.
|
||||
Flags for @code{rtsp_transport}:
|
||||
|
||||
@table @option
|
||||
@item initial_pause
|
||||
Do not start playing the stream immediately if set to 1. Default value
|
||||
is 0.
|
||||
|
||||
@item rtsp_transport
|
||||
Set RTSP trasport protocols.
|
||||
|
||||
It accepts the following values:
|
||||
@table @samp
|
||||
@item udp
|
||||
Use UDP as lower transport protocol.
|
||||
|
||||
@@ -731,56 +568,17 @@ passing proxies.
|
||||
|
||||
Multiple lower transport protocols may be specified, in that case they are
|
||||
tried one at a time (if the setup of one fails, the next one is tried).
|
||||
For the muxer, only the @samp{tcp} and @samp{udp} options are supported.
|
||||
For the muxer, only the @code{tcp} and @code{udp} options are supported.
|
||||
|
||||
@item rtsp_flags
|
||||
Set RTSP flags.
|
||||
Flags for @code{rtsp_flags}:
|
||||
|
||||
The following values are accepted:
|
||||
@table @samp
|
||||
@table @option
|
||||
@item filter_src
|
||||
Accept packets only from negotiated peer address and port.
|
||||
@item listen
|
||||
Act as a server, listening for an incoming connection.
|
||||
@end table
|
||||
|
||||
Default value is @samp{none}.
|
||||
|
||||
@item allowed_media_types
|
||||
Set media types to accept from the server.
|
||||
|
||||
The following flags are accepted:
|
||||
@table @samp
|
||||
@item video
|
||||
@item audio
|
||||
@item data
|
||||
@end table
|
||||
|
||||
By default it accepts all media types.
|
||||
|
||||
@item min_port
|
||||
Set minimum local UDP port. Default value is 5000.
|
||||
|
||||
@item max_port
|
||||
Set maximum local UDP port. Default value is 65000.
|
||||
|
||||
@item timeout
|
||||
Set maximum timeout (in seconds) to wait for incoming connections.
|
||||
|
||||
A value of -1 mean infinite (default). This option implies the
|
||||
@option{rtsp_flags} set to @samp{listen}.
|
||||
|
||||
@item reorder_queue_size
|
||||
Set number of packets to buffer for handling of reordered packets.
|
||||
|
||||
@item stimeout
|
||||
Set socket TCP I/O timeout in micro seconds.
|
||||
|
||||
@item user-agent
|
||||
Override User-Agent header. If not specified, it default to the
|
||||
libavformat identifier string.
|
||||
@end table
|
||||
|
||||
When receiving data over UDP, the demuxer tries to reorder received packets
|
||||
(since they may arrive out of order, or packets may get lost totally). This
|
||||
can be disabled by setting the maximum demuxing delay to zero (via
|
||||
@@ -791,36 +589,36 @@ streams to display can be chosen with @code{-vst} @var{n} and
|
||||
@code{-ast} @var{n} for video and audio respectively, and can be switched
|
||||
on the fly by pressing @code{v} and @code{a}.
|
||||
|
||||
@subsection Examples
|
||||
Example command lines:
|
||||
|
||||
The following examples all make use of the @command{ffplay} and
|
||||
@command{ffmpeg} tools.
|
||||
To watch a stream over UDP, with a max reordering delay of 0.5 seconds:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Watch a stream over UDP, with a max reordering delay of 0.5 seconds:
|
||||
@example
|
||||
ffplay -max_delay 500000 -rtsp_transport udp rtsp://server/video.mp4
|
||||
@end example
|
||||
|
||||
@item
|
||||
Watch a stream tunneled over HTTP:
|
||||
To watch a stream tunneled over HTTP:
|
||||
|
||||
@example
|
||||
ffplay -rtsp_transport http rtsp://server/video.mp4
|
||||
@end example
|
||||
|
||||
@item
|
||||
Send a stream in realtime to a RTSP server, for others to watch:
|
||||
To send a stream in realtime to a RTSP server, for others to watch:
|
||||
|
||||
@example
|
||||
ffmpeg -re -i @var{input} -f rtsp -muxdelay 0.1 rtsp://server/live.sdp
|
||||
@end example
|
||||
|
||||
@item
|
||||
Receive a stream in realtime:
|
||||
To receive a stream in realtime:
|
||||
|
||||
@example
|
||||
ffmpeg -rtsp_flags listen -i rtsp://ownaddress/live.sdp @var{output}
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@table @option
|
||||
@item stimeout
|
||||
Socket IO timeout in micro seconds.
|
||||
@end table
|
||||
|
||||
@section sap
|
||||
|
||||
@@ -967,76 +765,48 @@ The required syntax for a TCP url is:
|
||||
tcp://@var{hostname}:@var{port}[?@var{options}]
|
||||
@end example
|
||||
|
||||
@var{options} contains a list of &-separated options of the form
|
||||
@var{key}=@var{val}.
|
||||
|
||||
The list of supported options follows.
|
||||
|
||||
@table @option
|
||||
@item listen=@var{1|0}
|
||||
Listen for an incoming connection. Default value is 0.
|
||||
|
||||
@item listen
|
||||
Listen for an incoming connection
|
||||
|
||||
@item timeout=@var{microseconds}
|
||||
Set raise error timeout, expressed in microseconds.
|
||||
In read mode: if no data arrived in more than this time interval, raise error.
|
||||
In write mode: if socket cannot be written in more than this time interval, raise error.
|
||||
This also sets timeout on TCP connection establishing.
|
||||
|
||||
This option is only relevant in read mode: if no data arrived in more
|
||||
than this time interval, raise error.
|
||||
|
||||
@item listen_timeout=@var{microseconds}
|
||||
Set listen timeout, expressed in microseconds.
|
||||
@end table
|
||||
|
||||
The following example shows how to setup a listening TCP connection
|
||||
with @command{ffmpeg}, which is then accessed with @command{ffplay}:
|
||||
@example
|
||||
ffmpeg -i @var{input} -f @var{format} tcp://@var{hostname}:@var{port}?listen
|
||||
ffplay tcp://@var{hostname}:@var{port}
|
||||
@end example
|
||||
|
||||
@end table
|
||||
|
||||
@section tls
|
||||
|
||||
Transport Layer Security (TLS) / Secure Sockets Layer (SSL)
|
||||
Transport Layer Security/Secure Sockets Layer
|
||||
|
||||
The required syntax for a TLS/SSL url is:
|
||||
@example
|
||||
tls://@var{hostname}:@var{port}[?@var{options}]
|
||||
@end example
|
||||
|
||||
The following parameters can be set via command line options
|
||||
(or in code via @code{AVOption}s):
|
||||
|
||||
@table @option
|
||||
|
||||
@item ca_file, cafile=@var{filename}
|
||||
A file containing certificate authority (CA) root certificates to treat
|
||||
as trusted. If the linked TLS library contains a default this might not
|
||||
need to be specified for verification to work, but not all libraries and
|
||||
setups have defaults built in.
|
||||
The file must be in OpenSSL PEM format.
|
||||
@item listen
|
||||
Act as a server, listening for an incoming connection.
|
||||
|
||||
@item tls_verify=@var{1|0}
|
||||
If enabled, try to verify the peer that we are communicating with.
|
||||
Note, if using OpenSSL, this currently only makes sure that the
|
||||
peer certificate is signed by one of the root certificates in the CA
|
||||
database, but it does not validate that the certificate actually
|
||||
matches the host name we are trying to connect to. (With GnuTLS,
|
||||
the host name is validated as well.)
|
||||
@item cafile=@var{filename}
|
||||
Certificate authority file. The file must be in OpenSSL PEM format.
|
||||
|
||||
This is disabled by default since it requires a CA database to be
|
||||
provided by the caller in many cases.
|
||||
@item cert=@var{filename}
|
||||
Certificate file. The file must be in OpenSSL PEM format.
|
||||
|
||||
@item cert_file, cert=@var{filename}
|
||||
A file containing a certificate to use in the handshake with the peer.
|
||||
(When operating as server, in listen mode, this is more often required
|
||||
by the peer, while client certificates only are mandated in certain
|
||||
setups.)
|
||||
@item key=@var{filename}
|
||||
Private key file.
|
||||
|
||||
@item key_file, key=@var{filename}
|
||||
A file containing the private key for the certificate.
|
||||
|
||||
@item listen=@var{1|0}
|
||||
If enabled, listen for connections on the provided port, and assume
|
||||
the server role in the handshake instead of the client role.
|
||||
@item verify=@var{0|1}
|
||||
Verify the peer's certificate.
|
||||
|
||||
@end table
|
||||
|
||||
@@ -1058,7 +828,7 @@ ffplay tls://@var{hostname}:@var{port}
|
||||
|
||||
User Datagram Protocol.
|
||||
|
||||
The required syntax for an UDP URL is:
|
||||
The required syntax for a UDP url is:
|
||||
@example
|
||||
udp://@var{hostname}:@var{port}[?@var{options}]
|
||||
@end example
|
||||
@@ -1073,6 +843,7 @@ UDP socket buffer overruns. The @var{fifo_size} and
|
||||
The list of supported options follows.
|
||||
|
||||
@table @option
|
||||
|
||||
@item buffer_size=@var{size}
|
||||
Set the UDP socket buffer size in bytes. This is used both for the
|
||||
receiving and the sending buffer size.
|
||||
@@ -1122,53 +893,24 @@ Survive in case of UDP receiving circular buffer overrun. Default
|
||||
value is 0.
|
||||
|
||||
@item timeout=@var{microseconds}
|
||||
Set raise error timeout, expressed in microseconds.
|
||||
|
||||
This option is only relevant in read mode: if no data arrived in more
|
||||
than this time interval, raise error.
|
||||
In read mode: if no data arrived in more than this time interval, raise error.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
Some usage examples of the UDP protocol with @command{ffmpeg} follow.
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Use @command{ffmpeg} to stream over UDP to a remote endpoint:
|
||||
To stream over UDP to a remote endpoint:
|
||||
@example
|
||||
ffmpeg -i @var{input} -f @var{format} udp://@var{hostname}:@var{port}
|
||||
@end example
|
||||
|
||||
@item
|
||||
Use @command{ffmpeg} to stream in mpegts format over UDP using 188
|
||||
sized UDP packets, using a large input buffer:
|
||||
To stream in mpegts format over UDP using 188 sized UDP packets, using a large input buffer:
|
||||
@example
|
||||
ffmpeg -i @var{input} -f mpegts udp://@var{hostname}:@var{port}?pkt_size=188&buffer_size=65535
|
||||
@end example
|
||||
|
||||
@item
|
||||
Use @command{ffmpeg} to receive over UDP from a remote endpoint:
|
||||
To receive over UDP from a remote endpoint:
|
||||
@example
|
||||
ffmpeg -i udp://[@var{multicast-address}]:@var{port} ...
|
||||
ffmpeg -i udp://[@var{multicast-address}]:@var{port}
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@section unix
|
||||
|
||||
Unix local socket
|
||||
|
||||
The required syntax for a Unix socket URL is:
|
||||
|
||||
@example
|
||||
unix://@var{filepath}
|
||||
@end example
|
||||
|
||||
The following parameters can be set via command line options
|
||||
(or in code via @code{AVOption}s):
|
||||
|
||||
@table @option
|
||||
@item timeout
|
||||
Timeout in ms.
|
||||
@item listen
|
||||
Create the Unix socket in listening mode.
|
||||
@end table
|
||||
|
||||
@c man end PROTOCOLS
|
||||
|
||||
@@ -42,11 +42,10 @@ Set the internal sample format. Default value is @code{none}.
|
||||
This will automatically be chosen when it is not explicitly set.
|
||||
|
||||
@item icl, in_channel_layout
|
||||
@item ocl, out_channel_layout
|
||||
Set the input/output channel layout.
|
||||
Set the input channel layout.
|
||||
|
||||
See @ref{channel layout syntax,,the Channel Layout section in the ffmpeg-utils(1) manual,ffmpeg-utils}
|
||||
for the required syntax.
|
||||
@item ocl, out_channel_layout
|
||||
Set the output channel layout.
|
||||
|
||||
@item clev, center_mix_level
|
||||
Set the center mix level. It is a value expressed in deciBel, and must be
|
||||
@@ -64,11 +63,6 @@ be in the interval [-32,32].
|
||||
@item rmvol, rematrix_volume
|
||||
Set rematrix volume. Default value is 1.0.
|
||||
|
||||
@item rematrix_maxval
|
||||
Set maximum output value for rematrixing.
|
||||
This can be used to prevent clipping vs. preventing volumn reduction
|
||||
A value of 1.0 prevents cliping.
|
||||
|
||||
@item flags, swr_flags
|
||||
Set flags used by the converter. Default value is 0.
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
@anchor{scaler_options}
|
||||
@chapter Scaler Options
|
||||
@c man begin SCALER OPTIONS
|
||||
|
||||
@@ -10,7 +9,6 @@ FFmpeg tools. For programmatic use, they can be set explicitly in the
|
||||
|
||||
@table @option
|
||||
|
||||
@anchor{sws_flags}
|
||||
@item sws_flags
|
||||
Set the scaler flags. This is also used to set the scaling
|
||||
algorithm. Only a single algorithm should be selected.
|
||||
@@ -96,24 +94,6 @@ Set scaling algorithm parameters. The specified values are specific of
|
||||
some scaling algorithms and ignored by others. The specified values
|
||||
are floating point number values.
|
||||
|
||||
@item sws_dither
|
||||
Set the dithering algorithm. Accepts one of the following
|
||||
values. Default value is @samp{auto}.
|
||||
|
||||
@table @samp
|
||||
@item auto
|
||||
automatic choice
|
||||
|
||||
@item none
|
||||
no dithering
|
||||
|
||||
@item bayer
|
||||
bayer dither
|
||||
|
||||
@item ed
|
||||
error diffusion dither
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@c man end SCALER OPTIONS
|
||||
|
||||
24
doc/snow.txt
24
doc/snow.txt
@@ -50,10 +50,8 @@ header:
|
||||
temporal_decomposition_count u header_state
|
||||
spatial_decomposition_count u header_state
|
||||
colorspace_type u header_state
|
||||
if (nb_planes > 2) {
|
||||
chroma_h_shift u header_state
|
||||
chroma_v_shift u header_state
|
||||
}
|
||||
chroma_h_shift u header_state
|
||||
chroma_v_shift u header_state
|
||||
spatial_scalability b header_state
|
||||
max_ref_frames-1 u header_state
|
||||
qlogs
|
||||
@@ -61,7 +59,7 @@ header:
|
||||
if(!keyframe){
|
||||
update_mc b header_state
|
||||
if(update_mc){
|
||||
for(plane=0; plane<nb_plane_types; plane++){
|
||||
for(plane=0; plane<2; plane++){
|
||||
diag_mc b header_state
|
||||
htaps/2-1 u header_state
|
||||
for(i= p->htaps/2; i; i--)
|
||||
@@ -82,7 +80,7 @@ header:
|
||||
block_max_depth s header_state
|
||||
|
||||
qlogs:
|
||||
for(plane=0; plane<nb_plane_types; plane++){
|
||||
for(plane=0; plane<2; plane++){
|
||||
quant_table[plane][0][0] s header_state
|
||||
for(level=0; level < spatial_decomposition_count; level++){
|
||||
quant_table[plane][level][1]s header_state
|
||||
@@ -133,10 +131,8 @@ block(level):
|
||||
|
||||
residual:
|
||||
residual2(luma)
|
||||
if (nb_planes > 2) {
|
||||
residual2(chroma_cr)
|
||||
residual2(chroma_cb)
|
||||
}
|
||||
residual2(chroma_cr)
|
||||
residual2(chroma_cb)
|
||||
|
||||
residual2:
|
||||
for(level=0; level<spatial_decomposition_count; level++){
|
||||
@@ -150,7 +146,7 @@ residual2:
|
||||
subband:
|
||||
FIXME
|
||||
|
||||
nb_plane_types = gray ? 1 : 2;
|
||||
|
||||
|
||||
Tag description:
|
||||
----------------
|
||||
@@ -172,11 +168,7 @@ spatial_decomposition_count
|
||||
FIXME
|
||||
|
||||
colorspace_type
|
||||
0 unspecified YcbCr
|
||||
1 Gray
|
||||
2 Gray + Alpha
|
||||
3 GBR
|
||||
4 GBRA
|
||||
0
|
||||
this MUST NOT change within a bitstream
|
||||
|
||||
chroma_h_shift
|
||||
|
||||
24
doc/soc.txt
Normal file
24
doc/soc.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
Google Summer of Code and similar project guidelines
|
||||
|
||||
Summer of Code is a project by Google in which students are paid to implement
|
||||
some nice new features for various participating open source projects ...
|
||||
|
||||
This text is a collection of things to take care of for the next soc as
|
||||
it's a little late for this year's soc (2006).
|
||||
|
||||
The Goal:
|
||||
Our goal in respect to soc is and must be of course exactly one thing and
|
||||
that is to improve FFmpeg, to reach this goal, code must
|
||||
* conform to the development policy and patch submission guidelines
|
||||
* must improve FFmpeg somehow (faster, smaller, "better",
|
||||
more codecs supported, fewer bugs, cleaner, ...)
|
||||
|
||||
for mentors and other developers to help students to reach that goal it is
|
||||
essential that changes to their codebase are publicly visible, clean and
|
||||
easy reviewable that again leads us to:
|
||||
* use of a revision control system like git
|
||||
* separation of cosmetic from non-cosmetic changes (this is almost entirely
|
||||
ignored by mentors and students in soc 2006 which might lead to a surprise
|
||||
when the code will be reviewed at the end before a possible inclusion in
|
||||
FFmpeg, individual changes were generally not reviewable due to cosmetics).
|
||||
* frequent commits, so that comments can be provided early
|
||||
@@ -17,7 +17,6 @@ my $TEMPLATE_HEADER = $ENV{"FFMPEG_HEADER"} || <<EOT;
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="body">
|
||||
EOT
|
||||
|
||||
$PRE_BODY_CLOSE = '</div></div>';
|
||||
@@ -33,7 +32,7 @@ sub FFmpeg_print_page_foot($$)
|
||||
T2H_DEFAULT_program_string() : program_string();
|
||||
print $fh '<footer class="footer pagination-right">' . "\n";
|
||||
print $fh '<span class="label label-info">' . $program_string;
|
||||
print $fh "</span></footer></div></div></body>\n";
|
||||
print $fh "</span></footer></div>\n";
|
||||
}
|
||||
|
||||
$float = \&FFmpeg_float;
|
||||
@@ -93,6 +92,8 @@ $Texi2HTML::THISDOC{program_authors}
|
||||
|
||||
$description
|
||||
<meta name="keywords" content="$longtitle">
|
||||
<meta name="resource-type" content="document">
|
||||
<meta name="distribution" content="global">
|
||||
<meta name="Generator" content="$Texi2HTML::THISDOC{program}">
|
||||
$encoding
|
||||
$CSS_LINES
|
||||
|
||||
9
doc/texi2pod.pl
Normal file → Executable file
9
doc/texi2pod.pl
Normal file → Executable file
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env perl
|
||||
#! /usr/bin/perl
|
||||
|
||||
# Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
@@ -327,9 +327,6 @@ die "No filename or title\n" unless defined $fn && defined $tl;
|
||||
$chapters{NAME} = "$fn \- $tl\n";
|
||||
$chapters{FOOTNOTES} .= "=back\n" if exists $chapters{FOOTNOTES};
|
||||
|
||||
# always use utf8
|
||||
print "=encoding utf8\n\n";
|
||||
|
||||
unshift @chapters_sequence, "NAME";
|
||||
for $chapter (@chapters_sequence) {
|
||||
if (exists $chapters{$chapter}) {
|
||||
@@ -380,8 +377,8 @@ sub postprocess
|
||||
s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g;
|
||||
s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g;
|
||||
s/;\s+\@pxref\{(?:[^\}]*)\}//g;
|
||||
s/\@ref\{(?:[^,\}]*,)(?:[^,\}]*,)([^,\}]*).*\}/B<$1>/g;
|
||||
s/\@ref\{([^\}]*)\}/B<$1>/g;
|
||||
s/\@ref\{(?:[^,\}]*,)(?:[^,\}]*,)([^,\}]*).*\}/$1/g;
|
||||
s/\@ref\{([^\}]*)\}/$1/g;
|
||||
s/\@noindent\s*//g;
|
||||
s/\@refill//g;
|
||||
s/\@gol//g;
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#! /usr/bin/env perl
|
||||
|
||||
# This script will print the dependency of a Texinfo file to stdout.
|
||||
# texidep.pl <src-path> <input.texi> <output.ext>
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
die unless @ARGV == 3;
|
||||
|
||||
my ($src_path, $root, $target) = @ARGV;
|
||||
|
||||
sub print_deps {
|
||||
my ($file, $deps) = @_;
|
||||
$deps->{$file} = 1;
|
||||
|
||||
open(my $fh, "<", "$file") or die "Cannot open file '$file': $!";
|
||||
while (<$fh>) {
|
||||
if (my ($i) = /^\@(?:verbatim)?include\s+(\S+)/) {
|
||||
die "Circular dependency found in file $root\n" if exists $deps->{"doc/$1"};
|
||||
print "$target: doc/$1\n";
|
||||
|
||||
# skip looking for config.texi dependencies, since it has
|
||||
# none, and is not located in the source tree
|
||||
if ("$1" ne "config.texi") {
|
||||
print_deps("$src_path/doc/$1", {%$deps});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print_deps($root, {});
|
||||
500
doc/utils.texi
500
doc/utils.texi
@@ -96,42 +96,14 @@ year-month-day.
|
||||
@anchor{time duration syntax}
|
||||
@section Time duration
|
||||
|
||||
There are two accepted syntaxes for expressing time duration.
|
||||
|
||||
The accepted syntax is:
|
||||
@example
|
||||
[-][@var{HH}:]@var{MM}:@var{SS}[.@var{m}...]
|
||||
[-][HH:]MM:SS[.m...]
|
||||
[-]S+[.m...]
|
||||
@end example
|
||||
|
||||
@var{HH} expresses the number of hours, @var{MM} the number of minutes
|
||||
for a maximum of 2 digits, and @var{SS} the number of seconds for a
|
||||
maximum of 2 digits. The @var{m} at the end expresses decimal value for
|
||||
@var{SS}.
|
||||
|
||||
@emph{or}
|
||||
|
||||
@example
|
||||
[-]@var{S}+[.@var{m}...]
|
||||
@end example
|
||||
|
||||
@var{S} expresses the number of seconds, with the optional decimal part
|
||||
@var{m}.
|
||||
|
||||
In both expressions, the optional @samp{-} indicates negative duration.
|
||||
|
||||
@subsection Examples
|
||||
|
||||
The following examples are all valid time duration:
|
||||
|
||||
@table @samp
|
||||
@item 55
|
||||
55 seconds
|
||||
|
||||
@item 12:03:45
|
||||
12 hours, 03 minutes and 45 seconds
|
||||
|
||||
@item 23.189
|
||||
23.189 seconds
|
||||
@end table
|
||||
@var{HH} expresses the number of hours, @var{MM} the number a of minutes
|
||||
and @var{SS} the number of seconds.
|
||||
|
||||
@anchor{video size syntax}
|
||||
@section Video size
|
||||
@@ -226,18 +198,6 @@ The following abbreviations are recognized:
|
||||
3996x2160
|
||||
@item 4kscope
|
||||
4096x1716
|
||||
@item nhd
|
||||
640x360
|
||||
@item hqvga
|
||||
240x160
|
||||
@item wqvga
|
||||
400x240
|
||||
@item fwqvga
|
||||
432x240
|
||||
@item hvga
|
||||
480x320
|
||||
@item qhd
|
||||
960x540
|
||||
@end table
|
||||
|
||||
@anchor{video rate syntax}
|
||||
@@ -283,450 +243,18 @@ The undefined value can be expressed using the "0:0" string.
|
||||
@anchor{color syntax}
|
||||
@section Color
|
||||
|
||||
It can be the name of a color as defined below (case insensitive match) or a
|
||||
@code{[0x|#]RRGGBB[AA]} sequence, possibly followed by @@ and a string
|
||||
It can be the name of a color (case insensitive match) or a
|
||||
[0x|#]RRGGBB[AA] sequence, possibly followed by "@@" and a string
|
||||
representing the alpha component.
|
||||
|
||||
The alpha component may be a string composed by "0x" followed by an
|
||||
hexadecimal number or a decimal number between 0.0 and 1.0, which
|
||||
represents the opacity value (@samp{0x00} or @samp{0.0} means completely
|
||||
transparent, @samp{0xff} or @samp{1.0} completely opaque). If the alpha
|
||||
component is not specified then @samp{0xff} is assumed.
|
||||
represents the opacity value (0x00/0.0 means completely transparent,
|
||||
0xff/1.0 completely opaque).
|
||||
If the alpha component is not specified then 0xff is assumed.
|
||||
|
||||
The string @samp{random} will result in a random color.
|
||||
The string "random" will result in a random color.
|
||||
|
||||
The following names of colors are recognized:
|
||||
@table @samp
|
||||
@item AliceBlue
|
||||
0xF0F8FF
|
||||
@item AntiqueWhite
|
||||
0xFAEBD7
|
||||
@item Aqua
|
||||
0x00FFFF
|
||||
@item Aquamarine
|
||||
0x7FFFD4
|
||||
@item Azure
|
||||
0xF0FFFF
|
||||
@item Beige
|
||||
0xF5F5DC
|
||||
@item Bisque
|
||||
0xFFE4C4
|
||||
@item Black
|
||||
0x000000
|
||||
@item BlanchedAlmond
|
||||
0xFFEBCD
|
||||
@item Blue
|
||||
0x0000FF
|
||||
@item BlueViolet
|
||||
0x8A2BE2
|
||||
@item Brown
|
||||
0xA52A2A
|
||||
@item BurlyWood
|
||||
0xDEB887
|
||||
@item CadetBlue
|
||||
0x5F9EA0
|
||||
@item Chartreuse
|
||||
0x7FFF00
|
||||
@item Chocolate
|
||||
0xD2691E
|
||||
@item Coral
|
||||
0xFF7F50
|
||||
@item CornflowerBlue
|
||||
0x6495ED
|
||||
@item Cornsilk
|
||||
0xFFF8DC
|
||||
@item Crimson
|
||||
0xDC143C
|
||||
@item Cyan
|
||||
0x00FFFF
|
||||
@item DarkBlue
|
||||
0x00008B
|
||||
@item DarkCyan
|
||||
0x008B8B
|
||||
@item DarkGoldenRod
|
||||
0xB8860B
|
||||
@item DarkGray
|
||||
0xA9A9A9
|
||||
@item DarkGreen
|
||||
0x006400
|
||||
@item DarkKhaki
|
||||
0xBDB76B
|
||||
@item DarkMagenta
|
||||
0x8B008B
|
||||
@item DarkOliveGreen
|
||||
0x556B2F
|
||||
@item Darkorange
|
||||
0xFF8C00
|
||||
@item DarkOrchid
|
||||
0x9932CC
|
||||
@item DarkRed
|
||||
0x8B0000
|
||||
@item DarkSalmon
|
||||
0xE9967A
|
||||
@item DarkSeaGreen
|
||||
0x8FBC8F
|
||||
@item DarkSlateBlue
|
||||
0x483D8B
|
||||
@item DarkSlateGray
|
||||
0x2F4F4F
|
||||
@item DarkTurquoise
|
||||
0x00CED1
|
||||
@item DarkViolet
|
||||
0x9400D3
|
||||
@item DeepPink
|
||||
0xFF1493
|
||||
@item DeepSkyBlue
|
||||
0x00BFFF
|
||||
@item DimGray
|
||||
0x696969
|
||||
@item DodgerBlue
|
||||
0x1E90FF
|
||||
@item FireBrick
|
||||
0xB22222
|
||||
@item FloralWhite
|
||||
0xFFFAF0
|
||||
@item ForestGreen
|
||||
0x228B22
|
||||
@item Fuchsia
|
||||
0xFF00FF
|
||||
@item Gainsboro
|
||||
0xDCDCDC
|
||||
@item GhostWhite
|
||||
0xF8F8FF
|
||||
@item Gold
|
||||
0xFFD700
|
||||
@item GoldenRod
|
||||
0xDAA520
|
||||
@item Gray
|
||||
0x808080
|
||||
@item Green
|
||||
0x008000
|
||||
@item GreenYellow
|
||||
0xADFF2F
|
||||
@item HoneyDew
|
||||
0xF0FFF0
|
||||
@item HotPink
|
||||
0xFF69B4
|
||||
@item IndianRed
|
||||
0xCD5C5C
|
||||
@item Indigo
|
||||
0x4B0082
|
||||
@item Ivory
|
||||
0xFFFFF0
|
||||
@item Khaki
|
||||
0xF0E68C
|
||||
@item Lavender
|
||||
0xE6E6FA
|
||||
@item LavenderBlush
|
||||
0xFFF0F5
|
||||
@item LawnGreen
|
||||
0x7CFC00
|
||||
@item LemonChiffon
|
||||
0xFFFACD
|
||||
@item LightBlue
|
||||
0xADD8E6
|
||||
@item LightCoral
|
||||
0xF08080
|
||||
@item LightCyan
|
||||
0xE0FFFF
|
||||
@item LightGoldenRodYellow
|
||||
0xFAFAD2
|
||||
@item LightGreen
|
||||
0x90EE90
|
||||
@item LightGrey
|
||||
0xD3D3D3
|
||||
@item LightPink
|
||||
0xFFB6C1
|
||||
@item LightSalmon
|
||||
0xFFA07A
|
||||
@item LightSeaGreen
|
||||
0x20B2AA
|
||||
@item LightSkyBlue
|
||||
0x87CEFA
|
||||
@item LightSlateGray
|
||||
0x778899
|
||||
@item LightSteelBlue
|
||||
0xB0C4DE
|
||||
@item LightYellow
|
||||
0xFFFFE0
|
||||
@item Lime
|
||||
0x00FF00
|
||||
@item LimeGreen
|
||||
0x32CD32
|
||||
@item Linen
|
||||
0xFAF0E6
|
||||
@item Magenta
|
||||
0xFF00FF
|
||||
@item Maroon
|
||||
0x800000
|
||||
@item MediumAquaMarine
|
||||
0x66CDAA
|
||||
@item MediumBlue
|
||||
0x0000CD
|
||||
@item MediumOrchid
|
||||
0xBA55D3
|
||||
@item MediumPurple
|
||||
0x9370D8
|
||||
@item MediumSeaGreen
|
||||
0x3CB371
|
||||
@item MediumSlateBlue
|
||||
0x7B68EE
|
||||
@item MediumSpringGreen
|
||||
0x00FA9A
|
||||
@item MediumTurquoise
|
||||
0x48D1CC
|
||||
@item MediumVioletRed
|
||||
0xC71585
|
||||
@item MidnightBlue
|
||||
0x191970
|
||||
@item MintCream
|
||||
0xF5FFFA
|
||||
@item MistyRose
|
||||
0xFFE4E1
|
||||
@item Moccasin
|
||||
0xFFE4B5
|
||||
@item NavajoWhite
|
||||
0xFFDEAD
|
||||
@item Navy
|
||||
0x000080
|
||||
@item OldLace
|
||||
0xFDF5E6
|
||||
@item Olive
|
||||
0x808000
|
||||
@item OliveDrab
|
||||
0x6B8E23
|
||||
@item Orange
|
||||
0xFFA500
|
||||
@item OrangeRed
|
||||
0xFF4500
|
||||
@item Orchid
|
||||
0xDA70D6
|
||||
@item PaleGoldenRod
|
||||
0xEEE8AA
|
||||
@item PaleGreen
|
||||
0x98FB98
|
||||
@item PaleTurquoise
|
||||
0xAFEEEE
|
||||
@item PaleVioletRed
|
||||
0xD87093
|
||||
@item PapayaWhip
|
||||
0xFFEFD5
|
||||
@item PeachPuff
|
||||
0xFFDAB9
|
||||
@item Peru
|
||||
0xCD853F
|
||||
@item Pink
|
||||
0xFFC0CB
|
||||
@item Plum
|
||||
0xDDA0DD
|
||||
@item PowderBlue
|
||||
0xB0E0E6
|
||||
@item Purple
|
||||
0x800080
|
||||
@item Red
|
||||
0xFF0000
|
||||
@item RosyBrown
|
||||
0xBC8F8F
|
||||
@item RoyalBlue
|
||||
0x4169E1
|
||||
@item SaddleBrown
|
||||
0x8B4513
|
||||
@item Salmon
|
||||
0xFA8072
|
||||
@item SandyBrown
|
||||
0xF4A460
|
||||
@item SeaGreen
|
||||
0x2E8B57
|
||||
@item SeaShell
|
||||
0xFFF5EE
|
||||
@item Sienna
|
||||
0xA0522D
|
||||
@item Silver
|
||||
0xC0C0C0
|
||||
@item SkyBlue
|
||||
0x87CEEB
|
||||
@item SlateBlue
|
||||
0x6A5ACD
|
||||
@item SlateGray
|
||||
0x708090
|
||||
@item Snow
|
||||
0xFFFAFA
|
||||
@item SpringGreen
|
||||
0x00FF7F
|
||||
@item SteelBlue
|
||||
0x4682B4
|
||||
@item Tan
|
||||
0xD2B48C
|
||||
@item Teal
|
||||
0x008080
|
||||
@item Thistle
|
||||
0xD8BFD8
|
||||
@item Tomato
|
||||
0xFF6347
|
||||
@item Turquoise
|
||||
0x40E0D0
|
||||
@item Violet
|
||||
0xEE82EE
|
||||
@item Wheat
|
||||
0xF5DEB3
|
||||
@item White
|
||||
0xFFFFFF
|
||||
@item WhiteSmoke
|
||||
0xF5F5F5
|
||||
@item Yellow
|
||||
0xFFFF00
|
||||
@item YellowGreen
|
||||
0x9ACD32
|
||||
@end table
|
||||
|
||||
@anchor{channel layout syntax}
|
||||
@section Channel Layout
|
||||
|
||||
A channel layout specifies the spatial disposition of the channels in
|
||||
a multi-channel audio stream. To specify a channel layout, FFmpeg
|
||||
makes use of a special syntax.
|
||||
|
||||
Individual channels are identified by an id, as given by the table
|
||||
below:
|
||||
@table @samp
|
||||
@item FL
|
||||
front left
|
||||
@item FR
|
||||
front right
|
||||
@item FC
|
||||
front center
|
||||
@item LFE
|
||||
low frequency
|
||||
@item BL
|
||||
back left
|
||||
@item BR
|
||||
back right
|
||||
@item FLC
|
||||
front left-of-center
|
||||
@item FRC
|
||||
front right-of-center
|
||||
@item BC
|
||||
back center
|
||||
@item SL
|
||||
side left
|
||||
@item SR
|
||||
side right
|
||||
@item TC
|
||||
top center
|
||||
@item TFL
|
||||
top front left
|
||||
@item TFC
|
||||
top front center
|
||||
@item TFR
|
||||
top front right
|
||||
@item TBL
|
||||
top back left
|
||||
@item TBC
|
||||
top back center
|
||||
@item TBR
|
||||
top back right
|
||||
@item DL
|
||||
downmix left
|
||||
@item DR
|
||||
downmix right
|
||||
@item WL
|
||||
wide left
|
||||
@item WR
|
||||
wide right
|
||||
@item SDL
|
||||
surround direct left
|
||||
@item SDR
|
||||
surround direct right
|
||||
@item LFE2
|
||||
low frequency 2
|
||||
@end table
|
||||
|
||||
Standard channel layout compositions can be specified by using the
|
||||
following identifiers:
|
||||
@table @samp
|
||||
@item mono
|
||||
FC
|
||||
@item stereo
|
||||
FL+FR
|
||||
@item 2.1
|
||||
FL+FR+LFE
|
||||
@item 3.0
|
||||
FL+FR+FC
|
||||
@item 3.0(back)
|
||||
FL+FR+BC
|
||||
@item 4.0
|
||||
FL+FR+FC+BC
|
||||
@item quad
|
||||
FL+FR+BL+BR
|
||||
@item quad(side)
|
||||
FL+FR+SL+SR
|
||||
@item 3.1
|
||||
FL+FR+FC+LFE
|
||||
@item 5.0
|
||||
FL+FR+FC+BL+BR
|
||||
@item 5.0(side)
|
||||
FL+FR+FC+SL+SR
|
||||
@item 4.1
|
||||
FL+FR+FC+LFE+BC
|
||||
@item 5.1
|
||||
FL+FR+FC+LFE+BL+BR
|
||||
@item 5.1(side)
|
||||
FL+FR+FC+LFE+SL+SR
|
||||
@item 6.0
|
||||
FL+FR+FC+BC+SL+SR
|
||||
@item 6.0(front)
|
||||
FL+FR+FLC+FRC+SL+SR
|
||||
@item hexagonal
|
||||
FL+FR+FC+BL+BR+BC
|
||||
@item 6.1
|
||||
FL+FR+FC+LFE+BC+SL+SR
|
||||
@item 6.1
|
||||
FL+FR+FC+LFE+BL+BR+BC
|
||||
@item 6.1(front)
|
||||
FL+FR+LFE+FLC+FRC+SL+SR
|
||||
@item 7.0
|
||||
FL+FR+FC+BL+BR+SL+SR
|
||||
@item 7.0(front)
|
||||
FL+FR+FC+FLC+FRC+SL+SR
|
||||
@item 7.1
|
||||
FL+FR+FC+LFE+BL+BR+SL+SR
|
||||
@item 7.1(wide)
|
||||
FL+FR+FC+LFE+BL+BR+FLC+FRC
|
||||
@item 7.1(wide-side)
|
||||
FL+FR+FC+LFE+FLC+FRC+SL+SR
|
||||
@item octagonal
|
||||
FL+FR+FC+BL+BR+BC+SL+SR
|
||||
@item downmix
|
||||
DL+DR
|
||||
@end table
|
||||
|
||||
A custom channel layout can be specified as a sequence of terms, separated by
|
||||
'+' or '|'. Each term can be:
|
||||
@itemize
|
||||
@item
|
||||
the name of a standard channel layout (e.g. @samp{mono},
|
||||
@samp{stereo}, @samp{4.0}, @samp{quad}, @samp{5.0}, etc.)
|
||||
|
||||
@item
|
||||
the name of a single channel (e.g. @samp{FL}, @samp{FR}, @samp{FC}, @samp{LFE}, etc.)
|
||||
|
||||
@item
|
||||
a number of channels, in decimal, optionally followed by 'c', yielding
|
||||
the default channel layout for that number of channels (see the
|
||||
function @code{av_get_default_channel_layout})
|
||||
|
||||
@item
|
||||
a channel layout mask, in hexadecimal starting with "0x" (see the
|
||||
@code{AV_CH_*} macros in @file{libavutil/channel_layout.h}.
|
||||
@end itemize
|
||||
|
||||
Starting from libavutil version 53 the trailing character "c" to
|
||||
specify a number of channels will be required, while a channel layout
|
||||
mask could also be specified as a decimal number (if and only if not
|
||||
followed by "c").
|
||||
|
||||
See also the function @code{av_get_channel_layout} defined in
|
||||
@file{libavutil/channel_layout.h}.
|
||||
@c man end SYNTAX
|
||||
|
||||
@chapter Expression Evaluation
|
||||
@@ -858,7 +386,7 @@ Return 1 if @var{x} is lesser than or equal to @var{y}, 0 otherwise.
|
||||
Return the maximum between @var{x} and @var{y}.
|
||||
|
||||
@item min(x, y)
|
||||
Return the maximum between @var{x} and @var{y}.
|
||||
Return the minimum between @var{x} and @var{y}.
|
||||
|
||||
@item mod(x, y)
|
||||
Compute the remainder of division of @var{x} by @var{y}.
|
||||
@@ -1051,13 +579,13 @@ See reference "OpenCL Specification Version: 1.2 chapter 5.6.4".
|
||||
Select the index of the platform to run OpenCL code.
|
||||
|
||||
The specified index must be one of the indexes in the device list
|
||||
which can be obtained with @code{ffmpeg -opencl_bench} or @code{av_opencl_get_device_list()}.
|
||||
which can be obtained with @code{av_opencl_get_device_list()}.
|
||||
|
||||
@item device_idx
|
||||
Select the index of the device used to run OpenCL code.
|
||||
|
||||
The specifed index must be one of the indexes in the device list which
|
||||
can be obtained with @code{ffmpeg -opencl_bench} or @code{av_opencl_get_device_list()}.
|
||||
can be obtained with @code{av_opencl_get_device_list()}.
|
||||
|
||||
@end table
|
||||
|
||||
|
||||
109
doc/viterbi.txt
Normal file
109
doc/viterbi.txt
Normal file
@@ -0,0 +1,109 @@
|
||||
This is a quick description of the viterbi aka dynamic programing
|
||||
algorthm.
|
||||
|
||||
Its reason for existence is that wikipedia has become very poor on
|
||||
describing algorithms in a way that makes it useable for understanding
|
||||
them or anything else actually. It tends now to describe the very same
|
||||
algorithm under 50 different names and pages with few understandable
|
||||
by even people who fully understand the algorithm and the theory behind.
|
||||
|
||||
Problem description: (that is what it can solve)
|
||||
assume we have a 2d table, or you could call it a graph or matrix if you
|
||||
prefer
|
||||
|
||||
O O O O O O O
|
||||
|
||||
O O O O O O O
|
||||
|
||||
O O O O O O O
|
||||
|
||||
O O O O O O O
|
||||
|
||||
|
||||
That table has edges connecting points from each column to the next column
|
||||
and each edge has a score like: (only some edge and scores shown to keep it
|
||||
readable)
|
||||
|
||||
|
||||
O--5--O-----O-----O-----O-----O
|
||||
2 / 7 / \ / \ / \ /
|
||||
\ / \ / \ / \ / \ /
|
||||
O7-/--O--/--O--/--O--/--O--/--O
|
||||
\/ \/ 1/ \/ \/ \/ \/ \/ \/ \/
|
||||
/\ /\ 2\ /\ /\ /\ /\ /\ /\ /\
|
||||
O3-/--O--/--O--/--O--/--O--/--O
|
||||
/ \ / \ / \ / \ / \
|
||||
1 \ 9 \ / \ / \ / \
|
||||
O--2--O--1--O--5--O--3--O--8--O
|
||||
|
||||
|
||||
|
||||
Our goal is to find a path from left to right through it which
|
||||
minimizes the sum of the score of all edges.
|
||||
(and of course left/right is just a convention here it could be top down too)
|
||||
Similarly the minimum could be the maximum by just fliping the sign,
|
||||
Example of a path with scores:
|
||||
|
||||
O O O O O O O
|
||||
|
||||
>---O. O O .O-2-O O O
|
||||
5. .7 .
|
||||
O O-1-O O O 8 O O
|
||||
.
|
||||
O O O O O O-1-O---> (sum here is 24)
|
||||
|
||||
|
||||
The viterbi algorthm now solves this simply column by column
|
||||
For the previous column each point has a best path and a associated
|
||||
score:
|
||||
|
||||
O-----5 O
|
||||
\
|
||||
\
|
||||
O \ 1 O
|
||||
\/
|
||||
/\
|
||||
O / 2 O
|
||||
/
|
||||
/
|
||||
O-----2 O
|
||||
|
||||
|
||||
To move one column forward we just need to find the best path and associated
|
||||
scores for the next column
|
||||
here are some edges we could choose from:
|
||||
|
||||
|
||||
O-----5--3--O
|
||||
\ \8
|
||||
\ \
|
||||
O \ 1--9--O
|
||||
\/ \3
|
||||
/\ \
|
||||
O / 2--1--O
|
||||
/ \2
|
||||
/ \
|
||||
O-----2--4--O
|
||||
|
||||
Finding the new best paths and scores for each point of our new column is
|
||||
trivial given we know the previous column best paths and scores:
|
||||
|
||||
O-----0-----8
|
||||
\
|
||||
\
|
||||
O \ 0----10
|
||||
\/
|
||||
/\
|
||||
O / 0-----3
|
||||
/ \
|
||||
/ \
|
||||
O 0 4
|
||||
|
||||
|
||||
the viterbi algorthm continues exactly like this column for column until the
|
||||
end and then just picks the path with the best score (above that would be the
|
||||
one with score 3)
|
||||
|
||||
|
||||
Author: Michael niedermayer
|
||||
Copyright LGPL
|
||||
427
ffmpeg.c
427
ffmpeg.c
@@ -30,8 +30,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if HAVE_ISATTY
|
||||
#if HAVE_IO_H
|
||||
#include <io.h>
|
||||
@@ -40,9 +38,9 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavdevice/avdevice.h"
|
||||
#include "libswscale/swscale.h"
|
||||
#include "libswresample/swresample.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/channel_layout.h"
|
||||
@@ -125,7 +123,6 @@ static int64_t getmaxrss(void);
|
||||
static int run_as_daemon = 0;
|
||||
static int64_t video_size = 0;
|
||||
static int64_t audio_size = 0;
|
||||
static int64_t data_size = 0;
|
||||
static int64_t subtitle_size = 0;
|
||||
static int64_t extra_size = 0;
|
||||
static int nb_frames_dup = 0;
|
||||
@@ -314,7 +311,6 @@ void term_exit(void)
|
||||
|
||||
static volatile int received_sigterm = 0;
|
||||
static volatile int received_nb_signals = 0;
|
||||
static int main_return_code = 0;
|
||||
|
||||
static void
|
||||
sigterm_handler(int sig)
|
||||
@@ -353,7 +349,6 @@ void term_init(void)
|
||||
signal(SIGQUIT, sigterm_handler); /* Quit (POSIX). */
|
||||
}
|
||||
#endif
|
||||
avformat_network_deinit();
|
||||
|
||||
signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
|
||||
signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
|
||||
@@ -470,9 +465,7 @@ static void ffmpeg_cleanup(int ret)
|
||||
bsfc = next;
|
||||
}
|
||||
output_streams[i]->bitstream_filters = NULL;
|
||||
av_frame_free(&output_streams[i]->filtered_frame);
|
||||
|
||||
av_parser_close(output_streams[i]->parser);
|
||||
avcodec_free_frame(&output_streams[i]->filtered_frame);
|
||||
|
||||
av_freep(&output_streams[i]->forced_keyframes);
|
||||
av_expr_free(output_streams[i]->forced_keyframes_pexpr);
|
||||
@@ -494,7 +487,6 @@ static void ffmpeg_cleanup(int ret)
|
||||
avsubtitle_free(&input_streams[i]->prev_sub.subtitle);
|
||||
av_frame_free(&input_streams[i]->sub2video.frame);
|
||||
av_freep(&input_streams[i]->filters);
|
||||
av_freep(&input_streams[i]->hwaccel_device);
|
||||
av_freep(&input_streams[i]);
|
||||
}
|
||||
|
||||
@@ -514,8 +506,6 @@ static void ffmpeg_cleanup(int ret)
|
||||
if (received_sigterm) {
|
||||
av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n",
|
||||
(int) received_sigterm);
|
||||
} else if (ret) {
|
||||
av_log(NULL, AV_LOG_INFO, "Conversion failed!\n");
|
||||
}
|
||||
term_exit();
|
||||
}
|
||||
@@ -551,15 +541,6 @@ static void update_benchmark(const char *fmt, ...)
|
||||
}
|
||||
}
|
||||
|
||||
static void close_all_output_streams(OutputStream *ost, OSTFinished this_stream, OSTFinished others)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nb_output_streams; i++) {
|
||||
OutputStream *ost2 = output_streams[i];
|
||||
ost2->finished |= ost == ost2 ? this_stream : others;
|
||||
}
|
||||
}
|
||||
|
||||
static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
|
||||
{
|
||||
AVBitStreamFilterContext *bsfc = ost->bitstream_filters;
|
||||
@@ -660,8 +641,7 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
|
||||
ret = av_interleaved_write_frame(s, pkt);
|
||||
if (ret < 0) {
|
||||
print_error("av_interleaved_write_frame()", ret);
|
||||
main_return_code = 1;
|
||||
close_all_output_streams(ost, MUXER_FINISHED | ENCODER_FINISHED, ENCODER_FINISHED);
|
||||
exit_program(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -669,7 +649,7 @@ static void close_output_stream(OutputStream *ost)
|
||||
{
|
||||
OutputFile *of = output_files[ost->file_index];
|
||||
|
||||
ost->finished |= ENCODER_FINISHED;
|
||||
ost->finished = 1;
|
||||
if (of->shortest) {
|
||||
int64_t end = av_rescale_q(ost->sync_opts - ost->first_pts, ost->st->codec->time_base, AV_TIME_BASE_Q);
|
||||
of->recording_time = FFMIN(of->recording_time, end);
|
||||
@@ -709,12 +689,6 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost,
|
||||
|
||||
av_assert0(pkt.size || !pkt.data);
|
||||
update_benchmark(NULL);
|
||||
if (debug_ts) {
|
||||
av_log(NULL, AV_LOG_INFO, "encoder <- type:audio "
|
||||
"frame_pts:%s frame_pts_time:%s time_base:%d/%d\n",
|
||||
av_ts2str(frame->pts), av_ts2timestr(frame->pts, &enc->time_base),
|
||||
enc->time_base.num, enc->time_base.den);
|
||||
}
|
||||
if (avcodec_encode_audio2(enc, &pkt, frame, &got_packet) < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Audio encoding failed (avcodec_encode_audio2)\n");
|
||||
exit_program(1);
|
||||
@@ -776,9 +750,7 @@ static void do_subtitle_out(AVFormatContext *s,
|
||||
nb = 1;
|
||||
|
||||
/* shift timestamp to honor -ss and make check_recording_time() work with -t */
|
||||
pts = sub->pts;
|
||||
if (output_files[ost->file_index]->start_time != AV_NOPTS_VALUE)
|
||||
pts -= output_files[ost->file_index]->start_time;
|
||||
pts = sub->pts - output_files[ost->file_index]->start_time;
|
||||
for (i = 0; i < nb; i++) {
|
||||
ost->sync_opts = av_rescale_q(pts, AV_TIME_BASE_Q, enc->time_base);
|
||||
if (!check_recording_time(ost))
|
||||
@@ -842,29 +814,10 @@ static void do_video_out(AVFormatContext *s,
|
||||
nb_frames = 1;
|
||||
|
||||
format_video_sync = video_sync_method;
|
||||
if (format_video_sync == VSYNC_AUTO) {
|
||||
if(!strcmp(s->oformat->name, "avi")) {
|
||||
format_video_sync = VSYNC_VFR;
|
||||
} else
|
||||
format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : VSYNC_VFR) : VSYNC_CFR;
|
||||
if ( ist
|
||||
&& format_video_sync == VSYNC_CFR
|
||||
&& input_files[ist->file_index]->ctx->nb_streams == 1
|
||||
&& input_files[ist->file_index]->input_ts_offset == 0) {
|
||||
format_video_sync = VSYNC_VSCFR;
|
||||
}
|
||||
if (format_video_sync == VSYNC_CFR && copy_ts) {
|
||||
format_video_sync = VSYNC_VSCFR;
|
||||
}
|
||||
}
|
||||
if (format_video_sync == VSYNC_AUTO)
|
||||
format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : VSYNC_VFR) : VSYNC_CFR;
|
||||
|
||||
switch (format_video_sync) {
|
||||
case VSYNC_VSCFR:
|
||||
if (ost->frame_number == 0 && delta - duration >= 0.5) {
|
||||
av_log(NULL, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta - duration));
|
||||
delta = duration;
|
||||
ost->sync_opts = lrint(sync_ipts);
|
||||
}
|
||||
case VSYNC_CFR:
|
||||
// FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
|
||||
if (delta < -1.1)
|
||||
@@ -989,13 +942,6 @@ static void do_video_out(AVFormatContext *s,
|
||||
}
|
||||
|
||||
update_benchmark(NULL);
|
||||
if (debug_ts) {
|
||||
av_log(NULL, AV_LOG_INFO, "encoder <- type:video "
|
||||
"frame_pts:%s frame_pts_time:%s time_base:%d/%d\n",
|
||||
av_ts2str(in_picture->pts), av_ts2timestr(in_picture->pts, &enc->time_base),
|
||||
enc->time_base.num, enc->time_base.den);
|
||||
}
|
||||
|
||||
ret = avcodec_encode_video2(enc, &pkt, in_picture, &got_packet);
|
||||
update_benchmark("encode_video %d.%d", ost->file_index, ost->index);
|
||||
if (ret < 0) {
|
||||
@@ -1004,13 +950,6 @@ static void do_video_out(AVFormatContext *s,
|
||||
}
|
||||
|
||||
if (got_packet) {
|
||||
if (debug_ts) {
|
||||
av_log(NULL, AV_LOG_INFO, "encoder -> type:video "
|
||||
"pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n",
|
||||
av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &enc->time_base),
|
||||
av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &enc->time_base));
|
||||
}
|
||||
|
||||
if (pkt.pts == AV_NOPTS_VALUE && !(enc->codec->capabilities & CODEC_CAP_DELAY))
|
||||
pkt.pts = ost->sync_opts;
|
||||
|
||||
@@ -1107,21 +1046,19 @@ static int reap_filters(void)
|
||||
for (i = 0; i < nb_output_streams; i++) {
|
||||
OutputStream *ost = output_streams[i];
|
||||
OutputFile *of = output_files[ost->file_index];
|
||||
AVFilterContext *filter;
|
||||
AVCodecContext *enc = ost->st->codec;
|
||||
int ret = 0;
|
||||
|
||||
if (!ost->filter)
|
||||
continue;
|
||||
filter = ost->filter->filter;
|
||||
|
||||
if (!ost->filtered_frame && !(ost->filtered_frame = av_frame_alloc())) {
|
||||
if (!ost->filtered_frame && !(ost->filtered_frame = avcodec_alloc_frame())) {
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
} else
|
||||
avcodec_get_frame_defaults(ost->filtered_frame);
|
||||
filtered_frame = ost->filtered_frame;
|
||||
|
||||
while (1) {
|
||||
ret = av_buffersink_get_frame_flags(filter, filtered_frame,
|
||||
ret = av_buffersink_get_frame_flags(ost->filter->filter, filtered_frame,
|
||||
AV_BUFFERSINK_FLAG_NO_REQUEST);
|
||||
if (ret < 0) {
|
||||
if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
|
||||
@@ -1130,38 +1067,31 @@ static int reap_filters(void)
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ost->finished) {
|
||||
av_frame_unref(filtered_frame);
|
||||
continue;
|
||||
}
|
||||
frame_pts = AV_NOPTS_VALUE;
|
||||
if (filtered_frame->pts != AV_NOPTS_VALUE) {
|
||||
int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
|
||||
filtered_frame->pts = frame_pts =
|
||||
av_rescale_q(filtered_frame->pts, filter->inputs[0]->time_base, enc->time_base) -
|
||||
av_rescale_q(start_time, AV_TIME_BASE_Q, enc->time_base);
|
||||
filtered_frame->pts = frame_pts = av_rescale_q(filtered_frame->pts,
|
||||
ost->filter->filter->inputs[0]->time_base,
|
||||
ost->st->codec->time_base) -
|
||||
av_rescale_q(of->start_time,
|
||||
AV_TIME_BASE_Q,
|
||||
ost->st->codec->time_base);
|
||||
}
|
||||
//if (ost->source_index >= 0)
|
||||
// *filtered_frame= *input_streams[ost->source_index]->decoded_frame; //for me_threshold
|
||||
|
||||
switch (filter->inputs[0]->type) {
|
||||
|
||||
switch (ost->filter->filter->inputs[0]->type) {
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
filtered_frame->pts = frame_pts;
|
||||
if (!ost->frame_aspect_ratio.num)
|
||||
enc->sample_aspect_ratio = filtered_frame->sample_aspect_ratio;
|
||||
|
||||
if (debug_ts) {
|
||||
av_log(NULL, AV_LOG_INFO, "filter -> pts:%s pts_time:%s time_base:%d/%d\n",
|
||||
av_ts2str(filtered_frame->pts), av_ts2timestr(filtered_frame->pts, &enc->time_base),
|
||||
enc->time_base.num, enc->time_base.den);
|
||||
}
|
||||
ost->st->codec->sample_aspect_ratio = filtered_frame->sample_aspect_ratio;
|
||||
|
||||
do_video_out(of->ctx, ost, filtered_frame);
|
||||
break;
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
filtered_frame->pts = frame_pts;
|
||||
if (!(enc->codec->capabilities & CODEC_CAP_PARAM_CHANGE) &&
|
||||
enc->channels != av_frame_get_channels(filtered_frame)) {
|
||||
if (!(ost->st->codec->codec->capabilities & CODEC_CAP_PARAM_CHANGE) &&
|
||||
ost->st->codec->channels != av_frame_get_channels(filtered_frame)) {
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"Audio filter graph output is not normalized and encoder does not support parameter changes\n");
|
||||
break;
|
||||
@@ -1342,21 +1272,16 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
||||
}
|
||||
|
||||
if (is_last_report) {
|
||||
int64_t raw = audio_size + video_size + data_size + subtitle_size + extra_size;
|
||||
float percent = 0.0;
|
||||
|
||||
if (raw)
|
||||
percent = 100.0 * (total_size - raw) / raw;
|
||||
|
||||
int64_t raw= audio_size + video_size + subtitle_size + extra_size;
|
||||
av_log(NULL, AV_LOG_INFO, "\n");
|
||||
av_log(NULL, AV_LOG_INFO, "video:%1.0fkB audio:%1.0fkB subtitle:%1.0f data:%1.0f global headers:%1.0fkB muxing overhead %f%%\n",
|
||||
av_log(NULL, AV_LOG_INFO, "video:%1.0fkB audio:%1.0fkB subtitle:%1.0f global headers:%1.0fkB muxing overhead %f%%\n",
|
||||
video_size / 1024.0,
|
||||
audio_size / 1024.0,
|
||||
subtitle_size / 1024.0,
|
||||
data_size / 1024.0,
|
||||
extra_size / 1024.0,
|
||||
percent);
|
||||
if(video_size + data_size + audio_size + subtitle_size + extra_size == 0){
|
||||
100.0 * (total_size - raw) / raw
|
||||
);
|
||||
if(video_size + audio_size + subtitle_size + extra_size == 0){
|
||||
av_log(NULL, AV_LOG_WARNING, "Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)\n");
|
||||
}
|
||||
}
|
||||
@@ -1402,7 +1327,6 @@ static void flush_encoders(void)
|
||||
|
||||
if (encode) {
|
||||
AVPacket pkt;
|
||||
int pkt_size;
|
||||
int got_packet;
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL;
|
||||
@@ -1415,6 +1339,7 @@ static void flush_encoders(void)
|
||||
av_log(NULL, AV_LOG_FATAL, "%s encoding failed\n", desc);
|
||||
exit_program(1);
|
||||
}
|
||||
*size += pkt.size;
|
||||
if (ost->logfile && enc->stats_out) {
|
||||
fprintf(ost->logfile, "%s", enc->stats_out);
|
||||
}
|
||||
@@ -1422,21 +1347,15 @@ static void flush_encoders(void)
|
||||
stop_encoding = 1;
|
||||
break;
|
||||
}
|
||||
if (ost->finished & MUXER_FINISHED) {
|
||||
av_free_packet(&pkt);
|
||||
continue;
|
||||
}
|
||||
*size += pkt.size;
|
||||
if (pkt.pts != AV_NOPTS_VALUE)
|
||||
pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base);
|
||||
if (pkt.dts != AV_NOPTS_VALUE)
|
||||
pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base);
|
||||
if (pkt.duration > 0)
|
||||
pkt.duration = av_rescale_q(pkt.duration, enc->time_base, ost->st->time_base);
|
||||
pkt_size = pkt.size;
|
||||
write_frame(os, &pkt, ost);
|
||||
if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && vstats_filename) {
|
||||
do_video_stats(ost, pkt_size);
|
||||
do_video_stats(ost, pkt.size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1457,10 +1376,7 @@ static int check_output_constraints(InputStream *ist, OutputStream *ost)
|
||||
if (ost->source_index != ist_index)
|
||||
return 0;
|
||||
|
||||
if (ost->finished)
|
||||
return 0;
|
||||
|
||||
if (of->start_time != AV_NOPTS_VALUE && ist->pts < of->start_time)
|
||||
if (of->start_time && ist->pts < of->start_time)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@@ -1469,10 +1385,8 @@ static int check_output_constraints(InputStream *ist, OutputStream *ost)
|
||||
static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *pkt)
|
||||
{
|
||||
OutputFile *of = output_files[ost->file_index];
|
||||
InputFile *f = input_files [ist->file_index];
|
||||
int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
|
||||
int64_t ost_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ost->st->time_base);
|
||||
int64_t ist_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ist->st->time_base);
|
||||
int64_t ost_tb_start_time = av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base);
|
||||
int64_t ist_tb_start_time = av_rescale_q(of->start_time, AV_TIME_BASE_Q, ist->st->time_base);
|
||||
AVPicture pict;
|
||||
AVPacket opkt;
|
||||
|
||||
@@ -1483,7 +1397,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
|
||||
return;
|
||||
|
||||
if (pkt->pts == AV_NOPTS_VALUE) {
|
||||
if (!ost->frame_number && ist->pts < start_time &&
|
||||
if (!ost->frame_number && ist->pts < of->start_time &&
|
||||
!ost->copy_prior_start)
|
||||
return;
|
||||
} else {
|
||||
@@ -1493,29 +1407,17 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
|
||||
}
|
||||
|
||||
if (of->recording_time != INT64_MAX &&
|
||||
ist->pts >= of->recording_time + start_time) {
|
||||
ist->pts >= of->recording_time + of->start_time) {
|
||||
close_output_stream(ost);
|
||||
return;
|
||||
}
|
||||
|
||||
if (f->recording_time != INT64_MAX) {
|
||||
start_time = f->ctx->start_time;
|
||||
if (f->start_time != AV_NOPTS_VALUE)
|
||||
start_time += f->start_time;
|
||||
if (ist->pts >= f->recording_time + start_time) {
|
||||
close_output_stream(ost);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* force the input stream PTS */
|
||||
if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
|
||||
audio_size += pkt->size;
|
||||
else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
video_size += pkt->size;
|
||||
ost->sync_opts++;
|
||||
} else if (ost->st->codec->codec_type == AVMEDIA_TYPE_DATA) {
|
||||
data_size += pkt->size;
|
||||
} else if (ost->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
|
||||
subtitle_size += pkt->size;
|
||||
}
|
||||
@@ -1549,10 +1451,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
|
||||
&& ost->st->codec->codec_id != AV_CODEC_ID_MPEG2VIDEO
|
||||
&& ost->st->codec->codec_id != AV_CODEC_ID_VC1
|
||||
) {
|
||||
if (av_parser_change(ost->parser, ost->st->codec,
|
||||
&opkt.data, &opkt.size,
|
||||
pkt->data, pkt->size,
|
||||
pkt->flags & AV_PKT_FLAG_KEY)) {
|
||||
if (av_parser_change(av_stream_get_parser(ist->st), ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY)) {
|
||||
opkt.buf = av_buffer_create(opkt.data, opkt.size, av_buffer_default_free, NULL, 0);
|
||||
if (!opkt.buf)
|
||||
exit_program(1);
|
||||
@@ -1561,7 +1460,6 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
|
||||
opkt.data = pkt->data;
|
||||
opkt.size = pkt->size;
|
||||
}
|
||||
av_copy_packet_side_data(&opkt, pkt);
|
||||
|
||||
if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (of->ctx->oformat->flags & AVFMT_RAWPICTURE)) {
|
||||
/* store AVPicture in AVPacket, as expected by the output format */
|
||||
@@ -1602,7 +1500,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
|
||||
int i, ret, err = 0, resample_changed;
|
||||
AVRational decoded_frame_tb;
|
||||
|
||||
if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc()))
|
||||
if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
|
||||
return AVERROR(ENOMEM);
|
||||
if (!ist->filter_frame && !(ist->filter_frame = av_frame_alloc()))
|
||||
return AVERROR(ENOMEM);
|
||||
@@ -1738,6 +1636,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
|
||||
static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
|
||||
{
|
||||
AVFrame *decoded_frame, *f;
|
||||
void *buffer_to_free = NULL;
|
||||
int i, ret = 0, err = 0, resample_changed;
|
||||
int64_t best_effort_timestamp;
|
||||
AVRational *frame_sample_aspect;
|
||||
@@ -1772,26 +1671,18 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
|
||||
if(ist->top_field_first>=0)
|
||||
decoded_frame->top_field_first = ist->top_field_first;
|
||||
|
||||
if (ist->hwaccel_retrieve_data && decoded_frame->format == ist->hwaccel_pix_fmt) {
|
||||
err = ist->hwaccel_retrieve_data(ist->st->codec, decoded_frame);
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
}
|
||||
ist->hwaccel_retrieved_pix_fmt = decoded_frame->format;
|
||||
|
||||
best_effort_timestamp= av_frame_get_best_effort_timestamp(decoded_frame);
|
||||
if(best_effort_timestamp != AV_NOPTS_VALUE)
|
||||
ist->next_pts = ist->pts = av_rescale_q(decoded_frame->pts = best_effort_timestamp, ist->st->time_base, AV_TIME_BASE_Q);
|
||||
|
||||
if (debug_ts) {
|
||||
av_log(NULL, AV_LOG_INFO, "decoder -> ist_index:%d type:video "
|
||||
"frame_pts:%s frame_pts_time:%s best_effort_ts:%"PRId64" best_effort_ts_time:%s keyframe:%d frame_type:%d time_base:%d/%d\n",
|
||||
ist->st->index, av_ts2str(decoded_frame->pts),
|
||||
av_ts2timestr(decoded_frame->pts, &ist->st->time_base),
|
||||
best_effort_timestamp,
|
||||
av_ts2timestr(best_effort_timestamp, &ist->st->time_base),
|
||||
decoded_frame->key_frame, decoded_frame->pict_type,
|
||||
ist->st->time_base.num, ist->st->time_base.den);
|
||||
"frame_pts:%s frame_pts_time:%s best_effort_ts:%"PRId64" best_effort_ts_time:%s keyframe:%d frame_type:%d \n",
|
||||
ist->st->index, av_ts2str(decoded_frame->pts),
|
||||
av_ts2timestr(decoded_frame->pts, &ist->st->time_base),
|
||||
best_effort_timestamp,
|
||||
av_ts2timestr(best_effort_timestamp, &ist->st->time_base),
|
||||
decoded_frame->key_frame, decoded_frame->pict_type);
|
||||
}
|
||||
|
||||
pkt->size = 0;
|
||||
@@ -1844,9 +1735,9 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
av_frame_unref(ist->filter_frame);
|
||||
av_frame_unref(decoded_frame);
|
||||
av_free(buffer_to_free);
|
||||
return err < 0 ? err : ret;
|
||||
}
|
||||
|
||||
@@ -1866,32 +1757,25 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
|
||||
}
|
||||
|
||||
if (ist->fix_sub_duration) {
|
||||
int end = 1;
|
||||
if (ist->prev_sub.got_output) {
|
||||
end = av_rescale(subtitle.pts - ist->prev_sub.subtitle.pts,
|
||||
1000, AV_TIME_BASE);
|
||||
int end = av_rescale(subtitle.pts - ist->prev_sub.subtitle.pts,
|
||||
1000, AV_TIME_BASE);
|
||||
if (end < ist->prev_sub.subtitle.end_display_time) {
|
||||
av_log(ist->st->codec, AV_LOG_DEBUG,
|
||||
"Subtitle duration reduced from %d to %d%s\n",
|
||||
ist->prev_sub.subtitle.end_display_time, end,
|
||||
end <= 0 ? ", dropping it" : "");
|
||||
"Subtitle duration reduced from %d to %d\n",
|
||||
ist->prev_sub.subtitle.end_display_time, end);
|
||||
ist->prev_sub.subtitle.end_display_time = end;
|
||||
}
|
||||
}
|
||||
FFSWAP(int, *got_output, ist->prev_sub.got_output);
|
||||
FFSWAP(int, ret, ist->prev_sub.ret);
|
||||
FFSWAP(AVSubtitle, subtitle, ist->prev_sub.subtitle);
|
||||
if (end <= 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!*got_output)
|
||||
return ret;
|
||||
|
||||
sub2video_update(ist, &subtitle);
|
||||
|
||||
if (!subtitle.num_rects)
|
||||
goto out;
|
||||
if (!*got_output || !subtitle.num_rects)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < nb_output_streams; i++) {
|
||||
OutputStream *ost = output_streams[i];
|
||||
@@ -1902,7 +1786,6 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
|
||||
do_subtitle_out(output_files[ost->file_index]->ctx, ost, ist, &subtitle);
|
||||
}
|
||||
|
||||
out:
|
||||
avsubtitle_free(&subtitle);
|
||||
return ret;
|
||||
}
|
||||
@@ -1968,7 +1851,7 @@ static int output_packet(InputStream *ist, const AVPacket *pkt)
|
||||
if (avpkt.duration) {
|
||||
duration = av_rescale_q(avpkt.duration, ist->st->time_base, AV_TIME_BASE_Q);
|
||||
} else if(ist->st->codec->time_base.num != 0 && ist->st->codec->time_base.den != 0) {
|
||||
int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame;
|
||||
int ticks= av_stream_get_parser(ist->st) ? av_stream_get_parser(ist->st)->repeat_pict+1 : ist->st->codec->ticks_per_frame;
|
||||
duration = ((int64_t)AV_TIME_BASE *
|
||||
ist->st->codec->time_base.num * ticks) /
|
||||
ist->st->codec->time_base.den;
|
||||
@@ -2025,7 +1908,7 @@ static int output_packet(InputStream *ist, const AVPacket *pkt)
|
||||
} else if (pkt->duration) {
|
||||
ist->next_dts += av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);
|
||||
} else if(ist->st->codec->time_base.num != 0) {
|
||||
int ticks= ist->st->parser ? ist->st->parser->repeat_pict + 1 : ist->st->codec->ticks_per_frame;
|
||||
int ticks= av_stream_get_parser(ist->st) ? av_stream_get_parser(ist->st)->repeat_pict + 1 : ist->st->codec->ticks_per_frame;
|
||||
ist->next_dts += ((int64_t)AV_TIME_BASE *
|
||||
ist->st->codec->time_base.num * ticks) /
|
||||
ist->st->codec->time_base.den;
|
||||
@@ -2064,63 +1947,6 @@ static void print_sdp(void)
|
||||
av_freep(&avc);
|
||||
}
|
||||
|
||||
static const HWAccel *get_hwaccel(enum AVPixelFormat pix_fmt)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; hwaccels[i].name; i++)
|
||||
if (hwaccels[i].pix_fmt == pix_fmt)
|
||||
return &hwaccels[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
const enum AVPixelFormat *p;
|
||||
int ret;
|
||||
|
||||
for (p = pix_fmts; *p != -1; p++) {
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p);
|
||||
const HWAccel *hwaccel;
|
||||
|
||||
if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
|
||||
break;
|
||||
|
||||
hwaccel = get_hwaccel(*p);
|
||||
if (!hwaccel ||
|
||||
(ist->active_hwaccel_id && ist->active_hwaccel_id != hwaccel->id) ||
|
||||
(ist->hwaccel_id != HWACCEL_AUTO && ist->hwaccel_id != hwaccel->id))
|
||||
continue;
|
||||
|
||||
ret = hwaccel->init(s);
|
||||
if (ret < 0) {
|
||||
if (ist->hwaccel_id == hwaccel->id) {
|
||||
av_log(NULL, AV_LOG_FATAL,
|
||||
"%s hwaccel requested for input stream #%d:%d, "
|
||||
"but cannot be initialized.\n", hwaccel->name,
|
||||
ist->file_index, ist->st->index);
|
||||
exit_program(1);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
ist->active_hwaccel_id = hwaccel->id;
|
||||
ist->hwaccel_pix_fmt = *p;
|
||||
break;
|
||||
}
|
||||
|
||||
return *p;
|
||||
}
|
||||
|
||||
static int get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
|
||||
if (ist->hwaccel_get_buffer && frame->format == ist->hwaccel_pix_fmt)
|
||||
return ist->hwaccel_get_buffer(s, frame, flags);
|
||||
|
||||
return avcodec_default_get_buffer2(s, frame, flags);
|
||||
}
|
||||
|
||||
static int init_input_stream(int ist_index, char *error, int error_len)
|
||||
{
|
||||
int ret;
|
||||
@@ -2134,23 +1960,21 @@ static int init_input_stream(int ist_index, char *error, int error_len)
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
ist->st->codec->opaque = ist;
|
||||
ist->st->codec->get_format = get_format;
|
||||
ist->st->codec->get_buffer2 = get_buffer;
|
||||
ist->st->codec->thread_safe_callbacks = 1;
|
||||
|
||||
av_opt_set_int(ist->st->codec, "refcounted_frames", 1, 0);
|
||||
|
||||
if (!av_dict_get(ist->opts, "threads", NULL, 0))
|
||||
av_dict_set(&ist->opts, "threads", "auto", 0);
|
||||
if ((ret = avcodec_open2(ist->st->codec, codec, &ist->opts)) < 0) {
|
||||
char errbuf[128];
|
||||
if (ret == AVERROR_EXPERIMENTAL)
|
||||
abort_codec_experimental(codec, 0);
|
||||
|
||||
av_strerror(ret, errbuf, sizeof(errbuf));
|
||||
|
||||
snprintf(error, error_len,
|
||||
"Error while opening decoder for input stream "
|
||||
"#%d:%d : %s",
|
||||
ist->file_index, ist->st->index, av_err2str(ret));
|
||||
ist->file_index, ist->st->index, errbuf);
|
||||
return ret;
|
||||
}
|
||||
assert_avoptions(ist->opts);
|
||||
@@ -2158,6 +1982,7 @@ static int init_input_stream(int ist_index, char *error, int error_len)
|
||||
|
||||
ist->next_pts = AV_NOPTS_VALUE;
|
||||
ist->next_dts = AV_NOPTS_VALUE;
|
||||
ist->is_start = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2260,24 +2085,9 @@ static int transcode_init(void)
|
||||
AVCodecContext *codec;
|
||||
OutputStream *ost;
|
||||
InputStream *ist;
|
||||
char error[1024];
|
||||
char error[1024] = {0};
|
||||
int want_sdp = 1;
|
||||
|
||||
for (i = 0; i < nb_filtergraphs; i++) {
|
||||
FilterGraph *fg = filtergraphs[i];
|
||||
for (j = 0; j < fg->nb_outputs; j++) {
|
||||
OutputFilter *ofilter = fg->outputs[j];
|
||||
if (!ofilter->ost || ofilter->ost->source_index >= 0)
|
||||
continue;
|
||||
if (fg->nb_inputs != 1)
|
||||
continue;
|
||||
for (k = nb_input_streams-1; k >= 0 ; k--)
|
||||
if (fg->inputs[0]->ist == input_streams[k])
|
||||
break;
|
||||
ofilter->ost->source_index = k;
|
||||
}
|
||||
}
|
||||
|
||||
/* init framerate emulation */
|
||||
for (i = 0; i < nb_input_files; i++) {
|
||||
InputFile *ifile = input_files[i];
|
||||
@@ -2319,15 +2129,6 @@ static int transcode_init(void)
|
||||
ost->st->disposition = ist->st->disposition;
|
||||
codec->bits_per_raw_sample = icodec->bits_per_raw_sample;
|
||||
codec->chroma_sample_location = icodec->chroma_sample_location;
|
||||
} else {
|
||||
for (j=0; j<oc->nb_streams; j++) {
|
||||
AVStream *st = oc->streams[j];
|
||||
if (st != ost->st && st->codec->codec_type == codec->codec_type)
|
||||
break;
|
||||
}
|
||||
if (j == oc->nb_streams)
|
||||
if (codec->codec_type == AVMEDIA_TYPE_AUDIO || codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
ost->st->disposition = AV_DISPOSITION_DEFAULT;
|
||||
}
|
||||
|
||||
if (ost->stream_copy) {
|
||||
@@ -2417,8 +2218,6 @@ static int transcode_init(void)
|
||||
av_reduce(&codec->time_base.num, &codec->time_base.den,
|
||||
codec->time_base.num, codec->time_base.den, INT_MAX);
|
||||
|
||||
ost->parser = av_parser_init(codec->codec_id);
|
||||
|
||||
switch (codec->codec_type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
if (audio_volume != 256) {
|
||||
@@ -2431,7 +2230,6 @@ static int transcode_init(void)
|
||||
codec->frame_size = icodec->frame_size;
|
||||
codec->audio_service_type = icodec->audio_service_type;
|
||||
codec->block_align = icodec->block_align;
|
||||
codec->delay = icodec->delay;
|
||||
if((codec->block_align == 1 || codec->block_align == 1152 || codec->block_align == 576) && codec->codec_id == AV_CODEC_ID_MP3)
|
||||
codec->block_align= 0;
|
||||
if(codec->codec_id == AV_CODEC_ID_AC3)
|
||||
@@ -2498,25 +2296,12 @@ static int transcode_init(void)
|
||||
if (ist && !ost->frame_rate.num)
|
||||
ost->frame_rate = ist->framerate;
|
||||
if (ist && !ost->frame_rate.num)
|
||||
ost->frame_rate = ist->st->r_frame_rate;
|
||||
if (ist && !ost->frame_rate.num) {
|
||||
ost->frame_rate = (AVRational){25, 1};
|
||||
av_log(NULL, AV_LOG_WARNING,
|
||||
"No information "
|
||||
"about the input framerate is available. Falling "
|
||||
"back to a default value of 25fps for output stream #%d:%d. Use the -r option "
|
||||
"if you want a different framerate.\n",
|
||||
ost->file_index, ost->index);
|
||||
}
|
||||
ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25, 1};
|
||||
// ost->frame_rate = ist->st->avg_frame_rate.num ? ist->st->avg_frame_rate : (AVRational){25, 1};
|
||||
if (ost->enc && ost->enc->supported_framerates && !ost->force_fps) {
|
||||
int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);
|
||||
ost->frame_rate = ost->enc->supported_framerates[idx];
|
||||
}
|
||||
if (codec->codec_id == AV_CODEC_ID_MPEG4) {
|
||||
av_reduce(&ost->frame_rate.num, &ost->frame_rate.den,
|
||||
ost->frame_rate.num, ost->frame_rate.den, 65535);
|
||||
}
|
||||
}
|
||||
|
||||
switch (codec->codec_type) {
|
||||
@@ -2532,7 +2317,7 @@ static int transcode_init(void)
|
||||
if (ost->filter && !(codec->time_base.num && codec->time_base.den))
|
||||
codec->time_base = ost->filter->filter->inputs[0]->time_base;
|
||||
if ( av_q2d(codec->time_base) < 0.001 && video_sync_method != VSYNC_PASSTHROUGH
|
||||
&& (video_sync_method == VSYNC_CFR || video_sync_method == VSYNC_VSCFR || (video_sync_method == VSYNC_AUTO && !(oc->oformat->flags & AVFMT_VARIABLE_FPS)))){
|
||||
&& (video_sync_method == VSYNC_CFR || (video_sync_method == VSYNC_AUTO && !(oc->oformat->flags & AVFMT_VARIABLE_FPS)))){
|
||||
av_log(oc, AV_LOG_WARNING, "Frame rate very high for a muxer not efficiently supporting it.\n"
|
||||
"Please consider specifying a lower framerate, a different muxer or -vsync 2\n");
|
||||
}
|
||||
@@ -2550,17 +2335,10 @@ static int transcode_init(void)
|
||||
if (!strncmp(ost->enc->name, "libx264", 7) &&
|
||||
codec->pix_fmt == AV_PIX_FMT_NONE &&
|
||||
ost->filter->filter->inputs[0]->format != AV_PIX_FMT_YUV420P)
|
||||
av_log(NULL, AV_LOG_WARNING,
|
||||
av_log(NULL, AV_LOG_INFO,
|
||||
"No pixel format specified, %s for H.264 encoding chosen.\n"
|
||||
"Use -pix_fmt yuv420p for compatibility with outdated media players.\n",
|
||||
av_get_pix_fmt_name(ost->filter->filter->inputs[0]->format));
|
||||
if (!strncmp(ost->enc->name, "mpeg2video", 10) &&
|
||||
codec->pix_fmt == AV_PIX_FMT_NONE &&
|
||||
ost->filter->filter->inputs[0]->format != AV_PIX_FMT_YUV420P)
|
||||
av_log(NULL, AV_LOG_WARNING,
|
||||
"No pixel format specified, %s for MPEG-2 encoding chosen.\n"
|
||||
"Use -pix_fmt yuv420p for compatibility with outdated media players.\n",
|
||||
av_get_pix_fmt_name(ost->filter->filter->inputs[0]->format));
|
||||
codec->pix_fmt = ost->filter->filter->inputs[0]->format;
|
||||
|
||||
if (!icodec ||
|
||||
@@ -2622,7 +2400,7 @@ static int transcode_init(void)
|
||||
codec->stats_in = logbuffer;
|
||||
}
|
||||
if (codec->flags & CODEC_FLAG_PASS1) {
|
||||
f = av_fopen_utf8(logfilename, "wb");
|
||||
f = fopen(logfilename, "wb");
|
||||
if (!f) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n",
|
||||
logfilename, strerror(errno));
|
||||
@@ -2672,6 +2450,9 @@ static int transcode_init(void)
|
||||
av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
|
||||
" It takes bits/s as argument, not kbits/s\n");
|
||||
extra_size += ost->st->codec->extradata_size;
|
||||
|
||||
if (ost->st->codec->me_threshold)
|
||||
input_streams[ost->source_index]->st->codec->debug |= FF_DEBUG_MV;
|
||||
} else {
|
||||
av_opt_set_dict(ost->st->codec, &ost->opts);
|
||||
}
|
||||
@@ -2708,10 +2489,12 @@ static int transcode_init(void)
|
||||
oc = output_files[i]->ctx;
|
||||
oc->interrupt_callback = int_cb;
|
||||
if ((ret = avformat_write_header(oc, &output_files[i]->opts)) < 0) {
|
||||
char errbuf[128];
|
||||
av_strerror(ret, errbuf, sizeof(errbuf));
|
||||
snprintf(error, sizeof(error),
|
||||
"Could not write header for output file #%d "
|
||||
"(incorrect codec parameters ?): %s",
|
||||
i, av_err2str(ret));
|
||||
i, errbuf);
|
||||
ret = AVERROR(EINVAL);
|
||||
goto dump_format;
|
||||
}
|
||||
@@ -2875,7 +2658,7 @@ static int check_keyboard_interaction(int64_t cur_time)
|
||||
char buf[4096], target[64], command[256], arg[256] = {0};
|
||||
double time;
|
||||
int k, n = 0;
|
||||
fprintf(stderr, "\nEnter command: <target>|all <time>|-1 <command>[ <argument>]\n");
|
||||
fprintf(stderr, "\nEnter command: <target> <time> <command>[ <argument>]\n");
|
||||
i = 0;
|
||||
while ((k = read_key()) != '\n' && k != '\r' && i < sizeof(buf)-1)
|
||||
if (k > 0)
|
||||
@@ -2891,10 +2674,7 @@ static int check_keyboard_interaction(int64_t cur_time)
|
||||
if (time < 0) {
|
||||
ret = avfilter_graph_send_command(fg->graph, target, command, arg, buf, sizeof(buf),
|
||||
key == 'c' ? AVFILTER_CMD_FLAG_ONE : 0);
|
||||
fprintf(stderr, "Command reply for stream %d: ret:%d res:\n%s", i, ret, buf);
|
||||
} else if (key == 'c') {
|
||||
fprintf(stderr, "Queing commands only on filters supporting the specific command is unsupported\n");
|
||||
ret = AVERROR_PATCHWELCOME;
|
||||
fprintf(stderr, "Command reply for stream %d: ret:%d res:%s\n", i, ret, buf);
|
||||
} else {
|
||||
ret = avfilter_graph_queue_command(fg->graph, target, command, arg, 0, time);
|
||||
}
|
||||
@@ -2931,8 +2711,7 @@ static int check_keyboard_interaction(int64_t cur_time)
|
||||
"? show this help\n"
|
||||
"+ increase verbosity\n"
|
||||
"- decrease verbosity\n"
|
||||
"c Send command to first matching filter supporting it\n"
|
||||
"C Send/Que command to all matching filters\n"
|
||||
"c Send command to filtergraph\n"
|
||||
"D cycle through available debug modes\n"
|
||||
"h dump packets/hex press to cycle through the 3 states\n"
|
||||
"q quit\n"
|
||||
@@ -2965,15 +2744,11 @@ static void *input_thread(void *arg)
|
||||
|
||||
av_dup_packet(&pkt);
|
||||
av_fifo_generic_write(f->fifo, &pkt, sizeof(pkt), NULL);
|
||||
pthread_cond_signal(&f->fifo_cond);
|
||||
|
||||
pthread_mutex_unlock(&f->fifo_lock);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&f->fifo_lock);
|
||||
f->finished = 1;
|
||||
pthread_cond_signal(&f->fifo_cond);
|
||||
pthread_mutex_unlock(&f->fifo_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3025,10 +2800,6 @@ static int init_input_threads(void)
|
||||
if (!(f->fifo = av_fifo_alloc(8*sizeof(AVPacket))))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if (f->ctx->pb ? !f->ctx->pb->seekable :
|
||||
strcmp(f->ctx->iformat->name, "lavfi"))
|
||||
f->non_blocking = 1;
|
||||
|
||||
pthread_mutex_init(&f->fifo_lock, NULL);
|
||||
pthread_cond_init (&f->fifo_cond, NULL);
|
||||
|
||||
@@ -3044,22 +2815,14 @@ static int get_input_packet_mt(InputFile *f, AVPacket *pkt)
|
||||
|
||||
pthread_mutex_lock(&f->fifo_lock);
|
||||
|
||||
while (1) {
|
||||
if (av_fifo_size(f->fifo)) {
|
||||
av_fifo_generic_read(f->fifo, pkt, sizeof(*pkt), NULL);
|
||||
pthread_cond_signal(&f->fifo_cond);
|
||||
break;
|
||||
} else {
|
||||
if (f->finished) {
|
||||
if (f->finished)
|
||||
ret = AVERROR_EOF;
|
||||
break;
|
||||
}
|
||||
if (f->non_blocking) {
|
||||
else
|
||||
ret = AVERROR(EAGAIN);
|
||||
break;
|
||||
}
|
||||
pthread_cond_wait(&f->fifo_cond, &f->fifo_lock);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&f->fifo_lock);
|
||||
@@ -3250,21 +3013,22 @@ static int process_input(int file_index)
|
||||
int64_t pkt_dts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);
|
||||
int64_t delta = pkt_dts - ist->next_dts;
|
||||
if (is->iformat->flags & AVFMT_TS_DISCONT) {
|
||||
if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
|
||||
(delta > 1LL*dts_delta_threshold*AV_TIME_BASE &&
|
||||
ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) ||
|
||||
pkt_dts + AV_TIME_BASE/10 < FFMAX(ist->pts, ist->dts)) {
|
||||
ifile->ts_offset -= delta;
|
||||
av_log(NULL, AV_LOG_DEBUG,
|
||||
"timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",
|
||||
delta, ifile->ts_offset);
|
||||
pkt.dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
|
||||
if (pkt.pts != AV_NOPTS_VALUE)
|
||||
pkt.pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
|
||||
}
|
||||
if(delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
|
||||
(delta > 1LL*dts_delta_threshold*AV_TIME_BASE &&
|
||||
ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) ||
|
||||
pkt_dts+1<ist->pts){
|
||||
ifile->ts_offset -= delta;
|
||||
av_log(NULL, AV_LOG_DEBUG,
|
||||
"timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",
|
||||
delta, ifile->ts_offset);
|
||||
pkt.dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
|
||||
if (pkt.pts != AV_NOPTS_VALUE)
|
||||
pkt.pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
|
||||
}
|
||||
} else {
|
||||
if ( delta < -1LL*dts_error_threshold*AV_TIME_BASE ||
|
||||
(delta > 1LL*dts_error_threshold*AV_TIME_BASE && ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE)) {
|
||||
(delta > 1LL*dts_error_threshold*AV_TIME_BASE && ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE)
|
||||
) {
|
||||
av_log(NULL, AV_LOG_WARNING, "DTS %"PRId64", next:%"PRId64" st:%d invalid dropping\n", pkt.dts, ist->next_dts, pkt.stream_index);
|
||||
pkt.dts = AV_NOPTS_VALUE;
|
||||
}
|
||||
@@ -3272,7 +3036,8 @@ static int process_input(int file_index)
|
||||
int64_t pkt_pts = av_rescale_q(pkt.pts, ist->st->time_base, AV_TIME_BASE_Q);
|
||||
delta = pkt_pts - ist->next_dts;
|
||||
if ( delta < -1LL*dts_error_threshold*AV_TIME_BASE ||
|
||||
(delta > 1LL*dts_error_threshold*AV_TIME_BASE && ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE)) {
|
||||
(delta > 1LL*dts_error_threshold*AV_TIME_BASE && ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE)
|
||||
) {
|
||||
av_log(NULL, AV_LOG_WARNING, "PTS %"PRId64", next:%"PRId64" invalid dropping st:%d\n", pkt.pts, ist->next_dts, pkt.stream_index);
|
||||
pkt.pts = AV_NOPTS_VALUE;
|
||||
}
|
||||
@@ -3296,8 +3061,10 @@ static int process_input(int file_index)
|
||||
|
||||
ret = output_packet(ist, &pkt);
|
||||
if (ret < 0) {
|
||||
char buf[128];
|
||||
av_strerror(ret, buf, sizeof(buf));
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d: %s\n",
|
||||
ist->file_index, ist->st->index, av_err2str(ret));
|
||||
ist->file_index, ist->st->index, buf);
|
||||
if (exit_on_error)
|
||||
exit_program(1);
|
||||
}
|
||||
@@ -3490,8 +3257,6 @@ static int transcode(void)
|
||||
ist = input_streams[i];
|
||||
if (ist->decoding_needed) {
|
||||
avcodec_close(ist->st->codec);
|
||||
if (ist->hwaccel_uninit)
|
||||
ist->hwaccel_uninit(ist->st->codec);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3628,9 +3393,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
av_log(NULL, AV_LOG_DEBUG, "%"PRIu64" frames successfully decoded, %"PRIu64" decoding errors\n",
|
||||
decode_error_stat[0], decode_error_stat[1]);
|
||||
if ((decode_error_stat[0] + decode_error_stat[1]) * max_error_rate < decode_error_stat[1])
|
||||
exit_program(69);
|
||||
if (2*decode_error_stat[0] < decode_error_stat[1])
|
||||
exit_program(254);
|
||||
|
||||
exit_program(received_nb_signals ? 255 : main_return_code);
|
||||
return main_return_code;
|
||||
exit_program(received_nb_signals ? 255 : 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
56
ffmpeg.h
56
ffmpeg.h
@@ -51,24 +51,10 @@
|
||||
#define VSYNC_PASSTHROUGH 0
|
||||
#define VSYNC_CFR 1
|
||||
#define VSYNC_VFR 2
|
||||
#define VSYNC_VSCFR 0xfe
|
||||
#define VSYNC_DROP 0xff
|
||||
|
||||
#define MAX_STREAMS 1024 /* arbitrary sanity check value */
|
||||
|
||||
enum HWAccelID {
|
||||
HWACCEL_NONE = 0,
|
||||
HWACCEL_AUTO,
|
||||
HWACCEL_VDPAU,
|
||||
};
|
||||
|
||||
typedef struct HWAccel {
|
||||
const char *name;
|
||||
int (*init)(AVCodecContext *s);
|
||||
enum HWAccelID id;
|
||||
enum AVPixelFormat pix_fmt;
|
||||
} HWAccel;
|
||||
|
||||
/* select an input stream for an output stream */
|
||||
typedef struct StreamMap {
|
||||
int disabled; /* 1 is this mapping is disabled by a negative map */
|
||||
@@ -107,16 +93,11 @@ typedef struct OptionsContext {
|
||||
/* input options */
|
||||
int64_t input_ts_offset;
|
||||
int rate_emu;
|
||||
int accurate_seek;
|
||||
|
||||
SpecifierOpt *ts_scale;
|
||||
int nb_ts_scale;
|
||||
SpecifierOpt *dump_attachment;
|
||||
int nb_dump_attachment;
|
||||
SpecifierOpt *hwaccels;
|
||||
int nb_hwaccels;
|
||||
SpecifierOpt *hwaccel_devices;
|
||||
int nb_hwaccel_devices;
|
||||
|
||||
/* output options */
|
||||
StreamMap *stream_maps;
|
||||
@@ -171,8 +152,6 @@ typedef struct OptionsContext {
|
||||
int nb_intra_matrices;
|
||||
SpecifierOpt *inter_matrices;
|
||||
int nb_inter_matrices;
|
||||
SpecifierOpt *chroma_intra_matrices;
|
||||
int nb_chroma_intra_matrices;
|
||||
SpecifierOpt *top_field_first;
|
||||
int nb_top_field_first;
|
||||
SpecifierOpt *metadata_map;
|
||||
@@ -255,6 +234,7 @@ typedef struct InputStream {
|
||||
int64_t filter_in_rescale_delta_last;
|
||||
|
||||
double ts_scale;
|
||||
int is_start; /* is 1 at the start and after a discontinuity */
|
||||
int saw_first_ts;
|
||||
int showed_multi_packet_warning;
|
||||
AVDictionary *opts;
|
||||
@@ -293,19 +273,6 @@ typedef struct InputStream {
|
||||
int nb_filters;
|
||||
|
||||
int reinit_filters;
|
||||
|
||||
/* hwaccel options */
|
||||
enum HWAccelID hwaccel_id;
|
||||
char *hwaccel_device;
|
||||
|
||||
/* hwaccel context */
|
||||
enum HWAccelID active_hwaccel_id;
|
||||
void *hwaccel_ctx;
|
||||
void (*hwaccel_uninit)(AVCodecContext *s);
|
||||
int (*hwaccel_get_buffer)(AVCodecContext *s, AVFrame *frame, int flags);
|
||||
int (*hwaccel_retrieve_data)(AVCodecContext *s, AVFrame *frame);
|
||||
enum AVPixelFormat hwaccel_pix_fmt;
|
||||
enum AVPixelFormat hwaccel_retrieved_pix_fmt;
|
||||
} InputStream;
|
||||
|
||||
typedef struct InputFile {
|
||||
@@ -313,20 +280,15 @@ typedef struct InputFile {
|
||||
int eof_reached; /* true if eof reached */
|
||||
int eagain; /* true if last read attempt returned EAGAIN */
|
||||
int ist_index; /* index of first stream in input_streams */
|
||||
int64_t input_ts_offset;
|
||||
int64_t ts_offset;
|
||||
int64_t last_ts;
|
||||
int64_t start_time; /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */
|
||||
int64_t recording_time;
|
||||
int nb_streams; /* number of stream that ffmpeg is aware of; may be different
|
||||
from ctx.nb_streams if new streams appear during av_read_frame() */
|
||||
int nb_streams_warn; /* number of streams that the user was warned of */
|
||||
int rate_emu;
|
||||
int accurate_seek;
|
||||
|
||||
#if HAVE_PTHREADS
|
||||
pthread_t thread; /* thread reading from this file */
|
||||
int non_blocking; /* reading packets from the thread should not block */
|
||||
int finished; /* the thread has exited */
|
||||
int joined; /* the thread has been joined */
|
||||
pthread_mutex_t fifo_lock; /* lock for access to fifo */
|
||||
@@ -346,11 +308,6 @@ enum forced_keyframes_const {
|
||||
|
||||
extern const char *const forced_keyframes_const_names[];
|
||||
|
||||
typedef enum {
|
||||
ENCODER_FINISHED = 1,
|
||||
MUXER_FINISHED = 2,
|
||||
} OSTFinished ;
|
||||
|
||||
typedef struct OutputStream {
|
||||
int file_index; /* file index */
|
||||
int index; /* stream index in the output file */
|
||||
@@ -396,15 +353,13 @@ typedef struct OutputStream {
|
||||
|
||||
OutputFilter *filter;
|
||||
char *avfilter;
|
||||
char *filters; ///< filtergraph associated to the -filter option
|
||||
char *filters_script; ///< filtergraph script associated to the -filter_script option
|
||||
|
||||
int64_t sws_flags;
|
||||
AVDictionary *opts;
|
||||
AVDictionary *swr_opts;
|
||||
AVDictionary *resample_opts;
|
||||
char *apad;
|
||||
OSTFinished finished; /* no more packets should be written for this stream */
|
||||
int finished; /* no more packets should be written for this stream */
|
||||
int unavailable; /* true if the steram is unavailable (possibly temporarily) */
|
||||
int stream_copy;
|
||||
const char *attachment_filename;
|
||||
@@ -412,8 +367,6 @@ typedef struct OutputStream {
|
||||
int copy_prior_start;
|
||||
|
||||
int keep_pix_fmt;
|
||||
|
||||
AVCodecParserContext *parser;
|
||||
} OutputStream;
|
||||
|
||||
typedef struct OutputFile {
|
||||
@@ -463,13 +416,10 @@ extern int qp_hist;
|
||||
extern int stdin_interaction;
|
||||
extern int frame_bits_per_raw_sample;
|
||||
extern AVIOContext *progress_avio;
|
||||
extern float max_error_rate;
|
||||
|
||||
extern const AVIOInterruptCB int_cb;
|
||||
|
||||
extern const OptionDef options[];
|
||||
extern const HWAccel hwaccels[];
|
||||
|
||||
|
||||
void term_init(void);
|
||||
void term_exit(void);
|
||||
@@ -493,6 +443,4 @@ FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost);
|
||||
|
||||
int ffmpeg_parse_options(int argc, char **argv);
|
||||
|
||||
int vdpau_init(AVCodecContext *s);
|
||||
|
||||
#endif /* FFMPEG_H */
|
||||
|
||||
114
ffmpeg_filter.c
114
ffmpeg_filter.c
@@ -18,8 +18,6 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ffmpeg.h"
|
||||
|
||||
#include "libavfilter/avfilter.h"
|
||||
@@ -286,18 +284,21 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
|
||||
ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
|
||||
}
|
||||
|
||||
static int insert_trim(int64_t start_time, int64_t duration,
|
||||
AVFilterContext **last_filter, int *pad_idx,
|
||||
const char *filter_name)
|
||||
static int insert_trim(OutputStream *ost, AVFilterContext **last_filter, int *pad_idx)
|
||||
{
|
||||
OutputFile *of = output_files[ost->file_index];
|
||||
AVFilterGraph *graph = (*last_filter)->graph;
|
||||
AVFilterContext *ctx;
|
||||
const AVFilter *trim;
|
||||
enum AVMediaType type = avfilter_pad_get_type((*last_filter)->output_pads, *pad_idx);
|
||||
const char *name = (type == AVMEDIA_TYPE_VIDEO) ? "trim" : "atrim";
|
||||
const char *name = ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO ? "trim" : "atrim";
|
||||
char filter_name[128];
|
||||
int ret = 0;
|
||||
|
||||
if (duration == INT64_MAX && start_time == AV_NOPTS_VALUE)
|
||||
if (of->recording_time == INT64_MAX && !of->start_time)
|
||||
return 0;
|
||||
|
||||
// Use with duration and without output starttime is buggy with trim filters
|
||||
if (!of->start_time)
|
||||
return 0;
|
||||
|
||||
trim = avfilter_get_by_name(name);
|
||||
@@ -307,16 +308,18 @@ static int insert_trim(int64_t start_time, int64_t duration,
|
||||
return AVERROR_FILTER_NOT_FOUND;
|
||||
}
|
||||
|
||||
snprintf(filter_name, sizeof(filter_name), "%s for output stream %d:%d",
|
||||
name, ost->file_index, ost->index);
|
||||
ctx = avfilter_graph_alloc_filter(graph, trim, filter_name);
|
||||
if (!ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if (duration != INT64_MAX) {
|
||||
ret = av_opt_set_int(ctx, "durationi", duration,
|
||||
if (of->recording_time != INT64_MAX) {
|
||||
ret = av_opt_set_double(ctx, "duration", (double)of->recording_time / 1e6,
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
}
|
||||
if (ret >= 0 && start_time != AV_NOPTS_VALUE) {
|
||||
ret = av_opt_set_int(ctx, "starti", start_time,
|
||||
if (ret >= 0 && of->start_time) {
|
||||
ret = av_opt_set_double(ctx, "start", (double)of->start_time / 1e6,
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
}
|
||||
if (ret < 0) {
|
||||
@@ -341,7 +344,6 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
{
|
||||
char *pix_fmts;
|
||||
OutputStream *ost = ofilter->ost;
|
||||
OutputFile *of = output_files[ost->file_index];
|
||||
AVCodecContext *codec = ost->st->codec;
|
||||
AVFilterContext *last_filter = out->filter_ctx;
|
||||
int pad_idx = out->pad_idx;
|
||||
@@ -414,10 +416,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
pad_idx = 0;
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "trim for output stream %d:%d",
|
||||
ost->file_index, ost->index);
|
||||
ret = insert_trim(of->start_time, of->recording_time,
|
||||
&last_filter, &pad_idx, name);
|
||||
ret = insert_trim(ost, &last_filter, &pad_idx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -431,9 +430,9 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
|
||||
{
|
||||
OutputStream *ost = ofilter->ost;
|
||||
OutputFile *of = output_files[ost->file_index];
|
||||
AVCodecContext *codec = ost->st->codec;
|
||||
AVFilterContext *last_filter = out->filter_ctx;
|
||||
OutputFile *of = output_files[ost->file_index];
|
||||
int pad_idx = out->pad_idx;
|
||||
char *sample_fmts, *sample_rates, *channel_layouts;
|
||||
char name[255];
|
||||
@@ -543,10 +542,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "trim for output stream %d:%d",
|
||||
ost->file_index, ost->index);
|
||||
ret = insert_trim(of->start_time, of->recording_time,
|
||||
&last_filter, &pad_idx, name);
|
||||
ret = insert_trim(ost, &last_filter, &pad_idx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -560,7 +556,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
{ \
|
||||
AVFilterContext *ctx = inout->filter_ctx; \
|
||||
AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads; \
|
||||
int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs; \
|
||||
int nb_pads = in ? ctx->input_count : ctx->output_count; \
|
||||
AVIOContext *pb; \
|
||||
\
|
||||
if (avio_open_dyn_buf(&pb) < 0) \
|
||||
@@ -624,22 +620,17 @@ static int sub2video_prepare(InputStream *ist)
|
||||
static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
AVFilterInOut *in)
|
||||
{
|
||||
AVFilterContext *last_filter;
|
||||
const AVFilter *buffer_filt = avfilter_get_by_name("buffer");
|
||||
AVFilterContext *first_filter = in->filter_ctx;
|
||||
AVFilter *filter = avfilter_get_by_name("buffer");
|
||||
InputStream *ist = ifilter->ist;
|
||||
InputFile *f = input_files[ist->file_index];
|
||||
AVRational tb = ist->framerate.num ? av_inv_q(ist->framerate) :
|
||||
ist->st->time_base;
|
||||
AVRational fr = ist->framerate;
|
||||
AVRational sar;
|
||||
AVBPrint args;
|
||||
char name[255];
|
||||
int ret, pad_idx = 0;
|
||||
|
||||
if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot connect video filter to audio input\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
int pad_idx = in->pad_idx;
|
||||
int ret;
|
||||
|
||||
if (!fr.num)
|
||||
fr = av_guess_frame_rate(input_files[ist->file_index]->ctx, ist->st, NULL);
|
||||
@@ -659,8 +650,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
av_bprintf(&args,
|
||||
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:"
|
||||
"pixel_aspect=%d/%d:sws_param=flags=%d", ist->resample_width,
|
||||
ist->resample_height,
|
||||
ist->hwaccel_retrieve_data ? ist->hwaccel_retrieved_pix_fmt : ist->resample_pix_fmt,
|
||||
ist->resample_height, ist->resample_pix_fmt,
|
||||
tb.num, tb.den, sar.num, sar.den,
|
||||
SWS_BILINEAR + ((ist->st->codec->flags&CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0));
|
||||
if (fr.num && fr.den)
|
||||
@@ -668,10 +658,9 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
|
||||
ist->file_index, ist->st->index);
|
||||
|
||||
if ((ret = avfilter_graph_create_filter(&ifilter->filter, buffer_filt, name,
|
||||
if ((ret = avfilter_graph_create_filter(&ifilter->filter, filter, name,
|
||||
args.str, NULL, fg->graph)) < 0)
|
||||
return ret;
|
||||
last_filter = ifilter->filter;
|
||||
|
||||
if (ist->framerate.num) {
|
||||
AVFilterContext *setpts;
|
||||
@@ -684,10 +673,11 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
fg->graph)) < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = avfilter_link(last_filter, 0, setpts, 0)) < 0)
|
||||
if ((ret = avfilter_link(setpts, 0, first_filter, pad_idx)) < 0)
|
||||
return ret;
|
||||
|
||||
last_filter = setpts;
|
||||
first_filter = setpts;
|
||||
pad_idx = 0;
|
||||
}
|
||||
|
||||
if (do_deinterlace) {
|
||||
@@ -701,20 +691,14 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
fg->graph)) < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = avfilter_link(last_filter, 0, yadif, 0)) < 0)
|
||||
if ((ret = avfilter_link(yadif, 0, first_filter, pad_idx)) < 0)
|
||||
return ret;
|
||||
|
||||
last_filter = yadif;
|
||||
first_filter = yadif;
|
||||
pad_idx = 0;
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "trim for input stream %d:%d",
|
||||
ist->file_index, ist->st->index);
|
||||
ret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ?
|
||||
AV_NOPTS_VALUE : 0, f->recording_time, &last_filter, &pad_idx, name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
|
||||
if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
@@ -722,18 +706,13 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
AVFilterInOut *in)
|
||||
{
|
||||
AVFilterContext *last_filter;
|
||||
const AVFilter *abuffer_filt = avfilter_get_by_name("abuffer");
|
||||
AVFilterContext *first_filter = in->filter_ctx;
|
||||
AVFilter *filter = avfilter_get_by_name("abuffer");
|
||||
InputStream *ist = ifilter->ist;
|
||||
InputFile *f = input_files[ist->file_index];
|
||||
int pad_idx = in->pad_idx;
|
||||
AVBPrint args;
|
||||
char name[255];
|
||||
int ret, pad_idx = 0;
|
||||
|
||||
if (ist->st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot connect audio filter to non audio input\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
int ret;
|
||||
|
||||
av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
|
||||
av_bprintf(&args, "time_base=%d/%d:sample_rate=%d:sample_fmt=%s",
|
||||
@@ -748,11 +727,10 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
|
||||
ist->file_index, ist->st->index);
|
||||
|
||||
if ((ret = avfilter_graph_create_filter(&ifilter->filter, abuffer_filt,
|
||||
if ((ret = avfilter_graph_create_filter(&ifilter->filter, filter,
|
||||
name, args.str, NULL,
|
||||
fg->graph)) < 0)
|
||||
return ret;
|
||||
last_filter = ifilter->filter;
|
||||
|
||||
#define AUTO_INSERT_FILTER_INPUT(opt_name, filter_name, arg) do { \
|
||||
AVFilterContext *filt_ctx; \
|
||||
@@ -768,11 +746,11 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
if (ret < 0) \
|
||||
return ret; \
|
||||
\
|
||||
ret = avfilter_link(last_filter, 0, filt_ctx, 0); \
|
||||
ret = avfilter_link(filt_ctx, 0, first_filter, pad_idx); \
|
||||
if (ret < 0) \
|
||||
return ret; \
|
||||
\
|
||||
last_filter = filt_ctx; \
|
||||
first_filter = filt_ctx; \
|
||||
} while (0)
|
||||
|
||||
if (audio_sync_method > 0) {
|
||||
@@ -808,15 +786,7 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
snprintf(args, sizeof(args), "%f", audio_volume / 256.);
|
||||
AUTO_INSERT_FILTER_INPUT("-vol", "volume", args);
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "trim for input stream %d:%d",
|
||||
ist->file_index, ist->st->index);
|
||||
ret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ?
|
||||
AV_NOPTS_VALUE : 0, f->recording_time, &last_filter, &pad_idx, name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
|
||||
if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
@@ -871,10 +841,6 @@ int configure_filtergraph(FilterGraph *fg)
|
||||
if (strlen(args))
|
||||
args[strlen(args) - 1] = '\0';
|
||||
fg->graph->resample_lavr_opts = av_strdup(args);
|
||||
|
||||
e = av_dict_get(ost->opts, "threads", NULL, 0);
|
||||
if (e)
|
||||
av_opt_set(fg->graph, "threads", e->value, 0);
|
||||
}
|
||||
|
||||
if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
|
||||
|
||||
270
ffmpeg_opt.c
270
ffmpeg_opt.c
@@ -62,14 +62,6 @@
|
||||
outvar = o->name[i].u.type;\
|
||||
}\
|
||||
}
|
||||
|
||||
const HWAccel hwaccels[] = {
|
||||
#if HAVE_VDPAU_X11
|
||||
{ "vdpau", vdpau_init, HWACCEL_VDPAU, AV_PIX_FMT_VDPAU },
|
||||
#endif
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
char *vstats_filename;
|
||||
|
||||
float audio_drift_threshold = 0.1;
|
||||
@@ -92,7 +84,6 @@ int print_stats = -1;
|
||||
int qp_hist = 0;
|
||||
int stdin_interaction = 1;
|
||||
int frame_bits_per_raw_sample = 0;
|
||||
float max_error_rate = 2.0/3;
|
||||
|
||||
|
||||
static int intra_only = 0;
|
||||
@@ -104,7 +95,9 @@ static int do_psnr = 0;
|
||||
static int input_sync;
|
||||
static int override_ffserver = 0;
|
||||
|
||||
static void uninit_options(OptionsContext *o)
|
||||
static int64_t recording_time = INT64_MAX;
|
||||
|
||||
static void uninit_options(OptionsContext *o, int is_input)
|
||||
{
|
||||
const OptionDef *po = options;
|
||||
int i;
|
||||
@@ -134,19 +127,28 @@ static void uninit_options(OptionsContext *o)
|
||||
av_freep(&o->audio_channel_maps);
|
||||
av_freep(&o->streamid_map);
|
||||
av_freep(&o->attachments);
|
||||
|
||||
if (is_input)
|
||||
recording_time = o->recording_time;
|
||||
else
|
||||
recording_time = INT64_MAX;
|
||||
}
|
||||
|
||||
static void init_options(OptionsContext *o)
|
||||
static void init_options(OptionsContext *o, int is_input)
|
||||
{
|
||||
memset(o, 0, sizeof(*o));
|
||||
|
||||
if (!is_input && recording_time != INT64_MAX) {
|
||||
o->recording_time = recording_time;
|
||||
av_log(NULL, AV_LOG_WARNING,
|
||||
"-t is not an input option, keeping it for the next output;"
|
||||
" consider fixing your command line.\n");
|
||||
} else
|
||||
o->recording_time = INT64_MAX;
|
||||
o->stop_time = INT64_MAX;
|
||||
o->mux_max_delay = 0.7;
|
||||
o->start_time = AV_NOPTS_VALUE;
|
||||
o->recording_time = INT64_MAX;
|
||||
o->limit_filesize = UINT64_MAX;
|
||||
o->chapters_input_file = INT_MAX;
|
||||
o->accurate_seek = 1;
|
||||
}
|
||||
|
||||
/* return a copy of the input with the stream specifiers removed from the keys */
|
||||
@@ -559,14 +561,13 @@ static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *
|
||||
static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
|
||||
{
|
||||
int i;
|
||||
char *next, *codec_tag = NULL;
|
||||
|
||||
for (i = 0; i < ic->nb_streams; i++) {
|
||||
AVStream *st = ic->streams[i];
|
||||
AVCodecContext *dec = st->codec;
|
||||
InputStream *ist = av_mallocz(sizeof(*ist));
|
||||
char *framerate = NULL, *hwaccel = NULL, *hwaccel_device = NULL;
|
||||
char *codec_tag = NULL;
|
||||
char *next;
|
||||
char *framerate = NULL;
|
||||
|
||||
if (!ist)
|
||||
exit_program(1);
|
||||
@@ -602,7 +603,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
if(!ist->dec)
|
||||
ist->dec = avcodec_find_decoder(dec->codec_id);
|
||||
if (av_codec_get_lowres(dec)) {
|
||||
if (dec->lowres) {
|
||||
dec->flags |= CODEC_FLAG_EMU_EDGE;
|
||||
}
|
||||
|
||||
@@ -621,41 +622,6 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
|
||||
ist->top_field_first = -1;
|
||||
MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st);
|
||||
|
||||
MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
|
||||
if (hwaccel) {
|
||||
if (!strcmp(hwaccel, "none"))
|
||||
ist->hwaccel_id = HWACCEL_NONE;
|
||||
else if (!strcmp(hwaccel, "auto"))
|
||||
ist->hwaccel_id = HWACCEL_AUTO;
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; hwaccels[i].name; i++) {
|
||||
if (!strcmp(hwaccels[i].name, hwaccel)) {
|
||||
ist->hwaccel_id = hwaccels[i].id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ist->hwaccel_id) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n",
|
||||
hwaccel);
|
||||
av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: ");
|
||||
for (i = 0; hwaccels[i].name; i++)
|
||||
av_log(NULL, AV_LOG_FATAL, "%s ", hwaccels[i].name);
|
||||
av_log(NULL, AV_LOG_FATAL, "\n");
|
||||
exit_program(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MATCH_PER_STREAM_OPT(hwaccel_devices, str, hwaccel_device, ic, st);
|
||||
if (hwaccel_device) {
|
||||
ist->hwaccel_device = av_strdup(hwaccel_device);
|
||||
if (!ist->hwaccel_device)
|
||||
exit_program(1);
|
||||
}
|
||||
ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE;
|
||||
|
||||
break;
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
ist->guess_layout_max = INT_MAX;
|
||||
@@ -693,15 +659,11 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
|
||||
|
||||
static void assert_file_overwrite(const char *filename)
|
||||
{
|
||||
if (file_overwrite && no_file_overwrite) {
|
||||
fprintf(stderr, "Error, both -y and -n supplied. Exiting.\n");
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
if (!file_overwrite) {
|
||||
const char *proto_name = avio_find_protocol_name(filename);
|
||||
if (proto_name && !strcmp(proto_name, "file") && avio_check(filename, 0) == 0) {
|
||||
if (stdin_interaction && !no_file_overwrite) {
|
||||
if ((!file_overwrite || no_file_overwrite) &&
|
||||
(strchr(filename, ':') == NULL || filename[1] == ':' ||
|
||||
av_strstart(filename, "file:", NULL))) {
|
||||
if (avio_check(filename, 0) == 0) {
|
||||
if (stdin_interaction && (!no_file_overwrite || file_overwrite)) {
|
||||
fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
|
||||
fflush(stderr);
|
||||
term_exit();
|
||||
@@ -829,14 +791,6 @@ static int open_input_file(OptionsContext *o, const char *filename)
|
||||
find_codec_or_die(audio_codec_name , AVMEDIA_TYPE_AUDIO , 0)->id : AV_CODEC_ID_NONE;
|
||||
ic->subtitle_codec_id= subtitle_codec_name ?
|
||||
find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0)->id : AV_CODEC_ID_NONE;
|
||||
|
||||
if (video_codec_name)
|
||||
av_format_set_video_codec (ic, find_codec_or_die(video_codec_name , AVMEDIA_TYPE_VIDEO , 0));
|
||||
if (audio_codec_name)
|
||||
av_format_set_audio_codec (ic, find_codec_or_die(audio_codec_name , AVMEDIA_TYPE_AUDIO , 0));
|
||||
if (subtitle_codec_name)
|
||||
av_format_set_subtitle_codec(ic, find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0));
|
||||
|
||||
ic->flags |= AVFMT_FLAG_NONBLOCK;
|
||||
ic->interrupt_callback = int_cb;
|
||||
|
||||
@@ -865,13 +819,13 @@ static int open_input_file(OptionsContext *o, const char *filename)
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time;
|
||||
timestamp = o->start_time;
|
||||
/* add the stream start time */
|
||||
if (ic->start_time != AV_NOPTS_VALUE)
|
||||
timestamp += ic->start_time;
|
||||
|
||||
/* if seeking requested, we execute it */
|
||||
if (o->start_time != AV_NOPTS_VALUE) {
|
||||
if (o->start_time != 0) {
|
||||
ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, timestamp, 0);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
|
||||
@@ -893,13 +847,9 @@ static int open_input_file(OptionsContext *o, const char *filename)
|
||||
|
||||
f->ctx = ic;
|
||||
f->ist_index = nb_input_streams - ic->nb_streams;
|
||||
f->start_time = o->start_time;
|
||||
f->recording_time = o->recording_time;
|
||||
f->input_ts_offset = o->input_ts_offset;
|
||||
f->ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp);
|
||||
f->nb_streams = ic->nb_streams;
|
||||
f->rate_emu = o->rate_emu;
|
||||
f->accurate_seek = o->accurate_seek;
|
||||
|
||||
/* check if all codec options have been used */
|
||||
unused_opts = strip_specifiers(o->g->codec_opts);
|
||||
@@ -915,13 +865,8 @@ static int open_input_file(OptionsContext *o, const char *filename)
|
||||
const AVClass *class = avcodec_get_class();
|
||||
const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
|
||||
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
|
||||
const AVClass *fclass = avformat_get_class();
|
||||
const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0,
|
||||
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
|
||||
if (!option || foption)
|
||||
if (!option)
|
||||
continue;
|
||||
|
||||
|
||||
if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
|
||||
"input file #%d (%s) is not a decoding option.\n", e->key,
|
||||
@@ -978,14 +923,14 @@ static uint8_t *get_line(AVIOContext *s)
|
||||
|
||||
static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
|
||||
{
|
||||
int i, ret = -1;
|
||||
int i, ret = 1;
|
||||
char filename[1000];
|
||||
const char *base[3] = { getenv("AVCONV_DATADIR"),
|
||||
getenv("HOME"),
|
||||
AVCONV_DATADIR,
|
||||
};
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(base) && ret < 0; i++) {
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) {
|
||||
if (!base[i])
|
||||
continue;
|
||||
if (codec_name) {
|
||||
@@ -993,7 +938,7 @@ static int get_preset_file_2(const char *preset_name, const char *codec_name, AV
|
||||
i != 1 ? "" : "/.avconv", codec_name, preset_name);
|
||||
ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
|
||||
}
|
||||
if (ret < 0) {
|
||||
if (ret) {
|
||||
snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
|
||||
i != 1 ? "" : "/.avconv", preset_name);
|
||||
ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
|
||||
@@ -1200,36 +1145,26 @@ static char *get_ost_filters(OptionsContext *o, AVFormatContext *oc,
|
||||
OutputStream *ost)
|
||||
{
|
||||
AVStream *st = ost->st;
|
||||
char *filter = NULL, *filter_script = NULL;
|
||||
|
||||
if (ost->filters_script && ost->filters) {
|
||||
MATCH_PER_STREAM_OPT(filter_scripts, str, filter_script, oc, st);
|
||||
MATCH_PER_STREAM_OPT(filters, str, filter, oc, st);
|
||||
|
||||
if (filter_script && filter) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for "
|
||||
"output stream #%d:%d.\n", nb_output_files, st->index);
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
if (ost->filters_script)
|
||||
return read_file(ost->filters_script);
|
||||
else if (ost->filters)
|
||||
return av_strdup(ost->filters);
|
||||
if (filter_script)
|
||||
return read_file(filter_script);
|
||||
else if (filter)
|
||||
return av_strdup(filter);
|
||||
|
||||
return av_strdup(st->codec->codec_type == AVMEDIA_TYPE_VIDEO ?
|
||||
"null" : "anull");
|
||||
}
|
||||
|
||||
static void check_streamcopy_filters(OptionsContext *o, AVFormatContext *oc,
|
||||
const OutputStream *ost, enum AVMediaType type)
|
||||
{
|
||||
if (ost->filters_script || ost->filters) {
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"%s '%s' was defined for %s output stream %d:%d but codec copy was selected.\n"
|
||||
"Filtering and streamcopy cannot be used together.\n",
|
||||
ost->filters ? "Filtergraph" : "Filtergraph script",
|
||||
ost->filters ? ost->filters : ost->filters_script,
|
||||
av_get_media_type_string(type), ost->file_index, ost->index);
|
||||
exit_program(1);
|
||||
}
|
||||
}
|
||||
|
||||
static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
|
||||
{
|
||||
AVStream *st;
|
||||
@@ -1258,15 +1193,11 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in
|
||||
ost->frame_aspect_ratio = q;
|
||||
}
|
||||
|
||||
MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
|
||||
MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
|
||||
|
||||
if (!ost->stream_copy) {
|
||||
const char *p = NULL;
|
||||
char *frame_size = NULL;
|
||||
char *frame_pix_fmt = NULL;
|
||||
char *intra_matrix = NULL, *inter_matrix = NULL;
|
||||
char *chroma_intra_matrix = NULL;
|
||||
int do_pass = 0;
|
||||
int i;
|
||||
|
||||
@@ -1299,16 +1230,6 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in
|
||||
}
|
||||
parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
|
||||
}
|
||||
MATCH_PER_STREAM_OPT(chroma_intra_matrices, str, chroma_intra_matrix, oc, st);
|
||||
if (chroma_intra_matrix) {
|
||||
uint16_t *p = av_mallocz(sizeof(*video_enc->chroma_intra_matrix) * 64);
|
||||
if (!p) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
|
||||
exit_program(1);
|
||||
}
|
||||
av_codec_set_chroma_intra_matrix(video_enc, p);
|
||||
parse_matrix_coeffs(p, chroma_intra_matrix);
|
||||
}
|
||||
MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
|
||||
if (inter_matrix) {
|
||||
if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
|
||||
@@ -1384,9 +1305,6 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in
|
||||
MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
|
||||
}
|
||||
|
||||
if (ost->stream_copy)
|
||||
check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_VIDEO);
|
||||
|
||||
return ost;
|
||||
}
|
||||
|
||||
@@ -1403,9 +1321,6 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, in
|
||||
audio_enc = st->codec;
|
||||
audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
|
||||
|
||||
MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
|
||||
MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
|
||||
|
||||
if (!ost->stream_copy) {
|
||||
char *sample_fmt = NULL;
|
||||
|
||||
@@ -1443,9 +1358,6 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, in
|
||||
}
|
||||
}
|
||||
|
||||
if (ost->stream_copy)
|
||||
check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_AUDIO);
|
||||
|
||||
return ost;
|
||||
}
|
||||
|
||||
@@ -1534,8 +1446,7 @@ static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
|
||||
|
||||
for (i = 0; i < is->nb_chapters; i++) {
|
||||
AVChapter *in_ch = is->chapters[i], *out_ch;
|
||||
int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
|
||||
int64_t ts_off = av_rescale_q(start_time - ifile->ts_offset,
|
||||
int64_t ts_off = av_rescale_q(ofile->start_time - ifile->ts_offset,
|
||||
AV_TIME_BASE_Q, in_ch->time_base);
|
||||
int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
|
||||
av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
|
||||
@@ -1630,18 +1541,6 @@ static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
if (ost->avfilter && (ost->filters || ost->filters_script)) {
|
||||
const char *opt = ost->filters ? "-vf/-af/-filter" : "-filter_script";
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"%s '%s' was specified through the %s option "
|
||||
"for output stream %d:%d, which is fed from a complex filtergraph.\n"
|
||||
"%s and -filter_complex cannot be used together for the same stream.\n",
|
||||
ost->filters ? "Filtergraph" : "Filtergraph script",
|
||||
ost->filters ? ost->filters : ost->filters_script,
|
||||
opt, ost->file_index, ost->index, opt);
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n");
|
||||
exit_program(1);
|
||||
@@ -1682,12 +1581,11 @@ static int open_output_file(OptionsContext *o, const char *filename)
|
||||
}
|
||||
|
||||
if (o->stop_time != INT64_MAX && o->recording_time == INT64_MAX) {
|
||||
int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time;
|
||||
if (o->stop_time <= start_time) {
|
||||
if (o->stop_time <= o->start_time) {
|
||||
av_log(NULL, AV_LOG_WARNING, "-to value smaller than -ss; ignoring -to.\n");
|
||||
o->stop_time = INT64_MAX;
|
||||
} else {
|
||||
o->recording_time = o->stop_time - start_time;
|
||||
o->recording_time = o->stop_time - o->start_time;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1783,7 +1681,7 @@ static int open_output_file(OptionsContext *o, const char *filename)
|
||||
/* pick the "best" stream of each type */
|
||||
|
||||
/* video: highest resolution */
|
||||
if (!o->video_disable && oc->oformat->video_codec != AV_CODEC_ID_NONE) {
|
||||
if (!o->video_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) {
|
||||
int area = 0, idx = -1;
|
||||
int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);
|
||||
for (i = 0; i < nb_input_streams; i++) {
|
||||
@@ -1805,7 +1703,7 @@ static int open_output_file(OptionsContext *o, const char *filename)
|
||||
}
|
||||
|
||||
/* audio: most channels */
|
||||
if (!o->audio_disable && oc->oformat->audio_codec != AV_CODEC_ID_NONE) {
|
||||
if (!o->audio_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_AUDIO) != AV_CODEC_ID_NONE) {
|
||||
int channels = 0, idx = -1;
|
||||
for (i = 0; i < nb_input_streams; i++) {
|
||||
ist = input_streams[i];
|
||||
@@ -1821,7 +1719,7 @@ static int open_output_file(OptionsContext *o, const char *filename)
|
||||
|
||||
/* subtitles: pick first */
|
||||
MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, oc, "s");
|
||||
if (!o->subtitle_disable && (avcodec_find_encoder(oc->oformat->subtitle_codec) || subtitle_codec_name)) {
|
||||
if (!o->subtitle_disable && (oc->oformat->subtitle_codec != AV_CODEC_ID_NONE || subtitle_codec_name)) {
|
||||
for (i = 0; i < nb_input_streams; i++)
|
||||
if (input_streams[i]->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
|
||||
new_subtitle_stream(o, oc, i);
|
||||
@@ -2149,22 +2047,23 @@ static int opt_target(void *optctx, const char *opt, const char *arg)
|
||||
opt_video_codec(o, "c:v", "mpeg1video");
|
||||
opt_audio_codec(o, "c:a", "mp2");
|
||||
parse_option(o, "f", "vcd", options);
|
||||
av_dict_set(&o->g->codec_opts, "b:v", arg, 0);
|
||||
|
||||
parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
|
||||
parse_option(o, "r", frame_rates[norm], options);
|
||||
av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
|
||||
|
||||
av_dict_set(&o->g->codec_opts, "b:v", "1150000", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->codec_opts, "maxrate", "1150000", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->codec_opts, "minrate", "1150000", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->codec_opts, "bufsize", "327680", AV_DICT_DONT_OVERWRITE); // 40*1024*8;
|
||||
av_dict_set(&o->g->codec_opts, "b:v", "1150000", 0);
|
||||
av_dict_set(&o->g->codec_opts, "maxrate", "1150000", 0);
|
||||
av_dict_set(&o->g->codec_opts, "minrate", "1150000", 0);
|
||||
av_dict_set(&o->g->codec_opts, "bufsize", "327680", 0); // 40*1024*8;
|
||||
|
||||
av_dict_set(&o->g->codec_opts, "b:a", "224000", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->codec_opts, "b:a", "224000", 0);
|
||||
parse_option(o, "ar", "44100", options);
|
||||
parse_option(o, "ac", "2", options);
|
||||
|
||||
av_dict_set(&o->g->format_opts, "packetsize", "2324", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->format_opts, "muxrate", "1411200", AV_DICT_DONT_OVERWRITE); // 2352 * 75 * 8;
|
||||
av_dict_set(&o->g->format_opts, "packetsize", "2324", 0);
|
||||
av_dict_set(&o->g->format_opts, "muxrate", "1411200", 0); // 2352 * 75 * 8;
|
||||
|
||||
/* We have to offset the PTS, so that it is consistent with the SCR.
|
||||
SCR starts at 36000, but the first two packs contain only padding
|
||||
@@ -2181,18 +2080,18 @@ static int opt_target(void *optctx, const char *opt, const char *arg)
|
||||
parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
|
||||
parse_option(o, "r", frame_rates[norm], options);
|
||||
parse_option(o, "pix_fmt", "yuv420p", options);
|
||||
av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
|
||||
|
||||
av_dict_set(&o->g->codec_opts, "b:v", "2040000", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->codec_opts, "maxrate", "2516000", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->codec_opts, "minrate", "0", AV_DICT_DONT_OVERWRITE); // 1145000;
|
||||
av_dict_set(&o->g->codec_opts, "bufsize", "1835008", AV_DICT_DONT_OVERWRITE); // 224*1024*8;
|
||||
av_dict_set(&o->g->codec_opts, "scan_offset", "1", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->codec_opts, "b:v", "2040000", 0);
|
||||
av_dict_set(&o->g->codec_opts, "maxrate", "2516000", 0);
|
||||
av_dict_set(&o->g->codec_opts, "minrate", "0", 0); // 1145000;
|
||||
av_dict_set(&o->g->codec_opts, "bufsize", "1835008", 0); // 224*1024*8;
|
||||
av_dict_set(&o->g->codec_opts, "scan_offset", "1", 0);
|
||||
|
||||
av_dict_set(&o->g->codec_opts, "b:a", "224000", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->codec_opts, "b:a", "224000", 0);
|
||||
parse_option(o, "ar", "44100", options);
|
||||
|
||||
av_dict_set(&o->g->format_opts, "packetsize", "2324", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->format_opts, "packetsize", "2324", 0);
|
||||
|
||||
} else if (!strcmp(arg, "dvd")) {
|
||||
|
||||
@@ -2203,17 +2102,17 @@ static int opt_target(void *optctx, const char *opt, const char *arg)
|
||||
parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
|
||||
parse_option(o, "r", frame_rates[norm], options);
|
||||
parse_option(o, "pix_fmt", "yuv420p", options);
|
||||
av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
|
||||
|
||||
av_dict_set(&o->g->codec_opts, "b:v", "6000000", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->codec_opts, "maxrate", "9000000", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->codec_opts, "minrate", "0", AV_DICT_DONT_OVERWRITE); // 1500000;
|
||||
av_dict_set(&o->g->codec_opts, "bufsize", "1835008", AV_DICT_DONT_OVERWRITE); // 224*1024*8;
|
||||
av_dict_set(&o->g->codec_opts, "b:v", "6000000", 0);
|
||||
av_dict_set(&o->g->codec_opts, "maxrate", "9000000", 0);
|
||||
av_dict_set(&o->g->codec_opts, "minrate", "0", 0); // 1500000;
|
||||
av_dict_set(&o->g->codec_opts, "bufsize", "1835008", 0); // 224*1024*8;
|
||||
|
||||
av_dict_set(&o->g->format_opts, "packetsize", "2048", AV_DICT_DONT_OVERWRITE); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
|
||||
av_dict_set(&o->g->format_opts, "muxrate", "10080000", AV_DICT_DONT_OVERWRITE); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
|
||||
av_dict_set(&o->g->format_opts, "packetsize", "2048", 0); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
|
||||
av_dict_set(&o->g->format_opts, "muxrate", "10080000", 0); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
|
||||
|
||||
av_dict_set(&o->g->codec_opts, "b:a", "448000", AV_DICT_DONT_OVERWRITE);
|
||||
av_dict_set(&o->g->codec_opts, "b:a", "448000", 0);
|
||||
parse_option(o, "ar", "48000", options);
|
||||
|
||||
} else if (!strncmp(arg, "dv", 2)) {
|
||||
@@ -2550,9 +2449,7 @@ void show_help_default(const char *opt, const char *arg)
|
||||
int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
|
||||
show_help_children(avcodec_get_class(), flags);
|
||||
show_help_children(avformat_get_class(), flags);
|
||||
#if CONFIG_SWSCALE
|
||||
show_help_children(sws_get_class(), flags);
|
||||
#endif
|
||||
show_help_children(swr_get_class(), AV_OPT_FLAG_AUDIO_PARAM);
|
||||
show_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM);
|
||||
}
|
||||
@@ -2584,7 +2481,7 @@ static int open_files(OptionGroupList *l, const char *inout,
|
||||
OptionGroup *g = &l->groups[i];
|
||||
OptionsContext o;
|
||||
|
||||
init_options(&o);
|
||||
init_options(&o, !strcmp(inout, "input"));
|
||||
o.g = g;
|
||||
|
||||
ret = parse_optgroup(&o, g);
|
||||
@@ -2596,7 +2493,7 @@ static int open_files(OptionGroupList *l, const char *inout,
|
||||
|
||||
av_log(NULL, AV_LOG_DEBUG, "Opening an %s file: %s.\n", inout, g->arg);
|
||||
ret = open_file(&o, g->arg);
|
||||
uninit_options(&o);
|
||||
uninit_options(&o, !strcmp(inout, "input"));
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error opening %s file %s.\n",
|
||||
inout, g->arg);
|
||||
@@ -2681,7 +2578,7 @@ const OptionDef options[] = {
|
||||
{ "y", OPT_BOOL, { &file_overwrite },
|
||||
"overwrite output files" },
|
||||
{ "n", OPT_BOOL, { &no_file_overwrite },
|
||||
"never overwrite output files" },
|
||||
"do not overwrite output files" },
|
||||
{ "c", HAS_ARG | OPT_STRING | OPT_SPEC |
|
||||
OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(codec_names) },
|
||||
"codec name", "codec" },
|
||||
@@ -2704,8 +2601,7 @@ const OptionDef options[] = {
|
||||
{ "map_chapters", HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET |
|
||||
OPT_OUTPUT, { .off = OFFSET(chapters_input_file) },
|
||||
"set chapters mapping", "input_file_index" },
|
||||
{ "t", HAS_ARG | OPT_TIME | OPT_OFFSET |
|
||||
OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(recording_time) },
|
||||
{ "t", HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(recording_time) },
|
||||
"record or transcode \"duration\" seconds of audio/video",
|
||||
"duration" },
|
||||
{ "to", HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(stop_time) },
|
||||
@@ -2715,16 +2611,13 @@ const OptionDef options[] = {
|
||||
{ "ss", HAS_ARG | OPT_TIME | OPT_OFFSET |
|
||||
OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(start_time) },
|
||||
"set the start time offset", "time_off" },
|
||||
{ "accurate_seek", OPT_BOOL | OPT_OFFSET | OPT_EXPERT |
|
||||
OPT_INPUT, { .off = OFFSET(accurate_seek) },
|
||||
"enable/disable accurate seeking with -ss" },
|
||||
{ "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET |
|
||||
OPT_EXPERT | OPT_INPUT, { .off = OFFSET(input_ts_offset) },
|
||||
"set the input ts offset", "time_off" },
|
||||
{ "itsscale", HAS_ARG | OPT_DOUBLE | OPT_SPEC |
|
||||
OPT_EXPERT | OPT_INPUT, { .off = OFFSET(ts_scale) },
|
||||
"set the input ts scale", "scale" },
|
||||
{ "timestamp", HAS_ARG | OPT_PERFILE, { .func_arg = opt_recording_timestamp },
|
||||
{ "timestamp", HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_recording_timestamp },
|
||||
"set the recording timestamp ('now' to set the current time)", "time" },
|
||||
{ "metadata", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(metadata) },
|
||||
"add metadata", "string=string" },
|
||||
@@ -2781,7 +2674,7 @@ const OptionDef options[] = {
|
||||
{ "frames", OPT_INT64 | HAS_ARG | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(max_frames) },
|
||||
"set the number of frames to record", "number" },
|
||||
{ "tag", OPT_STRING | HAS_ARG | OPT_SPEC |
|
||||
OPT_EXPERT | OPT_OUTPUT | OPT_INPUT, { .off = OFFSET(codec_tags) },
|
||||
OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(codec_tags) },
|
||||
"force codec tag/fourcc", "fourcc/tag" },
|
||||
{ "q", HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
|
||||
OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(qscale) },
|
||||
@@ -2813,8 +2706,6 @@ const OptionDef options[] = {
|
||||
"extract an attachment into a file", "filename" },
|
||||
{ "debug_ts", OPT_BOOL | OPT_EXPERT, { &debug_ts },
|
||||
"print timestamp debugging info" },
|
||||
{ "max_error_rate", HAS_ARG | OPT_FLOAT, { &max_error_rate },
|
||||
"maximum error rate", "ratio of errors (0.0: no errors, 1.0: 100% errors) above which ffmpeg returns an error instead of success." },
|
||||
|
||||
/* video options */
|
||||
{ "vframes", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_frames },
|
||||
@@ -2872,9 +2763,6 @@ const OptionDef options[] = {
|
||||
{ "inter_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
|
||||
OPT_OUTPUT, { .off = OFFSET(inter_matrices) },
|
||||
"specify inter matrix coeffs", "matrix" },
|
||||
{ "chroma_intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
|
||||
OPT_OUTPUT, { .off = OFFSET(chroma_intra_matrices) },
|
||||
"specify intra matrix coeffs", "matrix" },
|
||||
{ "top", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_INT| OPT_SPEC |
|
||||
OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(top_field_first) },
|
||||
"top=1/bottom=0/auto=-1 field first", "" },
|
||||
@@ -2896,12 +2784,6 @@ const OptionDef options[] = {
|
||||
"force key frames at specified timestamps", "timestamps" },
|
||||
{ "b", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_bitrate },
|
||||
"video bitrate (please use -b:v)", "bitrate" },
|
||||
{ "hwaccel", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
|
||||
OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccels) },
|
||||
"use HW accelerated decoding", "hwaccel name" },
|
||||
{ "hwaccel_device", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
|
||||
OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccel_devices) },
|
||||
"select a device for HW acceleration" "devicename" },
|
||||
|
||||
/* audio options */
|
||||
{ "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames },
|
||||
|
||||
335
ffmpeg_vdpau.c
335
ffmpeg_vdpau.c
@@ -1,335 +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 <stdint.h>
|
||||
|
||||
#include <vdpau/vdpau.h>
|
||||
#include <vdpau/vdpau_x11.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "ffmpeg.h"
|
||||
|
||||
#include "libavcodec/vdpau.h"
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/buffer.h"
|
||||
#include "libavutil/frame.h"
|
||||
#include "libavutil/pixfmt.h"
|
||||
|
||||
typedef struct VDPAUContext {
|
||||
Display *dpy;
|
||||
|
||||
VdpDevice device;
|
||||
VdpDecoder decoder;
|
||||
VdpGetProcAddress *get_proc_address;
|
||||
|
||||
VdpGetErrorString *get_error_string;
|
||||
VdpGetInformationString *get_information_string;
|
||||
VdpDeviceDestroy *device_destroy;
|
||||
VdpDecoderCreate *decoder_create;
|
||||
VdpDecoderDestroy *decoder_destroy;
|
||||
VdpDecoderRender *decoder_render;
|
||||
VdpVideoSurfaceCreate *video_surface_create;
|
||||
VdpVideoSurfaceDestroy *video_surface_destroy;
|
||||
VdpVideoSurfaceGetBitsYCbCr *video_surface_get_bits;
|
||||
VdpVideoSurfaceGetParameters *video_surface_get_parameters;
|
||||
VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *video_surface_query;
|
||||
|
||||
AVFrame *tmp_frame;
|
||||
|
||||
enum AVPixelFormat pix_fmt;
|
||||
VdpYCbCrFormat vdpau_format;
|
||||
} VDPAUContext;
|
||||
|
||||
static void vdpau_uninit(AVCodecContext *s)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
VDPAUContext *ctx = ist->hwaccel_ctx;
|
||||
|
||||
ist->hwaccel_uninit = NULL;
|
||||
ist->hwaccel_get_buffer = NULL;
|
||||
ist->hwaccel_retrieve_data = NULL;
|
||||
|
||||
if (ctx->decoder_destroy)
|
||||
ctx->decoder_destroy(ctx->decoder);
|
||||
|
||||
if (ctx->device_destroy)
|
||||
ctx->device_destroy(ctx->device);
|
||||
|
||||
if (ctx->dpy)
|
||||
XCloseDisplay(ctx->dpy);
|
||||
|
||||
av_frame_free(&ctx->tmp_frame);
|
||||
|
||||
av_freep(&ist->hwaccel_ctx);
|
||||
av_freep(&s->hwaccel_context);
|
||||
}
|
||||
|
||||
static void vdpau_release_buffer(void *opaque, uint8_t *data)
|
||||
{
|
||||
VdpVideoSurface surface = *(VdpVideoSurface*)data;
|
||||
VDPAUContext *ctx = opaque;
|
||||
|
||||
ctx->video_surface_destroy(surface);
|
||||
av_freep(&data);
|
||||
}
|
||||
|
||||
static int vdpau_get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
VDPAUContext *ctx = ist->hwaccel_ctx;
|
||||
VdpVideoSurface *surface;
|
||||
VdpStatus err;
|
||||
|
||||
av_assert0(frame->format == AV_PIX_FMT_VDPAU);
|
||||
|
||||
surface = av_malloc(sizeof(*surface));
|
||||
if (!surface)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
frame->buf[0] = av_buffer_create((uint8_t*)surface, sizeof(*surface),
|
||||
vdpau_release_buffer, ctx,
|
||||
AV_BUFFER_FLAG_READONLY);
|
||||
if (!frame->buf[0]) {
|
||||
av_freep(&surface);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
// properly we should keep a pool of surfaces instead of creating
|
||||
// them anew for each frame, but since we don't care about speed
|
||||
// much in this code, we don't bother
|
||||
err = ctx->video_surface_create(ctx->device, VDP_CHROMA_TYPE_420,
|
||||
frame->width, frame->height, surface);
|
||||
if (err != VDP_STATUS_OK) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error allocating a VDPAU video surface: %s\n",
|
||||
ctx->get_error_string(err));
|
||||
av_buffer_unref(&frame->buf[0]);
|
||||
return AVERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
frame->data[3] = (uint8_t*)(uintptr_t)*surface;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vdpau_retrieve_data(AVCodecContext *s, AVFrame *frame)
|
||||
{
|
||||
VdpVideoSurface surface = (VdpVideoSurface)(uintptr_t)frame->data[3];
|
||||
InputStream *ist = s->opaque;
|
||||
VDPAUContext *ctx = ist->hwaccel_ctx;
|
||||
VdpStatus err;
|
||||
int ret, chroma_type;
|
||||
|
||||
err = ctx->video_surface_get_parameters(surface, &chroma_type,
|
||||
&ctx->tmp_frame->width,
|
||||
&ctx->tmp_frame->height);
|
||||
if (err != VDP_STATUS_OK) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error getting surface parameters: %s\n",
|
||||
ctx->get_error_string(err));
|
||||
return AVERROR_UNKNOWN;
|
||||
}
|
||||
ctx->tmp_frame->format = ctx->pix_fmt;
|
||||
|
||||
ret = av_frame_get_buffer(ctx->tmp_frame, 32);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ctx->tmp_frame->width = frame->width;
|
||||
ctx->tmp_frame->height = frame->height;
|
||||
|
||||
err = ctx->video_surface_get_bits(surface, ctx->vdpau_format,
|
||||
(void * const *)ctx->tmp_frame->data,
|
||||
ctx->tmp_frame->linesize);
|
||||
if (err != VDP_STATUS_OK) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error retrieving frame data from VDPAU: %s\n",
|
||||
ctx->get_error_string(err));
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (ctx->vdpau_format == VDP_YCBCR_FORMAT_YV12)
|
||||
FFSWAP(uint8_t*, ctx->tmp_frame->data[1], ctx->tmp_frame->data[2]);
|
||||
|
||||
ret = av_frame_copy_props(ctx->tmp_frame, frame);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
av_frame_unref(frame);
|
||||
av_frame_move_ref(frame, ctx->tmp_frame);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
av_frame_unref(ctx->tmp_frame);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const int vdpau_formats[][2] = {
|
||||
{ VDP_YCBCR_FORMAT_YV12, AV_PIX_FMT_YUV420P },
|
||||
{ VDP_YCBCR_FORMAT_NV12, AV_PIX_FMT_NV12 },
|
||||
{ VDP_YCBCR_FORMAT_YUYV, AV_PIX_FMT_YUYV422 },
|
||||
{ VDP_YCBCR_FORMAT_UYVY, AV_PIX_FMT_UYVY422 },
|
||||
};
|
||||
|
||||
static int vdpau_alloc(AVCodecContext *s)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
|
||||
AVVDPAUContext *vdpau_ctx;
|
||||
VDPAUContext *ctx;
|
||||
const char *display, *vendor;
|
||||
VdpStatus err;
|
||||
int i;
|
||||
|
||||
ctx = av_mallocz(sizeof(*ctx));
|
||||
if (!ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
ist->hwaccel_ctx = ctx;
|
||||
ist->hwaccel_uninit = vdpau_uninit;
|
||||
ist->hwaccel_get_buffer = vdpau_get_buffer;
|
||||
ist->hwaccel_retrieve_data = vdpau_retrieve_data;
|
||||
|
||||
ctx->tmp_frame = av_frame_alloc();
|
||||
if (!ctx->tmp_frame)
|
||||
goto fail;
|
||||
|
||||
ctx->dpy = XOpenDisplay(ist->hwaccel_device);
|
||||
if (!ctx->dpy) {
|
||||
av_log(NULL, loglevel, "Cannot open the X11 display %s.\n",
|
||||
XDisplayName(ist->hwaccel_device));
|
||||
goto fail;
|
||||
}
|
||||
display = XDisplayString(ctx->dpy);
|
||||
|
||||
err = vdp_device_create_x11(ctx->dpy, XDefaultScreen(ctx->dpy), &ctx->device,
|
||||
&ctx->get_proc_address);
|
||||
if (err != VDP_STATUS_OK) {
|
||||
av_log(NULL, loglevel, "VDPAU device creation on X11 display %s failed.\n",
|
||||
display);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#define GET_CALLBACK(id, result) \
|
||||
do { \
|
||||
void *tmp; \
|
||||
err = ctx->get_proc_address(ctx->device, id, &tmp); \
|
||||
if (err != VDP_STATUS_OK) { \
|
||||
av_log(NULL, loglevel, "Error getting the " #id " callback.\n"); \
|
||||
goto fail; \
|
||||
} \
|
||||
ctx->result = tmp; \
|
||||
} while (0)
|
||||
|
||||
GET_CALLBACK(VDP_FUNC_ID_GET_ERROR_STRING, get_error_string);
|
||||
GET_CALLBACK(VDP_FUNC_ID_GET_INFORMATION_STRING, get_information_string);
|
||||
GET_CALLBACK(VDP_FUNC_ID_DEVICE_DESTROY, device_destroy);
|
||||
GET_CALLBACK(VDP_FUNC_ID_DECODER_CREATE, decoder_create);
|
||||
GET_CALLBACK(VDP_FUNC_ID_DECODER_DESTROY, decoder_destroy);
|
||||
GET_CALLBACK(VDP_FUNC_ID_DECODER_RENDER, decoder_render);
|
||||
GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_CREATE, video_surface_create);
|
||||
GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, video_surface_destroy);
|
||||
GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, video_surface_get_bits);
|
||||
GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, video_surface_get_parameters);
|
||||
GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES,
|
||||
video_surface_query);
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(vdpau_formats); i++) {
|
||||
VdpBool supported;
|
||||
err = ctx->video_surface_query(ctx->device, VDP_CHROMA_TYPE_420,
|
||||
vdpau_formats[i][0], &supported);
|
||||
if (err != VDP_STATUS_OK) {
|
||||
av_log(NULL, loglevel,
|
||||
"Error querying VDPAU surface capabilities: %s\n",
|
||||
ctx->get_error_string(err));
|
||||
goto fail;
|
||||
}
|
||||
if (supported)
|
||||
break;
|
||||
}
|
||||
if (i == FF_ARRAY_ELEMS(vdpau_formats)) {
|
||||
av_log(NULL, loglevel,
|
||||
"No supported VDPAU format for retrieving the data.\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
ctx->vdpau_format = vdpau_formats[i][0];
|
||||
ctx->pix_fmt = vdpau_formats[i][1];
|
||||
|
||||
vdpau_ctx = av_vdpau_alloc_context();
|
||||
if (!vdpau_ctx)
|
||||
goto fail;
|
||||
vdpau_ctx->render = ctx->decoder_render;
|
||||
|
||||
s->hwaccel_context = vdpau_ctx;
|
||||
|
||||
ctx->get_information_string(&vendor);
|
||||
av_log(NULL, AV_LOG_VERBOSE, "Using VDPAU -- %s -- on X11 display %s, "
|
||||
"to decode input stream #%d:%d.\n", vendor,
|
||||
display, ist->file_index, ist->st->index);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
av_log(NULL, loglevel, "VDPAU init failed for stream #%d:%d.\n",
|
||||
ist->file_index, ist->st->index);
|
||||
vdpau_uninit(s);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
int vdpau_init(AVCodecContext *s)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
|
||||
AVVDPAUContext *vdpau_ctx;
|
||||
VDPAUContext *ctx;
|
||||
VdpStatus err;
|
||||
int profile, ret;
|
||||
|
||||
if (!ist->hwaccel_ctx) {
|
||||
ret = vdpau_alloc(s);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
ctx = ist->hwaccel_ctx;
|
||||
vdpau_ctx = s->hwaccel_context;
|
||||
|
||||
ret = av_vdpau_get_profile(s, &profile);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, loglevel, "No known VDPAU decoder profile for this stream.\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
if (ctx->decoder)
|
||||
ctx->decoder_destroy(ctx->decoder);
|
||||
|
||||
err = ctx->decoder_create(ctx->device, profile,
|
||||
s->coded_width, s->coded_height,
|
||||
16, &ctx->decoder);
|
||||
if (err != VDP_STATUS_OK) {
|
||||
av_log(NULL, loglevel, "Error creating the VDPAU decoder: %s\n",
|
||||
ctx->get_error_string(err));
|
||||
return AVERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
vdpau_ctx->decoder = ctx->decoder;
|
||||
|
||||
ist->hwaccel_get_buffer = vdpau_get_buffer;
|
||||
ist->hwaccel_retrieve_data = vdpau_retrieve_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
386
ffplay.c
386
ffplay.c
@@ -28,8 +28,6 @@
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/colorspace.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
@@ -123,7 +121,6 @@ typedef struct PacketQueue {
|
||||
|
||||
typedef struct VideoPicture {
|
||||
double pts; // presentation timestamp for this picture
|
||||
double duration; // estimated duration based on frame rate
|
||||
int64_t pos; // byte position in file
|
||||
SDL_Overlay *bmp;
|
||||
int width, height; /* source height & width */
|
||||
@@ -145,8 +142,6 @@ typedef struct AudioParams {
|
||||
int channels;
|
||||
int64_t channel_layout;
|
||||
enum AVSampleFormat fmt;
|
||||
int frame_size;
|
||||
int bytes_per_sec;
|
||||
} AudioParams;
|
||||
|
||||
typedef struct Clock {
|
||||
@@ -182,8 +177,6 @@ typedef struct VideoState {
|
||||
int read_pause_return;
|
||||
AVFormatContext *ic;
|
||||
int realtime;
|
||||
int audio_finished;
|
||||
int video_finished;
|
||||
|
||||
Clock audclk;
|
||||
Clock vidclk;
|
||||
@@ -223,7 +216,6 @@ typedef struct VideoState {
|
||||
int frame_drops_early;
|
||||
int frame_drops_late;
|
||||
AVFrame *frame;
|
||||
int64_t audio_frame_next_pts;
|
||||
|
||||
enum ShowMode {
|
||||
SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
|
||||
@@ -247,8 +239,13 @@ typedef struct VideoState {
|
||||
SDL_cond *subpq_cond;
|
||||
|
||||
double frame_timer;
|
||||
double frame_last_pts;
|
||||
double frame_last_duration;
|
||||
double frame_last_dropped_pts;
|
||||
double frame_last_returned_time;
|
||||
double frame_last_filter_delay;
|
||||
int64_t frame_last_dropped_pos;
|
||||
int frame_last_dropped_serial;
|
||||
int video_stream;
|
||||
AVStream *video_st;
|
||||
PacketQueue videoq;
|
||||
@@ -308,6 +305,7 @@ static int workaround_bugs = 1;
|
||||
static int fast = 0;
|
||||
static int genpts = 0;
|
||||
static int lowres = 0;
|
||||
static int idct = FF_IDCT_AUTO;
|
||||
static int error_concealment = 3;
|
||||
static int decoder_reorder_pts = -1;
|
||||
static int autoexit;
|
||||
@@ -359,6 +357,8 @@ int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
|
||||
|
||||
static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
|
||||
{
|
||||
MyAVPacketList *pkt1;
|
||||
@@ -405,16 +405,6 @@ static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
|
||||
{
|
||||
AVPacket pkt1, *pkt = &pkt1;
|
||||
av_init_packet(pkt);
|
||||
pkt->data = NULL;
|
||||
pkt->size = 0;
|
||||
pkt->stream_index = stream_index;
|
||||
return packet_queue_put(q, pkt);
|
||||
}
|
||||
|
||||
/* packet queue handling */
|
||||
static void packet_queue_init(PacketQueue *q)
|
||||
{
|
||||
@@ -783,14 +773,6 @@ static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw,
|
||||
}
|
||||
}
|
||||
|
||||
static void free_picture(VideoPicture *vp)
|
||||
{
|
||||
if (vp->bmp) {
|
||||
SDL_FreeYUVOverlay(vp->bmp);
|
||||
vp->bmp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void free_subpicture(SubPicture *sp)
|
||||
{
|
||||
avsubtitle_free(&sp->sub);
|
||||
@@ -993,8 +975,7 @@ static void video_audio_display(VideoState *s)
|
||||
}
|
||||
av_rdft_calc(s->rdft, data[ch]);
|
||||
}
|
||||
/* Least efficient way to do this, we should of course
|
||||
* directly access it but it is more than fast enough. */
|
||||
// least efficient way to do this, we should of course directly access it but its more than fast enough
|
||||
for (y = 0; y < s->height; y++) {
|
||||
double w = 1 / sqrt(nb_freq);
|
||||
int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
|
||||
@@ -1019,6 +1000,7 @@ static void video_audio_display(VideoState *s)
|
||||
|
||||
static void stream_close(VideoState *is)
|
||||
{
|
||||
VideoPicture *vp;
|
||||
int i;
|
||||
/* XXX: use a special url_shutdown call to abort parse cleanly */
|
||||
is->abort_request = 1;
|
||||
@@ -1028,10 +1010,13 @@ static void stream_close(VideoState *is)
|
||||
packet_queue_destroy(&is->subtitleq);
|
||||
|
||||
/* free all pictures */
|
||||
for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
|
||||
free_picture(&is->pictq[i]);
|
||||
for (i = 0; i < SUBPICTURE_QUEUE_SIZE; i++)
|
||||
free_subpicture(&is->subpq[i]);
|
||||
for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
|
||||
vp = &is->pictq[i];
|
||||
if (vp->bmp) {
|
||||
SDL_FreeYUVOverlay(vp->bmp);
|
||||
vp->bmp = NULL;
|
||||
}
|
||||
}
|
||||
SDL_DestroyMutex(is->pictq_mutex);
|
||||
SDL_DestroyCond(is->pictq_cond);
|
||||
SDL_DestroyMutex(is->subpq_mutex);
|
||||
@@ -1066,24 +1051,20 @@ static void sigterm_handler(int sig)
|
||||
exit(123);
|
||||
}
|
||||
|
||||
static void set_default_window_size(VideoPicture *vp)
|
||||
{
|
||||
SDL_Rect rect;
|
||||
calculate_display_rect(&rect, 0, 0, INT_MAX, vp->height, vp);
|
||||
default_width = rect.w;
|
||||
default_height = rect.h;
|
||||
}
|
||||
|
||||
static int video_open(VideoState *is, int force_set_video_mode, VideoPicture *vp)
|
||||
{
|
||||
int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
|
||||
int w,h;
|
||||
SDL_Rect rect;
|
||||
|
||||
if (is_full_screen) flags |= SDL_FULLSCREEN;
|
||||
else flags |= SDL_RESIZABLE;
|
||||
|
||||
if (vp && vp->width)
|
||||
set_default_window_size(vp);
|
||||
if (vp && vp->width) {
|
||||
calculate_display_rect(&rect, 0, 0, INT_MAX, vp->height, vp);
|
||||
default_width = rect.w;
|
||||
default_height = rect.h;
|
||||
}
|
||||
|
||||
if (is_full_screen && fs_screen_width) {
|
||||
w = fs_screen_width;
|
||||
@@ -1294,18 +1275,6 @@ static double compute_target_delay(double delay, VideoState *is)
|
||||
return delay;
|
||||
}
|
||||
|
||||
static double vp_duration(VideoState *is, VideoPicture *vp, VideoPicture *nextvp) {
|
||||
if (vp->serial == nextvp->serial) {
|
||||
double duration = nextvp->pts - vp->pts;
|
||||
if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
|
||||
return vp->duration;
|
||||
else
|
||||
return duration;
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
static void pictq_next_picture(VideoState *is) {
|
||||
/* update queue size and signal for next picture */
|
||||
if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
|
||||
@@ -1341,12 +1310,14 @@ static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial
|
||||
set_clock(&is->vidclk, pts, serial);
|
||||
sync_clock_to_slave(&is->extclk, &is->vidclk);
|
||||
is->video_current_pos = pos;
|
||||
is->frame_last_pts = pts;
|
||||
}
|
||||
|
||||
/* called to display each frame */
|
||||
static void video_refresh(void *opaque, double *remaining_time)
|
||||
{
|
||||
VideoState *is = opaque;
|
||||
VideoPicture *vp;
|
||||
double time;
|
||||
|
||||
SubPicture *sp, *sp2;
|
||||
@@ -1369,34 +1340,37 @@ static void video_refresh(void *opaque, double *remaining_time)
|
||||
redisplay = pictq_prev_picture(is);
|
||||
retry:
|
||||
if (is->pictq_size == 0) {
|
||||
SDL_LockMutex(is->pictq_mutex);
|
||||
if (is->frame_last_dropped_pts != AV_NOPTS_VALUE && is->frame_last_dropped_pts > is->frame_last_pts) {
|
||||
update_video_pts(is, is->frame_last_dropped_pts, is->frame_last_dropped_pos, is->frame_last_dropped_serial);
|
||||
is->frame_last_dropped_pts = AV_NOPTS_VALUE;
|
||||
}
|
||||
SDL_UnlockMutex(is->pictq_mutex);
|
||||
// nothing to do, no picture to display in the queue
|
||||
} else {
|
||||
double last_duration, duration, delay;
|
||||
VideoPicture *vp, *lastvp;
|
||||
|
||||
/* dequeue the picture */
|
||||
vp = &is->pictq[is->pictq_rindex];
|
||||
lastvp = &is->pictq[(is->pictq_rindex + VIDEO_PICTURE_QUEUE_SIZE - 1) % VIDEO_PICTURE_QUEUE_SIZE];
|
||||
|
||||
if (vp->serial != is->videoq.serial) {
|
||||
pictq_next_picture(is);
|
||||
is->video_current_pos = -1;
|
||||
redisplay = 0;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (lastvp->serial != vp->serial && !redisplay)
|
||||
is->frame_timer = av_gettime() / 1000000.0;
|
||||
|
||||
if (is->paused)
|
||||
goto display;
|
||||
|
||||
/* compute nominal last_duration */
|
||||
last_duration = vp_duration(is, lastvp, vp);
|
||||
last_duration = vp->pts - is->frame_last_pts;
|
||||
if (!isnan(last_duration) && last_duration > 0 && last_duration < is->max_frame_duration) {
|
||||
/* if duration of the last frame was sane, update last_duration in video state */
|
||||
is->frame_last_duration = last_duration;
|
||||
}
|
||||
if (redisplay)
|
||||
delay = 0.0;
|
||||
else
|
||||
delay = compute_target_delay(last_duration, is);
|
||||
delay = compute_target_delay(is->frame_last_duration, is);
|
||||
|
||||
time= av_gettime()/1000000.0;
|
||||
if (time < is->frame_timer + delay && !redisplay) {
|
||||
@@ -1415,7 +1389,7 @@ retry:
|
||||
|
||||
if (is->pictq_size > 1) {
|
||||
VideoPicture *nextvp = &is->pictq[(is->pictq_rindex + 1) % VIDEO_PICTURE_QUEUE_SIZE];
|
||||
duration = vp_duration(is, vp, nextvp);
|
||||
duration = nextvp->pts - vp->pts;
|
||||
if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
|
||||
if (!redisplay)
|
||||
is->frame_drops_late++;
|
||||
@@ -1516,7 +1490,8 @@ static void alloc_picture(VideoState *is)
|
||||
|
||||
vp = &is->pictq[is->pictq_windex];
|
||||
|
||||
free_picture(vp);
|
||||
if (vp->bmp)
|
||||
SDL_FreeYUVOverlay(vp->bmp);
|
||||
|
||||
video_open(is, 0, vp);
|
||||
|
||||
@@ -1558,7 +1533,7 @@ static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
|
||||
}
|
||||
}
|
||||
|
||||
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
|
||||
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos, int serial)
|
||||
{
|
||||
VideoPicture *vp;
|
||||
|
||||
@@ -1608,7 +1583,7 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double
|
||||
}
|
||||
/* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
|
||||
if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
|
||||
while (!vp->allocated && !is->abort_request) {
|
||||
while (!vp->allocated) {
|
||||
SDL_CondWait(is->pictq_cond, is->pictq_mutex);
|
||||
}
|
||||
}
|
||||
@@ -1655,7 +1630,6 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double
|
||||
SDL_UnlockYUVOverlay(vp->bmp);
|
||||
|
||||
vp->pts = pts;
|
||||
vp->duration = duration;
|
||||
vp->pos = pos;
|
||||
vp->serial = serial;
|
||||
|
||||
@@ -1678,15 +1652,24 @@ static int get_video_frame(VideoState *is, AVFrame *frame, AVPacket *pkt, int *s
|
||||
|
||||
if (pkt->data == flush_pkt.data) {
|
||||
avcodec_flush_buffers(is->video_st->codec);
|
||||
|
||||
SDL_LockMutex(is->pictq_mutex);
|
||||
// Make sure there are no long delay timers (ideally we should just flush the queue but that's harder)
|
||||
while (is->pictq_size && !is->videoq.abort_request) {
|
||||
SDL_CondWait(is->pictq_cond, is->pictq_mutex);
|
||||
}
|
||||
is->video_current_pos = -1;
|
||||
is->frame_last_pts = AV_NOPTS_VALUE;
|
||||
is->frame_last_duration = 0;
|
||||
is->frame_timer = (double)av_gettime() / 1000000.0;
|
||||
is->frame_last_dropped_pts = AV_NOPTS_VALUE;
|
||||
SDL_UnlockMutex(is->pictq_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt) < 0)
|
||||
return 0;
|
||||
|
||||
if (!got_picture && !pkt->data)
|
||||
is->video_finished = *serial;
|
||||
|
||||
if (got_picture) {
|
||||
int ret = 1;
|
||||
double dpts = NAN;
|
||||
@@ -1705,17 +1688,23 @@ static int get_video_frame(VideoState *is, AVFrame *frame, AVPacket *pkt, int *s
|
||||
frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
|
||||
|
||||
if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
|
||||
if (frame->pts != AV_NOPTS_VALUE) {
|
||||
double diff = dpts - get_master_clock(is);
|
||||
if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
|
||||
diff - is->frame_last_filter_delay < 0 &&
|
||||
*serial == is->vidclk.serial &&
|
||||
SDL_LockMutex(is->pictq_mutex);
|
||||
if (is->frame_last_pts != AV_NOPTS_VALUE && frame->pts != AV_NOPTS_VALUE) {
|
||||
double clockdiff = get_clock(&is->vidclk) - get_master_clock(is);
|
||||
double ptsdiff = dpts - is->frame_last_pts;
|
||||
if (!isnan(clockdiff) && fabs(clockdiff) < AV_NOSYNC_THRESHOLD &&
|
||||
!isnan(ptsdiff) && ptsdiff > 0 && ptsdiff < AV_NOSYNC_THRESHOLD &&
|
||||
clockdiff + ptsdiff - is->frame_last_filter_delay < 0 &&
|
||||
is->videoq.nb_packets) {
|
||||
is->frame_last_dropped_pos = pkt->pos;
|
||||
is->frame_last_dropped_pts = dpts;
|
||||
is->frame_last_dropped_serial = *serial;
|
||||
is->frame_drops_early++;
|
||||
av_frame_unref(frame);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(is->pictq_mutex);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1727,8 +1716,7 @@ static int get_video_frame(VideoState *is, AVFrame *frame, AVPacket *pkt, int *s
|
||||
static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
|
||||
AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
|
||||
{
|
||||
int ret, i;
|
||||
int nb_filters = graph->nb_filters;
|
||||
int ret;
|
||||
AVFilterInOut *outputs = NULL, *inputs = NULL;
|
||||
|
||||
if (filtergraph) {
|
||||
@@ -1756,10 +1744,6 @@ static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Reorder the filters to ensure that inputs of the custom filters are merged first */
|
||||
for (i = 0; i < graph->nb_filters - nb_filters; i++)
|
||||
FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
|
||||
|
||||
ret = avfilter_graph_config(graph, NULL);
|
||||
fail:
|
||||
avfilter_inout_free(&outputs);
|
||||
@@ -1830,8 +1814,6 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for
|
||||
int64_t channel_layouts[2] = { 0, -1 };
|
||||
int channels[2] = { 0, -1 };
|
||||
AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
|
||||
char aresample_swr_opts[512] = "";
|
||||
AVDictionaryEntry *e = NULL;
|
||||
char asrc_args[256];
|
||||
int ret;
|
||||
|
||||
@@ -1839,12 +1821,6 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for
|
||||
if (!(is->agraph = avfilter_graph_alloc()))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
|
||||
av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
|
||||
if (strlen(aresample_swr_opts))
|
||||
aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
|
||||
av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
|
||||
|
||||
ret = snprintf(asrc_args, sizeof(asrc_args),
|
||||
"sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
|
||||
is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
|
||||
@@ -1906,11 +1882,8 @@ static int video_thread(void *arg)
|
||||
VideoState *is = arg;
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
double pts;
|
||||
double duration;
|
||||
int ret;
|
||||
int serial = 0;
|
||||
AVRational tb = is->video_st->time_base;
|
||||
AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
|
||||
|
||||
#if CONFIG_AVFILTER
|
||||
AVFilterGraph *graph = avfilter_graph_alloc();
|
||||
@@ -1925,6 +1898,7 @@ static int video_thread(void *arg)
|
||||
while (is->paused && !is->videoq.abort_request)
|
||||
SDL_Delay(10);
|
||||
|
||||
avcodec_get_frame_defaults(frame);
|
||||
av_free_packet(&pkt);
|
||||
|
||||
ret = get_video_frame(is, frame, &pkt, &serial);
|
||||
@@ -1951,6 +1925,7 @@ static int video_thread(void *arg)
|
||||
event.type = FF_QUIT_EVENT;
|
||||
event.user.data1 = is;
|
||||
SDL_PushEvent(&event);
|
||||
av_free_packet(&pkt);
|
||||
goto the_end;
|
||||
}
|
||||
filt_in = is->in_video_filter;
|
||||
@@ -1959,20 +1934,20 @@ static int video_thread(void *arg)
|
||||
last_h = frame->height;
|
||||
last_format = frame->format;
|
||||
last_serial = serial;
|
||||
frame_rate = filt_out->inputs[0]->frame_rate;
|
||||
}
|
||||
|
||||
ret = av_buffersrc_add_frame(filt_in, frame);
|
||||
if (ret < 0)
|
||||
goto the_end;
|
||||
av_frame_unref(frame);
|
||||
avcodec_get_frame_defaults(frame);
|
||||
av_free_packet(&pkt);
|
||||
|
||||
while (ret >= 0) {
|
||||
is->frame_last_returned_time = av_gettime() / 1000000.0;
|
||||
|
||||
ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
|
||||
if (ret < 0) {
|
||||
if (ret == AVERROR_EOF)
|
||||
is->video_finished = serial;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
@@ -1980,20 +1955,22 @@ static int video_thread(void *arg)
|
||||
is->frame_last_filter_delay = av_gettime() / 1000000.0 - is->frame_last_returned_time;
|
||||
if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
|
||||
is->frame_last_filter_delay = 0;
|
||||
tb = filt_out->inputs[0]->time_base;
|
||||
#endif
|
||||
duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
|
||||
pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
|
||||
ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), serial);
|
||||
|
||||
pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(filt_out->inputs[0]->time_base);
|
||||
ret = queue_picture(is, frame, pts, av_frame_get_pkt_pos(frame), serial);
|
||||
av_frame_unref(frame);
|
||||
#if CONFIG_AVFILTER
|
||||
}
|
||||
#else
|
||||
pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(is->video_st->time_base);
|
||||
ret = queue_picture(is, frame, pts, pkt.pos, serial);
|
||||
av_frame_unref(frame);
|
||||
#endif
|
||||
|
||||
if (ret < 0)
|
||||
goto the_end;
|
||||
}
|
||||
the_end:
|
||||
avcodec_flush_buffers(is->video_st->codec);
|
||||
#if CONFIG_AVFILTER
|
||||
avfilter_graph_free(&graph);
|
||||
#endif
|
||||
@@ -2068,8 +2045,6 @@ static int subtitle_thread(void *arg)
|
||||
SDL_LockMutex(is->subpq_mutex);
|
||||
is->subpq_size++;
|
||||
SDL_UnlockMutex(is->subpq_mutex);
|
||||
} else if (got_subtitle) {
|
||||
avsubtitle_free(&sp->sub);
|
||||
}
|
||||
av_free_packet(pkt);
|
||||
}
|
||||
@@ -2154,6 +2129,8 @@ static int audio_decode_frame(VideoState *is)
|
||||
int64_t dec_channel_layout;
|
||||
int got_frame;
|
||||
av_unused double audio_clock0;
|
||||
int new_packet = 0;
|
||||
int flush_complete = 0;
|
||||
int wanted_nb_samples;
|
||||
AVRational tb;
|
||||
int ret;
|
||||
@@ -2161,12 +2138,13 @@ static int audio_decode_frame(VideoState *is)
|
||||
|
||||
for (;;) {
|
||||
/* NOTE: the audio packet can contain several frames */
|
||||
while (pkt_temp->stream_index != -1 || is->audio_buf_frames_pending) {
|
||||
while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet) || is->audio_buf_frames_pending) {
|
||||
if (!is->frame) {
|
||||
if (!(is->frame = av_frame_alloc()))
|
||||
if (!(is->frame = avcodec_alloc_frame()))
|
||||
return AVERROR(ENOMEM);
|
||||
} else {
|
||||
av_frame_unref(is->frame);
|
||||
avcodec_get_frame_defaults(is->frame);
|
||||
}
|
||||
|
||||
if (is->audioq.serial != is->audio_pkt_temp_serial)
|
||||
@@ -2176,6 +2154,9 @@ static int audio_decode_frame(VideoState *is)
|
||||
return -1;
|
||||
|
||||
if (!is->audio_buf_frames_pending) {
|
||||
if (flush_complete)
|
||||
break;
|
||||
new_packet = 0;
|
||||
len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
|
||||
if (len1 < 0) {
|
||||
/* if error, we skip the frame */
|
||||
@@ -2183,32 +2164,23 @@ static int audio_decode_frame(VideoState *is)
|
||||
break;
|
||||
}
|
||||
|
||||
pkt_temp->dts =
|
||||
pkt_temp->pts = AV_NOPTS_VALUE;
|
||||
pkt_temp->data += len1;
|
||||
pkt_temp->size -= len1;
|
||||
if (pkt_temp->data && pkt_temp->size <= 0 || !pkt_temp->data && !got_frame)
|
||||
pkt_temp->stream_index = -1;
|
||||
if (!pkt_temp->data && !got_frame)
|
||||
is->audio_finished = is->audio_pkt_temp_serial;
|
||||
|
||||
if (!got_frame)
|
||||
if (!got_frame) {
|
||||
/* stop sending empty packets if the decoder is finished */
|
||||
if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)
|
||||
flush_complete = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
tb = (AVRational){1, is->frame->sample_rate};
|
||||
if (is->frame->pts != AV_NOPTS_VALUE)
|
||||
is->frame->pts = av_rescale_q(is->frame->pts, dec->time_base, tb);
|
||||
else if (is->frame->pkt_pts != AV_NOPTS_VALUE)
|
||||
is->frame->pts = av_rescale_q(is->frame->pkt_pts, is->audio_st->time_base, tb);
|
||||
else if (is->audio_frame_next_pts != AV_NOPTS_VALUE)
|
||||
#if CONFIG_AVFILTER
|
||||
is->frame->pts = av_rescale_q(is->audio_frame_next_pts, (AVRational){1, is->audio_filter_src.freq}, tb);
|
||||
#else
|
||||
is->frame->pts = av_rescale_q(is->audio_frame_next_pts, (AVRational){1, is->audio_src.freq}, tb);
|
||||
#endif
|
||||
|
||||
if (is->frame->pts != AV_NOPTS_VALUE)
|
||||
is->audio_frame_next_pts = is->frame->pts + is->frame->nb_samples;
|
||||
if (pkt_temp->pts != AV_NOPTS_VALUE)
|
||||
pkt_temp->pts += (double) is->frame->nb_samples / is->frame->sample_rate / av_q2d(is->audio_st->time_base);
|
||||
|
||||
#if CONFIG_AVFILTER
|
||||
dec_channel_layout = get_valid_channel_layout(is->frame->channel_layout, av_frame_get_channels(is->frame));
|
||||
@@ -2241,6 +2213,7 @@ static int audio_decode_frame(VideoState *is)
|
||||
|
||||
if ((ret = av_buffersrc_add_frame(is->in_audio_filter, is->frame)) < 0)
|
||||
return ret;
|
||||
av_frame_unref(is->frame);
|
||||
#endif
|
||||
}
|
||||
#if CONFIG_AVFILTER
|
||||
@@ -2249,8 +2222,6 @@ static int audio_decode_frame(VideoState *is)
|
||||
is->audio_buf_frames_pending = 0;
|
||||
continue;
|
||||
}
|
||||
if (ret == AVERROR_EOF)
|
||||
is->audio_finished = is->audio_pkt_temp_serial;
|
||||
return ret;
|
||||
}
|
||||
is->audio_buf_frames_pending = 1;
|
||||
@@ -2347,7 +2318,6 @@ static int audio_decode_frame(VideoState *is)
|
||||
if (pkt->data)
|
||||
av_free_packet(pkt);
|
||||
memset(pkt_temp, 0, sizeof(*pkt_temp));
|
||||
pkt_temp->stream_index = -1;
|
||||
|
||||
if (is->audioq.abort_request) {
|
||||
return -1;
|
||||
@@ -2357,15 +2327,13 @@ static int audio_decode_frame(VideoState *is)
|
||||
SDL_CondSignal(is->continue_read_thread);
|
||||
|
||||
/* read next packet */
|
||||
if ((packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0)
|
||||
if ((new_packet = packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0)
|
||||
return -1;
|
||||
|
||||
if (pkt->data == flush_pkt.data) {
|
||||
avcodec_flush_buffers(dec);
|
||||
flush_complete = 0;
|
||||
is->audio_buf_frames_pending = 0;
|
||||
is->audio_frame_next_pts = AV_NOPTS_VALUE;
|
||||
if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek)
|
||||
is->audio_frame_next_pts = is->audio_st->start_time;
|
||||
}
|
||||
|
||||
*pkt_temp = *pkt;
|
||||
@@ -2377,6 +2345,8 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
|
||||
{
|
||||
VideoState *is = opaque;
|
||||
int audio_size, len1;
|
||||
int bytes_per_sec;
|
||||
int frame_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, 1, is->audio_tgt.fmt, 1);
|
||||
|
||||
audio_callback_time = av_gettime();
|
||||
|
||||
@@ -2386,7 +2356,7 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
|
||||
if (audio_size < 0) {
|
||||
/* if error, just output silence */
|
||||
is->audio_buf = is->silence_buf;
|
||||
is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
|
||||
is->audio_buf_size = sizeof(is->silence_buf) / frame_size * frame_size;
|
||||
} else {
|
||||
if (is->show_mode != SHOW_MODE_VIDEO)
|
||||
update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
|
||||
@@ -2402,10 +2372,11 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
|
||||
stream += len1;
|
||||
is->audio_buf_index += len1;
|
||||
}
|
||||
bytes_per_sec = is->audio_tgt.freq * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
|
||||
is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
|
||||
/* Let's assume the audio driver that is used by SDL has two periods. */
|
||||
if (!isnan(is->audio_clock)) {
|
||||
set_clock_at(&is->audclk, is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / is->audio_tgt.bytes_per_sec, is->audio_clock_serial, audio_callback_time / 1000000.0);
|
||||
set_clock_at(&is->audclk, is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / bytes_per_sec, is->audio_clock_serial, audio_callback_time / 1000000.0);
|
||||
sync_clock_to_slave(&is->extclk, &is->audclk);
|
||||
}
|
||||
}
|
||||
@@ -2414,7 +2385,7 @@ static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb
|
||||
{
|
||||
SDL_AudioSpec wanted_spec, spec;
|
||||
const char *env;
|
||||
static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
|
||||
const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
|
||||
|
||||
env = SDL_getenv("SDL_AUDIO_CHANNELS");
|
||||
if (env) {
|
||||
@@ -2464,12 +2435,6 @@ static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb
|
||||
audio_hw_params->freq = spec.freq;
|
||||
audio_hw_params->channel_layout = wanted_channel_layout;
|
||||
audio_hw_params->channels = spec.channels;
|
||||
audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
|
||||
audio_hw_params->bytes_per_sec = av_samples_get_buffer_size(NULL, audio_hw_params->channels, audio_hw_params->freq, audio_hw_params->fmt, 1);
|
||||
if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
|
||||
return -1;
|
||||
}
|
||||
return spec.size;
|
||||
}
|
||||
|
||||
@@ -2485,7 +2450,6 @@ static int stream_component_open(VideoState *is, int stream_index)
|
||||
int sample_rate, nb_channels;
|
||||
int64_t channel_layout;
|
||||
int ret;
|
||||
int stream_lowres = lowres;
|
||||
|
||||
if (stream_index < 0 || stream_index >= ic->nb_streams)
|
||||
return -1;
|
||||
@@ -2510,15 +2474,16 @@ static int stream_component_open(VideoState *is, int stream_index)
|
||||
|
||||
avctx->codec_id = codec->id;
|
||||
avctx->workaround_bugs = workaround_bugs;
|
||||
if(stream_lowres > av_codec_get_max_lowres(codec)){
|
||||
avctx->lowres = lowres;
|
||||
if(avctx->lowres > codec->max_lowres){
|
||||
av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
|
||||
av_codec_get_max_lowres(codec));
|
||||
stream_lowres = av_codec_get_max_lowres(codec);
|
||||
codec->max_lowres);
|
||||
avctx->lowres= codec->max_lowres;
|
||||
}
|
||||
av_codec_set_lowres(avctx, stream_lowres);
|
||||
avctx->idct_algo = idct;
|
||||
avctx->error_concealment = error_concealment;
|
||||
|
||||
if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
|
||||
if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
|
||||
if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
|
||||
if(codec->capabilities & CODEC_CAP_DR1)
|
||||
avctx->flags |= CODEC_FLAG_EMU_EDGE;
|
||||
@@ -2526,8 +2491,8 @@ static int stream_component_open(VideoState *is, int stream_index)
|
||||
opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
|
||||
if (!av_dict_get(opts, "threads", NULL, 0))
|
||||
av_dict_set(&opts, "threads", "auto", 0);
|
||||
if (stream_lowres)
|
||||
av_dict_set(&opts, "lowres", av_asprintf("%d", stream_lowres), AV_DICT_DONT_STRDUP_VAL);
|
||||
if (avctx->lowres)
|
||||
av_dict_set(&opts, "lowres", av_asprintf("%d", avctx->lowres), AV_DICT_DONT_STRDUP_VAL);
|
||||
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
|
||||
av_dict_set(&opts, "refcounted_frames", "1", 0);
|
||||
if (avcodec_open2(avctx, codec, &opts) < 0)
|
||||
@@ -2574,11 +2539,10 @@ static int stream_component_open(VideoState *is, int stream_index)
|
||||
is->audio_diff_avg_count = 0;
|
||||
/* since we do not have a precise anough audio fifo fullness,
|
||||
we correct audio sync only if larger than this threshold */
|
||||
is->audio_diff_threshold = 2.0 * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec;
|
||||
is->audio_diff_threshold = 2.0 * is->audio_hw_buf_size / av_samples_get_buffer_size(NULL, is->audio_tgt.channels, is->audio_tgt.freq, is->audio_tgt.fmt, 1);
|
||||
|
||||
memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
|
||||
memset(&is->audio_pkt_temp, 0, sizeof(is->audio_pkt_temp));
|
||||
is->audio_pkt_temp.stream_index = -1;
|
||||
|
||||
is->audio_stream = stream_index;
|
||||
is->audio_st = ic->streams[stream_index];
|
||||
@@ -2819,13 +2783,6 @@ static int read_thread(void *arg)
|
||||
}
|
||||
|
||||
is->show_mode = show_mode;
|
||||
if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
|
||||
AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
|
||||
AVCodecContext *avctx = st->codec;
|
||||
VideoPicture vp = {.width = avctx->width, .height = avctx->height, .sar = av_guess_sample_aspect_ratio(ic, st, NULL)};
|
||||
if (vp.width)
|
||||
set_default_window_size(&vp);
|
||||
}
|
||||
|
||||
/* open the streams */
|
||||
if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
|
||||
@@ -2844,8 +2801,7 @@ static int read_thread(void *arg)
|
||||
}
|
||||
|
||||
if (is->video_stream < 0 && is->audio_stream < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
|
||||
is->filename);
|
||||
av_log(NULL, AV_LOG_FATAL, "%s: could not open codecs\n", is->filename);
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
@@ -2915,7 +2871,6 @@ static int read_thread(void *arg)
|
||||
if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
|
||||
goto fail;
|
||||
packet_queue_put(&is->videoq, ©);
|
||||
packet_queue_put_nullpacket(&is->videoq, is->video_stream);
|
||||
}
|
||||
is->queue_attachments_req = 0;
|
||||
}
|
||||
@@ -2933,24 +2888,30 @@ static int read_thread(void *arg)
|
||||
SDL_UnlockMutex(wait_mutex);
|
||||
continue;
|
||||
}
|
||||
if (!is->paused &&
|
||||
(!is->audio_st || is->audio_finished == is->audioq.serial) &&
|
||||
(!is->video_st || (is->video_finished == is->videoq.serial && is->pictq_size == 0))) {
|
||||
if (loop != 1 && (!loop || --loop)) {
|
||||
stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
|
||||
} else if (autoexit) {
|
||||
ret = AVERROR_EOF;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (eof) {
|
||||
if (is->video_stream >= 0)
|
||||
packet_queue_put_nullpacket(&is->videoq, is->video_stream);
|
||||
if (is->audio_stream >= 0)
|
||||
packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
|
||||
if (is->subtitle_stream >= 0)
|
||||
packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
|
||||
if (is->video_stream >= 0) {
|
||||
av_init_packet(pkt);
|
||||
pkt->data = NULL;
|
||||
pkt->size = 0;
|
||||
pkt->stream_index = is->video_stream;
|
||||
packet_queue_put(&is->videoq, pkt);
|
||||
}
|
||||
if (is->audio_stream >= 0) {
|
||||
av_init_packet(pkt);
|
||||
pkt->data = NULL;
|
||||
pkt->size = 0;
|
||||
pkt->stream_index = is->audio_stream;
|
||||
packet_queue_put(&is->audioq, pkt);
|
||||
}
|
||||
SDL_Delay(10);
|
||||
if (is->audioq.size + is->videoq.size + is->subtitleq.size == 0) {
|
||||
if (loop != 1 && (!loop || --loop)) {
|
||||
stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
|
||||
} else if (autoexit) {
|
||||
ret = AVERROR_EOF;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
eof=0;
|
||||
continue;
|
||||
}
|
||||
@@ -3057,8 +3018,6 @@ static void stream_cycle_channel(VideoState *is, int codec_type)
|
||||
int start_index, stream_index;
|
||||
int old_index;
|
||||
AVStream *st;
|
||||
AVProgram *p = NULL;
|
||||
int nb_streams = is->ic->nb_streams;
|
||||
|
||||
if (codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
start_index = is->last_video_stream;
|
||||
@@ -3071,22 +3030,8 @@ static void stream_cycle_channel(VideoState *is, int codec_type)
|
||||
old_index = is->subtitle_stream;
|
||||
}
|
||||
stream_index = start_index;
|
||||
|
||||
if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
|
||||
p = av_find_program_from_stream(ic, NULL, is->video_stream);
|
||||
if (p) {
|
||||
nb_streams = p->nb_stream_indexes;
|
||||
for (start_index = 0; start_index < nb_streams; start_index++)
|
||||
if (p->stream_index[start_index] == stream_index)
|
||||
break;
|
||||
if (start_index == nb_streams)
|
||||
start_index = -1;
|
||||
stream_index = start_index;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (++stream_index >= nb_streams)
|
||||
if (++stream_index >= is->ic->nb_streams)
|
||||
{
|
||||
if (codec_type == AVMEDIA_TYPE_SUBTITLE)
|
||||
{
|
||||
@@ -3100,7 +3045,7 @@ static void stream_cycle_channel(VideoState *is, int codec_type)
|
||||
}
|
||||
if (stream_index == start_index)
|
||||
return;
|
||||
st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
|
||||
st = ic->streams[stream_index];
|
||||
if (st->codec->codec_type == codec_type) {
|
||||
/* check that parameters are OK */
|
||||
switch (codec_type) {
|
||||
@@ -3118,8 +3063,6 @@ static void stream_cycle_channel(VideoState *is, int codec_type)
|
||||
}
|
||||
}
|
||||
the_end:
|
||||
if (p && stream_index != -1)
|
||||
stream_index = p->stream_index[stream_index];
|
||||
stream_component_close(is, old_index);
|
||||
stream_component_open(is, stream_index);
|
||||
}
|
||||
@@ -3170,33 +3113,6 @@ static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
|
||||
}
|
||||
}
|
||||
|
||||
static void seek_chapter(VideoState *is, int incr)
|
||||
{
|
||||
int64_t pos = get_master_clock(is) * AV_TIME_BASE;
|
||||
int i;
|
||||
|
||||
if (!is->ic->nb_chapters)
|
||||
return;
|
||||
|
||||
/* find the current chapter */
|
||||
for (i = 0; i < is->ic->nb_chapters; i++) {
|
||||
AVChapter *ch = is->ic->chapters[i];
|
||||
if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i += incr;
|
||||
i = FFMAX(i, 0);
|
||||
if (i >= is->ic->nb_chapters)
|
||||
return;
|
||||
|
||||
av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
|
||||
stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
|
||||
AV_TIME_BASE_Q), 0, 0);
|
||||
}
|
||||
|
||||
/* handle an event sent by the GUI */
|
||||
static void event_loop(VideoState *cur_stream)
|
||||
{
|
||||
@@ -3234,11 +3150,6 @@ static void event_loop(VideoState *cur_stream)
|
||||
case SDLK_v:
|
||||
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
|
||||
break;
|
||||
case SDLK_c:
|
||||
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
|
||||
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
|
||||
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
|
||||
break;
|
||||
case SDLK_t:
|
||||
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
|
||||
break;
|
||||
@@ -3246,19 +3157,11 @@ static void event_loop(VideoState *cur_stream)
|
||||
toggle_audio_display(cur_stream);
|
||||
break;
|
||||
case SDLK_PAGEUP:
|
||||
if (cur_stream->ic->nb_chapters <= 1) {
|
||||
incr = 600.0;
|
||||
goto do_seek;
|
||||
}
|
||||
seek_chapter(cur_stream, 1);
|
||||
break;
|
||||
incr = 600.0;
|
||||
goto do_seek;
|
||||
case SDLK_PAGEDOWN:
|
||||
if (cur_stream->ic->nb_chapters <= 1) {
|
||||
incr = -600.0;
|
||||
goto do_seek;
|
||||
}
|
||||
seek_chapter(cur_stream, -1);
|
||||
break;
|
||||
incr = -600.0;
|
||||
goto do_seek;
|
||||
case SDLK_LEFT:
|
||||
incr = -10.0;
|
||||
goto do_seek;
|
||||
@@ -3499,6 +3402,7 @@ static const OptionDef options[] = {
|
||||
{ "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
|
||||
{ "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
|
||||
{ "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
|
||||
{ "idct", OPT_INT | HAS_ARG | OPT_EXPERT, { &idct }, "set idct algo", "algo" },
|
||||
{ "ec", OPT_INT | HAS_ARG | OPT_EXPERT, { &error_concealment }, "set error concealment options", "bit_mask" },
|
||||
{ "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
|
||||
{ "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
|
||||
@@ -3548,10 +3452,9 @@ void show_help_default(const char *opt, const char *arg)
|
||||
"q, ESC quit\n"
|
||||
"f toggle full screen\n"
|
||||
"p, SPC pause\n"
|
||||
"a cycle audio channel in the current program\n"
|
||||
"a cycle audio channel\n"
|
||||
"v cycle video channel\n"
|
||||
"t cycle subtitle channel in the current program\n"
|
||||
"c cycle program\n"
|
||||
"t cycle subtitle channel\n"
|
||||
"w show audio waves\n"
|
||||
"s activate frame-step mode\n"
|
||||
"left/right seek backward/forward 10 seconds\n"
|
||||
@@ -3591,6 +3494,7 @@ int main(int argc, char **argv)
|
||||
parse_loglevel(argc, argv, options);
|
||||
|
||||
/* register all codecs, demux and protocols */
|
||||
avcodec_register_all();
|
||||
#if CONFIG_AVDEVICE
|
||||
avdevice_register_all();
|
||||
#endif
|
||||
|
||||
460
ffserver.c
460
ffserver.c
@@ -36,7 +36,6 @@
|
||||
#include "libavformat/network.h"
|
||||
#include "libavformat/os_support.h"
|
||||
#include "libavformat/rtpdec.h"
|
||||
#include "libavformat/rtpproto.h"
|
||||
#include "libavformat/rtsp.h"
|
||||
#include "libavformat/avio_internal.h"
|
||||
#include "libavformat/internal.h"
|
||||
@@ -48,7 +47,6 @@
|
||||
#include "libavutil/dict.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/random_seed.h"
|
||||
#include "libavutil/parseutils.h"
|
||||
#include "libavutil/opt.h"
|
||||
@@ -65,6 +63,9 @@
|
||||
#include <time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#if HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include "cmdutils.h"
|
||||
|
||||
@@ -216,7 +217,6 @@ typedef struct FFStream {
|
||||
struct FFStream *feed; /* feed we are using (can be null if
|
||||
coming from file) */
|
||||
AVDictionary *in_opts; /* input parameters */
|
||||
AVDictionary *metadata; /* metadata to set on the stream */
|
||||
AVInputFormat *ifmt; /* if non NULL, force input format */
|
||||
AVOutputFormat *fmt;
|
||||
IPAddressACL *acl;
|
||||
@@ -229,6 +229,10 @@ typedef struct FFStream {
|
||||
int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
|
||||
char feed_filename[1024]; /* file name of the feed storage, or
|
||||
input file name for a stream */
|
||||
char author[512];
|
||||
char title[512];
|
||||
char copyright[512];
|
||||
char comment[512];
|
||||
pid_t pid; /* Of ffmpeg process */
|
||||
time_t pid_start; /* Of ffmpeg process */
|
||||
char **child_argv;
|
||||
@@ -287,7 +291,8 @@ static void rtsp_cmd_describe(HTTPContext *c, const char *url);
|
||||
static void rtsp_cmd_options(HTTPContext *c, const char *url);
|
||||
static void rtsp_cmd_setup(HTTPContext *c, const char *url, RTSPMessageHeader *h);
|
||||
static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h);
|
||||
static void rtsp_cmd_interrupt(HTTPContext *c, const char *url, RTSPMessageHeader *h, int pause_only);
|
||||
static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h);
|
||||
static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h);
|
||||
|
||||
/* SDP handling */
|
||||
static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
|
||||
@@ -505,9 +510,8 @@ static void start_children(FFStream *feed)
|
||||
char *slash;
|
||||
int i;
|
||||
|
||||
/* replace "ffserver" with "ffmpeg" in the path of current
|
||||
* program. Ignore user provided path */
|
||||
av_strlcpy(pathname, my_program_name, sizeof(pathname));
|
||||
|
||||
slash = strrchr(pathname, '/');
|
||||
if (!slash)
|
||||
slash = pathname;
|
||||
@@ -627,16 +631,17 @@ static void start_multicast(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* change state to send data */
|
||||
rtp_c->state = HTTPSTATE_SEND_DATA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* main loop of the HTTP server */
|
||||
/* main loop of the http server */
|
||||
static int http_server(void)
|
||||
{
|
||||
int server_fd = 0, rtsp_server_fd = 0;
|
||||
int ret, delay;
|
||||
int ret, delay, delay1;
|
||||
struct pollfd *poll_table, *poll_entry;
|
||||
HTTPContext *c, *c_next;
|
||||
|
||||
@@ -700,19 +705,18 @@ static int http_server(void)
|
||||
case HTTPSTATE_SEND_DATA:
|
||||
case HTTPSTATE_SEND_DATA_TRAILER:
|
||||
if (!c->is_packetized) {
|
||||
/* for TCP, we output as much as we can
|
||||
* (may need to put a limit) */
|
||||
/* for TCP, we output as much as we can (may need to put a limit) */
|
||||
c->poll_entry = poll_entry;
|
||||
poll_entry->fd = fd;
|
||||
poll_entry->events = POLLOUT;
|
||||
poll_entry++;
|
||||
} else {
|
||||
/* when ffserver is doing the timing, we work by
|
||||
looking at which packet needs to be sent every
|
||||
looking at which packet need to be sent every
|
||||
10 ms */
|
||||
/* one tick wait XXX: 10 ms assumed */
|
||||
if (delay > 10)
|
||||
delay = 10;
|
||||
delay1 = 10; /* one tick wait XXX: 10 ms assumed */
|
||||
if (delay1 < delay)
|
||||
delay = delay1;
|
||||
}
|
||||
break;
|
||||
case HTTPSTATE_WAIT_REQUEST:
|
||||
@@ -752,8 +756,8 @@ static int http_server(void)
|
||||
for(c = first_http_ctx; c != NULL; c = c_next) {
|
||||
c_next = c->next;
|
||||
if (handle_connection(c) < 0) {
|
||||
log_connection(c);
|
||||
/* close and free the connection */
|
||||
log_connection(c);
|
||||
close_connection(c);
|
||||
}
|
||||
}
|
||||
@@ -1002,7 +1006,9 @@ static int handle_connection(HTTPContext *c)
|
||||
if (len < 0) {
|
||||
if (ff_neterrno() != AVERROR(EAGAIN) &&
|
||||
ff_neterrno() != AVERROR(EINTR)) {
|
||||
goto close_connection;
|
||||
/* error : close connection */
|
||||
av_freep(&c->pb_buffer);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
c->buffer_ptr += len;
|
||||
@@ -1014,8 +1020,7 @@ static int handle_connection(HTTPContext *c)
|
||||
/* if error, exit */
|
||||
if (c->http_error)
|
||||
return -1;
|
||||
/* all the buffer was sent : synchronize to the incoming
|
||||
* stream */
|
||||
/* all the buffer was sent : synchronize to the incoming stream */
|
||||
c->state = HTTPSTATE_SEND_DATA_HEADER;
|
||||
c->buffer_ptr = c->buffer_end = c->buffer;
|
||||
}
|
||||
@@ -1026,7 +1031,7 @@ static int handle_connection(HTTPContext *c)
|
||||
case HTTPSTATE_SEND_DATA_HEADER:
|
||||
case HTTPSTATE_SEND_DATA_TRAILER:
|
||||
/* for packetized output, we consider we can always write (the
|
||||
input streams set the speed). It may be better to verify
|
||||
input streams sets the speed). It may be better to verify
|
||||
that we do not rely too much on the kernel queues */
|
||||
if (!c->is_packetized) {
|
||||
if (c->poll_entry->revents & (POLLERR | POLLHUP))
|
||||
@@ -1060,8 +1065,10 @@ static int handle_connection(HTTPContext *c)
|
||||
break;
|
||||
|
||||
case RTSPSTATE_SEND_REPLY:
|
||||
if (c->poll_entry->revents & (POLLERR | POLLHUP))
|
||||
goto close_connection;
|
||||
if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
|
||||
av_freep(&c->pb_buffer);
|
||||
return -1;
|
||||
}
|
||||
/* no need to write if no events */
|
||||
if (!(c->poll_entry->revents & POLLOUT))
|
||||
return 0;
|
||||
@@ -1069,7 +1076,9 @@ static int handle_connection(HTTPContext *c)
|
||||
if (len < 0) {
|
||||
if (ff_neterrno() != AVERROR(EAGAIN) &&
|
||||
ff_neterrno() != AVERROR(EINTR)) {
|
||||
goto close_connection;
|
||||
/* error : close connection */
|
||||
av_freep(&c->pb_buffer);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
c->buffer_ptr += len;
|
||||
@@ -1114,10 +1123,6 @@ static int handle_connection(HTTPContext *c)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
close_connection:
|
||||
av_freep(&c->pb_buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int extract_rates(char *rates, int ratelen, const char *request)
|
||||
@@ -1456,7 +1461,7 @@ static int validate_acl(FFStream *stream, HTTPContext *c)
|
||||
}
|
||||
|
||||
/* compute the real filename of a file by matching it without its
|
||||
extensions to all the stream's filenames */
|
||||
extensions to all the stream filenames */
|
||||
static void compute_real_filename(char *filename, int max_size)
|
||||
{
|
||||
char file1[1024];
|
||||
@@ -1490,7 +1495,7 @@ enum RedirType {
|
||||
REDIR_SDP,
|
||||
};
|
||||
|
||||
/* parse HTTP request and prepare header */
|
||||
/* parse http request and prepare header */
|
||||
static int http_parse_request(HTTPContext *c)
|
||||
{
|
||||
const char *p;
|
||||
@@ -1861,7 +1866,7 @@ static int http_parse_request(HTTPContext *c)
|
||||
goto send_error;
|
||||
}
|
||||
|
||||
/* prepare HTTP header */
|
||||
/* prepare http header */
|
||||
c->buffer[0] = 0;
|
||||
av_strlcatf(c->buffer, c->buffer_size, "HTTP/1.0 200 OK\r\n");
|
||||
mime_type = c->stream->fmt->mime_type;
|
||||
@@ -1940,7 +1945,7 @@ static void compute_status(HTTPContext *c)
|
||||
}
|
||||
|
||||
avio_printf(pb, "HTTP/1.0 200 OK\r\n");
|
||||
avio_printf(pb, "Content-type: text/html\r\n");
|
||||
avio_printf(pb, "Content-type: %s\r\n", "text/html");
|
||||
avio_printf(pb, "Pragma: no-cache\r\n");
|
||||
avio_printf(pb, "\r\n");
|
||||
|
||||
@@ -2179,10 +2184,8 @@ static int open_input_stream(HTTPContext *c, const char *info)
|
||||
buf_size = FFM_PACKET_SIZE;
|
||||
/* compute position (absolute time) */
|
||||
if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
|
||||
if ((ret = av_parse_time(&stream_pos, buf, 0)) < 0) {
|
||||
http_log("Invalid date specification '%s' for stream\n", buf);
|
||||
if ((ret = av_parse_time(&stream_pos, buf, 0)) < 0)
|
||||
return ret;
|
||||
}
|
||||
} else if (av_find_info_tag(buf, sizeof(buf), "buffer", info)) {
|
||||
int prebuffer = strtol(buf, 0, 10);
|
||||
stream_pos = av_gettime() - prebuffer * (int64_t)1000000;
|
||||
@@ -2193,22 +2196,18 @@ static int open_input_stream(HTTPContext *c, const char *info)
|
||||
buf_size = 0;
|
||||
/* compute position (relative time) */
|
||||
if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
|
||||
if ((ret = av_parse_time(&stream_pos, buf, 1)) < 0) {
|
||||
http_log("Invalid date specification '%s' for stream\n", buf);
|
||||
if ((ret = av_parse_time(&stream_pos, buf, 1)) < 0)
|
||||
return ret;
|
||||
}
|
||||
} else
|
||||
stream_pos = 0;
|
||||
}
|
||||
if (!input_filename[0]) {
|
||||
http_log("No filename was specified for stream\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if (input_filename[0] == '\0')
|
||||
return -1;
|
||||
|
||||
/* open stream */
|
||||
if ((ret = avformat_open_input(&s, input_filename, c->stream->ifmt, &c->stream->in_opts)) < 0) {
|
||||
http_log("Could not open input '%s': %s\n", input_filename, av_err2str(ret));
|
||||
return ret;
|
||||
http_log("could not open %s: %d\n", input_filename, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set buffer size */
|
||||
@@ -2216,15 +2215,14 @@ static int open_input_stream(HTTPContext *c, const char *info)
|
||||
|
||||
s->flags |= AVFMT_FLAG_GENPTS;
|
||||
c->fmt_in = s;
|
||||
if (strcmp(s->iformat->name, "ffm") &&
|
||||
(ret = avformat_find_stream_info(c->fmt_in, NULL)) < 0) {
|
||||
http_log("Could not find stream info for input '%s'\n", input_filename);
|
||||
if (strcmp(s->iformat->name, "ffm") && avformat_find_stream_info(c->fmt_in, NULL) < 0) {
|
||||
http_log("Could not find stream info '%s'\n", input_filename);
|
||||
avformat_close_input(&s);
|
||||
return ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* choose stream as clock source (we favor the video stream if
|
||||
* present) for packet sending */
|
||||
/* choose stream as clock source (we favorize video stream if
|
||||
present) for packet sending */
|
||||
c->pts_stream_index = 0;
|
||||
for(i=0;i<c->stream->nb_streams;i++) {
|
||||
if (c->pts_stream_index == 0 &&
|
||||
@@ -2273,10 +2271,12 @@ static int http_prepare_data(HTTPContext *c)
|
||||
av_freep(&c->pb_buffer);
|
||||
switch(c->state) {
|
||||
case HTTPSTATE_SEND_DATA_HEADER:
|
||||
ctx = avformat_alloc_context();
|
||||
c->fmt_ctx = *ctx;
|
||||
av_freep(&ctx);
|
||||
av_dict_copy(&(c->fmt_ctx.metadata), c->stream->metadata, 0);
|
||||
memset(&c->fmt_ctx, 0, sizeof(c->fmt_ctx));
|
||||
av_dict_set(&c->fmt_ctx.metadata, "author" , c->stream->author , 0);
|
||||
av_dict_set(&c->fmt_ctx.metadata, "comment" , c->stream->comment , 0);
|
||||
av_dict_set(&c->fmt_ctx.metadata, "copyright", c->stream->copyright, 0);
|
||||
av_dict_set(&c->fmt_ctx.metadata, "title" , c->stream->title , 0);
|
||||
|
||||
c->fmt_ctx.streams = av_mallocz(sizeof(AVStream *) * c->stream->nb_streams);
|
||||
|
||||
for(i=0;i<c->stream->nb_streams;i++) {
|
||||
@@ -2291,8 +2291,8 @@ static int http_prepare_data(HTTPContext *c)
|
||||
|
||||
*(c->fmt_ctx.streams[i]) = *src;
|
||||
c->fmt_ctx.streams[i]->priv_data = 0;
|
||||
/* XXX: should be done in AVStream, not in codec */
|
||||
c->fmt_ctx.streams[i]->codec->frame_number = 0;
|
||||
c->fmt_ctx.streams[i]->codec->frame_number = 0; /* XXX: should be done in
|
||||
AVStream, not in codec */
|
||||
}
|
||||
/* set output format parameters */
|
||||
c->fmt_ctx.oformat = c->stream->fmt;
|
||||
@@ -2310,14 +2310,13 @@ static int http_prepare_data(HTTPContext *c)
|
||||
/*
|
||||
* HACK to avoid mpeg ps muxer to spit many underflow errors
|
||||
* Default value from FFmpeg
|
||||
* Try to set it using configuration option
|
||||
* Try to set it use configuration option
|
||||
*/
|
||||
c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
|
||||
|
||||
if ((ret = avformat_write_header(&c->fmt_ctx, NULL)) < 0) {
|
||||
http_log("Error writing output header for stream '%s': %s\n",
|
||||
c->stream->filename, av_err2str(ret));
|
||||
return ret;
|
||||
if (avformat_write_header(&c->fmt_ctx, NULL) < 0) {
|
||||
http_log("Error writing output header\n");
|
||||
return -1;
|
||||
}
|
||||
av_dict_free(&c->fmt_ctx.metadata);
|
||||
|
||||
@@ -2361,7 +2360,7 @@ static int http_prepare_data(HTTPContext *c)
|
||||
goto redo;
|
||||
} else {
|
||||
no_loop:
|
||||
/* must send trailer now because EOF or error */
|
||||
/* must send trailer now because eof or error */
|
||||
c->state = HTTPSTATE_SEND_DATA_TRAILER;
|
||||
}
|
||||
}
|
||||
@@ -2403,8 +2402,8 @@ static int http_prepare_data(HTTPContext *c)
|
||||
send_it:
|
||||
ist = c->fmt_in->streams[source_index];
|
||||
/* specific handling for RTP: we use several
|
||||
* output streams (one for each RTP connection).
|
||||
* XXX: need more abstract handling */
|
||||
output stream (one for each RTP
|
||||
connection). XXX: need more abstract handling */
|
||||
if (c->is_packetized) {
|
||||
/* compute send time and duration */
|
||||
c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q);
|
||||
@@ -2448,9 +2447,8 @@ static int http_prepare_data(HTTPContext *c)
|
||||
if (pkt.pts != AV_NOPTS_VALUE)
|
||||
pkt.pts = av_rescale_q(pkt.pts, ist->time_base, ost->time_base);
|
||||
pkt.duration = av_rescale_q(pkt.duration, ist->time_base, ost->time_base);
|
||||
if ((ret = av_write_frame(ctx, &pkt)) < 0) {
|
||||
http_log("Error writing frame to output for stream '%s': %s\n",
|
||||
c->stream->filename, av_err2str(ret));
|
||||
if (av_write_frame(ctx, &pkt) < 0) {
|
||||
http_log("Error writing frame to output\n");
|
||||
c->state = HTTPSTATE_SEND_DATA_TRAILER;
|
||||
}
|
||||
|
||||
@@ -2494,7 +2492,7 @@ static int http_prepare_data(HTTPContext *c)
|
||||
|
||||
/* should convert the format at the same time */
|
||||
/* send data starting at c->buffer_ptr to the output connection
|
||||
* (either UDP or TCP) */
|
||||
(either UDP or TCP connection) */
|
||||
static int http_send_data(HTTPContext *c)
|
||||
{
|
||||
int len, ret;
|
||||
@@ -2617,26 +2615,19 @@ static int http_send_data(HTTPContext *c)
|
||||
static int http_start_receive_data(HTTPContext *c)
|
||||
{
|
||||
int fd;
|
||||
int ret;
|
||||
|
||||
if (c->stream->feed_opened) {
|
||||
http_log("Stream feed '%s' was not opened\n", c->stream->feed_filename);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if (c->stream->feed_opened)
|
||||
return -1;
|
||||
|
||||
/* Don't permit writing to this one */
|
||||
if (c->stream->readonly) {
|
||||
http_log("Cannot write to read-only file '%s'\n", c->stream->feed_filename);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if (c->stream->readonly)
|
||||
return -1;
|
||||
|
||||
/* open feed */
|
||||
fd = open(c->stream->feed_filename, O_RDWR);
|
||||
if (fd < 0) {
|
||||
ret = AVERROR(errno);
|
||||
http_log("Could not open feed file '%s': %s\n",
|
||||
c->stream->feed_filename, strerror(errno));
|
||||
return ret;
|
||||
http_log("Error opening feeder file: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
c->feed_fd = fd;
|
||||
|
||||
@@ -2645,19 +2636,13 @@ static int http_start_receive_data(HTTPContext *c)
|
||||
ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE);
|
||||
http_log("Truncating feed file '%s'\n", c->stream->feed_filename);
|
||||
if (ftruncate(c->feed_fd, FFM_PACKET_SIZE) < 0) {
|
||||
ret = AVERROR(errno);
|
||||
http_log("Error truncating feed file '%s': %s\n",
|
||||
c->stream->feed_filename, strerror(errno));
|
||||
return ret;
|
||||
http_log("Error truncating feed file: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
ret = ffm_read_write_index(fd);
|
||||
if (ret < 0) {
|
||||
http_log("Error reading write index from feed file '%s': %s\n",
|
||||
c->stream->feed_filename, strerror(errno));
|
||||
return ret;
|
||||
} else {
|
||||
c->stream->feed_write_index = ret;
|
||||
if ((c->stream->feed_write_index = ffm_read_write_index(fd)) < 0) {
|
||||
http_log("Error reading write index from feed file: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2961,9 +2946,9 @@ static int rtsp_parse_request(HTTPContext *c)
|
||||
else if (!strcmp(cmd, "PLAY"))
|
||||
rtsp_cmd_play(c, url, header);
|
||||
else if (!strcmp(cmd, "PAUSE"))
|
||||
rtsp_cmd_interrupt(c, url, header, 1);
|
||||
rtsp_cmd_pause(c, url, header);
|
||||
else if (!strcmp(cmd, "TEARDOWN"))
|
||||
rtsp_cmd_interrupt(c, url, header, 0);
|
||||
rtsp_cmd_teardown(c, url, header);
|
||||
else
|
||||
rtsp_reply_error(c, RTSP_STATUS_METHOD);
|
||||
|
||||
@@ -2986,7 +2971,6 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
|
||||
AVFormatContext *avc;
|
||||
AVStream *avs = NULL;
|
||||
AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
|
||||
AVDictionaryEntry *entry = av_dict_get(stream->metadata, "title", NULL, 0);
|
||||
int i;
|
||||
|
||||
avc = avformat_alloc_context();
|
||||
@@ -2995,7 +2979,7 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
|
||||
}
|
||||
avc->oformat = rtp_format;
|
||||
av_dict_set(&avc->metadata, "title",
|
||||
entry ? entry->value : "No Title", 0);
|
||||
stream->title[0] ? stream->title : "No Title", 0);
|
||||
avc->nb_streams = stream->nb_streams;
|
||||
if (stream->is_multicast) {
|
||||
snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
|
||||
@@ -3317,7 +3301,7 @@ static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h)
|
||||
avio_printf(c->pb, "\r\n");
|
||||
}
|
||||
|
||||
static void rtsp_cmd_interrupt(HTTPContext *c, const char *url, RTSPMessageHeader *h, int pause_only)
|
||||
static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h)
|
||||
{
|
||||
HTTPContext *rtp_c;
|
||||
|
||||
@@ -3327,14 +3311,29 @@ static void rtsp_cmd_interrupt(HTTPContext *c, const char *url, RTSPMessageHeade
|
||||
return;
|
||||
}
|
||||
|
||||
if (pause_only) {
|
||||
if (rtp_c->state != HTTPSTATE_SEND_DATA &&
|
||||
rtp_c->state != HTTPSTATE_WAIT_FEED) {
|
||||
rtsp_reply_error(c, RTSP_STATUS_STATE);
|
||||
return;
|
||||
}
|
||||
rtp_c->state = HTTPSTATE_READY;
|
||||
rtp_c->first_pts = AV_NOPTS_VALUE;
|
||||
if (rtp_c->state != HTTPSTATE_SEND_DATA &&
|
||||
rtp_c->state != HTTPSTATE_WAIT_FEED) {
|
||||
rtsp_reply_error(c, RTSP_STATUS_STATE);
|
||||
return;
|
||||
}
|
||||
|
||||
rtp_c->state = HTTPSTATE_READY;
|
||||
rtp_c->first_pts = AV_NOPTS_VALUE;
|
||||
/* now everything is OK, so we can send the connection parameters */
|
||||
rtsp_reply_header(c, RTSP_STATUS_OK);
|
||||
/* session ID */
|
||||
avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
|
||||
avio_printf(c->pb, "\r\n");
|
||||
}
|
||||
|
||||
static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h)
|
||||
{
|
||||
HTTPContext *rtp_c;
|
||||
|
||||
rtp_c = find_rtp_session_with_url(url, h->session_id);
|
||||
if (!rtp_c) {
|
||||
rtsp_reply_error(c, RTSP_STATUS_SESSION);
|
||||
return;
|
||||
}
|
||||
|
||||
/* now everything is OK, so we can send the connection parameters */
|
||||
@@ -3343,10 +3342,11 @@ static void rtsp_cmd_interrupt(HTTPContext *c, const char *url, RTSPMessageHeade
|
||||
avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
|
||||
avio_printf(c->pb, "\r\n");
|
||||
|
||||
if (!pause_only)
|
||||
close_connection(rtp_c);
|
||||
/* abort the session */
|
||||
close_connection(rtp_c);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************/
|
||||
/* RTP handling */
|
||||
|
||||
@@ -3491,8 +3491,7 @@ static int rtp_new_av_stream(HTTPContext *c,
|
||||
ipaddr, ntohs(dest_addr->sin_port),
|
||||
c->stream->filename, stream_index, c->protocol);
|
||||
|
||||
/* normally, no packets should be output here, but the packet size may
|
||||
* be checked */
|
||||
/* normally, no packets should be output here, but the packet size may be checked */
|
||||
if (ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) {
|
||||
/* XXX: close stream */
|
||||
goto fail;
|
||||
@@ -3534,7 +3533,7 @@ static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int cop
|
||||
}
|
||||
} else {
|
||||
/* live streams must use the actual feed's codec since it may be
|
||||
* updated later to carry extradata needed by them.
|
||||
* updated later to carry extradata needed by the streams.
|
||||
*/
|
||||
fst->codec = codec;
|
||||
}
|
||||
@@ -3671,14 +3670,9 @@ static void build_file_streams(void)
|
||||
av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);
|
||||
}
|
||||
|
||||
if (!stream->feed_filename[0]) {
|
||||
http_log("Unspecified feed file for stream '%s'\n", stream->filename);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
http_log("Opening feed file '%s' for stream '%s'\n", stream->feed_filename, stream->filename);
|
||||
http_log("Opening file '%s'\n", stream->feed_filename);
|
||||
if ((ret = avformat_open_input(&infile, stream->feed_filename, stream->ifmt, &stream->in_opts)) < 0) {
|
||||
http_log("Could not open '%s': %s\n", stream->feed_filename, av_err2str(ret));
|
||||
http_log("Could not open '%s': %d\n", stream->feed_filename, ret);
|
||||
/* remove stream (no need to spend more time on it) */
|
||||
fail:
|
||||
remove_stream(stream);
|
||||
@@ -3803,7 +3797,7 @@ static void build_feed_streams(void)
|
||||
}
|
||||
}
|
||||
if (avio_check(feed->feed_filename, AVIO_FLAG_WRITE) <= 0) {
|
||||
AVFormatContext *s = avformat_alloc_context();
|
||||
AVFormatContext s1 = {0}, *s = &s1;
|
||||
|
||||
if (feed->readonly) {
|
||||
http_log("Unable to create feed file '%s' as it is marked readonly\n",
|
||||
@@ -3827,9 +3821,6 @@ static void build_feed_streams(void)
|
||||
/* XXX: need better api */
|
||||
av_freep(&s->priv_data);
|
||||
avio_close(s->pb);
|
||||
s->streams = NULL;
|
||||
s->nb_streams = 0;
|
||||
avformat_free_context(s);
|
||||
}
|
||||
/* get feed size and write index */
|
||||
fd = open(feed->feed_filename, O_RDONLY);
|
||||
@@ -3924,7 +3915,7 @@ static void add_codec(FFStream *stream, AVCodecContext *av)
|
||||
av->rc_buffer_aggressivity = 1.0;
|
||||
|
||||
if (!av->rc_eq)
|
||||
av->rc_eq = av_strdup("tex^qComp");
|
||||
av->rc_eq = "tex^qComp";
|
||||
if (!av->i_quant_factor)
|
||||
av->i_quant_factor = -0.8;
|
||||
if (!av->b_quant_factor)
|
||||
@@ -3952,15 +3943,53 @@ static void add_codec(FFStream *stream, AVCodecContext *av)
|
||||
memcpy(st->codec, av, sizeof(AVCodecContext));
|
||||
}
|
||||
|
||||
static enum AVCodecID opt_codec(const char *name, enum AVMediaType type)
|
||||
static enum AVCodecID opt_audio_codec(const char *arg)
|
||||
{
|
||||
AVCodec *codec = avcodec_find_encoder_by_name(name);
|
||||
AVCodec *p= avcodec_find_encoder_by_name(arg);
|
||||
|
||||
if (!codec || codec->type != type)
|
||||
if (p == NULL || p->type != AVMEDIA_TYPE_AUDIO)
|
||||
return AV_CODEC_ID_NONE;
|
||||
return codec->id;
|
||||
|
||||
return p->id;
|
||||
}
|
||||
|
||||
static enum AVCodecID opt_video_codec(const char *arg)
|
||||
{
|
||||
AVCodec *p= avcodec_find_encoder_by_name(arg);
|
||||
|
||||
if (p == NULL || p->type != AVMEDIA_TYPE_VIDEO)
|
||||
return AV_CODEC_ID_NONE;
|
||||
|
||||
return p->id;
|
||||
}
|
||||
|
||||
/* simplistic plugin support */
|
||||
|
||||
#if HAVE_DLOPEN
|
||||
static void load_module(const char *filename)
|
||||
{
|
||||
void *dll;
|
||||
void (*init_func)(void);
|
||||
dll = dlopen(filename, RTLD_NOW);
|
||||
if (!dll) {
|
||||
fprintf(stderr, "Could not load module '%s' - %s\n",
|
||||
filename, dlerror());
|
||||
return;
|
||||
}
|
||||
|
||||
init_func = dlsym(dll, "ffserver_module_init");
|
||||
if (!init_func) {
|
||||
fprintf(stderr,
|
||||
"%s: init function 'ffserver_module_init()' not found\n",
|
||||
filename);
|
||||
dlclose(dll);
|
||||
return;
|
||||
}
|
||||
|
||||
init_func();
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ffserver_opt_default(const char *opt, const char *arg,
|
||||
AVCodecContext *avctx, int type)
|
||||
{
|
||||
@@ -3997,9 +4026,9 @@ static int ffserver_opt_preset(const char *arg,
|
||||
break;
|
||||
}
|
||||
if(!strcmp(tmp, "acodec")){
|
||||
*audio_id = opt_codec(tmp2, AVMEDIA_TYPE_AUDIO);
|
||||
*audio_id = opt_audio_codec(tmp2);
|
||||
}else if(!strcmp(tmp, "vcodec")){
|
||||
*video_id = opt_codec(tmp2, AVMEDIA_TYPE_VIDEO);
|
||||
*video_id = opt_video_codec(tmp2);
|
||||
}else if(!strcmp(tmp, "scodec")){
|
||||
/* opt_subtitle_codec(tmp2); */
|
||||
}else if(ffserver_opt_default(tmp, tmp2, avctx, type) < 0){
|
||||
@@ -4014,7 +4043,8 @@ static int ffserver_opt_preset(const char *arg,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static AVOutputFormat *ffserver_guess_format(const char *short_name, const char *filename, const char *mime_type)
|
||||
static AVOutputFormat *ffserver_guess_format(const char *short_name, const char *filename,
|
||||
const char *mime_type)
|
||||
{
|
||||
AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type);
|
||||
|
||||
@@ -4032,12 +4062,12 @@ static AVOutputFormat *ffserver_guess_format(const char *short_name, const char
|
||||
return fmt;
|
||||
}
|
||||
|
||||
static void report_config_error(const char *filename, int line_num, int log_level, int *errors, const char *fmt, ...)
|
||||
static void report_config_error(const char *filename, int line_num, int *errors, const char *fmt, ...)
|
||||
{
|
||||
va_list vl;
|
||||
va_start(vl, fmt);
|
||||
av_log(NULL, log_level, "%s:%d: ", filename, line_num);
|
||||
av_vlog(NULL, log_level, fmt, vl);
|
||||
fprintf(stderr, "%s:%d: ", filename, line_num);
|
||||
vfprintf(stderr, fmt, vl);
|
||||
va_end(vl);
|
||||
|
||||
(*errors)++;
|
||||
@@ -4048,23 +4078,21 @@ static int parse_ffconfig(const char *filename)
|
||||
FILE *f;
|
||||
char line[1024];
|
||||
char cmd[64];
|
||||
char arg[1024], arg2[1024];
|
||||
char arg[1024];
|
||||
const char *p;
|
||||
int val, errors, warnings, line_num;
|
||||
int val, errors, line_num;
|
||||
FFStream **last_stream, *stream, *redirect;
|
||||
FFStream **last_feed, *feed, *s;
|
||||
AVCodecContext audio_enc, video_enc;
|
||||
enum AVCodecID audio_id, video_id;
|
||||
int ret = 0;
|
||||
|
||||
f = fopen(filename, "r");
|
||||
if (!f) {
|
||||
ret = AVERROR(errno);
|
||||
av_log(NULL, AV_LOG_ERROR, "Could not open the configuration file '%s'\n", filename);
|
||||
return ret;
|
||||
perror(filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
errors = warnings = 0;
|
||||
errors = 0;
|
||||
line_num = 0;
|
||||
first_stream = NULL;
|
||||
last_stream = &first_stream;
|
||||
@@ -4075,9 +4103,8 @@ static int parse_ffconfig(const char *filename)
|
||||
redirect = NULL;
|
||||
audio_id = AV_CODEC_ID_NONE;
|
||||
video_id = AV_CODEC_ID_NONE;
|
||||
#define ERROR(...) report_config_error(filename, line_num, AV_LOG_ERROR, &errors, __VA_ARGS__)
|
||||
#define WARNING(...) report_config_error(filename, line_num, AV_LOG_WARNING, &warnings, __VA_ARGS__)
|
||||
|
||||
#define ERROR(...) report_config_error(filename, line_num, &errors, __VA_ARGS__)
|
||||
for(;;) {
|
||||
if (fgets(line, sizeof(line), f) == NULL)
|
||||
break;
|
||||
@@ -4103,7 +4130,7 @@ static int parse_ffconfig(const char *filename)
|
||||
ERROR("%s:%d: Invalid host/IP address: %s\n", arg);
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "NoDaemon")) {
|
||||
WARNING("NoDaemon option has no effect, you should remove it\n");
|
||||
// do nothing here, its the default now
|
||||
} else if (!av_strcasecmp(cmd, "RTSPPort")) {
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
val = atoi(arg);
|
||||
@@ -4150,10 +4177,6 @@ static int parse_ffconfig(const char *filename)
|
||||
ERROR("Already in a tag\n");
|
||||
} else {
|
||||
feed = av_mallocz(sizeof(FFStream));
|
||||
if (!feed) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
get_arg(feed->filename, sizeof(feed->filename), &p);
|
||||
q = strrchr(feed->filename, '>');
|
||||
if (*q)
|
||||
@@ -4166,7 +4189,7 @@ static int parse_ffconfig(const char *filename)
|
||||
}
|
||||
|
||||
feed->fmt = av_guess_format("ffm", NULL, NULL);
|
||||
/* default feed file */
|
||||
/* defaut feed file */
|
||||
snprintf(feed->feed_filename, sizeof(feed->feed_filename),
|
||||
"/tmp/%s.ffm", feed->filename);
|
||||
feed->feed_max_size = 5 * 1024 * 1024;
|
||||
@@ -4185,50 +4208,36 @@ static int parse_ffconfig(const char *filename)
|
||||
int i;
|
||||
|
||||
feed->child_argv = av_mallocz(64 * sizeof(char *));
|
||||
if (!feed->child_argv) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (i = 0; i < 62; i++) {
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
if (!arg[0])
|
||||
break;
|
||||
|
||||
feed->child_argv[i] = av_strdup(arg);
|
||||
if (!feed->child_argv[i]) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
feed->child_argv[i] =
|
||||
av_asprintf("http://%s:%d/%s",
|
||||
(my_http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" :
|
||||
inet_ntoa(my_http_addr.sin_addr), ntohs(my_http_addr.sin_port),
|
||||
feed->filename);
|
||||
if (!feed->child_argv[i]) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
feed->child_argv[i] = av_asprintf("http://%s:%d/%s",
|
||||
(my_http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" :
|
||||
inet_ntoa(my_http_addr.sin_addr),
|
||||
ntohs(my_http_addr.sin_port), feed->filename);
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "File") || !av_strcasecmp(cmd, "ReadOnlyFile")) {
|
||||
} else if (!av_strcasecmp(cmd, "ReadOnlyFile")) {
|
||||
if (feed) {
|
||||
get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
|
||||
feed->readonly = !av_strcasecmp(cmd, "ReadOnlyFile");
|
||||
feed->readonly = 1;
|
||||
} else if (stream) {
|
||||
get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "File")) {
|
||||
if (feed) {
|
||||
get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
|
||||
} else if (stream)
|
||||
get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
|
||||
} else if (!av_strcasecmp(cmd, "Truncate")) {
|
||||
if (feed) {
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
/* assume Truncate is true in case no argument is specified */
|
||||
if (!arg[0]) {
|
||||
feed->truncate = 1;
|
||||
} else {
|
||||
WARNING("Truncate N syntax in configuration file is deprecated, "
|
||||
"use Truncate alone with no arguments\n");
|
||||
feed->truncate = strtod(arg, NULL);
|
||||
}
|
||||
feed->truncate = strtod(arg, NULL);
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "FileMaxSize")) {
|
||||
if (feed) {
|
||||
@@ -4268,10 +4277,6 @@ static int parse_ffconfig(const char *filename)
|
||||
} else {
|
||||
FFStream *s;
|
||||
stream = av_mallocz(sizeof(FFStream));
|
||||
if (!stream) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
get_arg(stream->filename, sizeof(stream->filename), &p);
|
||||
q = strrchr(stream->filename, '>');
|
||||
if (q)
|
||||
@@ -4309,7 +4314,7 @@ static int parse_ffconfig(const char *filename)
|
||||
sfeed = sfeed->next_feed;
|
||||
}
|
||||
if (!sfeed)
|
||||
ERROR("Feed with name '%s' for stream '%s' is not defined\n", arg, stream->filename);
|
||||
ERROR("feed '%s' not defined\n", arg);
|
||||
else
|
||||
stream->feed = sfeed;
|
||||
}
|
||||
@@ -4348,36 +4353,18 @@ static int parse_ffconfig(const char *filename)
|
||||
} else {
|
||||
ERROR("FaviconURL only permitted for status streams\n");
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "Author") ||
|
||||
!av_strcasecmp(cmd, "Comment") ||
|
||||
!av_strcasecmp(cmd, "Copyright") ||
|
||||
!av_strcasecmp(cmd, "Title")) {
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
|
||||
if (stream) {
|
||||
char key[32];
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < strlen(cmd); i++)
|
||||
key[i] = av_tolower(cmd[i]);
|
||||
key[i] = 0;
|
||||
WARNING("'%s' option in configuration file is deprecated, "
|
||||
"use 'Metadata %s VALUE' instead\n", cmd, key);
|
||||
if ((ret = av_dict_set(&stream->metadata, key, arg, 0)) < 0) {
|
||||
ERROR("Could not set metadata '%s' to value '%s': %s\n",
|
||||
key, arg, av_err2str(ret));
|
||||
}
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "Metadata")) {
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
get_arg(arg2, sizeof(arg2), &p);
|
||||
if (stream) {
|
||||
int ret;
|
||||
if ((ret = av_dict_set(&stream->metadata, arg, arg2, 0)) < 0) {
|
||||
ERROR("Could not set metadata '%s' to value '%s': %s\n",
|
||||
arg, arg2, av_err2str(ret));
|
||||
}
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "Author")) {
|
||||
if (stream)
|
||||
get_arg(stream->author, sizeof(stream->author), &p);
|
||||
} else if (!av_strcasecmp(cmd, "Comment")) {
|
||||
if (stream)
|
||||
get_arg(stream->comment, sizeof(stream->comment), &p);
|
||||
} else if (!av_strcasecmp(cmd, "Copyright")) {
|
||||
if (stream)
|
||||
get_arg(stream->copyright, sizeof(stream->copyright), &p);
|
||||
} else if (!av_strcasecmp(cmd, "Title")) {
|
||||
if (stream)
|
||||
get_arg(stream->title, sizeof(stream->title), &p);
|
||||
} else if (!av_strcasecmp(cmd, "Preroll")) {
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
if (stream)
|
||||
@@ -4387,13 +4374,13 @@ static int parse_ffconfig(const char *filename)
|
||||
stream->send_on_key = 1;
|
||||
} else if (!av_strcasecmp(cmd, "AudioCodec")) {
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
audio_id = opt_codec(arg, AVMEDIA_TYPE_AUDIO);
|
||||
audio_id = opt_audio_codec(arg);
|
||||
if (audio_id == AV_CODEC_ID_NONE) {
|
||||
ERROR("Unknown AudioCodec: %s\n", arg);
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "VideoCodec")) {
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
video_id = opt_codec(arg, AVMEDIA_TYPE_VIDEO);
|
||||
video_id = opt_video_codec(arg);
|
||||
if (video_id == AV_CODEC_ID_NONE) {
|
||||
ERROR("Unknown VideoCodec: %s\n", arg);
|
||||
}
|
||||
@@ -4413,6 +4400,11 @@ static int parse_ffconfig(const char *filename)
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
if (stream)
|
||||
audio_enc.sample_rate = atoi(arg);
|
||||
} else if (!av_strcasecmp(cmd, "AudioQuality")) {
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
if (stream) {
|
||||
// audio_enc.quality = atof(arg) * 1000;
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "VideoBitRateRange")) {
|
||||
if (stream) {
|
||||
int minrate, maxrate;
|
||||
@@ -4454,14 +4446,10 @@ static int parse_ffconfig(const char *filename)
|
||||
} else if (!av_strcasecmp(cmd, "VideoSize")) {
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
if (stream) {
|
||||
ret = av_parse_video_size(&video_enc.width, &video_enc.height, arg);
|
||||
if (ret < 0) {
|
||||
ERROR("Invalid video size '%s'\n", arg);
|
||||
} else {
|
||||
if ((video_enc.width % 16) != 0 ||
|
||||
(video_enc.height % 16) != 0) {
|
||||
ERROR("Image size must be a multiple of 16\n");
|
||||
}
|
||||
av_parse_video_size(&video_enc.width, &video_enc.height, arg);
|
||||
if ((video_enc.width % 16) != 0 ||
|
||||
(video_enc.height % 16) != 0) {
|
||||
ERROR("Image size must be a multiple of 16\n");
|
||||
}
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "VideoFrameRate")) {
|
||||
@@ -4475,14 +4463,6 @@ static int parse_ffconfig(const char *filename)
|
||||
video_enc.time_base.den = frame_rate.num;
|
||||
}
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "PixelFormat")) {
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
if (stream) {
|
||||
video_enc.pix_fmt = av_get_pix_fmt(arg);
|
||||
if (video_enc.pix_fmt == AV_PIX_FMT_NONE) {
|
||||
ERROR("Unknown pixel format: %s\n", arg);
|
||||
}
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "VideoGopSize")) {
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
if (stream)
|
||||
@@ -4500,6 +4480,7 @@ static int parse_ffconfig(const char *filename)
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "AVOptionVideo") ||
|
||||
!av_strcasecmp(cmd, "AVOptionAudio")) {
|
||||
char arg2[1024];
|
||||
AVCodecContext *avctx;
|
||||
int type;
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
@@ -4512,7 +4493,7 @@ static int parse_ffconfig(const char *filename)
|
||||
type = AV_OPT_FLAG_AUDIO_PARAM;
|
||||
}
|
||||
if (ffserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) {
|
||||
ERROR("Error setting %s option to %s %s\n", cmd, arg, arg2);
|
||||
ERROR("AVOption error: %s %s\n", arg, arg2);
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "AVPresetVideo") ||
|
||||
!av_strcasecmp(cmd, "AVPresetAudio")) {
|
||||
@@ -4643,10 +4624,6 @@ static int parse_ffconfig(const char *filename)
|
||||
ERROR("Already in a tag\n");
|
||||
} else {
|
||||
redirect = av_mallocz(sizeof(FFStream));
|
||||
if (!redirect) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
*last_stream = redirect;
|
||||
last_stream = &redirect->next;
|
||||
|
||||
@@ -4669,19 +4646,21 @@ static int parse_ffconfig(const char *filename)
|
||||
redirect = NULL;
|
||||
}
|
||||
} else if (!av_strcasecmp(cmd, "LoadModule")) {
|
||||
ERROR("Loadable modules no longer supported\n");
|
||||
get_arg(arg, sizeof(arg), &p);
|
||||
#if HAVE_DLOPEN
|
||||
load_module(arg);
|
||||
#else
|
||||
ERROR("Module support not compiled into this version: '%s'\n", arg);
|
||||
#endif
|
||||
} else {
|
||||
ERROR("Incorrect keyword: '%s'\n", cmd);
|
||||
}
|
||||
}
|
||||
#undef ERROR
|
||||
|
||||
end:
|
||||
fclose(f);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (errors)
|
||||
return AVERROR(EINVAL);
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@@ -4736,9 +4715,6 @@ static const OptionDef options[] = {
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct sigaction sigact = { { 0 } };
|
||||
int ret = 0;
|
||||
|
||||
config_filename = av_strdup("/etc/ffserver.conf");
|
||||
|
||||
parse_loglevel(argc, argv, options);
|
||||
av_register_all();
|
||||
@@ -4750,6 +4726,9 @@ int main(int argc, char **argv)
|
||||
|
||||
parse_options(NULL, argc, argv, options, NULL);
|
||||
|
||||
if (!config_filename)
|
||||
config_filename = av_strdup("/etc/ffserver.conf");
|
||||
|
||||
unsetenv("http_proxy"); /* Kill the http_proxy */
|
||||
|
||||
av_lfg_init(&random_state, av_get_random_seed());
|
||||
@@ -4758,9 +4737,8 @@ int main(int argc, char **argv)
|
||||
sigact.sa_flags = SA_NOCLDSTOP | SA_RESTART;
|
||||
sigaction(SIGCHLD, &sigact, 0);
|
||||
|
||||
if ((ret = parse_ffconfig(config_filename)) < 0) {
|
||||
fprintf(stderr, "Error reading configuration file '%s': %s\n",
|
||||
config_filename, av_err2str(ret));
|
||||
if (parse_ffconfig(config_filename) < 0) {
|
||||
fprintf(stderr, "Incorrect config file - exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
av_freep(&config_filename);
|
||||
|
||||
@@ -38,23 +38,17 @@ static av_cold int zero12v_decode_init(AVCodecContext *avctx)
|
||||
static int zero12v_decode_frame(AVCodecContext *avctx, void *data,
|
||||
int *got_frame, AVPacket *avpkt)
|
||||
{
|
||||
int line = 0, ret;
|
||||
int line, ret;
|
||||
const int width = avctx->width;
|
||||
AVFrame *pic = data;
|
||||
uint16_t *y, *u, *v;
|
||||
const uint8_t *line_end, *src = avpkt->data;
|
||||
int stride = avctx->width * 8 / 3;
|
||||
|
||||
if (width == 1) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Width 1 not supported.\n");
|
||||
if (width <= 1 || avctx->height <= 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Dimensions %dx%d not supported.\n", width, avctx->height);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if ( avctx->codec_tag == MKTAG('0', '1', '2', 'v')
|
||||
&& avpkt->size % avctx->height == 0
|
||||
&& avpkt->size / avctx->height * 3 >= width * 8)
|
||||
stride = avpkt->size / avctx->height;
|
||||
|
||||
if (avpkt->size < avctx->height * stride) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Packet too small: %d instead of %d\n",
|
||||
avpkt->size, avctx->height * stride);
|
||||
@@ -67,45 +61,45 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data,
|
||||
pic->pict_type = AV_PICTURE_TYPE_I;
|
||||
pic->key_frame = 1;
|
||||
|
||||
y = (uint16_t *)pic->data[0];
|
||||
u = (uint16_t *)pic->data[1];
|
||||
v = (uint16_t *)pic->data[2];
|
||||
line_end = avpkt->data + stride;
|
||||
for (line = 0; line < avctx->height; line++) {
|
||||
uint16_t y_temp[6] = {0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000};
|
||||
uint16_t u_temp[3] = {0x8000, 0x8000, 0x8000};
|
||||
uint16_t v_temp[3] = {0x8000, 0x8000, 0x8000};
|
||||
int x;
|
||||
y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]);
|
||||
u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
|
||||
v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
|
||||
|
||||
while (line++ < avctx->height) {
|
||||
while (1) {
|
||||
uint32_t t = AV_RL32(src);
|
||||
for (x = 0; x < width; x += 6) {
|
||||
uint32_t t;
|
||||
|
||||
if (width - x < 6 || line_end - src < 16) {
|
||||
y = y_temp;
|
||||
u = u_temp;
|
||||
v = v_temp;
|
||||
}
|
||||
|
||||
if (line_end - src < 4)
|
||||
break;
|
||||
|
||||
t = AV_RL32(src);
|
||||
src += 4;
|
||||
*u++ = t << 6 & 0xFFC0;
|
||||
*y++ = t >> 4 & 0xFFC0;
|
||||
*v++ = t >> 14 & 0xFFC0;
|
||||
|
||||
if (src >= line_end - 1) {
|
||||
*y = 0x80;
|
||||
src++;
|
||||
line_end += stride;
|
||||
y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]);
|
||||
u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
|
||||
v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
|
||||
if (line_end - src < 4)
|
||||
break;
|
||||
}
|
||||
|
||||
t = AV_RL32(src);
|
||||
src += 4;
|
||||
*y++ = t << 6 & 0xFFC0;
|
||||
*u++ = t >> 4 & 0xFFC0;
|
||||
*y++ = t >> 14 & 0xFFC0;
|
||||
if (src >= line_end - 2) {
|
||||
if (!(width & 1)) {
|
||||
*y = 0x80;
|
||||
src += 2;
|
||||
}
|
||||
line_end += stride;
|
||||
y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]);
|
||||
u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
|
||||
v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
|
||||
|
||||
if (line_end - src < 4)
|
||||
break;
|
||||
}
|
||||
|
||||
t = AV_RL32(src);
|
||||
src += 4;
|
||||
@@ -113,15 +107,8 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data,
|
||||
*y++ = t >> 4 & 0xFFC0;
|
||||
*u++ = t >> 14 & 0xFFC0;
|
||||
|
||||
if (src >= line_end - 1) {
|
||||
*y = 0x80;
|
||||
src++;
|
||||
line_end += stride;
|
||||
y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]);
|
||||
u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
|
||||
v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
|
||||
if (line_end - src < 4)
|
||||
break;
|
||||
}
|
||||
|
||||
t = AV_RL32(src);
|
||||
src += 4;
|
||||
@@ -129,18 +116,21 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data,
|
||||
*v++ = t >> 4 & 0xFFC0;
|
||||
*y++ = t >> 14 & 0xFFC0;
|
||||
|
||||
if (src >= line_end - 2) {
|
||||
if (width & 1) {
|
||||
*y = 0x80;
|
||||
src += 2;
|
||||
}
|
||||
line_end += stride;
|
||||
y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]);
|
||||
u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
|
||||
v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
|
||||
if (width - x < 6)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (x < width) {
|
||||
y = x + (uint16_t *)(pic->data[0] + line * pic->linesize[0]);
|
||||
u = x/2 + (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
|
||||
v = x/2 + (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
|
||||
memcpy(y, y_temp, sizeof(*y) * (width - x));
|
||||
memcpy(u, u_temp, sizeof(*u) * (width - x + 1) / 2);
|
||||
memcpy(v, v_temp, sizeof(*v) * (width - x + 1) / 2);
|
||||
}
|
||||
|
||||
line_end += stride;
|
||||
src = line_end - stride;
|
||||
}
|
||||
|
||||
*got_frame = 1;
|
||||
@@ -150,10 +140,10 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data,
|
||||
|
||||
AVCodec ff_zero12v_decoder = {
|
||||
.name = "012v",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.id = AV_CODEC_ID_012V,
|
||||
.init = zero12v_decode_init,
|
||||
.decode = zero12v_decode_frame,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
|
||||
};
|
||||
|
||||
148
libavcodec/4xm.c
148
libavcodec/4xm.c
@@ -26,7 +26,6 @@
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/frame.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "avcodec.h"
|
||||
#include "bytestream.h"
|
||||
@@ -132,8 +131,7 @@ typedef struct CFrameBuffer {
|
||||
typedef struct FourXContext {
|
||||
AVCodecContext *avctx;
|
||||
DSPContext dsp;
|
||||
uint16_t *frame_buffer;
|
||||
uint16_t *last_frame_buffer;
|
||||
AVFrame *current_picture, *last_picture;
|
||||
GetBitContext pre_gb; ///< ac/dc prefix
|
||||
GetBitContext gb;
|
||||
GetByteContext g;
|
||||
@@ -343,7 +341,7 @@ static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
|
||||
int code = get_vlc2(&f->gb,
|
||||
block_type_vlc[1 - (f->version > 1)][index].table,
|
||||
BLOCK_TYPE_VLC_BITS, 1);
|
||||
uint16_t *start = f->last_frame_buffer;
|
||||
uint16_t *start = (uint16_t *)f->last_picture->data[0];
|
||||
uint16_t *end = start + stride * (f->avctx->height - h + 1) - (1 << log2w);
|
||||
int ret;
|
||||
int scale = 1;
|
||||
@@ -416,18 +414,29 @@ static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
|
||||
static int decode_p_frame(FourXContext *f, AVFrame *frame,
|
||||
const uint8_t *buf, int length)
|
||||
{
|
||||
int x, y;
|
||||
const int width = f->avctx->width;
|
||||
const int height = f->avctx->height;
|
||||
uint16_t *dst = f->frame_buffer;
|
||||
uint16_t *dst = (uint16_t *)frame->data[0];
|
||||
const int stride = frame->linesize[0] >> 1;
|
||||
uint16_t *src;
|
||||
unsigned int bitstream_size, bytestream_size, wordstream_size, extra,
|
||||
bytestream_offset, wordstream_offset;
|
||||
int ret;
|
||||
|
||||
src = f->last_frame_buffer;
|
||||
if (!f->last_picture->data[0]) {
|
||||
if ((ret = ff_get_buffer(f->avctx, f->last_picture,
|
||||
AV_GET_BUFFER_FLAG_REF)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
for (y=0; y<f->avctx->height; y++)
|
||||
memset(f->last_picture->data[0] + y*f->last_picture->linesize[0], 0, 2*f->avctx->width);
|
||||
}
|
||||
|
||||
src = (uint16_t *)f->last_picture->data[0];
|
||||
|
||||
if (f->version > 1) {
|
||||
extra = 20;
|
||||
@@ -452,12 +461,14 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
av_fast_padded_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size,
|
||||
bitstream_size);
|
||||
av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size,
|
||||
bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!f->bitstream_buffer)
|
||||
return AVERROR(ENOMEM);
|
||||
f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)(buf + extra),
|
||||
bitstream_size / 4);
|
||||
memset((uint8_t*)f->bitstream_buffer + bitstream_size,
|
||||
0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
init_get_bits(&f->gb, f->bitstream_buffer, 8 * bitstream_size);
|
||||
|
||||
wordstream_offset = extra + bitstream_size;
|
||||
@@ -467,14 +478,14 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
|
||||
bytestream2_init(&f->g, buf + bytestream_offset,
|
||||
length - bytestream_offset);
|
||||
|
||||
init_mv(f, width * 2);
|
||||
init_mv(f, frame->linesize[0]);
|
||||
|
||||
for (y = 0; y < height; y += 8) {
|
||||
for (x = 0; x < width; x += 8)
|
||||
if ((ret = decode_p_block(f, dst + x, src + x, 3, 3, width)) < 0)
|
||||
if ((ret = decode_p_block(f, dst + x, src + x, 3, 3, stride)) < 0)
|
||||
return ret;
|
||||
src += 8 * width;
|
||||
dst += 8 * width;
|
||||
src += 8 * stride;
|
||||
dst += 8 * stride;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -539,12 +550,12 @@ static int decode_i_block(FourXContext *f, int16_t *block)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void idct_put(FourXContext *f, int x, int y)
|
||||
static inline void idct_put(FourXContext *f, AVFrame *frame, int x, int y)
|
||||
{
|
||||
int16_t (*block)[64] = f->block;
|
||||
int stride = f->avctx->width;
|
||||
int stride = frame->linesize[0] >> 1;
|
||||
int i;
|
||||
uint16_t *dst = f->frame_buffer + y * stride + x;
|
||||
uint16_t *dst = ((uint16_t*)frame->data[0]) + y * stride + x;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
block[i][0] += 0x80 * 8 * 8;
|
||||
@@ -704,13 +715,14 @@ static int mix(int c0, int c1)
|
||||
return red / 3 * 1024 + green / 3 * 32 + blue / 3;
|
||||
}
|
||||
|
||||
static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length)
|
||||
static int decode_i2_frame(FourXContext *f, AVFrame *frame, const uint8_t *buf, int length)
|
||||
{
|
||||
int x, y, x2, y2;
|
||||
const int width = f->avctx->width;
|
||||
const int height = f->avctx->height;
|
||||
const int mbs = (FFALIGN(width, 16) >> 4) * (FFALIGN(height, 16) >> 4);
|
||||
uint16_t *dst = f->frame_buffer;
|
||||
uint16_t *dst = (uint16_t*)frame->data[0];
|
||||
const int stride = frame->linesize[0]>>1;
|
||||
const uint8_t *buf_end = buf + length;
|
||||
GetByteContext g3;
|
||||
|
||||
@@ -741,18 +753,18 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length)
|
||||
for (y2 = 0; y2 < 16; y2++) {
|
||||
for (x2 = 0; x2 < 16; x2++) {
|
||||
int index = 2 * (x2 >> 2) + 8 * (y2 >> 2);
|
||||
dst[y2 * width + x2] = color[(bits >> index) & 3];
|
||||
dst[y2 * stride + x2] = color[(bits >> index) & 3];
|
||||
}
|
||||
}
|
||||
dst += 16;
|
||||
}
|
||||
dst += 16 * width - x;
|
||||
dst += 16 * stride - x;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
|
||||
static int decode_i_frame(FourXContext *f, AVFrame *frame, const uint8_t *buf, int length)
|
||||
{
|
||||
int x, y, ret;
|
||||
const int width = f->avctx->width;
|
||||
@@ -791,12 +803,14 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
|
||||
|
||||
prestream_size = length + buf - prestream;
|
||||
|
||||
av_fast_padded_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size,
|
||||
prestream_size);
|
||||
av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size,
|
||||
prestream_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!f->bitstream_buffer)
|
||||
return AVERROR(ENOMEM);
|
||||
f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)prestream,
|
||||
prestream_size / 4);
|
||||
memset((uint8_t*)f->bitstream_buffer + prestream_size,
|
||||
0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
init_get_bits(&f->pre_gb, f->bitstream_buffer, 8 * prestream_size);
|
||||
|
||||
f->last_dc = 0 * 128 * 8 * 8;
|
||||
@@ -806,7 +820,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
|
||||
if ((ret = decode_i_mb(f)) < 0)
|
||||
return ret;
|
||||
|
||||
idct_put(f, x, y);
|
||||
idct_put(f, frame, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -828,8 +842,6 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
if (buf_size < 20)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
av_assert0(avctx->width % 16 == 0 && avctx->height % 16 == 0);
|
||||
|
||||
if (buf_size < AV_RL32(buf + 4) + 8) {
|
||||
av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n",
|
||||
buf_size, AV_RL32(buf + 4));
|
||||
@@ -909,24 +921,29 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
frame_size = buf_size - 12;
|
||||
}
|
||||
|
||||
if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
|
||||
FFSWAP(AVFrame*, f->current_picture, f->last_picture);
|
||||
|
||||
// alternatively we would have to use our own buffer management
|
||||
avctx->flags |= CODEC_FLAG_EMU_EDGE;
|
||||
|
||||
if ((ret = ff_reget_buffer(avctx, f->current_picture)) < 0)
|
||||
return ret;
|
||||
|
||||
if (frame_4cc == AV_RL32("ifr2")) {
|
||||
picture->pict_type = AV_PICTURE_TYPE_I;
|
||||
if ((ret = decode_i2_frame(f, buf - 4, frame_size + 4)) < 0) {
|
||||
f->current_picture->pict_type = AV_PICTURE_TYPE_I;
|
||||
if ((ret = decode_i2_frame(f, f->current_picture, buf - 4, frame_size + 4)) < 0) {
|
||||
av_log(f->avctx, AV_LOG_ERROR, "decode i2 frame failed\n");
|
||||
return ret;
|
||||
}
|
||||
} else if (frame_4cc == AV_RL32("ifrm")) {
|
||||
picture->pict_type = AV_PICTURE_TYPE_I;
|
||||
if ((ret = decode_i_frame(f, buf, frame_size)) < 0) {
|
||||
f->current_picture->pict_type = AV_PICTURE_TYPE_I;
|
||||
if ((ret = decode_i_frame(f, f->current_picture, buf, frame_size)) < 0) {
|
||||
av_log(f->avctx, AV_LOG_ERROR, "decode i frame failed\n");
|
||||
return ret;
|
||||
}
|
||||
} else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) {
|
||||
picture->pict_type = AV_PICTURE_TYPE_P;
|
||||
if ((ret = decode_p_frame(f, buf, frame_size)) < 0) {
|
||||
f->current_picture->pict_type = AV_PICTURE_TYPE_P;
|
||||
if ((ret = decode_p_frame(f, f->current_picture, buf, frame_size)) < 0) {
|
||||
av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n");
|
||||
return ret;
|
||||
}
|
||||
@@ -938,13 +955,10 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
buf_size);
|
||||
}
|
||||
|
||||
picture->key_frame = picture->pict_type == AV_PICTURE_TYPE_I;
|
||||
|
||||
av_image_copy_plane(picture->data[0], picture->linesize[0],
|
||||
(const uint8_t*)f->frame_buffer, avctx->width * 2,
|
||||
avctx->width * 2, avctx->height);
|
||||
FFSWAP(uint16_t *, f->frame_buffer, f->last_frame_buffer);
|
||||
f->current_picture->key_frame = f->current_picture->pict_type == AV_PICTURE_TYPE_I;
|
||||
|
||||
if ((ret = av_frame_ref(picture, f->current_picture)) < 0)
|
||||
return ret;
|
||||
*got_frame = 1;
|
||||
|
||||
emms_c();
|
||||
@@ -952,28 +966,9 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
static av_cold int decode_end(AVCodecContext *avctx)
|
||||
{
|
||||
FourXContext * const f = avctx->priv_data;
|
||||
int i;
|
||||
|
||||
av_freep(&f->frame_buffer);
|
||||
av_freep(&f->last_frame_buffer);
|
||||
av_freep(&f->bitstream_buffer);
|
||||
f->bitstream_buffer_size = 0;
|
||||
for (i = 0; i < CFRAME_BUFFER_COUNT; i++) {
|
||||
av_freep(&f->cfrm[i].data);
|
||||
f->cfrm[i].allocated_size = 0;
|
||||
}
|
||||
ff_free_vlc(&f->pre_vlc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_cold int decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
FourXContext * const f = avctx->priv_data;
|
||||
int ret;
|
||||
|
||||
if (avctx->extradata_size != 4 || !avctx->extradata) {
|
||||
av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n");
|
||||
@@ -984,17 +979,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
f->frame_buffer = av_mallocz(avctx->width * avctx->height * 2);
|
||||
f->last_frame_buffer = av_mallocz(avctx->width * avctx->height * 2);
|
||||
if (!f->frame_buffer || !f->last_frame_buffer) {
|
||||
decode_end(avctx);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
f->version = AV_RL32(avctx->extradata) >> 16;
|
||||
ff_dsputil_init(&f->dsp, avctx);
|
||||
f->avctx = avctx;
|
||||
@@ -1005,12 +989,35 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||
else
|
||||
avctx->pix_fmt = AV_PIX_FMT_BGR555;
|
||||
|
||||
f->current_picture = av_frame_alloc();
|
||||
f->last_picture = av_frame_alloc();
|
||||
if (!f->current_picture || !f->last_picture)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static av_cold int decode_end(AVCodecContext *avctx)
|
||||
{
|
||||
FourXContext * const f = avctx->priv_data;
|
||||
int i;
|
||||
|
||||
av_freep(&f->bitstream_buffer);
|
||||
f->bitstream_buffer_size = 0;
|
||||
for (i = 0; i < CFRAME_BUFFER_COUNT; i++) {
|
||||
av_freep(&f->cfrm[i].data);
|
||||
f->cfrm[i].allocated_size = 0;
|
||||
}
|
||||
ff_free_vlc(&f->pre_vlc);
|
||||
av_frame_free(&f->current_picture);
|
||||
av_frame_free(&f->last_picture);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec ff_fourxm_decoder = {
|
||||
.name = "4xm",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("4X Movie"),
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.id = AV_CODEC_ID_4XM,
|
||||
.priv_data_size = sizeof(FourXContext),
|
||||
@@ -1018,4 +1025,5 @@ AVCodec ff_fourxm_decoder = {
|
||||
.close = decode_end,
|
||||
.decode = decode_frame,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("4X Movie"),
|
||||
};
|
||||
|
||||
@@ -64,7 +64,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
unsigned char *pixptr, *pixptr_end;
|
||||
unsigned int height = avctx->height; // Real image height
|
||||
unsigned int dlen, p, row;
|
||||
const unsigned char *lp, *dp, *ep;
|
||||
const unsigned char *lp, *dp;
|
||||
unsigned char count;
|
||||
unsigned int planes = c->planes;
|
||||
unsigned char *planemap = c->planemap;
|
||||
@@ -73,8 +73,6 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
|
||||
return ret;
|
||||
|
||||
ep = encoded + buf_size;
|
||||
|
||||
/* Set data pointer after line lengths */
|
||||
dp = encoded + planes * (height << 1);
|
||||
|
||||
@@ -86,19 +84,19 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
for (row = 0; row < height; row++) {
|
||||
pixptr = frame->data[0] + row * frame->linesize[0] + planemap[p];
|
||||
pixptr_end = pixptr + frame->linesize[0];
|
||||
if (ep - lp < row * 2 + 2)
|
||||
return AVERROR_INVALIDDATA;
|
||||
if(lp - encoded + row*2 + 1 >= buf_size)
|
||||
return -1;
|
||||
dlen = av_be2ne16(*(const unsigned short *)(lp + row * 2));
|
||||
/* Decode a row of this plane */
|
||||
while (dlen > 0) {
|
||||
if (ep - dp <= 1)
|
||||
if (dp + 1 >= buf + buf_size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
if ((count = *dp++) <= 127) {
|
||||
count++;
|
||||
dlen -= count + 1;
|
||||
if (pixptr_end - pixptr < count * planes)
|
||||
if (pixptr + count * planes > pixptr_end)
|
||||
break;
|
||||
if (ep - dp < count)
|
||||
if (dp + count > buf + buf_size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
while (count--) {
|
||||
*pixptr = *dp++;
|
||||
@@ -106,7 +104,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
}
|
||||
} else {
|
||||
count = 257 - count;
|
||||
if (pixptr_end - pixptr < count * planes)
|
||||
if (pixptr + count * planes > pixptr_end)
|
||||
break;
|
||||
while (count--) {
|
||||
*pixptr = *dp;
|
||||
@@ -159,7 +157,17 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||
case 32:
|
||||
avctx->pix_fmt = AV_PIX_FMT_RGB32;
|
||||
c->planes = 4;
|
||||
/* handle planemap setup later for decoding rgb24 data as rbg32 */
|
||||
#if HAVE_BIGENDIAN
|
||||
c->planemap[0] = 1; // 1st plane is red
|
||||
c->planemap[1] = 2; // 2nd plane is green
|
||||
c->planemap[2] = 3; // 3rd plane is blue
|
||||
c->planemap[3] = 0; // 4th plane is alpha
|
||||
#else
|
||||
c->planemap[0] = 2; // 1st plane is red
|
||||
c->planemap[1] = 1; // 2nd plane is green
|
||||
c->planemap[2] = 0; // 3rd plane is blue
|
||||
c->planemap[3] = 3; // 4th plane is alpha
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
av_log(avctx, AV_LOG_ERROR, "Error: Unsupported color depth: %u.\n",
|
||||
@@ -167,22 +175,16 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if (avctx->pix_fmt == AV_PIX_FMT_RGB32) {
|
||||
c->planemap[0] = HAVE_BIGENDIAN ? 1 : 2; // 1st plane is red
|
||||
c->planemap[1] = HAVE_BIGENDIAN ? 2 : 1; // 2nd plane is green
|
||||
c->planemap[2] = HAVE_BIGENDIAN ? 3 : 0; // 3rd plane is blue
|
||||
c->planemap[3] = HAVE_BIGENDIAN ? 0 : 3; // 4th plane is alpha
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec ff_eightbps_decoder = {
|
||||
.name = "8bps",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"),
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.id = AV_CODEC_ID_8BPS,
|
||||
.priv_data_size = sizeof(EightBpsContext),
|
||||
.init = decode_init,
|
||||
.decode = decode_frame,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"),
|
||||
};
|
||||
|
||||
@@ -187,7 +187,6 @@ static av_cold int eightsvx_decode_close(AVCodecContext *avctx)
|
||||
#if CONFIG_EIGHTSVX_FIB_DECODER
|
||||
AVCodec ff_eightsvx_fib_decoder = {
|
||||
.name = "8svx_fib",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("8SVX fibonacci"),
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = AV_CODEC_ID_8SVX_FIB,
|
||||
.priv_data_size = sizeof (EightSvxContext),
|
||||
@@ -195,6 +194,7 @@ AVCodec ff_eightsvx_fib_decoder = {
|
||||
.decode = eightsvx_decode_frame,
|
||||
.close = eightsvx_decode_close,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("8SVX fibonacci"),
|
||||
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
};
|
||||
@@ -202,7 +202,6 @@ AVCodec ff_eightsvx_fib_decoder = {
|
||||
#if CONFIG_EIGHTSVX_EXP_DECODER
|
||||
AVCodec ff_eightsvx_exp_decoder = {
|
||||
.name = "8svx_exp",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("8SVX exponential"),
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = AV_CODEC_ID_8SVX_EXP,
|
||||
.priv_data_size = sizeof (EightSvxContext),
|
||||
@@ -210,6 +209,7 @@ AVCodec ff_eightsvx_exp_decoder = {
|
||||
.decode = eightsvx_decode_frame,
|
||||
.close = eightsvx_decode_close,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("8SVX exponential"),
|
||||
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
};
|
||||
|
||||
@@ -26,6 +26,7 @@ OBJS = allcodecs.o \
|
||||
options.o \
|
||||
parser.o \
|
||||
raw.o \
|
||||
rawdec.o \
|
||||
resample.o \
|
||||
resample2.o \
|
||||
utils.o \
|
||||
@@ -41,25 +42,20 @@ OBJS-$(CONFIG_DSPUTIL) += dsputil.o faanidct.o \
|
||||
simple_idct.o jrevdct.o
|
||||
OBJS-$(CONFIG_ENCODERS) += faandct.o jfdctfst.o jfdctint.o
|
||||
OBJS-$(CONFIG_ERROR_RESILIENCE) += error_resilience.o
|
||||
OBJS-$(CONFIG_EXIF) += exif.o tiff_common.o
|
||||
FFT-OBJS-$(CONFIG_HARDCODED_TABLES) += cos_tables.o cos_fixed_tables.o
|
||||
OBJS-$(CONFIG_FFT) += avfft.o fft_fixed.o fft_float.o \
|
||||
fft_fixed_32.o fft_init_table.o \
|
||||
$(FFT-OBJS-yes)
|
||||
OBJS-$(CONFIG_GOLOMB) += golomb.o
|
||||
OBJS-$(CONFIG_H263DSP) += h263dsp.o
|
||||
OBJS-$(CONFIG_H264CHROMA) += h264chroma.o
|
||||
OBJS-$(CONFIG_H264DSP) += h264dsp.o h264idct.o
|
||||
OBJS-$(CONFIG_H264PRED) += h264pred.o
|
||||
OBJS-$(CONFIG_H264QPEL) += h264qpel.o
|
||||
OBJS-$(CONFIG_HPELDSP) += hpeldsp.o
|
||||
OBJS-$(CONFIG_HUFFMAN) += huffman.o
|
||||
OBJS-$(CONFIG_INTRAX8) += intrax8.o intrax8dsp.o
|
||||
OBJS-$(CONFIG_LIBXVID) += libxvid_rc.o
|
||||
OBJS-$(CONFIG_LLVIDDSP) += lossless_videodsp.o
|
||||
OBJS-$(CONFIG_LPC) += lpc.o
|
||||
OBJS-$(CONFIG_LSP) += lsp.o
|
||||
OBJS-$(CONFIG_MDCT) += mdct_fixed.o mdct_float.o mdct_fixed_32.o
|
||||
OBJS-$(CONFIG_MDCT) += mdct_fixed.o mdct_float.o
|
||||
OBJS-$(CONFIG_MPEGAUDIO) += mpegaudio.o mpegaudiodata.o \
|
||||
mpegaudiodecheader.o
|
||||
OBJS-$(CONFIG_MPEGAUDIODSP) += mpegaudiodsp.o \
|
||||
@@ -125,8 +121,6 @@ OBJS-$(CONFIG_ASV2_DECODER) += asvdec.o asv.o mpeg12data.o
|
||||
OBJS-$(CONFIG_ASV2_ENCODER) += asvenc.o asv.o mpeg12data.o
|
||||
OBJS-$(CONFIG_ATRAC1_DECODER) += atrac1.o atrac.o
|
||||
OBJS-$(CONFIG_ATRAC3_DECODER) += atrac3.o atrac.o
|
||||
OBJS-$(CONFIG_ATRAC3P_DECODER) += atrac3plusdec.o atrac3plus.o \
|
||||
atrac3plusdsp.o atrac.o
|
||||
OBJS-$(CONFIG_AURA_DECODER) += cyuv.o
|
||||
OBJS-$(CONFIG_AURA2_DECODER) += aura.o
|
||||
OBJS-$(CONFIG_AVRN_DECODER) += avrndec.o mjpegdec.o mjpeg.o
|
||||
@@ -154,7 +148,6 @@ OBJS-$(CONFIG_CAVS_DECODER) += cavs.o cavsdec.o cavsdsp.o \
|
||||
OBJS-$(CONFIG_CDGRAPHICS_DECODER) += cdgraphics.o
|
||||
OBJS-$(CONFIG_CDXL_DECODER) += cdxl.o
|
||||
OBJS-$(CONFIG_CINEPAK_DECODER) += cinepak.o
|
||||
OBJS-$(CONFIG_CINEPAK_ENCODER) += cinepakenc.o elbg.o
|
||||
OBJS-$(CONFIG_CLJR_DECODER) += cljr.o
|
||||
OBJS-$(CONFIG_CLJR_ENCODER) += cljr.o
|
||||
OBJS-$(CONFIG_CLLC_DECODER) += cllc.o
|
||||
@@ -181,7 +174,7 @@ OBJS-$(CONFIG_DVBSUB_ENCODER) += dvbsub.o
|
||||
OBJS-$(CONFIG_DVDSUB_DECODER) += dvdsubdec.o
|
||||
OBJS-$(CONFIG_DVDSUB_ENCODER) += dvdsubenc.o
|
||||
OBJS-$(CONFIG_DVVIDEO_DECODER) += dvdec.o dv.o dvdata.o dv_profile.o
|
||||
OBJS-$(CONFIG_DVVIDEO_ENCODER) += dvenc.o dv.o dvdata.o dv_profile.o
|
||||
OBJS-$(CONFIG_DVVIDEO_ENCODER) += dv.o dvdata.o dv_profile.o
|
||||
OBJS-$(CONFIG_DXA_DECODER) += dxa.o
|
||||
OBJS-$(CONFIG_DXTORY_DECODER) += dxtory.o
|
||||
OBJS-$(CONFIG_EAC3_DECODER) += eac3dec.o eac3_data.o
|
||||
@@ -205,7 +198,6 @@ OBJS-$(CONFIG_FFV1_ENCODER) += ffv1enc.o ffv1.o
|
||||
OBJS-$(CONFIG_FFVHUFF_DECODER) += huffyuv.o huffyuvdec.o
|
||||
OBJS-$(CONFIG_FFVHUFF_ENCODER) += huffyuv.o huffyuvenc.o
|
||||
OBJS-$(CONFIG_FFWAVESYNTH_DECODER) += ffwavesynth.o
|
||||
OBJS-$(CONFIG_FIC_DECODER) += fic.o
|
||||
OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o flacdsp.o
|
||||
OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o flacdsp.o vorbis_data.o
|
||||
OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o
|
||||
@@ -237,10 +229,6 @@ OBJS-$(CONFIG_H264_DECODER) += h264.o \
|
||||
cabac.o h264_sei.o h264_ps.o \
|
||||
h264_refs.o h264_cavlc.o h264_cabac.o
|
||||
OBJS-$(CONFIG_H264_VDA_DECODER) += vda_h264_dec.o
|
||||
OBJS-$(CONFIG_HEVC_DECODER) += hevc.o hevc_mvs.o hevc_ps.o hevc_sei.o \
|
||||
hevc_cabac.o hevc_refs.o hevcpred.o \
|
||||
hevcdsp.o hevc_filter.o cabac.o
|
||||
OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o
|
||||
OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o huffyuvdec.o
|
||||
OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o huffyuvenc.o
|
||||
OBJS-$(CONFIG_IAC_DECODER) += imc.o
|
||||
@@ -272,8 +260,6 @@ OBJS-$(CONFIG_LOCO_DECODER) += loco.o
|
||||
OBJS-$(CONFIG_MACE3_DECODER) += mace.o
|
||||
OBJS-$(CONFIG_MACE6_DECODER) += mace.o
|
||||
OBJS-$(CONFIG_MDEC_DECODER) += mdec.o mpeg12.o mpeg12data.o
|
||||
OBJS-$(CONFIG_METASOUND_DECODER) += metasound.o metasound_data.o \
|
||||
twinvq.o
|
||||
OBJS-$(CONFIG_MICRODVD_DECODER) += microdvddec.o ass.o
|
||||
OBJS-$(CONFIG_MIMIC_DECODER) += mimic.o
|
||||
OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpeg.o
|
||||
@@ -284,34 +270,40 @@ OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o
|
||||
OBJS-$(CONFIG_MOTIONPIXELS_DECODER) += motionpixels.o
|
||||
OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o
|
||||
OBJS-$(CONFIG_MOVTEXT_ENCODER) += movtextenc.o ass_split.o
|
||||
OBJS-$(CONFIG_MP1_DECODER) += mpegaudiodec_fixed.o
|
||||
OBJS-$(CONFIG_MP1_DECODER) += mpegaudiodec.o
|
||||
OBJS-$(CONFIG_MP1FLOAT_DECODER) += mpegaudiodec_float.o
|
||||
OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec_fixed.o
|
||||
OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc_float.o mpegaudio.o \
|
||||
mpegaudiodata.o mpegaudiodsp_data.o
|
||||
OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc_fixed.o mpegaudio.o \
|
||||
OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec.o
|
||||
OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc.o mpegaudio.o \
|
||||
mpegaudiodata.o mpegaudiodsp_data.o
|
||||
OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o
|
||||
OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec_fixed.o
|
||||
OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec_fixed.o
|
||||
OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec.o
|
||||
OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec.o
|
||||
OBJS-$(CONFIG_MP3ADUFLOAT_DECODER) += mpegaudiodec_float.o
|
||||
OBJS-$(CONFIG_MP3FLOAT_DECODER) += mpegaudiodec_float.o
|
||||
OBJS-$(CONFIG_MP3ON4_DECODER) += mpegaudiodec_fixed.o mpeg4audio.o
|
||||
OBJS-$(CONFIG_MP3ON4_DECODER) += mpegaudiodec.o mpeg4audio.o
|
||||
OBJS-$(CONFIG_MP3ON4FLOAT_DECODER) += mpegaudiodec_float.o mpeg4audio.o
|
||||
OBJS-$(CONFIG_MPC7_DECODER) += mpc7.o mpc.o
|
||||
OBJS-$(CONFIG_MPC8_DECODER) += mpc8.o mpc.o
|
||||
OBJS-$(CONFIG_MPEGVIDEO_DECODER) += mpeg12.o mpeg12data.o \
|
||||
mpegvideo.o error_resilience.o
|
||||
OBJS-$(CONFIG_MPEG_XVMC_DECODER) += mpegvideo_xvmc.o
|
||||
OBJS-$(CONFIG_MPEG1VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o
|
||||
OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpeg12.o
|
||||
OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o
|
||||
OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o
|
||||
OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o \
|
||||
timecode.o
|
||||
OBJS-$(CONFIG_MPL2_DECODER) += mpl2dec.o ass.o
|
||||
OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4enc.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_MSMPEG4V3_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4enc.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o \
|
||||
h263dec.o h263.o ituh263dec.o \
|
||||
mpeg4videodec.o
|
||||
OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4.o msmpeg4enc.o msmpeg4data.o \
|
||||
h263.o
|
||||
OBJS-$(CONFIG_MSMPEG4V3_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o \
|
||||
h263dec.o h263.o ituh263dec.o \
|
||||
mpeg4videodec.o
|
||||
OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4.o msmpeg4enc.o msmpeg4data.o \
|
||||
h263.o
|
||||
OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o
|
||||
OBJS-$(CONFIG_MSA1_DECODER) += mss3.o mss34dsp.o
|
||||
OBJS-$(CONFIG_MSS1_DECODER) += mss1.o mss12.o
|
||||
@@ -329,27 +321,27 @@ OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o
|
||||
OBJS-$(CONFIG_PAF_VIDEO_DECODER) += paf.o
|
||||
OBJS-$(CONFIG_PAF_AUDIO_DECODER) += paf.o
|
||||
OBJS-$(CONFIG_PAM_DECODER) += pnmdec.o pnm.o
|
||||
OBJS-$(CONFIG_PAM_ENCODER) += pamenc.o
|
||||
OBJS-$(CONFIG_PAM_ENCODER) += pamenc.o pnm.o
|
||||
OBJS-$(CONFIG_PBM_DECODER) += pnmdec.o pnm.o
|
||||
OBJS-$(CONFIG_PBM_ENCODER) += pnmenc.o
|
||||
OBJS-$(CONFIG_PBM_ENCODER) += pnmenc.o pnm.o
|
||||
OBJS-$(CONFIG_PCX_DECODER) += pcx.o
|
||||
OBJS-$(CONFIG_PCX_ENCODER) += pcxenc.o
|
||||
OBJS-$(CONFIG_PGM_DECODER) += pnmdec.o pnm.o
|
||||
OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o
|
||||
OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o pnm.o
|
||||
OBJS-$(CONFIG_PGMYUV_DECODER) += pnmdec.o pnm.o
|
||||
OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o
|
||||
OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o pnm.o
|
||||
OBJS-$(CONFIG_PGSSUB_DECODER) += pgssubdec.o
|
||||
OBJS-$(CONFIG_PICTOR_DECODER) += pictordec.o cga_data.o
|
||||
OBJS-$(CONFIG_PJS_DECODER) += textdec.o ass.o
|
||||
OBJS-$(CONFIG_PNG_DECODER) += png.o pngdec.o pngdsp.o
|
||||
OBJS-$(CONFIG_PNG_ENCODER) += png.o pngenc.o
|
||||
OBJS-$(CONFIG_PPM_DECODER) += pnmdec.o pnm.o
|
||||
OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o
|
||||
OBJS-$(CONFIG_PRORES_DECODER) += proresdec2.o proresdsp.o proresdata.o
|
||||
OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o pnm.o
|
||||
OBJS-$(CONFIG_PRORES_DECODER) += proresdec2.o proresdsp.o
|
||||
OBJS-$(CONFIG_PRORES_LGPL_DECODER) += proresdec_lgpl.o proresdsp.o proresdata.o
|
||||
OBJS-$(CONFIG_PRORES_ENCODER) += proresenc_anatoliy.o
|
||||
OBJS-$(CONFIG_PRORES_AW_ENCODER) += proresenc_anatoliy.o
|
||||
OBJS-$(CONFIG_PRORES_KS_ENCODER) += proresenc_kostya.o proresdata.o
|
||||
OBJS-$(CONFIG_PRORES_KS_ENCODER) += proresenc_kostya.o proresdata.o proresdsp.o
|
||||
OBJS-$(CONFIG_PTX_DECODER) += ptx.o
|
||||
OBJS-$(CONFIG_QCELP_DECODER) += qcelpdec.o \
|
||||
celp_filters.o acelp_vectors.o \
|
||||
@@ -429,7 +421,7 @@ OBJS-$(CONFIG_TARGA_Y216_DECODER) += targa_y216dec.o
|
||||
OBJS-$(CONFIG_THEORA_DECODER) += xiph.o
|
||||
OBJS-$(CONFIG_THP_DECODER) += mjpegdec.o mjpeg.o
|
||||
OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o
|
||||
OBJS-$(CONFIG_TIFF_DECODER) += tiff.o lzw.o faxcompr.o tiff_data.o tiff_common.o
|
||||
OBJS-$(CONFIG_TIFF_DECODER) += tiff.o lzw.o faxcompr.o tiff_data.o
|
||||
OBJS-$(CONFIG_TIFF_ENCODER) += tiffenc.o rle.o lzwenc.o tiff_data.o
|
||||
OBJS-$(CONFIG_TMV_DECODER) += tmv.o cga_data.o
|
||||
OBJS-$(CONFIG_TRUEHD_DECODER) += mlpdec.o mlpdsp.o
|
||||
@@ -438,9 +430,9 @@ OBJS-$(CONFIG_TRUEMOTION2_DECODER) += truemotion2.o
|
||||
OBJS-$(CONFIG_TRUESPEECH_DECODER) += truespeech.o
|
||||
OBJS-$(CONFIG_TSCC_DECODER) += tscc.o msrledec.o
|
||||
OBJS-$(CONFIG_TSCC2_DECODER) += tscc2.o
|
||||
OBJS-$(CONFIG_TTA_DECODER) += tta.o ttadata.o ttadsp.o
|
||||
OBJS-$(CONFIG_TTA_DECODER) += tta.o ttadata.o
|
||||
OBJS-$(CONFIG_TTA_ENCODER) += ttaenc.o ttadata.o
|
||||
OBJS-$(CONFIG_TWINVQ_DECODER) += twinvqdec.o twinvq.o
|
||||
OBJS-$(CONFIG_TWINVQ_DECODER) += twinvq.o
|
||||
OBJS-$(CONFIG_TXD_DECODER) += txd.o s3tc.o
|
||||
OBJS-$(CONFIG_ULTI_DECODER) += ulti.o
|
||||
OBJS-$(CONFIG_UTVIDEO_DECODER) += utvideodec.o utvideo.o
|
||||
@@ -458,7 +450,7 @@ OBJS-$(CONFIG_VB_DECODER) += vb.o
|
||||
OBJS-$(CONFIG_VBLE_DECODER) += vble.o
|
||||
OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1.o vc1data.o vc1dsp.o \
|
||||
msmpeg4dec.o msmpeg4.o msmpeg4data.o \
|
||||
wmv2dsp.o
|
||||
intrax8.o intrax8dsp.o wmv2dsp.o
|
||||
OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o
|
||||
OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdav.o
|
||||
OBJS-$(CONFIG_VMDVIDEO_DECODER) += vmdav.o
|
||||
@@ -473,13 +465,10 @@ OBJS-$(CONFIG_VP5_DECODER) += vp5.o vp56.o vp56data.o vp56dsp.o \
|
||||
OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o vp56dsp.o \
|
||||
vp6dsp.o vp56rac.o
|
||||
OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp8dsp.o vp56rac.o
|
||||
OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9dsp.o vp56rac.o
|
||||
OBJS-$(CONFIG_VPLAYER_DECODER) += textdec.o ass.o
|
||||
OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o
|
||||
OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o
|
||||
OBJS-$(CONFIG_WAVPACK_ENCODER) += wavpackenc.o
|
||||
OBJS-$(CONFIG_WEBP_DECODER) += vp8.o vp8dsp.o vp56rac.o
|
||||
OBJS-$(CONFIG_WEBP_DECODER) += webp.o exif.o tiff_common.o
|
||||
OBJS-$(CONFIG_WEBVTT_DECODER) += webvttdec.o
|
||||
OBJS-$(CONFIG_WMALOSSLESS_DECODER) += wmalosslessdec.o wma_common.o
|
||||
OBJS-$(CONFIG_WMAPRO_DECODER) += wmaprodec.o wma.o wma_common.o
|
||||
@@ -492,7 +481,8 @@ OBJS-$(CONFIG_WMAVOICE_DECODER) += wmavoice.o \
|
||||
acelp_vectors.o acelp_filters.o
|
||||
OBJS-$(CONFIG_WMV1_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o wmv2dsp.o \
|
||||
msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
msmpeg4dec.o msmpeg4.o msmpeg4data.o \
|
||||
intrax8.o intrax8dsp.o
|
||||
OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o wmv2dsp.o \
|
||||
msmpeg4.o msmpeg4enc.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o
|
||||
@@ -524,8 +514,8 @@ OBJS-$(CONFIG_ZMBV_ENCODER) += zmbvenc.o
|
||||
# (AD)PCM decoders/encoders
|
||||
OBJS-$(CONFIG_PCM_ALAW_DECODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_ALAW_ENCODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_BLURAY_DECODER) += pcm-bluray.o
|
||||
OBJS-$(CONFIG_PCM_DVD_DECODER) += pcm-dvd.o
|
||||
OBJS-$(CONFIG_PCM_BLURAY_DECODER) += pcm-mpeg.o
|
||||
OBJS-$(CONFIG_PCM_DVD_DECODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_F32BE_DECODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_F32BE_ENCODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_F32LE_DECODER) += pcm.o
|
||||
@@ -595,7 +585,6 @@ OBJS-$(CONFIG_ADPCM_G722_DECODER) += g722.o g722dec.o
|
||||
OBJS-$(CONFIG_ADPCM_G722_ENCODER) += g722.o g722enc.o
|
||||
OBJS-$(CONFIG_ADPCM_G726_DECODER) += g726.o
|
||||
OBJS-$(CONFIG_ADPCM_G726_ENCODER) += g726.o
|
||||
OBJS-$(CONFIG_ADPCM_G726LE_DECODER) += g726.o
|
||||
OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_IMA_APC_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER) += adpcm.o adpcm_data.o
|
||||
@@ -625,22 +614,20 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o
|
||||
OBJS-$(CONFIG_VIMA_DECODER) += vima.o adpcm_data.o
|
||||
|
||||
# hardware accelerators
|
||||
OBJS-$(CONFIG_H263_VAAPI_HWACCEL) += vaapi_mpeg4.o vaapi_mpeg.o
|
||||
OBJS-$(CONFIG_H263_VAAPI_HWACCEL) += vaapi_mpeg4.o
|
||||
OBJS-$(CONFIG_H263_VDPAU_HWACCEL) += vdpau_mpeg4.o
|
||||
OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o
|
||||
OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o
|
||||
OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o
|
||||
OBJS-$(CONFIG_H264_VDPAU_HWACCEL) += vdpau_h264.o
|
||||
OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL) += vdpau_mpeg12.o
|
||||
OBJS-$(CONFIG_MPEG1_XVMC_HWACCEL) += mpegvideo_xvmc.o
|
||||
OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o vaapi_mpeg.o
|
||||
OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o
|
||||
OBJS-$(CONFIG_MPEG2_XVMC_HWACCEL) += mpegvideo_xvmc.o
|
||||
OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o vaapi_mpeg.o
|
||||
OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o
|
||||
OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL) += vdpau_mpeg4.o
|
||||
OBJS-$(CONFIG_VC1_DXVA2_HWACCEL) += dxva2_vc1.o
|
||||
OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o vaapi_mpeg.o
|
||||
OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o
|
||||
OBJS-$(CONFIG_VC1_VDPAU_HWACCEL) += vdpau_vc1.o
|
||||
|
||||
# libavformat dependencies
|
||||
@@ -649,7 +636,7 @@ OBJS-$(CONFIG_ADX_DEMUXER) += adx.o
|
||||
OBJS-$(CONFIG_CAF_DEMUXER) += mpeg4audio.o mpegaudiodata.o \
|
||||
ac3tab.o
|
||||
OBJS-$(CONFIG_DV_DEMUXER) += dv_profile.o
|
||||
OBJS-$(CONFIG_DV_MUXER) += dv_profile.o
|
||||
OBJS-$(CONFIG_DV_MUXER) += dv_profile.o timecode.o
|
||||
OBJS-$(CONFIG_FLAC_DEMUXER) += flac.o flacdata.o vorbis_data.o \
|
||||
vorbis_parser.o xiph.o
|
||||
OBJS-$(CONFIG_FLAC_MUXER) += flac.o flacdata.o vorbis_data.o
|
||||
@@ -665,11 +652,11 @@ OBJS-$(CONFIG_MATROSKA_MUXER) += mpeg4audio.o mpegaudiodata.o \
|
||||
flac.o flacdata.o vorbis_data.o xiph.o
|
||||
OBJS-$(CONFIG_MP2_MUXER) += mpegaudiodata.o mpegaudiodecheader.o
|
||||
OBJS-$(CONFIG_MP3_MUXER) += mpegaudiodata.o mpegaudiodecheader.o
|
||||
OBJS-$(CONFIG_MOV_DEMUXER) += mpeg4audio.o mpegaudiodata.o ac3tab.o
|
||||
OBJS-$(CONFIG_MOV_DEMUXER) += mpeg4audio.o mpegaudiodata.o ac3tab.o timecode.o
|
||||
OBJS-$(CONFIG_MOV_MUXER) += mpeg4audio.o mpegaudiodata.o
|
||||
OBJS-$(CONFIG_MPEGTS_MUXER) += mpeg4audio.o
|
||||
OBJS-$(CONFIG_MPEGTS_DEMUXER) += mpeg4audio.o mpegaudiodata.o
|
||||
OBJS-$(CONFIG_MXF_MUXER) += dnxhddata.o
|
||||
OBJS-$(CONFIG_MXF_MUXER) += timecode.o dnxhddata.o
|
||||
OBJS-$(CONFIG_NUT_MUXER) += mpegaudiodata.o
|
||||
OBJS-$(CONFIG_OGG_DEMUXER) += xiph.o flac.o flacdata.o \
|
||||
mpeg12data.o vorbis_parser.o \
|
||||
@@ -686,14 +673,10 @@ OBJS-$(CONFIG_WEBM_MUXER) += mpeg4audio.o mpegaudiodata.o \
|
||||
vorbis_data.o
|
||||
OBJS-$(CONFIG_WTV_DEMUXER) += mpeg4audio.o mpegaudiodata.o
|
||||
|
||||
# libavfilter dependencies
|
||||
OBJS-$(CONFIG_ELBG_FILTER) += elbg.o
|
||||
|
||||
# external codec libraries
|
||||
OBJS-$(CONFIG_LIBAACPLUS_ENCODER) += libaacplus.o
|
||||
OBJS-$(CONFIG_LIBCELT_DECODER) += libcelt_dec.o
|
||||
OBJS-$(CONFIG_LIBFAAC_ENCODER) += libfaac.o
|
||||
OBJS-$(CONFIG_LIBFDK_AAC_DECODER) += libfdk-aacdec.o
|
||||
OBJS-$(CONFIG_LIBFDK_AAC_ENCODER) += libfdk-aacenc.o
|
||||
OBJS-$(CONFIG_LIBGSM_DECODER) += libgsm.o
|
||||
OBJS-$(CONFIG_LIBGSM_ENCODER) += libgsm.o
|
||||
@@ -730,15 +713,12 @@ OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbisenc.o \
|
||||
vorbis_data.o vorbis_parser.o xiph.o
|
||||
OBJS-$(CONFIG_LIBVPX_VP8_DECODER) += libvpxdec.o
|
||||
OBJS-$(CONFIG_LIBVPX_VP8_ENCODER) += libvpxenc.o
|
||||
OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o libvpx.o
|
||||
OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o libvpx.o
|
||||
OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o
|
||||
OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o
|
||||
OBJS-$(CONFIG_LIBWAVPACK_ENCODER) += libwavpackenc.o
|
||||
OBJS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc.o
|
||||
OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o
|
||||
OBJS-$(CONFIG_LIBX265_ENCODER) += libx265.o
|
||||
OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o
|
||||
OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvid.o
|
||||
OBJS-$(CONFIG_LIBZVBI_TELETEXT_DECODER) += libzvbi-teletextdec.o
|
||||
|
||||
# parsers
|
||||
OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o \
|
||||
@@ -753,7 +733,6 @@ OBJS-$(CONFIG_COOK_PARSER) += cook_parser.o
|
||||
OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o dca.o
|
||||
OBJS-$(CONFIG_DIRAC_PARSER) += dirac_parser.o
|
||||
OBJS-$(CONFIG_DNXHD_PARSER) += dnxhd_parser.o
|
||||
OBJS-$(CONFIG_DPX_PARSER) += dpx_parser.o
|
||||
OBJS-$(CONFIG_DVBSUB_PARSER) += dvbsub_parser.o
|
||||
OBJS-$(CONFIG_DVD_NAV_PARSER) += dvd_nav_parser.o
|
||||
OBJS-$(CONFIG_DVDSUB_PARSER) += dvdsub_parser.o
|
||||
@@ -767,7 +746,6 @@ OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264.o \
|
||||
h264_refs.o h264_sei.o h264_direct.o \
|
||||
h264_loopfilter.o h264_cabac.o \
|
||||
h264_cavlc.o h264_ps.o
|
||||
OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o
|
||||
OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg_parser.o
|
||||
OBJS-$(CONFIG_MLP_PARSER) += mlp_parser.o mlp.o
|
||||
OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \
|
||||
@@ -778,7 +756,6 @@ OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o \
|
||||
mpegaudiodecheader.o mpegaudiodata.o
|
||||
OBJS-$(CONFIG_MPEGVIDEO_PARSER) += mpegvideo_parser.o \
|
||||
mpeg12.o mpeg12data.o
|
||||
OBJS-$(CONFIG_PNG_PARSER) += png_parser.o
|
||||
OBJS-$(CONFIG_PNM_PARSER) += pnm_parser.o pnm.o
|
||||
OBJS-$(CONFIG_RV30_PARSER) += rv34_parser.o
|
||||
OBJS-$(CONFIG_RV40_PARSER) += rv34_parser.o
|
||||
@@ -789,7 +766,6 @@ OBJS-$(CONFIG_VC1_PARSER) += vc1_parser.o vc1.o vc1data.o \
|
||||
OBJS-$(CONFIG_VORBIS_PARSER) += vorbis_parser.o xiph.o
|
||||
OBJS-$(CONFIG_VP3_PARSER) += vp3_parser.o
|
||||
OBJS-$(CONFIG_VP8_PARSER) += vp8_parser.o
|
||||
OBJS-$(CONFIG_VP9_PARSER) += vp9_parser.o
|
||||
|
||||
# bitstream filters
|
||||
OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o aacadtsdec.o \
|
||||
@@ -801,6 +777,7 @@ OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o
|
||||
OBJS-$(CONFIG_MJPEG2JPEG_BSF) += mjpeg2jpeg_bsf.o mjpeg.o
|
||||
OBJS-$(CONFIG_MJPEGA_DUMP_HEADER_BSF) += mjpega_dump_header_bsf.o
|
||||
OBJS-$(CONFIG_MOV2TEXTSUB_BSF) += movsub_bsf.o
|
||||
OBJS-$(CONFIG_MP3_HEADER_COMPRESS_BSF) += mp3_header_compress_bsf.o
|
||||
OBJS-$(CONFIG_MP3_HEADER_DECOMPRESS_BSF) += mp3_header_decompress_bsf.o \
|
||||
mpegaudiodata.o
|
||||
OBJS-$(CONFIG_NOISE_BSF) += noise_bsf.o
|
||||
@@ -808,14 +785,12 @@ OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o
|
||||
OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o
|
||||
|
||||
# thread libraries
|
||||
OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o
|
||||
OBJS-$(HAVE_THREADS) += pthread.o pthread_slice.o pthread_frame.o
|
||||
OBJS-$(HAVE_PTHREADS) += pthread.o
|
||||
OBJS-$(HAVE_W32THREADS) += pthread.o
|
||||
OBJS-$(HAVE_OS2THREADS) += pthread.o
|
||||
|
||||
OBJS-$(CONFIG_FRAME_THREAD_ENCODER) += frame_thread_encoder.o
|
||||
|
||||
# Windows resource file
|
||||
SLIBOBJS-$(HAVE_GNU_WINDRES) += avcodecres.o
|
||||
|
||||
SKIPHEADERS += %_tablegen.h \
|
||||
%_tables.h \
|
||||
aac_tablegen_decl.h \
|
||||
@@ -827,22 +802,21 @@ SKIPHEADERS += %_tablegen.h \
|
||||
SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h
|
||||
SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h
|
||||
SKIPHEADERS-$(CONFIG_LIBUTVIDEO) += libutvideo.h
|
||||
SKIPHEADERS-$(CONFIG_XVMC) += xvmc.h
|
||||
SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h
|
||||
SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_internal.h
|
||||
SKIPHEADERS-$(CONFIG_VDA) += vda.h
|
||||
SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h
|
||||
SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h
|
||||
|
||||
TESTPROGS = cabac \
|
||||
dct \
|
||||
fft \
|
||||
fft-fixed \
|
||||
fft-fixed32 \
|
||||
golomb \
|
||||
iirfilter \
|
||||
imgconvert \
|
||||
rangecoder \
|
||||
snowenc \
|
||||
|
||||
TESTPROGS-$(CONFIG_DCT) += dct
|
||||
TESTPROGS-$(HAVE_MMX) += motion
|
||||
TESTOBJS = dctref.o
|
||||
|
||||
@@ -862,7 +836,6 @@ HOSTPROGS = aac_tablegen \
|
||||
CLEANFILES = *_tables.c *_tables.h *_tablegen$(HOSTEXESUF)
|
||||
|
||||
$(SUBDIR)dct-test$(EXESUF): $(SUBDIR)dctref.o $(SUBDIR)aandcttab.o
|
||||
$(SUBDIR)dv_tablegen$(HOSTEXESUF): $(SUBDIR)dvdata_host.o
|
||||
|
||||
TRIG_TABLES = cos cos_fixed sin
|
||||
TRIG_TABLES := $(TRIG_TABLES:%=$(SUBDIR)%_tables.c)
|
||||
@@ -888,9 +861,9 @@ ifdef CONFIG_HARDCODED_TABLES
|
||||
$(SUBDIR)aacdec.o: $(SUBDIR)cbrt_tables.h
|
||||
$(SUBDIR)aacps.o: $(SUBDIR)aacps_tables.h
|
||||
$(SUBDIR)aactab.o: $(SUBDIR)aac_tables.h
|
||||
$(SUBDIR)dvenc.o: $(SUBDIR)dv_tables.h
|
||||
$(SUBDIR)dv.o: $(SUBDIR)dv_tables.h
|
||||
$(SUBDIR)sinewin.o: $(SUBDIR)sinewin_tables.h
|
||||
$(SUBDIR)mpegaudiodec_fixed.o: $(SUBDIR)mpegaudio_tables.h
|
||||
$(SUBDIR)mpegaudiodec.o: $(SUBDIR)mpegaudio_tables.h
|
||||
$(SUBDIR)mpegaudiodec_float.o: $(SUBDIR)mpegaudio_tables.h
|
||||
$(SUBDIR)motionpixels.o: $(SUBDIR)motionpixels_tables.h
|
||||
$(SUBDIR)pcm.o: $(SUBDIR)pcm_tables.h
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
#define C64YRES 200
|
||||
|
||||
typedef struct A64Context {
|
||||
/* general variables */
|
||||
AVFrame picture;
|
||||
|
||||
/* variables for multicolor modes */
|
||||
AVLFG randctx;
|
||||
int mc_lifetime;
|
||||
@@ -78,9 +81,13 @@ static void to_meta_with_crop(AVCodecContext *avctx, AVFrame *p, int *dest)
|
||||
for (y = blocky; y < blocky + 8 && y < C64YRES; y++) {
|
||||
for (x = blockx; x < blockx + 8 && x < C64XRES; x += 2) {
|
||||
if(x < width && y < height) {
|
||||
/* build average over 2 pixels */
|
||||
luma = (src[(x + 0 + y * p->linesize[0])] +
|
||||
src[(x + 1 + y * p->linesize[0])]) / 2;
|
||||
if (x + 1 < width) {
|
||||
/* build average over 2 pixels */
|
||||
luma = (src[(x + 0 + y * p->linesize[0])] +
|
||||
src[(x + 1 + y * p->linesize[0])]) / 2;
|
||||
} else {
|
||||
luma = src[(x + y * p->linesize[0])];
|
||||
}
|
||||
/* write blocks as linear data now so they are suitable for elbg */
|
||||
dest[0] = luma;
|
||||
}
|
||||
@@ -186,7 +193,6 @@ static void render_charset(AVCodecContext *avctx, uint8_t *charset,
|
||||
static av_cold int a64multi_close_encoder(AVCodecContext *avctx)
|
||||
{
|
||||
A64Context *c = avctx->priv_data;
|
||||
av_frame_free(&avctx->coded_frame);
|
||||
av_free(c->mc_meta_charset);
|
||||
av_free(c->mc_best_cb);
|
||||
av_free(c->mc_charset);
|
||||
@@ -195,7 +201,7 @@ static av_cold int a64multi_close_encoder(AVCodecContext *avctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_cold int a64multi_encode_init(AVCodecContext *avctx)
|
||||
static av_cold int a64multi_init_encoder(AVCodecContext *avctx)
|
||||
{
|
||||
A64Context *c = avctx->priv_data;
|
||||
int a;
|
||||
@@ -238,12 +244,8 @@ static av_cold int a64multi_encode_init(AVCodecContext *avctx)
|
||||
AV_WB32(avctx->extradata, c->mc_lifetime);
|
||||
AV_WB32(avctx->extradata + 16, INTERLACED);
|
||||
|
||||
avctx->coded_frame = av_frame_alloc();
|
||||
if (!avctx->coded_frame) {
|
||||
a64multi_close_encoder(avctx);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
avcodec_get_frame_defaults(&c->picture);
|
||||
avctx->coded_frame = &c->picture;
|
||||
avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
|
||||
avctx->coded_frame->key_frame = 1;
|
||||
if (!avctx->codec_tag)
|
||||
@@ -273,7 +275,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
||||
const AVFrame *pict, int *got_packet)
|
||||
{
|
||||
A64Context *c = avctx->priv_data;
|
||||
AVFrame *const p = avctx->coded_frame;
|
||||
AVFrame *const p = &c->picture;
|
||||
|
||||
int frame;
|
||||
int x, y;
|
||||
@@ -317,7 +319,9 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
||||
} else {
|
||||
/* fill up mc_meta_charset with data until lifetime exceeds */
|
||||
if (c->mc_frame_counter < c->mc_lifetime) {
|
||||
*p = *pict;
|
||||
ret = av_frame_ref(p, pict);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
p->pict_type = AV_PICTURE_TYPE_I;
|
||||
p->key_frame = 1;
|
||||
to_meta_with_crop(avctx, p, meta + 32000 * c->mc_frame_counter);
|
||||
@@ -334,14 +338,14 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
||||
req_size = 0;
|
||||
/* any frames to encode? */
|
||||
if (c->mc_lifetime) {
|
||||
req_size = charset_size + c->mc_lifetime*(screen_size + colram_size);
|
||||
if ((ret = ff_alloc_packet2(avctx, pkt, req_size)) < 0)
|
||||
int alloc_size = charset_size + c->mc_lifetime*(screen_size + colram_size);
|
||||
if ((ret = ff_alloc_packet2(avctx, pkt, alloc_size)) < 0)
|
||||
return ret;
|
||||
buf = pkt->data;
|
||||
|
||||
/* calc optimal new charset + charmaps */
|
||||
avpriv_init_elbg(meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx);
|
||||
avpriv_do_elbg (meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx);
|
||||
ff_init_elbg(meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx);
|
||||
ff_do_elbg (meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx);
|
||||
|
||||
/* create colorram map and a c64 readable charset */
|
||||
render_charset(avctx, charset, colram);
|
||||
@@ -352,6 +356,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
||||
/* advance pointers */
|
||||
buf += charset_size;
|
||||
charset += charset_size;
|
||||
req_size += charset_size;
|
||||
}
|
||||
|
||||
/* write x frames to buf */
|
||||
@@ -398,28 +403,28 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
||||
#if CONFIG_A64MULTI_ENCODER
|
||||
AVCodec ff_a64multi_encoder = {
|
||||
.name = "a64multi",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64"),
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.id = AV_CODEC_ID_A64_MULTI,
|
||||
.priv_data_size = sizeof(A64Context),
|
||||
.init = a64multi_encode_init,
|
||||
.init = a64multi_init_encoder,
|
||||
.encode2 = a64multi_encode_frame,
|
||||
.close = a64multi_close_encoder,
|
||||
.pix_fmts = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64"),
|
||||
.capabilities = CODEC_CAP_DELAY,
|
||||
};
|
||||
#endif
|
||||
#if CONFIG_A64MULTI5_ENCODER
|
||||
AVCodec ff_a64multi5_encoder = {
|
||||
.name = "a64multi5",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64, extended with 5th color (colram)"),
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.id = AV_CODEC_ID_A64_MULTI5,
|
||||
.priv_data_size = sizeof(A64Context),
|
||||
.init = a64multi_encode_init,
|
||||
.init = a64multi_init_encoder,
|
||||
.encode2 = a64multi_encode_frame,
|
||||
.close = a64multi_close_encoder,
|
||||
.pix_fmts = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64, extended with 5th color (colram)"),
|
||||
.capabilities = CODEC_CAP_DELAY,
|
||||
};
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user