mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-08 07:49:59 +01:00
Compare commits
98 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -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
|
||||
|
||||
170
Changelog
170
Changelog
@@ -1,90 +1,94 @@
|
||||
Entries are sorted chronologically from oldest to youngest within each release,
|
||||
releases are sorted from youngest to oldest.
|
||||
|
||||
version 2.8.1:
|
||||
- swscale: fix ticket #4881
|
||||
- doc: fix spelling errors
|
||||
- hls: only seek if there is an offset
|
||||
- asfdec: add more checks for size left in asf packet buffer
|
||||
- asfdec: alloc enough space for storing name in asf_read_metadata_obj
|
||||
- avcodec/pngdec: Check blend_op.
|
||||
- h264_mp4toannexb: fix pps offfset fault when there are more than one sps in avcc
|
||||
- avcodec/h264_mp4toannexb_bsf: Use av_freep() to free spspps_buf
|
||||
- avformat/avidec: Workaround broken initial frame
|
||||
- avformat/hls: fix some cases of HLS streams which require cookies
|
||||
- avcodec/pngdec: reset has_trns after every decode_frame_png()
|
||||
- lavf/img2dec: Fix memory leak
|
||||
- avcodec/mp3: fix skipping zeros
|
||||
- avformat/srtdec: make sure we probe a number
|
||||
- configure: check for ID3D11VideoContext
|
||||
- avformat/vobsub: compare correct packet stream IDs
|
||||
- avformat/srtdec: more lenient first line probing
|
||||
- avformat/srtdec: fix number check for the first character
|
||||
- avcodec/mips: build fix for MSA 64bit
|
||||
- avcodec/mips: build fix for MSA
|
||||
- avformat/httpauth: Add space after commas in HTTP/RTSP auth header
|
||||
- libavformat/hlsenc: Use of uninitialized memory unlinking old files
|
||||
- avcodec/x86/sbrdsp: Fix using uninitialized upper 32bit of noise
|
||||
- avcodec/ffv1dec: Fix off by 1 error in quant_table_count check
|
||||
- avcodec/ffv1dec: Explicitly check read_quant_table() return value
|
||||
- dnxhddata: correct weight tables
|
||||
- dnxhddec: decode and use interlace mb flag
|
||||
- swscale: fix ticket #4877
|
||||
- avcodec/rangecoder: Check e
|
||||
- avcodec/ffv1: seperate slice_count from max_slice_count
|
||||
- swscale: fix ticket 4850
|
||||
- cmdutils: Filter dst/srcw/h
|
||||
- avutil/log: fix zero length gnu_printf format string warning
|
||||
- lavf/webvttenc: Require webvtt file to contain exactly one WebVTT stream.
|
||||
- swscale/swscale: Fix "unused variable" warning
|
||||
- avcodec/mjpegdec: Fix decoding RGBA RCT LJPEG
|
||||
- MAINTAINERS: add 2.8, drop 2.2
|
||||
- doc: mention libavcodec can decode Opus natively
|
||||
- hevc: properly handle no_rasl_output_flag when removing pictures from the DPB
|
||||
- avfilter/af_ladspa: process all channels for nb_handles > 1
|
||||
- configure: add libsoxr to swresample's pkgconfig
|
||||
- lavc: Fix compilation with --disable-everything --enable-parser=mpeg4video.
|
||||
version <next>:
|
||||
|
||||
version 2.8:
|
||||
- colorkey video filter
|
||||
- BFSTM/BCSTM demuxer
|
||||
- little-endian ADPCM_THP decoder
|
||||
- Hap decoder and encoder
|
||||
- DirectDraw Surface image/texture decoder
|
||||
- ssim filter
|
||||
- optional new ASF demuxer
|
||||
- showvolume filter
|
||||
- Many improvements to the JPEG 2000 decoder
|
||||
- Go2Meeting decoding support
|
||||
- adrawgraph audio and drawgraph video filter
|
||||
- removegrain video filter
|
||||
- Intel QSV-accelerated MPEG-2 video and HEVC encoding
|
||||
- Intel QSV-accelerated MPEG-2 video and HEVC decoding
|
||||
- Intel QSV-accelerated VC-1 video decoding
|
||||
- libkvazaar HEVC encoder
|
||||
- erosion, dilation, deflate and inflate video filters
|
||||
- Dynamic Audio Normalizer as dynaudnorm filter
|
||||
- Reverse video and areverse audio filter
|
||||
- Random filter
|
||||
- deband filter
|
||||
- AAC fixed-point decoding
|
||||
- sidechaincompress audio filter
|
||||
- bitstream filter for converting HEVC from MP4 to Annex B
|
||||
- acrossfade audio filter
|
||||
- allyuv and allrgb video sources
|
||||
- atadenoise video filter
|
||||
- OS X VideoToolbox support
|
||||
- aphasemeter filter
|
||||
- showfreqs filter
|
||||
- vectorscope filter
|
||||
- waveform filter
|
||||
- hstack and vstack filter
|
||||
- Support DNx100 (1440x1080@8)
|
||||
- VAAPI hevc hwaccel
|
||||
- VDPAU hevc hwaccel
|
||||
- framerate filter
|
||||
- Switched default encoders for webm to VP9 and Opus
|
||||
- Removed experimental flag from the JPEG 2000 encoder
|
||||
version 2.7.2:
|
||||
- imc: use correct position for flcoeffs2 calculation
|
||||
- hevc: check slice address length
|
||||
- snow: remove an obsolete av_assert2
|
||||
- webp: fix infinite loop in webp_decode_frame
|
||||
- wavpack: limit extra_bits to 32 and use get_bits_long
|
||||
- ffmpeg: only count got_output/errors in decode_error_stat
|
||||
- ffmpeg: exit_on_error if decoding a packet failed
|
||||
- pthread_frame: forward error codes when flushing
|
||||
- huffyuvdec: validate image size
|
||||
- wavpack: use get_bits_long to read up to 32 bits
|
||||
- nutdec: check maxpos in read_sm_data before returning success
|
||||
- s302m: fix arithmetic exception
|
||||
- vc1dec: use get_bits_long and limit the read bits to 32
|
||||
- mpegaudiodec: copy AVFloatDSPContext from first context to all contexts
|
||||
- avcodec/vp8: Check buffer size in vp8_decode_frame_header()
|
||||
- avcodec/vp8: Fix null pointer dereference in ff_vp8_decode_free()
|
||||
- avcodec/diracdec: Check for hpel_base allocation failure
|
||||
- avcodec/rv34: Clear pointers in ff_rv34_decode_init_thread_copy()
|
||||
- avfilter/af_aresample: Check ff_all_* for allocation failures
|
||||
- avcodec/pthread_frame: clear priv_data, avoid stale pointer in error case
|
||||
- swscale/utils: Clear pix buffers
|
||||
- avutil/fifo: Fix the case where func() returns less bytes than requested in av_fifo_generic_write()
|
||||
- ffmpeg: Fix cleanup after failed allocation of output_files
|
||||
- avformat/mov: Fix deallocation when MOVStreamContext failed to allocate
|
||||
- ffmpeg: Fix crash with ost->last_frame allocation failure
|
||||
- ffmpeg: Fix cleanup with ost = NULL
|
||||
- avcodec/pthread_frame: check avctx on deallocation
|
||||
- avcodec/sanm: Reset sizes in destroy_buffers()
|
||||
- avcodec/alac: Clear pointers in allocate_buffers()
|
||||
- bytestream2: set the reader to the end when reading more than available
|
||||
- avcodec/utils: use a minimum 32pixel width in avcodec_align_dimensions2() for H.264
|
||||
- avcodec/mpegvideo: Clear pointers in ff_mpv_common_init()
|
||||
- oggparsedirac: check return value of init_get_bits
|
||||
- wmalosslessdec: reset frame->nb_samples on packet loss
|
||||
- wmalosslessdec: avoid reading 0 bits with get_bits
|
||||
- Put a space between string literals and macros.
|
||||
- avcodec/rawenc: Use ff_alloc_packet() instead of ff_alloc_packet2()
|
||||
- avcodec/aacsbr: check that the element type matches before applying SBR
|
||||
- avcodec/h264_slice: Use w/h from the AVFrame instead of mb_w/h
|
||||
- vp9/update_prob: prevent out of bounds table read
|
||||
- avfilter/vf_transpose: Fix rounding error
|
||||
- avcodec/h264_refs: discard mismatching references
|
||||
- avcodec/mjpegdec: Fix small picture upscale
|
||||
- avcodec/pngdec: Check values before updating context in decode_fctl_chunk()
|
||||
- avcodec/pngdec: Copy IHDR & plte state from last thread
|
||||
- avcodec/pngdec: Require a IHDR chunk before fctl
|
||||
- avcodec/pngdec: Only allow one IHDR chunk
|
||||
- wmavoice: limit wmavoice_decode_packet return value to packet size
|
||||
- swscale/swscale_unscaled: Fix rounding difference with RGBA output between little and big endian
|
||||
- ffmpeg: Do not use the data/size of a bitstream filter after failure
|
||||
- swscale/x86/rgb2rgb_template: fix signedness of v in shuffle_bytes_2103_{mmx,mmxext}
|
||||
- vda: unlock the pixel buffer base address.
|
||||
- swscale/rgb2rgb_template: Fix signedness of v in shuffle_bytes_2103_c()
|
||||
- swscale/rgb2rgb_template: Implement shuffle_bytes_0321_c and fix shuffle_bytes_2103_c on BE
|
||||
- swscale/rgb2rgb_template: Disable shuffle_bytes_2103_c on big endian
|
||||
- swr: Remember previously set int_sample_format from user
|
||||
- swresample: soxr implementation for swr_get_out_samples()
|
||||
- avformat/swfdec: Do not error out on pixel format changes
|
||||
- ffmpeg_opt: Fix forcing fourccs
|
||||
- configure: Check for x265_api_get
|
||||
- swscale/x86/rgb2rgb_template: don't call emms on sse2/avx functions
|
||||
- swscale/x86/rgb2rgb_template: add missing xmm clobbers
|
||||
- library.mak: Workaround SDL redefining main and breaking fate tests on mingw
|
||||
- vaapi_h264: fix RefPicList[] field flags.
|
||||
|
||||
version 2.7.1:
|
||||
- postproc: fix unaligned access
|
||||
- avformat: clarify what package needs to be compiled with SSL support
|
||||
- avcodec/libx264: Avoid reconfig on equivalent aspect ratios
|
||||
- avcodec/flacenc: Fix Invalid Rice order
|
||||
- tls_gnutls: fix hang on disconnection
|
||||
- avcodec/hevc_ps: Only discard overread VPS if a previous is available
|
||||
- ffmpeg: Free last_frame instead of just unref
|
||||
- avcodec/ffv1enc: fix bps for >8bit yuv when not explicitly set
|
||||
- avio: fix potential crashes when combining ffio_ensure_seekback + crc
|
||||
- examples/demuxing_decoding: use properties from frame instead of video_dec_ctx
|
||||
- h264: er: Copy from the previous reference only if compatible
|
||||
- doc: fix spelling errors
|
||||
- configure: only disable VSX for !ppc64el
|
||||
- ffmpeg_opt: Check for localtime() failure
|
||||
- avformat/singlejpeg: fix standalone compilation
|
||||
- configure: Disable VSX on unspecified / generic CPUs
|
||||
- avformat: Fix bug in parse_rps for HEVC.
|
||||
- takdec: ensure chan2 is a valid channel index
|
||||
- avcodec/h264_slice: Use AVFrame dimensions for grayscale handling
|
||||
|
||||
|
||||
version 2.7:
|
||||
|
||||
@@ -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`
|
||||
|
||||
32
MAINTAINERS
32
MAINTAINERS
@@ -14,6 +14,7 @@ patches and related discussions.
|
||||
Project Leader
|
||||
==============
|
||||
|
||||
Michael Niedermayer
|
||||
final design decisions
|
||||
|
||||
|
||||
@@ -42,7 +43,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
|
||||
@@ -137,7 +138,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
|
||||
@@ -171,7 +171,6 @@ Codecs:
|
||||
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 +200,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 +237,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 +298,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 +334,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 +344,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 +362,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 +384,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
|
||||
@@ -432,7 +415,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
|
||||
@@ -518,7 +500,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,7 +535,7 @@ 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
|
||||
@@ -564,11 +545,11 @@ x86 Michael Niedermayer
|
||||
Releases
|
||||
========
|
||||
|
||||
2.8 Michael Niedermayer
|
||||
2.7 Michael Niedermayer
|
||||
2.6 Michael Niedermayer
|
||||
2.5 Michael Niedermayer
|
||||
2.4 Michael Niedermayer
|
||||
2.2 Michael Niedermayer
|
||||
|
||||
If you want to maintain an older release, please contact us
|
||||
|
||||
@@ -599,7 +580,6 @@ Michael Niedermayer 9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB
|
||||
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
|
||||
|
||||
10
Makefile
10
Makefile
@@ -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)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
┌────────────────────────────────────────┐
|
||||
│ 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.
|
||||
|
||||
2
arch.mak
2
arch.mak
@@ -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)
|
||||
|
||||
135
cmdutils.c
135
cmdutils.c
@@ -63,7 +63,7 @@
|
||||
|
||||
static int init_report(const char *env);
|
||||
|
||||
AVDictionary *sws_dict;
|
||||
struct SwsContext *sws_opts;
|
||||
AVDictionary *swr_opts;
|
||||
AVDictionary *format_opts, *codec_opts, *resample_opts;
|
||||
|
||||
@@ -73,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);
|
||||
@@ -522,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;
|
||||
@@ -558,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
|
||||
@@ -649,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;
|
||||
@@ -658,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();
|
||||
|
||||
@@ -714,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);
|
||||
@@ -1322,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");
|
||||
@@ -1501,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))
|
||||
@@ -1579,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)) ||
|
||||
@@ -1873,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)
|
||||
@@ -2046,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;
|
||||
}
|
||||
|
||||
16
cmdutils.h
16
cmdutils.h
@@ -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;
|
||||
@@ -277,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;
|
||||
|
||||
@@ -529,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.
|
||||
*
|
||||
|
||||
@@ -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 $?
|
||||
346
configure
vendored
346
configure
vendored
@@ -155,7 +155,6 @@ Hardware accelerators:
|
||||
--disable-vaapi disable VAAPI code [autodetect]
|
||||
--disable-vda disable VDA code [autodetect]
|
||||
--disable-vdpau disable VDPAU code [autodetect]
|
||||
--enable-videotoolbox enable VideoToolbox code [autodetect]
|
||||
|
||||
Individual component options:
|
||||
--disable-everything disable all components listed below
|
||||
@@ -223,7 +222,6 @@ External library support:
|
||||
--enable-libgsm enable GSM de/encoding via libgsm [no]
|
||||
--enable-libiec61883 enable iec61883 via libiec61883 [no]
|
||||
--enable-libilbc enable iLBC de/encoding via libilbc [no]
|
||||
--enable-libkvazaar enable HEVC encoding via libkvazaar [no]
|
||||
--enable-libmfx enable HW acceleration through libmfx
|
||||
--enable-libmodplug enable ModPlug via libmodplug [no]
|
||||
--enable-libmp3lame enable MP3 encoding via libmp3lame [no]
|
||||
@@ -241,7 +239,6 @@ External library support:
|
||||
--enable-libschroedinger enable Dirac de/encoding via libschroedinger [no]
|
||||
--enable-libshine enable fixed-point MP3 encoding via libshine [no]
|
||||
--enable-libsmbclient enable Samba protocol via libsmbclient [no]
|
||||
--enable-libsnappy enable Snappy compression, needed for hap encoding [no]
|
||||
--enable-libsoxr enable Include libsoxr resampling [no]
|
||||
--enable-libspeex enable Speex de/encoding via libspeex [no]
|
||||
--enable-libssh enable SFTP protocol via libssh [no]
|
||||
@@ -324,7 +321,6 @@ Toolchain options:
|
||||
--extra-cxxflags=ECFLAGS add ECFLAGS to CXXFLAGS [$CXXFLAGS]
|
||||
--extra-ldflags=ELDFLAGS add ELDFLAGS to LDFLAGS [$LDFLAGS]
|
||||
--extra-ldexeflags=ELDFLAGS add ELDFLAGS to LDEXEFLAGS [$LDEXEFLAGS]
|
||||
--extra-ldlibflags=ELDFLAGS add ELDFLAGS to LDLIBFLAGS [$LDLIBFLAGS]
|
||||
--extra-libs=ELIBS add ELIBS [$ELIBS]
|
||||
--extra-version=STRING version string suffix []
|
||||
--optflags=OPTFLAGS override optimization-related compiler flags
|
||||
@@ -377,7 +373,7 @@ Optimization options (experts only):
|
||||
--disable-mipsdspr2 disable MIPS DSP ASE R2 optimizations
|
||||
--disable-msa disable MSA optimizations
|
||||
--disable-mipsfpu disable floating point MIPS optimizations
|
||||
--disable-mmi disable Loongson SIMD optimizations
|
||||
--disable-loongson3 disable Loongson-3 SIMD optimizations
|
||||
--disable-fast-unaligned consider unaligned accesses slow
|
||||
|
||||
Developer options (useful when working on FFmpeg itself):
|
||||
@@ -479,7 +475,7 @@ sh_quote(){
|
||||
}
|
||||
|
||||
cleanws(){
|
||||
echo "$@" | sed 's/^ *//;s/[[:space:]][[:space:]]*/ /g;s/ *$//'
|
||||
echo "$@" | sed 's/^ *//;s/ */ /g;s/ *$//;s/\\r//g'
|
||||
}
|
||||
|
||||
filter(){
|
||||
@@ -795,10 +791,6 @@ add_ldexeflags(){
|
||||
append LDEXEFLAGS $($ldflags_filter "$@")
|
||||
}
|
||||
|
||||
add_ldlibflags(){
|
||||
append LDLIBFLAGS $($ldflags_filter "$@")
|
||||
}
|
||||
|
||||
add_stripflags(){
|
||||
append ASMSTRIPFLAGS "$@"
|
||||
}
|
||||
@@ -1312,6 +1304,12 @@ check_host_cpp_condition(){
|
||||
EOF
|
||||
}
|
||||
|
||||
apply(){
|
||||
file=$1
|
||||
shift
|
||||
"$@" < "$file" > "$file.tmp" && mv "$file.tmp" "$file" || rm "$file.tmp"
|
||||
}
|
||||
|
||||
cp_if_changed(){
|
||||
cmp -s "$1" "$2" && echo "$2 is unchanged" && return
|
||||
mkdir -p "$(dirname $2)"
|
||||
@@ -1337,7 +1335,7 @@ COMPONENT_LIST="
|
||||
|
||||
EXAMPLE_LIST="
|
||||
avio_reading_example
|
||||
avio_dir_cmd_example
|
||||
avio_list_dir_example
|
||||
decoding_encoding_example
|
||||
demuxing_decoding_example
|
||||
extract_mvs_example
|
||||
@@ -1382,7 +1380,6 @@ EXTERNAL_LIBRARY_LIST="
|
||||
libgsm
|
||||
libiec61883
|
||||
libilbc
|
||||
libkvazaar
|
||||
libmfx
|
||||
libmodplug
|
||||
libmp3lame
|
||||
@@ -1399,7 +1396,6 @@ EXTERNAL_LIBRARY_LIST="
|
||||
libschroedinger
|
||||
libshine
|
||||
libsmbclient
|
||||
libsnappy
|
||||
libsoxr
|
||||
libspeex
|
||||
libssh
|
||||
@@ -1465,7 +1461,6 @@ HWACCEL_LIST="
|
||||
vaapi
|
||||
vda
|
||||
vdpau
|
||||
videotoolbox
|
||||
xvmc
|
||||
"
|
||||
|
||||
@@ -1594,9 +1589,7 @@ ARCH_EXT_LIST_MIPS="
|
||||
"
|
||||
|
||||
ARCH_EXT_LIST_LOONGSON="
|
||||
loongson2
|
||||
loongson3
|
||||
mmi
|
||||
"
|
||||
|
||||
ARCH_EXT_LIST_X86_SIMD="
|
||||
@@ -1686,7 +1679,6 @@ HEADERS_LIST="
|
||||
dev_video_bktr_ioctl_bt848_h
|
||||
dev_video_meteor_ioctl_meteor_h
|
||||
direct_h
|
||||
dirent_h
|
||||
dlfcn_h
|
||||
d3d11_h
|
||||
dxva_h
|
||||
@@ -1727,9 +1719,7 @@ MATH_FUNCS="
|
||||
atan2f
|
||||
cbrt
|
||||
cbrtf
|
||||
copysign
|
||||
cosf
|
||||
erf
|
||||
exp2
|
||||
exp2f
|
||||
expf
|
||||
@@ -1782,7 +1772,6 @@ SYSTEM_FUNCS="
|
||||
jack_port_get_latency_range
|
||||
kbhit
|
||||
localtime_r
|
||||
lstat
|
||||
lzo1x_999_compress
|
||||
mach_absolute_time
|
||||
MapViewOfFile
|
||||
@@ -1796,7 +1785,6 @@ SYSTEM_FUNCS="
|
||||
pthread_cancel
|
||||
sched_getaffinity
|
||||
SetConsoleTextAttribute
|
||||
SetConsoleCtrlHandler
|
||||
setmode
|
||||
setrlimit
|
||||
Sleep
|
||||
@@ -1836,7 +1824,6 @@ TYPES_LIST="
|
||||
CONDITION_VARIABLE_Ptr
|
||||
socklen_t
|
||||
struct_addrinfo
|
||||
struct_dcadec_exss_info_matrix_encoding
|
||||
struct_group_source_req
|
||||
struct_ip_mreq_source
|
||||
struct_ipv6_mreq
|
||||
@@ -1900,10 +1887,8 @@ CONFIG_EXTRA="
|
||||
faandct
|
||||
faanidct
|
||||
fdctdsp
|
||||
flacdsp
|
||||
fmtconvert
|
||||
frame_thread_encoder
|
||||
g722dsp
|
||||
gcrypt
|
||||
gmp
|
||||
golomb
|
||||
@@ -1921,9 +1906,7 @@ CONFIG_EXTRA="
|
||||
iirfilter
|
||||
imdct15
|
||||
intrax8
|
||||
ividsp
|
||||
jpegtables
|
||||
libx262
|
||||
lgplv3
|
||||
llauddsp
|
||||
llviddsp
|
||||
@@ -1934,7 +1917,6 @@ CONFIG_EXTRA="
|
||||
mpegaudiodsp
|
||||
mpegvideo
|
||||
mpegvideoenc
|
||||
mss34dsp
|
||||
pixblockdsp
|
||||
qpeldsp
|
||||
qsv
|
||||
@@ -1945,19 +1927,12 @@ CONFIG_EXTRA="
|
||||
riffenc
|
||||
rtpdec
|
||||
rtpenc_chain
|
||||
rv34dsp
|
||||
sinewin
|
||||
snappy
|
||||
startcode
|
||||
texturedsp
|
||||
texturedspenc
|
||||
tpeldsp
|
||||
videodsp
|
||||
vp3dsp
|
||||
vp56dsp
|
||||
vp8dsp
|
||||
wma_freqs
|
||||
wmv2dsp
|
||||
"
|
||||
|
||||
CMDLINE_SELECT="
|
||||
@@ -2065,7 +2040,7 @@ mips32r2_deps="mips"
|
||||
mips32r5_deps="mips"
|
||||
mips64r6_deps="mips"
|
||||
msa_deps="mips"
|
||||
mmi_deps="mips"
|
||||
loongson3_deps="mips"
|
||||
|
||||
altivec_deps="ppc"
|
||||
dcbzl_deps="ppc"
|
||||
@@ -2137,22 +2112,19 @@ me_cmp_select="fdctdsp idctdsp pixblockdsp"
|
||||
mpeg_er_select="error_resilience"
|
||||
mpegaudio_select="mpegaudiodsp"
|
||||
mpegaudiodsp_select="dct"
|
||||
mpegvideo_select="blockdsp h264chroma hpeldsp idctdsp me_cmp mpeg_er videodsp"
|
||||
mpegvideo_select="blockdsp h264chroma hpeldsp idctdsp me_cmp videodsp"
|
||||
mpegvideoenc_select="me_cmp mpegvideo pixblockdsp qpeldsp"
|
||||
qsvdec_select="qsv"
|
||||
qsvenc_select="qsv"
|
||||
|
||||
# decoders / encoders
|
||||
aac_decoder_select="imdct15 mdct sinewin"
|
||||
aac_fixed_decoder_select="mdct sinewin"
|
||||
aac_encoder_select="audio_frame_queue iirfilter lpc mdct sinewin"
|
||||
aac_encoder_select="audio_frame_queue iirfilter mdct sinewin"
|
||||
aac_latm_decoder_select="aac_decoder aac_latm_parser"
|
||||
ac3_decoder_select="ac3_parser ac3dsp bswapdsp fmtconvert mdct"
|
||||
ac3_fixed_decoder_select="ac3_parser ac3dsp bswapdsp mdct"
|
||||
ac3_encoder_select="ac3dsp audiodsp mdct me_cmp"
|
||||
ac3_fixed_encoder_select="ac3dsp audiodsp mdct me_cmp"
|
||||
adpcm_g722_decoder_select="g722dsp"
|
||||
adpcm_g722_encoder_select="g722dsp"
|
||||
aic_decoder_select="golomb idctdsp"
|
||||
alac_encoder_select="lpc"
|
||||
als_decoder_select="bswapdsp"
|
||||
@@ -2181,7 +2153,6 @@ cook_decoder_select="audiodsp mdct sinewin"
|
||||
cscd_decoder_select="lzo"
|
||||
cscd_decoder_suggest="zlib"
|
||||
dca_decoder_select="fmtconvert mdct"
|
||||
dds_decoder_select="texturedsp"
|
||||
dirac_decoder_select="dwt golomb videodsp mpegvideoenc"
|
||||
dnxhd_decoder_select="blockdsp idctdsp"
|
||||
dnxhd_encoder_select="aandcttables blockdsp fdctdsp idctdsp mpegvideoenc pixblockdsp"
|
||||
@@ -2199,8 +2170,8 @@ ffv1_encoder_select="rangecoder"
|
||||
ffvhuff_decoder_select="huffyuv_decoder"
|
||||
ffvhuff_encoder_select="huffyuv_encoder"
|
||||
fic_decoder_select="golomb"
|
||||
flac_decoder_select="flacdsp golomb"
|
||||
flac_encoder_select="bswapdsp flacdsp golomb lpc"
|
||||
flac_decoder_select="golomb"
|
||||
flac_encoder_select="bswapdsp golomb lpc"
|
||||
flashsv_decoder_select="zlib"
|
||||
flashsv_encoder_select="zlib"
|
||||
flashsv2_encoder_select="zlib"
|
||||
@@ -2211,9 +2182,9 @@ fourxm_decoder_select="blockdsp bswapdsp"
|
||||
fraps_decoder_select="bswapdsp huffman"
|
||||
g2m_decoder_select="blockdsp idctdsp jpegtables zlib"
|
||||
g729_decoder_select="audiodsp"
|
||||
h261_decoder_select="mpegvideo"
|
||||
h261_decoder_select="mpeg_er mpegvideo"
|
||||
h261_encoder_select="aandcttables mpegvideoenc"
|
||||
h263_decoder_select="h263_parser h263dsp mpegvideo qpeldsp"
|
||||
h263_decoder_select="error_resilience h263_parser h263dsp mpeg_er mpegvideo qpeldsp"
|
||||
h263_encoder_select="aandcttables h263dsp mpegvideoenc"
|
||||
h263i_decoder_select="h263_decoder"
|
||||
h263p_decoder_select="h263_decoder"
|
||||
@@ -2224,21 +2195,12 @@ h264_qsv_decoder_deps="libmfx"
|
||||
h264_qsv_decoder_select="h264_mp4toannexb_bsf h264_parser qsvdec h264_qsv_hwaccel"
|
||||
h264_qsv_encoder_deps="libmfx"
|
||||
h264_qsv_encoder_select="qsvenc"
|
||||
hap_decoder_select="snappy texturedsp"
|
||||
hap_encoder_deps="libsnappy"
|
||||
hap_encoder_select="texturedspenc"
|
||||
hevc_decoder_select="bswapdsp cabac golomb videodsp"
|
||||
hevc_qsv_encoder_deps="libmfx"
|
||||
hevc_qsv_decoder_deps="libmfx"
|
||||
hevc_qsv_decoder_select="hevc_mp4toannexb_bsf hevc_parser qsvdec hevc_qsv_hwaccel"
|
||||
hevc_qsv_encoder_select="qsvenc"
|
||||
huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp"
|
||||
huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llviddsp"
|
||||
iac_decoder_select="imc_decoder"
|
||||
imc_decoder_select="bswapdsp fft mdct sinewin"
|
||||
indeo3_decoder_select="hpeldsp"
|
||||
indeo4_decoder_select="ividsp"
|
||||
indeo5_decoder_select="ividsp"
|
||||
interplay_video_decoder_select="hpeldsp"
|
||||
jpegls_decoder_select="golomb mjpeg_decoder"
|
||||
jpegls_encoder_select="golomb"
|
||||
@@ -2268,25 +2230,19 @@ mpc7_decoder_select="bswapdsp mpegaudiodsp"
|
||||
mpc8_decoder_select="mpegaudiodsp"
|
||||
mpeg_xvmc_decoder_deps="X11_extensions_XvMClib_h"
|
||||
mpeg_xvmc_decoder_select="mpeg2video_decoder"
|
||||
mpegvideo_decoder_select="mpegvideo"
|
||||
mpeg1video_decoder_select="mpegvideo"
|
||||
mpegvideo_decoder_select="error_resilience mpeg_er mpegvideo"
|
||||
mpeg1video_decoder_select="error_resilience mpeg_er mpegvideo"
|
||||
mpeg1video_encoder_select="aandcttables mpegvideoenc h263dsp"
|
||||
mpeg2video_decoder_select="mpegvideo"
|
||||
mpeg2video_decoder_select="error_resilience mpeg_er mpegvideo"
|
||||
mpeg2video_encoder_select="aandcttables mpegvideoenc h263dsp"
|
||||
mpeg2_qsv_decoder_deps="libmfx"
|
||||
mpeg2_qsv_decoder_select="qsvdec mpeg2_qsv_hwaccel"
|
||||
mpeg2_qsv_encoder_deps="libmfx"
|
||||
mpeg2_qsv_encoder_select="qsvenc"
|
||||
mpeg4_decoder_select="h263_decoder mpeg4video_parser"
|
||||
mpeg4_encoder_select="h263_encoder"
|
||||
msa1_decoder_select="mss34dsp"
|
||||
msmpeg4v1_decoder_select="h263_decoder"
|
||||
msmpeg4v2_decoder_select="h263_decoder"
|
||||
msmpeg4v2_encoder_select="h263_encoder"
|
||||
msmpeg4v3_decoder_select="h263_decoder"
|
||||
msmpeg4v3_encoder_select="h263_encoder"
|
||||
mss2_decoder_select="vc1_decoder"
|
||||
mts2_decoder_select="mss34dsp"
|
||||
mss2_decoder_select="error_resilience mpeg_er qpeldsp vc1_decoder"
|
||||
mxpeg_decoder_select="mjpeg_decoder"
|
||||
nellymoser_decoder_select="mdct sinewin"
|
||||
nellymoser_encoder_select="audio_frame_queue mdct sinewin"
|
||||
@@ -2305,12 +2261,12 @@ ra_144_decoder_select="audiodsp"
|
||||
ralf_decoder_select="golomb"
|
||||
rawvideo_decoder_select="bswapdsp"
|
||||
rtjpeg_decoder_select="me_cmp"
|
||||
rv10_decoder_select="h263_decoder"
|
||||
rv10_decoder_select="error_resilience h263_decoder h263dsp mpeg_er"
|
||||
rv10_encoder_select="h263_encoder"
|
||||
rv20_decoder_select="h263_decoder"
|
||||
rv20_decoder_select="error_resilience h263_decoder h263dsp mpeg_er"
|
||||
rv20_encoder_select="h263_encoder"
|
||||
rv30_decoder_select="golomb h264pred h264qpel mpegvideo rv34dsp"
|
||||
rv40_decoder_select="golomb h264pred h264qpel mpegvideo rv34dsp"
|
||||
rv30_decoder_select="error_resilience golomb h264chroma h264pred h264qpel mpeg_er mpegvideo videodsp"
|
||||
rv40_decoder_select="error_resilience golomb h264chroma h264pred h264qpel mpeg_er mpegvideo videodsp"
|
||||
shorten_decoder_select="golomb"
|
||||
sipr_decoder_select="lsp"
|
||||
snow_decoder_select="dwt h264qpel hpeldsp me_cmp rangecoder videodsp"
|
||||
@@ -2334,23 +2290,20 @@ truemotion2_decoder_select="bswapdsp"
|
||||
truespeech_decoder_select="bswapdsp"
|
||||
tscc_decoder_select="zlib"
|
||||
twinvq_decoder_select="mdct lsp sinewin"
|
||||
txd_decoder_select="texturedsp"
|
||||
utvideo_decoder_select="bswapdsp"
|
||||
utvideo_encoder_select="bswapdsp huffman huffyuvencdsp"
|
||||
vble_decoder_select="huffyuvdsp"
|
||||
vc1_decoder_select="blockdsp h263_decoder h264qpel intrax8 qpeldsp startcode"
|
||||
vc1_decoder_select="blockdsp error_resilience h263_decoder h264chroma h264qpel intrax8 mpeg_er qpeldsp startcode"
|
||||
vc1image_decoder_select="vc1_decoder"
|
||||
vc1_qsv_decoder_deps="libmfx"
|
||||
vc1_qsv_decoder_select="qsvdec vc1_qsv_hwaccel"
|
||||
vorbis_decoder_select="mdct"
|
||||
vorbis_encoder_select="mdct"
|
||||
vp3_decoder_select="hpeldsp vp3dsp videodsp"
|
||||
vp5_decoder_select="h264chroma hpeldsp videodsp vp3dsp vp56dsp"
|
||||
vp6_decoder_select="h264chroma hpeldsp huffman videodsp vp3dsp vp56dsp"
|
||||
vp5_decoder_select="h264chroma hpeldsp videodsp vp3dsp"
|
||||
vp6_decoder_select="h264chroma hpeldsp huffman videodsp vp3dsp"
|
||||
vp6a_decoder_select="vp6_decoder"
|
||||
vp6f_decoder_select="vp6_decoder"
|
||||
vp7_decoder_select="h264pred videodsp vp8dsp"
|
||||
vp8_decoder_select="h264pred videodsp vp8dsp"
|
||||
vp7_decoder_select="h264pred videodsp"
|
||||
vp8_decoder_select="h264pred videodsp"
|
||||
vp9_decoder_select="videodsp vp9_parser"
|
||||
webp_decoder_select="vp8_decoder"
|
||||
wmalossless_decoder_select="llauddsp"
|
||||
@@ -2362,8 +2315,8 @@ wmav2_encoder_select="mdct sinewin wma_freqs"
|
||||
wmavoice_decoder_select="lsp rdft dct mdct sinewin"
|
||||
wmv1_decoder_select="h263_decoder"
|
||||
wmv1_encoder_select="h263_encoder"
|
||||
wmv2_decoder_select="blockdsp h263_decoder idctdsp intrax8 videodsp wmv2dsp"
|
||||
wmv2_encoder_select="h263_encoder wmv2dsp"
|
||||
wmv2_decoder_select="blockdsp h263_decoder idctdsp intrax8 videodsp"
|
||||
wmv2_encoder_select="h263_encoder"
|
||||
wmv3_decoder_select="vc1_decoder"
|
||||
wmv3image_decoder_select="wmv3_decoder"
|
||||
zerocodec_decoder_select="zlib"
|
||||
@@ -2374,22 +2327,18 @@ zmbv_encoder_select="zlib"
|
||||
|
||||
# hardware accelerators
|
||||
crystalhd_deps="libcrystalhd_libcrystalhd_if_h"
|
||||
d3d11va_deps="d3d11_h dxva_h ID3D11VideoDecoder ID3D11VideoContext"
|
||||
d3d11va_deps="d3d11_h dxva_h ID3D11VideoDecoder"
|
||||
dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode"
|
||||
vaapi_deps="va_va_h"
|
||||
vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads CoreServices_CoreServices_h"
|
||||
vda_extralibs="-framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore -framework CoreServices"
|
||||
vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
|
||||
vda_extralibs="-framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore"
|
||||
vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h"
|
||||
videotoolbox_deps="VideoToolbox_VideoToolbox_h pthreads CoreServices_CoreServices_h"
|
||||
videotoolbox_extralibs="-framework CoreFoundation -framework VideoToolbox -framework CoreMedia -framework QuartzCore -framework CoreServices"
|
||||
xvmc_deps="X11_extensions_XvMClib_h"
|
||||
|
||||
h263_vaapi_hwaccel_deps="vaapi"
|
||||
h263_vaapi_hwaccel_select="h263_decoder"
|
||||
h263_vdpau_hwaccel_deps="vdpau"
|
||||
h263_vdpau_hwaccel_select="h263_decoder"
|
||||
h263_videotoolbox_hwaccel_deps="videotoolbox"
|
||||
h263_videotoolbox_hwaccel_select="h263_decoder"
|
||||
h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser"
|
||||
h264_d3d11va_hwaccel_deps="d3d11va"
|
||||
h264_d3d11va_hwaccel_select="h264_decoder"
|
||||
@@ -2412,17 +2361,10 @@ h264_vdpau_decoder_deps="vdpau"
|
||||
h264_vdpau_decoder_select="h264_decoder"
|
||||
h264_vdpau_hwaccel_deps="vdpau"
|
||||
h264_vdpau_hwaccel_select="h264_decoder"
|
||||
h264_videotoolbox_hwaccel_deps="videotoolbox"
|
||||
h264_videotoolbox_hwaccel_select="h264_decoder"
|
||||
hevc_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_HEVC"
|
||||
hevc_d3d11va_hwaccel_select="hevc_decoder"
|
||||
hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC"
|
||||
hevc_dxva2_hwaccel_select="hevc_decoder"
|
||||
hevc_qsv_hwaccel_deps="libmfx"
|
||||
hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC"
|
||||
hevc_vaapi_hwaccel_select="hevc_decoder"
|
||||
hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC"
|
||||
hevc_vdpau_hwaccel_select="hevc_decoder"
|
||||
mpeg_vdpau_decoder_deps="vdpau"
|
||||
mpeg_vdpau_decoder_select="mpeg2video_decoder"
|
||||
mpeg_xvmc_hwaccel_deps="xvmc"
|
||||
@@ -2431,8 +2373,6 @@ mpeg1_vdpau_decoder_deps="vdpau"
|
||||
mpeg1_vdpau_decoder_select="mpeg1video_decoder"
|
||||
mpeg1_vdpau_hwaccel_deps="vdpau"
|
||||
mpeg1_vdpau_hwaccel_select="mpeg1video_decoder"
|
||||
mpeg1_videotoolbox_hwaccel_deps="videotoolbox"
|
||||
mpeg1_videotoolbox_hwaccel_select="mpeg1video_decoder"
|
||||
mpeg1_xvmc_hwaccel_deps="xvmc"
|
||||
mpeg1_xvmc_hwaccel_select="mpeg1video_decoder"
|
||||
mpeg2_crystalhd_decoder_select="crystalhd"
|
||||
@@ -2440,14 +2380,10 @@ mpeg2_d3d11va_hwaccel_deps="d3d11va"
|
||||
mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder"
|
||||
mpeg2_dxva2_hwaccel_deps="dxva2"
|
||||
mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
|
||||
mpeg2_qsv_hwaccel_deps="libmfx"
|
||||
mpeg2_qsv_hwaccel_select="qsvdec_mpeg2"
|
||||
mpeg2_vaapi_hwaccel_deps="vaapi"
|
||||
mpeg2_vaapi_hwaccel_select="mpeg2video_decoder"
|
||||
mpeg2_vdpau_hwaccel_deps="vdpau"
|
||||
mpeg2_vdpau_hwaccel_select="mpeg2video_decoder"
|
||||
mpeg2_videotoolbox_hwaccel_deps="videotoolbox"
|
||||
mpeg2_videotoolbox_hwaccel_select="mpeg2video_decoder"
|
||||
mpeg2_xvmc_hwaccel_deps="xvmc"
|
||||
mpeg2_xvmc_hwaccel_select="mpeg2video_decoder"
|
||||
mpeg4_crystalhd_decoder_select="crystalhd"
|
||||
@@ -2457,8 +2393,6 @@ mpeg4_vdpau_decoder_deps="vdpau"
|
||||
mpeg4_vdpau_decoder_select="mpeg4_decoder"
|
||||
mpeg4_vdpau_hwaccel_deps="vdpau"
|
||||
mpeg4_vdpau_hwaccel_select="mpeg4_decoder"
|
||||
mpeg4_videotoolbox_hwaccel_deps="videotoolbox"
|
||||
mpeg4_videotoolbox_hwaccel_select="mpeg4_decoder"
|
||||
msmpeg4_crystalhd_decoder_select="crystalhd"
|
||||
vc1_crystalhd_decoder_select="crystalhd"
|
||||
vc1_d3d11va_hwaccel_deps="d3d11va"
|
||||
@@ -2471,8 +2405,6 @@ vc1_vdpau_decoder_deps="vdpau"
|
||||
vc1_vdpau_decoder_select="vc1_decoder"
|
||||
vc1_vdpau_hwaccel_deps="vdpau"
|
||||
vc1_vdpau_hwaccel_select="vc1_decoder"
|
||||
vc1_qsv_hwaccel_deps="libmfx"
|
||||
vc1_qsv_hwaccel_select="qsvdec_vc1"
|
||||
wmv3_crystalhd_decoder_select="crystalhd"
|
||||
wmv3_d3d11va_hwaccel_select="vc1_d3d11va_hwaccel"
|
||||
wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
|
||||
@@ -2482,9 +2414,9 @@ wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
|
||||
|
||||
# parsers
|
||||
h264_parser_select="h264_decoder"
|
||||
hevc_parser_select="golomb"
|
||||
hevc_parser_select="hevc_decoder"
|
||||
mpegvideo_parser_select="mpegvideo"
|
||||
mpeg4video_parser_select="h263dsp mpegvideo qpeldsp"
|
||||
mpeg4video_parser_select="error_resilience h263dsp mpeg_er mpegvideo qpeldsp"
|
||||
vc1_parser_select="mpegvideo startcode vc1_decoder"
|
||||
|
||||
# bitstream_filters
|
||||
@@ -2506,7 +2438,6 @@ libgsm_ms_decoder_deps="libgsm"
|
||||
libgsm_ms_encoder_deps="libgsm"
|
||||
libilbc_decoder_deps="libilbc"
|
||||
libilbc_encoder_deps="libilbc"
|
||||
libkvazaar_encoder_deps="libkvazaar"
|
||||
libmodplug_demuxer_deps="libmodplug"
|
||||
libmp3lame_encoder_deps="libmp3lame"
|
||||
libmp3lame_encoder_select="audio_frame_queue"
|
||||
@@ -2544,7 +2475,6 @@ libvpx_vp9_encoder_deps="libvpx"
|
||||
libwavpack_encoder_deps="libwavpack"
|
||||
libwebp_encoder_deps="libwebp"
|
||||
libwebp_anim_encoder_deps="libwebp"
|
||||
libx262_encoder_deps="libx262"
|
||||
libx264_encoder_deps="libx264"
|
||||
libx264rgb_encoder_deps="libx264"
|
||||
libx264rgb_encoder_select="libx264_encoder"
|
||||
@@ -2561,7 +2491,6 @@ nvenc_hevc_encoder_deps="nvenc"
|
||||
# demuxers / muxers
|
||||
ac3_demuxer_select="ac3_parser"
|
||||
asf_demuxer_select="riffdec"
|
||||
asf_o_demuxer_select="riffdec"
|
||||
asf_muxer_select="riffenc"
|
||||
asf_stream_muxer_select="asf_muxer"
|
||||
avi_demuxer_select="riffdec exif"
|
||||
@@ -2679,7 +2608,6 @@ x11grab_indev_deps="x11grab"
|
||||
x11grab_xcb_indev_deps="libxcb"
|
||||
|
||||
# protocols
|
||||
async_protocol_deps="pthreads"
|
||||
bluray_protocol_deps="libbluray"
|
||||
ffrtmpcrypt_protocol_deps="!librtmp_protocol"
|
||||
ffrtmpcrypt_protocol_deps_any="gcrypt gmp openssl"
|
||||
@@ -2743,7 +2671,6 @@ cropdetect_filter_deps="gpl"
|
||||
delogo_filter_deps="gpl"
|
||||
deshake_filter_select="pixelutils"
|
||||
drawtext_filter_deps="libfreetype"
|
||||
dynaudnorm_filter_deps="copysign erf"
|
||||
ebur128_filter_deps="gpl"
|
||||
eq_filter_deps="gpl"
|
||||
fftfilt_filter_deps="avcodec"
|
||||
@@ -2778,13 +2705,10 @@ repeatfields_filter_deps="gpl"
|
||||
resample_filter_deps="avresample"
|
||||
sab_filter_deps="gpl swscale"
|
||||
scale_filter_deps="swscale"
|
||||
scale2ref_filter_deps="swscale"
|
||||
select_filter_select="pixelutils"
|
||||
smartblur_filter_deps="gpl swscale"
|
||||
showcqt_filter_deps="avcodec"
|
||||
showcqt_filter_select="fft"
|
||||
showfreqs_filter_deps="avcodec"
|
||||
showfreqs_filter_select="fft"
|
||||
showspectrum_filter_deps="avcodec"
|
||||
showspectrum_filter_select="rdft"
|
||||
spp_filter_deps="gpl avcodec"
|
||||
@@ -2804,7 +2728,7 @@ zoompan_filter_deps="swscale"
|
||||
|
||||
# examples
|
||||
avio_reading="avformat avcodec avutil"
|
||||
avio_dir_cmd="avformat avutil"
|
||||
avio_list_dir="avformat avutil"
|
||||
avcodec_example_deps="avcodec avutil"
|
||||
decoding_encoding_example_deps="avcodec avformat avutil"
|
||||
demuxing_decoding_example_deps="avcodec avformat avutil"
|
||||
@@ -2876,7 +2800,11 @@ ln_s="ln -s -f"
|
||||
nm_default="nm -g"
|
||||
objformat="elf"
|
||||
pkg_config_default=pkg-config
|
||||
ranlib_default="ranlib"
|
||||
if ranlib 2>&1 | grep -q "\-D "; then
|
||||
ranlib_default="ranlib -D"
|
||||
else
|
||||
ranlib_default="ranlib"
|
||||
fi
|
||||
strip_default="strip"
|
||||
yasmexe_default="yasm"
|
||||
windres_default="windres"
|
||||
@@ -2917,7 +2845,7 @@ sws_max_filter_size_default=256
|
||||
set_default sws_max_filter_size
|
||||
|
||||
# Enable hwaccels by default.
|
||||
enable d3d11va dxva2 vaapi vda vdpau videotoolbox xvmc
|
||||
enable d3d11va dxva2 vaapi vda vdpau xvmc
|
||||
enable xlib
|
||||
|
||||
# build settings
|
||||
@@ -2970,9 +2898,8 @@ if test -f configure; then
|
||||
source_path=.
|
||||
else
|
||||
source_path=$(cd $(dirname "$0"); pwd)
|
||||
case "$source_path" in
|
||||
*[[:blank:]]*) die "Out of tree builds are impossible with whitespace in source path." ;;
|
||||
esac
|
||||
echo "$source_path" | grep -q '[[:blank:]]' &&
|
||||
die "Out of tree builds are impossible with whitespace in source path."
|
||||
test -e "$source_path/config.h" &&
|
||||
die "Out of tree builds are impossible with config.h in source dir."
|
||||
fi
|
||||
@@ -3072,9 +2999,6 @@ for opt do
|
||||
--extra-ldexeflags=*)
|
||||
add_ldexeflags $optval
|
||||
;;
|
||||
--extra-ldlibflags=*)
|
||||
add_ldlibflags $optval
|
||||
;;
|
||||
--extra-libs=*)
|
||||
add_extralibs $optval
|
||||
;;
|
||||
@@ -3210,14 +3134,9 @@ case "$toolchain" in
|
||||
else
|
||||
cc_default="c99wrap cl"
|
||||
fi
|
||||
ld_default="$source_path/compat/windows/mslink"
|
||||
ld_default="link"
|
||||
nm_default="dumpbin -symbols"
|
||||
ar_default="lib"
|
||||
case "$arch" in
|
||||
arm*)
|
||||
as_default="armasm"
|
||||
;;
|
||||
esac
|
||||
target_os_default="win32"
|
||||
# Use a relative path for TMPDIR. This makes sure all the
|
||||
# ffconf temp files are written with a relative path, avoiding
|
||||
@@ -3259,11 +3178,7 @@ cc_default="${cross_prefix}${cc_default}"
|
||||
cxx_default="${cross_prefix}${cxx_default}"
|
||||
nm_default="${cross_prefix}${nm_default}"
|
||||
pkg_config_default="${cross_prefix}${pkg_config_default}"
|
||||
if ${cross_prefix}${ranlib_default} 2>&1 | grep -q "\-D "; then
|
||||
ranlib_default="${cross_prefix}${ranlib_default} -D"
|
||||
else
|
||||
ranlib_default="${cross_prefix}${ranlib_default}"
|
||||
fi
|
||||
ranlib_default="${cross_prefix}${ranlib_default}"
|
||||
strip_default="${cross_prefix}${strip_default}"
|
||||
windres_default="${cross_prefix}${windres_default}"
|
||||
|
||||
@@ -3414,7 +3329,6 @@ msvc_common_flags(){
|
||||
-lavifil32) echo vfw32.lib ;;
|
||||
-lavicap32) echo vfw32.lib user32.lib ;;
|
||||
-l*) echo ${flag#-l}.lib ;;
|
||||
-LARGEADDRESSAWARE) echo $flag ;;
|
||||
-L*) echo -libpath:${flag#-L} ;;
|
||||
*) echo $flag ;;
|
||||
esac
|
||||
@@ -3543,7 +3457,6 @@ tms470_flags(){
|
||||
probe_cc(){
|
||||
pfx=$1
|
||||
_cc=$2
|
||||
first=$3
|
||||
|
||||
unset _type _ident _cc_c _cc_e _cc_o _flags _cflags
|
||||
unset _ld_o _ldflags _ld_lib _ld_path
|
||||
@@ -3554,8 +3467,8 @@ probe_cc(){
|
||||
true # no-op to avoid reading stdin in following checks
|
||||
elif $_cc -v 2>&1 | grep -q '^gcc.*LLVM'; then
|
||||
_type=llvm_gcc
|
||||
gcc_extra_ver=$(expr "$($_cc --version 2>/dev/null | head -n1)" : '.*\((.*)\)')
|
||||
_ident="llvm-gcc $($_cc -dumpversion 2>/dev/null) $gcc_extra_ver"
|
||||
gcc_extra_ver=$(expr "$($_cc --version | head -n1)" : '.*\((.*)\)')
|
||||
_ident="llvm-gcc $($_cc -dumpversion) $gcc_extra_ver"
|
||||
_depflags='-MMD -MF $(@:.o=.d) -MT $@'
|
||||
_cflags_speed='-O3'
|
||||
_cflags_size='-Os'
|
||||
@@ -3566,14 +3479,8 @@ probe_cc(){
|
||||
gcc_pkg_ver=$(expr "$gcc_version" : '[^ ]* \(([^)]*)\)')
|
||||
gcc_ext_ver=$(expr "$gcc_version" : ".*$gcc_pkg_ver $gcc_basever \\(.*\\)")
|
||||
_ident=$(cleanws "gcc $gcc_basever $gcc_pkg_ver $gcc_ext_ver")
|
||||
case $gcc_basever in
|
||||
2*) _depflags='-MMD -MF $(@:.o=.d) -MT $@' ;;
|
||||
esac
|
||||
if [ "$first" = true ]; then
|
||||
case $gcc_basever in
|
||||
4.2*)
|
||||
warn "gcc 4.2 is outdated and may miscompile FFmpeg. Please use a newer compiler." ;;
|
||||
esac
|
||||
if ! $_cc -dumpversion | grep -q '^2\.'; then
|
||||
_depflags='-MMD -MF $(@:.o=.d) -MT $@'
|
||||
fi
|
||||
_cflags_speed='-O3'
|
||||
_cflags_size='-Os'
|
||||
@@ -3625,7 +3532,7 @@ probe_cc(){
|
||||
_flags_filter=tms470_flags
|
||||
elif $_cc -v 2>&1 | grep -q clang; then
|
||||
_type=clang
|
||||
_ident=$($_cc --version 2>/dev/null | head -n1)
|
||||
_ident=$($_cc --version | head -n1)
|
||||
_depflags='-MMD -MF $(@:.o=.d) -MT $@'
|
||||
_cflags_speed='-O3'
|
||||
_cflags_size='-Os'
|
||||
@@ -3688,16 +3595,16 @@ probe_cc(){
|
||||
_flags='-nologo -Qdiag-error:4044,10157'
|
||||
# -Qvec- -Qsimd- to prevent miscompilation, -GS, fp:precise for consistency
|
||||
# with MSVC which enables it by default.
|
||||
_cflags='-D_USE_MATH_DEFINES -Qms0 -Qvec- -Qsimd- -GS -fp:precise'
|
||||
_cflags='-D_USE_MATH_DEFINES -FIstdlib.h -Dstrtoll=_strtoi64 -Qms0 -Qvec- -Qsimd- -GS -fp:precise'
|
||||
disable stripping
|
||||
elif $_cc -nologo- 2>&1 | grep -q Microsoft; then
|
||||
elif $_cc 2>&1 | grep -q Microsoft; then
|
||||
_type=msvc
|
||||
_ident=$($_cc 2>&1 | head -n1)
|
||||
_DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< 2>&1 | awk '\''/including/ { sub(/^.*file: */, ""); gsub(/\\/, "/"); if (!match($$0, / /)) print "$@:", $$0 }'\'' > $(@:.o=.d)'
|
||||
_DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -showIncludes -Zs'
|
||||
_cflags_speed="-O2"
|
||||
_cflags_size="-O1"
|
||||
if $_cc -nologo- 2>&1 | grep -q Linker; then
|
||||
if $_cc 2>&1 | grep -q Linker; then
|
||||
_ld_o='-out:$@'
|
||||
else
|
||||
_ld_o='-Fe$@'
|
||||
@@ -3708,7 +3615,7 @@ probe_cc(){
|
||||
_ld_lib='lib%.a'
|
||||
_ld_path='-libpath:'
|
||||
_flags='-nologo'
|
||||
_cflags='-D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS'
|
||||
_cflags='-D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -Dinline=__inline -FIstdlib.h -Dstrtoll=_strtoi64'
|
||||
disable stripping
|
||||
elif $_cc --version 2>/dev/null | grep -q ^cparser; then
|
||||
_type=cparser
|
||||
@@ -3737,7 +3644,7 @@ set_ccvars(){
|
||||
fi
|
||||
}
|
||||
|
||||
probe_cc cc "$cc" "true"
|
||||
probe_cc cc "$cc"
|
||||
cflags_filter=$_flags_filter
|
||||
cflags_speed=$_cflags_speed
|
||||
cflags_size=$_cflags_size
|
||||
@@ -4043,7 +3950,7 @@ elif enabled mips; then
|
||||
check_cflags "-mtune=i6400 -mabi=64"
|
||||
check_ldflags "-mabi=64"
|
||||
;;
|
||||
loongson*)
|
||||
loongson3*)
|
||||
disable mipsfpu
|
||||
disable mips32r2
|
||||
disable mips32r5
|
||||
@@ -4051,24 +3958,14 @@ elif enabled mips; then
|
||||
disable mipsdspr1
|
||||
disable mipsdspr2
|
||||
disable msa
|
||||
enable local_aligned_8 local_aligned_16 local_aligned_32
|
||||
enable local_aligned_8 local_aligned_16
|
||||
enable simd_align_16
|
||||
enable fast_64bit
|
||||
enable fast_clz
|
||||
enable fast_cmov
|
||||
enable fast_unaligned
|
||||
disable aligned_stack
|
||||
case $cpu in
|
||||
loongson3*)
|
||||
cpuflags="-march=loongson3a -mhard-float -fno-expensive-optimizations"
|
||||
;;
|
||||
loongson2e)
|
||||
cpuflags="-march=loongson2e -mhard-float -fno-expensive-optimizations"
|
||||
;;
|
||||
loongson2f)
|
||||
cpuflags="-march=loongson2f -mhard-float -fno-expensive-optimizations"
|
||||
;;
|
||||
esac
|
||||
cpuflags="-march=loongson3a -mhard-float"
|
||||
;;
|
||||
generic)
|
||||
disable mips32r5
|
||||
@@ -4341,8 +4238,6 @@ case $target_os in
|
||||
else
|
||||
target_os=mingw32
|
||||
fi
|
||||
decklink_outdev_extralibs="$decklink_outdev_extralibs -lole32 -loleaut32"
|
||||
decklink_indev_extralibs="$decklink_indev_extralibs -lole32 -loleaut32"
|
||||
LIBTARGET=i386
|
||||
if enabled x86_64; then
|
||||
LIBTARGET="i386:x86-64"
|
||||
@@ -4551,19 +4446,8 @@ probe_libc(){
|
||||
# in such new versions and producing binaries requiring windows 7.0.
|
||||
# Therefore explicitly set the default to XP unless the user has
|
||||
# set something else on the command line.
|
||||
# Don't do this if WINAPI_FAMILY is set and is set to a non-desktop
|
||||
# family. For these cases, configure is free to use any functions
|
||||
# found in the SDK headers by default. (Alternatively, we could force
|
||||
# _WIN32_WINNT to 0x0602 in that case.)
|
||||
check_${pfx}cpp_condition stdlib.h "defined(_WIN32_WINNT)" ||
|
||||
{ check_${pfx}cpp <<EOF && add_${pfx}cppflags -D_WIN32_WINNT=0x0502; }
|
||||
#ifdef WINAPI_FAMILY
|
||||
#include <winapifamily.h>
|
||||
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
#error not desktop
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
add_${pfx}cppflags -D_WIN32_WINNT=0x0502
|
||||
elif check_${pfx}cpp_condition stddef.h "defined __KLIBC__"; then
|
||||
eval ${pfx}libc_type=klibc
|
||||
elif check_${pfx}cpp_condition sys/cdefs.h "defined __BIONIC__"; then
|
||||
@@ -4792,8 +4676,6 @@ elif enabled alpha; then
|
||||
|
||||
elif enabled arm; then
|
||||
|
||||
enabled msvc && check_cpp_condition stddef.h "defined _M_ARMT" && enable thumb
|
||||
|
||||
check_cpp_condition stddef.h "defined __thumb__" && check_cc <<EOF && enable_weak thumb
|
||||
float func(float a, float b){ return a+b; }
|
||||
EOF
|
||||
@@ -4802,9 +4684,7 @@ EOF
|
||||
|
||||
if check_cpp_condition stddef.h "defined __ARM_PCS_VFP"; then
|
||||
enable vfp_args
|
||||
elif check_cpp_condition stddef.h "defined _M_ARM_FP && _M_ARM_FP >= 30"; then
|
||||
enable vfp_args
|
||||
elif ! check_cpp_condition stddef.h "defined __ARM_PCS || defined __SOFTFP__" && [ $target_os != darwin ]; then
|
||||
elif ! check_cpp_condition stddef.h "defined __ARM_PCS || defined __SOFTFP__"; then
|
||||
case "${cross_prefix:-$cc}" in
|
||||
*hardfloat*) enable vfp_args; fpabi=vfp ;;
|
||||
*) check_ld "cc" <<EOF && enable vfp_args && fpabi=vfp || fpabi=soft ;;
|
||||
@@ -4843,15 +4723,11 @@ EOF
|
||||
|
||||
elif enabled mips; then
|
||||
|
||||
enabled loongson2 && check_inline_asm loongson2 '"dmult.g $8, $9, $10"'
|
||||
enabled loongson3 && check_inline_asm loongson3 '"gsldxc1 $f0, 0($2, $3)"'
|
||||
enabled mmi && check_inline_asm mmi '"punpcklhw $f0, $f0, $f0"'
|
||||
|
||||
# Enable minimum ISA based on selected options
|
||||
if enabled mips64 && (enabled mipsdspr1 || enabled mipsdspr2); then
|
||||
add_cflags "-mips64r2"
|
||||
add_asflags "-mips64r2"
|
||||
elif enabled mips64 && enabled mipsfpu && disabled loongson2 && disabled loongson3; then
|
||||
elif enabled mips64 && enabled mipsfpu && disabled loongson3; then
|
||||
add_cflags "-mips64"
|
||||
add_asflags "-mips64"
|
||||
elif enabled mipsdspr1 || enabled mipsdspr2; then
|
||||
@@ -4876,6 +4752,7 @@ elif enabled mips; then
|
||||
check_inline_asm mipsfpu '"madd.d $f0, $f2, $f4, $f6"'
|
||||
enabled msa && check_cflags "-mmsa" && check_ldflags "-mmsa" &&
|
||||
check_inline_asm msa '"addvi.b $w0, $w1, 1"'
|
||||
enabled loongson3 && check_inline_asm loongson3 '"gsldxc1 $f0, 0($2, $3)"'
|
||||
|
||||
enabled mips32r5 && add_asflags "-mips32r5 -mfp64"
|
||||
enabled mips64r6 && add_asflags "-mips64r6 -mfp64"
|
||||
@@ -5092,7 +4969,6 @@ check_func_headers conio.h kbhit
|
||||
check_func_headers io.h setmode
|
||||
check_func_headers lzo/lzo1x.h lzo1x_999_compress
|
||||
check_func_headers stdlib.h getenv
|
||||
check_func_headers sys/stat.h lstat
|
||||
|
||||
check_func_headers windows.h CoTaskMemFree -lole32
|
||||
check_func_headers windows.h GetProcessAffinityMask
|
||||
@@ -5101,7 +4977,6 @@ check_func_headers windows.h GetSystemTimeAsFileTime
|
||||
check_func_headers windows.h MapViewOfFile
|
||||
check_func_headers windows.h PeekNamedPipe
|
||||
check_func_headers windows.h SetConsoleTextAttribute
|
||||
check_func_headers windows.h SetConsoleCtrlHandler
|
||||
check_func_headers windows.h Sleep
|
||||
check_func_headers windows.h VirtualAlloc
|
||||
check_struct windows.h "CONDITION_VARIABLE" Ptr
|
||||
@@ -5109,9 +4984,7 @@ check_func_headers glob.h glob
|
||||
enabled xlib &&
|
||||
check_func_headers "X11/Xlib.h X11/extensions/Xvlib.h" XvGetPortAttribute -lXv -lX11 -lXext
|
||||
|
||||
check_header CoreServices/CoreServices.h
|
||||
check_header direct.h
|
||||
check_header dirent.h
|
||||
check_header dlfcn.h
|
||||
check_header d3d11.h
|
||||
check_header dxva.h
|
||||
@@ -5134,7 +5007,6 @@ check_header valgrind/valgrind.h
|
||||
check_header vdpau/vdpau.h
|
||||
check_header vdpau/vdpau_x11.h
|
||||
check_header VideoDecodeAcceleration/VDADecoder.h
|
||||
check_header VideoToolbox/VideoToolbox.h
|
||||
check_header windows.h
|
||||
check_header X11/extensions/XvMClib.h
|
||||
check_header asm/types.h
|
||||
@@ -5145,14 +5017,9 @@ check_lib2 "windows.h psapi.h" GetProcessMemoryInfo -lpsapi
|
||||
|
||||
check_struct "sys/time.h sys/resource.h" "struct rusage" ru_maxrss
|
||||
|
||||
check_type "windows.h dxva.h" "DXVA_PicParams_HEVC" -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_CRT_BUILD_DESKTOP_APP=0
|
||||
check_type "windows.h dxva.h" "DXVA_PicParams_HEVC"
|
||||
check_type "windows.h d3d11.h" "ID3D11VideoDecoder"
|
||||
check_type "windows.h d3d11.h" "ID3D11VideoContext"
|
||||
check_type "d3d9.h dxva2api.h" DXVA2_ConfigPictureDecode -D_WIN32_WINNT=0x0602
|
||||
|
||||
check_type "va/va.h" "VAPictureParameterBufferHEVC"
|
||||
|
||||
check_type "vdpau/vdpau.h" "VdpPictureInfoHEVC"
|
||||
check_type "d3d9.h dxva2api.h" DXVA2_ConfigPictureDecode -D_WIN32_WINNT=0x0600
|
||||
|
||||
if ! disabled w32threads && ! enabled pthreads; then
|
||||
check_func_headers "windows.h process.h" _beginthreadex &&
|
||||
@@ -5195,7 +5062,6 @@ check_lib math.h sin -lm && LIBM="-lm"
|
||||
disabled crystalhd || check_lib libcrystalhd/libcrystalhd_if.h DtsCrystalHDVersion -lcrystalhd || disable crystalhd
|
||||
|
||||
atan2f_args=2
|
||||
copysign_args=2
|
||||
ldexpf_args=2
|
||||
powf_args=2
|
||||
|
||||
@@ -5223,8 +5089,7 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 &&
|
||||
{ check_lib celt/celt.h celt_decoder_create_custom -lcelt0 ||
|
||||
die "ERROR: libcelt must be installed and version must be >= 0.11.0."; }
|
||||
enabled libcaca && require_pkg_config caca caca.h caca_create_canvas
|
||||
enabled libdcadec && require_pkg_config dcadec libdcadec/dca_context.h dcadec_context_create &&
|
||||
check_struct libdcadec/dca_context.h "struct dcadec_exss_info" matrix_encoding
|
||||
enabled libdcadec && require_pkg_config dcadec libdcadec/dca_context.h dcadec_context_create
|
||||
enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac
|
||||
enabled libfdk_aac && { use_pkg_config fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen ||
|
||||
{ require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac &&
|
||||
@@ -5240,7 +5105,6 @@ enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do
|
||||
check_lib "${gsm_hdr}" gsm_create -lgsm && break;
|
||||
done || die "ERROR: libgsm not found"; }
|
||||
enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc
|
||||
enabled libkvazaar && require_pkg_config kvazaar kvazaar.h kvz_api_get
|
||||
enabled libmfx && require_pkg_config libmfx "mfx/mfxvideo.h" MFXInit
|
||||
enabled libmodplug && require_pkg_config libmodplug libmodplug/modplug.h ModPlug_Load
|
||||
enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame
|
||||
@@ -5261,8 +5125,7 @@ enabled libschroedinger && require_pkg_config schroedinger-1.0 schroedinger/sc
|
||||
enabled libshine && require_pkg_config shine shine/layer3.h shine_encode_buffer
|
||||
enabled libsmbclient && { use_pkg_config smbclient libsmbclient.h smbc_init ||
|
||||
require smbclient libsmbclient.h smbc_init -lsmbclient; }
|
||||
enabled libsnappy && require snappy snappy-c.h snappy_compress -lsnappy
|
||||
enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr && LIBSOXR="-lsoxr"
|
||||
enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr
|
||||
enabled libssh && require_pkg_config libssh libssh/sftp.h sftp_init
|
||||
enabled libspeex && require_pkg_config speex speex/speex.h speex_decoder_init -lspeex
|
||||
enabled libstagefright_h264 && require_cpp libstagefright_h264 "binder/ProcessState.h media/stagefright/MetaData.h
|
||||
@@ -5278,33 +5141,13 @@ enabled libvidstab && require_pkg_config "vidstab >= 0.98" vid.stab/libvi
|
||||
enabled libvo_aacenc && require libvo_aacenc vo-aacenc/voAAC.h voGetAACEncAPI -lvo-aacenc
|
||||
enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
|
||||
enabled libvorbis && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
|
||||
|
||||
enabled libvpx && {
|
||||
enabled libvpx_vp8_decoder && {
|
||||
use_pkg_config "vpx >= 0.9.1" "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp8_dx ||
|
||||
check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_dec_init_ver -lvpx ||
|
||||
die "ERROR: libvpx decoder version must be >=0.9.1";
|
||||
}
|
||||
enabled libvpx_vp8_encoder && {
|
||||
use_pkg_config "vpx >= 0.9.7" "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp8_cx ||
|
||||
check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_enc_init_ver VP8E_SET_MAX_INTRA_BITRATE_PCT" -lvpx ||
|
||||
die "ERROR: libvpx encoder version must be >=0.9.7";
|
||||
}
|
||||
enabled libvpx_vp9_decoder && {
|
||||
use_pkg_config "vpx >= 1.3.0" "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp9_dx ||
|
||||
check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_vp9_dx" -lvpx ||
|
||||
disable libvpx_vp9_decoder;
|
||||
}
|
||||
enabled libvpx_vp9_encoder && {
|
||||
use_pkg_config "vpx >= 1.3.0" "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp9_cx ||
|
||||
check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_vp9_cx VP9E_SET_AQ_MODE" -lvpx ||
|
||||
disable libvpx_vp9_encoder;
|
||||
}
|
||||
if disabled_all libvpx_vp8_decoder libvpx_vp9_decoder libvpx_vp8_encoder libvpx_vp9_encoder; then
|
||||
die "libvpx enabled but no supported decoders found"
|
||||
fi
|
||||
}
|
||||
|
||||
enabled libvpx_vp8_decoder && { check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_dec_init_ver -lvpx ||
|
||||
die "ERROR: libvpx decoder version must be >=0.9.1"; }
|
||||
enabled libvpx_vp8_encoder && { check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_enc_init_ver VP8E_SET_MAX_INTRA_BITRATE_PCT" -lvpx ||
|
||||
die "ERROR: libvpx encoder version must be >=0.9.7"; }
|
||||
enabled libvpx_vp9_decoder && { check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_vp9_dx" -lvpx || disable libvpx_vp9_decoder; }
|
||||
enabled libvpx_vp9_encoder && { check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_vp9_cx VP9E_SET_AQ_MODE" -lvpx || disable libvpx_vp9_encoder; } }
|
||||
enabled libwavpack && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput -lwavpack
|
||||
enabled libwebp && {
|
||||
enabled libwebp_encoder && require_pkg_config "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion
|
||||
@@ -5313,9 +5156,7 @@ enabled libx264 && { use_pkg_config x264 "stdint.h x264.h" x264_encode
|
||||
{ require libx264 x264.h x264_encoder_encode -lx264 &&
|
||||
warn "using libx264 without pkg-config"; } } &&
|
||||
{ check_cpp_condition x264.h "X264_BUILD >= 118" ||
|
||||
die "ERROR: libx264 must be installed and version must be >= 0.118."; } &&
|
||||
{ check_cpp_condition x264.h "X264_MPEG2" &&
|
||||
enable libx262; }
|
||||
die "ERROR: libx264 must be installed and version must be >= 0.118."; }
|
||||
enabled libx265 && require_pkg_config x265 x265.h x265_api_get &&
|
||||
{ check_cpp_condition x265.h "X265_BUILD >= 57" ||
|
||||
die "ERROR: libx265 version must be >= 57."; }
|
||||
@@ -5390,9 +5231,6 @@ if ! disabled sdl; then
|
||||
disable sdl
|
||||
fi
|
||||
fi
|
||||
if test $target_os = "mingw32"; then
|
||||
sdl_libs="$sdl_libs -mconsole"
|
||||
fi
|
||||
fi
|
||||
enabled sdl && add_cflags $sdl_cflags && add_extralibs $sdl_libs
|
||||
|
||||
@@ -5556,7 +5394,6 @@ check_disable_warning -Wno-pointer-sign
|
||||
check_ldflags -Wl,--warn-common
|
||||
check_ldflags -Wl,-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample
|
||||
enabled rpath && add_ldexeflags -Wl,-rpath,$libdir
|
||||
enabled rpath && add_ldlibflags -Wl,-rpath,$libdir
|
||||
test_ldflags -Wl,-Bsymbolic && append SHFLAGS -Wl,-Bsymbolic
|
||||
|
||||
# add some strip flags
|
||||
@@ -5723,30 +5560,8 @@ elif enabled_any msvc icl; then
|
||||
fi
|
||||
# msvcrt10 x64 incorrectly enables log2, only msvcrt12 (MSVC 2013) onwards actually has log2.
|
||||
check_cpp_condition crtversion.h "_VC_CRT_MAJOR_VERSION >= 12" || disable log2
|
||||
# The CRT headers contain __declspec(restrict) in a few places, but if redefining
|
||||
# restrict, this might break. MSVC 2010 and 2012 fail with __declspec(__restrict)
|
||||
# (as it ends up if the restrict redefine is done before including stdlib.h), while
|
||||
# MSVC 2013 and newer can handle it fine.
|
||||
# If this declspec fails, force including stdlib.h before the restrict redefinition
|
||||
# happens in config.h.
|
||||
if [ $_restrict != restrict ]; then
|
||||
check_cc <<EOF || add_cflags -FIstdlib.h
|
||||
__declspec($_restrict) void* foo(int);
|
||||
EOF
|
||||
fi
|
||||
check_func strtoll || add_cflags -Dstrtoll=_strtoi64
|
||||
fi
|
||||
|
||||
for pfx in "" host_; do
|
||||
varname=${pfx%_}cc_type
|
||||
eval "type=\$$varname"
|
||||
if [ $type = "msvc" ]; then
|
||||
check_${pfx}cc <<EOF || add_${pfx}cflags -Dinline=__inline
|
||||
static inline int foo(int a) { return a; }
|
||||
EOF
|
||||
fi
|
||||
done
|
||||
|
||||
case $as_type in
|
||||
clang)
|
||||
add_asflags -Qunused-arguments
|
||||
@@ -5849,7 +5664,6 @@ enabled removelogo_filter && prepend avfilter_deps "avformat avcodec swscale"
|
||||
enabled resample_filter && prepend avfilter_deps "avresample"
|
||||
enabled sab_filter && prepend avfilter_deps "swscale"
|
||||
enabled scale_filter && prepend avfilter_deps "swscale"
|
||||
enabled scale2ref_filter && prepend avfilter_deps "swscale"
|
||||
enabled showspectrum_filter && prepend avfilter_deps "avcodec"
|
||||
enabled smartblur_filter && prepend avfilter_deps "swscale"
|
||||
enabled subtitles_filter && prepend avfilter_deps "avformat avcodec"
|
||||
@@ -5927,7 +5741,7 @@ if enabled mips; then
|
||||
echo "MIPS DSP R1 enabled ${mipsdspr1-no}"
|
||||
echo "MIPS DSP R2 enabled ${mipsdspr2-no}"
|
||||
echo "MIPS MSA enabled ${msa-no}"
|
||||
echo "LOONGSON MMI enabled ${mmi-no}"
|
||||
echo "LOONGSON3 enabled ${loongson3-no}"
|
||||
fi
|
||||
if enabled ppc; then
|
||||
echo "AltiVec enabled ${altivec-no}"
|
||||
@@ -5958,10 +5772,6 @@ test -n "$random_seed" &&
|
||||
echo "random seed ${random_seed}"
|
||||
echo
|
||||
|
||||
echo "Enabled programs:"
|
||||
print_enabled '' $PROGRAM_LIST | print_3_columns
|
||||
echo
|
||||
|
||||
echo "External libraries:"
|
||||
print_enabled '' $EXTERNAL_LIBRARY_LIST | print_3_columns
|
||||
echo
|
||||
@@ -6052,7 +5862,6 @@ DEPWINDRES=$dep_cc
|
||||
DOXYGEN=$doxygen
|
||||
LDFLAGS=$LDFLAGS
|
||||
LDEXEFLAGS=$LDEXEFLAGS
|
||||
LDLIBFLAGS=$LDLIBFLAGS
|
||||
SHFLAGS=$(echo $($ldflags_filter $SHFLAGS))
|
||||
ASMSTRIPFLAGS=$ASMSTRIPFLAGS
|
||||
YASMFLAGS=$YASMFLAGS
|
||||
@@ -6170,7 +5979,6 @@ enabled getenv || echo "#define getenv(x) NULL" >> $TMPH
|
||||
|
||||
mkdir -p doc
|
||||
mkdir -p tests
|
||||
mkdir -p tests/api
|
||||
echo "@c auto-generated by configure" > doc/config.texi
|
||||
|
||||
print_config ARCH_ "$config_files" $ARCH_LIST
|
||||
@@ -6265,4 +6073,4 @@ pkgconfig_generate libavfilter "FFmpeg audio/video filtering library" "$LIBAVF
|
||||
pkgconfig_generate libpostproc "FFmpeg postprocessing library" "$LIBPOSTPROC_VERSION" ""
|
||||
pkgconfig_generate libavresample "Libav audio resampling library" "$LIBAVRESAMPLE_VERSION" "$LIBM"
|
||||
pkgconfig_generate libswscale "FFmpeg image rescaling library" "$LIBSWSCALE_VERSION" "$LIBM"
|
||||
pkgconfig_generate libswresample "FFmpeg audio resampling library" "$LIBSWRESAMPLE_VERSION" "$LIBM $LIBSOXR"
|
||||
pkgconfig_generate libswresample "FFmpeg audio resampling library" "$LIBSWRESAMPLE_VERSION" "$LIBM"
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.1
|
||||
PROJECT_NUMBER = 2.7.2
|
||||
|
||||
# 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -420,26 +373,13 @@ ffmpeg -framerate 10 -pattern_type glob -i "*.png" out.mkv
|
||||
|
||||
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
|
||||
|
||||
@@ -543,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?
|
||||
|
||||
@@ -637,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
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -280,15 +280,13 @@ data read from the input file.
|
||||
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,8 +295,8 @@ 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
|
||||
@@ -307,13 +305,7 @@ will be preserved.
|
||||
When used as an output option (before an output filename), decodes but discards
|
||||
input until the timestamps reach @var{position}.
|
||||
|
||||
@var{position} 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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
1372
doc/filters.texi
1372
doc/filters.texi
File diff suppressed because it is too large
Load Diff
@@ -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.
|
||||
@@ -983,8 +954,8 @@ following image formats are supported:
|
||||
@item Musepack SV8 @tab @tab X
|
||||
@item Nellymoser Asao @tab X @tab X
|
||||
@item On2 AVC (Audio for Video Codec) @tab @tab X
|
||||
@item Opus @tab E @tab X
|
||||
@tab encoding supported through external library libopus
|
||||
@item Opus @tab E @tab E
|
||||
@tab supported through external library libopus
|
||||
@item PCM A-law @tab X @tab X
|
||||
@item PCM mu-law @tab X @tab X
|
||||
@item PCM signed 8-bit planar @tab X @tab X
|
||||
|
||||
@@ -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,21 +32,22 @@ 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.
|
||||
|
||||
|
||||
@@ -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,14 +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 and email address
|
||||
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
|
||||
@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
|
||||
@@ -210,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
|
||||
|
||||
@@ -326,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}.
|
||||
|
||||
@@ -352,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
|
||||
@@ -378,7 +375,7 @@ git checkout -b svn_23456 $SHA1
|
||||
where @var{$SHA1} is the commit hash from the @command{git log} output.
|
||||
|
||||
|
||||
@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
|
||||
@@ -389,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.
|
||||
|
||||
@@ -398,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
|
||||
|
||||
@@ -416,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.
|
||||
|
||||
181
doc/indevs.texi
181
doc/indevs.texi
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -977,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
|
||||
@@ -986,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
|
||||
|
||||
@@ -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}
|
||||
|
||||
446
ffmpeg.c
446
ffmpeg.c
@@ -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) {
|
||||
@@ -1867,22 +1800,17 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
|
||||
|
||||
opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base);
|
||||
opkt.flags = pkt->flags;
|
||||
|
||||
// FIXME remove the following 2 lines they shall be replaced by the bitstream filters
|
||||
if ( ost->st->codec->codec_id != AV_CODEC_ID_H264
|
||||
&& ost->st->codec->codec_id != AV_CODEC_ID_MPEG1VIDEO
|
||||
&& ost->st->codec->codec_id != AV_CODEC_ID_MPEG2VIDEO
|
||||
&& ost->st->codec->codec_id != AV_CODEC_ID_VC1
|
||||
if ( ost->enc_ctx->codec_id != AV_CODEC_ID_H264
|
||||
&& ost->enc_ctx->codec_id != AV_CODEC_ID_MPEG1VIDEO
|
||||
&& ost->enc_ctx->codec_id != AV_CODEC_ID_MPEG2VIDEO
|
||||
&& ost->enc_ctx->codec_id != AV_CODEC_ID_VC1
|
||||
) {
|
||||
int ret = av_parser_change(ost->parser, ost->st->codec,
|
||||
if (av_parser_change(ost->parser, ost->st->codec,
|
||||
&opkt.data, &opkt.size,
|
||||
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));
|
||||
exit_program(1);
|
||||
}
|
||||
if (ret) {
|
||||
pkt->flags & AV_PKT_FLAG_KEY)) {
|
||||
opkt.buf = av_buffer_create(opkt.data, opkt.size, av_buffer_default_free, NULL, 0);
|
||||
if (!opkt.buf)
|
||||
exit_program(1);
|
||||
@@ -1893,16 +1821,9 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
|
||||
}
|
||||
av_copy_packet_side_data(&opkt, pkt);
|
||||
|
||||
if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
|
||||
ost->st->codec->codec_id == AV_CODEC_ID_RAWVIDEO &&
|
||||
(of->ctx->oformat->flags & AVFMT_RAWPICTURE)) {
|
||||
if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (of->ctx->oformat->flags & AVFMT_RAWPICTURE)) {
|
||||
/* store AVPicture in AVPacket, as expected by the output format */
|
||||
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));
|
||||
exit_program(1);
|
||||
}
|
||||
avpicture_fill(&pict, opkt.data, ost->st->codec->pix_fmt, ost->st->codec->width, ost->st->codec->height);
|
||||
opkt.data = (uint8_t *)&pict;
|
||||
opkt.size = sizeof(AVPicture);
|
||||
opkt.flags |= AV_PKT_FLAG_KEY;
|
||||
@@ -1959,8 +1880,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 +2014,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 +2042,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 +2200,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 +2247,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 +2284,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,15 +2304,6 @@ 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;
|
||||
@@ -2582,76 +2495,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)
|
||||
{
|
||||
@@ -2762,7 +2605,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);
|
||||
@@ -2803,6 +2646,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;
|
||||
@@ -2839,7 +2697,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);
|
||||
@@ -2914,7 +2772,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);
|
||||
@@ -3011,6 +2869,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 &&
|
||||
@@ -3139,6 +3001,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) {
|
||||
@@ -3175,9 +3070,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 */
|
||||
@@ -3447,17 +3396,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;
|
||||
}
|
||||
@@ -3535,7 +3476,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)
|
||||
@@ -3838,7 +3779,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);
|
||||
@@ -4057,7 +4004,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);
|
||||
@@ -4166,7 +4112,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]);
|
||||
|
||||
17
ffmpeg.h
17
ffmpeg.h
@@ -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 */
|
||||
|
||||
129
ffmpeg_filter.c
129
ffmpeg_filter.c
@@ -85,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,
|
||||
@@ -289,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)
|
||||
@@ -423,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"),
|
||||
@@ -544,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);
|
||||
@@ -647,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);
|
||||
@@ -682,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 */
|
||||
@@ -738,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,
|
||||
@@ -954,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;
|
||||
|
||||
@@ -967,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;
|
||||
@@ -1003,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);
|
||||
@@ -1035,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;
|
||||
|
||||
@@ -1048,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);
|
||||
}
|
||||
|
||||
192
ffmpeg_opt.c
192
ffmpeg_opt.c
@@ -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);
|
||||
@@ -2950,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) {
|
||||
@@ -2964,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) {
|
||||
@@ -3045,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" },
|
||||
@@ -3085,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 },
|
||||
@@ -3248,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
ffmpeg_vda.c
Normal file
136
ffmpeg_vda.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
344
ffplay.c
344
ffplay.c
@@ -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;
|
||||
|
||||
@@ -2831,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);
|
||||
|
||||
303
ffserver.c
303
ffserver.c
@@ -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),
|
||||
@@ -2584,11 +2578,12 @@ static int http_receive_data(HTTPContext *c)
|
||||
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) {
|
||||
@@ -2621,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? */
|
||||
@@ -2827,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;
|
||||
@@ -2849,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);
|
||||
@@ -2860,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)
|
||||
@@ -2891,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",
|
||||
@@ -3058,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;
|
||||
@@ -3119,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)
|
||||
{
|
||||
@@ -3145,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] == '/' &&
|
||||
@@ -3226,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;
|
||||
|
||||
@@ -3281,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)
|
||||
@@ -3363,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)
|
||||
@@ -3403,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);
|
||||
@@ -3510,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;
|
||||
@@ -3540,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);
|
||||
}
|
||||
|
||||
@@ -3562,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);
|
||||
@@ -3589,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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3766,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -559,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]);
|
||||
}
|
||||
@@ -883,11 +883,11 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
}
|
||||
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");
|
||||
@@ -1026,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,
|
||||
};
|
||||
|
||||
@@ -184,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,
|
||||
};
|
||||
|
||||
@@ -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 },
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) << (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 */
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
3032
libavcodec/aacdec.c
3032
libavcodec/aacdec.c
File diff suppressed because it is too large
Load Diff
@@ -1,443 +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) << 1));
|
||||
|
||||
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) << 1));
|
||||
sign <<= nz & 1;
|
||||
nz >>= 1;
|
||||
dst[1] = (idx >> 2 & 3) * (1 + (((int)sign >> 31) << 1));
|
||||
sign <<= nz & 1;
|
||||
nz >>= 1;
|
||||
dst[2] = (idx >> 4 & 3) * (1 + (((int)sign >> 31) << 1));
|
||||
sign <<= nz & 1;
|
||||
nz >>= 1;
|
||||
dst[3] = (idx >> 6 & 3) * (1 + (((int)sign >> 31) << 1));
|
||||
|
||||
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];
|
||||
else
|
||||
coef = (int)cbrt_tab[coef];
|
||||
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 > 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 {
|
||||
s = s + 32;
|
||||
round = 1 << (s-1);
|
||||
for (i=0; i<len; i++) {
|
||||
out = (int)((int64_t)((int64_t)src[i] * c + round) >> s);
|
||||
dst[i] = out * ssign;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void noise_scale(int *coefs, int scale, int band_energy, int len)
|
||||
{
|
||||
int ssign = scale < 0 ? -1 : 1;
|
||||
int s = FFABS(scale);
|
||||
unsigned int round;
|
||||
int i, out, c = exp2tab[s & 3];
|
||||
int nlz = 0;
|
||||
|
||||
while (band_energy > 0x7fff) {
|
||||
band_energy >>= 1;
|
||||
nlz++;
|
||||
}
|
||||
c /= band_energy;
|
||||
s = 21 + nlz - (s >> 2);
|
||||
|
||||
if (s > 0) {
|
||||
round = 1 << (s-1);
|
||||
for (i=0; i<len; i++) {
|
||||
out = (int)(((int64_t)coefs[i] * c) >> 32);
|
||||
coefs[i] = ((int)(out+round) >> s) * ssign;
|
||||
}
|
||||
}
|
||||
else {
|
||||
s = s + 32;
|
||||
round = 1 << (s-1);
|
||||
for (i=0; i<len; i++) {
|
||||
out = (int)((int64_t)((int64_t)coefs[i] * c + round) >> s);
|
||||
coefs[i] = out * ssign;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
*coef += (pv.mant + (1 << (shift - 1))) >> 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 < 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 + 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 << 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;
|
||||
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 << 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,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] = {
|
||||
|
||||
@@ -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,9 +529,7 @@ 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];
|
||||
|
||||
@@ -519,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);
|
||||
@@ -547,46 +585,25 @@ 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->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);
|
||||
if (isnan(cpe->ch->coeffs[0])) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Input contains NaN\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));
|
||||
@@ -596,26 +613,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) {
|
||||
@@ -628,59 +635,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;
|
||||
}
|
||||
@@ -697,7 +667,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;
|
||||
@@ -716,7 +686,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);
|
||||
@@ -740,7 +710,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);
|
||||
@@ -754,7 +723,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);
|
||||
|
||||
@@ -777,7 +746,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;
|
||||
@@ -803,29 +772,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,
|
||||
@@ -844,8 +800,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++)
|
||||
@@ -855,7 +811,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);
|
||||
@@ -864,6 +819,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);
|
||||
|
||||
@@ -879,23 +837,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}
|
||||
};
|
||||
|
||||
@@ -906,6 +855,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)"),
|
||||
@@ -916,8 +872,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,
|
||||
|
||||
@@ -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 */
|
||||
@@ -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] + (par[ 1]>>1)) * 1431655765 + \
|
||||
0x40000000) >> 31);
|
||||
par[ 1] = (int)(((int64_t)((par[ 1]>>1) + par[ 2]) * 1431655765 + \
|
||||
0x40000000) >> 31);
|
||||
par[ 2] = (int)(((int64_t)(par[ 3] + (par[ 4]>>1)) * 1431655765 + \
|
||||
0x40000000) >> 31);
|
||||
par[ 3] = (int)(((int64_t)((par[ 4]>>1) + 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,33 +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;
|
||||
int denom;
|
||||
|
||||
decayed_peak = (int)(((int64_t)peak_decay_factor * \
|
||||
peak_decay_nrg[i] + 0x40000000) >> 31);
|
||||
peak_decay_nrg[i] = FFMAX(decayed_peak, power[i][n]);
|
||||
power_smooth[i] += (power[i][n] - power_smooth[i] + 2) >> 2;
|
||||
peak_decay_diff_smooth[i] += (peak_decay_nrg[i] - power[i][n] - \
|
||||
peak_decay_diff_smooth[i] + 2) >> 2;
|
||||
denom = peak_decay_diff_smooth[i] + (peak_decay_diff_smooth[i] >> 1);
|
||||
if (denom > power_smooth[i]) {
|
||||
int p = power_smooth[i];
|
||||
while (denom < 0x40000000) {
|
||||
denom <<= 1;
|
||||
p <<= 1;
|
||||
}
|
||||
transient_gain[i][n] = p / (denom >> 16);
|
||||
}
|
||||
else {
|
||||
transient_gain[i][n] = 1 << 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
#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];
|
||||
@@ -728,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
|
||||
// -----
|
||||
@@ -739,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++) {
|
||||
@@ -762,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++) {
|
||||
@@ -821,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];
|
||||
@@ -840,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) {
|
||||
@@ -895,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];
|
||||
@@ -904,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;
|
||||
@@ -936,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);
|
||||
#if USE_FIXED
|
||||
width <<= 1;
|
||||
#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];
|
||||
@@ -964,15 +889,15 @@ 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] + start + 1, r[k] + start + 1,
|
||||
@@ -981,10 +906,10 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -994,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);
|
||||
@@ -1011,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;
|
||||
@@ -1043,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);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
@@ -20,5 +20,74 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#define USE_FIXED 0
|
||||
#include "aacps_tablegen_template.c"
|
||||
#include <stdlib.h>
|
||||
#define CONFIG_HARDCODED_TABLES 0
|
||||
#include "aacps_tablegen.h"
|
||||
#include "tableprint.h"
|
||||
|
||||
void write_float_3d_array (const void *p, int b, int c, int d)
|
||||
{
|
||||
int i;
|
||||
const float *f = p;
|
||||
for (i = 0; i < b; i++) {
|
||||
printf("{\n");
|
||||
write_float_2d_array(f, c, d);
|
||||
printf("},\n");
|
||||
f += c * d;
|
||||
}
|
||||
}
|
||||
|
||||
void write_float_4d_array (const void *p, int a, int b, int c, int d)
|
||||
{
|
||||
int i;
|
||||
const float *f = p;
|
||||
for (i = 0; i < a; i++) {
|
||||
printf("{\n");
|
||||
write_float_3d_array(f, b, c, d);
|
||||
printf("},\n");
|
||||
f += b * c * d;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ps_tableinit();
|
||||
|
||||
write_fileheader();
|
||||
|
||||
printf("static const float pd_re_smooth[8*8*8] = {\n");
|
||||
write_float_array(pd_re_smooth, 8*8*8);
|
||||
printf("};\n");
|
||||
printf("static const float pd_im_smooth[8*8*8] = {\n");
|
||||
write_float_array(pd_im_smooth, 8*8*8);
|
||||
printf("};\n");
|
||||
|
||||
printf("static const float HA[46][8][4] = {\n");
|
||||
write_float_3d_array(HA, 46, 8, 4);
|
||||
printf("};\n");
|
||||
printf("static const float HB[46][8][4] = {\n");
|
||||
write_float_3d_array(HB, 46, 8, 4);
|
||||
printf("};\n");
|
||||
|
||||
printf("static const DECLARE_ALIGNED(16, float, f20_0_8)[8][8][2] = {\n");
|
||||
write_float_3d_array(f20_0_8, 8, 8, 2);
|
||||
printf("};\n");
|
||||
printf("static const DECLARE_ALIGNED(16, float, f34_0_12)[12][8][2] = {\n");
|
||||
write_float_3d_array(f34_0_12, 12, 8, 2);
|
||||
printf("};\n");
|
||||
printf("static const DECLARE_ALIGNED(16, float, f34_1_8)[8][8][2] = {\n");
|
||||
write_float_3d_array(f34_1_8, 8, 8, 2);
|
||||
printf("};\n");
|
||||
printf("static const DECLARE_ALIGNED(16, float, f34_2_4)[4][8][2] = {\n");
|
||||
write_float_3d_array(f34_2_4, 4, 8, 2);
|
||||
printf("};\n");
|
||||
|
||||
printf("static const DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2] = {\n");
|
||||
write_float_4d_array(Q_fract_allpass, 2, 50, 3, 2);
|
||||
printf("};\n");
|
||||
printf("static const DECLARE_ALIGNED(16, float, phi_fract)[2][50][2] = {\n");
|
||||
write_float_3d_array(phi_fract, 2, 50, 2);
|
||||
printf("};\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,107 +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
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#define CONFIG_HARDCODED_TABLES 0
|
||||
#include "aac_defines.h"
|
||||
|
||||
#if USE_FIXED
|
||||
#define TYPE_NAME "int32_t"
|
||||
#define INT32FLOAT int32_t
|
||||
#define ARRAY_RENAME(x) write_int32_t_ ## x
|
||||
#define ARRAY_URENAME(x) write_uint32_t_ ## x
|
||||
#include "aacps_fixed_tablegen.h"
|
||||
#else
|
||||
#define TYPE_NAME "float"
|
||||
#define INT32FLOAT float
|
||||
#define ARRAY_RENAME(x) write_float_ ## x
|
||||
#define ARRAY_URENAME(x) write_float_ ## x
|
||||
#include "aacps_tablegen.h"
|
||||
#endif /* USE_FIXED */
|
||||
#include "tableprint.h"
|
||||
|
||||
void ARRAY_RENAME(3d_array) (const void *p, int b, int c, int d)
|
||||
{
|
||||
int i;
|
||||
const INT32FLOAT *f = p;
|
||||
for (i = 0; i < b; i++) {
|
||||
printf("{\n");
|
||||
ARRAY_URENAME(2d_array)(f, c, d);
|
||||
printf("},\n");
|
||||
f += c * d;
|
||||
}
|
||||
}
|
||||
|
||||
void ARRAY_RENAME(4d_array) (const void *p, int a, int b, int c, int d)
|
||||
{
|
||||
int i;
|
||||
const INT32FLOAT *f = p;
|
||||
for (i = 0; i < a; i++) {
|
||||
printf("{\n");
|
||||
ARRAY_RENAME(3d_array)(f, b, c, d);
|
||||
printf("},\n");
|
||||
f += b * c * d;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ps_tableinit();
|
||||
|
||||
write_fileheader();
|
||||
|
||||
printf("static const %s pd_re_smooth[8*8*8] = {\n", TYPE_NAME);
|
||||
ARRAY_RENAME(array)(pd_re_smooth, 8*8*8);
|
||||
printf("};\n");
|
||||
printf("static const %s pd_im_smooth[8*8*8] = {\n", TYPE_NAME);
|
||||
ARRAY_RENAME(array)(pd_im_smooth, 8*8*8);
|
||||
printf("};\n");
|
||||
|
||||
printf("static const %s HA[46][8][4] = {\n", TYPE_NAME);
|
||||
ARRAY_RENAME(3d_array)(HA, 46, 8, 4);
|
||||
printf("};\n");
|
||||
printf("static const %s HB[46][8][4] = {\n", TYPE_NAME);
|
||||
ARRAY_RENAME(3d_array)(HB, 46, 8, 4);
|
||||
printf("};\n");
|
||||
|
||||
printf("static const DECLARE_ALIGNED(16, %s, f20_0_8)[8][8][2] = {\n", TYPE_NAME);
|
||||
ARRAY_RENAME(3d_array)(f20_0_8, 8, 8, 2);
|
||||
printf("};\n");
|
||||
printf("static const DECLARE_ALIGNED(16, %s, f34_0_12)[12][8][2] = {\n", TYPE_NAME);
|
||||
ARRAY_RENAME(3d_array)(f34_0_12, 12, 8, 2);
|
||||
printf("};\n");
|
||||
printf("static const DECLARE_ALIGNED(16, %s, f34_1_8)[8][8][2] = {\n", TYPE_NAME);
|
||||
ARRAY_RENAME(3d_array)(f34_1_8, 8, 8, 2);
|
||||
printf("};\n");
|
||||
printf("static const DECLARE_ALIGNED(16, %s, f34_2_4)[4][8][2] = {\n", TYPE_NAME);
|
||||
ARRAY_RENAME(3d_array)(f34_2_4, 4, 8, 2);
|
||||
printf("};\n");
|
||||
|
||||
printf("static const DECLARE_ALIGNED(16, %s, Q_fract_allpass)[2][50][3][2] = {\n", TYPE_NAME);
|
||||
ARRAY_RENAME(4d_array)(Q_fract_allpass, 2, 50, 3, 2);
|
||||
printf("};\n");
|
||||
printf("static const DECLARE_ALIGNED(16, %s, phi_fract)[2][50][2] = {\n", TYPE_NAME);
|
||||
ARRAY_RENAME(3d_array)(phi_fract, 2, 50, 2);
|
||||
printf("};\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -157,7 +157,7 @@ static const int8_t k_to_i_34[] = {
|
||||
33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33
|
||||
};
|
||||
|
||||
static const INTFLOAT g1_Q2[] = {
|
||||
Q31(0.0f), Q31(0.01899487526049f), Q31(0.0f), Q31(-0.07293139167538f),
|
||||
Q31(0.0f), Q31(0.30596630545168f), Q31(0.5f)
|
||||
static const float g1_Q2[] = {
|
||||
0.0f, 0.01899487526049f, 0.0f, -0.07293139167538f,
|
||||
0.0f, 0.30596630545168f, 0.5f
|
||||
};
|
||||
|
||||
216
libavcodec/aacpsdsp.c
Normal file
216
libavcodec/aacpsdsp.c
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libavutil/attributes.h"
|
||||
#include "aacpsdsp.h"
|
||||
|
||||
static void ps_add_squares_c(float *dst, const float (*src)[2], int n)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
dst[i] += src[i][0] * src[i][0] + src[i][1] * src[i][1];
|
||||
}
|
||||
|
||||
static void ps_mul_pair_single_c(float (*dst)[2], float (*src0)[2], float *src1,
|
||||
int n)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n; i++) {
|
||||
dst[i][0] = src0[i][0] * src1[i];
|
||||
dst[i][1] = src0[i][1] * src1[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void ps_hybrid_analysis_c(float (*out)[2], float (*in)[2],
|
||||
const float (*filter)[8][2],
|
||||
int stride, int n)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
float sum_re = filter[i][6][0] * in[6][0];
|
||||
float sum_im = filter[i][6][0] * in[6][1];
|
||||
|
||||
for (j = 0; j < 6; j++) {
|
||||
float in0_re = in[j][0];
|
||||
float in0_im = in[j][1];
|
||||
float in1_re = in[12-j][0];
|
||||
float in1_im = in[12-j][1];
|
||||
sum_re += filter[i][j][0] * (in0_re + in1_re) -
|
||||
filter[i][j][1] * (in0_im - in1_im);
|
||||
sum_im += filter[i][j][0] * (in0_im + in1_im) +
|
||||
filter[i][j][1] * (in0_re - in1_re);
|
||||
}
|
||||
out[i * stride][0] = sum_re;
|
||||
out[i * stride][1] = sum_im;
|
||||
}
|
||||
}
|
||||
|
||||
static void ps_hybrid_analysis_ileave_c(float (*out)[32][2], float L[2][38][64],
|
||||
int i, int len)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (; i < 64; i++) {
|
||||
for (j = 0; j < len; j++) {
|
||||
out[i][j][0] = L[0][j][i];
|
||||
out[i][j][1] = L[1][j][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ps_hybrid_synthesis_deint_c(float out[2][38][64],
|
||||
float (*in)[32][2],
|
||||
int i, int len)
|
||||
{
|
||||
int n;
|
||||
|
||||
for (; i < 64; i++) {
|
||||
for (n = 0; n < len; n++) {
|
||||
out[0][n][i] = in[i][n][0];
|
||||
out[1][n][i] = in[i][n][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ps_decorrelate_c(float (*out)[2], float (*delay)[2],
|
||||
float (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2],
|
||||
const float phi_fract[2], const float (*Q_fract)[2],
|
||||
const float *transient_gain,
|
||||
float g_decay_slope,
|
||||
int len)
|
||||
{
|
||||
static const float a[] = { 0.65143905753106f,
|
||||
0.56471812200776f,
|
||||
0.48954165955695f };
|
||||
float ag[PS_AP_LINKS];
|
||||
int m, n;
|
||||
|
||||
for (m = 0; m < PS_AP_LINKS; m++)
|
||||
ag[m] = a[m] * g_decay_slope;
|
||||
|
||||
for (n = 0; n < len; n++) {
|
||||
float in_re = delay[n][0] * phi_fract[0] - delay[n][1] * phi_fract[1];
|
||||
float in_im = delay[n][0] * phi_fract[1] + delay[n][1] * phi_fract[0];
|
||||
for (m = 0; m < PS_AP_LINKS; m++) {
|
||||
float a_re = ag[m] * in_re;
|
||||
float a_im = ag[m] * in_im;
|
||||
float link_delay_re = ap_delay[m][n+2-m][0];
|
||||
float link_delay_im = ap_delay[m][n+2-m][1];
|
||||
float fractional_delay_re = Q_fract[m][0];
|
||||
float fractional_delay_im = Q_fract[m][1];
|
||||
float apd_re = in_re;
|
||||
float apd_im = in_im;
|
||||
in_re = link_delay_re * fractional_delay_re -
|
||||
link_delay_im * fractional_delay_im - a_re;
|
||||
in_im = link_delay_re * fractional_delay_im +
|
||||
link_delay_im * fractional_delay_re - a_im;
|
||||
ap_delay[m][n+5][0] = apd_re + ag[m] * in_re;
|
||||
ap_delay[m][n+5][1] = apd_im + ag[m] * in_im;
|
||||
}
|
||||
out[n][0] = transient_gain[n] * in_re;
|
||||
out[n][1] = transient_gain[n] * in_im;
|
||||
}
|
||||
}
|
||||
|
||||
static void ps_stereo_interpolate_c(float (*l)[2], float (*r)[2],
|
||||
float h[2][4], float h_step[2][4],
|
||||
int len)
|
||||
{
|
||||
float h0 = h[0][0];
|
||||
float h1 = h[0][1];
|
||||
float h2 = h[0][2];
|
||||
float h3 = h[0][3];
|
||||
float hs0 = h_step[0][0];
|
||||
float hs1 = h_step[0][1];
|
||||
float hs2 = h_step[0][2];
|
||||
float hs3 = h_step[0][3];
|
||||
int n;
|
||||
|
||||
for (n = 0; n < len; n++) {
|
||||
//l is s, r is d
|
||||
float l_re = l[n][0];
|
||||
float l_im = l[n][1];
|
||||
float r_re = r[n][0];
|
||||
float r_im = r[n][1];
|
||||
h0 += hs0;
|
||||
h1 += hs1;
|
||||
h2 += hs2;
|
||||
h3 += hs3;
|
||||
l[n][0] = h0 * l_re + h2 * r_re;
|
||||
l[n][1] = h0 * l_im + h2 * r_im;
|
||||
r[n][0] = h1 * l_re + h3 * r_re;
|
||||
r[n][1] = h1 * l_im + h3 * r_im;
|
||||
}
|
||||
}
|
||||
|
||||
static void ps_stereo_interpolate_ipdopd_c(float (*l)[2], float (*r)[2],
|
||||
float h[2][4], float h_step[2][4],
|
||||
int len)
|
||||
{
|
||||
float h00 = h[0][0], h10 = h[1][0];
|
||||
float h01 = h[0][1], h11 = h[1][1];
|
||||
float h02 = h[0][2], h12 = h[1][2];
|
||||
float h03 = h[0][3], h13 = h[1][3];
|
||||
float hs00 = h_step[0][0], hs10 = h_step[1][0];
|
||||
float hs01 = h_step[0][1], hs11 = h_step[1][1];
|
||||
float hs02 = h_step[0][2], hs12 = h_step[1][2];
|
||||
float hs03 = h_step[0][3], hs13 = h_step[1][3];
|
||||
int n;
|
||||
|
||||
for (n = 0; n < len; n++) {
|
||||
//l is s, r is d
|
||||
float l_re = l[n][0];
|
||||
float l_im = l[n][1];
|
||||
float r_re = r[n][0];
|
||||
float r_im = r[n][1];
|
||||
h00 += hs00;
|
||||
h01 += hs01;
|
||||
h02 += hs02;
|
||||
h03 += hs03;
|
||||
h10 += hs10;
|
||||
h11 += hs11;
|
||||
h12 += hs12;
|
||||
h13 += hs13;
|
||||
|
||||
l[n][0] = h00 * l_re + h02 * r_re - h10 * l_im - h12 * r_im;
|
||||
l[n][1] = h00 * l_im + h02 * r_im + h10 * l_re + h12 * r_re;
|
||||
r[n][0] = h01 * l_re + h03 * r_re - h11 * l_im - h13 * r_im;
|
||||
r[n][1] = h01 * l_im + h03 * r_im + h11 * l_re + h13 * r_re;
|
||||
}
|
||||
}
|
||||
|
||||
av_cold void ff_psdsp_init(PSDSPContext *s)
|
||||
{
|
||||
s->add_squares = ps_add_squares_c;
|
||||
s->mul_pair_single = ps_mul_pair_single_c;
|
||||
s->hybrid_analysis = ps_hybrid_analysis_c;
|
||||
s->hybrid_analysis_ileave = ps_hybrid_analysis_ileave_c;
|
||||
s->hybrid_synthesis_deint = ps_hybrid_synthesis_deint_c;
|
||||
s->decorrelate = ps_decorrelate_c;
|
||||
s->stereo_interpolate[0] = ps_stereo_interpolate_c;
|
||||
s->stereo_interpolate[1] = ps_stereo_interpolate_ipdopd_c;
|
||||
|
||||
if (ARCH_ARM)
|
||||
ff_psdsp_init_arm(s);
|
||||
if (ARCH_MIPS)
|
||||
ff_psdsp_init_mips(s);
|
||||
}
|
||||
@@ -21,37 +21,34 @@
|
||||
#ifndef LIBAVCODEC_AACPSDSP_H
|
||||
#define LIBAVCODEC_AACPSDSP_H
|
||||
|
||||
#include "aac_defines.h"
|
||||
|
||||
#define PS_QMF_TIME_SLOTS 32
|
||||
#define PS_AP_LINKS 3
|
||||
#define PS_MAX_AP_DELAY 5
|
||||
|
||||
typedef struct PSDSPContext {
|
||||
void (*add_squares)(INTFLOAT *dst, const INTFLOAT (*src)[2], int n);
|
||||
void (*mul_pair_single)(INTFLOAT (*dst)[2], INTFLOAT (*src0)[2], INTFLOAT *src1,
|
||||
void (*add_squares)(float *dst, const float (*src)[2], int n);
|
||||
void (*mul_pair_single)(float (*dst)[2], float (*src0)[2], float *src1,
|
||||
int n);
|
||||
void (*hybrid_analysis)(INTFLOAT (*out)[2], INTFLOAT (*in)[2],
|
||||
const INTFLOAT (*filter)[8][2],
|
||||
void (*hybrid_analysis)(float (*out)[2], float (*in)[2],
|
||||
const float (*filter)[8][2],
|
||||
int stride, int n);
|
||||
void (*hybrid_analysis_ileave)(INTFLOAT (*out)[32][2], INTFLOAT L[2][38][64],
|
||||
void (*hybrid_analysis_ileave)(float (*out)[32][2], float L[2][38][64],
|
||||
int i, int len);
|
||||
void (*hybrid_synthesis_deint)(INTFLOAT out[2][38][64], INTFLOAT (*in)[32][2],
|
||||
void (*hybrid_synthesis_deint)(float out[2][38][64], float (*in)[32][2],
|
||||
int i, int len);
|
||||
void (*decorrelate)(INTFLOAT (*out)[2], INTFLOAT (*delay)[2],
|
||||
INTFLOAT (*ap_delay)[PS_QMF_TIME_SLOTS+PS_MAX_AP_DELAY][2],
|
||||
const INTFLOAT phi_fract[2], const INTFLOAT (*Q_fract)[2],
|
||||
const INTFLOAT *transient_gain,
|
||||
INTFLOAT g_decay_slope,
|
||||
void (*decorrelate)(float (*out)[2], float (*delay)[2],
|
||||
float (*ap_delay)[PS_QMF_TIME_SLOTS+PS_MAX_AP_DELAY][2],
|
||||
const float phi_fract[2], const float (*Q_fract)[2],
|
||||
const float *transient_gain,
|
||||
float g_decay_slope,
|
||||
int len);
|
||||
void (*stereo_interpolate[2])(INTFLOAT (*l)[2], INTFLOAT (*r)[2],
|
||||
INTFLOAT h[2][4], INTFLOAT h_step[2][4],
|
||||
void (*stereo_interpolate[2])(float (*l)[2], float (*r)[2],
|
||||
float h[2][4], float h_step[2][4],
|
||||
int len);
|
||||
} PSDSPContext;
|
||||
|
||||
void AAC_RENAME(ff_psdsp_init)(PSDSPContext *s);
|
||||
void ff_psdsp_init(PSDSPContext *s);
|
||||
void ff_psdsp_init_arm(PSDSPContext *s);
|
||||
void ff_psdsp_init_mips(PSDSPContext *s);
|
||||
void ff_psdsp_init_x86(PSDSPContext *s);
|
||||
|
||||
#endif /* LIBAVCODEC_AACPSDSP_H */
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* 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 "aacpsdsp_template.c"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user