mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-07 23:40:01 +01:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0723b7e4e | ||
|
|
6fbd4d2285 | ||
|
|
fa511b03d3 | ||
|
|
5767941df8 | ||
|
|
e6584a3f19 | ||
|
|
e8a51675ea | ||
|
|
1c06f776e6 | ||
|
|
e95f80c8df | ||
|
|
6a78425604 | ||
|
|
288ef1939f | ||
|
|
cd894807fe | ||
|
|
22878e8177 | ||
|
|
d6a1e5980b | ||
|
|
83feded492 | ||
|
|
2720715dab | ||
|
|
e04cb59ecc | ||
|
|
b21d387d6f |
1
.mailmap
1
.mailmap
@@ -1,3 +1,4 @@
|
||||
<james.darnley@gmail.com> <jdarnley@obe.tv>
|
||||
<jeebjp@gmail.com> <jan.ekstrom@aminocom.com>
|
||||
<sw@jkqxz.net> <mrt@jkqxz.net>
|
||||
<u@pkh.me> <cboesch@gopro.com>
|
||||
|
||||
4
CREDITS
4
CREDITS
@@ -1,6 +1,6 @@
|
||||
See the Git history of the project (https://git.ffmpeg.org/ffmpeg) to
|
||||
See the Git history of the project (git://source.ffmpeg.org/ffmpeg) to
|
||||
get the names of people who have contributed to FFmpeg.
|
||||
|
||||
To check the log, you can type the command "git log" in the FFmpeg
|
||||
source directory, or browse the online repository at
|
||||
https://git.ffmpeg.org/ffmpeg
|
||||
http://source.ffmpeg.org.
|
||||
|
||||
230
Changelog
230
Changelog
@@ -1,235 +1,8 @@
|
||||
Entries are sorted chronologically from oldest to youngest within each release,
|
||||
releases are sorted from youngest to oldest.
|
||||
|
||||
version 6.0.1:
|
||||
avcodec/4xm: Check for cfrm exhaustion
|
||||
avformat/mov: Disallow FTYP after streams
|
||||
doc/html: fix styling issue with Texinfo 7.0
|
||||
doc/html: support texinfo 7.0
|
||||
Changelog: update
|
||||
avformat/lafdec: Check for 0 parameters
|
||||
avformat/lafdec: Check for 0 parameters
|
||||
avfilter/buffersink: fix order of operation with = and <0
|
||||
avfilter/framesync: fix order of operation with = and <0
|
||||
tools/target_dec_fuzzer: Adjust threshold for CSCD
|
||||
avcodec/dovi_rpu: Use 64 bit in get_us/se_coeff()
|
||||
avformat/mov: Check that is_still_picture_avif has no trak based streams
|
||||
avformat/matroskadec: Fix declaration-after-statement warnings
|
||||
Update for FFmpeg 6.0.1
|
||||
fftools/ffmpeg_mux_init: Restrict disabling automatic copying of metadata
|
||||
avformat/rtsp: Use rtsp_st->stream_index
|
||||
avformat/rtsp: Use rtsp_st->stream_index
|
||||
avutil/tx_template: fix integer ovberflwo in fft3()
|
||||
avcodec/jpeg2000dec: Check image offset
|
||||
avformat/mxfdec: Check klv offset
|
||||
libavutil/ppc/cpu.c: check that AT_HWCAP2 is defined
|
||||
avcodec/h2645_parse: Avoid EAGAIN
|
||||
avcodec/xvididct: Make c* unsigned to avoid undefined overflows
|
||||
avcodec/bonk: Fix undefined overflow in predictor_calc_error()
|
||||
avformat/tmv: Check video chunk size
|
||||
avcodec/h264_parser: saturate dts a bit
|
||||
avformat/asfdec_f: Saturate presentation time in marker
|
||||
avformat/xwma: sanity check bits_per_coded_sample
|
||||
avformat/matroskadec: Check prebuffered_ns for overflow
|
||||
avformat/wavdec: Check left avio_tell for overflow
|
||||
avformat/tta: Better totalframes check
|
||||
avformat/rpl: Check for number_of_chunks overflow
|
||||
avformat/mov: compute absolute dts difference without overflow in mov_find_next_sample()
|
||||
avformat/jacosubdec: Check timeres
|
||||
avformat/jacosubdec: avoid signed integer overflows in get_shift()
|
||||
avformat/jacosubdec: Factorize code in get_shift() a bit
|
||||
avformat/sbgdec: Check for negative duration or un-representable end pts
|
||||
avcodec/escape124: Do not return random numbers
|
||||
avcodec/apedec: Fix an integer overflow in predictor_update_filter()
|
||||
tools/target_dec_fuzzer: Adjust wmapro threshold
|
||||
avcodec/wavarc: Allocate AV_INPUT_BUFFER_PADDING_SIZE
|
||||
avcodec/wavarc: Fix integer overflwo in do_stereo()
|
||||
avutil/tx_template: Fix some signed integer overflows in DECL_FFT5()
|
||||
avcodec/aacdec_template: Better avoidance of signed integer overflow in imdct_and_windowing_eld()
|
||||
tools/target_dec_fuzzer: Adjust threshold for MVHA
|
||||
avformat/avs: Check if return code is representable
|
||||
avcodec/flacdec: Fix integer overflow in "33bit" DECODER_SUBFRAME_FIXED_WIDE()
|
||||
avcodec/flacdec: Fix overflow in "33bit" decorrelate
|
||||
avcodec/lcldec: Make PNG filter addressing match the code afterwards
|
||||
avformat/westwood_vqa: Check chunk size
|
||||
avformat/sbgdec: Check for period overflow
|
||||
avformat/concatdec: Check in/outpoint for overflow
|
||||
avformat/mov: Check avif_info
|
||||
avformat/mxfdec: Remove this_partition
|
||||
avcodec/xvididct: Fix integer overflow in idct_row()
|
||||
avcodec/celp_math: avoid overflow in shift
|
||||
tools/target_dec_fuzzer: Adjust threshold for rtv1
|
||||
avformat/hls: reduce default max reload to 3
|
||||
avformat/format: Stop reading data at EOF during probing
|
||||
avcodec/bonk: Fix integer overflow in predictor_calc_error()
|
||||
avcodec/jpeg2000dec: jpeg2000 has its own lowres option
|
||||
avcodec/huffyuvdec: avoid undefined behavior with get_vlc2() failure
|
||||
avcodec/cscd: Fix "CamStudio Lossless Codec 1.0" gzip files
|
||||
avcodec/cscd: Check for CamStudio Lossless Codec 1.0 behavior in end check of LZO files
|
||||
avcodec/mpeg4videodec: consider lowres in dest_pcm[]
|
||||
avcodec/hevcdec: Fix undefined memcpy()
|
||||
avcodec/mpeg4videodec: more unsigned in amv computation
|
||||
avcodec/tta: fix signed overflow in decorrelate
|
||||
avcodec/apedec: remove unused variable
|
||||
avcodec/apedec: Fix 48khz 24bit below insane level
|
||||
avcodec/apedec: Fix CRC for 24bps and bigendian
|
||||
avcodec/wavarc: Check that nb_samples is not negative
|
||||
avcodec/wavarc: Check shift
|
||||
avcodec/xvididct: Fix integer overflow in idct_row()
|
||||
avformat/avr: Check sample rate
|
||||
avformat/imf_cpl: Replace NULL content_title_utf8 by ""
|
||||
avformat/imf_cpl: xmlNodeListGetString() can return NULL
|
||||
avcodec/aacdec_template: Fix undefined signed interger operations
|
||||
avcodec/wavarc: Fix k limit
|
||||
avcodec/rka: Fix integer overflow in decode_filter()
|
||||
avformat/rka: bps < 8 is invalid
|
||||
avcodec/pcm: allow Changing parameters
|
||||
avutil/tx_template: extend to 2M
|
||||
avcodec/jpeg2000dec: Check for reduction factor and image offset
|
||||
avutil/softfloat: Basic documentation for av_sincos_sf()
|
||||
avutil/softfloat: fix av_sincos_sf()
|
||||
tools/target_dec_fuzzer: Adjust threshold for speex
|
||||
avcodec/utils: fix 2 integer overflows in get_audio_frame_duration()
|
||||
avcodec/hevcdec: Avoid null pointer dereferences in MC
|
||||
avcodec/takdsp: Fix integer overflows
|
||||
avcodec/mpegvideo_dec: consider interlaced lowres 4:2:0 chroma in edge emulation check better
|
||||
avcodec/rka: use unsigned for buf0 additions
|
||||
avcodec/rka: Avoid undefined left shift
|
||||
avcodec: Ignoring errors is only possible before the input end
|
||||
avformat/jpegxl_probe: Forward error codes
|
||||
avformat/jpegxl_probe: check length instead of blindly reading
|
||||
avformat/jpegxl_probe: Remove intermediate macro obfuscation around get_bits*()
|
||||
avcodec/noise_bsf: Check for wrapped frames
|
||||
avformat/oggparsetheora: clip duration within 64bit
|
||||
avcodec/rka: avoid undefined multiply in cmode==0
|
||||
avcodec/rka: use 64bit for srate_pad computation
|
||||
avcodec/bonk: Avoid undefined integer overflow in predictor_calc_error()
|
||||
avformat/wavdec: Check that smv block fits in available space
|
||||
avcodec/adpcm: Fix integer overflow in intermediate in ADPCM_XMD
|
||||
avcodec/dpcm: fix undefined interger overflow in wady
|
||||
avcodec/tiff: add a zero DNG_LINEARIZATION_TABLE check
|
||||
avcodec/tak: Check remaining bits in ff_tak_decode_frame_header()
|
||||
avcodec/sonic: Fix two undefined integer overflows
|
||||
avcodec/utils: the IFF_ILBM implementation assumes that there are a multiple of 16 allocated
|
||||
avcodec/flacdec: Fix signed integre overflow
|
||||
avcodec/exr: Cleanup befor return
|
||||
avcodec/pngdec: Do not pass AVFrame into global header decode
|
||||
avcodec/pngdec: remove AVFrame argument from decode_iccp_chunk()
|
||||
avcodec/wavarc: Check order before using it to write the list
|
||||
avcodec/bonk: decode multiple passes in intlist_read() at once
|
||||
avcodec/vorbisdec: Check codebook float values to be finite
|
||||
avcodec/g2meet: Replace fake allocation avoidance for framebuf
|
||||
avutil/tx_priv: Use unsigned in BF() to avoid signed overflows
|
||||
avcodec/lcldec: More space for rgb24
|
||||
avcodec/lcldec: Support 4:1:1 and 4:2:2 with odd width
|
||||
libavcodec/lcldec: width and height should not be unsigned
|
||||
avformat/imf: fix invalid resource handling
|
||||
avcodec/escape124: Check that blocks are allocated before use
|
||||
avcodec/rka: Fix signed integer overflow in decode_filter()
|
||||
avcodec/huffyuvdec: Fix undefined behavior with shift
|
||||
avcodec/j2kenc: Replace RGB24 special case by generic test
|
||||
avcodec/j2kenc: Replace BGR48 / GRAY16 test by test for number of bits
|
||||
avcodec/j2kenc: simplify pixel format setup
|
||||
avcodec/j2kenc: Fix funky bpno errors on decoding
|
||||
avcodec/j2kenc: remove misleading pred value
|
||||
avcodec/j2kenc: fix 5/3 DWT identifer
|
||||
avcodec/vp3: Check width to avoid assertion failure
|
||||
avcodec/g729postfilter: Limit shift in long term filter
|
||||
avcodec/wavarc: Fix several integer overflows
|
||||
avcodec/tests/snowenc: Fix 2nd test
|
||||
avcodec/tests/snowenc: return a failure if DWT/IDWT mismatches
|
||||
avcodec/snowenc: Fix visual weight calculation
|
||||
avcodec/tests/snowenc: unbreak DWT tests
|
||||
avcodec/mpeg12dec: Check input size
|
||||
avcodec/escape124: Fix some return codes
|
||||
avcodec/escape124: fix signdness of end of input check
|
||||
Use https for repository links
|
||||
avcodec/nvdec_hevc: fail to initialize on unsupported profiles
|
||||
fftools/ffmpeg_enc: apply -top to individual encoded frames
|
||||
avcodec/on2avc: use correct fft sizes
|
||||
avcodec/on2avc: use the matching AVTX context for the 512 sized iMDCT
|
||||
examples: fix build of mux and resample_audio
|
||||
avcodec/nvenc: stop using deprecated rc modes with SDK 12.1
|
||||
configure: use non-deprecated nvenc GUID for conftest
|
||||
avcodec/x86/mathops: clip constants used with shift instructions within inline assembly
|
||||
avfilter/vsrc_ddagrab: calculate pointer position on rotated screens
|
||||
avfilter/vsrc_ddagrab: account for mouse-only frames during probing
|
||||
avcodec/aac_ac3_parser: add preprocessor checks for codec specific code
|
||||
avcodec/nvenc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
|
||||
Revert "lavc/nvenc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE"
|
||||
Revert "avcodec/nvenc: fix b-frame DTS behavior with fractional framerates"
|
||||
avcodec/vdpau_mpeg4: fix order of quant matrix coefficients
|
||||
avcodec/vdpau_mpeg12: fix order of quant matrix coefficients
|
||||
avcodec/nvdec_mpeg4: fix order of quant matrix coefficients
|
||||
avcodec/nvdec_mpeg2: fix order of quant matrix coefficients
|
||||
fftools/ffmpeg_filter: fix leak of AVIOContext in read_binary()
|
||||
fftools/ffmpeg: avoid possible invalid reads with short -tag values
|
||||
avcodec/mp_cmp: reject invalid comparison function values
|
||||
avcodec/aacpsy: clip global_quality within the psy_vbr_map array boundaries
|
||||
avutil/wchar_filename: propagate MultiByteToWideChar() and WideCharToMultiByte() failures
|
||||
avformat/concatf: check if any nodes were allocated
|
||||
avcodec/nvenc: fix b-frame DTS behavior with fractional framerates
|
||||
avcodec/vorbisdec: export skip_samples instead of dropping frames
|
||||
fftools/ffmpeg_mux_init: avoid invalid reads in forced keyframe parsing
|
||||
lavfi/vf_vpp_qsv: set the right timestamp for AVERROR_EOF
|
||||
avfilter/vf_untile: swap the chroma shift values used for plane offsets
|
||||
lavc/decode: stop mangling last_pkt_props->opaque
|
||||
avcodec/nvenc: avoid failing b_ref_mode check when unset
|
||||
lavu/vulkan: fix handle type for 32-bit targets
|
||||
vulkan: Fix win/i386 calling convention
|
||||
avfilter/graphparser: fix filter instance name when an id is provided
|
||||
avcodec/aacps_tablegen: fix build error after avutil bump
|
||||
avcodec/nvenc: fix potential NULL pointer dereference
|
||||
|
||||
|
||||
version 6.0:
|
||||
- Radiance HDR image support
|
||||
- ddagrab (Desktop Duplication) video capture filter
|
||||
- ffmpeg -shortest_buf_duration option
|
||||
- ffmpeg now requires threading to be built
|
||||
- ffmpeg now runs every muxer in a separate thread
|
||||
- Add new mode to cropdetect filter to detect crop-area based on motion vectors and edges
|
||||
- VAAPI decoding and encoding for 10/12bit 422, 10/12bit 444 HEVC and VP9
|
||||
- WBMP (Wireless Application Protocol Bitmap) image format
|
||||
- a3dscope filter
|
||||
- bonk decoder and demuxer
|
||||
- Micronas SC-4 audio decoder
|
||||
- LAF demuxer
|
||||
- APAC decoder and demuxer
|
||||
- Media 100i decoders
|
||||
- DTS to PTS reorder bsf
|
||||
- ViewQuest VQC decoder
|
||||
- backgroundkey filter
|
||||
- nvenc AV1 encoding support
|
||||
- MediaCodec decoder via NDKMediaCodec
|
||||
- MediaCodec encoder
|
||||
- oneVPL support for QSV
|
||||
- QSV AV1 encoder
|
||||
- QSV decoding and encoding for 10/12bit 422, 10/12bit 444 HEVC and VP9
|
||||
- showcwt multimedia filter
|
||||
- corr video filter
|
||||
- adrc audio filter
|
||||
- afdelaysrc audio filter
|
||||
- WADY DPCM decoder and demuxer
|
||||
- CBD2 DPCM decoder
|
||||
- ssim360 video filter
|
||||
- ffmpeg CLI new options: -stats_enc_pre[_fmt], -stats_enc_post[_fmt],
|
||||
-stats_mux_pre[_fmt]
|
||||
- hstack_vaapi, vstack_vaapi and xstack_vaapi filters
|
||||
- XMD ADPCM decoder and demuxer
|
||||
- media100 to mjpegb bsf
|
||||
- ffmpeg CLI new option: -fix_sub_duration_heartbeat
|
||||
- WavArc decoder and demuxer
|
||||
- CrystalHD decoders deprecated
|
||||
- SDNS demuxer
|
||||
- RKA decoder and demuxer
|
||||
- filtergraph syntax in ffmpeg CLI now supports passing file contents
|
||||
as option values, by prefixing option name with '/'
|
||||
- hstack_qsv, vstack_qsv and xstack_qsv filters
|
||||
|
||||
|
||||
version 5.1:
|
||||
- add ipfs/ipns gateway support
|
||||
- add ipfs/ipns protocol support
|
||||
- dialogue enhance audio filter
|
||||
- dropped obsolete XvMC hwaccel
|
||||
- pcm-bluray encoder
|
||||
@@ -252,7 +25,6 @@ version 5.1:
|
||||
- PHM image format support
|
||||
- remap_opencl filter
|
||||
- added chromakey_cuda filter
|
||||
- added bilateral_cuda filter
|
||||
|
||||
|
||||
version 5.0:
|
||||
|
||||
19
MAINTAINERS
19
MAINTAINERS
@@ -11,11 +11,17 @@ A (CC <address>) after the name means that the maintainer prefers to be CC-ed on
|
||||
patches and related discussions.
|
||||
|
||||
|
||||
Project Leader
|
||||
==============
|
||||
|
||||
final design decisions
|
||||
|
||||
|
||||
Applications
|
||||
============
|
||||
|
||||
ffmpeg:
|
||||
ffmpeg.c Michael Niedermayer, Anton Khirnov
|
||||
ffmpeg.c Michael Niedermayer
|
||||
|
||||
ffplay:
|
||||
ffplay.c Marton Balint
|
||||
@@ -34,8 +40,7 @@ Miscellaneous Areas
|
||||
===================
|
||||
|
||||
documentation Stefano Sabatini, Mike Melanson, Timothy Gu, Gyan Doshi
|
||||
project server day to day operations Árpád Gereöffy, Michael Niedermayer, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov
|
||||
project server emergencies Árpád Gereöffy, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov
|
||||
project server Árpád Gereöffy, Michael Niedermayer, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov
|
||||
presets Robert Swain
|
||||
metadata subsystem Aurelien Jacobs
|
||||
release management Michael Niedermayer
|
||||
@@ -110,6 +115,8 @@ Generic Parts:
|
||||
lzw.* Michael Niedermayer
|
||||
floating point AAN DCT:
|
||||
faandct.c, faandct.h Michael Niedermayer
|
||||
Non-power-of-two MDCT:
|
||||
mdct15.c, mdct15.h Rostislav Pehlivanov
|
||||
Golomb coding:
|
||||
golomb.c, golomb.h Michael Niedermayer
|
||||
motion estimation:
|
||||
@@ -134,7 +141,6 @@ Codecs:
|
||||
adpcm.c Zane van Iperen
|
||||
alacenc.c Jaikrishnan Menon
|
||||
alsdec.c Thilo Borgmann, Umair Khan
|
||||
amfenc* Dmitrii Ovchinnikov
|
||||
aptx.c Aurelien Jacobs
|
||||
ass* Aurelien Jacobs
|
||||
asv* Michael Niedermayer
|
||||
@@ -151,6 +157,7 @@ Codecs:
|
||||
ccaption_dec.c Anshul Maheshwari, Aman Gupta
|
||||
cljr Alex Beregszaszi
|
||||
cpia.c Stephan Hilb
|
||||
crystalhd.c Philip Langdale
|
||||
cscd.c Reimar Doeffinger
|
||||
cuviddec.c Timo Rothenpieler
|
||||
dca* foo86
|
||||
@@ -264,6 +271,7 @@ Codecs:
|
||||
xwd* Paul B Mahol
|
||||
|
||||
Hardware acceleration:
|
||||
crystalhd.c Philip Langdale
|
||||
dxva2* Hendrik Leppkes, Laurent Aimar, Steve Lhomme
|
||||
d3d11va* Steve Lhomme
|
||||
mediacodec* Matthieu Bouron, Aman Gupta
|
||||
@@ -427,7 +435,6 @@ Muxers/Demuxers:
|
||||
idcin.c Mike Melanson
|
||||
idroqdec.c Mike Melanson
|
||||
iff.c Jaikrishnan Menon
|
||||
imf* Pierre-Anthony Lemieux
|
||||
img2*.c Michael Niedermayer
|
||||
ipmovie.c Mike Melanson
|
||||
ircam* Paul B Mahol
|
||||
@@ -618,14 +625,12 @@ Leo Izen (thebombzen) B6FD 3CFC 7ACF 83FC 9137 6945 5A71 C331 FD2F A19A
|
||||
Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE
|
||||
Lynne FE50 139C 6805 72CA FD52 1F8D A2FE A5F0 3F03 4464
|
||||
Michael Niedermayer 9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB
|
||||
DD1E C9E8 DE08 5C62 9B3E 1846 B18E 8928 B394 8D64
|
||||
Nicolas George 24CE 01CE 9ACC 5CEB 74D8 8D9D B063 D997 36E5 4C93
|
||||
Niklas Haas (haasn) 1DDB 8076 B14D 5B48 32FC 99D9 EB52 DA9C 02BA 6FB4
|
||||
Nikolay Aleksandrov 8978 1D8C FB71 588E 4B27 EAA8 C4F0 B5FC E011 13B1
|
||||
Panagiotis Issaris 6571 13A3 33D9 3726 F728 AA98 F643 B12E ECF3 E029
|
||||
Peter Ross A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B
|
||||
Philip Langdale 5DC5 8D66 5FBA 3A43 18EC 045E F8D6 B194 6A75 682E
|
||||
Pierre-Anthony Lemieux (pal) F4B3 9492 E6F2 E4AF AEC8 46CB 698F A1F0 F8D4 EED4
|
||||
Ramiro Polla 7859 C65B 751B 1179 792E DAE8 8E95 8B2F 9B6C 5700
|
||||
Reimar Doeffinger C61D 16E5 9E2C D10C 8958 38A4 0899 A2B9 06D4 D9C7
|
||||
Reinhard Tartler 9300 5DC2 7E87 6C37 ED7B CA9A 9808 3544 9453 48A4
|
||||
|
||||
2
Makefile
2
Makefile
@@ -91,7 +91,7 @@ ffbuild/.config: $(CONFIGURABLE_COMPONENTS)
|
||||
SUBDIR_VARS := CLEANFILES FFLIBS HOSTPROGS TESTPROGS TOOLS \
|
||||
HEADERS ARCH_HEADERS BUILT_HEADERS SKIPHEADERS \
|
||||
ARMV5TE-OBJS ARMV6-OBJS ARMV8-OBJS VFP-OBJS NEON-OBJS \
|
||||
ALTIVEC-OBJS VSX-OBJS RVV-OBJS MMX-OBJS X86ASM-OBJS \
|
||||
ALTIVEC-OBJS VSX-OBJS MMX-OBJS X86ASM-OBJS \
|
||||
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSP-OBJS MSA-OBJS \
|
||||
MMI-OBJS LSX-OBJS LASX-OBJS OBJS SLIBOBJS SHLIBOBJS \
|
||||
STLIBOBJS HOSTOBJS TESTOBJS
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
|
||||
┌────────────────────────────────────────────┐
|
||||
│ RELEASE NOTES for FFmpeg 6.0 "Von Neumann" │
|
||||
│ RELEASE NOTES for FFmpeg 5.1 "Riemann" LTS │
|
||||
└────────────────────────────────────────────┘
|
||||
|
||||
The FFmpeg Project proudly presents FFmpeg 6.0 "Von Neumann", about 6
|
||||
months after the release of FFmpeg 5.1.
|
||||
The FFmpeg Project proudly presents FFmpeg 5.1 "Riemann" LTS, about 6
|
||||
months after the release of FFmpeg 5.0, our first Long Term Support
|
||||
release. While several past FFmpeg releases have enjoyed long term
|
||||
support, this is the first release where such an intention is made
|
||||
clear at release.
|
||||
|
||||
A complete Changelog is available at the root of the project, and the
|
||||
complete Git history on https://git.ffmpeg.org/gitweb/ffmpeg.git
|
||||
|
||||
@@ -187,6 +187,5 @@ static inline __device__ float __saturatef(float a) { return __nvvm_saturate_f(a
|
||||
static inline __device__ float __sinf(float a) { return __nvvm_sin_approx_f(a); }
|
||||
static inline __device__ float __cosf(float a) { return __nvvm_cos_approx_f(a); }
|
||||
static inline __device__ float __expf(float a) { return __nvvm_ex2_approx_f(a * (float)__builtin_log2(__builtin_exp(1))); }
|
||||
static inline __device__ float __powf(float a, float b) { return __nvvm_ex2_approx_f(__nvvm_lg2_approx_f(a) * b); }
|
||||
|
||||
#endif /* COMPAT_CUDA_CUDA_RUNTIME_H */
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$1" = "--version" ]; then
|
||||
rc.exe -?
|
||||
exit $?
|
||||
fi
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
echo "Usage: mswindres [-I/include/path ...] [-DSOME_DEFINE ...] [-o output.o] input.rc [output.o]" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
EXTRA_OPTS="-nologo"
|
||||
|
||||
while [ $# -gt 2 ]; do
|
||||
case $1 in
|
||||
-D*) EXTRA_OPTS="$EXTRA_OPTS -d$(echo $1 | sed -e "s/^..//" -e "s/ /\\\\ /g")" ;;
|
||||
-I*) EXTRA_OPTS="$EXTRA_OPTS -i$(echo $1 | sed -e "s/^..//" -e "s/ /\\\\ /g")" ;;
|
||||
-o) OPT_OUT="$2"; shift ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
IN="$1"
|
||||
if [ -z "$OPT_OUT" ]; then
|
||||
OUT="$2"
|
||||
else
|
||||
OUT="$OPT_OUT"
|
||||
fi
|
||||
|
||||
eval set -- $EXTRA_OPTS
|
||||
rc.exe "$@" -fo "$OUT" "$IN"
|
||||
147
doc/APIchanges
147
doc/APIchanges
@@ -1,140 +1,19 @@
|
||||
The last version increases of all libraries were on 2023-02-09
|
||||
Never assume the API of libav* to be stable unless at least 1 month has passed
|
||||
since the last major version increase or the API was added.
|
||||
|
||||
The last version increases were:
|
||||
libavcodec: 2021-04-27
|
||||
libavdevice: 2021-04-27
|
||||
libavfilter: 2021-04-27
|
||||
libavformat: 2021-04-27
|
||||
libpostproc: 2021-04-27
|
||||
libswresample: 2021-04-27
|
||||
libswscale: 2021-04-27
|
||||
libavutil: 2021-04-27
|
||||
|
||||
|
||||
API changes, most recent first:
|
||||
|
||||
-------- 8< --------- FFmpeg 6.0 was cut here -------- 8< ---------
|
||||
|
||||
2023-02-16 - 927042b409 - lavf 60.2.100 - avformat.h
|
||||
Deprecate AVFormatContext io_close callback.
|
||||
The superior io_close2 callback should be used instead.
|
||||
|
||||
2023-02-13 - 2296078397 - lavu 58.1.100 - frame.h
|
||||
Deprecate AVFrame.coded_picture_number and display_picture_number.
|
||||
Their usefulness is questionable and very few decoders set them.
|
||||
|
||||
2023-02-13 - 6b6f7db819 - lavc 60.2.100 - avcodec.h
|
||||
Add AVCodecContext.frame_num as a 64bit version of frame_number.
|
||||
Deprecate AVCodecContext.frame_number.
|
||||
|
||||
2023-02-12 - d1b9a3ddb4 - lavfi 9.1.100 - avfilter.h
|
||||
Add filtergraph segment parsing API.
|
||||
New structs:
|
||||
- AVFilterGraphSegment
|
||||
- AVFilterChain
|
||||
- AVFilterParams
|
||||
- AVFilterPadParams
|
||||
New functions:
|
||||
- avfilter_graph_segment_parse()
|
||||
- avfilter_graph_segment_create_filters()
|
||||
- avfilter_graph_segment_apply_opts()
|
||||
- avfilter_graph_segment_init()
|
||||
- avfilter_graph_segment_link()
|
||||
- avfilter_graph_segment_apply()
|
||||
|
||||
2023-02-09 - 719a93f4e4 - lavu 58.0.100 - csp.h
|
||||
Add av_csp_approximate_trc_gamma() and av_csp_trc_func_from_id().
|
||||
Add av_csp_trc_function.
|
||||
|
||||
2023-02-09 - 868a31b42d - lavc 60.0.100 - avcodec.h
|
||||
avcodec_decode_subtitle2() now accepts const AVPacket*.
|
||||
|
||||
2023-02-04 - d02340b9e3 - lavc 59.63.100
|
||||
Allow AV_CODEC_FLAG_COPY_OPAQUE to be used with decoders.
|
||||
|
||||
2023-01-29 - a1a80f2e64 - lavc 59.59.100 - avcodec.h
|
||||
Add AV_CODEC_FLAG_COPY_OPAQUE and AV_CODEC_FLAG_FRAME_DURATION.
|
||||
|
||||
2023-01-13 - 002d0ec740 - lavu 57.44.100 - ambient_viewing_environment.h frame.h
|
||||
Adds a new structure for holding H.274 Ambient Viewing Environment metadata,
|
||||
AVAmbientViewingEnvironment.
|
||||
Adds a new AVFrameSideDataType entry AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT
|
||||
for it.
|
||||
|
||||
2022-12-10 - 7a8d78f7e3 - lavc 59.55.100 - avcodec.h
|
||||
Add AV_HWACCEL_FLAG_UNSAFE_OUTPUT.
|
||||
|
||||
2022-11-24 - e97368eba5 - lavu 57.43.100 - tx.h
|
||||
Add AV_TX_FLOAT_DCT, AV_TX_DOUBLE_DCT and AV_TX_INT32_DCT.
|
||||
|
||||
2022-11-06 - 9dad237928 - lavu 57.42.100 - dict.h
|
||||
Add av_dict_iterate().
|
||||
|
||||
2022-11-03 - 6228ba141d - lavu 57.41.100 - channel_layout.h
|
||||
Add AV_CH_LAYOUT_7POINT1_TOP_BACK and AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK.
|
||||
|
||||
2022-10-30 - 83e918de71 - lavu 57.40.100 - channel_layout.h
|
||||
Add AV_CH_LAYOUT_CUBE and AV_CHANNEL_LAYOUT_CUBE.
|
||||
|
||||
2022-10-11 - 479747645f - lavu 57.39.101 - pixfmt.h
|
||||
Add AV_PIX_FMT_RGBF32 and AV_PIX_FMT_RGBAF32.
|
||||
|
||||
2022-10-05 - 37d5ddc317 - lavu 57.39.100 - cpu.h
|
||||
Add AV_CPU_FLAG_RVB_BASIC.
|
||||
|
||||
2022-10-03 - d09776d486 - lavf 59.34.100 - avio.h
|
||||
Make AVIODirContext an opaque type in a future major version bump.
|
||||
|
||||
2022-09-27 - 0c0a3deb18 - lavu 57.38.100 - cpu.h
|
||||
Add CPU flags for RISC-V vector extensions:
|
||||
AV_CPU_FLAG_RVV_I32, AV_CPU_FLAG_RVV_F32, AV_CPU_FLAG_RVV_I64,
|
||||
AV_CPU_FLAG_RVV_F64
|
||||
|
||||
2022-09-26 - a02a0e8db4 - lavc 59.48.100 - avcodec.h
|
||||
Deprecate avcodec_enum_to_chroma_pos() and avcodec_chroma_pos_to_enum().
|
||||
Use av_chroma_location_enum_to_pos() or av_chroma_location_pos_to_enum()
|
||||
instead.
|
||||
|
||||
2022-09-26 - xxxxxxxxxx - lavu 57.37.100 - pixdesc.h pixfmt.h
|
||||
Add av_chroma_location_enum_to_pos() and av_chroma_location_pos_to_enum().
|
||||
Add AV_PIX_FMT_RGBF32BE, AV_PIX_FMT_RGBF32LE, AV_PIX_FMT_RGBAF32BE,
|
||||
AV_PIX_FMT_RGBAF32LE.
|
||||
|
||||
2022-09-26 - cf856d8957 - lavc 59.47.100 - avcodec.h defs.h
|
||||
Move the AV_EF_* and FF_COMPLIANCE_* defines from avcodec.h to defs.h.
|
||||
|
||||
2022-09-03 - d75c4693fe - lavu 57.36.100 - pixfmt.h
|
||||
Add AV_PIX_FMT_P012, AV_PIX_FMT_Y212, AV_PIX_FMT_XV30, AV_PIX_FMT_XV36
|
||||
|
||||
2022-09-03 - dea9744560 - lavu 57.35.100 - file.h
|
||||
Deprecate av_tempfile() without replacement.
|
||||
|
||||
2022-08-03 - cc5a5c9860 - lavu 57.34.100 - pixfmt.h
|
||||
Add AV_PIX_FMT_VUYX.
|
||||
|
||||
2022-08-22 - 14726571dd - lavf 59 - avformat.h
|
||||
Deprecate av_stream_get_end_pts() without replacement.
|
||||
|
||||
2022-08-19 - 352799dca8 - lavc 59.42.102 - codec_id.h
|
||||
Deprecate AV_CODEC_ID_AYUV and ayuv decoder/encoder. The rawvideo codec
|
||||
and vuya pixel format combination will be used instead from now on.
|
||||
|
||||
2022-08-07 - e95b08a7dd - lavu 57.33.101 - pixfmt.h
|
||||
Add AV_PIX_FMT_RGBAF16{BE,LE} pixel formats.
|
||||
|
||||
2022-08-12 - e0bbdbe0a6 - lavu 57.33.100 - hwcontext_qsv.h
|
||||
Add loader field to AVQSVDeviceContext
|
||||
|
||||
2022-08-03 - 6ab8a9d375 - lavu 57.32.100 - pixfmt.h
|
||||
Add AV_PIX_FMT_VUYA.
|
||||
|
||||
2022-08-02 - e3838b856f - lavc 59.41.100 - avcodec.h codec.h
|
||||
Add AV_CODEC_FLAG_RECON_FRAME and AV_CODEC_CAP_ENCODER_RECON_FRAME.
|
||||
avcodec_receive_frame() may now be used on encoders when
|
||||
AV_CODEC_FLAG_RECON_FRAME is active.
|
||||
|
||||
2022-08-02 - eede1d2927 - lavu 57.31.100 - frame.h
|
||||
av_frame_make_writable() may now be called on non-refcounted
|
||||
frames and will make a refcounted copy out of them.
|
||||
Previously an error was returned in such cases.
|
||||
|
||||
2022-07-30 - e1a0f2df3d - lavc 59.40.100 - avcodec.h
|
||||
Add the AV_CODEC_FLAG2_ICC_PROFILES flag to AVCodecContext, to enable
|
||||
automatic reading and writing of embedded ICC profiles in image files.
|
||||
The "flags2" option now supports the corresponding flag "icc_profiles".
|
||||
|
||||
2022-07-19 - 4397f9a5a0 - lavu 57.30.100 - frame.h
|
||||
Add AVFrame.duration, deprecate AVFrame.pkt_duration.
|
||||
|
||||
-------- 8< --------- FFmpeg 5.1 was cut here -------- 8< ---------
|
||||
|
||||
2022-06-12 - 7cae3d8b76 - lavf 59.25.100 - avio.h
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = FFmpeg
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 6.0.1
|
||||
PROJECT_NUMBER = 5.1
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
@@ -1980,7 +1980,6 @@ PREDEFINED = __attribute__(x)= \
|
||||
av_alloc_size(...)= \
|
||||
AV_GCC_VERSION_AT_LEAST(x,y)=1 \
|
||||
AV_GCC_VERSION_AT_MOST(x,y)=0 \
|
||||
"FF_PAD_STRUCTURE(name,size,...)=typedef struct name { __VA_ARGS__ } name;" \
|
||||
__GNUC__
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
The FFmpeg developers.
|
||||
|
||||
For details about the authorship, see the Git history of the project
|
||||
(https://git.ffmpeg.org/ffmpeg), e.g. by typing the command
|
||||
(git://source.ffmpeg.org/ffmpeg), e.g. by typing the command
|
||||
@command{git log} in the FFmpeg source directory, or browsing the
|
||||
online repository at @url{https://git.ffmpeg.org/ffmpeg}.
|
||||
online repository at @url{http://source.ffmpeg.org}.
|
||||
|
||||
Maintainers for the specific components are listed in the file
|
||||
@file{MAINTAINERS} in the source code tree.
|
||||
|
||||
@@ -382,6 +382,9 @@ This applies a specific fixup to some Blu-ray streams which contain
|
||||
redundant PPSs modifying irrelevant parameters of the stream which
|
||||
confuse other transformations which require correct extradata.
|
||||
|
||||
A new single global PPS is created, and all of the redundant PPSs
|
||||
within the stream are removed.
|
||||
|
||||
@section hevc_metadata
|
||||
|
||||
Modify metadata embedded in an HEVC stream.
|
||||
|
||||
2
doc/bootstrap.min.css
vendored
2
doc/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
@@ -644,8 +644,6 @@ for codecs that support it. See also @file{doc/examples/export_mvs.c}.
|
||||
Do not skip samples and export skip information as frame side data.
|
||||
@item ass_ro_flush_noop
|
||||
Do not reset ASS ReadOrder field on flush.
|
||||
@item icc_profiles
|
||||
Generate/parse embedded ICC profiles from/to colorimetry tags.
|
||||
@end table
|
||||
|
||||
@item export_side_data @var{flags} (@emph{decoding/encoding,audio,video,subtitles})
|
||||
|
||||
@@ -77,17 +77,13 @@ The following options are supported by the libdav1d wrapper.
|
||||
@item framethreads
|
||||
Set amount of frame threads to use during decoding. The default value is 0 (autodetect).
|
||||
This option is deprecated for libdav1d >= 1.0 and will be removed in the future. Use the
|
||||
option @code{max_frame_delay} and the global option @code{threads} instead.
|
||||
global option @code{threads} instead.
|
||||
|
||||
@item tilethreads
|
||||
Set amount of tile threads to use during decoding. The default value is 0 (autodetect).
|
||||
This option is deprecated for libdav1d >= 1.0 and will be removed in the future. Use the
|
||||
global option @code{threads} instead.
|
||||
|
||||
@item max_frame_delay
|
||||
Set max amount of frames the decoder may buffer internally. The default value is 0
|
||||
(autodetect).
|
||||
|
||||
@item filmgrain
|
||||
Apply film grain to the decoded video if present in the bitstream. Defaults to the
|
||||
internal default of the library.
|
||||
|
||||
@@ -285,24 +285,6 @@ This demuxer accepts the following option:
|
||||
|
||||
@end table
|
||||
|
||||
@section ea
|
||||
|
||||
Electronic Arts Multimedia format demuxer.
|
||||
|
||||
This format is used by various Electronic Arts games.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item merge_alpha @var{bool}
|
||||
|
||||
Normally the VP6 alpha channel (if exists) is returned as a secondary video
|
||||
stream, by setting this option you can make the demuxer return a single video
|
||||
stream which contains the alpha channel in addition to the ordinary video.
|
||||
|
||||
@end table
|
||||
|
||||
@section imf
|
||||
|
||||
Interoperable Master Format demuxer.
|
||||
@@ -419,10 +401,6 @@ Use HTTP partial requests for downloading HTTP segments.
|
||||
|
||||
@item seg_format_options
|
||||
Set options for the demuxer of media segments using a list of key=value pairs separated by @code{:}.
|
||||
|
||||
@item seg_max_retry
|
||||
Maximum number of times to reload a segment on error, useful when segment skip on network error is not desired.
|
||||
Default value is 0.
|
||||
@end table
|
||||
|
||||
@section image2
|
||||
|
||||
@@ -25,9 +25,6 @@ proposal by a member of the General Assembly.
|
||||
They are part of the GA for two years, after which they need a confirmation by
|
||||
the GA.
|
||||
|
||||
A script to generate the current members of the general assembly (minus members
|
||||
voted in) can be found in `tools/general_assembly.pl`.
|
||||
|
||||
## Voting
|
||||
|
||||
Voting is done using a ranked voting system, currently running on https://vote.ffmpeg.org/ .
|
||||
|
||||
@@ -10,79 +10,41 @@
|
||||
|
||||
@contents
|
||||
|
||||
@chapter Introduction
|
||||
@chapter Notes for external developers
|
||||
|
||||
This text is concerned with the development @emph{of} FFmpeg itself. Information
|
||||
on using the FFmpeg libraries in other programs can be found elsewhere, e.g. in:
|
||||
@itemize @bullet
|
||||
@item
|
||||
the installed header files
|
||||
@item
|
||||
@url{http://ffmpeg.org/doxygen/trunk/index.html, the Doxygen documentation}
|
||||
generated from the headers
|
||||
@item
|
||||
the examples under @file{doc/examples}
|
||||
@end itemize
|
||||
This document is mostly useful for internal FFmpeg developers.
|
||||
External developers who need to use the API in their application should
|
||||
refer to the API doxygen documentation in the public headers, and
|
||||
check the examples in @file{doc/examples} and in the source code to
|
||||
see how the public API is employed.
|
||||
|
||||
If you modify FFmpeg code for your own use case, you are highly encouraged to
|
||||
@emph{submit your changes back to us}, using this document as a guide. There are
|
||||
both pragmatic and ideological reasons to do so:
|
||||
@itemize @bullet
|
||||
@item
|
||||
Maintaining external changes to keep up with upstream development is
|
||||
time-consuming and error-prone. With your code in the main tree, it will be
|
||||
maintained by FFmpeg developers.
|
||||
@item
|
||||
FFmpeg developers include leading experts in the field who can find bugs or
|
||||
design flaws in your code.
|
||||
@item
|
||||
By supporting the project you find useful you ensure it continues to be
|
||||
maintained and developed.
|
||||
@end itemize
|
||||
You can use the FFmpeg libraries in your commercial program, but you
|
||||
are encouraged to @emph{publish any patch you make}. In this case the
|
||||
best way to proceed is to send your patches to the ffmpeg-devel
|
||||
mailing list following the guidelines illustrated in the remainder of
|
||||
this document.
|
||||
|
||||
For more detailed legal information about the use of FFmpeg in
|
||||
external programs read the @file{LICENSE} file in the source tree and
|
||||
consult @url{https://ffmpeg.org/legal.html}.
|
||||
|
||||
@section Contributing code
|
||||
@chapter Contributing
|
||||
|
||||
All proposed code changes should be submitted for review to
|
||||
@url{mailto:ffmpeg-devel@@ffmpeg.org, the development mailing list}, as
|
||||
described in more detail in the @ref{Submitting patches} chapter. The code
|
||||
should comply with the @ref{Development Policy} and follow the @ref{Coding Rules}.
|
||||
There are 2 ways by which code gets into FFmpeg:
|
||||
@itemize @bullet
|
||||
@item Submitting patches to the ffmpeg-devel mailing list.
|
||||
See @ref{Submitting patches} for details.
|
||||
@item Directly committing changes to the main tree.
|
||||
@end itemize
|
||||
|
||||
Whichever way, changes should be reviewed by the maintainer of the code
|
||||
before they are committed. And they should follow the @ref{Coding Rules}.
|
||||
The developer making the commit and the author are responsible for their changes
|
||||
and should try to fix issues their commit causes.
|
||||
|
||||
@anchor{Coding Rules}
|
||||
@chapter Coding Rules
|
||||
|
||||
@section C language features
|
||||
|
||||
FFmpeg is programmed in the ISO C99 language, extended with:
|
||||
@itemize @bullet
|
||||
@item
|
||||
Atomic operations from C11 @file{stdatomic.h}. They are emulated on
|
||||
architectures/compilers that do not support them, so all FFmpeg-internal code
|
||||
may use atomics without any extra checks. However, @file{stdatomic.h} must not
|
||||
be included in public headers, so they stay C99-compatible.
|
||||
@end itemize
|
||||
|
||||
Compiler-specific extensions may be used with good reason, but must not be
|
||||
depended on, i.e. the code must still compile and work with compilers lacking
|
||||
the extension.
|
||||
|
||||
The following C99 features must not be used anywhere in the codebase:
|
||||
@itemize @bullet
|
||||
@item
|
||||
variable-length arrays;
|
||||
|
||||
@item
|
||||
complex numbers;
|
||||
|
||||
@item
|
||||
mixed statements and declarations.
|
||||
@end itemize
|
||||
|
||||
@section Code formatting conventions
|
||||
|
||||
There are the following guidelines regarding the indentation in files:
|
||||
@@ -105,39 +67,8 @@ K&R coding style is used.
|
||||
@end itemize
|
||||
The presentation is one inspired by 'indent -i4 -kr -nut'.
|
||||
|
||||
@subsection Vim configuration
|
||||
In order to configure Vim to follow FFmpeg formatting conventions, paste
|
||||
the following snippet into your @file{.vimrc}:
|
||||
@example
|
||||
" indentation rules for FFmpeg: 4 spaces, no tabs
|
||||
set expandtab
|
||||
set shiftwidth=4
|
||||
set softtabstop=4
|
||||
set cindent
|
||||
set cinoptions=(0
|
||||
" Allow tabs in Makefiles.
|
||||
autocmd FileType make,automake set noexpandtab shiftwidth=8 softtabstop=8
|
||||
" Trailing whitespace and tabs are forbidden, so highlight them.
|
||||
highlight ForbiddenWhitespace ctermbg=red guibg=red
|
||||
match ForbiddenWhitespace /\s\+$\|\t/
|
||||
" Do not highlight spaces at the end of line while typing on that line.
|
||||
autocmd InsertEnter * match ForbiddenWhitespace /\t\|\s\+\%#\@@<!$/
|
||||
@end example
|
||||
|
||||
@subsection Emacs configuration
|
||||
For Emacs, add these roughly equivalent lines to your @file{.emacs.d/init.el}:
|
||||
@lisp
|
||||
(c-add-style "ffmpeg"
|
||||
'("k&r"
|
||||
(c-basic-offset . 4)
|
||||
(indent-tabs-mode . nil)
|
||||
(show-trailing-whitespace . t)
|
||||
(c-offsets-alist
|
||||
(statement-cont . (c-lineup-assignments +)))
|
||||
)
|
||||
)
|
||||
(setq c-default-style "ffmpeg")
|
||||
@end lisp
|
||||
The main priority in FFmpeg is simplicity and small code size in order to
|
||||
minimize the bug count.
|
||||
|
||||
@section Comments
|
||||
Use the JavaDoc/Doxygen format (see examples below) so that code documentation
|
||||
@@ -179,51 +110,92 @@ int myfunc(int my_parameter)
|
||||
...
|
||||
@end example
|
||||
|
||||
@section Naming conventions
|
||||
@section C language features
|
||||
|
||||
Names of functions, variables, and struct members must be lowercase, using
|
||||
underscores (_) to separate words. For example, @samp{avfilter_get_video_buffer}
|
||||
is an acceptable function name and @samp{AVFilterGetVideo} is not.
|
||||
FFmpeg is programmed in the ISO C90 language with a few additional
|
||||
features from ISO C99, namely:
|
||||
|
||||
Struct, union, enum, and typedeffed type names must use CamelCase. All structs
|
||||
and unions should be typedeffed to the same name as the struct/union tag, e.g.
|
||||
@code{typedef struct AVFoo @{ ... @} AVFoo;}. Enums are typically not
|
||||
typedeffed.
|
||||
|
||||
Enumeration constants and macros must be UPPERCASE, except for macros
|
||||
masquerading as functions, which should use the function naming convention.
|
||||
|
||||
All identifiers in the libraries should be namespaced as follows:
|
||||
@itemize @bullet
|
||||
@item
|
||||
No namespacing for identifiers with file and lower scope (e.g. local variables,
|
||||
static functions), and struct and union members,
|
||||
the @samp{inline} keyword;
|
||||
|
||||
@item
|
||||
The @code{ff_} prefix must be used for variables and functions visible outside
|
||||
of file scope, but only used internally within a single library, e.g.
|
||||
@samp{ff_w64_demuxer}. This prevents name collisions when FFmpeg is statically
|
||||
linked.
|
||||
@samp{//} comments;
|
||||
|
||||
@item
|
||||
designated struct initializers (@samp{struct s x = @{ .i = 17 @};});
|
||||
|
||||
@item
|
||||
compound literals (@samp{x = (struct s) @{ 17, 23 @};}).
|
||||
|
||||
@item
|
||||
for loops with variable definition (@samp{for (int i = 0; i < 8; i++)});
|
||||
|
||||
@item
|
||||
Variadic macros (@samp{#define ARRAY(nb, ...) (int[nb + 1])@{ nb, __VA_ARGS__ @}});
|
||||
|
||||
@item
|
||||
Implementation defined behavior for signed integers is assumed to match the
|
||||
expected behavior for two's complement. Non representable values in integer
|
||||
casts are binary truncated. Shift right of signed values uses sign extension.
|
||||
@end itemize
|
||||
|
||||
These features are supported by all compilers we care about, so we will not
|
||||
accept patches to remove their use unless they absolutely do not impair
|
||||
clarity and performance.
|
||||
|
||||
All code must compile with recent versions of GCC and a number of other
|
||||
currently supported compilers. To ensure compatibility, please do not use
|
||||
additional C99 features or GCC extensions. Especially watch out for:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
mixing statements and declarations;
|
||||
|
||||
@item
|
||||
@samp{long long} (use @samp{int64_t} instead);
|
||||
|
||||
@item
|
||||
@samp{__attribute__} not protected by @samp{#ifdef __GNUC__} or similar;
|
||||
|
||||
@item
|
||||
GCC statement expressions (@samp{(x = (@{ int y = 4; y; @})}).
|
||||
@end itemize
|
||||
|
||||
@section Naming conventions
|
||||
All names should be composed with underscores (_), not CamelCase. For example,
|
||||
@samp{avfilter_get_video_buffer} is an acceptable function name and
|
||||
@samp{AVFilterGetVideo} is not. The exception from this are type names, like
|
||||
for example structs and enums; they should always be in CamelCase.
|
||||
|
||||
There are the following conventions for naming variables and functions:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
For local variables no prefix is required.
|
||||
|
||||
@item
|
||||
For file-scope variables and functions declared as @code{static}, no prefix
|
||||
is required.
|
||||
|
||||
@item
|
||||
For variables and functions visible outside of file scope, but only used
|
||||
internally by a library, an @code{ff_} prefix should be used,
|
||||
e.g. @samp{ff_w64_demuxer}.
|
||||
|
||||
@item
|
||||
For variables and functions visible outside of file scope, used internally
|
||||
across multiple libraries, use @code{avpriv_} as prefix, for example,
|
||||
@samp{avpriv_report_missing_feature}.
|
||||
|
||||
@item
|
||||
All other internal identifiers, like private type or macro names, should be
|
||||
namespaced only to avoid possible internal conflicts. E.g. @code{H264_NAL_SPS}
|
||||
vs. @code{HEVC_NAL_SPS}.
|
||||
|
||||
@item
|
||||
Each library has its own prefix for public symbols, in addition to the
|
||||
commonly used @code{av_} (@code{avformat_} for libavformat,
|
||||
@code{avcodec_} for libavcodec, @code{swr_} for libswresample, etc).
|
||||
Check the existing code and choose names accordingly.
|
||||
|
||||
@item
|
||||
Other public identifiers (struct, union, enum, macro, type names) must use their
|
||||
library's public prefix (@code{AV}, @code{Sws}, or @code{Swr}).
|
||||
Note that some symbols without these prefixes are also exported for
|
||||
retro-compatibility reasons. These exceptions are declared in the
|
||||
@code{lib<name>/lib<name>.v} files.
|
||||
@end itemize
|
||||
|
||||
Furthermore, name space reserved for the system should not be invaded.
|
||||
@@ -246,7 +218,39 @@ Casts should be used only when necessary. Unneeded parentheses
|
||||
should also be avoided if they don't make the code easier to understand.
|
||||
@end itemize
|
||||
|
||||
@anchor{Development Policy}
|
||||
@section Editor configuration
|
||||
In order to configure Vim to follow FFmpeg formatting conventions, paste
|
||||
the following snippet into your @file{.vimrc}:
|
||||
@example
|
||||
" indentation rules for FFmpeg: 4 spaces, no tabs
|
||||
set expandtab
|
||||
set shiftwidth=4
|
||||
set softtabstop=4
|
||||
set cindent
|
||||
set cinoptions=(0
|
||||
" Allow tabs in Makefiles.
|
||||
autocmd FileType make,automake set noexpandtab shiftwidth=8 softtabstop=8
|
||||
" Trailing whitespace and tabs are forbidden, so highlight them.
|
||||
highlight ForbiddenWhitespace ctermbg=red guibg=red
|
||||
match ForbiddenWhitespace /\s\+$\|\t/
|
||||
" Do not highlight spaces at the end of line while typing on that line.
|
||||
autocmd InsertEnter * match ForbiddenWhitespace /\t\|\s\+\%#\@@<!$/
|
||||
@end example
|
||||
|
||||
For Emacs, add these roughly equivalent lines to your @file{.emacs.d/init.el}:
|
||||
@lisp
|
||||
(c-add-style "ffmpeg"
|
||||
'("k&r"
|
||||
(c-basic-offset . 4)
|
||||
(indent-tabs-mode . nil)
|
||||
(show-trailing-whitespace . t)
|
||||
(c-offsets-alist
|
||||
(statement-cont . (c-lineup-assignments +)))
|
||||
)
|
||||
)
|
||||
(setq c-default-style "ffmpeg")
|
||||
@end lisp
|
||||
|
||||
@chapter Development Policy
|
||||
|
||||
@section Patches/Committing
|
||||
|
||||
@@ -1949,6 +1949,22 @@ Set the number of slices, used in parallelized encoding. Default value
|
||||
is 0. This is only used when @option{slice_mode} is set to
|
||||
@samp{fixed}.
|
||||
|
||||
@item slice_mode
|
||||
Set slice mode. Can assume one of the following possible values:
|
||||
|
||||
@table @samp
|
||||
@item fixed
|
||||
a fixed number of slices
|
||||
@item rowmb
|
||||
one slice per row of macroblocks
|
||||
@item auto
|
||||
automatic number of slices according to number of threads
|
||||
@item dyn
|
||||
dynamic slicing
|
||||
@end table
|
||||
|
||||
Default value is @samp{auto}.
|
||||
|
||||
@item loopfilter
|
||||
Enable loop filter, if set to 1 (automatically enabled). To disable
|
||||
set a value of 0.
|
||||
@@ -2160,8 +2176,6 @@ Set altref noise reduction filter type: backward, forward, centered.
|
||||
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 min-gf-interval
|
||||
Set minimum golden/alternate reference frame interval (VP9 only).
|
||||
@end table
|
||||
|
||||
@item error-resilient
|
||||
@@ -3230,9 +3244,9 @@ the average bitrate.
|
||||
than the average bitrate.
|
||||
|
||||
@item
|
||||
@var{AVBR} - average VBR mode, when @option{maxrate} is not specified, both
|
||||
@option{avbr_accuracy} and @option{avbr_convergence} are set to non-zero. This
|
||||
mode is available for H264 and HEVC on Windows.
|
||||
@var{AVBR} - average VBR mode, when @option{maxrate} is not specified. This mode
|
||||
is further configured by the @option{avbr_accuracy} and
|
||||
@option{avbr_convergence} options.
|
||||
@end itemize
|
||||
@end itemize
|
||||
|
||||
@@ -3286,6 +3300,19 @@ Specifies how many asynchronous operations an application performs
|
||||
before the application explicitly synchronizes the result. If zero,
|
||||
the value is not specified.
|
||||
|
||||
@item @var{avbr_accuracy}
|
||||
Accuracy of the AVBR ratecontrol (unit of tenth of percent).
|
||||
|
||||
@item @var{avbr_convergence}
|
||||
Convergence of the AVBR ratecontrol (unit of 100 frames)
|
||||
|
||||
The parameters @var{avbr_accuracy} and @var{avbr_convergence} are for the
|
||||
average variable bitrate control (AVBR) algorithm.
|
||||
The algorithm focuses on overall encoding quality while meeting the specified
|
||||
bitrate, @var{target_bitrate}, within the accuracy range @var{avbr_accuracy},
|
||||
after a @var{avbr_Convergence} period. This method does not follow HRD and the
|
||||
instant bitrate is not capped or padded.
|
||||
|
||||
@item @var{preset}
|
||||
This option itemizes a range of choices from veryfast (best speed) to veryslow
|
||||
(best quality).
|
||||
@@ -3310,55 +3337,10 @@ For encoders set this flag to ON to reduce power consumption and GPU usage.
|
||||
Following options can be used durning qsv encoding.
|
||||
|
||||
@table @option
|
||||
@item @var{global_quality}
|
||||
@item @var{i_quant_factor}
|
||||
@item @var{i_quant_offset}
|
||||
@item @var{b_quant_factor}
|
||||
@item @var{b_quant_offset}
|
||||
@item @var{qsv_config_qp}
|
||||
Supported in h264_qsv and hevc_qsv.
|
||||
Change these value to reset qsv codec's qp configuration.
|
||||
|
||||
@item @var{max_frame_size}
|
||||
Supported in h264_qsv and hevc_qsv.
|
||||
Change this value to reset qsv codec's MaxFrameSize configuration.
|
||||
|
||||
@item @var{gop_size}
|
||||
Change this value to reset qsv codec's gop configuration.
|
||||
|
||||
@item @var{int_ref_type}
|
||||
@item @var{int_ref_cycle_size}
|
||||
@item @var{int_ref_qp_delta}
|
||||
@item @var{int_ref_cycle_dist}
|
||||
Supported in h264_qsv and hevc_qsv.
|
||||
Change these value to reset qsv codec's Intra Refresh configuration.
|
||||
|
||||
@item @var{qmax}
|
||||
@item @var{qmin}
|
||||
@item @var{max_qp_i}
|
||||
@item @var{min_qp_i}
|
||||
@item @var{max_qp_p}
|
||||
@item @var{min_qp_p}
|
||||
@item @var{max_qp_b}
|
||||
@item @var{min_qp_b}
|
||||
Supported in h264_qsv.
|
||||
Change these value to reset qsv codec's max/min qp configuration.
|
||||
|
||||
@item @var{low_delay_brc}
|
||||
Supported in h264_qsv and hevc_qsv.
|
||||
Change this value to reset qsv codec's low_delay_brc configuration.
|
||||
|
||||
@item @var{framerate}
|
||||
Change this value to reset qsv codec's framerate configuration.
|
||||
|
||||
@item @var{bit_rate}
|
||||
@item @var{rc_buffer_size}
|
||||
@item @var{rc_initial_buffer_occupancy}
|
||||
@item @var{rc_max_rate}
|
||||
Change these value to reset qsv codec's bitrate control configuration.
|
||||
|
||||
@item @var{pic_timing_sei}
|
||||
Supported in h264_qsv and hevc_qsv.
|
||||
Change this value to reset qsv codec's pic_timing_sei configuration.
|
||||
This option can be set in per-frame metadata. QP parameter can be dynamically
|
||||
changed when encoding in CQP mode.
|
||||
@end table
|
||||
|
||||
@subsection H264 options
|
||||
@@ -3462,10 +3444,8 @@ Specifies intra refresh type. The major goal of intra refresh is improvement of
|
||||
error resilience without significant impact on encoded bitstream size caused by
|
||||
I frames. The SDK encoder achieves this by encoding part of each frame in
|
||||
refresh cycle using intra MBs. @var{none} means no refresh. @var{vertical} means
|
||||
vertical refresh, by column of MBs. @var{horizontal} means horizontal refresh,
|
||||
by rows of MBs. @var{slice} means horizontal refresh by slices without
|
||||
overlapping. In case of @var{slice}, in_ref_cycle_size is ignored. To enable
|
||||
intra refresh, B frame should be set to 0.
|
||||
vertical refresh, by column of MBs. To enable intra refresh, B frame should be
|
||||
set to 0.
|
||||
|
||||
@item @var{int_ref_cycle_size}
|
||||
Specifies number of pictures within refresh cycle starting from 2. 0 and 1 are
|
||||
@@ -3520,52 +3500,6 @@ Maximum video quantizer scale for B frame.
|
||||
|
||||
@item @var{min_qp_b}
|
||||
Minimum video quantizer scale for B frame.
|
||||
|
||||
@item @var{scenario}
|
||||
Provides a hint to encoder about the scenario for the encoding session.
|
||||
@table @samp
|
||||
@item unknown
|
||||
@item displayremoting
|
||||
@item videoconference
|
||||
@item archive
|
||||
@item livestreaming
|
||||
@item cameracapture
|
||||
@item videosurveillance
|
||||
@item gamestreaming
|
||||
@item remotegaming
|
||||
@end table
|
||||
|
||||
@item @var{avbr_accuracy}
|
||||
Accuracy of the AVBR ratecontrol (unit of tenth of percent).
|
||||
|
||||
@item @var{avbr_convergence}
|
||||
Convergence of the AVBR ratecontrol (unit of 100 frames)
|
||||
|
||||
The parameters @var{avbr_accuracy} and @var{avbr_convergence} are for the
|
||||
average variable bitrate control (AVBR) algorithm.
|
||||
The algorithm focuses on overall encoding quality while meeting the specified
|
||||
bitrate, @var{target_bitrate}, within the accuracy range @var{avbr_accuracy},
|
||||
after a @var{avbr_Convergence} period. This method does not follow HRD and the
|
||||
instant bitrate is not capped or padded.
|
||||
|
||||
@item @var{skip_frame}
|
||||
Use per-frame metadata "qsv_skip_frame" to skip frame when encoding. This option
|
||||
defines the usage of this metadata.
|
||||
@table @samp
|
||||
@item no_skip
|
||||
Frame skipping is disabled.
|
||||
@item insert_dummy
|
||||
Encoder inserts into bitstream frame where all macroblocks are encoded as
|
||||
skipped.
|
||||
@item insert_nothing
|
||||
Similar to insert_dummy, but encoder inserts nothing into bitstream. The skipped
|
||||
frames are still used in brc. For example, gop still include skipped frames, and
|
||||
the frames after skipped frames will be larger in size.
|
||||
@item brc_only
|
||||
skip_frame metadata indicates the number of missed frames before the current
|
||||
frame.
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@subsection HEVC Options
|
||||
@@ -3606,13 +3540,6 @@ Setting this flag turns on or off LowDelayBRC feautre in qsv plugin, which provi
|
||||
more accurate bitrate control to minimize the variance of bitstream size frame
|
||||
by frame. Value: -1-default 0-off 1-on
|
||||
|
||||
@item @var{adaptive_i}
|
||||
This flag controls insertion of I frames by the QSV encoder. Turn ON this flag
|
||||
to allow changing of frame type from P and B to I.
|
||||
|
||||
@item @var{adaptive_b}
|
||||
This flag controls changing of frame type from B to P.
|
||||
|
||||
@item @var{p_strategy}
|
||||
Enable P-pyramid: 0-default 1-simple 2-pyramid(bf need to be set to 0).
|
||||
|
||||
@@ -3656,15 +3583,6 @@ Set the encoding profile (scc requires libmfx >= 1.32).
|
||||
@item scc
|
||||
@end table
|
||||
|
||||
@item @var{tier}
|
||||
Set the encoding tier (only level >= 4 can support high tier).
|
||||
This option only takes effect when the level option is specified.
|
||||
|
||||
@table @samp
|
||||
@item main
|
||||
@item high
|
||||
@end table
|
||||
|
||||
@item @var{gpb}
|
||||
1: GPB (generalized P/B frame)
|
||||
|
||||
@@ -3691,10 +3609,8 @@ Specifies intra refresh type. The major goal of intra refresh is improvement of
|
||||
error resilience without significant impact on encoded bitstream size caused by
|
||||
I frames. The SDK encoder achieves this by encoding part of each frame in
|
||||
refresh cycle using intra MBs. @var{none} means no refresh. @var{vertical} means
|
||||
vertical refresh, by column of MBs. @var{horizontal} means horizontal refresh,
|
||||
by rows of MBs. @var{slice} means horizontal refresh by slices without
|
||||
overlapping. In case of @var{slice}, in_ref_cycle_size is ignored. To enable
|
||||
intra refresh, B frame should be set to 0.
|
||||
vertical refresh, by column of MBs. To enable intra refresh, B frame should be
|
||||
set to 0.
|
||||
|
||||
@item @var{int_ref_cycle_size}
|
||||
Specifies number of pictures within refresh cycle starting from 2. 0 and 1 are
|
||||
@@ -3725,52 +3641,6 @@ Maximum video quantizer scale for B frame.
|
||||
|
||||
@item @var{min_qp_b}
|
||||
Minimum video quantizer scale for B frame.
|
||||
|
||||
@item @var{scenario}
|
||||
Provides a hint to encoder about the scenario for the encoding session.
|
||||
@table @samp
|
||||
@item unknown
|
||||
@item displayremoting
|
||||
@item videoconference
|
||||
@item archive
|
||||
@item livestreaming
|
||||
@item cameracapture
|
||||
@item videosurveillance
|
||||
@item gamestreaming
|
||||
@item remotegaming
|
||||
@end table
|
||||
|
||||
@item @var{avbr_accuracy}
|
||||
Accuracy of the AVBR ratecontrol (unit of tenth of percent).
|
||||
|
||||
@item @var{avbr_convergence}
|
||||
Convergence of the AVBR ratecontrol (unit of 100 frames)
|
||||
|
||||
The parameters @var{avbr_accuracy} and @var{avbr_convergence} are for the
|
||||
average variable bitrate control (AVBR) algorithm.
|
||||
The algorithm focuses on overall encoding quality while meeting the specified
|
||||
bitrate, @var{target_bitrate}, within the accuracy range @var{avbr_accuracy},
|
||||
after a @var{avbr_Convergence} period. This method does not follow HRD and the
|
||||
instant bitrate is not capped or padded.
|
||||
|
||||
@item @var{skip_frame}
|
||||
Use per-frame metadata "qsv_skip_frame" to skip frame when encoding. This option
|
||||
defines the usage of this metadata.
|
||||
@table @samp
|
||||
@item no_skip
|
||||
Frame skipping is disabled.
|
||||
@item insert_dummy
|
||||
Encoder inserts into bitstream frame where all macroblocks are encoded as
|
||||
skipped.
|
||||
@item insert_nothing
|
||||
Similar to insert_dummy, but encoder inserts nothing into bitstream. The skipped
|
||||
frames are still used in brc. For example, gop still include skipped frames, and
|
||||
the frames after skipped frames will be larger in size.
|
||||
@item brc_only
|
||||
skip_frame metadata indicates the number of missed frames before the current
|
||||
frame.
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@subsection MPEG2 Options
|
||||
@@ -3804,48 +3674,6 @@ Number of columns for tiled encoding (requires libmfx >= 1.29).
|
||||
Number of rows for tiled encoding (requires libmfx >= 1.29).
|
||||
@end table
|
||||
|
||||
@subsection AV1 Options
|
||||
These options are used by av1_qsv (requires libvpl).
|
||||
@table @option
|
||||
@item @var{profile}
|
||||
@table @samp
|
||||
@item unknown
|
||||
@item main
|
||||
@end table
|
||||
|
||||
@item @var{tile_cols}
|
||||
Number of columns for tiled encoding.
|
||||
|
||||
@item @var{tile_rows}
|
||||
Number of rows for tiled encoding.
|
||||
|
||||
@item @var{adaptive_i}
|
||||
This flag controls insertion of I frames by the QSV encoder. Turn ON this flag
|
||||
to allow changing of frame type from P and B to I.
|
||||
|
||||
@item @var{adaptive_b}
|
||||
This flag controls changing of frame type from B to P.
|
||||
|
||||
@item @var{b_strategy}
|
||||
This option controls usage of B frames as reference.
|
||||
|
||||
@item @var{extbrc}
|
||||
Extended bitrate control.
|
||||
|
||||
@item @var{look_ahead_depth}
|
||||
Depth of look ahead in number frames, available when extbrc option is enabled.
|
||||
|
||||
@item @var{low_delay_brc}
|
||||
Setting this flag turns on or off LowDelayBRC feautre in qsv plugin, which provides
|
||||
more accurate bitrate control to minimize the variance of bitstream size frame
|
||||
by frame. Value: -1-default 0-off 1-on
|
||||
|
||||
@item max_frame_size
|
||||
Set the allowed max size in bytes for each frame. If the frame size exceeds
|
||||
the limitation, encoder will adjust the QP value to control the frame size.
|
||||
Invalid in CQP rate control mode.
|
||||
@end table
|
||||
|
||||
@section snow
|
||||
|
||||
@subsection Options
|
||||
|
||||
1
doc/examples/.gitignore
vendored
1
doc/examples/.gitignore
vendored
@@ -22,4 +22,3 @@
|
||||
/transcoding
|
||||
/vaapi_encode
|
||||
/vaapi_transcode
|
||||
/qsv_transcode
|
||||
|
||||
@@ -1,27 +1,26 @@
|
||||
EXAMPLES-$(CONFIG_AVIO_HTTP_SERVE_FILES) += avio_http_serve_files
|
||||
EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir
|
||||
EXAMPLES-$(CONFIG_AVIO_READ_CALLBACK_EXAMPLE) += avio_read_callback
|
||||
EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading
|
||||
EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio
|
||||
EXAMPLES-$(CONFIG_DECODE_FILTER_AUDIO_EXAMPLE) += decode_filter_audio
|
||||
EXAMPLES-$(CONFIG_DECODE_FILTER_VIDEO_EXAMPLE) += decode_filter_video
|
||||
EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video
|
||||
EXAMPLES-$(CONFIG_DEMUX_DECODE_EXAMPLE) += demux_decode
|
||||
EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
|
||||
EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio
|
||||
EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video
|
||||
EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE) += extract_mvs
|
||||
EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio
|
||||
EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE) += filtering_audio
|
||||
EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE) += filtering_video
|
||||
EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE) += http_multiclient
|
||||
EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode
|
||||
EXAMPLES-$(CONFIG_MUX_EXAMPLE) += mux
|
||||
EXAMPLES-$(CONFIG_QSV_DECODE_EXAMPLE) += qsv_decode
|
||||
EXAMPLES-$(CONFIG_REMUX_EXAMPLE) += remux
|
||||
EXAMPLES-$(CONFIG_RESAMPLE_AUDIO_EXAMPLE) += resample_audio
|
||||
EXAMPLES-$(CONFIG_SCALE_VIDEO_EXAMPLE) += scale_video
|
||||
EXAMPLES-$(CONFIG_SHOW_METADATA_EXAMPLE) += show_metadata
|
||||
EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata
|
||||
EXAMPLES-$(CONFIG_MUXING_EXAMPLE) += muxing
|
||||
EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec
|
||||
EXAMPLES-$(CONFIG_REMUXING_EXAMPLE) += remuxing
|
||||
EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio
|
||||
EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
|
||||
EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
|
||||
EXAMPLES-$(CONFIG_TRANSCODE_EXAMPLE) += transcode
|
||||
EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE) += transcoding
|
||||
EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE) += vaapi_encode
|
||||
EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE) += vaapi_transcode
|
||||
EXAMPLES-$(CONFIG_QSV_TRANSCODE_EXAMPLE) += qsv_transcode
|
||||
|
||||
EXAMPLES := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
|
||||
EXAMPLES_G := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
|
||||
|
||||
@@ -11,40 +11,33 @@ CFLAGS += -Wall -g
|
||||
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
|
||||
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
|
||||
|
||||
# missing the following targets, since they need special options in the FFmpeg build:
|
||||
# qsv_decode
|
||||
# qsv_transcode
|
||||
# vaapi_encode
|
||||
# vaapi_transcode
|
||||
|
||||
EXAMPLES=\
|
||||
avio_http_serve_files \
|
||||
avio_list_dir \
|
||||
avio_read_callback \
|
||||
EXAMPLES= avio_list_dir \
|
||||
avio_reading \
|
||||
decode_audio \
|
||||
decode_filter_audio \
|
||||
decode_filter_video \
|
||||
decode_video \
|
||||
demux_decode \
|
||||
demuxing_decoding \
|
||||
encode_audio \
|
||||
encode_video \
|
||||
extract_mvs \
|
||||
filtering_video \
|
||||
filtering_audio \
|
||||
http_multiclient \
|
||||
hw_decode \
|
||||
mux \
|
||||
remux \
|
||||
resample_audio \
|
||||
scale_video \
|
||||
show_metadata \
|
||||
metadata \
|
||||
muxing \
|
||||
remuxing \
|
||||
resampling_audio \
|
||||
scaling_video \
|
||||
transcode_aac \
|
||||
transcode
|
||||
transcoding \
|
||||
|
||||
OBJS=$(addsuffix .o,$(EXAMPLES))
|
||||
|
||||
# the following examples make explicit use of the math library
|
||||
avcodec: LDLIBS += -lm
|
||||
encode_audio: LDLIBS += -lm
|
||||
mux: LDLIBS += -lm
|
||||
resample_audio: LDLIBS += -lm
|
||||
muxing: LDLIBS += -lm
|
||||
resampling_audio: LDLIBS += -lm
|
||||
|
||||
.phony: all clean-test clean
|
||||
|
||||
|
||||
@@ -7,10 +7,8 @@ that you have them installed and working on your system.
|
||||
|
||||
Method 1: build the installed examples in a generic read/write user directory
|
||||
|
||||
Copy to a read/write user directory and run:
|
||||
make -f Makefile.example
|
||||
|
||||
It will link to the libraries on your system, assuming the PKG_CONFIG_PATH is
|
||||
Copy to a read/write user directory and just use "make", it will link
|
||||
to the libraries on your system, assuming the PKG_CONFIG_PATH is
|
||||
correctly configured.
|
||||
|
||||
Method 2: build the examples in-tree
|
||||
@@ -22,4 +20,4 @@ examples using "make examplesclean"
|
||||
|
||||
If you want to try the dedicated Makefile examples (to emulate the first
|
||||
method), go into doc/examples and run a command such as
|
||||
PKG_CONFIG_PATH=pc-uninstalled make -f Makefile.example
|
||||
PKG_CONFIG_PATH=pc-uninstalled make.
|
||||
|
||||
@@ -20,13 +20,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavformat AVIOContext list directory API usage example
|
||||
* @example avio_list_dir.c
|
||||
*
|
||||
* Show how to list directories through the libavformat AVIOContext API.
|
||||
*/
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavformat/avio.h>
|
||||
|
||||
@@ -21,11 +21,12 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavformat AVIOContext read callback API usage example
|
||||
* @example avio_read_callback.c
|
||||
* @file
|
||||
* libavformat AVIOContext API example.
|
||||
*
|
||||
* Make libavformat demuxer access media content through a custom
|
||||
* AVIOContext read callback.
|
||||
* @example avio_reading.c
|
||||
*/
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
@@ -21,11 +21,10 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavcodec audio decoding API usage example
|
||||
* @example decode_audio.c
|
||||
* @file
|
||||
* audio decoding with libavcodec API example
|
||||
*
|
||||
* Decode data from an MP2 input file and generate a raw audio file to
|
||||
* be played with ffplay.
|
||||
* @example decode_audio.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -21,11 +21,10 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavcodec video decoding API usage example
|
||||
* @example decode_video.c *
|
||||
* @file
|
||||
* video decoding with libavcodec API example
|
||||
*
|
||||
* Read from an MPEG1 video file, decode frames, and generate PGM images as
|
||||
* output.
|
||||
* @example decode_video.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -70,12 +69,12 @@ static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("saving frame %3"PRId64"\n", dec_ctx->frame_num);
|
||||
printf("saving frame %3d\n", dec_ctx->frame_number);
|
||||
fflush(stdout);
|
||||
|
||||
/* the picture is allocated by the decoder. no need to
|
||||
free it */
|
||||
snprintf(buf, sizeof(buf), "%s-%"PRId64, filename, dec_ctx->frame_num);
|
||||
snprintf(buf, sizeof(buf), "%s-%d", filename, dec_ctx->frame_number);
|
||||
pgm_save(frame->data[0], frame->linesize[0],
|
||||
frame->width, frame->height, buf);
|
||||
}
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavformat and libavcodec demuxing and decoding API usage example
|
||||
* @example demux_decode.c
|
||||
* @file
|
||||
* Demuxing and decoding example.
|
||||
*
|
||||
* Show how to use the libavformat and libavcodec API to demux and decode audio
|
||||
* and video data. Write the output as raw audio and input files to be played by
|
||||
* ffplay.
|
||||
* Show how to use the libavformat and libavcodec API to demux and
|
||||
* decode audio and video data.
|
||||
* @example demuxing_decoding.c
|
||||
*/
|
||||
|
||||
#include <libavutil/imgutils.h>
|
||||
@@ -73,8 +73,8 @@ static int output_video_frame(AVFrame *frame)
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("video_frame n:%d\n",
|
||||
video_frame_count++);
|
||||
printf("video_frame n:%d coded_n:%d\n",
|
||||
video_frame_count++, frame->coded_picture_number);
|
||||
|
||||
/* copy decoded frame to destination buffer:
|
||||
* this is required since rawvideo expects non aligned data */
|
||||
@@ -21,10 +21,10 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavcodec encoding audio API usage examples
|
||||
* @example encode_audio.c
|
||||
* @file
|
||||
* audio encoding with libavcodec API example.
|
||||
*
|
||||
* Generate a synthetic audio signal and encode it to an output MP2 file.
|
||||
* @example encode_audio.c
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavcodec encoding video API usage example
|
||||
* @example encode_video.c
|
||||
* @file
|
||||
* video encoding with libavcodec API example
|
||||
*
|
||||
* Generate synthetic video data and encode it to an output file.
|
||||
* @example encode_video.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -202,7 +202,7 @@ int main(int argc, char **argv)
|
||||
It makes only sense because this tiny examples writes packets
|
||||
directly. This is called "elementary stream" and only works for some
|
||||
codecs. To create a valid file, you usually need to write packets
|
||||
into a proper file format or protocol; see mux.c.
|
||||
into a proper file format or protocol; see muxing.c.
|
||||
*/
|
||||
if (codec->id == AV_CODEC_ID_MPEG1VIDEO || codec->id == AV_CODEC_ID_MPEG2VIDEO)
|
||||
fwrite(endcode, 1, sizeof(endcode), f);
|
||||
|
||||
@@ -21,14 +21,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavcodec motion vectors extraction API usage example
|
||||
* @example extract_mvs.c
|
||||
*
|
||||
* Read from input file, decode video stream and print a motion vectors
|
||||
* representation to stdout.
|
||||
*/
|
||||
|
||||
#include <libavutil/motion_vector.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
@@ -69,11 +61,10 @@ static int decode_packet(const AVPacket *pkt)
|
||||
const AVMotionVector *mvs = (const AVMotionVector *)sd->data;
|
||||
for (i = 0; i < sd->size / sizeof(*mvs); i++) {
|
||||
const AVMotionVector *mv = &mvs[i];
|
||||
printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64",%4d,%4d,%4d\n",
|
||||
printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64"\n",
|
||||
video_frame_count, mv->source,
|
||||
mv->w, mv->h, mv->src_x, mv->src_y,
|
||||
mv->dst_x, mv->dst_y, mv->flags,
|
||||
mv->motion_x, mv->motion_y, mv->motion_scale);
|
||||
mv->dst_x, mv->dst_y, mv->flags);
|
||||
}
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
@@ -175,7 +166,7 @@ int main(int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
printf("framenum,source,blockw,blockh,srcx,srcy,dstx,dsty,flags,motion_x,motion_y,motion_scale\n");
|
||||
printf("framenum,source,blockw,blockh,srcx,srcy,dstx,dsty,flags\n");
|
||||
|
||||
/* read frames from the file */
|
||||
while (av_read_frame(fmt_ctx, pkt) >= 0) {
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavfilter audio filtering API usage example
|
||||
* @example filter_audio.c
|
||||
* @file
|
||||
* libavfilter API usage example.
|
||||
*
|
||||
* This example will generate a sine wave audio, pass it through a simple filter
|
||||
* chain, and then compute the MD5 checksum of the output data.
|
||||
* @example filter_audio.c
|
||||
* This example will generate a sine wave audio,
|
||||
* pass it through a simple filter chain, and then compute the MD5 checksum of
|
||||
* the output data.
|
||||
*
|
||||
* The filter chain it uses is:
|
||||
* (input) -> abuffer -> volume -> aformat -> abuffersink -> (output)
|
||||
|
||||
@@ -23,11 +23,9 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file audio decoding and filtering usage example
|
||||
* @example decode_filter_audio.c
|
||||
*
|
||||
* Demux, decode and filter audio input file, generate a raw audio
|
||||
* file to be played with ffplay.
|
||||
* @file
|
||||
* API example for audio decoding and filtering
|
||||
* @example filtering_audio.c
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
@@ -24,7 +24,7 @@
|
||||
/**
|
||||
* @file
|
||||
* API example for decoding and filtering
|
||||
* @example decode_filter_video.c
|
||||
* @example filtering_video.c
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 600 /* for usleep */
|
||||
@@ -21,11 +21,12 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavformat multi-client network API usage example
|
||||
* @example avio_http_serve_files.c
|
||||
* @file
|
||||
* libavformat multi-client network API usage example.
|
||||
*
|
||||
* Serve a file without decoding or demuxing it over the HTTP protocol. Multiple
|
||||
* clients can connect and will receive the same file.
|
||||
* @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>
|
||||
@@ -24,11 +24,12 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file HW-accelerated decoding API usage.example
|
||||
* @example hw_decode.c
|
||||
* @file
|
||||
* HW-Accelerated decoding example.
|
||||
*
|
||||
* Perform HW-accelerated decoding with output frames from HW video
|
||||
* surfaces.
|
||||
* @example hw_decode.c
|
||||
* This example shows how to do HW-accelerated decoding with output
|
||||
* frames from the HW video surfaces.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -21,10 +21,9 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavformat metadata extraction API usage example
|
||||
* @example show_metadata.c
|
||||
*
|
||||
* Show metadata from an input file.
|
||||
* @file
|
||||
* Shows how the metadata API can be used in application programs.
|
||||
* @example metadata.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -53,7 +52,7 @@ int main (int argc, char **argv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
while ((tag = av_dict_iterate(fmt_ctx->metadata, tag)))
|
||||
while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
|
||||
printf("%s=%s\n", tag->key, tag->value);
|
||||
|
||||
avformat_close_input(&fmt_ctx);
|
||||
@@ -21,11 +21,12 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavformat muxing API usage example
|
||||
* @example mux.c
|
||||
* @file
|
||||
* libavformat API example.
|
||||
*
|
||||
* Generate a synthetic audio and video signal and mux them to a media file in
|
||||
* any supported libavformat format. The default codecs are used.
|
||||
* Output a media file in any supported libavformat format. The default
|
||||
* codecs are used.
|
||||
* @example muxing.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -218,6 +219,8 @@ static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
|
||||
int sample_rate, int nb_samples)
|
||||
{
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
int ret;
|
||||
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Error allocating an audio frame\n");
|
||||
exit(1);
|
||||
@@ -229,7 +232,8 @@ static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
|
||||
frame->nb_samples = nb_samples;
|
||||
|
||||
if (nb_samples) {
|
||||
if (av_frame_get_buffer(frame, 0) < 0) {
|
||||
ret = av_frame_get_buffer(frame, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error allocating an audio buffer\n");
|
||||
exit(1);
|
||||
}
|
||||
@@ -1,438 +0,0 @@
|
||||
/*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file Intel QSV-accelerated video transcoding API usage example
|
||||
* @example qsv_transcode.c
|
||||
*
|
||||
* Perform QSV-accelerated transcoding and show to dynamically change
|
||||
* encoder's options.
|
||||
*
|
||||
* Usage: qsv_transcode input_stream codec output_stream initial option
|
||||
* { frame_number new_option }
|
||||
* e.g: - qsv_transcode input.mp4 h264_qsv output_h264.mp4 "g 60"
|
||||
* - qsv_transcode input.mp4 hevc_qsv output_hevc.mp4 "g 60 async_depth 1"
|
||||
* 100 "g 120"
|
||||
* (initialize codec with gop_size 60 and change it to 120 after 100
|
||||
* frames)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/opt.h>
|
||||
|
||||
static AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
|
||||
static AVBufferRef *hw_device_ctx = NULL;
|
||||
static AVCodecContext *decoder_ctx = NULL, *encoder_ctx = NULL;
|
||||
static int video_stream = -1;
|
||||
|
||||
typedef struct DynamicSetting {
|
||||
int frame_number;
|
||||
char* optstr;
|
||||
} DynamicSetting;
|
||||
static DynamicSetting *dynamic_setting;
|
||||
static int setting_number;
|
||||
static int current_setting_number;
|
||||
|
||||
static int str_to_dict(char* optstr, AVDictionary **opt)
|
||||
{
|
||||
char *key, *value;
|
||||
if (strlen(optstr) == 0)
|
||||
return 0;
|
||||
key = strtok(optstr, " ");
|
||||
if (key == NULL)
|
||||
return AVERROR(ENAVAIL);
|
||||
value = strtok(NULL, " ");
|
||||
if (value == NULL)
|
||||
return AVERROR(ENAVAIL);
|
||||
av_dict_set(opt, key, value, 0);
|
||||
do {
|
||||
key = strtok(NULL, " ");
|
||||
if (key == NULL)
|
||||
return 0;
|
||||
value = strtok(NULL, " ");
|
||||
if (value == NULL)
|
||||
return AVERROR(ENAVAIL);
|
||||
av_dict_set(opt, key, value, 0);
|
||||
} while(key != NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dynamic_set_parameter(AVCodecContext *avctx)
|
||||
{
|
||||
AVDictionary *opts = NULL;
|
||||
int ret = 0;
|
||||
static int frame_number = 0;
|
||||
frame_number++;
|
||||
if (current_setting_number < setting_number &&
|
||||
frame_number == dynamic_setting[current_setting_number].frame_number) {
|
||||
AVDictionaryEntry *e = NULL;
|
||||
ret = str_to_dict(dynamic_setting[current_setting_number].optstr, &opts);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "The dynamic parameter is wrong\n");
|
||||
goto fail;
|
||||
}
|
||||
/* Set common option. The dictionary will be freed and replaced
|
||||
* by a new one containing all options not found in common option list.
|
||||
* Then this new dictionary is used to set private option. */
|
||||
if ((ret = av_opt_set_dict(avctx, &opts)) < 0)
|
||||
goto fail;
|
||||
/* Set codec specific option */
|
||||
if ((ret = av_opt_set_dict(avctx->priv_data, &opts)) < 0)
|
||||
goto fail;
|
||||
/* There is no "framerate" option in commom option list. Use "-r" to set
|
||||
* framerate, which is compatible with ffmpeg commandline. The video is
|
||||
* assumed to be average frame rate, so set time_base to 1/framerate. */
|
||||
e = av_dict_get(opts, "r", NULL, 0);
|
||||
if (e) {
|
||||
avctx->framerate = av_d2q(atof(e->value), INT_MAX);
|
||||
encoder_ctx->time_base = av_inv_q(encoder_ctx->framerate);
|
||||
}
|
||||
}
|
||||
fail:
|
||||
av_dict_free(&opts);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
|
||||
{
|
||||
while (*pix_fmts != AV_PIX_FMT_NONE) {
|
||||
if (*pix_fmts == AV_PIX_FMT_QSV) {
|
||||
return AV_PIX_FMT_QSV;
|
||||
}
|
||||
|
||||
pix_fmts++;
|
||||
}
|
||||
|
||||
fprintf(stderr, "The QSV pixel format not offered in get_format()\n");
|
||||
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
static int open_input_file(char *filename)
|
||||
{
|
||||
int ret;
|
||||
const AVCodec *decoder = NULL;
|
||||
AVStream *video = NULL;
|
||||
|
||||
if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {
|
||||
fprintf(stderr, "Cannot open input file '%s', Error code: %s\n",
|
||||
filename, av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
|
||||
fprintf(stderr, "Cannot find input stream information. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot find a video stream in the input file. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
video_stream = ret;
|
||||
video = ifmt_ctx->streams[video_stream];
|
||||
|
||||
switch(video->codecpar->codec_id) {
|
||||
case AV_CODEC_ID_H264:
|
||||
decoder = avcodec_find_decoder_by_name("h264_qsv");
|
||||
break;
|
||||
case AV_CODEC_ID_HEVC:
|
||||
decoder = avcodec_find_decoder_by_name("hevc_qsv");
|
||||
break;
|
||||
case AV_CODEC_ID_VP9:
|
||||
decoder = avcodec_find_decoder_by_name("vp9_qsv");
|
||||
break;
|
||||
case AV_CODEC_ID_VP8:
|
||||
decoder = avcodec_find_decoder_by_name("vp8_qsv");
|
||||
break;
|
||||
case AV_CODEC_ID_AV1:
|
||||
decoder = avcodec_find_decoder_by_name("av1_qsv");
|
||||
break;
|
||||
case AV_CODEC_ID_MPEG2VIDEO:
|
||||
decoder = avcodec_find_decoder_by_name("mpeg2_qsv");
|
||||
break;
|
||||
case AV_CODEC_ID_MJPEG:
|
||||
decoder = avcodec_find_decoder_by_name("mjpeg_qsv");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Codec is not supportted by qsv\n");
|
||||
return AVERROR(ENAVAIL);
|
||||
}
|
||||
|
||||
if (!(decoder_ctx = avcodec_alloc_context3(decoder)))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if ((ret = avcodec_parameters_to_context(decoder_ctx, video->codecpar)) < 0) {
|
||||
fprintf(stderr, "avcodec_parameters_to_context error. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
decoder_ctx->framerate = av_guess_frame_rate(ifmt_ctx, video, NULL);
|
||||
|
||||
decoder_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
|
||||
if (!decoder_ctx->hw_device_ctx) {
|
||||
fprintf(stderr, "A hardware device reference create failed.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
decoder_ctx->get_format = get_format;
|
||||
decoder_ctx->pkt_timebase = video->time_base;
|
||||
if ((ret = avcodec_open2(decoder_ctx, decoder, NULL)) < 0)
|
||||
fprintf(stderr, "Failed to open codec for decoding. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int encode_write(AVPacket *enc_pkt, AVFrame *frame)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
av_packet_unref(enc_pkt);
|
||||
|
||||
if((ret = dynamic_set_parameter(encoder_ctx)) < 0) {
|
||||
fprintf(stderr, "Failed to set dynamic parameter. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = avcodec_send_frame(encoder_ctx, frame)) < 0) {
|
||||
fprintf(stderr, "Error during encoding. Error code: %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
while (1) {
|
||||
if (ret = avcodec_receive_packet(encoder_ctx, enc_pkt))
|
||||
break;
|
||||
enc_pkt->stream_index = 0;
|
||||
av_packet_rescale_ts(enc_pkt, encoder_ctx->time_base,
|
||||
ofmt_ctx->streams[0]->time_base);
|
||||
if ((ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt)) < 0) {
|
||||
fprintf(stderr, "Error during writing data to output file. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (ret == AVERROR_EOF)
|
||||
return 0;
|
||||
ret = ((ret == AVERROR(EAGAIN)) ? 0:-1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dec_enc(AVPacket *pkt, const AVCodec *enc_codec, char *optstr)
|
||||
{
|
||||
AVFrame *frame;
|
||||
int ret = 0;
|
||||
|
||||
ret = avcodec_send_packet(decoder_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding. Error code: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
if (!(frame = av_frame_alloc()))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
ret = avcodec_receive_frame(decoder_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
av_frame_free(&frame);
|
||||
return 0;
|
||||
} else if (ret < 0) {
|
||||
fprintf(stderr, "Error while decoding. Error code: %s\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
if (!encoder_ctx->hw_frames_ctx) {
|
||||
AVDictionaryEntry *e = NULL;
|
||||
AVDictionary *opts = NULL;
|
||||
AVStream *ost;
|
||||
/* we need to ref hw_frames_ctx of decoder to initialize encoder's codec.
|
||||
Only after we get a decoded frame, can we obtain its hw_frames_ctx */
|
||||
encoder_ctx->hw_frames_ctx = av_buffer_ref(decoder_ctx->hw_frames_ctx);
|
||||
if (!encoder_ctx->hw_frames_ctx) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
/* set AVCodecContext Parameters for encoder, here we keep them stay
|
||||
* the same as decoder.
|
||||
*/
|
||||
encoder_ctx->time_base = av_inv_q(decoder_ctx->framerate);
|
||||
encoder_ctx->pix_fmt = AV_PIX_FMT_QSV;
|
||||
encoder_ctx->width = decoder_ctx->width;
|
||||
encoder_ctx->height = decoder_ctx->height;
|
||||
if ((ret = str_to_dict(optstr, &opts)) < 0) {
|
||||
fprintf(stderr, "Failed to set encoding parameter.\n");
|
||||
goto fail;
|
||||
}
|
||||
/* There is no "framerate" option in commom option list. Use "-r" to
|
||||
* set framerate, which is compatible with ffmpeg commandline. The
|
||||
* video is assumed to be average frame rate, so set time_base to
|
||||
* 1/framerate. */
|
||||
e = av_dict_get(opts, "r", NULL, 0);
|
||||
if (e) {
|
||||
encoder_ctx->framerate = av_d2q(atof(e->value), INT_MAX);
|
||||
encoder_ctx->time_base = av_inv_q(encoder_ctx->framerate);
|
||||
}
|
||||
if ((ret = avcodec_open2(encoder_ctx, enc_codec, &opts)) < 0) {
|
||||
fprintf(stderr, "Failed to open encode codec. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
av_dict_free(&opts);
|
||||
goto fail;
|
||||
}
|
||||
av_dict_free(&opts);
|
||||
|
||||
if (!(ost = avformat_new_stream(ofmt_ctx, enc_codec))) {
|
||||
fprintf(stderr, "Failed to allocate stream for output format.\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ost->time_base = encoder_ctx->time_base;
|
||||
ret = avcodec_parameters_from_context(ost->codecpar, encoder_ctx);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to copy the stream parameters. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* write the stream header */
|
||||
if ((ret = avformat_write_header(ofmt_ctx, NULL)) < 0) {
|
||||
fprintf(stderr, "Error while writing stream header. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
frame->pts = av_rescale_q(frame->pts, decoder_ctx->pkt_timebase,
|
||||
encoder_ctx->time_base);
|
||||
if ((ret = encode_write(pkt, frame)) < 0)
|
||||
fprintf(stderr, "Error during encoding and writing.\n");
|
||||
|
||||
fail:
|
||||
av_frame_free(&frame);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const AVCodec *enc_codec;
|
||||
int ret = 0;
|
||||
AVPacket *dec_pkt;
|
||||
|
||||
if (argc < 5 || (argc - 5) % 2) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Usage: %s <input file> <encoder> <output file>"
|
||||
" <\"encoding option set 0\"> [<frame_number> <\"encoding options set 1\">]...\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
setting_number = (argc - 5) / 2;
|
||||
dynamic_setting = av_malloc(setting_number * sizeof(*dynamic_setting));
|
||||
current_setting_number = 0;
|
||||
for (int i = 0; i < setting_number; i++) {
|
||||
dynamic_setting[i].frame_number = atoi(argv[i*2 + 5]);
|
||||
dynamic_setting[i].optstr = argv[i*2 + 6];
|
||||
}
|
||||
|
||||
ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_QSV, NULL, NULL, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to create a QSV device. Error code: %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
dec_pkt = av_packet_alloc();
|
||||
if (!dec_pkt) {
|
||||
fprintf(stderr, "Failed to allocate decode packet\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = open_input_file(argv[1])) < 0)
|
||||
goto end;
|
||||
|
||||
if (!(enc_codec = avcodec_find_encoder_by_name(argv[2]))) {
|
||||
fprintf(stderr, "Could not find encoder '%s'\n", argv[2]);
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = (avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, argv[3]))) < 0) {
|
||||
fprintf(stderr, "Failed to deduce output format from file extension. Error code: "
|
||||
"%s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!(encoder_ctx = avcodec_alloc_context3(enc_codec))) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avio_open(&ofmt_ctx->pb, argv[3], AVIO_FLAG_WRITE);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot open output file. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* read all packets and only transcoding video */
|
||||
while (ret >= 0) {
|
||||
if ((ret = av_read_frame(ifmt_ctx, dec_pkt)) < 0)
|
||||
break;
|
||||
|
||||
if (video_stream == dec_pkt->stream_index)
|
||||
ret = dec_enc(dec_pkt, enc_codec, argv[4]);
|
||||
|
||||
av_packet_unref(dec_pkt);
|
||||
}
|
||||
|
||||
/* flush decoder */
|
||||
av_packet_unref(dec_pkt);
|
||||
if ((ret = dec_enc(dec_pkt, enc_codec, argv[4])) < 0) {
|
||||
fprintf(stderr, "Failed to flush decoder %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* flush encoder */
|
||||
if ((ret = encode_write(dec_pkt, NULL)) < 0) {
|
||||
fprintf(stderr, "Failed to flush encoder %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* write the trailer for output stream */
|
||||
if ((ret = av_write_trailer(ofmt_ctx)) < 0)
|
||||
fprintf(stderr, "Failed to write trailer %s\n", av_err2str(ret));
|
||||
|
||||
end:
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
avformat_close_input(&ofmt_ctx);
|
||||
avcodec_free_context(&decoder_ctx);
|
||||
avcodec_free_context(&encoder_ctx);
|
||||
av_buffer_unref(&hw_device_ctx);
|
||||
av_packet_free(&dec_pkt);
|
||||
av_freep(&dynamic_setting);
|
||||
return ret;
|
||||
}
|
||||
@@ -21,11 +21,12 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file Intel QSV-accelerated H.264 decoding API usage example
|
||||
* @example qsv_decode.c
|
||||
* @file
|
||||
* Intel QSV-accelerated H.264 decoding example.
|
||||
*
|
||||
* Perform QSV-accelerated H.264 decoding with output frames in the
|
||||
* GPU video surfaces, write the decoded frames to an output file.
|
||||
* @example qsvdec.c
|
||||
* This example shows how to do QSV-accelerated H.264 decoding with output
|
||||
* frames in the GPU video surfaces.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -21,11 +21,11 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavformat/libavcodec demuxing and muxing API usage example
|
||||
* @example remux.c
|
||||
* @file
|
||||
* libavformat/libavcodec demuxing and muxing API example.
|
||||
*
|
||||
* Remux streams from one container format to another. Data is copied from the
|
||||
* input to the output without transcoding.
|
||||
* Remux streams from one container format to another.
|
||||
* @example remuxing.c
|
||||
*/
|
||||
|
||||
#include <libavutil/timestamp.h>
|
||||
@@ -21,12 +21,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file audio resampling API usage example
|
||||
* @example resample_audio.c
|
||||
*
|
||||
* Generate a synthetic audio signal, and Use libswresample API to perform audio
|
||||
* resampling. The output is written to a raw audio file to be played with
|
||||
* ffplay.
|
||||
* @example resampling_audio.c
|
||||
* libswresample API use example.
|
||||
*/
|
||||
|
||||
#include <libavutil/opt.h>
|
||||
@@ -21,10 +21,9 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libswscale API usage example
|
||||
* @example scale_video.c
|
||||
*
|
||||
* Generate a synthetic video signal and use libswscale to perform rescaling.
|
||||
* @file
|
||||
* libswscale API use example.
|
||||
* @example scaling_video.c
|
||||
*/
|
||||
|
||||
#include <libavutil/imgutils.h>
|
||||
@@ -19,11 +19,12 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file audio transcoding to MPEG/AAC API usage example
|
||||
* @example transcode_aac.c
|
||||
* @file
|
||||
* Simple audio converter
|
||||
*
|
||||
* Convert an input audio file to AAC in an MP4 container. Formats other than
|
||||
* MP4 are supported based on the output file extension.
|
||||
* @example transcode_aac.c
|
||||
* Convert an input audio file to AAC in an MP4 container using FFmpeg.
|
||||
* Formats other than MP4 are supported based on the output file extension.
|
||||
* @author Andreas Unterweger (dustsigns@gmail.com)
|
||||
*/
|
||||
|
||||
|
||||
@@ -23,11 +23,9 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file demuxing, decoding, filtering, encoding and muxing API usage example
|
||||
* @example transcode.c
|
||||
*
|
||||
* Convert input to output file, applying some hard-coded filter-graph on both
|
||||
* audio and video streams.
|
||||
* @file
|
||||
* API example for demuxing, decoding, filtering, encoding and muxing
|
||||
* @example transcoding.c
|
||||
*/
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
@@ -1,4 +1,6 @@
|
||||
/*
|
||||
* Video Acceleration API (video encoding) encode sample
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
@@ -19,12 +21,13 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file Intel VAAPI-accelerated encoding API usage example
|
||||
* @example vaapi_encode.c
|
||||
* @file
|
||||
* Intel VAAPI-accelerated encoding example.
|
||||
*
|
||||
* @example vaapi_encode.c
|
||||
* This example shows how to do VAAPI-accelerated encoding. now only support NV12
|
||||
* raw file, usage like: vaapi_encode 1920 1080 input.yuv output.h264
|
||||
*
|
||||
* Perform VAAPI-accelerated encoding. Read input from an NV12 raw
|
||||
* file, and write the H.264 encoded data to an output raw file.
|
||||
* Usage: vaapi_encode 1920 1080 input.yuv output.h264
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/*
|
||||
* Video Acceleration API (video transcoding) transcode sample
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
@@ -19,10 +21,11 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file Intel VAAPI-accelerated transcoding API usage example
|
||||
* @example vaapi_transcode.c
|
||||
* @file
|
||||
* Intel VAAPI-accelerated transcoding example.
|
||||
*
|
||||
* Perform VAAPI-accelerated transcoding.
|
||||
* @example vaapi_transcode.c
|
||||
* This example shows how to do VAAPI-accelerated transcoding.
|
||||
* Usage: vaapi_transcode input_stream codec output_stream
|
||||
* e.g: - vaapi_transcode input.mp4 h264_vaapi output_h264.mp4
|
||||
* - vaapi_transcode input.mp4 vp9_vaapi output_vp9.ivf
|
||||
|
||||
281
doc/ffmpeg.texi
281
doc/ffmpeg.texi
@@ -877,20 +877,9 @@ This is not the same as the @option{-framerate} option used for some input forma
|
||||
like image2 or v4l2 (it used to be the same in older versions of FFmpeg).
|
||||
If in doubt use @option{-framerate} instead of the input option @option{-r}.
|
||||
|
||||
As an output option:
|
||||
@table @option
|
||||
@item video encoding
|
||||
Duplicate or drop frames right before encoding them to achieve constant output
|
||||
As an output option, duplicate or drop input frames to achieve constant output
|
||||
frame rate @var{fps}.
|
||||
|
||||
@item video streamcopy
|
||||
Indicate to the muxer that @var{fps} is the stream frame rate. No data is
|
||||
dropped or duplicated in this case. This may produce invalid files if @var{fps}
|
||||
does not match the actual stream frame rate as determined by packet timestamps.
|
||||
See also the @code{setts} bitstream filter.
|
||||
|
||||
@end table
|
||||
|
||||
@item -fpsmax[:@var{stream_specifier}] @var{fps} (@emph{output,per-stream})
|
||||
Set maximum frame rate (Hz value, fraction or abbreviation).
|
||||
|
||||
@@ -923,32 +912,6 @@ If used together with @option{-vcodec copy}, it will affect the aspect ratio
|
||||
stored at container level, but not the aspect ratio stored in encoded
|
||||
frames, if it exists.
|
||||
|
||||
@item -display_rotation[:@var{stream_specifier}] @var{rotation} (@emph{input,per-stream})
|
||||
Set video rotation metadata.
|
||||
|
||||
@var{rotation} is a decimal number specifying the amount in degree by
|
||||
which the video should be rotated counter-clockwise before being
|
||||
displayed.
|
||||
|
||||
This option overrides the rotation/display transform metadata stored in
|
||||
the file, if any. When the video is being transcoded (rather than
|
||||
copied) and @code{-autorotate} is enabled, the video will be rotated at
|
||||
the filtering stage. Otherwise, the metadata will be written into the
|
||||
output file if the muxer supports it.
|
||||
|
||||
If the @code{-display_hflip} and/or @code{-display_vflip} options are
|
||||
given, they are applied after the rotation specified by this option.
|
||||
|
||||
@item -display_hflip[:@var{stream_specifier}] (@emph{input,per-stream})
|
||||
Set whether on display the image should be horizontally flipped.
|
||||
|
||||
See the @code{-display_rotation} option for more details.
|
||||
|
||||
@item -display_vflip[:@var{stream_specifier}] (@emph{input,per-stream})
|
||||
Set whether on display the image should be vertically flipped.
|
||||
|
||||
See the @code{-display_rotation} option for more details.
|
||||
|
||||
@item -vn (@emph{input/output})
|
||||
As an input option, blocks all video streams of a file from being filtered or
|
||||
being automatically selected or mapped for any output. See @code{-discard}
|
||||
@@ -1022,9 +985,14 @@ list separated with slashes. Two first values are the beginning and
|
||||
end frame numbers, last one is quantizer to use if positive, or quality
|
||||
factor if negative.
|
||||
|
||||
@item -ilme
|
||||
Force interlacing support in encoder (MPEG-2 and MPEG-4 only).
|
||||
Use this option if your input file is interlaced and you want
|
||||
to keep the interlaced format for minimum losses.
|
||||
The alternative is to deinterlace the input stream by use of a filter
|
||||
such as @code{yadif} or @code{bwdif}, but deinterlacing introduces losses.
|
||||
@item -psnr
|
||||
Calculate PSNR of compressed frames. This option is deprecated, pass the
|
||||
PSNR flag to the encoder instead, using @code{-flags +psnr}.
|
||||
Calculate PSNR of compressed frames.
|
||||
@item -vstats
|
||||
Dump video coding statistics to @file{vstats_HHMMSS.log}.
|
||||
@item -vstats_file @var{file}
|
||||
@@ -1041,6 +1009,8 @@ version > 1:
|
||||
@code{out= %2d st= %2d frame= %5d q= %2.1f PSNR= %6.2f f_size= %6d s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s}
|
||||
@item -top[:@var{stream_specifier}] @var{n} (@emph{output,per-stream})
|
||||
top=1/bottom=0/auto=-1 field first
|
||||
@item -dc @var{precision}
|
||||
Intra_dc_precision.
|
||||
@item -vtag @var{fourcc/tag} (@emph{output})
|
||||
Force video tag/fourcc. This is an alias for @code{-tag:v}.
|
||||
@item -qphist (@emph{global})
|
||||
@@ -1342,22 +1312,6 @@ List all hardware acceleration components enabled in this build of ffmpeg.
|
||||
Actual runtime availability depends on the hardware and its suitable driver
|
||||
being installed.
|
||||
|
||||
@item -fix_sub_duration_heartbeat[:@var{stream_specifier}]
|
||||
Set a specific output video stream as the heartbeat stream according to which
|
||||
to split and push through currently in-progress subtitle upon receipt of a
|
||||
random access packet.
|
||||
|
||||
This lowers the latency of subtitles for which the end packet or the following
|
||||
subtitle has not yet been received. As a drawback, this will most likely lead
|
||||
to duplication of subtitle events in order to cover the full duration, so
|
||||
when dealing with use cases where latency of when the subtitle event is passed
|
||||
on to output is not relevant this option should not be utilized.
|
||||
|
||||
Requires @option{-fix_sub_duration} to be set for the relevant input subtitle
|
||||
stream for this to have any effect, as well as for the input subtitle stream
|
||||
having to be directly mapped to the same output in which the heartbeat stream
|
||||
resides.
|
||||
|
||||
@end table
|
||||
|
||||
@section Audio Options
|
||||
@@ -1456,18 +1410,18 @@ Set the size of the canvas used to render subtitles.
|
||||
@section Advanced options
|
||||
|
||||
@table @option
|
||||
@item -map [-]@var{input_file_id}[:@var{stream_specifier}][?] | @var{[linklabel]} (@emph{output})
|
||||
@item -map [-]@var{input_file_id}[:@var{stream_specifier}][?][,@var{sync_file_id}[:@var{stream_specifier}]] | @var{[linklabel]} (@emph{output})
|
||||
|
||||
Create one or more streams in the output file. This option has two forms for
|
||||
specifying the data source(s): the first selects one or more streams from some
|
||||
input file (specified with @code{-i}), the second takes an output from some
|
||||
complex filtergraph (specified with @code{-filter_complex} or
|
||||
@code{-filter_complex_script}).
|
||||
Designate one or more input streams as a source for the output file. Each input
|
||||
stream is identified by the input file index @var{input_file_id} and
|
||||
the input stream index @var{input_stream_id} within the input
|
||||
file. Both indices start at 0. If specified,
|
||||
@var{sync_file_id}:@var{stream_specifier} sets which input stream
|
||||
is used as a presentation sync reference.
|
||||
|
||||
In the first form, an output stream is created for every stream from the input
|
||||
file with the index @var{input_file_id}. If @var{stream_specifier} is given,
|
||||
only those streams that match the specifier are used (see the
|
||||
@ref{Stream specifiers} section for the @var{stream_specifier} syntax).
|
||||
The first @code{-map} option on the command line specifies the
|
||||
source for output stream 0, the second @code{-map} option specifies
|
||||
the source for output stream 1, etc.
|
||||
|
||||
A @code{-} character before the stream identifier creates a "negative" mapping.
|
||||
It disables matching streams from already created mappings.
|
||||
@@ -1481,56 +1435,39 @@ An alternative @var{[linklabel]} form will map outputs from complex filter
|
||||
graphs (see the @option{-filter_complex} option) to the output file.
|
||||
@var{linklabel} must correspond to a defined output link label in the graph.
|
||||
|
||||
This option may be specified multiple times, each adding more streams to the
|
||||
output file. Any given input stream may also be mapped any number of times as a
|
||||
source for different output streams, e.g. in order to use different encoding
|
||||
options and/or filters. The streams are created in the output in the same order
|
||||
in which the @code{-map} options are given on the commandline.
|
||||
|
||||
Using this option disables the default mappings for this output file.
|
||||
|
||||
Examples:
|
||||
|
||||
@table @emph
|
||||
|
||||
@item map everything
|
||||
To map ALL streams from the first input file to output
|
||||
For example, to map ALL streams from the first input file to output
|
||||
@example
|
||||
ffmpeg -i INPUT -map 0 output
|
||||
@end example
|
||||
|
||||
@item select specific stream
|
||||
If you have two audio streams in the first input file, these streams are
|
||||
identified by @var{0:0} and @var{0:1}. You can use @code{-map} to select which
|
||||
streams to place in an output file. For example:
|
||||
For example, if you have two audio streams in the first input file,
|
||||
these streams are identified by "0:0" and "0:1". You can use
|
||||
@code{-map} to select which streams to place in an output file. For
|
||||
example:
|
||||
@example
|
||||
ffmpeg -i INPUT -map 0:1 out.wav
|
||||
@end example
|
||||
will map the second input stream in @file{INPUT} to the (single) output stream
|
||||
in @file{out.wav}.
|
||||
will map the input stream in @file{INPUT} identified by "0:1" to
|
||||
the (single) output stream in @file{out.wav}.
|
||||
|
||||
@item create multiple streams
|
||||
To select the stream with index 2 from input file @file{a.mov} (specified by the
|
||||
identifier @var{0:2}), and stream with index 6 from input @file{b.mov}
|
||||
(specified by the identifier @var{1:6}), and copy them to the output file
|
||||
@file{out.mov}:
|
||||
For example, to select the stream with index 2 from input file
|
||||
@file{a.mov} (specified by the identifier "0:2"), and stream with
|
||||
index 6 from input @file{b.mov} (specified by the identifier "1:6"),
|
||||
and copy them to the output file @file{out.mov}:
|
||||
@example
|
||||
ffmpeg -i a.mov -i b.mov -c copy -map 0:2 -map 1:6 out.mov
|
||||
@end example
|
||||
|
||||
@item create multiple streams 2
|
||||
To select all video and the third audio stream from an input file:
|
||||
@example
|
||||
ffmpeg -i INPUT -map 0:v -map 0:a:2 OUTPUT
|
||||
@end example
|
||||
|
||||
@item negative map
|
||||
To map all the streams except the second audio, use negative mappings
|
||||
@example
|
||||
ffmpeg -i INPUT -map 0 -map -0:a:1 OUTPUT
|
||||
@end example
|
||||
|
||||
@item optional map
|
||||
To map the video and audio streams from the first input, and using the
|
||||
trailing @code{?}, ignore the audio mapping if no audio streams exist in
|
||||
the first input:
|
||||
@@ -1538,13 +1475,12 @@ the first input:
|
||||
ffmpeg -i INPUT -map 0:v -map 0:a? OUTPUT
|
||||
@end example
|
||||
|
||||
@item map by language
|
||||
To pick the English audio stream:
|
||||
@example
|
||||
ffmpeg -i INPUT -map 0:m:language:eng OUTPUT
|
||||
@end example
|
||||
|
||||
@end table
|
||||
Note that using this option disables the default mappings for this output file.
|
||||
|
||||
@item -ignore_unknown
|
||||
Ignore input streams with unknown type instead of failing if copying
|
||||
@@ -1555,10 +1491,6 @@ Allow input streams with unknown type to be copied instead of failing if copying
|
||||
such streams is attempted.
|
||||
|
||||
@item -map_channel [@var{input_file_id}.@var{stream_specifier}.@var{channel_id}|-1][?][:@var{output_file_id}.@var{stream_specifier}]
|
||||
This option is deprecated and will be removed. It can be replaced by the
|
||||
@var{pan} filter. In some cases it may be easier to use some combination of the
|
||||
@var{channelsplit}, @var{channelmap}, or @var{amerge} filters.
|
||||
|
||||
Map an audio channel from a given input to an output. If
|
||||
@var{output_file_id}.@var{stream_specifier} is not set, the audio channel will
|
||||
be mapped on all the audio streams.
|
||||
@@ -1742,6 +1674,18 @@ The default is -1.1. One possible usecase is to avoid framedrops in case
|
||||
of noisy timestamps or to increase frame drop precision in case of exact
|
||||
timestamps.
|
||||
|
||||
@item -async @var{samples_per_second}
|
||||
Audio sync method. "Stretches/squeezes" the audio stream to match the timestamps,
|
||||
the parameter is the maximum samples per second by which the audio is changed.
|
||||
-async 1 is a special case where only the start of the audio stream is corrected
|
||||
without any later correction.
|
||||
|
||||
Note that the timestamps may be further modified by the muxer, after this.
|
||||
For example, in the case that the format option @option{avoid_negative_ts}
|
||||
is enabled.
|
||||
|
||||
This option has been deprecated. Use the @code{aresample} audio filter instead.
|
||||
|
||||
@item -adrift_threshold @var{time}
|
||||
Set the minimum difference between timestamps and audio data (in seconds) to trigger
|
||||
adding/dropping samples to make it match the timestamps. This option effectively is
|
||||
@@ -1821,22 +1765,6 @@ Default value is 0.
|
||||
Enable bitexact mode for (de)muxer and (de/en)coder
|
||||
@item -shortest (@emph{output})
|
||||
Finish encoding when the shortest output stream ends.
|
||||
|
||||
Note that this option may require buffering frames, which introduces extra
|
||||
latency. The maximum amount of this latency may be controlled with the
|
||||
@code{-shortest_buf_duration} option.
|
||||
|
||||
@item -shortest_buf_duration @var{duration} (@emph{output})
|
||||
The @code{-shortest} option may require buffering potentially large amounts
|
||||
of data when at least one of the streams is "sparse" (i.e. has large gaps
|
||||
between frames – this is typically the case for subtitles).
|
||||
|
||||
This option controls the maximum duration of buffered frames in seconds.
|
||||
Larger values may allow the @code{-shortest} option to produce more accurate
|
||||
results, but increase memory use and latency.
|
||||
|
||||
The default value is 10 seconds.
|
||||
|
||||
@item -dts_delta_threshold
|
||||
Timestamp discontinuity delta threshold.
|
||||
@item -dts_error_threshold @var{seconds}
|
||||
@@ -1971,16 +1899,13 @@ to the @option{-ss} option is considered an actual timestamp, and is not
|
||||
offset by the start time of the file. This matters only for files which do
|
||||
not start from timestamp 0, such as transport streams.
|
||||
|
||||
@item -thread_queue_size @var{size} (@emph{input/output})
|
||||
For input, this option sets the maximum number of queued packets when reading
|
||||
from the file or device. With low latency / high rate live streams, packets may
|
||||
be discarded if they are not read in a timely manner; setting this value can
|
||||
@item -thread_queue_size @var{size} (@emph{input})
|
||||
This option sets the maximum number of queued packets when reading from the
|
||||
file or device. With low latency / high rate live streams, packets may be
|
||||
discarded if they are not read in a timely manner; setting this value can
|
||||
force ffmpeg to use a separate input thread and read packets as soon as they
|
||||
arrive. By default ffmpeg only does this if multiple inputs are specified.
|
||||
|
||||
For output, this option specified the maximum number of packets that may be
|
||||
queued to each muxing thread.
|
||||
|
||||
@item -sdp_file @var{file} (@emph{global})
|
||||
Print sdp information for an output stream to @var{file}.
|
||||
This allows dumping sdp information when at least one output isn't an
|
||||
@@ -2061,116 +1986,6 @@ encoder/muxer, it does not change the stream to conform to this value. Setting
|
||||
values that do not match the stream properties may result in encoding failures
|
||||
or invalid output files.
|
||||
|
||||
@item -stats_enc_pre[:@var{stream_specifier}] @var{path} (@emph{output,per-stream})
|
||||
@item -stats_enc_post[:@var{stream_specifier}] @var{path} (@emph{output,per-stream})
|
||||
@item -stats_mux_pre[:@var{stream_specifier}] @var{path} (@emph{output,per-stream})
|
||||
Write per-frame encoding information about the matching streams into the file
|
||||
given by @var{path}.
|
||||
|
||||
@option{-stats_enc_pre} writes information about raw video or audio frames right
|
||||
before they are sent for encoding, while @option{-stats_enc_post} writes
|
||||
information about encoded packets as they are received from the encoder.
|
||||
@option{-stats_mux_pre} writes information about packets just as they are about to
|
||||
be sent to the muxer. Every frame or packet produces one line in the specified
|
||||
file. The format of this line is controlled by @option{-stats_enc_pre_fmt} /
|
||||
@option{-stats_enc_post_fmt} / @option{-stats_mux_pre_fmt}.
|
||||
|
||||
When stats for multiple streams are written into a single file, the lines
|
||||
corresponding to different streams will be interleaved. The precise order of
|
||||
this interleaving is not specified and not guaranteed to remain stable between
|
||||
different invocations of the program, even with the same options.
|
||||
|
||||
@item -stats_enc_pre_fmt[:@var{stream_specifier}] @var{format_spec} (@emph{output,per-stream})
|
||||
@item -stats_enc_post_fmt[:@var{stream_specifier}] @var{format_spec} (@emph{output,per-stream})
|
||||
@item -stats_mux_pre_fmt[:@var{stream_specifier}] @var{format_spec} (@emph{output,per-stream})
|
||||
Specify the format for the lines written with @option{-stats_enc_pre} /
|
||||
@option{-stats_enc_post} / @option{-stats_mux_pre}.
|
||||
|
||||
@var{format_spec} is a string that may contain directives of the form
|
||||
@var{@{fmt@}}. @var{format_spec} is backslash-escaped --- use \@{, \@}, and \\
|
||||
to write a literal @{, @}, or \, respectively, into the output.
|
||||
|
||||
The directives given with @var{fmt} may be one of the following:
|
||||
@table @option
|
||||
@item fidx
|
||||
Index of the output file.
|
||||
|
||||
@item sidx
|
||||
Index of the output stream in the file.
|
||||
|
||||
@item n
|
||||
Frame number. Pre-encoding: number of frames sent to the encoder so far.
|
||||
Post-encoding: number of packets received from the encoder so far.
|
||||
Muxing: number of packets submitted to the muxer for this stream so far.
|
||||
|
||||
@item ni
|
||||
Input frame number. Index of the input frame (i.e. output by a decoder) that
|
||||
corresponds to this output frame or packet. -1 if unavailable.
|
||||
|
||||
@item tb
|
||||
Encoder timebase, as a rational number @var{num/den}. Note that this may be
|
||||
different from the timebase used by the muxer.
|
||||
|
||||
@item tbi
|
||||
Timebase for @var{ptsi}, as a rational number @var{num/den}. Available when
|
||||
@var{ptsi} is available, @var{0/1} otherwise.
|
||||
|
||||
@item pts
|
||||
Presentation timestamp of the frame or packet, as an integer. Should be
|
||||
multiplied by the timebase to compute presentation time.
|
||||
|
||||
@item ptsi
|
||||
Presentation timestamp of the input frame (see @var{ni}), as an integer. Should
|
||||
be multiplied by @var{tbi} to compute presentation time. Printed as
|
||||
(2^63 - 1 = 9223372036854775807) when not available.
|
||||
|
||||
@item t
|
||||
Presentation time of the frame or packet, as a decimal number. Equal to
|
||||
@var{pts} multiplied by @var{tb}.
|
||||
|
||||
@item ti
|
||||
Presentation time of the input frame (see @var{ni}), as a decimal number. Equal
|
||||
to @var{ptsi} multiplied by @var{tbi}. Printed as inf when not available.
|
||||
|
||||
@item dts
|
||||
Decoding timestamp of the packet, as an integer. Should be multiplied by the
|
||||
timebase to compute presentation time. Post-encoding only.
|
||||
|
||||
@item dt
|
||||
Decoding time of the frame or packet, as a decimal number. Equal to
|
||||
@var{dts} multiplied by @var{tb}.
|
||||
|
||||
@item sn
|
||||
Number of audio samples sent to the encoder so far. Audio and pre-encoding only.
|
||||
|
||||
@item samp
|
||||
Number of audio samples in the frame. Audio and pre-encoding only.
|
||||
|
||||
@item size
|
||||
Size of the encoded packet in bytes. Post-encoding only.
|
||||
|
||||
@item br
|
||||
Current bitrate in bits per second. Post-encoding only.
|
||||
|
||||
@item abr
|
||||
Average bitrate for the whole stream so far, in bits per second, -1 if it cannot
|
||||
be determined at this point. Post-encoding only.
|
||||
@end table
|
||||
|
||||
The default format strings are:
|
||||
@table @option
|
||||
@item pre-encoding
|
||||
@{fidx@} @{sidx@} @{n@} @{t@}
|
||||
@item post-encoding
|
||||
@{fidx@} @{sidx@} @{n@} @{t@}
|
||||
@end table
|
||||
In the future, new items may be added to the end of the default formatting
|
||||
strings. Users who depend on the format staying exactly the same, should
|
||||
prescribe it manually.
|
||||
|
||||
Note that stats for different streams written into the same file may have
|
||||
different formats.
|
||||
|
||||
@end table
|
||||
|
||||
@section Preset files
|
||||
|
||||
@@ -92,8 +92,6 @@
|
||||
<xsd:attribute name="best_effort_timestamp_time" type="xsd:float" />
|
||||
<xsd:attribute name="pkt_duration" type="xsd:long" />
|
||||
<xsd:attribute name="pkt_duration_time" type="xsd:float"/>
|
||||
<xsd:attribute name="duration" type="xsd:long" />
|
||||
<xsd:attribute name="duration_time" type="xsd:float"/>
|
||||
<xsd:attribute name="pkt_pos" type="xsd:long" />
|
||||
<xsd:attribute name="pkt_size" type="xsd:int" />
|
||||
|
||||
@@ -246,7 +244,6 @@
|
||||
<xsd:attribute name="channels" type="xsd:int"/>
|
||||
<xsd:attribute name="channel_layout" type="xsd:string"/>
|
||||
<xsd:attribute name="bits_per_sample" type="xsd:int"/>
|
||||
<xsd:attribute name="initial_padding" type="xsd:int"/>
|
||||
|
||||
<xsd:attribute name="id" type="xsd:string"/>
|
||||
<xsd:attribute name="r_frame_rate" type="xsd:string" use="required"/>
|
||||
|
||||
1287
doc/filters.texi
1287
doc/filters.texi
File diff suppressed because it is too large
Load Diff
@@ -510,8 +510,6 @@ library:
|
||||
@tab A format used by libvpx
|
||||
@item Internet Video Recording @tab @tab X
|
||||
@item IRCAM @tab X @tab X
|
||||
@item LAF @tab @tab X
|
||||
@tab Limitless Audio Format
|
||||
@item LATM @tab X @tab X
|
||||
@item LMLM4 @tab @tab X
|
||||
@tab Used by Linux Media Labs MPEG-4 PCI boards
|
||||
@@ -534,8 +532,6 @@ library:
|
||||
@item Metal Gear Solid: The Twin Snakes @tab @tab X
|
||||
@item Megalux Frame @tab @tab X
|
||||
@tab Used by Megalux Ultimate Paint
|
||||
@item MobiClip MODS @tab @tab X
|
||||
@item MobiClip MOFLEX @tab @tab X
|
||||
@item Mobotix .mxg @tab @tab X
|
||||
@item Monkey's Audio @tab @tab X
|
||||
@item Motion Pixels MVI @tab @tab X
|
||||
@@ -579,7 +575,6 @@ library:
|
||||
@item Ogg @tab X @tab X
|
||||
@item Playstation Portable PMP @tab @tab X
|
||||
@item Portable Voice Format @tab @tab X
|
||||
@item RK Audio (RKA) @tab @tab X
|
||||
@item TechnoTrend PVA @tab @tab X
|
||||
@tab Used by TechnoTrend DVB PCI boards.
|
||||
@item QCP @tab @tab X
|
||||
@@ -587,10 +582,8 @@ library:
|
||||
@item raw AC-3 @tab X @tab X
|
||||
@item raw AMR-NB @tab @tab X
|
||||
@item raw AMR-WB @tab @tab X
|
||||
@item raw APAC @tab @tab X
|
||||
@item raw aptX @tab X @tab X
|
||||
@item raw aptX HD @tab X @tab X
|
||||
@item raw Bonk @tab @tab X
|
||||
@item raw Chinese AVS video @tab X @tab X
|
||||
@item raw DFPWM @tab X @tab X
|
||||
@item raw Dirac @tab X @tab X
|
||||
@@ -666,10 +659,8 @@ library:
|
||||
@item Sample Dump eXchange @tab @tab X
|
||||
@item SAP @tab X @tab X
|
||||
@item SBG @tab @tab X
|
||||
@item SDNS @tab @tab X
|
||||
@item SDP @tab @tab X
|
||||
@item SER @tab @tab X
|
||||
@item Digital Pictures SGA @tab @tab X
|
||||
@item Sega FILM/CPK @tab X @tab X
|
||||
@tab Used in many Sega Saturn console games.
|
||||
@item Silicon Graphics Movie @tab @tab X
|
||||
@@ -707,9 +698,7 @@ library:
|
||||
@item Vivo @tab @tab X
|
||||
@item VPK @tab @tab X
|
||||
@tab Audio format used in Sony PS games.
|
||||
@item Marble WADY @tab @tab X
|
||||
@item WAV @tab X @tab X
|
||||
@item Waveform Archiver @tab @tab X
|
||||
@item WavPack @tab X @tab X
|
||||
@item WebM @tab X @tab X
|
||||
@item Windows Televison (WTV) @tab X @tab X
|
||||
@@ -721,7 +710,6 @@ library:
|
||||
@tab Multimedia format used in Westwood Studios games.
|
||||
@item Wideband Single-bit Data (WSD) @tab @tab X
|
||||
@item WVE @tab @tab X
|
||||
@item Konami XMD @tab @tab X
|
||||
@item XMV @tab @tab X
|
||||
@tab Microsoft video container used in Xbox games.
|
||||
@item XVAG @tab @tab X
|
||||
@@ -761,8 +749,6 @@ following image formats are supported:
|
||||
@tab OpenEXR
|
||||
@item FITS @tab X @tab X
|
||||
@tab Flexible Image Transport System
|
||||
@item HDR @tab X @tab X
|
||||
@tab Radiance HDR RGBE Image format
|
||||
@item IMG @tab @tab X
|
||||
@tab GEM Raster image
|
||||
@item JPEG @tab X @tab X
|
||||
@@ -771,7 +757,6 @@ following image formats are supported:
|
||||
@item JPEG-LS @tab X @tab X
|
||||
@item LJPEG @tab X @tab
|
||||
@tab Lossless JPEG
|
||||
@item Media 100 @tab @tab X
|
||||
@item MSP @tab @tab X
|
||||
@tab Microsoft Paint image
|
||||
@item PAM @tab X @tab X
|
||||
@@ -814,8 +799,6 @@ following image formats are supported:
|
||||
@tab Targa (.TGA) image format
|
||||
@item VBN @tab X @tab X
|
||||
@tab Vizrt Binary Image format
|
||||
@item WBMP @tab X @tab X
|
||||
@tab Wireless Application Protocol Bitmap image format
|
||||
@item WebP @tab E @tab X
|
||||
@tab WebP image format, encoding supported through external library libwebp
|
||||
@item XBM @tab X @tab X
|
||||
@@ -1168,7 +1151,6 @@ following image formats are supported:
|
||||
@item ADPCM IMA Electronic Arts SEAD @tab @tab X
|
||||
@item ADPCM IMA Funcom @tab @tab X
|
||||
@item ADPCM IMA High Voltage Software ALP @tab X @tab X
|
||||
@item ADPCM IMA Mobiclip MOFLEX @tab @tab X
|
||||
@item ADPCM IMA QuickTime @tab X @tab X
|
||||
@item ADPCM IMA Simon & Schuster Interactive @tab X @tab X
|
||||
@item ADPCM IMA Ubisoft APM @tab X @tab X
|
||||
@@ -1198,7 +1180,6 @@ following image formats are supported:
|
||||
@item ADPCM Sound Blaster Pro 4-bit @tab @tab X
|
||||
@item ADPCM VIMA @tab @tab X
|
||||
@tab Used in LucasArts SMUSH animations.
|
||||
@item ADPCM Konami XMD @tab @tab X
|
||||
@item ADPCM Westwood Studios IMA @tab X @tab X
|
||||
@tab Used in Westwood Studios games like Command and Conquer.
|
||||
@item ADPCM Yamaha @tab X @tab X
|
||||
@@ -1220,7 +1201,6 @@ following image formats are supported:
|
||||
@item ATRAC9 @tab @tab X
|
||||
@item Bink Audio @tab @tab X
|
||||
@tab Used in Bink and Smacker files in many games.
|
||||
@item Bonk audio @tab @tab X
|
||||
@item CELT @tab @tab E
|
||||
@tab decoding supported through external library libcelt
|
||||
@item codec2 @tab E @tab E
|
||||
@@ -1236,12 +1216,9 @@ following image formats are supported:
|
||||
@item DCA (DTS Coherent Acoustics) @tab X @tab X
|
||||
@tab supported extensions: XCh, XXCH, X96, XBR, XLL, LBR (partially)
|
||||
@item Dolby E @tab @tab X
|
||||
@item DPCM Cuberoot-Delta-Exact @tab @tab X
|
||||
@tab Used in few games.
|
||||
@item DPCM Gremlin @tab @tab X
|
||||
@item DPCM id RoQ @tab X @tab X
|
||||
@tab Used in Quake III, Jedi Knight 2 and other computer games.
|
||||
@item DPCM Marble WADY @tab @tab X
|
||||
@item DPCM Interplay @tab @tab X
|
||||
@tab Used in various Interplay computer games.
|
||||
@item DPCM Squareroot-Delta-Exact @tab @tab X
|
||||
@@ -1262,7 +1239,6 @@ following image formats are supported:
|
||||
@item Enhanced AC-3 @tab X @tab X
|
||||
@item EVRC (Enhanced Variable Rate Codec) @tab @tab X
|
||||
@item FLAC (Free Lossless Audio Codec) @tab X @tab IX
|
||||
@item FTR Voice @tab @tab X
|
||||
@item G.723.1 @tab X @tab X
|
||||
@item G.729 @tab @tab X
|
||||
@item GSM @tab E @tab X
|
||||
@@ -1276,8 +1252,6 @@ following image formats are supported:
|
||||
@item Interplay ACM @tab @tab X
|
||||
@item MACE (Macintosh Audio Compression/Expansion) 3:1 @tab @tab X
|
||||
@item MACE (Macintosh Audio Compression/Expansion) 6:1 @tab @tab X
|
||||
@item Marian's A-pac audio @tab @tab X
|
||||
@item MI-SC4 (Micronas SC-4 Audio) @tab @tab X
|
||||
@item MLP (Meridian Lossless Packing) @tab X @tab X
|
||||
@tab Used in DVD-Audio discs.
|
||||
@item Monkey's Audio @tab @tab X
|
||||
@@ -1287,7 +1261,6 @@ following image formats are supported:
|
||||
@item MP3 (MPEG audio layer 3) @tab E @tab IX
|
||||
@tab encoding supported through external library LAME, ADU MP3 and MP3onMP4 also supported
|
||||
@item MPEG-4 Audio Lossless Coding (ALS) @tab @tab X
|
||||
@item MobiClip FastAudio @tab @tab X
|
||||
@item Musepack SV7 @tab @tab X
|
||||
@item Musepack SV8 @tab @tab X
|
||||
@item Nellymoser Asao @tab X @tab X
|
||||
@@ -1322,7 +1295,6 @@ following image formats are supported:
|
||||
@item PCM unsigned 24-bit little-endian @tab X @tab X
|
||||
@item PCM unsigned 32-bit big-endian @tab X @tab X
|
||||
@item PCM unsigned 32-bit little-endian @tab X @tab X
|
||||
@item PCM SGA @tab @tab X
|
||||
@item QCELP / PureVoice @tab @tab X
|
||||
@item QDesign Music Codec 1 @tab @tab X
|
||||
@item QDesign Music Codec 2 @tab @tab X
|
||||
@@ -1335,7 +1307,6 @@ following image formats are supported:
|
||||
@tab Real low bitrate AC-3 codec
|
||||
@item RealAudio Lossless @tab @tab X
|
||||
@item RealAudio SIPR / ACELP.NET @tab @tab X
|
||||
@item RK Audio (RKA) @tab @tab X
|
||||
@item SBC (low-complexity subband codec) @tab X @tab X
|
||||
@tab Used in Bluetooth A2DP
|
||||
@item Shorten @tab @tab X
|
||||
@@ -1356,11 +1327,9 @@ following image formats are supported:
|
||||
@item TwinVQ (VQF flavor) @tab @tab X
|
||||
@item VIMA @tab @tab X
|
||||
@tab Used in LucasArts SMUSH animations.
|
||||
@item ViewQuest VQC @tab @tab X
|
||||
@item Vorbis @tab E @tab X
|
||||
@tab A native but very primitive encoder exists.
|
||||
@item Voxware MetaSound @tab @tab X
|
||||
@item Waveform Archiver @tab @tab X
|
||||
@item WavPack @tab X @tab X
|
||||
@item Westwood Audio (SND1) @tab @tab X
|
||||
@item Windows Media Audio 1 @tab X @tab X
|
||||
|
||||
@@ -53,7 +53,7 @@ Most distribution and operating system provide a package for it.
|
||||
@section Cloning the source tree
|
||||
|
||||
@example
|
||||
git clone https://git.ffmpeg.org/ffmpeg.git <target>
|
||||
git clone git://source.ffmpeg.org/ffmpeg <target>
|
||||
@end example
|
||||
|
||||
This will put the FFmpeg sources into the directory @var{<target>}.
|
||||
@@ -187,18 +187,11 @@ to make sure you don't have untracked files or deletions.
|
||||
git add [-i|-p|-A] <filenames/dirnames>
|
||||
@end example
|
||||
|
||||
Make sure you have told Git your name, email address and GPG key
|
||||
Make sure you have told Git your name and email address
|
||||
|
||||
@example
|
||||
git config --global user.name "My Name"
|
||||
git config --global user.email my@@email.invalid
|
||||
git config --global user.signingkey ABCDEF0123245
|
||||
@end example
|
||||
|
||||
Enable signing all commits or use -S
|
||||
|
||||
@example
|
||||
git config --global commit.gpgsign true
|
||||
@end example
|
||||
|
||||
Use @option{--global} to set the global configuration for all your Git checkouts.
|
||||
@@ -430,19 +423,6 @@ git checkout -b svn_23456 $SHA1
|
||||
where @var{$SHA1} is the commit hash from the @command{git log} output.
|
||||
|
||||
|
||||
@chapter gpg key generation
|
||||
|
||||
If you have no gpg key yet, we recommend that you create a ed25519 based key as it
|
||||
is small, fast and secure. Especially it results in small signatures in git.
|
||||
|
||||
@example
|
||||
gpg --default-new-key-algo "ed25519/cert,sign+cv25519/encr" --quick-generate-key "human@@server.com"
|
||||
@end example
|
||||
|
||||
When generating a key, make sure the email specified matches the email used in git as some sites like
|
||||
github consider mismatches a reason to declare such commits unverified. After generating a key you
|
||||
can add it to the MAINTAINER file and upload it to a keyserver.
|
||||
|
||||
@chapter Pre-push checklist
|
||||
|
||||
Once you have a set of commits that you feel are ready for pushing,
|
||||
|
||||
@@ -795,6 +795,12 @@ deletes them. Increase this to allow continue clients to download segments which
|
||||
were recently referenced in the playlist. Default value is 1, meaning segments older than
|
||||
@code{hls_list_size+1} will be deleted.
|
||||
|
||||
@item hls_ts_options @var{options_list}
|
||||
Set output format options using a :-separated list of key=value
|
||||
parameters. Values containing @code{:} special characters must be
|
||||
escaped.
|
||||
@code{hls_ts_options} is deprecated, use hls_segment_options instead of it..
|
||||
|
||||
@item hls_start_number_source
|
||||
Start the playlist sequence number (@code{#EXT-X-MEDIA-SEQUENCE}) according to the specified source.
|
||||
Unless @code{hls_flags single_file} is set, it also specifies source of starting sequence numbers of
|
||||
@@ -1909,8 +1915,6 @@ Conform to System B (DVB) instead of System A (ATSC).
|
||||
Mark the initial packet of each stream as discontinuity.
|
||||
@item nit
|
||||
Emit NIT table.
|
||||
@item omit_rai
|
||||
Disable writing of random access indicator.
|
||||
@end table
|
||||
|
||||
@item mpegts_copyts @var{boolean}
|
||||
@@ -2363,11 +2367,6 @@ Note that splitting may not be accurate, unless you force the
|
||||
reference stream key-frames at the given time. See the introductory
|
||||
notice and the examples below.
|
||||
|
||||
@item min_seg_duration @var{time}
|
||||
Set minimum segment duration to @var{time}, the value must be a duration
|
||||
specification. This prevents the muxer ending segments at a duration below
|
||||
this value. Only effective with @code{segment_time}. Default value is "0".
|
||||
|
||||
@item segment_atclocktime @var{1|0}
|
||||
If set to "1" split at regular clock time intervals starting from 00:00
|
||||
o'clock. The @var{time} value specified in @option{segment_time} is
|
||||
|
||||
@@ -267,11 +267,6 @@ CELL/SPU:
|
||||
http://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/30B3520C93F437AB87257060006FFE5E/$file/Language_Extensions_for_CBEA_2.4.pdf
|
||||
http://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/9F820A5FFA3ECE8C8725716A0062585F/$file/CBE_Handbook_v1.1_24APR2007_pub.pdf
|
||||
|
||||
RISC-V-specific:
|
||||
----------------
|
||||
The RISC-V Instruction Set Manual, Volume 1, Unprivileged ISA:
|
||||
https://riscv.org/technical/specifications/
|
||||
|
||||
GCC asm links:
|
||||
--------------
|
||||
official doc but quite ugly
|
||||
|
||||
@@ -275,33 +275,6 @@ For example, to convert a GIF file given inline with @command{ffmpeg}:
|
||||
ffmpeg -i "data:image/gif;base64,R0lGODdhCAAIAMIEAAAAAAAA//8AAP//AP///////////////ywAAAAACAAIAAADF0gEDLojDgdGiJdJqUX02iB4E8Q9jUMkADs=" smiley.png
|
||||
@end example
|
||||
|
||||
@section fd
|
||||
|
||||
File descriptor access protocol.
|
||||
|
||||
The accepted syntax is:
|
||||
@example
|
||||
fd: -fd @var{file_descriptor}
|
||||
@end example
|
||||
|
||||
If @option{fd} is not specified, by default the stdout file descriptor will be
|
||||
used for writing, stdin for reading. Unlike the pipe protocol, fd protocol has
|
||||
seek support if it corresponding to a regular file. fd protocol doesn't support
|
||||
pass file descriptor via URL for security.
|
||||
|
||||
This protocol accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item blocksize
|
||||
Set I/O operation maximum block size, in bytes. Default value is
|
||||
@code{INT_MAX}, which results in not limiting the requested block size.
|
||||
Setting this value reasonably low improves user termination request reaction
|
||||
time, which is valuable if data transmission is slow.
|
||||
|
||||
@item fd
|
||||
Set file descriptor.
|
||||
@end table
|
||||
|
||||
@section file
|
||||
|
||||
File access protocol.
|
||||
@@ -649,6 +622,9 @@ This protocol wraps the IPFS native protocols (ipfs:// and ipns://) to be sent
|
||||
to such a gateway. Users can (and should) host their own node which means this
|
||||
protocol will use one's local gateway to access files on the IPFS network.
|
||||
|
||||
If a user doesn't have a node of their own then the public gateway @code{https://dweb.link}
|
||||
is used by default.
|
||||
|
||||
This protocol accepts the following options:
|
||||
|
||||
@table @option
|
||||
@@ -656,18 +632,18 @@ This protocol accepts the following options:
|
||||
@item gateway
|
||||
Defines the gateway to use. When not set, the protocol will first try
|
||||
locating the local gateway by looking at @code{$IPFS_GATEWAY}, @code{$IPFS_PATH}
|
||||
and @code{$HOME/.ipfs/}, in that order.
|
||||
and @code{$HOME/.ipfs/}, in that order. If that fails @code{https://dweb.link} will be used.
|
||||
|
||||
@end table
|
||||
|
||||
One can use this protocol in 2 ways. Using IPFS:
|
||||
@example
|
||||
ffplay ipfs://<hash>
|
||||
ffplay ipfs://QmbGtJg23skhvFmu9mJiePVByhfzu5rwo74MEkVDYAmF5T
|
||||
@end example
|
||||
|
||||
Or the IPNS protocol (IPNS is mutable IPFS):
|
||||
@example
|
||||
ffplay ipns://<hash>
|
||||
ffplay ipns://QmbGtJg23skhvFmu9mJiePVByhfzu5rwo74MEkVDYAmF5T
|
||||
@end example
|
||||
|
||||
@section mmst
|
||||
@@ -714,7 +690,7 @@ The accepted syntax is:
|
||||
pipe:[@var{number}]
|
||||
@end example
|
||||
|
||||
If @option{fd} isn't specified, @var{number} is the number corresponding to the file descriptor of the
|
||||
@var{number} is the number corresponding to the file descriptor of the
|
||||
pipe (e.g. 0 for stdin, 1 for stdout, 2 for stderr). If @var{number}
|
||||
is not specified, by default the stdout file descriptor will be used
|
||||
for writing, stdin for reading.
|
||||
@@ -741,8 +717,6 @@ Set I/O operation maximum block size, in bytes. Default value is
|
||||
@code{INT_MAX}, which results in not limiting the requested block size.
|
||||
Setting this value reasonably low improves user termination request reaction
|
||||
time, which is valuable if data transmission is slow.
|
||||
@item fd
|
||||
Set file descriptor.
|
||||
@end table
|
||||
|
||||
Note that some formats (typically MOV), require the output protocol to
|
||||
@@ -1204,59 +1178,6 @@ Options can be set on the @command{ffmpeg}/@command{ffplay} command
|
||||
line, or set in code via @code{AVOption}s or in
|
||||
@code{avformat_open_input}.
|
||||
|
||||
@subsection Muxer
|
||||
The following options are supported.
|
||||
|
||||
@table @option
|
||||
@item rtsp_transport
|
||||
Set RTSP transport protocols.
|
||||
|
||||
It accepts the following values:
|
||||
@table @samp
|
||||
@item udp
|
||||
Use UDP as lower transport protocol.
|
||||
|
||||
@item tcp
|
||||
Use TCP (interleaving within the RTSP control channel) as lower
|
||||
transport protocol.
|
||||
@end table
|
||||
|
||||
Default value is @samp{0}.
|
||||
|
||||
@item rtsp_flags
|
||||
Set RTSP flags.
|
||||
|
||||
The following values are accepted:
|
||||
@table @samp
|
||||
@item latm
|
||||
Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC.
|
||||
@item rfc2190
|
||||
Use RFC 2190 packetization instead of RFC 4629 for H.263.
|
||||
@item skip_rtcp
|
||||
Don't send RTCP sender reports.
|
||||
@item h264_mode0
|
||||
Use mode 0 for H.264 in RTP.
|
||||
@item send_bye
|
||||
Send RTCP BYE packets when finishing.
|
||||
@end table
|
||||
|
||||
Default value is @samp{0}.
|
||||
|
||||
|
||||
@item min_port
|
||||
Set minimum local UDP port. Default value is 5000.
|
||||
|
||||
@item max_port
|
||||
Set maximum local UDP port. Default value is 65000.
|
||||
|
||||
@item buffer_size
|
||||
Set the maximum socket buffer size in bytes.
|
||||
|
||||
@item pkt_size
|
||||
Set max send packet size (in bytes). Default value is 1472.
|
||||
@end table
|
||||
|
||||
@subsection Demuxer
|
||||
The following options are supported.
|
||||
|
||||
@table @option
|
||||
@@ -1282,10 +1203,6 @@ Use UDP multicast as lower transport protocol.
|
||||
@item http
|
||||
Use HTTP tunneling as lower transport protocol, which is useful for
|
||||
passing proxies.
|
||||
|
||||
@item https
|
||||
Use HTTPs tunneling as lower transport protocol, which is useful for
|
||||
passing proxies and widely used for security consideration.
|
||||
@end table
|
||||
|
||||
Multiple lower transport protocols may be specified, in that case they are
|
||||
@@ -1303,9 +1220,6 @@ Accept packets only from negotiated peer address and port.
|
||||
Act as a server, listening for an incoming connection.
|
||||
@item prefer_tcp
|
||||
Try TCP for RTP transport first, if TCP is available as RTSP RTP transport.
|
||||
@item satip_raw
|
||||
Export raw MPEG-TS stream instead of demuxing. The flag will simply write out
|
||||
the raw stream, with the original PAT/PMT/PIDs intact.
|
||||
@end table
|
||||
|
||||
Default value is @samp{none}.
|
||||
@@ -1318,7 +1232,6 @@ The following flags are accepted:
|
||||
@item video
|
||||
@item audio
|
||||
@item data
|
||||
@item subtitle
|
||||
@end table
|
||||
|
||||
By default it accepts all media types.
|
||||
@@ -1343,9 +1256,6 @@ Set socket TCP I/O timeout in microseconds.
|
||||
@item user_agent
|
||||
Override User-Agent header. If not specified, it defaults to the
|
||||
libavformat identifier string.
|
||||
|
||||
@item buffer_size
|
||||
Set the maximum socket buffer size in bytes.
|
||||
@end table
|
||||
|
||||
When receiving data over UDP, the demuxer tries to reorder received packets
|
||||
|
||||
@@ -11,8 +11,18 @@ programmatic use.
|
||||
|
||||
@table @option
|
||||
|
||||
@item uchl, used_chlayout
|
||||
Set used input channel layout. Default is unset. This option is
|
||||
@item ich, in_channel_count
|
||||
Set the number of input channels. Default value is 0. Setting this
|
||||
value is not mandatory if the corresponding channel layout
|
||||
@option{in_channel_layout} is set.
|
||||
|
||||
@item och, out_channel_count
|
||||
Set the number of output channels. Default value is 0. Setting this
|
||||
value is not mandatory if the corresponding channel layout
|
||||
@option{out_channel_layout} is set.
|
||||
|
||||
@item uch, used_channel_count
|
||||
Set the number of used input channels. Default value is 0. This option is
|
||||
only used for special remapping.
|
||||
|
||||
@item isr, in_sample_rate
|
||||
@@ -31,8 +41,8 @@ Specify the output sample format. It is set by default to @code{none}.
|
||||
Set the internal sample format. Default value is @code{none}.
|
||||
This will automatically be chosen when it is not explicitly set.
|
||||
|
||||
@item ichl, in_chlayout
|
||||
@item ochl, out_chlayout
|
||||
@item icl, in_channel_layout
|
||||
@item ocl, out_channel_layout
|
||||
Set the input/output channel layout.
|
||||
|
||||
See @ref{channel layout syntax,,the Channel Layout section in the ffmpeg-utils(1) manual,ffmpeg-utils}
|
||||
|
||||
106
doc/t2h.pm
106
doc/t2h.pm
@@ -20,45 +20,8 @@
|
||||
# License along with FFmpeg; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
# Texinfo 7.0 changed the syntax of various functions.
|
||||
# Provide a shim for older versions.
|
||||
sub ff_set_from_init_file($$) {
|
||||
my $key = shift;
|
||||
my $value = shift;
|
||||
if (exists &{'texinfo_set_from_init_file'}) {
|
||||
texinfo_set_from_init_file($key, $value);
|
||||
} else {
|
||||
set_from_init_file($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
sub ff_get_conf($) {
|
||||
my $key = shift;
|
||||
if (exists &{'texinfo_get_conf'}) {
|
||||
texinfo_get_conf($key);
|
||||
} else {
|
||||
get_conf($key);
|
||||
}
|
||||
}
|
||||
|
||||
sub get_formatting_function($$) {
|
||||
my $obj = shift;
|
||||
my $func = shift;
|
||||
|
||||
my $sub = $obj->can('formatting_function');
|
||||
if ($sub) {
|
||||
return $obj->formatting_function($func);
|
||||
} else {
|
||||
return $obj->{$func};
|
||||
}
|
||||
}
|
||||
|
||||
# determine texinfo version
|
||||
my $program_version_num = version->declare(ff_get_conf('PACKAGE_VERSION'))->numify;
|
||||
my $program_version_6_8 = $program_version_num >= 6.008000;
|
||||
|
||||
# no navigation elements
|
||||
ff_set_from_init_file('HEADERS', 0);
|
||||
set_from_init_file('HEADERS', 0);
|
||||
|
||||
sub ffmpeg_heading_command($$$$$)
|
||||
{
|
||||
@@ -92,7 +55,7 @@ sub ffmpeg_heading_command($$$$$)
|
||||
$element = $command->{'parent'};
|
||||
}
|
||||
if ($element) {
|
||||
$result .= &{get_formatting_function($self, 'format_element_header')}($self, $cmdname,
|
||||
$result .= &{$self->{'format_element_header'}}($self, $cmdname,
|
||||
$command, $element);
|
||||
}
|
||||
|
||||
@@ -149,11 +112,7 @@ sub ffmpeg_heading_command($$$$$)
|
||||
$cmdname
|
||||
= $Texinfo::Common::level_to_structuring_command{$cmdname}->[$heading_level];
|
||||
}
|
||||
# format_heading_text expects an array of headings for texinfo >= 7.0
|
||||
if ($program_version_num >= 7.000000) {
|
||||
$heading = [$heading];
|
||||
}
|
||||
$result .= &{get_formatting_function($self,'format_heading_text')}(
|
||||
$result .= &{$self->{'format_heading_text'}}(
|
||||
$self, $cmdname, $heading,
|
||||
$heading_level +
|
||||
$self->get_conf('CHAPTER_HEADER_LEVEL') - 1, $command);
|
||||
@@ -167,19 +126,23 @@ foreach my $command (keys(%Texinfo::Common::sectioning_commands), 'node') {
|
||||
texinfo_register_command_formatting($command, \&ffmpeg_heading_command);
|
||||
}
|
||||
|
||||
# determine if texinfo is at least version 6.8
|
||||
my $program_version_num = version->declare(get_conf('PACKAGE_VERSION'))->numify;
|
||||
my $program_version_6_8 = $program_version_num >= 6.008000;
|
||||
|
||||
# print the TOC where @contents is used
|
||||
if ($program_version_6_8) {
|
||||
ff_set_from_init_file('CONTENTS_OUTPUT_LOCATION', 'inline');
|
||||
set_from_init_file('CONTENTS_OUTPUT_LOCATION', 'inline');
|
||||
} else {
|
||||
ff_set_from_init_file('INLINE_CONTENTS', 1);
|
||||
set_from_init_file('INLINE_CONTENTS', 1);
|
||||
}
|
||||
|
||||
# make chapters <h2>
|
||||
ff_set_from_init_file('CHAPTER_HEADER_LEVEL', 2);
|
||||
set_from_init_file('CHAPTER_HEADER_LEVEL', 2);
|
||||
|
||||
# Do not add <hr>
|
||||
ff_set_from_init_file('DEFAULT_RULE', '');
|
||||
ff_set_from_init_file('BIG_RULE', '');
|
||||
set_from_init_file('DEFAULT_RULE', '');
|
||||
set_from_init_file('BIG_RULE', '');
|
||||
|
||||
# Customized file beginning
|
||||
sub ffmpeg_begin_file($$$)
|
||||
@@ -196,18 +159,7 @@ sub ffmpeg_begin_file($$$)
|
||||
my ($title, $description, $encoding, $date, $css_lines,
|
||||
$doctype, $bodytext, $copying_comment, $after_body_open,
|
||||
$extra_head, $program_and_version, $program_homepage,
|
||||
$program, $generator);
|
||||
if ($program_version_num >= 7.000000) {
|
||||
($title, $description, $encoding, $date, $css_lines,
|
||||
$doctype, $bodytext, $copying_comment, $after_body_open,
|
||||
$extra_head, $program_and_version, $program_homepage,
|
||||
$program, $generator) = $self->_file_header_information($command);
|
||||
} else {
|
||||
($title, $description, $encoding, $date, $css_lines,
|
||||
$doctype, $bodytext, $copying_comment, $after_body_open,
|
||||
$extra_head, $program_and_version, $program_homepage,
|
||||
$program, $generator) = $self->_file_header_informations($command);
|
||||
}
|
||||
$program, $generator) = $self->_file_header_informations($command);
|
||||
|
||||
my $links = $self->_get_links ($filename, $element);
|
||||
|
||||
@@ -271,7 +223,7 @@ if ($program_version_6_8) {
|
||||
sub ffmpeg_end_file($)
|
||||
{
|
||||
my $self = shift;
|
||||
my $program_string = &{get_formatting_function($self,'format_program_string')}($self);
|
||||
my $program_string = &{$self->{'format_program_string'}}($self);
|
||||
my $program_text = <<EOT;
|
||||
<p style="font-size: small;">
|
||||
$program_string
|
||||
@@ -292,7 +244,7 @@ if ($program_version_6_8) {
|
||||
|
||||
# Dummy title command
|
||||
# Ignore title. Title is handled through ffmpeg_begin_file().
|
||||
ff_set_from_init_file('USE_TITLEPAGE_FOR_TITLE', 1);
|
||||
set_from_init_file('USE_TITLEPAGE_FOR_TITLE', 1);
|
||||
sub ffmpeg_title($$$$)
|
||||
{
|
||||
return '';
|
||||
@@ -310,14 +262,8 @@ sub ffmpeg_float($$$$$)
|
||||
my $args = shift;
|
||||
my $content = shift;
|
||||
|
||||
my ($caption, $prepended);
|
||||
if ($program_version_num >= 7.000000) {
|
||||
($caption, $prepended) = Texinfo::Convert::Converter::float_name_caption($self,
|
||||
$command);
|
||||
} else {
|
||||
($caption, $prepended) = Texinfo::Common::float_name_caption($self,
|
||||
$command);
|
||||
}
|
||||
my ($caption, $prepended) = Texinfo::Common::float_name_caption($self,
|
||||
$command);
|
||||
my $caption_text = '';
|
||||
my $prepended_text;
|
||||
my $prepended_save = '';
|
||||
@@ -389,13 +335,8 @@ sub ffmpeg_float($$$$$)
|
||||
$caption->{'args'}->[0], 'float caption');
|
||||
}
|
||||
if ($prepended_text.$caption_text ne '') {
|
||||
if ($program_version_num >= 7.000000) {
|
||||
$prepended_text = $self->html_attribute_class('div',['float-caption']). '>'
|
||||
. $prepended_text;
|
||||
} else {
|
||||
$prepended_text = $self->_attribute_class('div','float-caption'). '>'
|
||||
. $prepended_text;
|
||||
}
|
||||
$prepended_text = $self->_attribute_class('div','float-caption'). '>'
|
||||
. $prepended_text;
|
||||
$caption_text .= '</div>';
|
||||
}
|
||||
my $html_class = '';
|
||||
@@ -408,13 +349,8 @@ sub ffmpeg_float($$$$$)
|
||||
$prepended_text = '';
|
||||
$caption_text = '';
|
||||
}
|
||||
if ($program_version_num >= 7.000000) {
|
||||
return $self->html_attribute_class('div', [$html_class]). '>' . "\n" .
|
||||
$prepended_text . $caption_text . $content . '</div>';
|
||||
} else {
|
||||
return $self->_attribute_class('div', $html_class). '>' . "\n" .
|
||||
$prepended_text . $caption_text . $content . '</div>';
|
||||
}
|
||||
return $self->_attribute_class('div', $html_class). '>' . "\n" .
|
||||
$prepended_text . $caption_text . $content . '</div>';
|
||||
}
|
||||
|
||||
texinfo_register_command_formatting('float',
|
||||
|
||||
@@ -704,326 +704,3 @@ Also note that this function requires a special iteration way, due to coefficien
|
||||
beginning to overlap, particularly `[o1]` with `[0]` after the second iteration.
|
||||
To iterate further, set `z = &z[16]` via `z += 8` for the second iteration. After
|
||||
the 4th iteration, the layout resets, so repeat the same.
|
||||
|
||||
|
||||
# 15-point AVX FFT transform
|
||||
The 15-point transform is based on the following unrolling. The input
|
||||
must be permuted via the following loop:
|
||||
|
||||
``` C
|
||||
for (int k = 0; k < s->sub[0].len; k++) {
|
||||
int cnt = 0;
|
||||
int tmp[15];
|
||||
memcpy(tmp, &s->map[k*15], 15*sizeof(*tmp));
|
||||
for (int i = 1; i < 15; i += 3) {
|
||||
s->map[k*15 + cnt] = tmp[i];
|
||||
cnt++;
|
||||
}
|
||||
for (int i = 2; i < 15; i += 3) {
|
||||
s->map[k*15 + cnt] = tmp[i];
|
||||
cnt++;
|
||||
}
|
||||
for (int i = 0; i < 15; i += 3) {
|
||||
s->map[k*15 + cnt] = tmp[i];
|
||||
cnt++;
|
||||
}
|
||||
memmove(&s->map[k*15 + 7], &s->map[k*15 + 6], 4*sizeof(int));
|
||||
memmove(&s->map[k*15 + 3], &s->map[k*15 + 1], 4*sizeof(int));
|
||||
s->map[k*15 + 1] = tmp[2];
|
||||
s->map[k*15 + 2] = tmp[0];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
This separates the ACs from the DCs and flips the SIMD direction to
|
||||
performing 5x3pt transforms at once, followed by 3x5pt transforms.
|
||||
|
||||
``` C
|
||||
static av_always_inline void fft15(TXComplex *out, TXComplex *in,
|
||||
ptrdiff_t stride)
|
||||
{
|
||||
const TXSample *tab = TX_TAB(ff_tx_tab_53);
|
||||
TXComplex q[20];
|
||||
TXComplex dc[3], pc[32];
|
||||
TXComplex y[32], k[32];
|
||||
TXComplex t[32];
|
||||
TXComplex r[32];
|
||||
TXComplex z0[32];
|
||||
|
||||
/* DC */
|
||||
pc[0].re = in[ 1].im - in[ 0].im;
|
||||
pc[0].im = in[ 1].re - in[ 0].re;
|
||||
pc[1].re = in[ 1].re + in[ 0].re;
|
||||
pc[1].im = in[ 1].im + in[ 0].im;
|
||||
|
||||
dc[0].re = in[2].re + pc[1].re;
|
||||
dc[0].im = in[2].im + pc[1].im;
|
||||
|
||||
pc[0].re = tab[ 8] * pc[0].re;
|
||||
pc[0].im = tab[ 9] * pc[0].im;
|
||||
pc[1].re = tab[10] * pc[1].re;
|
||||
pc[1].im = tab[11] * pc[1].im;
|
||||
|
||||
dc[1].re = pc[0].re + pc[1].re;
|
||||
dc[1].im = pc[0].im + pc[1].im;
|
||||
dc[2].re = pc[1].re - pc[0].re;
|
||||
dc[2].im = pc[1].im - pc[0].im;
|
||||
|
||||
dc[1].re = in[2].re - dc[1].re;
|
||||
dc[1].im = in[2].im + dc[1].im;
|
||||
dc[2].re = in[2].re - dc[2].re;
|
||||
dc[2].im = in[2].im + dc[2].im;
|
||||
|
||||
/* ACs */
|
||||
q[0].im = in[ 3].re - in[ 7].re; // NOTE THE ORDER
|
||||
q[0].re = in[ 3].im - in[ 7].im;
|
||||
q[1].im = in[ 4].re - in[ 8].re;
|
||||
q[1].re = in[ 4].im - in[ 8].im;
|
||||
q[2].im = in[ 5].re - in[ 9].re;
|
||||
q[2].re = in[ 5].im - in[ 9].im;
|
||||
q[3].re = in[ 6].im - in[10].im;
|
||||
q[3].im = in[ 6].re - in[10].re;
|
||||
|
||||
q[4].re = in[ 3].re + in[ 7].re;
|
||||
q[4].im = in[ 3].im + in[ 7].im;
|
||||
q[5].re = in[ 4].re + in[ 8].re;
|
||||
q[5].im = in[ 4].im + in[ 8].im;
|
||||
q[6].re = in[ 5].re + in[ 9].re;
|
||||
q[6].im = in[ 5].im + in[ 9].im;
|
||||
q[7].re = in[ 6].re + in[10].re;
|
||||
q[7].im = in[ 6].im + in[10].im;
|
||||
|
||||
y[0].re = in[11].re + q[4].re;
|
||||
y[0].im = in[11].im + q[4].im;
|
||||
y[1].re = in[12].re + q[5].re;
|
||||
y[1].im = in[12].im + q[5].im;
|
||||
y[2].re = in[13].re + q[6].re;
|
||||
y[2].im = in[13].im + q[6].im;
|
||||
y[3].re = in[14].re + q[7].re;
|
||||
y[3].im = in[14].im + q[7].im;
|
||||
|
||||
q[0].re = tab[ 8] * q[0].re;
|
||||
q[0].im = tab[ 9] * q[0].im;
|
||||
q[1].re = tab[ 8] * q[1].re;
|
||||
q[1].im = tab[ 9] * q[1].im;
|
||||
q[2].re = tab[ 8] * q[2].re;
|
||||
q[2].im = tab[ 9] * q[2].im;
|
||||
q[3].re = tab[ 8] * q[3].re;
|
||||
q[3].im = tab[ 9] * q[3].im;
|
||||
|
||||
q[4].re = tab[10] * q[4].re;
|
||||
q[4].im = tab[11] * q[4].im;
|
||||
q[5].re = tab[10] * q[5].re;
|
||||
q[5].im = tab[11] * q[5].im;
|
||||
q[6].re = tab[10] * q[6].re;
|
||||
q[6].im = tab[11] * q[6].im;
|
||||
q[7].re = tab[10] * q[7].re;
|
||||
q[7].im = tab[11] * q[7].im;
|
||||
|
||||
k[0].re = q[4].re - q[0].re;
|
||||
k[0].im = q[4].im - q[0].im;
|
||||
k[1].re = q[5].re - q[1].re;
|
||||
k[1].im = q[5].im - q[1].im;
|
||||
k[2].re = q[6].re - q[2].re;
|
||||
k[2].im = q[6].im - q[2].im;
|
||||
k[3].re = q[7].re - q[3].re;
|
||||
k[3].im = q[7].im - q[3].im;
|
||||
|
||||
k[4].re = q[4].re + q[0].re;
|
||||
k[4].im = q[4].im + q[0].im;
|
||||
k[5].re = q[5].re + q[1].re;
|
||||
k[5].im = q[5].im + q[1].im;
|
||||
k[6].re = q[6].re + q[2].re;
|
||||
k[6].im = q[6].im + q[2].im;
|
||||
k[7].re = q[7].re + q[3].re;
|
||||
k[7].im = q[7].im + q[3].im;
|
||||
|
||||
k[0].re = in[11].re - k[0].re;
|
||||
k[0].im = in[11].im + k[0].im;
|
||||
k[1].re = in[12].re - k[1].re;
|
||||
k[1].im = in[12].im + k[1].im;
|
||||
k[2].re = in[13].re - k[2].re;
|
||||
k[2].im = in[13].im + k[2].im;
|
||||
k[3].re = in[14].re - k[3].re;
|
||||
k[3].im = in[14].im + k[3].im;
|
||||
|
||||
k[4].re = in[11].re - k[4].re;
|
||||
k[4].im = in[11].im + k[4].im;
|
||||
k[5].re = in[12].re - k[5].re;
|
||||
k[5].im = in[12].im + k[5].im;
|
||||
k[6].re = in[13].re - k[6].re;
|
||||
k[6].im = in[13].im + k[6].im;
|
||||
k[7].re = in[14].re - k[7].re;
|
||||
k[7].im = in[14].im + k[7].im;
|
||||
|
||||
/* 15pt start here */
|
||||
t[0].re = y[3].re + y[0].re;
|
||||
t[0].im = y[3].im + y[0].im;
|
||||
t[1].re = y[2].re + y[1].re;
|
||||
t[1].im = y[2].im + y[1].im;
|
||||
t[2].re = y[1].re - y[2].re;
|
||||
t[2].im = y[1].im - y[2].im;
|
||||
t[3].re = y[0].re - y[3].re;
|
||||
t[3].im = y[0].im - y[3].im;
|
||||
|
||||
t[4].re = k[3].re + k[0].re;
|
||||
t[4].im = k[3].im + k[0].im;
|
||||
t[5].re = k[2].re + k[1].re;
|
||||
t[5].im = k[2].im + k[1].im;
|
||||
t[6].re = k[1].re - k[2].re;
|
||||
t[6].im = k[1].im - k[2].im;
|
||||
t[7].re = k[0].re - k[3].re;
|
||||
t[7].im = k[0].im - k[3].im;
|
||||
|
||||
t[ 8].re = k[7].re + k[4].re;
|
||||
t[ 8].im = k[7].im + k[4].im;
|
||||
t[ 9].re = k[6].re + k[5].re;
|
||||
t[ 9].im = k[6].im + k[5].im;
|
||||
t[10].re = k[5].re - k[6].re;
|
||||
t[10].im = k[5].im - k[6].im;
|
||||
t[11].re = k[4].re - k[7].re;
|
||||
t[11].im = k[4].im - k[7].im;
|
||||
|
||||
out[ 0*stride].re = dc[0].re + t[0].re + t[ 1].re;
|
||||
out[ 0*stride].im = dc[0].im + t[0].im + t[ 1].im;
|
||||
out[10*stride].re = dc[1].re + t[4].re + t[ 5].re;
|
||||
out[10*stride].im = dc[1].im + t[4].im + t[ 5].im;
|
||||
out[ 5*stride].re = dc[2].re + t[8].re + t[ 9].re;
|
||||
out[ 5*stride].im = dc[2].im + t[8].im + t[ 9].im;
|
||||
|
||||
r[0].re = t[0].re * tab[0];
|
||||
r[0].im = t[0].im * tab[1];
|
||||
r[1].re = t[1].re * tab[0];
|
||||
r[1].im = t[1].im * tab[1];
|
||||
r[2].re = t[2].re * tab[4];
|
||||
r[2].im = t[2].im * tab[5];
|
||||
r[3].re = t[3].re * tab[4];
|
||||
r[3].im = t[3].im * tab[5];
|
||||
|
||||
r[4].re = t[4].re * tab[0];
|
||||
r[4].im = t[4].im * tab[1];
|
||||
r[5].re = t[5].re * tab[0];
|
||||
r[5].im = t[5].im * tab[1];
|
||||
r[6].re = t[6].re * tab[4];
|
||||
r[6].im = t[6].im * tab[5];
|
||||
r[7].re = t[7].re * tab[4];
|
||||
r[7].im = t[7].im * tab[5];
|
||||
|
||||
r[ 8].re = t[ 8].re * tab[0];
|
||||
r[ 8].im = t[ 8].im * tab[1];
|
||||
r[ 9].re = t[ 9].re * tab[0];
|
||||
r[ 9].im = t[ 9].im * tab[1];
|
||||
r[10].re = t[10].re * tab[4];
|
||||
r[10].im = t[10].im * tab[5];
|
||||
r[11].re = t[11].re * tab[4];
|
||||
r[11].im = t[11].im * tab[5];
|
||||
|
||||
t[0].re = t[0].re * tab[2];
|
||||
t[0].im = t[0].im * tab[3];
|
||||
t[1].re = t[1].re * tab[2];
|
||||
t[1].im = t[1].im * tab[3];
|
||||
t[2].re = t[2].re * tab[6];
|
||||
t[2].im = t[2].im * tab[7];
|
||||
t[3].re = t[3].re * tab[6];
|
||||
t[3].im = t[3].im * tab[7];
|
||||
|
||||
t[4].re = t[4].re * tab[2];
|
||||
t[4].im = t[4].im * tab[3];
|
||||
t[5].re = t[5].re * tab[2];
|
||||
t[5].im = t[5].im * tab[3];
|
||||
t[6].re = t[6].re * tab[6];
|
||||
t[6].im = t[6].im * tab[7];
|
||||
t[7].re = t[7].re * tab[6];
|
||||
t[7].im = t[7].im * tab[7];
|
||||
|
||||
t[ 8].re = t[ 8].re * tab[2];
|
||||
t[ 8].im = t[ 8].im * tab[3];
|
||||
t[ 9].re = t[ 9].re * tab[2];
|
||||
t[ 9].im = t[ 9].im * tab[3];
|
||||
t[10].re = t[10].re * tab[6];
|
||||
t[10].im = t[10].im * tab[7];
|
||||
t[11].re = t[11].re * tab[6];
|
||||
t[11].im = t[11].im * tab[7];
|
||||
|
||||
r[0].re = r[0].re - t[1].re;
|
||||
r[0].im = r[0].im - t[1].im;
|
||||
r[1].re = r[1].re - t[0].re;
|
||||
r[1].im = r[1].im - t[0].im;
|
||||
r[2].re = r[2].re - t[3].re;
|
||||
r[2].im = r[2].im - t[3].im;
|
||||
r[3].re = r[3].re + t[2].re;
|
||||
r[3].im = r[3].im + t[2].im;
|
||||
|
||||
r[4].re = r[4].re - t[5].re;
|
||||
r[4].im = r[4].im - t[5].im;
|
||||
r[5].re = r[5].re - t[4].re;
|
||||
r[5].im = r[5].im - t[4].im;
|
||||
r[6].re = r[6].re - t[7].re;
|
||||
r[6].im = r[6].im - t[7].im;
|
||||
r[7].re = r[7].re + t[6].re;
|
||||
r[7].im = r[7].im + t[6].im;
|
||||
|
||||
r[ 8].re = r[ 8].re - t[ 9].re;
|
||||
r[ 8].im = r[ 8].im - t[ 9].im;
|
||||
r[ 9].re = r[ 9].re - t[ 8].re;
|
||||
r[ 9].im = r[ 9].im - t[ 8].im;
|
||||
r[10].re = r[10].re - t[11].re;
|
||||
r[10].im = r[10].im - t[11].im;
|
||||
r[11].re = r[11].re + t[10].re;
|
||||
r[11].im = r[11].im + t[10].im;
|
||||
|
||||
z0[ 0].re = r[ 3].im + r[ 0].re;
|
||||
z0[ 0].im = r[ 3].re + r[ 0].im;
|
||||
z0[ 1].re = r[ 2].im + r[ 1].re;
|
||||
z0[ 1].im = r[ 2].re + r[ 1].im;
|
||||
z0[ 2].re = r[ 1].im - r[ 2].re;
|
||||
z0[ 2].im = r[ 1].re - r[ 2].im;
|
||||
z0[ 3].re = r[ 0].im - r[ 3].re;
|
||||
z0[ 3].im = r[ 0].re - r[ 3].im;
|
||||
|
||||
z0[ 4].re = r[ 7].im + r[ 4].re;
|
||||
z0[ 4].im = r[ 7].re + r[ 4].im;
|
||||
z0[ 5].re = r[ 6].im + r[ 5].re;
|
||||
z0[ 5].im = r[ 6].re + r[ 5].im;
|
||||
z0[ 6].re = r[ 5].im - r[ 6].re;
|
||||
z0[ 6].im = r[ 5].re - r[ 6].im;
|
||||
z0[ 7].re = r[ 4].im - r[ 7].re;
|
||||
z0[ 7].im = r[ 4].re - r[ 7].im;
|
||||
|
||||
z0[ 8].re = r[11].im + r[ 8].re;
|
||||
z0[ 8].im = r[11].re + r[ 8].im;
|
||||
z0[ 9].re = r[10].im + r[ 9].re;
|
||||
z0[ 9].im = r[10].re + r[ 9].im;
|
||||
z0[10].re = r[ 9].im - r[10].re;
|
||||
z0[10].im = r[ 9].re - r[10].im;
|
||||
z0[11].re = r[ 8].im - r[11].re;
|
||||
z0[11].im = r[ 8].re - r[11].im;
|
||||
|
||||
out[ 6*stride].re = dc[0].re + z0[0].re;
|
||||
out[ 6*stride].im = dc[0].im + z0[3].re;
|
||||
out[12*stride].re = dc[0].re + z0[2].im;
|
||||
out[12*stride].im = dc[0].im + z0[1].im;
|
||||
out[ 3*stride].re = dc[0].re + z0[1].re;
|
||||
out[ 3*stride].im = dc[0].im + z0[2].re;
|
||||
out[ 9*stride].re = dc[0].re + z0[3].im;
|
||||
out[ 9*stride].im = dc[0].im + z0[0].im;
|
||||
|
||||
out[ 1*stride].re = dc[1].re + z0[4].re;
|
||||
out[ 1*stride].im = dc[1].im + z0[7].re;
|
||||
out[ 7*stride].re = dc[1].re + z0[6].im;
|
||||
out[ 7*stride].im = dc[1].im + z0[5].im;
|
||||
out[13*stride].re = dc[1].re + z0[5].re;
|
||||
out[13*stride].im = dc[1].im + z0[6].re;
|
||||
out[ 4*stride].re = dc[1].re + z0[7].im;
|
||||
out[ 4*stride].im = dc[1].im + z0[4].im;
|
||||
|
||||
out[11*stride].re = dc[2].re + z0[8].re;
|
||||
out[11*stride].im = dc[2].im + z0[11].re;
|
||||
out[ 2*stride].re = dc[2].re + z0[10].im;
|
||||
out[ 2*stride].im = dc[2].im + z0[9].im;
|
||||
out[ 8*stride].re = dc[2].re + z0[9].re;
|
||||
out[ 8*stride].im = dc[2].im + z0[10].re;
|
||||
out[14*stride].re = dc[2].re + z0[11].im;
|
||||
out[14*stride].im = dc[2].im + z0[8].im;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -713,12 +713,8 @@ FL+FR+FC+LFE+BL+BR+SL+SR
|
||||
FL+FR+FC+LFE+BL+BR+FLC+FRC
|
||||
@item 7.1(wide-side)
|
||||
FL+FR+FC+LFE+FLC+FRC+SL+SR
|
||||
@item 7.1(top)
|
||||
FL+FR+FC+LFE+BL+BR+TFL+TFR
|
||||
@item octagonal
|
||||
FL+FR+FC+BL+BR+BC+SL+SR
|
||||
@item cube
|
||||
FL+FR+BL+BR+TFL+TFR+TBL+TBR
|
||||
@item hexadecagonal
|
||||
FL+FR+FC+BL+BR+BC+SL+SR+WL+WR+TBL+TBR+TBC+TFC+TFL+TFR
|
||||
@item downmix
|
||||
@@ -1077,13 +1073,13 @@ indication of the corresponding powers of 10 and of 2.
|
||||
@item T
|
||||
10^12 / 2^40
|
||||
@item P
|
||||
10^15 / 2^50
|
||||
10^15 / 2^40
|
||||
@item E
|
||||
10^18 / 2^60
|
||||
10^18 / 2^50
|
||||
@item Z
|
||||
10^21 / 2^70
|
||||
10^21 / 2^60
|
||||
@item Y
|
||||
10^24 / 2^80
|
||||
10^24 / 2^70
|
||||
@end table
|
||||
|
||||
@c man end EXPRESSION EVALUATION
|
||||
|
||||
@@ -15,7 +15,5 @@ OBJS-$(HAVE_LASX) += $(LASX-OBJS) $(LASX-OBJS-yes)
|
||||
OBJS-$(HAVE_ALTIVEC) += $(ALTIVEC-OBJS) $(ALTIVEC-OBJS-yes)
|
||||
OBJS-$(HAVE_VSX) += $(VSX-OBJS) $(VSX-OBJS-yes)
|
||||
|
||||
OBJS-$(HAVE_RVV) += $(RVV-OBJS) $(RVV-OBJS-yes)
|
||||
|
||||
OBJS-$(HAVE_MMX) += $(MMX-OBJS) $(MMX-OBJS-yes)
|
||||
OBJS-$(HAVE_X86ASM) += $(X86ASM-OBJS) $(X86ASM-OBJS-yes)
|
||||
|
||||
@@ -10,21 +10,13 @@ ALLAVPROGS = $(AVBASENAMES:%=%$(PROGSSUF)$(EXESUF))
|
||||
ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
|
||||
|
||||
OBJS-ffmpeg += \
|
||||
fftools/ffmpeg_demux.o \
|
||||
fftools/ffmpeg_filter.o \
|
||||
fftools/ffmpeg_hw.o \
|
||||
fftools/ffmpeg_mux.o \
|
||||
fftools/ffmpeg_mux_init.o \
|
||||
fftools/ffmpeg_opt.o \
|
||||
fftools/objpool.o \
|
||||
fftools/sync_queue.o \
|
||||
fftools/thread_queue.o \
|
||||
|
||||
define DOFFTOOL
|
||||
OBJS-$(1) += fftools/cmdutils.o fftools/opt_common.o fftools/$(1).o $(OBJS-$(1)-yes)
|
||||
ifdef HAVE_GNU_WINDRES
|
||||
OBJS-$(1) += fftools/fftoolsres.o
|
||||
endif
|
||||
$(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1))
|
||||
$$(OBJS-$(1)): | fftools
|
||||
$$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1))
|
||||
|
||||
@@ -90,12 +90,6 @@ void register_exit(void (*cb)(int ret))
|
||||
program_exit = cb;
|
||||
}
|
||||
|
||||
void report_and_exit(int ret)
|
||||
{
|
||||
av_log(NULL, AV_LOG_FATAL, "%s\n", av_err2str(ret));
|
||||
exit_program(AVUNERROR(ret));
|
||||
}
|
||||
|
||||
void exit_program(int ret)
|
||||
{
|
||||
if (program_exit)
|
||||
@@ -656,7 +650,7 @@ static void init_parse_context(OptionParseContext *octx,
|
||||
octx->nb_groups = nb_groups;
|
||||
octx->groups = av_calloc(octx->nb_groups, sizeof(*octx->groups));
|
||||
if (!octx->groups)
|
||||
report_and_exit(AVERROR(ENOMEM));
|
||||
exit_program(1);
|
||||
|
||||
for (i = 0; i < octx->nb_groups; i++)
|
||||
octx->groups[i].group_def = &groups[i];
|
||||
@@ -798,7 +792,12 @@ do { \
|
||||
|
||||
void print_error(const char *filename, int err)
|
||||
{
|
||||
av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, av_err2str(err));
|
||||
char errbuf[128];
|
||||
const char *errbuf_ptr = errbuf;
|
||||
|
||||
if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
|
||||
errbuf_ptr = strerror(AVUNERROR(err));
|
||||
av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
|
||||
}
|
||||
|
||||
int read_yesno(void)
|
||||
@@ -921,7 +920,7 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
|
||||
break;
|
||||
}
|
||||
|
||||
while (t = av_dict_iterate(opts, t)) {
|
||||
while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
|
||||
const AVClass *priv_class;
|
||||
char *p = strchr(t->key, ':');
|
||||
|
||||
@@ -959,8 +958,11 @@ AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
|
||||
if (!s->nb_streams)
|
||||
return NULL;
|
||||
opts = av_calloc(s->nb_streams, sizeof(*opts));
|
||||
if (!opts)
|
||||
report_and_exit(AVERROR(ENOMEM));
|
||||
if (!opts) {
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"Could not alloc memory for stream options.\n");
|
||||
exit_program(1);
|
||||
}
|
||||
for (i = 0; i < s->nb_streams; i++)
|
||||
opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codecpar->codec_id,
|
||||
s, s->streams[i], NULL);
|
||||
@@ -975,8 +977,10 @@ void *grow_array(void *array, int elem_size, int *size, int new_size)
|
||||
}
|
||||
if (*size < new_size) {
|
||||
uint8_t *tmp = av_realloc_array(array, new_size, elem_size);
|
||||
if (!tmp)
|
||||
report_and_exit(AVERROR(ENOMEM));
|
||||
if (!tmp) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
|
||||
exit_program(1);
|
||||
}
|
||||
memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
|
||||
*size = new_size;
|
||||
return tmp;
|
||||
@@ -989,8 +993,10 @@ void *allocate_array_elem(void *ptr, size_t elem_size, int *nb_elems)
|
||||
void *new_elem;
|
||||
|
||||
if (!(new_elem = av_mallocz(elem_size)) ||
|
||||
av_dynarray_add_nofree(ptr, nb_elems, new_elem) < 0)
|
||||
report_and_exit(AVERROR(ENOMEM));
|
||||
av_dynarray_add_nofree(ptr, nb_elems, new_elem) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
|
||||
exit_program(1);
|
||||
}
|
||||
return new_elem;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,17 +54,6 @@ extern int hide_banner;
|
||||
*/
|
||||
void register_exit(void (*cb)(int ret));
|
||||
|
||||
/**
|
||||
* Reports an error corresponding to the provided
|
||||
* AVERROR code and calls exit_program() with the
|
||||
* corresponding POSIX error code.
|
||||
* @note ret must be an AVERROR-value of a POSIX error code
|
||||
* (i.e. AVERROR(EFOO) and not AVERROR_FOO).
|
||||
* library functions can return both, so call this only
|
||||
* with AVERROR(EFOO) of your own.
|
||||
*/
|
||||
void report_and_exit(int ret) av_noreturn;
|
||||
|
||||
/**
|
||||
* Wraps exit with a program-specific cleanup routine.
|
||||
*/
|
||||
|
||||
2508
fftools/ffmpeg.c
2508
fftools/ffmpeg.c
File diff suppressed because it is too large
Load Diff
398
fftools/ffmpeg.h
398
fftools/ffmpeg.h
@@ -21,13 +21,11 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "cmdutils.h"
|
||||
#include "sync_queue.h"
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavformat/avio.h"
|
||||
@@ -49,12 +47,6 @@
|
||||
|
||||
#include "libswresample/swresample.h"
|
||||
|
||||
// deprecated features
|
||||
#define FFMPEG_OPT_PSNR 1
|
||||
#define FFMPEG_OPT_MAP_CHANNEL 1
|
||||
#define FFMPEG_OPT_MAP_SYNC 1
|
||||
#define FFMPEG_ROTATION_METADATA 1
|
||||
|
||||
enum VideoSyncMethod {
|
||||
VSYNC_AUTO = -1,
|
||||
VSYNC_PASSTHROUGH,
|
||||
@@ -83,15 +75,15 @@ typedef struct StreamMap {
|
||||
int disabled; /* 1 is this mapping is disabled by a negative map */
|
||||
int file_index;
|
||||
int stream_index;
|
||||
int sync_file_index;
|
||||
int sync_stream_index;
|
||||
char *linklabel; /* name of an output link, for mapping lavfi outputs */
|
||||
} StreamMap;
|
||||
|
||||
#if FFMPEG_OPT_MAP_CHANNEL
|
||||
typedef struct {
|
||||
int file_idx, stream_idx, channel_idx; // input
|
||||
int ofile_idx, ostream_idx; // output
|
||||
} AudioChannelMap;
|
||||
#endif
|
||||
|
||||
typedef struct OptionsContext {
|
||||
OptionGroup *g;
|
||||
@@ -127,7 +119,6 @@ typedef struct OptionsContext {
|
||||
int accurate_seek;
|
||||
int thread_queue_size;
|
||||
int input_sync_ref;
|
||||
int find_stream_info;
|
||||
|
||||
SpecifierOpt *ts_scale;
|
||||
int nb_ts_scale;
|
||||
@@ -145,10 +136,11 @@ typedef struct OptionsContext {
|
||||
/* output options */
|
||||
StreamMap *stream_maps;
|
||||
int nb_stream_maps;
|
||||
#if FFMPEG_OPT_MAP_CHANNEL
|
||||
AudioChannelMap *audio_channel_maps; /* one info entry per -map_channel */
|
||||
int nb_audio_channel_maps; /* number of (valid) -map_channel settings */
|
||||
#endif
|
||||
int metadata_global_manual;
|
||||
int metadata_streams_manual;
|
||||
int metadata_chapters_manual;
|
||||
const char **attachments;
|
||||
int nb_attachments;
|
||||
|
||||
@@ -156,10 +148,9 @@ typedef struct OptionsContext {
|
||||
|
||||
int64_t recording_time;
|
||||
int64_t stop_time;
|
||||
int64_t limit_filesize;
|
||||
uint64_t limit_filesize;
|
||||
float mux_preload;
|
||||
float mux_max_delay;
|
||||
float shortest_buf_duration;
|
||||
int shortest;
|
||||
int bitexact;
|
||||
|
||||
@@ -192,12 +183,6 @@ typedef struct OptionsContext {
|
||||
int nb_force_fps;
|
||||
SpecifierOpt *frame_aspect_ratios;
|
||||
int nb_frame_aspect_ratios;
|
||||
SpecifierOpt *display_rotations;
|
||||
int nb_display_rotations;
|
||||
SpecifierOpt *display_hflips;
|
||||
int nb_display_hflips;
|
||||
SpecifierOpt *display_vflips;
|
||||
int nb_display_vflips;
|
||||
SpecifierOpt *rc_overrides;
|
||||
int nb_rc_overrides;
|
||||
SpecifierOpt *intra_matrices;
|
||||
@@ -224,8 +209,6 @@ typedef struct OptionsContext {
|
||||
int nb_reinit_filters;
|
||||
SpecifierOpt *fix_sub_duration;
|
||||
int nb_fix_sub_duration;
|
||||
SpecifierOpt *fix_sub_duration_heartbeat;
|
||||
int nb_fix_sub_duration_heartbeat;
|
||||
SpecifierOpt *canvas_sizes;
|
||||
int nb_canvas_sizes;
|
||||
SpecifierOpt *pass;
|
||||
@@ -254,18 +237,6 @@ typedef struct OptionsContext {
|
||||
int nb_autoscale;
|
||||
SpecifierOpt *bits_per_raw_sample;
|
||||
int nb_bits_per_raw_sample;
|
||||
SpecifierOpt *enc_stats_pre;
|
||||
int nb_enc_stats_pre;
|
||||
SpecifierOpt *enc_stats_post;
|
||||
int nb_enc_stats_post;
|
||||
SpecifierOpt *mux_stats;
|
||||
int nb_mux_stats;
|
||||
SpecifierOpt *enc_stats_pre_fmt;
|
||||
int nb_enc_stats_pre_fmt;
|
||||
SpecifierOpt *enc_stats_post_fmt;
|
||||
int nb_enc_stats_post_fmt;
|
||||
SpecifierOpt *mux_stats_fmt;
|
||||
int nb_mux_stats_fmt;
|
||||
} OptionsContext;
|
||||
|
||||
typedef struct InputFilter {
|
||||
@@ -341,22 +312,12 @@ typedef struct InputStream {
|
||||
#define DECODING_FOR_OST 1
|
||||
#define DECODING_FOR_FILTER 2
|
||||
int processing_needed; /* non zero if the packets must be processed */
|
||||
// should attach FrameData as opaque_ref after decoding
|
||||
int want_frame_data;
|
||||
|
||||
/**
|
||||
* Codec parameters - to be used by the decoding/streamcopy code.
|
||||
* st->codecpar should not be accessed, because it may be modified
|
||||
* concurrently by the demuxing thread.
|
||||
*/
|
||||
AVCodecParameters *par;
|
||||
AVCodecContext *dec_ctx;
|
||||
const AVCodec *dec;
|
||||
AVFrame *decoded_frame;
|
||||
AVPacket *pkt;
|
||||
|
||||
AVRational framerate_guessed;
|
||||
|
||||
int64_t prev_pkt_pts;
|
||||
int64_t start; /* time when read started */
|
||||
/* predicted dts of the next packet read for this stream or (when there are
|
||||
@@ -369,12 +330,6 @@ typedef struct InputStream {
|
||||
int64_t pts; ///< current pts of the decoded frame (in AV_TIME_BASE units)
|
||||
int wrap_correction_done;
|
||||
|
||||
// the value of AVCodecParserContext.repeat_pict from the AVStream parser
|
||||
// for the last packet returned from ifile_get_packet()
|
||||
// -1 if unknown
|
||||
// FIXME: this is a hack, the avstream parser should not be used
|
||||
int last_pkt_repeat_pict;
|
||||
|
||||
int64_t filter_in_rescale_delta_last;
|
||||
|
||||
int64_t min_pts; /* pts with the smallest value in a current stream */
|
||||
@@ -424,8 +379,12 @@ typedef struct InputStream {
|
||||
char *hwaccel_device;
|
||||
enum AVPixelFormat hwaccel_output_format;
|
||||
|
||||
/* hwaccel context */
|
||||
void *hwaccel_ctx;
|
||||
void (*hwaccel_uninit)(AVCodecContext *s);
|
||||
int (*hwaccel_retrieve_data)(AVCodecContext *s, AVFrame *frame);
|
||||
enum AVPixelFormat hwaccel_pix_fmt;
|
||||
enum AVPixelFormat hwaccel_retrieved_pix_fmt;
|
||||
|
||||
/* stats */
|
||||
// combined size of all the packets read
|
||||
@@ -442,46 +401,38 @@ typedef struct InputStream {
|
||||
int got_output;
|
||||
} InputStream;
|
||||
|
||||
typedef struct LastFrameDuration {
|
||||
int stream_idx;
|
||||
int64_t duration;
|
||||
} LastFrameDuration;
|
||||
|
||||
typedef struct InputFile {
|
||||
int index;
|
||||
|
||||
AVFormatContext *ctx;
|
||||
int eof_reached; /* true if eof reached */
|
||||
int eagain; /* true if last read attempt returned EAGAIN */
|
||||
int ist_index; /* index of first stream in input_streams */
|
||||
int loop; /* set number of times input stream should be looped */
|
||||
int64_t duration; /* actual duration of the longest stream in a file
|
||||
at the moment when looping happens */
|
||||
AVRational time_base; /* time base of the duration */
|
||||
int64_t input_ts_offset;
|
||||
int input_sync_ref;
|
||||
/**
|
||||
* Effective format start time based on enabled streams.
|
||||
*/
|
||||
int64_t start_time_effective;
|
||||
|
||||
int64_t ts_offset;
|
||||
/**
|
||||
* Extra timestamp offset added by discontinuity handling.
|
||||
*/
|
||||
int64_t ts_offset_discont;
|
||||
int64_t last_ts;
|
||||
int64_t start_time; /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */
|
||||
int64_t recording_time;
|
||||
|
||||
/* streams that ffmpeg is aware of;
|
||||
* there may be extra streams in ctx that are not mapped to an InputStream
|
||||
* if new streams appear dynamically during demuxing */
|
||||
InputStream **streams;
|
||||
int nb_streams;
|
||||
|
||||
int nb_streams; /* number of stream that ffmpeg is aware of; may be different
|
||||
from ctx.nb_streams if new streams appear during av_read_frame() */
|
||||
int nb_streams_warn; /* number of streams that the user was warned of */
|
||||
int rate_emu;
|
||||
float readrate;
|
||||
int accurate_seek;
|
||||
|
||||
/* when looping the input file, this queue is used by decoders to report
|
||||
* the last frame duration back to the demuxer thread */
|
||||
AVThreadMessageQueue *audio_duration_queue;
|
||||
int audio_duration_queue_size;
|
||||
AVPacket *pkt;
|
||||
|
||||
#if HAVE_THREADS
|
||||
AVThreadMessageQueue *in_thread_queue;
|
||||
pthread_t thread; /* thread reading from this file */
|
||||
int non_blocking; /* reading packets from the thread should not block */
|
||||
int joined; /* the thread has been joined */
|
||||
int thread_queue_size; /* maximum number of queued packets */
|
||||
#endif
|
||||
} InputFile;
|
||||
|
||||
enum forced_keyframes_const {
|
||||
@@ -496,41 +447,6 @@ enum forced_keyframes_const {
|
||||
#define ABORT_ON_FLAG_EMPTY_OUTPUT (1 << 0)
|
||||
#define ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM (1 << 1)
|
||||
|
||||
enum EncStatsType {
|
||||
ENC_STATS_LITERAL = 0,
|
||||
ENC_STATS_FILE_IDX,
|
||||
ENC_STATS_STREAM_IDX,
|
||||
ENC_STATS_FRAME_NUM,
|
||||
ENC_STATS_FRAME_NUM_IN,
|
||||
ENC_STATS_TIMEBASE,
|
||||
ENC_STATS_TIMEBASE_IN,
|
||||
ENC_STATS_PTS,
|
||||
ENC_STATS_PTS_TIME,
|
||||
ENC_STATS_PTS_IN,
|
||||
ENC_STATS_PTS_TIME_IN,
|
||||
ENC_STATS_DTS,
|
||||
ENC_STATS_DTS_TIME,
|
||||
ENC_STATS_SAMPLE_NUM,
|
||||
ENC_STATS_NB_SAMPLES,
|
||||
ENC_STATS_PKT_SIZE,
|
||||
ENC_STATS_BITRATE,
|
||||
ENC_STATS_AVG_BITRATE,
|
||||
};
|
||||
|
||||
typedef struct EncStatsComponent {
|
||||
enum EncStatsType type;
|
||||
|
||||
uint8_t *str;
|
||||
size_t str_len;
|
||||
} EncStatsComponent;
|
||||
|
||||
typedef struct EncStats {
|
||||
EncStatsComponent *components;
|
||||
int nb_components;
|
||||
|
||||
AVIOContext *io;
|
||||
} EncStats;
|
||||
|
||||
extern const char *const forced_keyframes_const_names[];
|
||||
|
||||
typedef enum {
|
||||
@@ -538,92 +454,68 @@ typedef enum {
|
||||
MUXER_FINISHED = 2,
|
||||
} OSTFinished ;
|
||||
|
||||
enum {
|
||||
KF_FORCE_SOURCE = 1,
|
||||
KF_FORCE_SOURCE_NO_DROP = 2,
|
||||
};
|
||||
|
||||
typedef struct KeyframeForceCtx {
|
||||
int type;
|
||||
|
||||
int64_t ref_pts;
|
||||
|
||||
// timestamps of the forced keyframes, in AV_TIME_BASE_Q
|
||||
int64_t *pts;
|
||||
int nb_pts;
|
||||
int index;
|
||||
|
||||
AVExpr *pexpr;
|
||||
double expr_const_values[FKF_NB];
|
||||
|
||||
int dropped_keyframe;
|
||||
} KeyframeForceCtx;
|
||||
|
||||
typedef struct OutputStream {
|
||||
const AVClass *class;
|
||||
|
||||
int file_index; /* file index */
|
||||
int index; /* stream index in the output file */
|
||||
|
||||
/* input stream that is the source for this output stream;
|
||||
* may be NULL for streams with no well-defined source, e.g.
|
||||
* attachments or outputs from complex filtergraphs */
|
||||
InputStream *ist;
|
||||
|
||||
int source_index; /* InputStream index */
|
||||
AVStream *st; /* stream in the output file */
|
||||
/* number of frames emitted by the video-encoding sync code */
|
||||
int64_t vsync_frame_number;
|
||||
/* predicted pts of the next frame to be encoded
|
||||
* audio/video encoding only */
|
||||
int64_t next_pts;
|
||||
/* dts of the last packet sent to the muxing queue, in AV_TIME_BASE_Q */
|
||||
int encoding_needed; /* true if encoding needed for this stream */
|
||||
int64_t frame_number;
|
||||
/* input pts and corresponding output pts
|
||||
for A/V sync */
|
||||
struct InputStream *sync_ist; /* input stream to sync against */
|
||||
int64_t sync_opts; /* output frame counter, could be changed to some true timestamp */ // FIXME look at frame_number
|
||||
/* pts of the first frame encoded for this stream, used for limiting
|
||||
* recording time */
|
||||
int64_t first_pts;
|
||||
/* dts of the last packet sent to the muxer */
|
||||
int64_t last_mux_dts;
|
||||
/* pts of the last frame received from the filters, in AV_TIME_BASE_Q */
|
||||
int64_t last_filter_pts;
|
||||
|
||||
// timestamp from which the streamcopied streams should start,
|
||||
// in AV_TIME_BASE_Q;
|
||||
// everything before it should be discarded
|
||||
int64_t ts_copy_start;
|
||||
|
||||
// the timebase of the packets sent to the muxer
|
||||
AVRational mux_timebase;
|
||||
AVRational enc_timebase;
|
||||
|
||||
AVBSFContext *bsf_ctx;
|
||||
|
||||
AVCodecContext *enc_ctx;
|
||||
AVCodecParameters *ref_par; /* associated input codec parameters with encoders options applied */
|
||||
const AVCodec *enc;
|
||||
int64_t max_frames;
|
||||
AVFrame *filtered_frame;
|
||||
AVFrame *last_frame;
|
||||
AVFrame *sq_frame;
|
||||
AVPacket *pkt;
|
||||
int64_t last_dropped;
|
||||
int64_t last_nb0_frames[3];
|
||||
|
||||
void *hwaccel_ctx;
|
||||
|
||||
/* video only */
|
||||
AVRational frame_rate;
|
||||
AVRational max_frame_rate;
|
||||
enum VideoSyncMethod vsync_method;
|
||||
int is_cfr;
|
||||
const char *fps_mode;
|
||||
int force_fps;
|
||||
int top_field_first;
|
||||
#if FFMPEG_ROTATION_METADATA
|
||||
int rotate_overridden;
|
||||
#endif
|
||||
int autoscale;
|
||||
int bitexact;
|
||||
int bits_per_raw_sample;
|
||||
#if FFMPEG_ROTATION_METADATA
|
||||
double rotate_override_value;
|
||||
#endif
|
||||
|
||||
AVRational frame_aspect_ratio;
|
||||
|
||||
KeyframeForceCtx kf;
|
||||
/* forced key frames */
|
||||
int64_t forced_kf_ref_pts;
|
||||
int64_t *forced_kf_pts;
|
||||
int forced_kf_count;
|
||||
int forced_kf_index;
|
||||
char *forced_keyframes;
|
||||
AVExpr *forced_keyframes_pexpr;
|
||||
double forced_keyframes_expr_const_values[FKF_NB];
|
||||
int dropped_keyframe;
|
||||
|
||||
/* audio only */
|
||||
#if FFMPEG_OPT_MAP_CHANNEL
|
||||
int *audio_channels_map; /* list of the channels id to pick from the source stream */
|
||||
int audio_channels_mapped; /* number of channels in audio_channels_map */
|
||||
#endif
|
||||
|
||||
char *logfile_prefix;
|
||||
FILE *logfile;
|
||||
@@ -639,6 +531,7 @@ typedef struct OutputStream {
|
||||
char *apad;
|
||||
OSTFinished finished; /* no more packets should be written for this stream */
|
||||
int unavailable; /* true if the steram is unavailable (possibly temporarily) */
|
||||
int stream_copy;
|
||||
|
||||
// init_output_stream() has been called for this stream
|
||||
// The encoder and the bitstream filters have been initialized and the stream
|
||||
@@ -651,16 +544,15 @@ typedef struct OutputStream {
|
||||
int streamcopy_started;
|
||||
int copy_initial_nonkeyframes;
|
||||
int copy_prior_start;
|
||||
char *disposition;
|
||||
|
||||
int keep_pix_fmt;
|
||||
|
||||
/* stats */
|
||||
// combined size of all the packets sent to the muxer
|
||||
uint64_t data_size_mux;
|
||||
// combined size of all the packets received from the encoder
|
||||
uint64_t data_size_enc;
|
||||
// combined size of all the packets written
|
||||
uint64_t data_size;
|
||||
// number of packets send to the muxer
|
||||
atomic_uint_least64_t packets_written;
|
||||
uint64_t packets_written;
|
||||
// number of frames/samples sent to the encoder
|
||||
uint64_t frames_encoded;
|
||||
uint64_t samples_encoded;
|
||||
@@ -670,48 +562,51 @@ typedef struct OutputStream {
|
||||
/* packet quality factor */
|
||||
int quality;
|
||||
|
||||
int max_muxing_queue_size;
|
||||
|
||||
/* the packets are buffered here until the muxer is ready to be initialized */
|
||||
AVFifo *muxing_queue;
|
||||
|
||||
/*
|
||||
* The size of the AVPackets' buffers in queue.
|
||||
* Updated when a packet is either pushed or pulled from the queue.
|
||||
*/
|
||||
size_t muxing_queue_data_size;
|
||||
|
||||
/* Threshold after which max_muxing_queue_size will be in effect */
|
||||
size_t muxing_queue_data_threshold;
|
||||
|
||||
/* packet picture type */
|
||||
int pict_type;
|
||||
|
||||
/* frame encode sum of squared error values */
|
||||
int64_t error[4];
|
||||
|
||||
int sq_idx_encode;
|
||||
int sq_idx_mux;
|
||||
|
||||
EncStats enc_stats_pre;
|
||||
EncStats enc_stats_post;
|
||||
|
||||
/*
|
||||
* bool on whether this stream should be utilized for splitting
|
||||
* subtitles utilizing fix_sub_duration at random access points.
|
||||
*/
|
||||
unsigned int fix_sub_duration_heartbeat;
|
||||
} OutputStream;
|
||||
|
||||
typedef struct OutputFile {
|
||||
const AVClass *class;
|
||||
|
||||
int index;
|
||||
|
||||
const AVOutputFormat *format;
|
||||
const char *url;
|
||||
|
||||
OutputStream **streams;
|
||||
int nb_streams;
|
||||
|
||||
SyncQueue *sq_encode;
|
||||
|
||||
AVFormatContext *ctx;
|
||||
AVDictionary *opts;
|
||||
int ost_index; /* index of the first stream in output_streams */
|
||||
int64_t recording_time; ///< desired length of the resulting file in microseconds == AV_TIME_BASE units
|
||||
int64_t start_time; ///< start time in microseconds == AV_TIME_BASE units
|
||||
uint64_t limit_filesize; /* filesize limit expressed in bytes */
|
||||
|
||||
int shortest;
|
||||
int bitexact;
|
||||
|
||||
int header_written;
|
||||
} OutputFile;
|
||||
|
||||
extern InputStream **input_streams;
|
||||
extern int nb_input_streams;
|
||||
extern InputFile **input_files;
|
||||
extern int nb_input_files;
|
||||
|
||||
extern OutputStream **output_streams;
|
||||
extern int nb_output_streams;
|
||||
extern OutputFile **output_files;
|
||||
extern int nb_output_files;
|
||||
|
||||
@@ -725,10 +620,13 @@ extern float audio_drift_threshold;
|
||||
extern float dts_delta_threshold;
|
||||
extern float dts_error_threshold;
|
||||
|
||||
extern int audio_volume;
|
||||
extern int audio_sync_method;
|
||||
extern enum VideoSyncMethod video_sync_method;
|
||||
extern float frame_drop_threshold;
|
||||
extern int do_benchmark;
|
||||
extern int do_benchmark_all;
|
||||
extern int do_deinterlace;
|
||||
extern int do_hex_dump;
|
||||
extern int do_pkt_dump;
|
||||
extern int copy_ts;
|
||||
@@ -741,6 +639,7 @@ extern int print_stats;
|
||||
extern int64_t stats_period;
|
||||
extern int qp_hist;
|
||||
extern int stdin_interaction;
|
||||
extern int frame_bits_per_raw_sample;
|
||||
extern AVIOContext *progress_avio;
|
||||
extern float max_error_rate;
|
||||
|
||||
@@ -752,19 +651,15 @@ extern int auto_conversion_filters;
|
||||
extern const AVIOInterruptCB int_cb;
|
||||
|
||||
extern const OptionDef options[];
|
||||
#if CONFIG_QSV
|
||||
extern char *qsv_device;
|
||||
#endif
|
||||
extern HWDevice *filter_hw_device;
|
||||
|
||||
extern int want_sdp;
|
||||
extern unsigned nb_output_dumped;
|
||||
extern int main_return_code;
|
||||
|
||||
extern int ignore_unknown_streams;
|
||||
extern int copy_unknown_streams;
|
||||
|
||||
extern int recast_media;
|
||||
|
||||
#if FFMPEG_OPT_PSNR
|
||||
extern int do_psnr;
|
||||
#endif
|
||||
|
||||
void term_init(void);
|
||||
void term_exit(void);
|
||||
@@ -774,12 +669,7 @@ void show_usage(void);
|
||||
void remove_avoptions(AVDictionary **a, AVDictionary *b);
|
||||
void assert_avoptions(AVDictionary *m);
|
||||
|
||||
void assert_file_overwrite(const char *filename);
|
||||
char *file_read(const char *filename);
|
||||
AVDictionary *strip_specifiers(const AVDictionary *dict);
|
||||
const AVCodec *find_codec_or_die(void *logctx, const char *name,
|
||||
enum AVMediaType type, int encoder);
|
||||
int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_idx, int is_global);
|
||||
int guess_input_channel_layout(InputStream *ist);
|
||||
|
||||
int configure_filtergraph(FilterGraph *fg);
|
||||
void check_filter_outputs(void);
|
||||
@@ -793,9 +683,8 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame);
|
||||
|
||||
int ffmpeg_parse_options(int argc, char **argv);
|
||||
|
||||
void enc_stats_write(OutputStream *ost, EncStats *es,
|
||||
const AVFrame *frame, const AVPacket *pkt,
|
||||
uint64_t frame_num);
|
||||
int videotoolbox_init(AVCodecContext *s);
|
||||
int qsv_init(AVCodecContext *s);
|
||||
|
||||
HWDevice *hw_device_get_by_name(const char *name);
|
||||
int hw_device_init_from_string(const char *arg, HWDevice **dev);
|
||||
@@ -807,99 +696,12 @@ int hw_device_setup_for_filter(FilterGraph *fg);
|
||||
|
||||
int hwaccel_decode_init(AVCodecContext *avctx);
|
||||
|
||||
/*
|
||||
* Initialize muxing state for the given stream, should be called
|
||||
* after the codec/streamcopy setup has been done.
|
||||
*
|
||||
* Open the muxer once all the streams have been initialized.
|
||||
*/
|
||||
int of_stream_init(OutputFile *of, OutputStream *ost);
|
||||
/* open the muxer when all the streams are initialized */
|
||||
int of_check_init(OutputFile *of);
|
||||
int of_write_trailer(OutputFile *of);
|
||||
int of_open(const OptionsContext *o, const char *filename);
|
||||
void of_close(OutputFile **pof);
|
||||
|
||||
void of_enc_stats_close(void);
|
||||
|
||||
/*
|
||||
* Send a single packet to the output, applying any bitstream filters
|
||||
* associated with the output stream. This may result in any number
|
||||
* of packets actually being written, depending on what bitstream
|
||||
* filters are applied. The supplied packet is consumed and will be
|
||||
* blank (as if newly-allocated) when this function returns.
|
||||
*
|
||||
* If eof is set, instead indicate EOF to all bitstream filters and
|
||||
* therefore flush any delayed packets to the output. A blank packet
|
||||
* must be supplied in this case.
|
||||
*/
|
||||
void of_output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int eof);
|
||||
int64_t of_filesize(OutputFile *of);
|
||||
|
||||
int ifile_open(const OptionsContext *o, const char *filename);
|
||||
void ifile_close(InputFile **f);
|
||||
|
||||
/**
|
||||
* Get next input packet from the demuxer.
|
||||
*
|
||||
* @param pkt the packet is written here when this function returns 0
|
||||
* @return
|
||||
* - 0 when a packet has been read successfully
|
||||
* - 1 when stream end was reached, but the stream is looped;
|
||||
* caller should flush decoders and read from this demuxer again
|
||||
* - a negative error code on failure
|
||||
*/
|
||||
int ifile_get_packet(InputFile *f, AVPacket **pkt);
|
||||
|
||||
/* iterate over all input streams in all input files;
|
||||
* pass NULL to start iteration */
|
||||
InputStream *ist_iter(InputStream *prev);
|
||||
|
||||
#define SPECIFIER_OPT_FMT_str "%s"
|
||||
#define SPECIFIER_OPT_FMT_i "%i"
|
||||
#define SPECIFIER_OPT_FMT_i64 "%"PRId64
|
||||
#define SPECIFIER_OPT_FMT_ui64 "%"PRIu64
|
||||
#define SPECIFIER_OPT_FMT_f "%f"
|
||||
#define SPECIFIER_OPT_FMT_dbl "%lf"
|
||||
|
||||
#define WARN_MULTIPLE_OPT_USAGE(name, type, so, st)\
|
||||
{\
|
||||
char namestr[128] = "";\
|
||||
const char *spec = so->specifier && so->specifier[0] ? so->specifier : "";\
|
||||
for (int _i = 0; opt_name_##name[_i]; _i++)\
|
||||
av_strlcatf(namestr, sizeof(namestr), "-%s%s", opt_name_##name[_i], opt_name_##name[_i+1] ? (opt_name_##name[_i+2] ? ", " : " or ") : "");\
|
||||
av_log(NULL, AV_LOG_WARNING, "Multiple %s options specified for stream %d, only the last option '-%s%s%s "SPECIFIER_OPT_FMT_##type"' will be used.\n",\
|
||||
namestr, st->index, opt_name_##name[0], spec[0] ? ":" : "", spec, so->u.type);\
|
||||
}
|
||||
|
||||
#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
|
||||
{\
|
||||
int _ret, _matches = 0;\
|
||||
SpecifierOpt *so;\
|
||||
for (int _i = 0; _i < o->nb_ ## name; _i++) {\
|
||||
char *spec = o->name[_i].specifier;\
|
||||
if ((_ret = check_stream_specifier(fmtctx, st, spec)) > 0) {\
|
||||
outvar = o->name[_i].u.type;\
|
||||
so = &o->name[_i];\
|
||||
_matches++;\
|
||||
} else if (_ret < 0)\
|
||||
exit_program(1);\
|
||||
}\
|
||||
if (_matches > 1)\
|
||||
WARN_MULTIPLE_OPT_USAGE(name, type, so, st);\
|
||||
}
|
||||
|
||||
#define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)\
|
||||
{\
|
||||
int i;\
|
||||
for (i = 0; i < o->nb_ ## name; i++) {\
|
||||
char *spec = o->name[i].specifier;\
|
||||
if (!strcmp(spec, mediatype))\
|
||||
outvar = o->name[i].u.type;\
|
||||
}\
|
||||
}
|
||||
|
||||
extern const char * const opt_name_codec_names[];
|
||||
extern const char * const opt_name_codec_tags[];
|
||||
extern const char * const opt_name_frame_rates[];
|
||||
extern const char * const opt_name_top_field_first[];
|
||||
void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
|
||||
int unqueue);
|
||||
|
||||
#endif /* FFTOOLS_FFMPEG_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,9 +52,8 @@ static const enum AVPixelFormat *get_compliance_normal_pix_fmts(const AVCodec *c
|
||||
}
|
||||
}
|
||||
|
||||
static enum AVPixelFormat
|
||||
choose_pixel_fmt(const AVCodec *codec, enum AVPixelFormat target,
|
||||
int strict_std_compliance)
|
||||
static enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx,
|
||||
const AVCodec *codec, enum AVPixelFormat target)
|
||||
{
|
||||
if (codec && codec->pix_fmts) {
|
||||
const enum AVPixelFormat *p = codec->pix_fmts;
|
||||
@@ -63,7 +62,7 @@ choose_pixel_fmt(const AVCodec *codec, enum AVPixelFormat target,
|
||||
int has_alpha = desc ? desc->nb_components % 2 == 0 : 0;
|
||||
enum AVPixelFormat best= AV_PIX_FMT_NONE;
|
||||
|
||||
if (strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
|
||||
if (enc_ctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
|
||||
p = get_compliance_normal_pix_fmts(codec, p);
|
||||
}
|
||||
for (; *p != AV_PIX_FMT_NONE; p++) {
|
||||
@@ -90,7 +89,6 @@ choose_pixel_fmt(const AVCodec *codec, enum AVPixelFormat target,
|
||||
static const char *choose_pix_fmts(OutputFilter *ofilter, AVBPrint *bprint)
|
||||
{
|
||||
OutputStream *ost = ofilter->ost;
|
||||
AVCodecContext *enc = ost->enc_ctx;
|
||||
const AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, "strict", NULL, 0);
|
||||
if (strict_dict)
|
||||
// used by choose_pixel_fmt() and below
|
||||
@@ -104,14 +102,13 @@ static const char *choose_pix_fmts(OutputFilter *ofilter, AVBPrint *bprint)
|
||||
return av_get_pix_fmt_name(ost->enc_ctx->pix_fmt);
|
||||
}
|
||||
if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
|
||||
return av_get_pix_fmt_name(choose_pixel_fmt(enc->codec, enc->pix_fmt,
|
||||
ost->enc_ctx->strict_std_compliance));
|
||||
} else if (enc->codec->pix_fmts) {
|
||||
return av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc_ctx, ost->enc, ost->enc_ctx->pix_fmt));
|
||||
} else if (ost->enc && ost->enc->pix_fmts) {
|
||||
const enum AVPixelFormat *p;
|
||||
|
||||
p = enc->codec->pix_fmts;
|
||||
p = ost->enc->pix_fmts;
|
||||
if (ost->enc_ctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
|
||||
p = get_compliance_normal_pix_fmts(enc->codec, p);
|
||||
p = get_compliance_normal_pix_fmts(ost->enc, p);
|
||||
}
|
||||
|
||||
for (; *p != AV_PIX_FMT_NONE; p++) {
|
||||
@@ -119,7 +116,7 @@ static const char *choose_pix_fmts(OutputFilter *ofilter, AVBPrint *bprint)
|
||||
av_bprintf(bprint, "%s%c", name, p[1] == AV_PIX_FMT_NONE ? '\0' : '|');
|
||||
}
|
||||
if (!av_bprint_is_complete(bprint))
|
||||
report_and_exit(AVERROR(ENOMEM));
|
||||
exit_program(1);
|
||||
return bprint->str;
|
||||
} else
|
||||
return NULL;
|
||||
@@ -183,7 +180,7 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
|
||||
InputFilter *ifilter;
|
||||
|
||||
if (!fg)
|
||||
report_and_exit(AVERROR(ENOMEM));
|
||||
exit_program(1);
|
||||
fg->index = nb_filtergraphs;
|
||||
|
||||
ofilter = ALLOC_ARRAY_ELEM(fg->outputs, fg->nb_outputs);
|
||||
@@ -200,7 +197,7 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
|
||||
|
||||
ifilter->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
|
||||
if (!ifilter->frame_queue)
|
||||
report_and_exit(AVERROR(ENOMEM));
|
||||
exit_program(1);
|
||||
|
||||
GROW_ARRAY(ist->filters, ist->nb_filters);
|
||||
ist->filters[ist->nb_filters - 1] = ifilter;
|
||||
@@ -224,7 +221,7 @@ static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
|
||||
res = av_asprintf("%s:%s", ctx->filter->name,
|
||||
avfilter_pad_get_name(pads, inout->pad_idx));
|
||||
if (!res)
|
||||
report_and_exit(AVERROR(ENOMEM));
|
||||
exit_program(1);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -271,7 +268,7 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
|
||||
"matches no streams.\n", p, fg->graph_desc);
|
||||
exit_program(1);
|
||||
}
|
||||
ist = input_files[file_idx]->streams[st->index];
|
||||
ist = input_streams[input_files[file_idx]->ist_index + st->index];
|
||||
if (ist->user_set_discard == AVDISCARD_ALL) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s "
|
||||
"matches a disabled input stream.\n", p, fg->graph_desc);
|
||||
@@ -279,13 +276,14 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
|
||||
}
|
||||
} else {
|
||||
/* find the first unused stream of corresponding type */
|
||||
for (ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
|
||||
for (i = 0; i < nb_input_streams; i++) {
|
||||
ist = input_streams[i];
|
||||
if (ist->user_set_discard == AVDISCARD_ALL)
|
||||
continue;
|
||||
if (ist->dec_ctx->codec_type == type && ist->discard)
|
||||
break;
|
||||
}
|
||||
if (!ist) {
|
||||
if (i == nb_input_streams) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Cannot find a matching stream for "
|
||||
"unlabeled input pad %d on filter %s\n", in->pad_idx,
|
||||
in->filter_ctx->name);
|
||||
@@ -308,164 +306,12 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
|
||||
|
||||
ifilter->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
|
||||
if (!ifilter->frame_queue)
|
||||
report_and_exit(AVERROR(ENOMEM));
|
||||
exit_program(1);
|
||||
|
||||
GROW_ARRAY(ist->filters, ist->nb_filters);
|
||||
ist->filters[ist->nb_filters - 1] = ifilter;
|
||||
}
|
||||
|
||||
static int read_binary(const char *path, uint8_t **data, int *len)
|
||||
{
|
||||
AVIOContext *io = NULL;
|
||||
int64_t fsize;
|
||||
int ret;
|
||||
|
||||
*data = NULL;
|
||||
*len = 0;
|
||||
|
||||
ret = avio_open2(&io, path, AVIO_FLAG_READ, &int_cb, NULL);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open file '%s': %s\n",
|
||||
path, av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
fsize = avio_size(io);
|
||||
if (fsize < 0 || fsize > INT_MAX) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot obtain size of file %s\n", path);
|
||||
ret = AVERROR(EIO);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*data = av_malloc(fsize);
|
||||
if (!*data) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = avio_read(io, *data, fsize);
|
||||
if (ret != fsize) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error reading file %s\n", path);
|
||||
ret = ret < 0 ? ret : AVERROR(EIO);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*len = fsize;
|
||||
|
||||
ret = 0;
|
||||
fail:
|
||||
avio_close(io);
|
||||
if (ret < 0) {
|
||||
av_freep(data);
|
||||
*len = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int filter_opt_apply(AVFilterContext *f, const char *key, const char *val)
|
||||
{
|
||||
const AVOption *o;
|
||||
int ret;
|
||||
|
||||
ret = av_opt_set(f, key, val, AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret >= 0)
|
||||
return 0;
|
||||
|
||||
if (ret == AVERROR_OPTION_NOT_FOUND && key[0] == '/')
|
||||
o = av_opt_find(f, key + 1, NULL, 0, AV_OPT_SEARCH_CHILDREN);
|
||||
if (!o)
|
||||
goto err_apply;
|
||||
|
||||
// key is a valid option name prefixed with '/'
|
||||
// interpret value as a path from which to load the actual option value
|
||||
key++;
|
||||
|
||||
if (o->type == AV_OPT_TYPE_BINARY) {
|
||||
uint8_t *data;
|
||||
int len;
|
||||
|
||||
ret = read_binary(val, &data, &len);
|
||||
if (ret < 0)
|
||||
goto err_load;
|
||||
|
||||
ret = av_opt_set_bin(f, key, data, len, AV_OPT_SEARCH_CHILDREN);
|
||||
av_freep(&data);
|
||||
} else {
|
||||
char *data = file_read(val);
|
||||
if (!data) {
|
||||
ret = AVERROR(EIO);
|
||||
goto err_load;
|
||||
}
|
||||
|
||||
ret = av_opt_set(f, key, data, AV_OPT_SEARCH_CHILDREN);
|
||||
av_freep(&data);
|
||||
}
|
||||
if (ret < 0)
|
||||
goto err_apply;
|
||||
|
||||
return 0;
|
||||
|
||||
err_apply:
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"Error applying option '%s' to filter '%s': %s\n",
|
||||
key, f->filter->name, av_err2str(ret));
|
||||
return ret;
|
||||
err_load:
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"Error loading value for option '%s' from file '%s'\n",
|
||||
key, val);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int graph_opts_apply(AVFilterGraphSegment *seg)
|
||||
{
|
||||
for (size_t i = 0; i < seg->nb_chains; i++) {
|
||||
AVFilterChain *ch = seg->chains[i];
|
||||
|
||||
for (size_t j = 0; j < ch->nb_filters; j++) {
|
||||
AVFilterParams *p = ch->filters[j];
|
||||
const AVDictionaryEntry *e = NULL;
|
||||
|
||||
av_assert0(p->filter);
|
||||
|
||||
while ((e = av_dict_iterate(p->opts, e))) {
|
||||
int ret = filter_opt_apply(p->filter, e->key, e->value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
av_dict_free(&p->opts);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int graph_parse(AVFilterGraph *graph, const char *desc,
|
||||
AVFilterInOut **inputs, AVFilterInOut **outputs)
|
||||
{
|
||||
AVFilterGraphSegment *seg;
|
||||
int ret;
|
||||
|
||||
ret = avfilter_graph_segment_parse(graph, desc, 0, &seg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = avfilter_graph_segment_create_filters(seg, 0);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
ret = graph_opts_apply(seg);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
ret = avfilter_graph_segment_apply(seg, 0, inputs, outputs);
|
||||
|
||||
fail:
|
||||
avfilter_graph_segment_free(&seg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int init_complex_filtergraph(FilterGraph *fg)
|
||||
{
|
||||
AVFilterInOut *inputs, *outputs, *cur;
|
||||
@@ -479,7 +325,7 @@ int init_complex_filtergraph(FilterGraph *fg)
|
||||
return AVERROR(ENOMEM);
|
||||
graph->nb_threads = 1;
|
||||
|
||||
ret = graph_parse(graph, fg->graph_desc, &inputs, &outputs);
|
||||
ret = avfilter_graph_parse2(graph, fg->graph_desc, &inputs, &outputs);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
@@ -604,7 +450,8 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
snprintf(args, sizeof(args), "%d:%d",
|
||||
ofilter->width, ofilter->height);
|
||||
|
||||
while ((e = av_dict_iterate(ost->sws_dict, e))) {
|
||||
while ((e = av_dict_get(ost->sws_dict, "", e,
|
||||
AV_DICT_IGNORE_SUFFIX))) {
|
||||
av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
|
||||
}
|
||||
|
||||
@@ -711,7 +558,6 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
pad_idx = 0; \
|
||||
} while (0)
|
||||
av_bprint_init(&args, 0, AV_BPRINT_SIZE_UNLIMITED);
|
||||
#if FFMPEG_OPT_MAP_CHANNEL
|
||||
if (ost->audio_channels_mapped) {
|
||||
AVChannelLayout mapped_layout = { 0 };
|
||||
int i;
|
||||
@@ -724,7 +570,6 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
AUTO_INSERT_FILTER("-map_channel", "pan", args.str);
|
||||
av_bprint_clear(&args);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (codec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
|
||||
av_channel_layout_default(&codec->ch_layout, codec->ch_layout.nb_channels);
|
||||
@@ -758,11 +603,11 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
if (ost->apad && of->shortest) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < of->nb_streams; i++)
|
||||
if (of->streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
for (i=0; i<of->ctx->nb_streams; i++)
|
||||
if (of->ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
break;
|
||||
|
||||
if (i < of->nb_streams) {
|
||||
if (i<of->ctx->nb_streams) {
|
||||
AUTO_INSERT_FILTER("-apad", "apad", ost->apad);
|
||||
}
|
||||
}
|
||||
@@ -889,7 +734,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
}
|
||||
|
||||
if (!fr.num)
|
||||
fr = ist->framerate_guessed;
|
||||
fr = av_guess_frame_rate(input_files[ist->file_index]->ctx, ist->st, NULL);
|
||||
|
||||
if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
|
||||
ret = sub2video_prepare(ist, ifilter);
|
||||
@@ -1042,6 +887,40 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
last_filter = filt_ctx; \
|
||||
} while (0)
|
||||
|
||||
if (audio_sync_method > 0) {
|
||||
char args[256] = {0};
|
||||
|
||||
av_strlcatf(args, sizeof(args), "async=%d", audio_sync_method);
|
||||
if (audio_drift_threshold != 0.1)
|
||||
av_strlcatf(args, sizeof(args), ":min_hard_comp=%f", audio_drift_threshold);
|
||||
if (!fg->reconfiguration)
|
||||
av_strlcatf(args, sizeof(args), ":first_pts=0");
|
||||
AUTO_INSERT_FILTER_INPUT("-async", "aresample", args);
|
||||
}
|
||||
|
||||
// if (ost->audio_channels_mapped) {
|
||||
// int i;
|
||||
// AVBPrint pan_buf;
|
||||
// av_bprint_init(&pan_buf, 256, 8192);
|
||||
// av_bprintf(&pan_buf, "0x%"PRIx64,
|
||||
// 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]);
|
||||
// AUTO_INSERT_FILTER_INPUT("-map_channel", "pan", pan_buf.str);
|
||||
// av_bprint_finalize(&pan_buf, NULL);
|
||||
// }
|
||||
|
||||
if (audio_volume != 256) {
|
||||
char args[256];
|
||||
|
||||
av_log(NULL, AV_LOG_WARNING, "-vol has been deprecated. Use the volume "
|
||||
"audio filter instead.\n");
|
||||
|
||||
snprintf(args, sizeof(args), "%f", audio_volume / 256.);
|
||||
AUTO_INSERT_FILTER_INPUT("-vol", "volume", args);
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "trim for input stream %d:%d",
|
||||
ist->file_index, ist->st->index);
|
||||
if (copy_ts) {
|
||||
@@ -1124,39 +1003,44 @@ int configure_filtergraph(FilterGraph *fg)
|
||||
|
||||
if (simple) {
|
||||
OutputStream *ost = fg->outputs[0]->ost;
|
||||
char args[512];
|
||||
const AVDictionaryEntry *e = NULL;
|
||||
|
||||
if (filter_nbthreads) {
|
||||
ret = av_opt_set(fg->graph, "threads", filter_nbthreads, 0);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
} else {
|
||||
const AVDictionaryEntry *e = NULL;
|
||||
e = av_dict_get(ost->encoder_opts, "threads", NULL, 0);
|
||||
if (e)
|
||||
av_opt_set(fg->graph, "threads", e->value, 0);
|
||||
}
|
||||
|
||||
if (av_dict_count(ost->sws_dict)) {
|
||||
ret = av_dict_get_string(ost->sws_dict,
|
||||
&fg->graph->scale_sws_opts,
|
||||
'=', ':');
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
args[0] = 0;
|
||||
e = NULL;
|
||||
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;
|
||||
fg->graph->scale_sws_opts = av_strdup(args);
|
||||
}
|
||||
|
||||
if (av_dict_count(ost->swr_opts)) {
|
||||
char *args;
|
||||
ret = av_dict_get_string(ost->swr_opts, &args, '=', ':');
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
av_opt_set(fg->graph, "aresample_swr_opts", args, 0);
|
||||
av_free(args);
|
||||
args[0] = 0;
|
||||
e = NULL;
|
||||
while ((e = av_dict_get(ost->swr_opts, "", e,
|
||||
AV_DICT_IGNORE_SUFFIX))) {
|
||||
av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
|
||||
}
|
||||
if (strlen(args))
|
||||
args[strlen(args)-1] = 0;
|
||||
av_opt_set(fg->graph, "aresample_swr_opts", args, 0);
|
||||
} else {
|
||||
fg->graph->nb_threads = filter_complex_nbthreads;
|
||||
}
|
||||
|
||||
if ((ret = graph_parse(fg->graph, graph_desc, &inputs, &outputs)) < 0)
|
||||
if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
|
||||
goto fail;
|
||||
|
||||
ret = hw_device_setup_for_filter(fg);
|
||||
@@ -1230,8 +1114,16 @@ int configure_filtergraph(FilterGraph *fg)
|
||||
|
||||
for (i = 0; i < fg->nb_outputs; i++) {
|
||||
OutputStream *ost = fg->outputs[i]->ost;
|
||||
if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO &&
|
||||
!(ost->enc_ctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE))
|
||||
if (!ost->enc) {
|
||||
/* identical to the same check in ffmpeg.c, needed because
|
||||
complex filter graphs are initialized earlier */
|
||||
av_log(NULL, AV_LOG_ERROR, "Encoder (codec %s) not found for output stream #%d:%d\n",
|
||||
avcodec_get_name(ost->st->codecpar->codec_id), ost->file_index, ost->index);
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ int hw_device_setup_for_decode(InputStream *ist)
|
||||
if (ist->hwaccel_id == HWACCEL_AUTO) {
|
||||
ist->hwaccel_device_type = dev->type;
|
||||
} else if (ist->hwaccel_device_type != dev->type) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Invalid hwaccel device "
|
||||
av_log(ist->dec_ctx, AV_LOG_ERROR, "Invalid hwaccel device "
|
||||
"specified for decoder: device %s of type %s is not "
|
||||
"usable with hwaccel %s.\n", dev->name,
|
||||
av_hwdevice_get_type_name(dev->type),
|
||||
@@ -390,7 +390,7 @@ int hw_device_setup_for_decode(InputStream *ist)
|
||||
type = config->device_type;
|
||||
dev = hw_device_get_by_type(type);
|
||||
if (dev) {
|
||||
av_log(NULL, AV_LOG_INFO, "Using auto "
|
||||
av_log(ist->dec_ctx, AV_LOG_INFO, "Using auto "
|
||||
"hwaccel type %s with existing device %s.\n",
|
||||
av_hwdevice_get_type_name(type), dev->name);
|
||||
}
|
||||
@@ -408,12 +408,12 @@ int hw_device_setup_for_decode(InputStream *ist)
|
||||
continue;
|
||||
}
|
||||
if (ist->hwaccel_device) {
|
||||
av_log(NULL, AV_LOG_INFO, "Using auto "
|
||||
av_log(ist->dec_ctx, AV_LOG_INFO, "Using auto "
|
||||
"hwaccel type %s with new device created "
|
||||
"from %s.\n", av_hwdevice_get_type_name(type),
|
||||
ist->hwaccel_device);
|
||||
} else {
|
||||
av_log(NULL, AV_LOG_INFO, "Using auto "
|
||||
av_log(ist->dec_ctx, AV_LOG_INFO, "Using auto "
|
||||
"hwaccel type %s with new default device.\n",
|
||||
av_hwdevice_get_type_name(type));
|
||||
}
|
||||
@@ -421,7 +421,7 @@ int hw_device_setup_for_decode(InputStream *ist)
|
||||
if (dev) {
|
||||
ist->hwaccel_device_type = type;
|
||||
} else {
|
||||
av_log(NULL, AV_LOG_INFO, "Auto hwaccel "
|
||||
av_log(ist->dec_ctx, AV_LOG_INFO, "Auto hwaccel "
|
||||
"disabled: no device found.\n");
|
||||
ist->hwaccel_id = HWACCEL_NONE;
|
||||
return 0;
|
||||
@@ -429,7 +429,7 @@ int hw_device_setup_for_decode(InputStream *ist)
|
||||
}
|
||||
|
||||
if (!dev) {
|
||||
av_log(NULL, AV_LOG_ERROR, "No device available "
|
||||
av_log(ist->dec_ctx, AV_LOG_ERROR, "No device available "
|
||||
"for decoder: device type %s needed for codec %s.\n",
|
||||
av_hwdevice_get_type_name(type), ist->dec->name);
|
||||
return err;
|
||||
@@ -461,7 +461,7 @@ int hw_device_setup_for_encode(OutputStream *ost)
|
||||
}
|
||||
|
||||
for (i = 0;; i++) {
|
||||
config = avcodec_get_hw_config(ost->enc_ctx->codec, i);
|
||||
config = avcodec_get_hw_config(ost->enc, i);
|
||||
if (!config)
|
||||
break;
|
||||
|
||||
@@ -472,7 +472,7 @@ int hw_device_setup_for_encode(OutputStream *ost)
|
||||
av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using input "
|
||||
"frames context (format %s) with %s encoder.\n",
|
||||
av_get_pix_fmt_name(ost->enc_ctx->pix_fmt),
|
||||
ost->enc_ctx->codec->name);
|
||||
ost->enc->name);
|
||||
ost->enc_ctx->hw_frames_ctx = av_buffer_ref(frames_ref);
|
||||
if (!ost->enc_ctx->hw_frames_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
@@ -487,7 +487,7 @@ int hw_device_setup_for_encode(OutputStream *ost)
|
||||
if (dev) {
|
||||
av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using device %s "
|
||||
"(type %s) with %s encoder.\n", dev->name,
|
||||
av_hwdevice_get_type_name(dev->type), ost->enc_ctx->codec->name);
|
||||
av_hwdevice_get_type_name(dev->type), ost->enc->name);
|
||||
ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
|
||||
if (!ost->enc_ctx->hw_device_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
@@ -16,78 +16,100 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ffmpeg.h"
|
||||
#include "ffmpeg_mux.h"
|
||||
#include "objpool.h"
|
||||
#include "sync_queue.h"
|
||||
#include "thread_queue.h"
|
||||
|
||||
#include "libavutil/fifo.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/log.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/timestamp.h"
|
||||
#include "libavutil/thread.h"
|
||||
|
||||
#include "libavcodec/packet.h"
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavformat/avio.h"
|
||||
|
||||
int want_sdp = 1;
|
||||
|
||||
static Muxer *mux_from_of(OutputFile *of)
|
||||
static void close_all_output_streams(OutputStream *ost, OSTFinished this_stream, OSTFinished others)
|
||||
{
|
||||
return (Muxer*)of;
|
||||
}
|
||||
|
||||
static int64_t filesize(AVIOContext *pb)
|
||||
{
|
||||
int64_t ret = -1;
|
||||
|
||||
if (pb) {
|
||||
ret = avio_size(pb);
|
||||
if (ret <= 0) // FIXME improve avio_size() so it works with non seekable output too
|
||||
ret = avio_tell(pb);
|
||||
int i;
|
||||
for (i = 0; i < nb_output_streams; i++) {
|
||||
OutputStream *ost2 = output_streams[i];
|
||||
ost2->finished |= ost == ost2 ? this_stream : others;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
|
||||
void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
|
||||
int unqueue)
|
||||
{
|
||||
MuxStream *ms = ms_from_ost(ost);
|
||||
AVFormatContext *s = mux->fc;
|
||||
AVFormatContext *s = of->ctx;
|
||||
AVStream *st = ost->st;
|
||||
int64_t fs;
|
||||
uint64_t frame_num;
|
||||
int ret;
|
||||
|
||||
fs = filesize(s->pb);
|
||||
atomic_store(&mux->last_filesize, fs);
|
||||
if (fs >= mux->limit_filesize) {
|
||||
ret = AVERROR_EOF;
|
||||
goto fail;
|
||||
/*
|
||||
* Audio encoders may split the packets -- #frames in != #packets out.
|
||||
* But there is no reordering, so we can limit the number of output packets
|
||||
* by simply dropping them here.
|
||||
* Counting encoded video frames needs to be done separately because of
|
||||
* reordering, see do_video_out().
|
||||
* Do not count the packet when unqueued because it has been counted when queued.
|
||||
*/
|
||||
if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed) && !unqueue) {
|
||||
if (ost->frame_number >= ost->max_frames) {
|
||||
av_packet_unref(pkt);
|
||||
return;
|
||||
}
|
||||
ost->frame_number++;
|
||||
}
|
||||
|
||||
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP)
|
||||
if (!of->header_written) {
|
||||
AVPacket *tmp_pkt;
|
||||
/* the muxer is not initialized yet, buffer the packet */
|
||||
if (!av_fifo_can_write(ost->muxing_queue)) {
|
||||
size_t cur_size = av_fifo_can_read(ost->muxing_queue);
|
||||
unsigned int are_we_over_size =
|
||||
(ost->muxing_queue_data_size + pkt->size) > ost->muxing_queue_data_threshold;
|
||||
size_t limit = are_we_over_size ? ost->max_muxing_queue_size : SIZE_MAX;
|
||||
size_t new_size = FFMIN(2 * cur_size, limit);
|
||||
|
||||
if (new_size <= cur_size) {
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"Too many packets buffered for output stream %d:%d.\n",
|
||||
ost->file_index, ost->st->index);
|
||||
exit_program(1);
|
||||
}
|
||||
ret = av_fifo_grow2(ost->muxing_queue, new_size - cur_size);
|
||||
if (ret < 0)
|
||||
exit_program(1);
|
||||
}
|
||||
ret = av_packet_make_refcounted(pkt);
|
||||
if (ret < 0)
|
||||
exit_program(1);
|
||||
tmp_pkt = av_packet_alloc();
|
||||
if (!tmp_pkt)
|
||||
exit_program(1);
|
||||
av_packet_move_ref(tmp_pkt, pkt);
|
||||
ost->muxing_queue_data_size += tmp_pkt->size;
|
||||
av_fifo_write(ost->muxing_queue, &tmp_pkt, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP) ||
|
||||
(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0))
|
||||
pkt->pts = pkt->dts = AV_NOPTS_VALUE;
|
||||
|
||||
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
if (ost->frame_rate.num && ost->is_cfr) {
|
||||
if (pkt->duration > 0)
|
||||
av_log(ost, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
|
||||
av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
|
||||
pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate),
|
||||
pkt->time_base);
|
||||
ost->mux_timebase);
|
||||
}
|
||||
}
|
||||
|
||||
av_packet_rescale_ts(pkt, pkt->time_base, ost->st->time_base);
|
||||
pkt->time_base = ost->st->time_base;
|
||||
av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base);
|
||||
|
||||
if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
|
||||
if (pkt->dts != AV_NOPTS_VALUE &&
|
||||
@@ -97,26 +119,25 @@ static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
|
||||
pkt->dts, pkt->pts,
|
||||
ost->file_index, ost->st->index);
|
||||
pkt->pts =
|
||||
pkt->dts = pkt->pts + pkt->dts + ms->last_mux_dts + 1
|
||||
- FFMIN3(pkt->pts, pkt->dts, ms->last_mux_dts + 1)
|
||||
- FFMAX3(pkt->pts, pkt->dts, ms->last_mux_dts + 1);
|
||||
pkt->dts = pkt->pts + pkt->dts + ost->last_mux_dts + 1
|
||||
- FFMIN3(pkt->pts, pkt->dts, ost->last_mux_dts + 1)
|
||||
- FFMAX3(pkt->pts, pkt->dts, ost->last_mux_dts + 1);
|
||||
}
|
||||
if ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) &&
|
||||
pkt->dts != AV_NOPTS_VALUE &&
|
||||
ms->last_mux_dts != AV_NOPTS_VALUE) {
|
||||
int64_t max = ms->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
|
||||
ost->last_mux_dts != AV_NOPTS_VALUE) {
|
||||
int64_t max = ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
|
||||
if (pkt->dts < max) {
|
||||
int loglevel = max - pkt->dts > 2 || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
|
||||
if (exit_on_error)
|
||||
loglevel = AV_LOG_ERROR;
|
||||
av_log(s, loglevel, "Non-monotonous DTS in output stream "
|
||||
"%d:%d; previous: %"PRId64", current: %"PRId64"; ",
|
||||
ost->file_index, ost->st->index, ms->last_mux_dts, pkt->dts);
|
||||
ost->file_index, ost->st->index, ost->last_mux_dts, pkt->dts);
|
||||
if (exit_on_error) {
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
av_log(NULL, AV_LOG_FATAL, "aborting.\n");
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
av_log(s, loglevel, "changing to %"PRId64". This may result "
|
||||
"in incorrect timestamps in the output file.\n",
|
||||
max);
|
||||
@@ -126,17 +147,17 @@ static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
|
||||
}
|
||||
}
|
||||
}
|
||||
ms->last_mux_dts = pkt->dts;
|
||||
ost->last_mux_dts = pkt->dts;
|
||||
|
||||
ost->data_size_mux += pkt->size;
|
||||
frame_num = atomic_fetch_add(&ost->packets_written, 1);
|
||||
ost->data_size += pkt->size;
|
||||
ost->packets_written++;
|
||||
|
||||
pkt->stream_index = ost->index;
|
||||
|
||||
if (debug_ts) {
|
||||
av_log(ost, AV_LOG_INFO, "muxer <- type:%s "
|
||||
av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
|
||||
"pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s size:%d\n",
|
||||
av_get_media_type_string(st->codecpar->codec_type),
|
||||
av_get_media_type_string(ost->enc_ctx->codec_type),
|
||||
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
|
||||
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
|
||||
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ost->st->time_base),
|
||||
@@ -144,307 +165,12 @@ static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
|
||||
);
|
||||
}
|
||||
|
||||
if (ms->stats.io)
|
||||
enc_stats_write(ost, &ms->stats, NULL, pkt, frame_num);
|
||||
|
||||
ret = av_interleaved_write_frame(s, pkt);
|
||||
if (ret < 0) {
|
||||
print_error("av_interleaved_write_frame()", ret);
|
||||
goto fail;
|
||||
main_return_code = 1;
|
||||
close_all_output_streams(ost, MUXER_FINISHED | ENCODER_FINISHED, ENCODER_FINISHED);
|
||||
}
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
av_packet_unref(pkt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sync_queue_process(Muxer *mux, OutputStream *ost, AVPacket *pkt, int *stream_eof)
|
||||
{
|
||||
OutputFile *of = &mux->of;
|
||||
|
||||
if (ost->sq_idx_mux >= 0) {
|
||||
int ret = sq_send(mux->sq_mux, ost->sq_idx_mux, SQPKT(pkt));
|
||||
if (ret < 0) {
|
||||
if (ret == AVERROR_EOF)
|
||||
*stream_eof = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
ret = sq_receive(mux->sq_mux, -1, SQPKT(mux->sq_pkt));
|
||||
if (ret < 0)
|
||||
return (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) ? 0 : ret;
|
||||
|
||||
ret = write_packet(mux, of->streams[ret],
|
||||
mux->sq_pkt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
} else if (pkt)
|
||||
return write_packet(mux, ost, pkt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void thread_set_name(OutputFile *of)
|
||||
{
|
||||
char name[16];
|
||||
snprintf(name, sizeof(name), "mux%d:%s", of->index, of->format->name);
|
||||
ff_thread_setname(name);
|
||||
}
|
||||
|
||||
static void *muxer_thread(void *arg)
|
||||
{
|
||||
Muxer *mux = arg;
|
||||
OutputFile *of = &mux->of;
|
||||
AVPacket *pkt = NULL;
|
||||
int ret = 0;
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
thread_set_name(of);
|
||||
|
||||
while (1) {
|
||||
OutputStream *ost;
|
||||
int stream_idx, stream_eof = 0;
|
||||
|
||||
ret = tq_receive(mux->tq, &stream_idx, pkt);
|
||||
if (stream_idx < 0) {
|
||||
av_log(mux, AV_LOG_VERBOSE, "All streams finished\n");
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ost = of->streams[stream_idx];
|
||||
ret = sync_queue_process(mux, ost, ret < 0 ? NULL : pkt, &stream_eof);
|
||||
av_packet_unref(pkt);
|
||||
if (ret == AVERROR_EOF && stream_eof)
|
||||
tq_receive_finish(mux->tq, stream_idx);
|
||||
else if (ret < 0) {
|
||||
av_log(mux, AV_LOG_ERROR, "Error muxing a packet\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
av_packet_free(&pkt);
|
||||
|
||||
for (unsigned int i = 0; i < mux->fc->nb_streams; i++)
|
||||
tq_receive_finish(mux->tq, i);
|
||||
|
||||
av_log(mux, AV_LOG_VERBOSE, "Terminating muxer thread\n");
|
||||
|
||||
return (void*)(intptr_t)ret;
|
||||
}
|
||||
|
||||
static int thread_submit_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!pkt || ost->finished & MUXER_FINISHED)
|
||||
goto finish;
|
||||
|
||||
ret = tq_send(mux->tq, ost->index, pkt);
|
||||
if (ret < 0)
|
||||
goto finish;
|
||||
|
||||
return 0;
|
||||
|
||||
finish:
|
||||
if (pkt)
|
||||
av_packet_unref(pkt);
|
||||
|
||||
ost->finished |= MUXER_FINISHED;
|
||||
tq_send_finish(mux->tq, ost->index);
|
||||
return ret == AVERROR_EOF ? 0 : ret;
|
||||
}
|
||||
|
||||
static int queue_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
|
||||
{
|
||||
MuxStream *ms = ms_from_ost(ost);
|
||||
AVPacket *tmp_pkt = NULL;
|
||||
int ret;
|
||||
|
||||
if (!av_fifo_can_write(ms->muxing_queue)) {
|
||||
size_t cur_size = av_fifo_can_read(ms->muxing_queue);
|
||||
size_t pkt_size = pkt ? pkt->size : 0;
|
||||
unsigned int are_we_over_size =
|
||||
(ms->muxing_queue_data_size + pkt_size) > ms->muxing_queue_data_threshold;
|
||||
size_t limit = are_we_over_size ? ms->max_muxing_queue_size : SIZE_MAX;
|
||||
size_t new_size = FFMIN(2 * cur_size, limit);
|
||||
|
||||
if (new_size <= cur_size) {
|
||||
av_log(ost, AV_LOG_ERROR,
|
||||
"Too many packets buffered for output stream %d:%d.\n",
|
||||
ost->file_index, ost->st->index);
|
||||
return AVERROR(ENOSPC);
|
||||
}
|
||||
ret = av_fifo_grow2(ms->muxing_queue, new_size - cur_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pkt) {
|
||||
ret = av_packet_make_refcounted(pkt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
tmp_pkt = av_packet_alloc();
|
||||
if (!tmp_pkt)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
av_packet_move_ref(tmp_pkt, pkt);
|
||||
ms->muxing_queue_data_size += tmp_pkt->size;
|
||||
}
|
||||
av_fifo_write(ms->muxing_queue, &tmp_pkt, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int submit_packet(Muxer *mux, AVPacket *pkt, OutputStream *ost)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (mux->tq) {
|
||||
return thread_submit_packet(mux, ost, pkt);
|
||||
} else {
|
||||
/* the muxer is not initialized yet, buffer the packet */
|
||||
ret = queue_packet(mux, ost, pkt);
|
||||
if (ret < 0) {
|
||||
if (pkt)
|
||||
av_packet_unref(pkt);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void of_output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int eof)
|
||||
{
|
||||
Muxer *mux = mux_from_of(of);
|
||||
MuxStream *ms = ms_from_ost(ost);
|
||||
const char *err_msg;
|
||||
int ret = 0;
|
||||
|
||||
if (!eof && pkt->dts != AV_NOPTS_VALUE)
|
||||
ost->last_mux_dts = av_rescale_q(pkt->dts, pkt->time_base, AV_TIME_BASE_Q);
|
||||
|
||||
/* apply the output bitstream filters */
|
||||
if (ms->bsf_ctx) {
|
||||
int bsf_eof = 0;
|
||||
|
||||
ret = av_bsf_send_packet(ms->bsf_ctx, eof ? NULL : pkt);
|
||||
if (ret < 0) {
|
||||
err_msg = "submitting a packet for bitstream filtering";
|
||||
goto fail;
|
||||
}
|
||||
|
||||
while (!bsf_eof) {
|
||||
ret = av_bsf_receive_packet(ms->bsf_ctx, pkt);
|
||||
if (ret == AVERROR(EAGAIN))
|
||||
return;
|
||||
else if (ret == AVERROR_EOF)
|
||||
bsf_eof = 1;
|
||||
else if (ret < 0) {
|
||||
err_msg = "applying bitstream filters to a packet";
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = submit_packet(mux, bsf_eof ? NULL : pkt, ost);
|
||||
if (ret < 0)
|
||||
goto mux_fail;
|
||||
}
|
||||
} else {
|
||||
ret = submit_packet(mux, eof ? NULL : pkt, ost);
|
||||
if (ret < 0)
|
||||
goto mux_fail;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
mux_fail:
|
||||
err_msg = "submitting a packet to the muxer";
|
||||
|
||||
fail:
|
||||
av_log(ost, AV_LOG_ERROR, "Error %s\n", err_msg);
|
||||
if (exit_on_error)
|
||||
exit_program(1);
|
||||
|
||||
}
|
||||
|
||||
static int thread_stop(Muxer *mux)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
if (!mux || !mux->tq)
|
||||
return 0;
|
||||
|
||||
for (unsigned int i = 0; i < mux->fc->nb_streams; i++)
|
||||
tq_send_finish(mux->tq, i);
|
||||
|
||||
pthread_join(mux->thread, &ret);
|
||||
|
||||
tq_free(&mux->tq);
|
||||
|
||||
return (int)(intptr_t)ret;
|
||||
}
|
||||
|
||||
static void pkt_move(void *dst, void *src)
|
||||
{
|
||||
av_packet_move_ref(dst, src);
|
||||
}
|
||||
|
||||
static int thread_start(Muxer *mux)
|
||||
{
|
||||
AVFormatContext *fc = mux->fc;
|
||||
ObjPool *op;
|
||||
int ret;
|
||||
|
||||
op = objpool_alloc_packets();
|
||||
if (!op)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
mux->tq = tq_alloc(fc->nb_streams, mux->thread_queue_size, op, pkt_move);
|
||||
if (!mux->tq) {
|
||||
objpool_free(&op);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
ret = pthread_create(&mux->thread, NULL, muxer_thread, (void*)mux);
|
||||
if (ret) {
|
||||
tq_free(&mux->tq);
|
||||
return AVERROR(ret);
|
||||
}
|
||||
|
||||
/* flush the muxing queues */
|
||||
for (int i = 0; i < fc->nb_streams; i++) {
|
||||
OutputStream *ost = mux->of.streams[i];
|
||||
MuxStream *ms = ms_from_ost(ost);
|
||||
AVPacket *pkt;
|
||||
|
||||
/* try to improve muxing time_base (only possible if nothing has been written yet) */
|
||||
if (!av_fifo_can_read(ms->muxing_queue))
|
||||
ost->mux_timebase = ost->st->time_base;
|
||||
|
||||
while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0) {
|
||||
ret = thread_submit_packet(mux, ost, pkt);
|
||||
if (pkt) {
|
||||
ms->muxing_queue_data_size -= pkt->size;
|
||||
av_packet_free(&pkt);
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int print_sdp(void)
|
||||
@@ -456,16 +182,16 @@ static int print_sdp(void)
|
||||
AVFormatContext **avc;
|
||||
|
||||
for (i = 0; i < nb_output_files; i++) {
|
||||
if (!mux_from_of(output_files[i])->header_written)
|
||||
if (!output_files[i]->header_written)
|
||||
return 0;
|
||||
}
|
||||
|
||||
avc = av_malloc_array(nb_output_files, sizeof(*avc));
|
||||
if (!avc)
|
||||
return AVERROR(ENOMEM);
|
||||
exit_program(1);
|
||||
for (i = 0, j = 0; i < nb_output_files; i++) {
|
||||
if (!strcmp(output_files[i]->format->name, "rtp")) {
|
||||
avc[j] = mux_from_of(output_files[i])->fc;
|
||||
if (!strcmp(output_files[i]->ctx->oformat->name, "rtp")) {
|
||||
avc[j] = output_files[i]->ctx;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
@@ -495,36 +221,34 @@ static int print_sdp(void)
|
||||
av_freep(&sdp_filename);
|
||||
}
|
||||
|
||||
// SDP successfully written, allow muxer threads to start
|
||||
ret = 1;
|
||||
|
||||
fail:
|
||||
av_freep(&avc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mux_check_init(Muxer *mux)
|
||||
/* open the muxer when all the streams are initialized */
|
||||
int of_check_init(OutputFile *of)
|
||||
{
|
||||
OutputFile *of = &mux->of;
|
||||
AVFormatContext *fc = mux->fc;
|
||||
int ret, i;
|
||||
|
||||
for (i = 0; i < fc->nb_streams; i++) {
|
||||
OutputStream *ost = of->streams[i];
|
||||
for (i = 0; i < of->ctx->nb_streams; i++) {
|
||||
OutputStream *ost = output_streams[of->ost_index + i];
|
||||
if (!ost->initialized)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = avformat_write_header(fc, &mux->opts);
|
||||
ret = avformat_write_header(of->ctx, &of->opts);
|
||||
if (ret < 0) {
|
||||
av_log(mux, AV_LOG_ERROR, "Could not write header (incorrect codec "
|
||||
"parameters ?): %s\n", av_err2str(ret));
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"Could not write header for output file #%d "
|
||||
"(incorrect codec parameters ?): %s\n",
|
||||
of->index, av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
//assert_avoptions(of->opts);
|
||||
mux->header_written = 1;
|
||||
of->header_written = 1;
|
||||
|
||||
av_dump_format(fc, of->index, fc->url, 1);
|
||||
av_dump_format(of->ctx, of->index, of->ctx->url, 1);
|
||||
nb_output_dumped++;
|
||||
|
||||
if (sdp_filename || want_sdp) {
|
||||
@@ -532,220 +256,62 @@ int mux_check_init(Muxer *mux)
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error writing the SDP.\n");
|
||||
return ret;
|
||||
} else if (ret == 1) {
|
||||
/* SDP is written only after all the muxers are ready, so now we
|
||||
* start ALL the threads */
|
||||
for (i = 0; i < nb_output_files; i++) {
|
||||
ret = thread_start(mux_from_of(output_files[i]));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = thread_start(mux_from_of(of));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* flush the muxing queues */
|
||||
for (i = 0; i < of->ctx->nb_streams; i++) {
|
||||
OutputStream *ost = output_streams[of->ost_index + i];
|
||||
AVPacket *pkt;
|
||||
|
||||
/* try to improve muxing time_base (only possible if nothing has been written yet) */
|
||||
if (!av_fifo_can_read(ost->muxing_queue))
|
||||
ost->mux_timebase = ost->st->time_base;
|
||||
|
||||
while (av_fifo_read(ost->muxing_queue, &pkt, 1) >= 0) {
|
||||
ost->muxing_queue_data_size -= pkt->size;
|
||||
of_write_packet(of, pkt, ost, 1);
|
||||
av_packet_free(&pkt);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bsf_init(MuxStream *ms)
|
||||
{
|
||||
OutputStream *ost = &ms->ost;
|
||||
AVBSFContext *ctx = ms->bsf_ctx;
|
||||
int ret;
|
||||
|
||||
if (!ctx)
|
||||
return 0;
|
||||
|
||||
ret = avcodec_parameters_copy(ctx->par_in, ost->st->codecpar);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ctx->time_base_in = ost->st->time_base;
|
||||
|
||||
ret = av_bsf_init(ctx);
|
||||
if (ret < 0) {
|
||||
av_log(ms, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n",
|
||||
ctx->filter->name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ost->st->time_base = ctx->time_base_out;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int of_stream_init(OutputFile *of, OutputStream *ost)
|
||||
{
|
||||
Muxer *mux = mux_from_of(of);
|
||||
MuxStream *ms = ms_from_ost(ost);
|
||||
int ret;
|
||||
|
||||
if (ost->sq_idx_mux >= 0)
|
||||
sq_set_tb(mux->sq_mux, ost->sq_idx_mux, ost->mux_timebase);
|
||||
|
||||
/* initialize bitstream filters for the output stream
|
||||
* needs to be done here, because the codec id for streamcopy is not
|
||||
* known until now */
|
||||
ret = bsf_init(ms);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ost->initialized = 1;
|
||||
|
||||
return mux_check_init(mux);
|
||||
}
|
||||
|
||||
int of_write_trailer(OutputFile *of)
|
||||
{
|
||||
Muxer *mux = mux_from_of(of);
|
||||
AVFormatContext *fc = mux->fc;
|
||||
int ret;
|
||||
|
||||
if (!mux->tq) {
|
||||
av_log(mux, AV_LOG_ERROR,
|
||||
"Nothing was written into output file, because "
|
||||
"at least one of its streams received no packets.\n");
|
||||
if (!of->header_written) {
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"Nothing was written into output file %d (%s), because "
|
||||
"at least one of its streams received no packets.\n",
|
||||
of->index, of->ctx->url);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
ret = thread_stop(mux);
|
||||
if (ret < 0)
|
||||
main_return_code = ret;
|
||||
|
||||
ret = av_write_trailer(fc);
|
||||
ret = av_write_trailer(of->ctx);
|
||||
if (ret < 0) {
|
||||
av_log(mux, AV_LOG_ERROR, "Error writing trailer: %s\n", av_err2str(ret));
|
||||
av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", of->ctx->url, av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
mux->last_filesize = filesize(fc->pb);
|
||||
|
||||
if (!(of->format->flags & AVFMT_NOFILE)) {
|
||||
ret = avio_closep(&fc->pb);
|
||||
if (ret < 0) {
|
||||
av_log(mux, AV_LOG_ERROR, "Error closing file: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ost_free(OutputStream **post)
|
||||
{
|
||||
OutputStream *ost = *post;
|
||||
MuxStream *ms;
|
||||
|
||||
if (!ost)
|
||||
return;
|
||||
ms = ms_from_ost(ost);
|
||||
|
||||
if (ost->logfile) {
|
||||
if (fclose(ost->logfile))
|
||||
av_log(ms, AV_LOG_ERROR,
|
||||
"Error closing logfile, loss of information possible: %s\n",
|
||||
av_err2str(AVERROR(errno)));
|
||||
ost->logfile = NULL;
|
||||
}
|
||||
|
||||
if (ms->muxing_queue) {
|
||||
AVPacket *pkt;
|
||||
while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0)
|
||||
av_packet_free(&pkt);
|
||||
av_fifo_freep2(&ms->muxing_queue);
|
||||
}
|
||||
|
||||
av_bsf_free(&ms->bsf_ctx);
|
||||
|
||||
av_frame_free(&ost->filtered_frame);
|
||||
av_frame_free(&ost->sq_frame);
|
||||
av_frame_free(&ost->last_frame);
|
||||
av_packet_free(&ost->pkt);
|
||||
av_dict_free(&ost->encoder_opts);
|
||||
|
||||
av_freep(&ost->kf.pts);
|
||||
av_expr_free(ost->kf.pexpr);
|
||||
|
||||
av_freep(&ost->avfilter);
|
||||
av_freep(&ost->logfile_prefix);
|
||||
av_freep(&ost->apad);
|
||||
|
||||
#if FFMPEG_OPT_MAP_CHANNEL
|
||||
av_freep(&ost->audio_channels_map);
|
||||
ost->audio_channels_mapped = 0;
|
||||
#endif
|
||||
|
||||
av_dict_free(&ost->sws_dict);
|
||||
av_dict_free(&ost->swr_opts);
|
||||
|
||||
if (ost->enc_ctx)
|
||||
av_freep(&ost->enc_ctx->stats_in);
|
||||
avcodec_free_context(&ost->enc_ctx);
|
||||
|
||||
for (int i = 0; i < ost->enc_stats_pre.nb_components; i++)
|
||||
av_freep(&ost->enc_stats_pre.components[i].str);
|
||||
av_freep(&ost->enc_stats_pre.components);
|
||||
|
||||
for (int i = 0; i < ost->enc_stats_post.nb_components; i++)
|
||||
av_freep(&ost->enc_stats_post.components[i].str);
|
||||
av_freep(&ost->enc_stats_post.components);
|
||||
|
||||
for (int i = 0; i < ms->stats.nb_components; i++)
|
||||
av_freep(&ms->stats.components[i].str);
|
||||
av_freep(&ms->stats.components);
|
||||
|
||||
av_freep(post);
|
||||
}
|
||||
|
||||
static void fc_close(AVFormatContext **pfc)
|
||||
{
|
||||
AVFormatContext *fc = *pfc;
|
||||
|
||||
if (!fc)
|
||||
return;
|
||||
|
||||
if (!(fc->oformat->flags & AVFMT_NOFILE))
|
||||
avio_closep(&fc->pb);
|
||||
avformat_free_context(fc);
|
||||
|
||||
*pfc = NULL;
|
||||
}
|
||||
|
||||
void of_close(OutputFile **pof)
|
||||
{
|
||||
OutputFile *of = *pof;
|
||||
Muxer *mux;
|
||||
AVFormatContext *s;
|
||||
|
||||
if (!of)
|
||||
return;
|
||||
mux = mux_from_of(of);
|
||||
|
||||
thread_stop(mux);
|
||||
|
||||
sq_free(&of->sq_encode);
|
||||
sq_free(&mux->sq_mux);
|
||||
|
||||
for (int i = 0; i < of->nb_streams; i++)
|
||||
ost_free(&of->streams[i]);
|
||||
av_freep(&of->streams);
|
||||
|
||||
av_dict_free(&mux->opts);
|
||||
|
||||
av_packet_free(&mux->sq_pkt);
|
||||
|
||||
fc_close(&mux->fc);
|
||||
s = of->ctx;
|
||||
if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE))
|
||||
avio_closep(&s->pb);
|
||||
avformat_free_context(s);
|
||||
av_dict_free(&of->opts);
|
||||
|
||||
av_freep(pof);
|
||||
}
|
||||
|
||||
int64_t of_filesize(OutputFile *of)
|
||||
{
|
||||
Muxer *mux = mux_from_of(of);
|
||||
return atomic_load(&mux->last_filesize);
|
||||
}
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Muxer internal APIs - should not be included outside of ffmpeg_mux*
|
||||
*
|
||||
* 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 FFTOOLS_FFMPEG_MUX_H
|
||||
#define FFTOOLS_FFMPEG_MUX_H
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "thread_queue.h"
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
|
||||
#include "libavcodec/packet.h"
|
||||
|
||||
#include "libavutil/dict.h"
|
||||
#include "libavutil/fifo.h"
|
||||
#include "libavutil/thread.h"
|
||||
|
||||
typedef struct MuxStream {
|
||||
OutputStream ost;
|
||||
|
||||
// name used for logging
|
||||
char log_name[32];
|
||||
|
||||
/* the packets are buffered here until the muxer is ready to be initialized */
|
||||
AVFifo *muxing_queue;
|
||||
|
||||
AVBSFContext *bsf_ctx;
|
||||
|
||||
EncStats stats;
|
||||
|
||||
int64_t max_frames;
|
||||
|
||||
/*
|
||||
* The size of the AVPackets' buffers in queue.
|
||||
* Updated when a packet is either pushed or pulled from the queue.
|
||||
*/
|
||||
size_t muxing_queue_data_size;
|
||||
|
||||
int max_muxing_queue_size;
|
||||
|
||||
/* Threshold after which max_muxing_queue_size will be in effect */
|
||||
size_t muxing_queue_data_threshold;
|
||||
|
||||
/* dts of the last packet sent to the muxer, in the stream timebase
|
||||
* used for making up missing dts values */
|
||||
int64_t last_mux_dts;
|
||||
} MuxStream;
|
||||
|
||||
typedef struct Muxer {
|
||||
OutputFile of;
|
||||
|
||||
// name used for logging
|
||||
char log_name[32];
|
||||
|
||||
AVFormatContext *fc;
|
||||
|
||||
pthread_t thread;
|
||||
ThreadQueue *tq;
|
||||
|
||||
AVDictionary *opts;
|
||||
|
||||
int thread_queue_size;
|
||||
|
||||
/* filesize limit expressed in bytes */
|
||||
int64_t limit_filesize;
|
||||
atomic_int_least64_t last_filesize;
|
||||
int header_written;
|
||||
|
||||
SyncQueue *sq_mux;
|
||||
AVPacket *sq_pkt;
|
||||
} Muxer;
|
||||
|
||||
/* whether we want to print an SDP, set in of_open() */
|
||||
extern int want_sdp;
|
||||
|
||||
int mux_check_init(Muxer *mux);
|
||||
|
||||
static MuxStream *ms_from_ost(OutputStream *ost)
|
||||
{
|
||||
return (MuxStream*)ost;
|
||||
}
|
||||
|
||||
#endif /* FFTOOLS_FFMPEG_MUX_H */
|
||||
File diff suppressed because it is too large
Load Diff
2494
fftools/ffmpeg_opt.c
2494
fftools/ffmpeg_opt.c
File diff suppressed because it is too large
Load Diff
@@ -1860,7 +1860,7 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
|
||||
}
|
||||
pix_fmts[nb_pix_fmts] = AV_PIX_FMT_NONE;
|
||||
|
||||
while ((e = av_dict_iterate(sws_dict, e))) {
|
||||
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
|
||||
@@ -1915,14 +1915,8 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
|
||||
} while (0)
|
||||
|
||||
if (autorotate) {
|
||||
double theta = 0.0;
|
||||
int32_t *displaymatrix = NULL;
|
||||
AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
|
||||
if (sd)
|
||||
displaymatrix = (int32_t *)sd->data;
|
||||
if (!displaymatrix)
|
||||
displaymatrix = (int32_t *)av_stream_get_side_data(is->video_st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
|
||||
theta = get_rotation(displaymatrix);
|
||||
int32_t *displaymatrix = (int32_t *)av_stream_get_side_data(is->video_st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
|
||||
double theta = get_rotation(displaymatrix);
|
||||
|
||||
if (fabs(theta - 90) < 1.0) {
|
||||
INSERT_FILT("transpose", "clock");
|
||||
@@ -1966,7 +1960,7 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for
|
||||
|
||||
av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
|
||||
|
||||
while ((e = av_dict_iterate(swr_opts, e)))
|
||||
while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
|
||||
av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
|
||||
if (strlen(aresample_swr_opts))
|
||||
aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
|
||||
@@ -3537,7 +3531,7 @@ static void opt_input_file(void *optctx, const char *filename)
|
||||
exit(1);
|
||||
}
|
||||
if (!strcmp(filename, "-"))
|
||||
filename = "fd:";
|
||||
filename = "pipe:";
|
||||
input_filename = filename;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,13 +27,11 @@
|
||||
#include "libavutil/ffversion.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavformat/version.h"
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavcodec/version.h"
|
||||
#include "libavutil/ambient_viewing_environment.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/bprint.h"
|
||||
@@ -657,7 +655,7 @@ static int writer_open(WriterContext **wctx, const Writer *writer, const char *a
|
||||
goto fail;
|
||||
}
|
||||
|
||||
while ((opt = av_dict_iterate(opts, opt))) {
|
||||
while ((opt = av_dict_get(opts, "", opt, AV_DICT_IGNORE_SUFFIX))) {
|
||||
if ((ret = av_opt_set(*wctx, opt->key, opt->value, AV_OPT_SEARCH_CHILDREN)) < 0) {
|
||||
av_log(*wctx, AV_LOG_ERROR, "Failed to set option '%s' with value '%s' provided to writer context\n",
|
||||
opt->key, opt->value);
|
||||
@@ -1898,14 +1896,12 @@ static void writer_register_all(void)
|
||||
writer_print_string(w, k, pbuf.str, 0); \
|
||||
} while (0)
|
||||
|
||||
#define print_list_fmt(k, f, n, m, ...) do { \
|
||||
#define print_list_fmt(k, f, n, ...) do { \
|
||||
av_bprint_clear(&pbuf); \
|
||||
for (int idx = 0; idx < n; idx++) { \
|
||||
for (int idx2 = 0; idx2 < m; idx2++) { \
|
||||
if (idx > 0 || idx2 > 0) \
|
||||
av_bprint_chars(&pbuf, ' ', 1); \
|
||||
av_bprintf(&pbuf, f, __VA_ARGS__); \
|
||||
} \
|
||||
if (idx > 0) \
|
||||
av_bprint_chars(&pbuf, ' ', 1); \
|
||||
av_bprintf(&pbuf, f, __VA_ARGS__); \
|
||||
} \
|
||||
writer_print_string(w, k, pbuf.str, 0); \
|
||||
} while (0)
|
||||
@@ -1946,7 +1942,7 @@ static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id
|
||||
return 0;
|
||||
writer_print_section_header(w, section_id);
|
||||
|
||||
while ((tag = av_dict_iterate(tags, tag))) {
|
||||
while ((tag = av_dict_get(tags, "", tag, AV_DICT_IGNORE_SUFFIX))) {
|
||||
if ((ret = print_str_validate(tag->key, tag->value)) < 0)
|
||||
break;
|
||||
}
|
||||
@@ -2016,7 +2012,7 @@ static void print_dovi_metadata(WriterContext *w, const AVDOVIMetadata *dovi)
|
||||
const AVDOVIReshapingCurve *curve = &mapping->curves[c];
|
||||
writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_COMPONENT);
|
||||
|
||||
print_list_fmt("pivots", "%"PRIu16, curve->num_pivots, 1, curve->pivots[idx]);
|
||||
print_list_fmt("pivots", "%"PRIu16, curve->num_pivots, curve->pivots[idx]);
|
||||
|
||||
writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST);
|
||||
for (int i = 0; i < curve->num_pivots - 1; i++) {
|
||||
@@ -2028,7 +2024,7 @@ static void print_dovi_metadata(WriterContext *w, const AVDOVIMetadata *dovi)
|
||||
print_str("mapping_idc_name", "polynomial");
|
||||
print_int("poly_order", curve->poly_order[i]);
|
||||
print_list_fmt("poly_coef", "%"PRIi64,
|
||||
curve->poly_order[i] + 1, 1,
|
||||
curve->poly_order[i] + 1,
|
||||
curve->poly_coef[i][idx]);
|
||||
break;
|
||||
case AV_DOVI_MAPPING_MMR:
|
||||
@@ -2036,8 +2032,8 @@ static void print_dovi_metadata(WriterContext *w, const AVDOVIMetadata *dovi)
|
||||
print_int("mmr_order", curve->mmr_order[i]);
|
||||
print_int("mmr_constant", curve->mmr_constant[i]);
|
||||
print_list_fmt("mmr_coef", "%"PRIi64,
|
||||
curve->mmr_order[i], 7,
|
||||
curve->mmr_coef[i][idx][idx2]);
|
||||
curve->mmr_order[i] * 7,
|
||||
curve->mmr_coef[i][0][idx]);
|
||||
break;
|
||||
default:
|
||||
print_str("mapping_idc_name", "unknown");
|
||||
@@ -2075,15 +2071,15 @@ static void print_dovi_metadata(WriterContext *w, const AVDOVIMetadata *dovi)
|
||||
print_int("dm_metadata_id", color->dm_metadata_id);
|
||||
print_int("scene_refresh_flag", color->scene_refresh_flag);
|
||||
print_list_fmt("ycc_to_rgb_matrix", "%d/%d",
|
||||
FF_ARRAY_ELEMS(color->ycc_to_rgb_matrix), 1,
|
||||
FF_ARRAY_ELEMS(color->ycc_to_rgb_matrix),
|
||||
color->ycc_to_rgb_matrix[idx].num,
|
||||
color->ycc_to_rgb_matrix[idx].den);
|
||||
print_list_fmt("ycc_to_rgb_offset", "%d/%d",
|
||||
FF_ARRAY_ELEMS(color->ycc_to_rgb_offset), 1,
|
||||
FF_ARRAY_ELEMS(color->ycc_to_rgb_offset),
|
||||
color->ycc_to_rgb_offset[idx].num,
|
||||
color->ycc_to_rgb_offset[idx].den);
|
||||
print_list_fmt("rgb_to_lms_matrix", "%d/%d",
|
||||
FF_ARRAY_ELEMS(color->rgb_to_lms_matrix), 1,
|
||||
FF_ARRAY_ELEMS(color->rgb_to_lms_matrix),
|
||||
color->rgb_to_lms_matrix[idx].num,
|
||||
color->rgb_to_lms_matrix[idx].den);
|
||||
print_int("signal_eotf", color->signal_eotf);
|
||||
@@ -2269,17 +2265,6 @@ static void print_dynamic_hdr_vivid(WriterContext *w, const AVDynamicHDRVivid *m
|
||||
}
|
||||
}
|
||||
|
||||
static void print_ambient_viewing_environment(WriterContext *w,
|
||||
const AVAmbientViewingEnvironment *env)
|
||||
{
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
print_q("ambient_illuminance", env->ambient_illuminance, '/');
|
||||
print_q("ambient_light_x", env->ambient_light_x, '/');
|
||||
print_q("ambient_light_y", env->ambient_light_y, '/');
|
||||
}
|
||||
|
||||
static void print_pkt_side_data(WriterContext *w,
|
||||
AVCodecParameters *par,
|
||||
const AVPacketSideData *side_data,
|
||||
@@ -2297,11 +2282,8 @@ static void print_pkt_side_data(WriterContext *w,
|
||||
writer_print_section_header(w, id_data);
|
||||
print_str("side_data_type", name ? name : "unknown");
|
||||
if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) {
|
||||
double rotation = av_display_rotation_get((int32_t *)sd->data);
|
||||
if (isnan(rotation))
|
||||
rotation = 0;
|
||||
writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1);
|
||||
print_int("rotation", rotation);
|
||||
print_int("rotation", av_display_rotation_get((int32_t *)sd->data));
|
||||
} else if (sd->type == AV_PKT_DATA_STEREO3D) {
|
||||
const AVStereo3D *stereo = (AVStereo3D *)sd->data;
|
||||
print_str("type", av_stereo3d_type_name(stereo->type));
|
||||
@@ -2513,12 +2495,8 @@ static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int p
|
||||
print_val("size", pkt->size, unit_byte_str);
|
||||
if (pkt->pos != -1) print_fmt ("pos", "%"PRId64, pkt->pos);
|
||||
else print_str_opt("pos", "N/A");
|
||||
print_fmt("flags", "%c%c%c", pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_',
|
||||
pkt->flags & AV_PKT_FLAG_DISCARD ? 'D' : '_',
|
||||
pkt->flags & AV_PKT_FLAG_CORRUPT ? 'C' : '_');
|
||||
if (do_show_data)
|
||||
writer_print_data(w, "data", pkt->data, pkt->size);
|
||||
writer_print_data_hash(w, "data_hash", pkt->data, pkt->size);
|
||||
print_fmt("flags", "%c%c", pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_',
|
||||
pkt->flags & AV_PKT_FLAG_DISCARD ? 'D' : '_');
|
||||
|
||||
if (pkt->side_data_elems) {
|
||||
size_t size;
|
||||
@@ -2537,6 +2515,9 @@ static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int p
|
||||
SECTION_ID_PACKET_SIDE_DATA);
|
||||
}
|
||||
|
||||
if (do_show_data)
|
||||
writer_print_data(w, "data", pkt->data, pkt->size);
|
||||
writer_print_data_hash(w, "data_hash", pkt->data, pkt->size);
|
||||
writer_print_section_footer(w);
|
||||
|
||||
av_bprint_finalize(&pbuf, NULL);
|
||||
@@ -2589,14 +2570,8 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
|
||||
print_time("pkt_dts_time", frame->pkt_dts, &stream->time_base);
|
||||
print_ts ("best_effort_timestamp", frame->best_effort_timestamp);
|
||||
print_time("best_effort_timestamp_time", frame->best_effort_timestamp, &stream->time_base);
|
||||
#if LIBAVUTIL_VERSION_MAJOR < 59
|
||||
AV_NOWARN_DEPRECATED(
|
||||
print_duration_ts ("pkt_duration", frame->pkt_duration);
|
||||
print_duration_time("pkt_duration_time", frame->pkt_duration, &stream->time_base);
|
||||
)
|
||||
#endif
|
||||
print_duration_ts ("duration", frame->duration);
|
||||
print_duration_time("duration_time", frame->duration, &stream->time_base);
|
||||
if (frame->pkt_pos != -1) print_fmt ("pkt_pos", "%"PRId64, frame->pkt_pos);
|
||||
else print_str_opt("pkt_pos", "N/A");
|
||||
if (frame->pkt_size != -1) print_val ("pkt_size", frame->pkt_size, unit_byte_str);
|
||||
@@ -2618,12 +2593,8 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
|
||||
print_str_opt("sample_aspect_ratio", "N/A");
|
||||
}
|
||||
print_fmt("pict_type", "%c", av_get_picture_type_char(frame->pict_type));
|
||||
#if LIBAVUTIL_VERSION_MAJOR < 59
|
||||
AV_NOWARN_DEPRECATED(
|
||||
print_int("coded_picture_number", frame->coded_picture_number);
|
||||
print_int("display_picture_number", frame->display_picture_number);
|
||||
)
|
||||
#endif
|
||||
print_int("interlaced_frame", frame->interlaced_frame);
|
||||
print_int("top_field_first", frame->top_field_first);
|
||||
print_int("repeat_pict", frame->repeat_pict);
|
||||
@@ -2662,11 +2633,8 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
|
||||
name = av_frame_side_data_name(sd->type);
|
||||
print_str("side_data_type", name ? name : "unknown");
|
||||
if (sd->type == AV_FRAME_DATA_DISPLAYMATRIX && sd->size >= 9*4) {
|
||||
double rotation = av_display_rotation_get((int32_t *)sd->data);
|
||||
if (isnan(rotation))
|
||||
rotation = 0;
|
||||
writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1);
|
||||
print_int("rotation", rotation);
|
||||
print_int("rotation", av_display_rotation_get((int32_t *)sd->data));
|
||||
} else if (sd->type == AV_FRAME_DATA_AFD && sd->size > 0) {
|
||||
print_int("active_format", *sd->data);
|
||||
} else if (sd->type == AV_FRAME_DATA_GOP_TIMECODE && sd->size >= 8) {
|
||||
@@ -2721,9 +2689,6 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
|
||||
} else if (sd->type == AV_FRAME_DATA_DYNAMIC_HDR_VIVID) {
|
||||
AVDynamicHDRVivid *metadata = (AVDynamicHDRVivid *)sd->data;
|
||||
print_dynamic_hdr_vivid(w, metadata);
|
||||
} else if (sd->type == AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT) {
|
||||
print_ambient_viewing_environment(
|
||||
w, (const AVAmbientViewingEnvironment *)sd->data);
|
||||
}
|
||||
writer_print_section_footer(w);
|
||||
}
|
||||
@@ -2738,7 +2703,7 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
|
||||
|
||||
static av_always_inline int process_frame(WriterContext *w,
|
||||
InputFile *ifile,
|
||||
AVFrame *frame, const AVPacket *pkt,
|
||||
AVFrame *frame, AVPacket *pkt,
|
||||
int *packet_new)
|
||||
{
|
||||
AVFormatContext *fmt_ctx = ifile->fmt_ctx;
|
||||
@@ -2879,10 +2844,9 @@ static int read_interval_packets(WriterContext *w, InputFile *ifile,
|
||||
}
|
||||
if (selected_streams[pkt->stream_index]) {
|
||||
AVRational tb = ifile->streams[pkt->stream_index].st->time_base;
|
||||
int64_t pts = pkt->pts != AV_NOPTS_VALUE ? pkt->pts : pkt->dts;
|
||||
|
||||
if (pts != AV_NOPTS_VALUE)
|
||||
*cur_ts = av_rescale_q(pts, tb, AV_TIME_BASE_Q);
|
||||
if (pkt->pts != AV_NOPTS_VALUE)
|
||||
*cur_ts = av_rescale_q(pkt->pts, tb, AV_TIME_BASE_Q);
|
||||
|
||||
if (!has_start && *cur_ts != AV_NOPTS_VALUE) {
|
||||
start = *cur_ts;
|
||||
@@ -2916,7 +2880,7 @@ static int read_interval_packets(WriterContext *w, InputFile *ifile,
|
||||
}
|
||||
av_packet_unref(pkt);
|
||||
//Flush remaining frames that are cached in the decoder
|
||||
for (i = 0; i < ifile->nb_streams; i++) {
|
||||
for (i = 0; i < fmt_ctx->nb_streams; i++) {
|
||||
pkt->stream_index = i;
|
||||
if (do_read_frames) {
|
||||
while (process_frame(w, ifile, frame, pkt, &(int){1}) > 0);
|
||||
@@ -3074,8 +3038,6 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id
|
||||
}
|
||||
|
||||
print_int("bits_per_sample", av_get_bits_per_sample(par->codec_id));
|
||||
|
||||
print_int("initial_padding", par->initial_padding);
|
||||
break;
|
||||
|
||||
case AVMEDIA_TYPE_SUBTITLE:
|
||||
@@ -3302,9 +3264,15 @@ static int show_format(WriterContext *w, InputFile *ifile)
|
||||
|
||||
static void show_error(WriterContext *w, int err)
|
||||
{
|
||||
char errbuf[128];
|
||||
const char *errbuf_ptr = errbuf;
|
||||
|
||||
if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
|
||||
errbuf_ptr = strerror(AVUNERROR(err));
|
||||
|
||||
writer_print_section_header(w, SECTION_ID_ERROR);
|
||||
print_int("code", err);
|
||||
print_str("string", av_err2str(err));
|
||||
print_str("string", errbuf_ptr);
|
||||
writer_print_section_footer(w);
|
||||
}
|
||||
|
||||
@@ -3317,8 +3285,10 @@ static int open_input_file(InputFile *ifile, const char *filename,
|
||||
int scan_all_pmts_set = 0;
|
||||
|
||||
fmt_ctx = avformat_alloc_context();
|
||||
if (!fmt_ctx)
|
||||
report_and_exit(AVERROR(ENOMEM));
|
||||
if (!fmt_ctx) {
|
||||
print_error(filename, AVERROR(ENOMEM));
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
|
||||
av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
|
||||
@@ -3336,7 +3306,7 @@ static int open_input_file(InputFile *ifile, const char *filename,
|
||||
ifile->fmt_ctx = fmt_ctx;
|
||||
if (scan_all_pmts_set)
|
||||
av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
|
||||
while ((t = av_dict_iterate(format_opts, t)))
|
||||
while ((t = av_dict_get(format_opts, "", t, AV_DICT_IGNORE_SUFFIX)))
|
||||
av_log(NULL, AV_LOG_WARNING, "Option %s skipped - not known to demuxer.\n", t->key);
|
||||
|
||||
if (find_stream_info) {
|
||||
@@ -3735,7 +3705,7 @@ static void opt_input_file(void *optctx, const char *arg)
|
||||
exit_program(1);
|
||||
}
|
||||
if (!strcmp(arg, "-"))
|
||||
arg = "fd:";
|
||||
arg = "pipe:";
|
||||
input_filename = arg;
|
||||
}
|
||||
|
||||
@@ -3754,7 +3724,7 @@ static void opt_output_file(void *optctx, const char *arg)
|
||||
exit_program(1);
|
||||
}
|
||||
if (!strcmp(arg, "-"))
|
||||
arg = "fd:";
|
||||
arg = "pipe:";
|
||||
output_filename = arg;
|
||||
}
|
||||
|
||||
@@ -4056,7 +4026,7 @@ int main(int argc, char **argv)
|
||||
WriterContext *wctx;
|
||||
char *buf;
|
||||
char *w_name = NULL, *w_args = NULL;
|
||||
int ret, input_ret, i;
|
||||
int ret, i;
|
||||
|
||||
init_dynload();
|
||||
|
||||
@@ -4180,14 +4150,10 @@ int main(int argc, char **argv)
|
||||
show_error(wctx, ret);
|
||||
}
|
||||
|
||||
input_ret = ret;
|
||||
|
||||
writer_print_section_footer(wctx);
|
||||
ret = writer_close(&wctx);
|
||||
if (ret < 0)
|
||||
av_log(NULL, AV_LOG_ERROR, "Writing output failed: %s\n", av_err2str(ret));
|
||||
|
||||
ret = FFMIN(ret, input_ret);
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||
<asmv3:application>
|
||||
<asmv3:windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||
</asmv3:windowsSettings>
|
||||
</asmv3:application>
|
||||
</assembly>
|
||||
@@ -1,2 +0,0 @@
|
||||
#include <windows.h>
|
||||
1 RT_MANIFEST fftools.manifest
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "libavcodec/packet.h"
|
||||
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/error.h"
|
||||
#include "libavutil/frame.h"
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
#include "objpool.h"
|
||||
|
||||
struct ObjPool {
|
||||
void *pool[32];
|
||||
unsigned int pool_count;
|
||||
|
||||
ObjPoolCBAlloc alloc;
|
||||
ObjPoolCBReset reset;
|
||||
ObjPoolCBFree free;
|
||||
};
|
||||
|
||||
ObjPool *objpool_alloc(ObjPoolCBAlloc cb_alloc, ObjPoolCBReset cb_reset,
|
||||
ObjPoolCBFree cb_free)
|
||||
{
|
||||
ObjPool *op = av_mallocz(sizeof(*op));
|
||||
|
||||
if (!op)
|
||||
return NULL;
|
||||
|
||||
op->alloc = cb_alloc;
|
||||
op->reset = cb_reset;
|
||||
op->free = cb_free;
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
void objpool_free(ObjPool **pop)
|
||||
{
|
||||
ObjPool *op = *pop;
|
||||
|
||||
if (!op)
|
||||
return;
|
||||
|
||||
for (unsigned int i = 0; i < op->pool_count; i++)
|
||||
op->free(&op->pool[i]);
|
||||
|
||||
av_freep(pop);
|
||||
}
|
||||
|
||||
int objpool_get(ObjPool *op, void **obj)
|
||||
{
|
||||
if (op->pool_count) {
|
||||
*obj = op->pool[--op->pool_count];
|
||||
op->pool[op->pool_count] = NULL;
|
||||
} else
|
||||
*obj = op->alloc();
|
||||
|
||||
return *obj ? 0 : AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
void objpool_release(ObjPool *op, void **obj)
|
||||
{
|
||||
if (!*obj)
|
||||
return;
|
||||
|
||||
op->reset(*obj);
|
||||
|
||||
if (op->pool_count < FF_ARRAY_ELEMS(op->pool))
|
||||
op->pool[op->pool_count++] = *obj;
|
||||
else
|
||||
op->free(obj);
|
||||
|
||||
*obj = NULL;
|
||||
}
|
||||
|
||||
static void *alloc_packet(void)
|
||||
{
|
||||
return av_packet_alloc();
|
||||
}
|
||||
static void *alloc_frame(void)
|
||||
{
|
||||
return av_frame_alloc();
|
||||
}
|
||||
|
||||
static void reset_packet(void *obj)
|
||||
{
|
||||
av_packet_unref(obj);
|
||||
}
|
||||
static void reset_frame(void *obj)
|
||||
{
|
||||
av_frame_unref(obj);
|
||||
}
|
||||
|
||||
static void free_packet(void **obj)
|
||||
{
|
||||
AVPacket *pkt = *obj;
|
||||
av_packet_free(&pkt);
|
||||
*obj = NULL;
|
||||
}
|
||||
static void free_frame(void **obj)
|
||||
{
|
||||
AVFrame *frame = *obj;
|
||||
av_frame_free(&frame);
|
||||
*obj = NULL;
|
||||
}
|
||||
|
||||
ObjPool *objpool_alloc_packets(void)
|
||||
{
|
||||
return objpool_alloc(alloc_packet, reset_packet, free_packet);
|
||||
}
|
||||
ObjPool *objpool_alloc_frames(void)
|
||||
{
|
||||
return objpool_alloc(alloc_frame, reset_frame, free_frame);
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef FFTOOLS_OBJPOOL_H
|
||||
#define FFTOOLS_OBJPOOL_H
|
||||
|
||||
typedef struct ObjPool ObjPool;
|
||||
|
||||
typedef void* (*ObjPoolCBAlloc)(void);
|
||||
typedef void (*ObjPoolCBReset)(void *);
|
||||
typedef void (*ObjPoolCBFree)(void **);
|
||||
|
||||
void objpool_free(ObjPool **op);
|
||||
ObjPool *objpool_alloc(ObjPoolCBAlloc cb_alloc, ObjPoolCBReset cb_reset,
|
||||
ObjPoolCBFree cb_free);
|
||||
ObjPool *objpool_alloc_packets(void);
|
||||
ObjPool *objpool_alloc_frames(void);
|
||||
|
||||
int objpool_get(ObjPool *op, void **obj);
|
||||
void objpool_release(ObjPool *op, void **obj);
|
||||
|
||||
#endif // FFTOOLS_OBJPOOL_H
|
||||
@@ -335,12 +335,9 @@ static void print_codec(const AVCodec *c)
|
||||
printf(" Supported hardware devices: ");
|
||||
for (int i = 0;; i++) {
|
||||
const AVCodecHWConfig *config = avcodec_get_hw_config(c, i);
|
||||
const char *name;
|
||||
if (!config)
|
||||
break;
|
||||
name = av_hwdevice_get_type_name(config->device_type);
|
||||
if (name)
|
||||
printf("%s ", name);
|
||||
printf("%s ", av_hwdevice_get_type_name(config->device_type));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
@@ -642,8 +639,10 @@ static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
|
||||
|
||||
while ((desc = avcodec_descriptor_next(desc)))
|
||||
nb_codecs++;
|
||||
if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs))))
|
||||
report_and_exit(AVERROR(ENOMEM));
|
||||
if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs)))) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
|
||||
exit_program(1);
|
||||
}
|
||||
desc = NULL;
|
||||
while ((desc = avcodec_descriptor_next(desc)))
|
||||
codecs[i++] = desc;
|
||||
|
||||
@@ -1,448 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/error.h"
|
||||
#include "libavutil/fifo.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
#include "objpool.h"
|
||||
#include "sync_queue.h"
|
||||
|
||||
typedef struct SyncQueueStream {
|
||||
AVFifo *fifo;
|
||||
AVRational tb;
|
||||
|
||||
/* stream head: largest timestamp seen */
|
||||
int64_t head_ts;
|
||||
int limiting;
|
||||
/* no more frames will be sent for this stream */
|
||||
int finished;
|
||||
|
||||
uint64_t frames_sent;
|
||||
uint64_t frames_max;
|
||||
} SyncQueueStream;
|
||||
|
||||
struct SyncQueue {
|
||||
enum SyncQueueType type;
|
||||
|
||||
/* no more frames will be sent for any stream */
|
||||
int finished;
|
||||
/* sync head: the stream with the _smallest_ head timestamp
|
||||
* this stream determines which frames can be output */
|
||||
int head_stream;
|
||||
/* the finished stream with the smallest finish timestamp or -1 */
|
||||
int head_finished_stream;
|
||||
|
||||
// maximum buffering duration in microseconds
|
||||
int64_t buf_size_us;
|
||||
|
||||
SyncQueueStream *streams;
|
||||
unsigned int nb_streams;
|
||||
|
||||
// pool of preallocated frames to avoid constant allocations
|
||||
ObjPool *pool;
|
||||
};
|
||||
|
||||
static void frame_move(const SyncQueue *sq, SyncQueueFrame dst,
|
||||
SyncQueueFrame src)
|
||||
{
|
||||
if (sq->type == SYNC_QUEUE_PACKETS)
|
||||
av_packet_move_ref(dst.p, src.p);
|
||||
else
|
||||
av_frame_move_ref(dst.f, src.f);
|
||||
}
|
||||
|
||||
static int64_t frame_ts(const SyncQueue *sq, SyncQueueFrame frame)
|
||||
{
|
||||
return (sq->type == SYNC_QUEUE_PACKETS) ?
|
||||
frame.p->pts + frame.p->duration :
|
||||
frame.f->pts + frame.f->duration;
|
||||
}
|
||||
|
||||
static int frame_null(const SyncQueue *sq, SyncQueueFrame frame)
|
||||
{
|
||||
return (sq->type == SYNC_QUEUE_PACKETS) ? (frame.p == NULL) : (frame.f == NULL);
|
||||
}
|
||||
|
||||
static void finish_stream(SyncQueue *sq, unsigned int stream_idx)
|
||||
{
|
||||
SyncQueueStream *st = &sq->streams[stream_idx];
|
||||
|
||||
st->finished = 1;
|
||||
|
||||
if (st->limiting && st->head_ts != AV_NOPTS_VALUE) {
|
||||
/* check if this stream is the new finished head */
|
||||
if (sq->head_finished_stream < 0 ||
|
||||
av_compare_ts(st->head_ts, st->tb,
|
||||
sq->streams[sq->head_finished_stream].head_ts,
|
||||
sq->streams[sq->head_finished_stream].tb) < 0) {
|
||||
sq->head_finished_stream = stream_idx;
|
||||
}
|
||||
|
||||
/* mark as finished all streams that should no longer receive new frames,
|
||||
* due to them being ahead of some finished stream */
|
||||
st = &sq->streams[sq->head_finished_stream];
|
||||
for (unsigned int i = 0; i < sq->nb_streams; i++) {
|
||||
SyncQueueStream *st1 = &sq->streams[i];
|
||||
if (st != st1 && st1->head_ts != AV_NOPTS_VALUE &&
|
||||
av_compare_ts(st->head_ts, st->tb, st1->head_ts, st1->tb) <= 0)
|
||||
st1->finished = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* mark the whole queue as finished if all streams are finished */
|
||||
for (unsigned int i = 0; i < sq->nb_streams; i++) {
|
||||
if (!sq->streams[i].finished)
|
||||
return;
|
||||
}
|
||||
sq->finished = 1;
|
||||
}
|
||||
|
||||
static void queue_head_update(SyncQueue *sq)
|
||||
{
|
||||
if (sq->head_stream < 0) {
|
||||
/* wait for one timestamp in each stream before determining
|
||||
* the queue head */
|
||||
for (unsigned int i = 0; i < sq->nb_streams; i++) {
|
||||
SyncQueueStream *st = &sq->streams[i];
|
||||
if (st->limiting && st->head_ts == AV_NOPTS_VALUE)
|
||||
return;
|
||||
}
|
||||
|
||||
// placeholder value, correct one will be found below
|
||||
sq->head_stream = 0;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < sq->nb_streams; i++) {
|
||||
SyncQueueStream *st_head = &sq->streams[sq->head_stream];
|
||||
SyncQueueStream *st_other = &sq->streams[i];
|
||||
if (st_other->limiting && st_other->head_ts != AV_NOPTS_VALUE &&
|
||||
av_compare_ts(st_other->head_ts, st_other->tb,
|
||||
st_head->head_ts, st_head->tb) < 0)
|
||||
sq->head_stream = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* update this stream's head timestamp */
|
||||
static void stream_update_ts(SyncQueue *sq, unsigned int stream_idx, int64_t ts)
|
||||
{
|
||||
SyncQueueStream *st = &sq->streams[stream_idx];
|
||||
|
||||
if (ts == AV_NOPTS_VALUE ||
|
||||
(st->head_ts != AV_NOPTS_VALUE && st->head_ts >= ts))
|
||||
return;
|
||||
|
||||
st->head_ts = ts;
|
||||
|
||||
/* if this stream is now ahead of some finished stream, then
|
||||
* this stream is also finished */
|
||||
if (sq->head_finished_stream >= 0 &&
|
||||
av_compare_ts(sq->streams[sq->head_finished_stream].head_ts,
|
||||
sq->streams[sq->head_finished_stream].tb,
|
||||
ts, st->tb) <= 0)
|
||||
finish_stream(sq, stream_idx);
|
||||
|
||||
/* update the overall head timestamp if it could have changed */
|
||||
if (st->limiting &&
|
||||
(sq->head_stream < 0 || sq->head_stream == stream_idx))
|
||||
queue_head_update(sq);
|
||||
}
|
||||
|
||||
/* If the queue for the given stream (or all streams when stream_idx=-1)
|
||||
* is overflowing, trigger a fake heartbeat on lagging streams.
|
||||
*
|
||||
* @return 1 if heartbeat triggered, 0 otherwise
|
||||
*/
|
||||
static int overflow_heartbeat(SyncQueue *sq, int stream_idx)
|
||||
{
|
||||
SyncQueueStream *st;
|
||||
SyncQueueFrame frame;
|
||||
int64_t tail_ts = AV_NOPTS_VALUE;
|
||||
|
||||
/* if no stream specified, pick the one that is most ahead */
|
||||
if (stream_idx < 0) {
|
||||
int64_t ts = AV_NOPTS_VALUE;
|
||||
|
||||
for (int i = 0; i < sq->nb_streams; i++) {
|
||||
st = &sq->streams[i];
|
||||
if (st->head_ts != AV_NOPTS_VALUE &&
|
||||
(ts == AV_NOPTS_VALUE ||
|
||||
av_compare_ts(ts, sq->streams[stream_idx].tb,
|
||||
st->head_ts, st->tb) < 0)) {
|
||||
ts = st->head_ts;
|
||||
stream_idx = i;
|
||||
}
|
||||
}
|
||||
/* no stream has a timestamp yet -> nothing to do */
|
||||
if (stream_idx < 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
st = &sq->streams[stream_idx];
|
||||
|
||||
/* get the chosen stream's tail timestamp */
|
||||
for (size_t i = 0; tail_ts == AV_NOPTS_VALUE &&
|
||||
av_fifo_peek(st->fifo, &frame, 1, i) >= 0; i++)
|
||||
tail_ts = frame_ts(sq, frame);
|
||||
|
||||
/* overflow triggers when the tail is over specified duration behind the head */
|
||||
if (tail_ts == AV_NOPTS_VALUE || tail_ts >= st->head_ts ||
|
||||
av_rescale_q(st->head_ts - tail_ts, st->tb, AV_TIME_BASE_Q) < sq->buf_size_us)
|
||||
return 0;
|
||||
|
||||
/* signal a fake timestamp for all streams that prevent tail_ts from being output */
|
||||
tail_ts++;
|
||||
for (unsigned int i = 0; i < sq->nb_streams; i++) {
|
||||
SyncQueueStream *st1 = &sq->streams[i];
|
||||
int64_t ts;
|
||||
|
||||
if (st == st1 || st1->finished ||
|
||||
(st1->head_ts != AV_NOPTS_VALUE &&
|
||||
av_compare_ts(tail_ts, st->tb, st1->head_ts, st1->tb) <= 0))
|
||||
continue;
|
||||
|
||||
ts = av_rescale_q(tail_ts, st->tb, st1->tb);
|
||||
if (st1->head_ts != AV_NOPTS_VALUE)
|
||||
ts = FFMAX(st1->head_ts + 1, ts);
|
||||
|
||||
stream_update_ts(sq, i, ts);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame)
|
||||
{
|
||||
SyncQueueStream *st;
|
||||
SyncQueueFrame dst;
|
||||
int64_t ts;
|
||||
int ret;
|
||||
|
||||
av_assert0(stream_idx < sq->nb_streams);
|
||||
st = &sq->streams[stream_idx];
|
||||
|
||||
av_assert0(st->tb.num > 0 && st->tb.den > 0);
|
||||
|
||||
if (frame_null(sq, frame)) {
|
||||
finish_stream(sq, stream_idx);
|
||||
return 0;
|
||||
}
|
||||
if (st->finished)
|
||||
return AVERROR_EOF;
|
||||
|
||||
ret = objpool_get(sq->pool, (void**)&dst);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
frame_move(sq, dst, frame);
|
||||
|
||||
ts = frame_ts(sq, dst);
|
||||
|
||||
ret = av_fifo_write(st->fifo, &dst, 1);
|
||||
if (ret < 0) {
|
||||
frame_move(sq, frame, dst);
|
||||
objpool_release(sq->pool, (void**)&dst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
stream_update_ts(sq, stream_idx, ts);
|
||||
|
||||
st->frames_sent++;
|
||||
if (st->frames_sent >= st->frames_max)
|
||||
finish_stream(sq, stream_idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int receive_for_stream(SyncQueue *sq, unsigned int stream_idx,
|
||||
SyncQueueFrame frame)
|
||||
{
|
||||
SyncQueueStream *st_head = sq->head_stream >= 0 ?
|
||||
&sq->streams[sq->head_stream] : NULL;
|
||||
SyncQueueStream *st;
|
||||
|
||||
av_assert0(stream_idx < sq->nb_streams);
|
||||
st = &sq->streams[stream_idx];
|
||||
|
||||
if (av_fifo_can_read(st->fifo)) {
|
||||
SyncQueueFrame peek;
|
||||
int64_t ts;
|
||||
int cmp = 1;
|
||||
|
||||
av_fifo_peek(st->fifo, &peek, 1, 0);
|
||||
ts = frame_ts(sq, peek);
|
||||
|
||||
/* check if this stream's tail timestamp does not overtake
|
||||
* the overall queue head */
|
||||
if (ts != AV_NOPTS_VALUE && st_head)
|
||||
cmp = av_compare_ts(ts, st->tb, st_head->head_ts, st_head->tb);
|
||||
|
||||
/* We can release frames that do not end after the queue head.
|
||||
* Frames with no timestamps are just passed through with no conditions.
|
||||
*/
|
||||
if (cmp <= 0 || ts == AV_NOPTS_VALUE) {
|
||||
frame_move(sq, frame, peek);
|
||||
objpool_release(sq->pool, (void**)&peek);
|
||||
av_fifo_drain2(st->fifo, 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (sq->finished || (st->finished && !av_fifo_can_read(st->fifo))) ?
|
||||
AVERROR_EOF : AVERROR(EAGAIN);
|
||||
}
|
||||
|
||||
static int receive_internal(SyncQueue *sq, int stream_idx, SyncQueueFrame frame)
|
||||
{
|
||||
int nb_eof = 0;
|
||||
int ret;
|
||||
|
||||
/* read a frame for a specific stream */
|
||||
if (stream_idx >= 0) {
|
||||
ret = receive_for_stream(sq, stream_idx, frame);
|
||||
return (ret < 0) ? ret : stream_idx;
|
||||
}
|
||||
|
||||
/* read a frame for any stream with available output */
|
||||
for (unsigned int i = 0; i < sq->nb_streams; i++) {
|
||||
ret = receive_for_stream(sq, i, frame);
|
||||
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) {
|
||||
nb_eof += (ret == AVERROR_EOF);
|
||||
continue;
|
||||
}
|
||||
return (ret < 0) ? ret : i;
|
||||
}
|
||||
|
||||
return (nb_eof == sq->nb_streams) ? AVERROR_EOF : AVERROR(EAGAIN);
|
||||
}
|
||||
|
||||
int sq_receive(SyncQueue *sq, int stream_idx, SyncQueueFrame frame)
|
||||
{
|
||||
int ret = receive_internal(sq, stream_idx, frame);
|
||||
|
||||
/* try again if the queue overflowed and triggered a fake heartbeat
|
||||
* for lagging streams */
|
||||
if (ret == AVERROR(EAGAIN) && overflow_heartbeat(sq, stream_idx))
|
||||
ret = receive_internal(sq, stream_idx, frame);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sq_add_stream(SyncQueue *sq, int limiting)
|
||||
{
|
||||
SyncQueueStream *tmp, *st;
|
||||
|
||||
tmp = av_realloc_array(sq->streams, sq->nb_streams + 1, sizeof(*sq->streams));
|
||||
if (!tmp)
|
||||
return AVERROR(ENOMEM);
|
||||
sq->streams = tmp;
|
||||
|
||||
st = &sq->streams[sq->nb_streams];
|
||||
memset(st, 0, sizeof(*st));
|
||||
|
||||
st->fifo = av_fifo_alloc2(1, sizeof(SyncQueueFrame), AV_FIFO_FLAG_AUTO_GROW);
|
||||
if (!st->fifo)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
/* we set a valid default, so that a pathological stream that never
|
||||
* receives even a real timebase (and no frames) won't stall all other
|
||||
* streams forever; cf. overflow_heartbeat() */
|
||||
st->tb = (AVRational){ 1, 1 };
|
||||
st->head_ts = AV_NOPTS_VALUE;
|
||||
st->frames_max = UINT64_MAX;
|
||||
st->limiting = limiting;
|
||||
|
||||
return sq->nb_streams++;
|
||||
}
|
||||
|
||||
void sq_set_tb(SyncQueue *sq, unsigned int stream_idx, AVRational tb)
|
||||
{
|
||||
SyncQueueStream *st;
|
||||
|
||||
av_assert0(stream_idx < sq->nb_streams);
|
||||
st = &sq->streams[stream_idx];
|
||||
|
||||
av_assert0(!av_fifo_can_read(st->fifo));
|
||||
|
||||
if (st->head_ts != AV_NOPTS_VALUE)
|
||||
st->head_ts = av_rescale_q(st->head_ts, st->tb, tb);
|
||||
|
||||
st->tb = tb;
|
||||
}
|
||||
|
||||
void sq_limit_frames(SyncQueue *sq, unsigned int stream_idx, uint64_t frames)
|
||||
{
|
||||
SyncQueueStream *st;
|
||||
|
||||
av_assert0(stream_idx < sq->nb_streams);
|
||||
st = &sq->streams[stream_idx];
|
||||
|
||||
st->frames_max = frames;
|
||||
if (st->frames_sent >= st->frames_max)
|
||||
finish_stream(sq, stream_idx);
|
||||
}
|
||||
|
||||
SyncQueue *sq_alloc(enum SyncQueueType type, int64_t buf_size_us)
|
||||
{
|
||||
SyncQueue *sq = av_mallocz(sizeof(*sq));
|
||||
|
||||
if (!sq)
|
||||
return NULL;
|
||||
|
||||
sq->type = type;
|
||||
sq->buf_size_us = buf_size_us;
|
||||
|
||||
sq->head_stream = -1;
|
||||
sq->head_finished_stream = -1;
|
||||
|
||||
sq->pool = (type == SYNC_QUEUE_PACKETS) ? objpool_alloc_packets() :
|
||||
objpool_alloc_frames();
|
||||
if (!sq->pool) {
|
||||
av_freep(&sq);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sq;
|
||||
}
|
||||
|
||||
void sq_free(SyncQueue **psq)
|
||||
{
|
||||
SyncQueue *sq = *psq;
|
||||
|
||||
if (!sq)
|
||||
return;
|
||||
|
||||
for (unsigned int i = 0; i < sq->nb_streams; i++) {
|
||||
SyncQueueFrame frame;
|
||||
while (av_fifo_read(sq->streams[i].fifo, &frame, 1) >= 0)
|
||||
objpool_release(sq->pool, (void**)&frame);
|
||||
|
||||
av_fifo_freep2(&sq->streams[i].fifo);
|
||||
}
|
||||
|
||||
av_freep(&sq->streams);
|
||||
|
||||
objpool_free(&sq->pool);
|
||||
|
||||
av_freep(psq);
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef FFTOOLS_SYNC_QUEUE_H
|
||||
#define FFTOOLS_SYNC_QUEUE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "libavcodec/packet.h"
|
||||
|
||||
#include "libavutil/frame.h"
|
||||
|
||||
enum SyncQueueType {
|
||||
SYNC_QUEUE_PACKETS,
|
||||
SYNC_QUEUE_FRAMES,
|
||||
};
|
||||
|
||||
typedef union SyncQueueFrame {
|
||||
AVFrame *f;
|
||||
AVPacket *p;
|
||||
} SyncQueueFrame;
|
||||
|
||||
#define SQFRAME(frame) ((SyncQueueFrame){ .f = (frame) })
|
||||
#define SQPKT(pkt) ((SyncQueueFrame){ .p = (pkt) })
|
||||
|
||||
typedef struct SyncQueue SyncQueue;
|
||||
|
||||
/**
|
||||
* Allocate a sync queue of the given type.
|
||||
*
|
||||
* @param buf_size_us maximum duration that will be buffered in microseconds
|
||||
*/
|
||||
SyncQueue *sq_alloc(enum SyncQueueType type, int64_t buf_size_us);
|
||||
void sq_free(SyncQueue **sq);
|
||||
|
||||
/**
|
||||
* Add a new stream to the sync queue.
|
||||
*
|
||||
* @param limiting whether the stream is limiting, i.e. no other stream can be
|
||||
* longer than this one
|
||||
* @return
|
||||
* - a non-negative stream index on success
|
||||
* - a negative error code on error
|
||||
*/
|
||||
int sq_add_stream(SyncQueue *sq, int limiting);
|
||||
|
||||
/**
|
||||
* Set the timebase for the stream with index stream_idx. Should be called
|
||||
* before sending any frames for this stream.
|
||||
*/
|
||||
void sq_set_tb(SyncQueue *sq, unsigned int stream_idx, AVRational tb);
|
||||
|
||||
/**
|
||||
* Limit the number of output frames for stream with index stream_idx
|
||||
* to max_frames.
|
||||
*/
|
||||
void sq_limit_frames(SyncQueue *sq, unsigned int stream_idx,
|
||||
uint64_t max_frames);
|
||||
|
||||
/**
|
||||
* Submit a frame for the stream with index stream_idx.
|
||||
*
|
||||
* On success, the sync queue takes ownership of the frame and will reset the
|
||||
* contents of the supplied frame. On failure, the frame remains owned by the
|
||||
* caller.
|
||||
*
|
||||
* Sending a frame with NULL contents marks the stream as finished.
|
||||
*
|
||||
* @return
|
||||
* - 0 on success
|
||||
* - AVERROR_EOF when no more frames should be submitted for this stream
|
||||
* - another a negative error code on failure
|
||||
*/
|
||||
int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame);
|
||||
|
||||
/**
|
||||
* Read a frame from the queue.
|
||||
*
|
||||
* @param stream_idx index of the stream to read a frame for. May be -1, then
|
||||
* try to read a frame from any stream that is ready for
|
||||
* output.
|
||||
* @param frame output frame will be written here on success. The frame is owned
|
||||
* by the caller.
|
||||
*
|
||||
* @return
|
||||
* - a non-negative index of the stream to which the returned frame belongs
|
||||
* - AVERROR(EAGAIN) when more frames need to be submitted to the queue
|
||||
* - AVERROR_EOF when no more frames will be available for this stream (for any
|
||||
* stream if stream_idx is -1)
|
||||
* - another negative error code on failure
|
||||
*/
|
||||
int sq_receive(SyncQueue *sq, int stream_idx, SyncQueueFrame frame);
|
||||
|
||||
#endif // FFTOOLS_SYNC_QUEUE_H
|
||||
@@ -1,245 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/error.h"
|
||||
#include "libavutil/fifo.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/thread.h"
|
||||
|
||||
#include "objpool.h"
|
||||
#include "thread_queue.h"
|
||||
|
||||
enum {
|
||||
FINISHED_SEND = (1 << 0),
|
||||
FINISHED_RECV = (1 << 1),
|
||||
};
|
||||
|
||||
typedef struct FifoElem {
|
||||
void *obj;
|
||||
unsigned int stream_idx;
|
||||
} FifoElem;
|
||||
|
||||
struct ThreadQueue {
|
||||
int *finished;
|
||||
unsigned int nb_streams;
|
||||
|
||||
AVFifo *fifo;
|
||||
|
||||
ObjPool *obj_pool;
|
||||
void (*obj_move)(void *dst, void *src);
|
||||
|
||||
pthread_mutex_t lock;
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
|
||||
void tq_free(ThreadQueue **ptq)
|
||||
{
|
||||
ThreadQueue *tq = *ptq;
|
||||
|
||||
if (!tq)
|
||||
return;
|
||||
|
||||
if (tq->fifo) {
|
||||
FifoElem elem;
|
||||
while (av_fifo_read(tq->fifo, &elem, 1) >= 0)
|
||||
objpool_release(tq->obj_pool, &elem.obj);
|
||||
}
|
||||
av_fifo_freep2(&tq->fifo);
|
||||
|
||||
objpool_free(&tq->obj_pool);
|
||||
|
||||
av_freep(&tq->finished);
|
||||
|
||||
pthread_cond_destroy(&tq->cond);
|
||||
pthread_mutex_destroy(&tq->lock);
|
||||
|
||||
av_freep(ptq);
|
||||
}
|
||||
|
||||
ThreadQueue *tq_alloc(unsigned int nb_streams, size_t queue_size,
|
||||
ObjPool *obj_pool, void (*obj_move)(void *dst, void *src))
|
||||
{
|
||||
ThreadQueue *tq;
|
||||
int ret;
|
||||
|
||||
tq = av_mallocz(sizeof(*tq));
|
||||
if (!tq)
|
||||
return NULL;
|
||||
|
||||
ret = pthread_cond_init(&tq->cond, NULL);
|
||||
if (ret) {
|
||||
av_freep(&tq);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = pthread_mutex_init(&tq->lock, NULL);
|
||||
if (ret) {
|
||||
pthread_cond_destroy(&tq->cond);
|
||||
av_freep(&tq);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tq->finished = av_calloc(nb_streams, sizeof(*tq->finished));
|
||||
if (!tq->finished)
|
||||
goto fail;
|
||||
tq->nb_streams = nb_streams;
|
||||
|
||||
tq->fifo = av_fifo_alloc2(queue_size, sizeof(FifoElem), 0);
|
||||
if (!tq->fifo)
|
||||
goto fail;
|
||||
|
||||
tq->obj_pool = obj_pool;
|
||||
tq->obj_move = obj_move;
|
||||
|
||||
return tq;
|
||||
fail:
|
||||
tq_free(&tq);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int tq_send(ThreadQueue *tq, unsigned int stream_idx, void *data)
|
||||
{
|
||||
int *finished;
|
||||
int ret;
|
||||
|
||||
av_assert0(stream_idx < tq->nb_streams);
|
||||
finished = &tq->finished[stream_idx];
|
||||
|
||||
pthread_mutex_lock(&tq->lock);
|
||||
|
||||
if (*finished & FINISHED_SEND) {
|
||||
ret = AVERROR(EINVAL);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
while (!(*finished & FINISHED_RECV) && !av_fifo_can_write(tq->fifo))
|
||||
pthread_cond_wait(&tq->cond, &tq->lock);
|
||||
|
||||
if (*finished & FINISHED_RECV) {
|
||||
ret = AVERROR_EOF;
|
||||
*finished |= FINISHED_SEND;
|
||||
} else {
|
||||
FifoElem elem = { .stream_idx = stream_idx };
|
||||
|
||||
ret = objpool_get(tq->obj_pool, &elem.obj);
|
||||
if (ret < 0)
|
||||
goto finish;
|
||||
|
||||
tq->obj_move(elem.obj, data);
|
||||
|
||||
ret = av_fifo_write(tq->fifo, &elem, 1);
|
||||
av_assert0(ret >= 0);
|
||||
pthread_cond_broadcast(&tq->cond);
|
||||
}
|
||||
|
||||
finish:
|
||||
pthread_mutex_unlock(&tq->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int receive_locked(ThreadQueue *tq, int *stream_idx,
|
||||
void *data)
|
||||
{
|
||||
FifoElem elem;
|
||||
unsigned int nb_finished = 0;
|
||||
|
||||
if (av_fifo_read(tq->fifo, &elem, 1) >= 0) {
|
||||
tq->obj_move(data, elem.obj);
|
||||
objpool_release(tq->obj_pool, &elem.obj);
|
||||
*stream_idx = elem.stream_idx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < tq->nb_streams; i++) {
|
||||
if (!(tq->finished[i] & FINISHED_SEND))
|
||||
continue;
|
||||
|
||||
/* return EOF to the consumer at most once for each stream */
|
||||
if (!(tq->finished[i] & FINISHED_RECV)) {
|
||||
tq->finished[i] |= FINISHED_RECV;
|
||||
*stream_idx = i;
|
||||
return AVERROR_EOF;
|
||||
}
|
||||
|
||||
nb_finished++;
|
||||
}
|
||||
|
||||
return nb_finished == tq->nb_streams ? AVERROR_EOF : AVERROR(EAGAIN);
|
||||
}
|
||||
|
||||
int tq_receive(ThreadQueue *tq, int *stream_idx, void *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
*stream_idx = -1;
|
||||
|
||||
pthread_mutex_lock(&tq->lock);
|
||||
|
||||
while (1) {
|
||||
ret = receive_locked(tq, stream_idx, data);
|
||||
if (ret == AVERROR(EAGAIN)) {
|
||||
pthread_cond_wait(&tq->cond, &tq->lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
pthread_cond_broadcast(&tq->cond);
|
||||
|
||||
pthread_mutex_unlock(&tq->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void tq_send_finish(ThreadQueue *tq, unsigned int stream_idx)
|
||||
{
|
||||
av_assert0(stream_idx < tq->nb_streams);
|
||||
|
||||
pthread_mutex_lock(&tq->lock);
|
||||
|
||||
/* mark the stream as send-finished;
|
||||
* next time the consumer thread tries to read this stream it will get
|
||||
* an EOF and recv-finished flag will be set */
|
||||
tq->finished[stream_idx] |= FINISHED_SEND;
|
||||
pthread_cond_broadcast(&tq->cond);
|
||||
|
||||
pthread_mutex_unlock(&tq->lock);
|
||||
}
|
||||
|
||||
void tq_receive_finish(ThreadQueue *tq, unsigned int stream_idx)
|
||||
{
|
||||
av_assert0(stream_idx < tq->nb_streams);
|
||||
|
||||
pthread_mutex_lock(&tq->lock);
|
||||
|
||||
/* mark the stream as recv-finished;
|
||||
* next time the producer thread tries to send for this stream, it will
|
||||
* get an EOF and send-finished flag will be set */
|
||||
tq->finished[stream_idx] |= FINISHED_RECV;
|
||||
pthread_cond_broadcast(&tq->cond);
|
||||
|
||||
pthread_mutex_unlock(&tq->lock);
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef FFTOOLS_THREAD_QUEUE_H
|
||||
#define FFTOOLS_THREAD_QUEUE_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "objpool.h"
|
||||
|
||||
typedef struct ThreadQueue ThreadQueue;
|
||||
|
||||
/**
|
||||
* Allocate a queue for sending data between threads.
|
||||
*
|
||||
* @param nb_streams number of streams for which a distinct EOF state is
|
||||
* maintained
|
||||
* @param queue_size number of items that can be stored in the queue without
|
||||
* blocking
|
||||
* @param obj_pool object pool that will be used to allocate items stored in the
|
||||
* queue; the pool becomes owned by the queue
|
||||
* @param callback that moves the contents between two data pointers
|
||||
*/
|
||||
ThreadQueue *tq_alloc(unsigned int nb_streams, size_t queue_size,
|
||||
ObjPool *obj_pool, void (*obj_move)(void *dst, void *src));
|
||||
void tq_free(ThreadQueue **tq);
|
||||
|
||||
/**
|
||||
* Send an item for the given stream to the queue.
|
||||
*
|
||||
* @param data the item to send, its contents will be moved using the callback
|
||||
* provided to tq_alloc(); on failure the item will be left
|
||||
* untouched
|
||||
* @return
|
||||
* - 0 the item was successfully sent
|
||||
* - AVERROR(ENOMEM) could not allocate an item for writing to the FIFO
|
||||
* - AVERROR(EINVAL) the sending side has previously been marked as finished
|
||||
* - AVERROR_EOF the receiving side has marked the given stream as finished
|
||||
*/
|
||||
int tq_send(ThreadQueue *tq, unsigned int stream_idx, void *data);
|
||||
/**
|
||||
* Mark the given stream finished from the sending side.
|
||||
*/
|
||||
void tq_send_finish(ThreadQueue *tq, unsigned int stream_idx);
|
||||
|
||||
/**
|
||||
* Read the next item from the queue.
|
||||
*
|
||||
* @param stream_idx the index of the stream that was processed or -1 will be
|
||||
* written here
|
||||
* @param data the data item will be written here on success using the
|
||||
* callback provided to tq_alloc()
|
||||
* @return
|
||||
* - 0 a data item was successfully read; *stream_idx contains a non-negative
|
||||
* stream index
|
||||
* - AVERROR_EOF When *stream_idx is non-negative, this signals that the sending
|
||||
* side has marked the given stream as finished. This will happen at most once
|
||||
* for each stream. When *stream_idx is -1, all streams are done.
|
||||
*/
|
||||
int tq_receive(ThreadQueue *tq, int *stream_idx, void *data);
|
||||
/**
|
||||
* Mark the given stream finished from the receiving side.
|
||||
*/
|
||||
void tq_receive_finish(ThreadQueue *tq, unsigned int stream_idx);
|
||||
|
||||
#endif // FFTOOLS_THREAD_QUEUE_H
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "codec_internal.h"
|
||||
#include "decode.h"
|
||||
#include "internal.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
|
||||
static av_cold int zero12v_decode_init(AVCodecContext *avctx)
|
||||
@@ -131,8 +131,8 @@ static int zero12v_decode_frame(AVCodecContext *avctx, AVFrame *pic,
|
||||
u = x/2 + (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
|
||||
v = x/2 + (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
|
||||
memcpy(y, y_temp, sizeof(*y) * (width - x));
|
||||
memcpy(u, u_temp, sizeof(*u) * ((width - x + 1) / 2));
|
||||
memcpy(v, v_temp, sizeof(*v) * ((width - x + 1) / 2));
|
||||
memcpy(u, u_temp, sizeof(*u) * (width - x + 1) / 2);
|
||||
memcpy(v, v_temp, sizeof(*v) * (width - x + 1) / 2);
|
||||
}
|
||||
|
||||
line_end += stride;
|
||||
@@ -146,10 +146,11 @@ static int zero12v_decode_frame(AVCodecContext *avctx, AVFrame *pic,
|
||||
|
||||
const FFCodec ff_zero12v_decoder = {
|
||||
.p.name = "012v",
|
||||
CODEC_LONG_NAME("Uncompressed 4:2:2 10-bit"),
|
||||
.p.long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
|
||||
.p.type = AVMEDIA_TYPE_VIDEO,
|
||||
.p.id = AV_CODEC_ID_012V,
|
||||
.init = zero12v_decode_init,
|
||||
FF_CODEC_DECODE_CB(zero12v_decode_frame),
|
||||
.p.capabilities = AV_CODEC_CAP_DR1,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||
};
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
#include "bswapdsp.h"
|
||||
#include "bytestream.h"
|
||||
#include "codec_internal.h"
|
||||
#include "decode.h"
|
||||
#include "get_bits.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
#define BLOCK_TYPE_VLC_BITS 5
|
||||
@@ -875,7 +875,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
|
||||
}
|
||||
|
||||
for (i = 0; i < CFRAME_BUFFER_COUNT; i++)
|
||||
if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_num)
|
||||
if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
|
||||
av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n",
|
||||
f->cfrm[i].id);
|
||||
|
||||
@@ -887,8 +887,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
|
||||
}
|
||||
|
||||
if (i >= CFRAME_BUFFER_COUNT) {
|
||||
if (free_index < 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
i = free_index;
|
||||
f->cfrm[i].id = id;
|
||||
}
|
||||
@@ -912,9 +910,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
|
||||
buf = cfrm->data;
|
||||
frame_size = cfrm->size;
|
||||
|
||||
if (id != avctx->frame_num)
|
||||
av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %"PRId64"\n",
|
||||
id, avctx->frame_num);
|
||||
if (id != avctx->frame_number)
|
||||
av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n",
|
||||
id, avctx->frame_number);
|
||||
|
||||
if (f->version <= 1)
|
||||
return AVERROR_INVALIDDATA;
|
||||
@@ -952,11 +950,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
|
||||
} else if (frame_4cc == AV_RL32("snd_")) {
|
||||
av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n",
|
||||
buf_size);
|
||||
return AVERROR_INVALIDDATA;
|
||||
} else {
|
||||
av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n",
|
||||
buf_size);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
picture->key_frame = picture->pict_type == AV_PICTURE_TYPE_I;
|
||||
@@ -968,6 +964,8 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
|
||||
|
||||
*got_frame = 1;
|
||||
|
||||
emms_c();
|
||||
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
@@ -1014,7 +1012,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
f->version = AV_RL32(avctx->extradata) >> 16;
|
||||
ff_blockdsp_init(&f->bdsp);
|
||||
ff_blockdsp_init(&f->bdsp, avctx);
|
||||
ff_bswapdsp_init(&f->bbdsp);
|
||||
f->avctx = avctx;
|
||||
|
||||
@@ -1030,7 +1028,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||
|
||||
const FFCodec ff_fourxm_decoder = {
|
||||
.p.name = "4xm",
|
||||
CODEC_LONG_NAME("4X Movie"),
|
||||
.p.long_name = NULL_IF_CONFIG_SMALL("4X Movie"),
|
||||
.p.type = AVMEDIA_TYPE_VIDEO,
|
||||
.p.id = AV_CODEC_ID_4XM,
|
||||
.priv_data_size = sizeof(FourXContext),
|
||||
@@ -1038,5 +1036,5 @@ const FFCodec ff_fourxm_decoder = {
|
||||
.close = decode_end,
|
||||
FF_CODEC_DECODE_CB(decode_frame),
|
||||
.p.capabilities = AV_CODEC_CAP_DR1,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
|
||||
};
|
||||
|
||||
@@ -30,13 +30,16 @@
|
||||
* : RGB32 (RGB 32bpp, 4th plane is alpha)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libavutil/bswap.h"
|
||||
#include "libavutil/internal.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "avcodec.h"
|
||||
#include "codec_internal.h"
|
||||
#include "decode.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
static const enum AVPixelFormat pixfmt_rgb24[] = {
|
||||
@@ -68,9 +71,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
|
||||
unsigned char *planemap = c->planemap;
|
||||
int ret;
|
||||
|
||||
if (buf_size < planes * height * 2)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
|
||||
return ret;
|
||||
|
||||
@@ -175,11 +175,12 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||
|
||||
const FFCodec ff_eightbps_decoder = {
|
||||
.p.name = "8bps",
|
||||
CODEC_LONG_NAME("QuickTime 8BPS video"),
|
||||
.p.long_name = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"),
|
||||
.p.type = AVMEDIA_TYPE_VIDEO,
|
||||
.p.id = AV_CODEC_ID_8BPS,
|
||||
.priv_data_size = sizeof(EightBpsContext),
|
||||
.init = decode_init,
|
||||
FF_CODEC_DECODE_CB(decode_frame),
|
||||
.p.capabilities = AV_CODEC_CAP_DR1,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||
};
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#include "libavutil/avassert.h"
|
||||
#include "avcodec.h"
|
||||
#include "codec_internal.h"
|
||||
#include "decode.h"
|
||||
#include "internal.h"
|
||||
#include "libavutil/common.h"
|
||||
|
||||
/** decoder context */
|
||||
@@ -151,7 +151,7 @@ static int eightsvx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
|
||||
|
||||
*got_frame_ptr = 1;
|
||||
|
||||
return ((avctx->frame_num == 0) * hdr_size + buf_size) * channels;
|
||||
return ((avctx->frame_number == 0) * hdr_size + buf_size) * channels;
|
||||
}
|
||||
|
||||
static av_cold int eightsvx_decode_init(AVCodecContext *avctx)
|
||||
@@ -189,7 +189,7 @@ static av_cold int eightsvx_decode_close(AVCodecContext *avctx)
|
||||
#if CONFIG_EIGHTSVX_FIB_DECODER
|
||||
const FFCodec ff_eightsvx_fib_decoder = {
|
||||
.p.name = "8svx_fib",
|
||||
CODEC_LONG_NAME("8SVX fibonacci"),
|
||||
.p.long_name = NULL_IF_CONFIG_SMALL("8SVX fibonacci"),
|
||||
.p.type = AVMEDIA_TYPE_AUDIO,
|
||||
.p.id = AV_CODEC_ID_8SVX_FIB,
|
||||
.priv_data_size = sizeof (EightSvxContext),
|
||||
@@ -199,12 +199,13 @@ const FFCodec ff_eightsvx_fib_decoder = {
|
||||
.p.capabilities = AV_CODEC_CAP_DR1,
|
||||
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||
};
|
||||
#endif
|
||||
#if CONFIG_EIGHTSVX_EXP_DECODER
|
||||
const FFCodec ff_eightsvx_exp_decoder = {
|
||||
.p.name = "8svx_exp",
|
||||
CODEC_LONG_NAME("8SVX exponential"),
|
||||
.p.long_name = NULL_IF_CONFIG_SMALL("8SVX exponential"),
|
||||
.p.type = AVMEDIA_TYPE_AUDIO,
|
||||
.p.id = AV_CODEC_ID_8SVX_EXP,
|
||||
.priv_data_size = sizeof (EightSvxContext),
|
||||
@@ -214,5 +215,6 @@ const FFCodec ff_eightsvx_exp_decoder = {
|
||||
.p.capabilities = AV_CODEC_CAP_DR1,
|
||||
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -91,19 +91,16 @@ OBJS-$(CONFIG_FDCTDSP) += fdctdsp.o jfdctfst.o jfdctint.o
|
||||
FFT-OBJS-$(CONFIG_HARDCODED_TABLES) += cos_tables.o
|
||||
OBJS-$(CONFIG_FFT) += avfft.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
|
||||
OBJS-$(CONFIG_H264CHROMA) += h264chroma.o
|
||||
OBJS-$(CONFIG_H264DSP) += h264dsp.o h264idct.o
|
||||
OBJS-$(CONFIG_H264PARSE) += h264_parse.o h264_ps.o h2645data.o \
|
||||
h2645_parse.o h2645_vui.o
|
||||
OBJS-$(CONFIG_H264PARSE) += h264_parse.o h2645_parse.o h264_ps.o
|
||||
OBJS-$(CONFIG_H264PRED) += h264pred.o
|
||||
OBJS-$(CONFIG_H264QPEL) += h264qpel.o
|
||||
OBJS-$(CONFIG_H264_SEI) += h264_sei.o h2645_sei.o
|
||||
OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o hevc_ps.o hevc_data.o \
|
||||
h2645data.o h2645_parse.o h2645_vui.o
|
||||
OBJS-$(CONFIG_HEVC_SEI) += hevc_sei.o h2645_sei.o \
|
||||
OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o h2645_parse.o hevc_ps.o hevc_sei.o hevc_data.o \
|
||||
dynamic_hdr10_plus.o dynamic_hdr_vivid.o
|
||||
OBJS-$(CONFIG_HPELDSP) += hpeldsp.o
|
||||
OBJS-$(CONFIG_HUFFMAN) += huffman.o
|
||||
@@ -111,12 +108,12 @@ OBJS-$(CONFIG_HUFFYUVDSP) += huffyuvdsp.o
|
||||
OBJS-$(CONFIG_HUFFYUVENCDSP) += huffyuvencdsp.o
|
||||
OBJS-$(CONFIG_IDCTDSP) += idctdsp.o simple_idct.o jrevdct.o
|
||||
OBJS-$(CONFIG_IIRFILTER) += iirfilter.o
|
||||
OBJS-$(CONFIG_MDCT15) += mdct15.o
|
||||
OBJS-$(CONFIG_INFLATE_WRAPPER) += zlib_wrapper.o
|
||||
OBJS-$(CONFIG_INTRAX8) += intrax8.o intrax8dsp.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_IVIDSP) += ivi_dsp.o
|
||||
OBJS-$(CONFIG_JNI) += ffjni.o jni.o
|
||||
OBJS-$(CONFIG_JPEGTABLES) += jpegtables.o
|
||||
OBJS-$(CONFIG_LCMS2) += fflcms2.o
|
||||
OBJS-$(CONFIG_LLAUDDSP) += lossless_audiodsp.o
|
||||
OBJS-$(CONFIG_LLVIDDSP) += lossless_videodsp.o
|
||||
OBJS-$(CONFIG_LLVIDENCDSP) += lossless_videoencdsp.o
|
||||
@@ -135,7 +132,7 @@ OBJS-$(CONFIG_MPEGAUDIODSP) += mpegaudiodsp.o \
|
||||
mpegaudiodsp_float.o
|
||||
OBJS-$(CONFIG_MPEGAUDIOHEADER) += mpegaudiodecheader.o mpegaudiotabs.o
|
||||
OBJS-$(CONFIG_MPEG4AUDIO) += mpeg4audio.o mpeg4audio_sample_rates.o
|
||||
OBJS-$(CONFIG_MPEGVIDEO) += mpegvideo.o rl.o \
|
||||
OBJS-$(CONFIG_MPEGVIDEO) += mpegvideo.o mpegvideodsp.o rl.o \
|
||||
mpegvideo_motion.o \
|
||||
mpegvideodata.o mpegpicture.o \
|
||||
to_upper4.o
|
||||
@@ -143,11 +140,7 @@ OBJS-$(CONFIG_MPEGVIDEODEC) += mpegvideo_dec.o mpegutils.o
|
||||
OBJS-$(CONFIG_MPEGVIDEOENC) += mpegvideo_enc.o mpeg12data.o \
|
||||
motion_est.o ratecontrol.o \
|
||||
mpegvideoencdsp.o
|
||||
OBJS-$(CONFIG_MSMPEG4DEC) += msmpeg4dec.o msmpeg4.o msmpeg4data.o \
|
||||
msmpeg4_vc1_data.o
|
||||
OBJS-$(CONFIG_MSMPEG4ENC) += msmpeg4enc.o msmpeg4.o msmpeg4data.o \
|
||||
msmpeg4_vc1_data.o
|
||||
OBJS-$(CONFIG_MSS34DSP) += mss34dsp.o jpegquanttables.o
|
||||
OBJS-$(CONFIG_MSS34DSP) += mss34dsp.o
|
||||
OBJS-$(CONFIG_PIXBLOCKDSP) += pixblockdsp.o
|
||||
OBJS-$(CONFIG_QPELDSP) += qpeldsp.o
|
||||
OBJS-$(CONFIG_QSV) += qsv.o
|
||||
@@ -163,7 +156,6 @@ OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o
|
||||
OBJS-$(CONFIG_TEXTUREDSPENC) += texturedspenc.o
|
||||
OBJS-$(CONFIG_TPELDSP) += tpeldsp.o
|
||||
OBJS-$(CONFIG_VAAPI_ENCODE) += vaapi_encode.o
|
||||
OBJS-$(CONFIG_AV1_AMF_ENCODER) += amfenc_av1.o
|
||||
OBJS-$(CONFIG_VC1DSP) += vc1dsp.o
|
||||
OBJS-$(CONFIG_VIDEODSP) += videodsp.o
|
||||
OBJS-$(CONFIG_VP3DSP) += vp3dsp.o
|
||||
@@ -202,7 +194,7 @@ OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o ac3enc.o ac3tab.o \
|
||||
OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o kbdwin.o
|
||||
OBJS-$(CONFIG_AC3_MF_ENCODER) += mfenc.o mf_utils.o
|
||||
OBJS-$(CONFIG_ACELP_KELVIN_DECODER) += g729dec.o lsp.o celp_math.o celp_filters.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o g729postfilter.o
|
||||
OBJS-$(CONFIG_AGM_DECODER) += agm.o jpegquanttables.o
|
||||
OBJS-$(CONFIG_AGM_DECODER) += agm.o
|
||||
OBJS-$(CONFIG_AIC_DECODER) += aic.o
|
||||
OBJS-$(CONFIG_ALAC_DECODER) += alac.o alac_data.o alacdsp.o
|
||||
OBJS-$(CONFIG_ALAC_ENCODER) += alacenc.o alac_data.o
|
||||
@@ -219,10 +211,7 @@ OBJS-$(CONFIG_AMRWB_DECODER) += amrwbdec.o celp_filters.o \
|
||||
acelp_pitch_delay.o
|
||||
OBJS-$(CONFIG_AMV_ENCODER) += mjpegenc.o mjpegenc_common.o
|
||||
OBJS-$(CONFIG_ANM_DECODER) += anm.o
|
||||
OBJS-$(CONFIG_ANULL_DECODER) += null.o
|
||||
OBJS-$(CONFIG_ANULL_ENCODER) += null.o
|
||||
OBJS-$(CONFIG_ANSI_DECODER) += ansi.o cga_data.o
|
||||
OBJS-$(CONFIG_APAC_DECODER) += apac.o
|
||||
OBJS-$(CONFIG_APE_DECODER) += apedec.o
|
||||
OBJS-$(CONFIG_APTX_DECODER) += aptxdec.o aptx.o
|
||||
OBJS-$(CONFIG_APTX_ENCODER) += aptxenc.o aptx.o
|
||||
@@ -252,9 +241,6 @@ OBJS-$(CONFIG_AURA_DECODER) += cyuv.o
|
||||
OBJS-$(CONFIG_AURA2_DECODER) += aura.o
|
||||
OBJS-$(CONFIG_AV1_DECODER) += av1dec.o
|
||||
OBJS-$(CONFIG_AV1_CUVID_DECODER) += cuviddec.o
|
||||
OBJS-$(CONFIG_AV1_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_AV1_NVENC_ENCODER) += nvenc_av1.o nvenc.o
|
||||
OBJS-$(CONFIG_AV1_QSV_ENCODER) += qsvenc_av1.o
|
||||
OBJS-$(CONFIG_AVRN_DECODER) += avrndec.o
|
||||
OBJS-$(CONFIG_AVRP_DECODER) += r210dec.o
|
||||
OBJS-$(CONFIG_AVRP_ENCODER) += r210enc.o
|
||||
@@ -275,12 +261,10 @@ OBJS-$(CONFIG_BMP_DECODER) += bmp.o msrledec.o
|
||||
OBJS-$(CONFIG_BMP_ENCODER) += bmpenc.o
|
||||
OBJS-$(CONFIG_BMV_AUDIO_DECODER) += bmvaudio.o
|
||||
OBJS-$(CONFIG_BMV_VIDEO_DECODER) += bmvvideo.o
|
||||
OBJS-$(CONFIG_BONK_DECODER) += bonk.o
|
||||
OBJS-$(CONFIG_BRENDER_PIX_DECODER) += brenderpix.o
|
||||
OBJS-$(CONFIG_C93_DECODER) += c93.o
|
||||
OBJS-$(CONFIG_CAVS_DECODER) += cavs.o cavsdec.o cavsdsp.o \
|
||||
cavsdata.o
|
||||
OBJS-$(CONFIG_CBD2_DECODER) += dpcm.o
|
||||
OBJS-$(CONFIG_CCAPTION_DECODER) += ccaption_dec.o ass.o
|
||||
OBJS-$(CONFIG_CDGRAPHICS_DECODER) += cdgraphics.o
|
||||
OBJS-$(CONFIG_CDTOONS_DECODER) += cdtoons.o
|
||||
@@ -344,15 +328,15 @@ OBJS-$(CONFIG_EAMAD_DECODER) += eamad.o eaidct.o mpeg12.o \
|
||||
OBJS-$(CONFIG_EATGQ_DECODER) += eatgq.o eaidct.o
|
||||
OBJS-$(CONFIG_EATGV_DECODER) += eatgv.o
|
||||
OBJS-$(CONFIG_EATQI_DECODER) += eatqi.o eaidct.o mpeg12.o \
|
||||
mpeg12data.o
|
||||
mpeg12data.o mpegvideodata.o
|
||||
OBJS-$(CONFIG_EIGHTBPS_DECODER) += 8bps.o
|
||||
OBJS-$(CONFIG_EIGHTSVX_EXP_DECODER) += 8svx.o
|
||||
OBJS-$(CONFIG_EIGHTSVX_FIB_DECODER) += 8svx.o
|
||||
OBJS-$(CONFIG_ESCAPE124_DECODER) += escape124.o
|
||||
OBJS-$(CONFIG_ESCAPE130_DECODER) += escape130.o
|
||||
OBJS-$(CONFIG_EVRC_DECODER) += evrcdec.o acelp_vectors.o lsp.o
|
||||
OBJS-$(CONFIG_EXR_DECODER) += exr.o exrdsp.o half2float.o
|
||||
OBJS-$(CONFIG_EXR_ENCODER) += exrenc.o float2half.o
|
||||
OBJS-$(CONFIG_EXR_DECODER) += exr.o exrdsp.o
|
||||
OBJS-$(CONFIG_EXR_ENCODER) += exrenc.o
|
||||
OBJS-$(CONFIG_FASTAUDIO_DECODER) += fastaudio.o
|
||||
OBJS-$(CONFIG_FFV1_DECODER) += ffv1dec.o ffv1.o
|
||||
OBJS-$(CONFIG_FFV1_ENCODER) += ffv1enc.o ffv1.o
|
||||
@@ -360,8 +344,8 @@ OBJS-$(CONFIG_FFWAVESYNTH_DECODER) += ffwavesynth.o
|
||||
OBJS-$(CONFIG_FIC_DECODER) += fic.o
|
||||
OBJS-$(CONFIG_FITS_DECODER) += fitsdec.o fits.o
|
||||
OBJS-$(CONFIG_FITS_ENCODER) += fitsenc.o
|
||||
OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flacdsp.o flac.o
|
||||
OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flacencdsp.o
|
||||
OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o
|
||||
OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o
|
||||
OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o
|
||||
OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o
|
||||
OBJS-$(CONFIG_FLASHSV2_ENCODER) += flashsv2enc.o
|
||||
@@ -373,7 +357,6 @@ OBJS-$(CONFIG_FMVC_DECODER) += fmvc.o
|
||||
OBJS-$(CONFIG_FOURXM_DECODER) += 4xm.o
|
||||
OBJS-$(CONFIG_FRAPS_DECODER) += fraps.o
|
||||
OBJS-$(CONFIG_FRWU_DECODER) += frwu.o
|
||||
OBJS-$(CONFIG_FTR_DECODER) += ftr.o
|
||||
OBJS-$(CONFIG_G2M_DECODER) += g2meet.o elsdec.o mjpegdec_common.o
|
||||
OBJS-$(CONFIG_G723_1_DECODER) += g723_1dec.o g723_1.o \
|
||||
acelp_vectors.o celp_filters.o celp_math.o
|
||||
@@ -400,12 +383,11 @@ OBJS-$(CONFIG_H263_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
|
||||
OBJS-$(CONFIG_H264_DECODER) += h264dec.o h264_cabac.o h264_cavlc.o \
|
||||
h264_direct.o h264_loopfilter.o \
|
||||
h264_mb.o h264_picture.o \
|
||||
h264_refs.o \
|
||||
h264_refs.o h264_sei.o \
|
||||
h264_slice.o h264data.o h274.o
|
||||
OBJS-$(CONFIG_H264_AMF_ENCODER) += amfenc_h264.o
|
||||
OBJS-$(CONFIG_H264_CUVID_DECODER) += cuviddec.o
|
||||
OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_H264_MEDIACODEC_ENCODER) += mediacodecenc.o
|
||||
OBJS-$(CONFIG_H264_MF_ENCODER) += mfenc.o mf_utils.o
|
||||
OBJS-$(CONFIG_H264_MMAL_DECODER) += mmaldec.o
|
||||
OBJS-$(CONFIG_H264_NVENC_ENCODER) += nvenc_h264.o nvenc.o
|
||||
@@ -413,8 +395,7 @@ OBJS-$(CONFIG_H264_OMX_ENCODER) += omx.o
|
||||
OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec.o
|
||||
OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o
|
||||
OBJS-$(CONFIG_H264_RKMPP_DECODER) += rkmppdec.o
|
||||
OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o h264_levels.o \
|
||||
h2645data.o
|
||||
OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o h264_levels.o
|
||||
OBJS-$(CONFIG_H264_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
|
||||
OBJS-$(CONFIG_H264_V4L2M2M_DECODER) += v4l2_m2m_dec.o
|
||||
OBJS-$(CONFIG_H264_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
|
||||
@@ -422,8 +403,6 @@ OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o
|
||||
OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o
|
||||
OBJS-$(CONFIG_HCA_DECODER) += hcadec.o
|
||||
OBJS-$(CONFIG_HCOM_DECODER) += hcom.o
|
||||
OBJS-$(CONFIG_HDR_DECODER) += hdrdec.o
|
||||
OBJS-$(CONFIG_HDR_ENCODER) += hdrenc.o
|
||||
OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \
|
||||
hevc_cabac.o hevc_refs.o hevcpred.o \
|
||||
hevcdsp.o hevc_filter.o hevc_data.o \
|
||||
@@ -431,15 +410,13 @@ OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \
|
||||
OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o
|
||||
OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_HEVC_MEDIACODEC_ENCODER) += mediacodecenc.o
|
||||
OBJS-$(CONFIG_HEVC_MF_ENCODER) += mfenc.o mf_utils.o
|
||||
OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o nvenc.o
|
||||
OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec.o
|
||||
OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \
|
||||
hevc_data.o
|
||||
OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o
|
||||
OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level.o \
|
||||
h2645data.o
|
||||
OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level.o
|
||||
OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o
|
||||
OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
|
||||
OBJS-$(CONFIG_HEVC_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
|
||||
@@ -485,11 +462,10 @@ OBJS-$(CONFIG_MACE6_DECODER) += mace.o
|
||||
OBJS-$(CONFIG_MAGICYUV_DECODER) += magicyuv.o
|
||||
OBJS-$(CONFIG_MAGICYUV_ENCODER) += magicyuvenc.o
|
||||
OBJS-$(CONFIG_MDEC_DECODER) += mdec.o mpeg12.o mpeg12data.o
|
||||
OBJS-$(CONFIG_MEDIA100_DECODER) += mjpegbdec.o
|
||||
OBJS-$(CONFIG_METASOUND_DECODER) += metasound.o twinvq.o
|
||||
OBJS-$(CONFIG_METASOUND_DECODER) += metasound.o metasound_data.o \
|
||||
twinvq.o
|
||||
OBJS-$(CONFIG_MICRODVD_DECODER) += microdvddec.o ass.o
|
||||
OBJS-$(CONFIG_MIMIC_DECODER) += mimic.o
|
||||
OBJS-$(CONFIG_MISC4_DECODER) += misc4.o
|
||||
OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpegdec_common.o
|
||||
OBJS-$(CONFIG_MJPEG_QSV_DECODER) += qsvdec.o
|
||||
OBJS-$(CONFIG_MJPEG_ENCODER) += mjpegenc.o mjpegenc_common.o \
|
||||
@@ -538,7 +514,7 @@ OBJS-$(CONFIG_MPEG2_CUVID_DECODER) += cuviddec.o
|
||||
OBJS-$(CONFIG_MPEG2_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_MPEG2_VAAPI_ENCODER) += vaapi_encode_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_V4L2M2M_DECODER) += v4l2_m2m_dec.o
|
||||
OBJS-$(CONFIG_MPEG4_DECODER) += mpeg4videodsp.o xvididct.o
|
||||
OBJS-$(CONFIG_MPEG4_DECODER) += xvididct.o
|
||||
OBJS-$(CONFIG_MPEG4_ENCODER) += mpeg4videoenc.o
|
||||
OBJS-$(CONFIG_MPEG4_CUVID_DECODER) += cuviddec.o
|
||||
OBJS-$(CONFIG_MPEG4_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
@@ -548,6 +524,11 @@ OBJS-$(CONFIG_MPEG4_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
|
||||
OBJS-$(CONFIG_MPL2_DECODER) += mpl2dec.o ass.o
|
||||
OBJS-$(CONFIG_MSA1_DECODER) += mss3.o
|
||||
OBJS-$(CONFIG_MSCC_DECODER) += mscc.o
|
||||
OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4enc.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_MSMPEG4V3_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4enc.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_MSNSIREN_DECODER) += siren.o
|
||||
OBJS-$(CONFIG_MSP2_DECODER) += msp2dec.o
|
||||
OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o
|
||||
@@ -567,13 +548,13 @@ OBJS-$(CONFIG_MXPEG_DECODER) += mxpegdec.o
|
||||
OBJS-$(CONFIG_NELLYMOSER_DECODER) += nellymoserdec.o nellymoser.o
|
||||
OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o
|
||||
OBJS-$(CONFIG_NOTCHLC_DECODER) += notchlc.o
|
||||
OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o jpegquanttables.o
|
||||
OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o
|
||||
OBJS-$(CONFIG_ON2AVC_DECODER) += on2avc.o on2avcdata.o
|
||||
OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opusdec_celt.o opus_celt.o \
|
||||
OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opus.o opus_celt.o opus_rc.o \
|
||||
opus_pvq.o opus_silk.o opustab.o vorbis_data.o \
|
||||
opusdsp.o opus_parse.o opus_rc.o
|
||||
OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opusenc_psy.o opus_celt.o \
|
||||
opus_pvq.o opus_rc.o opustab.o
|
||||
opusdsp.o
|
||||
OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opus.o opus_rc.o opustab.o opus_pvq.o \
|
||||
opusenc_psy.o vorbis_data.o
|
||||
OBJS-$(CONFIG_PAF_AUDIO_DECODER) += pafaudio.o
|
||||
OBJS-$(CONFIG_PAF_VIDEO_DECODER) += pafvideo.o
|
||||
OBJS-$(CONFIG_PAM_DECODER) += pnmdec.o pnm.o
|
||||
@@ -590,8 +571,8 @@ OBJS-$(CONFIG_PGMYUV_DECODER) += pnmdec.o pnm.o
|
||||
OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o
|
||||
OBJS-$(CONFIG_PGSSUB_DECODER) += pgssubdec.o
|
||||
OBJS-$(CONFIG_PGX_DECODER) += pgxdec.o
|
||||
OBJS-$(CONFIG_PHM_DECODER) += pnmdec.o pnm.o half2float.o
|
||||
OBJS-$(CONFIG_PHM_ENCODER) += pnmenc.o float2half.o
|
||||
OBJS-$(CONFIG_PHM_DECODER) += pnmdec.o pnm.o
|
||||
OBJS-$(CONFIG_PHM_ENCODER) += pnmenc.o
|
||||
OBJS-$(CONFIG_PHOTOCD_DECODER) += photocd.o
|
||||
OBJS-$(CONFIG_PICTOR_DECODER) += pictordec.o cga_data.o
|
||||
OBJS-$(CONFIG_PIXLET_DECODER) += pixlet.o
|
||||
@@ -631,7 +612,6 @@ OBJS-$(CONFIG_RASC_DECODER) += rasc.o
|
||||
OBJS-$(CONFIG_RAWVIDEO_DECODER) += rawdec.o
|
||||
OBJS-$(CONFIG_RAWVIDEO_ENCODER) += rawenc.o
|
||||
OBJS-$(CONFIG_REALTEXT_DECODER) += realtextdec.o ass.o
|
||||
OBJS-$(CONFIG_RKA_DECODER) += rka.o
|
||||
OBJS-$(CONFIG_RL2_DECODER) += rl2.o
|
||||
OBJS-$(CONFIG_ROQ_DECODER) += roqvideodec.o roqvideo.o
|
||||
OBJS-$(CONFIG_ROQ_ENCODER) += roqvideoenc.o roqvideo.o elbg.o
|
||||
@@ -676,8 +656,7 @@ OBJS-$(CONFIG_SOL_DPCM_DECODER) += dpcm.o
|
||||
OBJS-$(CONFIG_SONIC_DECODER) += sonic.o
|
||||
OBJS-$(CONFIG_SONIC_ENCODER) += sonic.o
|
||||
OBJS-$(CONFIG_SONIC_LS_ENCODER) += sonic.o
|
||||
OBJS-$(CONFIG_SPEEDHQ_DECODER) += speedhqdec.o speedhq.o mpeg12.o \
|
||||
mpeg12data.o
|
||||
OBJS-$(CONFIG_SPEEDHQ_DECODER) += speedhq.o mpeg12.o mpeg12data.o simple_idct.o
|
||||
OBJS-$(CONFIG_SPEEDHQ_ENCODER) += speedhq.o mpeg12data.o mpeg12enc.o speedhqenc.o
|
||||
OBJS-$(CONFIG_SPEEX_DECODER) += speexdec.o
|
||||
OBJS-$(CONFIG_SP5X_DECODER) += sp5xdec.o
|
||||
@@ -720,7 +699,7 @@ OBJS-$(CONFIG_TSCC2_DECODER) += tscc2.o
|
||||
OBJS-$(CONFIG_TTA_DECODER) += tta.o ttadata.o ttadsp.o
|
||||
OBJS-$(CONFIG_TTA_ENCODER) += ttaenc.o ttaencdsp.o ttadata.o
|
||||
OBJS-$(CONFIG_TTML_ENCODER) += ttmlenc.o ass_split.o
|
||||
OBJS-$(CONFIG_TWINVQ_DECODER) += twinvqdec.o twinvq.o
|
||||
OBJS-$(CONFIG_TWINVQ_DECODER) += twinvqdec.o twinvq.o metasound_data.o
|
||||
OBJS-$(CONFIG_TXD_DECODER) += txd.o
|
||||
OBJS-$(CONFIG_ULTI_DECODER) += ulti.o
|
||||
OBJS-$(CONFIG_UTVIDEO_DECODER) += utvideodec.o utvideodsp.o
|
||||
@@ -740,7 +719,8 @@ OBJS-$(CONFIG_VBN_ENCODER) += vbnenc.o
|
||||
OBJS-$(CONFIG_VBLE_DECODER) += vble.o
|
||||
OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1_block.o vc1_loopfilter.o \
|
||||
vc1_mc.o vc1_pred.o vc1.o vc1data.o \
|
||||
msmpeg4_vc1_data.o wmv2data.o
|
||||
msmpeg4dec.o msmpeg4.o msmpeg4data.o \
|
||||
wmv2dsp.o wmv2data.o
|
||||
OBJS-$(CONFIG_VC1_CUVID_DECODER) += cuviddec.o
|
||||
OBJS-$(CONFIG_VC1_MMAL_DECODER) += mmaldec.o
|
||||
OBJS-$(CONFIG_VC1_QSV_DECODER) += qsvdec.o
|
||||
@@ -750,18 +730,16 @@ OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o
|
||||
OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdaudio.o
|
||||
OBJS-$(CONFIG_VMDVIDEO_DECODER) += vmdvideo.o
|
||||
OBJS-$(CONFIG_VMNC_DECODER) += vmnc.o
|
||||
OBJS-$(CONFIG_VNULL_DECODER) += null.o
|
||||
OBJS-$(CONFIG_VNULL_ENCODER) += null.o
|
||||
OBJS-$(CONFIG_VORBIS_DECODER) += vorbisdec.o vorbisdsp.o vorbis.o \
|
||||
vorbis_data.o
|
||||
OBJS-$(CONFIG_VORBIS_ENCODER) += vorbisenc.o vorbis.o \
|
||||
vorbis_data.o
|
||||
OBJS-$(CONFIG_VP3_DECODER) += vp3.o jpegquanttables.o
|
||||
OBJS-$(CONFIG_VP5_DECODER) += vp5.o vp56.o vp56data.o vpx_rac.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 \
|
||||
vp6dsp.o vpx_rac.o
|
||||
OBJS-$(CONFIG_VP7_DECODER) += vp8.o vpx_rac.o
|
||||
OBJS-$(CONFIG_VP8_DECODER) += vp8.o vpx_rac.o
|
||||
vp6dsp.o vp56rac.o
|
||||
OBJS-$(CONFIG_VP7_DECODER) += vp8.o vp56rac.o
|
||||
OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp56rac.o
|
||||
OBJS-$(CONFIG_VP8_CUVID_DECODER) += cuviddec.o
|
||||
OBJS-$(CONFIG_VP8_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_VP8_QSV_DECODER) += qsvdec.o
|
||||
@@ -770,7 +748,7 @@ OBJS-$(CONFIG_VP8_VAAPI_ENCODER) += vaapi_encode_vp8.o
|
||||
OBJS-$(CONFIG_VP8_V4L2M2M_DECODER) += v4l2_m2m_dec.o
|
||||
OBJS-$(CONFIG_VP8_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
|
||||
OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o vp9lpf.o vp9recon.o \
|
||||
vp9block.o vp9prob.o vp9mvs.o vpx_rac.o \
|
||||
vp9block.o vp9prob.o vp9mvs.o vp56rac.o \
|
||||
vp9dsp_8bpp.o vp9dsp_10bpp.o vp9dsp_12bpp.o
|
||||
OBJS-$(CONFIG_VP9_CUVID_DECODER) += cuviddec.o
|
||||
OBJS-$(CONFIG_VP9_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
@@ -780,13 +758,8 @@ OBJS-$(CONFIG_VP9_QSV_ENCODER) += qsvenc_vp9.o
|
||||
OBJS-$(CONFIG_VPLAYER_DECODER) += textdec.o ass.o
|
||||
OBJS-$(CONFIG_VP9_V4L2M2M_DECODER) += v4l2_m2m_dec.o
|
||||
OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o
|
||||
OBJS-$(CONFIG_VQC_DECODER) += vqcdec.o
|
||||
OBJS-$(CONFIG_WADY_DPCM_DECODER) += dpcm.o
|
||||
OBJS-$(CONFIG_WAVARC_DECODER) += wavarc.o
|
||||
OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o wavpackdata.o dsd.o
|
||||
OBJS-$(CONFIG_WAVPACK_ENCODER) += wavpackdata.o wavpackenc.o
|
||||
OBJS-$(CONFIG_WBMP_DECODER) += wbmpdec.o
|
||||
OBJS-$(CONFIG_WBMP_ENCODER) += wbmpenc.o
|
||||
OBJS-$(CONFIG_WCMV_DECODER) += wcmv.o
|
||||
OBJS-$(CONFIG_WEBP_DECODER) += webp.o
|
||||
OBJS-$(CONFIG_WEBVTT_DECODER) += webvttdec.o ass.o
|
||||
@@ -800,8 +773,12 @@ OBJS-$(CONFIG_WMAV2_ENCODER) += wmaenc.o wma.o wma_common.o aactab.o
|
||||
OBJS-$(CONFIG_WMAVOICE_DECODER) += wmavoice.o \
|
||||
celp_filters.o \
|
||||
acelp_vectors.o acelp_filters.o
|
||||
OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o wmv2data.o
|
||||
OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o wmv2data.o
|
||||
OBJS-$(CONFIG_WMV1_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_WMV1_ENCODER) += msmpeg4enc.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o wmv2data.o \
|
||||
msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o wmv2data.o \
|
||||
msmpeg4.o msmpeg4enc.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o
|
||||
OBJS-$(CONFIG_WRAPPED_AVFRAME_DECODER) += wrapped_avframe.o
|
||||
OBJS-$(CONFIG_WRAPPED_AVFRAME_ENCODER) += wrapped_avframe.o
|
||||
@@ -965,7 +942,6 @@ OBJS-$(CONFIG_ADPCM_THP_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_THP_LE_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_VIMA_DECODER) += vima.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_XA_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_XMD_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_ZORK_DECODER) += adpcm.o adpcm_data.o
|
||||
@@ -1076,8 +1052,8 @@ OBJS-$(CONFIG_ALAC_AT_ENCODER) += audiotoolboxenc.o
|
||||
OBJS-$(CONFIG_ILBC_AT_ENCODER) += audiotoolboxenc.o
|
||||
OBJS-$(CONFIG_PCM_ALAW_AT_ENCODER) += audiotoolboxenc.o
|
||||
OBJS-$(CONFIG_PCM_MULAW_AT_ENCODER) += audiotoolboxenc.o
|
||||
OBJS-$(CONFIG_LIBAOM_AV1_DECODER) += libaomdec.o libaom.o
|
||||
OBJS-$(CONFIG_LIBAOM_AV1_ENCODER) += libaomenc.o libaom.o
|
||||
OBJS-$(CONFIG_LIBAOM_AV1_DECODER) += libaomdec.o
|
||||
OBJS-$(CONFIG_LIBAOM_AV1_ENCODER) += libaomenc.o
|
||||
OBJS-$(CONFIG_LIBARIBB24_DECODER) += libaribb24.o ass.o
|
||||
OBJS-$(CONFIG_LIBCELT_DECODER) += libcelt_dec.o
|
||||
OBJS-$(CONFIG_LIBCODEC2_DECODER) += libcodec2.o
|
||||
@@ -1138,7 +1114,7 @@ OBJS-$(CONFIG_AAC_LATM_PARSER) += latm_parser.o
|
||||
OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o
|
||||
OBJS-$(CONFIG_AC3_PARSER) += aac_ac3_parser.o ac3tab.o \
|
||||
ac3_channel_layout_tab.o
|
||||
OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o
|
||||
OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o
|
||||
OBJS-$(CONFIG_AMR_PARSER) += amr_parser.o
|
||||
OBJS-$(CONFIG_AV1_PARSER) += av1_parser.o
|
||||
OBJS-$(CONFIG_AVS2_PARSER) += avs2.o avs2_parser.o
|
||||
@@ -1158,19 +1134,16 @@ OBJS-$(CONFIG_DVBSUB_PARSER) += dvbsub_parser.o
|
||||
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
|
||||
OBJS-$(CONFIG_FTR_PARSER) += ftr_parser.o
|
||||
OBJS-$(CONFIG_G723_1_PARSER) += g723_1_parser.o
|
||||
OBJS-$(CONFIG_G729_PARSER) += g729_parser.o
|
||||
OBJS-$(CONFIG_GIF_PARSER) += gif_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 h264data.o
|
||||
OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264_sei.o h264data.o
|
||||
OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o hevc_data.o
|
||||
OBJS-$(CONFIG_HDR_PARSER) += hdr_parser.o
|
||||
OBJS-$(CONFIG_IPU_PARSER) += ipu_parser.o
|
||||
OBJS-$(CONFIG_JPEG2000_PARSER) += jpeg2000_parser.o
|
||||
OBJS-$(CONFIG_MISC4_PARSER) += misc4_parser.o
|
||||
OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg_parser.o
|
||||
OBJS-$(CONFIG_MLP_PARSER) += mlp_parse.o mlp_parser.o mlp.o
|
||||
OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \
|
||||
@@ -1179,8 +1152,8 @@ OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \
|
||||
OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o
|
||||
OBJS-$(CONFIG_MPEGVIDEO_PARSER) += mpegvideo_parser.o \
|
||||
mpeg12.o mpeg12data.o
|
||||
OBJS-$(CONFIG_OPUS_PARSER) += opus_parser.o opus_parse.o \
|
||||
vorbis_data.o
|
||||
OBJS-$(CONFIG_OPUS_PARSER) += opus_parser.o opus.o opustab.o \
|
||||
opus_rc.o vorbis_data.o
|
||||
OBJS-$(CONFIG_PNG_PARSER) += png_parser.o
|
||||
OBJS-$(CONFIG_PNM_PARSER) += pnm_parser.o pnm.o
|
||||
OBJS-$(CONFIG_QOI_PARSER) += qoi_parser.o
|
||||
@@ -1190,14 +1163,13 @@ OBJS-$(CONFIG_SBC_PARSER) += sbc_parser.o
|
||||
OBJS-$(CONFIG_SIPR_PARSER) += sipr_parser.o
|
||||
OBJS-$(CONFIG_TAK_PARSER) += tak_parser.o tak.o
|
||||
OBJS-$(CONFIG_VC1_PARSER) += vc1_parser.o vc1.o vc1data.o \
|
||||
wmv2data.o
|
||||
simple_idct.o wmv2data.o
|
||||
OBJS-$(CONFIG_VP3_PARSER) += vp3_parser.o
|
||||
OBJS-$(CONFIG_VP8_PARSER) += vp8_parser.o
|
||||
OBJS-$(CONFIG_VP9_PARSER) += vp9_parser.o
|
||||
OBJS-$(CONFIG_WEBP_PARSER) += webp_parser.o
|
||||
OBJS-$(CONFIG_XBM_PARSER) += xbm_parser.o
|
||||
OBJS-$(CONFIG_XMA_PARSER) += xma_parser.o
|
||||
OBJS-$(CONFIG_XWD_PARSER) += xwd_parser.o
|
||||
|
||||
# bitstream filters
|
||||
OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o
|
||||
@@ -1207,22 +1179,18 @@ OBJS-$(CONFIG_AV1_FRAME_SPLIT_BSF) += av1_frame_split_bsf.o
|
||||
OBJS-$(CONFIG_CHOMP_BSF) += chomp_bsf.o
|
||||
OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o
|
||||
OBJS-$(CONFIG_DCA_CORE_BSF) += dca_core_bsf.o
|
||||
OBJS-$(CONFIG_DTS2PTS_BSF) += dts2pts_bsf.o
|
||||
OBJS-$(CONFIG_DV_ERROR_MARKER_BSF) += dv_error_marker_bsf.o
|
||||
OBJS-$(CONFIG_EAC3_CORE_BSF) += eac3_core_bsf.o
|
||||
OBJS-$(CONFIG_EXTRACT_EXTRADATA_BSF) += extract_extradata_bsf.o \
|
||||
av1_parse.o h2645_parse.o
|
||||
OBJS-$(CONFIG_FILTER_UNITS_BSF) += filter_units_bsf.o
|
||||
OBJS-$(CONFIG_H264_METADATA_BSF) += h264_metadata_bsf.o h264_levels.o \
|
||||
h2645data.o
|
||||
OBJS-$(CONFIG_H264_METADATA_BSF) += h264_metadata_bsf.o h264_levels.o
|
||||
OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += h264_mp4toannexb_bsf.o
|
||||
OBJS-$(CONFIG_H264_REDUNDANT_PPS_BSF) += h264_redundant_pps_bsf.o
|
||||
OBJS-$(CONFIG_HAPQA_EXTRACT_BSF) += hapqa_extract_bsf.o hap.o
|
||||
OBJS-$(CONFIG_HEVC_METADATA_BSF) += h265_metadata_bsf.o h265_profile_level.o \
|
||||
h2645data.o
|
||||
OBJS-$(CONFIG_HEVC_METADATA_BSF) += h265_metadata_bsf.o h265_profile_level.o
|
||||
OBJS-$(CONFIG_HEVC_MP4TOANNEXB_BSF) += hevc_mp4toannexb_bsf.o
|
||||
OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o
|
||||
OBJS-$(CONFIG_MEDIA100_TO_MJPEGB_BSF) += media100_to_mjpegb_bsf.o
|
||||
OBJS-$(CONFIG_MJPEG2JPEG_BSF) += mjpeg2jpeg_bsf.o
|
||||
OBJS-$(CONFIG_MJPEGA_DUMP_HEADER_BSF) += mjpega_dump_header_bsf.o
|
||||
OBJS-$(CONFIG_MPEG4_UNPACK_BFRAMES_BSF) += mpeg4_unpack_bframes_bsf.o
|
||||
@@ -1253,7 +1221,7 @@ OBJS-$(HAVE_THREADS) += pthread.o pthread_slice.o pthread_fram
|
||||
OBJS-$(CONFIG_FRAME_THREAD_ENCODER) += frame_thread_encoder.o
|
||||
|
||||
# Windows resource file
|
||||
SHLIBOBJS-$(HAVE_GNU_WINDRES) += avcodecres.o
|
||||
SLIBOBJS-$(HAVE_GNU_WINDRES) += avcodecres.o
|
||||
|
||||
SKIPHEADERS += %_tablegen.h \
|
||||
%_tables.h \
|
||||
@@ -1263,15 +1231,12 @@ SKIPHEADERS += %_tablegen.h \
|
||||
aaccoder_trellis.h \
|
||||
aacenc_quantization.h \
|
||||
aacenc_quantization_misc.h \
|
||||
bitstream_template.h \
|
||||
$(ARCH)/vpx_arith.h \
|
||||
$(ARCH)/vp56_arith.h \
|
||||
|
||||
SKIPHEADERS-$(CONFIG_AMF) += amfenc.h
|
||||
SKIPHEADERS-$(CONFIG_D3D11VA) += d3d11va.h dxva2_internal.h
|
||||
SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h
|
||||
SKIPHEADERS-$(CONFIG_JNI) += ffjni.h
|
||||
SKIPHEADERS-$(CONFIG_LCMS2) += fflcms2.h
|
||||
SKIPHEADERS-$(CONFIG_LIBAOM) += libaom.h
|
||||
SKIPHEADERS-$(CONFIG_LIBJXL) += libjxl.h
|
||||
SKIPHEADERS-$(CONFIG_LIBVPX) += libvpx.h
|
||||
SKIPHEADERS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.h
|
||||
@@ -1286,12 +1251,9 @@ SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_decode.h vaapi_hevc.h vaapi_enco
|
||||
SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h
|
||||
SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.h vt_internal.h
|
||||
SKIPHEADERS-$(CONFIG_V4L2_M2M) += v4l2_buffers.h v4l2_context.h v4l2_m2m.h
|
||||
SKIPHEADERS-$(CONFIG_ZLIB) += zlib_wrapper.h
|
||||
|
||||
TESTPROGS = avcodec \
|
||||
avpacket \
|
||||
bitstream_be \
|
||||
bitstream_le \
|
||||
celp_math \
|
||||
codec_desc \
|
||||
htmlsubtitles \
|
||||
|
||||
@@ -76,7 +76,7 @@ static void to_meta_with_crop(AVCodecContext *avctx,
|
||||
int luma = 0;
|
||||
int height = FFMIN(avctx->height, C64YRES);
|
||||
int width = FFMIN(avctx->width , C64XRES);
|
||||
const uint8_t *src = p->data[0];
|
||||
uint8_t *src = p->data[0];
|
||||
|
||||
for (blocky = 0; blocky < C64YRES; blocky += 8) {
|
||||
for (blockx = 0; blockx < C64XRES; blockx += 8) {
|
||||
@@ -395,7 +395,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
||||
#if CONFIG_A64MULTI_ENCODER
|
||||
const FFCodec ff_a64multi_encoder = {
|
||||
.p.name = "a64multi",
|
||||
CODEC_LONG_NAME("Multicolor charset for Commodore 64"),
|
||||
.p.long_name = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64"),
|
||||
.p.type = AVMEDIA_TYPE_VIDEO,
|
||||
.p.id = AV_CODEC_ID_A64_MULTI,
|
||||
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
|
||||
@@ -404,13 +404,13 @@ const FFCodec ff_a64multi_encoder = {
|
||||
FF_CODEC_ENCODE_CB(a64multi_encode_frame),
|
||||
.close = a64multi_close_encoder,
|
||||
.p.pix_fmts = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
|
||||
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
|
||||
};
|
||||
#endif
|
||||
#if CONFIG_A64MULTI5_ENCODER
|
||||
const FFCodec ff_a64multi5_encoder = {
|
||||
.p.name = "a64multi5",
|
||||
CODEC_LONG_NAME("Multicolor charset for Commodore 64, extended with 5th color (colram)"),
|
||||
.p.long_name = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64, extended with 5th color (colram)"),
|
||||
.p.type = AVMEDIA_TYPE_VIDEO,
|
||||
.p.id = AV_CODEC_ID_A64_MULTI5,
|
||||
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
|
||||
@@ -419,6 +419,6 @@ const FFCodec ff_a64multi5_encoder = {
|
||||
FF_CODEC_ENCODE_CB(a64multi_encode_frame),
|
||||
.close = a64multi_close_encoder,
|
||||
.p.pix_fmts = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
|
||||
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -36,8 +36,11 @@
|
||||
#include "libavutil/float_dsp.h"
|
||||
#include "libavutil/fixed_dsp.h"
|
||||
#include "libavutil/mem_internal.h"
|
||||
#include "libavutil/tx.h"
|
||||
#include "avcodec.h"
|
||||
#if !USE_FIXED
|
||||
#include "mdct15.h"
|
||||
#endif
|
||||
#include "fft.h"
|
||||
#include "mpeg4audio.h"
|
||||
#include "sbr.h"
|
||||
|
||||
@@ -323,24 +326,16 @@ struct AACContext {
|
||||
* @name Computed / set up during initialization
|
||||
* @{
|
||||
*/
|
||||
AVTXContext *mdct120;
|
||||
AVTXContext *mdct128;
|
||||
AVTXContext *mdct480;
|
||||
AVTXContext *mdct512;
|
||||
AVTXContext *mdct960;
|
||||
AVTXContext *mdct1024;
|
||||
AVTXContext *mdct_ltp;
|
||||
|
||||
av_tx_fn mdct120_fn;
|
||||
av_tx_fn mdct128_fn;
|
||||
av_tx_fn mdct480_fn;
|
||||
av_tx_fn mdct512_fn;
|
||||
av_tx_fn mdct960_fn;
|
||||
av_tx_fn mdct1024_fn;
|
||||
av_tx_fn mdct_ltp_fn;
|
||||
FFTContext mdct;
|
||||
FFTContext mdct_small;
|
||||
FFTContext mdct_ld;
|
||||
FFTContext mdct_ltp;
|
||||
#if USE_FIXED
|
||||
AVFixedDSPContext *fdsp;
|
||||
#else
|
||||
MDCT15Context *mdct120;
|
||||
MDCT15Context *mdct480;
|
||||
MDCT15Context *mdct960;
|
||||
AVFloatDSPContext *fdsp;
|
||||
#endif /* USE_FIXED */
|
||||
int random_state;
|
||||
@@ -371,7 +366,6 @@ struct AACContext {
|
||||
int warned_960_sbr;
|
||||
unsigned warned_71_wide;
|
||||
int warned_gain_control;
|
||||
int warned_he_aac_mono;
|
||||
|
||||
/* aacdec functions pointers */
|
||||
void (*imdct_and_windowing)(AACContext *ac, SingleChannelElement *sce);
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
#include "libavutil/common.h"
|
||||
#include "parser.h"
|
||||
#include "aac_ac3_parser.h"
|
||||
#include "ac3_parser_internal.h"
|
||||
#include "adts_header.h"
|
||||
|
||||
int ff_aac_ac3_parse(AVCodecParserContext *s1,
|
||||
AVCodecContext *avctx,
|
||||
@@ -40,131 +38,83 @@ int ff_aac_ac3_parse(AVCodecParserContext *s1,
|
||||
int new_frame_start;
|
||||
int got_frame = 0;
|
||||
|
||||
if (s1->flags & PARSER_FLAG_COMPLETE_FRAMES) {
|
||||
i = buf_size;
|
||||
got_frame = 1;
|
||||
} else {
|
||||
get_next:
|
||||
i=END_NOT_FOUND;
|
||||
if(s->remaining_size <= buf_size){
|
||||
if(s->remaining_size && !s->need_next_header){
|
||||
i= s->remaining_size;
|
||||
s->remaining_size = 0;
|
||||
}else{ //we need a header first
|
||||
len=0;
|
||||
for(i=s->remaining_size; i<buf_size; i++){
|
||||
s->state = (s->state<<8) + buf[i];
|
||||
if((len=s->sync(s->state, &s->need_next_header, &new_frame_start)))
|
||||
break;
|
||||
i=END_NOT_FOUND;
|
||||
if(s->remaining_size <= buf_size){
|
||||
if(s->remaining_size && !s->need_next_header){
|
||||
i= s->remaining_size;
|
||||
s->remaining_size = 0;
|
||||
}else{ //we need a header first
|
||||
len=0;
|
||||
for(i=s->remaining_size; i<buf_size; i++){
|
||||
s->state = (s->state<<8) + buf[i];
|
||||
if((len=s->sync(s->state, s, &s->need_next_header, &new_frame_start)))
|
||||
break;
|
||||
}
|
||||
if(len<=0){
|
||||
i=END_NOT_FOUND;
|
||||
}else{
|
||||
got_frame = 1;
|
||||
s->state=0;
|
||||
i-= s->header_size -1;
|
||||
s->remaining_size = len;
|
||||
if(!new_frame_start || pc->index+i<=0){
|
||||
s->remaining_size += i;
|
||||
goto get_next;
|
||||
}
|
||||
if(len<=0){
|
||||
i=END_NOT_FOUND;
|
||||
}else{
|
||||
got_frame = 1;
|
||||
s->state=0;
|
||||
i-= s->header_size -1;
|
||||
s->remaining_size = len;
|
||||
if(!new_frame_start || pc->index+i<=0){
|
||||
s->remaining_size += i;
|
||||
goto get_next;
|
||||
}
|
||||
else if (i < 0) {
|
||||
s->remaining_size += i;
|
||||
}
|
||||
else if (i < 0) {
|
||||
s->remaining_size += i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ff_combine_frame(pc, i, &buf, &buf_size)<0){
|
||||
s->remaining_size -= FFMIN(s->remaining_size, buf_size);
|
||||
*poutbuf = NULL;
|
||||
*poutbuf_size = 0;
|
||||
return buf_size;
|
||||
}
|
||||
if(ff_combine_frame(pc, i, &buf, &buf_size)<0){
|
||||
s->remaining_size -= FFMIN(s->remaining_size, buf_size);
|
||||
*poutbuf = NULL;
|
||||
*poutbuf_size = 0;
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
*poutbuf = buf;
|
||||
*poutbuf_size = buf_size;
|
||||
|
||||
if (got_frame) {
|
||||
int bit_rate;
|
||||
/* update codec info */
|
||||
if(s->codec_id)
|
||||
avctx->codec_id = s->codec_id;
|
||||
|
||||
if (got_frame) {
|
||||
/* Due to backwards compatible HE-AAC the sample rate, channel count,
|
||||
and total number of samples found in an AAC ADTS header are not
|
||||
reliable. Bit rate is still accurate because the total frame
|
||||
duration in seconds is still correct (as is the number of bits in
|
||||
the frame). */
|
||||
if (avctx->codec_id != AV_CODEC_ID_AAC) {
|
||||
#if CONFIG_AC3_PARSER
|
||||
AC3HeaderInfo hdr, *phrd = &hdr;
|
||||
int offset = ff_ac3_find_syncword(buf, buf_size);
|
||||
|
||||
if (offset < 0)
|
||||
return i;
|
||||
|
||||
buf += offset;
|
||||
buf_size -= offset;
|
||||
while (buf_size > 0) {
|
||||
int ret = avpriv_ac3_parse_header(&phrd, buf, buf_size);
|
||||
|
||||
if (ret < 0 || hdr.frame_size > buf_size)
|
||||
return i;
|
||||
|
||||
if (buf_size > hdr.frame_size) {
|
||||
buf += hdr.frame_size;
|
||||
buf_size -= hdr.frame_size;
|
||||
continue;
|
||||
}
|
||||
/* Check for false positives since the syncword is not enough.
|
||||
See section 6.1.2 of A/52. */
|
||||
if (av_crc(s->crc_ctx, 0, buf + 2, hdr.frame_size - 2))
|
||||
return i;
|
||||
break;
|
||||
}
|
||||
|
||||
avctx->sample_rate = hdr.sample_rate;
|
||||
|
||||
if (hdr.bitstream_id > 10)
|
||||
avctx->codec_id = AV_CODEC_ID_EAC3;
|
||||
|
||||
avctx->sample_rate = s->sample_rate;
|
||||
if (!CONFIG_EAC3_DECODER || avctx->codec_id != AV_CODEC_ID_EAC3) {
|
||||
av_channel_layout_uninit(&avctx->ch_layout);
|
||||
if (hdr.channel_layout) {
|
||||
av_channel_layout_from_mask(&avctx->ch_layout, hdr.channel_layout);
|
||||
if (s->channel_layout) {
|
||||
av_channel_layout_from_mask(&avctx->ch_layout, s->channel_layout);
|
||||
} else {
|
||||
avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
|
||||
avctx->ch_layout.nb_channels = hdr.channels;
|
||||
avctx->ch_layout.nb_channels = s->channels;
|
||||
}
|
||||
#if FF_API_OLD_CHANNEL_LAYOUT
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
avctx->channels = avctx->ch_layout.nb_channels;
|
||||
avctx->channel_layout = hdr.channel_layout;
|
||||
avctx->channel_layout = s->channel_layout;
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
}
|
||||
s1->duration = hdr.num_blocks * 256;
|
||||
avctx->audio_service_type = hdr.bitstream_mode;
|
||||
if (hdr.bitstream_mode == 0x7 && hdr.channels > 1)
|
||||
avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
|
||||
bit_rate = hdr.bit_rate;
|
||||
#endif
|
||||
} else {
|
||||
#if CONFIG_AAC_PARSER
|
||||
AACADTSHeaderInfo hdr, *phrd = &hdr;
|
||||
int ret = avpriv_adts_header_parse(&phrd, buf, buf_size);
|
||||
|
||||
if (ret < 0)
|
||||
return i;
|
||||
|
||||
bit_rate = hdr.bit_rate;
|
||||
#endif
|
||||
s1->duration = s->samples;
|
||||
avctx->audio_service_type = s->service_type;
|
||||
}
|
||||
|
||||
/* Calculate the average bit rate */
|
||||
s->frame_number++;
|
||||
if (!CONFIG_EAC3_DECODER || avctx->codec_id != AV_CODEC_ID_EAC3) {
|
||||
avctx->bit_rate +=
|
||||
(bit_rate - avctx->bit_rate) / s->frame_number;
|
||||
(s->bit_rate - avctx->bit_rate) / s->frame_number;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#define AVCODEC_AAC_AC3_PARSER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "libavutil/crc.h"
|
||||
#include "avcodec.h"
|
||||
#include "parser.h"
|
||||
|
||||
@@ -40,15 +39,24 @@ typedef enum {
|
||||
|
||||
typedef struct AACAC3ParseContext {
|
||||
ParseContext pc;
|
||||
int frame_size;
|
||||
int header_size;
|
||||
int (*sync)(uint64_t state, int *need_next_header, int *new_frame_start);
|
||||
int (*sync)(uint64_t state, struct AACAC3ParseContext *hdr_info,
|
||||
int *need_next_header, int *new_frame_start);
|
||||
|
||||
int channels;
|
||||
int sample_rate;
|
||||
int bit_rate;
|
||||
int samples;
|
||||
uint64_t channel_layout;
|
||||
int service_type;
|
||||
|
||||
const AVCRC *crc_ctx;
|
||||
int remaining_size;
|
||||
uint64_t state;
|
||||
|
||||
int need_next_header;
|
||||
int frame_number;
|
||||
enum AVCodecID codec_id;
|
||||
} AACAC3ParseContext;
|
||||
|
||||
int ff_aac_ac3_parse(AVCodecParserContext *s1,
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "put_bits.h"
|
||||
#include "get_bits.h"
|
||||
#include "mpeg4audio.h"
|
||||
#include "mpeg4audio_copy_pce.h"
|
||||
|
||||
typedef struct AACBSFContext {
|
||||
int first_frame_done;
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include "libavutil/softfloat.h"
|
||||
|
||||
#define FFT_FLOAT 0
|
||||
|
||||
#define AAC_RENAME(x) x ## _fixed
|
||||
#define AAC_RENAME_32(x) x ## _fixed_32
|
||||
#define AAC_RENAME2(x) x ## _fixed
|
||||
@@ -43,7 +45,7 @@ typedef int AAC_SIGNE;
|
||||
#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 TX_SCALE(x) ((x) * 128.0f)
|
||||
#define RANGE15(x) x
|
||||
#define GET_GAIN(x, y) (-(y) * (1 << (x))) + 1024
|
||||
#define AAC_MUL16(x, y) (int)(((int64_t)(x) * (y) + 0x8000) >> 16)
|
||||
#define AAC_MUL26(x, y) (int)(((int64_t)(x) * (y) + 0x2000000) >> 26)
|
||||
@@ -76,6 +78,8 @@ typedef int AAC_SIGNE;
|
||||
|
||||
#else
|
||||
|
||||
#define FFT_FLOAT 1
|
||||
|
||||
#define AAC_RENAME(x) x
|
||||
#define AAC_RENAME_32(x) x
|
||||
#define AAC_RENAME2(x) ff_ ## x
|
||||
@@ -90,7 +94,7 @@ typedef unsigned AAC_SIGNE;
|
||||
#define Q23(x) ((float)(x))
|
||||
#define Q30(x) ((float)(x))
|
||||
#define Q31(x) ((float)(x))
|
||||
#define TX_SCALE(x) ((x) / 32768.0f)
|
||||
#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))
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
#include "get_bits.h"
|
||||
#include "mpeg4audio.h"
|
||||
|
||||
static int aac_sync(uint64_t state, int *need_next_header, int *new_frame_start)
|
||||
static int aac_sync(uint64_t state, AACAC3ParseContext *hdr_info,
|
||||
int *need_next_header, int *new_frame_start)
|
||||
{
|
||||
GetBitContext bits;
|
||||
AACADTSHeaderInfo hdr;
|
||||
@@ -45,6 +46,10 @@ static int aac_sync(uint64_t state, int *need_next_header, int *new_frame_start)
|
||||
return 0;
|
||||
*need_next_header = 0;
|
||||
*new_frame_start = 1;
|
||||
hdr_info->sample_rate = hdr.sample_rate;
|
||||
hdr_info->channels = ff_mpeg4audio_channels[hdr.chan_config];
|
||||
hdr_info->samples = hdr.samples;
|
||||
hdr_info->bit_rate = hdr.bit_rate;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,229 +62,6 @@
|
||||
|
||||
#include "libavcodec/aaccoder_trellis.h"
|
||||
|
||||
typedef float (*quantize_and_encode_band_func)(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, float *energy);
|
||||
|
||||
/**
|
||||
* 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, float *energy, 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;
|
||||
float cost = 0;
|
||||
float qenergy = 0;
|
||||
const int dim = BT_PAIR ? 2 : 4;
|
||||
int resbits = 0;
|
||||
int off;
|
||||
|
||||
if (BT_ZERO || BT_NOISE || BT_STEREO) {
|
||||
for (int i = 0; i < size; i++)
|
||||
cost += in[i]*in[i];
|
||||
if (bits)
|
||||
*bits = 0;
|
||||
if (energy)
|
||||
*energy = qenergy;
|
||||
if (out) {
|
||||
for (int i = 0; i < size; i += dim)
|
||||
for (int j = 0; j < dim; j++)
|
||||
out[i+j] = 0.0f;
|
||||
}
|
||||
return cost * lambda;
|
||||
}
|
||||
if (!scaled) {
|
||||
s->abs_pow34(s->scoefs, in, size);
|
||||
scaled = s->scoefs;
|
||||
}
|
||||
s->quant_bands(s->qcoefs, in, scaled, size, !BT_UNSIGNED, aac_cb_maxval[cb], Q34, ROUNDING);
|
||||
if (BT_UNSIGNED) {
|
||||
off = 0;
|
||||
} else {
|
||||
off = aac_cb_maxval[cb];
|
||||
}
|
||||
for (int 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 (int 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 (int 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++;
|
||||
qenergy += quantized*quantized;
|
||||
rd += di*di;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < dim; j++) {
|
||||
quantized = vec[j]*IQ;
|
||||
qenergy += quantized*quantized;
|
||||
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 (int 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 (int 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;
|
||||
if (energy)
|
||||
*energy = qenergy;
|
||||
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, float *energy) {
|
||||
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, float *energy) { \
|
||||
return quantize_and_encode_band_cost_template( \
|
||||
s, pb, in, quant, scaled, size, scale_idx, \
|
||||
BT_ESC ? ESC_BT : cb, lambda, uplim, bits, energy, \
|
||||
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 const quantize_and_encode_band_func quantize_and_encode_band_cost_arr[] =
|
||||
{
|
||||
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 const quantize_and_encode_band_func quantize_and_encode_band_cost_rtz_arr[] =
|
||||
{
|
||||
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,
|
||||
};
|
||||
|
||||
float ff_quantize_and_encode_band_cost(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, float *energy)
|
||||
{
|
||||
return quantize_and_encode_band_cost_arr[cb](s, pb, in, quant, scaled, size,
|
||||
scale_idx, cb, lambda, uplim,
|
||||
bits, energy);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
(rtz ? quantize_and_encode_band_cost_rtz_arr : quantize_and_encode_band_cost_arr)[cb](s, pb, in, out, NULL, size, scale_idx, cb,
|
||||
lambda, INFINITY, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* structure used in optimal codebook search
|
||||
*/
|
||||
@@ -346,7 +123,7 @@ static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce
|
||||
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, NULL);
|
||||
lambda / band->threshold, INFINITY, NULL, NULL, 0);
|
||||
}
|
||||
cost_stay_here = path[swb][cb].cost + rd;
|
||||
cost_get_here = minrd + rd + run_bits + 4;
|
||||
@@ -569,7 +346,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, NULL);
|
||||
q + q0, cb, lambda / band->threshold, INFINITY, NULL, NULL, 0);
|
||||
}
|
||||
minrd = FFMIN(minrd, dist);
|
||||
|
||||
@@ -881,7 +658,7 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne
|
||||
sce->ics.swb_sizes[g],
|
||||
sce->sf_idx[(w+w2)*16+g],
|
||||
sce->band_alt[(w+w2)*16+g],
|
||||
lambda/band->threshold, INFINITY, NULL, NULL);
|
||||
lambda/band->threshold, INFINITY, NULL, NULL, 0);
|
||||
/* Estimate rd on average as 5 bits for SF, 4 for the CB, plus spread energy * lambda/thr */
|
||||
dist2 += band->energy/(band->spread*band->spread)*lambda*dist_thresh/band->threshold;
|
||||
}
|
||||
@@ -1065,25 +842,25 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe)
|
||||
sce0->ics.swb_sizes[g],
|
||||
sce0->sf_idx[w*16+g],
|
||||
sce0->band_type[w*16+g],
|
||||
lambda / (band0->threshold + FLT_MIN), INFINITY, &b1, NULL);
|
||||
lambda / (band0->threshold + FLT_MIN), INFINITY, &b1, NULL, 0);
|
||||
dist1 += quantize_band_cost(s, &sce1->coeffs[start + (w+w2)*128],
|
||||
R34,
|
||||
sce1->ics.swb_sizes[g],
|
||||
sce1->sf_idx[w*16+g],
|
||||
sce1->band_type[w*16+g],
|
||||
lambda / (band1->threshold + FLT_MIN), INFINITY, &b2, NULL);
|
||||
lambda / (band1->threshold + FLT_MIN), INFINITY, &b2, NULL, 0);
|
||||
dist2 += quantize_band_cost(s, M,
|
||||
M34,
|
||||
sce0->ics.swb_sizes[g],
|
||||
mididx,
|
||||
midcb,
|
||||
lambda / (minthr + FLT_MIN), INFINITY, &b3, NULL);
|
||||
lambda / (minthr + FLT_MIN), INFINITY, &b3, NULL, 0);
|
||||
dist2 += quantize_band_cost(s, S,
|
||||
S34,
|
||||
sce1->ics.swb_sizes[g],
|
||||
sididx,
|
||||
sidcb,
|
||||
mslambda / (minthr * bmax + FLT_MIN), INFINITY, &b4, NULL);
|
||||
mslambda / (minthr * bmax + FLT_MIN), INFINITY, &b4, NULL, 0);
|
||||
B0 += b1+b2;
|
||||
B1 += b3+b4;
|
||||
dist1 -= b1+b2;
|
||||
|
||||
@@ -127,7 +127,7 @@ static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,
|
||||
&s->scoefs[start + w*128], size,
|
||||
sce->sf_idx[win*16+swb],
|
||||
aac_cb_out_map[cb],
|
||||
0, INFINITY, NULL, NULL);
|
||||
0, INFINITY, NULL, NULL, 0);
|
||||
}
|
||||
cost_stay_here = path[swb][cb].cost + bits;
|
||||
cost_get_here = minbits + bits + run_bits + 4;
|
||||
|
||||
@@ -32,14 +32,16 @@
|
||||
* @author Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
*/
|
||||
|
||||
#define FFT_FLOAT 1
|
||||
#define USE_FIXED 0
|
||||
#define TX_TYPE AV_TX_FLOAT_MDCT
|
||||
|
||||
#include "libavutil/float_dsp.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "avcodec.h"
|
||||
#include "codec_internal.h"
|
||||
#include "get_bits.h"
|
||||
#include "fft.h"
|
||||
#include "mdct15.h"
|
||||
#include "lpc.h"
|
||||
#include "kbdwin.h"
|
||||
#include "sinewin.h"
|
||||
@@ -552,7 +554,7 @@ static av_cold int latm_decode_init(AVCodecContext *avctx)
|
||||
|
||||
const FFCodec ff_aac_decoder = {
|
||||
.p.name = "aac",
|
||||
CODEC_LONG_NAME("AAC (Advanced Audio Coding)"),
|
||||
.p.long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
|
||||
.p.type = AVMEDIA_TYPE_AUDIO,
|
||||
.p.id = AV_CODEC_ID_AAC,
|
||||
.priv_data_size = sizeof(AACContext),
|
||||
@@ -563,8 +565,10 @@ const FFCodec ff_aac_decoder = {
|
||||
AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
|
||||
},
|
||||
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
|
||||
CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(aac_channel_layout)
|
||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
|
||||
#if FF_API_OLD_CHANNEL_LAYOUT
|
||||
.p.channel_layouts = aac_channel_layout,
|
||||
#endif
|
||||
.p.ch_layouts = aac_ch_layout,
|
||||
.flush = flush,
|
||||
.p.priv_class = &aac_decoder_class,
|
||||
@@ -578,7 +582,7 @@ const FFCodec ff_aac_decoder = {
|
||||
*/
|
||||
const FFCodec ff_aac_latm_decoder = {
|
||||
.p.name = "aac_latm",
|
||||
CODEC_LONG_NAME("AAC LATM (Advanced Audio Coding LATM syntax)"),
|
||||
.p.long_name = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Coding LATM syntax)"),
|
||||
.p.type = AVMEDIA_TYPE_AUDIO,
|
||||
.p.id = AV_CODEC_ID_AAC_LATM,
|
||||
.priv_data_size = sizeof(struct LATMContext),
|
||||
@@ -589,8 +593,10 @@ const FFCodec ff_aac_latm_decoder = {
|
||||
AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
|
||||
},
|
||||
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
|
||||
CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(aac_channel_layout)
|
||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
|
||||
#if FF_API_OLD_CHANNEL_LAYOUT
|
||||
.p.channel_layouts = aac_channel_layout,
|
||||
#endif
|
||||
.p.ch_layouts = aac_ch_layout,
|
||||
.flush = flush,
|
||||
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user