Compare commits
380 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2b6bc8e340 | |||
| 470bdd397f | |||
| 0ca22536c7 | |||
| 4621bc436b | |||
| d94d786bf0 | |||
| 3f69797e9b | |||
| 49fc747b48 | |||
| 526aca805f | |||
| cec42e6f4d | |||
| 7e2c695169 | |||
| cff516d9e8 | |||
| 0696a555b6 | |||
| 62e87d065b | |||
| 3d9f1c0dbb | |||
| 1bccba1893 | |||
| f3da3e2aed | |||
| e112096885 | |||
| c6bb765972 | |||
| 24bd4b363e | |||
| fbe2f77e3f | |||
| 51f686fa77 | |||
| 873ca28390 | |||
| 91b6d89d0a | |||
| 2a73404558 | |||
| 72b224e3f6 | |||
| 7b1803a427 | |||
| f00f588a6e | |||
| dc92c6045f | |||
| 46e4028e69 | |||
| 6fe1f5646e | |||
| c6950985cb | |||
| 751e525757 | |||
| 19257891d1 | |||
| c7b34fa733 | |||
| b8148973c5 | |||
| 8dce138510 | |||
| 13b75ba30a | |||
| 34e76d75a0 | |||
| 010fd5deb6 | |||
| 46e791a9b3 | |||
| d2161b8a6d | |||
| c5e12dc10d | |||
| 4ecb216ad4 | |||
| d2b2c66b17 | |||
| bbea86d809 | |||
| 12f256a729 | |||
| b54b8a628c | |||
| d8b37664d5 | |||
| 41f97fe378 | |||
| 197c0f618a | |||
| 573a7b4c67 | |||
| 3c7597f2e9 | |||
| 965a8bda94 | |||
| e229fbf5ce | |||
| 874945c7b9 | |||
| 974f9d255d | |||
| 302f11e719 | |||
| 8c2f006d10 | |||
| 3cd17b9b5c | |||
| 4180a83892 | |||
| 6fabd85865 | |||
| c6ab367dbe | |||
| 40e846bb3f | |||
| f6755e5e19 | |||
| eb0872335f | |||
| 1b6390dd5b | |||
| edc7ef376b | |||
| 1a88eef93b | |||
| d3cefc271d | |||
| 9d230f4666 | |||
| 4b17205c77 | |||
| 41157f6bff | |||
| f106232e94 | |||
| 269a522aec | |||
| 496c02a065 | |||
| 6fe77207ed | |||
| 00a0c0fd75 | |||
| a21ec4e1ee | |||
| 0c03d860f4 | |||
| a697577a64 | |||
| 99f3f5a8d5 | |||
| d4a7e89793 | |||
| e681e92d2c | |||
| 123d356829 | |||
| 119659b759 | |||
| f0cc6f74fc | |||
| f5060bce31 | |||
| cde38373d1 | |||
| a2b234b917 | |||
| f1cdd93517 | |||
| 0e3c36518d | |||
| 858f43043f | |||
| d0fd9bec1f | |||
| d755045e78 | |||
| 3820c6a979 | |||
| 7cfea0d41c | |||
| 8c08247990 | |||
| 2316c35865 | |||
| 3dd0d43d8c | |||
| 2f6d3459d9 | |||
| 2c58d73413 | |||
| 5b14f436c6 | |||
| d7a13ff23b | |||
| b65c06ee5e | |||
| a7a7c6e44c | |||
| d41b91ba33 | |||
| 34c5f6685a | |||
| 784506c2b5 | |||
| 26241af6f8 | |||
| 7ad0581686 | |||
| 3219de21f4 | |||
| 93eda8dcba | |||
| 1dc135e03d | |||
| f040f3e5d5 | |||
| 7f320ed15d | |||
| 5b88d24f24 | |||
| 3e187a9a2d | |||
| 4bfaa040fc | |||
| 5124bf8ea6 | |||
| 50ce06cc7c | |||
| a628b70831 | |||
| e274976c92 | |||
| 1586fda2fc | |||
| 34b9c7612d | |||
| ea4b99f82c | |||
| 8b30abd020 | |||
| 435b0ab969 | |||
| c78d268e9f | |||
| e56d322032 | |||
| 3ffc224435 | |||
| e7e4c65571 | |||
| 4aa876f288 | |||
| a9ce4583df | |||
| 93fa19addf | |||
| 5c7ffbbda3 | |||
| 8be41ad2bb | |||
| 9a8d2f51cf | |||
| d013f51303 | |||
| 548a07cdc4 | |||
| 0f331f94c0 | |||
| 0a06e2824a | |||
| dc0bc71471 | |||
| 5af5396970 | |||
| d17298b666 | |||
| ece3912daf | |||
| d092b7f04c | |||
| 1601420be4 | |||
| bdf79f29db | |||
| 4e80d4bf25 | |||
| e3ffc7ab4a | |||
| 76cb34f7f5 | |||
| da87a699ea | |||
| 86a52988bd | |||
| d259a0534e | |||
| 710dccf036 | |||
| fc69fa8474 | |||
| 88ccca204a | |||
| 07a3024631 | |||
| cf1f615b67 | |||
| 900039e7dc | |||
| fad0748b92 | |||
| 6c25411c06 | |||
| c1d29678f1 | |||
| 4fe6f9f627 | |||
| 694416e327 | |||
| c1db1a5ff4 | |||
| 8ef86669ca | |||
| 0cd23e0d1e | |||
| ed3d433676 | |||
| 1258bdf7f0 | |||
| 54e94522b8 | |||
| 8405b63294 | |||
| e6264f00ad | |||
| 183f580594 | |||
| 70373bde2d | |||
| 67ed1ee680 | |||
| 1f6c88e287 | |||
| 725d7fb2c6 | |||
| 258584cfaf | |||
| 9e3848328d | |||
| 27f3696502 | |||
| 65dc698607 | |||
| 185126415e | |||
| 93f3752b97 | |||
| cf115791da | |||
| bc3d86cddb | |||
| aa9dadccac | |||
| 0ecde45570 | |||
| ca43c6e1f5 | |||
| 2deaccfe67 | |||
| a9c73b13c1 | |||
| d972df307a | |||
| 082bdba4e7 | |||
| 1039803823 | |||
| acba2a36b3 | |||
| 588a7769c7 | |||
| 08940cd545 | |||
| 196be9284a | |||
| d61c3d1fca | |||
| ec1f59150d | |||
| b996cde193 | |||
| 63465f0070 | |||
| 3300005351 | |||
| 4eb67f3ddc | |||
| ae270314c7 | |||
| b9a3e0af07 | |||
| 132bd4bc4f | |||
| cd8bedb9fa | |||
| d332aa6ec6 | |||
| 169a02da1e | |||
| af3a608e7e | |||
| 327dd70690 | |||
| bcedc2b0f0 | |||
| 6ad10cbec9 | |||
| b0b1b208f5 | |||
| 6acf5ff1d3 | |||
| e98f3ba221 | |||
| 32808460cc | |||
| edf06a0562 | |||
| 5ae4842122 | |||
| ab6f4bc064 | |||
| c3ce508135 | |||
| c6cb24ffbf | |||
| 06c87da410 | |||
| f7ef265387 | |||
| 6d3f047a85 | |||
| f43dac169e | |||
| f10ba15d73 | |||
| 54661cf0b2 | |||
| 50f62fef19 | |||
| abd20c2057 | |||
| d1de492330 | |||
| 04ad22d77a | |||
| a30a30b59a | |||
| 484eb2b0e3 | |||
| 746a65640f | |||
| 50e4d38ce4 | |||
| 1e7ff902f2 | |||
| dceec28eac | |||
| 95db0aa276 | |||
| 1e6f641052 | |||
| 03ef13889c | |||
| ab3f129011 | |||
| ab91919e57 | |||
| 13aaefb70e | |||
| 19a29c92db | |||
| ffcd26d25b | |||
| 42fd94b514 | |||
| 679df05683 | |||
| 717c3ebfa4 | |||
| 43b094fa03 | |||
| 483f5bccc1 | |||
| ce17111ed1 | |||
| a8c8a2f3f4 | |||
| 485372e91c | |||
| b87fc3526f | |||
| d165ec179e | |||
| 94541f5f76 | |||
| 5e71f4aa6a | |||
| 1900d023ae | |||
| 2c8a8a114c | |||
| 99ab664ff8 | |||
| 131f2c366e | |||
| 9362282fd1 | |||
| 1f25a3ddb8 | |||
| e69d8fc619 | |||
| 6197d35a93 | |||
| 8f00ff5ae0 | |||
| eee1faef75 | |||
| 1ef419447e | |||
| 6752f8ef04 | |||
| 98fdd0baf3 | |||
| f7cb979766 | |||
| 0fb4a85603 | |||
| 2ef386d0a6 | |||
| 114c0f002a | |||
| 6b6932471e | |||
| 5ac6daf995 | |||
| 763c0d25b1 | |||
| b1863e3d94 | |||
| 4afccfdc04 | |||
| a3d45dbcc1 | |||
| 15466db69e | |||
| 27816fb9ef | |||
| f06d9dced4 | |||
| 26cb351452 | |||
| 762a5878a6 | |||
| f0af6e705f | |||
| 70b97a89d2 | |||
| 1d1adf5ff4 | |||
| acfad331ad | |||
| 43f8a422b3 | |||
| 95bd0f3a4b | |||
| eddf146ada | |||
| 7293372959 | |||
| 2e1226a695 | |||
| f66d2bf949 | |||
| 4a6ac71742 | |||
| 08337cca05 | |||
| 9c655d2a57 | |||
| f00f799833 | |||
| 05684cee42 | |||
| e693af81b7 | |||
| 73ebc4046e | |||
| 1cbd7b08f6 | |||
| a330aca126 | |||
| 2e7bd0f725 | |||
| a066b2cedd | |||
| a18e8d82de | |||
| 441ef87ea8 | |||
| 6e53134f98 | |||
| 237751eb25 | |||
| 264eb0074f | |||
| 7db809a373 | |||
| 0df814cf97 | |||
| 88fa3243dd | |||
| 2a6f2cd848 | |||
| c001472226 | |||
| 1ec0541ae0 | |||
| 151554e1eb | |||
| ac91bfe086 | |||
| bbcf6f5c62 | |||
| e740506d31 | |||
| 65aac419e5 | |||
| 662714abbe | |||
| 51782e8690 | |||
| 0afb004d3c | |||
| a9c3b588af | |||
| f775a92054 | |||
| cccb06b095 | |||
| be54d1f104 | |||
| e84d17c7c9 | |||
| 254fabe758 | |||
| d1f8eaf3d2 | |||
| 483a02e25f | |||
| 3f06023bd2 | |||
| ce3a8c983f | |||
| f5c880cecb | |||
| 2af2c7ecff | |||
| 12aa4220dd | |||
| e40688ed80 | |||
| d403242a28 | |||
| f921a47fae | |||
| a7fa1c9b2b | |||
| 6ff54eb87b | |||
| 7f2ab5e50f | |||
| aebb9410c5 | |||
| 459090181f | |||
| 071d7f4e17 | |||
| 620197d1ff | |||
| 73e7fe8e64 | |||
| 973e67e5d2 | |||
| d89cd16afa | |||
| 7cbceb16ad | |||
| 157dd52700 | |||
| 23614d09d5 | |||
| bea4894d0c | |||
| 250cf2d4da | |||
| 93d076b4fd | |||
| 8749b83e0b | |||
| a9b600cf39 | |||
| c3c8365dbd | |||
| 6432f8826d | |||
| e04ae11fa0 | |||
| 08fadda68a | |||
| 9473e5a05d | |||
| 8a24ccfee3 | |||
| 3ba55ea4ae | |||
| 265db41540 | |||
| ed5041143e | |||
| 965f96c5ed | |||
| 3b6aeb148b | |||
| 259bb2555b | |||
| 665b67014f | |||
| 1051c152f9 | |||
| 5a0862af55 | |||
| 6e94e77632 | |||
| f5bb7b9992 | |||
| 0e9209183a | |||
| 90932a9e3c |
+1
-3
@@ -28,7 +28,6 @@
|
||||
/ffserver
|
||||
/config.*
|
||||
/coverage.info
|
||||
/avversion.h
|
||||
/doc/*.1
|
||||
/doc/*.3
|
||||
/doc/*.html
|
||||
@@ -37,7 +36,7 @@
|
||||
/doc/avoptions_codec.texi
|
||||
/doc/avoptions_format.texi
|
||||
/doc/doxy/html/
|
||||
/doc/examples/avio_dir_cmd
|
||||
/doc/examples/avio_list_dir
|
||||
/doc/examples/avio_reading
|
||||
/doc/examples/decoding_encoding
|
||||
/doc/examples/demuxing_decoding
|
||||
@@ -63,7 +62,6 @@
|
||||
/libavutil/ffversion.h
|
||||
/tests/audiogen
|
||||
/tests/base64
|
||||
/tests/checkasm/checkasm
|
||||
/tests/data/
|
||||
/tests/pixfmts.mak
|
||||
/tests/rotozoom
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
See the Git history of the project (https://git.ffmpeg.org/ffmpeg) to
|
||||
See the Git history of the project (git://source.ffmpeg.org/ffmpeg) to
|
||||
get the names of people who have contributed to FFmpeg.
|
||||
|
||||
To check the log, you can type the command "git log" in the FFmpeg
|
||||
source directory, or browse the online repository at
|
||||
https://git.ffmpeg.org/ffmpeg
|
||||
http://source.ffmpeg.org.
|
||||
|
||||
@@ -15,11 +15,3 @@ NOTICE
|
||||
------
|
||||
|
||||
- Non system dependencies (e.g. libx264, libvpx) are disabled by default.
|
||||
|
||||
NOTICE for Package Maintainers
|
||||
------------------------------
|
||||
|
||||
- It is recommended to build FFmpeg twice, first with minimal external dependencies so
|
||||
that 3rd party packages, which depend on FFmpegs libavutil/libavfilter/libavcodec/libavformat
|
||||
can then be built. And last build FFmpeg with full dependancies (which may in turn depend on
|
||||
some of these 3rd party packages). This avoids circular dependencies during build.
|
||||
|
||||
@@ -16,7 +16,6 @@ Specifically, the GPL parts of FFmpeg are:
|
||||
- optional x86 optimizations in the files
|
||||
- `libavcodec/x86/flac_dsp_gpl.asm`
|
||||
- `libavcodec/x86/idct_mmx.c`
|
||||
- `libavfilter/x86/vf_removegrain.asm`
|
||||
- libutvideo encoding/decoding wrappers in
|
||||
`libavcodec/libutvideo*.cpp`
|
||||
- the X11 grabber in `libavdevice/x11grab.c`
|
||||
|
||||
+9
-32
@@ -42,7 +42,7 @@ QuickTime faststart:
|
||||
Miscellaneous Areas
|
||||
===================
|
||||
|
||||
documentation Stefano Sabatini, Mike Melanson, Timothy Gu, Lou Logan
|
||||
documentation Stefano Sabatini, Mike Melanson, Timothy Gu
|
||||
build system (configure, makefiles) Diego Biurrun, Mans Rullgard
|
||||
project server Árpád Gereöffy, Michael Niedermayer, Reimar Doeffinger, Alexander Strasser, Lou Logan
|
||||
presets Robert Swain
|
||||
@@ -56,7 +56,7 @@ Communication
|
||||
website Deby Barbara Lepage
|
||||
fate.ffmpeg.org Timothy Gu
|
||||
Trac bug tracker Alexander Strasser, Michael Niedermayer, Carl Eugen Hoyos, Lou Logan
|
||||
mailing lists Baptiste Coudurier, Lou Logan
|
||||
mailing lists Michael Niedermayer, Baptiste Coudurier, Lou Logan
|
||||
Google+ Paul B Mahol, Michael Niedermayer, Alexander Strasser
|
||||
Twitter Lou Logan, Reynaldo H. Verdejo Pinochet
|
||||
Launchpad Timothy Gu
|
||||
@@ -137,7 +137,6 @@ Codecs:
|
||||
4xm.c Michael Niedermayer
|
||||
8bps.c Roberto Togni
|
||||
8svx.c Jaikrishnan Menon
|
||||
aacenc*, aaccoder.c Rostislav Pehlivanov
|
||||
aasc.c Kostya Shishkov
|
||||
ac3* Justin Ruggles
|
||||
alacenc.c Jaikrishnan Menon
|
||||
@@ -166,12 +165,11 @@ Codecs:
|
||||
dca.c Kostya Shishkov, Benjamin Larsson
|
||||
dnxhd* Baptiste Coudurier
|
||||
dpcm.c Mike Melanson
|
||||
dss_sp.c Oleksij Rempel
|
||||
dss_sp.c Oleksij Rempel, Michael Niedermayer
|
||||
dv.c Roman Shaposhnik
|
||||
dvbsubdec.c Anshul Maheshwari
|
||||
dxa.c Kostya Shishkov
|
||||
eacmv*, eaidct*, eat* Peter Ross
|
||||
evrc* Paul B Mahol
|
||||
exif.c, exif.h Thilo Borgmann
|
||||
ffv1* Michael Niedermayer
|
||||
ffwavesynth.c Nicolas George
|
||||
@@ -201,7 +199,6 @@ Codecs:
|
||||
libcelt_dec.c Nicolas George
|
||||
libdirac* David Conrad
|
||||
libgsm.c Michel Bardiaux
|
||||
libkvazaar.c Arttu Ylä-Outinen
|
||||
libopenjpeg.c Jaikrishnan Menon
|
||||
libopenjpegenc.c Michael Bradshaw
|
||||
libschroedinger* David Conrad
|
||||
@@ -239,7 +236,6 @@ Codecs:
|
||||
qdm2.c, qdm2data.h Roberto Togni, Benjamin Larsson
|
||||
qdrw.c Kostya Shishkov
|
||||
qpeg.c Kostya Shishkov
|
||||
qsv* Ivan Uskov
|
||||
qtrle.c Mike Melanson
|
||||
ra144.c, ra144.h, ra288.c, ra288.h Roberto Togni
|
||||
resample2.c Michael Niedermayer
|
||||
@@ -301,12 +297,11 @@ Codecs:
|
||||
|
||||
Hardware acceleration:
|
||||
crystalhd.c Philip Langdale
|
||||
dxva2* Hendrik Leppkes, Laurent Aimar
|
||||
dxva2* Laurent Aimar
|
||||
libstagefright.cpp Mohamed Naufal
|
||||
vaapi* Gwenole Beauchesne
|
||||
vda* Sebastien Zwickert
|
||||
vdpau* Philip Langdale, Carl Eugen Hoyos
|
||||
videotoolbox* Sebastien Zwickert
|
||||
vdpau* Carl Eugen Hoyos
|
||||
|
||||
|
||||
libavdevice
|
||||
@@ -338,7 +333,6 @@ Generic parts:
|
||||
graphdump.c Nicolas George
|
||||
|
||||
Filters:
|
||||
f_drawgraph.c Paul B Mahol
|
||||
af_adelay.c Paul B Mahol
|
||||
af_aecho.c Paul B Mahol
|
||||
af_afade.c Paul B Mahol
|
||||
@@ -349,21 +343,14 @@ Filters:
|
||||
af_astreamsync.c Nicolas George
|
||||
af_atempo.c Pavel Koshevoy
|
||||
af_biquads.c Paul B Mahol
|
||||
af_chorus.c Paul B Mahol
|
||||
af_compand.c Paul B Mahol
|
||||
af_ladspa.c Paul B Mahol
|
||||
af_pan.c Nicolas George
|
||||
af_sidechaincompress.c Paul B Mahol
|
||||
af_silenceremove.c Paul B Mahol
|
||||
avf_aphasemeter.c Paul B Mahol
|
||||
avf_avectorscope.c Paul B Mahol
|
||||
avf_showcqt.c Muhammad Faiz
|
||||
vf_blend.c Paul B Mahol
|
||||
vf_colorchannelmixer.c Paul B Mahol
|
||||
vf_colorbalance.c Paul B Mahol
|
||||
vf_colorkey.c Timo Rothenpieler
|
||||
vf_colorlevels.c Paul B Mahol
|
||||
vf_deband.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
|
||||
@@ -374,16 +361,12 @@ Filters:
|
||||
vf_il.c Paul B Mahol
|
||||
vf_lenscorrection.c Daniel Oberhoff
|
||||
vf_mergeplanes.c Paul B Mahol
|
||||
vf_neighbor.c Paul B Mahol
|
||||
vf_psnr.c Paul B Mahol
|
||||
vf_random.c Paul B Mahol
|
||||
vf_scale.c Michael Niedermayer
|
||||
vf_separatefields.c Paul B Mahol
|
||||
vf_ssim.c Paul B Mahol
|
||||
vf_stereo3d.c Paul B Mahol
|
||||
vf_telecine.c Paul B Mahol
|
||||
vf_yadif.c Michael Niedermayer
|
||||
vf_zoompan.c Paul B Mahol
|
||||
|
||||
Sources:
|
||||
vsrc_mandelbrot.c Michael Niedermayer
|
||||
@@ -400,7 +383,6 @@ Generic parts:
|
||||
|
||||
Muxers/Demuxers:
|
||||
4xm.c Mike Melanson
|
||||
aadec.c Vesselin Bontchev (vesselin.bontchev at yandex dot com)
|
||||
adtsenc.c Robert Swain
|
||||
afc.c Paul B Mahol
|
||||
aiffdec.c Baptiste Coudurier, Matthieu Bouron
|
||||
@@ -419,7 +401,7 @@ Muxers/Demuxers:
|
||||
cdxl.c Paul B Mahol
|
||||
crc.c Michael Niedermayer
|
||||
daud.c Reimar Doeffinger
|
||||
dss.c Oleksij Rempel
|
||||
dss.c Oleksij Rempel, Michael Niedermayer
|
||||
dtshddec.c Paul B Mahol
|
||||
dv.c Roman Shaposhnik
|
||||
dxa.c Kostya Shishkov
|
||||
@@ -432,7 +414,6 @@ Muxers/Demuxers:
|
||||
gxf.c Reimar Doeffinger
|
||||
gxfenc.c Baptiste Coudurier
|
||||
hls.c Anssi Hannula
|
||||
hls encryption (hlsenc.c) Christian Suloway
|
||||
idcin.c Mike Melanson
|
||||
idroqdec.c Mike Melanson
|
||||
iff.c Jaikrishnan Menon
|
||||
@@ -455,7 +436,7 @@ Muxers/Demuxers:
|
||||
mgsts.c Paul B Mahol
|
||||
microdvd* Aurelien Jacobs
|
||||
mm.c Peter Ross
|
||||
mov.c Baptiste Coudurier
|
||||
mov.c Michael Niedermayer, Baptiste Coudurier
|
||||
movenc.c Baptiste Coudurier, Matthieu Bouron
|
||||
mpc.c Kostya Shishkov
|
||||
mpeg.c Michael Niedermayer
|
||||
@@ -518,7 +499,6 @@ Muxers/Demuxers:
|
||||
wvenc.c Paul B Mahol
|
||||
|
||||
Protocols:
|
||||
async.c Zhang Rui
|
||||
bluray.c Petri Hintukainen
|
||||
ftp.c Lukasz Marek
|
||||
http.c Ronald S. Bultje
|
||||
@@ -554,21 +534,20 @@ Amiga / PowerPC Colin Ward
|
||||
Linux / PowerPC Luca Barbato
|
||||
Windows MinGW Alex Beregszaszi, Ramiro Polla
|
||||
Windows Cygwin Victor Paesa
|
||||
Windows MSVC Matthew Oliver, Hendrik Leppkes
|
||||
Windows MSVC Matthew Oliver
|
||||
Windows ICL Matthew Oliver
|
||||
ADI/Blackfin DSP Marc Hoffman
|
||||
Sparc Roman Shaposhnik
|
||||
x86 Michael Niedermayer
|
||||
OS/2 KO Myung-Hun
|
||||
|
||||
|
||||
Releases
|
||||
========
|
||||
|
||||
2.8 Michael Niedermayer
|
||||
2.7 Michael Niedermayer
|
||||
2.6 Michael Niedermayer
|
||||
2.5 Michael Niedermayer
|
||||
2.4 Michael Niedermayer
|
||||
|
||||
If you want to maintain an older release, please contact us
|
||||
|
||||
@@ -596,11 +575,9 @@ Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE
|
||||
Lou Logan 7D68 DC73 CBEF EABB 671A B6CF 621C 2E28 82F8 DC3A
|
||||
Luca Barbato 6677 4209 213C 8843 5B67 29E7 E84C 78C2 84E9 0E34
|
||||
Michael Niedermayer 9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB
|
||||
DD1E C9E8 DE08 5C62 9B3E 1846 B18E 8928 B394 8D64
|
||||
Nicolas George 24CE 01CE 9ACC 5CEB 74D8 8D9D B063 D997 36E5 4C93
|
||||
Panagiotis Issaris 6571 13A3 33D9 3726 F728 AA98 F643 B12E ECF3 E029
|
||||
Peter Ross A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B
|
||||
Philip Langdale 5DC5 8D66 5FBA 3A43 18EC 045E F8D6 B194 6A75 682E
|
||||
Reimar Doeffinger C61D 16E5 9E2C D10C 8958 38A4 0899 A2B9 06D4 D9C7
|
||||
Reinhard Tartler 9300 5DC2 7E87 6C37 ED7B CA9A 9808 3544 9453 48A4
|
||||
Reynaldo H. Verdejo Pinochet 6E27 CD34 170C C78E 4D4F 5F40 C18E 077F 3114 452A
|
||||
|
||||
@@ -31,10 +31,7 @@ $(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog)-$(CONFIG_OPENCL) += cmdutils_o
|
||||
OBJS-ffmpeg += ffmpeg_opt.o ffmpeg_filter.o
|
||||
OBJS-ffmpeg-$(HAVE_VDPAU_X11) += ffmpeg_vdpau.o
|
||||
OBJS-ffmpeg-$(HAVE_DXVA2_LIB) += ffmpeg_dxva2.o
|
||||
ifndef CONFIG_VIDEOTOOLBOX
|
||||
OBJS-ffmpeg-$(CONFIG_VDA) += ffmpeg_videotoolbox.o
|
||||
endif
|
||||
OBJS-ffmpeg-$(CONFIG_VIDEOTOOLBOX) += ffmpeg_videotoolbox.o
|
||||
OBJS-ffmpeg-$(CONFIG_VDA) += ffmpeg_vda.o
|
||||
OBJS-ffserver += ffserver_config.o
|
||||
|
||||
TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64
|
||||
@@ -63,7 +60,6 @@ include $(SRC_PATH)/common.mak
|
||||
|
||||
FF_EXTRALIBS := $(FFEXTRALIBS)
|
||||
FF_DEP_LIBS := $(DEP_LIBS)
|
||||
FF_STATIC_DEP_LIBS := $(STATIC_DEP_LIBS)
|
||||
|
||||
all: $(AVPROGS)
|
||||
|
||||
@@ -85,7 +81,7 @@ SUBDIR_VARS := CLEANFILES EXAMPLES FFLIBS HOSTPROGS TESTPROGS TOOLS \
|
||||
ARMV5TE-OBJS ARMV6-OBJS ARMV8-OBJS VFP-OBJS NEON-OBJS \
|
||||
ALTIVEC-OBJS MMX-OBJS YASM-OBJS \
|
||||
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSPR1-OBJS MSA-OBJS \
|
||||
MMI-OBJS OBJS SLIBOBJS HOSTOBJS TESTOBJS
|
||||
LOONGSON3-OBJS OBJS SLIBOBJS HOSTOBJS TESTOBJS
|
||||
|
||||
define RESET
|
||||
$(1) :=
|
||||
@@ -179,7 +175,7 @@ clean::
|
||||
|
||||
distclean::
|
||||
$(RM) $(DISTCLEANSUFFIXES)
|
||||
$(RM) config.* .config libavutil/avconfig.h .version avversion.h version.h libavutil/ffversion.h libavcodec/codec_names.h
|
||||
$(RM) config.* .config libavutil/avconfig.h .version version.h libavutil/ffversion.h libavcodec/codec_names.h
|
||||
|
||||
config:
|
||||
$(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION)
|
||||
|
||||
+6
-6
@@ -1,15 +1,15 @@
|
||||
|
||||
┌────────────────────────────────────────┐
|
||||
│ RELEASE NOTES for FFmpeg 2.8 "Feynman" │
|
||||
└────────────────────────────────────────┘
|
||||
┌─────────────────────────────────────┐
|
||||
│ RELEASE NOTES for FFmpeg 2.7 "Nash" │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
The FFmpeg Project proudly presents FFmpeg 2.8 "Feynman", about 3
|
||||
months after the release of FFmpeg 2.7.
|
||||
The FFmpeg Project proudly presents FFmpeg 2.7 "Nash", about 3
|
||||
months after the release of FFmpeg 2.6.
|
||||
|
||||
A complete Changelog is available at the root of the project, and the
|
||||
complete Git history on http://source.ffmpeg.org.
|
||||
|
||||
We hope you will like this release as much as we enjoyed working on it, and
|
||||
as usual, if you have any questions about it, or any FFmpeg related topic,
|
||||
feel free to join us on the #ffmpeg IRC channel (on irc.libera.chat) or ask
|
||||
feel free to join us on the #ffmpeg IRC channel (on irc.freenode.net) or ask
|
||||
on the mailing-lists.
|
||||
|
||||
@@ -8,7 +8,7 @@ OBJS-$(HAVE_MIPSFPU) += $(MIPSFPU-OBJS) $(MIPSFPU-OBJS-yes)
|
||||
OBJS-$(HAVE_MIPSDSPR1) += $(MIPSDSPR1-OBJS) $(MIPSDSPR1-OBJS-yes)
|
||||
OBJS-$(HAVE_MIPSDSPR2) += $(MIPSDSPR2-OBJS) $(MIPSDSPR2-OBJS-yes)
|
||||
OBJS-$(HAVE_MSA) += $(MSA-OBJS) $(MSA-OBJS-yes)
|
||||
OBJS-$(HAVE_MMI) += $(MMI-OBJS) $(MMI-OBJS-yes)
|
||||
OBJS-$(HAVE_LOONGSON3) += $(LOONGSON3-OBJS) $(LOONGSON3-OBJS-yes)
|
||||
|
||||
OBJS-$(HAVE_ALTIVEC) += $(ALTIVEC-OBJS) $(ALTIVEC-OBJS-yes)
|
||||
OBJS-$(HAVE_VSX) += $(VSX-OBJS) $(VSX-OBJS-yes)
|
||||
|
||||
+98
-53
@@ -60,13 +60,10 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#if HAVE_SETDLLDIRECTORY
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
static int init_report(const char *env);
|
||||
|
||||
AVDictionary *sws_dict;
|
||||
struct SwsContext *sws_opts;
|
||||
AVDictionary *swr_opts;
|
||||
AVDictionary *format_opts, *codec_opts, *resample_opts;
|
||||
|
||||
@@ -76,13 +73,20 @@ int hide_banner = 0;
|
||||
|
||||
void init_opts(void)
|
||||
{
|
||||
av_dict_set(&sws_dict, "flags", "bicubic", 0);
|
||||
|
||||
if(CONFIG_SWSCALE)
|
||||
sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void uninit_opts(void)
|
||||
{
|
||||
#if CONFIG_SWSCALE
|
||||
sws_freeContext(sws_opts);
|
||||
sws_opts = NULL;
|
||||
#endif
|
||||
|
||||
av_dict_free(&swr_opts);
|
||||
av_dict_free(&sws_dict);
|
||||
av_dict_free(&format_opts);
|
||||
av_dict_free(&codec_opts);
|
||||
av_dict_free(&resample_opts);
|
||||
@@ -109,15 +113,6 @@ static void log_callback_report(void *ptr, int level, const char *fmt, va_list v
|
||||
}
|
||||
}
|
||||
|
||||
void init_dynload(void)
|
||||
{
|
||||
#if HAVE_SETDLLDIRECTORY
|
||||
/* Calling SetDllDirectory with the empty string (but not NULL) removes the
|
||||
* current working directory from the DLL search path as a security pre-caution. */
|
||||
SetDllDirectory("");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void (*program_exit)(int ret);
|
||||
|
||||
void register_exit(void (*cb)(int ret))
|
||||
@@ -534,7 +529,7 @@ static const AVOption *opt_find(void *obj, const char *name, const char *unit,
|
||||
return o;
|
||||
}
|
||||
|
||||
#define FLAGS (o->type == AV_OPT_TYPE_FLAGS && (arg[0]=='-' || arg[0]=='+')) ? AV_DICT_APPEND : 0
|
||||
#define FLAGS (o->type == AV_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
|
||||
int opt_default(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
const AVOption *o;
|
||||
@@ -570,24 +565,14 @@ int opt_default(void *optctx, const char *opt, const char *arg)
|
||||
}
|
||||
#if CONFIG_SWSCALE
|
||||
sc = sws_get_class();
|
||||
if (!consumed && (o = opt_find(&sc, opt, NULL, 0,
|
||||
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
|
||||
struct SwsContext *sws = sws_alloc_context();
|
||||
int ret = av_opt_set(sws, opt, arg, 0);
|
||||
sws_freeContext(sws);
|
||||
if (!strcmp(opt, "srcw") || !strcmp(opt, "srch") ||
|
||||
!strcmp(opt, "dstw") || !strcmp(opt, "dsth") ||
|
||||
!strcmp(opt, "src_format") || !strcmp(opt, "dst_format")) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Directly using swscale dimensions/format options is not supported, please use the -s or -pix_fmt options\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if (!consumed && 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);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
av_dict_set(&sws_dict, opt, arg, FLAGS);
|
||||
|
||||
consumed = 1;
|
||||
}
|
||||
#else
|
||||
@@ -661,7 +646,9 @@ static void finish_group(OptionParseContext *octx, int group_idx,
|
||||
*g = octx->cur_group;
|
||||
g->arg = arg;
|
||||
g->group_def = l->group_def;
|
||||
g->sws_dict = sws_dict;
|
||||
#if CONFIG_SWSCALE
|
||||
g->sws_opts = sws_opts;
|
||||
#endif
|
||||
g->swr_opts = swr_opts;
|
||||
g->codec_opts = codec_opts;
|
||||
g->format_opts = format_opts;
|
||||
@@ -670,7 +657,9 @@ static void finish_group(OptionParseContext *octx, int group_idx,
|
||||
codec_opts = NULL;
|
||||
format_opts = NULL;
|
||||
resample_opts = NULL;
|
||||
sws_dict = NULL;
|
||||
#if CONFIG_SWSCALE
|
||||
sws_opts = NULL;
|
||||
#endif
|
||||
swr_opts = NULL;
|
||||
init_opts();
|
||||
|
||||
@@ -726,8 +715,9 @@ void uninit_parse_context(OptionParseContext *octx)
|
||||
av_dict_free(&l->groups[j].codec_opts);
|
||||
av_dict_free(&l->groups[j].format_opts);
|
||||
av_dict_free(&l->groups[j].resample_opts);
|
||||
|
||||
av_dict_free(&l->groups[j].sws_dict);
|
||||
#if CONFIG_SWSCALE
|
||||
sws_freeContext(l->groups[j].sws_opts);
|
||||
#endif
|
||||
av_dict_free(&l->groups[j].swr_opts);
|
||||
}
|
||||
av_freep(&l->groups);
|
||||
@@ -1334,12 +1324,12 @@ static void print_codec(const AVCodec *c)
|
||||
if (c->type == AVMEDIA_TYPE_VIDEO ||
|
||||
c->type == AVMEDIA_TYPE_AUDIO) {
|
||||
printf(" Threading capabilities: ");
|
||||
switch (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
|
||||
AV_CODEC_CAP_SLICE_THREADS)) {
|
||||
case AV_CODEC_CAP_FRAME_THREADS |
|
||||
AV_CODEC_CAP_SLICE_THREADS: printf("frame and slice"); break;
|
||||
case AV_CODEC_CAP_FRAME_THREADS: printf("frame"); break;
|
||||
case AV_CODEC_CAP_SLICE_THREADS: printf("slice"); break;
|
||||
switch (c->capabilities & (CODEC_CAP_FRAME_THREADS |
|
||||
CODEC_CAP_SLICE_THREADS)) {
|
||||
case CODEC_CAP_FRAME_THREADS |
|
||||
CODEC_CAP_SLICE_THREADS: printf("frame and slice"); break;
|
||||
case CODEC_CAP_FRAME_THREADS: printf("frame"); break;
|
||||
case CODEC_CAP_SLICE_THREADS: printf("slice"); break;
|
||||
default: printf("no"); break;
|
||||
}
|
||||
printf("\n");
|
||||
@@ -1513,11 +1503,11 @@ static void print_codecs(int encoder)
|
||||
|
||||
while ((codec = next_codec_for_id(desc->id, codec, encoder))) {
|
||||
printf(" %c", get_media_type_char(desc->type));
|
||||
printf((codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? "F" : ".");
|
||||
printf((codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : ".");
|
||||
printf((codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) ? "X" : ".");
|
||||
printf((codec->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)?"B" : ".");
|
||||
printf((codec->capabilities & AV_CODEC_CAP_DR1) ? "D" : ".");
|
||||
printf((codec->capabilities & CODEC_CAP_FRAME_THREADS) ? "F" : ".");
|
||||
printf((codec->capabilities & CODEC_CAP_SLICE_THREADS) ? "S" : ".");
|
||||
printf((codec->capabilities & CODEC_CAP_EXPERIMENTAL) ? "X" : ".");
|
||||
printf((codec->capabilities & CODEC_CAP_DRAW_HORIZ_BAND)?"B" : ".");
|
||||
printf((codec->capabilities & CODEC_CAP_DR1) ? "D" : ".");
|
||||
|
||||
printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : "");
|
||||
if (strcmp(codec->name, desc->name))
|
||||
@@ -1591,10 +1581,10 @@ int show_filters(void *optctx, const char *opt, const char *arg)
|
||||
*(descr_cur++) = '>';
|
||||
}
|
||||
pad = i ? filter->outputs : filter->inputs;
|
||||
for (j = 0; pad && avfilter_pad_get_name(pad, j); j++) {
|
||||
for (j = 0; pad && pad[j].name; j++) {
|
||||
if (descr_cur >= descr + sizeof(descr) - 4)
|
||||
break;
|
||||
*(descr_cur++) = get_media_type_char(avfilter_pad_get_type(pad, j));
|
||||
*(descr_cur++) = get_media_type_char(pad[j].type);
|
||||
}
|
||||
if (!j)
|
||||
*(descr_cur++) = ((!i && (filter->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)) ||
|
||||
@@ -1885,6 +1875,64 @@ int read_yesno(void)
|
||||
return yesno;
|
||||
}
|
||||
|
||||
int cmdutils_read_file(const char *filename, char **bufptr, size_t *size)
|
||||
{
|
||||
int64_t ret;
|
||||
FILE *f = av_fopen_utf8(filename, "rb");
|
||||
|
||||
if (!f) {
|
||||
ret = AVERROR(errno);
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename,
|
||||
strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = fseek(f, 0, SEEK_END);
|
||||
if (ret == -1) {
|
||||
ret = AVERROR(errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ftell(f);
|
||||
if (ret < 0) {
|
||||
ret = AVERROR(errno);
|
||||
goto out;
|
||||
}
|
||||
*size = ret;
|
||||
|
||||
ret = fseek(f, 0, SEEK_SET);
|
||||
if (ret == -1) {
|
||||
ret = AVERROR(errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
*bufptr = av_malloc(*size + 1);
|
||||
if (!*bufptr) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Could not allocate file buffer\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto out;
|
||||
}
|
||||
ret = fread(*bufptr, 1, *size, f);
|
||||
if (ret < *size) {
|
||||
av_free(*bufptr);
|
||||
if (ferror(f)) {
|
||||
ret = AVERROR(errno);
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while reading file '%s': %s\n",
|
||||
filename, strerror(errno));
|
||||
} else
|
||||
ret = AVERROR_EOF;
|
||||
} else {
|
||||
ret = 0;
|
||||
(*bufptr)[(*size)++] = '\0';
|
||||
}
|
||||
|
||||
out:
|
||||
if (ret < 0)
|
||||
av_log(NULL, AV_LOG_ERROR, "IO error: %s\n", av_err2str(ret));
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
|
||||
FILE *get_preset_file(char *filename, size_t filename_size,
|
||||
const char *preset_name, int is_path,
|
||||
const char *codec_name)
|
||||
@@ -2058,10 +2106,7 @@ double get_rotation(AVStream *st)
|
||||
theta -= 360*floor(theta/360 + 0.9/360);
|
||||
|
||||
if (fabs(theta - 90*round(theta/90)) > 2)
|
||||
av_log(NULL, AV_LOG_WARNING, "Odd rotation angle.\n"
|
||||
"If you want to help, upload a sample "
|
||||
"of this file to ftp://upload.ffmpeg.org/incoming/ "
|
||||
"and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)");
|
||||
av_log_ask_for_sample(NULL, "Odd rotation angle\n");
|
||||
|
||||
return theta;
|
||||
}
|
||||
@@ -2075,7 +2120,7 @@ static int print_device_sources(AVInputFormat *fmt, AVDictionary *opts)
|
||||
if (!fmt || !fmt->priv_class || !AV_IS_INPUT_DEVICE(fmt->priv_class->category))
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
printf("Auto-detected sources for %s:\n", fmt->name);
|
||||
printf("Audo-detected sources for %s:\n", fmt->name);
|
||||
if (!fmt->get_device_list) {
|
||||
ret = AVERROR(ENOSYS);
|
||||
printf("Cannot list sources. Not implemented.\n");
|
||||
@@ -2105,7 +2150,7 @@ static int print_device_sinks(AVOutputFormat *fmt, AVDictionary *opts)
|
||||
if (!fmt || !fmt->priv_class || !AV_IS_OUTPUT_DEVICE(fmt->priv_class->category))
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
printf("Auto-detected sinks for %s:\n", fmt->name);
|
||||
printf("Audo-detected sinks for %s:\n", fmt->name);
|
||||
if (!fmt->get_device_list) {
|
||||
ret = AVERROR(ENOSYS);
|
||||
printf("Cannot list sinks. Not implemented.\n");
|
||||
|
||||
+16
-9
@@ -46,7 +46,7 @@ extern const int program_birth_year;
|
||||
|
||||
extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
|
||||
extern AVFormatContext *avformat_opts;
|
||||
extern AVDictionary *sws_dict;
|
||||
extern struct SwsContext *sws_opts;
|
||||
extern AVDictionary *swr_opts;
|
||||
extern AVDictionary *format_opts, *codec_opts, *resample_opts;
|
||||
extern int hide_banner;
|
||||
@@ -61,11 +61,6 @@ void register_exit(void (*cb)(int ret));
|
||||
*/
|
||||
void exit_program(int ret) av_noreturn;
|
||||
|
||||
/**
|
||||
* Initialize dynamic library loading
|
||||
*/
|
||||
void init_dynload(void);
|
||||
|
||||
/**
|
||||
* Initialize the cmdutils option system, in particular
|
||||
* allocate the *_opts contexts.
|
||||
@@ -282,7 +277,7 @@ typedef struct OptionGroup {
|
||||
AVDictionary *codec_opts;
|
||||
AVDictionary *format_opts;
|
||||
AVDictionary *resample_opts;
|
||||
AVDictionary *sws_dict;
|
||||
struct SwsContext *sws_opts;
|
||||
AVDictionary *swr_opts;
|
||||
} OptionGroup;
|
||||
|
||||
@@ -450,13 +445,13 @@ int show_devices(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
#if CONFIG_AVDEVICE
|
||||
/**
|
||||
* Print a listing containing autodetected sinks of the output device.
|
||||
* Print a listing containing audodetected sinks of the output device.
|
||||
* Device name with options may be passed as an argument to limit results.
|
||||
*/
|
||||
int show_sinks(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Print a listing containing autodetected sources of the input device.
|
||||
* Print a listing containing audodetected sources of the input device.
|
||||
* Device name with options may be passed as an argument to limit results.
|
||||
*/
|
||||
int show_sources(void *optctx, const char *opt, const char *arg);
|
||||
@@ -534,6 +529,18 @@ int show_colors(void *optctx, const char *opt, const char *arg);
|
||||
*/
|
||||
int read_yesno(void);
|
||||
|
||||
/**
|
||||
* Read the file with name filename, and put its content in a newly
|
||||
* allocated 0-terminated buffer.
|
||||
*
|
||||
* @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
|
||||
* AVERROR error code in case of failure.
|
||||
*/
|
||||
int cmdutils_read_file(const char *filename, char **bufptr, size_t *size);
|
||||
|
||||
/**
|
||||
* Get a file corresponding to a preset file.
|
||||
*
|
||||
|
||||
+2
-3
@@ -118,9 +118,8 @@ TOOLOBJS := $(TOOLS:%=tools/%.o)
|
||||
TOOLS := $(TOOLS:%=tools/%$(EXESUF))
|
||||
HEADERS += $(HEADERS-yes)
|
||||
|
||||
PATH_LIBNAME = $(foreach NAME,$(1),lib$(NAME)/$($(2)LIBNAME))
|
||||
DEP_LIBS := $(foreach lib,$(FFLIBS),$(call PATH_LIBNAME,$(lib),$(CONFIG_SHARED:yes=S)))
|
||||
STATIC_DEP_LIBS := $(foreach lib,$(FFLIBS),$(call PATH_LIBNAME,$(lib)))
|
||||
PATH_LIBNAME = $(foreach NAME,$(1),lib$(NAME)/$($(CONFIG_SHARED:yes=S)LIBNAME))
|
||||
DEP_LIBS := $(foreach lib,$(FFLIBS),$(call PATH_LIBNAME,$(lib)))
|
||||
|
||||
SRC_DIR := $(SRC_PATH)/lib$(NAME)
|
||||
ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)/$(ARCH)/*.h))
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
LINK_EXE_PATH=$(dirname "$(command -v cl)")/link
|
||||
if [ -x "$LINK_EXE_PATH" ]; then
|
||||
"$LINK_EXE_PATH" $@
|
||||
else
|
||||
link $@
|
||||
fi
|
||||
exit $?
|
||||
+2
-41
@@ -15,42 +15,6 @@ libavutil: 2014-08-09
|
||||
|
||||
API changes, most recent first:
|
||||
|
||||
-------- 8< --------- FFmpeg 2.8 was cut here -------- 8< ---------
|
||||
|
||||
2015-08-27 - 1dd854e1 - lavc 56.58.100 - vaapi.h
|
||||
Deprecate old VA-API context (vaapi_context) fields that were only
|
||||
set and used by libavcodec. They are all managed internally now.
|
||||
|
||||
2015-08-19 - 9f8e57ef - lavu 54.31.100 - pixfmt.h
|
||||
Add a unique pixel format for VA-API (AV_PIX_FMT_VAAPI) that
|
||||
indicates the nature of the underlying storage: a VA surface. This
|
||||
yields the same value as AV_PIX_FMT_VAAPI_VLD.
|
||||
Deprecate old VA-API related pixel formats: AV_PIX_FMT_VAAPI_MOCO,
|
||||
AV_PIX_FMT_VAAPI_IDCT, AV_PIX_FMT_VAAPI_VLD.
|
||||
|
||||
2015-08-02 - lavu 54.30.100 / 54.17.0
|
||||
9ed59f1 / 7a7df34c - Add av_blowfish_alloc().
|
||||
a130ec9 / ae365453 - Add av_rc4_alloc().
|
||||
9ca1997 / 5d8bea3b - Add av_xtea_alloc().
|
||||
3cf08e9 / d9e8b47e - Add av_des_alloc().
|
||||
|
||||
2015-07-27 - lavc 56.56.100 / 56.35.0 - avcodec.h
|
||||
94d68a4 / 7c6eb0a1 - Rename CODEC_FLAG* defines to AV_CODEC_FLAG*.
|
||||
444e987 / def97856 - Rename CODEC_CAP_* defines to AV_CODEC_CAP_*.
|
||||
29d147c / 059a9348 - Rename FF_INPUT_BUFFER_PADDING_SIZE and FF_MIN_BUFFER_SIZE
|
||||
to AV_INPUT_BUFFER_PADDING_SIZE and AV_INPUT_BUFFER_MIN_SIZE.
|
||||
|
||||
2015-07-22 - c40ecff - lavc 56.51.100 - avcodec.h
|
||||
Add AV_PKT_DATA_QUALITY_STATS to export the quality value, PSNR, and pict_type
|
||||
of an AVPacket.
|
||||
|
||||
2015-07-16 - 8dad213 - lavc 56.49.100
|
||||
Add av_codec_get_codec_properties(), FF_CODEC_PROPERTY_LOSSLESS
|
||||
and FF_CODEC_PROPERTY_CLOSED_CAPTIONS
|
||||
|
||||
2015-07-03 - d563e13 / 83212943 - lavu 54.28.100 / 56.15.0
|
||||
Add av_version_info().
|
||||
|
||||
-------- 8< --------- FFmpeg 2.7 was cut here -------- 8< ---------
|
||||
|
||||
2015-06-04 - cc17b43 - lswr 1.2.100
|
||||
@@ -232,7 +196,7 @@ API changes, most recent first:
|
||||
Add av_opt_get_dict_val/set_dict_val with AV_OPT_TYPE_DICT to support
|
||||
dictionary types being set as options.
|
||||
|
||||
2014-08-13 - afbd4b7e09 - lavf 56.01.0 - avformat.h
|
||||
2014-08-13 - afbd4b8 - lavf 56.01.0 - avformat.h
|
||||
Add AVFormatContext.event_flags and AVStream.event_flags for signaling to
|
||||
the user when events happen in the file/stream.
|
||||
|
||||
@@ -249,7 +213,7 @@ API changes, most recent first:
|
||||
2014-08-08 - 5c3c671 - lavf 55.53.100 - avio.h
|
||||
Add avio_feof() and deprecate url_feof().
|
||||
|
||||
2014-08-07 - bb789016d4 - lsws 2.1.3 - swscale.h
|
||||
2014-08-07 - bb78903 - lsws 2.1.3 - swscale.h
|
||||
sws_getContext is not going to be removed in the future.
|
||||
|
||||
2014-08-07 - a561662 / ad1ee5f - lavc 55.73.101 / 55.57.3 - avcodec.h
|
||||
@@ -728,9 +692,6 @@ API changes, most recent first:
|
||||
av_ripemd_update()
|
||||
av_ripemd_final()
|
||||
|
||||
2013-06-10 - 82ef670 - lavu 52.35.101 - hmac.h
|
||||
Add AV_HMAC_SHA224, AV_HMAC_SHA256, AV_HMAC_SHA384, AV_HMAC_SHA512
|
||||
|
||||
2013-06-04 - 30b491f / fc962d4 - lavu 52.35.100 / 52.13.0 - mem.h
|
||||
Add av_realloc_array and av_reallocp_array
|
||||
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ PROJECT_NAME = FFmpeg
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 2.8.22
|
||||
PROJECT_NUMBER = 2.7.7
|
||||
|
||||
# With the PROJECT_LOGO tag one can specify a logo or icon that is included
|
||||
# in the documentation. The maximum height of the logo should not exceed 55
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ DOCS-$(CONFIG_MANPAGES) += $(MANPAGES)
|
||||
DOCS-$(CONFIG_TXTPAGES) += $(TXTPAGES)
|
||||
DOCS = $(DOCS-yes)
|
||||
|
||||
DOC_EXAMPLES-$(CONFIG_AVIO_DIR_CMD_EXAMPLE) += avio_dir_cmd
|
||||
DOC_EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir
|
||||
DOC_EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading
|
||||
DOC_EXAMPLES-$(CONFIG_AVCODEC_EXAMPLE) += avcodec
|
||||
DOC_EXAMPLES-$(CONFIG_DECODING_ENCODING_EXAMPLE) += decoding_encoding
|
||||
|
||||
+2
-2
@@ -3,9 +3,9 @@
|
||||
The FFmpeg developers.
|
||||
|
||||
For details about the authorship, see the Git history of the project
|
||||
(https://git.ffmpeg.org/ffmpeg), e.g. by typing the command
|
||||
(git://source.ffmpeg.org/ffmpeg), e.g. by typing the command
|
||||
@command{git log} in the FFmpeg source directory, or browsing the
|
||||
online repository at @url{https://git.ffmpeg.org/ffmpeg}.
|
||||
online repository at @url{http://source.ffmpeg.org}.
|
||||
|
||||
Maintainers for the specific components are listed in the file
|
||||
@file{MAINTAINERS} in the source code tree.
|
||||
|
||||
@@ -475,9 +475,6 @@ per-block quantization parameter (QP)
|
||||
motion vector
|
||||
@item dct_coeff
|
||||
|
||||
@item green_metadata
|
||||
display complexity metadata for the upcoming frame, GoP or for a given duration.
|
||||
|
||||
@item skip
|
||||
|
||||
@item startcode
|
||||
@@ -1045,11 +1042,7 @@ Possible values:
|
||||
@item color_primaries @var{integer} (@emph{decoding/encoding,video})
|
||||
@item color_trc @var{integer} (@emph{decoding/encoding,video})
|
||||
@item colorspace @var{integer} (@emph{decoding/encoding,video})
|
||||
|
||||
@item color_range @var{integer} (@emph{decoding/encoding,video})
|
||||
If used as input parameter, it serves as a hint to the decoder, which
|
||||
color_range the input has.
|
||||
|
||||
@item chroma_sample_location @var{integer} (@emph{decoding/encoding,video})
|
||||
|
||||
@item log_level_offset @var{integer}
|
||||
|
||||
@@ -25,13 +25,6 @@ enabled decoders.
|
||||
A description of some of the currently available video decoders
|
||||
follows.
|
||||
|
||||
@section hevc
|
||||
|
||||
HEVC / H.265 decoder.
|
||||
|
||||
Note: the @option{skip_loop_filter} option has effect only at level
|
||||
@code{all}.
|
||||
|
||||
@section rawvideo
|
||||
|
||||
Raw video decoder.
|
||||
@@ -195,25 +188,6 @@ without this library.
|
||||
@chapter Subtitles Decoders
|
||||
@c man begin SUBTILES DECODERS
|
||||
|
||||
@section dvbsub
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item compute_clut
|
||||
@table @option
|
||||
@item -1
|
||||
Compute clut if no matching CLUT is in the stream.
|
||||
@item 0
|
||||
Never compute CLUT
|
||||
@item 1
|
||||
Always compute CLUT and override the one provided in the stream.
|
||||
@end table
|
||||
@item dvb_substream
|
||||
Selects the dvb substream, or all substreams if -1 which is default.
|
||||
|
||||
@end table
|
||||
|
||||
@section dvdsub
|
||||
|
||||
This codec decodes the bitmap subtitles used in DVDs; the same subtitles can
|
||||
|
||||
+1
-79
@@ -18,12 +18,6 @@ enabled demuxers.
|
||||
|
||||
The description of some of the currently available demuxers follows.
|
||||
|
||||
@section aa
|
||||
|
||||
Audible Format 2, 3, and 4 demuxer.
|
||||
|
||||
This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files.
|
||||
|
||||
@section applehttp
|
||||
|
||||
Apple HTTP Live Streaming demuxer.
|
||||
@@ -118,47 +112,6 @@ file is not available or accurate.
|
||||
If the duration is set for all files, then it is possible to seek in the
|
||||
whole concatenated video.
|
||||
|
||||
@item @code{inpoint @var{timestamp}}
|
||||
In point of the file. When the demuxer opens the file it instantly seeks to the
|
||||
specified timestamp. Seeking is done so that all streams can be presented
|
||||
successfully at In point.
|
||||
|
||||
This directive works best with intra frame codecs, because for non-intra frame
|
||||
ones you will usually get extra packets before the actual In point and the
|
||||
decoded content will most likely contain frames before In point too.
|
||||
|
||||
For each file, packets before the file In point will have timestamps less than
|
||||
the calculated start timestamp of the file (negative in case of the first
|
||||
file), and the duration of the files (if not specified by the @code{duration}
|
||||
directive) will be reduced based on their specified In point.
|
||||
|
||||
Because of potential packets before the specified In point, packet timestamps
|
||||
may overlap between two concatenated files.
|
||||
|
||||
@item @code{outpoint @var{timestamp}}
|
||||
Out point of the file. When the demuxer reaches the specified decoding
|
||||
timestamp in any of the streams, it handles it as an end of file condition and
|
||||
skips the current and all the remaining packets from all streams.
|
||||
|
||||
Out point is exclusive, which means that the demuxer will not output packets
|
||||
with a decoding timestamp greater or equal to Out point.
|
||||
|
||||
This directive works best with intra frame codecs and formats where all streams
|
||||
are tightly interleaved. For non-intra frame codecs you will usually get
|
||||
additional packets with presentation timestamp after Out point therefore the
|
||||
decoded content will most likely contain frames after Out point too. If your
|
||||
streams are not tightly interleaved you may not get all the packets from all
|
||||
streams before Out point and you may only will be able to decode the earliest
|
||||
stream until Out point.
|
||||
|
||||
The duration of the files (if not specified by the @code{duration}
|
||||
directive) will be reduced based on their specified Out point.
|
||||
|
||||
@item @code{file_packet_metadata @var{key=value}}
|
||||
Metadata of the packets of the file. The specified metadata will be set for
|
||||
each file packet. You can specify this directive multiple times to add multiple
|
||||
metadata entries.
|
||||
|
||||
@item @code{stream}
|
||||
Introduce a stream in the virtual file.
|
||||
All subsequent stream-related directives apply to the last introduced
|
||||
@@ -283,24 +236,6 @@ used to end the output video at the length of the shortest input file,
|
||||
which in this case is @file{input.mp4} as the GIF in this example loops
|
||||
infinitely.
|
||||
|
||||
@section hls
|
||||
|
||||
HLS demuxer
|
||||
|
||||
It accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item live_start_index
|
||||
segment index to start live streams at (negative values are from the end).
|
||||
|
||||
@item allowed_extensions
|
||||
',' separated list of file extensions that hls is allowed to access.
|
||||
|
||||
@item max_reload
|
||||
Maximum number of times a insufficient list is attempted to be reloaded.
|
||||
Default value is 1000.
|
||||
@end table
|
||||
|
||||
@section image2
|
||||
|
||||
Image file demuxer.
|
||||
@@ -457,26 +392,13 @@ is known to be non malicious.
|
||||
|
||||
MPEG-2 transport stream demuxer.
|
||||
|
||||
This demuxer accepts the following options:
|
||||
@table @option
|
||||
@item resync_size
|
||||
Set size limit for looking up a new synchronization. Default value is
|
||||
65536.
|
||||
|
||||
@item fix_teletext_pts
|
||||
Override teletext packet PTS and DTS values with the timestamps calculated
|
||||
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.
|
||||
|
||||
@item ts_packetsize
|
||||
Output option carrying the raw packet size in bytes.
|
||||
Show the detected raw packet size, cannot be set by the user.
|
||||
|
||||
@item scan_all_pmts
|
||||
Scan and combine all PMTs. The value is an integer with value from -1
|
||||
to 1 (-1 means automatic setting, 1 means enabled, 0 means
|
||||
disabled). Default value is -1.
|
||||
@end table
|
||||
|
||||
@section rawvideo
|
||||
|
||||
@@ -400,35 +400,6 @@ finding a new maintainer and also don't forget updating the @file{MAINTAINERS} f
|
||||
|
||||
We think our rules are not too hard. If you have comments, contact us.
|
||||
|
||||
@section Code of conduct
|
||||
|
||||
Be friendly and respectful towards others and third parties.
|
||||
Treat others the way you yourself want to be treated.
|
||||
|
||||
Be considerate. Not everyone shares the same viewpoint and priorities as you do.
|
||||
Different opinions and interpretations help the project.
|
||||
Looking at issues from a different perspective assists development.
|
||||
|
||||
Do not assume malice for things that can be attributed to incompetence. Even if
|
||||
it is malice, it's rarely good to start with that as initial assumption.
|
||||
|
||||
Stay friendly even if someone acts contrarily. Everyone has a bad day
|
||||
once in a while.
|
||||
If you yourself have a bad day or are angry then try to take a break and reply
|
||||
once you are calm and without anger if you have to.
|
||||
|
||||
Try to help other team members and cooperate if you can.
|
||||
|
||||
The goal of software development is to create technical excellence, not for any
|
||||
individual to be better and "win" against the others. Large software projects
|
||||
are only possible and successful through teamwork.
|
||||
|
||||
If someone struggles do not put them down. Give them a helping hand
|
||||
instead and point them in the right direction.
|
||||
|
||||
Finally, keep in mind the immortal words of Bill and Ted,
|
||||
"Be excellent to each other."
|
||||
|
||||
@anchor{Submitting patches}
|
||||
@section Submitting patches
|
||||
|
||||
@@ -572,10 +543,6 @@ tools/trasher, the noise bitstream filter, and
|
||||
should not crash, end in a (near) infinite loop, or allocate ridiculous
|
||||
amounts of memory when fed damaged data.
|
||||
|
||||
@item
|
||||
Did you test your decoder or demuxer against sample files?
|
||||
Samples may be obtained at @url{http://samples.ffmpeg.org}.
|
||||
|
||||
@item
|
||||
Does the patch not mix functional and cosmetic changes?
|
||||
|
||||
@@ -666,10 +633,6 @@ not related to the comments received during review. Such patches will
|
||||
be rejected. Instead, submit significant changes or new features as
|
||||
separate patches.
|
||||
|
||||
Everyone is welcome to review patches. Also if you are waiting for your patch
|
||||
to be reviewed, please consider helping to review other patches, that is a great
|
||||
way to get everyone's patches reviewed sooner.
|
||||
|
||||
@anchor{Regression tests}
|
||||
@section Regression tests
|
||||
|
||||
@@ -734,25 +697,6 @@ In case you need finer control over how valgrind is invoked, use the
|
||||
@code{--target-exec='valgrind <your_custom_valgrind_options>} option in
|
||||
your configure line instead.
|
||||
|
||||
@anchor{Maintenance}
|
||||
@chapter Maintenance process
|
||||
|
||||
@anchor{MAINTAINERS}
|
||||
@section MAINTAINERS
|
||||
|
||||
The developers maintaining each part of the codebase are listed in @file{MAINTAINERS}.
|
||||
Being listed in @file{MAINTAINERS}, gives one the right to have git write access to
|
||||
the specific repository.
|
||||
|
||||
@anchor{Becoming a maintainer}
|
||||
@section Becoming a maintainer
|
||||
|
||||
People add themselves to @file{MAINTAINERS} by sending a patch like any other code
|
||||
change. These get reviewed by the community like any other patch. It is expected
|
||||
that, if someone has an objection to a new maintainer, she is willing to object
|
||||
in public with her full name and is willing to take over maintainership for the area.
|
||||
|
||||
|
||||
@anchor{Release process}
|
||||
@section Release process
|
||||
|
||||
|
||||
+73
-161
@@ -1342,30 +1342,6 @@ disabled
|
||||
A description of some of the currently available video encoders
|
||||
follows.
|
||||
|
||||
@section jpeg2000
|
||||
|
||||
The native jpeg 2000 encoder is lossy by default, the @code{-q:v}
|
||||
option can be used to set the encoding quality. Lossless encoding
|
||||
can be selected with @code{-pred 1}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item format
|
||||
Can be set to either @code{j2k} or @code{jp2} (the default) that
|
||||
makes it possible to store non-rgb pix_fmts.
|
||||
|
||||
@end table
|
||||
|
||||
@section snow
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item iterative_dia_size
|
||||
dia size for the iterative motion estimation
|
||||
@end table
|
||||
|
||||
@section libtheora
|
||||
|
||||
libtheora Theora encoder wrapper.
|
||||
@@ -1440,153 +1416,113 @@ You need to explicitly configure the build with @code{--enable-libvpx}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following options are supported by the libvpx wrapper. The
|
||||
@command{vpxenc}-equivalent options or values are listed in parentheses
|
||||
for easy migration.
|
||||
|
||||
To reduce the duplication of documentation, only the private options
|
||||
and some others requiring special attention are documented here. For
|
||||
the documentation of the undocumented generic options, see
|
||||
@ref{codec-options,,the Codec Options chapter}.
|
||||
|
||||
To get more documentation of the libvpx options, invoke the command
|
||||
@command{ffmpeg -h encoder=libvpx}, @command{ffmpeg -h encoder=libvpx-vp9} or
|
||||
@command{vpxenc --help}. Further information is available in the libvpx API
|
||||
documentation.
|
||||
Mapping from FFmpeg to libvpx options with conversion notes in parentheses.
|
||||
|
||||
@table @option
|
||||
|
||||
@item b (@emph{target-bitrate})
|
||||
Set bitrate in bits/s. Note that FFmpeg's @option{b} option is
|
||||
expressed in bits/s, while @command{vpxenc}'s @option{target-bitrate} is in
|
||||
kilobits/s.
|
||||
@item threads
|
||||
g_threads
|
||||
|
||||
@item g (@emph{kf-max-dist})
|
||||
@item profile
|
||||
g_profile
|
||||
|
||||
@item keyint_min (@emph{kf-min-dist})
|
||||
@item vb
|
||||
rc_target_bitrate
|
||||
|
||||
@item qmin (@emph{min-q})
|
||||
@item g
|
||||
kf_max_dist
|
||||
|
||||
@item qmax (@emph{max-q})
|
||||
@item keyint_min
|
||||
kf_min_dist
|
||||
|
||||
@item bufsize (@emph{buf-sz}, @emph{buf-optimal-sz})
|
||||
Set ratecontrol buffer size (in bits). Note @command{vpxenc}'s options are
|
||||
specified in milliseconds, the libvpx wrapper converts this value as follows:
|
||||
@code{buf-sz = bufsize * 1000 / bitrate},
|
||||
@code{buf-optimal-sz = bufsize * 1000 / bitrate * 5 / 6}.
|
||||
@item qmin
|
||||
rc_min_quantizer
|
||||
|
||||
@item rc_init_occupancy (@emph{buf-initial-sz})
|
||||
Set number of bits which should be loaded into the rc buffer before decoding
|
||||
starts. Note @command{vpxenc}'s option is specified in milliseconds, the libvpx
|
||||
wrapper converts this value as follows:
|
||||
@code{rc_init_occupancy * 1000 / bitrate}.
|
||||
@item qmax
|
||||
rc_max_quantizer
|
||||
|
||||
@item undershoot-pct
|
||||
Set datarate undershoot (min) percentage of the target bitrate.
|
||||
@item bufsize, vb
|
||||
rc_buf_sz
|
||||
@code{(bufsize * 1000 / vb)}
|
||||
|
||||
@item overshoot-pct
|
||||
Set datarate overshoot (max) percentage of the target bitrate.
|
||||
rc_buf_optimal_sz
|
||||
@code{(bufsize * 1000 / vb * 5 / 6)}
|
||||
|
||||
@item skip_threshold (@emph{drop-frame})
|
||||
@item rc_init_occupancy, vb
|
||||
rc_buf_initial_sz
|
||||
@code{(rc_init_occupancy * 1000 / vb)}
|
||||
|
||||
@item qcomp (@emph{bias-pct})
|
||||
@item rc_buffer_aggressivity
|
||||
rc_undershoot_pct
|
||||
|
||||
@item maxrate (@emph{maxsection-pct})
|
||||
Set GOP max bitrate in bits/s. Note @command{vpxenc}'s option is specified as a
|
||||
percentage of the target bitrate, the libvpx wrapper converts this value as
|
||||
follows: @code{(maxrate * 100 / bitrate)}.
|
||||
@item skip_threshold
|
||||
rc_dropframe_thresh
|
||||
|
||||
@item minrate (@emph{minsection-pct})
|
||||
Set GOP min bitrate in bits/s. Note @command{vpxenc}'s option is specified as a
|
||||
percentage of the target bitrate, the libvpx wrapper converts this value as
|
||||
follows: @code{(minrate * 100 / bitrate)}.
|
||||
@item qcomp
|
||||
rc_2pass_vbr_bias_pct
|
||||
|
||||
@item minrate, maxrate, b @emph{end-usage=cbr}
|
||||
@code{(minrate == maxrate == bitrate)}.
|
||||
@item maxrate, vb
|
||||
rc_2pass_vbr_maxsection_pct
|
||||
@code{(maxrate * 100 / vb)}
|
||||
|
||||
@item crf (@emph{end-usage=cq}, @emph{cq-level})
|
||||
@item minrate, vb
|
||||
rc_2pass_vbr_minsection_pct
|
||||
@code{(minrate * 100 / vb)}
|
||||
|
||||
@item quality, deadline (@emph{deadline})
|
||||
@table @samp
|
||||
@item best
|
||||
Use best quality deadline. Poorly named and quite slow, this option should be
|
||||
avoided as it may give worse quality output than good.
|
||||
@item good
|
||||
Use good quality deadline. This is a good trade-off between speed and quality
|
||||
when used with the @option{cpu-used} option.
|
||||
@item realtime
|
||||
Use realtime quality deadline.
|
||||
@item minrate, maxrate, vb
|
||||
@code{VPX_CBR}
|
||||
@code{(minrate == maxrate == vb)}
|
||||
|
||||
@item crf
|
||||
@code{VPX_CQ}, @code{VP8E_SET_CQ_LEVEL}
|
||||
|
||||
@item quality
|
||||
@table @option
|
||||
@item @var{best}
|
||||
@code{VPX_DL_BEST_QUALITY}
|
||||
@item @var{good}
|
||||
@code{VPX_DL_GOOD_QUALITY}
|
||||
@item @var{realtime}
|
||||
@code{VPX_DL_REALTIME}
|
||||
@end table
|
||||
|
||||
@item speed, cpu-used (@emph{cpu-used})
|
||||
Set quality/speed ratio modifier. Higher values speed up the encode at the cost
|
||||
of quality.
|
||||
@item speed
|
||||
@code{VP8E_SET_CPUUSED}
|
||||
|
||||
@item nr (@emph{noise-sensitivity})
|
||||
@item nr
|
||||
@code{VP8E_SET_NOISE_SENSITIVITY}
|
||||
|
||||
@item static-thresh
|
||||
Set a change threshold on blocks below which they will be skipped by the
|
||||
encoder.
|
||||
@item mb_threshold
|
||||
@code{VP8E_SET_STATIC_THRESHOLD}
|
||||
|
||||
@item slices (@emph{token-parts})
|
||||
Note that FFmpeg's @option{slices} option gives the total number of partitions,
|
||||
while @command{vpxenc}'s @option{token-parts} is given as
|
||||
@code{log2(partitions)}.
|
||||
@item slices
|
||||
@code{VP8E_SET_TOKEN_PARTITIONS}
|
||||
|
||||
@item max-intra-rate
|
||||
Set maximum I-frame bitrate as a percentage of the target bitrate. A value of 0
|
||||
means unlimited.
|
||||
@code{VP8E_SET_MAX_INTRA_BITRATE_PCT}
|
||||
|
||||
@item force_key_frames
|
||||
@code{VPX_EFLAG_FORCE_KF}
|
||||
|
||||
@item Alternate reference frame related
|
||||
@table @option
|
||||
@item auto-alt-ref
|
||||
Enable use of alternate reference frames (2-pass only).
|
||||
@item arnr-max-frames
|
||||
Set altref noise reduction max frame count.
|
||||
@item arnr-type
|
||||
Set altref noise reduction filter type: backward, forward, centered.
|
||||
@item arnr-strength
|
||||
Set altref noise reduction filter strength.
|
||||
@item rc-lookahead, lag-in-frames (@emph{lag-in-frames})
|
||||
Set number of frames to look ahead for frametype and ratecontrol.
|
||||
@item vp8flags altref
|
||||
@code{VP8E_SET_ENABLEAUTOALTREF}
|
||||
@item @var{arnr_max_frames}
|
||||
@code{VP8E_SET_ARNR_MAXFRAMES}
|
||||
@item @var{arnr_type}
|
||||
@code{VP8E_SET_ARNR_TYPE}
|
||||
@item @var{arnr_strength}
|
||||
@code{VP8E_SET_ARNR_STRENGTH}
|
||||
@item @var{rc_lookahead}
|
||||
g_lag_in_frames
|
||||
@end table
|
||||
|
||||
@item error-resilient
|
||||
Enable error resiliency features.
|
||||
@item vp8flags error_resilient
|
||||
g_error_resilient
|
||||
|
||||
@item VP9-specific options
|
||||
@table @option
|
||||
@item lossless
|
||||
Enable lossless mode.
|
||||
@item tile-columns
|
||||
Set number of tile columns to use. Note this is given as
|
||||
@code{log2(tile_columns)}. For example, 8 tile columns would be requested by
|
||||
setting the @option{tile-columns} option to 3.
|
||||
@item tile-rows
|
||||
Set number of tile rows to use. Note this is given as @code{log2(tile_rows)}.
|
||||
For example, 4 tile rows would be requested by setting the @option{tile-rows}
|
||||
option to 2.
|
||||
@item frame-parallel
|
||||
Enable frame parallel decodability features.
|
||||
@item aq-mode
|
||||
Set adaptive quantization mode (0: off (default), 1: variance 2: complexity, 3:
|
||||
cyclic refresh).
|
||||
@item colorspace @emph{color-space}
|
||||
Set input color space. The VP9 bitstream supports signaling the following
|
||||
colorspaces:
|
||||
@table @option
|
||||
@item @samp{rgb} @emph{sRGB}
|
||||
@item @samp{bt709} @emph{bt709}
|
||||
@item @samp{unspecified} @emph{unknown}
|
||||
@item @samp{bt470bg} @emph{bt601}
|
||||
@item @samp{smpte170m} @emph{smpte170}
|
||||
@item @samp{smpte240m} @emph{smpte240}
|
||||
@item @samp{bt2020_ncl} @emph{bt2020}
|
||||
@end table
|
||||
@end table
|
||||
@item aq_mode
|
||||
@code{VP9E_SET_AQ_MODE}
|
||||
|
||||
@end table
|
||||
|
||||
@@ -2324,30 +2260,6 @@ Setting a higher @option{bits_per_mb} limit will improve the speed.
|
||||
For the fastest encoding speed set the @option{qscale} parameter (4 is the
|
||||
recommended value) and do not set a size constraint.
|
||||
|
||||
@section libkvazaar
|
||||
|
||||
Kvazaar H.265/HEVC encoder.
|
||||
|
||||
Requires the presence of the libkvazaar headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@option{--enable-libkvazaar}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item b
|
||||
Set target video bitrate in bit/s and enable rate control.
|
||||
|
||||
@item threads
|
||||
Set number of encoding threads.
|
||||
|
||||
@item kvazaar-params
|
||||
Set kvazaar parameters as a list of @var{name}=@var{value} pairs separated
|
||||
by commas (,). See kvazaar documentation for a list of options.
|
||||
|
||||
@end table
|
||||
|
||||
@c man end VIDEO ENCODERS
|
||||
|
||||
@chapter Subtitles Encoders
|
||||
|
||||
@@ -11,14 +11,13 @@ CFLAGS += -Wall -g
|
||||
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
|
||||
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
|
||||
|
||||
EXAMPLES= avio_dir_cmd \
|
||||
EXAMPLES= avio_list_dir \
|
||||
avio_reading \
|
||||
decoding_encoding \
|
||||
demuxing_decoding \
|
||||
extract_mvs \
|
||||
filtering_video \
|
||||
filtering_audio \
|
||||
http_multiclient \
|
||||
metadata \
|
||||
muxing \
|
||||
remuxing \
|
||||
|
||||
@@ -54,13 +54,28 @@ static const char *type_string(int type)
|
||||
return "<UNKNOWN>";
|
||||
}
|
||||
|
||||
static int list_op(const char *input_dir)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *input_dir = NULL;
|
||||
AVIODirEntry *entry = NULL;
|
||||
AVIODirContext *ctx = NULL;
|
||||
int cnt, ret;
|
||||
char filemode[4], uid_and_gid[20];
|
||||
|
||||
av_log_set_level(AV_LOG_DEBUG);
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s input_dir\n"
|
||||
"API example program to show how to list files in directory "
|
||||
"accessed through AVIOContext.\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
input_dir = argv[1];
|
||||
|
||||
/* register codecs and formats and other lavf/lavc components*/
|
||||
av_register_all();
|
||||
avformat_network_init();
|
||||
|
||||
if ((ret = avio_open_dir(&ctx, input_dir, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open directory: %s.\n", av_err2str(ret));
|
||||
goto fail;
|
||||
@@ -99,81 +114,6 @@ static int list_op(const char *input_dir)
|
||||
|
||||
fail:
|
||||
avio_close_dir(&ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int del_op(const char *url)
|
||||
{
|
||||
int ret = avpriv_io_delete(url);
|
||||
if (ret < 0)
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot delete '%s': %s.\n", url, av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int move_op(const char *src, const char *dst)
|
||||
{
|
||||
int ret = avpriv_io_move(src, dst);
|
||||
if (ret < 0)
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot move '%s' into '%s': %s.\n", src, dst, av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void usage(const char *program_name)
|
||||
{
|
||||
fprintf(stderr, "usage: %s OPERATION entry1 [entry2]\n"
|
||||
"API example program to show how to manipulate resources "
|
||||
"accessed through AVIOContext.\n"
|
||||
"OPERATIONS:\n"
|
||||
"list list content of the directory\n"
|
||||
"move rename content in directory\n"
|
||||
"del delete content in directory\n",
|
||||
program_name);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *op = NULL;
|
||||
int ret;
|
||||
|
||||
av_log_set_level(AV_LOG_DEBUG);
|
||||
|
||||
if (argc < 2) {
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* register codecs and formats and other lavf/lavc components*/
|
||||
av_register_all();
|
||||
avformat_network_init();
|
||||
|
||||
op = argv[1];
|
||||
if (strcmp(op, "list") == 0) {
|
||||
if (argc < 3) {
|
||||
av_log(NULL, AV_LOG_INFO, "Missing argument for list operation.\n");
|
||||
ret = AVERROR(EINVAL);
|
||||
} else {
|
||||
ret = list_op(argv[2]);
|
||||
}
|
||||
} else if (strcmp(op, "del") == 0) {
|
||||
if (argc < 3) {
|
||||
av_log(NULL, AV_LOG_INFO, "Missing argument for del operation.\n");
|
||||
ret = AVERROR(EINVAL);
|
||||
} else {
|
||||
ret = del_op(argv[2]);
|
||||
}
|
||||
} else if (strcmp(op, "move") == 0) {
|
||||
if (argc < 4) {
|
||||
av_log(NULL, AV_LOG_INFO, "Missing argument for move operation.\n");
|
||||
ret = AVERROR(EINVAL);
|
||||
} else {
|
||||
ret = move_op(argv[2], argv[3]);
|
||||
}
|
||||
} else {
|
||||
av_log(NULL, AV_LOG_INFO, "Invalid operation %s\n", op);
|
||||
ret = AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
avformat_network_deinit();
|
||||
|
||||
return ret < 0 ? 1 : 0;
|
||||
@@ -245,7 +245,7 @@ static void audio_decode_example(const char *outfilename, const char *filename)
|
||||
AVCodecContext *c= NULL;
|
||||
int len;
|
||||
FILE *f, *outfile;
|
||||
uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
|
||||
AVPacket avpkt;
|
||||
AVFrame *decoded_frame = NULL;
|
||||
|
||||
@@ -521,7 +521,7 @@ static int decode_write_frame(const char *outfilename, AVCodecContext *avctx,
|
||||
/* the picture is allocated by the decoder, no need to free it */
|
||||
snprintf(buf, sizeof(buf), outfilename, *frame_count);
|
||||
pgm_save(frame->data[0], frame->linesize[0],
|
||||
frame->width, frame->height, buf);
|
||||
avctx->width, avctx->height, buf);
|
||||
(*frame_count)++;
|
||||
}
|
||||
if (pkt->data) {
|
||||
@@ -538,13 +538,13 @@ static void video_decode_example(const char *outfilename, const char *filename)
|
||||
int frame_count;
|
||||
FILE *f;
|
||||
AVFrame *frame;
|
||||
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
|
||||
AVPacket avpkt;
|
||||
|
||||
av_init_packet(&avpkt);
|
||||
|
||||
/* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
|
||||
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
printf("Decode video file %s to %s\n", filename, outfilename);
|
||||
|
||||
@@ -561,8 +561,8 @@ static void video_decode_example(const char *outfilename, const char *filename)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
|
||||
c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames
|
||||
if(codec->capabilities&CODEC_CAP_TRUNCATED)
|
||||
c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
|
||||
|
||||
/* For some codecs, such as msmpeg4 and mpeg4, width and height
|
||||
MUST be initialized there because this information is not
|
||||
|
||||
@@ -38,10 +38,7 @@
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavutil/opt.h>
|
||||
|
||||
const char *filter_descr = "scale=78:24,transpose=cclock";
|
||||
/* other way:
|
||||
scale=78:24 [scl]; [scl] transpose=cclock // assumes "[in]" and "[out]" to be input output pads respectively
|
||||
*/
|
||||
const char *filter_descr = "scale=78:24";
|
||||
|
||||
static AVFormatContext *fmt_ctx;
|
||||
static AVCodecContext *dec_ctx;
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Stephan Holljes
|
||||
*
|
||||
* 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 multi-client network API usage example.
|
||||
*
|
||||
* @example http_multiclient.c
|
||||
* This example will serve a file without decoding or demuxing it over http.
|
||||
* Multiple clients can connect and will receive the same file.
|
||||
*/
|
||||
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void process_client(AVIOContext *client, const char *in_uri)
|
||||
{
|
||||
AVIOContext *input = NULL;
|
||||
uint8_t buf[1024];
|
||||
int ret, n, reply_code;
|
||||
char *resource = NULL;
|
||||
while ((ret = avio_handshake(client)) > 0) {
|
||||
av_opt_get(client, "resource", AV_OPT_SEARCH_CHILDREN, &resource);
|
||||
// check for strlen(resource) is necessary, because av_opt_get()
|
||||
// may return empty string.
|
||||
if (resource && strlen(resource))
|
||||
break;
|
||||
}
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
av_log(client, AV_LOG_TRACE, "resource=%p\n", resource);
|
||||
if (resource && resource[0] == '/' && !strcmp((resource + 1), in_uri)) {
|
||||
reply_code = 200;
|
||||
} else {
|
||||
reply_code = AVERROR_HTTP_NOT_FOUND;
|
||||
}
|
||||
if ((ret = av_opt_set_int(client, "reply_code", reply_code, AV_OPT_SEARCH_CHILDREN)) < 0) {
|
||||
av_log(client, AV_LOG_ERROR, "Failed to set reply_code: %s.\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
av_log(client, AV_LOG_TRACE, "Set reply code to %d\n", reply_code);
|
||||
|
||||
while ((ret = avio_handshake(client)) > 0);
|
||||
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
fprintf(stderr, "Handshake performed.\n");
|
||||
if (reply_code != 200)
|
||||
goto end;
|
||||
fprintf(stderr, "Opening input file.\n");
|
||||
if ((ret = avio_open2(&input, in_uri, AVIO_FLAG_READ, NULL, NULL)) < 0) {
|
||||
av_log(input, AV_LOG_ERROR, "Failed to open input: %s: %s.\n", in_uri,
|
||||
av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
for(;;) {
|
||||
n = avio_read(input, buf, sizeof(buf));
|
||||
if (n < 0) {
|
||||
if (n == AVERROR_EOF)
|
||||
break;
|
||||
av_log(input, AV_LOG_ERROR, "Error reading from input: %s.\n",
|
||||
av_err2str(n));
|
||||
break;
|
||||
}
|
||||
avio_write(client, buf, n);
|
||||
avio_flush(client);
|
||||
}
|
||||
end:
|
||||
fprintf(stderr, "Flushing client\n");
|
||||
avio_flush(client);
|
||||
fprintf(stderr, "Closing client\n");
|
||||
avio_close(client);
|
||||
fprintf(stderr, "Closing input\n");
|
||||
avio_close(input);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
av_log_set_level(AV_LOG_TRACE);
|
||||
AVDictionary *options = NULL;
|
||||
AVIOContext *client = NULL, *server = NULL;
|
||||
const char *in_uri, *out_uri;
|
||||
int ret, pid;
|
||||
if (argc < 3) {
|
||||
printf("usage: %s input http://hostname[:port]\n"
|
||||
"API example program to serve http to multiple clients.\n"
|
||||
"\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_uri = argv[1];
|
||||
out_uri = argv[2];
|
||||
|
||||
av_register_all();
|
||||
avformat_network_init();
|
||||
|
||||
if ((ret = av_dict_set(&options, "listen", "2", 0)) < 0) {
|
||||
fprintf(stderr, "Failed to set listen mode for server: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
if ((ret = avio_open2(&server, out_uri, AVIO_FLAG_WRITE, NULL, &options)) < 0) {
|
||||
fprintf(stderr, "Failed to open server: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
fprintf(stderr, "Entering main loop.\n");
|
||||
for(;;) {
|
||||
if ((ret = avio_accept(server, &client)) < 0)
|
||||
goto end;
|
||||
fprintf(stderr, "Accepted client, forking process.\n");
|
||||
// XXX: Since we don't reap our children and don't ignore signals
|
||||
// this produces zombie processes.
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
perror("Fork failed");
|
||||
ret = AVERROR(errno);
|
||||
goto end;
|
||||
}
|
||||
if (pid == 0) {
|
||||
fprintf(stderr, "In child.\n");
|
||||
process_client(client, in_uri);
|
||||
avio_close(server);
|
||||
exit(0);
|
||||
}
|
||||
if (pid > 0)
|
||||
avio_close(client);
|
||||
}
|
||||
end:
|
||||
avio_close(server);
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
fprintf(stderr, "Some errors occurred: %s\n", av_err2str(ret));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -172,7 +172,7 @@ static void add_stream(OutputStream *ost, AVFormatContext *oc,
|
||||
|
||||
/* Some formats want stream headers to be separate. */
|
||||
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
@@ -230,7 +230,7 @@ static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, A
|
||||
/* increment frequency by 110 Hz per second */
|
||||
ost->tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
|
||||
|
||||
if (c->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
|
||||
if (c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
|
||||
nb_samples = 10000;
|
||||
else
|
||||
nb_samples = c->frame_size;
|
||||
|
||||
@@ -405,7 +405,7 @@ int main(int argc, char **argv)
|
||||
decoder_ctx->codec_id = AV_CODEC_ID_H264;
|
||||
if (video_st->codec->extradata_size) {
|
||||
decoder_ctx->extradata = av_mallocz(video_st->codec->extradata_size +
|
||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!decoder_ctx->extradata) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto finish;
|
||||
|
||||
@@ -101,7 +101,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
out_stream->codec->codec_tag = 0;
|
||||
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
}
|
||||
av_dump_format(ofmt_ctx, 0, out_filename, 1);
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ static int open_output_file(const char *filename,
|
||||
* Mark the encoder so that it behaves accordingly.
|
||||
*/
|
||||
if ((*output_format_context)->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
(*output_codec_context)->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
(*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) {
|
||||
|
||||
@@ -161,7 +161,7 @@ static int open_output_file(const char *filename)
|
||||
}
|
||||
|
||||
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
}
|
||||
av_dump_format(ofmt_ctx, 0, filename, 1);
|
||||
@@ -449,7 +449,7 @@ static int flush_encoder(unsigned int stream_index)
|
||||
int got_frame;
|
||||
|
||||
if (!(ofmt_ctx->streams[stream_index]->codec->codec->capabilities &
|
||||
AV_CODEC_CAP_DELAY))
|
||||
CODEC_CAP_DELAY))
|
||||
return 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
+56
-27
@@ -12,7 +12,7 @@
|
||||
|
||||
@chapter Synopsis
|
||||
|
||||
ffmpeg [@var{global_options}] @{[@var{input_file_options}] -i @file{input_url}@} ... @{[@var{output_file_options}] @file{output_url}@} ...
|
||||
ffmpeg [@var{global_options}] @{[@var{input_file_options}] -i @file{input_file}@} ... @{[@var{output_file_options}] @file{output_file}@} ...
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
@@ -24,10 +24,10 @@ rates and resize video on the fly with a high quality polyphase filter.
|
||||
@command{ffmpeg} reads from an arbitrary number of input "files" (which can be regular
|
||||
files, pipes, network streams, grabbing devices, etc.), specified by the
|
||||
@code{-i} option, and writes to an arbitrary number of output "files", which are
|
||||
specified by a plain output url. Anything found on the command line which
|
||||
cannot be interpreted as an option is considered to be an output url.
|
||||
specified by a plain output filename. Anything found on the command line which
|
||||
cannot be interpreted as an option is considered to be an output filename.
|
||||
|
||||
Each input or output url can, in principle, contain any number of streams of
|
||||
Each input or output file can, in principle, contain any number of streams of
|
||||
different types (video/audio/subtitle/attachment/data). The allowed number and/or
|
||||
types of streams may be limited by the container format. Selecting which
|
||||
streams from which inputs will go into which output is either done automatically
|
||||
@@ -243,8 +243,8 @@ Force input or output file format. The format is normally auto detected for inpu
|
||||
files and guessed from the file extension for output files, so this option is not
|
||||
needed in most cases.
|
||||
|
||||
@item -i @var{url} (@emph{input})
|
||||
input file url
|
||||
@item -i @var{filename} (@emph{input})
|
||||
input file name
|
||||
|
||||
@item -y (@emph{global})
|
||||
Overwrite output files without asking.
|
||||
@@ -277,18 +277,16 @@ libx264, and the 138th audio, which will be encoded with libvorbis.
|
||||
When used as an input option (before @code{-i}), limit the @var{duration} of
|
||||
data read from the input file.
|
||||
|
||||
When used as an output option (before an output url), stop writing the
|
||||
When used as an output option (before an output filename), stop writing the
|
||||
output after its duration reaches @var{duration}.
|
||||
|
||||
@var{duration} must be a time duration specification,
|
||||
see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
@var{duration} may be a number in seconds, or in @code{hh:mm:ss[.xxx]} form.
|
||||
|
||||
-to and -t are mutually exclusive and -t has priority.
|
||||
|
||||
@item -to @var{position} (@emph{output})
|
||||
Stop writing the output at @var{position}.
|
||||
@var{position} must be a time duration specification,
|
||||
see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
@var{position} may be a number in seconds, or in @code{hh:mm:ss[.xxx]} form.
|
||||
|
||||
-to and -t are mutually exclusive and -t has priority.
|
||||
|
||||
@@ -297,23 +295,17 @@ 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 that in most formats it is not possible to seek exactly,
|
||||
so @command{ffmpeg} will seek to the closest seek point before @var{position}.
|
||||
@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 url), decodes but discards
|
||||
When used as an output option (before an output filename), decodes but discards
|
||||
input until the timestamps reach @var{position}.
|
||||
|
||||
@var{position} must be a time duration specification,
|
||||
see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
|
||||
@item -sseof @var{position} (@emph{input/output})
|
||||
|
||||
Like the @code{-ss} option but relative to the "end of file". That is negative
|
||||
values are earlier in the file, 0 is at EOF.
|
||||
@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.
|
||||
@@ -328,7 +320,7 @@ the time duration specified in @var{offset}.
|
||||
@item -timestamp @var{date} (@emph{output})
|
||||
Set the recording timestamp in the container.
|
||||
|
||||
@var{date} must be a date specification,
|
||||
@var{date} must be a time duration specification,
|
||||
see @ref{date syntax,,the Date section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
|
||||
@item -metadata[:metadata_specifier] @var{key}=@var{value} (@emph{output,per-metadata})
|
||||
@@ -698,10 +690,6 @@ is not specified, the value of the @var{DISPLAY} environment variable is used
|
||||
For DXVA2, this option should contain the number of the display adapter to use.
|
||||
If this option is not specified, the default adapter is used.
|
||||
@end table
|
||||
|
||||
@item -hwaccels
|
||||
List all hardware acceleration methods supported in this build of ffmpeg.
|
||||
|
||||
@end table
|
||||
|
||||
@section Audio Options
|
||||
@@ -1094,7 +1082,7 @@ may be reassigned to a different value.
|
||||
For example, to set the stream 0 PID to 33 and the stream 1 PID to 36 for
|
||||
an output mpegts file:
|
||||
@example
|
||||
ffmpeg -i inurl -streamid 0:33 -streamid 1:36 out.ts
|
||||
ffmpeg -i infile -streamid 0:33 -streamid 1:36 out.ts
|
||||
@end example
|
||||
|
||||
@item -bsf[:@var{stream_specifier}] @var{bitstream_filters} (@emph{output,per-stream})
|
||||
@@ -1311,6 +1299,47 @@ If no such file is found, then ffmpeg will search for a file named
|
||||
|
||||
@c man end OPTIONS
|
||||
|
||||
@chapter Tips
|
||||
@c man begin TIPS
|
||||
|
||||
@itemize
|
||||
@item
|
||||
For streaming at very low bitrates, 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:
|
||||
|
||||
@example
|
||||
ffmpeg -g 3 -r 3 -t 10 -b:v 50k -s qcif -f rv10 /tmp/b.rm
|
||||
@end example
|
||||
|
||||
@item
|
||||
The parameter 'q' which is displayed while encoding is the current
|
||||
quantizer. The value 1 indicates that a very good quality could
|
||||
be achieved. The value 31 indicates the worst quality. If q=31 appears
|
||||
too often, it means that the encoder cannot compress enough to meet
|
||||
your bitrate. You must either increase the bitrate, decrease the
|
||||
frame rate or decrease the frame size.
|
||||
|
||||
@item
|
||||
If your computer is not fast enough, you can speed up the
|
||||
compression at the expense of the compression ratio. You can use
|
||||
'-me zero' to speed up motion estimation, and '-g 0' to disable
|
||||
motion estimation completely (you have only I-frames, which means it
|
||||
is about as good as JPEG compression).
|
||||
|
||||
@item
|
||||
To have very low audio bitrates, reduce the sampling frequency
|
||||
(down to 22050 Hz for MPEG audio, 22050 or 11025 for AC-3).
|
||||
|
||||
@item
|
||||
To have a constant quality (but a variable bitrate), use the option
|
||||
'-qscale n' when 'n' is between 1 (excellent quality) and 31 (worst
|
||||
quality).
|
||||
|
||||
@end itemize
|
||||
@c man end TIPS
|
||||
|
||||
@chapter Examples
|
||||
@c man begin EXAMPLES
|
||||
|
||||
|
||||
+5
-13
@@ -12,7 +12,7 @@
|
||||
|
||||
@chapter Synopsis
|
||||
|
||||
ffplay [@var{options}] [@file{input_url}]
|
||||
ffplay [@var{options}] [@file{input_file}]
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
@@ -47,17 +47,9 @@ Disable video.
|
||||
@item -sn
|
||||
Disable subtitles.
|
||||
@item -ss @var{pos}
|
||||
Seek to @var{pos}. Note that in most formats it is not possible to seek
|
||||
exactly, so @command{ffplay} will seek to the nearest seek point to
|
||||
@var{pos}.
|
||||
|
||||
@var{pos} must be a time duration specification,
|
||||
see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
Seek to a given position in seconds.
|
||||
@item -t @var{duration}
|
||||
Play @var{duration} seconds of audio/video.
|
||||
|
||||
@var{duration} must be a time duration specification,
|
||||
see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
play <duration> seconds of audio/video
|
||||
@item -bytes
|
||||
Seek by bytes.
|
||||
@item -nodisp
|
||||
@@ -106,8 +98,8 @@ the input audio.
|
||||
Use the option "-filters" to show all the available filters (including
|
||||
sources and sinks).
|
||||
|
||||
@item -i @var{input_url}
|
||||
Read @var{input_url}.
|
||||
@item -i @var{input_file}
|
||||
Read @var{input_file}.
|
||||
@end table
|
||||
|
||||
@section Advanced options
|
||||
|
||||
+5
-5
@@ -12,7 +12,7 @@
|
||||
|
||||
@chapter Synopsis
|
||||
|
||||
ffprobe [@var{options}] [@file{input_url}]
|
||||
ffprobe [@var{options}] [@file{input_file}]
|
||||
|
||||
@chapter Description
|
||||
@c man begin DESCRIPTION
|
||||
@@ -24,8 +24,8 @@ For example it can be used to check the format of the container used
|
||||
by a multimedia stream and the format and type of each media stream
|
||||
contained in it.
|
||||
|
||||
If a url is specified in input, ffprobe will try to open and
|
||||
probe the url content. If the url cannot be opened or recognized as
|
||||
If a filename is specified in input, ffprobe will try to open and
|
||||
probe the file content. If the file cannot be opened or recognized as
|
||||
a multimedia file, a positive exit code is returned.
|
||||
|
||||
ffprobe may be employed both as a standalone application or in
|
||||
@@ -332,8 +332,8 @@ with name "PIXEL_FORMAT".
|
||||
Force bitexact output, useful to produce output which is not dependent
|
||||
on the specific build.
|
||||
|
||||
@item -i @var{input_url}
|
||||
Read @var{input_url}.
|
||||
@item -i @var{input_file}
|
||||
Read @var{input_file}.
|
||||
|
||||
@end table
|
||||
@c man end
|
||||
|
||||
@@ -36,10 +36,8 @@ Possible forms of stream specifiers are:
|
||||
Matches the stream with this index. E.g. @code{-threads:1 4} would set the
|
||||
thread count for the second stream to 4.
|
||||
@item @var{stream_type}[:@var{stream_index}]
|
||||
@var{stream_type} is one of following: 'v' or 'V' for video, 'a' for audio, 's'
|
||||
for subtitle, 'd' for data, and 't' for attachments. 'v' matches all video
|
||||
streams, 'V' only matches video streams which are not attached pictures, video
|
||||
thumbnails or cover arts. If @var{stream_index} is given, then it matches
|
||||
@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
|
||||
stream number @var{stream_index} of this type. Otherwise, it matches all
|
||||
streams of this type.
|
||||
@item p:@var{program_id}[:@var{stream_index}]
|
||||
|
||||
@@ -98,7 +98,7 @@ Buffer references ownership and permissions
|
||||
The AVFilterLink structure has a few AVFilterBufferRef fields. The
|
||||
cur_buf and out_buf were used with the deprecated
|
||||
start_frame/draw_slice/end_frame API and should no longer be used.
|
||||
src_buf and partial_buf are used by libavfilter internally
|
||||
src_buf, cur_buf_copy and partial_buf are used by libavfilter internally
|
||||
and must not be accessed by filters.
|
||||
|
||||
Reference permissions
|
||||
|
||||
+11
-1363
File diff suppressed because it is too large
Load Diff
@@ -205,10 +205,6 @@ For example to separate the fields with newlines and indention:
|
||||
ffprobe -dump_separator "
|
||||
" -i ~/videos/matrixbench_mpeg2.mpg
|
||||
@end example
|
||||
|
||||
@item max_streams @var{integer} (@emph{input})
|
||||
Specifies the maximum number of streams. This can be used to reject files that
|
||||
would require too many resources due to a large number of streams.
|
||||
@end table
|
||||
|
||||
@c man end FORMAT OPTIONS
|
||||
|
||||
+3
-32
@@ -145,14 +145,6 @@ x265 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 kvazaar
|
||||
|
||||
FFmpeg can make use of the kvazaar library for HEVC encoding.
|
||||
|
||||
Go to @url{https://github.com/ultravideo/kvazaar} and follow the
|
||||
instructions for installing the library. Then pass
|
||||
@code{--enable-libkvazaar} to configure to enable it.
|
||||
|
||||
@section libilbc
|
||||
|
||||
iLBC is a narrowband speech codec that has been made freely available
|
||||
@@ -200,17 +192,6 @@ end user having AviSynth or AvxSynth installed - they'll only need to be
|
||||
installed to use AviSynth scripts (obviously).
|
||||
@end float
|
||||
|
||||
@section Intel QuickSync Video
|
||||
|
||||
FFmpeg can use Intel QuickSync Video (QSV) for accelerated encoding and decoding
|
||||
of multiple codecs. To use QSV, FFmpeg must be linked against the @code{libmfx}
|
||||
dispatcher, which loads the actual decoding libraries.
|
||||
|
||||
The dispatcher is open source and can be downloaded from
|
||||
@url{https://github.com/lu-zero/mfx_dispatch.git}. FFmpeg needs to be configured
|
||||
with the @code{--enable-libmfx} option and @code{pkg-config} needs to be able to
|
||||
locate the dispatcher's @code{.pc} files.
|
||||
|
||||
|
||||
@chapter Supported File Formats, Codecs or Features
|
||||
|
||||
@@ -226,10 +207,6 @@ library:
|
||||
@item 4xm @tab @tab X
|
||||
@tab 4X Technologies format, used in some games.
|
||||
@item 8088flex TMV @tab @tab X
|
||||
@item AAX @tab @tab X
|
||||
@tab Audible Enhanced Audio format, used in audiobooks.
|
||||
@item AA @tab @tab X
|
||||
@tab Audible Format 2, 3, and 4, used in audiobooks.
|
||||
@item ACT Voice @tab @tab X
|
||||
@tab contains G.729 audio
|
||||
@item Adobe Filmstrip @tab X @tab X
|
||||
@@ -266,8 +243,6 @@ library:
|
||||
@tab Used in Z and Z95 games.
|
||||
@item Brute Force & Ignorance @tab @tab X
|
||||
@tab Used in the game Flash Traffic: City of Angels.
|
||||
@item BFSTM @tab @tab X
|
||||
@tab Audio format used on the Nintendo WiiU (based on BRSTM).
|
||||
@item BRSTM @tab @tab X
|
||||
@tab Audio format used on the Nintendo Wii.
|
||||
@item BWF @tab X @tab X
|
||||
@@ -298,7 +273,6 @@ library:
|
||||
@item Deluxe Paint Animation @tab @tab X
|
||||
@item DFA @tab @tab X
|
||||
@tab This format is used in Chronomaster game
|
||||
@item DirectDraw Surface @tab @tab X
|
||||
@item DSD Stream File (DSF) @tab @tab X
|
||||
@item DV video @tab X @tab X
|
||||
@item DXA @tab @tab X
|
||||
@@ -503,7 +477,6 @@ library:
|
||||
@tab Tiertex .seq files used in the DOS CD-ROM version of the game Flashback.
|
||||
@item True Audio @tab @tab X
|
||||
@item VC-1 test bitstream @tab X @tab X
|
||||
@item Vidvox Hap @tab X @tab X
|
||||
@item Vivo @tab @tab X
|
||||
@item WAV @tab X @tab X
|
||||
@item WavPack @tab X @tab X
|
||||
@@ -690,8 +663,6 @@ following image formats are supported:
|
||||
@tab Sorenson H.263 used in Flash
|
||||
@item Forward Uncompressed @tab @tab X
|
||||
@item Fraps @tab @tab X
|
||||
@item Go2Meeting @tab @tab X
|
||||
@tab fourcc: G2M2, G2M3
|
||||
@item Go2Webinar @tab @tab X
|
||||
@tab fourcc: G2M4
|
||||
@item H.261 @tab X @tab X
|
||||
@@ -700,7 +671,7 @@ following image formats are supported:
|
||||
@item H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 @tab E @tab X
|
||||
@tab encoding supported through external library libx264 and OpenH264
|
||||
@item HEVC @tab X @tab X
|
||||
@tab encoding supported through external library libx265 and libkvazaar
|
||||
@tab encoding supported through the external library libx265
|
||||
@item HNM version 4 @tab @tab X
|
||||
@item HuffYUV @tab X @tab X
|
||||
@item HuffYUV FFmpeg variant @tab X @tab X
|
||||
@@ -865,7 +836,7 @@ following image formats are supported:
|
||||
@item Name @tab Encoding @tab Decoding @tab Comments
|
||||
@item 8SVX exponential @tab @tab X
|
||||
@item 8SVX fibonacci @tab @tab X
|
||||
@item AAC+ @tab E @tab IX
|
||||
@item AAC+ @tab E @tab X
|
||||
@tab encoding supported through external library libaacplus
|
||||
@item AAC @tab E @tab X
|
||||
@tab encoding supported through external library libfaac and libvo-aacenc
|
||||
@@ -905,7 +876,7 @@ following image formats are supported:
|
||||
@item ADPCM MS IMA @tab X @tab X
|
||||
@item ADPCM Nintendo Gamecube AFC @tab @tab X
|
||||
@item ADPCM Nintendo Gamecube DTK @tab @tab X
|
||||
@item ADPCM Nintendo THP @tab @tab X
|
||||
@item ADPCM Nintendo Gamecube THP @tab @tab X
|
||||
@item ADPCM QT IMA @tab X @tab X
|
||||
@item ADPCM SEGA CRI ADX @tab X @tab X
|
||||
@tab Used in Sega Dreamcast games.
|
||||
|
||||
+27
-50
@@ -1,10 +1,10 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle Using Git to develop FFmpeg
|
||||
@settitle Using git to develop FFmpeg
|
||||
|
||||
@titlepage
|
||||
@center @titlefont{Using Git to develop FFmpeg}
|
||||
@center @titlefont{Using git to develop FFmpeg}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
@@ -13,9 +13,9 @@
|
||||
|
||||
@chapter Introduction
|
||||
|
||||
This document aims in giving some quick references on a set of useful Git
|
||||
This document aims in giving some quick references on a set of useful git
|
||||
commands. You should always use the extensive and detailed documentation
|
||||
provided directly by Git:
|
||||
provided directly by git:
|
||||
|
||||
@example
|
||||
git --help
|
||||
@@ -32,28 +32,29 @@ man git-<command>
|
||||
shows information about the subcommand <command>.
|
||||
|
||||
Additional information could be found on the
|
||||
@url{http://gitref.org, Git Reference} website.
|
||||
@url{http://gitref.org, Git Reference} website
|
||||
|
||||
For more information about the Git project, visit the
|
||||
@url{http://git-scm.com/, Git website}.
|
||||
|
||||
@url{http://git-scm.com/, Git website}
|
||||
|
||||
Consult these resources whenever you have problems, they are quite exhaustive.
|
||||
|
||||
What follows now is a basic introduction to Git and some FFmpeg-specific
|
||||
guidelines to ease the contribution to the project.
|
||||
guidelines to ease the contribution to the project
|
||||
|
||||
@chapter Basics Usage
|
||||
|
||||
@section Get Git
|
||||
@section Get GIT
|
||||
|
||||
You can get Git from @url{http://git-scm.com/}
|
||||
You can get git from @url{http://git-scm.com/}
|
||||
Most distribution and operating system provide a package for it.
|
||||
|
||||
|
||||
@section Cloning the source tree
|
||||
|
||||
@example
|
||||
git clone https://git.ffmpeg.org/ffmpeg.git <target>
|
||||
git clone git://source.ffmpeg.org/ffmpeg <target>
|
||||
@end example
|
||||
|
||||
This will put the FFmpeg sources into the directory @var{<target>}.
|
||||
@@ -107,7 +108,7 @@ git add [-A] <filename/dirname>
|
||||
git rm [-r] <filename/dirname>
|
||||
@end example
|
||||
|
||||
Git needs to get notified of all changes you make to your working
|
||||
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.
|
||||
|
||||
@@ -127,8 +128,8 @@ will show all local modifications in your working directory as unified diff.
|
||||
git log <filename(s)>
|
||||
@end example
|
||||
|
||||
You may also use the graphical tools like @command{gitview} or @command{gitk}
|
||||
or the web interface available at @url{http://source.ffmpeg.org/}.
|
||||
You may also use the graphical tools like gitview or gitk or the web
|
||||
interface available at http://source.ffmpeg.org/
|
||||
|
||||
@section Checking source tree status
|
||||
|
||||
@@ -149,7 +150,6 @@ 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.
|
||||
@@ -172,21 +172,14 @@ to make sure you don't have untracked files or deletions.
|
||||
git add [-i|-p|-A] <filenames/dirnames>
|
||||
@end example
|
||||
|
||||
Make sure you have told Git your name, email address and GPG key
|
||||
Make sure you have told git your name and email address
|
||||
|
||||
@example
|
||||
git config --global user.name "My Name"
|
||||
git config --global user.email my@@email.invalid
|
||||
git config --global user.signingkey ABCDEF0123245
|
||||
@end example
|
||||
|
||||
Enable signing all commits or use -S
|
||||
|
||||
@example
|
||||
git config --global commit.gpgsign true
|
||||
@end example
|
||||
|
||||
Use @option{--global} to set the global configuration for all your Git checkouts.
|
||||
Use @var{--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
|
||||
@@ -217,7 +210,7 @@ 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 @command{git format-patch}.
|
||||
the patch by git format-patch.
|
||||
|
||||
@section Preparing a patchset
|
||||
|
||||
@@ -333,12 +326,10 @@ faulty commit disappear from the history.
|
||||
@section Pushing changes to remote trees
|
||||
|
||||
@example
|
||||
git push origin master --dry-run
|
||||
git push
|
||||
@end example
|
||||
|
||||
Will simulate a push of the local master branch to the default remote
|
||||
(@var{origin}). And list which branches and ranges or commits would have been
|
||||
pushed.
|
||||
Will push the changes to the default remote (@var{origin}).
|
||||
Git will prevent you from pushing changes if the local and remote trees are
|
||||
out of sync. Refer to @ref{Updating the source tree to the latest revision}.
|
||||
|
||||
@@ -359,24 +350,23 @@ branches matching the local ones.
|
||||
|
||||
@section Finding a specific svn revision
|
||||
|
||||
Since version 1.7.1 Git supports @samp{:/foo} syntax for specifying commits
|
||||
Since version 1.7.1 git supports @var{:/foo} syntax for specifying commits
|
||||
based on a regular expression. see man gitrevisions
|
||||
|
||||
@example
|
||||
git show :/'as revision 23456'
|
||||
@end example
|
||||
|
||||
will show the svn changeset @samp{r23456}. With older Git versions searching in
|
||||
will show the svn changeset @var{r23456}. With older git versions searching in
|
||||
the @command{git log} output is the easiest option (especially if a pager with
|
||||
search capabilities is used).
|
||||
|
||||
This commit can be checked out with
|
||||
|
||||
@example
|
||||
git checkout -b svn_23456 :/'as revision 23456'
|
||||
@end example
|
||||
|
||||
or for Git < 1.7.1 with
|
||||
or for git < 1.7.1 with
|
||||
|
||||
@example
|
||||
git checkout -b svn_23456 $SHA1
|
||||
@@ -385,20 +375,7 @@ git checkout -b svn_23456 $SHA1
|
||||
where @var{$SHA1} is the commit hash from the @command{git log} output.
|
||||
|
||||
|
||||
@chapter gpg key generation
|
||||
|
||||
If you have no gpg key yet, we recommend that you create a ed25519 based key as it
|
||||
is small, fast and secure. Especially it results in small signatures in git.
|
||||
|
||||
@example
|
||||
gpg --default-new-key-algo "ed25519/cert,sign+cv25519/encr" --quick-generate-key "human@@server.com"
|
||||
@end example
|
||||
|
||||
When generating a key, make sure the email specified matches the email used in git as some sites like
|
||||
github consider mismatches a reason to declare such commits unverified. After generating a key you
|
||||
can add it to the MAINTAINER file and upload it to a keyserver.
|
||||
|
||||
@chapter Pre-push checklist
|
||||
@chapter pre-push checklist
|
||||
|
||||
Once you have a set of commits that you feel are ready for pushing,
|
||||
work through the following checklist to doublecheck everything is in
|
||||
@@ -409,7 +386,7 @@ Apply your common sense, but if in doubt, err on the side of caution.
|
||||
First, make sure that the commits and branches you are going to push
|
||||
match what you want pushed and that nothing is missing, extraneous or
|
||||
wrong. You can see what will be pushed by running the git push command
|
||||
with @option{--dry-run} first. And then inspecting the commits listed with
|
||||
with --dry-run first. And then inspecting the commits listed with
|
||||
@command{git log -p 1234567..987654}. The @command{git status} command
|
||||
may help in finding local changes that have been forgotten to be added.
|
||||
|
||||
@@ -418,7 +395,7 @@ Next let the code pass through a full run of our testsuite.
|
||||
@itemize
|
||||
@item @command{make distclean}
|
||||
@item @command{/path/to/ffmpeg/configure}
|
||||
@item @command{make fate}
|
||||
@item @command{make check}
|
||||
@item if fate fails due to missing samples run @command{make fate-rsync} and retry
|
||||
@end itemize
|
||||
|
||||
@@ -436,5 +413,5 @@ recommended.
|
||||
|
||||
@chapter Server Issues
|
||||
|
||||
Contact the project admins at @email{root@@ffmpeg.org} if you have technical
|
||||
problems with the Git server.
|
||||
Contact the project admins @email{root@@ffmpeg.org} if you have technical
|
||||
problems with the GIT server.
|
||||
|
||||
+17
-164
@@ -51,18 +51,6 @@ ffmpeg -f alsa -i hw:0 alsaout.wav
|
||||
For more information see:
|
||||
@url{http://www.alsa-project.org/alsa-doc/alsa-lib/pcm.html}
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item sample_rate
|
||||
Set the sample rate in Hz. Default is 48000.
|
||||
|
||||
@item channels
|
||||
Set the number of channels. Default is 2.
|
||||
|
||||
@end table
|
||||
|
||||
@section avfoundation
|
||||
|
||||
AVFoundation input device.
|
||||
@@ -126,19 +114,6 @@ und the first one in this list is used instead. Available pixel formats are:
|
||||
bgr48be, uyvy422, yuva444p, yuva444p16le, yuv444p, yuv422p16, yuv422p10, yuv444p10,
|
||||
yuv420p, nv12, yuyv422, gray}
|
||||
|
||||
@item -framerate
|
||||
Set the grabbing frame rate. Default is @code{ntsc}, corresponding to a
|
||||
frame rate of @code{30000/1001}.
|
||||
|
||||
@item -video_size
|
||||
Set the video frame size.
|
||||
|
||||
@item -capture_cursor
|
||||
Capture the mouse pointer. Default is 0.
|
||||
|
||||
@item -capture_mouse_clicks
|
||||
Capture the screen mouse clicks. Default is 0.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
@@ -175,36 +150,6 @@ $ ffmpeg -f avfoundation -pixel_format bgr0 -i "default:none" out.avi
|
||||
|
||||
BSD video input device.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item framerate
|
||||
Set the frame rate.
|
||||
|
||||
@item video_size
|
||||
Set the video frame size. Default is @code{vga}.
|
||||
|
||||
@item standard
|
||||
|
||||
Available values are:
|
||||
@table @samp
|
||||
@item pal
|
||||
|
||||
@item ntsc
|
||||
|
||||
@item secam
|
||||
|
||||
@item paln
|
||||
|
||||
@item palm
|
||||
|
||||
@item ntscj
|
||||
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@section decklink
|
||||
|
||||
The decklink input device provides capture capabilities for Blackmagic
|
||||
@@ -266,6 +211,18 @@ Capture video clip at 1080i50 10 bit:
|
||||
ffmpeg -bm_v210 1 -f decklink -i 'UltraStudio Mini Recorder@@11' -acodec copy -vcodec copy output.avi
|
||||
@end example
|
||||
|
||||
@item
|
||||
Capture video clip at 720p50 with 32bit audio:
|
||||
@example
|
||||
ffmpeg -bm_audiodepth 32 -f decklink -i 'UltraStudio Mini Recorder@@14' -acodec copy -vcodec copy output.avi
|
||||
@end example
|
||||
|
||||
@item
|
||||
Capture video clip at 576i50 with 8 audio channels:
|
||||
@example
|
||||
ffmpeg -bm_channels 8 -f decklink -i 'UltraStudio Mini Recorder@@3' -acodec copy -vcodec copy output.avi
|
||||
@end example
|
||||
|
||||
@end itemize
|
||||
|
||||
@section dshow
|
||||
@@ -318,11 +275,11 @@ If set to @option{true}, print a list of selected device's options
|
||||
and exit.
|
||||
|
||||
@item video_device_number
|
||||
Set video device number for devices with the same name (starts at 0,
|
||||
Set video device number for devices with same name (starts at 0,
|
||||
defaults to 0).
|
||||
|
||||
@item audio_device_number
|
||||
Set audio device number for devices with the same name (starts at 0,
|
||||
Set audio device number for devices with same name (starts at 0,
|
||||
defaults to 0).
|
||||
|
||||
@item pixel_format
|
||||
@@ -472,27 +429,6 @@ $ ffmpeg -f dshow -show_video_device_dialog true -crossbar_video_input_pin_numbe
|
||||
|
||||
Linux DV 1394 input device.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item framerate
|
||||
Set the frame rate. Default is 25.
|
||||
|
||||
@item standard
|
||||
|
||||
Available values are:
|
||||
@table @samp
|
||||
@item pal
|
||||
|
||||
@item ntsc
|
||||
|
||||
@end table
|
||||
|
||||
Default value is @code{ntsc}.
|
||||
|
||||
@end table
|
||||
|
||||
@section fbdev
|
||||
|
||||
Linux framebuffer input device.
|
||||
@@ -505,27 +441,18 @@ console. It is accessed through a file device node, usually
|
||||
For more detailed information read the file
|
||||
Documentation/fb/framebuffer.txt included in the Linux source tree.
|
||||
|
||||
See also @url{http://linux-fbdev.sourceforge.net/}, and fbset(1).
|
||||
|
||||
To record from the framebuffer device @file{/dev/fb0} with
|
||||
@command{ffmpeg}:
|
||||
@example
|
||||
ffmpeg -f fbdev -framerate 10 -i /dev/fb0 out.avi
|
||||
ffmpeg -f fbdev -r 10 -i /dev/fb0 out.avi
|
||||
@end example
|
||||
|
||||
You can take a single screenshot image with the command:
|
||||
@example
|
||||
ffmpeg -f fbdev -framerate 1 -i /dev/fb0 -frames:v 1 screenshot.jpeg
|
||||
ffmpeg -f fbdev -frames:v 1 -r 1 -i /dev/fb0 screenshot.jpeg
|
||||
@end example
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item framerate
|
||||
Set the frame rate. Default is 25.
|
||||
|
||||
@end table
|
||||
See also @url{http://linux-fbdev.sourceforge.net/}, and fbset(1).
|
||||
|
||||
@section gdigrab
|
||||
|
||||
@@ -711,15 +638,6 @@ $ jack_connect metro:120_bpm ffmpeg:input_1
|
||||
For more information read:
|
||||
@url{http://jackaudio.org/}
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item channels
|
||||
Set the number of channels. Default is 2.
|
||||
|
||||
@end table
|
||||
|
||||
@section lavfi
|
||||
|
||||
Libavfilter input virtual device.
|
||||
@@ -760,9 +678,6 @@ Set the filename of the filtergraph to be read and sent to the other
|
||||
filters. Syntax of the filtergraph is the same as the one specified by
|
||||
the option @var{graph}.
|
||||
|
||||
@item dumpgraph
|
||||
Dump graph to stderr.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
@@ -964,19 +879,6 @@ ffmpeg -f oss -i /dev/dsp /tmp/oss.wav
|
||||
For more information about OSS see:
|
||||
@url{http://manuals.opensound.com/usersguide/dsp.html}
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item sample_rate
|
||||
Set the sample rate in Hz. Default is 48000.
|
||||
|
||||
@item channels
|
||||
Set the number of channels. Default is 2.
|
||||
|
||||
@end table
|
||||
|
||||
|
||||
@section pulse
|
||||
|
||||
PulseAudio input device.
|
||||
@@ -1017,10 +919,6 @@ 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.
|
||||
|
||||
@item wallclock
|
||||
Set the initial PTS using the current time. Default is 1.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
@@ -1056,22 +954,6 @@ ffmpeg -f qtkit -i "default" out.mpg
|
||||
ffmpeg -f qtkit -list_devices true -i ""
|
||||
@end example
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item frame_rate
|
||||
Set frame rate. Default is 30.
|
||||
|
||||
@item list_devices
|
||||
If set to @code{true}, print a list of devices and exit. Default is
|
||||
@code{false}.
|
||||
|
||||
@item video_device_index
|
||||
Select the video device by index for devices with the same name (starts at 0).
|
||||
|
||||
@end table
|
||||
|
||||
@section sndio
|
||||
|
||||
sndio input device.
|
||||
@@ -1089,18 +971,6 @@ command:
|
||||
ffmpeg -f sndio -i /dev/audio0 /tmp/oss.wav
|
||||
@end example
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item sample_rate
|
||||
Set the sample rate in Hz. Default is 48000.
|
||||
|
||||
@item channels
|
||||
Set the number of channels. Default is 2.
|
||||
|
||||
@end table
|
||||
|
||||
@section video4linux2, v4l2
|
||||
|
||||
Video4Linux2 input video device.
|
||||
@@ -1223,10 +1093,6 @@ Force conversion from monotonic to absolute timestamps.
|
||||
@end table
|
||||
|
||||
Default value is @code{default}.
|
||||
|
||||
@item use_libv4l2
|
||||
Use libv4l2 (v4l-utils) conversion functions. Default is 0.
|
||||
|
||||
@end table
|
||||
|
||||
@section vfwcap
|
||||
@@ -1237,19 +1103,6 @@ The filename passed as input is the capture driver number, ranging from
|
||||
0 to 9. You may use "list" as filename to print a list of drivers. Any
|
||||
other filename will be interpreted as device number 0.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item video_size
|
||||
Set the video frame size.
|
||||
|
||||
@item framerate
|
||||
Set the grabbing frame rate. Default value is @code{ntsc},
|
||||
corresponding to a frame rate of @code{30000/1001}.
|
||||
|
||||
@end table
|
||||
|
||||
@section x11grab
|
||||
|
||||
X11 video input device.
|
||||
|
||||
@@ -47,16 +47,12 @@ Files that have MIPS copyright notice in them:
|
||||
* libavutil/mips/
|
||||
float_dsp_mips.c
|
||||
libm_mips.h
|
||||
softfloat_tables.h
|
||||
* libavcodec/
|
||||
fft_fixed_32.c
|
||||
fft_init_table.c
|
||||
fft_table.h
|
||||
mdct_fixed_32.c
|
||||
* libavcodec/mips/
|
||||
aacdec_fixed.c
|
||||
aacsbr_fixed.c
|
||||
aacsbr_template.c
|
||||
aaccoder_mips.c
|
||||
aacpsy_mips.h
|
||||
ac3dsp_mips.c
|
||||
|
||||
@@ -54,7 +54,7 @@ thread.
|
||||
If the codec allocates writable tables in its init(), add an init_thread_copy()
|
||||
which re-allocates them for other threads.
|
||||
|
||||
Add AV_CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very little
|
||||
Add CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very little
|
||||
speed gain at this point but it should work.
|
||||
|
||||
If there are inter-frame dependencies, so the codec calls
|
||||
|
||||
+7
-87
@@ -263,62 +263,6 @@ ffmpeg in.nut -hls_segment_filename 'file%03d.ts' out.m3u8
|
||||
This example will produce the playlist, @file{out.m3u8}, and segment files:
|
||||
@file{file000.ts}, @file{file001.ts}, @file{file002.ts}, etc.
|
||||
|
||||
@item hls_key_info_file @var{key_info_file}
|
||||
Use the information in @var{key_info_file} for segment encryption. The first
|
||||
line of @var{key_info_file} specifies the key URI written to the playlist. The
|
||||
key URL is used to access the encryption key during playback. The second line
|
||||
specifies the path to the key file used to obtain the key during the encryption
|
||||
process. The key file is read as a single packed array of 16 octets in binary
|
||||
format. The optional third line specifies the initialization vector (IV) as a
|
||||
hexadecimal string to be used instead of the segment sequence number (default)
|
||||
for encryption. Changes to @var{key_info_file} will result in segment
|
||||
encryption with the new key/IV and an entry in the playlist for the new key
|
||||
URI/IV.
|
||||
|
||||
Key info file format:
|
||||
@example
|
||||
@var{key URI}
|
||||
@var{key file path}
|
||||
@var{IV} (optional)
|
||||
@end example
|
||||
|
||||
Example key URIs:
|
||||
@example
|
||||
http://server/file.key
|
||||
/path/to/file.key
|
||||
file.key
|
||||
@end example
|
||||
|
||||
Example key file paths:
|
||||
@example
|
||||
file.key
|
||||
/path/to/file.key
|
||||
@end example
|
||||
|
||||
Example IV:
|
||||
@example
|
||||
0123456789ABCDEF0123456789ABCDEF
|
||||
@end example
|
||||
|
||||
Key info file example:
|
||||
@example
|
||||
http://server/file.key
|
||||
/path/to/file.key
|
||||
0123456789ABCDEF0123456789ABCDEF
|
||||
@end example
|
||||
|
||||
Example shell script:
|
||||
@example
|
||||
#!/bin/sh
|
||||
BASE_URL=$@{1:-'.'@}
|
||||
openssl rand 16 > file.key
|
||||
echo $BASE_URL/file.key > file.keyinfo
|
||||
echo file.key >> file.keyinfo
|
||||
echo $(openssl rand -hex 16) >> file.keyinfo
|
||||
ffmpeg -f lavfi -re -i testsrc -c:v h264 -hls_flags delete_segments \
|
||||
-hls_key_info_file file.keyinfo out.m3u8
|
||||
@end example
|
||||
|
||||
@item hls_flags single_file
|
||||
If this flag is set, the muxer will store all segments in a single MPEG-TS
|
||||
file, and will use byte ranges in the playlist. HLS playlists generated with
|
||||
@@ -667,13 +611,6 @@ point on IIS with this muxer. Example:
|
||||
ffmpeg -re @var{<normal input/transcoding options>} -movflags isml+frag_keyframe -f ismv http://server/publishingpoint.isml/Streams(Encoder1)
|
||||
@end example
|
||||
|
||||
@subsection Audible AAX
|
||||
|
||||
Audible AAX files are encrypted M4B files, and they can be decrypted by specifying a 4 byte activation secret.
|
||||
@example
|
||||
ffmpeg -activation_bytes 1CEB00DA -i test.aax -vn -c:a copy output.mp4
|
||||
@end example
|
||||
|
||||
@section mp3
|
||||
|
||||
The MP3 muxer writes a raw MP3 stream with the following optional features:
|
||||
@@ -766,10 +703,6 @@ Set a constant muxrate (default VBR).
|
||||
@item -pcr_period @var{numer}
|
||||
Override the default PCR retransmission time (default 20ms), ignored
|
||||
if variable muxrate is selected.
|
||||
@item pat_period @var{number}
|
||||
Maximal time in seconds between PAT/PMT tables.
|
||||
@item sdt_period @var{number}
|
||||
Maximal time in seconds between SDT tables.
|
||||
@item -pes_payload_size @var{number}
|
||||
Set minimum PES packet payload in bytes.
|
||||
@item -mpegts_flags @var{flags}
|
||||
@@ -821,8 +754,6 @@ Option mpegts_flags may take a set of such flags:
|
||||
Reemit PAT/PMT before writing the next packet.
|
||||
@item latm
|
||||
Use LATM packetization for AAC.
|
||||
@item pat_pmt_at_frames
|
||||
Reemit PAT and PMT at each video frame.
|
||||
@end table
|
||||
|
||||
@subsection Example
|
||||
@@ -839,21 +770,6 @@ ffmpeg -i file.mpg -c copy \
|
||||
-y out.ts
|
||||
@end example
|
||||
|
||||
@section mxf, mxf_d10
|
||||
|
||||
MXF muxer.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The muxer options are:
|
||||
|
||||
@table @option
|
||||
@item store_user_comments @var{bool}
|
||||
Set if user comments should be stored if available or never.
|
||||
IRT D-10 does not allow user comments. The default is thus to write them for
|
||||
mxf but not for mxf_d10
|
||||
@end table
|
||||
|
||||
@section null
|
||||
|
||||
Null muxer.
|
||||
@@ -992,6 +908,13 @@ Allow caching (only affects M3U8 list files).
|
||||
Allow live-friendly file generation.
|
||||
@end table
|
||||
|
||||
@item segment_list_type @var{type}
|
||||
Select the listing format.
|
||||
@table @option
|
||||
@item @var{flat} use a simple flat list of entries.
|
||||
@item @var{hls} use a m3u8-like structure.
|
||||
@end table
|
||||
|
||||
@item segment_list_size @var{size}
|
||||
Update the list file so that it contains at most @var{size}
|
||||
segments. If 0 the list file will contain all the segments. Default
|
||||
@@ -1001,9 +924,6 @@ value is 0.
|
||||
Prepend @var{prefix} to each entry. Useful to generate absolute paths.
|
||||
By default no prefix is applied.
|
||||
|
||||
@item segment_list_type @var{type}
|
||||
Select the listing format.
|
||||
|
||||
The following values are recognized:
|
||||
@table @samp
|
||||
@item flat
|
||||
|
||||
@@ -175,6 +175,12 @@ Notes:
|
||||
|
||||
@itemize
|
||||
|
||||
@item It is possible that coreutils' @code{link.exe} conflicts with MSVC's linker.
|
||||
You can find out by running @code{which link} to see which @code{link.exe} you
|
||||
are using. If it is located at @code{/bin/link.exe}, then you have the wrong one
|
||||
in your @code{PATH}. Either move or remove that copy, or make sure MSVC's
|
||||
@code{link.exe} takes precedence in your @code{PATH} over coreutils'.
|
||||
|
||||
@item If you wish to build with zlib support, you will have to grab a compatible
|
||||
zlib binary from somewhere, with an MSVC import lib, or if you wish to link
|
||||
statically, you can follow the instructions below to build a compatible
|
||||
|
||||
@@ -19,18 +19,6 @@ supported protocols.
|
||||
|
||||
A description of the currently available protocols follows.
|
||||
|
||||
@section async
|
||||
|
||||
Asynchronous data filling wrapper for input stream.
|
||||
|
||||
Fill data in a background thread, to decouple I/O operation from demux thread.
|
||||
|
||||
@example
|
||||
async:@var{URL}
|
||||
async:http://host/resource
|
||||
async:cache:http://host/resource
|
||||
@end example
|
||||
|
||||
@section bluray
|
||||
|
||||
Read BluRay playlist.
|
||||
@@ -304,8 +292,6 @@ autodetection in the future.
|
||||
If set to 1 enables experimental HTTP server. This can be used to send data when
|
||||
used as an output option, or read data from a client with HTTP POST when used as
|
||||
an input option.
|
||||
If set to 2 enables experimental mutli-client HTTP server. This is not yet implemented
|
||||
in ffmpeg.c or ffserver.c and thus must not be used as a command line option.
|
||||
@example
|
||||
# Server side (sending):
|
||||
ffmpeg -i somefile.ogg -c copy -listen 1 -f ogg http://@var{server}:@var{port}
|
||||
|
||||
@@ -122,22 +122,6 @@ a_dither).
|
||||
|
||||
@end table
|
||||
|
||||
@item alphablend
|
||||
Set the alpha blending to use when the input has alpha but the output does not.
|
||||
Default value is @samp{none}.
|
||||
|
||||
@table @samp
|
||||
@item uniform_color
|
||||
Blend onto a uniform background color
|
||||
|
||||
@item checkerboard
|
||||
Blend onto a checkerboard
|
||||
|
||||
@item none
|
||||
No blending
|
||||
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@c man end SCALER OPTIONS
|
||||
|
||||
+1
-1
@@ -384,7 +384,7 @@ sub postprocess
|
||||
# @* is also impossible in .pod; we discard it and any newline that
|
||||
# follows it. Similarly, our macro @gol must be discarded.
|
||||
|
||||
s/\@anchor\{(?:[^\}]*)\}//g;
|
||||
s/\@anchor{(?:[^\}]*)\}//g;
|
||||
s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g;
|
||||
s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g;
|
||||
s/;\s+\@pxref\{(?:[^\}]*)\}//g;
|
||||
|
||||
@@ -238,14 +238,6 @@ The following abbreviations are recognized:
|
||||
480x320
|
||||
@item qhd
|
||||
960x540
|
||||
@item 2kdci
|
||||
2048x1080
|
||||
@item 4kdci
|
||||
4096x2160
|
||||
@item uhd2160
|
||||
3840x2160
|
||||
@item uhd4320
|
||||
7680x4320
|
||||
@end table
|
||||
|
||||
@anchor{video rate syntax}
|
||||
|
||||
@@ -420,4 +420,4 @@ done:
|
||||
|
||||
When all of this is done, you can submit your patch to the ffmpeg-devel
|
||||
mailing-list for review. If you need any help, feel free to come on our IRC
|
||||
channel, #ffmpeg-devel on irc.libera.chat.
|
||||
channel, #ffmpeg-devel on irc.freenode.net.
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
#include "libavutil/parseutils.h"
|
||||
#include "libavutil/samplefmt.h"
|
||||
#include "libavutil/fifo.h"
|
||||
#include "libavutil/internal.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/dict.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
@@ -80,10 +79,6 @@
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#endif
|
||||
#if HAVE_SETCONSOLECTRLHANDLER
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
@@ -137,6 +132,8 @@ AVIOContext *progress_avio = NULL;
|
||||
|
||||
static uint8_t *subtitle_out;
|
||||
|
||||
#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
|
||||
|
||||
InputStream **input_streams = NULL;
|
||||
int nb_input_streams = 0;
|
||||
InputFile **input_files = NULL;
|
||||
@@ -172,8 +169,8 @@ static int sub2video_get_blank_frame(InputStream *ist)
|
||||
AVFrame *frame = ist->sub2video.frame;
|
||||
|
||||
av_frame_unref(frame);
|
||||
ist->sub2video.frame->width = ist->dec_ctx->width ? ist->dec_ctx->width : ist->sub2video.w;
|
||||
ist->sub2video.frame->height = ist->dec_ctx->height ? ist->dec_ctx->height : ist->sub2video.h;
|
||||
ist->sub2video.frame->width = ist->sub2video.w;
|
||||
ist->sub2video.frame->height = ist->sub2video.h;
|
||||
ist->sub2video.frame->format = AV_PIX_FMT_RGB32;
|
||||
if ((ret = av_frame_get_buffer(frame, 32)) < 0)
|
||||
return ret;
|
||||
@@ -193,9 +190,7 @@ static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h,
|
||||
return;
|
||||
}
|
||||
if (r->x < 0 || r->x + r->w > w || r->y < 0 || r->y + r->h > h) {
|
||||
av_log(NULL, AV_LOG_WARNING, "sub2video: rectangle (%d %d %d %d) overflowing %d %d\n",
|
||||
r->x, r->y, r->w, r->h, w, h
|
||||
);
|
||||
av_log(NULL, AV_LOG_WARNING, "sub2video: rectangle overflowing\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -227,6 +222,7 @@ static void sub2video_push_ref(InputStream *ist, int64_t pts)
|
||||
|
||||
static void sub2video_update(InputStream *ist, AVSubtitle *sub)
|
||||
{
|
||||
int w = ist->sub2video.w, h = ist->sub2video.h;
|
||||
AVFrame *frame = ist->sub2video.frame;
|
||||
int8_t *dst;
|
||||
int dst_linesize;
|
||||
@@ -254,7 +250,7 @@ static void sub2video_update(InputStream *ist, AVSubtitle *sub)
|
||||
dst = frame->data [0];
|
||||
dst_linesize = frame->linesize[0];
|
||||
for (i = 0; i < num_rects; i++)
|
||||
sub2video_copy_rect(dst, dst_linesize, frame->width, frame->height, sub->rects[i]);
|
||||
sub2video_copy_rect(dst, dst_linesize, w, h, sub->rects[i]);
|
||||
sub2video_push_ref(ist, pts);
|
||||
ist->sub2video.end_pts = end_pts;
|
||||
}
|
||||
@@ -295,7 +291,7 @@ static void sub2video_flush(InputStream *ist)
|
||||
if (ist->sub2video.end_pts < INT64_MAX)
|
||||
sub2video_update(ist, NULL);
|
||||
for (i = 0; i < ist->nb_filters; i++)
|
||||
av_buffersrc_add_frame(ist->filters[i]->filter, NULL);
|
||||
av_buffersrc_add_ref(ist->filters[i]->filter, NULL, 0);
|
||||
}
|
||||
|
||||
/* end of sub2video hack */
|
||||
@@ -317,7 +313,6 @@ void term_exit(void)
|
||||
static volatile int received_sigterm = 0;
|
||||
static volatile int received_nb_signals = 0;
|
||||
static volatile int transcode_init_done = 0;
|
||||
static volatile int ffmpeg_exited = 0;
|
||||
static int main_return_code = 0;
|
||||
|
||||
static void
|
||||
@@ -326,46 +321,10 @@ sigterm_handler(int sig)
|
||||
received_sigterm = sig;
|
||||
received_nb_signals++;
|
||||
term_exit_sigsafe();
|
||||
if(received_nb_signals > 3) {
|
||||
write(2/*STDERR_FILENO*/, "Received > 3 system signals, hard exiting\n",
|
||||
strlen("Received > 3 system signals, hard exiting\n"));
|
||||
|
||||
if(received_nb_signals > 3)
|
||||
exit(123);
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_SETCONSOLECTRLHANDLER
|
||||
static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
|
||||
{
|
||||
av_log(NULL, AV_LOG_DEBUG, "\nReceived windows signal %ld\n", fdwCtrlType);
|
||||
|
||||
switch (fdwCtrlType)
|
||||
{
|
||||
case CTRL_C_EVENT:
|
||||
case CTRL_BREAK_EVENT:
|
||||
sigterm_handler(SIGINT);
|
||||
return TRUE;
|
||||
|
||||
case CTRL_CLOSE_EVENT:
|
||||
case CTRL_LOGOFF_EVENT:
|
||||
case CTRL_SHUTDOWN_EVENT:
|
||||
sigterm_handler(SIGTERM);
|
||||
/* Basically, with these 3 events, when we return from this method the
|
||||
process is hard terminated, so stall as long as we need to
|
||||
to try and let the main thread(s) clean up and gracefully terminate
|
||||
(we have at most 5 seconds, but should be done far before that). */
|
||||
while (!ffmpeg_exited) {
|
||||
Sleep(0);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
av_log(NULL, AV_LOG_ERROR, "Received unknown windows signal %ld\n", fdwCtrlType);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void term_init(void)
|
||||
{
|
||||
#if HAVE_TERMIOS_H
|
||||
@@ -399,9 +358,6 @@ void term_init(void)
|
||||
#ifdef SIGXCPU
|
||||
signal(SIGXCPU, sigterm_handler);
|
||||
#endif
|
||||
#if HAVE_SETCONSOLECTRLHANDLER
|
||||
SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* read a key without blocking */
|
||||
@@ -435,6 +391,10 @@ static int read_key(void)
|
||||
is_pipe = !GetConsoleMode(input_handle, &dw);
|
||||
}
|
||||
|
||||
if (stdin->_cnt > 0) {
|
||||
read(0, &ch, 1);
|
||||
return ch;
|
||||
}
|
||||
if (is_pipe) {
|
||||
/* When running under a GUI, you will end here. */
|
||||
if (!PeekNamedPipe(input_handle, NULL, 0, NULL, &nchars, NULL)) {
|
||||
@@ -469,7 +429,7 @@ static void ffmpeg_cleanup(int ret)
|
||||
|
||||
if (do_benchmark) {
|
||||
int maxrss = getmaxrss() / 1024;
|
||||
av_log(NULL, AV_LOG_INFO, "bench: maxrss=%ikB\n", maxrss);
|
||||
printf("bench: maxrss=%ikB\n", maxrss);
|
||||
}
|
||||
|
||||
for (i = 0; i < nb_filtergraphs; i++) {
|
||||
@@ -575,13 +535,12 @@ static void ffmpeg_cleanup(int ret)
|
||||
avformat_network_deinit();
|
||||
|
||||
if (received_sigterm) {
|
||||
av_log(NULL, AV_LOG_INFO, "Exiting normally, received signal %d.\n",
|
||||
av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n",
|
||||
(int) received_sigterm);
|
||||
} else if (ret && transcode_init_done) {
|
||||
av_log(NULL, AV_LOG_INFO, "Conversion failed!\n");
|
||||
}
|
||||
term_exit();
|
||||
ffmpeg_exited = 1;
|
||||
}
|
||||
|
||||
void remove_avoptions(AVDictionary **a, AVDictionary *b)
|
||||
@@ -618,7 +577,7 @@ static void update_benchmark(const char *fmt, ...)
|
||||
va_start(va, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, va);
|
||||
va_end(va);
|
||||
av_log(NULL, AV_LOG_INFO, "bench: %8"PRIu64" %s \n", t - current_time, buf);
|
||||
printf("bench: %8"PRIu64" %s \n", t - current_time, buf);
|
||||
}
|
||||
current_time = t;
|
||||
}
|
||||
@@ -640,7 +599,7 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
|
||||
int ret;
|
||||
|
||||
if (!ost->st->codec->extradata_size && ost->enc_ctx->extradata_size) {
|
||||
ost->st->codec->extradata = av_mallocz(ost->enc_ctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
ost->st->codec->extradata = av_mallocz(ost->enc_ctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (ost->st->codec->extradata) {
|
||||
memcpy(ost->st->codec->extradata, ost->enc_ctx->extradata, ost->enc_ctx->extradata_size);
|
||||
ost->st->codec->extradata_size = ost->enc_ctx->extradata_size;
|
||||
@@ -665,20 +624,6 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
|
||||
}
|
||||
ost->frame_number++;
|
||||
}
|
||||
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
int i;
|
||||
uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,
|
||||
NULL);
|
||||
ost->quality = sd ? AV_RL32(sd) : -1;
|
||||
ost->pict_type = sd ? sd[4] : AV_PICTURE_TYPE_NONE;
|
||||
|
||||
for (i = 0; i<FF_ARRAY_ELEMS(ost->error); i++) {
|
||||
if (sd && i < sd[5])
|
||||
ost->error[i] = AV_RL64(sd + 8 + 8*i);
|
||||
else
|
||||
ost->error[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (bsfc)
|
||||
av_packet_split_side_data(pkt);
|
||||
@@ -693,17 +638,11 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
|
||||
&new_pkt.data, &new_pkt.size,
|
||||
pkt->data, pkt->size,
|
||||
pkt->flags & AV_PKT_FLAG_KEY);
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
if(a == 0 && new_pkt.data != pkt->data
|
||||
#if FF_API_DESTRUCT_PACKET
|
||||
&& new_pkt.destruct
|
||||
#endif
|
||||
) {
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
uint8_t *t = av_malloc(new_pkt.size + AV_INPUT_BUFFER_PADDING_SIZE); //the new should be a subset of the old so cannot overflow
|
||||
if(a == 0 && new_pkt.data != pkt->data && new_pkt.destruct) {
|
||||
uint8_t *t = av_malloc(new_pkt.size + FF_INPUT_BUFFER_PADDING_SIZE); //the new should be a subset of the old so cannot overflow
|
||||
if(t) {
|
||||
memcpy(t, new_pkt.data, new_pkt.size);
|
||||
memset(t + new_pkt.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
memset(t + new_pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
new_pkt.data = t;
|
||||
new_pkt.buf = NULL;
|
||||
a = 1;
|
||||
@@ -1131,7 +1070,7 @@ static void do_video_out(AVFormatContext *s,
|
||||
int got_packet, forced_keyframe = 0;
|
||||
double pts_time;
|
||||
|
||||
if (enc->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME) &&
|
||||
if (enc->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME) &&
|
||||
ost->top_field_first >= 0)
|
||||
in_picture->top_field_first = !!ost->top_field_first;
|
||||
|
||||
@@ -1157,7 +1096,7 @@ static void do_video_out(AVFormatContext *s,
|
||||
ost->forced_keyframes_expr_const_values[FKF_T] = pts_time;
|
||||
res = av_expr_eval(ost->forced_keyframes_pexpr,
|
||||
ost->forced_keyframes_expr_const_values, NULL);
|
||||
ff_dlog(NULL, "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n",
|
||||
av_dlog(NULL, "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n",
|
||||
ost->forced_keyframes_expr_const_values[FKF_N],
|
||||
ost->forced_keyframes_expr_const_values[FKF_N_FORCED],
|
||||
ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N],
|
||||
@@ -1210,7 +1149,7 @@ static void do_video_out(AVFormatContext *s,
|
||||
av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &enc->time_base));
|
||||
}
|
||||
|
||||
if (pkt.pts == AV_NOPTS_VALUE && !(enc->codec->capabilities & AV_CODEC_CAP_DELAY))
|
||||
if (pkt.pts == AV_NOPTS_VALUE && !(enc->codec->capabilities & CODEC_CAP_DELAY))
|
||||
pkt.pts = ost->sync_opts;
|
||||
|
||||
av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base);
|
||||
@@ -1275,11 +1214,9 @@ static void do_video_stats(OutputStream *ost, int frame_size)
|
||||
enc = ost->enc_ctx;
|
||||
if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
frame_number = ost->st->nb_frames;
|
||||
fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number,
|
||||
ost->quality / (float)FF_QP2LAMBDA);
|
||||
|
||||
if (ost->error[0]>=0 && (enc->flags & AV_CODEC_FLAG_PSNR))
|
||||
fprintf(vstats_file, "PSNR= %6.2f ", psnr(ost->error[0] / (enc->width * enc->height * 255.0 * 255.0)));
|
||||
fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, enc->coded_frame ? enc->coded_frame->quality / (float)FF_QP2LAMBDA : 0);
|
||||
if (enc->coded_frame && (enc->flags&CODEC_FLAG_PSNR))
|
||||
fprintf(vstats_file, "PSNR= %6.2f ", psnr(enc->coded_frame->error[0] / (enc->width * enc->height * 255.0 * 255.0)));
|
||||
|
||||
fprintf(vstats_file,"f_size= %6d ", frame_size);
|
||||
/* compute pts value */
|
||||
@@ -1291,7 +1228,7 @@ static void do_video_stats(OutputStream *ost, int frame_size)
|
||||
avg_bitrate = (double)(ost->data_size * 8) / ti1 / 1000.0;
|
||||
fprintf(vstats_file, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ",
|
||||
(double)ost->data_size / 1024, ti1, bitrate, avg_bitrate);
|
||||
fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(ost->pict_type));
|
||||
fprintf(vstats_file, "type= %c\n", enc->coded_frame ? av_get_picture_type_char(enc->coded_frame->pict_type) : 'I');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1389,7 +1326,7 @@ static int reap_filters(int flush)
|
||||
do_video_out(of->ctx, ost, filtered_frame, float_pts);
|
||||
break;
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
if (!(enc->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE) &&
|
||||
if (!(enc->codec->capabilities & CODEC_CAP_PARAM_CHANGE) &&
|
||||
enc->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");
|
||||
@@ -1428,8 +1365,8 @@ static void print_final_stats(int64_t total_size)
|
||||
}
|
||||
extra_size += ost->enc_ctx->extradata_size;
|
||||
data_size += ost->data_size;
|
||||
if ( (ost->enc_ctx->flags & (AV_CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))
|
||||
!= AV_CODEC_FLAG_PASS1)
|
||||
if ( (ost->enc_ctx->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))
|
||||
!= CODEC_FLAG_PASS1)
|
||||
pass1_used = 0;
|
||||
}
|
||||
|
||||
@@ -1568,9 +1505,8 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
||||
float q = -1;
|
||||
ost = output_streams[i];
|
||||
enc = ost->enc_ctx;
|
||||
if (!ost->stream_copy)
|
||||
q = ost->quality / (float) FF_QP2LAMBDA;
|
||||
|
||||
if (!ost->stream_copy && enc->coded_frame)
|
||||
q = enc->coded_frame->quality / (float)FF_QP2LAMBDA;
|
||||
if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q);
|
||||
av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
|
||||
@@ -1597,8 +1533,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
||||
for (j = 0; j < 32; j++)
|
||||
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X", (int)lrintf(log2(qp_histogram[j] + 1)));
|
||||
}
|
||||
|
||||
if ((enc->flags & AV_CODEC_FLAG_PSNR) && (ost->pict_type != AV_PICTURE_TYPE_NONE || is_last_report)) {
|
||||
if ((enc->flags&CODEC_FLAG_PSNR) && (enc->coded_frame || is_last_report)) {
|
||||
int j;
|
||||
double error, error_sum = 0;
|
||||
double scale, scale_sum = 0;
|
||||
@@ -1610,7 +1545,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
||||
error = enc->error[j];
|
||||
scale = enc->width * enc->height * 255.0 * 255.0 * frame_number;
|
||||
} else {
|
||||
error = ost->error[j];
|
||||
error = enc->coded_frame->error[j];
|
||||
scale = enc->width * enc->height * 255.0 * 255.0;
|
||||
}
|
||||
if (j)
|
||||
@@ -1749,9 +1684,7 @@ static void flush_encoders(void)
|
||||
ret = encode(enc, &pkt, NULL, &got_packet);
|
||||
update_benchmark("flush %s %d.%d", desc, ost->file_index, ost->index);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "%s encoding failed: %s\n",
|
||||
desc,
|
||||
av_err2str(ret));
|
||||
av_log(NULL, AV_LOG_FATAL, "%s encoding failed\n", desc);
|
||||
exit_program(1);
|
||||
}
|
||||
if (ost->logfile && enc->stats_out) {
|
||||
@@ -1878,8 +1811,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
|
||||
pkt->data, pkt->size,
|
||||
pkt->flags & AV_PKT_FLAG_KEY);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "av_parser_change failed: %s\n",
|
||||
av_err2str(ret));
|
||||
av_log(NULL, AV_LOG_FATAL, "av_parser_change failed\n");
|
||||
exit_program(1);
|
||||
}
|
||||
if (ret) {
|
||||
@@ -1899,8 +1831,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
|
||||
/* store AVPicture in AVPacket, as expected by the output format */
|
||||
int ret = avpicture_fill(&pict, opkt.data, ost->st->codec->pix_fmt, ost->st->codec->width, ost->st->codec->height);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "avpicture_fill failed: %s\n",
|
||||
av_err2str(ret));
|
||||
av_log(NULL, AV_LOG_FATAL, "avpicture_fill failed\n");
|
||||
exit_program(1);
|
||||
}
|
||||
opkt.data = (uint8_t *)&pict;
|
||||
@@ -1959,8 +1890,17 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
|
||||
if (ret < 0 && exit_on_error)
|
||||
exit_program(1);
|
||||
|
||||
if (!*got_output || ret < 0)
|
||||
if (!*got_output || ret < 0) {
|
||||
if (!pkt->size) {
|
||||
for (i = 0; i < ist->nb_filters; i++)
|
||||
#if 1
|
||||
av_buffersrc_add_ref(ist->filters[i]->filter, NULL, 0);
|
||||
#else
|
||||
av_buffersrc_add_frame(ist->filters[i]->filter, NULL);
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ist->samples_decoded += decoded_frame->nb_samples;
|
||||
ist->frames_decoded++;
|
||||
@@ -2084,13 +2024,12 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
|
||||
if (ist->dec_ctx->codec_id == AV_CODEC_ID_H264) {
|
||||
ist->st->codec->has_b_frames = ist->dec_ctx->has_b_frames;
|
||||
} else
|
||||
av_log(ist->dec_ctx, AV_LOG_WARNING,
|
||||
"has_b_frames is larger in decoder than demuxer %d > %d.\n"
|
||||
"If you want to help, upload a sample "
|
||||
"of this file to ftp://upload.ffmpeg.org/incoming/ "
|
||||
"and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)",
|
||||
ist->dec_ctx->has_b_frames,
|
||||
ist->st->codec->has_b_frames);
|
||||
av_log_ask_for_sample(
|
||||
ist->dec_ctx,
|
||||
"has_b_frames is larger in decoder than demuxer %d > %d ",
|
||||
ist->dec_ctx->has_b_frames,
|
||||
ist->st->codec->has_b_frames
|
||||
);
|
||||
}
|
||||
|
||||
if (*got_output || ret<0)
|
||||
@@ -2113,8 +2052,17 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
|
||||
}
|
||||
}
|
||||
|
||||
if (!*got_output || ret < 0)
|
||||
if (!*got_output || ret < 0) {
|
||||
if (!pkt->size) {
|
||||
for (i = 0; i < ist->nb_filters; i++)
|
||||
#if 1
|
||||
av_buffersrc_add_ref(ist->filters[i]->filter, NULL, 0);
|
||||
#else
|
||||
av_buffersrc_add_frame(ist->filters[i]->filter, NULL);
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(ist->top_field_first>=0)
|
||||
decoded_frame->top_field_first = ist->top_field_first;
|
||||
@@ -2262,17 +2210,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int send_filter_eof(InputStream *ist)
|
||||
{
|
||||
int i, ret;
|
||||
for (i = 0; i < ist->nb_filters; i++) {
|
||||
ret = av_buffersrc_add_frame(ist->filters[i]->filter, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* pkt = NULL means EOF (needed to flush decoder buffers) */
|
||||
static int process_input_packet(InputStream *ist, const AVPacket *pkt)
|
||||
{
|
||||
@@ -2320,7 +2257,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt)
|
||||
ist->dts = ist->next_dts;
|
||||
|
||||
if (avpkt.size && avpkt.size != pkt->size &&
|
||||
!(ist->dec->capabilities & AV_CODEC_CAP_SUBFRAMES)) {
|
||||
!(ist->dec->capabilities & CODEC_CAP_SUBFRAMES)) {
|
||||
av_log(NULL, ist->showed_multi_packet_warning ? AV_LOG_VERBOSE : AV_LOG_WARNING,
|
||||
"Multiple frames in a packet from stream %d\n", pkt->stream_index);
|
||||
ist->showed_multi_packet_warning = 1;
|
||||
@@ -2357,13 +2294,8 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d: %s\n",
|
||||
ist->file_index, ist->st->index, av_err2str(ret));
|
||||
if (exit_on_error)
|
||||
exit_program(1);
|
||||
break;
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
avpkt.dts=
|
||||
avpkt.pts= AV_NOPTS_VALUE;
|
||||
@@ -2382,26 +2314,13 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt)
|
||||
break;
|
||||
}
|
||||
|
||||
/* after flushing, send an EOF on all the filter inputs attached to the stream */
|
||||
if (!pkt && ist->decoding_needed && !got_output) {
|
||||
int ret = send_filter_eof(ist);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Error marking filters as finished\n");
|
||||
exit_program(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* handle stream copy */
|
||||
if (!ist->decoding_needed) {
|
||||
ist->dts = ist->next_dts;
|
||||
switch (ist->dec_ctx->codec_type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
if (ist->dec_ctx->sample_rate) {
|
||||
ist->next_dts += ((int64_t)AV_TIME_BASE * ist->dec_ctx->frame_size) /
|
||||
ist->dec_ctx->sample_rate;
|
||||
} else {
|
||||
ist->next_dts += av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);
|
||||
}
|
||||
ist->next_dts += ((int64_t)AV_TIME_BASE * ist->dec_ctx->frame_size) /
|
||||
ist->dec_ctx->sample_rate;
|
||||
break;
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
if (ist->framerate.num) {
|
||||
@@ -2590,76 +2509,6 @@ static int compare_int64(const void *a, const void *b)
|
||||
return va < vb ? -1 : va > vb ? +1 : 0;
|
||||
}
|
||||
|
||||
static int init_output_stream(OutputStream *ost, char *error, int error_len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (ost->encoding_needed) {
|
||||
AVCodec *codec = ost->enc;
|
||||
AVCodecContext *dec = NULL;
|
||||
InputStream *ist;
|
||||
|
||||
if ((ist = get_input_stream(ost)))
|
||||
dec = ist->dec_ctx;
|
||||
if (dec && dec->subtitle_header) {
|
||||
/* ASS code assumes this buffer is null terminated so add extra byte. */
|
||||
ost->enc_ctx->subtitle_header = av_mallocz(dec->subtitle_header_size + 1);
|
||||
if (!ost->enc_ctx->subtitle_header)
|
||||
return AVERROR(ENOMEM);
|
||||
memcpy(ost->enc_ctx->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);
|
||||
ost->enc_ctx->subtitle_header_size = dec->subtitle_header_size;
|
||||
}
|
||||
if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0))
|
||||
av_dict_set(&ost->encoder_opts, "threads", "auto", 0);
|
||||
av_dict_set(&ost->encoder_opts, "side_data_only_packets", "1", 0);
|
||||
if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
|
||||
!codec->defaults &&
|
||||
!av_dict_get(ost->encoder_opts, "b", NULL, 0) &&
|
||||
!av_dict_get(ost->encoder_opts, "ab", NULL, 0))
|
||||
av_dict_set(&ost->encoder_opts, "b", "128000", 0);
|
||||
|
||||
if ((ret = avcodec_open2(ost->enc_ctx, codec, &ost->encoder_opts)) < 0) {
|
||||
if (ret == AVERROR_EXPERIMENTAL)
|
||||
abort_codec_experimental(codec, 1);
|
||||
snprintf(error, error_len,
|
||||
"Error while opening encoder for output stream #%d:%d - "
|
||||
"maybe incorrect parameters such as bit_rate, rate, width or height",
|
||||
ost->file_index, ost->index);
|
||||
return ret;
|
||||
}
|
||||
if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
|
||||
!(ost->enc->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE))
|
||||
av_buffersink_set_frame_size(ost->filter->filter,
|
||||
ost->enc_ctx->frame_size);
|
||||
assert_avoptions(ost->encoder_opts);
|
||||
if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000)
|
||||
av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
|
||||
" It takes bits/s as argument, not kbits/s\n");
|
||||
|
||||
ret = avcodec_copy_context(ost->st->codec, ost->enc_ctx);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL,
|
||||
"Error initializing the output stream codec context.\n");
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
// copy timebase while removing common factors
|
||||
ost->st->time_base = av_add_q(ost->enc_ctx->time_base, (AVRational){0, 1});
|
||||
ost->st->codec->codec= ost->enc_ctx->codec;
|
||||
} else {
|
||||
ret = av_opt_set_dict(ost->enc_ctx, &ost->encoder_opts);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL,
|
||||
"Error setting up codec context options.\n");
|
||||
return ret;
|
||||
}
|
||||
// copy timebase while removing common factors
|
||||
ost->st->time_base = av_add_q(ost->st->codec->time_base, (AVRational){0, 1});
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void parse_forced_key_frames(char *kf, OutputStream *ost,
|
||||
AVCodecContext *avctx)
|
||||
{
|
||||
@@ -2770,7 +2619,7 @@ static void set_encoder_id(OutputFile *of, OutputStream *ost)
|
||||
if (!encoder_string)
|
||||
exit_program(1);
|
||||
|
||||
if (!(format_flags & AVFMT_FLAG_BITEXACT) && !(codec_flags & AV_CODEC_FLAG_BITEXACT))
|
||||
if (!(format_flags & AVFMT_FLAG_BITEXACT) && !(codec_flags & CODEC_FLAG_BITEXACT))
|
||||
av_strlcpy(encoder_string, LIBAVCODEC_IDENT " ", encoder_string_len);
|
||||
else
|
||||
av_strlcpy(encoder_string, "Lavc ", encoder_string_len);
|
||||
@@ -2811,6 +2660,21 @@ static int transcode_init(void)
|
||||
input_streams[j + ifile->ist_index]->start = av_gettime_relative();
|
||||
}
|
||||
|
||||
/* output stream init */
|
||||
for (i = 0; i < nb_output_files; i++) {
|
||||
oc = output_files[i]->ctx;
|
||||
if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
|
||||
av_dump_format(oc, i, oc->filename, 1);
|
||||
av_log(NULL, AV_LOG_ERROR, "Output file #%d does not contain any stream\n", i);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* init complex filtergraphs */
|
||||
for (i = 0; i < nb_filtergraphs; i++)
|
||||
if ((ret = avfilter_graph_config(filtergraphs[i]->graph, NULL)) < 0)
|
||||
return ret;
|
||||
|
||||
/* for each output stream, we compute the right encoding parameters */
|
||||
for (i = 0; i < nb_output_streams; i++) {
|
||||
AVCodecContext *enc_ctx;
|
||||
@@ -2847,7 +2711,7 @@ static int transcode_init(void)
|
||||
|
||||
av_assert0(ist && !ost->filter);
|
||||
|
||||
extra_size = (uint64_t)dec_ctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE;
|
||||
extra_size = (uint64_t)dec_ctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;
|
||||
|
||||
if (extra_size > INT_MAX) {
|
||||
return AVERROR(EINVAL);
|
||||
@@ -2886,8 +2750,7 @@ static int transcode_init(void)
|
||||
* overhead
|
||||
*/
|
||||
if(!strcmp(oc->oformat->name, "avi")) {
|
||||
if ( copy_tb<0 && ist->st->r_frame_rate.num
|
||||
&& av_q2d(ist->st->r_frame_rate) >= av_q2d(ist->st->avg_frame_rate)
|
||||
if ( copy_tb<0 && av_q2d(ist->st->r_frame_rate) >= av_q2d(ist->st->avg_frame_rate)
|
||||
&& 0.5/av_q2d(ist->st->r_frame_rate) > av_q2d(ist->st->time_base)
|
||||
&& 0.5/av_q2d(ist->st->r_frame_rate) > av_q2d(dec_ctx->time_base)
|
||||
&& av_q2d(ist->st->time_base) < 1.0/500 && av_q2d(dec_ctx->time_base) < 1.0/500
|
||||
@@ -2923,7 +2786,7 @@ static int transcode_init(void)
|
||||
enc_ctx->time_base = dec_ctx->time_base;
|
||||
}
|
||||
|
||||
if (!ost->frame_rate.num)
|
||||
if (ist && !ost->frame_rate.num)
|
||||
ost->frame_rate = ist->framerate;
|
||||
if(ost->frame_rate.num)
|
||||
enc_ctx->time_base = av_inv_q(ost->frame_rate);
|
||||
@@ -3020,6 +2883,10 @@ static int transcode_init(void)
|
||||
goto dump_format;
|
||||
}
|
||||
|
||||
if (ist)
|
||||
ist->decoding_needed |= DECODING_FOR_OST;
|
||||
ost->encoding_needed = 1;
|
||||
|
||||
set_encoder_id(output_files[ost->file_index], ost);
|
||||
|
||||
if (!ost->filter &&
|
||||
@@ -3148,6 +3015,39 @@ static int transcode_init(void)
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
/* two pass mode */
|
||||
if (enc_ctx->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2)) {
|
||||
char logfilename[1024];
|
||||
FILE *f;
|
||||
|
||||
snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
|
||||
ost->logfile_prefix ? ost->logfile_prefix :
|
||||
DEFAULT_PASS_LOGFILENAME_PREFIX,
|
||||
i);
|
||||
if (!strcmp(ost->enc->name, "libx264")) {
|
||||
av_dict_set(&ost->encoder_opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
|
||||
} else {
|
||||
if (enc_ctx->flags & CODEC_FLAG_PASS2) {
|
||||
char *logbuffer;
|
||||
size_t logbuffer_size;
|
||||
if (cmdutils_read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
|
||||
logfilename);
|
||||
exit_program(1);
|
||||
}
|
||||
enc_ctx->stats_in = logbuffer;
|
||||
}
|
||||
if (enc_ctx->flags & CODEC_FLAG_PASS1) {
|
||||
f = av_fopen_utf8(logfilename, "wb");
|
||||
if (!f) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n",
|
||||
logfilename, strerror(errno));
|
||||
exit_program(1);
|
||||
}
|
||||
ost->logfile = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ost->disposition) {
|
||||
@@ -3184,9 +3084,63 @@ static int transcode_init(void)
|
||||
|
||||
/* open each encoder */
|
||||
for (i = 0; i < nb_output_streams; i++) {
|
||||
ret = init_output_stream(output_streams[i], error, sizeof(error));
|
||||
if (ret < 0)
|
||||
goto dump_format;
|
||||
ost = output_streams[i];
|
||||
if (ost->encoding_needed) {
|
||||
AVCodec *codec = ost->enc;
|
||||
AVCodecContext *dec = NULL;
|
||||
|
||||
if ((ist = get_input_stream(ost)))
|
||||
dec = ist->dec_ctx;
|
||||
if (dec && dec->subtitle_header) {
|
||||
/* ASS code assumes this buffer is null terminated so add extra byte. */
|
||||
ost->enc_ctx->subtitle_header = av_mallocz(dec->subtitle_header_size + 1);
|
||||
if (!ost->enc_ctx->subtitle_header) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto dump_format;
|
||||
}
|
||||
memcpy(ost->enc_ctx->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);
|
||||
ost->enc_ctx->subtitle_header_size = dec->subtitle_header_size;
|
||||
}
|
||||
if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0))
|
||||
av_dict_set(&ost->encoder_opts, "threads", "auto", 0);
|
||||
av_dict_set(&ost->encoder_opts, "side_data_only_packets", "1", 0);
|
||||
|
||||
if ((ret = avcodec_open2(ost->enc_ctx, codec, &ost->encoder_opts)) < 0) {
|
||||
if (ret == AVERROR_EXPERIMENTAL)
|
||||
abort_codec_experimental(codec, 1);
|
||||
snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d:%d - maybe incorrect parameters such as bit_rate, rate, width or height",
|
||||
ost->file_index, ost->index);
|
||||
goto dump_format;
|
||||
}
|
||||
if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
|
||||
!(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE))
|
||||
av_buffersink_set_frame_size(ost->filter->filter,
|
||||
ost->enc_ctx->frame_size);
|
||||
assert_avoptions(ost->encoder_opts);
|
||||
if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000)
|
||||
av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
|
||||
" It takes bits/s as argument, not kbits/s\n");
|
||||
|
||||
ret = avcodec_copy_context(ost->st->codec, ost->enc_ctx);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL,
|
||||
"Error initializing the output stream codec context.\n");
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
// copy timebase while removing common factors
|
||||
ost->st->time_base = av_add_q(ost->enc_ctx->time_base, (AVRational){0, 1});
|
||||
ost->st->codec->codec= ost->enc_ctx->codec;
|
||||
} else {
|
||||
ret = av_opt_set_dict(ost->enc_ctx, &ost->encoder_opts);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL,
|
||||
"Error setting up codec context options.\n");
|
||||
return ret;
|
||||
}
|
||||
// copy timebase while removing common factors
|
||||
ost->st->time_base = av_add_q(ost->st->codec->time_base, (AVRational){0, 1});
|
||||
}
|
||||
}
|
||||
|
||||
/* init input streams */
|
||||
@@ -3456,17 +3410,9 @@ static int check_keyboard_interaction(int64_t cur_time)
|
||||
if(!debug) debug = 1;
|
||||
while(debug & (FF_DEBUG_DCT_COEFF|FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) //unsupported, would just crash
|
||||
debug += debug;
|
||||
}else{
|
||||
char buf[32];
|
||||
int k = 0;
|
||||
i = 0;
|
||||
while ((k = read_key()) != '\n' && k != '\r' && i < sizeof(buf)-1)
|
||||
if (k > 0)
|
||||
buf[i++] = k;
|
||||
buf[i] = 0;
|
||||
if (k <= 0 || sscanf(buf, "%d", &debug)!=1)
|
||||
}else
|
||||
if(scanf("%d", &debug)!=1)
|
||||
fprintf(stderr,"error parsing debug value\n");
|
||||
}
|
||||
for(i=0;i<nb_input_streams;i++) {
|
||||
input_streams[i]->st->codec->debug = debug;
|
||||
}
|
||||
@@ -3544,7 +3490,7 @@ static void free_input_threads(void)
|
||||
InputFile *f = input_files[i];
|
||||
AVPacket pkt;
|
||||
|
||||
if (!f || !f->in_thread_queue)
|
||||
if (!f->in_thread_queue)
|
||||
continue;
|
||||
av_thread_message_queue_set_err_send(f->in_thread_queue, AVERROR_EOF);
|
||||
while (av_thread_message_queue_recv(f->in_thread_queue, &pkt, 0) >= 0)
|
||||
@@ -3847,7 +3793,13 @@ static int process_input(int file_index)
|
||||
|
||||
sub2video_heartbeat(ist, pkt.pts);
|
||||
|
||||
process_input_packet(ist, &pkt);
|
||||
ret = process_input_packet(ist, &pkt);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d: %s\n",
|
||||
ist->file_index, ist->st->index, av_err2str(ret));
|
||||
if (exit_on_error)
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
discard_packet:
|
||||
av_free_packet(&pkt);
|
||||
@@ -4066,7 +4018,6 @@ static int transcode(void)
|
||||
av_freep(&ost->apad);
|
||||
av_freep(&ost->disposition);
|
||||
av_dict_free(&ost->encoder_opts);
|
||||
av_dict_free(&ost->sws_dict);
|
||||
av_dict_free(&ost->swr_opts);
|
||||
av_dict_free(&ost->resample_opts);
|
||||
av_dict_free(&ost->bsf_args);
|
||||
@@ -4122,8 +4073,6 @@ int main(int argc, char **argv)
|
||||
int ret;
|
||||
int64_t ti;
|
||||
|
||||
init_dynload();
|
||||
|
||||
register_exit(ffmpeg_cleanup);
|
||||
|
||||
setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
|
||||
@@ -4177,7 +4126,7 @@ int main(int argc, char **argv)
|
||||
exit_program(1);
|
||||
ti = getutime() - ti;
|
||||
if (do_benchmark) {
|
||||
av_log(NULL, AV_LOG_INFO, "bench: utime=%0.3fs\n", ti / 1000000.0);
|
||||
printf("bench: utime=%0.3fs\n", ti / 1000000.0);
|
||||
}
|
||||
av_log(NULL, AV_LOG_DEBUG, "%"PRIu64" frames successfully decoded, %"PRIu64" decoding errors\n",
|
||||
decode_error_stat[0], decode_error_stat[1]);
|
||||
|
||||
@@ -63,7 +63,6 @@ enum HWAccelID {
|
||||
HWACCEL_VDPAU,
|
||||
HWACCEL_DXVA2,
|
||||
HWACCEL_VDA,
|
||||
HWACCEL_VIDEOTOOLBOX,
|
||||
};
|
||||
|
||||
typedef struct HWAccel {
|
||||
@@ -93,7 +92,6 @@ typedef struct OptionsContext {
|
||||
|
||||
/* input/output options */
|
||||
int64_t start_time;
|
||||
int64_t start_time_eof;
|
||||
int seek_timestamp;
|
||||
const char *format;
|
||||
|
||||
@@ -231,7 +229,6 @@ typedef struct OutputFilter {
|
||||
|
||||
/* temporary storage until stream maps are processed */
|
||||
AVFilterInOut *out_tmp;
|
||||
enum AVMediaType type;
|
||||
} OutputFilter;
|
||||
|
||||
typedef struct FilterGraph {
|
||||
@@ -432,8 +429,8 @@ typedef struct OutputStream {
|
||||
char *filters; ///< filtergraph associated to the -filter option
|
||||
char *filters_script; ///< filtergraph script associated to the -filter_script option
|
||||
|
||||
int64_t sws_flags;
|
||||
AVDictionary *encoder_opts;
|
||||
AVDictionary *sws_dict;
|
||||
AVDictionary *swr_opts;
|
||||
AVDictionary *resample_opts;
|
||||
AVDictionary *bsf_args;
|
||||
@@ -458,15 +455,6 @@ typedef struct OutputStream {
|
||||
// number of frames/samples sent to the encoder
|
||||
uint64_t frames_encoded;
|
||||
uint64_t samples_encoded;
|
||||
|
||||
/* packet quality factor */
|
||||
int quality;
|
||||
|
||||
/* packet picture type */
|
||||
int pict_type;
|
||||
|
||||
/* frame encode sum of squared error values */
|
||||
int64_t error[4];
|
||||
} OutputStream;
|
||||
|
||||
typedef struct OutputFile {
|
||||
@@ -521,7 +509,6 @@ extern int frame_bits_per_raw_sample;
|
||||
extern AVIOContext *progress_avio;
|
||||
extern float max_error_rate;
|
||||
extern int vdpau_api_ver;
|
||||
extern char *videotoolbox_pixfmt;
|
||||
|
||||
extern const AVIOInterruptCB int_cb;
|
||||
|
||||
@@ -549,13 +536,11 @@ int configure_filtergraph(FilterGraph *fg);
|
||||
int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out);
|
||||
int ist_in_filtergraph(FilterGraph *fg, InputStream *ist);
|
||||
FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost);
|
||||
int init_complex_filtergraph(FilterGraph *fg);
|
||||
|
||||
int ffmpeg_parse_options(int argc, char **argv);
|
||||
|
||||
int vdpau_init(AVCodecContext *s);
|
||||
int dxva2_init(AVCodecContext *s);
|
||||
int vda_init(AVCodecContext *s);
|
||||
int videotoolbox_init(AVCodecContext *s);
|
||||
|
||||
#endif /* FFMPEG_H */
|
||||
|
||||
+52
-117
@@ -38,28 +38,6 @@
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "libavutil/samplefmt.h"
|
||||
|
||||
|
||||
static const enum AVPixelFormat *get_compliance_unofficial_pix_fmts(enum AVCodecID codec_id, const enum AVPixelFormat default_formats[])
|
||||
{
|
||||
static const enum AVPixelFormat mjpeg_formats[] =
|
||||
{ AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P,
|
||||
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P,
|
||||
AV_PIX_FMT_NONE };
|
||||
static const enum AVPixelFormat ljpeg_formats[] =
|
||||
{ AV_PIX_FMT_BGRA ,
|
||||
AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P,
|
||||
AV_PIX_FMT_YUV420P , AV_PIX_FMT_YUV444P , AV_PIX_FMT_YUV422P,
|
||||
AV_PIX_FMT_NONE};
|
||||
|
||||
if (codec_id == AV_CODEC_ID_MJPEG) {
|
||||
return mjpeg_formats;
|
||||
} else if (codec_id == AV_CODEC_ID_LJPEG) {
|
||||
return ljpeg_formats;
|
||||
} else {
|
||||
return default_formats;
|
||||
}
|
||||
}
|
||||
|
||||
enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCodec *codec, enum AVPixelFormat target)
|
||||
{
|
||||
if (codec && codec->pix_fmts) {
|
||||
@@ -67,9 +45,18 @@ enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCod
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(target);
|
||||
int has_alpha = desc ? desc->nb_components % 2 == 0 : 0;
|
||||
enum AVPixelFormat best= AV_PIX_FMT_NONE;
|
||||
static const enum AVPixelFormat mjpeg_formats[] =
|
||||
{ AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE };
|
||||
static const enum AVPixelFormat ljpeg_formats[] =
|
||||
{ AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUV420P,
|
||||
AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
|
||||
|
||||
if (enc_ctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
|
||||
p = get_compliance_unofficial_pix_fmts(enc_ctx->codec_id, p);
|
||||
if (enc_ctx->codec_id == AV_CODEC_ID_MJPEG) {
|
||||
p = mjpeg_formats;
|
||||
} else if (enc_ctx->codec_id == AV_CODEC_ID_LJPEG) {
|
||||
p =ljpeg_formats;
|
||||
}
|
||||
}
|
||||
for (; *p != AV_PIX_FMT_NONE; p++) {
|
||||
best= avcodec_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL);
|
||||
@@ -98,7 +85,7 @@ void choose_sample_fmt(AVStream *st, AVCodec *codec)
|
||||
break;
|
||||
}
|
||||
if (*p == -1) {
|
||||
if((codec->capabilities & AV_CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codec->sample_fmt) > av_get_sample_fmt_name(codec->sample_fmts[0]))
|
||||
if((codec->capabilities & CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codec->sample_fmt) > av_get_sample_fmt_name(codec->sample_fmts[0]))
|
||||
av_log(NULL, AV_LOG_ERROR, "Conversion will not be lossless.\n");
|
||||
if(av_get_sample_fmt_name(st->codec->sample_fmt))
|
||||
av_log(NULL, AV_LOG_WARNING,
|
||||
@@ -139,7 +126,12 @@ static char *choose_pix_fmts(OutputStream *ost)
|
||||
|
||||
p = ost->enc->pix_fmts;
|
||||
if (ost->enc_ctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
|
||||
p = get_compliance_unofficial_pix_fmts(ost->enc_ctx->codec_id, p);
|
||||
if (ost->enc_ctx->codec_id == AV_CODEC_ID_MJPEG) {
|
||||
p = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE };
|
||||
} else if (ost->enc_ctx->codec_id == AV_CODEC_ID_LJPEG) {
|
||||
p = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUV420P,
|
||||
AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
|
||||
}
|
||||
}
|
||||
|
||||
for (; *p != AV_PIX_FMT_NONE; p++) {
|
||||
@@ -297,45 +289,6 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
|
||||
ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
|
||||
}
|
||||
|
||||
int init_complex_filtergraph(FilterGraph *fg)
|
||||
{
|
||||
AVFilterInOut *inputs, *outputs, *cur;
|
||||
AVFilterGraph *graph;
|
||||
int ret = 0;
|
||||
|
||||
/* this graph is only used for determining the kinds of inputs
|
||||
* and outputs we have, and is discarded on exit from this function */
|
||||
graph = avfilter_graph_alloc();
|
||||
if (!graph)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
ret = avfilter_graph_parse2(graph, fg->graph_desc, &inputs, &outputs);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
for (cur = inputs; cur; cur = cur->next)
|
||||
init_input_filter(fg, cur);
|
||||
|
||||
for (cur = outputs; cur;) {
|
||||
GROW_ARRAY(fg->outputs, fg->nb_outputs);
|
||||
fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0]));
|
||||
if (!fg->outputs[fg->nb_outputs - 1])
|
||||
exit_program(1);
|
||||
|
||||
fg->outputs[fg->nb_outputs - 1]->graph = fg;
|
||||
fg->outputs[fg->nb_outputs - 1]->out_tmp = cur;
|
||||
fg->outputs[fg->nb_outputs - 1]->type = avfilter_pad_get_type(cur->filter_ctx->output_pads,
|
||||
cur->pad_idx);
|
||||
cur = cur->next;
|
||||
fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL;
|
||||
}
|
||||
|
||||
fail:
|
||||
avfilter_inout_free(&inputs);
|
||||
avfilter_graph_free(&graph);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int insert_trim(int64_t start_time, int64_t duration,
|
||||
AVFilterContext **last_filter, int *pad_idx,
|
||||
const char *filter_name)
|
||||
@@ -431,17 +384,11 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
if (codec->width || codec->height) {
|
||||
char args[255];
|
||||
AVFilterContext *filter;
|
||||
AVDictionaryEntry *e = NULL;
|
||||
|
||||
snprintf(args, sizeof(args), "%d:%d",
|
||||
snprintf(args, sizeof(args), "%d:%d:0x%X",
|
||||
codec->width,
|
||||
codec->height);
|
||||
|
||||
while ((e = av_dict_get(ost->sws_dict, "", e,
|
||||
AV_DICT_IGNORE_SUFFIX))) {
|
||||
av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
|
||||
}
|
||||
|
||||
codec->height,
|
||||
(unsigned)ost->sws_flags);
|
||||
snprintf(name, sizeof(name), "scaler for output stream %d:%d",
|
||||
ost->file_index, ost->index);
|
||||
if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
|
||||
@@ -552,7 +499,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
av_get_default_channel_layout(ost->audio_channels_mapped));
|
||||
for (i = 0; i < ost->audio_channels_mapped; i++)
|
||||
if (ost->audio_channels_map[i] != -1)
|
||||
av_bprintf(&pan_buf, "|c%d=c%d", i, ost->audio_channels_map[i]);
|
||||
av_bprintf(&pan_buf, ":c%d=c%d", i, ost->audio_channels_map[i]);
|
||||
|
||||
AUTO_INSERT_FILTER("-map_channel", "pan", pan_buf.str);
|
||||
av_bprint_finalize(&pan_buf, NULL);
|
||||
@@ -655,11 +602,6 @@ int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOu
|
||||
av_freep(&ofilter->name);
|
||||
DESCRIBE_FILTER_LINK(ofilter, out, 0);
|
||||
|
||||
if (!ofilter->ost) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Filter %s has a unconnected output\n", ofilter->name);
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
switch (avfilter_pad_get_type(out->filter_ctx->output_pads, out->pad_idx)) {
|
||||
case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fg, ofilter, out);
|
||||
case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fg, ofilter, out);
|
||||
@@ -690,8 +632,8 @@ static int sub2video_prepare(InputStream *ist)
|
||||
}
|
||||
av_log(avf, AV_LOG_INFO, "sub2video: using %dx%d canvas\n", w, h);
|
||||
}
|
||||
ist->sub2video.w = ist->resample_width = w;
|
||||
ist->sub2video.h = ist->resample_height = h;
|
||||
ist->sub2video.w = ist->dec_ctx->width = ist->resample_width = w;
|
||||
ist->sub2video.h = ist->dec_ctx->height = ist->resample_height = h;
|
||||
|
||||
/* rectangles are AV_PIX_FMT_PAL8, but we have no guarantee that the
|
||||
palettes for all rectangles are identical or compatible */
|
||||
@@ -746,7 +688,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
ist->resample_height,
|
||||
ist->hwaccel_retrieve_data ? ist->hwaccel_retrieved_pix_fmt : ist->resample_pix_fmt,
|
||||
tb.num, tb.den, sar.num, sar.den,
|
||||
SWS_BILINEAR + ((ist->dec_ctx->flags&AV_CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0));
|
||||
SWS_BILINEAR + ((ist->dec_ctx->flags&CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0));
|
||||
if (fr.num && fr.den)
|
||||
av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den);
|
||||
snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
|
||||
@@ -962,7 +904,7 @@ static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
int configure_filtergraph(FilterGraph *fg)
|
||||
{
|
||||
AVFilterInOut *inputs, *outputs, *cur;
|
||||
int ret, i, simple = !fg->graph_desc;
|
||||
int ret, i, init = !fg->graph, simple = !fg->graph_desc;
|
||||
const char *graph_desc = simple ? fg->outputs[0]->ost->avfilter :
|
||||
fg->graph_desc;
|
||||
|
||||
@@ -975,13 +917,7 @@ int configure_filtergraph(FilterGraph *fg)
|
||||
char args[512];
|
||||
AVDictionaryEntry *e = NULL;
|
||||
|
||||
args[0] = 0;
|
||||
while ((e = av_dict_get(ost->sws_dict, "", e,
|
||||
AV_DICT_IGNORE_SUFFIX))) {
|
||||
av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
|
||||
}
|
||||
if (strlen(args))
|
||||
args[strlen(args)-1] = 0;
|
||||
snprintf(args, sizeof(args), "flags=0x%X", (unsigned)ost->sws_flags);
|
||||
fg->graph->scale_sws_opts = av_strdup(args);
|
||||
|
||||
args[0] = 0;
|
||||
@@ -1011,30 +947,14 @@ int configure_filtergraph(FilterGraph *fg)
|
||||
return ret;
|
||||
|
||||
if (simple && (!inputs || inputs->next || !outputs || outputs->next)) {
|
||||
const char *num_inputs;
|
||||
const char *num_outputs;
|
||||
if (!outputs) {
|
||||
num_outputs = "0";
|
||||
} else if (outputs->next) {
|
||||
num_outputs = ">1";
|
||||
} else {
|
||||
num_outputs = "1";
|
||||
}
|
||||
if (!inputs) {
|
||||
num_inputs = "0";
|
||||
} else if (inputs->next) {
|
||||
num_inputs = ">1";
|
||||
} else {
|
||||
num_inputs = "1";
|
||||
}
|
||||
av_log(NULL, AV_LOG_ERROR, "Simple filtergraph '%s' was expected "
|
||||
"to have exactly 1 input and 1 output."
|
||||
" However, it had %s input(s) and %s output(s)."
|
||||
" Please adjust, or use a complex filtergraph (-filter_complex) instead.\n",
|
||||
graph_desc, num_inputs, num_outputs);
|
||||
av_log(NULL, AV_LOG_ERROR, "Simple filtergraph '%s' does not have "
|
||||
"exactly one input and output.\n", graph_desc);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
for (cur = inputs; !simple && init && cur; cur = cur->next)
|
||||
init_input_filter(fg, cur);
|
||||
|
||||
for (cur = inputs, i = 0; cur; cur = cur->next, i++)
|
||||
if ((ret = configure_input_filter(fg, fg->inputs[i], cur)) < 0) {
|
||||
avfilter_inout_free(&inputs);
|
||||
@@ -1043,12 +963,27 @@ int configure_filtergraph(FilterGraph *fg)
|
||||
}
|
||||
avfilter_inout_free(&inputs);
|
||||
|
||||
for (cur = outputs, i = 0; cur; cur = cur->next, i++)
|
||||
configure_output_filter(fg, fg->outputs[i], cur);
|
||||
avfilter_inout_free(&outputs);
|
||||
if (!init || simple) {
|
||||
/* we already know the mappings between lavfi outputs and output streams,
|
||||
* so we can finish the setup */
|
||||
for (cur = outputs, i = 0; cur; cur = cur->next, i++)
|
||||
configure_output_filter(fg, fg->outputs[i], cur);
|
||||
avfilter_inout_free(&outputs);
|
||||
|
||||
if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
|
||||
return ret;
|
||||
if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
|
||||
return ret;
|
||||
} else {
|
||||
/* wait until output mappings are processed */
|
||||
for (cur = outputs; cur;) {
|
||||
GROW_ARRAY(fg->outputs, fg->nb_outputs);
|
||||
if (!(fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0]))))
|
||||
exit_program(1);
|
||||
fg->outputs[fg->nb_outputs - 1]->graph = fg;
|
||||
fg->outputs[fg->nb_outputs - 1]->out_tmp = cur;
|
||||
cur = cur->next;
|
||||
fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
fg->reconfiguration = 1;
|
||||
|
||||
@@ -1056,7 +991,7 @@ int configure_filtergraph(FilterGraph *fg)
|
||||
OutputStream *ost = fg->outputs[i]->ost;
|
||||
if (ost &&
|
||||
ost->enc->type == AVMEDIA_TYPE_AUDIO &&
|
||||
!(ost->enc->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE))
|
||||
!(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE))
|
||||
av_buffersink_set_frame_size(ost->filter->filter,
|
||||
ost->enc_ctx->frame_size);
|
||||
}
|
||||
|
||||
+33
-164
@@ -40,9 +40,6 @@
|
||||
#include "libavutil/parseutils.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/pixfmt.h"
|
||||
#include "libavutil/time_internal.h"
|
||||
|
||||
#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
|
||||
|
||||
#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
|
||||
{\
|
||||
@@ -74,10 +71,7 @@ const HWAccel hwaccels[] = {
|
||||
{ "dxva2", dxva2_init, HWACCEL_DXVA2, AV_PIX_FMT_DXVA2_VLD },
|
||||
#endif
|
||||
#if CONFIG_VDA
|
||||
{ "vda", videotoolbox_init, HWACCEL_VDA, AV_PIX_FMT_VDA },
|
||||
#endif
|
||||
#if CONFIG_VIDEOTOOLBOX
|
||||
{ "videotoolbox", videotoolbox_init, HWACCEL_VIDEOTOOLBOX, AV_PIX_FMT_VIDEOTOOLBOX },
|
||||
{ "vda", vda_init, HWACCEL_VDA, AV_PIX_FMT_VDA },
|
||||
#endif
|
||||
{ 0 },
|
||||
};
|
||||
@@ -159,25 +153,12 @@ static void init_options(OptionsContext *o)
|
||||
o->stop_time = INT64_MAX;
|
||||
o->mux_max_delay = 0.7;
|
||||
o->start_time = AV_NOPTS_VALUE;
|
||||
o->start_time_eof = AV_NOPTS_VALUE;
|
||||
o->recording_time = INT64_MAX;
|
||||
o->limit_filesize = UINT64_MAX;
|
||||
o->chapters_input_file = INT_MAX;
|
||||
o->accurate_seek = 1;
|
||||
}
|
||||
|
||||
static int show_hwaccels(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("Hardware acceleration methods:\n");
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(hwaccels) - 1; i++) {
|
||||
printf("%s\n", hwaccels[i].name);
|
||||
}
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return a copy of the input with the stream specifiers removed from the keys */
|
||||
static AVDictionary *strip_specifiers(AVDictionary *dict)
|
||||
{
|
||||
@@ -249,7 +230,6 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
|
||||
int sync_file_idx = -1, sync_stream_idx = 0;
|
||||
char *p, *sync;
|
||||
char *map;
|
||||
char *allow_unused;
|
||||
|
||||
if (*arg == '-') {
|
||||
negative = 1;
|
||||
@@ -294,8 +274,6 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
|
||||
exit_program(1);
|
||||
}
|
||||
} else {
|
||||
if (allow_unused = strchr(map, '?'))
|
||||
*allow_unused = 0;
|
||||
file_idx = strtol(map, &p, 0);
|
||||
if (file_idx >= nb_input_files || file_idx < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
|
||||
@@ -333,13 +311,8 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
|
||||
}
|
||||
|
||||
if (!m) {
|
||||
if (allow_unused) {
|
||||
av_log(NULL, AV_LOG_VERBOSE, "Stream map '%s' matches no streams; ignoring.\n", arg);
|
||||
} else {
|
||||
av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n"
|
||||
"To ignore this, add a trailing '?' to the map.\n", arg);
|
||||
exit_program(1);
|
||||
}
|
||||
av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg);
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
av_freep(&map);
|
||||
@@ -674,11 +647,9 @@ 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 FF_API_EMU_EDGE
|
||||
if (av_codec_get_lowres(dec)) {
|
||||
dec->flags |= CODEC_FLAG_EMU_EDGE;
|
||||
}
|
||||
#endif
|
||||
|
||||
ist->resample_height = ist->dec_ctx->height;
|
||||
ist->resample_width = ist->dec_ctx->width;
|
||||
@@ -951,12 +922,6 @@ static int open_input_file(OptionsContext *o, const char *filename)
|
||||
}
|
||||
}
|
||||
|
||||
if (o->start_time_eof != AV_NOPTS_VALUE) {
|
||||
if (ic->duration>0) {
|
||||
o->start_time = o->start_time_eof + ic->duration;
|
||||
} else
|
||||
av_log(NULL, AV_LOG_WARNING, "Cannot use -sseof, duration of %s not known\n", filename);
|
||||
}
|
||||
timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time;
|
||||
/* add the stream start time */
|
||||
if (!o->seek_timestamp && ic->start_time != AV_NOPTS_VALUE)
|
||||
@@ -1244,7 +1209,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
|
||||
|
||||
MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
|
||||
if (qscale >= 0) {
|
||||
ost->enc_ctx->flags |= AV_CODEC_FLAG_QSCALE;
|
||||
ost->enc_ctx->flags |= CODEC_FLAG_QSCALE;
|
||||
ost->enc_ctx->global_quality = FF_QP2LAMBDA * qscale;
|
||||
}
|
||||
|
||||
@@ -1252,9 +1217,9 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
|
||||
ost->disposition = av_strdup(ost->disposition);
|
||||
|
||||
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
ost->enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
av_dict_copy(&ost->sws_dict, o->g->sws_dict, 0);
|
||||
av_opt_get_int(o->g->sws_opts, "sws_flags", 0, &ost->sws_flags);
|
||||
|
||||
av_dict_copy(&ost->swr_opts, o->g->swr_opts, 0);
|
||||
if (ost->enc && av_get_exact_bits_per_sample(ost->enc->id) == 24)
|
||||
@@ -1474,17 +1439,17 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in
|
||||
video_enc->rc_override_count = i;
|
||||
|
||||
if (do_psnr)
|
||||
video_enc->flags|= AV_CODEC_FLAG_PSNR;
|
||||
video_enc->flags|= CODEC_FLAG_PSNR;
|
||||
|
||||
/* two pass mode */
|
||||
MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
|
||||
if (do_pass) {
|
||||
if (do_pass & 1) {
|
||||
video_enc->flags |= AV_CODEC_FLAG_PASS1;
|
||||
video_enc->flags |= CODEC_FLAG_PASS1;
|
||||
av_dict_set(&ost->encoder_opts, "flags", "+pass1", AV_DICT_APPEND);
|
||||
}
|
||||
if (do_pass & 2) {
|
||||
video_enc->flags |= AV_CODEC_FLAG_PASS2;
|
||||
video_enc->flags |= CODEC_FLAG_PASS2;
|
||||
av_dict_set(&ost->encoder_opts, "flags", "+pass2", AV_DICT_APPEND);
|
||||
}
|
||||
}
|
||||
@@ -1494,40 +1459,6 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in
|
||||
!(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
|
||||
exit_program(1);
|
||||
|
||||
if (do_pass) {
|
||||
char logfilename[1024];
|
||||
FILE *f;
|
||||
|
||||
snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
|
||||
ost->logfile_prefix ? ost->logfile_prefix :
|
||||
DEFAULT_PASS_LOGFILENAME_PREFIX,
|
||||
i);
|
||||
if (!strcmp(ost->enc->name, "libx264")) {
|
||||
av_dict_set(&ost->encoder_opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
|
||||
} else {
|
||||
if (video_enc->flags & AV_CODEC_FLAG_PASS2) {
|
||||
char *logbuffer = read_file(logfilename);
|
||||
|
||||
if (!logbuffer) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
|
||||
logfilename);
|
||||
exit_program(1);
|
||||
}
|
||||
video_enc->stats_in = logbuffer;
|
||||
}
|
||||
if (video_enc->flags & AV_CODEC_FLAG_PASS1) {
|
||||
f = av_fopen_utf8(logfilename, "wb");
|
||||
if (!f) {
|
||||
av_log(NULL, AV_LOG_FATAL,
|
||||
"Cannot write log file '%s' for pass-1 encoding: %s\n",
|
||||
logfilename, strerror(errno));
|
||||
exit_program(1);
|
||||
}
|
||||
ost->logfile = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
|
||||
if (ost->forced_keyframes)
|
||||
ost->forced_keyframes = av_strdup(ost->forced_keyframes);
|
||||
@@ -1806,7 +1737,8 @@ static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
|
||||
{
|
||||
OutputStream *ost;
|
||||
|
||||
switch (ofilter->type) {
|
||||
switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
|
||||
ofilter->out_tmp->pad_idx)) {
|
||||
case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc, -1); break;
|
||||
case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc, -1); break;
|
||||
default:
|
||||
@@ -1839,19 +1771,11 @@ static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
avfilter_inout_free(&ofilter->out_tmp);
|
||||
}
|
||||
|
||||
static int init_complex_filters(void)
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < nb_filtergraphs; i++) {
|
||||
ret = init_complex_filtergraph(filtergraphs[i]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n");
|
||||
exit_program(1);
|
||||
}
|
||||
return 0;
|
||||
avfilter_inout_free(&ofilter->out_tmp);
|
||||
}
|
||||
|
||||
static int configure_complex_filters(void)
|
||||
@@ -1876,6 +1800,10 @@ static int open_output_file(OptionsContext *o, const char *filename)
|
||||
AVDictionary *unused_opts = NULL;
|
||||
AVDictionaryEntry *e = NULL;
|
||||
|
||||
if (configure_complex_filters() < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Error configuring filters.\n");
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
if (o->stop_time != INT64_MAX && o->recording_time != INT64_MAX) {
|
||||
o->stop_time = INT64_MAX;
|
||||
@@ -1930,7 +1858,8 @@ static int open_output_file(OptionsContext *o, const char *filename)
|
||||
if (!ofilter->out_tmp || ofilter->out_tmp->name)
|
||||
continue;
|
||||
|
||||
switch (ofilter->type) {
|
||||
switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
|
||||
ofilter->out_tmp->pad_idx)) {
|
||||
case AVMEDIA_TYPE_VIDEO: o->video_disable = 1; break;
|
||||
case AVMEDIA_TYPE_AUDIO: o->audio_disable = 1; break;
|
||||
case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;
|
||||
@@ -1989,7 +1918,7 @@ static int open_output_file(OptionsContext *o, const char *filename)
|
||||
for (i = 0; i < nb_input_streams; i++) {
|
||||
int new_area;
|
||||
ist = input_streams[i];
|
||||
new_area = ist->st->codec->width * ist->st->codec->height + 100000000*!!ist->st->codec_info_nb_frames;
|
||||
new_area = ist->st->codec->width * ist->st->codec->height;
|
||||
if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
|
||||
new_area = 1;
|
||||
if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
|
||||
@@ -2006,14 +1935,12 @@ static int open_output_file(OptionsContext *o, const char *filename)
|
||||
|
||||
/* audio: most channels */
|
||||
if (!o->audio_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_AUDIO) != AV_CODEC_ID_NONE) {
|
||||
int best_score = 0, idx = -1;
|
||||
int channels = 0, idx = -1;
|
||||
for (i = 0; i < nb_input_streams; i++) {
|
||||
int score;
|
||||
ist = input_streams[i];
|
||||
score = ist->st->codec->channels + 100000000*!!ist->st->codec_info_nb_frames;
|
||||
if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
|
||||
score > best_score) {
|
||||
best_score = score;
|
||||
ist->st->codec->channels > channels) {
|
||||
channels = ist->st->codec->channels;
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
@@ -2100,7 +2027,6 @@ loop_end:
|
||||
if(o-> data_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_DATA)
|
||||
continue;
|
||||
|
||||
ost = NULL;
|
||||
switch (ist->st->codec->codec_type) {
|
||||
case AVMEDIA_TYPE_VIDEO: ost = new_video_stream (o, oc, src_idx); break;
|
||||
case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream (o, oc, src_idx); break;
|
||||
@@ -2124,9 +2050,6 @@ loop_end:
|
||||
exit_program(1);
|
||||
}
|
||||
}
|
||||
if (ost)
|
||||
ost->sync_ist = input_streams[ input_files[map->sync_file_index]->ist_index
|
||||
+ map->sync_stream_index];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2156,7 +2079,7 @@ loop_end:
|
||||
avio_read(pb, attachment, len);
|
||||
|
||||
ost = new_attachment_stream(o, oc, -1);
|
||||
ost->stream_copy = 1;
|
||||
ost->stream_copy = 0;
|
||||
ost->attachment_filename = o->attachments[i];
|
||||
ost->finished = 1;
|
||||
ost->st->codec->extradata = attachment;
|
||||
@@ -2178,12 +2101,6 @@ loop_end:
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
|
||||
av_dump_format(oc, nb_output_files - 1, oc->filename, 1);
|
||||
av_log(NULL, AV_LOG_ERROR, "Output file #%d does not contain any stream\n", nb_output_files - 1);
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
/* check if all codec options have been used */
|
||||
unused_opts = strip_specifiers(o->g->codec_opts);
|
||||
for (i = of->ost_index; i < nb_output_streams; i++) {
|
||||
@@ -2226,17 +2143,6 @@ loop_end:
|
||||
}
|
||||
av_dict_free(&unused_opts);
|
||||
|
||||
/* set the encoding/decoding_needed flags */
|
||||
for (i = of->ost_index; i < nb_output_streams; i++) {
|
||||
OutputStream *ost = output_streams[i];
|
||||
|
||||
ost->encoding_needed = !ost->stream_copy;
|
||||
if (ost->encoding_needed && ost->source_index >= 0) {
|
||||
InputStream *ist = input_streams[ost->source_index];
|
||||
ist->decoding_needed |= DECODING_FOR_OST;
|
||||
}
|
||||
}
|
||||
|
||||
/* check filename in case of an image number is expected */
|
||||
if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
|
||||
if (!av_filename_number_test(oc->filename)) {
|
||||
@@ -2332,7 +2238,6 @@ loop_end:
|
||||
char type, *val;
|
||||
const char *stream_spec;
|
||||
int index = 0, j, ret = 0;
|
||||
char now_time[256];
|
||||
|
||||
val = strchr(o->metadata[i].u.str, '=');
|
||||
if (!val) {
|
||||
@@ -2342,17 +2247,6 @@ loop_end:
|
||||
}
|
||||
*val++ = 0;
|
||||
|
||||
if (!strcmp(o->metadata[i].u.str, "creation_time") &&
|
||||
!strcmp(val, "now")) {
|
||||
time_t now = time(0);
|
||||
struct tm *ptm, tmbuf;
|
||||
ptm = localtime_r(&now, &tmbuf);
|
||||
if (ptm) {
|
||||
if (strftime(now_time, sizeof(now_time), "%Y-%m-%d %H:%M:%S", ptm))
|
||||
val = now_time;
|
||||
}
|
||||
}
|
||||
|
||||
parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);
|
||||
if (type == 's') {
|
||||
for (j = 0; j < oc->nb_streams; j++) {
|
||||
@@ -2545,10 +2439,8 @@ static int opt_vstats(void *optctx, const char *opt, const char *arg)
|
||||
time_t today2 = time(NULL);
|
||||
struct tm *today = localtime(&today2);
|
||||
|
||||
if (!today) { // maybe tomorrow
|
||||
av_log(NULL, AV_LOG_FATAL, "Unable to get current time: %s\n", strerror(errno));
|
||||
exit_program(1);
|
||||
}
|
||||
if (!today)
|
||||
return AVERROR(errno);
|
||||
|
||||
snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
|
||||
today->tm_sec);
|
||||
@@ -2883,8 +2775,8 @@ enum OptGroup {
|
||||
};
|
||||
|
||||
static const OptionGroupDef groups[] = {
|
||||
[GROUP_OUTFILE] = { "output url", NULL, OPT_OUTPUT },
|
||||
[GROUP_INFILE] = { "input url", "i", OPT_INPUT },
|
||||
[GROUP_OUTFILE] = { "output file", NULL, OPT_OUTPUT },
|
||||
[GROUP_INFILE] = { "input file", "i", OPT_INPUT },
|
||||
};
|
||||
|
||||
static int open_files(OptionGroupList *l, const char *inout,
|
||||
@@ -2903,7 +2795,6 @@ static int open_files(OptionGroupList *l, const char *inout,
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file "
|
||||
"%s.\n", inout, g->arg);
|
||||
uninit_options(&o);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2951,13 +2842,6 @@ int ffmpeg_parse_options(int argc, char **argv)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* create the complex filtergraphs */
|
||||
ret = init_complex_filters();
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Error initializing complex filters.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* open output files */
|
||||
ret = open_files(&octx.groups[GROUP_OUTFILE], "output", open_output_file);
|
||||
if (ret < 0) {
|
||||
@@ -2965,13 +2849,6 @@ int ffmpeg_parse_options(int argc, char **argv)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* configure the complex filtergraphs */
|
||||
ret = configure_complex_filters();
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Error configuring complex filters.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
uninit_parse_context(&octx);
|
||||
if (ret < 0) {
|
||||
@@ -3046,9 +2923,6 @@ 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" },
|
||||
{ "sseof", HAS_ARG | OPT_TIME | OPT_OFFSET |
|
||||
OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(start_time_eof) },
|
||||
"set the start time offset relative to EOF", "time_off" },
|
||||
{ "seek_timestamp", HAS_ARG | OPT_INT | OPT_OFFSET |
|
||||
OPT_INPUT, { .off = OFFSET(seek_timestamp) },
|
||||
"enable/disable seeking by timestamp with -ss" },
|
||||
@@ -3086,8 +2960,8 @@ const OptionDef options[] = {
|
||||
OPT_INPUT, { .off = OFFSET(rate_emu) },
|
||||
"read input at native frame rate", "" },
|
||||
{ "target", HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_target },
|
||||
"specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\" or \"dv50\" "
|
||||
"with optional prefixes \"pal-\", \"ntsc-\" or \"film-\")", "type" },
|
||||
"specify target file type (\"vcd\", \"svcd\", \"dvd\","
|
||||
" \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
|
||||
{ "vsync", HAS_ARG | OPT_EXPERT, { opt_vsync },
|
||||
"video sync method", "" },
|
||||
{ "frame_drop_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &frame_drop_threshold },
|
||||
@@ -3249,15 +3123,10 @@ const OptionDef options[] = {
|
||||
"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" },
|
||||
"select a device for HW acceleration" "devicename" },
|
||||
#if HAVE_VDPAU_X11
|
||||
{ "vdpau_api_ver", HAS_ARG | OPT_INT | OPT_EXPERT, { &vdpau_api_ver }, "" },
|
||||
#endif
|
||||
#if CONFIG_VDA || CONFIG_VIDEOTOOLBOX
|
||||
{ "videotoolbox_pixfmt", HAS_ARG | OPT_STRING | OPT_EXPERT, { &videotoolbox_pixfmt}, "" },
|
||||
#endif
|
||||
{ "hwaccels", OPT_EXIT, { .func_arg = show_hwaccels },
|
||||
"show available HW acceleration methods" },
|
||||
{ "autorotate", HAS_ARG | OPT_BOOL | OPT_SPEC |
|
||||
OPT_EXPERT | OPT_INPUT, { .off = OFFSET(autorotate) },
|
||||
"automatically insert correct rotate filters" },
|
||||
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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 "libavcodec/avcodec.h"
|
||||
#include "libavcodec/vda.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
|
||||
#include "ffmpeg.h"
|
||||
|
||||
typedef struct VDAContext {
|
||||
AVFrame *tmp_frame;
|
||||
} VDAContext;
|
||||
|
||||
static int vda_retrieve_data(AVCodecContext *s, AVFrame *frame)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
VDAContext *vda = ist->hwaccel_ctx;
|
||||
CVPixelBufferRef pixbuf = (CVPixelBufferRef)frame->data[3];
|
||||
OSType pixel_format = CVPixelBufferGetPixelFormatType(pixbuf);
|
||||
CVReturn err;
|
||||
uint8_t *data[4] = { 0 };
|
||||
int linesize[4] = { 0 };
|
||||
int planes, ret, i;
|
||||
|
||||
av_frame_unref(vda->tmp_frame);
|
||||
|
||||
switch (pixel_format) {
|
||||
case kCVPixelFormatType_420YpCbCr8Planar: vda->tmp_frame->format = AV_PIX_FMT_YUV420P; break;
|
||||
case kCVPixelFormatType_422YpCbCr8: vda->tmp_frame->format = AV_PIX_FMT_UYVY422; break;
|
||||
default:
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"Unsupported pixel format: %u\n", pixel_format);
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
|
||||
vda->tmp_frame->width = frame->width;
|
||||
vda->tmp_frame->height = frame->height;
|
||||
ret = av_frame_get_buffer(vda->tmp_frame, 32);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
err = CVPixelBufferLockBaseAddress(pixbuf, kCVPixelBufferLock_ReadOnly);
|
||||
if (err != kCVReturnSuccess) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error locking the pixel buffer.\n");
|
||||
return AVERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
if (CVPixelBufferIsPlanar(pixbuf)) {
|
||||
|
||||
planes = CVPixelBufferGetPlaneCount(pixbuf);
|
||||
for (i = 0; i < planes; i++) {
|
||||
data[i] = CVPixelBufferGetBaseAddressOfPlane(pixbuf, i);
|
||||
linesize[i] = CVPixelBufferGetBytesPerRowOfPlane(pixbuf, i);
|
||||
}
|
||||
} else {
|
||||
data[0] = CVPixelBufferGetBaseAddress(pixbuf);
|
||||
linesize[0] = CVPixelBufferGetBytesPerRow(pixbuf);
|
||||
}
|
||||
|
||||
av_image_copy(vda->tmp_frame->data, vda->tmp_frame->linesize,
|
||||
(const uint8_t **)data, linesize, vda->tmp_frame->format,
|
||||
frame->width, frame->height);
|
||||
|
||||
ret = av_frame_copy_props(vda->tmp_frame, frame);
|
||||
CVPixelBufferUnlockBaseAddress(pixbuf, kCVPixelBufferLock_ReadOnly);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
av_frame_unref(frame);
|
||||
av_frame_move_ref(frame, vda->tmp_frame);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vda_uninit(AVCodecContext *s)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
VDAContext *vda = ist->hwaccel_ctx;
|
||||
|
||||
ist->hwaccel_uninit = NULL;
|
||||
ist->hwaccel_retrieve_data = NULL;
|
||||
|
||||
av_frame_free(&vda->tmp_frame);
|
||||
|
||||
av_vda_default_free(s);
|
||||
av_freep(&ist->hwaccel_ctx);
|
||||
}
|
||||
|
||||
int vda_init(AVCodecContext *s)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
|
||||
VDAContext *vda;
|
||||
int ret;
|
||||
|
||||
vda = av_mallocz(sizeof(*vda));
|
||||
if (!vda)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
ist->hwaccel_ctx = vda;
|
||||
ist->hwaccel_uninit = vda_uninit;
|
||||
ist->hwaccel_retrieve_data = vda_retrieve_data;
|
||||
|
||||
vda->tmp_frame = av_frame_alloc();
|
||||
if (!vda->tmp_frame) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = av_vda_default_init(s);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, loglevel, "Error creating VDA decoder.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
vda_uninit(s);
|
||||
return ret;
|
||||
}
|
||||
+1
-2
@@ -289,8 +289,7 @@ do {
|
||||
|
||||
s->hwaccel_context = vdpau_ctx;
|
||||
} else
|
||||
if (av_vdpau_bind_context(s, ctx->device, ctx->get_proc_address,
|
||||
AV_HWACCEL_FLAG_IGNORE_LEVEL))
|
||||
if (av_vdpau_bind_context(s, ctx->device, ctx->get_proc_address, 0))
|
||||
goto fail;
|
||||
|
||||
ctx->get_information_string(&vendor);
|
||||
|
||||
@@ -1,187 +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 <CoreServices/CoreServices.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "libavcodec/avcodec.h"
|
||||
#if CONFIG_VDA
|
||||
# include "libavcodec/vda.h"
|
||||
#endif
|
||||
#if CONFIG_VIDEOTOOLBOX
|
||||
# include "libavcodec/videotoolbox.h"
|
||||
#endif
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "ffmpeg.h"
|
||||
|
||||
typedef struct VTContext {
|
||||
AVFrame *tmp_frame;
|
||||
} VTContext;
|
||||
|
||||
char *videotoolbox_pixfmt;
|
||||
|
||||
static int videotoolbox_retrieve_data(AVCodecContext *s, AVFrame *frame)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
VTContext *vt = ist->hwaccel_ctx;
|
||||
CVPixelBufferRef pixbuf = (CVPixelBufferRef)frame->data[3];
|
||||
OSType pixel_format = CVPixelBufferGetPixelFormatType(pixbuf);
|
||||
CVReturn err;
|
||||
uint8_t *data[4] = { 0 };
|
||||
int linesize[4] = { 0 };
|
||||
int planes, ret, i;
|
||||
char codec_str[32];
|
||||
|
||||
av_frame_unref(vt->tmp_frame);
|
||||
|
||||
switch (pixel_format) {
|
||||
case kCVPixelFormatType_420YpCbCr8Planar: vt->tmp_frame->format = AV_PIX_FMT_YUV420P; break;
|
||||
case kCVPixelFormatType_422YpCbCr8: vt->tmp_frame->format = AV_PIX_FMT_UYVY422; break;
|
||||
case kCVPixelFormatType_32BGRA: vt->tmp_frame->format = AV_PIX_FMT_BGRA; break;
|
||||
#ifdef kCFCoreFoundationVersionNumber10_7
|
||||
case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: vt->tmp_frame->format = AV_PIX_FMT_NV12; break;
|
||||
#endif
|
||||
default:
|
||||
av_get_codec_tag_string(codec_str, sizeof(codec_str), s->codec_tag);
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"%s: Unsupported pixel format: %s\n", codec_str, videotoolbox_pixfmt);
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
|
||||
vt->tmp_frame->width = frame->width;
|
||||
vt->tmp_frame->height = frame->height;
|
||||
ret = av_frame_get_buffer(vt->tmp_frame, 32);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
err = CVPixelBufferLockBaseAddress(pixbuf, kCVPixelBufferLock_ReadOnly);
|
||||
if (err != kCVReturnSuccess) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error locking the pixel buffer.\n");
|
||||
return AVERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
if (CVPixelBufferIsPlanar(pixbuf)) {
|
||||
|
||||
planes = CVPixelBufferGetPlaneCount(pixbuf);
|
||||
for (i = 0; i < planes; i++) {
|
||||
data[i] = CVPixelBufferGetBaseAddressOfPlane(pixbuf, i);
|
||||
linesize[i] = CVPixelBufferGetBytesPerRowOfPlane(pixbuf, i);
|
||||
}
|
||||
} else {
|
||||
data[0] = CVPixelBufferGetBaseAddress(pixbuf);
|
||||
linesize[0] = CVPixelBufferGetBytesPerRow(pixbuf);
|
||||
}
|
||||
|
||||
av_image_copy(vt->tmp_frame->data, vt->tmp_frame->linesize,
|
||||
(const uint8_t **)data, linesize, vt->tmp_frame->format,
|
||||
frame->width, frame->height);
|
||||
|
||||
ret = av_frame_copy_props(vt->tmp_frame, frame);
|
||||
CVPixelBufferUnlockBaseAddress(pixbuf, kCVPixelBufferLock_ReadOnly);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
av_frame_unref(frame);
|
||||
av_frame_move_ref(frame, vt->tmp_frame);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void videotoolbox_uninit(AVCodecContext *s)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
VTContext *vt = ist->hwaccel_ctx;
|
||||
|
||||
ist->hwaccel_uninit = NULL;
|
||||
ist->hwaccel_retrieve_data = NULL;
|
||||
|
||||
av_frame_free(&vt->tmp_frame);
|
||||
|
||||
if (ist->hwaccel_id == HWACCEL_VIDEOTOOLBOX) {
|
||||
#if CONFIG_VIDEOTOOLBOX
|
||||
av_videotoolbox_default_free(s);
|
||||
#endif
|
||||
} else {
|
||||
#if CONFIG_VDA
|
||||
av_vda_default_free(s);
|
||||
#endif
|
||||
}
|
||||
av_freep(&ist->hwaccel_ctx);
|
||||
}
|
||||
|
||||
int videotoolbox_init(AVCodecContext *s)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
|
||||
int ret = 0;
|
||||
VTContext *vt;
|
||||
|
||||
vt = av_mallocz(sizeof(*vt));
|
||||
if (!vt)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
ist->hwaccel_ctx = vt;
|
||||
ist->hwaccel_uninit = videotoolbox_uninit;
|
||||
ist->hwaccel_retrieve_data = videotoolbox_retrieve_data;
|
||||
|
||||
vt->tmp_frame = av_frame_alloc();
|
||||
if (!vt->tmp_frame) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (ist->hwaccel_id == HWACCEL_VIDEOTOOLBOX) {
|
||||
#if CONFIG_VIDEOTOOLBOX
|
||||
if (!videotoolbox_pixfmt) {
|
||||
ret = av_videotoolbox_default_init(s);
|
||||
} else {
|
||||
AVVideotoolboxContext *vtctx = av_videotoolbox_alloc_context();
|
||||
CFStringRef pixfmt_str = CFStringCreateWithCString(kCFAllocatorDefault,
|
||||
videotoolbox_pixfmt,
|
||||
kCFStringEncodingUTF8);
|
||||
vtctx->cv_pix_fmt_type = UTGetOSTypeFromString(pixfmt_str);
|
||||
ret = av_videotoolbox_default_init2(s, vtctx);
|
||||
CFRelease(pixfmt_str);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#if CONFIG_VDA
|
||||
if (!videotoolbox_pixfmt) {
|
||||
ret = av_vda_default_init(s);
|
||||
} else {
|
||||
AVVDAContext *vdactx = av_vda_alloc_context();
|
||||
CFStringRef pixfmt_str = CFStringCreateWithCString(kCFAllocatorDefault,
|
||||
videotoolbox_pixfmt,
|
||||
kCFStringEncodingUTF8);
|
||||
vdactx->cv_pix_fmt_type = UTGetOSTypeFromString(pixfmt_str);
|
||||
ret = av_vda_default_init2(s, vdactx);
|
||||
CFRelease(pixfmt_str);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (ret < 0) {
|
||||
av_log(NULL, loglevel,
|
||||
"Error creating %s decoder.\n", ist->hwaccel_id == HWACCEL_VIDEOTOOLBOX ? "Videotoolbox" : "VDA");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
videotoolbox_uninit(s);
|
||||
return ret;
|
||||
}
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/colorspace.h"
|
||||
#include "libavutil/eval.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
@@ -65,9 +66,7 @@ const char program_name[] = "ffplay";
|
||||
const int program_birth_year = 2003;
|
||||
|
||||
#define MAX_QUEUE_SIZE (15 * 1024 * 1024)
|
||||
#define MIN_FRAMES 25
|
||||
#define EXTERNAL_CLOCK_MIN_FRAMES 2
|
||||
#define EXTERNAL_CLOCK_MAX_FRAMES 10
|
||||
#define MIN_FRAMES 5
|
||||
|
||||
/* Minimum SDL audio buffer size, in samples. */
|
||||
#define SDL_AUDIO_MIN_BUFFER_SIZE 512
|
||||
@@ -103,7 +102,7 @@ const int program_birth_year = 2003;
|
||||
|
||||
#define CURSOR_HIDE_DELAY 1000000
|
||||
|
||||
static unsigned sws_flags = SWS_BICUBIC;
|
||||
static int64_t sws_flags = SWS_BICUBIC;
|
||||
|
||||
typedef struct MyAVPacketList {
|
||||
AVPacket pkt;
|
||||
@@ -224,9 +223,6 @@ typedef struct VideoState {
|
||||
Decoder viddec;
|
||||
Decoder subdec;
|
||||
|
||||
int viddec_width;
|
||||
int viddec_height;
|
||||
|
||||
int audio_stream;
|
||||
|
||||
int av_sync_type;
|
||||
@@ -282,7 +278,6 @@ typedef struct VideoState {
|
||||
#if !CONFIG_AVFILTER
|
||||
struct SwsContext *img_convert_ctx;
|
||||
#endif
|
||||
struct SwsContext *sub_convert_ctx;
|
||||
SDL_Rect last_display_rect;
|
||||
int eof;
|
||||
|
||||
@@ -834,50 +829,229 @@ static void fill_border(int xleft, int ytop, int width, int height, int x, int y
|
||||
#define ALPHA_BLEND(a, oldp, newp, s)\
|
||||
((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
|
||||
|
||||
#define RGBA_IN(r, g, b, a, s)\
|
||||
{\
|
||||
unsigned int v = ((const uint32_t *)(s))[0];\
|
||||
a = (v >> 24) & 0xff;\
|
||||
r = (v >> 16) & 0xff;\
|
||||
g = (v >> 8) & 0xff;\
|
||||
b = v & 0xff;\
|
||||
}
|
||||
|
||||
#define YUVA_IN(y, u, v, a, s, pal)\
|
||||
{\
|
||||
unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
|
||||
a = (val >> 24) & 0xff;\
|
||||
y = (val >> 16) & 0xff;\
|
||||
u = (val >> 8) & 0xff;\
|
||||
v = val & 0xff;\
|
||||
}
|
||||
|
||||
#define YUVA_OUT(d, y, u, v, a)\
|
||||
{\
|
||||
((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
|
||||
}
|
||||
|
||||
|
||||
#define BPP 1
|
||||
|
||||
static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
|
||||
{
|
||||
int x, y, Y, U, V, A;
|
||||
int wrap, wrap3, width2, skip2;
|
||||
int y, u, v, a, u1, v1, a1, w, h;
|
||||
uint8_t *lum, *cb, *cr;
|
||||
const uint8_t *p;
|
||||
const uint32_t *pal;
|
||||
int dstx, dsty, dstw, dsth;
|
||||
const AVPicture *src = &rect->pict;
|
||||
|
||||
dstw = av_clip(rect->w, 0, imgw);
|
||||
dsth = av_clip(rect->h, 0, imgh);
|
||||
dstx = av_clip(rect->x, 0, imgw - dstw);
|
||||
dsty = av_clip(rect->y, 0, imgh - dsth);
|
||||
lum = dst->data[0] + dstx + dsty * dst->linesize[0];
|
||||
cb = dst->data[1] + dstx/2 + (dsty >> 1) * dst->linesize[1];
|
||||
cr = dst->data[2] + dstx/2 + (dsty >> 1) * dst->linesize[2];
|
||||
lum = dst->data[0] + dsty * dst->linesize[0];
|
||||
cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
|
||||
cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
|
||||
|
||||
for (y = 0; y<dsth; y++) {
|
||||
for (x = 0; x<dstw; x++) {
|
||||
Y = src->data[0][x + y*src->linesize[0]];
|
||||
A = src->data[3][x + y*src->linesize[3]];
|
||||
lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
|
||||
lum++;
|
||||
}
|
||||
lum += dst->linesize[0] - dstw;
|
||||
}
|
||||
width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
|
||||
skip2 = dstx >> 1;
|
||||
wrap = dst->linesize[0];
|
||||
wrap3 = rect->pict.linesize[0];
|
||||
p = rect->pict.data[0];
|
||||
pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
|
||||
|
||||
for (y = 0; y<dsth/2; y++) {
|
||||
for (x = 0; x<dstw/2; x++) {
|
||||
U = src->data[1][x + y*src->linesize[1]];
|
||||
V = src->data[2][x + y*src->linesize[2]];
|
||||
A = src->data[3][2*x + 2*y *src->linesize[3]]
|
||||
+ src->data[3][2*x + 1 + 2*y *src->linesize[3]]
|
||||
+ src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
|
||||
+ src->data[3][2*x + (2*y+1)*src->linesize[3]];
|
||||
cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
|
||||
cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
|
||||
if (dsty & 1) {
|
||||
lum += dstx;
|
||||
cb += skip2;
|
||||
cr += skip2;
|
||||
|
||||
if (dstx & 1) {
|
||||
YUVA_IN(y, u, v, a, p, pal);
|
||||
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
|
||||
cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
|
||||
cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
|
||||
cb++;
|
||||
cr++;
|
||||
lum++;
|
||||
p += BPP;
|
||||
}
|
||||
for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
|
||||
YUVA_IN(y, u, v, a, p, pal);
|
||||
u1 = u;
|
||||
v1 = v;
|
||||
a1 = a;
|
||||
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
|
||||
|
||||
YUVA_IN(y, u, v, a, p + BPP, pal);
|
||||
u1 += u;
|
||||
v1 += v;
|
||||
a1 += a;
|
||||
lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
|
||||
cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
|
||||
cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
|
||||
cb++;
|
||||
cr++;
|
||||
p += 2 * BPP;
|
||||
lum += 2;
|
||||
}
|
||||
if (w) {
|
||||
YUVA_IN(y, u, v, a, p, pal);
|
||||
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
|
||||
cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
|
||||
cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
|
||||
p++;
|
||||
lum++;
|
||||
}
|
||||
p += wrap3 - dstw * BPP;
|
||||
lum += wrap - dstw - dstx;
|
||||
cb += dst->linesize[1] - width2 - skip2;
|
||||
cr += dst->linesize[2] - width2 - skip2;
|
||||
}
|
||||
for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
|
||||
lum += dstx;
|
||||
cb += skip2;
|
||||
cr += skip2;
|
||||
|
||||
if (dstx & 1) {
|
||||
YUVA_IN(y, u, v, a, p, pal);
|
||||
u1 = u;
|
||||
v1 = v;
|
||||
a1 = a;
|
||||
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
|
||||
p += wrap3;
|
||||
lum += wrap;
|
||||
YUVA_IN(y, u, v, a, p, pal);
|
||||
u1 += u;
|
||||
v1 += v;
|
||||
a1 += a;
|
||||
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
|
||||
cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
|
||||
cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
|
||||
cb++;
|
||||
cr++;
|
||||
p += -wrap3 + BPP;
|
||||
lum += -wrap + 1;
|
||||
}
|
||||
for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
|
||||
YUVA_IN(y, u, v, a, p, pal);
|
||||
u1 = u;
|
||||
v1 = v;
|
||||
a1 = a;
|
||||
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
|
||||
|
||||
YUVA_IN(y, u, v, a, p + BPP, pal);
|
||||
u1 += u;
|
||||
v1 += v;
|
||||
a1 += a;
|
||||
lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
|
||||
p += wrap3;
|
||||
lum += wrap;
|
||||
|
||||
YUVA_IN(y, u, v, a, p, pal);
|
||||
u1 += u;
|
||||
v1 += v;
|
||||
a1 += a;
|
||||
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
|
||||
|
||||
YUVA_IN(y, u, v, a, p + BPP, pal);
|
||||
u1 += u;
|
||||
v1 += v;
|
||||
a1 += a;
|
||||
lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
|
||||
|
||||
cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
|
||||
cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
|
||||
|
||||
cb++;
|
||||
cr++;
|
||||
p += -wrap3 + 2 * BPP;
|
||||
lum += -wrap + 2;
|
||||
}
|
||||
if (w) {
|
||||
YUVA_IN(y, u, v, a, p, pal);
|
||||
u1 = u;
|
||||
v1 = v;
|
||||
a1 = a;
|
||||
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
|
||||
p += wrap3;
|
||||
lum += wrap;
|
||||
YUVA_IN(y, u, v, a, p, pal);
|
||||
u1 += u;
|
||||
v1 += v;
|
||||
a1 += a;
|
||||
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
|
||||
cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
|
||||
cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
|
||||
cb++;
|
||||
cr++;
|
||||
p += -wrap3 + BPP;
|
||||
lum += -wrap + 1;
|
||||
}
|
||||
p += wrap3 + (wrap3 - dstw * BPP);
|
||||
lum += wrap + (wrap - dstw - dstx);
|
||||
cb += dst->linesize[1] - width2 - skip2;
|
||||
cr += dst->linesize[2] - width2 - skip2;
|
||||
}
|
||||
/* handle odd height */
|
||||
if (h) {
|
||||
lum += dstx;
|
||||
cb += skip2;
|
||||
cr += skip2;
|
||||
|
||||
if (dstx & 1) {
|
||||
YUVA_IN(y, u, v, a, p, pal);
|
||||
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
|
||||
cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
|
||||
cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
|
||||
cb++;
|
||||
cr++;
|
||||
lum++;
|
||||
p += BPP;
|
||||
}
|
||||
for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
|
||||
YUVA_IN(y, u, v, a, p, pal);
|
||||
u1 = u;
|
||||
v1 = v;
|
||||
a1 = a;
|
||||
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
|
||||
|
||||
YUVA_IN(y, u, v, a, p + BPP, pal);
|
||||
u1 += u;
|
||||
v1 += v;
|
||||
a1 += a;
|
||||
lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
|
||||
cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
|
||||
cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
|
||||
cb++;
|
||||
cr++;
|
||||
p += 2 * BPP;
|
||||
lum += 2;
|
||||
}
|
||||
if (w) {
|
||||
YUVA_IN(y, u, v, a, p, pal);
|
||||
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
|
||||
cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
|
||||
cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
|
||||
}
|
||||
cb += dst->linesize[1] - dstw/2;
|
||||
cr += dst->linesize[2] - dstw/2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1132,7 +1306,6 @@ static void stream_close(VideoState *is)
|
||||
#if !CONFIG_AVFILTER
|
||||
sws_freeContext(is->img_convert_ctx);
|
||||
#endif
|
||||
sws_freeContext(is->sub_convert_ctx);
|
||||
av_free(is);
|
||||
}
|
||||
|
||||
@@ -1302,11 +1475,11 @@ static double get_master_clock(VideoState *is)
|
||||
}
|
||||
|
||||
static void check_external_clock_speed(VideoState *is) {
|
||||
if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
|
||||
is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
|
||||
if (is->video_stream >= 0 && is->videoq.nb_packets <= MIN_FRAMES / 2 ||
|
||||
is->audio_stream >= 0 && is->audioq.nb_packets <= MIN_FRAMES / 2) {
|
||||
set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
|
||||
} else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
|
||||
(is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
|
||||
} else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&
|
||||
(is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {
|
||||
set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
|
||||
} else {
|
||||
double speed = is->extclk.speed;
|
||||
@@ -1678,18 +1851,7 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double
|
||||
av_picture_copy(&pict, (AVPicture *)src_frame,
|
||||
src_frame->format, vp->width, vp->height);
|
||||
#else
|
||||
{
|
||||
AVDictionaryEntry *e = av_dict_get(sws_dict, "sws_flags", NULL, 0);
|
||||
if (e) {
|
||||
const AVClass *class = sws_get_class();
|
||||
const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
|
||||
AV_OPT_SEARCH_FAKE_OBJ);
|
||||
int ret = av_opt_eval_flags(&class, o, e->value, &sws_flags);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
|
||||
is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
|
||||
vp->width, vp->height, src_frame->format, vp->width, vp->height,
|
||||
AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
|
||||
@@ -1731,9 +1893,6 @@ static int get_video_frame(VideoState *is, AVFrame *frame)
|
||||
|
||||
frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
|
||||
|
||||
is->viddec_width = frame->width;
|
||||
is->viddec_height = frame->height;
|
||||
|
||||
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);
|
||||
@@ -1799,23 +1958,15 @@ fail:
|
||||
static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
|
||||
{
|
||||
static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
|
||||
char sws_flags_str[512] = "";
|
||||
char sws_flags_str[128];
|
||||
char buffersrc_args[256];
|
||||
int ret;
|
||||
AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
|
||||
AVCodecContext *codec = is->video_st->codec;
|
||||
AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
|
||||
AVDictionaryEntry *e = NULL;
|
||||
|
||||
while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
|
||||
if (!strcmp(e->key, "sws_flags")) {
|
||||
av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
|
||||
} else
|
||||
av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
|
||||
}
|
||||
if (strlen(sws_flags_str))
|
||||
sws_flags_str[strlen(sws_flags_str)-1] = '\0';
|
||||
|
||||
av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
|
||||
snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%"PRId64, sws_flags);
|
||||
graph->scale_sws_opts = av_strdup(sws_flags_str);
|
||||
|
||||
snprintf(buffersrc_args, sizeof(buffersrc_args),
|
||||
@@ -2177,7 +2328,8 @@ static int subtitle_thread(void *arg)
|
||||
Frame *sp;
|
||||
int got_subtitle;
|
||||
double pts;
|
||||
int i;
|
||||
int i, j;
|
||||
int r, g, b, y, u, v, a;
|
||||
|
||||
for (;;) {
|
||||
if (!(sp = frame_queue_peek_writable(&is->subpq)))
|
||||
@@ -2196,41 +2348,14 @@ static int subtitle_thread(void *arg)
|
||||
|
||||
for (i = 0; i < sp->sub.num_rects; i++)
|
||||
{
|
||||
int in_w = sp->sub.rects[i]->w;
|
||||
int in_h = sp->sub.rects[i]->h;
|
||||
int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
|
||||
int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
|
||||
int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
|
||||
int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
|
||||
AVPicture newpic;
|
||||
|
||||
//can not use avpicture_alloc as it is not compatible with avsubtitle_free()
|
||||
av_image_fill_linesizes(newpic.linesize, AV_PIX_FMT_YUVA420P, out_w);
|
||||
newpic.data[0] = av_malloc(newpic.linesize[0] * out_h);
|
||||
newpic.data[3] = av_malloc(newpic.linesize[3] * out_h);
|
||||
newpic.data[1] = av_malloc(newpic.linesize[1] * ((out_h+1)/2));
|
||||
newpic.data[2] = av_malloc(newpic.linesize[2] * ((out_h+1)/2));
|
||||
|
||||
is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
|
||||
in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
|
||||
AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
|
||||
if (!is->sub_convert_ctx || !newpic.data[0] || !newpic.data[3] ||
|
||||
!newpic.data[1] || !newpic.data[2]
|
||||
) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
|
||||
exit(1);
|
||||
for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
|
||||
{
|
||||
RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
|
||||
y = RGB_TO_Y_CCIR(r, g, b);
|
||||
u = RGB_TO_U_CCIR(r, g, b, 0);
|
||||
v = RGB_TO_V_CCIR(r, g, b, 0);
|
||||
YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
|
||||
}
|
||||
sws_scale(is->sub_convert_ctx,
|
||||
(void*)sp->sub.rects[i]->pict.data, sp->sub.rects[i]->pict.linesize,
|
||||
0, in_h, newpic.data, newpic.linesize);
|
||||
|
||||
av_free(sp->sub.rects[i]->pict.data[0]);
|
||||
av_free(sp->sub.rects[i]->pict.data[1]);
|
||||
sp->sub.rects[i]->pict = newpic;
|
||||
sp->sub.rects[i]->w = out_w;
|
||||
sp->sub.rects[i]->h = out_h;
|
||||
sp->sub.rects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
|
||||
sp->sub.rects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
|
||||
}
|
||||
|
||||
/* now we can update the picture count */
|
||||
@@ -2323,13 +2448,6 @@ static int audio_decode_frame(VideoState *is)
|
||||
return -1;
|
||||
|
||||
do {
|
||||
#if defined(_WIN32)
|
||||
while (frame_queue_nb_remaining(&is->sampq) == 0) {
|
||||
if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
|
||||
return -1;
|
||||
av_usleep (1000);
|
||||
}
|
||||
#endif
|
||||
if (!(af = frame_queue_peek_readable(&is->sampq)))
|
||||
return -1;
|
||||
frame_queue_next(&is->sampq);
|
||||
@@ -2577,15 +2695,10 @@ static int stream_component_open(VideoState *is, int stream_index)
|
||||
}
|
||||
av_codec_set_lowres(avctx, stream_lowres);
|
||||
|
||||
#if FF_API_EMU_EDGE
|
||||
if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
|
||||
#endif
|
||||
if (fast)
|
||||
avctx->flags2 |= AV_CODEC_FLAG2_FAST;
|
||||
#if FF_API_EMU_EDGE
|
||||
if(codec->capabilities & AV_CODEC_CAP_DR1)
|
||||
if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
|
||||
if(codec->capabilities & CODEC_CAP_DR1)
|
||||
avctx->flags |= CODEC_FLAG_EMU_EDGE;
|
||||
#endif
|
||||
|
||||
opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
|
||||
if (!av_dict_get(opts, "threads", NULL, 0))
|
||||
@@ -2658,9 +2771,6 @@ static int stream_component_open(VideoState *is, int stream_index)
|
||||
is->video_stream = stream_index;
|
||||
is->video_st = ic->streams[stream_index];
|
||||
|
||||
is->viddec_width = avctx->width;
|
||||
is->viddec_height = avctx->height;
|
||||
|
||||
decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
|
||||
decoder_start(&is->viddec, video_thread, is);
|
||||
is->queue_attachments_req = 1;
|
||||
@@ -2869,7 +2979,7 @@ static int read_thread(void *arg)
|
||||
AVStream *st = ic->streams[i];
|
||||
enum AVMediaType type = st->codec->codec_type;
|
||||
st->discard = AVDISCARD_ALL;
|
||||
if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
|
||||
if (wanted_stream_spec[type] && st_index[type] == -1)
|
||||
if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
|
||||
st_index[type] = i;
|
||||
}
|
||||
@@ -3684,8 +3794,6 @@ int main(int argc, char **argv)
|
||||
VideoState *is;
|
||||
char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
|
||||
|
||||
init_dynload();
|
||||
|
||||
av_log_set_flags(AV_LOG_SKIP_REPEATED);
|
||||
parse_loglevel(argc, argv, options);
|
||||
|
||||
|
||||
@@ -1732,57 +1732,6 @@ static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void print_color_range(WriterContext *w, enum AVColorRange color_range, const char *fallback)
|
||||
{
|
||||
const char *val = av_color_range_name(color_range);
|
||||
if (!val || color_range == AVCOL_RANGE_UNSPECIFIED) {
|
||||
print_str_opt("color_range", fallback);
|
||||
} else {
|
||||
print_str("color_range", val);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_color_space(WriterContext *w, enum AVColorSpace color_space)
|
||||
{
|
||||
const char *val = av_color_space_name(color_space);
|
||||
if (!val || color_space == AVCOL_SPC_UNSPECIFIED) {
|
||||
print_str_opt("color_space", "unknown");
|
||||
} else {
|
||||
print_str("color_space", val);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_primaries(WriterContext *w, enum AVColorPrimaries color_primaries)
|
||||
{
|
||||
const char *val = av_color_primaries_name(color_primaries);
|
||||
if (!val || color_primaries == AVCOL_PRI_UNSPECIFIED) {
|
||||
print_str_opt("color_primaries", "unknown");
|
||||
} else {
|
||||
print_str("color_primaries", val);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_color_trc(WriterContext *w, enum AVColorTransferCharacteristic color_trc)
|
||||
{
|
||||
const char *val = av_color_transfer_name(color_trc);
|
||||
if (!val || color_trc == AVCOL_TRC_UNSPECIFIED) {
|
||||
print_str_opt("color_transfer", "unknown");
|
||||
} else {
|
||||
print_str("color_transfer", val);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_chroma_location(WriterContext *w, enum AVChromaLocation chroma_location)
|
||||
{
|
||||
const char *val = av_chroma_location_name(chroma_location);
|
||||
if (!val || chroma_location == AVCHROMA_LOC_UNSPECIFIED) {
|
||||
print_str_opt("chroma_location", "unspecified");
|
||||
} else {
|
||||
print_str("chroma_location", val);
|
||||
}
|
||||
}
|
||||
|
||||
static void show_packet(WriterContext *w, AVFormatContext *fmt_ctx, AVPacket *pkt, int packet_idx)
|
||||
{
|
||||
char val_str[128];
|
||||
@@ -2225,12 +2174,28 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id
|
||||
if (s) print_str ("pix_fmt", s);
|
||||
else print_str_opt("pix_fmt", "unknown");
|
||||
print_int("level", dec_ctx->level);
|
||||
if (dec_ctx->color_range != AVCOL_RANGE_UNSPECIFIED)
|
||||
print_str ("color_range", av_color_range_name(dec_ctx->color_range));
|
||||
else
|
||||
print_str_opt("color_range", "N/A");
|
||||
s = av_get_colorspace_name(dec_ctx->colorspace);
|
||||
if (s) print_str ("color_space", s);
|
||||
else print_str_opt("color_space", "unknown");
|
||||
|
||||
print_color_range(w, dec_ctx->color_range, "N/A");
|
||||
print_color_space(w, dec_ctx->colorspace);
|
||||
print_color_trc(w, dec_ctx->color_trc);
|
||||
print_primaries(w, dec_ctx->color_primaries);
|
||||
print_chroma_location(w, dec_ctx->chroma_sample_location);
|
||||
if (dec_ctx->color_trc != AVCOL_TRC_UNSPECIFIED)
|
||||
print_str("color_transfer", av_color_transfer_name(dec_ctx->color_trc));
|
||||
else
|
||||
print_str_opt("color_transfer", av_color_transfer_name(dec_ctx->color_trc));
|
||||
|
||||
if (dec_ctx->color_primaries != AVCOL_PRI_UNSPECIFIED)
|
||||
print_str("color_primaries", av_color_primaries_name(dec_ctx->color_primaries));
|
||||
else
|
||||
print_str_opt("color_primaries", av_color_primaries_name(dec_ctx->color_primaries));
|
||||
|
||||
if (dec_ctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED)
|
||||
print_str("chroma_location", av_chroma_location_name(dec_ctx->chroma_sample_location));
|
||||
else
|
||||
print_str_opt("chroma_location", av_chroma_location_name(dec_ctx->chroma_sample_location));
|
||||
|
||||
if (dec_ctx->timecode_frame_start >= 0) {
|
||||
char tcbuf[AV_TIMECODE_STR_SIZE];
|
||||
@@ -2866,9 +2831,6 @@ static int opt_show_format_entry(void *optctx, const char *opt, const char *arg)
|
||||
char *buf = av_asprintf("format=%s", arg);
|
||||
int ret;
|
||||
|
||||
if (!buf)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
av_log(NULL, AV_LOG_WARNING,
|
||||
"Option '%s' is deprecated, use '-show_entries format=%s' instead\n",
|
||||
opt, arg);
|
||||
@@ -3177,8 +3139,6 @@ int main(int argc, char **argv)
|
||||
char *w_name = NULL, *w_args = NULL;
|
||||
int ret, i;
|
||||
|
||||
init_dynload();
|
||||
|
||||
av_log_set_flags(AV_LOG_SKIP_REPEATED);
|
||||
register_exit(ffprobe_cleanup);
|
||||
|
||||
|
||||
+148
-162
@@ -31,7 +31,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "libavformat/avformat.h"
|
||||
/* FIXME: those are internal headers, ffserver _really_ shouldn't use them */
|
||||
// FIXME those are internal headers, ffserver _really_ shouldn't use them
|
||||
#include "libavformat/ffm.h"
|
||||
#include "libavformat/network.h"
|
||||
#include "libavformat/os_support.h"
|
||||
@@ -209,7 +209,6 @@ static void close_connection(HTTPContext *c);
|
||||
|
||||
/* HTTP handling */
|
||||
static int handle_connection(HTTPContext *c);
|
||||
static inline void print_stream_params(AVIOContext *pb, FFServerStream *stream);
|
||||
static void compute_status(HTTPContext *c);
|
||||
static int open_input_stream(HTTPContext *c, const char *info);
|
||||
static int http_parse_request(HTTPContext *c);
|
||||
@@ -251,8 +250,7 @@ static unsigned int nb_connections;
|
||||
|
||||
static uint64_t current_bandwidth;
|
||||
|
||||
/* Making this global saves on passing it around everywhere */
|
||||
static int64_t cur_time;
|
||||
static int64_t cur_time; // Making this global saves on passing it around everywhere
|
||||
|
||||
static AVLFG random_state;
|
||||
|
||||
@@ -316,12 +314,12 @@ static char *ctime1(char *buf2, int buf_size)
|
||||
static void http_vlog(const char *fmt, va_list vargs)
|
||||
{
|
||||
static int print_prefix = 1;
|
||||
char buf[32];
|
||||
|
||||
if (!logfile)
|
||||
return;
|
||||
|
||||
if (print_prefix) {
|
||||
char buf[32];
|
||||
ctime1(buf, sizeof(buf));
|
||||
fprintf(logfile, "%s ", buf);
|
||||
}
|
||||
@@ -506,7 +504,8 @@ static void start_multicast(void)
|
||||
random1 = av_lfg_get(&random_state);
|
||||
|
||||
/* open the RTP connection */
|
||||
snprintf(session_id, sizeof(session_id), "%08x%08x", random0, random1);
|
||||
snprintf(session_id, sizeof(session_id), "%08x%08x",
|
||||
random0, random1);
|
||||
|
||||
/* choose a port if none given */
|
||||
if (stream->multicast_port == 0) {
|
||||
@@ -631,8 +630,9 @@ static int http_server(void)
|
||||
poll_entry++;
|
||||
} else {
|
||||
/* when ffserver is doing the timing, we work by
|
||||
* looking at which packet needs to be sent every
|
||||
* 10 ms (one tick wait XXX: 10 ms assumed) */
|
||||
looking at which packet needs to be sent every
|
||||
10 ms */
|
||||
/* one tick wait XXX: 10 ms assumed */
|
||||
if (delay > 10)
|
||||
delay = 10;
|
||||
}
|
||||
@@ -655,7 +655,7 @@ static int http_server(void)
|
||||
}
|
||||
|
||||
/* wait for an event on one connection. We poll at least every
|
||||
* second to handle timeouts */
|
||||
second to handle timeouts */
|
||||
do {
|
||||
ret = poll(poll_table, poll_entry - poll_table, delay);
|
||||
if (ret < 0 && ff_neterrno() != AVERROR(EAGAIN) &&
|
||||
@@ -703,9 +703,13 @@ static void start_wait_request(HTTPContext *c, int is_rtsp)
|
||||
c->buffer_ptr = c->buffer;
|
||||
c->buffer_end = c->buffer + c->buffer_size - 1; /* leave room for '\0' */
|
||||
|
||||
c->state = is_rtsp ? RTSPSTATE_WAIT_REQUEST : HTTPSTATE_WAIT_REQUEST;
|
||||
c->timeout = cur_time +
|
||||
(is_rtsp ? RTSP_REQUEST_TIMEOUT : HTTP_REQUEST_TIMEOUT);
|
||||
if (is_rtsp) {
|
||||
c->timeout = cur_time + RTSP_REQUEST_TIMEOUT;
|
||||
c->state = RTSPSTATE_WAIT_REQUEST;
|
||||
} else {
|
||||
c->timeout = cur_time + HTTP_REQUEST_TIMEOUT;
|
||||
c->state = HTTPSTATE_WAIT_REQUEST;
|
||||
}
|
||||
}
|
||||
|
||||
static void http_send_too_busy_reply(int fd)
|
||||
@@ -783,6 +787,7 @@ static void close_connection(HTTPContext *c)
|
||||
HTTPContext **cp, *c1;
|
||||
int i, nb_streams;
|
||||
AVFormatContext *ctx;
|
||||
URLContext *h;
|
||||
AVStream *st;
|
||||
|
||||
/* remove connection from list */
|
||||
@@ -827,7 +832,9 @@ static void close_connection(HTTPContext *c)
|
||||
av_freep(&ctx->streams[0]);
|
||||
av_freep(&ctx);
|
||||
}
|
||||
ffurl_close(c->rtp_handles[i]);
|
||||
h = c->rtp_handles[i];
|
||||
if (h)
|
||||
ffurl_close(h);
|
||||
}
|
||||
|
||||
ctx = &c->fmt_ctx;
|
||||
@@ -896,11 +903,11 @@ static int handle_connection(HTTPContext *c)
|
||||
if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "\n\n", 2)) ||
|
||||
(ptr >= c->buffer + 4 && !memcmp(ptr-4, "\r\n\r\n", 4))) {
|
||||
/* request found : parse it and reply */
|
||||
if (c->state == HTTPSTATE_WAIT_REQUEST)
|
||||
if (c->state == HTTPSTATE_WAIT_REQUEST) {
|
||||
ret = http_parse_request(c);
|
||||
else
|
||||
} else {
|
||||
ret = rtsp_parse_request(c);
|
||||
|
||||
}
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
} else if (ptr >= c->buffer_end) {
|
||||
@@ -945,8 +952,8 @@ 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
|
||||
* that we do not rely too much on the kernel queues */
|
||||
input streams set 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))
|
||||
return -1;
|
||||
@@ -1159,10 +1166,8 @@ static int modify_current_stream(HTTPContext *c, char *rates)
|
||||
break;
|
||||
}
|
||||
|
||||
if (c->switch_feed_streams[i] >= 0 &&
|
||||
c->switch_feed_streams[i] != c->feed_streams[i]) {
|
||||
if (c->switch_feed_streams[i] >= 0 && c->switch_feed_streams[i] != c->feed_streams[i])
|
||||
action_required = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return action_required;
|
||||
@@ -1266,17 +1271,17 @@ static int validate_acl(FFServerStream *stream, HTTPContext *c)
|
||||
|
||||
if (stream->dynamic_acl[0]) {
|
||||
acl = parse_dynamic_acl(stream, c);
|
||||
|
||||
ret = validate_acl_list(acl, c);
|
||||
|
||||
free_acl_list(acl);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* compute the real filename of a file by matching it without its
|
||||
* extensions to all the stream's filenames
|
||||
*/
|
||||
/* compute the real filename of a file by matching it without its
|
||||
extensions to all the stream's filenames */
|
||||
static void compute_real_filename(char *filename, int max_size)
|
||||
{
|
||||
char file1[1024];
|
||||
@@ -1394,7 +1399,7 @@ static int http_parse_request(HTTPContext *c)
|
||||
compute_real_filename(filename, sizeof(filename) - 1);
|
||||
}
|
||||
|
||||
/* "redirect" request to index.html */
|
||||
// "redirect" / request to index.html
|
||||
if (!strlen(filename))
|
||||
av_strlcpy(filename, "index.html", sizeof(filename) - 1);
|
||||
|
||||
@@ -1733,9 +1738,8 @@ static int http_parse_request(HTTPContext *c)
|
||||
return 0;
|
||||
send_status:
|
||||
compute_status(c);
|
||||
/* horrible: we use this value to avoid
|
||||
* going to the send data state */
|
||||
c->http_error = 200;
|
||||
c->http_error = 200; /* horrible : we use this value to avoid
|
||||
going to the send data state */
|
||||
c->state = HTTPSTATE_SEND_HEADER;
|
||||
return 0;
|
||||
}
|
||||
@@ -1750,52 +1754,6 @@ static void fmt_bytecount(AVIOContext *pb, int64_t count)
|
||||
avio_printf(pb, "%"PRId64"%c", count, *s);
|
||||
}
|
||||
|
||||
static inline void print_stream_params(AVIOContext *pb, FFServerStream *stream)
|
||||
{
|
||||
int i, stream_no;
|
||||
const char *type = "unknown";
|
||||
char parameters[64];
|
||||
AVStream *st;
|
||||
AVCodec *codec;
|
||||
|
||||
stream_no = stream->nb_streams;
|
||||
|
||||
avio_printf(pb, "<table cellspacing=0 cellpadding=4><tr><th>Stream<th>"
|
||||
"type<th>kbits/s<th align=left>codec<th align=left>"
|
||||
"Parameters\n");
|
||||
|
||||
for (i = 0; i < stream_no; i++) {
|
||||
st = stream->streams[i];
|
||||
codec = avcodec_find_encoder(st->codec->codec_id);
|
||||
|
||||
parameters[0] = 0;
|
||||
|
||||
switch(st->codec->codec_type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
type = "audio";
|
||||
snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz",
|
||||
st->codec->channels, st->codec->sample_rate);
|
||||
break;
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
type = "video";
|
||||
snprintf(parameters, sizeof(parameters),
|
||||
"%dx%d, q=%d-%d, fps=%d", st->codec->width,
|
||||
st->codec->height, st->codec->qmin, st->codec->qmax,
|
||||
st->codec->time_base.den / st->codec->time_base.num);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
avio_printf(pb, "<tr><td align=right>%d<td>%s<td align=right>%d"
|
||||
"<td>%s<td>%s\n",
|
||||
i, type, st->codec->bit_rate/1000,
|
||||
codec ? codec->name : "", parameters);
|
||||
}
|
||||
|
||||
avio_printf(pb, "</table>\n");
|
||||
}
|
||||
|
||||
static void compute_status(HTTPContext *c)
|
||||
{
|
||||
HTTPContext *c1;
|
||||
@@ -1846,8 +1804,8 @@ static void compute_status(HTTPContext *c)
|
||||
strcpy(eosf - 3, ".ram");
|
||||
else if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
|
||||
/* generate a sample RTSP director if
|
||||
* unicast. Generate an SDP redirector if
|
||||
* multicast */
|
||||
unicast. Generate an SDP redirector if
|
||||
multicast */
|
||||
eosf = strrchr(sfilename, '.');
|
||||
if (!eosf)
|
||||
eosf = sfilename + strlen(sfilename);
|
||||
@@ -1936,7 +1894,7 @@ static void compute_status(HTTPContext *c)
|
||||
|
||||
avio_printf(pb, "<h2>Feed %s</h2>", stream->filename);
|
||||
if (stream->pid) {
|
||||
avio_printf(pb, "Running as pid %"PRId64".\n", (int64_t) stream->pid);
|
||||
avio_printf(pb, "Running as pid %d.\n", stream->pid);
|
||||
|
||||
#if defined(linux)
|
||||
{
|
||||
@@ -1945,8 +1903,8 @@ static void compute_status(HTTPContext *c)
|
||||
|
||||
/* This is somewhat linux specific I guess */
|
||||
snprintf(ps_cmd, sizeof(ps_cmd),
|
||||
"ps -o \"%%cpu,cputime\" --no-headers %"PRId64"",
|
||||
(int64_t) stream->pid);
|
||||
"ps -o \"%%cpu,cputime\" --no-headers %d",
|
||||
stream->pid);
|
||||
|
||||
pid_stat = popen(ps_cmd, "r");
|
||||
if (pid_stat) {
|
||||
@@ -1966,7 +1924,42 @@ static void compute_status(HTTPContext *c)
|
||||
avio_printf(pb, "<p>");
|
||||
}
|
||||
|
||||
print_stream_params(pb, stream);
|
||||
avio_printf(pb, "<table cellspacing=0 cellpadding=4><tr><th>Stream<th>"
|
||||
"type<th>kbits/s<th align=left>codec<th align=left>"
|
||||
"Parameters\n");
|
||||
|
||||
for (i = 0; i < stream->nb_streams; i++) {
|
||||
AVStream *st = stream->streams[i];
|
||||
AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
|
||||
const char *type = "unknown";
|
||||
char parameters[64];
|
||||
|
||||
parameters[0] = 0;
|
||||
|
||||
switch(st->codec->codec_type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
type = "audio";
|
||||
snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz",
|
||||
st->codec->channels, st->codec->sample_rate);
|
||||
break;
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
type = "video";
|
||||
snprintf(parameters, sizeof(parameters),
|
||||
"%dx%d, q=%d-%d, fps=%d", st->codec->width,
|
||||
st->codec->height, st->codec->qmin, st->codec->qmax,
|
||||
st->codec->time_base.den / st->codec->time_base.num);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
avio_printf(pb, "<tr><td align=right>%d<td>%s<td align=right>%d"
|
||||
"<td>%s<td>%s\n",
|
||||
i, type, st->codec->bit_rate/1000,
|
||||
codec ? codec->name : "", parameters);
|
||||
}
|
||||
|
||||
avio_printf(pb, "</table>\n");
|
||||
stream = stream->next;
|
||||
}
|
||||
|
||||
@@ -2118,7 +2111,8 @@ static int64_t get_server_clock(HTTPContext *c)
|
||||
return (cur_time - c->start_time) * 1000;
|
||||
}
|
||||
|
||||
/* return the estimated time (in us) at which the current packet must be sent */
|
||||
/* return the estimated time at which the current packet must be sent
|
||||
(in us) */
|
||||
static int64_t get_packet_send_clock(HTTPContext *c)
|
||||
{
|
||||
int bytes_left, bytes_sent, frame_bytes;
|
||||
@@ -2126,10 +2120,11 @@ static int64_t get_packet_send_clock(HTTPContext *c)
|
||||
frame_bytes = c->cur_frame_bytes;
|
||||
if (frame_bytes <= 0)
|
||||
return c->cur_pts;
|
||||
|
||||
bytes_left = c->buffer_end - c->buffer_ptr;
|
||||
bytes_sent = frame_bytes - bytes_left;
|
||||
return c->cur_pts + (c->cur_frame_duration * bytes_sent) / frame_bytes;
|
||||
else {
|
||||
bytes_left = c->buffer_end - c->buffer_ptr;
|
||||
bytes_sent = frame_bytes - bytes_left;
|
||||
return c->cur_pts + (c->cur_frame_duration * bytes_sent) / frame_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2156,8 +2151,7 @@ static int http_prepare_data(HTTPContext *c)
|
||||
AVStream *src;
|
||||
c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream));
|
||||
|
||||
/* if file or feed, then just take streams from FFServerStream
|
||||
* struct */
|
||||
/* if file or feed, then just take streams from FFServerStream struct */
|
||||
if (!c->stream->feed ||
|
||||
c->stream->feed == c->stream)
|
||||
src = c->stream->streams[i];
|
||||
@@ -2222,23 +2216,23 @@ static int http_prepare_data(HTTPContext *c)
|
||||
if (ret < 0) {
|
||||
if (c->stream->feed) {
|
||||
/* if coming from feed, it means we reached the end of the
|
||||
* ffm file, so must wait for more data */
|
||||
ffm file, so must wait for more data */
|
||||
c->state = HTTPSTATE_WAIT_FEED;
|
||||
return 1; /* state changed */
|
||||
}
|
||||
if (ret == AVERROR(EAGAIN)) {
|
||||
} else if (ret == AVERROR(EAGAIN)) {
|
||||
/* input not ready, come back later */
|
||||
return 0;
|
||||
}
|
||||
if (c->stream->loop) {
|
||||
avformat_close_input(&c->fmt_in);
|
||||
if (open_input_stream(c, "") < 0)
|
||||
goto no_loop;
|
||||
goto redo;
|
||||
} else {
|
||||
if (c->stream->loop) {
|
||||
avformat_close_input(&c->fmt_in);
|
||||
if (open_input_stream(c, "") < 0)
|
||||
goto no_loop;
|
||||
goto redo;
|
||||
} else {
|
||||
no_loop:
|
||||
/* must send trailer now because EOF or error */
|
||||
c->state = HTTPSTATE_SEND_DATA_TRAILER;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int source_index = pkt.stream_index;
|
||||
@@ -2309,9 +2303,9 @@ static int http_prepare_data(HTTPContext *c)
|
||||
max_packet_size = c->rtp_handles[c->packet_stream_index]->max_packet_size;
|
||||
ret = ffio_open_dyn_packet_buf(&ctx->pb,
|
||||
max_packet_size);
|
||||
} else
|
||||
} else {
|
||||
ret = avio_open_dyn_buf(&ctx->pb);
|
||||
|
||||
}
|
||||
if (ret < 0) {
|
||||
/* XXX: potential leak */
|
||||
return -1;
|
||||
@@ -2374,8 +2368,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) */
|
||||
static int http_send_data(HTTPContext *c)
|
||||
{
|
||||
int len, ret;
|
||||
@@ -2456,8 +2449,8 @@ static int http_send_data(HTTPContext *c)
|
||||
rtsp_c->packet_buffer_ptr += len;
|
||||
if (rtsp_c->packet_buffer_ptr < rtsp_c->packet_buffer_end) {
|
||||
/* if we could not send all the data, we will
|
||||
* send it later, so a new state is needed to
|
||||
* "lock" the RTSP TCP connection */
|
||||
send it later, so a new state is needed to
|
||||
"lock" the RTSP TCP connection */
|
||||
rtsp_c->state = RTSPSTATE_SEND_PACKET;
|
||||
break;
|
||||
} else
|
||||
@@ -2541,8 +2534,9 @@ static int http_start_receive_data(HTTPContext *c)
|
||||
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;
|
||||
}
|
||||
c->stream->feed_write_index = ret;
|
||||
}
|
||||
|
||||
c->stream->feed_write_index = FFMAX(ffm_read_write_index(fd),
|
||||
@@ -2580,17 +2574,16 @@ static int http_receive_data(HTTPContext *c)
|
||||
} else if (c->buffer_ptr - c->buffer >= 2 &&
|
||||
!memcmp(c->buffer_ptr - 1, "\r\n", 2)) {
|
||||
c->chunk_size = strtol(c->buffer, 0, 16);
|
||||
if (c->chunk_size <= 0) { // end of stream or invalid chunk size
|
||||
c->chunk_size = 0;
|
||||
if (c->chunk_size == 0) // end of stream
|
||||
goto fail;
|
||||
}
|
||||
c->buffer_ptr = c->buffer;
|
||||
break;
|
||||
} else if (++loop_run > 10)
|
||||
} else if (++loop_run > 10) {
|
||||
/* no chunk header, abort */
|
||||
goto fail;
|
||||
else
|
||||
} else {
|
||||
c->buffer_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
if (c->buffer_end > c->buffer_ptr) {
|
||||
@@ -2605,7 +2598,6 @@ static int http_receive_data(HTTPContext *c)
|
||||
/* end of connection : close it */
|
||||
goto fail;
|
||||
else {
|
||||
av_assert0(len <= c->chunk_size);
|
||||
c->chunk_size -= len;
|
||||
c->buffer_ptr += len;
|
||||
c->data_count += len;
|
||||
@@ -2624,7 +2616,7 @@ static int http_receive_data(HTTPContext *c)
|
||||
if (c->buffer_ptr >= c->buffer_end) {
|
||||
FFServerStream *feed = c->stream;
|
||||
/* a packet has been received : write it in the store, except
|
||||
* if header */
|
||||
if header */
|
||||
if (c->data_count > FFM_PACKET_SIZE) {
|
||||
/* XXX: use llseek or url_seek
|
||||
* XXX: Should probably fail? */
|
||||
@@ -2830,10 +2822,10 @@ static int rtsp_parse_request(HTTPContext *c)
|
||||
the_end:
|
||||
len = avio_close_dyn_buf(c->pb, &c->pb_buffer);
|
||||
c->pb = NULL; /* safety */
|
||||
if (len < 0)
|
||||
if (len < 0) {
|
||||
/* XXX: cannot do more */
|
||||
return -1;
|
||||
|
||||
}
|
||||
c->buffer_ptr = c->pb_buffer;
|
||||
c->buffer_end = c->pb_buffer + len;
|
||||
c->state = RTSPSTATE_SEND_REPLY;
|
||||
@@ -2852,9 +2844,9 @@ static int prepare_sdp_description(FFServerStream *stream, uint8_t **pbuffer,
|
||||
*pbuffer = NULL;
|
||||
|
||||
avc = avformat_alloc_context();
|
||||
if (!avc || !rtp_format)
|
||||
if (!avc || !rtp_format) {
|
||||
return -1;
|
||||
|
||||
}
|
||||
avc->oformat = rtp_format;
|
||||
av_dict_set(&avc->metadata, "title",
|
||||
entry ? entry->value : "No Title", 0);
|
||||
@@ -2863,8 +2855,9 @@ static int prepare_sdp_description(FFServerStream *stream, uint8_t **pbuffer,
|
||||
snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
|
||||
inet_ntoa(stream->multicast_ip),
|
||||
stream->multicast_port, stream->multicast_ttl);
|
||||
} else
|
||||
} else {
|
||||
snprintf(avc->filename, 1024, "rtp://0.0.0.0");
|
||||
}
|
||||
|
||||
avc->streams = av_malloc_array(avc->nb_streams, sizeof(*avc->streams));
|
||||
if (!avc->streams)
|
||||
@@ -2894,7 +2887,7 @@ static int prepare_sdp_description(FFServerStream *stream, uint8_t **pbuffer,
|
||||
|
||||
static void rtsp_cmd_options(HTTPContext *c, const char *url)
|
||||
{
|
||||
/* rtsp_reply_header(c, RTSP_STATUS_OK); */
|
||||
// rtsp_reply_header(c, RTSP_STATUS_OK);
|
||||
avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK");
|
||||
avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
|
||||
avio_printf(c->pb, "Public: %s\r\n",
|
||||
@@ -3061,7 +3054,7 @@ static void rtsp_cmd_setup(HTTPContext *c, const char *url,
|
||||
}
|
||||
|
||||
/* test if stream is OK (test needed because several SETUP needs
|
||||
* to be done for a given file) */
|
||||
to be done for a given file) */
|
||||
if (rtp_c->stream != stream) {
|
||||
rtsp_reply_error(c, RTSP_STATUS_SERVICE);
|
||||
return;
|
||||
@@ -3122,10 +3115,8 @@ static void rtsp_cmd_setup(HTTPContext *c, const char *url,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* find an RTP connection by using the session ID. Check consistency
|
||||
* with filename
|
||||
*/
|
||||
/* find an RTP connection by using the session ID. Check consistency
|
||||
with filename */
|
||||
static HTTPContext *find_rtp_session_with_url(const char *url,
|
||||
const char *session_id)
|
||||
{
|
||||
@@ -3148,10 +3139,10 @@ static HTTPContext *find_rtp_session_with_url(const char *url,
|
||||
for(s=0; s<rtp_c->stream->nb_streams; ++s) {
|
||||
snprintf(buf, sizeof(buf), "%s/streamid=%d",
|
||||
rtp_c->stream->filename, s);
|
||||
if(!strncmp(path, buf, sizeof(buf)))
|
||||
/* XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE
|
||||
* if nb_streams>1? */
|
||||
if(!strncmp(path, buf, sizeof(buf))) {
|
||||
// XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1?
|
||||
return rtp_c;
|
||||
}
|
||||
}
|
||||
len = strlen(path);
|
||||
if (len > 0 && path[len - 1] == '/' &&
|
||||
@@ -3229,7 +3220,7 @@ static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
|
||||
const char *proto_str;
|
||||
|
||||
/* XXX: should output a warning page when coming
|
||||
* close to the connection limit */
|
||||
close to the connection limit */
|
||||
if (nb_connections >= config.nb_max_connections)
|
||||
goto fail;
|
||||
|
||||
@@ -3284,11 +3275,9 @@ static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* add a new RTP stream in an RTP connection (used in RTSP SETUP
|
||||
* command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is
|
||||
* used.
|
||||
*/
|
||||
/* add a new RTP stream in an RTP connection (used in RTSP SETUP
|
||||
command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is
|
||||
used. */
|
||||
static int rtp_new_av_stream(HTTPContext *c,
|
||||
int stream_index, struct sockaddr_in *dest_addr,
|
||||
HTTPContext *rtsp_c)
|
||||
@@ -3366,10 +3355,10 @@ static int rtp_new_av_stream(HTTPContext *c,
|
||||
|
||||
/* 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)
|
||||
if (ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) {
|
||||
/* XXX: close stream */
|
||||
goto fail;
|
||||
|
||||
}
|
||||
if (avformat_write_header(ctx, NULL) < 0) {
|
||||
fail:
|
||||
if (h)
|
||||
@@ -3406,12 +3395,12 @@ static AVStream *add_av_stream1(FFServerStream *stream,
|
||||
return NULL;
|
||||
}
|
||||
avcodec_copy_context(fst->codec, codec);
|
||||
} else
|
||||
} else {
|
||||
/* live streams must use the actual feed's codec since it may be
|
||||
* updated later to carry extradata needed by them.
|
||||
*/
|
||||
fst->codec = codec;
|
||||
|
||||
}
|
||||
fst->priv_data = av_mallocz(sizeof(FeedData));
|
||||
fst->index = stream->nb_streams;
|
||||
avpriv_set_pts_info(fst, 33, 1, 90000);
|
||||
@@ -3513,7 +3502,7 @@ static void extract_mpeg4_header(AVFormatContext *infile)
|
||||
if (p[0] == 0x00 && p[1] == 0x00 &&
|
||||
p[2] == 0x01 && p[3] == 0xb6) {
|
||||
size = p - pkt.data;
|
||||
st->codec->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
st->codec->extradata_size = size;
|
||||
memcpy(st->codec->extradata, pkt.data, size);
|
||||
break;
|
||||
@@ -3543,7 +3532,7 @@ static void build_file_streams(void)
|
||||
/* open stream */
|
||||
if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
|
||||
/* specific case : if transport stream output to RTP,
|
||||
* we use a raw transport stream reader */
|
||||
we use a raw transport stream reader */
|
||||
av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);
|
||||
}
|
||||
|
||||
@@ -3565,7 +3554,7 @@ static void build_file_streams(void)
|
||||
remove_stream(stream);
|
||||
} else {
|
||||
/* find all the AVStreams inside and reference them in
|
||||
* 'stream' */
|
||||
'stream' */
|
||||
if (avformat_find_stream_info(infile, NULL) < 0) {
|
||||
http_log("Could not find codec parameters from '%s'\n",
|
||||
stream->feed_filename);
|
||||
@@ -3592,17 +3581,16 @@ static void build_feed_streams(void)
|
||||
/* gather all streams */
|
||||
for(stream = config.first_stream; stream; stream = stream->next) {
|
||||
feed = stream->feed;
|
||||
if (!feed)
|
||||
continue;
|
||||
|
||||
if (stream->is_feed) {
|
||||
for(i=0;i<stream->nb_streams;i++)
|
||||
stream->feed_streams[i] = i;
|
||||
} else {
|
||||
/* we handle a stream coming from a feed */
|
||||
for(i=0;i<stream->nb_streams;i++)
|
||||
stream->feed_streams[i] = add_av_stream(feed,
|
||||
stream->streams[i]);
|
||||
if (feed) {
|
||||
if (stream->is_feed) {
|
||||
for(i=0;i<stream->nb_streams;i++)
|
||||
stream->feed_streams[i] = i;
|
||||
} else {
|
||||
/* we handle a stream coming from a feed */
|
||||
for(i=0;i<stream->nb_streams;i++)
|
||||
stream->feed_streams[i] = add_av_stream(feed,
|
||||
stream->streams[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3769,24 +3757,24 @@ static void compute_bandwidth(void)
|
||||
static void handle_child_exit(int sig)
|
||||
{
|
||||
pid_t pid;
|
||||
int status, uptime;
|
||||
int status;
|
||||
|
||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
|
||||
FFServerStream *feed;
|
||||
|
||||
for (feed = config.first_feed; feed; feed = feed->next) {
|
||||
if (feed->pid != pid)
|
||||
continue;
|
||||
if (feed->pid == pid) {
|
||||
int uptime = time(0) - feed->pid_start;
|
||||
|
||||
uptime = time(0) - feed->pid_start;
|
||||
feed->pid = 0;
|
||||
fprintf(stderr,
|
||||
"%s: Pid %"PRId64" exited with status %d after %d seconds\n",
|
||||
feed->filename, (int64_t) pid, status, uptime);
|
||||
feed->pid = 0;
|
||||
fprintf(stderr,
|
||||
"%s: Pid %d exited with status %d after %d seconds\n",
|
||||
feed->filename, pid, status, uptime);
|
||||
|
||||
if (uptime < 30)
|
||||
/* Turn off any more restarts */
|
||||
ffserver_free_child_args(&feed->child_argv);
|
||||
if (uptime < 30)
|
||||
/* Turn off any more restarts */
|
||||
ffserver_free_child_args(&feed->child_argv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3820,8 +3808,6 @@ int main(int argc, char **argv)
|
||||
struct sigaction sigact = { { 0 } };
|
||||
int ret = 0;
|
||||
|
||||
init_dynload();
|
||||
|
||||
config.filename = av_strdup("/etc/ffserver.conf");
|
||||
|
||||
parse_loglevel(argc, argv, options);
|
||||
|
||||
+3
-3
@@ -230,9 +230,9 @@ static void add_codec(FFServerStream *stream, AVCodecContext *av,
|
||||
/* compute default parameters */
|
||||
switch(av->codec_type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
if (!av_dict_get(recommended, "b", NULL, 0)) {
|
||||
if (!av_dict_get(recommended, "ab", NULL, 0)) {
|
||||
av->bit_rate = 64000;
|
||||
av_dict_set_int(&recommended, "b", av->bit_rate, 0);
|
||||
av_dict_set_int(&recommended, "ab", av->bit_rate, 0);
|
||||
WARNING("Setting default value for audio bit rate = %d. "
|
||||
"Use NoDefaults to disable it.\n",
|
||||
av->bit_rate);
|
||||
@@ -923,7 +923,7 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd,
|
||||
ffserver_get_arg(arg, sizeof(arg), p);
|
||||
ffserver_set_float_param(&f, arg, 1000, -FLT_MAX, FLT_MAX, config,
|
||||
"Invalid %s: '%s'\n", cmd, arg);
|
||||
if (ffserver_save_avoption_int("b", (int64_t)lrintf(f),
|
||||
if (ffserver_save_avoption_int("ab", (int64_t)lrintf(f),
|
||||
AV_OPT_FLAG_AUDIO_PARAM, config) < 0)
|
||||
goto nomem;
|
||||
} else if (!av_strcasecmp(cmd, "AudioChannels")) {
|
||||
|
||||
+3
-3
@@ -131,8 +131,8 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data,
|
||||
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));
|
||||
memcpy(u, u_temp, sizeof(*u) * (width - x + 1) / 2);
|
||||
memcpy(v, v_temp, sizeof(*v) * (width - x + 1) / 2);
|
||||
}
|
||||
|
||||
line_end += stride;
|
||||
@@ -151,5 +151,5 @@ AVCodec ff_zero12v_decoder = {
|
||||
.id = AV_CODEC_ID_012V,
|
||||
.init = zero12v_decode_init,
|
||||
.decode = zero12v_decode_frame,
|
||||
.capabilities = AV_CODEC_CAP_DR1,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
};
|
||||
|
||||
+9
-17
@@ -158,7 +158,7 @@ typedef struct FourXContext {
|
||||
#define FIX_1_847759065 121095
|
||||
#define FIX_2_613125930 171254
|
||||
|
||||
#define MULTIPLY(var, const) ((int)((var) * (unsigned)(const)) >> 16)
|
||||
#define MULTIPLY(var, const) (((var) * (const)) >> 16)
|
||||
|
||||
static void idct(int16_t block[64])
|
||||
{
|
||||
@@ -351,8 +351,6 @@ static int decode_p_block(FourXContext *f, uint16_t *dst, const uint16_t *src,
|
||||
index = size2index[log2h][log2w];
|
||||
av_assert0(index >= 0);
|
||||
|
||||
if (get_bits_left(&f->gb) < 1)
|
||||
return AVERROR_INVALIDDATA;
|
||||
h = 1 << log2h;
|
||||
code = get_vlc2(&f->gb, block_type_vlc[1 - (f->version > 1)][index].table,
|
||||
BLOCK_TYPE_VLC_BITS, 1);
|
||||
@@ -498,9 +496,9 @@ static int decode_i_block(FourXContext *f, int16_t *block)
|
||||
{
|
||||
int code, i, j, level, val;
|
||||
|
||||
if (get_bits_left(&f->pre_gb) < 2) {
|
||||
av_log(f->avctx, AV_LOG_ERROR, "%d bits left before decode_i_block()\n", get_bits_left(&f->pre_gb));
|
||||
return AVERROR_INVALIDDATA;
|
||||
if (get_bits_left(&f->gb) < 2){
|
||||
av_log(f->avctx, AV_LOG_ERROR, "%d bits left before decode_i_block()\n", get_bits_left(&f->gb));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* DC coef */
|
||||
@@ -525,10 +523,6 @@ static int decode_i_block(FourXContext *f, int16_t *block)
|
||||
break;
|
||||
if (code == 0xf0) {
|
||||
i += 16;
|
||||
if (i >= 64) {
|
||||
av_log(f->avctx, AV_LOG_ERROR, "run %d overflow\n", i);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (code & 0xf) {
|
||||
level = get_xbits(&f->gb, code & 0xf);
|
||||
@@ -565,7 +559,7 @@ static inline void idct_put(FourXContext *f, int x, int y)
|
||||
idct(block[i]);
|
||||
}
|
||||
|
||||
if (!(f->avctx->flags & AV_CODEC_FLAG_GRAY)) {
|
||||
if (!(f->avctx->flags & CODEC_FLAG_GRAY)) {
|
||||
for (i = 4; i < 6; i++)
|
||||
idct(block[i]);
|
||||
}
|
||||
@@ -738,7 +732,7 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length)
|
||||
for (x = 0; x < width; x += 16) {
|
||||
unsigned int color[4] = { 0 }, bits;
|
||||
if (buf_end - buf < 8)
|
||||
return AVERROR_INVALIDDATA;
|
||||
return -1;
|
||||
// warning following is purely guessed ...
|
||||
color[0] = bytestream2_get_le16u(&g3);
|
||||
color[1] = bytestream2_get_le16u(&g3);
|
||||
@@ -884,18 +878,16 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
}
|
||||
|
||||
if (i >= CFRAME_BUFFER_COUNT) {
|
||||
if (free_index < 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
i = free_index;
|
||||
f->cfrm[i].id = id;
|
||||
}
|
||||
cfrm = &f->cfrm[i];
|
||||
|
||||
if (data_size > UINT_MAX - cfrm->size - AV_INPUT_BUFFER_PADDING_SIZE)
|
||||
if (data_size > UINT_MAX - cfrm->size - FF_INPUT_BUFFER_PADDING_SIZE)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
cfrm->data = av_fast_realloc(cfrm->data, &cfrm->allocated_size,
|
||||
cfrm->size + data_size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
// explicit check needed as memcpy below might not catch a NULL
|
||||
if (!cfrm->data) {
|
||||
av_log(f->avctx, AV_LOG_ERROR, "realloc failure\n");
|
||||
@@ -1034,5 +1026,5 @@ AVCodec ff_fourxm_decoder = {
|
||||
.init = decode_init,
|
||||
.close = decode_end,
|
||||
.decode = decode_frame,
|
||||
.capabilities = AV_CODEC_CAP_DR1,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
};
|
||||
|
||||
+3
-9
@@ -70,9 +70,6 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
unsigned char *planemap = c->planemap;
|
||||
int ret;
|
||||
|
||||
if (buf_size < planes * height *2)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
|
||||
return ret;
|
||||
|
||||
@@ -123,15 +120,12 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
}
|
||||
|
||||
if (avctx->bits_per_coded_sample <= 8) {
|
||||
int size;
|
||||
const uint8_t *pal = av_packet_get_side_data(avpkt,
|
||||
AV_PKT_DATA_PALETTE,
|
||||
&size);
|
||||
if (pal && size == AVPALETTE_SIZE) {
|
||||
NULL);
|
||||
if (pal) {
|
||||
frame->palette_has_changed = 1;
|
||||
memcpy(c->pal, pal, AVPALETTE_SIZE);
|
||||
} else if (pal) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Palette size %d is wrong\n", size);
|
||||
}
|
||||
|
||||
memcpy (frame->data[1], c->pal, AVPALETTE_SIZE);
|
||||
@@ -190,5 +184,5 @@ AVCodec ff_eightbps_decoder = {
|
||||
.priv_data_size = sizeof(EightBpsContext),
|
||||
.init = decode_init,
|
||||
.decode = decode_frame,
|
||||
.capabilities = AV_CODEC_CAP_DR1,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
};
|
||||
|
||||
+2
-2
@@ -194,7 +194,7 @@ AVCodec ff_eightsvx_fib_decoder = {
|
||||
.init = eightsvx_decode_init,
|
||||
.decode = eightsvx_decode_frame,
|
||||
.close = eightsvx_decode_close,
|
||||
.capabilities = AV_CODEC_CAP_DR1,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
};
|
||||
@@ -209,7 +209,7 @@ AVCodec ff_eightsvx_exp_decoder = {
|
||||
.init = eightsvx_decode_init,
|
||||
.decode = eightsvx_decode_frame,
|
||||
.close = eightsvx_decode_close,
|
||||
.capabilities = AV_CODEC_CAP_DR1,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
};
|
||||
|
||||
+37
-83
@@ -13,7 +13,6 @@ HEADERS = avcodec.h \
|
||||
vda.h \
|
||||
vdpau.h \
|
||||
version.h \
|
||||
videotoolbox.h \
|
||||
vorbis_parser.h \
|
||||
xvmc.h \
|
||||
|
||||
@@ -57,7 +56,6 @@ 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_FLACDSP) += flacdsp.o
|
||||
OBJS-$(CONFIG_FMTCONVERT) += fmtconvert.o
|
||||
OBJS-$(CONFIG_GOLOMB) += golomb.o
|
||||
OBJS-$(CONFIG_H263DSP) += h263dsp.o
|
||||
@@ -73,7 +71,6 @@ OBJS-$(CONFIG_IDCTDSP) += idctdsp.o simple_idct.o jrevdct.o
|
||||
OBJS-$(CONFIG_IIRFILTER) += iirfilter.o
|
||||
OBJS-$(CONFIG_IMDCT15) += imdct15.o
|
||||
OBJS-$(CONFIG_INTRAX8) += intrax8.o intrax8dsp.o
|
||||
OBJS-$(CONFIG_IVIDSP) += ivi_dsp.o
|
||||
OBJS-$(CONFIG_JPEGTABLES) += jpegtables.o
|
||||
OBJS-$(CONFIG_LIBXVID) += libxvid_rc.o
|
||||
OBJS-$(CONFIG_LLAUDDSP) += lossless_audiodsp.o
|
||||
@@ -91,11 +88,10 @@ OBJS-$(CONFIG_MPEGAUDIODSP) += mpegaudiodsp.o \
|
||||
mpegaudiodsp_float.o
|
||||
OBJS-$(CONFIG_MPEGVIDEO) += mpegvideo.o mpegvideodsp.o rl.o \
|
||||
mpegvideo_motion.o mpegutils.o \
|
||||
mpegvideodata.o mpegpicture.o
|
||||
mpegvideodata.o
|
||||
OBJS-$(CONFIG_MPEGVIDEOENC) += mpegvideo_enc.o mpeg12data.o \
|
||||
motion_est.o ratecontrol.o \
|
||||
mpegvideoencdsp.o
|
||||
OBJS-$(CONFIG_MSS34DSP) += mss34dsp.o
|
||||
OBJS-$(CONFIG_NVENC) += nvenc.o
|
||||
OBJS-$(CONFIG_PIXBLOCKDSP) += pixblockdsp.o
|
||||
OBJS-$(CONFIG_QPELDSP) += qpeldsp.o
|
||||
@@ -105,36 +101,23 @@ OBJS-$(CONFIG_QSVENC) += qsvenc.o
|
||||
OBJS-$(CONFIG_RANGECODER) += rangecoder.o
|
||||
RDFT-OBJS-$(CONFIG_HARDCODED_TABLES) += sin_tables.o
|
||||
OBJS-$(CONFIG_RDFT) += rdft.o $(RDFT-OBJS-yes)
|
||||
OBJS-$(CONFIG_RV34DSP) += rv34dsp.o
|
||||
OBJS-$(CONFIG_SHARED) += log2_tab.o reverse.o
|
||||
OBJS-$(CONFIG_SINEWIN) += sinewin.o sinewin_fixed.o
|
||||
OBJS-$(CONFIG_SNAPPY) += snappy.o
|
||||
OBJS-$(CONFIG_SHARED) += log2_tab.o
|
||||
OBJS-$(CONFIG_SINEWIN) += sinewin.o
|
||||
OBJS-$(CONFIG_STARTCODE) += startcode.o
|
||||
OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o
|
||||
OBJS-$(CONFIG_TEXTUREDSPENC) += texturedspenc.o
|
||||
OBJS-$(CONFIG_TPELDSP) += tpeldsp.o
|
||||
OBJS-$(CONFIG_VIDEODSP) += videodsp.o
|
||||
OBJS-$(CONFIG_VP3DSP) += vp3dsp.o
|
||||
OBJS-$(CONFIG_VP56DSP) += vp56dsp.o
|
||||
OBJS-$(CONFIG_VP8DSP) += vp8dsp.o
|
||||
OBJS-$(CONFIG_WMA_FREQS) += wma_freqs.o
|
||||
OBJS-$(CONFIG_WMV2DSP) += wmv2dsp.o
|
||||
|
||||
# decoders/encoders
|
||||
OBJS-$(CONFIG_ZERO12V_DECODER) += 012v.o
|
||||
OBJS-$(CONFIG_A64MULTI_ENCODER) += a64multienc.o elbg.o
|
||||
OBJS-$(CONFIG_A64MULTI5_ENCODER) += a64multienc.o elbg.o
|
||||
OBJS-$(CONFIG_AAC_DECODER) += aacdec.o aactab.o aacsbr.o aacps_float.o \
|
||||
OBJS-$(CONFIG_AAC_DECODER) += aacdec.o aactab.o aacsbr.o aacps.o \
|
||||
aacadtsdec.o mpeg4audio.o kbdwin.o \
|
||||
sbrdsp.o aacpsdsp_float.o
|
||||
OBJS-$(CONFIG_AAC_FIXED_DECODER) += aacdec_fixed.o aactab.o aacsbr_fixed.o aacps_fixed.o \
|
||||
aacadtsdec.o mpeg4audio.o kbdwin.o \
|
||||
sbrdsp_fixed.o aacpsdsp_fixed.o
|
||||
OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacenctab.o \
|
||||
sbrdsp.o aacpsdsp.o
|
||||
OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o \
|
||||
aacpsy.o aactab.o \
|
||||
aacenc_is.o \
|
||||
aacenc_tns.o \
|
||||
aacenc_pred.o \
|
||||
psymodel.o mpeg4audio.o kbdwin.o
|
||||
OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o
|
||||
OBJS-$(CONFIG_AC3_DECODER) += ac3dec_float.o ac3dec_data.o ac3.o kbdwin.o
|
||||
@@ -219,7 +202,6 @@ OBJS-$(CONFIG_DCA_DECODER) += dcadec.o dca.o dcadsp.o \
|
||||
dcadata.o dca_exss.o \
|
||||
dca_xll.o synth_filter.o
|
||||
OBJS-$(CONFIG_DCA_ENCODER) += dcaenc.o dca.o dcadata.o
|
||||
OBJS-$(CONFIG_DDS_DECODER) += dds.o
|
||||
OBJS-$(CONFIG_DIRAC_DECODER) += diracdec.o dirac.o diracdsp.o \
|
||||
dirac_arith.o mpeg12data.o dirac_dwt.o
|
||||
OBJS-$(CONFIG_DFA_DECODER) += dfa.o
|
||||
@@ -261,8 +243,8 @@ OBJS-$(CONFIG_FFV1_DECODER) += ffv1dec.o ffv1.o
|
||||
OBJS-$(CONFIG_FFV1_ENCODER) += ffv1enc.o ffv1.o
|
||||
OBJS-$(CONFIG_FFWAVESYNTH_DECODER) += ffwavesynth.o
|
||||
OBJS-$(CONFIG_FIC_DECODER) += fic.o
|
||||
OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o
|
||||
OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o vorbis_data.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
|
||||
OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o
|
||||
OBJS-$(CONFIG_FLASHSV2_ENCODER) += flashsv2enc.o
|
||||
@@ -271,7 +253,7 @@ OBJS-$(CONFIG_FLIC_DECODER) += flicvideo.o
|
||||
OBJS-$(CONFIG_FOURXM_DECODER) += 4xm.o
|
||||
OBJS-$(CONFIG_FRAPS_DECODER) += fraps.o
|
||||
OBJS-$(CONFIG_FRWU_DECODER) += frwu.o
|
||||
OBJS-$(CONFIG_G2M_DECODER) += g2meet.o elsdec.o
|
||||
OBJS-$(CONFIG_G2M_DECODER) += g2meet.o
|
||||
OBJS-$(CONFIG_G723_1_DECODER) += g723_1.o acelp_vectors.o \
|
||||
celp_filters.o celp_math.o
|
||||
OBJS-$(CONFIG_G723_1_ENCODER) += g723_1.o acelp_vectors.o celp_math.o
|
||||
@@ -284,24 +266,20 @@ OBJS-$(CONFIG_H261_DECODER) += h261dec.o h261data.o h261.o
|
||||
OBJS-$(CONFIG_H261_ENCODER) += h261enc.o h261data.o h261.o
|
||||
OBJS-$(CONFIG_H263_DECODER) += h263dec.o h263.o ituh263dec.o \
|
||||
mpeg4video.o mpeg4videodec.o flvdec.o\
|
||||
intelh263dec.o h263data.o
|
||||
intelh263dec.o
|
||||
OBJS-$(CONFIG_H263_ENCODER) += mpeg4videoenc.o mpeg4video.o \
|
||||
h263.o h263data.o ituh263enc.o flvenc.o
|
||||
h263.o ituh263enc.o flvenc.o
|
||||
OBJS-$(CONFIG_H264_DECODER) += h264.o h264_cabac.o h264_cavlc.o \
|
||||
h264_direct.o h264_loopfilter.o \
|
||||
h264_mb.o h264_picture.o h264_ps.o \
|
||||
h264_refs.o h264_sei.o h264_slice.o
|
||||
OBJS-$(CONFIG_H264_MMAL_DECODER) += mmaldec.o
|
||||
OBJS-$(CONFIG_H264_VDA_DECODER) += vda_h264_dec.o
|
||||
OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec_h2645.o
|
||||
OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec_h264.o
|
||||
OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o
|
||||
OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o
|
||||
OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.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 hevc_parse.o hevc_data.o
|
||||
OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec_h2645.o
|
||||
OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o hevc_parse.o
|
||||
hevcdsp.o hevc_filter.o
|
||||
OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o
|
||||
OBJS-$(CONFIG_HQ_HQA_DECODER) += hq_hqa.o hq_hqadata.o hq_hqadsp.o \
|
||||
canopus.o
|
||||
@@ -315,8 +293,8 @@ OBJS-$(CONFIG_IFF_ILBM_DECODER) += iff.o
|
||||
OBJS-$(CONFIG_IMC_DECODER) += imc.o
|
||||
OBJS-$(CONFIG_INDEO2_DECODER) += indeo2.o
|
||||
OBJS-$(CONFIG_INDEO3_DECODER) += indeo3.o
|
||||
OBJS-$(CONFIG_INDEO4_DECODER) += indeo4.o ivi.o
|
||||
OBJS-$(CONFIG_INDEO5_DECODER) += indeo5.o ivi.o
|
||||
OBJS-$(CONFIG_INDEO4_DECODER) += indeo4.o ivi.o ivi_dsp.o
|
||||
OBJS-$(CONFIG_INDEO5_DECODER) += indeo5.o ivi.o ivi_dsp.o
|
||||
OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER) += dpcm.o
|
||||
OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o
|
||||
OBJS-$(CONFIG_JACOSUB_DECODER) += jacosubdec.o ass.o
|
||||
@@ -368,8 +346,6 @@ 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_MPEG2_QSV_DECODER) += qsvdec_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_QSV_ENCODER) += qsvenc_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG4_DECODER) += xvididct.o
|
||||
OBJS-$(CONFIG_MPL2_DECODER) += mpl2dec.o ass.o
|
||||
OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
@@ -378,13 +354,13 @@ 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_MSRLE_DECODER) += msrle.o msrledec.o
|
||||
OBJS-$(CONFIG_MSA1_DECODER) += mss3.o
|
||||
OBJS-$(CONFIG_MSA1_DECODER) += mss3.o mss34dsp.o
|
||||
OBJS-$(CONFIG_MSS1_DECODER) += mss1.o mss12.o
|
||||
OBJS-$(CONFIG_MSS2_DECODER) += mss2.o mss12.o mss2dsp.o
|
||||
OBJS-$(CONFIG_MSVIDEO1_DECODER) += msvideo1.o
|
||||
OBJS-$(CONFIG_MSVIDEO1_ENCODER) += msvideo1enc.o elbg.o
|
||||
OBJS-$(CONFIG_MSZH_DECODER) += lcldec.o
|
||||
OBJS-$(CONFIG_MTS2_DECODER) += mss4.o
|
||||
OBJS-$(CONFIG_MTS2_DECODER) += mss4.o mss34dsp.o
|
||||
OBJS-$(CONFIG_MVC1_DECODER) += mvcdec.o
|
||||
OBJS-$(CONFIG_MVC2_DECODER) += mvcdec.o
|
||||
OBJS-$(CONFIG_MXPEG_DECODER) += mxpegdec.o
|
||||
@@ -448,8 +424,8 @@ OBJS-$(CONFIG_RV10_DECODER) += rv10.o
|
||||
OBJS-$(CONFIG_RV10_ENCODER) += rv10enc.o
|
||||
OBJS-$(CONFIG_RV20_DECODER) += rv10.o
|
||||
OBJS-$(CONFIG_RV20_ENCODER) += rv20enc.o
|
||||
OBJS-$(CONFIG_RV30_DECODER) += rv30.o rv34.o rv30dsp.o
|
||||
OBJS-$(CONFIG_RV40_DECODER) += rv40.o rv34.o rv40dsp.o
|
||||
OBJS-$(CONFIG_RV30_DECODER) += rv30.o rv34.o rv30dsp.o rv34dsp.o
|
||||
OBJS-$(CONFIG_RV40_DECODER) += rv40.o rv34.o rv34dsp.o rv40dsp.o
|
||||
OBJS-$(CONFIG_SAMI_DECODER) += samidec.o ass.o
|
||||
OBJS-$(CONFIG_S302M_DECODER) += s302m.o
|
||||
OBJS-$(CONFIG_S302M_ENCODER) += s302menc.o
|
||||
@@ -506,7 +482,7 @@ OBJS-$(CONFIG_TSCC2_DECODER) += tscc2.o
|
||||
OBJS-$(CONFIG_TTA_DECODER) += tta.o ttadata.o ttadsp.o
|
||||
OBJS-$(CONFIG_TTA_ENCODER) += ttaenc.o ttadata.o
|
||||
OBJS-$(CONFIG_TWINVQ_DECODER) += twinvqdec.o twinvq.o
|
||||
OBJS-$(CONFIG_TXD_DECODER) += txd.o
|
||||
OBJS-$(CONFIG_TXD_DECODER) += txd.o s3tc.o
|
||||
OBJS-$(CONFIG_ULTI_DECODER) += ulti.o
|
||||
OBJS-$(CONFIG_UTVIDEO_DECODER) += utvideodec.o utvideo.o
|
||||
OBJS-$(CONFIG_UTVIDEO_ENCODER) += utvideoenc.o utvideo.o
|
||||
@@ -526,7 +502,6 @@ OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1_block.o vc1_loopfilter.o
|
||||
vc1dsp.o \
|
||||
msmpeg4dec.o msmpeg4.o msmpeg4data.o \
|
||||
wmv2dsp.o
|
||||
OBJS-$(CONFIG_VC1_QSV_DECODER) += qsvdec_vc1.o
|
||||
OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o
|
||||
OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdaudio.o
|
||||
OBJS-$(CONFIG_VMDVIDEO_DECODER) += vmdvideo.o
|
||||
@@ -536,11 +511,12 @@ OBJS-$(CONFIG_VORBIS_DECODER) += vorbisdec.o vorbisdsp.o vorbis.o \
|
||||
OBJS-$(CONFIG_VORBIS_ENCODER) += vorbisenc.o vorbis.o \
|
||||
vorbis_data.o
|
||||
OBJS-$(CONFIG_VP3_DECODER) += vp3.o
|
||||
OBJS-$(CONFIG_VP5_DECODER) += vp5.o vp56.o vp56data.o vp56rac.o
|
||||
OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o \
|
||||
OBJS-$(CONFIG_VP5_DECODER) += vp5.o vp56.o vp56data.o vp56dsp.o \
|
||||
vp56rac.o
|
||||
OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o vp56dsp.o \
|
||||
vp6dsp.o vp56rac.o
|
||||
OBJS-$(CONFIG_VP7_DECODER) += vp8.o vp56rac.o
|
||||
OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp56rac.o
|
||||
OBJS-$(CONFIG_VP7_DECODER) += vp8.o vp8dsp.o vp56rac.o
|
||||
OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp8dsp.o vp56rac.o
|
||||
OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9dsp.o vp56rac.o vp9dsp_8bpp.o \
|
||||
vp9dsp_10bpp.o vp9dsp_12bpp.o
|
||||
OBJS-$(CONFIG_VPLAYER_DECODER) += textdec.o ass.o
|
||||
@@ -562,9 +538,9 @@ OBJS-$(CONFIG_WMAVOICE_DECODER) += wmavoice.o \
|
||||
acelp_vectors.o acelp_filters.o
|
||||
OBJS-$(CONFIG_WMV1_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_WMV1_ENCODER) += msmpeg4enc.o
|
||||
OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o \
|
||||
OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o wmv2dsp.o \
|
||||
msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o \
|
||||
OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o wmv2dsp.o \
|
||||
msmpeg4.o msmpeg4enc.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o
|
||||
OBJS-$(CONFIG_WS_SND1_DECODER) += ws-snd1.o
|
||||
@@ -700,35 +676,27 @@ OBJS-$(CONFIG_VIMA_DECODER) += vima.o adpcm_data.o
|
||||
OBJS-$(CONFIG_D3D11VA) += dxva2.o
|
||||
OBJS-$(CONFIG_DXVA2) += dxva2.o
|
||||
OBJS-$(CONFIG_VAAPI) += vaapi.o
|
||||
OBJS-$(CONFIG_VDA) += vda.o videotoolbox.o
|
||||
OBJS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.o
|
||||
OBJS-$(CONFIG_VDA) += vda.o
|
||||
OBJS-$(CONFIG_VDPAU) += vdpau.o
|
||||
|
||||
OBJS-$(CONFIG_H263_VAAPI_HWACCEL) += vaapi_mpeg4.o
|
||||
OBJS-$(CONFIG_H263_VDPAU_HWACCEL) += vdpau_mpeg4.o
|
||||
OBJS-$(CONFIG_H263_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o
|
||||
OBJS-$(CONFIG_H264_D3D11VA_HWACCEL) += dxva2_h264.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_H264_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o
|
||||
OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL) += dxva2_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL) += dxva2_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_VAAPI_HWACCEL) += vaapi_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o
|
||||
OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL) += vdpau_mpeg12.o
|
||||
OBJS-$(CONFIG_MPEG1_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o
|
||||
OBJS-$(CONFIG_MPEG1_XVMC_HWACCEL) += mpegvideo_xvmc.o
|
||||
OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL) += dxva2_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o
|
||||
OBJS-$(CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o
|
||||
OBJS-$(CONFIG_MPEG2_XVMC_HWACCEL) += mpegvideo_xvmc.o
|
||||
OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o
|
||||
OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL) += vdpau_mpeg4.o
|
||||
OBJS-$(CONFIG_MPEG4_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o
|
||||
OBJS-$(CONFIG_VC1_D3D11VA_HWACCEL) += dxva2_vc1.o
|
||||
OBJS-$(CONFIG_VC1_DXVA2_HWACCEL) += dxva2_vc1.o
|
||||
OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o
|
||||
@@ -789,7 +757,6 @@ OBJS-$(CONFIG_LIBGSM_MS_DECODER) += libgsmdec.o
|
||||
OBJS-$(CONFIG_LIBGSM_MS_ENCODER) += libgsmenc.o
|
||||
OBJS-$(CONFIG_LIBILBC_DECODER) += libilbc.o
|
||||
OBJS-$(CONFIG_LIBILBC_ENCODER) += libilbc.o
|
||||
OBJS-$(CONFIG_LIBKVAZAAR_ENCODER) += libkvazaar.o
|
||||
OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o mpegaudiodecheader.o
|
||||
OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o
|
||||
OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o
|
||||
@@ -825,7 +792,6 @@ OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o libvpx.o
|
||||
OBJS-$(CONFIG_LIBWAVPACK_ENCODER) += libwavpackenc.o
|
||||
OBJS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.o libwebpenc.o
|
||||
OBJS-$(CONFIG_LIBWEBP_ANIM_ENCODER) += libwebpenc_common.o libwebpenc_animencoder.o
|
||||
OBJS-$(CONFIG_LIBX262_ENCODER) += libx264.o
|
||||
OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o
|
||||
OBJS-$(CONFIG_LIBX265_ENCODER) += libx265.o
|
||||
OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o
|
||||
@@ -851,17 +817,16 @@ OBJS-$(CONFIG_DVD_NAV_PARSER) += dvd_nav_parser.o
|
||||
OBJS-$(CONFIG_DVDSUB_PARSER) += dvdsub_parser.o
|
||||
OBJS-$(CONFIG_FLAC_PARSER) += flac_parser.o flacdata.o flac.o \
|
||||
vorbis_data.o
|
||||
OBJS-$(CONFIG_G729_PARSER) += g729_parser.o
|
||||
OBJS-$(CONFIG_GSM_PARSER) += gsm_parser.o
|
||||
OBJS-$(CONFIG_H261_PARSER) += h261_parser.o
|
||||
OBJS-$(CONFIG_H263_PARSER) += h263_parser.o
|
||||
OBJS-$(CONFIG_H264_PARSER) += h264_parser.o
|
||||
OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o hevc_parse.o hevc_ps.o hevc_data.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 \
|
||||
mpeg4videodec.o mpeg4video.o \
|
||||
ituh263dec.o h263dec.o h263data.o
|
||||
ituh263dec.o h263dec.o
|
||||
OBJS-$(CONFIG_PNG_PARSER) += png_parser.o
|
||||
OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o \
|
||||
mpegaudiodecheader.o mpegaudiodata.o
|
||||
@@ -884,7 +849,6 @@ OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o aacadtsdec.o \
|
||||
OBJS-$(CONFIG_CHOMP_BSF) += chomp_bsf.o
|
||||
OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o
|
||||
OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += h264_mp4toannexb_bsf.o
|
||||
OBJS-$(CONFIG_HEVC_MP4TOANNEXB_BSF) += hevc_mp4toannexb_bsf.o
|
||||
OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o
|
||||
OBJS-$(CONFIG_MJPEG2JPEG_BSF) += mjpeg2jpeg_bsf.o
|
||||
OBJS-$(CONFIG_MJPEGA_DUMP_HEADER_BSF) += mjpega_dump_header_bsf.o
|
||||
@@ -909,6 +873,7 @@ SKIPHEADERS += %_tablegen.h \
|
||||
%_tables.h \
|
||||
aac_tablegen_decl.h \
|
||||
fft-internal.h \
|
||||
libutvideo.h \
|
||||
old_codec_ids.h \
|
||||
tableprint.h \
|
||||
tableprint_vlc.h \
|
||||
@@ -918,22 +883,21 @@ SKIPHEADERS-$(CONFIG_D3D11VA) += d3d11va.h dxva2_internal.h
|
||||
SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h
|
||||
SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h
|
||||
SKIPHEADERS-$(CONFIG_LIBUTVIDEO) += libutvideo.h
|
||||
SKIPHEADERS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.h
|
||||
SKIPHEADERS-$(CONFIG_QSV) += qsv.h qsv_internal.h
|
||||
SKIPHEADERS-$(CONFIG_QSVDEC) += qsvdec.h
|
||||
SKIPHEADERS-$(CONFIG_QSVENC) += qsvenc.h
|
||||
SKIPHEADERS-$(CONFIG_XVMC) += xvmc.h
|
||||
SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_internal.h
|
||||
SKIPHEADERS-$(CONFIG_VDA) += vda.h vda_vt_internal.h
|
||||
SKIPHEADERS-$(CONFIG_VDA) += vda.h vda_internal.h
|
||||
SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h
|
||||
SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.h vda_vt_internal.h
|
||||
|
||||
TESTPROGS = imgconvert \
|
||||
jpeg2000dwt \
|
||||
mathops \
|
||||
options \
|
||||
avfft \
|
||||
|
||||
TESTPROGS += api-flac
|
||||
|
||||
TESTPROGS-$(CONFIG_CABAC) += cabac
|
||||
TESTPROGS-$(CONFIG_FFT) += fft fft-fixed fft-fixed32
|
||||
TESTPROGS-$(CONFIG_IDCTDSP) += dct
|
||||
@@ -949,12 +913,9 @@ TOOLS = fourcc2pixfmt
|
||||
|
||||
HOSTPROGS = aac_tablegen \
|
||||
aacps_tablegen \
|
||||
aacps_fixed_tablegen \
|
||||
aacsbr_tablegen \
|
||||
aacsbr_fixed_tablegen \
|
||||
cabac_tablegen \
|
||||
cbrt_tablegen \
|
||||
cbrt_fixed_tablegen \
|
||||
cos_tablegen \
|
||||
dsd_tablegen \
|
||||
dv_tablegen \
|
||||
@@ -963,7 +924,6 @@ HOSTPROGS = aac_tablegen \
|
||||
pcm_tablegen \
|
||||
qdm2_tablegen \
|
||||
sinewin_tablegen \
|
||||
sinewin_fixed_tablegen \
|
||||
|
||||
CLEANFILES = *_tables.c *_tables.h *_tablegen$(HOSTEXESUF)
|
||||
|
||||
@@ -982,9 +942,8 @@ else
|
||||
$(SUBDIR)%_tablegen$(HOSTEXESUF): HOSTCFLAGS += -DCONFIG_SMALL=0
|
||||
endif
|
||||
|
||||
GEN_HEADERS = cabac_tables.h cbrt_tables.h cbrt_fixed_tables.h aacps_tables.h aacps_fixed_tables.h aacsbr_tables.h \
|
||||
aacsbr_fixed_tables.h aac_tables.h dsd_tables.h dv_tables.h \
|
||||
sinewin_tables.h sinewin_fixed_tables.h mpegaudio_tables.h motionpixels_tables.h \
|
||||
GEN_HEADERS = cabac_tables.h cbrt_tables.h aacps_tables.h aacsbr_tables.h aac_tables.h dsd_tables.h dv_tables.h \
|
||||
sinewin_tables.h mpegaudio_tables.h motionpixels_tables.h \
|
||||
pcm_tables.h qdm2_tables.h
|
||||
GEN_HEADERS := $(addprefix $(SUBDIR), $(GEN_HEADERS))
|
||||
|
||||
@@ -993,18 +952,13 @@ $(GEN_HEADERS): $(SUBDIR)%_tables.h: $(SUBDIR)%_tablegen$(HOSTEXESUF)
|
||||
|
||||
ifdef CONFIG_HARDCODED_TABLES
|
||||
$(SUBDIR)aacdec.o: $(SUBDIR)cbrt_tables.h
|
||||
$(SUBDIR)aacdec_fixed.o: $(SUBDIR)cbrt_fixed_tables.h
|
||||
$(SUBDIR)aacps_float.o: $(SUBDIR)aacps_tables.h
|
||||
$(SUBDIR)aacps_fixed.o: $(SUBDIR)aacps_fixed_tables.h
|
||||
$(SUBDIR)aacps.o: $(SUBDIR)aacps_tables.h
|
||||
$(SUBDIR)aacsbr.o: $(SUBDIR)aacsbr_tables.h
|
||||
$(SUBDIR)aacsbr_fixed.o: $(SUBDIR)aacsbr_fixed_tables.h
|
||||
$(SUBDIR)aactab.o: $(SUBDIR)aac_tables.h
|
||||
$(SUBDIR)aactab_fixed.o: $(SUBDIR)aac_fixed_tables.h
|
||||
$(SUBDIR)cabac.o: $(SUBDIR)cabac_tables.h
|
||||
$(SUBDIR)dsddec.o: $(SUBDIR)dsd_tables.h
|
||||
$(SUBDIR)dvenc.o: $(SUBDIR)dv_tables.h
|
||||
$(SUBDIR)sinewin.o: $(SUBDIR)sinewin_tables.h
|
||||
$(SUBDIR)sinewin_fixed.o: $(SUBDIR)sinewin_fixed_tables.h
|
||||
$(SUBDIR)mpegaudiodec_fixed.o: $(SUBDIR)mpegaudio_tables.h
|
||||
$(SUBDIR)mpegaudiodec_float.o: $(SUBDIR)mpegaudio_tables.h
|
||||
$(SUBDIR)motionpixels.o: $(SUBDIR)motionpixels_tables.h
|
||||
|
||||
@@ -66,8 +66,7 @@ static const int mc_colors[5]={0x0,0xb,0xc,0xf,0x1};
|
||||
//static const int mc_colors[5]={0x0,0x8,0xa,0xf,0x7};
|
||||
//static const int mc_colors[5]={0x0,0x9,0x8,0xa,0x3};
|
||||
|
||||
static void to_meta_with_crop(AVCodecContext *avctx,
|
||||
const AVFrame *p, int *dest)
|
||||
static void to_meta_with_crop(AVCodecContext *avctx, const AVFrame *p, int *dest)
|
||||
{
|
||||
int blockx, blocky, x, y;
|
||||
int luma = 0;
|
||||
@@ -235,7 +234,7 @@ static av_cold int a64multi_encode_init(AVCodecContext *avctx)
|
||||
}
|
||||
|
||||
/* set up extradata */
|
||||
if (!(avctx->extradata = av_mallocz(8 * 4 + AV_INPUT_BUFFER_PADDING_SIZE))) {
|
||||
if (!(avctx->extradata = av_mallocz(8 * 4 + FF_INPUT_BUFFER_PADDING_SIZE))) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Failed to allocate memory for extradata.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
@@ -328,7 +327,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
||||
/* any frames to encode? */
|
||||
if (c->mc_lifetime) {
|
||||
int alloc_size = charset_size + c->mc_lifetime*(screen_size + colram_size);
|
||||
if ((ret = ff_alloc_packet2(avctx, pkt, alloc_size, 0)) < 0)
|
||||
if ((ret = ff_alloc_packet2(avctx, pkt, alloc_size)) < 0)
|
||||
return ret;
|
||||
buf = pkt->data;
|
||||
|
||||
@@ -406,7 +405,7 @@ AVCodec ff_a64multi_encoder = {
|
||||
.encode2 = a64multi_encode_frame,
|
||||
.close = a64multi_close_encoder,
|
||||
.pix_fmts = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
|
||||
.capabilities = AV_CODEC_CAP_DELAY,
|
||||
.capabilities = CODEC_CAP_DELAY,
|
||||
};
|
||||
#endif
|
||||
#if CONFIG_A64MULTI5_ENCODER
|
||||
@@ -420,6 +419,6 @@ AVCodec ff_a64multi5_encoder = {
|
||||
.encode2 = a64multi_encode_frame,
|
||||
.close = a64multi_close_encoder,
|
||||
.pix_fmts = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
|
||||
.capabilities = AV_CODEC_CAP_DELAY,
|
||||
.capabilities = CODEC_CAP_DELAY,
|
||||
};
|
||||
#endif
|
||||
|
||||
+23
-49
@@ -30,14 +30,9 @@
|
||||
#ifndef AVCODEC_AAC_H
|
||||
#define AVCODEC_AAC_H
|
||||
|
||||
|
||||
#include "aac_defines.h"
|
||||
#include "libavutil/float_dsp.h"
|
||||
#include "libavutil/fixed_dsp.h"
|
||||
#include "avcodec.h"
|
||||
#if !USE_FIXED
|
||||
#include "imdct15.h"
|
||||
#endif
|
||||
#include "fft.h"
|
||||
#include "mpeg4audio.h"
|
||||
#include "sbr.h"
|
||||
@@ -50,8 +45,6 @@
|
||||
#define TNS_MAX_ORDER 20
|
||||
#define MAX_LTP_LONG_SFB 40
|
||||
|
||||
#define CLIP_AVOIDANCE_FACTOR 0.95f
|
||||
|
||||
enum RawDataBlockType {
|
||||
TYPE_SCE,
|
||||
TYPE_CPE,
|
||||
@@ -83,10 +76,9 @@ enum BandType {
|
||||
ZERO_BT = 0, ///< Scalefactors and spectral data are all zero.
|
||||
FIRST_PAIR_BT = 5, ///< This and later band types encode two values (rather than four) with one code word.
|
||||
ESC_BT = 11, ///< Spectral data are coded with an escape sequence.
|
||||
RESERVED_BT = 12, ///< Band types following are encoded differently from others.
|
||||
NOISE_BT = 13, ///< Spectral data are scaled white noise not coded in the bitstream.
|
||||
INTENSITY_BT2 = 14, ///< Scalefactor data are intensity stereo positions (out of phase).
|
||||
INTENSITY_BT = 15, ///< Scalefactor data are intensity stereo positions (in phase).
|
||||
INTENSITY_BT2 = 14, ///< Scalefactor data are intensity stereo positions.
|
||||
INTENSITY_BT = 15, ///< Scalefactor data are intensity stereo positions.
|
||||
};
|
||||
|
||||
#define IS_CODEBOOK_UNSIGNED(x) (((x) - 1) & 10)
|
||||
@@ -133,14 +125,12 @@ typedef struct OutputConfiguration {
|
||||
* Predictor State
|
||||
*/
|
||||
typedef struct PredictorState {
|
||||
AAC_FLOAT cor0;
|
||||
AAC_FLOAT cor1;
|
||||
AAC_FLOAT var0;
|
||||
AAC_FLOAT var1;
|
||||
AAC_FLOAT r0;
|
||||
AAC_FLOAT r1;
|
||||
AAC_FLOAT k1;
|
||||
AAC_FLOAT x_est;
|
||||
float cor0;
|
||||
float cor1;
|
||||
float var0;
|
||||
float var1;
|
||||
float r0;
|
||||
float r1;
|
||||
} PredictorState;
|
||||
|
||||
#define MAX_PREDICTORS 672
|
||||
@@ -161,7 +151,7 @@ typedef struct PredictorState {
|
||||
typedef struct LongTermPrediction {
|
||||
int8_t present;
|
||||
int16_t lag;
|
||||
INTFLOAT coef;
|
||||
float coef;
|
||||
int8_t used[MAX_LTP_LONG_SFB];
|
||||
} LongTermPrediction;
|
||||
|
||||
@@ -183,10 +173,7 @@ typedef struct IndividualChannelStream {
|
||||
int predictor_present;
|
||||
int predictor_initialized;
|
||||
int predictor_reset_group;
|
||||
int predictor_reset_count[31]; ///< used by encoder to count prediction resets
|
||||
uint8_t prediction_used[41];
|
||||
uint8_t window_clipping[8]; ///< set if a certain window is near clipping
|
||||
float clip_avoidance_factor; ///< set if any window is near clipping to the necessary atennuation factor to avoid it
|
||||
} IndividualChannelStream;
|
||||
|
||||
/**
|
||||
@@ -198,8 +185,7 @@ typedef struct TemporalNoiseShaping {
|
||||
int length[8][4];
|
||||
int direction[8][4];
|
||||
int order[8][4];
|
||||
int coef_idx[8][4][TNS_MAX_ORDER];
|
||||
INTFLOAT coef[8][4][TNS_MAX_ORDER];
|
||||
float coef[8][4][TNS_MAX_ORDER];
|
||||
} TemporalNoiseShaping;
|
||||
|
||||
/**
|
||||
@@ -236,7 +222,7 @@ typedef struct ChannelCoupling {
|
||||
int ch_select[8]; /**< [0] shared list of gains; [1] list of gains for right channel;
|
||||
* [2] list of gains for left channel; [3] lists of gains for both channels
|
||||
*/
|
||||
INTFLOAT gain[16][120];
|
||||
float gain[16][120];
|
||||
} ChannelCoupling;
|
||||
|
||||
/**
|
||||
@@ -247,21 +233,17 @@ typedef struct SingleChannelElement {
|
||||
TemporalNoiseShaping tns;
|
||||
Pulse pulse;
|
||||
enum BandType band_type[128]; ///< band types
|
||||
enum BandType band_alt[128]; ///< alternative band type (used by encoder)
|
||||
int band_type_run_end[120]; ///< band type run end points
|
||||
INTFLOAT sf[120]; ///< scalefactors
|
||||
float sf[120]; ///< scalefactors
|
||||
int sf_idx[128]; ///< scalefactor indices (used by encoder)
|
||||
uint8_t zeroes[128]; ///< band is not coded (used by encoder)
|
||||
float is_ener[128]; ///< Intensity stereo pos (used by encoder)
|
||||
float pns_ener[128]; ///< Noise energy values (used by encoder)
|
||||
DECLARE_ALIGNED(32, INTFLOAT, pcoeffs)[1024]; ///< coefficients for IMDCT, pristine
|
||||
DECLARE_ALIGNED(32, INTFLOAT, coeffs)[1024]; ///< coefficients for IMDCT, maybe processed
|
||||
DECLARE_ALIGNED(32, INTFLOAT, saved)[1536]; ///< overlap
|
||||
DECLARE_ALIGNED(32, INTFLOAT, ret_buf)[2048]; ///< PCM output buffer
|
||||
DECLARE_ALIGNED(16, INTFLOAT, ltp_state)[3072]; ///< time signal for LTP
|
||||
DECLARE_ALIGNED(32, AAC_FLOAT, prcoeffs)[1024]; ///< Main prediction coefs (used by encoder)
|
||||
DECLARE_ALIGNED(32, float, pcoeffs)[1024]; ///< coefficients for IMDCT, pristine
|
||||
DECLARE_ALIGNED(32, float, coeffs)[1024]; ///< coefficients for IMDCT, maybe processed
|
||||
DECLARE_ALIGNED(32, float, saved)[1536]; ///< overlap
|
||||
DECLARE_ALIGNED(32, float, ret_buf)[2048]; ///< PCM output buffer
|
||||
DECLARE_ALIGNED(16, float, ltp_state)[3072]; ///< time signal for LTP
|
||||
PredictorState predictor_state[MAX_PREDICTORS];
|
||||
INTFLOAT *ret; ///< PCM output
|
||||
float *ret; ///< PCM output
|
||||
} SingleChannelElement;
|
||||
|
||||
/**
|
||||
@@ -272,9 +254,7 @@ typedef struct ChannelElement {
|
||||
// CPE specific
|
||||
int common_window; ///< Set if channels share a common 'IndividualChannelStream' in bitstream.
|
||||
int ms_mode; ///< Signals mid/side stereo flags coding mode (used by encoder)
|
||||
uint8_t is_mode; ///< Set if any bands have been encoded using intensity stereo (used by encoder)
|
||||
uint8_t ms_mask[128]; ///< Set if mid/side stereo is used for each scalefactor window band
|
||||
uint8_t is_mask[128]; ///< Set if intensity stereo is used (used by encoder)
|
||||
// shared
|
||||
SingleChannelElement ch[2];
|
||||
// CCE specific
|
||||
@@ -308,7 +288,7 @@ struct AACContext {
|
||||
* (We do not want to have these on the stack.)
|
||||
* @{
|
||||
*/
|
||||
DECLARE_ALIGNED(32, INTFLOAT, buf_mdct)[1024];
|
||||
DECLARE_ALIGNED(32, float, buf_mdct)[1024];
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@@ -319,12 +299,8 @@ struct AACContext {
|
||||
FFTContext mdct_small;
|
||||
FFTContext mdct_ld;
|
||||
FFTContext mdct_ltp;
|
||||
#if USE_FIXED
|
||||
AVFixedDSPContext *fdsp;
|
||||
#else
|
||||
IMDCT15Context *mdct480;
|
||||
AVFloatDSPContext *fdsp;
|
||||
#endif /* USE_FIXED */
|
||||
int random_state;
|
||||
/** @} */
|
||||
|
||||
@@ -344,7 +320,7 @@ struct AACContext {
|
||||
int dmono_mode; ///< 0->not dmono, 1->use first channel, 2->use second channel
|
||||
/** @} */
|
||||
|
||||
DECLARE_ALIGNED(32, INTFLOAT, temp)[128];
|
||||
DECLARE_ALIGNED(32, float, temp)[128];
|
||||
|
||||
OutputConfiguration oc[2];
|
||||
int warned_num_aac_frames;
|
||||
@@ -352,13 +328,11 @@ struct AACContext {
|
||||
/* aacdec functions pointers */
|
||||
void (*imdct_and_windowing)(AACContext *ac, SingleChannelElement *sce);
|
||||
void (*apply_ltp)(AACContext *ac, SingleChannelElement *sce);
|
||||
void (*apply_tns)(INTFLOAT coef[1024], TemporalNoiseShaping *tns,
|
||||
void (*apply_tns)(float coef[1024], TemporalNoiseShaping *tns,
|
||||
IndividualChannelStream *ics, int decode);
|
||||
void (*windowing_and_mdct_ltp)(AACContext *ac, INTFLOAT *out,
|
||||
INTFLOAT *in, IndividualChannelStream *ics);
|
||||
void (*windowing_and_mdct_ltp)(AACContext *ac, float *out,
|
||||
float *in, IndividualChannelStream *ics);
|
||||
void (*update_ltp)(AACContext *ac, SingleChannelElement *sce);
|
||||
void (*vector_pow43)(int *coefs, int len);
|
||||
void (*subband_scale)(int *dst, int *src, int scale, int offset, int len);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc,
|
||||
}
|
||||
av_free(avctx->extradata);
|
||||
avctx->extradata_size = 2 + pce_size;
|
||||
avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!avctx->extradata) {
|
||||
avctx->extradata_size = 0;
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* AAC defines
|
||||
*
|
||||
* 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 AVCODEC_AAC_DEFINES_H
|
||||
#define AVCODEC_AAC_DEFINES_H
|
||||
|
||||
#ifndef USE_FIXED
|
||||
#define USE_FIXED 0
|
||||
#endif
|
||||
|
||||
#if USE_FIXED
|
||||
|
||||
#include "libavutil/softfloat.h"
|
||||
|
||||
#define FFT_FLOAT 0
|
||||
#define FFT_FIXED_32 1
|
||||
|
||||
#define AAC_RENAME(x) x ## _fixed
|
||||
#define AAC_RENAME_32(x) x ## _fixed_32
|
||||
#define INTFLOAT int
|
||||
#define INT64FLOAT int64_t
|
||||
#define SHORTFLOAT int16_t
|
||||
#define AAC_FLOAT SoftFloat
|
||||
#define AAC_SIGNE int
|
||||
#define FIXR(a) ((int)((a) * 1 + 0.5))
|
||||
#define FIXR10(a) ((int)((a) * 1024.0 + 0.5))
|
||||
#define Q23(a) (int)((a) * 8388608.0 + 0.5)
|
||||
#define Q30(x) (int)((x)*1073741824.0 + 0.5)
|
||||
#define Q31(x) (int)((x)*2147483648.0 + 0.5)
|
||||
#define RANGE15(x) x
|
||||
#define GET_GAIN(x, y) (-(y) * (1 << (x))) + 1024
|
||||
#define AAC_MUL16(x, y) (int)(((int64_t)(x) * (y) + 0x8000) >> 16)
|
||||
#define AAC_MUL26(x, y) (int)(((int64_t)(x) * (y) + 0x2000000) >> 26)
|
||||
#define AAC_MUL30(x, y) (int)(((int64_t)(x) * (y) + 0x20000000) >> 30)
|
||||
#define AAC_MUL31(x, y) (int)(((int64_t)(x) * (y) + 0x40000000) >> 31)
|
||||
#define AAC_MADD28(x, y, a, b) (int)((((int64_t)(x) * (y)) + \
|
||||
((int64_t)(a) * (b)) + \
|
||||
0x8000000) >> 28)
|
||||
#define AAC_MADD30(x, y, a, b) (int)((((int64_t)(x) * (y)) + \
|
||||
((int64_t)(a) * (b)) + \
|
||||
0x20000000) >> 30)
|
||||
#define AAC_MADD30_V8(x, y, a, b, c, d, e, f) (int)((((int64_t)(x) * (y)) + \
|
||||
((int64_t)(a) * (b)) + \
|
||||
((int64_t)(c) * (d)) + \
|
||||
((int64_t)(e) * (f)) + \
|
||||
0x20000000) >> 30)
|
||||
#define AAC_MSUB30(x, y, a, b) (int)((((int64_t)(x) * (y)) - \
|
||||
((int64_t)(a) * (b)) + \
|
||||
0x20000000) >> 30)
|
||||
#define AAC_MSUB30_V8(x, y, a, b, c, d, e, f) (int)((((int64_t)(x) * (y)) + \
|
||||
((int64_t)(a) * (b)) - \
|
||||
((int64_t)(c) * (d)) - \
|
||||
((int64_t)(e) * (f)) + \
|
||||
0x20000000) >> 30)
|
||||
#define AAC_MSUB31_V3(x, y, z) (int)((((int64_t)(x) * (z)) - \
|
||||
((int64_t)(y) * (z)) + \
|
||||
0x40000000) >> 31)
|
||||
#define AAC_HALF_SUM(x, y) (((x) >> 1) + ((y) >> 1))
|
||||
#define AAC_SRA_R(x, y) (int)(((x) + (1 << ((y) - 1))) >> (y))
|
||||
|
||||
#else
|
||||
|
||||
#define FFT_FLOAT 1
|
||||
#define FFT_FIXED_32 0
|
||||
|
||||
#define AAC_RENAME(x) x
|
||||
#define AAC_RENAME_32(x) x
|
||||
#define INTFLOAT float
|
||||
#define INT64FLOAT float
|
||||
#define SHORTFLOAT float
|
||||
#define AAC_FLOAT float
|
||||
#define AAC_SIGNE unsigned
|
||||
#define FIXR(x) ((float)(x))
|
||||
#define FIXR10(x) ((float)(x))
|
||||
#define Q23(x) x
|
||||
#define Q30(x) x
|
||||
#define Q31(x) x
|
||||
#define RANGE15(x) (32768.0 * (x))
|
||||
#define GET_GAIN(x, y) powf((x), -(y))
|
||||
#define AAC_MUL16(x, y) ((x) * (y))
|
||||
#define AAC_MUL26(x, y) ((x) * (y))
|
||||
#define AAC_MUL30(x, y) ((x) * (y))
|
||||
#define AAC_MUL31(x, y) ((x) * (y))
|
||||
#define AAC_MADD28(x, y, a, b) ((x) * (y) + (a) * (b))
|
||||
#define AAC_MADD30(x, y, a, b) ((x) * (y) + (a) * (b))
|
||||
#define AAC_MADD30_V8(x, y, a, b, c, d, e, f) ((x) * (y) + (a) * (b) + \
|
||||
(c) * (d) + (e) * (f))
|
||||
#define AAC_MSUB30(x, y, a, b) ((x) * (y) - (a) * (b))
|
||||
#define AAC_MSUB30_V8(x, y, a, b, c, d, e, f) ((x) * (y) + (a) * (b) - \
|
||||
(c) * (d) - (e) * (f))
|
||||
#define AAC_MSUB31_V3(x, y, z) ((x) - (y)) * (z)
|
||||
#define AAC_HALF_SUM(x, y) ((x) + (y)) * 0.5f
|
||||
#define AAC_SRA_R(x, y) (x)
|
||||
|
||||
#endif /* USE_FIXED */
|
||||
|
||||
#endif /* AVCODEC_AAC_DEFINES_H */
|
||||
@@ -34,7 +34,7 @@ static int aac_sync(uint64_t state, AACAC3ParseContext *hdr_info,
|
||||
int size;
|
||||
union {
|
||||
uint64_t u64;
|
||||
uint8_t u8[8 + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
uint8_t u8[8 + FF_INPUT_BUFFER_PADDING_SIZE];
|
||||
} tmp;
|
||||
|
||||
tmp.u64 = av_be2ne64(state);
|
||||
|
||||
@@ -33,7 +33,5 @@ int main(void)
|
||||
|
||||
WRITE_ARRAY("const", float, ff_aac_pow2sf_tab);
|
||||
|
||||
WRITE_ARRAY("const", float, ff_aac_pow34sf_tab);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -30,15 +30,12 @@
|
||||
#else
|
||||
#include "libavutil/mathematics.h"
|
||||
float ff_aac_pow2sf_tab[428];
|
||||
float ff_aac_pow34sf_tab[428];
|
||||
|
||||
av_cold void ff_aac_tableinit(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 428; i++) {
|
||||
for (i = 0; i < 428; i++)
|
||||
ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.0);
|
||||
ff_aac_pow34sf_tab[i] = pow(ff_aac_pow2sf_tab[i], 3.0/4.0);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_HARDCODED_TABLES */
|
||||
|
||||
|
||||
@@ -28,11 +28,9 @@
|
||||
#if CONFIG_HARDCODED_TABLES
|
||||
#define ff_aac_tableinit()
|
||||
extern const float ff_aac_pow2sf_tab[428];
|
||||
extern const float ff_aac_pow34sf_tab[428];
|
||||
#else
|
||||
void ff_aac_tableinit(void);
|
||||
extern float ff_aac_pow2sf_tab[428];
|
||||
extern float ff_aac_pow34sf_tab[428];
|
||||
#endif /* CONFIG_HARDCODED_TABLES */
|
||||
|
||||
#endif /* AVCODEC_AAC_TABLEGEN_DECL_H */
|
||||
|
||||
+358
-181
@@ -39,26 +39,290 @@
|
||||
#include "aac.h"
|
||||
#include "aacenc.h"
|
||||
#include "aactab.h"
|
||||
#include "aacenctab.h"
|
||||
#include "aacenc_utils.h"
|
||||
#include "aacenc_quantization.h"
|
||||
#include "aac_tablegen_decl.h"
|
||||
|
||||
#include "aacenc_is.h"
|
||||
#include "aacenc_tns.h"
|
||||
#include "aacenc_pred.h"
|
||||
|
||||
/** Frequency in Hz for lower limit of noise substitution **/
|
||||
#define NOISE_LOW_LIMIT 4500
|
||||
#define NOISE_LOW_LIMIT 4000
|
||||
|
||||
/* Energy spread threshold value below which no PNS is used, this corresponds to
|
||||
* typically around 17Khz, after which PNS usage decays ending at 19Khz */
|
||||
#define NOISE_SPREAD_THRESHOLD 0.5f
|
||||
/** Total number of usable codebooks **/
|
||||
#define CB_TOT 13
|
||||
|
||||
/* This constant gets divided by lambda to return ~1.65 which when multiplied
|
||||
* by the band->threshold and compared to band->energy is the boundary between
|
||||
* excessive PNS and little PNS usage. */
|
||||
#define NOISE_LAMBDA_NUMERATOR 252.1f
|
||||
/** bits needed to code codebook run value for long windows */
|
||||
static const uint8_t run_value_bits_long[64] = {
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10,
|
||||
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 15
|
||||
};
|
||||
|
||||
/** bits needed to code codebook run value for short windows */
|
||||
static const uint8_t run_value_bits_short[16] = {
|
||||
3, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 9
|
||||
};
|
||||
|
||||
static const uint8_t * const run_value_bits[2] = {
|
||||
run_value_bits_long, run_value_bits_short
|
||||
};
|
||||
|
||||
/** Map to convert values from BandCodingPath index to a codebook index **/
|
||||
static const uint8_t aac_cb_out_map[CB_TOT] = {0,1,2,3,4,5,6,7,8,9,10,11,13};
|
||||
/** Inverse map to convert from codebooks to BandCodingPath indices **/
|
||||
static const uint8_t aac_cb_in_map[CB_TOT+1] = {0,1,2,3,4,5,6,7,8,9,10,11,0,12};
|
||||
|
||||
/**
|
||||
* Quantize one coefficient.
|
||||
* @return absolute value of the quantized coefficient
|
||||
* @see 3GPP TS26.403 5.6.2 "Scalefactor determination"
|
||||
*/
|
||||
static av_always_inline int quant(float coef, const float Q)
|
||||
{
|
||||
float a = coef * Q;
|
||||
return sqrtf(a * sqrtf(a)) + 0.4054;
|
||||
}
|
||||
|
||||
static void quantize_bands(int *out, const float *in, const float *scaled,
|
||||
int size, float Q34, int is_signed, int maxval)
|
||||
{
|
||||
int i;
|
||||
double qc;
|
||||
for (i = 0; i < size; i++) {
|
||||
qc = scaled[i] * Q34;
|
||||
out[i] = (int)FFMIN(qc + 0.4054, (double)maxval);
|
||||
if (is_signed && in[i] < 0.0f) {
|
||||
out[i] = -out[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void abs_pow34_v(float *out, const float *in, const int size)
|
||||
{
|
||||
#ifndef USE_REALLY_FULL_SEARCH
|
||||
int i;
|
||||
for (i = 0; i < size; i++) {
|
||||
float a = fabsf(in[i]);
|
||||
out[i] = sqrtf(a * sqrtf(a));
|
||||
}
|
||||
#endif /* USE_REALLY_FULL_SEARCH */
|
||||
}
|
||||
|
||||
static const uint8_t aac_cb_range [12] = {0, 3, 3, 3, 3, 9, 9, 8, 8, 13, 13, 17};
|
||||
static const uint8_t aac_cb_maxval[12] = {0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12, 16};
|
||||
|
||||
/**
|
||||
* Calculate rate distortion cost for quantizing with given codebook
|
||||
*
|
||||
* @return quantization distortion
|
||||
*/
|
||||
static av_always_inline float quantize_and_encode_band_cost_template(
|
||||
struct AACEncContext *s,
|
||||
PutBitContext *pb, const float *in,
|
||||
const float *scaled, int size, int scale_idx,
|
||||
int cb, const float lambda, const float uplim,
|
||||
int *bits, int BT_ZERO, int BT_UNSIGNED,
|
||||
int BT_PAIR, int BT_ESC, int BT_NOISE)
|
||||
{
|
||||
const int q_idx = POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512;
|
||||
const float Q = ff_aac_pow2sf_tab [q_idx];
|
||||
const float Q34 = ff_aac_pow34sf_tab[q_idx];
|
||||
const float IQ = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
|
||||
const float CLIPPED_ESCAPE = 165140.0f*IQ;
|
||||
int i, j;
|
||||
float cost = 0;
|
||||
const int dim = BT_PAIR ? 2 : 4;
|
||||
int resbits = 0;
|
||||
int off;
|
||||
|
||||
if (BT_ZERO) {
|
||||
for (i = 0; i < size; i++)
|
||||
cost += in[i]*in[i];
|
||||
if (bits)
|
||||
*bits = 0;
|
||||
return cost * lambda;
|
||||
}
|
||||
if (BT_NOISE) {
|
||||
for (i = 0; i < size; i++)
|
||||
cost += in[i]*in[i];
|
||||
if (bits)
|
||||
*bits = 0;
|
||||
return cost * lambda;
|
||||
}
|
||||
if (!scaled) {
|
||||
abs_pow34_v(s->scoefs, in, size);
|
||||
scaled = s->scoefs;
|
||||
}
|
||||
quantize_bands(s->qcoefs, in, scaled, size, Q34, !BT_UNSIGNED, aac_cb_maxval[cb]);
|
||||
if (BT_UNSIGNED) {
|
||||
off = 0;
|
||||
} else {
|
||||
off = aac_cb_maxval[cb];
|
||||
}
|
||||
for (i = 0; i < size; i += dim) {
|
||||
const float *vec;
|
||||
int *quants = s->qcoefs + i;
|
||||
int curidx = 0;
|
||||
int curbits;
|
||||
float rd = 0.0f;
|
||||
for (j = 0; j < dim; j++) {
|
||||
curidx *= aac_cb_range[cb];
|
||||
curidx += quants[j] + off;
|
||||
}
|
||||
curbits = ff_aac_spectral_bits[cb-1][curidx];
|
||||
vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
|
||||
if (BT_UNSIGNED) {
|
||||
for (j = 0; j < dim; j++) {
|
||||
float t = fabsf(in[i+j]);
|
||||
float di;
|
||||
if (BT_ESC && vec[j] == 64.0f) { //FIXME: slow
|
||||
if (t >= CLIPPED_ESCAPE) {
|
||||
di = t - CLIPPED_ESCAPE;
|
||||
curbits += 21;
|
||||
} else {
|
||||
int c = av_clip_uintp2(quant(t, Q), 13);
|
||||
di = t - c*cbrtf(c)*IQ;
|
||||
curbits += av_log2(c)*2 - 4 + 1;
|
||||
}
|
||||
} else {
|
||||
di = t - vec[j]*IQ;
|
||||
}
|
||||
if (vec[j] != 0.0f)
|
||||
curbits++;
|
||||
rd += di*di;
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < dim; j++) {
|
||||
float di = in[i+j] - vec[j]*IQ;
|
||||
rd += di*di;
|
||||
}
|
||||
}
|
||||
cost += rd * lambda + curbits;
|
||||
resbits += curbits;
|
||||
if (cost >= uplim)
|
||||
return uplim;
|
||||
if (pb) {
|
||||
put_bits(pb, ff_aac_spectral_bits[cb-1][curidx], ff_aac_spectral_codes[cb-1][curidx]);
|
||||
if (BT_UNSIGNED)
|
||||
for (j = 0; j < dim; j++)
|
||||
if (ff_aac_codebook_vectors[cb-1][curidx*dim+j] != 0.0f)
|
||||
put_bits(pb, 1, in[i+j] < 0.0f);
|
||||
if (BT_ESC) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
if (ff_aac_codebook_vectors[cb-1][curidx*2+j] == 64.0f) {
|
||||
int coef = av_clip_uintp2(quant(fabsf(in[i+j]), Q), 13);
|
||||
int len = av_log2(coef);
|
||||
|
||||
put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
|
||||
put_sbits(pb, len, coef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bits)
|
||||
*bits = resbits;
|
||||
return cost;
|
||||
}
|
||||
|
||||
static float quantize_and_encode_band_cost_NONE(struct AACEncContext *s, PutBitContext *pb,
|
||||
const float *in, const float *scaled,
|
||||
int size, int scale_idx, int cb,
|
||||
const float lambda, const float uplim,
|
||||
int *bits) {
|
||||
av_assert0(0);
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
#define QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NAME, BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE) \
|
||||
static float quantize_and_encode_band_cost_ ## NAME( \
|
||||
struct AACEncContext *s, \
|
||||
PutBitContext *pb, const float *in, \
|
||||
const float *scaled, int size, int scale_idx, \
|
||||
int cb, const float lambda, const float uplim, \
|
||||
int *bits) { \
|
||||
return quantize_and_encode_band_cost_template( \
|
||||
s, pb, in, scaled, size, scale_idx, \
|
||||
BT_ESC ? ESC_BT : cb, lambda, uplim, bits, \
|
||||
BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE); \
|
||||
}
|
||||
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ZERO, 1, 0, 0, 0, 0)
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SQUAD, 0, 0, 0, 0, 0)
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UQUAD, 0, 1, 0, 0, 0)
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SPAIR, 0, 0, 1, 0, 0)
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UPAIR, 0, 1, 1, 0, 0)
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC, 0, 1, 1, 1, 0)
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NOISE, 0, 0, 0, 0, 1)
|
||||
|
||||
static float (*const quantize_and_encode_band_cost_arr[])(
|
||||
struct AACEncContext *s,
|
||||
PutBitContext *pb, const float *in,
|
||||
const float *scaled, int size, int scale_idx,
|
||||
int cb, const float lambda, const float uplim,
|
||||
int *bits) = {
|
||||
quantize_and_encode_band_cost_ZERO,
|
||||
quantize_and_encode_band_cost_SQUAD,
|
||||
quantize_and_encode_band_cost_SQUAD,
|
||||
quantize_and_encode_band_cost_UQUAD,
|
||||
quantize_and_encode_band_cost_UQUAD,
|
||||
quantize_and_encode_band_cost_SPAIR,
|
||||
quantize_and_encode_band_cost_SPAIR,
|
||||
quantize_and_encode_band_cost_UPAIR,
|
||||
quantize_and_encode_band_cost_UPAIR,
|
||||
quantize_and_encode_band_cost_UPAIR,
|
||||
quantize_and_encode_band_cost_UPAIR,
|
||||
quantize_and_encode_band_cost_ESC,
|
||||
quantize_and_encode_band_cost_NONE, /* CB 12 doesn't exist */
|
||||
quantize_and_encode_band_cost_NOISE,
|
||||
};
|
||||
|
||||
#define quantize_and_encode_band_cost( \
|
||||
s, pb, in, scaled, size, scale_idx, cb, \
|
||||
lambda, uplim, bits) \
|
||||
quantize_and_encode_band_cost_arr[cb]( \
|
||||
s, pb, in, scaled, size, scale_idx, cb, \
|
||||
lambda, uplim, bits)
|
||||
|
||||
static float quantize_band_cost(struct AACEncContext *s, const float *in,
|
||||
const float *scaled, int size, int scale_idx,
|
||||
int cb, const float lambda, const float uplim,
|
||||
int *bits)
|
||||
{
|
||||
return quantize_and_encode_band_cost(s, NULL, in, scaled, size, scale_idx,
|
||||
cb, lambda, uplim, bits);
|
||||
}
|
||||
|
||||
static void quantize_and_encode_band(struct AACEncContext *s, PutBitContext *pb,
|
||||
const float *in, int size, int scale_idx,
|
||||
int cb, const float lambda)
|
||||
{
|
||||
quantize_and_encode_band_cost(s, pb, in, NULL, size, scale_idx, cb, lambda,
|
||||
INFINITY, NULL);
|
||||
}
|
||||
|
||||
static float find_max_val(int group_len, int swb_size, const float *scaled) {
|
||||
float maxval = 0.0f;
|
||||
int w2, i;
|
||||
for (w2 = 0; w2 < group_len; w2++) {
|
||||
for (i = 0; i < swb_size; i++) {
|
||||
maxval = FFMAX(maxval, scaled[w2*128+i]);
|
||||
}
|
||||
}
|
||||
return maxval;
|
||||
}
|
||||
|
||||
static int find_min_book(float maxval, int sf) {
|
||||
float Q = ff_aac_pow2sf_tab[POW_SF2_ZERO - sf + SCALE_ONE_POS - SCALE_DIV_512];
|
||||
float Q34 = sqrtf(Q * sqrtf(Q));
|
||||
int qmaxval, cb;
|
||||
qmaxval = maxval * Q34 + 0.4054f;
|
||||
if (qmaxval == 0) cb = 0;
|
||||
else if (qmaxval == 1) cb = 1;
|
||||
else if (qmaxval == 2) cb = 3;
|
||||
else if (qmaxval <= 4) cb = 5;
|
||||
else if (qmaxval <= 7) cb = 7;
|
||||
else if (qmaxval <= 12) cb = 9;
|
||||
else cb = 11;
|
||||
return cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* structure used in optimal codebook search
|
||||
@@ -75,7 +339,7 @@ typedef struct BandCodingPath {
|
||||
static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce,
|
||||
int win, int group_len, const float lambda)
|
||||
{
|
||||
BandCodingPath path[120][CB_TOT_ALL];
|
||||
BandCodingPath path[120][CB_TOT];
|
||||
int w, swb, cb, start, size;
|
||||
int i, j;
|
||||
const int max_sfb = sce->ics.max_sfb;
|
||||
@@ -88,7 +352,7 @@ static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce
|
||||
|
||||
abs_pow34_v(s->scoefs, sce->coeffs, 1024);
|
||||
start = win*128;
|
||||
for (cb = 0; cb < CB_TOT_ALL; cb++) {
|
||||
for (cb = 0; cb < CB_TOT; cb++) {
|
||||
path[0][cb].cost = 0.0f;
|
||||
path[0][cb].prev_idx = -1;
|
||||
path[0][cb].run = 0;
|
||||
@@ -96,7 +360,7 @@ static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce
|
||||
for (swb = 0; swb < max_sfb; swb++) {
|
||||
size = sce->ics.swb_sizes[swb];
|
||||
if (sce->zeroes[win*16 + swb]) {
|
||||
for (cb = 0; cb < CB_TOT_ALL; cb++) {
|
||||
for (cb = 0; cb < CB_TOT; cb++) {
|
||||
path[swb+1][cb].prev_idx = cb;
|
||||
path[swb+1][cb].cost = path[swb][cb].cost;
|
||||
path[swb+1][cb].run = path[swb][cb].run + 1;
|
||||
@@ -106,22 +370,15 @@ static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce
|
||||
int mincb = next_mincb;
|
||||
next_minrd = INFINITY;
|
||||
next_mincb = 0;
|
||||
for (cb = 0; cb < CB_TOT_ALL; cb++) {
|
||||
for (cb = 0; cb < CB_TOT; cb++) {
|
||||
float cost_stay_here, cost_get_here;
|
||||
float rd = 0.0f;
|
||||
if (cb >= 12 && sce->band_type[win*16+swb] < aac_cb_out_map[cb] ||
|
||||
cb < aac_cb_in_map[sce->band_type[win*16+swb]] && sce->band_type[win*16+swb] > aac_cb_out_map[cb]) {
|
||||
path[swb+1][cb].prev_idx = -1;
|
||||
path[swb+1][cb].cost = INFINITY;
|
||||
path[swb+1][cb].run = path[swb][cb].run + 1;
|
||||
continue;
|
||||
}
|
||||
for (w = 0; w < group_len; w++) {
|
||||
FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(win+w)*16+swb];
|
||||
rd += quantize_band_cost(s, &sce->coeffs[start + w*128],
|
||||
&s->scoefs[start + w*128], size,
|
||||
rd += quantize_band_cost(s, sce->coeffs + start + w*128,
|
||||
s->scoefs + start + w*128, size,
|
||||
sce->sf_idx[(win+w)*16+swb], aac_cb_out_map[cb],
|
||||
lambda / band->threshold, INFINITY, NULL, 0);
|
||||
lambda / band->threshold, INFINITY, NULL);
|
||||
}
|
||||
cost_stay_here = path[swb][cb].cost + rd;
|
||||
cost_get_here = minrd + rd + run_bits + 4;
|
||||
@@ -149,12 +406,11 @@ static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce
|
||||
//convert resulting path from backward-linked list
|
||||
stack_len = 0;
|
||||
idx = 0;
|
||||
for (cb = 1; cb < CB_TOT_ALL; cb++)
|
||||
for (cb = 1; cb < CB_TOT; cb++)
|
||||
if (path[max_sfb][cb].cost < path[max_sfb][idx].cost)
|
||||
idx = cb;
|
||||
ppos = max_sfb;
|
||||
while (ppos > 0) {
|
||||
av_assert1(idx >= 0);
|
||||
cb = idx;
|
||||
stackrun[stack_len] = path[ppos][cb].run;
|
||||
stackcb [stack_len] = cb;
|
||||
@@ -185,7 +441,7 @@ static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce
|
||||
static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,
|
||||
int win, int group_len, const float lambda)
|
||||
{
|
||||
BandCodingPath path[120][CB_TOT_ALL];
|
||||
BandCodingPath path[120][CB_TOT];
|
||||
int w, swb, cb, start, size;
|
||||
int i, j;
|
||||
const int max_sfb = sce->ics.max_sfb;
|
||||
@@ -198,7 +454,7 @@ static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,
|
||||
|
||||
abs_pow34_v(s->scoefs, sce->coeffs, 1024);
|
||||
start = win*128;
|
||||
for (cb = 0; cb < CB_TOT_ALL; cb++) {
|
||||
for (cb = 0; cb < CB_TOT; cb++) {
|
||||
path[0][cb].cost = run_bits+4;
|
||||
path[0][cb].prev_idx = -1;
|
||||
path[0][cb].run = 0;
|
||||
@@ -222,7 +478,7 @@ static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,
|
||||
}
|
||||
next_minbits = path[swb+1][0].cost;
|
||||
next_mincb = 0;
|
||||
for (cb = 1; cb < CB_TOT_ALL; cb++) {
|
||||
for (cb = 1; cb < CB_TOT; cb++) {
|
||||
path[swb+1][cb].cost = 61450;
|
||||
path[swb+1][cb].prev_idx = -1;
|
||||
path[swb+1][cb].run = 0;
|
||||
@@ -239,21 +495,21 @@ static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,
|
||||
path[swb+1][cb].prev_idx = -1;
|
||||
path[swb+1][cb].run = 0;
|
||||
}
|
||||
for (cb = startcb; cb < CB_TOT_ALL; cb++) {
|
||||
for (cb = startcb; cb < CB_TOT; cb++) {
|
||||
float cost_stay_here, cost_get_here;
|
||||
float bits = 0.0f;
|
||||
if (cb >= 12 && sce->band_type[win*16+swb] != aac_cb_out_map[cb]) {
|
||||
if (cb == 12 && sce->band_type[win*16+swb] != NOISE_BT) {
|
||||
path[swb+1][cb].cost = 61450;
|
||||
path[swb+1][cb].prev_idx = -1;
|
||||
path[swb+1][cb].run = 0;
|
||||
continue;
|
||||
}
|
||||
for (w = 0; w < group_len; w++) {
|
||||
bits += quantize_band_cost(s, &sce->coeffs[start + w*128],
|
||||
&s->scoefs[start + w*128], size,
|
||||
sce->sf_idx[win*16+swb],
|
||||
bits += quantize_band_cost(s, sce->coeffs + start + w*128,
|
||||
s->scoefs + start + w*128, size,
|
||||
sce->sf_idx[(win+w)*16+swb],
|
||||
aac_cb_out_map[cb],
|
||||
0, INFINITY, NULL, 0);
|
||||
0, INFINITY, NULL);
|
||||
}
|
||||
cost_stay_here = path[swb][cb].cost + bits;
|
||||
cost_get_here = minbits + bits + run_bits + 4;
|
||||
@@ -281,7 +537,7 @@ static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,
|
||||
//convert resulting path from backward-linked list
|
||||
stack_len = 0;
|
||||
idx = 0;
|
||||
for (cb = 1; cb < CB_TOT_ALL; cb++)
|
||||
for (cb = 1; cb < CB_TOT; cb++)
|
||||
if (path[max_sfb][cb].cost < path[max_sfb][idx].cost)
|
||||
idx = cb;
|
||||
ppos = max_sfb;
|
||||
@@ -314,6 +570,16 @@ static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the minimum scalefactor where the quantized coef does not clip. */
|
||||
static av_always_inline uint8_t coef2minsf(float coef) {
|
||||
return av_clip_uint8(log2f(coef)*4 - 69 + SCALE_ONE_POS - SCALE_DIV_512);
|
||||
}
|
||||
|
||||
/** Return the maximum scalefactor where the quantized coef is not zero. */
|
||||
static av_always_inline uint8_t coef2maxsf(float coef) {
|
||||
return av_clip_uint8(log2f(coef)*4 + 6 + SCALE_ONE_POS - SCALE_DIV_512);
|
||||
}
|
||||
|
||||
typedef struct TrellisPath {
|
||||
float cost;
|
||||
int prev;
|
||||
@@ -322,43 +588,6 @@ typedef struct TrellisPath {
|
||||
#define TRELLIS_STAGES 121
|
||||
#define TRELLIS_STATES (SCALE_MAX_DIFF+1)
|
||||
|
||||
static void set_special_band_scalefactors(AACEncContext *s, SingleChannelElement *sce)
|
||||
{
|
||||
int w, g, start = 0;
|
||||
int minscaler_n = sce->sf_idx[0], minscaler_i = sce->sf_idx[0];
|
||||
int bands = 0;
|
||||
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = 0;
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
if (sce->band_type[w*16+g] == INTENSITY_BT || sce->band_type[w*16+g] == INTENSITY_BT2) {
|
||||
sce->sf_idx[w*16+g] = av_clip(ceilf(log2f(sce->is_ener[w*16+g])*2), -155, 100);
|
||||
minscaler_i = FFMIN(minscaler_i, sce->sf_idx[w*16+g]);
|
||||
bands++;
|
||||
} else if (sce->band_type[w*16+g] == NOISE_BT) {
|
||||
sce->sf_idx[w*16+g] = av_clip(4+log2f(sce->pns_ener[w*16+g])*2, -100, 155);
|
||||
minscaler_n = FFMIN(minscaler_n, sce->sf_idx[w*16+g]);
|
||||
bands++;
|
||||
}
|
||||
start += sce->ics.swb_sizes[g];
|
||||
}
|
||||
}
|
||||
|
||||
if (!bands)
|
||||
return;
|
||||
|
||||
/* Clip the scalefactor indices */
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
if (sce->band_type[w*16+g] == INTENSITY_BT || sce->band_type[w*16+g] == INTENSITY_BT2) {
|
||||
sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler_i, minscaler_i + SCALE_MAX_DIFF);
|
||||
} else if (sce->band_type[w*16+g] == NOISE_BT) {
|
||||
sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler_n, minscaler_n + SCALE_MAX_DIFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s,
|
||||
SingleChannelElement *sce,
|
||||
const float lambda)
|
||||
@@ -424,7 +653,7 @@ static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s,
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = w*128;
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
const float *coefs = &sce->coeffs[start];
|
||||
const float *coefs = sce->coeffs + start;
|
||||
float qmin, qmax;
|
||||
int nz = 0;
|
||||
|
||||
@@ -463,7 +692,7 @@ static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s,
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
|
||||
dist += quantize_band_cost(s, coefs + w2*128, s->scoefs + start + w2*128, sce->ics.swb_sizes[g],
|
||||
q + q0, cb, lambda / band->threshold, INFINITY, NULL, 0);
|
||||
q + q0, cb, lambda / band->threshold, INFINITY, NULL);
|
||||
}
|
||||
minrd = FFMIN(minrd, dist);
|
||||
|
||||
@@ -519,9 +748,11 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
{
|
||||
int start = 0, i, w, w2, g;
|
||||
int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels * (lambda / 120.f);
|
||||
const float freq_mult = avctx->sample_rate/(1024.0f/sce->ics.num_windows)/2.0f;
|
||||
float dists[128] = { 0 }, uplims[128] = { 0 };
|
||||
float maxvals[128];
|
||||
int fflag, minscaler;
|
||||
int noise_sf[128] = { 0 };
|
||||
int fflag, minscaler, minscaler_n;
|
||||
int its = 0;
|
||||
int allz = 0;
|
||||
float minthr = INFINITY;
|
||||
@@ -532,12 +763,13 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
//XXX: some heuristic to determine initial quantizers will reduce search time
|
||||
//determine zero bands and upper limits
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = 0;
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
int nz = 0;
|
||||
float uplim = 0.0f, energy = 0.0f;
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
|
||||
uplim += band->threshold;
|
||||
uplim += band->threshold;
|
||||
energy += band->energy;
|
||||
if (band->energy <= band->threshold || band->threshold == 0.0f) {
|
||||
sce->zeroes[(w+w2)*16+g] = 1;
|
||||
@@ -546,10 +778,18 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
nz = 1;
|
||||
}
|
||||
uplims[w*16+g] = uplim *512;
|
||||
if (s->options.pns && start*freq_mult > NOISE_LOW_LIMIT && energy < uplim * 1.2f) {
|
||||
noise_sf[w*16+g] = av_clip(4+FFMIN(log2f(energy)*2,255), -100, 155);
|
||||
sce->band_type[w*16+g] = NOISE_BT;
|
||||
nz= 1;
|
||||
} else { /** Band type will be determined by the twoloop algorithm */
|
||||
sce->band_type[w*16+g] = 0;
|
||||
}
|
||||
sce->zeroes[w*16+g] = !nz;
|
||||
if (nz)
|
||||
minthr = FFMIN(minthr, uplim);
|
||||
allz |= nz;
|
||||
start += sce->ics.swb_sizes[g];
|
||||
}
|
||||
}
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
@@ -580,6 +820,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
do {
|
||||
int tbits, qstep;
|
||||
minscaler = sce->sf_idx[0];
|
||||
minscaler_n = sce->sf_idx[0];
|
||||
//inner loop - quantize spectrum to fit into given number of bits
|
||||
qstep = its ? 1 : 32;
|
||||
do {
|
||||
@@ -588,13 +829,17 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = w*128;
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
const float *coefs = &sce->coeffs[start];
|
||||
const float *scaled = &s->scoefs[start];
|
||||
const float *coefs = sce->coeffs + start;
|
||||
const float *scaled = s->scoefs + start;
|
||||
int bits = 0;
|
||||
int cb;
|
||||
float dist = 0.0f;
|
||||
|
||||
if (sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218) {
|
||||
if (sce->band_type[w*16+g] == NOISE_BT) {
|
||||
minscaler_n = FFMIN(minscaler_n, noise_sf[w*16+g]);
|
||||
start += sce->ics.swb_sizes[g];
|
||||
continue;
|
||||
} else if (sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218) {
|
||||
start += sce->ics.swb_sizes[g];
|
||||
continue;
|
||||
}
|
||||
@@ -609,8 +854,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
cb,
|
||||
1.0f,
|
||||
INFINITY,
|
||||
&b,
|
||||
0);
|
||||
&b);
|
||||
bits += b;
|
||||
}
|
||||
dists[w*16+g] = dist - bits;
|
||||
@@ -639,9 +883,16 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
fflag = 0;
|
||||
minscaler = av_clip(minscaler, 60, 255 - SCALE_MAX_DIFF);
|
||||
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
|
||||
for (g = 0; g < sce->ics.num_swb; g++)
|
||||
if (sce->band_type[w*16+g] == NOISE_BT)
|
||||
sce->sf_idx[w*16+g] = av_clip(noise_sf[w*16+g], minscaler_n, minscaler_n + SCALE_MAX_DIFF);
|
||||
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
int prevsc = sce->sf_idx[w*16+g];
|
||||
if (sce->band_type[w*16+g] == NOISE_BT)
|
||||
continue;
|
||||
if (dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60) {
|
||||
if (find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]-1))
|
||||
sce->sf_idx[w*16+g]--;
|
||||
@@ -684,7 +935,7 @@ static void search_for_quantizers_faac(AVCodecContext *avctx, AACEncContext *s,
|
||||
}
|
||||
} else {
|
||||
for (w = 0; w < 8; w++) {
|
||||
const float *coeffs = &sce->coeffs[w*128];
|
||||
const float *coeffs = sce->coeffs + w*128;
|
||||
curband = start = 0;
|
||||
for (i = 0; i < 128; i++) {
|
||||
if (i - start >= sce->ics.swb_sizes[curband]) {
|
||||
@@ -709,7 +960,7 @@ static void search_for_quantizers_faac(AVCodecContext *avctx, AACEncContext *s,
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = w*128;
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
float *coefs = &sce->coeffs[start];
|
||||
float *coefs = sce->coeffs + start;
|
||||
const int size = sce->ics.swb_sizes[g];
|
||||
int start2 = start, end2 = start + size, peakpos = start;
|
||||
float maxval = -1, thr = 0.0f, t;
|
||||
@@ -750,8 +1001,8 @@ static void search_for_quantizers_faac(AVCodecContext *avctx, AACEncContext *s,
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = w*128;
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
const float *coefs = &sce->coeffs[start];
|
||||
const float *scaled = &s->scoefs[start];
|
||||
const float *coefs = sce->coeffs + start;
|
||||
const float *scaled = s->scoefs + start;
|
||||
const int size = sce->ics.swb_sizes[g];
|
||||
int scf, prev_scf, step;
|
||||
int min_scf = -1, max_scf = 256;
|
||||
@@ -776,12 +1027,11 @@ static void search_for_quantizers_faac(AVCodecContext *avctx, AACEncContext *s,
|
||||
ESC_BT,
|
||||
lambda,
|
||||
INFINITY,
|
||||
&b,
|
||||
0);
|
||||
&b);
|
||||
dist -= b;
|
||||
}
|
||||
dist *= 1.0f / 512.0f / lambda;
|
||||
quant_max = quant(maxq[w*16+g], ff_aac_pow2sf_tab[POW_SF2_ZERO - scf + SCALE_ONE_POS - SCALE_DIV_512], ROUND_STANDARD);
|
||||
quant_max = quant(maxq[w*16+g], ff_aac_pow2sf_tab[POW_SF2_ZERO - scf + SCALE_ONE_POS - SCALE_DIV_512]);
|
||||
if (quant_max >= 8191) { // too much, return to the previous quantizer
|
||||
sce->sf_idx[w*16+g] = prev_scf;
|
||||
break;
|
||||
@@ -861,50 +1111,17 @@ static void search_for_quantizers_fast(AVCodecContext *avctx, AACEncContext *s,
|
||||
sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
|
||||
}
|
||||
|
||||
static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce)
|
||||
{
|
||||
int start = 0, w, w2, g;
|
||||
const float lambda = s->lambda;
|
||||
const float freq_mult = avctx->sample_rate/(1024.0f/sce->ics.num_windows)/2.0f;
|
||||
const float spread_threshold = NOISE_SPREAD_THRESHOLD*(lambda/120.f);
|
||||
const float thr_mult = NOISE_LAMBDA_NUMERATOR/lambda;
|
||||
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = 0;
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
if (start*freq_mult > NOISE_LOW_LIMIT*(lambda/170.0f)) {
|
||||
float energy = 0.0f, threshold = 0.0f, spread = 0.0f;
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
FFPsyBand *band = &s->psy.ch[s->cur_channel+0].psy_bands[(w+w2)*16+g];
|
||||
energy += band->energy;
|
||||
threshold += band->threshold;
|
||||
spread += band->spread;
|
||||
}
|
||||
if (spread > spread_threshold*sce->ics.group_len[w] &&
|
||||
((sce->zeroes[w*16+g] && energy >= threshold) ||
|
||||
energy < threshold*thr_mult*sce->ics.group_len[w])) {
|
||||
sce->band_type[w*16+g] = NOISE_BT;
|
||||
sce->pns_ener[w*16+g] = energy / sce->ics.group_len[w];
|
||||
sce->zeroes[w*16+g] = 0;
|
||||
}
|
||||
}
|
||||
start += sce->ics.swb_sizes[g];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void search_for_ms(AACEncContext *s, ChannelElement *cpe)
|
||||
static void search_for_ms(AACEncContext *s, ChannelElement *cpe,
|
||||
const float lambda)
|
||||
{
|
||||
int start = 0, i, w, w2, g;
|
||||
float M[128], S[128];
|
||||
float *L34 = s->scoefs, *R34 = s->scoefs + 128, *M34 = s->scoefs + 128*2, *S34 = s->scoefs + 128*3;
|
||||
const float lambda = s->lambda;
|
||||
SingleChannelElement *sce0 = &cpe->ch[0];
|
||||
SingleChannelElement *sce1 = &cpe->ch[1];
|
||||
if (!cpe->common_window)
|
||||
return;
|
||||
for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) {
|
||||
start = 0;
|
||||
for (g = 0; g < sce0->ics.num_swb; g++) {
|
||||
if (!cpe->ch[0].zeroes[w*16+g] && !cpe->ch[1].zeroes[w*16+g]) {
|
||||
float dist1 = 0.0f, dist2 = 0.0f;
|
||||
@@ -914,39 +1131,39 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe)
|
||||
float minthr = FFMIN(band0->threshold, band1->threshold);
|
||||
float maxthr = FFMAX(band0->threshold, band1->threshold);
|
||||
for (i = 0; i < sce0->ics.swb_sizes[g]; i++) {
|
||||
M[i] = (sce0->coeffs[start+(w+w2)*128+i]
|
||||
+ sce1->coeffs[start+(w+w2)*128+i]) * 0.5;
|
||||
M[i] = (sce0->pcoeffs[start+w2*128+i]
|
||||
+ sce1->pcoeffs[start+w2*128+i]) * 0.5;
|
||||
S[i] = M[i]
|
||||
- sce1->coeffs[start+(w+w2)*128+i];
|
||||
- sce1->pcoeffs[start+w2*128+i];
|
||||
}
|
||||
abs_pow34_v(L34, sce0->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]);
|
||||
abs_pow34_v(R34, sce1->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]);
|
||||
abs_pow34_v(L34, sce0->coeffs+start+w2*128, sce0->ics.swb_sizes[g]);
|
||||
abs_pow34_v(R34, sce1->coeffs+start+w2*128, sce0->ics.swb_sizes[g]);
|
||||
abs_pow34_v(M34, M, sce0->ics.swb_sizes[g]);
|
||||
abs_pow34_v(S34, S, sce0->ics.swb_sizes[g]);
|
||||
dist1 += quantize_band_cost(s, &sce0->coeffs[start + (w+w2)*128],
|
||||
dist1 += quantize_band_cost(s, sce0->coeffs + start + w2*128,
|
||||
L34,
|
||||
sce0->ics.swb_sizes[g],
|
||||
sce0->sf_idx[(w+w2)*16+g],
|
||||
sce0->band_type[(w+w2)*16+g],
|
||||
lambda / band0->threshold, INFINITY, NULL, 0);
|
||||
dist1 += quantize_band_cost(s, &sce1->coeffs[start + (w+w2)*128],
|
||||
lambda / band0->threshold, INFINITY, NULL);
|
||||
dist1 += quantize_band_cost(s, sce1->coeffs + start + w2*128,
|
||||
R34,
|
||||
sce1->ics.swb_sizes[g],
|
||||
sce1->sf_idx[(w+w2)*16+g],
|
||||
sce1->band_type[(w+w2)*16+g],
|
||||
lambda / band1->threshold, INFINITY, NULL, 0);
|
||||
lambda / band1->threshold, INFINITY, NULL);
|
||||
dist2 += quantize_band_cost(s, M,
|
||||
M34,
|
||||
sce0->ics.swb_sizes[g],
|
||||
sce0->sf_idx[(w+w2)*16+g],
|
||||
sce0->band_type[(w+w2)*16+g],
|
||||
lambda / maxthr, INFINITY, NULL, 0);
|
||||
lambda / maxthr, INFINITY, NULL);
|
||||
dist2 += quantize_band_cost(s, S,
|
||||
S34,
|
||||
sce1->ics.swb_sizes[g],
|
||||
sce1->sf_idx[(w+w2)*16+g],
|
||||
sce1->band_type[(w+w2)*16+g],
|
||||
lambda / minthr, INFINITY, NULL, 0);
|
||||
lambda / minthr, INFINITY, NULL);
|
||||
}
|
||||
cpe->ms_mask[w*16+g] = dist2 < dist1;
|
||||
}
|
||||
@@ -960,64 +1177,24 @@ AACCoefficientsEncoder ff_aac_coders[AAC_CODER_NB] = {
|
||||
search_for_quantizers_faac,
|
||||
encode_window_bands_info,
|
||||
quantize_and_encode_band,
|
||||
ff_aac_encode_tns_info,
|
||||
ff_aac_encode_main_pred,
|
||||
ff_aac_adjust_common_prediction,
|
||||
ff_aac_apply_main_pred,
|
||||
ff_aac_apply_tns,
|
||||
set_special_band_scalefactors,
|
||||
search_for_pns,
|
||||
ff_aac_search_for_tns,
|
||||
search_for_ms,
|
||||
ff_aac_search_for_is,
|
||||
ff_aac_search_for_pred,
|
||||
},
|
||||
[AAC_CODER_ANMR] = {
|
||||
search_for_quantizers_anmr,
|
||||
encode_window_bands_info,
|
||||
quantize_and_encode_band,
|
||||
ff_aac_encode_tns_info,
|
||||
ff_aac_encode_main_pred,
|
||||
ff_aac_adjust_common_prediction,
|
||||
ff_aac_apply_main_pred,
|
||||
ff_aac_apply_tns,
|
||||
set_special_band_scalefactors,
|
||||
search_for_pns,
|
||||
ff_aac_search_for_tns,
|
||||
search_for_ms,
|
||||
ff_aac_search_for_is,
|
||||
ff_aac_search_for_pred,
|
||||
},
|
||||
[AAC_CODER_TWOLOOP] = {
|
||||
search_for_quantizers_twoloop,
|
||||
codebook_trellis_rate,
|
||||
quantize_and_encode_band,
|
||||
ff_aac_encode_tns_info,
|
||||
ff_aac_encode_main_pred,
|
||||
ff_aac_adjust_common_prediction,
|
||||
ff_aac_apply_main_pred,
|
||||
ff_aac_apply_tns,
|
||||
set_special_band_scalefactors,
|
||||
search_for_pns,
|
||||
ff_aac_search_for_tns,
|
||||
search_for_ms,
|
||||
ff_aac_search_for_is,
|
||||
ff_aac_search_for_pred,
|
||||
},
|
||||
[AAC_CODER_FAST] = {
|
||||
search_for_quantizers_fast,
|
||||
encode_window_bands_info,
|
||||
quantize_and_encode_band,
|
||||
ff_aac_encode_tns_info,
|
||||
ff_aac_encode_main_pred,
|
||||
ff_aac_adjust_common_prediction,
|
||||
ff_aac_apply_main_pred,
|
||||
ff_aac_apply_tns,
|
||||
set_special_band_scalefactors,
|
||||
search_for_pns,
|
||||
ff_aac_search_for_tns,
|
||||
search_for_ms,
|
||||
ff_aac_search_for_is,
|
||||
ff_aac_search_for_pred,
|
||||
},
|
||||
};
|
||||
|
||||
+3033
-14
File diff suppressed because it is too large
Load Diff
@@ -1,463 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* AAC decoder fixed-point implementation
|
||||
*
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
*
|
||||
* 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
|
||||
* AAC decoder
|
||||
* @author Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* @author Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
*
|
||||
* Fixed point implementation
|
||||
* @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com )
|
||||
*/
|
||||
|
||||
#define FFT_FLOAT 0
|
||||
#define FFT_FIXED_32 1
|
||||
#define USE_FIXED 1
|
||||
|
||||
#include "libavutil/fixed_dsp.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "avcodec.h"
|
||||
#include "internal.h"
|
||||
#include "get_bits.h"
|
||||
#include "fft.h"
|
||||
#include "lpc.h"
|
||||
#include "kbdwin.h"
|
||||
#include "sinewin.h"
|
||||
|
||||
#include "aac.h"
|
||||
#include "aactab.h"
|
||||
#include "aacdectab.h"
|
||||
#include "cbrt_tablegen.h"
|
||||
#include "sbr.h"
|
||||
#include "aacsbr.h"
|
||||
#include "mpeg4audio.h"
|
||||
#include "aacadtsdec.h"
|
||||
#include "libavutil/intfloat.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
static av_always_inline void reset_predict_state(PredictorState *ps)
|
||||
{
|
||||
ps->r0.mant = 0;
|
||||
ps->r0.exp = 0;
|
||||
ps->r1.mant = 0;
|
||||
ps->r1.exp = 0;
|
||||
ps->cor0.mant = 0;
|
||||
ps->cor0.exp = 0;
|
||||
ps->cor1.mant = 0;
|
||||
ps->cor1.exp = 0;
|
||||
ps->var0.mant = 0x20000000;
|
||||
ps->var0.exp = 1;
|
||||
ps->var1.mant = 0x20000000;
|
||||
ps->var1.exp = 1;
|
||||
}
|
||||
|
||||
static const int exp2tab[4] = { Q31(1.0000000000/2), Q31(1.1892071150/2), Q31(1.4142135624/2), Q31(1.6817928305/2) }; // 2^0, 2^0.25, 2^0.5, 2^0.75
|
||||
|
||||
static inline int *DEC_SPAIR(int *dst, unsigned idx)
|
||||
{
|
||||
dst[0] = (idx & 15) - 4;
|
||||
dst[1] = (idx >> 4 & 15) - 4;
|
||||
|
||||
return dst + 2;
|
||||
}
|
||||
|
||||
static inline int *DEC_SQUAD(int *dst, unsigned idx)
|
||||
{
|
||||
dst[0] = (idx & 3) - 1;
|
||||
dst[1] = (idx >> 2 & 3) - 1;
|
||||
dst[2] = (idx >> 4 & 3) - 1;
|
||||
dst[3] = (idx >> 6 & 3) - 1;
|
||||
|
||||
return dst + 4;
|
||||
}
|
||||
|
||||
static inline int *DEC_UPAIR(int *dst, unsigned idx, unsigned sign)
|
||||
{
|
||||
dst[0] = (idx & 15) * (1 - (sign & 0xFFFFFFFE));
|
||||
dst[1] = (idx >> 4 & 15) * (1 - ((sign & 1) * 2));
|
||||
|
||||
return dst + 2;
|
||||
}
|
||||
|
||||
static inline int *DEC_UQUAD(int *dst, unsigned idx, unsigned sign)
|
||||
{
|
||||
unsigned nz = idx >> 12;
|
||||
|
||||
dst[0] = (idx & 3) * (1 + (((int)sign >> 31) * 2));
|
||||
sign <<= nz & 1;
|
||||
nz >>= 1;
|
||||
dst[1] = (idx >> 2 & 3) * (1 + (((int)sign >> 31) * 2));
|
||||
sign <<= nz & 1;
|
||||
nz >>= 1;
|
||||
dst[2] = (idx >> 4 & 3) * (1 + (((int)sign >> 31) * 2));
|
||||
sign <<= nz & 1;
|
||||
nz >>= 1;
|
||||
dst[3] = (idx >> 6 & 3) * (1 + (((int)sign >> 31) * 2));
|
||||
|
||||
return dst + 4;
|
||||
}
|
||||
|
||||
static void vector_pow43(int *coefs, int len)
|
||||
{
|
||||
int i, coef;
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
coef = coefs[i];
|
||||
if (coef < 0)
|
||||
coef = -(int)cbrt_tab[(-coef) & 8191];
|
||||
else
|
||||
coef = (int)cbrt_tab[ coef & 8191];
|
||||
coefs[i] = coef;
|
||||
}
|
||||
}
|
||||
|
||||
static void subband_scale(int *dst, int *src, int scale, int offset, int len)
|
||||
{
|
||||
int ssign = scale < 0 ? -1 : 1;
|
||||
int s = FFABS(scale);
|
||||
unsigned int round;
|
||||
int i, out, c = exp2tab[s & 3];
|
||||
|
||||
s = offset - (s >> 2);
|
||||
|
||||
if (s > 31) {
|
||||
for (i=0; i<len; i++) {
|
||||
dst[i] = 0;
|
||||
}
|
||||
} else if (s > 0) {
|
||||
round = 1 << (s-1);
|
||||
for (i=0; i<len; i++) {
|
||||
out = (int)(((int64_t)src[i] * c) >> 32);
|
||||
dst[i] = ((int)(out+round) >> s) * ssign;
|
||||
}
|
||||
} else if (s > -32) {
|
||||
s = s + 32;
|
||||
round = 1 << (s-1);
|
||||
for (i=0; i<len; i++) {
|
||||
out = (int)((int64_t)((int64_t)src[i] * c + round) >> s);
|
||||
dst[i] = out * (unsigned)ssign;
|
||||
}
|
||||
} else {
|
||||
av_log(NULL, AV_LOG_ERROR, "Overflow in subband_scale()\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void noise_scale(int *coefs, int scale, int band_energy, int len)
|
||||
{
|
||||
int s = -scale;
|
||||
unsigned int round;
|
||||
int i, out, c = exp2tab[s & 3];
|
||||
int nlz = 0;
|
||||
|
||||
av_assert0(s >= 0);
|
||||
while (band_energy > 0x7fff) {
|
||||
band_energy >>= 1;
|
||||
nlz++;
|
||||
}
|
||||
c /= band_energy;
|
||||
s = 21 + nlz - (s >> 2);
|
||||
|
||||
if (s > 31) {
|
||||
for (i=0; i<len; i++) {
|
||||
coefs[i] = 0;
|
||||
}
|
||||
} else if (s >= 0) {
|
||||
round = s ? 1 << (s-1) : 0;
|
||||
for (i=0; i<len; i++) {
|
||||
out = (int)(((int64_t)coefs[i] * c) >> 32);
|
||||
coefs[i] = -((int)(out+round) >> s);
|
||||
}
|
||||
}
|
||||
else {
|
||||
s = s + 32;
|
||||
if (s > 0) {
|
||||
round = 1 << (s-1);
|
||||
for (i=0; i<len; i++) {
|
||||
out = (int)((int64_t)((int64_t)coefs[i] * c + round) >> s);
|
||||
coefs[i] = -out;
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<len; i++)
|
||||
coefs[i] = -(int64_t)coefs[i] * c * (1 << -s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static av_always_inline SoftFloat flt16_round(SoftFloat pf)
|
||||
{
|
||||
SoftFloat tmp;
|
||||
int s;
|
||||
|
||||
tmp.exp = pf.exp;
|
||||
s = pf.mant >> 31;
|
||||
tmp.mant = (pf.mant ^ s) - s;
|
||||
tmp.mant = (tmp.mant + 0x00200000U) & 0xFFC00000U;
|
||||
tmp.mant = (tmp.mant ^ s) - s;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static av_always_inline SoftFloat flt16_even(SoftFloat pf)
|
||||
{
|
||||
SoftFloat tmp;
|
||||
int s;
|
||||
|
||||
tmp.exp = pf.exp;
|
||||
s = pf.mant >> 31;
|
||||
tmp.mant = (pf.mant ^ s) - s;
|
||||
tmp.mant = (tmp.mant + 0x001FFFFFU + (tmp.mant & 0x00400000U >> 16)) & 0xFFC00000U;
|
||||
tmp.mant = (tmp.mant ^ s) - s;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static av_always_inline SoftFloat flt16_trunc(SoftFloat pf)
|
||||
{
|
||||
SoftFloat pun;
|
||||
int s;
|
||||
|
||||
pun.exp = pf.exp;
|
||||
s = pf.mant >> 31;
|
||||
pun.mant = (pf.mant ^ s) - s;
|
||||
pun.mant = pun.mant & 0xFFC00000U;
|
||||
pun.mant = (pun.mant ^ s) - s;
|
||||
|
||||
return pun;
|
||||
}
|
||||
|
||||
static av_always_inline void predict(PredictorState *ps, int *coef,
|
||||
int output_enable)
|
||||
{
|
||||
const SoftFloat a = { 1023410176, 0 }; // 61.0 / 64
|
||||
const SoftFloat alpha = { 973078528, 0 }; // 29.0 / 32
|
||||
SoftFloat e0, e1;
|
||||
SoftFloat pv;
|
||||
SoftFloat k1, k2;
|
||||
SoftFloat r0 = ps->r0, r1 = ps->r1;
|
||||
SoftFloat cor0 = ps->cor0, cor1 = ps->cor1;
|
||||
SoftFloat var0 = ps->var0, var1 = ps->var1;
|
||||
SoftFloat tmp;
|
||||
|
||||
if (var0.exp > 1 || (var0.exp == 1 && var0.mant > 0x20000000)) {
|
||||
k1 = av_mul_sf(cor0, flt16_even(av_div_sf(a, var0)));
|
||||
}
|
||||
else {
|
||||
k1.mant = 0;
|
||||
k1.exp = 0;
|
||||
}
|
||||
|
||||
if (var1.exp > 1 || (var1.exp == 1 && var1.mant > 0x20000000)) {
|
||||
k2 = av_mul_sf(cor1, flt16_even(av_div_sf(a, var1)));
|
||||
}
|
||||
else {
|
||||
k2.mant = 0;
|
||||
k2.exp = 0;
|
||||
}
|
||||
|
||||
tmp = av_mul_sf(k1, r0);
|
||||
pv = flt16_round(av_add_sf(tmp, av_mul_sf(k2, r1)));
|
||||
if (output_enable) {
|
||||
int shift = 28 - pv.exp;
|
||||
|
||||
if (shift < 31) {
|
||||
if (shift > 0) {
|
||||
*coef += (unsigned)((pv.mant + (1 << (shift - 1))) >> shift);
|
||||
} else
|
||||
*coef += (unsigned)pv.mant << -shift;
|
||||
}
|
||||
}
|
||||
|
||||
e0 = av_int2sf(*coef, 2);
|
||||
e1 = av_sub_sf(e0, tmp);
|
||||
|
||||
ps->cor1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor1), av_mul_sf(r1, e1)));
|
||||
tmp = av_add_sf(av_mul_sf(r1, r1), av_mul_sf(e1, e1));
|
||||
tmp.exp--;
|
||||
ps->var1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var1), tmp));
|
||||
ps->cor0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor0), av_mul_sf(r0, e0)));
|
||||
tmp = av_add_sf(av_mul_sf(r0, r0), av_mul_sf(e0, e0));
|
||||
tmp.exp--;
|
||||
ps->var0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var0), tmp));
|
||||
|
||||
ps->r1 = flt16_trunc(av_mul_sf(a, av_sub_sf(r0, av_mul_sf(k1, e0))));
|
||||
ps->r0 = flt16_trunc(av_mul_sf(a, e0));
|
||||
}
|
||||
|
||||
|
||||
static const int cce_scale_fixed[8] = {
|
||||
Q30(1.0), //2^(0/8)
|
||||
Q30(1.0905077327), //2^(1/8)
|
||||
Q30(1.1892071150), //2^(2/8)
|
||||
Q30(1.2968395547), //2^(3/8)
|
||||
Q30(1.4142135624), //2^(4/8)
|
||||
Q30(1.5422108254), //2^(5/8)
|
||||
Q30(1.6817928305), //2^(6/8)
|
||||
Q30(1.8340080864), //2^(7/8)
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply dependent channel coupling (applied before IMDCT).
|
||||
*
|
||||
* @param index index into coupling gain array
|
||||
*/
|
||||
static void apply_dependent_coupling_fixed(AACContext *ac,
|
||||
SingleChannelElement *target,
|
||||
ChannelElement *cce, int index)
|
||||
{
|
||||
IndividualChannelStream *ics = &cce->ch[0].ics;
|
||||
const uint16_t *offsets = ics->swb_offset;
|
||||
int *dest = target->coeffs;
|
||||
const int *src = cce->ch[0].coeffs;
|
||||
int g, i, group, k, idx = 0;
|
||||
if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
|
||||
av_log(ac->avctx, AV_LOG_ERROR,
|
||||
"Dependent coupling is not supported together with LTP\n");
|
||||
return;
|
||||
}
|
||||
for (g = 0; g < ics->num_window_groups; g++) {
|
||||
for (i = 0; i < ics->max_sfb; i++, idx++) {
|
||||
if (cce->ch[0].band_type[idx] != ZERO_BT) {
|
||||
const int gain = cce->coup.gain[index][idx];
|
||||
int shift, round, c, tmp;
|
||||
|
||||
if (gain < 0) {
|
||||
c = -cce_scale_fixed[-gain & 7];
|
||||
shift = (-gain-1024) >> 3;
|
||||
}
|
||||
else {
|
||||
c = cce_scale_fixed[gain & 7];
|
||||
shift = (gain-1024) >> 3;
|
||||
}
|
||||
|
||||
if (shift < -31) {
|
||||
// Nothing to do
|
||||
} else if (shift < 0) {
|
||||
shift = -shift;
|
||||
round = 1 << (shift - 1);
|
||||
|
||||
for (group = 0; group < ics->group_len[g]; group++) {
|
||||
for (k = offsets[i]; k < offsets[i + 1]; k++) {
|
||||
tmp = (int)(((int64_t)src[group * 128 + k] * c + \
|
||||
(int64_t)0x1000000000) >> 37);
|
||||
dest[group * 128 + k] += (tmp + (int64_t)round) >> shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (group = 0; group < ics->group_len[g]; group++) {
|
||||
for (k = offsets[i]; k < offsets[i + 1]; k++) {
|
||||
tmp = (int)(((int64_t)src[group * 128 + k] * c + \
|
||||
(int64_t)0x1000000000) >> 37);
|
||||
dest[group * 128 + k] += tmp * (1U << shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dest += ics->group_len[g] * 128;
|
||||
src += ics->group_len[g] * 128;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply independent channel coupling (applied after IMDCT).
|
||||
*
|
||||
* @param index index into coupling gain array
|
||||
*/
|
||||
static void apply_independent_coupling_fixed(AACContext *ac,
|
||||
SingleChannelElement *target,
|
||||
ChannelElement *cce, int index)
|
||||
{
|
||||
int i, c, shift, round, tmp;
|
||||
const int gain = cce->coup.gain[index][0];
|
||||
const int *src = cce->ch[0].ret;
|
||||
unsigned int *dest = target->ret;
|
||||
const int len = 1024 << (ac->oc[1].m4ac.sbr == 1);
|
||||
|
||||
c = cce_scale_fixed[gain & 7];
|
||||
shift = (gain-1024) >> 3;
|
||||
if (shift < 0) {
|
||||
shift = -shift;
|
||||
round = 1 << (shift - 1);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
|
||||
dest[i] += (tmp + round) >> shift;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < len; i++) {
|
||||
tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
|
||||
dest[i] += tmp * (1U << shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "aacdec_template.c"
|
||||
|
||||
AVCodec ff_aac_fixed_decoder = {
|
||||
.name = "aac_fixed",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = AV_CODEC_ID_AAC,
|
||||
.priv_data_size = sizeof(AACContext),
|
||||
.init = aac_decode_init,
|
||||
.close = aac_decode_close,
|
||||
.decode = aac_decode_frame,
|
||||
.sample_fmts = (const enum AVSampleFormat[]) {
|
||||
AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_NONE
|
||||
},
|
||||
.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
|
||||
.channel_layouts = aac_channel_layout,
|
||||
.flush = flush,
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
+38
-3
@@ -38,11 +38,46 @@
|
||||
/* @name ltp_coef
|
||||
* Table of the LTP coefficients
|
||||
*/
|
||||
static const INTFLOAT ltp_coef[8] = {
|
||||
Q30(0.570829f), Q30(0.696616f), Q30(0.813004f), Q30(0.911304f),
|
||||
Q30(0.984900f), Q30(1.067894f), Q30(1.194601f), Q30(1.369533f),
|
||||
static const float ltp_coef[8] = {
|
||||
0.570829, 0.696616, 0.813004, 0.911304,
|
||||
0.984900, 1.067894, 1.194601, 1.369533,
|
||||
};
|
||||
|
||||
/* @name tns_tmp2_map
|
||||
* Tables of the tmp2[] arrays of LPC coefficients used for TNS.
|
||||
* The suffix _M_N[] indicate the values of coef_compress and coef_res
|
||||
* respectively.
|
||||
* @{
|
||||
*/
|
||||
static const float tns_tmp2_map_1_3[4] = {
|
||||
0.00000000, -0.43388373, 0.64278758, 0.34202015,
|
||||
};
|
||||
|
||||
static const float tns_tmp2_map_0_3[8] = {
|
||||
0.00000000, -0.43388373, -0.78183150, -0.97492790,
|
||||
0.98480773, 0.86602539, 0.64278758, 0.34202015,
|
||||
};
|
||||
|
||||
static const float tns_tmp2_map_1_4[8] = {
|
||||
0.00000000, -0.20791170, -0.40673664, -0.58778524,
|
||||
0.67369562, 0.52643216, 0.36124167, 0.18374951,
|
||||
};
|
||||
|
||||
static const float tns_tmp2_map_0_4[16] = {
|
||||
0.00000000, -0.20791170, -0.40673664, -0.58778524,
|
||||
-0.74314481, -0.86602539, -0.95105654, -0.99452192,
|
||||
0.99573416, 0.96182561, 0.89516330, 0.79801720,
|
||||
0.67369562, 0.52643216, 0.36124167, 0.18374951,
|
||||
};
|
||||
|
||||
static const float * const tns_tmp2_map[4] = {
|
||||
tns_tmp2_map_0_3,
|
||||
tns_tmp2_map_0_4,
|
||||
tns_tmp2_map_1_3,
|
||||
tns_tmp2_map_1_4
|
||||
};
|
||||
// @}
|
||||
|
||||
static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 4, 5, 0, 5, 0 };
|
||||
|
||||
static const uint8_t aac_channel_layout_map[16][5][3] = {
|
||||
|
||||
+194
-235
@@ -27,6 +27,7 @@
|
||||
/***********************************
|
||||
* TODOs:
|
||||
* add sane pulse detection
|
||||
* add temporal noise shaping
|
||||
***********************************/
|
||||
|
||||
#include "libavutil/float_dsp.h"
|
||||
@@ -41,11 +42,127 @@
|
||||
#include "aac.h"
|
||||
#include "aactab.h"
|
||||
#include "aacenc.h"
|
||||
#include "aacenctab.h"
|
||||
#include "aacenc_utils.h"
|
||||
|
||||
#include "psymodel.h"
|
||||
|
||||
#define AAC_MAX_CHANNELS 6
|
||||
|
||||
#define ERROR_IF(cond, ...) \
|
||||
if (cond) { \
|
||||
av_log(avctx, AV_LOG_ERROR, __VA_ARGS__); \
|
||||
return AVERROR(EINVAL); \
|
||||
}
|
||||
|
||||
#define WARN_IF(cond, ...) \
|
||||
if (cond) { \
|
||||
av_log(avctx, AV_LOG_WARNING, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
float ff_aac_pow34sf_tab[428];
|
||||
|
||||
static const uint8_t swb_size_1024_96[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 12, 16, 16, 24, 28, 36, 44,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_64[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8,
|
||||
12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 36,
|
||||
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_48[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28,
|
||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||
96
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_32[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28,
|
||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_24[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28,
|
||||
32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_16[] = {
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28,
|
||||
32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_8[] = {
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
|
||||
16, 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28, 28,
|
||||
32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80
|
||||
};
|
||||
|
||||
static const uint8_t *swb_size_1024[] = {
|
||||
swb_size_1024_96, swb_size_1024_96, swb_size_1024_64,
|
||||
swb_size_1024_48, swb_size_1024_48, swb_size_1024_32,
|
||||
swb_size_1024_24, swb_size_1024_24, swb_size_1024_16,
|
||||
swb_size_1024_16, swb_size_1024_16, swb_size_1024_8,
|
||||
swb_size_1024_8
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_96[] = {
|
||||
4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_48[] = {
|
||||
4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_24[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_16[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_8[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20
|
||||
};
|
||||
|
||||
static const uint8_t *swb_size_128[] = {
|
||||
/* the last entry on the following row is swb_size_128_64 but is a
|
||||
duplicate of swb_size_128_96 */
|
||||
swb_size_128_96, swb_size_128_96, swb_size_128_96,
|
||||
swb_size_128_48, swb_size_128_48, swb_size_128_48,
|
||||
swb_size_128_24, swb_size_128_24, swb_size_128_16,
|
||||
swb_size_128_16, swb_size_128_16, swb_size_128_8,
|
||||
swb_size_128_8
|
||||
};
|
||||
|
||||
/** default channel configurations */
|
||||
static const uint8_t aac_chan_configs[6][5] = {
|
||||
{1, TYPE_SCE}, // 1 channel - single channel element
|
||||
{1, TYPE_CPE}, // 2 channels - channel pair
|
||||
{2, TYPE_SCE, TYPE_CPE}, // 3 channels - center + stereo
|
||||
{3, TYPE_SCE, TYPE_CPE, TYPE_SCE}, // 4 channels - front center + stereo + back center
|
||||
{3, TYPE_SCE, TYPE_CPE, TYPE_CPE}, // 5 channels - front center + stereo + back stereo
|
||||
{4, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_LFE}, // 6 channels - front center + stereo + back stereo + LFE
|
||||
};
|
||||
|
||||
/**
|
||||
* Table to remap channels from libavcodec's default order to AAC order.
|
||||
*/
|
||||
static const uint8_t aac_chan_maps[AAC_MAX_CHANNELS][AAC_MAX_CHANNELS] = {
|
||||
{ 0 },
|
||||
{ 0, 1 },
|
||||
{ 2, 0, 1 },
|
||||
{ 2, 0, 1, 3 },
|
||||
{ 2, 0, 1, 3, 4 },
|
||||
{ 2, 0, 1, 4, 5, 3 },
|
||||
};
|
||||
|
||||
/**
|
||||
* Make AAC audio config object.
|
||||
* @see 1.6.2.1 "Syntax - AudioSpecificConfig"
|
||||
@@ -56,7 +173,7 @@ static void put_audio_specific_config(AVCodecContext *avctx)
|
||||
AACEncContext *s = avctx->priv_data;
|
||||
|
||||
init_put_bits(&pb, avctx->extradata, avctx->extradata_size);
|
||||
put_bits(&pb, 5, s->profile+1); //profile
|
||||
put_bits(&pb, 5, 2); //object type - AAC-LC
|
||||
put_bits(&pb, 4, s->samplerate_index); //sample rate index
|
||||
put_bits(&pb, 4, s->channels);
|
||||
//GASpecificConfig
|
||||
@@ -148,7 +265,7 @@ static void apply_window_and_mdct(AACEncContext *s, SingleChannelElement *sce,
|
||||
s->mdct1024.mdct_calc(&s->mdct1024, sce->coeffs, output);
|
||||
else
|
||||
for (i = 0; i < 1024; i += 128)
|
||||
s->mdct128.mdct_calc(&s->mdct128, &sce->coeffs[i], output + i*2);
|
||||
s->mdct128.mdct_calc(&s->mdct128, sce->coeffs + i, output + i*2);
|
||||
memcpy(audio, audio + 1024, sizeof(audio[0]) * 1024);
|
||||
memcpy(sce->pcoeffs, sce->coeffs, sizeof(sce->pcoeffs));
|
||||
}
|
||||
@@ -166,7 +283,7 @@ static void put_ics_info(AACEncContext *s, IndividualChannelStream *info)
|
||||
put_bits(&s->pb, 1, info->use_kb_window[0]);
|
||||
if (info->window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
|
||||
put_bits(&s->pb, 6, info->max_sfb);
|
||||
put_bits(&s->pb, 1, !!info->predictor_present);
|
||||
put_bits(&s->pb, 1, 0); // no prediction
|
||||
} else {
|
||||
put_bits(&s->pb, 4, info->max_sfb);
|
||||
for (w = 1; w < 8; w++)
|
||||
@@ -195,14 +312,26 @@ static void encode_ms_info(PutBitContext *pb, ChannelElement *cpe)
|
||||
static void adjust_frame_information(ChannelElement *cpe, int chans)
|
||||
{
|
||||
int i, w, w2, g, ch;
|
||||
int maxsfb, cmaxsfb;
|
||||
int start, maxsfb, cmaxsfb;
|
||||
|
||||
for (ch = 0; ch < chans; ch++) {
|
||||
IndividualChannelStream *ics = &cpe->ch[ch].ics;
|
||||
start = 0;
|
||||
maxsfb = 0;
|
||||
cpe->ch[ch].pulse.num_pulse = 0;
|
||||
for (w = 0; w < ics->num_windows; w += ics->group_len[w]) {
|
||||
for (w2 = 0; w2 < ics->group_len[w]; w2++) {
|
||||
for (w2 = 0; w2 < ics->group_len[w]; w2++) {
|
||||
start = (w+w2) * 128;
|
||||
for (g = 0; g < ics->num_swb; g++) {
|
||||
//apply M/S
|
||||
if (cpe->common_window && !ch && cpe->ms_mask[w*16 + g]) {
|
||||
for (i = 0; i < ics->swb_sizes[g]; i++) {
|
||||
cpe->ch[0].coeffs[start+i] = (cpe->ch[0].pcoeffs[start+i] + cpe->ch[1].pcoeffs[start+i]) * 0.5f;
|
||||
cpe->ch[1].coeffs[start+i] = cpe->ch[0].coeffs[start+i] - cpe->ch[1].pcoeffs[start+i];
|
||||
}
|
||||
}
|
||||
start += ics->swb_sizes[g];
|
||||
}
|
||||
for (cmaxsfb = ics->num_swb; cmaxsfb > 0 && cpe->ch[ch].zeroes[w*16+cmaxsfb-1]; cmaxsfb--)
|
||||
;
|
||||
maxsfb = FFMAX(maxsfb, cmaxsfb);
|
||||
@@ -242,59 +371,6 @@ static void adjust_frame_information(ChannelElement *cpe, int chans)
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_intensity_stereo(ChannelElement *cpe)
|
||||
{
|
||||
int w, w2, g, i;
|
||||
IndividualChannelStream *ics = &cpe->ch[0].ics;
|
||||
if (!cpe->common_window)
|
||||
return;
|
||||
for (w = 0; w < ics->num_windows; w += ics->group_len[w]) {
|
||||
for (w2 = 0; w2 < ics->group_len[w]; w2++) {
|
||||
int start = (w+w2) * 128;
|
||||
for (g = 0; g < ics->num_swb; g++) {
|
||||
int p = -1 + 2 * (cpe->ch[1].band_type[w*16+g] - 14);
|
||||
float scale = cpe->ch[0].is_ener[w*16+g];
|
||||
if (!cpe->is_mask[w*16 + g]) {
|
||||
start += ics->swb_sizes[g];
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < ics->swb_sizes[g]; i++) {
|
||||
float sum = (cpe->ch[0].coeffs[start+i] + p*cpe->ch[1].coeffs[start+i])*scale;
|
||||
cpe->ch[0].coeffs[start+i] = sum;
|
||||
cpe->ch[1].coeffs[start+i] = 0.0f;
|
||||
}
|
||||
start += ics->swb_sizes[g];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_mid_side_stereo(ChannelElement *cpe)
|
||||
{
|
||||
int w, w2, g, i;
|
||||
IndividualChannelStream *ics = &cpe->ch[0].ics;
|
||||
if (!cpe->common_window)
|
||||
return;
|
||||
for (w = 0; w < ics->num_windows; w += ics->group_len[w]) {
|
||||
for (w2 = 0; w2 < ics->group_len[w]; w2++) {
|
||||
int start = (w+w2) * 128;
|
||||
for (g = 0; g < ics->num_swb; g++) {
|
||||
if (!cpe->ms_mask[w*16 + g]) {
|
||||
start += ics->swb_sizes[g];
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < ics->swb_sizes[g]; i++) {
|
||||
float L = (cpe->ch[0].coeffs[start+i] + cpe->ch[1].coeffs[start+i]) * 0.5f;
|
||||
float R = L - cpe->ch[1].coeffs[start+i];
|
||||
cpe->ch[0].coeffs[start+i] = L;
|
||||
cpe->ch[1].coeffs[start+i] = R;
|
||||
}
|
||||
start += ics->swb_sizes[g];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode scalefactor band coding type.
|
||||
*/
|
||||
@@ -302,9 +378,6 @@ static void encode_band_info(AACEncContext *s, SingleChannelElement *sce)
|
||||
{
|
||||
int w;
|
||||
|
||||
if (s->coder->set_special_band_scalefactors)
|
||||
s->coder->set_special_band_scalefactors(s, sce);
|
||||
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
|
||||
s->coder->encode_window_bands_info(s, sce, w, sce->ics.group_len[w], s->lambda);
|
||||
}
|
||||
@@ -316,7 +389,7 @@ static void encode_scale_factors(AVCodecContext *avctx, AACEncContext *s,
|
||||
SingleChannelElement *sce)
|
||||
{
|
||||
int diff, off_sf = sce->sf_idx[0], off_pns = sce->sf_idx[0] - NOISE_OFFSET;
|
||||
int off_is = 0, noise_flag = 1;
|
||||
int noise_flag = 1;
|
||||
int i, w;
|
||||
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
@@ -329,10 +402,6 @@ static void encode_scale_factors(AVCodecContext *avctx, AACEncContext *s,
|
||||
put_bits(&s->pb, NOISE_PRE_BITS, diff + NOISE_PRE);
|
||||
continue;
|
||||
}
|
||||
} else if (sce->band_type[w*16 + i] == INTENSITY_BT ||
|
||||
sce->band_type[w*16 + i] == INTENSITY_BT2) {
|
||||
diff = sce->sf_idx[w*16 + i] - off_is;
|
||||
off_is = sce->sf_idx[w*16 + i];
|
||||
} else {
|
||||
diff = sce->sf_idx[w*16 + i] - off_sf;
|
||||
off_sf = sce->sf_idx[w*16 + i];
|
||||
@@ -378,40 +447,17 @@ static void encode_spectral_coeffs(AACEncContext *s, SingleChannelElement *sce)
|
||||
start += sce->ics.swb_sizes[i];
|
||||
continue;
|
||||
}
|
||||
for (w2 = w; w2 < w + sce->ics.group_len[w]; w2++) {
|
||||
s->coder->quantize_and_encode_band(s, &s->pb,
|
||||
&sce->coeffs[start + w2*128],
|
||||
NULL, sce->ics.swb_sizes[i],
|
||||
for (w2 = w; w2 < w + sce->ics.group_len[w]; w2++)
|
||||
s->coder->quantize_and_encode_band(s, &s->pb, sce->coeffs + start + w2*128,
|
||||
sce->ics.swb_sizes[i],
|
||||
sce->sf_idx[w*16 + i],
|
||||
sce->band_type[w*16 + i],
|
||||
s->lambda,
|
||||
sce->ics.window_clipping[w]);
|
||||
}
|
||||
s->lambda);
|
||||
start += sce->ics.swb_sizes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Downscale spectral coefficients for near-clipping windows to avoid artifacts
|
||||
*/
|
||||
static void avoid_clipping(AACEncContext *s, SingleChannelElement *sce)
|
||||
{
|
||||
int start, i, j, w;
|
||||
|
||||
if (sce->ics.clip_avoidance_factor < 1.0f) {
|
||||
for (w = 0; w < sce->ics.num_windows; w++) {
|
||||
start = 0;
|
||||
for (i = 0; i < sce->ics.max_sfb; i++) {
|
||||
float *swb_coeffs = &sce->coeffs[start + w*128];
|
||||
for (j = 0; j < sce->ics.swb_sizes[i]; j++)
|
||||
swb_coeffs[j] *= sce->ics.clip_avoidance_factor;
|
||||
start += sce->ics.swb_sizes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode one channel of audio data.
|
||||
*/
|
||||
@@ -420,17 +466,12 @@ static int encode_individual_channel(AVCodecContext *avctx, AACEncContext *s,
|
||||
int common_window)
|
||||
{
|
||||
put_bits(&s->pb, 8, sce->sf_idx[0]);
|
||||
if (!common_window) {
|
||||
if (!common_window)
|
||||
put_ics_info(s, &sce->ics);
|
||||
if (s->coder->encode_main_pred)
|
||||
s->coder->encode_main_pred(s, sce);
|
||||
}
|
||||
encode_band_info(s, sce);
|
||||
encode_scale_factors(avctx, s, sce);
|
||||
encode_pulses(s, &sce->pulse);
|
||||
put_bits(&s->pb, 1, !!sce->tns.present);
|
||||
if (s->coder->encode_tns_info)
|
||||
s->coder->encode_tns_info(s, sce);
|
||||
put_bits(&s->pb, 1, 0); //tns
|
||||
put_bits(&s->pb, 1, 0); //ssr
|
||||
encode_spectral_coeffs(s, sce);
|
||||
return 0;
|
||||
@@ -488,12 +529,9 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
||||
AACEncContext *s = avctx->priv_data;
|
||||
float **samples = s->planar_samples, *samples2, *la, *overlap;
|
||||
ChannelElement *cpe;
|
||||
SingleChannelElement *sce;
|
||||
int i, ch, w, chans, tag, start_ch, ret;
|
||||
int ms_mode = 0, is_mode = 0, tns_mode = 0, pred_mode = 0;
|
||||
int i, ch, w, g, chans, tag, start_ch, ret, ms_mode = 0;
|
||||
int chan_el_counter[4];
|
||||
FFPsyWindowInfo windows[AAC_MAX_CHANNELS];
|
||||
int k;
|
||||
|
||||
if (s->last_frame == 2)
|
||||
return 0;
|
||||
@@ -520,7 +558,6 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
||||
for (ch = 0; ch < chans; ch++) {
|
||||
IndividualChannelStream *ics = &cpe->ch[ch].ics;
|
||||
int cur_channel = start_ch + ch;
|
||||
float clip_avoidance_factor;
|
||||
overlap = &samples[cur_channel][0];
|
||||
samples2 = overlap + 1024;
|
||||
la = samples2 + (448+64);
|
||||
@@ -548,50 +585,33 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
||||
ics->num_windows = wi[ch].num_windows;
|
||||
ics->swb_sizes = s->psy.bands [ics->num_windows == 8];
|
||||
ics->num_swb = tag == TYPE_LFE ? ics->num_swb : s->psy.num_bands[ics->num_windows == 8];
|
||||
ics->max_sfb = FFMIN(ics->max_sfb, ics->num_swb);
|
||||
ics->swb_offset = wi[ch].window_type[0] == EIGHT_SHORT_SEQUENCE ?
|
||||
ff_swb_offset_128 [s->samplerate_index]:
|
||||
ff_swb_offset_1024[s->samplerate_index];
|
||||
ics->tns_max_bands = wi[ch].window_type[0] == EIGHT_SHORT_SEQUENCE ?
|
||||
ff_tns_max_bands_128 [s->samplerate_index]:
|
||||
ff_tns_max_bands_1024[s->samplerate_index];
|
||||
clip_avoidance_factor = 0.0f;
|
||||
for (w = 0; w < ics->num_windows; w++)
|
||||
ics->group_len[w] = wi[ch].grouping[w];
|
||||
for (w = 0; w < ics->num_windows; w++) {
|
||||
if (wi[ch].clipping[w] > CLIP_AVOIDANCE_FACTOR) {
|
||||
ics->window_clipping[w] = 1;
|
||||
clip_avoidance_factor = FFMAX(clip_avoidance_factor, wi[ch].clipping[w]);
|
||||
} else {
|
||||
ics->window_clipping[w] = 0;
|
||||
}
|
||||
}
|
||||
if (clip_avoidance_factor > CLIP_AVOIDANCE_FACTOR) {
|
||||
ics->clip_avoidance_factor = CLIP_AVOIDANCE_FACTOR / clip_avoidance_factor;
|
||||
} else {
|
||||
ics->clip_avoidance_factor = 1.0f;
|
||||
}
|
||||
|
||||
apply_window_and_mdct(s, &cpe->ch[ch], overlap);
|
||||
|
||||
for (k = 0; k < 1024; k++) {
|
||||
if (!(fabs(cpe->ch[ch].coeffs[k]) < 1E16)) { // Ensure headroom for energy calculation
|
||||
av_log(avctx, AV_LOG_ERROR, "Input contains (near) NaN/+-Inf\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if (isnan(cpe->ch[ch].coeffs[ 0]) || isinf(cpe->ch[ch].coeffs[ 0]) ||
|
||||
isnan(cpe->ch[ch].coeffs[ 128]) || isinf(cpe->ch[ch].coeffs[ 128]) ||
|
||||
isnan(cpe->ch[ch].coeffs[2*128]) || isinf(cpe->ch[ch].coeffs[2*128]) ||
|
||||
isnan(cpe->ch[ch].coeffs[3*128]) || isinf(cpe->ch[ch].coeffs[3*128]) ||
|
||||
isnan(cpe->ch[ch].coeffs[4*128]) || isinf(cpe->ch[ch].coeffs[4*128]) ||
|
||||
isnan(cpe->ch[ch].coeffs[5*128]) || isinf(cpe->ch[ch].coeffs[5*128]) ||
|
||||
isnan(cpe->ch[ch].coeffs[6*128]) || isinf(cpe->ch[ch].coeffs[6*128]) ||
|
||||
isnan(cpe->ch[ch].coeffs[7*128]) || isinf(cpe->ch[ch].coeffs[7*128])) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Input contains NaN/+-Inf\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
avoid_clipping(s, &cpe->ch[ch]);
|
||||
}
|
||||
start_ch += chans;
|
||||
}
|
||||
if ((ret = ff_alloc_packet2(avctx, avpkt, 8192 * s->channels, 0)) < 0)
|
||||
if ((ret = ff_alloc_packet2(avctx, avpkt, 8192 * s->channels)) < 0)
|
||||
return ret;
|
||||
do {
|
||||
int frame_bits;
|
||||
|
||||
init_put_bits(&s->pb, avpkt->data, avpkt->size);
|
||||
|
||||
if ((avctx->frame_number & 0xFF)==1 && !(avctx->flags & AV_CODEC_FLAG_BITEXACT))
|
||||
if ((avctx->frame_number & 0xFF)==1 && !(avctx->flags & CODEC_FLAG_BITEXACT))
|
||||
put_bitstream_info(s, LIBAVCODEC_IDENT);
|
||||
start_ch = 0;
|
||||
memset(chan_el_counter, 0, sizeof(chan_el_counter));
|
||||
@@ -601,26 +621,16 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
||||
tag = s->chan_map[i+1];
|
||||
chans = tag == TYPE_CPE ? 2 : 1;
|
||||
cpe = &s->cpe[i];
|
||||
cpe->common_window = 0;
|
||||
memset(cpe->is_mask, 0, sizeof(cpe->is_mask));
|
||||
memset(cpe->ms_mask, 0, sizeof(cpe->ms_mask));
|
||||
put_bits(&s->pb, 3, tag);
|
||||
put_bits(&s->pb, 4, chan_el_counter[tag]++);
|
||||
for (ch = 0; ch < chans; ch++) {
|
||||
sce = &cpe->ch[ch];
|
||||
coeffs[ch] = sce->coeffs;
|
||||
sce->ics.predictor_present = 0;
|
||||
memset(&sce->ics.prediction_used, 0, sizeof(sce->ics.prediction_used));
|
||||
memset(&sce->tns, 0, sizeof(TemporalNoiseShaping));
|
||||
for (w = 0; w < 128; w++)
|
||||
if (sce->band_type[w] > RESERVED_BT)
|
||||
sce->band_type[w] = 0;
|
||||
}
|
||||
for (ch = 0; ch < chans; ch++)
|
||||
coeffs[ch] = cpe->ch[ch].coeffs;
|
||||
s->psy.model->analyze(&s->psy, start_ch, coeffs, wi);
|
||||
for (ch = 0; ch < chans; ch++) {
|
||||
s->cur_channel = start_ch + ch;
|
||||
s->coder->search_for_quantizers(avctx, s, &cpe->ch[ch], s->lambda);
|
||||
}
|
||||
cpe->common_window = 0;
|
||||
if (chans > 1
|
||||
&& wi[0].window_type[0] == wi[1].window_type[0]
|
||||
&& wi[0].window_shape == wi[1].window_shape) {
|
||||
@@ -633,59 +643,22 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ch = 0; ch < chans; ch++) { /* TNS and PNS */
|
||||
sce = &cpe->ch[ch];
|
||||
s->cur_channel = start_ch + ch;
|
||||
if (s->options.pns && s->coder->search_for_pns)
|
||||
s->coder->search_for_pns(s, avctx, sce);
|
||||
if (s->options.tns && s->coder->search_for_tns)
|
||||
s->coder->search_for_tns(s, sce);
|
||||
if (s->options.tns && s->coder->apply_tns_filt)
|
||||
s->coder->apply_tns_filt(s, sce);
|
||||
if (sce->tns.present)
|
||||
tns_mode = 1;
|
||||
}
|
||||
s->cur_channel = start_ch;
|
||||
if (s->options.intensity_stereo) { /* Intensity Stereo */
|
||||
if (s->coder->search_for_is)
|
||||
s->coder->search_for_is(s, avctx, cpe);
|
||||
if (cpe->is_mode) is_mode = 1;
|
||||
apply_intensity_stereo(cpe);
|
||||
}
|
||||
if (s->options.pred) { /* Prediction */
|
||||
for (ch = 0; ch < chans; ch++) {
|
||||
sce = &cpe->ch[ch];
|
||||
s->cur_channel = start_ch + ch;
|
||||
if (s->options.pred && s->coder->search_for_pred)
|
||||
s->coder->search_for_pred(s, sce);
|
||||
if (cpe->ch[ch].ics.predictor_present) pred_mode = 1;
|
||||
if (s->options.stereo_mode && cpe->common_window) {
|
||||
if (s->options.stereo_mode > 0) {
|
||||
IndividualChannelStream *ics = &cpe->ch[0].ics;
|
||||
for (w = 0; w < ics->num_windows; w += ics->group_len[w])
|
||||
for (g = 0; g < ics->num_swb; g++)
|
||||
cpe->ms_mask[w*16+g] = 1;
|
||||
} else if (s->coder->search_for_ms) {
|
||||
s->coder->search_for_ms(s, cpe, s->lambda);
|
||||
}
|
||||
if (s->coder->adjust_common_prediction)
|
||||
s->coder->adjust_common_prediction(s, cpe);
|
||||
for (ch = 0; ch < chans; ch++) {
|
||||
sce = &cpe->ch[ch];
|
||||
s->cur_channel = start_ch + ch;
|
||||
if (s->options.pred && s->coder->apply_main_pred)
|
||||
s->coder->apply_main_pred(s, sce);
|
||||
}
|
||||
s->cur_channel = start_ch;
|
||||
}
|
||||
if (s->options.stereo_mode) { /* Mid/Side stereo */
|
||||
if (s->options.stereo_mode == -1 && s->coder->search_for_ms)
|
||||
s->coder->search_for_ms(s, cpe);
|
||||
else if (cpe->common_window)
|
||||
memset(cpe->ms_mask, 1, sizeof(cpe->ms_mask));
|
||||
for (w = 0; w < 128; w++)
|
||||
cpe->ms_mask[w] = cpe->is_mask[w] ? 0 : cpe->ms_mask[w];
|
||||
apply_mid_side_stereo(cpe);
|
||||
}
|
||||
adjust_frame_information(cpe, chans);
|
||||
if (chans == 2) {
|
||||
put_bits(&s->pb, 1, cpe->common_window);
|
||||
if (cpe->common_window) {
|
||||
put_ics_info(s, &cpe->ch[0].ics);
|
||||
if (s->coder->encode_main_pred)
|
||||
s->coder->encode_main_pred(s, &cpe->ch[0]);
|
||||
encode_ms_info(&s->pb, cpe);
|
||||
if (cpe->ms_mode) ms_mode = 1;
|
||||
}
|
||||
@@ -702,7 +675,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
||||
s->psy.bitres.bits = frame_bits / s->channels;
|
||||
break;
|
||||
}
|
||||
if (is_mode || ms_mode || tns_mode || pred_mode) {
|
||||
if (ms_mode) {
|
||||
for (i = 0; i < s->chan_map[0]; i++) {
|
||||
// Must restore coeffs
|
||||
chans = tag == TYPE_CPE ? 2 : 1;
|
||||
@@ -721,7 +694,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
||||
avctx->frame_bits = put_bits_count(&s->pb);
|
||||
|
||||
// rate control stuff
|
||||
if (!(avctx->flags & AV_CODEC_FLAG_QSCALE)) {
|
||||
if (!(avctx->flags & CODEC_FLAG_QSCALE)) {
|
||||
float ratio = avctx->bit_rate * 1024.0f / avctx->sample_rate / avctx->frame_bits;
|
||||
s->lambda *= ratio;
|
||||
s->lambda = FFMIN(s->lambda, 65536.f);
|
||||
@@ -745,7 +718,6 @@ static av_cold int aac_encode_end(AVCodecContext *avctx)
|
||||
ff_mdct_end(&s->mdct1024);
|
||||
ff_mdct_end(&s->mdct128);
|
||||
ff_psy_end(&s->psy);
|
||||
ff_lpc_end(&s->lpc);
|
||||
if (s->psypp)
|
||||
ff_psy_preprocess_end(s->psypp);
|
||||
av_freep(&s->buffer.samples);
|
||||
@@ -759,7 +731,7 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
|
||||
s->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
|
||||
if (!s->fdsp)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
@@ -782,7 +754,7 @@ static av_cold int alloc_buffers(AVCodecContext *avctx, AACEncContext *s)
|
||||
int ch;
|
||||
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->buffer.samples, s->channels, 3 * 1024 * sizeof(s->buffer.samples[0]), alloc_fail);
|
||||
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->cpe, s->chan_map[0], sizeof(ChannelElement), alloc_fail);
|
||||
FF_ALLOCZ_OR_GOTO(avctx, avctx->extradata, 5 + AV_INPUT_BUFFER_PADDING_SIZE, alloc_fail);
|
||||
FF_ALLOCZ_OR_GOTO(avctx, avctx->extradata, 5 + FF_INPUT_BUFFER_PADDING_SIZE, alloc_fail);
|
||||
|
||||
for(ch = 0; ch < s->channels; ch++)
|
||||
s->planar_samples[ch] = s->buffer.samples + 3 * 1024 * ch;
|
||||
@@ -808,29 +780,16 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
|
||||
|
||||
s->channels = avctx->channels;
|
||||
|
||||
ERROR_IF(i == 16 || i >= ff_aac_swb_size_1024_len || i >= ff_aac_swb_size_128_len,
|
||||
ERROR_IF(i == 16
|
||||
|| i >= (sizeof(swb_size_1024) / sizeof(*swb_size_1024))
|
||||
|| i >= (sizeof(swb_size_128) / sizeof(*swb_size_128)),
|
||||
"Unsupported sample rate %d\n", avctx->sample_rate);
|
||||
ERROR_IF(s->channels > AAC_MAX_CHANNELS,
|
||||
"Unsupported number of channels: %d\n", s->channels);
|
||||
ERROR_IF(avctx->profile != FF_PROFILE_UNKNOWN && avctx->profile != FF_PROFILE_AAC_LOW,
|
||||
"Unsupported profile %d\n", avctx->profile);
|
||||
WARN_IF(1024.0 * avctx->bit_rate / avctx->sample_rate > 6144 * s->channels,
|
||||
"Too many bits per frame requested, clamping to max\n");
|
||||
if (avctx->profile == FF_PROFILE_AAC_MAIN) {
|
||||
s->options.pred = 1;
|
||||
} else if ((avctx->profile == FF_PROFILE_AAC_LOW ||
|
||||
avctx->profile == FF_PROFILE_UNKNOWN) && s->options.pred) {
|
||||
s->profile = 0; /* Main */
|
||||
WARN_IF(1, "Prediction requested, changing profile to AAC-Main\n");
|
||||
} else if (avctx->profile == FF_PROFILE_AAC_LOW ||
|
||||
avctx->profile == FF_PROFILE_UNKNOWN) {
|
||||
s->profile = 1; /* Low */
|
||||
} else {
|
||||
ERROR_IF(1, "Unsupported profile %d\n", avctx->profile);
|
||||
}
|
||||
|
||||
if (s->options.aac_coder != AAC_CODER_TWOLOOP) {
|
||||
s->options.intensity_stereo = 0;
|
||||
s->options.pns = 0;
|
||||
}
|
||||
|
||||
avctx->bit_rate = (int)FFMIN(
|
||||
6144 * s->channels / 1024.0 * avctx->sample_rate,
|
||||
@@ -849,8 +808,8 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
|
||||
avctx->extradata_size = 5;
|
||||
put_audio_specific_config(avctx);
|
||||
|
||||
sizes[0] = ff_aac_swb_size_1024[i];
|
||||
sizes[1] = ff_aac_swb_size_128[i];
|
||||
sizes[0] = swb_size_1024[i];
|
||||
sizes[1] = swb_size_128[i];
|
||||
lengths[0] = ff_aac_num_swb_1024[i];
|
||||
lengths[1] = ff_aac_num_swb_128[i];
|
||||
for (i = 0; i < s->chan_map[0]; i++)
|
||||
@@ -860,7 +819,6 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
|
||||
goto fail;
|
||||
s->psypp = ff_psy_preprocess_init(avctx);
|
||||
s->coder = &ff_aac_coders[s->options.aac_coder];
|
||||
ff_lpc_init(&s->lpc, 2*avctx->frame_size, TNS_MAX_ORDER, FF_LPC_TYPE_LEVINSON);
|
||||
|
||||
if (HAVE_MIPSDSPR1)
|
||||
ff_aac_coder_init_mips(s);
|
||||
@@ -869,6 +827,9 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
|
||||
|
||||
ff_aac_tableinit();
|
||||
|
||||
for (i = 0; i < 428; i++)
|
||||
ff_aac_pow34sf_tab[i] = sqrt(ff_aac_pow2sf_tab[i] * sqrt(ff_aac_pow2sf_tab[i]));
|
||||
|
||||
avctx->initial_padding = 1024;
|
||||
ff_af_queue_init(avctx, &s->afq);
|
||||
|
||||
@@ -884,23 +845,14 @@ static const AVOption aacenc_options[] = {
|
||||
{"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.i64 = -1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
|
||||
{"ms_off", "Disable Mid/Side coding", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
|
||||
{"ms_force", "Force Mid/Side for the whole frame if possible", 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
|
||||
{"aac_coder", "Coding algorithm", offsetof(AACEncContext, options.aac_coder), AV_OPT_TYPE_INT, {.i64 = AAC_CODER_TWOLOOP}, 0, AAC_CODER_NB-1, AACENC_FLAGS, "aac_coder"},
|
||||
{"aac_coder", "", offsetof(AACEncContext, options.aac_coder), AV_OPT_TYPE_INT, {.i64 = AAC_CODER_TWOLOOP}, 0, AAC_CODER_NB-1, AACENC_FLAGS, "aac_coder"},
|
||||
{"faac", "FAAC-inspired method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_FAAC}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_coder"},
|
||||
{"anmr", "ANMR method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_ANMR}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_coder"},
|
||||
{"twoloop", "Two loop searching method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_TWOLOOP}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_coder"},
|
||||
{"fast", "Constant quantizer", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_FAST}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_coder"},
|
||||
{"aac_pns", "Perceptual Noise Substitution", offsetof(AACEncContext, options.pns), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, AACENC_FLAGS, "aac_pns"},
|
||||
{"disable", "Disable perceptual noise substitution", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_pns"},
|
||||
{"enable", "Enable perceptual noise substitution", 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_pns"},
|
||||
{"aac_is", "Intensity stereo coding", offsetof(AACEncContext, options.intensity_stereo), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, AACENC_FLAGS, "intensity_stereo"},
|
||||
{"disable", "Disable intensity stereo coding", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, INT_MIN, INT_MAX, AACENC_FLAGS, "intensity_stereo"},
|
||||
{"enable", "Enable intensity stereo coding", 0, AV_OPT_TYPE_CONST, {.i64 = 1}, INT_MIN, INT_MAX, AACENC_FLAGS, "intensity_stereo"},
|
||||
{"aac_tns", "Temporal noise shaping", offsetof(AACEncContext, options.tns), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AACENC_FLAGS, "aac_tns"},
|
||||
{"disable", "Disable temporal noise shaping", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_tns"},
|
||||
{"enable", "Enable temporal noise shaping", 0, AV_OPT_TYPE_CONST, {.i64 = 1}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_tns"},
|
||||
{"aac_pred", "AAC-Main prediction", offsetof(AACEncContext, options.pred), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AACENC_FLAGS, "aac_pred"},
|
||||
{"disable", "Disable AAC-Main prediction", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_pred"},
|
||||
{"enable", "Enable AAC-Main prediction", 0, AV_OPT_TYPE_CONST, {.i64 = 1}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_pred"},
|
||||
{"aac_pns", "Perceptual Noise Substitution", offsetof(AACEncContext, options.pns), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AACENC_FLAGS, "aac_pns"},
|
||||
{"disable", "Disable PNS", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_pns"},
|
||||
{"enable", "Enable PNS (Proof of concept)", 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_pns"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -911,6 +863,13 @@ static const AVClass aacenc_class = {
|
||||
LIBAVUTIL_VERSION_INT,
|
||||
};
|
||||
|
||||
/* duplicated from avpriv_mpeg4audio_sample_rates to avoid shared build
|
||||
* failures */
|
||||
static const int mpeg4audio_sample_rates[16] = {
|
||||
96000, 88200, 64000, 48000, 44100, 32000,
|
||||
24000, 22050, 16000, 12000, 11025, 8000, 7350
|
||||
};
|
||||
|
||||
AVCodec ff_aac_encoder = {
|
||||
.name = "aac",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
|
||||
@@ -921,8 +880,8 @@ AVCodec ff_aac_encoder = {
|
||||
.encode2 = aac_encode_frame,
|
||||
.close = aac_encode_end,
|
||||
.supported_samplerates = mpeg4audio_sample_rates,
|
||||
.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY |
|
||||
AV_CODEC_CAP_EXPERIMENTAL,
|
||||
.capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY |
|
||||
CODEC_CAP_EXPERIMENTAL,
|
||||
.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
.priv_class = &aacenc_class,
|
||||
|
||||
+5
-20
@@ -30,8 +30,6 @@
|
||||
#include "audio_frame_queue.h"
|
||||
#include "psymodel.h"
|
||||
|
||||
#include "lpc.h"
|
||||
|
||||
typedef enum AACCoder {
|
||||
AAC_CODER_FAAC = 0,
|
||||
AAC_CODER_ANMR,
|
||||
@@ -45,9 +43,6 @@ typedef struct AACEncOptions {
|
||||
int stereo_mode;
|
||||
int aac_coder;
|
||||
int pns;
|
||||
int tns;
|
||||
int pred;
|
||||
int intensity_stereo;
|
||||
} AACEncOptions;
|
||||
|
||||
struct AACEncContext;
|
||||
@@ -57,19 +52,9 @@ typedef struct AACCoefficientsEncoder {
|
||||
SingleChannelElement *sce, const float lambda);
|
||||
void (*encode_window_bands_info)(struct AACEncContext *s, SingleChannelElement *sce,
|
||||
int win, int group_len, const float lambda);
|
||||
void (*quantize_and_encode_band)(struct AACEncContext *s, PutBitContext *pb, const float *in, float *out, int size,
|
||||
int scale_idx, int cb, const float lambda, int rtz);
|
||||
void (*encode_tns_info)(struct AACEncContext *s, SingleChannelElement *sce);
|
||||
void (*encode_main_pred)(struct AACEncContext *s, SingleChannelElement *sce);
|
||||
void (*adjust_common_prediction)(struct AACEncContext *s, ChannelElement *cpe);
|
||||
void (*apply_main_pred)(struct AACEncContext *s, SingleChannelElement *sce);
|
||||
void (*apply_tns_filt)(struct AACEncContext *s, SingleChannelElement *sce);
|
||||
void (*set_special_band_scalefactors)(struct AACEncContext *s, SingleChannelElement *sce);
|
||||
void (*search_for_pns)(struct AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce);
|
||||
void (*search_for_tns)(struct AACEncContext *s, SingleChannelElement *sce);
|
||||
void (*search_for_ms)(struct AACEncContext *s, ChannelElement *cpe);
|
||||
void (*search_for_is)(struct AACEncContext *s, AVCodecContext *avctx, ChannelElement *cpe);
|
||||
void (*search_for_pred)(struct AACEncContext *s, SingleChannelElement *sce);
|
||||
void (*quantize_and_encode_band)(struct AACEncContext *s, PutBitContext *pb, const float *in, int size,
|
||||
int scale_idx, int cb, const float lambda);
|
||||
void (*search_for_ms)(struct AACEncContext *s, ChannelElement *cpe, const float lambda);
|
||||
} AACCoefficientsEncoder;
|
||||
|
||||
extern AACCoefficientsEncoder ff_aac_coders[];
|
||||
@@ -86,8 +71,6 @@ typedef struct AACEncContext {
|
||||
AVFloatDSPContext *fdsp;
|
||||
float *planar_samples[6]; ///< saved preprocessed input
|
||||
|
||||
int profile; ///< copied from avctx
|
||||
LPCContext lpc; ///< used by TNS
|
||||
int samplerate_index; ///< MPEG-4 samplerate index
|
||||
int channels; ///< channel count
|
||||
const uint8_t *chan_map; ///< channel configuration map
|
||||
@@ -108,6 +91,8 @@ typedef struct AACEncContext {
|
||||
} buffer;
|
||||
} AACEncContext;
|
||||
|
||||
extern float ff_aac_pow34sf_tab[428];
|
||||
|
||||
void ff_aac_coder_init_mips(AACEncContext *c);
|
||||
|
||||
#endif /* AVCODEC_AACENC_H */
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* AAC encoder intensity stereo
|
||||
* Copyright (C) 2015 Rostislav Pehlivanov
|
||||
*
|
||||
* 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
|
||||
* AAC encoder Intensity Stereo
|
||||
* @author Rostislav Pehlivanov ( atomnuker gmail com )
|
||||
*/
|
||||
|
||||
#include "aacenc.h"
|
||||
#include "aacenc_utils.h"
|
||||
#include "aacenc_is.h"
|
||||
#include "aacenc_quantization.h"
|
||||
|
||||
struct AACISError ff_aac_is_encoding_err(AACEncContext *s, ChannelElement *cpe,
|
||||
int start, int w, int g, float ener0,
|
||||
float ener1, float ener01,
|
||||
int use_pcoeffs, int phase)
|
||||
{
|
||||
int i, w2;
|
||||
SingleChannelElement *sce0 = &cpe->ch[0];
|
||||
SingleChannelElement *sce1 = &cpe->ch[1];
|
||||
float *L = use_pcoeffs ? sce0->pcoeffs : sce0->coeffs;
|
||||
float *R = use_pcoeffs ? sce1->pcoeffs : sce1->coeffs;
|
||||
float *L34 = &s->scoefs[256*0], *R34 = &s->scoefs[256*1];
|
||||
float *IS = &s->scoefs[256*2], *I34 = &s->scoefs[256*3];
|
||||
float dist1 = 0.0f, dist2 = 0.0f;
|
||||
struct AACISError is_error = {0};
|
||||
|
||||
for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) {
|
||||
FFPsyBand *band0 = &s->psy.ch[s->cur_channel+0].psy_bands[(w+w2)*16+g];
|
||||
FFPsyBand *band1 = &s->psy.ch[s->cur_channel+1].psy_bands[(w+w2)*16+g];
|
||||
int is_band_type, is_sf_idx = FFMAX(1, sce0->sf_idx[(w+w2)*16+g]-4);
|
||||
float e01_34 = phase*pow(ener1/ener0, 3.0/4.0);
|
||||
float maxval, dist_spec_err = 0.0f;
|
||||
float minthr = FFMIN(band0->threshold, band1->threshold);
|
||||
for (i = 0; i < sce0->ics.swb_sizes[g]; i++)
|
||||
IS[i] = (L[start+(w+w2)*128+i] + phase*R[start+(w+w2)*128+i])*sqrt(ener0/ener01);
|
||||
abs_pow34_v(L34, &L[start+(w+w2)*128], sce0->ics.swb_sizes[g]);
|
||||
abs_pow34_v(R34, &R[start+(w+w2)*128], sce0->ics.swb_sizes[g]);
|
||||
abs_pow34_v(I34, IS, sce0->ics.swb_sizes[g]);
|
||||
maxval = find_max_val(1, sce0->ics.swb_sizes[g], I34);
|
||||
is_band_type = find_min_book(maxval, is_sf_idx);
|
||||
dist1 += quantize_band_cost(s, &L[start + (w+w2)*128], L34,
|
||||
sce0->ics.swb_sizes[g],
|
||||
sce0->sf_idx[(w+w2)*16+g],
|
||||
sce0->band_type[(w+w2)*16+g],
|
||||
s->lambda / band0->threshold, INFINITY, NULL, 0);
|
||||
dist1 += quantize_band_cost(s, &R[start + (w+w2)*128], R34,
|
||||
sce1->ics.swb_sizes[g],
|
||||
sce1->sf_idx[(w+w2)*16+g],
|
||||
sce1->band_type[(w+w2)*16+g],
|
||||
s->lambda / band1->threshold, INFINITY, NULL, 0);
|
||||
dist2 += quantize_band_cost(s, IS, I34, sce0->ics.swb_sizes[g],
|
||||
is_sf_idx, is_band_type,
|
||||
s->lambda / minthr, INFINITY, NULL, 0);
|
||||
for (i = 0; i < sce0->ics.swb_sizes[g]; i++) {
|
||||
dist_spec_err += (L34[i] - I34[i])*(L34[i] - I34[i]);
|
||||
dist_spec_err += (R34[i] - I34[i]*e01_34)*(R34[i] - I34[i]*e01_34);
|
||||
}
|
||||
dist_spec_err *= s->lambda / minthr;
|
||||
dist2 += dist_spec_err;
|
||||
}
|
||||
|
||||
is_error.pass = dist2 <= dist1;
|
||||
is_error.phase = phase;
|
||||
is_error.error = fabsf(dist1 - dist2);
|
||||
is_error.dist1 = dist1;
|
||||
is_error.dist2 = dist2;
|
||||
|
||||
return is_error;
|
||||
}
|
||||
|
||||
void ff_aac_search_for_is(AACEncContext *s, AVCodecContext *avctx, ChannelElement *cpe)
|
||||
{
|
||||
SingleChannelElement *sce0 = &cpe->ch[0];
|
||||
SingleChannelElement *sce1 = &cpe->ch[1];
|
||||
int start = 0, count = 0, w, w2, g, i;
|
||||
const float freq_mult = avctx->sample_rate/(1024.0f/sce0->ics.num_windows)/2.0f;
|
||||
|
||||
if (!cpe->common_window)
|
||||
return;
|
||||
|
||||
for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) {
|
||||
start = 0;
|
||||
for (g = 0; g < sce0->ics.num_swb; g++) {
|
||||
if (start*freq_mult > INT_STEREO_LOW_LIMIT*(s->lambda/170.0f) &&
|
||||
cpe->ch[0].band_type[w*16+g] != NOISE_BT && !cpe->ch[0].zeroes[w*16+g] &&
|
||||
cpe->ch[1].band_type[w*16+g] != NOISE_BT && !cpe->ch[1].zeroes[w*16+g]) {
|
||||
float ener0 = 0.0f, ener1 = 0.0f, ener01 = 0.0f;
|
||||
struct AACISError ph_err1, ph_err2, *erf;
|
||||
for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) {
|
||||
for (i = 0; i < sce0->ics.swb_sizes[g]; i++) {
|
||||
float coef0 = sce0->pcoeffs[start+(w+w2)*128+i];
|
||||
float coef1 = sce1->pcoeffs[start+(w+w2)*128+i];
|
||||
ener0 += coef0*coef0;
|
||||
ener1 += coef1*coef1;
|
||||
ener01 += (coef0 + coef1)*(coef0 + coef1);
|
||||
}
|
||||
}
|
||||
ph_err1 = ff_aac_is_encoding_err(s, cpe, start, w, g,
|
||||
ener0, ener1, ener01, 0, -1);
|
||||
ph_err2 = ff_aac_is_encoding_err(s, cpe, start, w, g,
|
||||
ener0, ener1, ener01, 0, +1);
|
||||
erf = ph_err1.error < ph_err2.error ? &ph_err1 : &ph_err2;
|
||||
if (erf->pass) {
|
||||
cpe->is_mask[w*16+g] = 1;
|
||||
cpe->ch[0].is_ener[w*16+g] = sqrt(ener0/ener01);
|
||||
cpe->ch[1].is_ener[w*16+g] = ener0/ener1;
|
||||
cpe->ch[1].band_type[w*16+g] = erf->phase ? INTENSITY_BT : INTENSITY_BT2;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
start += sce0->ics.swb_sizes[g];
|
||||
}
|
||||
}
|
||||
cpe->is_mode = !!count;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* AAC encoder intensity stereo
|
||||
* Copyright (C) 2015 Rostislav Pehlivanov
|
||||
*
|
||||
* 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
|
||||
* AAC encoder Intensity Stereo
|
||||
* @author Rostislav Pehlivanov ( atomnuker gmail com )
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AACENC_IS_H
|
||||
#define AVCODEC_AACENC_IS_H
|
||||
|
||||
#include "aacenc.h"
|
||||
|
||||
/** Frequency in Hz for lower limit of intensity stereo **/
|
||||
#define INT_STEREO_LOW_LIMIT 6100
|
||||
|
||||
struct AACISError {
|
||||
int pass; /* 1 if dist2 <= dist1 */
|
||||
int phase; /* -1 or +1 */
|
||||
float error; /* fabs(dist1 - dist2) */
|
||||
float dist1; /* From original coeffs */
|
||||
float dist2; /* From IS'd coeffs */
|
||||
};
|
||||
|
||||
struct AACISError ff_aac_is_encoding_err(AACEncContext *s, ChannelElement *cpe,
|
||||
int start, int w, int g, float ener0,
|
||||
float ener1, float ener01,
|
||||
int use_pcoeffs, int phase);
|
||||
void ff_aac_search_for_is(AACEncContext *s, AVCodecContext *avctx, ChannelElement *cpe);
|
||||
|
||||
#endif /* AVCODEC_AACENC_IS_H */
|
||||
@@ -1,342 +0,0 @@
|
||||
/*
|
||||
* AAC encoder main-type prediction
|
||||
* Copyright (C) 2015 Rostislav Pehlivanov
|
||||
*
|
||||
* 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
|
||||
* AAC encoder Intensity Stereo
|
||||
* @author Rostislav Pehlivanov ( atomnuker gmail com )
|
||||
*/
|
||||
|
||||
#include "aactab.h"
|
||||
#include "aacenc_pred.h"
|
||||
#include "aacenc_utils.h"
|
||||
#include "aacenc_is.h" /* <- Needed for common window distortions */
|
||||
#include "aacenc_quantization.h"
|
||||
|
||||
#define RESTORE_PRED(sce, sfb) \
|
||||
if (sce->ics.prediction_used[sfb]) {\
|
||||
sce->ics.prediction_used[sfb] = 0;\
|
||||
sce->band_type[sfb] = sce->band_alt[sfb];\
|
||||
}
|
||||
|
||||
static inline float flt16_round(float pf)
|
||||
{
|
||||
union av_intfloat32 tmp;
|
||||
tmp.f = pf;
|
||||
tmp.i = (tmp.i + 0x00008000U) & 0xFFFF0000U;
|
||||
return tmp.f;
|
||||
}
|
||||
|
||||
static inline float flt16_even(float pf)
|
||||
{
|
||||
union av_intfloat32 tmp;
|
||||
tmp.f = pf;
|
||||
tmp.i = (tmp.i + 0x00007FFFU + (tmp.i & 0x00010000U >> 16)) & 0xFFFF0000U;
|
||||
return tmp.f;
|
||||
}
|
||||
|
||||
static inline float flt16_trunc(float pf)
|
||||
{
|
||||
union av_intfloat32 pun;
|
||||
pun.f = pf;
|
||||
pun.i &= 0xFFFF0000U;
|
||||
return pun.f;
|
||||
}
|
||||
|
||||
static inline void predict(PredictorState *ps, float *coef, float *rcoef, int set)
|
||||
{
|
||||
float k2;
|
||||
const float a = 0.953125; // 61.0 / 64
|
||||
const float alpha = 0.90625; // 29.0 / 32
|
||||
const float k1 = ps->k1;
|
||||
const float r0 = ps->r0, r1 = ps->r1;
|
||||
const float cor0 = ps->cor0, cor1 = ps->cor1;
|
||||
const float var0 = ps->var0, var1 = ps->var1;
|
||||
const float e0 = *coef - ps->x_est;
|
||||
const float e1 = e0 - k1 * r0;
|
||||
|
||||
if (set)
|
||||
*coef = e0;
|
||||
|
||||
ps->cor1 = flt16_trunc(alpha * cor1 + r1 * e1);
|
||||
ps->var1 = flt16_trunc(alpha * var1 + 0.5f * (r1 * r1 + e1 * e1));
|
||||
ps->cor0 = flt16_trunc(alpha * cor0 + r0 * e0);
|
||||
ps->var0 = flt16_trunc(alpha * var0 + 0.5f * (r0 * r0 + e0 * e0));
|
||||
ps->r1 = flt16_trunc(a * (r0 - k1 * e0));
|
||||
ps->r0 = flt16_trunc(a * e0);
|
||||
|
||||
/* Prediction for next frame */
|
||||
ps->k1 = ps->var0 > 1 ? ps->cor0 * flt16_even(a / ps->var0) : 0;
|
||||
k2 = ps->var1 > 1 ? ps->cor1 * flt16_even(a / ps->var1) : 0;
|
||||
*rcoef = ps->x_est = flt16_round(ps->k1*ps->r0 + k2*ps->r1);
|
||||
}
|
||||
|
||||
static inline void reset_predict_state(PredictorState *ps)
|
||||
{
|
||||
ps->r0 = 0.0f;
|
||||
ps->r1 = 0.0f;
|
||||
ps->k1 = 0.0f;
|
||||
ps->cor0 = 0.0f;
|
||||
ps->cor1 = 0.0f;
|
||||
ps->var0 = 1.0f;
|
||||
ps->var1 = 1.0f;
|
||||
ps->x_est = 0.0f;
|
||||
}
|
||||
|
||||
static inline void reset_all_predictors(PredictorState *ps)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_PREDICTORS; i++)
|
||||
reset_predict_state(&ps[i]);
|
||||
}
|
||||
|
||||
static inline void reset_predictor_group(SingleChannelElement *sce, int group_num)
|
||||
{
|
||||
int i;
|
||||
PredictorState *ps = sce->predictor_state;
|
||||
for (i = group_num - 1; i < MAX_PREDICTORS; i += 30)
|
||||
reset_predict_state(&ps[i]);
|
||||
}
|
||||
|
||||
void ff_aac_apply_main_pred(AACEncContext *s, SingleChannelElement *sce)
|
||||
{
|
||||
int sfb, k;
|
||||
const int pmax = FFMIN(sce->ics.max_sfb, ff_aac_pred_sfb_max[s->samplerate_index]);
|
||||
|
||||
if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
|
||||
for (sfb = 0; sfb < pmax; sfb++) {
|
||||
for (k = sce->ics.swb_offset[sfb]; k < sce->ics.swb_offset[sfb + 1]; k++) {
|
||||
predict(&sce->predictor_state[k], &sce->coeffs[k], &sce->prcoeffs[k],
|
||||
sce->ics.predictor_present && sce->ics.prediction_used[sfb]);
|
||||
}
|
||||
}
|
||||
if (sce->ics.predictor_reset_group) {
|
||||
reset_predictor_group(sce, sce->ics.predictor_reset_group);
|
||||
}
|
||||
} else {
|
||||
reset_all_predictors(sce->predictor_state);
|
||||
}
|
||||
}
|
||||
|
||||
/* If inc = 0 you can check if this returns 0 to see if you can reset freely */
|
||||
static inline int update_counters(IndividualChannelStream *ics, int inc)
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < 31; i++) {
|
||||
ics->predictor_reset_count[i] += inc;
|
||||
if (ics->predictor_reset_count[i] > PRED_RESET_FRAME_MIN)
|
||||
return i; /* Reset this immediately */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ff_aac_adjust_common_prediction(AACEncContext *s, ChannelElement *cpe)
|
||||
{
|
||||
int start, w, w2, g, i, count = 0;
|
||||
SingleChannelElement *sce0 = &cpe->ch[0];
|
||||
SingleChannelElement *sce1 = &cpe->ch[1];
|
||||
const int pmax0 = FFMIN(sce0->ics.max_sfb, ff_aac_pred_sfb_max[s->samplerate_index]);
|
||||
const int pmax1 = FFMIN(sce1->ics.max_sfb, ff_aac_pred_sfb_max[s->samplerate_index]);
|
||||
const int pmax = FFMIN(pmax0, pmax1);
|
||||
|
||||
if (!cpe->common_window ||
|
||||
sce0->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE ||
|
||||
sce1->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE)
|
||||
return;
|
||||
|
||||
for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) {
|
||||
start = 0;
|
||||
for (g = 0; g < sce0->ics.num_swb; g++) {
|
||||
int sfb = w*16+g;
|
||||
int sum = sce0->ics.prediction_used[sfb] + sce1->ics.prediction_used[sfb];
|
||||
float ener0 = 0.0f, ener1 = 0.0f, ener01 = 0.0f;
|
||||
struct AACISError ph_err1, ph_err2, *erf;
|
||||
if (sfb < PRED_SFB_START || sfb > pmax || sum != 2) {
|
||||
RESTORE_PRED(sce0, sfb);
|
||||
RESTORE_PRED(sce1, sfb);
|
||||
start += sce0->ics.swb_sizes[g];
|
||||
continue;
|
||||
}
|
||||
for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) {
|
||||
for (i = 0; i < sce0->ics.swb_sizes[g]; i++) {
|
||||
float coef0 = sce0->pcoeffs[start+(w+w2)*128+i];
|
||||
float coef1 = sce1->pcoeffs[start+(w+w2)*128+i];
|
||||
ener0 += coef0*coef0;
|
||||
ener1 += coef1*coef1;
|
||||
ener01 += (coef0 + coef1)*(coef0 + coef1);
|
||||
}
|
||||
}
|
||||
ph_err1 = ff_aac_is_encoding_err(s, cpe, start, w, g,
|
||||
ener0, ener1, ener01, 1, -1);
|
||||
ph_err2 = ff_aac_is_encoding_err(s, cpe, start, w, g,
|
||||
ener0, ener1, ener01, 1, +1);
|
||||
erf = ph_err1.error < ph_err2.error ? &ph_err1 : &ph_err2;
|
||||
if (erf->pass) {
|
||||
sce0->ics.prediction_used[sfb] = 1;
|
||||
sce1->ics.prediction_used[sfb] = 1;
|
||||
count++;
|
||||
} else {
|
||||
RESTORE_PRED(sce0, sfb);
|
||||
RESTORE_PRED(sce1, sfb);
|
||||
}
|
||||
start += sce0->ics.swb_sizes[g];
|
||||
}
|
||||
}
|
||||
|
||||
sce1->ics.predictor_present = sce0->ics.predictor_present = !!count;
|
||||
}
|
||||
|
||||
static void update_pred_resets(SingleChannelElement *sce)
|
||||
{
|
||||
int i, max_group_id_c, max_frame = 0;
|
||||
float avg_frame = 0.0f;
|
||||
IndividualChannelStream *ics = &sce->ics;
|
||||
|
||||
/* Update the counters and immediately update any frame behind schedule */
|
||||
if ((ics->predictor_reset_group = update_counters(&sce->ics, 1)))
|
||||
return;
|
||||
|
||||
for (i = 1; i < 31; i++) {
|
||||
/* Count-based */
|
||||
if (ics->predictor_reset_count[i] > max_frame) {
|
||||
max_group_id_c = i;
|
||||
max_frame = ics->predictor_reset_count[i];
|
||||
}
|
||||
avg_frame = (ics->predictor_reset_count[i] + avg_frame)/2;
|
||||
}
|
||||
|
||||
if (max_frame > PRED_RESET_MIN) {
|
||||
ics->predictor_reset_group = max_group_id_c;
|
||||
} else {
|
||||
ics->predictor_reset_group = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ff_aac_search_for_pred(AACEncContext *s, SingleChannelElement *sce)
|
||||
{
|
||||
int sfb, i, count = 0, cost_coeffs = 0, cost_pred = 0;
|
||||
const int pmax = FFMIN(sce->ics.max_sfb, ff_aac_pred_sfb_max[s->samplerate_index]);
|
||||
float *O34 = &s->scoefs[128*0], *P34 = &s->scoefs[128*1];
|
||||
float *SENT = &s->scoefs[128*2], *S34 = &s->scoefs[128*3];
|
||||
float *QERR = &s->scoefs[128*4];
|
||||
|
||||
if (sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
|
||||
sce->ics.predictor_present = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sce->ics.predictor_initialized) {
|
||||
reset_all_predictors(sce->predictor_state);
|
||||
sce->ics.predictor_initialized = 1;
|
||||
memcpy(sce->prcoeffs, sce->coeffs, 1024*sizeof(float));
|
||||
for (i = 1; i < 31; i++)
|
||||
sce->ics.predictor_reset_count[i] = i;
|
||||
}
|
||||
|
||||
update_pred_resets(sce);
|
||||
memcpy(sce->band_alt, sce->band_type, sizeof(sce->band_type));
|
||||
|
||||
for (sfb = PRED_SFB_START; sfb < pmax; sfb++) {
|
||||
int cost1, cost2, cb_p;
|
||||
float dist1, dist2, dist_spec_err = 0.0f;
|
||||
const int cb_n = sce->band_type[sfb];
|
||||
const int start_coef = sce->ics.swb_offset[sfb];
|
||||
const int num_coeffs = sce->ics.swb_offset[sfb + 1] - start_coef;
|
||||
const FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[sfb];
|
||||
|
||||
if (start_coef + num_coeffs > MAX_PREDICTORS)
|
||||
continue;
|
||||
|
||||
/* Normal coefficients */
|
||||
abs_pow34_v(O34, &sce->coeffs[start_coef], num_coeffs);
|
||||
dist1 = quantize_and_encode_band_cost(s, NULL, &sce->coeffs[start_coef], NULL,
|
||||
O34, num_coeffs, sce->sf_idx[sfb],
|
||||
cb_n, s->lambda / band->threshold, INFINITY, &cost1, 0);
|
||||
cost_coeffs += cost1;
|
||||
|
||||
/* Encoded coefficients - needed for #bits, band type and quant. error */
|
||||
for (i = 0; i < num_coeffs; i++)
|
||||
SENT[i] = sce->coeffs[start_coef + i] - sce->prcoeffs[start_coef + i];
|
||||
abs_pow34_v(S34, SENT, num_coeffs);
|
||||
if (cb_n < RESERVED_BT)
|
||||
cb_p = find_min_book(find_max_val(1, num_coeffs, S34), sce->sf_idx[sfb]);
|
||||
else
|
||||
cb_p = cb_n;
|
||||
quantize_and_encode_band_cost(s, NULL, SENT, QERR, S34, num_coeffs,
|
||||
sce->sf_idx[sfb], cb_p, s->lambda / band->threshold, INFINITY,
|
||||
&cost2, 0);
|
||||
|
||||
/* Reconstructed coefficients - needed for distortion measurements */
|
||||
for (i = 0; i < num_coeffs; i++)
|
||||
sce->prcoeffs[start_coef + i] += QERR[i] != 0.0f ? (sce->prcoeffs[start_coef + i] - QERR[i]) : 0.0f;
|
||||
abs_pow34_v(P34, &sce->prcoeffs[start_coef], num_coeffs);
|
||||
if (cb_n < RESERVED_BT)
|
||||
cb_p = find_min_book(find_max_val(1, num_coeffs, P34), sce->sf_idx[sfb]);
|
||||
else
|
||||
cb_p = cb_n;
|
||||
dist2 = quantize_and_encode_band_cost(s, NULL, &sce->prcoeffs[start_coef], NULL,
|
||||
P34, num_coeffs, sce->sf_idx[sfb],
|
||||
cb_p, s->lambda / band->threshold, INFINITY, NULL, 0);
|
||||
for (i = 0; i < num_coeffs; i++)
|
||||
dist_spec_err += (O34[i] - P34[i])*(O34[i] - P34[i]);
|
||||
dist_spec_err *= s->lambda / band->threshold;
|
||||
dist2 += dist_spec_err;
|
||||
|
||||
if (dist2 <= dist1 && cb_p <= cb_n) {
|
||||
cost_pred += cost2;
|
||||
sce->ics.prediction_used[sfb] = 1;
|
||||
sce->band_alt[sfb] = cb_n;
|
||||
sce->band_type[sfb] = cb_p;
|
||||
count++;
|
||||
} else {
|
||||
cost_pred += cost1;
|
||||
sce->band_alt[sfb] = cb_p;
|
||||
}
|
||||
}
|
||||
|
||||
if (count && cost_coeffs < cost_pred) {
|
||||
count = 0;
|
||||
for (sfb = PRED_SFB_START; sfb < pmax; sfb++)
|
||||
RESTORE_PRED(sce, sfb);
|
||||
memset(&sce->ics.prediction_used, 0, sizeof(sce->ics.prediction_used));
|
||||
}
|
||||
|
||||
sce->ics.predictor_present = !!count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encoder predictors data.
|
||||
*/
|
||||
void ff_aac_encode_main_pred(AACEncContext *s, SingleChannelElement *sce)
|
||||
{
|
||||
int sfb;
|
||||
IndividualChannelStream *ics = &sce->ics;
|
||||
const int pmax = FFMIN(ics->max_sfb, ff_aac_pred_sfb_max[s->samplerate_index]);
|
||||
|
||||
if (!ics->predictor_present)
|
||||
return;
|
||||
|
||||
put_bits(&s->pb, 1, !!ics->predictor_reset_group);
|
||||
if (ics->predictor_reset_group)
|
||||
put_bits(&s->pb, 5, ics->predictor_reset_group);
|
||||
for (sfb = 0; sfb < pmax; sfb++)
|
||||
put_bits(&s->pb, 1, ics->prediction_used[sfb]);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* AAC encoder main-type prediction
|
||||
* Copyright (C) 2015 Rostislav Pehlivanov
|
||||
*
|
||||
* 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
|
||||
* AAC encoder main prediction
|
||||
* @author Rostislav Pehlivanov ( atomnuker gmail com )
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AACENC_PRED_H
|
||||
#define AVCODEC_AACENC_PRED_H
|
||||
|
||||
#include "aacenc.h"
|
||||
|
||||
/* Every predictor group needs to get reset at least once in this many frames */
|
||||
#define PRED_RESET_FRAME_MIN 240
|
||||
|
||||
/* Any frame with less than this amount of frames since last reset is ok */
|
||||
#define PRED_RESET_MIN 64
|
||||
|
||||
/* Raise to filter any low frequency artifacts due to prediction */
|
||||
#define PRED_SFB_START 10
|
||||
|
||||
void ff_aac_apply_main_pred(AACEncContext *s, SingleChannelElement *sce);
|
||||
void ff_aac_adjust_common_prediction(AACEncContext *s, ChannelElement *cpe);
|
||||
void ff_aac_search_for_pred(AACEncContext *s, SingleChannelElement *sce);
|
||||
void ff_aac_encode_main_pred(AACEncContext *s, SingleChannelElement *sce);
|
||||
|
||||
#endif /* AVCODEC_AACENC_PRED_H */
|
||||
@@ -1,260 +0,0 @@
|
||||
/*
|
||||
* AAC encoder intensity stereo
|
||||
* Copyright (C) 2015 Rostislav Pehlivanov
|
||||
*
|
||||
* 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
|
||||
* AAC encoder quantizer
|
||||
* @author Rostislav Pehlivanov ( atomnuker gmail com )
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AACENC_QUANTIZATION_H
|
||||
#define AVCODEC_AACENC_QUANTIZATION_H
|
||||
|
||||
#include "aactab.h"
|
||||
#include "aacenc.h"
|
||||
#include "aacenctab.h"
|
||||
#include "aacenc_utils.h"
|
||||
|
||||
/**
|
||||
* Calculate rate distortion cost for quantizing with given codebook
|
||||
*
|
||||
* @return quantization distortion
|
||||
*/
|
||||
static av_always_inline float quantize_and_encode_band_cost_template(
|
||||
struct AACEncContext *s,
|
||||
PutBitContext *pb, const float *in, float *out,
|
||||
const float *scaled, int size, int scale_idx,
|
||||
int cb, const float lambda, const float uplim,
|
||||
int *bits, int BT_ZERO, int BT_UNSIGNED,
|
||||
int BT_PAIR, int BT_ESC, int BT_NOISE, int BT_STEREO,
|
||||
const float ROUNDING)
|
||||
{
|
||||
const int q_idx = POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512;
|
||||
const float Q = ff_aac_pow2sf_tab [q_idx];
|
||||
const float Q34 = ff_aac_pow34sf_tab[q_idx];
|
||||
const float IQ = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
|
||||
const float CLIPPED_ESCAPE = 165140.0f*IQ;
|
||||
int i, j;
|
||||
float cost = 0;
|
||||
const int dim = BT_PAIR ? 2 : 4;
|
||||
int resbits = 0;
|
||||
int off;
|
||||
|
||||
if (BT_ZERO || BT_NOISE || BT_STEREO) {
|
||||
for (i = 0; i < size; i++)
|
||||
cost += in[i]*in[i];
|
||||
if (bits)
|
||||
*bits = 0;
|
||||
if (out) {
|
||||
for (i = 0; i < size; i += dim)
|
||||
for (j = 0; j < dim; j++)
|
||||
out[i+j] = 0.0f;
|
||||
}
|
||||
return cost * lambda;
|
||||
}
|
||||
if (!scaled) {
|
||||
abs_pow34_v(s->scoefs, in, size);
|
||||
scaled = s->scoefs;
|
||||
}
|
||||
quantize_bands(s->qcoefs, in, scaled, size, Q34, !BT_UNSIGNED, aac_cb_maxval[cb], ROUNDING);
|
||||
if (BT_UNSIGNED) {
|
||||
off = 0;
|
||||
} else {
|
||||
off = aac_cb_maxval[cb];
|
||||
}
|
||||
for (i = 0; i < size; i += dim) {
|
||||
const float *vec;
|
||||
int *quants = s->qcoefs + i;
|
||||
int curidx = 0;
|
||||
int curbits;
|
||||
float quantized, rd = 0.0f;
|
||||
for (j = 0; j < dim; j++) {
|
||||
curidx *= aac_cb_range[cb];
|
||||
curidx += quants[j] + off;
|
||||
}
|
||||
curbits = ff_aac_spectral_bits[cb-1][curidx];
|
||||
vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
|
||||
if (BT_UNSIGNED) {
|
||||
for (j = 0; j < dim; j++) {
|
||||
float t = fabsf(in[i+j]);
|
||||
float di;
|
||||
if (BT_ESC && vec[j] == 64.0f) { //FIXME: slow
|
||||
if (t >= CLIPPED_ESCAPE) {
|
||||
quantized = CLIPPED_ESCAPE;
|
||||
curbits += 21;
|
||||
} else {
|
||||
int c = av_clip_uintp2(quant(t, Q, ROUNDING), 13);
|
||||
quantized = c*cbrtf(c)*IQ;
|
||||
curbits += av_log2(c)*2 - 4 + 1;
|
||||
}
|
||||
} else {
|
||||
quantized = vec[j]*IQ;
|
||||
}
|
||||
di = t - quantized;
|
||||
if (out)
|
||||
out[i+j] = in[i+j] >= 0 ? quantized : -quantized;
|
||||
if (vec[j] != 0.0f)
|
||||
curbits++;
|
||||
rd += di*di;
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < dim; j++) {
|
||||
quantized = vec[j]*IQ;
|
||||
if (out)
|
||||
out[i+j] = quantized;
|
||||
rd += (in[i+j] - quantized)*(in[i+j] - quantized);
|
||||
}
|
||||
}
|
||||
cost += rd * lambda + curbits;
|
||||
resbits += curbits;
|
||||
if (cost >= uplim)
|
||||
return uplim;
|
||||
if (pb) {
|
||||
put_bits(pb, ff_aac_spectral_bits[cb-1][curidx], ff_aac_spectral_codes[cb-1][curidx]);
|
||||
if (BT_UNSIGNED)
|
||||
for (j = 0; j < dim; j++)
|
||||
if (ff_aac_codebook_vectors[cb-1][curidx*dim+j] != 0.0f)
|
||||
put_bits(pb, 1, in[i+j] < 0.0f);
|
||||
if (BT_ESC) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
if (ff_aac_codebook_vectors[cb-1][curidx*2+j] == 64.0f) {
|
||||
int coef = av_clip_uintp2(quant(fabsf(in[i+j]), Q, ROUNDING), 13);
|
||||
int len = av_log2(coef);
|
||||
|
||||
put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
|
||||
put_sbits(pb, len, coef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bits)
|
||||
*bits = resbits;
|
||||
return cost;
|
||||
}
|
||||
|
||||
static inline float quantize_and_encode_band_cost_NONE(struct AACEncContext *s, PutBitContext *pb,
|
||||
const float *in, float *quant, const float *scaled,
|
||||
int size, int scale_idx, int cb,
|
||||
const float lambda, const float uplim,
|
||||
int *bits) {
|
||||
av_assert0(0);
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
#define QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NAME, BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE, BT_STEREO, ROUNDING) \
|
||||
static float quantize_and_encode_band_cost_ ## NAME( \
|
||||
struct AACEncContext *s, \
|
||||
PutBitContext *pb, const float *in, float *quant, \
|
||||
const float *scaled, int size, int scale_idx, \
|
||||
int cb, const float lambda, const float uplim, \
|
||||
int *bits) { \
|
||||
return quantize_and_encode_band_cost_template( \
|
||||
s, pb, in, quant, scaled, size, scale_idx, \
|
||||
BT_ESC ? ESC_BT : cb, lambda, uplim, bits, \
|
||||
BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE, BT_STEREO, \
|
||||
ROUNDING); \
|
||||
}
|
||||
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ZERO, 1, 0, 0, 0, 0, 0, ROUND_STANDARD)
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SQUAD, 0, 0, 0, 0, 0, 0, ROUND_STANDARD)
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UQUAD, 0, 1, 0, 0, 0, 0, ROUND_STANDARD)
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SPAIR, 0, 0, 1, 0, 0, 0, ROUND_STANDARD)
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UPAIR, 0, 1, 1, 0, 0, 0, ROUND_STANDARD)
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC, 0, 1, 1, 1, 0, 0, ROUND_STANDARD)
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC_RTZ, 0, 1, 1, 1, 0, 0, ROUND_TO_ZERO)
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NOISE, 0, 0, 0, 0, 1, 0, ROUND_STANDARD)
|
||||
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(STEREO,0, 0, 0, 0, 0, 1, ROUND_STANDARD)
|
||||
|
||||
static float (*const quantize_and_encode_band_cost_arr[])(
|
||||
struct AACEncContext *s,
|
||||
PutBitContext *pb, const float *in, float *quant,
|
||||
const float *scaled, int size, int scale_idx,
|
||||
int cb, const float lambda, const float uplim,
|
||||
int *bits) = {
|
||||
quantize_and_encode_band_cost_ZERO,
|
||||
quantize_and_encode_band_cost_SQUAD,
|
||||
quantize_and_encode_band_cost_SQUAD,
|
||||
quantize_and_encode_band_cost_UQUAD,
|
||||
quantize_and_encode_band_cost_UQUAD,
|
||||
quantize_and_encode_band_cost_SPAIR,
|
||||
quantize_and_encode_band_cost_SPAIR,
|
||||
quantize_and_encode_band_cost_UPAIR,
|
||||
quantize_and_encode_band_cost_UPAIR,
|
||||
quantize_and_encode_band_cost_UPAIR,
|
||||
quantize_and_encode_band_cost_UPAIR,
|
||||
quantize_and_encode_band_cost_ESC,
|
||||
quantize_and_encode_band_cost_NONE, /* CB 12 doesn't exist */
|
||||
quantize_and_encode_band_cost_NOISE,
|
||||
quantize_and_encode_band_cost_STEREO,
|
||||
quantize_and_encode_band_cost_STEREO,
|
||||
};
|
||||
|
||||
static float (*const quantize_and_encode_band_cost_rtz_arr[])(
|
||||
struct AACEncContext *s,
|
||||
PutBitContext *pb, const float *in, float *quant,
|
||||
const float *scaled, int size, int scale_idx,
|
||||
int cb, const float lambda, const float uplim,
|
||||
int *bits) = {
|
||||
quantize_and_encode_band_cost_ZERO,
|
||||
quantize_and_encode_band_cost_SQUAD,
|
||||
quantize_and_encode_band_cost_SQUAD,
|
||||
quantize_and_encode_band_cost_UQUAD,
|
||||
quantize_and_encode_band_cost_UQUAD,
|
||||
quantize_and_encode_band_cost_SPAIR,
|
||||
quantize_and_encode_band_cost_SPAIR,
|
||||
quantize_and_encode_band_cost_UPAIR,
|
||||
quantize_and_encode_band_cost_UPAIR,
|
||||
quantize_and_encode_band_cost_UPAIR,
|
||||
quantize_and_encode_band_cost_UPAIR,
|
||||
quantize_and_encode_band_cost_ESC_RTZ,
|
||||
quantize_and_encode_band_cost_NONE, /* CB 12 doesn't exist */
|
||||
quantize_and_encode_band_cost_NOISE,
|
||||
quantize_and_encode_band_cost_STEREO,
|
||||
quantize_and_encode_band_cost_STEREO,
|
||||
};
|
||||
|
||||
#define quantize_and_encode_band_cost( \
|
||||
s, pb, in, quant, scaled, size, scale_idx, cb, \
|
||||
lambda, uplim, bits, rtz) \
|
||||
((rtz) ? quantize_and_encode_band_cost_rtz_arr : quantize_and_encode_band_cost_arr)[cb]( \
|
||||
s, pb, in, quant, scaled, size, scale_idx, cb, \
|
||||
lambda, uplim, bits)
|
||||
|
||||
static inline float quantize_band_cost(struct AACEncContext *s, const float *in,
|
||||
const float *scaled, int size, int scale_idx,
|
||||
int cb, const float lambda, const float uplim,
|
||||
int *bits, int rtz)
|
||||
{
|
||||
return quantize_and_encode_band_cost(s, NULL, in, NULL, scaled, size, scale_idx,
|
||||
cb, lambda, uplim, bits, rtz);
|
||||
}
|
||||
|
||||
static inline void quantize_and_encode_band(struct AACEncContext *s, PutBitContext *pb,
|
||||
const float *in, float *out, int size, int scale_idx,
|
||||
int cb, const float lambda, int rtz)
|
||||
{
|
||||
quantize_and_encode_band_cost(s, pb, in, out, NULL, size, scale_idx, cb, lambda,
|
||||
INFINITY, NULL, rtz);
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_AACENC_QUANTIZATION_H */
|
||||
@@ -1,194 +0,0 @@
|
||||
/*
|
||||
* AAC encoder TNS
|
||||
* Copyright (C) 2015 Rostislav Pehlivanov
|
||||
*
|
||||
* 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
|
||||
* AAC encoder temporal noise shaping
|
||||
* @author Rostislav Pehlivanov ( atomnuker gmail com )
|
||||
*/
|
||||
|
||||
#include "aacenc.h"
|
||||
#include "aacenc_tns.h"
|
||||
#include "aactab.h"
|
||||
#include "aacenc_utils.h"
|
||||
#include "aacenc_quantization.h"
|
||||
|
||||
/**
|
||||
* Encode TNS data.
|
||||
* Coefficient compression saves a single bit per coefficient.
|
||||
*/
|
||||
void ff_aac_encode_tns_info(AACEncContext *s, SingleChannelElement *sce)
|
||||
{
|
||||
uint8_t u_coef;
|
||||
const uint8_t coef_res = TNS_Q_BITS == 4;
|
||||
int i, w, filt, coef_len, coef_compress = 0;
|
||||
const int is8 = sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE;
|
||||
TemporalNoiseShaping *tns = &sce->tns;
|
||||
|
||||
if (!sce->tns.present)
|
||||
return;
|
||||
|
||||
for (i = 0; i < sce->ics.num_windows; i++) {
|
||||
put_bits(&s->pb, 2 - is8, sce->tns.n_filt[i]);
|
||||
if (tns->n_filt[i]) {
|
||||
put_bits(&s->pb, 1, coef_res);
|
||||
for (filt = 0; filt < tns->n_filt[i]; filt++) {
|
||||
put_bits(&s->pb, 6 - 2 * is8, tns->length[i][filt]);
|
||||
put_bits(&s->pb, 5 - 2 * is8, tns->order[i][filt]);
|
||||
if (tns->order[i][filt]) {
|
||||
put_bits(&s->pb, 1, !!tns->direction[i][filt]);
|
||||
put_bits(&s->pb, 1, !!coef_compress);
|
||||
coef_len = coef_res + 3 - coef_compress;
|
||||
for (w = 0; w < tns->order[i][filt]; w++) {
|
||||
u_coef = (tns->coef_idx[i][filt][w])&(~(~0<<coef_len));
|
||||
put_bits(&s->pb, coef_len, u_coef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void quantize_coefs(double *coef, int *idx, float *lpc, int order)
|
||||
{
|
||||
int i;
|
||||
uint8_t u_coef;
|
||||
const float *quant_arr = tns_tmp2_map[TNS_Q_BITS == 4];
|
||||
const double iqfac_p = ((1 << (TNS_Q_BITS-1)) - 0.5)/(M_PI/2.0);
|
||||
const double iqfac_m = ((1 << (TNS_Q_BITS-1)) + 0.5)/(M_PI/2.0);
|
||||
for (i = 0; i < order; i++) {
|
||||
idx[i] = ceilf(asin(coef[i])*((coef[i] >= 0) ? iqfac_p : iqfac_m));
|
||||
u_coef = (idx[i])&(~(~0<<TNS_Q_BITS));
|
||||
lpc[i] = quant_arr[u_coef];
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply TNS filter */
|
||||
void ff_aac_apply_tns(AACEncContext *s, SingleChannelElement *sce)
|
||||
{
|
||||
TemporalNoiseShaping *tns = &sce->tns;
|
||||
IndividualChannelStream *ics = &sce->ics;
|
||||
int w, filt, m, i, top, order, bottom, start, end, size, inc;
|
||||
const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
|
||||
float lpc[TNS_MAX_ORDER];
|
||||
|
||||
for (w = 0; w < ics->num_windows; w++) {
|
||||
bottom = ics->num_swb;
|
||||
for (filt = 0; filt < tns->n_filt[w]; filt++) {
|
||||
top = bottom;
|
||||
bottom = FFMAX(0, top - tns->length[w][filt]);
|
||||
order = tns->order[w][filt];
|
||||
if (order == 0)
|
||||
continue;
|
||||
|
||||
// tns_decode_coef
|
||||
compute_lpc_coefs(tns->coef[w][filt], order, lpc, 0, 0, 0);
|
||||
|
||||
start = ics->swb_offset[FFMIN(bottom, mmm)];
|
||||
end = ics->swb_offset[FFMIN( top, mmm)];
|
||||
if ((size = end - start) <= 0)
|
||||
continue;
|
||||
if (tns->direction[w][filt]) {
|
||||
inc = -1;
|
||||
start = end - 1;
|
||||
} else {
|
||||
inc = 1;
|
||||
}
|
||||
start += w * 128;
|
||||
|
||||
// ar filter
|
||||
for (m = 0; m < size; m++, start += inc)
|
||||
for (i = 1; i <= FFMIN(m, order); i++)
|
||||
sce->coeffs[start] += lpc[i-1]*sce->pcoeffs[start - i*inc];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ff_aac_search_for_tns(AACEncContext *s, SingleChannelElement *sce)
|
||||
{
|
||||
TemporalNoiseShaping *tns = &sce->tns;
|
||||
int w, w2, g, count = 0;
|
||||
const int mmm = FFMIN(sce->ics.tns_max_bands, sce->ics.max_sfb);
|
||||
const int is8 = sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE;
|
||||
const int order = is8 ? 7 : s->profile == FF_PROFILE_AAC_LOW ? 12 : TNS_MAX_ORDER;
|
||||
|
||||
int sfb_start = av_clip(tns_min_sfb[is8][s->samplerate_index], 0, mmm);
|
||||
int sfb_end = av_clip(sce->ics.num_swb, 0, mmm);
|
||||
|
||||
for (w = 0; w < sce->ics.num_windows; w++) {
|
||||
float e_ratio = 0.0f, threshold = 0.0f, spread = 0.0f, en[2] = {0.0, 0.0f};
|
||||
double gain = 0.0f, coefs[MAX_LPC_ORDER] = {0};
|
||||
int coef_start = w*sce->ics.num_swb + sce->ics.swb_offset[sfb_start];
|
||||
int coef_len = sce->ics.swb_offset[sfb_end] - sce->ics.swb_offset[sfb_start];
|
||||
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
if (w*16+g < sfb_start || w*16+g > sfb_end)
|
||||
continue;
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
|
||||
if ((w+w2)*16+g > sfb_start + ((sfb_end - sfb_start)/2))
|
||||
en[1] += band->energy;
|
||||
else
|
||||
en[0] += band->energy;
|
||||
threshold += band->threshold;
|
||||
spread += band->spread;
|
||||
}
|
||||
}
|
||||
|
||||
if (coef_len <= 0 || (sfb_end - sfb_start) <= 0)
|
||||
continue;
|
||||
else
|
||||
e_ratio = en[0]/en[1];
|
||||
|
||||
/* LPC */
|
||||
gain = ff_lpc_calc_ref_coefs_f(&s->lpc, &sce->coeffs[coef_start],
|
||||
coef_len, order, coefs);
|
||||
|
||||
if (gain > TNS_GAIN_THRESHOLD_LOW && gain < TNS_GAIN_THRESHOLD_HIGH &&
|
||||
(en[0]+en[1]) > TNS_GAIN_THRESHOLD_LOW*threshold &&
|
||||
spread < TNS_SPREAD_THRESHOLD && order) {
|
||||
if (is8 || order < 2 || (e_ratio > TNS_E_RATIO_LOW && e_ratio < TNS_E_RATIO_HIGH)) {
|
||||
tns->n_filt[w] = 1;
|
||||
for (g = 0; g < tns->n_filt[w]; g++) {
|
||||
tns->length[w][g] = sfb_end - sfb_start;
|
||||
tns->direction[w][g] = en[0] < en[1];
|
||||
tns->order[w][g] = order;
|
||||
quantize_coefs(coefs, tns->coef_idx[w][g], tns->coef[w][g],
|
||||
order);
|
||||
}
|
||||
} else { /* 2 filters due to energy disbalance */
|
||||
tns->n_filt[w] = 2;
|
||||
for (g = 0; g < tns->n_filt[w]; g++) {
|
||||
tns->direction[w][g] = en[g] < en[!g];
|
||||
tns->order[w][g] = !g ? order/2 : order - tns->order[w][g-1];
|
||||
tns->length[w][g] = !g ? (sfb_end - sfb_start)/2 : \
|
||||
(sfb_end - sfb_start) - tns->length[w][g-1];
|
||||
quantize_coefs(&coefs[!g ? 0 : order - tns->order[w][g-1]],
|
||||
tns->coef_idx[w][g], tns->coef[w][g],
|
||||
tns->order[w][g]);
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
sce->tns.present = !!count;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* AAC encoder TNS
|
||||
* Copyright (C) 2015 Rostislav Pehlivanov
|
||||
*
|
||||
* 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
|
||||
* AAC encoder temporal noise shaping
|
||||
* @author Rostislav Pehlivanov ( atomnuker gmail com )
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AACENC_TNS_H
|
||||
#define AVCODEC_AACENC_TNS_H
|
||||
|
||||
#include "aacenc.h"
|
||||
|
||||
/* Could be set to 3 to save an additional bit at the cost of little quality */
|
||||
#define TNS_Q_BITS 4
|
||||
|
||||
/* TNS will only be used if the LPC gain is within these margins */
|
||||
#define TNS_GAIN_THRESHOLD_LOW 1.395f
|
||||
#define TNS_GAIN_THRESHOLD_HIGH 11.19f
|
||||
|
||||
/* If the energy ratio between the low SFBs vs the high SFBs is not between
|
||||
* those two values, use 2 filters instead */
|
||||
#define TNS_E_RATIO_LOW 0.77
|
||||
#define TNS_E_RATIO_HIGH 1.23
|
||||
|
||||
/* Do not use TNS if the psy band spread is below this value */
|
||||
#define TNS_SPREAD_THRESHOLD 37.081512f
|
||||
|
||||
void ff_aac_encode_tns_info(AACEncContext *s, SingleChannelElement *sce);
|
||||
void ff_aac_apply_tns(AACEncContext *s, SingleChannelElement *sce);
|
||||
void ff_aac_search_for_tns(AACEncContext *s, SingleChannelElement *sce);
|
||||
|
||||
#endif /* AVCODEC_AACENC_TNS_H */
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* AAC encoder utilities
|
||||
* Copyright (C) 2015 Rostislav Pehlivanov
|
||||
*
|
||||
* 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
|
||||
* AAC encoder utilities
|
||||
* @author Rostislav Pehlivanov ( atomnuker gmail com )
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AACENC_UTILS_H
|
||||
#define AVCODEC_AACENC_UTILS_H
|
||||
|
||||
#include "aac.h"
|
||||
#include "aac_tablegen_decl.h"
|
||||
#include "aacenctab.h"
|
||||
|
||||
#define ROUND_STANDARD 0.4054f
|
||||
#define ROUND_TO_ZERO 0.1054f
|
||||
#define C_QUANT 0.4054f
|
||||
|
||||
static inline void abs_pow34_v(float *out, const float *in, const int size)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < size; i++) {
|
||||
float a = fabsf(in[i]);
|
||||
out[i] = sqrtf(a * sqrtf(a));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quantize one coefficient.
|
||||
* @return absolute value of the quantized coefficient
|
||||
* @see 3GPP TS26.403 5.6.2 "Scalefactor determination"
|
||||
*/
|
||||
static inline int quant(float coef, const float Q, const float rounding)
|
||||
{
|
||||
float a = coef * Q;
|
||||
return sqrtf(a * sqrtf(a)) + rounding;
|
||||
}
|
||||
|
||||
static inline void quantize_bands(int *out, const float *in, const float *scaled,
|
||||
int size, float Q34, int is_signed, int maxval,
|
||||
const float rounding)
|
||||
{
|
||||
int i;
|
||||
double qc;
|
||||
for (i = 0; i < size; i++) {
|
||||
qc = scaled[i] * Q34;
|
||||
out[i] = (int)FFMIN(qc + rounding, (double)maxval);
|
||||
if (is_signed && in[i] < 0.0f) {
|
||||
out[i] = -out[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline float find_max_val(int group_len, int swb_size, const float *scaled)
|
||||
{
|
||||
float maxval = 0.0f;
|
||||
int w2, i;
|
||||
for (w2 = 0; w2 < group_len; w2++) {
|
||||
for (i = 0; i < swb_size; i++) {
|
||||
maxval = FFMAX(maxval, scaled[w2*128+i]);
|
||||
}
|
||||
}
|
||||
return maxval;
|
||||
}
|
||||
|
||||
static inline int find_min_book(float maxval, int sf)
|
||||
{
|
||||
float Q = ff_aac_pow2sf_tab[POW_SF2_ZERO - sf + SCALE_ONE_POS - SCALE_DIV_512];
|
||||
float Q34 = sqrtf(Q * sqrtf(Q));
|
||||
int qmaxval, cb;
|
||||
qmaxval = maxval * Q34 + C_QUANT;
|
||||
if (qmaxval == 0) cb = 0;
|
||||
else if (qmaxval == 1) cb = 1;
|
||||
else if (qmaxval == 2) cb = 3;
|
||||
else if (qmaxval <= 4) cb = 5;
|
||||
else if (qmaxval <= 7) cb = 7;
|
||||
else if (qmaxval <= 12) cb = 9;
|
||||
else cb = 11;
|
||||
return cb;
|
||||
}
|
||||
|
||||
/** Return the minimum scalefactor where the quantized coef does not clip. */
|
||||
static inline uint8_t coef2minsf(float coef)
|
||||
{
|
||||
return av_clip_uint8(log2f(coef)*4 - 69 + SCALE_ONE_POS - SCALE_DIV_512);
|
||||
}
|
||||
|
||||
/** Return the maximum scalefactor where the quantized coef is not zero. */
|
||||
static inline uint8_t coef2maxsf(float coef)
|
||||
{
|
||||
return av_clip_uint8(log2f(coef)*4 + 6 + SCALE_ONE_POS - SCALE_DIV_512);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the closest possible index to an array of float values, given a value.
|
||||
*/
|
||||
static inline int quant_array_idx(const float val, const float *arr, const int num)
|
||||
{
|
||||
int i, index = 0;
|
||||
float quant_min_err = INFINITY;
|
||||
for (i = 0; i < num; i++) {
|
||||
float error = (val - arr[i])*(val - arr[i]);
|
||||
if (error < quant_min_err) {
|
||||
quant_min_err = error;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
#define ERROR_IF(cond, ...) \
|
||||
if (cond) { \
|
||||
av_log(avctx, AV_LOG_ERROR, __VA_ARGS__); \
|
||||
return AVERROR(EINVAL); \
|
||||
}
|
||||
|
||||
#define WARN_IF(cond, ...) \
|
||||
if (cond) { \
|
||||
av_log(avctx, AV_LOG_WARNING, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
|
||||
#endif /* AVCODEC_AACENC_UTILS_H */
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* AAC encoder data
|
||||
* Copyright (c) 2015 Rostislav Pehlivanov ( atomnuker gmail com )
|
||||
*
|
||||
* 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 "aacenctab.h"
|
||||
|
||||
static const uint8_t swb_size_128_96[] = {
|
||||
4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_64[] = {
|
||||
4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_48[] = {
|
||||
4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_24[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_16[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_8[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_96[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 12, 16, 16, 24, 28, 36, 44,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_64[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8,
|
||||
12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 36,
|
||||
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_48[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28,
|
||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||
96
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_32[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28,
|
||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_24[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28,
|
||||
32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_16[] = {
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28,
|
||||
32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_8[] = {
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
|
||||
16, 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28, 28,
|
||||
32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80
|
||||
};
|
||||
|
||||
const uint8_t *ff_aac_swb_size_128[] = {
|
||||
swb_size_128_96, swb_size_128_96, swb_size_128_64,
|
||||
swb_size_128_48, swb_size_128_48, swb_size_128_48,
|
||||
swb_size_128_24, swb_size_128_24, swb_size_128_16,
|
||||
swb_size_128_16, swb_size_128_16, swb_size_128_8,
|
||||
swb_size_128_8
|
||||
};
|
||||
|
||||
const uint8_t *ff_aac_swb_size_1024[] = {
|
||||
swb_size_1024_96, swb_size_1024_96, swb_size_1024_64,
|
||||
swb_size_1024_48, swb_size_1024_48, swb_size_1024_32,
|
||||
swb_size_1024_24, swb_size_1024_24, swb_size_1024_16,
|
||||
swb_size_1024_16, swb_size_1024_16, swb_size_1024_8,
|
||||
swb_size_1024_8
|
||||
};
|
||||
|
||||
const int ff_aac_swb_size_128_len = FF_ARRAY_ELEMS(ff_aac_swb_size_128);
|
||||
const int ff_aac_swb_size_1024_len = FF_ARRAY_ELEMS(ff_aac_swb_size_1024);
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* AAC encoder data
|
||||
* Copyright (c) 2015 Rostislav Pehlivanov ( atomnuker gmail com )
|
||||
*
|
||||
* 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
|
||||
* AAC encoder data
|
||||
* @author Rostislav Pehlivanov ( atomnuker gmail com )
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AACENCTAB_H
|
||||
#define AVCODEC_AACENCTAB_H
|
||||
|
||||
#include "aac.h"
|
||||
|
||||
/** Total number of usable codebooks **/
|
||||
#define CB_TOT 12
|
||||
|
||||
/** Total number of codebooks, including special ones **/
|
||||
#define CB_TOT_ALL 15
|
||||
|
||||
#define AAC_MAX_CHANNELS 6
|
||||
|
||||
extern const uint8_t *ff_aac_swb_size_1024[];
|
||||
extern const int ff_aac_swb_size_1024_len;
|
||||
extern const uint8_t *ff_aac_swb_size_128[];
|
||||
extern const int ff_aac_swb_size_128_len;
|
||||
|
||||
/** default channel configurations */
|
||||
static const uint8_t aac_chan_configs[6][5] = {
|
||||
{1, TYPE_SCE}, // 1 channel - single channel element
|
||||
{1, TYPE_CPE}, // 2 channels - channel pair
|
||||
{2, TYPE_SCE, TYPE_CPE}, // 3 channels - center + stereo
|
||||
{3, TYPE_SCE, TYPE_CPE, TYPE_SCE}, // 4 channels - front center + stereo + back center
|
||||
{3, TYPE_SCE, TYPE_CPE, TYPE_CPE}, // 5 channels - front center + stereo + back stereo
|
||||
{4, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_LFE}, // 6 channels - front center + stereo + back stereo + LFE
|
||||
};
|
||||
|
||||
/**
|
||||
* Table to remap channels from libavcodec's default order to AAC order.
|
||||
*/
|
||||
static const uint8_t aac_chan_maps[AAC_MAX_CHANNELS][AAC_MAX_CHANNELS] = {
|
||||
{ 0 },
|
||||
{ 0, 1 },
|
||||
{ 2, 0, 1 },
|
||||
{ 2, 0, 1, 3 },
|
||||
{ 2, 0, 1, 3, 4 },
|
||||
{ 2, 0, 1, 4, 5, 3 },
|
||||
};
|
||||
|
||||
/* duplicated from avpriv_mpeg4audio_sample_rates to avoid shared build
|
||||
* failures */
|
||||
static const int mpeg4audio_sample_rates[16] = {
|
||||
96000, 88200, 64000, 48000, 44100, 32000,
|
||||
24000, 22050, 16000, 12000, 11025, 8000, 7350
|
||||
};
|
||||
|
||||
/** bits needed to code codebook run value for long windows */
|
||||
static const uint8_t run_value_bits_long[64] = {
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10,
|
||||
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 15
|
||||
};
|
||||
|
||||
/** bits needed to code codebook run value for short windows */
|
||||
static const uint8_t run_value_bits_short[16] = {
|
||||
3, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 9
|
||||
};
|
||||
|
||||
/* TNS starting SFBs for long and short windows */
|
||||
static const uint8_t tns_min_sfb_short[16] = {
|
||||
2, 2, 2, 3, 3, 4, 6, 6, 8, 10, 10, 12, 12, 12, 12, 12
|
||||
};
|
||||
|
||||
static const uint8_t tns_min_sfb_long[16] = {
|
||||
12, 13, 15, 16, 17, 20, 25, 26, 24, 28, 30, 31, 31, 31, 31, 31
|
||||
};
|
||||
|
||||
static const uint8_t * const tns_min_sfb[2] = {
|
||||
tns_min_sfb_long, tns_min_sfb_short
|
||||
};
|
||||
|
||||
static const uint8_t * const run_value_bits[2] = {
|
||||
run_value_bits_long, run_value_bits_short
|
||||
};
|
||||
|
||||
/** Map to convert values from BandCodingPath index to a codebook index **/
|
||||
static const uint8_t aac_cb_out_map[CB_TOT_ALL] = {0,1,2,3,4,5,6,7,8,9,10,11,13,14,15};
|
||||
/** Inverse map to convert from codebooks to BandCodingPath indices **/
|
||||
static const uint8_t aac_cb_in_map[CB_TOT_ALL+1] = {0,1,2,3,4,5,6,7,8,9,10,11,0,12,13,14};
|
||||
|
||||
static const uint8_t aac_cb_range [12] = {0, 3, 3, 3, 3, 9, 9, 8, 8, 13, 13, 17};
|
||||
static const uint8_t aac_cb_maxval[12] = {0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12, 16};
|
||||
|
||||
#endif /* AVCODEC_AACENCTAB_H */
|
||||
+91
-157
@@ -17,23 +17,16 @@
|
||||
* 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
|
||||
*
|
||||
* Note: Rounding-to-nearest used unless otherwise stated
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/internal.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "avcodec.h"
|
||||
#include "get_bits.h"
|
||||
#include "aacps.h"
|
||||
#if USE_FIXED
|
||||
#include "aacps_fixed_tablegen.h"
|
||||
#else
|
||||
#include "libavutil/internal.h"
|
||||
#include "aacps_tablegen.h"
|
||||
#endif /* USE_FIXED */
|
||||
#include "aacpsdata.c"
|
||||
|
||||
#define PS_BASELINE 0 ///< Operate in Baseline PS mode
|
||||
@@ -155,7 +148,7 @@ static void ipdopd_reset(int8_t *ipd_hist, int8_t *opd_hist)
|
||||
}
|
||||
}
|
||||
|
||||
int AAC_RENAME(ff_ps_read_data)(AVCodecContext *avctx, GetBitContext *gb_host, PSContext *ps, int bits_left)
|
||||
int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host, PSContext *ps, int bits_left)
|
||||
{
|
||||
int e;
|
||||
int bit_count_start = get_bits_count(gb_host);
|
||||
@@ -309,41 +302,35 @@ err:
|
||||
|
||||
/** Split one subband into 2 subsubbands with a symmetric real filter.
|
||||
* The filter must have its non-center even coefficients equal to zero. */
|
||||
static void hybrid2_re(INTFLOAT (*in)[2], INTFLOAT (*out)[32][2], const INTFLOAT filter[8], int len, int reverse)
|
||||
static void hybrid2_re(float (*in)[2], float (*out)[32][2], const float filter[8], int len, int reverse)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < len; i++, in++) {
|
||||
INT64FLOAT re_in = AAC_MUL31(filter[6], in[6][0]); //real inphase
|
||||
INT64FLOAT re_op = 0.0f; //real out of phase
|
||||
INT64FLOAT im_in = AAC_MUL31(filter[6], in[6][1]); //imag inphase
|
||||
INT64FLOAT im_op = 0.0f; //imag out of phase
|
||||
float re_in = filter[6] * in[6][0]; //real inphase
|
||||
float re_op = 0.0f; //real out of phase
|
||||
float im_in = filter[6] * in[6][1]; //imag inphase
|
||||
float im_op = 0.0f; //imag out of phase
|
||||
for (j = 0; j < 6; j += 2) {
|
||||
re_op += (INT64FLOAT)filter[j+1] * (in[j+1][0] + in[12-j-1][0]);
|
||||
im_op += (INT64FLOAT)filter[j+1] * (in[j+1][1] + in[12-j-1][1]);
|
||||
re_op += filter[j+1] * (in[j+1][0] + in[12-j-1][0]);
|
||||
im_op += filter[j+1] * (in[j+1][1] + in[12-j-1][1]);
|
||||
}
|
||||
|
||||
#if USE_FIXED
|
||||
re_op = (re_op + 0x40000000) >> 31;
|
||||
im_op = (im_op + 0x40000000) >> 31;
|
||||
#endif /* USE_FIXED */
|
||||
|
||||
out[ reverse][i][0] = (INTFLOAT)(re_in + re_op);
|
||||
out[ reverse][i][1] = (INTFLOAT)(im_in + im_op);
|
||||
out[!reverse][i][0] = (INTFLOAT)(re_in - re_op);
|
||||
out[!reverse][i][1] = (INTFLOAT)(im_in - im_op);
|
||||
out[ reverse][i][0] = re_in + re_op;
|
||||
out[ reverse][i][1] = im_in + im_op;
|
||||
out[!reverse][i][0] = re_in - re_op;
|
||||
out[!reverse][i][1] = im_in - im_op;
|
||||
}
|
||||
}
|
||||
|
||||
/** Split one subband into 6 subsubbands with a complex filter */
|
||||
static void hybrid6_cx(PSDSPContext *dsp, INTFLOAT (*in)[2], INTFLOAT (*out)[32][2],
|
||||
TABLE_CONST INTFLOAT (*filter)[8][2], int len)
|
||||
static void hybrid6_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2],
|
||||
TABLE_CONST float (*filter)[8][2], int len)
|
||||
{
|
||||
int i;
|
||||
int N = 8;
|
||||
LOCAL_ALIGNED_16(INTFLOAT, temp, [8], [2]);
|
||||
LOCAL_ALIGNED_16(float, temp, [8], [2]);
|
||||
|
||||
for (i = 0; i < len; i++, in++) {
|
||||
dsp->hybrid_analysis(temp, in, (const INTFLOAT (*)[8][2]) filter, 1, N);
|
||||
dsp->hybrid_analysis(temp, in, (const float (*)[8][2]) filter, 1, N);
|
||||
out[0][i][0] = temp[6][0];
|
||||
out[0][i][1] = temp[6][1];
|
||||
out[1][i][0] = temp[7][0];
|
||||
@@ -360,18 +347,18 @@ static void hybrid6_cx(PSDSPContext *dsp, INTFLOAT (*in)[2], INTFLOAT (*out)[32]
|
||||
}
|
||||
|
||||
static void hybrid4_8_12_cx(PSDSPContext *dsp,
|
||||
INTFLOAT (*in)[2], INTFLOAT (*out)[32][2],
|
||||
TABLE_CONST INTFLOAT (*filter)[8][2], int N, int len)
|
||||
float (*in)[2], float (*out)[32][2],
|
||||
TABLE_CONST float (*filter)[8][2], int N, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++, in++) {
|
||||
dsp->hybrid_analysis(out[0] + i, in, (const INTFLOAT (*)[8][2]) filter, 32, N);
|
||||
dsp->hybrid_analysis(out[0] + i, in, (const float (*)[8][2]) filter, 32, N);
|
||||
}
|
||||
}
|
||||
|
||||
static void hybrid_analysis(PSDSPContext *dsp, INTFLOAT out[91][32][2],
|
||||
INTFLOAT in[5][44][2], INTFLOAT L[2][38][64],
|
||||
static void hybrid_analysis(PSDSPContext *dsp, float out[91][32][2],
|
||||
float in[5][44][2], float L[2][38][64],
|
||||
int is34, int len)
|
||||
{
|
||||
int i, j;
|
||||
@@ -400,8 +387,8 @@ static void hybrid_analysis(PSDSPContext *dsp, INTFLOAT out[91][32][2],
|
||||
}
|
||||
}
|
||||
|
||||
static void hybrid_synthesis(PSDSPContext *dsp, INTFLOAT out[2][38][64],
|
||||
INTFLOAT in[91][32][2], int is34, int len)
|
||||
static void hybrid_synthesis(PSDSPContext *dsp, float out[2][38][64],
|
||||
float in[91][32][2], int is34, int len)
|
||||
{
|
||||
int i, n;
|
||||
if (is34) {
|
||||
@@ -442,7 +429,7 @@ static void hybrid_synthesis(PSDSPContext *dsp, INTFLOAT out[2][38][64],
|
||||
}
|
||||
|
||||
/// All-pass filter decay slope
|
||||
#define DECAY_SLOPE Q30(0.05f)
|
||||
#define DECAY_SLOPE 0.05f
|
||||
/// Number of frequency bands that can be addressed by the parameter index, b(k)
|
||||
static const int NR_PAR_BANDS[] = { 20, 34 };
|
||||
static const int NR_IPDOPD_BANDS[] = { 11, 17 };
|
||||
@@ -496,43 +483,28 @@ static void map_idx_34_to_20(int8_t *par_mapped, const int8_t *par, int full)
|
||||
}
|
||||
}
|
||||
|
||||
static void map_val_34_to_20(INTFLOAT par[PS_MAX_NR_IIDICC])
|
||||
static void map_val_34_to_20(float par[PS_MAX_NR_IIDICC])
|
||||
{
|
||||
#if USE_FIXED
|
||||
par[ 0] = (int)(((int64_t)(par[ 0] + (unsigned)(par[ 1]>>1)) * 1431655765 + \
|
||||
0x40000000) >> 31);
|
||||
par[ 1] = (int)(((int64_t)((par[ 1]>>1) + (unsigned)par[ 2]) * 1431655765 + \
|
||||
0x40000000) >> 31);
|
||||
par[ 2] = (int)(((int64_t)(par[ 3] + (unsigned)(par[ 4]>>1)) * 1431655765 + \
|
||||
0x40000000) >> 31);
|
||||
par[ 3] = (int)(((int64_t)((par[ 4]>>1) + (unsigned)par[ 5]) * 1431655765 + \
|
||||
0x40000000) >> 31);
|
||||
#else
|
||||
par[ 0] = (2*par[ 0] + par[ 1]) * 0.33333333f;
|
||||
par[ 1] = ( par[ 1] + 2*par[ 2]) * 0.33333333f;
|
||||
par[ 2] = (2*par[ 3] + par[ 4]) * 0.33333333f;
|
||||
par[ 3] = ( par[ 4] + 2*par[ 5]) * 0.33333333f;
|
||||
#endif /* USE_FIXED */
|
||||
par[ 4] = AAC_HALF_SUM(par[ 6], par[ 7]);
|
||||
par[ 5] = AAC_HALF_SUM(par[ 8], par[ 9]);
|
||||
par[ 4] = ( par[ 6] + par[ 7]) * 0.5f;
|
||||
par[ 5] = ( par[ 8] + par[ 9]) * 0.5f;
|
||||
par[ 6] = par[10];
|
||||
par[ 7] = par[11];
|
||||
par[ 8] = AAC_HALF_SUM(par[12], par[13]);
|
||||
par[ 9] = AAC_HALF_SUM(par[14], par[15]);
|
||||
par[ 8] = ( par[12] + par[13]) * 0.5f;
|
||||
par[ 9] = ( par[14] + par[15]) * 0.5f;
|
||||
par[10] = par[16];
|
||||
par[11] = par[17];
|
||||
par[12] = par[18];
|
||||
par[13] = par[19];
|
||||
par[14] = AAC_HALF_SUM(par[20], par[21]);
|
||||
par[15] = AAC_HALF_SUM(par[22], par[23]);
|
||||
par[16] = AAC_HALF_SUM(par[24], par[25]);
|
||||
par[17] = AAC_HALF_SUM(par[26], par[27]);
|
||||
#if USE_FIXED
|
||||
par[18] = (((par[28]+2)>>2) + ((par[29]+2)>>2) + ((par[30]+2)>>2) + ((par[31]+2)>>2));
|
||||
#else
|
||||
par[14] = ( par[20] + par[21]) * 0.5f;
|
||||
par[15] = ( par[22] + par[23]) * 0.5f;
|
||||
par[16] = ( par[24] + par[25]) * 0.5f;
|
||||
par[17] = ( par[26] + par[27]) * 0.5f;
|
||||
par[18] = ( par[28] + par[29] + par[30] + par[31]) * 0.25f;
|
||||
#endif /* USE_FIXED */
|
||||
par[19] = AAC_HALF_SUM(par[32], par[33]);
|
||||
par[19] = ( par[32] + par[33]) * 0.5f;
|
||||
}
|
||||
|
||||
static void map_idx_10_to_34(int8_t *par_mapped, const int8_t *par, int full)
|
||||
@@ -617,7 +589,7 @@ static void map_idx_20_to_34(int8_t *par_mapped, const int8_t *par, int full)
|
||||
par_mapped[ 0] = par[ 0];
|
||||
}
|
||||
|
||||
static void map_val_20_to_34(INTFLOAT par[PS_MAX_NR_IIDICC])
|
||||
static void map_val_20_to_34(float par[PS_MAX_NR_IIDICC])
|
||||
{
|
||||
par[33] = par[19];
|
||||
par[32] = par[19];
|
||||
@@ -648,29 +620,27 @@ static void map_val_20_to_34(INTFLOAT par[PS_MAX_NR_IIDICC])
|
||||
par[ 7] = par[ 4];
|
||||
par[ 6] = par[ 4];
|
||||
par[ 5] = par[ 3];
|
||||
par[ 4] = AAC_HALF_SUM(par[ 2], par[ 3]);
|
||||
par[ 4] = (par[ 2] + par[ 3]) * 0.5f;
|
||||
par[ 3] = par[ 2];
|
||||
par[ 2] = par[ 1];
|
||||
par[ 1] = AAC_HALF_SUM(par[ 0], par[ 1]);
|
||||
par[ 1] = (par[ 0] + par[ 1]) * 0.5f;
|
||||
}
|
||||
|
||||
static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
|
||||
static void decorrelation(PSContext *ps, float (*out)[32][2], const float (*s)[32][2], int is34)
|
||||
{
|
||||
LOCAL_ALIGNED_16(INTFLOAT, power, [34], [PS_QMF_TIME_SLOTS]);
|
||||
LOCAL_ALIGNED_16(INTFLOAT, transient_gain, [34], [PS_QMF_TIME_SLOTS]);
|
||||
INTFLOAT *peak_decay_nrg = ps->peak_decay_nrg;
|
||||
INTFLOAT *power_smooth = ps->power_smooth;
|
||||
INTFLOAT *peak_decay_diff_smooth = ps->peak_decay_diff_smooth;
|
||||
INTFLOAT (*delay)[PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2] = ps->delay;
|
||||
INTFLOAT (*ap_delay)[PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2] = ps->ap_delay;
|
||||
#if !USE_FIXED
|
||||
LOCAL_ALIGNED_16(float, power, [34], [PS_QMF_TIME_SLOTS]);
|
||||
LOCAL_ALIGNED_16(float, transient_gain, [34], [PS_QMF_TIME_SLOTS]);
|
||||
float *peak_decay_nrg = ps->peak_decay_nrg;
|
||||
float *power_smooth = ps->power_smooth;
|
||||
float *peak_decay_diff_smooth = ps->peak_decay_diff_smooth;
|
||||
float (*delay)[PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2] = ps->delay;
|
||||
float (*ap_delay)[PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2] = ps->ap_delay;
|
||||
const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20;
|
||||
const float peak_decay_factor = 0.76592833836465f;
|
||||
const float transient_impact = 1.5f;
|
||||
const float a_smooth = 0.25f; ///< Smoothing coefficient
|
||||
#endif /* USE_FIXED */
|
||||
const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20;
|
||||
int i, k, m, n;
|
||||
int n0 = 0, nL = 32;
|
||||
const INTFLOAT peak_decay_factor = Q31(0.76592833836465f);
|
||||
|
||||
memset(power, 0, 34 * sizeof(*power));
|
||||
|
||||
@@ -688,24 +658,6 @@ static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT
|
||||
}
|
||||
|
||||
//Transient detection
|
||||
#if USE_FIXED
|
||||
for (i = 0; i < NR_PAR_BANDS[is34]; i++) {
|
||||
for (n = n0; n < nL; n++) {
|
||||
int decayed_peak;
|
||||
decayed_peak = (int)(((int64_t)peak_decay_factor * \
|
||||
peak_decay_nrg[i] + 0x40000000) >> 31);
|
||||
peak_decay_nrg[i] = FFMAX(decayed_peak, power[i][n]);
|
||||
power_smooth[i] += (power[i][n] + 2LL - power_smooth[i]) >> 2;
|
||||
peak_decay_diff_smooth[i] += (peak_decay_nrg[i] + 2LL - power[i][n] - \
|
||||
peak_decay_diff_smooth[i]) >> 2;
|
||||
|
||||
if (peak_decay_diff_smooth[i]) {
|
||||
transient_gain[i][n] = FFMIN(power_smooth[i]*43691LL / peak_decay_diff_smooth[i], 1<<16);
|
||||
} else
|
||||
transient_gain[i][n] = 1 << 16;
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < NR_PAR_BANDS[is34]; i++) {
|
||||
for (n = n0; n < nL; n++) {
|
||||
float decayed_peak = peak_decay_factor * peak_decay_nrg[i];
|
||||
@@ -719,7 +671,6 @@ static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_FIXED */
|
||||
//Decorrelation and transient reduction
|
||||
// PS_AP_LINKS - 1
|
||||
// -----
|
||||
@@ -730,22 +681,8 @@ static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT
|
||||
//d[k][z] (out) = transient_gain_mapped[k][z] * H[k][z] * s[k][z]
|
||||
for (k = 0; k < NR_ALLPASS_BANDS[is34]; k++) {
|
||||
int b = k_to_i[k];
|
||||
#if USE_FIXED
|
||||
int g_decay_slope;
|
||||
|
||||
if (k - DECAY_CUTOFF[is34] <= 0) {
|
||||
g_decay_slope = 1 << 30;
|
||||
}
|
||||
else if (k - DECAY_CUTOFF[is34] >= 20) {
|
||||
g_decay_slope = 0;
|
||||
}
|
||||
else {
|
||||
g_decay_slope = (1 << 30) - DECAY_SLOPE * (k - DECAY_CUTOFF[is34]);
|
||||
}
|
||||
#else
|
||||
float g_decay_slope = 1.f - DECAY_SLOPE * (k - DECAY_CUTOFF[is34]);
|
||||
g_decay_slope = av_clipf(g_decay_slope, 0.f, 1.f);
|
||||
#endif /* USE_FIXED */
|
||||
memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0]));
|
||||
memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0]));
|
||||
for (m = 0; m < PS_AP_LINKS; m++) {
|
||||
@@ -753,7 +690,7 @@ static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT
|
||||
}
|
||||
ps->dsp.decorrelate(out[k], delay[k] + PS_MAX_DELAY - 2, ap_delay[k],
|
||||
phi_fract[is34][k],
|
||||
(const INTFLOAT (*)[2]) Q_fract_allpass[is34][k],
|
||||
(const float (*)[2]) Q_fract_allpass[is34][k],
|
||||
transient_gain[b], g_decay_slope, nL - n0);
|
||||
}
|
||||
for (; k < SHORT_DELAY_BAND[is34]; k++) {
|
||||
@@ -812,14 +749,14 @@ static void remap20(int8_t (**p_par_mapped)[PS_MAX_NR_IIDICC],
|
||||
}
|
||||
}
|
||||
|
||||
static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)[32][2], int is34)
|
||||
static void stereo_processing(PSContext *ps, float (*l)[32][2], float (*r)[32][2], int is34)
|
||||
{
|
||||
int e, b, k;
|
||||
|
||||
INTFLOAT (*H11)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H11;
|
||||
INTFLOAT (*H12)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H12;
|
||||
INTFLOAT (*H21)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H21;
|
||||
INTFLOAT (*H22)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H22;
|
||||
float (*H11)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H11;
|
||||
float (*H12)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H12;
|
||||
float (*H21)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H21;
|
||||
float (*H22)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H22;
|
||||
int8_t *opd_hist = ps->opd_hist;
|
||||
int8_t *ipd_hist = ps->ipd_hist;
|
||||
int8_t iid_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];
|
||||
@@ -831,7 +768,7 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)
|
||||
int8_t (*ipd_mapped)[PS_MAX_NR_IIDICC] = ipd_mapped_buf;
|
||||
int8_t (*opd_mapped)[PS_MAX_NR_IIDICC] = opd_mapped_buf;
|
||||
const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20;
|
||||
TABLE_CONST INTFLOAT (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB;
|
||||
TABLE_CONST float (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB;
|
||||
|
||||
//Remapping
|
||||
if (ps->num_env_old) {
|
||||
@@ -886,7 +823,7 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)
|
||||
//Mixing
|
||||
for (e = 0; e < ps->num_env; e++) {
|
||||
for (b = 0; b < NR_PAR_BANDS[is34]; b++) {
|
||||
INTFLOAT h11, h12, h21, h22;
|
||||
float h11, h12, h21, h22;
|
||||
h11 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][0];
|
||||
h12 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][1];
|
||||
h21 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][2];
|
||||
@@ -895,27 +832,27 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)
|
||||
if (!PS_BASELINE && ps->enable_ipdopd && b < NR_IPDOPD_BANDS[is34]) {
|
||||
//The spec say says to only run this smoother when enable_ipdopd
|
||||
//is set but the reference decoder appears to run it constantly
|
||||
INTFLOAT h11i, h12i, h21i, h22i;
|
||||
INTFLOAT ipd_adj_re, ipd_adj_im;
|
||||
float h11i, h12i, h21i, h22i;
|
||||
float ipd_adj_re, ipd_adj_im;
|
||||
int opd_idx = opd_hist[b] * 8 + opd_mapped[e][b];
|
||||
int ipd_idx = ipd_hist[b] * 8 + ipd_mapped[e][b];
|
||||
INTFLOAT opd_re = pd_re_smooth[opd_idx];
|
||||
INTFLOAT opd_im = pd_im_smooth[opd_idx];
|
||||
INTFLOAT ipd_re = pd_re_smooth[ipd_idx];
|
||||
INTFLOAT ipd_im = pd_im_smooth[ipd_idx];
|
||||
float opd_re = pd_re_smooth[opd_idx];
|
||||
float opd_im = pd_im_smooth[opd_idx];
|
||||
float ipd_re = pd_re_smooth[ipd_idx];
|
||||
float ipd_im = pd_im_smooth[ipd_idx];
|
||||
opd_hist[b] = opd_idx & 0x3F;
|
||||
ipd_hist[b] = ipd_idx & 0x3F;
|
||||
|
||||
ipd_adj_re = AAC_MADD30(opd_re, ipd_re, opd_im, ipd_im);
|
||||
ipd_adj_im = AAC_MSUB30(opd_im, ipd_re, opd_re, ipd_im);
|
||||
h11i = AAC_MUL30(h11, opd_im);
|
||||
h11 = AAC_MUL30(h11, opd_re);
|
||||
h12i = AAC_MUL30(h12, ipd_adj_im);
|
||||
h12 = AAC_MUL30(h12, ipd_adj_re);
|
||||
h21i = AAC_MUL30(h21, opd_im);
|
||||
h21 = AAC_MUL30(h21, opd_re);
|
||||
h22i = AAC_MUL30(h22, ipd_adj_im);
|
||||
h22 = AAC_MUL30(h22, ipd_adj_re);
|
||||
ipd_adj_re = opd_re*ipd_re + opd_im*ipd_im;
|
||||
ipd_adj_im = opd_im*ipd_re - opd_re*ipd_im;
|
||||
h11i = h11 * opd_im;
|
||||
h11 = h11 * opd_re;
|
||||
h12i = h12 * ipd_adj_im;
|
||||
h12 = h12 * ipd_adj_re;
|
||||
h21i = h21 * opd_im;
|
||||
h21 = h21 * opd_re;
|
||||
h22i = h22 * ipd_adj_im;
|
||||
h22 = h22 * ipd_adj_re;
|
||||
H11[1][e+1][b] = h11i;
|
||||
H12[1][e+1][b] = h12i;
|
||||
H21[1][e+1][b] = h21i;
|
||||
@@ -927,14 +864,11 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)
|
||||
H22[0][e+1][b] = h22;
|
||||
}
|
||||
for (k = 0; k < NR_BANDS[is34]; k++) {
|
||||
LOCAL_ALIGNED_16(INTFLOAT, h, [2], [4]);
|
||||
LOCAL_ALIGNED_16(INTFLOAT, h_step, [2], [4]);
|
||||
float h[2][4];
|
||||
float h_step[2][4];
|
||||
int start = ps->border_position[e];
|
||||
int stop = ps->border_position[e+1];
|
||||
INTFLOAT width = Q30(1.f) / ((stop - start) ? (stop - start) : 1);
|
||||
#if USE_FIXED
|
||||
width = FFMIN(2U*width, INT_MAX);
|
||||
#endif
|
||||
float width = 1.f / (stop - start);
|
||||
b = k_to_i[k];
|
||||
h[0][0] = H11[0][e][b];
|
||||
h[0][1] = H12[0][e][b];
|
||||
@@ -955,27 +889,27 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)
|
||||
}
|
||||
}
|
||||
//Interpolation
|
||||
h_step[0][0] = AAC_MSUB31_V3(H11[0][e+1][b], h[0][0], width);
|
||||
h_step[0][1] = AAC_MSUB31_V3(H12[0][e+1][b], h[0][1], width);
|
||||
h_step[0][2] = AAC_MSUB31_V3(H21[0][e+1][b], h[0][2], width);
|
||||
h_step[0][3] = AAC_MSUB31_V3(H22[0][e+1][b], h[0][3], width);
|
||||
h_step[0][0] = (H11[0][e+1][b] - h[0][0]) * width;
|
||||
h_step[0][1] = (H12[0][e+1][b] - h[0][1]) * width;
|
||||
h_step[0][2] = (H21[0][e+1][b] - h[0][2]) * width;
|
||||
h_step[0][3] = (H22[0][e+1][b] - h[0][3]) * width;
|
||||
if (!PS_BASELINE && ps->enable_ipdopd) {
|
||||
h_step[1][0] = AAC_MSUB31_V3(H11[1][e+1][b], h[1][0], width);
|
||||
h_step[1][1] = AAC_MSUB31_V3(H12[1][e+1][b], h[1][1], width);
|
||||
h_step[1][2] = AAC_MSUB31_V3(H21[1][e+1][b], h[1][2], width);
|
||||
h_step[1][3] = AAC_MSUB31_V3(H22[1][e+1][b], h[1][3], width);
|
||||
h_step[1][0] = (H11[1][e+1][b] - h[1][0]) * width;
|
||||
h_step[1][1] = (H12[1][e+1][b] - h[1][1]) * width;
|
||||
h_step[1][2] = (H21[1][e+1][b] - h[1][2]) * width;
|
||||
h_step[1][3] = (H22[1][e+1][b] - h[1][3]) * width;
|
||||
}
|
||||
ps->dsp.stereo_interpolate[!PS_BASELINE && ps->enable_ipdopd](
|
||||
l[k] + 1 + start, r[k] + 1 + start,
|
||||
l[k] + start + 1, r[k] + start + 1,
|
||||
h, h_step, stop - start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top)
|
||||
int ff_ps_apply(AVCodecContext *avctx, PSContext *ps, float L[2][38][64], float R[2][38][64], int top)
|
||||
{
|
||||
INTFLOAT (*Lbuf)[32][2] = ps->Lbuf;
|
||||
INTFLOAT (*Rbuf)[32][2] = ps->Rbuf;
|
||||
float (*Lbuf)[32][2] = ps->Lbuf;
|
||||
float (*Rbuf)[32][2] = ps->Rbuf;
|
||||
const int len = 32;
|
||||
int is34 = ps->is34bands;
|
||||
|
||||
@@ -985,7 +919,7 @@ int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][
|
||||
memset(ps->ap_delay + top, 0, (NR_ALLPASS_BANDS[is34] - top)*sizeof(ps->ap_delay[0]));
|
||||
|
||||
hybrid_analysis(&ps->dsp, Lbuf, ps->in_buf, L, is34, len);
|
||||
decorrelation(ps, Rbuf, (const INTFLOAT (*)[32][2]) Lbuf, is34);
|
||||
decorrelation(ps, Rbuf, (const float (*)[32][2]) Lbuf, is34);
|
||||
stereo_processing(ps, Lbuf, Rbuf, is34);
|
||||
hybrid_synthesis(&ps->dsp, L, Lbuf, is34, len);
|
||||
hybrid_synthesis(&ps->dsp, R, Rbuf, is34, len);
|
||||
@@ -1002,7 +936,7 @@ int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][
|
||||
#define PS_VLC_ROW(name) \
|
||||
{ name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) }
|
||||
|
||||
av_cold void AAC_RENAME(ff_ps_init)(void) {
|
||||
av_cold void ff_ps_init(void) {
|
||||
// Syntax initialization
|
||||
static const struct {
|
||||
const void *ps_codes, *ps_bits;
|
||||
@@ -1034,7 +968,7 @@ av_cold void AAC_RENAME(ff_ps_init)(void) {
|
||||
ps_tableinit();
|
||||
}
|
||||
|
||||
av_cold void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps)
|
||||
av_cold void ff_ps_ctx_init(PSContext *ps)
|
||||
{
|
||||
AAC_RENAME(ff_psdsp_init)(&ps->dsp);
|
||||
ff_psdsp_init(&ps->dsp);
|
||||
}
|
||||
|
||||
+16
-16
@@ -61,26 +61,26 @@ typedef struct PSContext {
|
||||
int is34bands;
|
||||
int is34bands_old;
|
||||
|
||||
DECLARE_ALIGNED(16, INTFLOAT, in_buf)[5][44][2];
|
||||
DECLARE_ALIGNED(16, INTFLOAT, delay)[PS_MAX_SSB][PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2];
|
||||
DECLARE_ALIGNED(16, INTFLOAT, ap_delay)[PS_MAX_AP_BANDS][PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2];
|
||||
DECLARE_ALIGNED(16, INTFLOAT, peak_decay_nrg)[34];
|
||||
DECLARE_ALIGNED(16, INTFLOAT, power_smooth)[34];
|
||||
DECLARE_ALIGNED(16, INTFLOAT, peak_decay_diff_smooth)[34];
|
||||
DECLARE_ALIGNED(16, INTFLOAT, H11)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
|
||||
DECLARE_ALIGNED(16, INTFLOAT, H12)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
|
||||
DECLARE_ALIGNED(16, INTFLOAT, H21)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
|
||||
DECLARE_ALIGNED(16, INTFLOAT, H22)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
|
||||
DECLARE_ALIGNED(16, INTFLOAT, Lbuf)[91][32][2];
|
||||
DECLARE_ALIGNED(16, INTFLOAT, Rbuf)[91][32][2];
|
||||
DECLARE_ALIGNED(16, float, in_buf)[5][44][2];
|
||||
DECLARE_ALIGNED(16, float, delay)[PS_MAX_SSB][PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2];
|
||||
DECLARE_ALIGNED(16, float, ap_delay)[PS_MAX_AP_BANDS][PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2];
|
||||
DECLARE_ALIGNED(16, float, peak_decay_nrg)[34];
|
||||
DECLARE_ALIGNED(16, float, power_smooth)[34];
|
||||
DECLARE_ALIGNED(16, float, peak_decay_diff_smooth)[34];
|
||||
DECLARE_ALIGNED(16, float, H11)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
|
||||
DECLARE_ALIGNED(16, float, H12)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
|
||||
DECLARE_ALIGNED(16, float, H21)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
|
||||
DECLARE_ALIGNED(16, float, H22)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
|
||||
DECLARE_ALIGNED(16, float, Lbuf)[91][32][2];
|
||||
DECLARE_ALIGNED(16, float, Rbuf)[91][32][2];
|
||||
int8_t opd_hist[PS_MAX_NR_IIDICC];
|
||||
int8_t ipd_hist[PS_MAX_NR_IIDICC];
|
||||
PSDSPContext dsp;
|
||||
} PSContext;
|
||||
|
||||
void AAC_RENAME(ff_ps_init)(void);
|
||||
void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps);
|
||||
int AAC_RENAME(ff_ps_read_data)(AVCodecContext *avctx, GetBitContext *gb, PSContext *ps, int bits_left);
|
||||
int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top);
|
||||
void ff_ps_init(void);
|
||||
void ff_ps_ctx_init(PSContext *ps);
|
||||
int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb, PSContext *ps, int bits_left);
|
||||
int ff_ps_apply(AVCodecContext *avctx, PSContext *ps, float L[2][38][64], float R[2][38][64], int top);
|
||||
|
||||
#endif /* AVCODEC_PS_H */
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* MPEG-4 Parametric Stereo decoding functions
|
||||
* Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define USE_FIXED 1
|
||||
|
||||
#include "aacps.c"
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Generate a header file for hardcoded Parametric Stereo tables
|
||||
*
|
||||
* Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define USE_FIXED 1
|
||||
#include "aacps_tablegen_template.c"
|
||||
@@ -1,403 +0,0 @@
|
||||
/*
|
||||
* Header file for hardcoded Parametric Stereo tables
|
||||
*
|
||||
* Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Note: Rounding-to-nearest used unless otherwise stated
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AACPS_FIXED_TABLEGEN_H
|
||||
#define AACPS_FIXED_TABLEGEN_H
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if CONFIG_HARDCODED_TABLES
|
||||
#define ps_tableinit()
|
||||
#define TABLE_CONST const
|
||||
#include "libavcodec/aacps_fixed_tables.h"
|
||||
#else
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
#include "aac_defines.h"
|
||||
#include "libavutil/softfloat.h"
|
||||
#define NR_ALLPASS_BANDS20 30
|
||||
#define NR_ALLPASS_BANDS34 50
|
||||
#define PS_AP_LINKS 3
|
||||
#define TABLE_CONST
|
||||
static int pd_re_smooth[8*8*8];
|
||||
static int pd_im_smooth[8*8*8];
|
||||
static int HA[46][8][4];
|
||||
static int HB[46][8][4];
|
||||
static DECLARE_ALIGNED(16, int, f20_0_8) [ 8][8][2];
|
||||
static DECLARE_ALIGNED(16, int, f34_0_12)[12][8][2];
|
||||
static DECLARE_ALIGNED(16, int, f34_1_8) [ 8][8][2];
|
||||
static DECLARE_ALIGNED(16, int, f34_2_4) [ 4][8][2];
|
||||
static TABLE_CONST DECLARE_ALIGNED(16, int, Q_fract_allpass)[2][50][3][2];
|
||||
static DECLARE_ALIGNED(16, int, phi_fract)[2][50][2];
|
||||
|
||||
static const int g0_Q8[] = {
|
||||
Q31(0.00746082949812f), Q31(0.02270420949825f), Q31(0.04546865930473f), Q31(0.07266113929591f),
|
||||
Q31(0.09885108575264f), Q31(0.11793710567217f), Q31(0.125f)
|
||||
};
|
||||
|
||||
static const int g0_Q12[] = {
|
||||
Q31(0.04081179924692f), Q31(0.03812810994926f), Q31(0.05144908135699f), Q31(0.06399831151592f),
|
||||
Q31(0.07428313801106f), Q31(0.08100347892914f), Q31(0.08333333333333f)
|
||||
};
|
||||
|
||||
static const int g1_Q8[] = {
|
||||
Q31(0.01565675600122f), Q31(0.03752716391991f), Q31(0.05417891378782f), Q31(0.08417044116767f),
|
||||
Q31(0.10307344158036f), Q31(0.12222452249753f), Q31(0.125f)
|
||||
};
|
||||
|
||||
static const int g2_Q4[] = {
|
||||
Q31(-0.05908211155639f), Q31(-0.04871498374946f), Q31(0.0f), Q31(0.07778723915851f),
|
||||
Q31( 0.16486303567403f), Q31( 0.23279856662996f), Q31(0.25f)
|
||||
};
|
||||
|
||||
static const int sintbl_4[4] = { 0, 1073741824, 0, -1073741824 };
|
||||
static const int costbl_4[4] = { 1073741824, 0, -1073741824, 0 };
|
||||
static const int sintbl_8[8] = { 0, 759250125, 1073741824, 759250125,
|
||||
0, -759250125, -1073741824, -759250125 };
|
||||
static const int costbl_8[8] = { 1073741824, 759250125, 0, -759250125,
|
||||
-1073741824, -759250125, 0, 759250125 };
|
||||
static const int sintbl_12[12] = { 0, 536870912, 929887697, 1073741824,
|
||||
929887697, 536870912, 0, -536870912,
|
||||
-929887697, -1073741824, -929887697, -536870912 };
|
||||
static const int costbl_12[12] = { 1073741824, 929887697, 536870912, 0,
|
||||
-536870912, -929887697, -1073741824, -929887697,
|
||||
-536870912, 0, 536870912, 929887697 };
|
||||
|
||||
static void make_filters_from_proto(int (*filter)[8][2], const int *proto, int bands)
|
||||
{
|
||||
|
||||
const int *sinptr, *cosptr;
|
||||
int s, c, sinhalf, coshalf;
|
||||
int q, n;
|
||||
|
||||
if (bands == 4) {
|
||||
sinptr = sintbl_4;
|
||||
cosptr = costbl_4;
|
||||
sinhalf = 759250125;
|
||||
coshalf = 759250125;
|
||||
} else if (bands == 8) {
|
||||
sinptr = sintbl_8;
|
||||
cosptr = costbl_8;
|
||||
sinhalf = 410903207;
|
||||
coshalf = 992008094;
|
||||
} else {
|
||||
sinptr = sintbl_12;
|
||||
cosptr = costbl_12;
|
||||
sinhalf = 277904834;
|
||||
coshalf = 1037154959;
|
||||
}
|
||||
|
||||
for (q = 0; q < bands; q++) {
|
||||
for (n = 0; n < 7; n++) {
|
||||
int theta = (q*(n-6) + (n>>1) - 3) % bands;
|
||||
|
||||
if (theta < 0)
|
||||
theta += bands;
|
||||
s = sinptr[theta];
|
||||
c = cosptr[theta];
|
||||
|
||||
if (n & 1) {
|
||||
theta = (int)(((int64_t)c * coshalf - (int64_t)s * sinhalf + 0x20000000) >> 30);
|
||||
s = (int)(((int64_t)s * coshalf + (int64_t)c * sinhalf + 0x20000000) >> 30);
|
||||
c = theta;
|
||||
}
|
||||
filter[q][n][0] = (int)(((int64_t)proto[n] * c + 0x20000000) >> 30);
|
||||
filter[q][n][1] = -(int)(((int64_t)proto[n] * s + 0x20000000) >> 30);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ps_tableinit(void)
|
||||
{
|
||||
static const int ipdopd_sin[] = { Q30(0), Q30(M_SQRT1_2), Q30(1), Q30( M_SQRT1_2), Q30( 0), Q30(-M_SQRT1_2), Q30(-1), Q30(-M_SQRT1_2) };
|
||||
static const int ipdopd_cos[] = { Q30(1), Q30(M_SQRT1_2), Q30(0), Q30(-M_SQRT1_2), Q30(-1), Q30(-M_SQRT1_2), Q30( 0), Q30( M_SQRT1_2) };
|
||||
int pd0, pd1, pd2;
|
||||
int idx;
|
||||
|
||||
static const int alpha_tab[] =
|
||||
{
|
||||
Q30(1.5146213770f/M_PI), Q30(1.5181334019f/M_PI), Q30(1.5234849453f/M_PI), Q30(1.5369486809f/M_PI), Q30(1.5500687361f/M_PI), Q30(1.5679757595f/M_PI),
|
||||
Q30(1.4455626011f/M_PI), Q30(1.4531552792f/M_PI), Q30(1.4648091793f/M_PI), Q30(1.4945238829f/M_PI), Q30(1.5239057541f/M_PI), Q30(1.5644006729f/M_PI),
|
||||
Q30(1.3738563061f/M_PI), Q30(1.3851221800f/M_PI), Q30(1.4026404619f/M_PI), Q30(1.4484288692f/M_PI), Q30(1.4949874878f/M_PI), Q30(1.5604078770f/M_PI),
|
||||
Q30(1.2645189762f/M_PI), Q30(1.2796478271f/M_PI), Q30(1.3038636446f/M_PI), Q30(1.3710125685f/M_PI), Q30(1.4443849325f/M_PI), Q30(1.5532352924f/M_PI),
|
||||
Q30(1.1507037878f/M_PI), Q30(1.1669205427f/M_PI), Q30(1.1938756704f/M_PI), Q30(1.2754167318f/M_PI), Q30(1.3761177063f/M_PI), Q30(1.5429240465f/M_PI),
|
||||
Q30(1.0079245567f/M_PI), Q30(1.0208238363f/M_PI), Q30(1.0433073044f/M_PI), Q30(1.1208510399f/M_PI), Q30(1.2424604893f/M_PI), Q30(1.5185726881f/M_PI),
|
||||
Q30(0.8995233774f/M_PI), Q30(0.9069069624f/M_PI), Q30(0.9201194048f/M_PI), Q30(0.9698365927f/M_PI), Q30(1.0671583414f/M_PI), Q30(1.4647934437f/M_PI),
|
||||
Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI),
|
||||
Q30(0.6712729335f/M_PI), Q30(0.6638893485f/M_PI), Q30(0.6506769061f/M_PI), Q30(0.6009597182f/M_PI), Q30(0.5036380291f/M_PI), Q30(0.1060028747f/M_PI),
|
||||
Q30(0.5628717542f/M_PI), Q30(0.5499725342f/M_PI), Q30(0.5274890065f/M_PI), Q30(0.4499453008f/M_PI), Q30(0.3283358216f/M_PI), Q30(0.0522236861f/M_PI),
|
||||
Q30(0.4200925827f/M_PI), Q30(0.4038758278f/M_PI), Q30(0.3769206405f/M_PI), Q30(0.2953795493f/M_PI), Q30(0.1946786791f/M_PI), Q30(0.0278722942f/M_PI),
|
||||
Q30(0.3062773645f/M_PI), Q30(0.2911485136f/M_PI), Q30(0.2669326365f/M_PI), Q30(0.1997837722f/M_PI), Q30(0.1264114529f/M_PI), Q30(0.0175609849f/M_PI),
|
||||
Q30(0.1969399750f/M_PI), Q30(0.1856741160f/M_PI), Q30(0.1681558639f/M_PI), Q30(0.1223674342f/M_PI), Q30(0.0758088827f/M_PI), Q30(0.0103884479f/M_PI),
|
||||
Q30(0.1252337098f/M_PI), Q30(0.1176410317f/M_PI), Q30(0.1059871912f/M_PI), Q30(0.0762724727f/M_PI), Q30(0.0468905345f/M_PI), Q30(0.0063956482f/M_PI),
|
||||
Q30(0.0561749674f/M_PI), Q30(0.0526629239f/M_PI), Q30(0.0473113805f/M_PI), Q30(0.0338476151f/M_PI), Q30(0.0207276177f/M_PI), Q30(0.0028205961f/M_PI),
|
||||
Q30(1.5676341057f/M_PI), Q30(1.5678333044f/M_PI), Q30(1.5681363344f/M_PI), Q30(1.5688960552f/M_PI), Q30(1.5696337223f/M_PI), Q30(1.5706381798f/M_PI),
|
||||
Q30(1.5651730299f/M_PI), Q30(1.5655272007f/M_PI), Q30(1.5660660267f/M_PI), Q30(1.5674170256f/M_PI), Q30(1.5687289238f/M_PI), Q30(1.5705151558f/M_PI),
|
||||
Q30(1.5607966185f/M_PI), Q30(1.5614265203f/M_PI), Q30(1.5623844862f/M_PI), Q30(1.5647867918f/M_PI), Q30(1.5671195984f/M_PI), Q30(1.5702962875f/M_PI),
|
||||
Q30(1.5530153513f/M_PI), Q30(1.5541347265f/M_PI), Q30(1.5558375120f/M_PI), Q30(1.5601085424f/M_PI), Q30(1.5642569065f/M_PI), Q30(1.5699069500f/M_PI),
|
||||
Q30(1.5391840935f/M_PI), Q30(1.5411708355f/M_PI), Q30(1.5441943407f/M_PI), Q30(1.5517836809f/M_PI), Q30(1.5591609478f/M_PI), Q30(1.5692136288f/M_PI),
|
||||
Q30(1.5146213770f/M_PI), Q30(1.5181334019f/M_PI), Q30(1.5234849453f/M_PI), Q30(1.5369486809f/M_PI), Q30(1.5500687361f/M_PI), Q30(1.5679757595f/M_PI),
|
||||
Q30(1.4915299416f/M_PI), Q30(1.4964480400f/M_PI), Q30(1.5039558411f/M_PI), Q30(1.5229074955f/M_PI), Q30(1.5414420366f/M_PI), Q30(1.5667995214f/M_PI),
|
||||
Q30(1.4590617418f/M_PI), Q30(1.4658898115f/M_PI), Q30(1.4763505459f/M_PI), Q30(1.5029321909f/M_PI), Q30(1.5291173458f/M_PI), Q30(1.5651149750f/M_PI),
|
||||
Q30(1.4136143923f/M_PI), Q30(1.4229322672f/M_PI), Q30(1.4373078346f/M_PI), Q30(1.4743183851f/M_PI), Q30(1.5113102198f/M_PI), Q30(1.5626684427f/M_PI),
|
||||
Q30(1.3505556583f/M_PI), Q30(1.3628427982f/M_PI), Q30(1.3820509911f/M_PI), Q30(1.4327841997f/M_PI), Q30(1.4850014448f/M_PI), Q30(1.5590143204f/M_PI),
|
||||
Q30(1.2645189762f/M_PI), Q30(1.2796478271f/M_PI), Q30(1.3038636446f/M_PI), Q30(1.3710125685f/M_PI), Q30(1.4443849325f/M_PI), Q30(1.5532352924f/M_PI),
|
||||
Q30(1.1919227839f/M_PI), Q30(1.2081253529f/M_PI), Q30(1.2346779108f/M_PI), Q30(1.3123005629f/M_PI), Q30(1.4034168720f/M_PI), Q30(1.5471596718f/M_PI),
|
||||
Q30(1.1061993837f/M_PI), Q30(1.1219338179f/M_PI), Q30(1.1484941244f/M_PI), Q30(1.2320860624f/M_PI), Q30(1.3421301842f/M_PI), Q30(1.5373806953f/M_PI),
|
||||
Q30(1.0079245567f/M_PI), Q30(1.0208238363f/M_PI), Q30(1.0433073044f/M_PI), Q30(1.1208510399f/M_PI), Q30(1.2424604893f/M_PI), Q30(1.5185726881f/M_PI),
|
||||
Q30(0.8995233774f/M_PI), Q30(0.9069069624f/M_PI), Q30(0.9201194048f/M_PI), Q30(0.9698365927f/M_PI), Q30(1.0671583414f/M_PI), Q30(1.4647934437f/M_PI),
|
||||
Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI),
|
||||
Q30(0.6712729335f/M_PI), Q30(0.6638893485f/M_PI), Q30(0.6506769061f/M_PI), Q30(0.6009597182f/M_PI), Q30(0.5036380291f/M_PI), Q30(0.1060028747f/M_PI),
|
||||
Q30(0.5628717542f/M_PI), Q30(0.5499725342f/M_PI), Q30(0.5274890065f/M_PI), Q30(0.4499453008f/M_PI), Q30(0.3283358216f/M_PI), Q30(0.0522236861f/M_PI),
|
||||
Q30(0.4645969570f/M_PI), Q30(0.4488625824f/M_PI), Q30(0.4223022461f/M_PI), Q30(0.3387103081f/M_PI), Q30(0.2286661267f/M_PI), Q30(0.0334156826f/M_PI),
|
||||
Q30(0.3788735867f/M_PI), Q30(0.3626709878f/M_PI), Q30(0.3361184299f/M_PI), Q30(0.2584958076f/M_PI), Q30(0.1673794836f/M_PI), Q30(0.0236366931f/M_PI),
|
||||
Q30(0.3062773645f/M_PI), Q30(0.2911485136f/M_PI), Q30(0.2669326365f/M_PI), Q30(0.1997837722f/M_PI), Q30(0.1264114529f/M_PI), Q30(0.0175609849f/M_PI),
|
||||
Q30(0.2202406377f/M_PI), Q30(0.2079535723f/M_PI), Q30(0.1887452900f/M_PI), Q30(0.1380121708f/M_PI), Q30(0.0857949182f/M_PI), Q30(0.0117820343f/M_PI),
|
||||
Q30(0.1571819335f/M_PI), Q30(0.1478640437f/M_PI), Q30(0.1334884763f/M_PI), Q30(0.0964778885f/M_PI), Q30(0.0594860613f/M_PI), Q30(0.0081279324f/M_PI),
|
||||
Q30(0.1117345318f/M_PI), Q30(0.1049065739f/M_PI), Q30(0.0944457650f/M_PI), Q30(0.0678641573f/M_PI), Q30(0.0416790098f/M_PI), Q30(0.0056813755f/M_PI),
|
||||
Q30(0.0792663917f/M_PI), Q30(0.0743482932f/M_PI), Q30(0.0668405443f/M_PI), Q30(0.0478888862f/M_PI), Q30(0.0293543357f/M_PI), Q30(0.0039967746f/M_PI),
|
||||
Q30(0.0561749674f/M_PI), Q30(0.0526629239f/M_PI), Q30(0.0473113805f/M_PI), Q30(0.0338476151f/M_PI), Q30(0.0207276177f/M_PI), Q30(0.0028205961f/M_PI),
|
||||
Q30(0.0316122435f/M_PI), Q30(0.0296254847f/M_PI), Q30(0.0266019460f/M_PI), Q30(0.0190126132f/M_PI), Q30(0.0116353342f/M_PI), Q30(0.0015827164f/M_PI),
|
||||
Q30(0.0177809205f/M_PI), Q30(0.0166615788f/M_PI), Q30(0.0149587989f/M_PI), Q30(0.0106877899f/M_PI), Q30(0.0065393616f/M_PI), Q30(0.0008894200f/M_PI),
|
||||
Q30(0.0099996664f/M_PI), Q30(0.0093698399f/M_PI), Q30(0.0084118480f/M_PI), Q30(0.0060095116f/M_PI), Q30(0.0036767013f/M_PI), Q30(0.0005000498f/M_PI),
|
||||
Q30(0.0056233541f/M_PI), Q30(0.0052691097f/M_PI), Q30(0.0047303112f/M_PI), Q30(0.0033792770f/M_PI), Q30(0.0020674451f/M_PI), Q30(0.0002811795f/M_PI),
|
||||
Q30(0.0031622672f/M_PI), Q30(0.0029630491f/M_PI), Q30(0.0026600463f/M_PI), Q30(0.0019002859f/M_PI), Q30(0.0011625893f/M_PI), Q30(0.0001581155f/M_PI)
|
||||
};
|
||||
|
||||
static const int gamma_tab[] =
|
||||
{
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0195873566f/M_PI), Q30(0.0303316917f/M_PI), Q30(0.0448668823f/M_PI), Q30(0.0522258915f/M_PI), Q30(0.0561044961f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0433459543f/M_PI), Q30(0.0672172382f/M_PI), Q30(0.0997167900f/M_PI), Q30(0.1162951663f/M_PI), Q30(0.1250736862f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0672341362f/M_PI), Q30(0.1045235619f/M_PI), Q30(0.1558904350f/M_PI), Q30(0.1824723780f/M_PI), Q30(0.1966800541f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1011129096f/M_PI), Q30(0.1580764502f/M_PI), Q30(0.2387557179f/M_PI), Q30(0.2820728719f/M_PI), Q30(0.3058380187f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1315985769f/M_PI), Q30(0.2072522491f/M_PI), Q30(0.3188187480f/M_PI), Q30(0.3825501204f/M_PI), Q30(0.4193951190f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1603866369f/M_PI), Q30(0.2549437582f/M_PI), Q30(0.4029446840f/M_PI), Q30(0.4980689585f/M_PI), Q30(0.5615641475f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1736015975f/M_PI), Q30(0.2773745656f/M_PI), Q30(0.4461984038f/M_PI), Q30(0.5666890144f/M_PI), Q30(0.6686112881f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1784276664f/M_PI), Q30(0.2856673002f/M_PI), Q30(0.4630723596f/M_PI), Q30(0.5971632004f/M_PI), Q30(0.7603877187f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1736015975f/M_PI), Q30(0.2773745656f/M_PI), Q30(0.4461984038f/M_PI), Q30(0.5666890144f/M_PI), Q30(0.6686112881f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1603866369f/M_PI), Q30(0.2549437582f/M_PI), Q30(0.4029446840f/M_PI), Q30(0.4980689585f/M_PI), Q30(0.5615641475f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1315985769f/M_PI), Q30(0.2072522491f/M_PI), Q30(0.3188187480f/M_PI), Q30(0.3825501204f/M_PI), Q30(0.4193951190f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1011129096f/M_PI), Q30(0.1580764502f/M_PI), Q30(0.2387557179f/M_PI), Q30(0.2820728719f/M_PI), Q30(0.3058380187f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0672341362f/M_PI), Q30(0.1045235619f/M_PI), Q30(0.1558904350f/M_PI), Q30(0.1824723780f/M_PI), Q30(0.1966800541f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0433459543f/M_PI), Q30(0.0672172382f/M_PI), Q30(0.0997167900f/M_PI), Q30(0.1162951663f/M_PI), Q30(0.1250736862f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0195873566f/M_PI), Q30(0.0303316917f/M_PI), Q30(0.0448668823f/M_PI), Q30(0.0522258915f/M_PI), Q30(0.0561044961f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0011053939f/M_PI), Q30(0.0017089852f/M_PI), Q30(0.0025254129f/M_PI), Q30(0.0029398468f/M_PI), Q30(0.0031597170f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0019607407f/M_PI), Q30(0.0030395309f/M_PI), Q30(0.0044951206f/M_PI), Q30(0.0052305623f/M_PI), Q30(0.0056152637f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0034913034f/M_PI), Q30(0.0054070661f/M_PI), Q30(0.0079917293f/M_PI), Q30(0.0092999367f/M_PI), Q30(0.0099875759f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0062100487f/M_PI), Q30(0.0096135242f/M_PI), Q30(0.0142110568f/M_PI), Q30(0.0165348612f/M_PI), Q30(0.0177587029f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0110366223f/M_PI), Q30(0.0170863140f/M_PI), Q30(0.0252620988f/M_PI), Q30(0.0293955617f/M_PI), Q30(0.0315726399f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0195873566f/M_PI), Q30(0.0303316917f/M_PI), Q30(0.0448668823f/M_PI), Q30(0.0522258915f/M_PI), Q30(0.0561044961f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0275881495f/M_PI), Q30(0.0427365713f/M_PI), Q30(0.0632618815f/M_PI), Q30(0.0736731067f/M_PI), Q30(0.0791663304f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0387469754f/M_PI), Q30(0.0600636788f/M_PI), Q30(0.0890387669f/M_PI), Q30(0.1037906483f/M_PI), Q30(0.1115923747f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0541138873f/M_PI), Q30(0.0839984417f/M_PI), Q30(0.1248718798f/M_PI), Q30(0.1458375156f/M_PI), Q30(0.1569785923f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0747506917f/M_PI), Q30(0.1163287833f/M_PI), Q30(0.1738867164f/M_PI), Q30(0.2038587779f/M_PI), Q30(0.2199459076f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1011129096f/M_PI), Q30(0.1580764502f/M_PI), Q30(0.2387557179f/M_PI), Q30(0.2820728719f/M_PI), Q30(0.3058380187f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1212290376f/M_PI), Q30(0.1903949380f/M_PI), Q30(0.2907958031f/M_PI), Q30(0.3466993868f/M_PI), Q30(0.3782821596f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1418247074f/M_PI), Q30(0.2240308374f/M_PI), Q30(0.3474813402f/M_PI), Q30(0.4202919006f/M_PI), Q30(0.4637607038f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1603866369f/M_PI), Q30(0.2549437582f/M_PI), Q30(0.4029446840f/M_PI), Q30(0.4980689585f/M_PI), Q30(0.5615641475f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1736015975f/M_PI), Q30(0.2773745656f/M_PI), Q30(0.4461984038f/M_PI), Q30(0.5666890144f/M_PI), Q30(0.6686112881f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1784276664f/M_PI), Q30(0.2856673002f/M_PI), Q30(0.4630723596f/M_PI), Q30(0.5971632004f/M_PI), Q30(0.7603877187f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1736015975f/M_PI), Q30(0.2773745656f/M_PI), Q30(0.4461984038f/M_PI), Q30(0.5666890144f/M_PI), Q30(0.6686112881f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1603866369f/M_PI), Q30(0.2549437582f/M_PI), Q30(0.4029446840f/M_PI), Q30(0.4980689585f/M_PI), Q30(0.5615641475f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1418247074f/M_PI), Q30(0.2240308374f/M_PI), Q30(0.3474813402f/M_PI), Q30(0.4202919006f/M_PI), Q30(0.4637607038f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1212290376f/M_PI), Q30(0.1903949380f/M_PI), Q30(0.2907958031f/M_PI), Q30(0.3466993868f/M_PI), Q30(0.3782821596f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.1011129096f/M_PI), Q30(0.1580764502f/M_PI), Q30(0.2387557179f/M_PI), Q30(0.2820728719f/M_PI), Q30(0.3058380187f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0747506917f/M_PI), Q30(0.1163287833f/M_PI), Q30(0.1738867164f/M_PI), Q30(0.2038587779f/M_PI), Q30(0.2199459076f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0541138873f/M_PI), Q30(0.0839984417f/M_PI), Q30(0.1248718798f/M_PI), Q30(0.1458375156f/M_PI), Q30(0.1569785923f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0387469754f/M_PI), Q30(0.0600636788f/M_PI), Q30(0.0890387669f/M_PI), Q30(0.1037906483f/M_PI), Q30(0.1115923747f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0275881495f/M_PI), Q30(0.0427365713f/M_PI), Q30(0.0632618815f/M_PI), Q30(0.0736731067f/M_PI), Q30(0.0791663304f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0195873566f/M_PI), Q30(0.0303316917f/M_PI), Q30(0.0448668823f/M_PI), Q30(0.0522258915f/M_PI), Q30(0.0561044961f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0110366223f/M_PI), Q30(0.0170863140f/M_PI), Q30(0.0252620988f/M_PI), Q30(0.0293955617f/M_PI), Q30(0.0315726399f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0062100487f/M_PI), Q30(0.0096135242f/M_PI), Q30(0.0142110568f/M_PI), Q30(0.0165348612f/M_PI), Q30(0.0177587029f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0034913034f/M_PI), Q30(0.0054070661f/M_PI), Q30(0.0079917293f/M_PI), Q30(0.0092999367f/M_PI), Q30(0.0099875759f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0019607407f/M_PI), Q30(0.0030395309f/M_PI), Q30(0.0044951206f/M_PI), Q30(0.0052305623f/M_PI), Q30(0.0056152637f/M_PI),
|
||||
Q30(0.0000000000f/M_PI), Q30(0.0011053939f/M_PI), Q30(0.0017089852f/M_PI), Q30(0.0025254129f/M_PI), Q30(0.0029398468f/M_PI), Q30(0.0031597170f/M_PI)
|
||||
};
|
||||
|
||||
static const int iid_par_dequant_c1[] = {
|
||||
//iid_par_dequant_default
|
||||
Q30(1.41198278375959f), Q30(1.40313815268360f), Q30(1.38687670404960f), Q30(1.34839972492648f),
|
||||
Q30(1.29124937110028f), Q30(1.19603741667993f), Q30(1.10737240362323f), Q30(1),
|
||||
Q30(0.87961716655242f), Q30(0.75464859232732f), Q30(0.57677990744575f), Q30(0.42640143271122f),
|
||||
Q30(0.27671828230984f), Q30(0.17664462766713f), Q30(0.07940162697653f),
|
||||
//iid_par_dequant_fine
|
||||
Q30(1.41420649135832f), Q30(1.41419120222364f), Q30(1.41414285699784f), Q30(1.41399000859438f),
|
||||
Q30(1.41350698548044f), Q30(1.41198278375959f), Q30(1.40977302262355f), Q30(1.40539479488545f),
|
||||
Q30(1.39677960498402f), Q30(1.38005309967827f), Q30(1.34839972492648f), Q30(1.31392017367631f),
|
||||
Q30(1.26431008149654f), Q30(1.19603741667993f), Q30(1.10737240362323f), Q30(1),
|
||||
Q30(0.87961716655242f), Q30(0.75464859232732f), Q30(0.63365607219232f), Q30(0.52308104267543f),
|
||||
Q30(0.42640143271122f), Q30(0.30895540465965f), Q30(0.22137464873077f), Q30(0.15768788954414f),
|
||||
Q30(0.11198225164225f), Q30(0.07940162697653f), Q30(0.04469901562677f), Q30(0.02514469318284f),
|
||||
Q30(0.01414142856998f), Q30(0.00795258154731f), Q30(0.00447211359449f),
|
||||
};
|
||||
|
||||
static const int acos_icc_invq[] = {
|
||||
Q31(0), Q31(0.178427635f/M_PI), Q31(0.28566733f/M_PI), Q31(0.46307236f/M_PI), Q31(0.59716315f/M_PI), Q31(0.78539816f/M_PI), Q31(1.10030855f/M_PI), Q31(1.57079633f/M_PI)
|
||||
};
|
||||
int iid, icc;
|
||||
|
||||
int k, m;
|
||||
static const int8_t f_center_20[] = {
|
||||
-3, -1, 1, 3, 5, 7, 10, 14, 18, 22,
|
||||
};
|
||||
static const int32_t f_center_34[] = {
|
||||
Q31( 2/768.0),Q31( 6/768.0),Q31(10/768.0),Q31(14/768.0),Q31( 18/768.0),Q31( 22/768.0),Q31( 26/768.0),Q31(30/768.0),
|
||||
Q31( 34/768.0),Q31(-10/768.0),Q31(-6/768.0),Q31(-2/768.0),Q31( 51/768.0),Q31( 57/768.0),Q31( 15/768.0),Q31(21/768.0),
|
||||
Q31( 27/768.0),Q31( 33/768.0),Q31(39/768.0),Q31(45/768.0),Q31( 54/768.0),Q31( 66/768.0),Q31( 78/768.0),Q31(42/768.0),
|
||||
Q31(102/768.0),Q31( 66/768.0),Q31(78/768.0),Q31(90/768.0),Q31(102/768.0),Q31(114/768.0),Q31(126/768.0),Q31(90/768.0)
|
||||
};
|
||||
static const int fractional_delay_links[] = { Q31(0.43f), Q31(0.75f), Q31(0.347f) };
|
||||
const int fractional_delay_gain = Q31(0.39f);
|
||||
|
||||
for (pd0 = 0; pd0 < 8; pd0++) {
|
||||
int pd0_re = (ipdopd_cos[pd0]+2)>>2;
|
||||
int pd0_im = (ipdopd_sin[pd0]+2)>>2;
|
||||
for (pd1 = 0; pd1 < 8; pd1++) {
|
||||
int pd1_re = ipdopd_cos[pd1] >> 1;
|
||||
int pd1_im = ipdopd_sin[pd1] >> 1;
|
||||
for (pd2 = 0; pd2 < 8; pd2++) {
|
||||
int shift, round;
|
||||
int pd2_re = ipdopd_cos[pd2];
|
||||
int pd2_im = ipdopd_sin[pd2];
|
||||
int re_smooth = pd0_re + pd1_re + pd2_re;
|
||||
int im_smooth = pd0_im + pd1_im + pd2_im;
|
||||
|
||||
SoftFloat pd_mag = av_int2sf(((ipdopd_cos[(pd0-pd1)&7]+8)>>4) + ((ipdopd_cos[(pd0-pd2)&7]+4)>>3) +
|
||||
((ipdopd_cos[(pd1-pd2)&7]+2)>>2) + 0x15000000, 28);
|
||||
pd_mag = av_div_sf(FLOAT_1, av_sqrt_sf(pd_mag));
|
||||
shift = 30 - pd_mag.exp;
|
||||
round = 1 << (shift-1);
|
||||
pd_re_smooth[pd0*64+pd1*8+pd2] = (int)(((int64_t)re_smooth * pd_mag.mant + round) >> shift);
|
||||
pd_im_smooth[pd0*64+pd1*8+pd2] = (int)(((int64_t)im_smooth * pd_mag.mant + round) >> shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
for (iid = 0; iid < 46; iid++) {
|
||||
int c1, c2;
|
||||
|
||||
c1 = iid_par_dequant_c1[iid];
|
||||
if (iid < 15)
|
||||
c2 = iid_par_dequant_c1[14-iid];
|
||||
else
|
||||
c2 = iid_par_dequant_c1[60-iid];
|
||||
|
||||
for (icc = 0; icc < 8; icc++) {
|
||||
/*if (PS_BASELINE || ps->icc_mode < 3)*/{
|
||||
int alpha, beta;
|
||||
int ca, sa, cb, sb;
|
||||
|
||||
alpha = acos_icc_invq[icc];
|
||||
beta = (int)(((int64_t)alpha * 1518500250 + 0x40000000) >> 31);
|
||||
alpha >>= 1;
|
||||
beta = (int)(((int64_t)beta * (c1 - c2) + 0x40000000) >> 31);
|
||||
av_sincos_sf(beta + alpha, &sa, &ca);
|
||||
av_sincos_sf(beta - alpha, &sb, &cb);
|
||||
|
||||
HA[iid][icc][0] = (int)(((int64_t)c2 * ca + 0x20000000) >> 30);
|
||||
HA[iid][icc][1] = (int)(((int64_t)c1 * cb + 0x20000000) >> 30);
|
||||
HA[iid][icc][2] = (int)(((int64_t)c2 * sa + 0x20000000) >> 30);
|
||||
HA[iid][icc][3] = (int)(((int64_t)c1 * sb + 0x20000000) >> 30);
|
||||
} /* else */ {
|
||||
int alpha_int, gamma_int;
|
||||
int alpha_c_int, alpha_s_int, gamma_c_int, gamma_s_int;
|
||||
|
||||
alpha_int = alpha_tab[idx];
|
||||
gamma_int = gamma_tab[idx];
|
||||
|
||||
av_sincos_sf(alpha_int, &alpha_s_int, &alpha_c_int);
|
||||
av_sincos_sf(gamma_int, &gamma_s_int, &gamma_c_int);
|
||||
|
||||
alpha_c_int = (int)(((int64_t)alpha_c_int * 1518500250 + 0x20000000) >> 30);
|
||||
alpha_s_int = (int)(((int64_t)alpha_s_int * 1518500250 + 0x20000000) >> 30);
|
||||
|
||||
HB[iid][icc][0] = (int)(((int64_t)alpha_c_int * gamma_c_int + 0x20000000) >> 30);
|
||||
HB[iid][icc][1] = (int)(((int64_t)alpha_s_int * gamma_c_int + 0x20000000) >> 30);
|
||||
HB[iid][icc][2] = -(int)(((int64_t)alpha_s_int * gamma_s_int + 0x20000000) >> 30);
|
||||
HB[iid][icc][3] = (int)(((int64_t)alpha_c_int * gamma_s_int + 0x20000000) >> 30);
|
||||
}
|
||||
|
||||
if (icc < 5 || icc > 6)
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
for (k = 0; k < NR_ALLPASS_BANDS20; k++) {
|
||||
int theta;
|
||||
int64_t f_center;
|
||||
int c, s;
|
||||
|
||||
if (k < FF_ARRAY_ELEMS(f_center_20))
|
||||
f_center = f_center_20[k];
|
||||
else
|
||||
f_center = (k << 3) - 52;
|
||||
|
||||
for (m = 0; m < PS_AP_LINKS; m++) {
|
||||
theta = (int)(((int64_t)fractional_delay_links[m] * f_center + 8) >> 4);
|
||||
av_sincos_sf(-theta, &s, &c);
|
||||
Q_fract_allpass[0][k][m][0] = c;
|
||||
Q_fract_allpass[0][k][m][1] = s;
|
||||
}
|
||||
|
||||
theta = (int)(((int64_t)fractional_delay_gain * f_center + 8) >> 4);
|
||||
av_sincos_sf(-theta, &s, &c);
|
||||
phi_fract[0][k][0] = c;
|
||||
phi_fract[0][k][1] = s;
|
||||
}
|
||||
|
||||
for (k = 0; k < NR_ALLPASS_BANDS34; k++) {
|
||||
int theta, f_center;
|
||||
int c, s;
|
||||
|
||||
if (k < FF_ARRAY_ELEMS(f_center_34))
|
||||
f_center = f_center_34[k];
|
||||
else
|
||||
f_center = ((int64_t)k << 26) - (53 << 25);
|
||||
|
||||
for (m = 0; m < PS_AP_LINKS; m++) {
|
||||
theta = (int)(((int64_t)fractional_delay_links[m] * f_center + 0x10000000) >> 27);
|
||||
av_sincos_sf(-theta, &s, &c);
|
||||
Q_fract_allpass[1][k][m][0] = c;
|
||||
Q_fract_allpass[1][k][m][1] = s;
|
||||
}
|
||||
|
||||
theta = (int)(((int64_t)fractional_delay_gain * f_center + 0x10000000) >> 27);
|
||||
av_sincos_sf(-theta, &s, &c);
|
||||
phi_fract[1][k][0] = c;
|
||||
phi_fract[1][k][1] = s;
|
||||
}
|
||||
|
||||
make_filters_from_proto(f20_0_8, g0_Q8, 8);
|
||||
make_filters_from_proto(f34_0_12, g0_Q12, 12);
|
||||
make_filters_from_proto(f34_1_8, g1_Q8, 8);
|
||||
make_filters_from_proto(f34_2_4, g2_Q4, 4);
|
||||
}
|
||||
#endif /* CONFIG_HARDCODED_TABLES */
|
||||
|
||||
#endif /* AACPS_FIXED_TABLEGEN_H */
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* MPEG-4 Parametric Stereo decoding functions
|
||||
* Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define USE_FIXED 0
|
||||
|
||||
#include "aacps.c"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user