merge upstream 5.1.1

This commit is contained in:
su-fang 2023-03-28 10:15:24 +08:00
parent f943597956
commit a6338d9a91
4471 changed files with 379365 additions and 187332 deletions

2
.gitattributes vendored
View File

@ -1,2 +0,0 @@
*.pnm -diff -text
tests/ref/fate/sub-scc eol=crlf

25
.mailmap Normal file
View File

@ -0,0 +1,25 @@
<james.darnley@gmail.com> <jdarnley@obe.tv>
<jeebjp@gmail.com> <jan.ekstrom@aminocom.com>
<sw@jkqxz.net> <mrt@jkqxz.net>
<u@pkh.me> <cboesch@gopro.com>
<zhilizhao@tencent.com> <quinkblack@foxmail.com>
<zhilizhao@tencent.com> <wantlamy@gmail.com>
<modmaker@google.com> <modmaker-at-google.com@ffmpeg.org>
<stebbins@jetheaddev.com> <jstebbins@jetheaddev.com>
<barryjzhao@tencent.com> <mypopydev@gmail.com>
<barryjzhao@tencent.com> <jun.zhao@intel.com>
<josh@itanimul.li> <joshdk@obe.tv>
<michael@niedermayer.cc> <michaelni@gmx.at>
<linjie.justin.fu@gmail.com> <linjie.fu@intel.com>
<linjie.justin.fu@gmail.com> <fulinjie@zju.edu.cn>
<ceffmpeg@gmail.com> <cehoyos@ag.or.at>
<ceffmpeg@gmail.com> <cehoyos@rainbow.studorg.tuwien.ac.at>
<ffmpeg@gyani.pro> <gyandoshi@gmail.com>
<atomnuker@gmail.com> <rpehlivanov@obe.tv>
<lizhong1008@gmail.com> <zhong.li@intel.com>
<lizhong1008@gmail.com> <zhongli_dev@126.com>
<andreas.rheinhardt@gmail.com> <andreas.rheinhardt@googlemail.com>
rcombs <rcombs@rcombs.me> <rodger.combs@gmail.com>
<thilo.borgmann@mail.de> <thilo.borgmann@googlemail.com>
<liuqi05@kuaishou.com> <lq@chinaffmpeg.org>
<ruiling.song83@gmail.com> <ruiling.song@intel.com>

557
Changelog
View File

@ -1,303 +1,268 @@
Entries are sorted chronologically from oldest to youngest within each release,
releases are sorted from youngest to oldest.
version 4.2.2
- cbs_mpeg2: Fix parsing the last unit
- cbs_mpeg2: Rearrange start code search
- cbs_mpeg2: Decompose Sequence End
- cbs_mpeg2: Fix parsing of picture and slice headers
- cbs: Remove useless initializations
- mpeg2_metadata, cbs_mpeg2: Fix handling of colour_description
- lavc/cbs_h2645_syntax_template: Fix memleak
- avcodec/cbs: Fix potential overflow
- avcodec/cbs: Factor out common code for writing units
- avcodec/ffwavesynth: Fix undefined overflow in wavesynth_synth_sample()
- avcodec/ffwavesynth: Fix undefined overflow in wavesynth_synth_sample()
- avcodec/cook: Use 3 stage VLC decoding for channel_coupling
- avcodec/wmalosslessdec: Fixes undefined overflow in dequantization in decode_subframe()
- avcodec/sonic: Check e in get_symbol()
- avcodec/twinvqdec: Correct overflow in block align check
- avcodec/vc1dec: Fix "return -1" cases
- avcodec/vc1dec: Free sprite_output_frame on error
- avcodec/atrac9dec: Clamp band_ext_data to max that can be read if skipped.
- avcodec/agm: Include block size in the MV check for flags == 3
- avcodec/wmadec: Keep track of exponent initialization per channel
- avcodec/iff: Check that video_size is large enough for the read parameters
- avcodec/cbs_vp9: Check data_size
- avcodec/cbs_vp9: Check index_size
- avcodec/adpcm: Clip predictor for APC
- avcodec/targa: Check colors vs. available space
- avcodec/dstdec: Use get_ur_golomb_jpegls()
- avcodec/wmavoice: Check remaining input in parse_packet_header()
- avcodec/wmalosslessdec: Fix 2 overflows in mclms
- avcodec/wmaprodec: Fixes integer overflow with 32bit samples
- avcodec/adpcm: Fix invalid shift in xa_decode()
- avcodec/wmalosslessdec: Fix several integer issues
- avcodec/wmalosslessdec: Check that padding bits is not more than sample bits
- avcodec/iff: Skip overflowing runs in decode_delta_d()
- avcodec/pnm: Check that the header is not truncated
- avcodec/mp3_header_decompress_bsf: Check sample_rate_index
- avcodec/cbs_av1_syntax_template: Check num_y_points
- avformat/rmdec: Initialize and sanity check offset in ivr_read_header()
- avcodec/agm: Do not allow MVs out of the picture area as no edge is allocated
- avcodec/apedec: Fix 2 integer overflows
- avformat/id3v2: Fix double-free on error
- avcodec/wmaprodec: Set packet_loss when we error out on a sanity check
- avcodec/wmaprodec: Check offset
- avcodec/truemotion2: Fix 2 integer overflows in tm2_low_res_block()
- avcodec/wmaprodec: Check if the channel sum of all internal contexts match the external
- avcodec/atrac9dec: Check q_unit_cnt more completely before using it to access at9_tab_band_ext_group
- avcodec/fitsdec: Use lrint()
- avcodec/g729dec: Avoid using buf_size
- avcodec/g729dec: Factor block_size out
- avcodec/g729dec: require buf_size to be non 0
- avcodec/alac: Fix integer overflow in lpc_prediction() with sign
- avcodec/wmaprodec: Fix buflen computation in save_bits()
- avcodec/vc1_block: Fix integer overflow in AC rescaling in vc1_decode_i_block_adv()
- avcodec/vmdaudio: Check chunk counts to avoid integer overflow
- avformat/mxfdec: Clear metadata_sets_count in mxf_read_close()
- avcodec/nuv: Use ff_set_dimensions()
- avformat/vividas: Error out on audio packets in the absence of audio streams
- avformat/vividas: Check and require 1 video stream
- avcodec/ffwavesynth: Fix integer overflow with pink_ts_cur/next
- avcodec/ralf: Fix integer overflows with the filter coefficient in decode_channel()
- avcodec/g729dec: Use 64bit and clip in scalar product
- avcodec/mxpegdec: Check for multiple SOF
- avcodec/nuv: Move comptype check up
- avcodec/wmavoice: Fix integer overflow in synth_frame()
- avcodec/rawdec: Check bits_per_coded_sample more pedantically for 16bit cases
- avutil/lfg: Correct index increment type to avoid undefined behavior
- avcodec/cngdec: Remove AV_CODEC_CAP_DELAY
- avcodec/iff: Move index use after check in decodeplane8()
- avcodec/atrac3: Check for huge block aligns
- avcodec/ralf: use multiply instead of shift to avoid undefined behavior in decode_block()
- avcodec/wmadec: Require previous exponents for reuse
- avcodec/vc1_block: Fix undefined behavior in ac prediction rescaling
- avcodec/qdm2: The smallest header seems to have 2 bytes so treat 1 as invalid
- avcodec/apedec: Fixes integer overflow of res+*data in do_apply_filter()
- avcodec/sonic: Fix integer overflow in predictor_calc_error()
- avformat/vividas: Add EOF check in val_1 loop in track_header()
- avcodec/atrac9dec: Check precision_fine/coarse
- avformat/mp3dec: Check that the frame fits within the probe buffer
- vcodec/agm: Alloc based on coded dimensions
- avcodec/wmaprodec: get frame during frame decode
- avcodec/interplayacm: Fix overflow of last unused value
- avcodec/adpcm: Fix undefined behavior with negative predictions in IMA OKI
- avcodec/cook: Move up and extend block_align check
- avcodec/sbcdec: Fix integer overflows in sbc_synthesize_four()
- avcodec/twinvq: Check block_align
- avcodec/cook: Enlarge gain table
- avcodec/cook: Check samples_per_channel earlier
- avcodec/atrac3plus: Check split point in fill mode 3
- avcodec/wmavoice: Check sample_rate
- avcodec/xsubdec: fix overflow in alpha handling
- avcodec/iff: Check available space before entering loop in decode_long_vertical_delta2() / decode_long_vertical_delta()
- avcodec/apedec: Fix integer overflow in filter_3800()
- avutil/lfg: Document the AVLFG struct
- avcodec/ffv1dec: Use a different error message for the slice level CRC
- avcodec/apedec: Fix undefined integer overflow in long_filter_ehigh_3830()
- avcodec/dstdec: Check that AC probabilities are within range
- avcodec/dstdec: Check read_table() for failure
- avformat/vividas: Fix n_sb_blocks Check
- avcodec/snowenc: Set mb_num to avoid ratecontrol floating point divisions by 0.0
- avcodec/snowenc: Fix 2 undefined shifts
- avformat/nutenc: Do not pass NULL to memcmp() in get_needed_flags()
- avcodec/aptx: Check the number of channels
- avcodec/aacdec_template: Check samplerate
- avcodec/truemotion2: Fix several integer overflows in tm2_low_res_block()
- avcodec/utils: Check block_align
- avcodec/wmalosslessdec: Fix some integer anomalies
- avcodec/adpcm: Fix invalid shifts in ADPCM DTK
- avcodec/apedec: Only clear the needed buffer space, instead of all
- avcodec/libvorbisdec: Fix insufficient input checks leading to out of array reads
- avcodec/g723_1dec: fix invalid shift with negative sid_gain
- avcodec/vp5: Check render_x/y
- avcodec/hcom: Check the root entry and the right entries
- avcodec/qdrw: Check input for header/skiped space before get_buffer()
- avcodec/ralf: Skip initializing unused filter variables
- avcodec/takdec: Fix overflow with large sample rates
- avcodec/atrac9dec: Set channels
- avcodec/alsdec: Check that input space for header exists in read_diff_float_data()
- avformat/pjsdec: Check duration for overflow
- avcodec/agm: Check for reference frame earlier
- avcodec/ptx: Check that the input contains at least one line
- avcodec/alac: Fix integer overflow in LPC
- avcodec/smacker: Fix integer overflows in pred[] in smka_decode_frame()
- avcodec/aliaspixdec: Check input size against minimal picture size
- avcodec/ffwavesynth: Fix integer overflows in pink noise addition
- avcodec/vc1_block: Fixes integer overflow in vc1_decode_i_block_adv()
- avcodec/wmalosslessdec: Check block_align
- avcodec/g729dec: Avoid computing invalid temporary pointers for ff_acelp_weighted_vector_sum()
- avcodec/g729postfilter: Fix left shift of negative value
- avcodec/binkaudio: Check sample rate
- avcodec/sbcdec: Fix integer overflows in sbc_synthesize_eight()
- avcodec/adpcm: Check initial predictor for ADPCM_IMA_EA_EACS
- avcodec/g723_1dec: Fix overflow in shift
- avcodec/apedec: Fix integer overflow in predictor_update_3930()
- avcodec/g729postfilter: Fix undefined intermediate pointers
- avcodec/g729postfilter: Fix undefined shifts
- avcodec/lsp: Fix undefined shifts in lsp2poly()
- avcodec/adpcm: Fix left shifts in AV_CODEC_ID_ADPCM_EA
- avformat/shortendec: Check k in probe
- avfilter/vf_geq: Use av_clipd() instead of av_clipf()
- avcodec/wmaprodec: Check that the streams channels do not exceed the overall channels
- avcodec/qdmc: Check input space in qdmc_get_vlc()
- avcodec/wmaprodec: Fix cleanup on error
- avcodec/pcm: Check bits_per_coded_sample
- avcodec/exr: Allow duplicate use of channel indexes
- avcodec/fitsdec: Fail on 0 naxisn
- avcodec/dxv: Subtract 12 earlier in dxv_decompress_cocg()
- libavcodec/dxv: Remove redundant seek
- avcodec/ituh263dec: Check input for minimal frame size
- avcodec/truemotion1: Check that the input has enough space for a minimal index_stream
- avformat/mpsubdec: Clear queue on error
- avcodec/sunrast: Check that the input is large enough for the maximally compressed image
- avcodec/sunrast: Check for availability of maplength before allocating image
- avformat/subtitles: Check nb_subs in ff_subtitles_queue_finalize()
- avcodec/vc1_block: Fix invalid left shift in vc1_decode_p_mb()
- avcodec/wmaprodec: Check if there is a stream
- avcodec/g2meet: Check for end of input in jpg_decode_block()
- avcodec/g2meet: Check if adjusted pixel was on the stack
- avformat/electronicarts: If no packet has been read at the end do not treat it as if theres a packet
- avcodec/dxv: Check op_offset in dxv_decompress_yo()
- avcodec/utils: Check sample_rate before opening the decoder
- avcodec/aptx: Fix multiple shift anomalies
- avcodec/fitsdec: fix use of uninitialised values
- avcodec/motionpixels: Mark 2 functions as always_inline
- avcodec/ituh263dec: Make the condition for the studio slice start code match between ff_h263_resync() and ff_mpeg4_decode_studio_slice_header()
- avcodec/ralf: Fix integer overflow in decode_channel()
- vcodec/vc1: compute rangex/y only for P/B frames
- avcodec/vc1_pred: Fix invalid shifts in scaleforopp()
- avcodec/vc1_block: Fix invalid shift with rangeredfrm
- avcodec/vc1: Check for excessive resolution
- avcodec/vc1: check REFDIST
- avcodec/apedec: Fix several integer overflows in predictor_update_filter() and do_apply_filter()
- avcodec/hevc_cabac: Tighten the limit on k in ff_hevc_cu_qp_delta_abs()
- avcodec/4xm: Check index in decode_i_block() also in the path where its not used.
- avcodec/loco: Check for end of input in the first line
- avcodec/atrac3: Check block_align
- avcodec/alsdec: Avoid dereferencing context pointer in inner interleave loop
- avcodec/hcom: Check that there are dictionary entries
- avcodec/fitsdec: Prevent division by 0 with huge data_max
- avcodec/dstdec: Fix integer overflow in samples_per_frame computation
- avcodec/g729_parser: Check block_size
- avcodec/sbcdec: Initialize number of channels
- avcodec/utils: Optimize ff_color_frame() using memcpy()
- avcodec/aacdec: Check if we run out of input in read_stream_mux_config()
- avcodec/utils: Use av_memcpy_backptr() in ff_color_frame()
- avcodec/smacker: Fix integer overflow in signed int multiply in SMK_BLK_FILL
- avcodec/alac: Fix invalid shifts in 20/24 bps
- avcodec/alac: fix undefined behavior with INT_MIN in lpc_prediction()
- avcodec/ffwavesynth: Fix integer overflow in timestamps
- avformat/vividas: Test size and packet numbers a bit more
- avformat/vividas: Check n_sb_blocks against input space
- avcodec/dxv: Check op_offset in both directions
- avcodec/adpcm: Check number of channels for MTAF
- avcodec/sunrast: Fix indention
- avcodec/sunrast: Fix return type for "unsupported (compression) type"
- avcodec/utils: Check channels fully earlier
- avformat/mov: Check for EOF in mov_read_meta()
- avcodec/hevcdec: Fix memleak of a53_caption
- avformat/vividas: Remove align offset which is always masked off
- avformat/vividas: remove dead assignment
- avformat/cdxl: Fix integer overflow in intermediate
- avcodec/hevcdec: repeat character in skiped
- repeat an even number of characters in occured
- avcodec/gdv: Replace assert() checking bitstream by if()
- libavcodec/utils: Free threads on init failure
- avcodec/htmlsubtitles: Avoid locale dependant isdigit()
- avcodec/alsdec: Check k from being outside what our implementation can handle
- avcodec/takdec: Fix integer overflow in decorrelate()
- avcodec/aacps: Fix integer overflows in hybrid_synthesis()
- avcodec/mpeg4videodec: Fix integer overflow in mpeg4_decode_studio_block()
- avcodec/vp56rac: delay signaling an error on truncated input
- avcodec/pnm_parser: Use memchr() in pnm_parse()
- tests: Fix bash errors in lavf_container tests.
- avformat/matroskadec: Fix use-after-free when demuxing ProRes
- avformat/matroskadec: Fix demuxing ProRes
- avcodec/cbs_av1: fix array size for ar_coeffs_cb_plus_128 and ar_coeffs_cr_plus_128
- avcodec/cbs_av1: avoid reading trailing bits when obu type is OBU_TILE_LIST
- lavc/cbs_h2645: Fix incorrect max size of nalu unit
- avcodec/extract_extradata_bsf: Don't unref uninitialized buffers
- avformat/av1: Fix leak of dynamic buffer in case of parsing failure
- libavformat/rtsp: return error if rtsp_hd_out is null instead of crash
- cbs_h264: Fix missing inferred colour description fields
- avcodec/cbs_av1: keep separate reference frame state for reading and writing
- avcodec/cbs_av1: fix reading reference order hint in skip_mode_params()
- avcodec/amfnec: allocate packets using av_new_packet()
- avcodec/nvenc: make sure newly allocated packets are refcounted
- lavc/mpeg4audio: add chan_config check to avoid indeterminate channels
- aformat/movenc: add missing padding to output track extradata
- avcodec/nvenc: add driver version info for SDK 9.1
- avcodec/bsf: check that AVBSFInternal was allocated before dereferencing it
version 5.1.1:
- avformat/asfdec_o: limit recursion depth in asf_read_unknown()
- avformat/mov: Check count sums in build_open_gop_key_points()
- doc/git-howto.texi: Document commit signing
- libavcodec/8bps: Check that line lengths fit within the buffer
- avcodec/midivid: Perform lzss_uncompress() before ff_reget_buffer()
- libavformat/iff: Check for overflow in body_end calculation
- avformat/avidec: Prevent entity expansion attacks
- avcodec/h263dec: Sanity check against minimal I/P frame size
- avcodec/hevcdec: Check s->ref in the md5 path similar to hwaccel
- avcodec/mpegaudiodec_template: use unsigned shift in handle_crc()
- avformat/subviewerdec: Make read_ts() more flexible
- avcodec/mjpegdec: bayer and rct are incompatible
- MAINTAINERS: Add ED25519 key for signing my commits in the future
- avcodec/pngdec: Fix APNG_DISPOSE_OP_BACKGROUND
- avcodec/libvpx: fix assembling vp9 packets with alpha channel
- fftools/ffmpeg_opt: try to propagate the requested output channel layout
- avcodec/libsvtav1: properly initialize the flush EbBufferHeaderType struct
- configure: enable the av1_frame_split bsf for the av1 decoder
- swresample/swresample: fill the correct buffer to print the output layout string
- ffprobe: restore reporting error code for failed inputs
- ipfsgateway: Remove default gateway
- avcodec/libspeexdec: Fix use of uninitialized value
- avformat/avisynth: use ch_layout.nb_channels for channel count
- fate/lavf-image: Disable file checksums for exr tests
- tests/fate-run: Allow to skip file checksums for lavf_image
- fate/imf: Rename IMF fate-target
- avcodec/alac: don't fail if channels aren't set during init() when extradata is valid
- configure: properly require libx264 if enabled
version 5.1:
- add ipfs/ipns protocol support
- dialogue enhance audio filter
- dropped obsolete XvMC hwaccel
- pcm-bluray encoder
- DFPWM audio encoder/decoder and raw muxer/demuxer
- SITI filter
- Vizrt Binary Image encoder/decoder
- avsynctest source filter
- feedback video filter
- pixelize video filter
- colormap video filter
- colorchart video source filter
- multiply video filter
- PGS subtitle frame merge bitstream filter
- blurdetect filter
- tiltshelf audio filter
- QOI image format support
- ffprobe -o option
- virtualbass audio filter
- VDPAU AV1 hwaccel
- PHM image format support
- remap_opencl filter
- added chromakey_cuda filter
version 5.0:
- ADPCM IMA Westwood encoder
- Westwood AUD muxer
- ADPCM IMA Acorn Replay decoder
- Argonaut Games CVG demuxer
- Argonaut Games CVG muxer
- Concatf protocol
- afwtdn audio filter
- audio and video segment filters
- Apple Graphics (SMC) encoder
- hsvkey and hsvhold video filters
- adecorrelate audio filter
- atilt audio filter
- grayworld video filter
- AV1 Low overhead bitstream format muxer
- swscale slice threading
- MSN Siren decoder
- scharr video filter
- apsyclip audio filter
- morpho video filter
- amr parser
- (a)latency filters
- GEM Raster image decoder
- asdr audio filter
- speex decoder
- limitdiff video filter
- xcorrelate video filter
- varblur video filter
- huesaturation video filter
- colorspectrum source video filter
- RTP packetizer for uncompressed video (RFC 4175)
- bitpacked encoder
- VideoToolbox VP9 hwaccel
- VideoToolbox ProRes hwaccel
- support loongarch.
- aspectralstats audio filter
- adynamicsmooth audio filter
- libplacebo filter
- vflip_vulkan, hflip_vulkan and flip_vulkan filters
- adynamicequalizer audio filter
- yadif_videotoolbox filter
- VideoToolbox ProRes encoder
- anlmf audio filter
- IMF demuxer (experimental)
version 4.4:
- AudioToolbox output device
- MacCaption demuxer
- PGX decoder
- chromanr video filter
- VDPAU accelerated HEVC 10/12bit decoding
- ADPCM IMA Ubisoft APM encoder
- Rayman 2 APM muxer
- AV1 encoding support SVT-AV1
- Cineform HD encoder
- ADPCM Argonaut Games encoder
- Argonaut Games ASF muxer
- AV1 Low overhead bitstream format demuxer
- RPZA video encoder
- ADPCM IMA MOFLEX decoder
- MobiClip FastAudio decoder
- MobiClip video decoder
- MOFLEX demuxer
- MODS demuxer
- PhotoCD decoder
- MCA demuxer
- AV1 decoder (Hardware acceleration used only)
- SVS demuxer
- Argonaut Games BRP demuxer
- DAT demuxer
- aax demuxer
- IPU decoder, parser and demuxer
- Intel QSV-accelerated AV1 decoding
- Argonaut Games Video decoder
- libwavpack encoder removed
- ACE demuxer
- AVS3 demuxer
- AVS3 video decoder via libuavs3d
- Cintel RAW decoder
- VDPAU accelerated VP9 10/12bit decoding
- afreqshift and aphaseshift filters
- High Voltage Software ADPCM encoder
- LEGO Racers ALP (.tun & .pcm) muxer
- AV1 VAAPI decoder
- adenorm filter
- ADPCM IMA AMV encoder
- AMV muxer
- NVDEC AV1 hwaccel
- DXVA2/D3D11VA hardware accelerated AV1 decoding
- speechnorm filter
- SpeedHQ encoder
- asupercut filter
- asubcut filter
- Microsoft Paint (MSP) version 2 decoder
- Microsoft Paint (MSP) demuxer
- AV1 monochrome encoding support via libaom >= 2.0.1
- asuperpass and asuperstop filter
- shufflepixels filter
- tmidequalizer filter
- estdif filter
- epx filter
- Dolby E parser
- shear filter
- kirsch filter
- colortemperature filter
- colorcontrast filter
- PFM encoder
- colorcorrect filter
- binka demuxer
- XBM parser
- xbm_pipe demuxer
- colorize filter
- CRI parser
- aexciter audio filter
- exposure video filter
- monochrome video filter
- setts bitstream filter
- vif video filter
- OpenEXR image encoder
- Simbiosis IMX decoder
- Simbiosis IMX demuxer
- Digital Pictures SGA demuxer and decoders
- TTML subtitle encoder and muxer
- identity video filter
- msad video filter
- gophers protocol
- RIST protocol via librist
version 4.3:
- v360 filter
- Intel QSV-accelerated MJPEG decoding
- Intel QSV-accelerated VP9 decoding
- Support for TrueHD in mp4
- Support AMD AMF encoder on Linux (via Vulkan)
- IMM5 video decoder
- ZeroMQ protocol
- support Sipro ACELP.KELVIN decoding
- streamhash muxer
- sierpinski video source
- scroll video filter
- photosensitivity filter
- anlms filter
- arnndn filter
- bilateral filter
- maskedmin and maskedmax filters
- VDPAU VP9 hwaccel
- median filter
- QSV-accelerated VP9 encoding
- AV1 encoding support via librav1e
- AV1 frame merge bitstream filter
- AV1 Annex B demuxer
- axcorrelate filter
- mvdv decoder
- mvha decoder
- MPEG-H 3D Audio support in mp4
- thistogram filter
- freezeframes filter
- Argonaut Games ADPCM decoder
- Argonaut Games ASF demuxer
- xfade video filter
- xfade_opencl filter
- afirsrc audio filter source
- pad_opencl filter
- Simon & Schuster Interactive ADPCM decoder
- Real War KVAG demuxer
- CDToons video decoder
- siren audio decoder
- Rayman 2 ADPCM decoder
- Rayman 2 APM demuxer
- cas video filter
- High Voltage Software ADPCM decoder
- LEGO Racers ALP (.tun & .pcm) demuxer
- AMQP 0-9-1 protocol (RabbitMQ)
- Vulkan support
- avgblur_vulkan, overlay_vulkan, scale_vulkan and chromaber_vulkan filters
- ADPCM IMA MTF decoder
- FWSE demuxer
- DERF DPCM decoder
- DERF demuxer
- CRI HCA decoder
- CRI HCA demuxer
- overlay_cuda filter
- switch from AvxSynth to AviSynth+ on Linux
- mv30 decoder
- Expanded styling support for 3GPP Timed Text Subtitles (movtext)
- WebP parser
- tmedian filter
- maskedthreshold filter
- Support for muxing pcm and pgs in m2ts
- Cunning Developments ADPCM decoder
- asubboost filter
- Pro Pinball Series Soundbank demuxer
- pcm_rechunk bitstream filter
- scdet filter
- NotchLC decoder
- gradients source video filter
- MediaFoundation encoder wrapper
- untile filter
- Simon & Schuster Interactive ADPCM encoder
- PFM decoder
- dblur video filter
- Real War KVAG muxer
version 4.2.1:
- avformat/vividas: check for tiny blocks using alignment
- avcodec/vc1_pred: Fix refdist in scaleforopp()
- avcodec/vorbisdec: fix FASTDIV usage for vr_type == 2
- avcodec/iff: Check for overlap in cmap_read_palette()
- avcodec/apedec: Fix 32bit int overflow in do_apply_filter()
- lavf/rawenc: Only accept the appropriate stream type for raw muxers.
- avformat/matroskadec: use av_fast_realloc to reallocate ebml list arrays
- avformat/matroskadec: use proper types for some EbmlSyntax fields
- avcodec/ralf: fix undefined shift in extend_code()
- avcodec/ralf: fix undefined shift
- avcodec/bgmc: Check input space in ff_bgmc_decode_init()
- avcodec/vp3: Check for end of input in 2 places of vp4_unpack_macroblocks()
- avcodec/truemotion2: Fix multiple integer overflows in tm2_null_res_block()
- avcodec/vc1_block: Check the return code from vc1_decode_p_block()
- avcodec/vc1dec: Require res_sprite for wmv3images
- avcodec/vc1_block: Check for double escapes
- avcodec/vorbisdec: Check get_vlc2() failure
- avcodec/tta: Fix integer overflow in prediction
- avcodec/vb: Check input packet size to be large enough to contain flags
- avcodec/cavsdec: Limit the number of access units per packet to 2
- avcodec/atrac9dec: Check block_align
- avcodec/alac: Check for bps of 0
- avcodec/alac: Fix multiple integer overflows in lpc_prediction()
- avcodec/rl2: set dimensions
- avcodec/aacdec: Add FF_CODEC_CAP_INIT_CLEANUP
- avcodec/idcinvideo: Add 320x240 default maximum resolution
- avformat/realtextdec: free queue on error
- avcodec/vp5/6/8: use vpX_rac_is_end()
- avformat/vividas: Check av_xiphlacing() return value before use
- avcodec/alsdec: Fix integer overflow in decode_var_block_data()
- avcodec/alsdec: Limit maximum channels to 512
- avcodec/anm: Check input size for a frame with just a stop code
- avcodec/flicvideo: Optimize and Simplify FLI_COPY in flic_decode_frame_24BPP() by using bytestream2_get_buffer()
- avcodec/loco: Check left column value
- avcodec/ffwavesynth: Fixes invalid shift with pink noise seeking
- avcodec/ffwavesynth: Fix integer overflow for some corner case values
- avcodec/indeo2: Check remaining input more often
- avcodec/diracdec: Check that slices are fewer than pixels
- avcodec/vp56: Consider the alpha start as end of the prior header
- avcodec/4xm: Check for end of input in decode_p_block()
- avcodec/hevcdec: Check delta_luma_weight_l0/1
- avcodec/hnm4video: Optimize postprocess_current_frame()
- avcodec/hevc_refs: Optimize 16bit generate_missing_ref()
- avcodec/scpr: Use av_memcpy_backptr() in type 17 and 33
- avcodec/tiff: Enforce increasing offsets
- avcodec/dds: Use ff_set_dimensions()
- avformat/vividas: Fix another infinite loop
- avformat/vividas: Fix infinite loop in header parser
- avcodec/mpc8: Fix 32bit mask/enum
- avcodec/alsdec: Fix integer overflows of raw_samples in decode_var_block_data()
- avcodec/alsdec: Fix integer overflow of raw_samples in decode_blocks()
- avcodec/alsdec: fix mantisse shift
- avcodec/pngdec: consider chunk size in minimal size check
- avcodec/vc1_block: Fix invalid shifts in vc1_decode_i_blocks()
- avcodec/vc1_block: fix invalid shift in vc1_decode_p_mb()
- avcodec/aacdec_template: fix integer overflow in imdct_and_windowing()
- avformat/mpegts: Check if ready on SCTE reception
- avcodec/omx: fix xFramerate calculation
- avformat/avidec: add support for recognizing HEVC fourcc when demuxing
- avformat/mpegts: fix teletext PTS when selecting teletext streams only
- avcodec/h2645_parse: zero initialize the rbsp buffer
- avcodec/omx: Fix handling of fragmented buffers
- avcodec/omx: ensure zerocopy mode can be disabled on rpi builds
- avformat/mxfdec: do not ignore bad size errors
- avformat/matroskadec: Fix seeking
- ffplay: properly detect all window size changes
version 4.2:
- tpad filter

View File

@ -21,10 +21,11 @@ Specifically, the GPL parts of FFmpeg are:
- `compat/solaris/make_sunver.pl`
- `doc/t2h.pm`
- `doc/texi2pod.pl`
- `libswresample/swresample-test.c`
- `libswresample/tests/swresample.c`
- `tests/checkasm/*`
- `tests/tiny_ssim.c`
- the following filters in libavfilter:
- `signature_lookup.c`
- `vf_blackframe.c`
- `vf_boxblur.c`
- `vf_colormatrix.c`
@ -34,13 +35,13 @@ Specifically, the GPL parts of FFmpeg are:
- `vf_eq.c`
- `vf_find_rect.c`
- `vf_fspp.c`
- `vf_geq.c`
- `vf_histeq.c`
- `vf_hqdn3d.c`
- `vf_interlace.c`
- `vf_kerndeint.c`
- `vf_lensfun.c` (GPL version 3 or later)
- `vf_mcdeint.c`
- `vf_mpdecimate.c`
- `vf_nnedi.c`
- `vf_owdenoise.c`
- `vf_perspective.c`
- `vf_phase.c`
@ -49,12 +50,14 @@ Specifically, the GPL parts of FFmpeg are:
- `vf_pullup.c`
- `vf_repeatfields.c`
- `vf_sab.c`
- `vf_signature.c`
- `vf_smartblur.c`
- `vf_spp.c`
- `vf_stereo3d.c`
- `vf_super2xsai.c`
- `vf_tinterlace.c`
- `vf_uspp.c`
- `vf_vaguedenoiser.c`
- `vsrc_mptestsrc.c`
Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then
@ -80,24 +83,39 @@ affect the licensing of binaries resulting from the combination.
### Compatible libraries
The following libraries are under GPL:
The following libraries are under GPL version 2:
- avisynth
- frei0r
- libcdio
- libdavs2
- librubberband
- libvidstab
- libx264
- libx265
- libxavs
- libxavs2
- libxvid
When combining them with FFmpeg, FFmpeg needs to be licensed as GPL as well by
passing `--enable-gpl` to configure.
The OpenCORE and VisualOn libraries are under the Apache License 2.0. That
license is incompatible with the LGPL v2.1 and the GPL v2, but not with
The following libraries are under LGPL version 3:
- gmp
- libaribb24
- liblensfun
When combining them with FFmpeg, use the configure option `--enable-version3` to
upgrade FFmpeg to the LGPL v3.
The VMAF, mbedTLS, RK MPI, OpenCORE and VisualOn libraries are under the Apache License
2.0. That license is incompatible with the LGPL v2.1 and the GPL v2, but not with
version 3 of those licenses. So to combine these libraries with FFmpeg, the
license version needs to be upgraded by passing `--enable-version3` to configure.
The smbclient library is under the GPL v3, to combine it with FFmpeg,
the options `--enable-gpl` and `--enable-version3` have to be passed to
configure to upgrade FFmpeg to the GPL v3.
### Incompatible libraries
There are certain libraries you can combine with FFmpeg whose licenses are not

View File

@ -53,11 +53,11 @@ Communication
website Deby Barbara Lepage
fate.ffmpeg.org Timothy Gu
Trac bug tracker Alexander Strasser, Michael Niedermayer, Carl Eugen Hoyos
Patchwork Andriy Gelman
mailing lists Baptiste Coudurier
Google+ Paul B Mahol, Michael Niedermayer, Alexander Strasser
Twitter Lou Logan, Reynaldo H. Verdejo Pinochet
Twitter Reynaldo H. Verdejo Pinochet
Launchpad Timothy Gu
ffmpeg-security Andreas Cadhalpun, Carl Eugen Hoyos, Clément Bœsch, Michael Niedermayer, Reimar Doeffinger, Rodger Combs, wm4
ffmpeg-security Andreas Cadhalpun, Carl Eugen Hoyos, Clément Bœsch, Michael Niedermayer, Reimar Doeffinger, rcombs, wm4
libavutil
@ -78,6 +78,7 @@ Other:
float_dsp Loren Merritt
hash Reimar Doeffinger
hwcontext_cuda* Timo Rothenpieler
hwcontext_vulkan* Lynne
intfloat* Michael Niedermayer
integer.c, integer.h Michael Niedermayer
lzo Reimar Doeffinger
@ -88,6 +89,7 @@ Other:
rational.c, rational.h Michael Niedermayer
rc4 Reimar Doeffinger
ripemd.c, ripemd.h James Almer
tx* Lynne
libavcodec
@ -136,13 +138,14 @@ Codecs:
8bps.c Roberto Togni
8svx.c Jaikrishnan Menon
aacenc*, aaccoder.c Rostislav Pehlivanov
adpcm.c Zane van Iperen
alacenc.c Jaikrishnan Menon
alsdec.c Thilo Borgmann, Umair Khan
aptx.c Aurelien Jacobs
ass* Aurelien Jacobs
asv* Michael Niedermayer
atrac3plus* Maxim Poliakovski
audiotoolbox* Rodger Combs
audiotoolbox* rcombs
avs2* Huiwen Ren
bgmc.c, bgmc.h Thilo Borgmann
binkaudio.c Peter Ross
@ -158,6 +161,7 @@ Codecs:
cscd.c Reimar Doeffinger
cuviddec.c Timo Rothenpieler
dca* foo86
dfpwm* Jack Bruienne
dirac* Rostislav Pehlivanov
dnxhd* Baptiste Coudurier
dolby_e* foo86
@ -190,14 +194,17 @@ Codecs:
libcodec2.c Tomas Härdin
libdirac* David Conrad
libdavs2.c Huiwen Ren
libjxl*.c, libjxl.h Leo Izen
libgsm.c Michel Bardiaux
libkvazaar.c Arttu Ylä-Outinen
libopenh264enc.c Martin Storsjo, Linjie Fu
libopenjpeg.c Jaikrishnan Menon
libopenjpegenc.c Michael Bradshaw
libtheoraenc.c David Conrad
libvorbis.c David Conrad
libvpx* James Zern
libxavs.c Stefan Gehrer
libxavs2.c Huiwen Ren
libzvbi-teletextdec.c Marton Balint
lzo.h, lzo.c Reimar Doeffinger
mdec.c Michael Niedermayer
@ -213,6 +220,7 @@ Codecs:
msvideo1.c Mike Melanson
nuv.c Reimar Doeffinger
nvdec*, nvenc* Timo Rothenpieler
omx.c Martin Storsjo, Aman Gupta
opus* Rostislav Pehlivanov
paf.* Paul B Mahol
pcx.c Ivo van Poorten
@ -220,7 +228,7 @@ Codecs:
ptx.c Ivo van Poorten
qcelp* Reynaldo H. Verdejo Pinochet
qdm2.c, qdm2data.h Roberto Togni
qsv* Mark Thompson, Zhong Li
qsv* Mark Thompson, Zhong Li, Haihao Xiang
qtrle.c Mike Melanson
ra144.c, ra144.h, ra288.c, ra288.h Roberto Togni
resample2.c Michael Niedermayer
@ -230,7 +238,6 @@ Codecs:
rv10.c Michael Niedermayer
s3tc* Ivo van Poorten
smc.c Mike Melanson
smvjpegdec.c Ash Hughes
snow* Michael Niedermayer, Loren Merritt
sonic.c Alex Beregszaszi
speedhq.c Steinar H. Gunderson
@ -261,7 +268,6 @@ Codecs:
xan.c Mike Melanson
xbm* Paul B Mahol
xface Stefano Sabatini
xvmc.c Ivan Kalvachev
xwd* Paul B Mahol
Hardware acceleration:
@ -269,8 +275,8 @@ Hardware acceleration:
dxva2* Hendrik Leppkes, Laurent Aimar, Steve Lhomme
d3d11va* Steve Lhomme
mediacodec* Matthieu Bouron, Aman Gupta
vaapi* Gwenole Beauchesne
vaapi_encode* Mark Thompson
vaapi* Haihao Xiang
vaapi_encode* Mark Thompson, Haihao Xiang
vdpau* Philip Langdale, Carl Eugen Hoyos
videotoolbox* Rick Kern, Aman Gupta
@ -349,6 +355,7 @@ Filters:
vf_il.c Paul B Mahol
vf_(t)interlace Thomas Mundt (CC <thomas.mundt@hr.de>)
vf_lenscorrection.c Daniel Oberhoff
vf_libplacebo.c Niklas Haas
vf_mergeplanes.c Paul B Mahol
vf_mestimate.c Davinder Singh
vf_minterpolate.c Davinder Singh
@ -368,6 +375,8 @@ Filters:
Sources:
vsrc_mandelbrot.c Michael Niedermayer
dnn Yejun Guo
libavformat
===========
@ -386,7 +395,13 @@ Muxers/Demuxers:
afc.c Paul B Mahol
aiffdec.c Baptiste Coudurier, Matthieu Bouron
aiffenc.c Baptiste Coudurier, Matthieu Bouron
alp.c Zane van Iperen
amvenc.c Zane van Iperen
apm.c Zane van Iperen
apngdec.c Benoit Fouet
argo_asf.c Zane van Iperen
argo_brp.c Zane van Iperen
argo_cvg.c Zane van Iperen
ass* Aurelien Jacobs
astdec.c Paul B Mahol
astenc.c James Almer
@ -403,6 +418,7 @@ Muxers/Demuxers:
dashdec.c Steven Liu
dashenc.c Karthick Jeyapal
daud.c Reimar Doeffinger
dfpwmdec.c Jack Bruienne
dss.c Oleksij Rempel
dtsdec.c foo86
dtshddec.c Paul B Mahol
@ -423,15 +439,17 @@ Muxers/Demuxers:
ipmovie.c Mike Melanson
ircam* Paul B Mahol
iss.c Stefan Gehrer
jpegxl_probe.* Leo Izen
jvdec.c Peter Ross
kvag.c Zane van Iperen
libmodplug.c Clément Bœsch
libopenmpt.c Josh de Kock
lmlm4.c Ivo van Poorten
lvfdec.c Paul B Mahol
lxfdec.c Tomas Härdin
matroska.c Aurelien Jacobs
matroskadec.c Aurelien Jacobs
matroskaenc.c David Conrad
matroska.c Aurelien Jacobs, Andreas Rheinhardt
matroskadec.c Aurelien Jacobs, Andreas Rheinhardt
matroskaenc.c David Conrad, Andreas Rheinhardt
matroska subtitles (matroskaenc.c) John Peebles
metadata* Aurelien Jacobs
mgsts.c Paul B Mahol
@ -446,7 +464,7 @@ Muxers/Demuxers:
mpegtsenc.c Baptiste Coudurier
msnwc_tcp.c Ramiro Polla
mtv.c Reynaldo H. Verdejo Pinochet
mxf* Baptiste Coudurier
mxf* Baptiste Coudurier, Tomas Härdin
nistspheredec.c Paul B Mahol
nsvdec.c Francois Revol
nut* Michael Niedermayer
@ -454,9 +472,9 @@ Muxers/Demuxers:
oggdec.c, oggdec.h David Conrad
oggenc.c Baptiste Coudurier
oggparse*.c David Conrad
oggparsedaala* Rostislav Pehlivanov
oma.c Maxim Poliakovski
paf.c Paul B Mahol
pp_bnk.c Zane van Iperen
psxstr.c Mike Melanson
pva.c Ivo van Poorten
pvfdec.c Paul B Mahol
@ -501,7 +519,9 @@ Protocols:
bluray.c Petri Hintukainen
ftp.c Lukasz Marek
http.c Ronald S. Bultje
libsrt.c Zhao Zhili
libssh.c Lukasz Marek
libzmq.c Andriy Gelman
mms*.c Ronald S. Bultje
udp.c Luca Abeni
icecast.c Marvin Scholz
@ -526,6 +546,7 @@ Operating systems / CPU architectures
Alpha Falk Hueffner
MIPS Manojkumar Bhosale, Shiyou Yin
LoongArch Shiyou Yin
Mac OS X / PowerPC Romain Dolbeau, Guillaume Poirier
Amiga / PowerPC Colin Ward
Linux / PowerPC Lauri Kasanen
@ -557,6 +578,7 @@ Joakim Plate
Jun Zhao
Kieran Kunhya
Kirill Gavrilov
Limin Wang
Martin Storsjö
Panagiotis Issaris
Pedro Arthur
@ -595,17 +617,22 @@ Daniel Verkamp 78A6 07ED 782C 653E C628 B8B9 F0EB 8DD8 2F0E 21C7
FFmpeg release signing key FCF9 86EA 15E6 E293 A564 4F10 B432 2F04 D676 58D8
Ganesh Ajjanagadde C96A 848E 97C3 CEA2 AB72 5CE4 45F9 6A2D 3C36 FB1B
Gwenole Beauchesne 2E63 B3A6 3E44 37E2 017D 2704 53C7 6266 B153 99C4
Haihao Xiang (haihao) 1F0C 31E8 B4FE F7A4 4DC1 DC99 E0F5 76D4 76FC 437F
Jaikrishnan Menon 61A1 F09F 01C9 2D45 78E1 C862 25DC 8831 AF70 D368
James Almer 7751 2E8C FD94 A169 57E6 9A7A 1463 01AD 7376 59E0
Jean Delvare 7CA6 9F44 60F1 BDC4 1FD2 C858 A552 6B9B B3CD 4E6A
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
Lou Logan (llogan) 7D68 DC73 CBEF EABB 671A B6CF 621C 2E28 82F8 DC3A
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
Ramiro Polla 7859 C65B 751B 1179 792E DAE8 8E95 8B2F 9B6C 5700
Reimar Doeffinger C61D 16E5 9E2C D10C 8958 38A4 0899 A2B9 06D4 D9C7
Reinhard Tartler 9300 5DC2 7E87 6C37 ED7B CA9A 9808 3544 9453 48A4
Reynaldo H. Verdejo Pinochet 6E27 CD34 170C C78E 4D4F 5F40 C18E 077F 3114 452A
@ -614,7 +641,9 @@ Sascha Sommer 38A0 F88B 868E 9D3A 97D4 D6A0 E823 706F 1E07 0D3C
Stefano Sabatini 0D0B AD6B 5330 BBAD D3D6 6A0C 719C 2839 FC43 2D5F
Steinar H. Gunderson C2E9 004F F028 C18E 4EAD DB83 7F61 7561 7797 8F76
Stephan Hilb 4F38 0B3A 5F39 B99B F505 E562 8D5C 5554 4E17 8863
Thilo Borgmann (thilo) CE1D B7F4 4D20 FC3A DD9F FE5A 257C 5B8F 1D20 B92F
Tiancheng "Timothy" Gu 9456 AFC0 814A 8139 E994 8351 7FE6 B095 B582 B0D4
Tim Nicholson 38CF DB09 3ED0 F607 8B67 6CED 0C0B FC44 8B0B FC83
Tomas Härdin (thardin) A79D 4E3D F38F 763F 91F5 8B33 A01E 8AE0 41BB 2551
Wei Gao 4269 7741 857A 0E60 9EC5 08D2 4744 4EFA 62C1 87B9
Zane van Iperen (zane) 61AE D40F 368B 6F26 9DAE 3892 6861 6B2D 8AC4 DCC5

View File

@ -13,17 +13,19 @@ vpath %.v $(SRC_PATH)
vpath %.texi $(SRC_PATH)
vpath %.cu $(SRC_PATH)
vpath %.ptx $(SRC_PATH)
vpath %.metal $(SRC_PATH)
vpath %/fate_config.sh.template $(SRC_PATH)
TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64 audiomatch
HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options
ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale swresample
# $(FFLIBS-yes) needs to be in linking order
FFLIBS-$(CONFIG_AVDEVICE) += avdevice
FFLIBS-$(CONFIG_AVFILTER) += avfilter
FFLIBS-$(CONFIG_AVFORMAT) += avformat
FFLIBS-$(CONFIG_AVCODEC) += avcodec
FFLIBS-$(CONFIG_AVRESAMPLE) += avresample
FFLIBS-$(CONFIG_POSTPROC) += postproc
FFLIBS-$(CONFIG_SWRESAMPLE) += swresample
FFLIBS-$(CONFIG_SWSCALE) += swscale
@ -50,24 +52,40 @@ $(TOOLS): %$(EXESUF): %.o
target_dec_%_fuzzer$(EXESUF): target_dec_%_fuzzer.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
tools/target_bsf_%_fuzzer$(EXESUF): tools/target_bsf_%_fuzzer.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
target_dem_%_fuzzer$(EXESUF): target_dem_%_fuzzer.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
tools/target_dem_fuzzer$(EXESUF): tools/target_dem_fuzzer.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
tools/target_io_dem_fuzzer$(EXESUF): tools/target_io_dem_fuzzer.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
tools/enum_options$(EXESUF): ELIBS = $(FF_EXTRALIBS)
tools/enum_options$(EXESUF): $(FF_DEP_LIBS)
tools/scale_slice_test$(EXESUF): $(FF_DEP_LIBS)
tools/scale_slice_test$(EXESUF): ELIBS = $(FF_EXTRALIBS)
tools/sofa2wavs$(EXESUF): ELIBS = $(FF_EXTRALIBS)
tools/uncoded_frame$(EXESUF): $(FF_DEP_LIBS)
tools/uncoded_frame$(EXESUF): ELIBS = $(FF_EXTRALIBS)
tools/target_dec_%_fuzzer$(EXESUF): $(FF_DEP_LIBS)
tools/target_dem_%_fuzzer$(EXESUF): $(FF_DEP_LIBS)
CONFIGURABLE_COMPONENTS = \
$(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c)) \
$(SRC_PATH)/libavcodec/bitstream_filters.c \
$(SRC_PATH)/libavcodec/hwaccels.h \
$(SRC_PATH)/libavcodec/parsers.c \
$(SRC_PATH)/libavformat/protocols.c \
config.h: ffbuild/.config
config_components.h: ffbuild/.config
ffbuild/.config: $(CONFIGURABLE_COMPONENTS)
@-tput bold 2>/dev/null
@-printf '\nWARNING: $(?) newer than config.h, rerun configure\n\n'
@-printf '\nWARNING: $(?) newer than config_components.h, rerun configure\n\n'
@-tput sgr0 2>/dev/null
SUBDIR_VARS := CLEANFILES FFLIBS HOSTPROGS TESTPROGS TOOLS \
@ -75,7 +93,8 @@ SUBDIR_VARS := CLEANFILES FFLIBS HOSTPROGS TESTPROGS TOOLS \
ARMV5TE-OBJS ARMV6-OBJS ARMV8-OBJS VFP-OBJS NEON-OBJS \
ALTIVEC-OBJS VSX-OBJS MMX-OBJS X86ASM-OBJS \
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSP-OBJS MSA-OBJS \
MMI-OBJS OBJS SLIBOBJS HOSTOBJS TESTOBJS
MMI-OBJS LSX-OBJS LASX-OBJS OBJS SLIBOBJS SHLIBOBJS \
STLIBOBJS HOSTOBJS TESTOBJS
define RESET
$(1) :=
@ -97,12 +116,13 @@ include $(SRC_PATH)/fftools/Makefile
include $(SRC_PATH)/doc/Makefile
include $(SRC_PATH)/doc/examples/Makefile
libavcodec/utils.o libavformat/utils.o libavdevice/avdevice.o libavfilter/avfilter.o libavutil/utils.o libpostproc/postprocess.o libswresample/swresample.o libswscale/utils.o : libavutil/ffversion.h
$(ALLFFLIBS:%=lib%/version.o): libavutil/ffversion.h
$(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF)
ifeq ($(STRIPTYPE),direct)
$(STRIP) -o $@ $<
else
$(RM) $@
$(CP) $< $@
$(STRIP) $@
endif
@ -143,11 +163,12 @@ clean::
$(RM) -rf coverage.info coverage.info.in lcov
distclean:: clean
$(RM) .version avversion.h config.asm config.h mapfile \
$(RM) .version config.asm config.h config_components.h mapfile \
ffbuild/.config ffbuild/config.* libavutil/avconfig.h \
version.h libavutil/ffversion.h libavcodec/codec_names.h \
libavcodec/bsf_list.c libavformat/protocol_list.c \
libavcodec/codec_list.c libavcodec/parser_list.c \
libavfilter/filter_list.c libavdevice/indev_list.c libavdevice/outdev_list.c \
libavformat/muxer_list.c libavformat/demuxer_list.c
ifeq ($(SRC_LINK),src)
$(RM) src

View File

@ -9,7 +9,7 @@ such as audio, video, subtitles and related metadata.
* `libavcodec` provides implementation of a wider range of codecs.
* `libavformat` implements streaming protocols, container formats and basic I/O access.
* `libavutil` includes hashers, decompressors and miscellaneous utility functions.
* `libavfilter` provides a mean to alter decoded Audio and Video through chain of filters.
* `libavfilter` provides means to alter decoded audio and video through a directed graph of connected filters.
* `libavdevice` provides an abstraction to access capture and playback devices.
* `libswresample` implements audio mixing and resampling routines.
* `libswscale` implements color conversion and scaling routines.

View File

@ -1 +1 @@
4.2.2
5.1.1

View File

@ -1,15 +1,18 @@
┌────────────────────────────────────┐
│ RELEASE NOTES for FFmpeg 4.2 "Ada"
└────────────────────────────────────┘
────────────────────────────────────────────┐
│ RELEASE NOTES for FFmpeg 5.1 "Riemann" LTS
────────────────────────────────────────────┘
The FFmpeg Project proudly presents FFmpeg 4.2 "Ada", about 8
months after the release of FFmpeg 4.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
We hope you will like this release as much as we enjoyed working on it, and
as usual, if you have any questions about it, or any FFmpeg related topic,
feel free to join us on the #ffmpeg IRC channel (on irc.freenode.net) or ask
feel free to join us on the #ffmpeg IRC channel (on irc.libera.chat) or ask
on the mailing-lists.

View File

@ -1 +1 @@
4.2.2
5.1.1

View File

@ -96,7 +96,7 @@ do { \
atomic_load(object)
#define atomic_exchange(object, desired) \
InterlockedExchangePointer(object, desired);
InterlockedExchangePointer((PVOID volatile *)object, (PVOID)desired)
#define atomic_exchange_explicit(object, desired, order) \
atomic_exchange(object, desired)

File diff suppressed because it is too large Load Diff

View File

@ -1,94 +0,0 @@
// Avisynth C Interface Version 0.20
// Copyright 2003 Kevin Atkinson
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
// http://www.gnu.org/copyleft/gpl.html .
//
// As a special exception, I give you permission to link to the
// Avisynth C interface with independent modules that communicate with
// the Avisynth C interface solely through the interfaces defined in
// avisynth_c.h, regardless of the license terms of these independent
// modules, and to copy and distribute the resulting combined work
// under terms of your choice, provided that every copy of the
// combined work is accompanied by a complete copy of the source code
// of the Avisynth C interface and Avisynth itself (with the version
// used to produce the combined work), being distributed under the
// terms of the GNU General Public License plus this exception. An
// independent module is a module which is not derived from or based
// on Avisynth C Interface, such as 3rd-party filters, import and
// export plugins, or graphical user interfaces.
#ifndef AVS_CAPI_H
#define AVS_CAPI_H
#ifdef __cplusplus
# define EXTERN_C extern "C"
#else
# define EXTERN_C
#endif
#ifdef BUILDING_AVSCORE
# if defined(GCC) && defined(X86_32)
# define AVSC_CC
# else // MSVC builds and 64-bit GCC
# ifndef AVSC_USE_STDCALL
# define AVSC_CC __cdecl
# else
# define AVSC_CC __stdcall
# endif
# endif
#else // needed for programs that talk to AviSynth+
# ifndef AVSC_WIN32_GCC32 // see comment below
# ifndef AVSC_USE_STDCALL
# define AVSC_CC __cdecl
# else
# define AVSC_CC __stdcall
# endif
# else
# define AVSC_CC
# endif
#endif
// On 64-bit Windows, there's only one calling convention,
// so there is no difference between MSVC and GCC. On 32-bit,
// this isn't true. The convention that GCC needs to use to
// even build AviSynth+ as 32-bit makes anything that uses
// it incompatible with 32-bit MSVC builds of AviSynth+.
// The AVSC_WIN32_GCC32 define is meant to provide a user
// switchable way to make builds of FFmpeg to test 32-bit
// GCC builds of AviSynth+ without having to screw around
// with alternate headers, while still default to the usual
// situation of using 32-bit MSVC builds of AviSynth+.
// Hopefully, this situation will eventually be resolved
// and a broadly compatible solution will arise so the
// same 32-bit FFmpeg build can handle either MSVC or GCC
// builds of AviSynth+.
#define AVSC_INLINE static __inline
#ifdef BUILDING_AVSCORE
# define AVSC_EXPORT __declspec(dllexport)
# define AVSC_API(ret, name) EXTERN_C AVSC_EXPORT ret AVSC_CC name
#else
# define AVSC_EXPORT EXTERN_C __declspec(dllexport)
# ifndef AVSC_NO_DECLSPEC
# define AVSC_API(ret, name) EXTERN_C __declspec(dllimport) ret AVSC_CC name
# else
# define AVSC_API(ret, name) typedef ret (AVSC_CC *name##_func)
# endif
#endif
#endif //AVS_CAPI_H

View File

@ -1,70 +0,0 @@
// Avisynth C Interface Version 0.20
// Copyright 2003 Kevin Atkinson
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
// http://www.gnu.org/copyleft/gpl.html .
//
// As a special exception, I give you permission to link to the
// Avisynth C interface with independent modules that communicate with
// the Avisynth C interface solely through the interfaces defined in
// avisynth_c.h, regardless of the license terms of these independent
// modules, and to copy and distribute the resulting combined work
// under terms of your choice, provided that every copy of the
// combined work is accompanied by a complete copy of the source code
// of the Avisynth C interface and Avisynth itself (with the version
// used to produce the combined work), being distributed under the
// terms of the GNU General Public License plus this exception. An
// independent module is a module which is not derived from or based
// on Avisynth C Interface, such as 3rd-party filters, import and
// export plugins, or graphical user interfaces.
#ifndef AVS_CONFIG_H
#define AVS_CONFIG_H
// Undefine this to get cdecl calling convention
#define AVSC_USE_STDCALL 1
// NOTE TO PLUGIN AUTHORS:
// Because FRAME_ALIGN can be substantially higher than the alignment
// a plugin actually needs, plugins should not use FRAME_ALIGN to check for
// alignment. They should always request the exact alignment value they need.
// This is to make sure that plugins work over the widest range of AviSynth
// builds possible.
#define FRAME_ALIGN 64
#if defined(_M_AMD64) || defined(__x86_64)
# define X86_64
#elif defined(_M_IX86) || defined(__i386__)
# define X86_32
#else
# error Unsupported CPU architecture.
#endif
#if defined(_MSC_VER)
# define MSVC
#elif defined(__GNUC__)
# define GCC
#elif defined(__clang__)
# define CLANG
#else
# error Unsupported compiler.
#endif
#if defined(GCC)
# undef __forceinline
# define __forceinline inline
#endif
#endif //AVS_CONFIG_H

View File

@ -1,57 +0,0 @@
// Avisynth C Interface Version 0.20
// Copyright 2003 Kevin Atkinson
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
// http://www.gnu.org/copyleft/gpl.html .
//
// As a special exception, I give you permission to link to the
// Avisynth C interface with independent modules that communicate with
// the Avisynth C interface solely through the interfaces defined in
// avisynth_c.h, regardless of the license terms of these independent
// modules, and to copy and distribute the resulting combined work
// under terms of your choice, provided that every copy of the
// combined work is accompanied by a complete copy of the source code
// of the Avisynth C interface and Avisynth itself (with the version
// used to produce the combined work), being distributed under the
// terms of the GNU General Public License plus this exception. An
// independent module is a module which is not derived from or based
// on Avisynth C Interface, such as 3rd-party filters, import and
// export plugins, or graphical user interfaces.
#ifndef AVS_TYPES_H
#define AVS_TYPES_H
// Define all types necessary for interfacing with avisynth.dll
#ifdef __cplusplus
#include <cstddef>
#else
#include <stddef.h>
#endif
// Raster types used by VirtualDub & Avisynth
typedef unsigned int Pixel32;
typedef unsigned char BYTE;
// Audio Sample information
typedef float SFLOAT;
#ifdef __GNUC__
typedef long long int INT64;
#else
typedef __int64 INT64;
#endif
#endif //AVS_TYPES_H

View File

@ -1,728 +0,0 @@
// Avisynth C Interface Version 0.20
// Copyright 2003 Kevin Atkinson
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301 USA, or visit
// http://www.gnu.org/copyleft/gpl.html .
//
// As a special exception, I give you permission to link to the
// Avisynth C interface with independent modules that communicate with
// the Avisynth C interface solely through the interfaces defined in
// avisynth_c.h, regardless of the license terms of these independent
// modules, and to copy and distribute the resulting combined work
// under terms of your choice, provided that every copy of the
// combined work is accompanied by a complete copy of the source code
// of the Avisynth C interface and Avisynth itself (with the version
// used to produce the combined work), being distributed under the
// terms of the GNU General Public License plus this exception. An
// independent module is a module which is not derived from or based
// on Avisynth C Interface, such as 3rd-party filters, import and
// export plugins, or graphical user interfaces.
#ifndef __AVXSYNTH_C__
#define __AVXSYNTH_C__
#include "windowsPorts/windows2linux.h"
#include <stdarg.h>
#ifdef __cplusplus
# define EXTERN_C extern "C"
#else
# define EXTERN_C
#endif
#define AVSC_USE_STDCALL 1
#ifndef AVSC_USE_STDCALL
# define AVSC_CC __cdecl
#else
# define AVSC_CC __stdcall
#endif
#define AVSC_INLINE static __inline
#ifdef AVISYNTH_C_EXPORTS
# define AVSC_EXPORT EXTERN_C
# define AVSC_API(ret, name) EXTERN_C __declspec(dllexport) ret AVSC_CC name
#else
# define AVSC_EXPORT EXTERN_C __declspec(dllexport)
# ifndef AVSC_NO_DECLSPEC
# define AVSC_API(ret, name) EXTERN_C __declspec(dllimport) ret AVSC_CC name
# else
# define AVSC_API(ret, name) typedef ret (AVSC_CC *name##_func)
# endif
#endif
#ifdef __GNUC__
typedef long long int INT64;
#else
typedef __int64 INT64;
#endif
/////////////////////////////////////////////////////////////////////
//
// Constants
//
#ifndef __AVXSYNTH_H__
enum { AVISYNTH_INTERFACE_VERSION = 3 };
#endif
enum {AVS_SAMPLE_INT8 = 1<<0,
AVS_SAMPLE_INT16 = 1<<1,
AVS_SAMPLE_INT24 = 1<<2,
AVS_SAMPLE_INT32 = 1<<3,
AVS_SAMPLE_FLOAT = 1<<4};
enum {AVS_PLANAR_Y=1<<0,
AVS_PLANAR_U=1<<1,
AVS_PLANAR_V=1<<2,
AVS_PLANAR_ALIGNED=1<<3,
AVS_PLANAR_Y_ALIGNED=AVS_PLANAR_Y|AVS_PLANAR_ALIGNED,
AVS_PLANAR_U_ALIGNED=AVS_PLANAR_U|AVS_PLANAR_ALIGNED,
AVS_PLANAR_V_ALIGNED=AVS_PLANAR_V|AVS_PLANAR_ALIGNED};
// Colorspace properties.
enum {AVS_CS_BGR = 1<<28,
AVS_CS_YUV = 1<<29,
AVS_CS_INTERLEAVED = 1<<30,
AVS_CS_PLANAR = 1<<31};
// Specific colorformats
enum {
AVS_CS_UNKNOWN = 0,
AVS_CS_BGR24 = 1<<0 | AVS_CS_BGR | AVS_CS_INTERLEAVED,
AVS_CS_BGR32 = 1<<1 | AVS_CS_BGR | AVS_CS_INTERLEAVED,
AVS_CS_YUY2 = 1<<2 | AVS_CS_YUV | AVS_CS_INTERLEAVED,
AVS_CS_YV12 = 1<<3 | AVS_CS_YUV | AVS_CS_PLANAR, // y-v-u, planar
AVS_CS_I420 = 1<<4 | AVS_CS_YUV | AVS_CS_PLANAR, // y-u-v, planar
AVS_CS_IYUV = 1<<4 | AVS_CS_YUV | AVS_CS_PLANAR // same as above
};
enum {
AVS_IT_BFF = 1<<0,
AVS_IT_TFF = 1<<1,
AVS_IT_FIELDBASED = 1<<2};
enum {
AVS_FILTER_TYPE=1,
AVS_FILTER_INPUT_COLORSPACE=2,
AVS_FILTER_OUTPUT_TYPE=9,
AVS_FILTER_NAME=4,
AVS_FILTER_AUTHOR=5,
AVS_FILTER_VERSION=6,
AVS_FILTER_ARGS=7,
AVS_FILTER_ARGS_INFO=8,
AVS_FILTER_ARGS_DESCRIPTION=10,
AVS_FILTER_DESCRIPTION=11};
enum { //SUBTYPES
AVS_FILTER_TYPE_AUDIO=1,
AVS_FILTER_TYPE_VIDEO=2,
AVS_FILTER_OUTPUT_TYPE_SAME=3,
AVS_FILTER_OUTPUT_TYPE_DIFFERENT=4};
enum {
AVS_CACHE_NOTHING=0,
AVS_CACHE_RANGE=1,
AVS_CACHE_ALL=2,
AVS_CACHE_AUDIO=3,
AVS_CACHE_AUDIO_NONE=4,
AVS_CACHE_AUDIO_AUTO=5
};
#define AVS_FRAME_ALIGN 16
typedef struct AVS_Clip AVS_Clip;
typedef struct AVS_ScriptEnvironment AVS_ScriptEnvironment;
/////////////////////////////////////////////////////////////////////
//
// AVS_VideoInfo
//
// AVS_VideoInfo is layed out identicly to VideoInfo
typedef struct AVS_VideoInfo {
int width, height; // width=0 means no video
unsigned fps_numerator, fps_denominator;
int num_frames;
int pixel_type;
int audio_samples_per_second; // 0 means no audio
int sample_type;
INT64 num_audio_samples;
int nchannels;
// Imagetype properties
int image_type;
} AVS_VideoInfo;
// useful functions of the above
AVSC_INLINE int avs_has_video(const AVS_VideoInfo * p)
{ return (p->width!=0); }
AVSC_INLINE int avs_has_audio(const AVS_VideoInfo * p)
{ return (p->audio_samples_per_second!=0); }
AVSC_INLINE int avs_is_rgb(const AVS_VideoInfo * p)
{ return !!(p->pixel_type&AVS_CS_BGR); }
AVSC_INLINE int avs_is_rgb24(const AVS_VideoInfo * p)
{ return (p->pixel_type&AVS_CS_BGR24)==AVS_CS_BGR24; } // Clear out additional properties
AVSC_INLINE int avs_is_rgb32(const AVS_VideoInfo * p)
{ return (p->pixel_type & AVS_CS_BGR32) == AVS_CS_BGR32 ; }
AVSC_INLINE int avs_is_yuv(const AVS_VideoInfo * p)
{ return !!(p->pixel_type&AVS_CS_YUV ); }
AVSC_INLINE int avs_is_yuy2(const AVS_VideoInfo * p)
{ return (p->pixel_type & AVS_CS_YUY2) == AVS_CS_YUY2; }
AVSC_INLINE int avs_is_yv12(const AVS_VideoInfo * p)
{ return ((p->pixel_type & AVS_CS_YV12) == AVS_CS_YV12)||((p->pixel_type & AVS_CS_I420) == AVS_CS_I420); }
AVSC_INLINE int avs_is_color_space(const AVS_VideoInfo * p, int c_space)
{ return ((p->pixel_type & c_space) == c_space); }
AVSC_INLINE int avs_is_property(const AVS_VideoInfo * p, int property)
{ return ((p->pixel_type & property)==property ); }
AVSC_INLINE int avs_is_planar(const AVS_VideoInfo * p)
{ return !!(p->pixel_type & AVS_CS_PLANAR); }
AVSC_INLINE int avs_is_field_based(const AVS_VideoInfo * p)
{ return !!(p->image_type & AVS_IT_FIELDBASED); }
AVSC_INLINE int avs_is_parity_known(const AVS_VideoInfo * p)
{ return ((p->image_type & AVS_IT_FIELDBASED)&&(p->image_type & (AVS_IT_BFF | AVS_IT_TFF))); }
AVSC_INLINE int avs_is_bff(const AVS_VideoInfo * p)
{ return !!(p->image_type & AVS_IT_BFF); }
AVSC_INLINE int avs_is_tff(const AVS_VideoInfo * p)
{ return !!(p->image_type & AVS_IT_TFF); }
AVSC_INLINE int avs_bits_per_pixel(const AVS_VideoInfo * p)
{
switch (p->pixel_type) {
case AVS_CS_BGR24: return 24;
case AVS_CS_BGR32: return 32;
case AVS_CS_YUY2: return 16;
case AVS_CS_YV12:
case AVS_CS_I420: return 12;
default: return 0;
}
}
AVSC_INLINE int avs_bytes_from_pixels(const AVS_VideoInfo * p, int pixels)
{ return pixels * (avs_bits_per_pixel(p)>>3); } // Will work on planar images, but will return only luma planes
AVSC_INLINE int avs_row_size(const AVS_VideoInfo * p)
{ return avs_bytes_from_pixels(p,p->width); } // Also only returns first plane on planar images
AVSC_INLINE int avs_bmp_size(const AVS_VideoInfo * vi)
{ if (avs_is_planar(vi)) {int p = vi->height * ((avs_row_size(vi)+3) & ~3); p+=p>>1; return p; } return vi->height * ((avs_row_size(vi)+3) & ~3); }
AVSC_INLINE int avs_samples_per_second(const AVS_VideoInfo * p)
{ return p->audio_samples_per_second; }
AVSC_INLINE int avs_bytes_per_channel_sample(const AVS_VideoInfo * p)
{
switch (p->sample_type) {
case AVS_SAMPLE_INT8: return sizeof(signed char);
case AVS_SAMPLE_INT16: return sizeof(signed short);
case AVS_SAMPLE_INT24: return 3;
case AVS_SAMPLE_INT32: return sizeof(signed int);
case AVS_SAMPLE_FLOAT: return sizeof(float);
default: return 0;
}
}
AVSC_INLINE int avs_bytes_per_audio_sample(const AVS_VideoInfo * p)
{ return p->nchannels*avs_bytes_per_channel_sample(p);}
AVSC_INLINE INT64 avs_audio_samples_from_frames(const AVS_VideoInfo * p, INT64 frames)
{ return ((INT64)(frames) * p->audio_samples_per_second * p->fps_denominator / p->fps_numerator); }
AVSC_INLINE int avs_frames_from_audio_samples(const AVS_VideoInfo * p, INT64 samples)
{ return (int)(samples * (INT64)p->fps_numerator / (INT64)p->fps_denominator / (INT64)p->audio_samples_per_second); }
AVSC_INLINE INT64 avs_audio_samples_from_bytes(const AVS_VideoInfo * p, INT64 bytes)
{ return bytes / avs_bytes_per_audio_sample(p); }
AVSC_INLINE INT64 avs_bytes_from_audio_samples(const AVS_VideoInfo * p, INT64 samples)
{ return samples * avs_bytes_per_audio_sample(p); }
AVSC_INLINE int avs_audio_channels(const AVS_VideoInfo * p)
{ return p->nchannels; }
AVSC_INLINE int avs_sample_type(const AVS_VideoInfo * p)
{ return p->sample_type;}
// useful mutator
AVSC_INLINE void avs_set_property(AVS_VideoInfo * p, int property)
{ p->image_type|=property; }
AVSC_INLINE void avs_clear_property(AVS_VideoInfo * p, int property)
{ p->image_type&=~property; }
AVSC_INLINE void avs_set_field_based(AVS_VideoInfo * p, int isfieldbased)
{ if (isfieldbased) p->image_type|=AVS_IT_FIELDBASED; else p->image_type&=~AVS_IT_FIELDBASED; }
AVSC_INLINE void avs_set_fps(AVS_VideoInfo * p, unsigned numerator, unsigned denominator)
{
unsigned x=numerator, y=denominator;
while (y) { // find gcd
unsigned t = x%y; x = y; y = t;
}
p->fps_numerator = numerator/x;
p->fps_denominator = denominator/x;
}
AVSC_INLINE int avs_is_same_colorspace(AVS_VideoInfo * x, AVS_VideoInfo * y)
{
return (x->pixel_type == y->pixel_type)
|| (avs_is_yv12(x) && avs_is_yv12(y));
}
/////////////////////////////////////////////////////////////////////
//
// AVS_VideoFrame
//
// VideoFrameBuffer holds information about a memory block which is used
// for video data. For efficiency, instances of this class are not deleted
// when the refcount reaches zero; instead they're stored in a linked list
// to be reused. The instances are deleted when the corresponding AVS
// file is closed.
// AVS_VideoFrameBuffer is layed out identicly to VideoFrameBuffer
// DO NOT USE THIS STRUCTURE DIRECTLY
typedef struct AVS_VideoFrameBuffer {
unsigned char * data;
int data_size;
// sequence_number is incremented every time the buffer is changed, so
// that stale views can tell they're no longer valid.
long sequence_number;
long refcount;
} AVS_VideoFrameBuffer;
// VideoFrame holds a "window" into a VideoFrameBuffer.
// AVS_VideoFrame is layed out identicly to IVideoFrame
// DO NOT USE THIS STRUCTURE DIRECTLY
typedef struct AVS_VideoFrame {
int refcount;
AVS_VideoFrameBuffer * vfb;
int offset, pitch, row_size, height, offsetU, offsetV, pitchUV; // U&V offsets are from top of picture.
} AVS_VideoFrame;
// Access functions for AVS_VideoFrame
AVSC_INLINE int avs_get_pitch(const AVS_VideoFrame * p) {
return p->pitch;}
AVSC_INLINE int avs_get_pitch_p(const AVS_VideoFrame * p, int plane) {
switch (plane) {
case AVS_PLANAR_U: case AVS_PLANAR_V: return p->pitchUV;}
return p->pitch;}
AVSC_INLINE int avs_get_row_size(const AVS_VideoFrame * p) {
return p->row_size; }
AVSC_INLINE int avs_get_row_size_p(const AVS_VideoFrame * p, int plane) {
int r;
switch (plane) {
case AVS_PLANAR_U: case AVS_PLANAR_V:
if (p->pitchUV) return p->row_size>>1;
else return 0;
case AVS_PLANAR_U_ALIGNED: case AVS_PLANAR_V_ALIGNED:
if (p->pitchUV) {
r = ((p->row_size+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)) )>>1; // Aligned rowsize
if (r < p->pitchUV)
return r;
return p->row_size>>1;
} else return 0;
case AVS_PLANAR_Y_ALIGNED:
r = (p->row_size+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)); // Aligned rowsize
if (r <= p->pitch)
return r;
return p->row_size;
}
return p->row_size;
}
AVSC_INLINE int avs_get_height(const AVS_VideoFrame * p) {
return p->height;}
AVSC_INLINE int avs_get_height_p(const AVS_VideoFrame * p, int plane) {
switch (plane) {
case AVS_PLANAR_U: case AVS_PLANAR_V:
if (p->pitchUV) return p->height>>1;
return 0;
}
return p->height;}
AVSC_INLINE const unsigned char* avs_get_read_ptr(const AVS_VideoFrame * p) {
return p->vfb->data + p->offset;}
AVSC_INLINE const unsigned char* avs_get_read_ptr_p(const AVS_VideoFrame * p, int plane)
{
switch (plane) {
case AVS_PLANAR_U: return p->vfb->data + p->offsetU;
case AVS_PLANAR_V: return p->vfb->data + p->offsetV;
default: return p->vfb->data + p->offset;}
}
AVSC_INLINE int avs_is_writable(const AVS_VideoFrame * p) {
return (p->refcount == 1 && p->vfb->refcount == 1);}
AVSC_INLINE unsigned char* avs_get_write_ptr(const AVS_VideoFrame * p)
{
if (avs_is_writable(p)) {
++p->vfb->sequence_number;
return p->vfb->data + p->offset;
} else
return 0;
}
AVSC_INLINE unsigned char* avs_get_write_ptr_p(const AVS_VideoFrame * p, int plane)
{
if (plane==AVS_PLANAR_Y && avs_is_writable(p)) {
++p->vfb->sequence_number;
return p->vfb->data + p->offset;
} else if (plane==AVS_PLANAR_Y) {
return 0;
} else {
switch (plane) {
case AVS_PLANAR_U: return p->vfb->data + p->offsetU;
case AVS_PLANAR_V: return p->vfb->data + p->offsetV;
default: return p->vfb->data + p->offset;
}
}
}
#if defined __cplusplus
extern "C"
{
#endif // __cplusplus
AVSC_API(void, avs_release_video_frame)(AVS_VideoFrame *);
// makes a shallow copy of a video frame
AVSC_API(AVS_VideoFrame *, avs_copy_video_frame)(AVS_VideoFrame *);
#if defined __cplusplus
}
#endif // __cplusplus
#ifndef AVSC_NO_DECLSPEC
AVSC_INLINE void avs_release_frame(AVS_VideoFrame * f)
{avs_release_video_frame(f);}
AVSC_INLINE AVS_VideoFrame * avs_copy_frame(AVS_VideoFrame * f)
{return avs_copy_video_frame(f);}
#endif
/////////////////////////////////////////////////////////////////////
//
// AVS_Value
//
// Treat AVS_Value as a fat pointer. That is use avs_copy_value
// and avs_release_value appropiaty as you would if AVS_Value was
// a pointer.
// To maintain source code compatibility with future versions of the
// avisynth_c API don't use the AVS_Value directly. Use the helper
// functions below.
// AVS_Value is layed out identicly to AVSValue
typedef struct AVS_Value AVS_Value;
struct AVS_Value {
short type; // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, or 'l'ong
// for some function e'rror
short array_size;
union {
void * clip; // do not use directly, use avs_take_clip
char boolean;
int integer;
INT64 integer64; // match addition of __int64 to avxplugin.h
float floating_pt;
const char * string;
const AVS_Value * array;
} d;
};
// AVS_Value should be initilized with avs_void.
// Should also set to avs_void after the value is released
// with avs_copy_value. Consider it the equalvent of setting
// a pointer to NULL
static const AVS_Value avs_void = {'v'};
AVSC_API(void, avs_copy_value)(AVS_Value * dest, AVS_Value src);
AVSC_API(void, avs_release_value)(AVS_Value);
AVSC_INLINE int avs_defined(AVS_Value v) { return v.type != 'v'; }
AVSC_INLINE int avs_is_clip(AVS_Value v) { return v.type == 'c'; }
AVSC_INLINE int avs_is_bool(AVS_Value v) { return v.type == 'b'; }
AVSC_INLINE int avs_is_int(AVS_Value v) { return v.type == 'i'; }
AVSC_INLINE int avs_is_float(AVS_Value v) { return v.type == 'f' || v.type == 'i'; }
AVSC_INLINE int avs_is_string(AVS_Value v) { return v.type == 's'; }
AVSC_INLINE int avs_is_array(AVS_Value v) { return v.type == 'a'; }
AVSC_INLINE int avs_is_error(AVS_Value v) { return v.type == 'e'; }
#if defined __cplusplus
extern "C"
{
#endif // __cplusplus
AVSC_API(AVS_Clip *, avs_take_clip)(AVS_Value, AVS_ScriptEnvironment *);
AVSC_API(void, avs_set_to_clip)(AVS_Value *, AVS_Clip *);
#if defined __cplusplus
}
#endif // __cplusplus
AVSC_INLINE int avs_as_bool(AVS_Value v)
{ return v.d.boolean; }
AVSC_INLINE int avs_as_int(AVS_Value v)
{ return v.d.integer; }
AVSC_INLINE const char * avs_as_string(AVS_Value v)
{ return avs_is_error(v) || avs_is_string(v) ? v.d.string : 0; }
AVSC_INLINE double avs_as_float(AVS_Value v)
{ return avs_is_int(v) ? v.d.integer : v.d.floating_pt; }
AVSC_INLINE const char * avs_as_error(AVS_Value v)
{ return avs_is_error(v) ? v.d.string : 0; }
AVSC_INLINE const AVS_Value * avs_as_array(AVS_Value v)
{ return v.d.array; }
AVSC_INLINE int avs_array_size(AVS_Value v)
{ return avs_is_array(v) ? v.array_size : 1; }
AVSC_INLINE AVS_Value avs_array_elt(AVS_Value v, int index)
{ return avs_is_array(v) ? v.d.array[index] : v; }
// only use these functions on am AVS_Value that does not already have
// an active value. Remember, treat AVS_Value as a fat pointer.
AVSC_INLINE AVS_Value avs_new_value_bool(int v0)
{ AVS_Value v = {0}; v.type = 'b'; v.d.boolean = v0 == 0 ? 0 : 1; return v; }
AVSC_INLINE AVS_Value avs_new_value_int(int v0)
{ AVS_Value v = {0}; v.type = 'i'; v.d.integer = v0; return v; }
AVSC_INLINE AVS_Value avs_new_value_string(const char * v0)
{ AVS_Value v = {0}; v.type = 's'; v.d.string = v0; return v; }
AVSC_INLINE AVS_Value avs_new_value_float(float v0)
{ AVS_Value v = {0}; v.type = 'f'; v.d.floating_pt = v0; return v;}
AVSC_INLINE AVS_Value avs_new_value_error(const char * v0)
{ AVS_Value v = {0}; v.type = 'e'; v.d.string = v0; return v; }
#ifndef AVSC_NO_DECLSPEC
AVSC_INLINE AVS_Value avs_new_value_clip(AVS_Clip * v0)
{ AVS_Value v = {0}; avs_set_to_clip(&v, v0); return v; }
#endif
AVSC_INLINE AVS_Value avs_new_value_array(AVS_Value * v0, int size)
{ AVS_Value v = {0}; v.type = 'a'; v.d.array = v0; v.array_size = size; return v; }
/////////////////////////////////////////////////////////////////////
//
// AVS_Clip
//
#if defined __cplusplus
extern "C"
{
#endif // __cplusplus
AVSC_API(void, avs_release_clip)(AVS_Clip *);
AVSC_API(AVS_Clip *, avs_copy_clip)(AVS_Clip *);
AVSC_API(const char *, avs_clip_get_error)(AVS_Clip *); // return 0 if no error
AVSC_API(const AVS_VideoInfo *, avs_get_video_info)(AVS_Clip *);
AVSC_API(int, avs_get_version)(AVS_Clip *);
AVSC_API(AVS_VideoFrame *, avs_get_frame)(AVS_Clip *, int n);
// The returned video frame must be released with avs_release_video_frame
AVSC_API(int, avs_get_parity)(AVS_Clip *, int n);
// return field parity if field_based, else parity of first field in frame
AVSC_API(int, avs_get_audio)(AVS_Clip *, void * buf,
INT64 start, INT64 count);
// start and count are in samples
AVSC_API(int, avs_set_cache_hints)(AVS_Clip *,
int cachehints, size_t frame_range);
#if defined __cplusplus
}
#endif // __cplusplus
// This is the callback type used by avs_add_function
typedef AVS_Value (AVSC_CC * AVS_ApplyFunc)
(AVS_ScriptEnvironment *, AVS_Value args, void * user_data);
typedef struct AVS_FilterInfo AVS_FilterInfo;
struct AVS_FilterInfo
{
// these members should not be modified outside of the AVS_ApplyFunc callback
AVS_Clip * child;
AVS_VideoInfo vi;
AVS_ScriptEnvironment * env;
AVS_VideoFrame * (AVSC_CC * get_frame)(AVS_FilterInfo *, int n);
int (AVSC_CC * get_parity)(AVS_FilterInfo *, int n);
int (AVSC_CC * get_audio)(AVS_FilterInfo *, void * buf,
INT64 start, INT64 count);
int (AVSC_CC * set_cache_hints)(AVS_FilterInfo *, int cachehints,
int frame_range);
void (AVSC_CC * free_filter)(AVS_FilterInfo *);
// Should be set when ever there is an error to report.
// It is cleared before any of the above methods are called
const char * error;
// this is to store whatever and may be modified at will
void * user_data;
};
// Create a new filter
// fi is set to point to the AVS_FilterInfo so that you can
// modify it once it is initilized.
// store_child should generally be set to true. If it is not
// set than ALL methods (the function pointers) must be defined
// If it is set than you do not need to worry about freeing the child
// clip.
#if defined __cplusplus
extern "C"
{
#endif // __cplusplus
AVSC_API(AVS_Clip *, avs_new_c_filter)(AVS_ScriptEnvironment * e,
AVS_FilterInfo * * fi,
AVS_Value child, int store_child);
#if defined __cplusplus
}
#endif // __cplusplus
/////////////////////////////////////////////////////////////////////
//
// AVS_ScriptEnvironment
//
// For GetCPUFlags. These are backwards-compatible with those in VirtualDub.
enum {
/* slowest CPU to support extension */
AVS_CPU_FORCE = 0x01, // N/A
AVS_CPU_FPU = 0x02, // 386/486DX
AVS_CPU_MMX = 0x04, // P55C, K6, PII
AVS_CPU_INTEGER_SSE = 0x08, // PIII, Athlon
AVS_CPU_SSE = 0x10, // PIII, Athlon XP/MP
AVS_CPU_SSE2 = 0x20, // PIV, Hammer
AVS_CPU_3DNOW = 0x40, // K6-2
AVS_CPU_3DNOW_EXT = 0x80, // Athlon
AVS_CPU_X86_64 = 0xA0, // Hammer (note: equiv. to 3DNow + SSE2,
// which only Hammer will have anyway)
};
#if defined __cplusplus
extern "C"
{
#endif // __cplusplus
AVSC_API(const char *, avs_get_error)(AVS_ScriptEnvironment *); // return 0 if no error
AVSC_API(long, avs_get_cpu_flags)(AVS_ScriptEnvironment *);
AVSC_API(int, avs_check_version)(AVS_ScriptEnvironment *, int version);
AVSC_API(char *, avs_save_string)(AVS_ScriptEnvironment *, const char* s, int length);
AVSC_API(char *, avs_sprintf)(AVS_ScriptEnvironment *, const char * fmt, ...);
AVSC_API(char *, avs_vsprintf)(AVS_ScriptEnvironment *, const char * fmt, va_list val);
// note: val is really a va_list; I hope everyone typedefs va_list to a pointer
AVSC_API(int, avs_add_function)(AVS_ScriptEnvironment *,
const char * name, const char * params,
AVS_ApplyFunc apply, void * user_data);
AVSC_API(int, avs_function_exists)(AVS_ScriptEnvironment *, const char * name);
AVSC_API(AVS_Value, avs_invoke)(AVS_ScriptEnvironment *, const char * name,
AVS_Value args, const char** arg_names);
// The returned value must be be released with avs_release_value
AVSC_API(AVS_Value, avs_get_var)(AVS_ScriptEnvironment *, const char* name);
// The returned value must be be released with avs_release_value
AVSC_API(int, avs_set_var)(AVS_ScriptEnvironment *, const char* name, AVS_Value val);
AVSC_API(int, avs_set_global_var)(AVS_ScriptEnvironment *, const char* name, const AVS_Value val);
//void avs_push_context(AVS_ScriptEnvironment *, int level=0);
//void avs_pop_context(AVS_ScriptEnvironment *);
AVSC_API(AVS_VideoFrame *, avs_new_video_frame_a)(AVS_ScriptEnvironment *,
const AVS_VideoInfo * vi, int align);
// align should be at least 16
#if defined __cplusplus
}
#endif // __cplusplus
#ifndef AVSC_NO_DECLSPEC
AVSC_INLINE
AVS_VideoFrame * avs_new_video_frame(AVS_ScriptEnvironment * env,
const AVS_VideoInfo * vi)
{return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);}
AVSC_INLINE
AVS_VideoFrame * avs_new_frame(AVS_ScriptEnvironment * env,
const AVS_VideoInfo * vi)
{return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);}
#endif
#if defined __cplusplus
extern "C"
{
#endif // __cplusplus
AVSC_API(int, avs_make_writable)(AVS_ScriptEnvironment *, AVS_VideoFrame * * pvf);
AVSC_API(void, avs_bit_blt)(AVS_ScriptEnvironment *, unsigned char* dstp, int dst_pitch, const unsigned char* srcp, int src_pitch, int row_size, int height);
typedef void (AVSC_CC *AVS_ShutdownFunc)(void* user_data, AVS_ScriptEnvironment * env);
AVSC_API(void, avs_at_exit)(AVS_ScriptEnvironment *, AVS_ShutdownFunc function, void * user_data);
AVSC_API(AVS_VideoFrame *, avs_subframe)(AVS_ScriptEnvironment *, AVS_VideoFrame * src, int rel_offset, int new_pitch, int new_row_size, int new_height);
// The returned video frame must be be released
AVSC_API(int, avs_set_memory_max)(AVS_ScriptEnvironment *, int mem);
AVSC_API(int, avs_set_working_dir)(AVS_ScriptEnvironment *, const char * newdir);
// avisynth.dll exports this; it's a way to use it as a library, without
// writing an AVS script or without going through AVIFile.
AVSC_API(AVS_ScriptEnvironment *, avs_create_script_environment)(int version);
#if defined __cplusplus
}
#endif // __cplusplus
// this symbol is the entry point for the plugin and must
// be defined
AVSC_EXPORT
const char * AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env);
#if defined __cplusplus
extern "C"
{
#endif // __cplusplus
AVSC_API(void, avs_delete_script_environment)(AVS_ScriptEnvironment *);
AVSC_API(AVS_VideoFrame *, avs_subframe_planar)(AVS_ScriptEnvironment *, AVS_VideoFrame * src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV);
// The returned video frame must be be released
#if defined __cplusplus
}
#endif // __cplusplus
#endif //__AVXSYNTH_C__

View File

@ -1,85 +0,0 @@
#ifndef __DATA_TYPE_CONVERSIONS_H__
#define __DATA_TYPE_CONVERSIONS_H__
#include <stdint.h>
#include <wchar.h>
#ifdef __cplusplus
namespace avxsynth {
#endif // __cplusplus
typedef int64_t __int64;
typedef int32_t __int32;
#ifdef __cplusplus
typedef bool BOOL;
#else
typedef uint32_t BOOL;
#endif // __cplusplus
typedef void* HMODULE;
typedef void* LPVOID;
typedef void* PVOID;
typedef PVOID HANDLE;
typedef HANDLE HWND;
typedef HANDLE HINSTANCE;
typedef void* HDC;
typedef void* HBITMAP;
typedef void* HICON;
typedef void* HFONT;
typedef void* HGDIOBJ;
typedef void* HBRUSH;
typedef void* HMMIO;
typedef void* HACMSTREAM;
typedef void* HACMDRIVER;
typedef void* HIC;
typedef void* HACMOBJ;
typedef HACMSTREAM* LPHACMSTREAM;
typedef void* HACMDRIVERID;
typedef void* LPHACMDRIVER;
typedef unsigned char BYTE;
typedef BYTE* LPBYTE;
typedef char TCHAR;
typedef TCHAR* LPTSTR;
typedef const TCHAR* LPCTSTR;
typedef char* LPSTR;
typedef LPSTR LPOLESTR;
typedef const char* LPCSTR;
typedef LPCSTR LPCOLESTR;
typedef wchar_t WCHAR;
typedef unsigned short WORD;
typedef unsigned int UINT;
typedef UINT MMRESULT;
typedef uint32_t DWORD;
typedef DWORD COLORREF;
typedef DWORD FOURCC;
typedef DWORD HRESULT;
typedef DWORD* LPDWORD;
typedef DWORD* DWORD_PTR;
typedef int32_t LONG;
typedef int32_t* LONG_PTR;
typedef LONG_PTR LRESULT;
typedef uint32_t ULONG;
typedef uint32_t* ULONG_PTR;
//typedef __int64_t intptr_t;
typedef uint64_t _fsize_t;
//
// Structures
//
typedef struct _GUID {
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[8];
} GUID;
typedef GUID REFIID;
typedef GUID CLSID;
typedef CLSID* LPCLSID;
typedef GUID IID;
#ifdef __cplusplus
}; // namespace avxsynth
#endif // __cplusplus
#endif // __DATA_TYPE_CONVERSIONS_H__

View File

@ -1,77 +0,0 @@
#ifndef __WINDOWS2LINUX_H__
#define __WINDOWS2LINUX_H__
/*
* LINUX SPECIFIC DEFINITIONS
*/
//
// Data types conversions
//
#include <stdlib.h>
#include <string.h>
#include "basicDataTypeConversions.h"
#ifdef __cplusplus
namespace avxsynth {
#endif // __cplusplus
//
// purposefully define the following MSFT definitions
// to mean nothing (as they do not mean anything on Linux)
//
#define __stdcall
#define __cdecl
#define noreturn
#define __declspec(x)
#define STDAPI extern "C" HRESULT
#define STDMETHODIMP HRESULT __stdcall
#define STDMETHODIMP_(x) x __stdcall
#define STDMETHOD(x) virtual HRESULT x
#define STDMETHOD_(a, x) virtual a x
#ifndef TRUE
#define TRUE true
#endif
#ifndef FALSE
#define FALSE false
#endif
#define S_OK (0x00000000)
#define S_FALSE (0x00000001)
#define E_NOINTERFACE (0X80004002)
#define E_POINTER (0x80004003)
#define E_FAIL (0x80004005)
#define E_OUTOFMEMORY (0x8007000E)
#define INVALID_HANDLE_VALUE ((HANDLE)((LONG_PTR)-1))
#define FAILED(hr) ((hr) & 0x80000000)
#define SUCCEEDED(hr) (!FAILED(hr))
//
// Functions
//
#define MAKEDWORD(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
#define MAKEWORD(a,b) (((a) << 8) | (b))
#define lstrlen strlen
#define lstrcpy strcpy
#define lstrcmpi strcasecmp
#define _stricmp strcasecmp
#define InterlockedIncrement(x) __sync_fetch_and_add((x), 1)
#define InterlockedDecrement(x) __sync_fetch_and_sub((x), 1)
// Windows uses (new, old) ordering but GCC has (old, new)
#define InterlockedCompareExchange(x,y,z) __sync_val_compare_and_swap(x,z,y)
#define UInt32x32To64(a, b) ( (uint64_t) ( ((uint64_t)((uint32_t)(a))) * ((uint32_t)(b)) ) )
#define Int64ShrlMod32(a, b) ( (uint64_t) ( (uint64_t)(a) >> (b) ) )
#define Int32x32To64(a, b) ((__int64)(((__int64)((long)(a))) * ((long)(b))))
#define MulDiv(nNumber, nNumerator, nDenominator) (int32_t) (((int64_t) (nNumber) * (int64_t) (nNumerator) + (int64_t) ((nDenominator)/2)) / (int64_t) (nDenominator))
#ifdef __cplusplus
}; // namespace avxsynth
#endif // __cplusplus
#endif // __WINDOWS2LINUX_H__

View File

@ -1,7 +1,7 @@
/*
* Minimum CUDA compatibility definitions header
*
* Copyright (c) 2019 Rodger Combs
* Copyright (c) 2019 rcombs
*
* This file is part of FFmpeg.
*
@ -49,6 +49,16 @@ typedef struct __device_builtin__ __align__(4) ushort2
unsigned short x, y;
} ushort2;
typedef struct __device_builtin__ __align__(8) float2
{
float x, y;
} float2;
typedef struct __device_builtin__ __align__(8) int2
{
int x, y;
} int2;
typedef struct __device_builtin__ uint3
{
unsigned int x, y, z;
@ -56,11 +66,6 @@ typedef struct __device_builtin__ uint3
typedef struct uint3 dim3;
typedef struct __device_builtin__ __align__(8) int2
{
int x, y;
} int2;
typedef struct __device_builtin__ __align__(4) uchar4
{
unsigned char x, y, z, w;
@ -68,7 +73,7 @@ typedef struct __device_builtin__ __align__(4) uchar4
typedef struct __device_builtin__ __align__(8) ushort4
{
unsigned char x, y, z, w;
unsigned short x, y, z, w;
} ushort4;
typedef struct __device_builtin__ __align__(16) int4
@ -76,6 +81,11 @@ typedef struct __device_builtin__ __align__(16) int4
int x, y, z, w;
} int4;
typedef struct __device_builtin__ __align__(16) float4
{
float x, y, z, w;
} float4;
// Accessors for special registers
#define GETCOMP(reg, comp) \
asm("mov.u32 %0, %%" #reg "." #comp ";" : "=r"(tmp)); \
@ -100,24 +110,31 @@ GET(getThreadIdx, tid)
#define threadIdx (getThreadIdx())
// Basic initializers (simple macros rather than inline functions)
#define make_int2(a, b) ((int2){.x = a, .y = b})
#define make_uchar2(a, b) ((uchar2){.x = a, .y = b})
#define make_ushort2(a, b) ((ushort2){.x = a, .y = b})
#define make_float2(a, b) ((float2){.x = a, .y = b})
#define make_int4(a, b, c, d) ((int4){.x = a, .y = b, .z = c, .w = d})
#define make_uchar4(a, b, c, d) ((uchar4){.x = a, .y = b, .z = c, .w = d})
#define make_ushort4(a, b, c, d) ((ushort4){.x = a, .y = b, .z = c, .w = d})
#define make_float4(a, b, c, d) ((float4){.x = a, .y = b, .z = c, .w = d})
// Conversions from the tex instruction's 4-register output to various types
#define TEX2D(type, ret) static inline __device__ void conv(type* out, unsigned a, unsigned b, unsigned c, unsigned d) {*out = (ret);}
TEX2D(unsigned char, a & 0xFF)
TEX2D(unsigned short, a & 0xFFFF)
TEX2D(float, a)
TEX2D(uchar2, make_uchar2(a & 0xFF, b & 0xFF))
TEX2D(ushort2, make_ushort2(a & 0xFFFF, b & 0xFFFF))
TEX2D(float2, make_float2(a, b))
TEX2D(uchar4, make_uchar4(a & 0xFF, b & 0xFF, c & 0xFF, d & 0xFF))
TEX2D(ushort4, make_ushort4(a & 0xFFFF, b & 0xFFFF, c & 0xFFFF, d & 0xFFFF))
TEX2D(float4, make_float4(a, b, c, d))
// Template calling tex instruction and converting the output to the selected type
template <class T>
static inline __device__ T tex2D(cudaTextureObject_t texObject, float x, float y)
template<typename T>
inline __device__ T tex2D(cudaTextureObject_t texObject, float x, float y)
{
T ret;
unsigned ret1, ret2, ret3, ret4;
@ -128,4 +145,47 @@ static inline __device__ T tex2D(cudaTextureObject_t texObject, float x, float y
return ret;
}
template<>
inline __device__ float4 tex2D<float4>(cudaTextureObject_t texObject, float x, float y)
{
float4 ret;
asm("tex.2d.v4.f32.f32 {%0, %1, %2, %3}, [%4, {%5, %6}];" :
"=r"(ret.x), "=r"(ret.y), "=r"(ret.z), "=r"(ret.w) :
"l"(texObject), "f"(x), "f"(y));
return ret;
}
template<>
inline __device__ float tex2D<float>(cudaTextureObject_t texObject, float x, float y)
{
return tex2D<float4>(texObject, x, y).x;
}
template<>
inline __device__ float2 tex2D<float2>(cudaTextureObject_t texObject, float x, float y)
{
float4 ret = tex2D<float4>(texObject, x, y);
return make_float2(ret.x, ret.y);
}
// Math helper functions
static inline __device__ float floorf(float a) { return __builtin_floorf(a); }
static inline __device__ float floor(float a) { return __builtin_floorf(a); }
static inline __device__ double floor(double a) { return __builtin_floor(a); }
static inline __device__ float ceilf(float a) { return __builtin_ceilf(a); }
static inline __device__ float ceil(float a) { return __builtin_ceilf(a); }
static inline __device__ double ceil(double a) { return __builtin_ceil(a); }
static inline __device__ float truncf(float a) { return __builtin_truncf(a); }
static inline __device__ float trunc(float a) { return __builtin_truncf(a); }
static inline __device__ double trunc(double a) { return __builtin_trunc(a); }
static inline __device__ float fabsf(float a) { return __builtin_fabsf(a); }
static inline __device__ float fabs(float a) { return __builtin_fabsf(a); }
static inline __device__ double fabs(double a) { return __builtin_fabs(a); }
static inline __device__ float sqrtf(float a) { return __builtin_sqrtf(a); }
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))); }
#endif /* COMPAT_CUDA_CUDA_RUNTIME_H */

View File

@ -1,36 +0,0 @@
#!/bin/sh
# Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
#
# 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.
set -e
OUT="$1"
IN="$2"
NAME="$(basename "$IN" | sed 's/\..*//')"
printf "const char %s_ptx[] = \\" "$NAME" > "$OUT"
while IFS= read -r LINE
do
printf "\n\t\"%s\\\n\"" "$(printf "%s" "$LINE" | sed -e 's/\r//g' -e 's/["\\]/\\&/g')" >> "$OUT"
done < "$IN"
printf ";\n" >> "$OUT"
exit 0

View File

@ -59,7 +59,7 @@ int avpriv_vsnprintf(char *s, size_t n, const char *fmt,
* recommends to provide _snprintf/_vsnprintf() a buffer size that
* is one less than the actual buffer, and zero it before calling
* _snprintf/_vsnprintf() to workaround this problem.
* See http://msdn.microsoft.com/en-us/library/1kt27hek(v=vs.80).aspx */
* See https://web.archive.org/web/20151214111935/http://msdn.microsoft.com/en-us/library/1kt27hek(v=vs.80).aspx */
memset(s, 0, n);
va_copy(ap_copy, ap);
ret = _vsnprintf(s, n - 1, fmt, ap_copy);

View File

@ -27,15 +27,19 @@
#define COMPAT_OS2THREADS_H
#define INCL_DOS
#define INCL_DOSERRORS
#include <os2.h>
#undef __STRICT_ANSI__ /* for _beginthread() */
#include <stdlib.h>
#include <time.h>
#include <sys/builtin.h>
#include <sys/fmutex.h>
#include "libavutil/attributes.h"
#include "libavutil/common.h"
#include "libavutil/time.h"
typedef struct {
TID tid;
@ -163,6 +167,28 @@ static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
return 0;
}
static av_always_inline int pthread_cond_timedwait(pthread_cond_t *cond,
pthread_mutex_t *mutex,
const struct timespec *abstime)
{
int64_t abs_milli = abstime->tv_sec * 1000LL + abstime->tv_nsec / 1000000;
ULONG t = av_clip64(abs_milli - av_gettime() / 1000, 0, ULONG_MAX);
__atomic_increment(&cond->wait_count);
pthread_mutex_unlock(mutex);
APIRET ret = DosWaitEventSem(cond->event_sem, t);
__atomic_decrement(&cond->wait_count);
DosPostEventSem(cond->ack_sem);
pthread_mutex_lock(mutex);
return (ret == ERROR_TIMEOUT) ? ETIMEDOUT : 0;
}
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond,
pthread_mutex_t *mutex)
{

View File

@ -20,11 +20,40 @@
#define COMPAT_W32DLFCN_H
#ifdef _WIN32
#include <stdint.h>
#include <windows.h>
#include "config.h"
#if (_WIN32_WINNT < 0x0602) || HAVE_WINRT
#include "libavutil/macros.h"
#include "libavutil/wchar_filename.h"
#endif
static inline wchar_t *get_module_filename(HMODULE module)
{
wchar_t *path = NULL, *new_path;
DWORD path_size = 0, path_len;
do {
path_size = path_size ? FFMIN(2 * path_size, INT16_MAX + 1) : MAX_PATH;
new_path = av_realloc_array(path, path_size, sizeof *path);
if (!new_path) {
av_free(path);
return NULL;
}
path = new_path;
// Returns path_size in case of insufficient buffer.
// Whether the error is set or not and whether the output
// is null-terminated or not depends on the version of Windows.
path_len = GetModuleFileNameW(module, path, path_size);
} while (path_len && path_size <= INT16_MAX && path_size <= path_len);
if (!path_len) {
av_free(path);
return NULL;
}
return path;
}
/**
* Safe function used to open dynamic libs. This attempts to improve program security
* by removing the current directory from the dll search path. Only dll's found in the
@ -34,29 +63,53 @@
*/
static inline HMODULE win32_dlopen(const char *name)
{
wchar_t *name_w;
HMODULE module = NULL;
if (utf8towchar(name, &name_w))
name_w = NULL;
#if _WIN32_WINNT < 0x0602
// Need to check if KB2533623 is available
// On Win7 and earlier we check if KB2533623 is available
if (!GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetDefaultDllDirectories")) {
HMODULE module = NULL;
wchar_t *path = NULL, *name_w = NULL;
DWORD pathlen;
if (utf8towchar(name, &name_w))
wchar_t *path = NULL, *new_path;
DWORD pathlen, pathsize, namelen;
if (!name_w)
goto exit;
path = (wchar_t *)av_mallocz_array(MAX_PATH, sizeof(wchar_t));
namelen = wcslen(name_w);
// Try local directory first
pathlen = GetModuleFileNameW(NULL, path, MAX_PATH);
pathlen = wcsrchr(path, '\\') - path;
if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH)
path = get_module_filename(NULL);
if (!path)
goto exit;
path[pathlen] = '\\';
new_path = wcsrchr(path, '\\');
if (!new_path)
goto exit;
pathlen = new_path - path;
pathsize = pathlen + namelen + 2;
new_path = av_realloc_array(path, pathsize, sizeof *path);
if (!new_path)
goto exit;
path = new_path;
wcscpy(path + pathlen + 1, name_w);
module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (module == NULL) {
// Next try System32 directory
pathlen = GetSystemDirectoryW(path, MAX_PATH);
if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH)
pathlen = GetSystemDirectoryW(path, pathsize);
if (!pathlen)
goto exit;
path[pathlen] = '\\';
// Buffer is not enough in two cases:
// 1. system directory + \ + module name
// 2. system directory even without the module name.
if (pathlen + namelen + 2 > pathsize) {
pathsize = pathlen + namelen + 2;
new_path = av_realloc_array(path, pathsize, sizeof *path);
if (!new_path)
goto exit;
path = new_path;
// Query again to handle the case #2.
pathlen = GetSystemDirectoryW(path, pathsize);
if (!pathlen)
goto exit;
}
path[pathlen] = L'\\';
wcscpy(path + pathlen + 1, name_w);
module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
}
@ -73,16 +126,19 @@ exit:
# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
#endif
#if HAVE_WINRT
wchar_t *name_w = NULL;
int ret;
if (utf8towchar(name, &name_w))
if (!name_w)
return NULL;
ret = LoadPackagedLibrary(name_w, 0);
av_free(name_w);
return ret;
module = LoadPackagedLibrary(name_w, 0);
#else
return LoadLibraryExA(name, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
#define LOAD_FLAGS (LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32)
/* filename may be be in CP_ACP */
if (!name_w)
return LoadLibraryExA(name, NULL, LOAD_FLAGS);
module = LoadLibraryExW(name_w, NULL, LOAD_FLAGS);
#undef LOAD_FLAGS
#endif
av_free(name_w);
return module;
}
#define dlopen(name, flags) win32_dlopen(name)
#define dlclose FreeLibrary

View File

@ -38,11 +38,13 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <process.h>
#include <time.h>
#include "libavutil/attributes.h"
#include "libavutil/common.h"
#include "libavutil/internal.h"
#include "libavutil/mem.h"
#include "libavutil/time.h"
typedef struct pthread_t {
void *handle;
@ -61,6 +63,9 @@ typedef CONDITION_VARIABLE pthread_cond_t;
#define InitializeCriticalSection(x) InitializeCriticalSectionEx(x, 0, 0)
#define WaitForSingleObject(a, b) WaitForSingleObjectEx(a, b, FALSE)
#define PTHREAD_CANCEL_ENABLE 1
#define PTHREAD_CANCEL_DISABLE 0
static av_unused unsigned __stdcall attribute_align_arg win32thread_worker(void *arg)
{
pthread_t *h = (pthread_t*)arg;
@ -156,10 +161,31 @@ static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex
return 0;
}
static inline int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime)
{
int64_t abs_milli = abstime->tv_sec * 1000LL + abstime->tv_nsec / 1000000;
DWORD t = av_clip64(abs_milli - av_gettime() / 1000, 0, UINT32_MAX);
if (!SleepConditionVariableSRW(cond, mutex, t, 0)) {
DWORD err = GetLastError();
if (err == ERROR_TIMEOUT)
return ETIMEDOUT;
else
return EINVAL;
}
return 0;
}
static inline int pthread_cond_signal(pthread_cond_t *cond)
{
WakeConditionVariable(cond);
return 0;
}
static inline int pthread_setcancelstate(int state, int *oldstate)
{
return 0;
}
#endif /* COMPAT_W32PTHREADS_H */

1091
configure vendored

File diff suppressed because it is too large Load Diff

6
debian/changelog vendored
View File

@ -1,8 +1,8 @@
ffmpeg (7:4.2.2-ok3) yangtze; urgency=medium
ffmpeg (7:5.1.1-ok1) yangtze; urgency=medium
* update version info
* Update upstream version.
-- luzhiping <luzhiping@kylinos.cn> Mon, 22 Aug 2022 13:53:40 +0800
-- sufang <sufang@kylinos.cn> Tue, 28 Mar 2023 10:11:44 +0800
ffmpeg (7:4.2.2-ok2) yangtze; urgency=medium

2
debian/control vendored
View File

@ -1,7 +1,7 @@
Source: ffmpeg
Section: video
Priority: optional
Maintainer: Openkylin Developers <packaging@lists.openkylin.top>
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
XSBC-Original-Maintainer: Debian Multimedia Maintainers <debian-multimedia@lists.debian.org>
Uploaders: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>,
Alexander Strasser <eclipse7@gmx.net>,

View File

@ -0,0 +1,287 @@
From: James Cowgill <jcowgill@debian.org>
Date: Sun, 11 Aug 2019 16:50:56 +0100
Subject: [PATCH v2] avcodec/arm/sbcenc: avoid callee preserved vfp registers
When compiling FFmpeg with GCC-9, some very random segfaults were
observed in code which had previously called down into the SBC encoder
NEON assembly routines. This was caused by these functions clobbering
some of the vfp callee saved registers (d8 - d15 aka q4 - q7). GCC was
using these registers to save local variables, but after these
functions returned, they would contain garbage.
Fix by reallocating the registers in the two affected functions in
the following way:
ff_sbc_analyze_4_neon: q2-q5 => q8-q11, then q1-q4 => q8-q11
ff_sbc_analyze_8_neon: q2-q9 => q8-q15
The reason for using these replacements is to keep closely related
sets of registers consecutively numbered which hopefully makes the
code more easy to follow. Since this commit only reallocates
registers, it should have no performance impact.
Signed-off-by: James Cowgill <jcowgill@debian.org>
---
libavcodec/arm/sbcdsp_neon.S | 220 +++++++++++++++++++++----------------------
1 file changed, 110 insertions(+), 110 deletions(-)
diff --git a/libavcodec/arm/sbcdsp_neon.S b/libavcodec/arm/sbcdsp_neon.S
index d83d21d..914abfb 100644
--- a/libavcodec/arm/sbcdsp_neon.S
+++ b/libavcodec/arm/sbcdsp_neon.S
@@ -38,49 +38,49 @@ function ff_sbc_analyze_4_neon, export=1
/* TODO: merge even and odd cases (or even merge all four calls to this
* function) in order to have only aligned reads from 'in' array
* and reduce number of load instructions */
- vld1.16 {d4, d5}, [r0, :64]!
- vld1.16 {d8, d9}, [r2, :128]!
+ vld1.16 {d16, d17}, [r0, :64]!
+ vld1.16 {d20, d21}, [r2, :128]!
- vmull.s16 q0, d4, d8
- vld1.16 {d6, d7}, [r0, :64]!
- vmull.s16 q1, d5, d9
- vld1.16 {d10, d11}, [r2, :128]!
+ vmull.s16 q0, d16, d20
+ vld1.16 {d18, d19}, [r0, :64]!
+ vmull.s16 q1, d17, d21
+ vld1.16 {d22, d23}, [r2, :128]!
- vmlal.s16 q0, d6, d10
- vld1.16 {d4, d5}, [r0, :64]!
- vmlal.s16 q1, d7, d11
- vld1.16 {d8, d9}, [r2, :128]!
+ vmlal.s16 q0, d18, d22
+ vld1.16 {d16, d17}, [r0, :64]!
+ vmlal.s16 q1, d19, d23
+ vld1.16 {d20, d21}, [r2, :128]!
- vmlal.s16 q0, d4, d8
- vld1.16 {d6, d7}, [r0, :64]!
- vmlal.s16 q1, d5, d9
- vld1.16 {d10, d11}, [r2, :128]!
+ vmlal.s16 q0, d16, d20
+ vld1.16 {d18, d19}, [r0, :64]!
+ vmlal.s16 q1, d17, d21
+ vld1.16 {d22, d23}, [r2, :128]!
- vmlal.s16 q0, d6, d10
- vld1.16 {d4, d5}, [r0, :64]!
- vmlal.s16 q1, d7, d11
- vld1.16 {d8, d9}, [r2, :128]!
+ vmlal.s16 q0, d18, d22
+ vld1.16 {d16, d17}, [r0, :64]!
+ vmlal.s16 q1, d19, d23
+ vld1.16 {d20, d21}, [r2, :128]!
- vmlal.s16 q0, d4, d8
- vmlal.s16 q1, d5, d9
+ vmlal.s16 q0, d16, d20
+ vmlal.s16 q1, d17, d21
vpadd.s32 d0, d0, d1
vpadd.s32 d1, d2, d3
vrshrn.s32 d0, q0, SBC_PROTO_FIXED_SCALE
- vld1.16 {d2, d3, d4, d5}, [r2, :128]!
+ vld1.16 {d16, d17, d18, d19}, [r2, :128]!
vdup.i32 d1, d0[1] /* TODO: can be eliminated */
vdup.i32 d0, d0[0] /* TODO: can be eliminated */
- vmull.s16 q3, d2, d0
- vmull.s16 q4, d3, d0
- vmlal.s16 q3, d4, d1
- vmlal.s16 q4, d5, d1
+ vmull.s16 q10, d16, d0
+ vmull.s16 q11, d17, d0
+ vmlal.s16 q10, d18, d1
+ vmlal.s16 q11, d19, d1
- vpadd.s32 d0, d6, d7 /* TODO: can be eliminated */
- vpadd.s32 d1, d8, d9 /* TODO: can be eliminated */
+ vpadd.s32 d0, d20, d21 /* TODO: can be eliminated */
+ vpadd.s32 d1, d22, d23 /* TODO: can be eliminated */
vst1.32 {d0, d1}, [r1, :128]
@@ -91,57 +91,57 @@ function ff_sbc_analyze_8_neon, export=1
/* TODO: merge even and odd cases (or even merge all four calls to this
* function) in order to have only aligned reads from 'in' array
* and reduce number of load instructions */
- vld1.16 {d4, d5}, [r0, :64]!
- vld1.16 {d8, d9}, [r2, :128]!
-
- vmull.s16 q6, d4, d8
- vld1.16 {d6, d7}, [r0, :64]!
- vmull.s16 q7, d5, d9
- vld1.16 {d10, d11}, [r2, :128]!
- vmull.s16 q8, d6, d10
- vld1.16 {d4, d5}, [r0, :64]!
- vmull.s16 q9, d7, d11
- vld1.16 {d8, d9}, [r2, :128]!
-
- vmlal.s16 q6, d4, d8
- vld1.16 {d6, d7}, [r0, :64]!
- vmlal.s16 q7, d5, d9
- vld1.16 {d10, d11}, [r2, :128]!
- vmlal.s16 q8, d6, d10
- vld1.16 {d4, d5}, [r0, :64]!
- vmlal.s16 q9, d7, d11
- vld1.16 {d8, d9}, [r2, :128]!
-
- vmlal.s16 q6, d4, d8
- vld1.16 {d6, d7}, [r0, :64]!
- vmlal.s16 q7, d5, d9
- vld1.16 {d10, d11}, [r2, :128]!
- vmlal.s16 q8, d6, d10
- vld1.16 {d4, d5}, [r0, :64]!
- vmlal.s16 q9, d7, d11
- vld1.16 {d8, d9}, [r2, :128]!
-
- vmlal.s16 q6, d4, d8
- vld1.16 {d6, d7}, [r0, :64]!
- vmlal.s16 q7, d5, d9
- vld1.16 {d10, d11}, [r2, :128]!
- vmlal.s16 q8, d6, d10
- vld1.16 {d4, d5}, [r0, :64]!
- vmlal.s16 q9, d7, d11
- vld1.16 {d8, d9}, [r2, :128]!
-
- vmlal.s16 q6, d4, d8
- vld1.16 {d6, d7}, [r0, :64]!
- vmlal.s16 q7, d5, d9
- vld1.16 {d10, d11}, [r2, :128]!
-
- vmlal.s16 q8, d6, d10
- vmlal.s16 q9, d7, d11
-
- vpadd.s32 d0, d12, d13
- vpadd.s32 d1, d14, d15
- vpadd.s32 d2, d16, d17
- vpadd.s32 d3, d18, d19
+ vld1.16 {d16, d17}, [r0, :64]!
+ vld1.16 {d20, d21}, [r2, :128]!
+
+ vmull.s16 q12, d16, d20
+ vld1.16 {d18, d19}, [r0, :64]!
+ vmull.s16 q13, d17, d21
+ vld1.16 {d22, d23}, [r2, :128]!
+ vmull.s16 q14, d18, d22
+ vld1.16 {d16, d17}, [r0, :64]!
+ vmull.s16 q15, d19, d23
+ vld1.16 {d20, d21}, [r2, :128]!
+
+ vmlal.s16 q12, d16, d20
+ vld1.16 {d18, d19}, [r0, :64]!
+ vmlal.s16 q13, d17, d21
+ vld1.16 {d22, d23}, [r2, :128]!
+ vmlal.s16 q14, d18, d22
+ vld1.16 {d16, d17}, [r0, :64]!
+ vmlal.s16 q15, d19, d23
+ vld1.16 {d20, d21}, [r2, :128]!
+
+ vmlal.s16 q12, d16, d20
+ vld1.16 {d18, d19}, [r0, :64]!
+ vmlal.s16 q13, d17, d21
+ vld1.16 {d22, d23}, [r2, :128]!
+ vmlal.s16 q14, d18, d22
+ vld1.16 {d16, d17}, [r0, :64]!
+ vmlal.s16 q15, d19, d23
+ vld1.16 {d20, d21}, [r2, :128]!
+
+ vmlal.s16 q12, d16, d20
+ vld1.16 {d18, d19}, [r0, :64]!
+ vmlal.s16 q13, d17, d21
+ vld1.16 {d22, d23}, [r2, :128]!
+ vmlal.s16 q14, d18, d22
+ vld1.16 {d16, d17}, [r0, :64]!
+ vmlal.s16 q15, d19, d23
+ vld1.16 {d20, d21}, [r2, :128]!
+
+ vmlal.s16 q12, d16, d20
+ vld1.16 {d18, d19}, [r0, :64]!
+ vmlal.s16 q13, d17, d21
+ vld1.16 {d22, d23}, [r2, :128]!
+
+ vmlal.s16 q14, d18, d22
+ vmlal.s16 q15, d19, d23
+
+ vpadd.s32 d0, d24, d25
+ vpadd.s32 d1, d26, d27
+ vpadd.s32 d2, d28, d29
+ vpadd.s32 d3, d30, d31
vrshr.s32 q0, q0, SBC_PROTO_FIXED_SCALE
vrshr.s32 q1, q1, SBC_PROTO_FIXED_SCALE
@@ -153,38 +153,38 @@ function ff_sbc_analyze_8_neon, export=1
vdup.i32 d1, d0[1] /* TODO: can be eliminated */
vdup.i32 d0, d0[0] /* TODO: can be eliminated */
- vld1.16 {d4, d5}, [r2, :128]!
- vmull.s16 q6, d4, d0
- vld1.16 {d6, d7}, [r2, :128]!
- vmull.s16 q7, d5, d0
- vmull.s16 q8, d6, d0
- vmull.s16 q9, d7, d0
-
- vld1.16 {d4, d5}, [r2, :128]!
- vmlal.s16 q6, d4, d1
- vld1.16 {d6, d7}, [r2, :128]!
- vmlal.s16 q7, d5, d1
- vmlal.s16 q8, d6, d1
- vmlal.s16 q9, d7, d1
-
- vld1.16 {d4, d5}, [r2, :128]!
- vmlal.s16 q6, d4, d2
- vld1.16 {d6, d7}, [r2, :128]!
- vmlal.s16 q7, d5, d2
- vmlal.s16 q8, d6, d2
- vmlal.s16 q9, d7, d2
-
- vld1.16 {d4, d5}, [r2, :128]!
- vmlal.s16 q6, d4, d3
- vld1.16 {d6, d7}, [r2, :128]!
- vmlal.s16 q7, d5, d3
- vmlal.s16 q8, d6, d3
- vmlal.s16 q9, d7, d3
-
- vpadd.s32 d0, d12, d13 /* TODO: can be eliminated */
- vpadd.s32 d1, d14, d15 /* TODO: can be eliminated */
- vpadd.s32 d2, d16, d17 /* TODO: can be eliminated */
- vpadd.s32 d3, d18, d19 /* TODO: can be eliminated */
+ vld1.16 {d16, d17}, [r2, :128]!
+ vmull.s16 q12, d16, d0
+ vld1.16 {d18, d19}, [r2, :128]!
+ vmull.s16 q13, d17, d0
+ vmull.s16 q14, d18, d0
+ vmull.s16 q15, d19, d0
+
+ vld1.16 {d16, d17}, [r2, :128]!
+ vmlal.s16 q12, d16, d1
+ vld1.16 {d18, d19}, [r2, :128]!
+ vmlal.s16 q13, d17, d1
+ vmlal.s16 q14, d18, d1
+ vmlal.s16 q15, d19, d1
+
+ vld1.16 {d16, d17}, [r2, :128]!
+ vmlal.s16 q12, d16, d2
+ vld1.16 {d18, d19}, [r2, :128]!
+ vmlal.s16 q13, d17, d2
+ vmlal.s16 q14, d18, d2
+ vmlal.s16 q15, d19, d2
+
+ vld1.16 {d16, d17}, [r2, :128]!
+ vmlal.s16 q12, d16, d3
+ vld1.16 {d18, d19}, [r2, :128]!
+ vmlal.s16 q13, d17, d3
+ vmlal.s16 q14, d18, d3
+ vmlal.s16 q15, d19, d3
+
+ vpadd.s32 d0, d24, d25 /* TODO: can be eliminated */
+ vpadd.s32 d1, d26, d27 /* TODO: can be eliminated */
+ vpadd.s32 d2, d28, d29 /* TODO: can be eliminated */
+ vpadd.s32 d3, d30, d31 /* TODO: can be eliminated */
vst1.32 {d0, d1, d2, d3}, [r1, :128]

View File

@ -0,0 +1,36 @@
From: James Cowgill <jcowgill@debian.org>
Date: Fri, 1 Nov 2019 08:51:07 +0000
Subject: [PATCH] avcodec/libtwolame: fix mono default bitrate
As of libtwolame 0.4.0, 384 kbps is not accepted as a valid bitrate
for encoding mono audio and the maximum bitrate is now halved to 192
kbps to comply with the MP2 standard. Example error:
twolame_init_params(): 384kbps is an invalid bitrate for mono encoding.
Adjust the default bitrate calculation to take this into account.
Signed-off-by: James Cowgill <jcowgill@debian.org>
---
libavcodec/libtwolame.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/libavcodec/libtwolame.c b/libavcodec/libtwolame.c
index 030f888..5ceb3d9 100644
--- a/libavcodec/libtwolame.c
+++ b/libavcodec/libtwolame.c
@@ -78,8 +78,12 @@ static av_cold int twolame_encode_init(AVCodecContext *avctx)
twolame_set_in_samplerate(s->glopts, avctx->sample_rate);
twolame_set_out_samplerate(s->glopts, avctx->sample_rate);
- if (!avctx->bit_rate)
- avctx->bit_rate = avctx->sample_rate < 28000 ? 160000 : 384000;
+ if (!avctx->bit_rate) {
+ if ((s->mode == TWOLAME_AUTO_MODE && avctx->channels == 1) || s->mode == TWOLAME_MONO)
+ avctx->bit_rate = avctx->sample_rate < 28000 ? 80000 : 192000;
+ else
+ avctx->bit_rate = avctx->sample_rate < 28000 ? 160000 : 384000;
+ }
if (avctx->flags & AV_CODEC_FLAG_QSCALE || !avctx->bit_rate) {
twolame_set_VBR(s->glopts, TRUE);

View File

@ -2,19 +2,543 @@ 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: 2017-10-21
libavdevice: 2017-10-21
libavfilter: 2017-10-21
libavformat: 2017-10-21
libavresample: 2017-10-21
libpostproc: 2017-10-21
libswresample: 2017-10-21
libswscale: 2017-10-21
libavutil: 2017-10-21
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 5.1 was cut here -------- 8< ---------
2022-06-12 - 7cae3d8b76 - lavf 59.25.100 - avio.h
Add avio_vprintf(), similar to avio_printf() but allow to use it
from within a function taking a variable argument list as input.
2022-06-12 - ff59ecc4de - lavu 57.27.100 - uuid.h
Add UUID handling functions.
Add av_uuid_parse(), av_uuid_urn_parse(), av_uuid_parse_range(),
av_uuid_parse_range(), av_uuid_equal(), av_uuid_copy(), and av_uuid_nil().
2022-06-01 - d42b410e05 - lavu 57.26.100 - csp.h
Add public API for colorspace structs.
Add av_csp_luma_coeffs_from_avcsp(), av_csp_primaries_desc_from_id(),
and av_csp_primaries_id_from_desc().
2022-05-23 - 4cdc14aa95 - lavu 57.25.100 - avutil.h
Deprecate av_fopen_utf8() without replacement.
2022-03-16 - f3a0e2ee2b - all libraries - version_major.h
Add lib<name>/version_major.h as new installed headers, which only
contain the major version number (and corresponding API deprecation
defines).
2022-03-15 - cdba98bb80 - swr 4.5.100 - swresample.h
Add swr_alloc_set_opts2() and swr_build_matrix2().
Deprecate swr_alloc_set_opts() and swr_build_matrix().
2022-03-15 - cdba98bb80 - lavfi 8.28.100 - avfilter.h buffersink.h buffersrc.h
Update AVFilterLink for the new channel layout API: add ch_layout,
deprecate channel_layout.
Update the buffersink filter sink for the new channel layout API:
add av_buffersink_get_ch_layout() and the ch_layouts option,
deprecate av_buffersink_get_channel_layout() and the channel_layouts option.
Update AVBufferSrcParameters for the new channel layout API:
add ch_layout, deprecate channel_layout.
2022-03-15 - cdba98bb80 - lavf 59.19.100 - avformat.h
Add AV_DISPOSITION_NON_DIEGETIC.
2022-03-15 - cdba98bb80 - lavc 59.24.100 - avcodec.h codec_par.h
Update AVCodecParameters for the new channel layout API: add ch_layout,
deprecate channels/channel_layout.
Update AVCodecContext for the new channel layout API: add ch_layout,
deprecate channels/channel_layout.
Update AVCodec for the new channel layout API: add ch_layouts,
deprecate channel_layouts.
2022-03-15 - cdba98bb80 - lavu 57.24.100 - channel_layout.h frame.h opt.h
Add new channel layout API based on the AVChannelLayout struct.
Add support for Ambisonic audio.
Deprecate previous channel layout API based on uint64 bitmasks.
Add AV_OPT_TYPE_CHLAYOUT option type, deprecate AV_OPT_TYPE_CHANNEL_LAYOUT.
Update AVFrame for the new channel layout API: add ch_layout, deprecate
channels/channel_layout.
2022-03-10 - f629ea2e18 - lavu 57.23.100 - cpu.h
Add AV_CPU_FLAG_AVX512ICL.
2022-02-07 - a10f1aec1f - lavu 57.21.100 - fifo.h
Deprecate AVFifoBuffer and the API around it, namely av_fifo_alloc(),
av_fifo_alloc_array(), av_fifo_free(), av_fifo_freep(), av_fifo_reset(),
av_fifo_size(), av_fifo_space(), av_fifo_generic_peek_at(),
av_fifo_generic_peek(), av_fifo_generic_read(), av_fifo_generic_write(),
av_fifo_realloc2(), av_fifo_grow(), av_fifo_drain() and av_fifo_peek2().
Users should switch to the AVFifo-API.
2022-02-07 - 7329b22c05 - lavu 57.20.100 - fifo.h
Add a new FIFO API, which allows setting a FIFO element size.
This API operates on these elements rather than on bytes.
Add av_fifo_alloc2(), av_fifo_elem_size(), av_fifo_can_read(),
av_fifo_can_write(), av_fifo_grow2(), av_fifo_drain2(), av_fifo_write(),
av_fifo_write_from_cb(), av_fifo_read(), av_fifo_read_to_cb(),
av_fifo_peek(), av_fifo_peek_to_cb(), av_fifo_drain2(), av_fifo_reset2(),
av_fifo_freep2(), av_fifo_auto_grow_limit().
2022-01-26 - af94ab7c7c0 - lavu 57.19.100 - tx.h
Add AV_TX_FLOAT_RDFT, AV_TX_DOUBLE_RDFT and AV_TX_INT32_RDFT.
-------- 8< --------- FFmpeg 5.0 was cut here -------- 8< ---------
2022-01-04 - 78dc21b123e - lavu 57.16.100 - frame.h
Add AV_FRAME_DATA_DOVI_METADATA.
2022-01-03 - 70f318e6b6c - lavf 59.13.100 - avformat.h
Add AVFMT_EXPERIMENTAL flag.
2021-12-22 - b7e1ec7bda9 - lavu 57.13.100 - hwcontext_videotoolbox.h
Add av_vt_pixbuf_set_attachments
2021-12-22 - 69bd95dcd8d - lavu 57.13.100 - hwcontext_videotoolbox.h
Add av_map_videotoolbox_chroma_loc_from_av
Add av_map_videotoolbox_color_matrix_from_av
Add av_map_videotoolbox_color_primaries_from_av
Add av_map_videotoolbox_color_trc_from_av
2021-12-21 - ffbab99f2c2 - lavu 57.12.100 - cpu.h
Add AV_CPU_FLAG_SLOW_GATHER.
2021-12-20 - 278068dc60d - lavu 57.11.101 - display.h
Modified the documentation of av_display_rotation_set()
to match its longstanding actual behaviour of treating
the angle as directed clockwise.
2021-12-12 - 64834bb86a1 - lavf 59.10.100 - avformat.h
Add AVFormatContext io_close2 which returns an int
2021-12-10 - f45cbb775e4 - lavu 57.11.100 - hwcontext_vulkan.h
Add AVVkFrame.offset and AVVulkanFramesContext.flags.
2021-12-04 - b9c928a486f - lavfi 8.19.100 - avfilter.h
Add AVFILTER_FLAG_METADATA_ONLY.
2021-12-03 - b236ef0a594 - lavu 57.10.100 - frame.h
Add AVFrame.time_base
2021-11-22 - b2cd1fb2ec6 - lavu 57.9.100 - pixfmt.h
Add AV_PIX_FMT_P210, AV_PIX_FMT_P410, AV_PIX_FMT_P216, and AV_PIX_FMT_P416.
2021-11-17 - 54e65aa38ab - lavf 57.9.100 - frame.h
Add AV_FRAME_DATA_DOVI_RPU_BUFFER.
2021-11-16 - ed75a08d36c - lavf 59.9.100 - avformat.h
Add av_stream_get_class(). Schedule adding AVStream.av_class at libavformat
major version 60.
Add av_disposition_to_string() and av_disposition_from_string().
Add "disposition" AVOption to AVStream's class.
2021-11-12 - 8478d60d5b5 - lavu 57.8.100 - hwcontext_vulkan.h
Added AVVkFrame.sem_value, AVVulkanDeviceContext.queue_family_encode_index,
nb_encode_queues, queue_family_decode_index, and nb_decode_queues.
2021-10-18 - 682bafdb125 - lavf 59.8.100 - avio.h
Introduce public bytes_{read,written} statistic fields to AVIOContext.
2021-10-13 - a5622ed16f8 - lavf 59.7.100 - avio.h
Deprecate AVIOContext.written. Originally added as a private entry in
commit 3f75e5116b900f1428aa13041fc7d6301bf1988a, its grouping with
the comment noting its private state was missed during merging of the field
from Libav (most likely due to an already existing field in between).
2021-09-21 - 0760d9153c3 - lavu 57.7.100 - pixfmt.h
Add AV_PIX_FMT_X2BGR10.
2021-09-20 - 8d5de914d31 - lavu 57.6.100 - mem.h
Deprecate av_mallocz_array() as it is identical to av_calloc().
2021-09-20 - 176b8d785bf - lavc 59.9.100 - avcodec.h
Deprecate AVCodecContext.sub_text_format and the corresponding
AVOptions. It is unused since the last major bump.
2021-09-20 - dd846bc4a91 - lavc 59.8.100 - avcodec.h codec.h
Deprecate AV_CODEC_FLAG_TRUNCATED and AV_CODEC_CAP_TRUNCATED,
as they are redundant with parsers.
2021-09-17 - ccfdef79b13 - lavu 57.5.101 - buffer.h
Constified the input parameters in av_buffer_replace(), av_buffer_ref(),
and av_buffer_pool_buffer_get_opaque().
2021-09-08 - 4f78711f9c2 - lavu 57.5.100 - hwcontext_d3d11va.h
Add AVD3D11VAFramesContext.texture_infos
2021-09-06 - 42cd64c1826 - lsws 6.1.100 - swscale.h
Add AVFrame-based scaling API:
- sws_scale_frame()
- sws_frame_start()
- sws_frame_end()
- sws_send_slice()
- sws_receive_slice()
- sws_receive_slice_alignment()
2021-09-02 - cbf111059d2 - lavc 59.7.100 - avcodec.h
Incremented the number of elements of AVCodecParser.codec_ids to seven.
2021-08-24 - 590a7e02f04 - lavc 59.6.100 - avcodec.h
Add FF_CODEC_PROPERTY_FILM_GRAIN
2021-08-20 - 7c5f998196d - lavfi 8.3.100 - avfilter.H
Add avfilter_filter_pad_count() as a replacement for avfilter_pad_count().
Deprecate avfilter_pad_count().
2021-08-17 - 8c53b145993 - lavu 57.4.101 - opt.h
av_opt_copy() now guarantees that allocated src and dst options
don't alias each other even on error.
2021-08-14 - d5de9965ef6 - lavu 57.4.100 - imgutils.h
Add av_image_copy_plane_uc_from()
2021-08-02 - a1a0fddfd05 - lavc 59.4.100 - packet.h
Add AVPacket.opaque, AVPacket.opaque_ref, AVPacket.time_base.
2021-07-23 - 2dd8acbe800 - lavu 57.3.100 - common.h macros.h
Move several macros (AV_NE, FFDIFFSIGN, FFMAX, FFMAX3, FFMIN, FFMIN3,
FFSWAP, FF_ARRAY_ELEMS, MKTAG, MKBETAG) from common.h to macros.h.
2021-07-22 - e3b5ff17c2e - lavu 57.2.100 - film_grain_params.h
Add AV_FILM_GRAIN_PARAMS_H274, AVFilmGrainH274Params
2021-07-19 - c1bf56a526f - lavu 57.1.100 - cpu.h
Add av_cpu_force_count()
2021-06-17 - aca923b3653 - lavc 59.2.100 - packet.h
Add AV_PKT_DATA_DYNAMIC_HDR10_PLUS
2021-06-09 - 2cccab96f6f - lavf 59.3.100 - avformat.h
Add pts_wrap_bits to AVStream
2021-06-10 - 7c9763070d9 - lavc 59.1.100 - avcodec.h codec.h
Move av_get_profile_name() from avcodec.h to codec.h.
2021-06-10 - bb3648e6766 - lavc 59.1.100 - avcodec.h codec_par.h
Move av_get_audio_frame_duration2() from avcodec.h to codec_par.h.
2021-06-10 - 881db34f6a0 - lavc 59.1.100 - avcodec.h codec_id.h
Move av_get_bits_per_sample(), av_get_exact_bits_per_sample(),
avcodec_profile_name(), and av_get_pcm_codec() from avcodec.h
to codec_id.h.
2021-06-10 - ff0a96046d8 - lavc 59.1.100 - avcodec.h defs.h
Add new installed header defs.h. The following definitions are moved
into it from avcodec.h:
- AVDiscard
- AVAudioServiceType
- AVPanScan
- AVCPBProperties and av_cpb_properties_alloc()
- AVProducerReferenceTime
- av_xiphlacing()
2021-04-27 - cb3ac722f4 - lavc 59.0.100 - avcodec.h
Constified AVCodecParserContext.parser.
2021-04-27 - 8b3e6ce5f4 - lavd 59.0.100 - avdevice.h
The av_*_device_next API functions now accept and return
pointers to const AVInputFormat resp. AVOutputFormat.
2021-04-27 - d7e0d428fa - lavd 59.0.100 - avdevice.h
avdevice_list_input_sources and avdevice_list_output_sinks now accept
pointers to const AVInputFormat resp. const AVOutputFormat.
2021-04-27 - 46dac8cf3d - lavf 59.0.100 - avformat.h
av_find_best_stream now uses a const AVCodec ** parameter
for the returned decoder.
2021-04-27 - 626535f6a1 - lavc 59.0.100 - codec.h
avcodec_find_encoder_by_name(), avcodec_find_encoder(),
avcodec_find_decoder_by_name() and avcodec_find_decoder()
now return a pointer to const AVCodec.
2021-04-27 - 14fa0a4efb - lavf 59.0.100 - avformat.h
Constified AVFormatContext.*_codec.
2021-04-27 - 56450a0ee4 - lavf 59.0.100 - avformat.h
Constified the pointers to AVInputFormats and AVOutputFormats
in AVFormatContext, avformat_alloc_output_context2(),
av_find_input_format(), av_probe_input_format(),
av_probe_input_format2(), av_probe_input_format3(),
av_probe_input_buffer2(), av_probe_input_buffer(),
avformat_open_input(), av_guess_format() and av_guess_codec().
Furthermore, constified the AVProbeData in av_probe_input_format(),
av_probe_input_format2() and av_probe_input_format3().
2021-04-19 - 18af1ea8d1 - lavu 56.74.100 - tx.h
Add AV_TX_FULL_IMDCT and AV_TX_UNALIGNED.
2021-04-17 - f1bf465aa0 - lavu 56.73.100 - frame.h detection_bbox.h
Add AV_FRAME_DATA_DETECTION_BBOXES
2021-04-06 - 557953a397 - lavf 58.78.100 - avformat.h
Add avformat_index_get_entries_count(), avformat_index_get_entry(),
and avformat_index_get_entry_from_timestamp().
2021-03-21 - a77beea6c8 - lavu 56.72.100 - frame.h
Deprecated av_get_colorspace_name().
Use av_color_space_name() instead.
-------- 8< --------- FFmpeg 4.4 was cut here -------- 8< ---------
2021-03-19 - e8c0bca6bd - lavu 56.69.100 - adler32.h
Added a typedef for the type of the Adler-32 checksums
used by av_adler32_update(). It will be changed to uint32_t
at the next major bump.
The type of the parameter for the length of the input buffer
will also be changed to size_t at the next major bump.
2021-03-19 - e318438f2f - lavf 58.75.100 - avformat.h
AVChapter.id will be changed from int to int64_t
on the next major version bump.
2021-03-17 - f7db77bd87 - lavc 58.133.100 - codec.h
Deprecated av_init_packet(). Once removed, sizeof(AVPacket) will
no longer be a part of the public ABI.
Deprecated AVPacketList.
2021-03-16 - 7d09579190 - lavc 58.132.100 - codec.h
Add AV_CODEC_CAP_OTHER_THREADS as a new name for
AV_CODEC_CAP_AUTO_THREADS. AV_CODEC_CAP_AUTO_THREADS
is now deprecated.
2021-03-12 - 6e7e3a3820 - lavc 58.131.100 - avcodec.h codec.h
Add a get_encode_buffer callback to AVCodecContext, similar to
get_buffer2 but for encoders.
Add avcodec_default_get_encode_buffer().
Add AV_GET_ENCODE_BUFFER_FLAG_REF.
Encoders may now be flagged as AV_CODEC_CAP_DR1 capable.
2021-03-10 - 42e68fe015 - lavf 58.72.100 - avformat.h
Change AVBufferRef related AVStream function and struct size
parameter and fields type to size_t at next major bump.
2021-03-10 - d79e0fe65c - lavc 58.130.100 - packet.h
Change AVBufferRef related AVPacket function and struct size
parameter and fields type to size_t at next major bump.
2021-03-10 - 14040a1d91 - lavu 56.68.100 - buffer.h frame.h
Change AVBufferRef and relevant AVFrame function and struct size
parameter and fields type to size_t at next major bump.
2021-03-04 - a0eec776b6 - lavc 58.128.101 - avcodec.h
Enable err_recognition to be set for encoders.
2021-03-03 - 2ff40b98ec - lavf 58.70.100 - avformat.h
Deprecate AVFMT_FLAG_PRIV_OPT. It will do nothing
as soon as av_demuxer_open() is removed.
2021-02-27 - dd9227e48f - lavc 58.126.100 - avcodec.h
Deprecated avcodec_get_frame_class().
2021-02-21 - 5ca40d6d94 - lavu 56.66.100 - tx.h
Add enum AVTXFlags and AVTXFlags.AV_TX_INPLACE
2021-02-14 - 4f49ca7bbc - lavd 58.12.100 - avdevice.h
Deprecated avdevice_capabilities_create() and
avdevice_capabilities_free().
2021-02-10 - 1bda9bb68a - lavu 56.65.100 - common.h
Add FFABS64U()
2021-01-26 - 5dd9567080 - lavu 56.64.100 - common.h
Add FFABSU()
2021-01-25 - 56709ca8aa - lavc 58.119.100 - avcodec.h
Deprecate AVCodecContext.debug_mv, FF_DEBUG_VIS_MV_P_FOR, FF_DEBUG_VIS_MV_B_FOR,
FF_DEBUG_VIS_MV_B_BACK
2021-01-11 - ebdd33086a - lavc 58.116.100 - avcodec.h
Add FF_PROFILE_VVC_MAIN_10 and FF_PROFILE_VVC_MAIN_10_444.
2020-01-01 - baecaa16c1 - lavu 56.63.100 - video_enc_params.h
Add AV_VIDEO_ENC_PARAMS_MPEG2
2020-12-03 - eca12f4d5a - lavu 56.62.100 - timecode.h
Add av_timecode_init_from_components.
2020-11-27 - a83098ab03 - lavc 58.114.100 - avcodec.h
Deprecate AVCodecContext.thread_safe_callbacks. Starting with
LIBAVCODEC_VERSION_MAJOR=60, user callbacks must always be
thread-safe when frame threading is used.
2020-11-25 - d243dd540a - lavc 58.113.100 - avcodec.h
Adds a new flag AV_CODEC_EXPORT_DATA_FILM_GRAIN for export_side_data.
2020-11-25 - 4f9ee87253 - lavu 56.61.100 - film_grain_params.h
Adds a new API for extracting codec film grain parameters as side data.
Adds a new AVFrameSideDataType entry AV_FRAME_DATA_FILM_GRAIN_PARAMS for it.
2020-10-28 - f95d9510ff - lavf 58.64.100 - avformat.h
Add AVSTREAM_EVENT_FLAG_NEW_PACKETS.
2020-09-28 - 68918d3b7f - lavu 56.60.100 - buffer.h
Add a av_buffer_replace() convenience function.
2020-09-13 - 837b6eb90e - lavu 56.59.100 - timecode.h
Add av_timecode_make_smpte_tc_string2.
2020-08-21 - 06f2651204 - lavu 56.58.100 - avstring.h
Deprecate av_d2str(). Use av_asprintf() instead.
2020-08-04 - 34de0abbe7 - lavu 56.58.100 - channel_layout.h
Add AV_CH_LAYOUT_22POINT2 together with its newly required pieces:
AV_CH_TOP_SIDE_LEFT, AV_CH_TOP_SIDE_RIGHT, AV_CH_BOTTOM_FRONT_CENTER,
AV_CH_BOTTOM_FRONT_LEFT, AV_CH_BOTTOM_FRONT_RIGHT.
2020-07-23 - 84655b7101 - lavu 56.57.100 - cpu.h
Add AV_CPU_FLAG_MMI and AV_CPU_FLAG_MSA.
2020-07-22 - 3a8e927176 - lavu 56.56.100 - imgutils.h
Add av_image_fill_plane_sizes().
2020-07-15 - 448a9aaa78 - lavc 58.96.100 - packet.h
Add AV_PKT_DATA_S12M_TIMECODE.
2020-06-12 - b09fb030c1 - lavu 56.55.100 - pixdesc.h
Add AV_PIX_FMT_X2RGB10.
2020-06-11 - bc8ab084fb - lavu 56.54.100 - frame.h
Add AV_FRAME_DATA_SEI_UNREGISTERED.
2020-06-10 - 1b4a98b029 - lavu 56.53.100 - log.h opt.h
Add av_opt_child_class_iterate() and AVClass.child_class_iterate().
Deprecate av_opt_child_class_next() and AVClass.child_class_next().
-------- 8< --------- FFmpeg 4.3 was cut here -------- 8< ---------
2020-06-05 - ec39c2276a - lavu 56.50.100 - buffer.h
Passing NULL as alloc argument to av_buffer_pool_init2() is now allowed.
2020-05-27 - ba6cada92e - lavc 58.88.100 - avcodec.h codec.h
Move AVCodec-related public API to new header codec.h.
2020-05-23 - 064b875e89 - lavu 56.49.100 - video_enc_params.h
Add AV_VIDEO_ENC_PARAMS_H264.
2020-05-23 - 2e08b39444 - lavu 56.48.100 - hwcontext.h
Add av_hwdevice_ctx_create_derived_opts.
2020-05-23 - 6b65c4ec54 - lavu 56.47.100 - rational.h
Add av_gcd_q().
2020-05-22 - af9e622776 - lavu 56.46.101 - opt.h
Add AV_OPT_FLAG_CHILD_CONSTS.
2020-05-22 - 9d443c3e68 - lavc 58.87.100 - avcodec.h codec_par.h
Move AVBitstreamFilter-related public API to new header bsf.h.
Move AVCodecParameters-related public API to new header codec_par.h.
2020-05-21 - 13b1bbff0b - lavc 58.86.101 - avcodec.h
Deprecated AV_CODEC_CAP_INTRA_ONLY and AV_CODEC_CAP_LOSSLESS.
2020-05-17 - 84af196c65 - lavu 56.46.100 - common.h
Add av_sat_add64() and av_sat_sub64()
2020-05-12 - 991d417692 - lavu 56.45.100 - video_enc_params.h
lavc 58.84.100 - avcodec.h
Add a new API for exporting video encoding information.
Replaces the deprecated API for exporting QP tables from decoders.
Add AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS to request this information from
decoders.
2020-05-10 - dccd07f66d - lavu 56.44.100 - hwcontext_vulkan.h
Add enabled_inst_extensions, num_enabled_inst_extensions, enabled_dev_extensions
and num_enabled_dev_extensions fields to AVVulkanDeviceContext
2020-04-22 - 0e1db79e37 - lavc 58.81.100 - packet.h
- lavu 56.43.100 - dovi_meta.h
Add AV_PKT_DATA_DOVI_CONF and AVDOVIDecoderConfigurationRecord.
2020-04-15 - 22b25b3ea5 - lavc 58.79.100 - avcodec.h
Add formal support for calling avcodec_flush_buffers() on encoders.
Encoders that set the cap AV_CODEC_CAP_ENCODER_FLUSH will be flushed.
For all other encoders, the call is now a no-op rather than undefined
behaviour.
2020-04-10 - 672946c7fe - lavc 58.78.100 - avcodec.h codec_desc.h codec_id.h packet.h
Move AVCodecDesc-related public API to new header codec_desc.h.
Move AVCodecID enum to new header codec_id.h.
Move AVPacket-related public API to new header packet.h.
2020-03-29 - 4cb0dda555 - lavf 58.42.100 - avformat.h
av_read_frame() now guarantees to handle uninitialized input packets
and to return refcounted packets on success.
2020-03-27 - c52ec0367d - lavc 58.77.100 - avcodec.h
av_packet_ref() now guarantees to return the destination packet
in a blank state on error.
2020-03-10 - 05d27f342b - lavc 58.75.100 - avcodec.h
Add AV_PKT_DATA_ICC_PROFILE.
2020-02-21 - d005a7cdfd - lavc 58.73.101 - avcodec.h
Add AV_CODEC_EXPORT_DATA_PRFT.
2020-02-21 - c666689491 - lavc 58.73.100 - avcodec.h
Add AVCodecContext.export_side_data and AV_CODEC_EXPORT_DATA_MVS.
2020-02-13 - e8f054b095 - lavu 56.41.100 - tx.h
Add AV_TX_INT32_FFT and AV_TX_INT32_MDCT
2020-02-12 - 3182114f88 - lavu 56.40.100 - log.h
Add av_log_once().
2020-02-04 - a88449ffb2 - lavu 56.39.100 - hwcontext.h
Add AV_PIX_FMT_VULKAN
Add AV_HWDEVICE_TYPE_VULKAN and implementation.
2020-01-30 - 27529eeb27 - lavf 58.37.100 - avio.h
Add avio_protocol_get_class().
2020-01-15 - 717b2074ec - lavc 58.66.100 - avcodec.h
Add AV_PKT_DATA_PRFT and AVProducerReferenceTime.
2019-12-27 - 45259a0ee4 - lavu 56.38.100 - eval.h
Add av_expr_count_func().
2019-12-26 - 16685114d5 - lavu 56.37.100 - buffer.h
Add av_buffer_pool_buffer_get_opaque().
2019-11-17 - 1c23abc88f - lavu 56.36.100 - eval API
Add av_expr_count_vars().
2019-10-14 - f3746d31f9 - lavu 56.35.101 - opt.h
Add AV_OPT_FLAG_RUNTIME_PARAM.
2019-09-25 - f8406ab4b9 - lavc 58.59.100 - avcodec.h
Add max_samples
2019-09-04 - 2a9d461abc - lavu 56.35.100 - hwcontext_videotoolbox.h
Add av_map_videotoolbox_format_from_pixfmt2() for full range pixfmt
2019-09-01 - 8821d1f56e - lavu 56.34.100 - pixfmt.h
Add EBU Tech. 3213-E AVColorPrimaries value
2019-08-17 - 95fa73a2b4 - lavf 58.31.101 - avio.h
4K limit removed from avio_printf.
2019-08-17 - a82f8f2f10 - lavf 58.31.100 - avio.h
Add avio_print_string_array and avio_print.
2019-07-27 - 42e2319ba9 - lavu 56.33.100 - tx.h
Add AV_TX_DOUBLE_FFT and AV_TX_DOUBLE_MDCT
-------- 8< --------- FFmpeg 4.2 was cut here -------- 8< ---------
2019-06-21 - a30e44098a - lavu 56.30.100 - frame.h
@ -1165,7 +1689,7 @@ API changes, most recent first:
2014-04-15 - ef818d8 - lavf 55.37.101 - avformat.h
Add av_format_inject_global_side_data()
2014-04-12 - 4f698be - lavu 52.76.100 - log.h
2014-04-12 - 4f698be8f - lavu 52.76.100 - log.h
Add av_log_get_flags()
2014-04-11 - 6db42a2b - lavd 55.12.100 - avdevice.h

View File

@ -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 = 4.2.2
PROJECT_NUMBER = 5.1.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

View File

@ -27,6 +27,9 @@ HTMLPAGES = $(AVPROGS-yes:%=doc/%.html) $(AVPROGS-yes:%=doc/%-all.html) $(COMP
doc/mailing-list-faq.html \
doc/nut.html \
doc/platform.html \
$(SRC_PATH)/doc/bootstrap.min.css \
$(SRC_PATH)/doc/style.min.css \
$(SRC_PATH)/doc/default.css \
TXTPAGES = doc/fate.txt \
@ -102,7 +105,7 @@ DOXY_INPUT_DEPS = $(addprefix $(SRC_PATH)/, $(DOXY_INPUT)) ffbuild/config.mak
doc/doxy/html: TAG = DOXY
doc/doxy/html: $(SRC_PATH)/doc/Doxyfile $(SRC_PATH)/doc/doxy-wrapper.sh $(DOXY_INPUT_DEPS)
$(M)OUT_DIR=$$PWD/doc/doxy; cd $(SRC_PATH); ./doc/doxy-wrapper.sh $$OUT_DIR $< $(DOXYGEN) $(DOXY_INPUT);
$(M)$(SRC_PATH)/doc/doxy-wrapper.sh $$PWD/doc/doxy $(SRC_PATH) doc/Doxyfile $(DOXYGEN) $(DOXY_INPUT);
install-doc: install-html install-man

View File

@ -81,7 +81,7 @@ Top-left position.
@end table
@item tick_rate
Set the tick rate (@emph{num_units_in_display_tick / time_scale}) in
Set the tick rate (@emph{time_scale / num_units_in_display_tick}) in
the timing info in the sequence header.
@item num_ticks_per_picture
Set the number of ticks in each picture, to indicate that the stream
@ -132,6 +132,36 @@ the header stored in extradata to the key packets:
ffmpeg -i INPUT -map 0 -flags:v +global_header -c:v libx264 -bsf:v dump_extra out.ts
@end example
@section dv_error_marker
Blocks in DV which are marked as damaged are replaced by blocks of the specified color.
@table @option
@item color
The color to replace damaged blocks by
@item sta
A 16 bit mask which specifies which of the 16 possible error status values are
to be replaced by colored blocks. 0xFFFE is the default which replaces all non 0
error status values.
@table @samp
@item ok
No error, no concealment
@item err
Error, No concealment
@item res
Reserved
@item notok
Error or concealment
@item notres
Not reserved
@item Aa, Ba, Ca, Ab, Bb, Cb, A, B, C, a, b, erri, erru
The specific error status code
@end table
see page 44-46 or section 5.5 of
@url{http://web.archive.org/web/20060927044735/http://www.smpte.org/smpte_store/standards/pdf/s314m.pdf}
@end table
@section eac3_core
Extract the core from a E-AC-3 stream, dropping extra channels.
@ -217,12 +247,20 @@ Modify metadata embedded in an H.264 stream.
Insert or remove AUD NAL units in all access units of the stream.
@table @samp
@item pass
@item insert
@item remove
@end table
Default is pass.
@item sample_aspect_ratio
Set the sample aspect ratio of the stream in the VUI parameters.
See H.264 table E-1.
@item overscan_appropriate_flag
Set whether the stream is suitable for display using overscan
or not (see H.264 section E.2.1).
@item video_format
@item video_full_range_flag
@ -240,7 +278,7 @@ Set the chroma sample location in the stream (see H.264 section
E.2.1 and figure E-1).
@item tick_rate
Set the tick rate (num_units_in_tick / time_scale) in the VUI
Set the tick rate (time_scale / num_units_in_tick) in the VUI
parameters. This is the smallest time unit representable in the
stream, and in many cases represents the field rate of the stream
(double the frame rate).
@ -249,6 +287,11 @@ Set whether the stream has fixed framerate - typically this indicates
that the framerate is exactly half the tick rate, but the exact
meaning is dependent on interlacing and the picture structure (see
H.264 section E.2.1 and table E-6).
@item zero_new_constraint_set_flags
Zero constraint_set4_flag and constraint_set5_flag in the SPS. These
bits were reserved in a previous version of the H.264 spec, and thus
some hardware decoders require these to be zero. The result of zeroing
this is still a valid bitstream.
@item crop_left
@item crop_right
@ -272,6 +315,37 @@ insert the string ``hello'' associated with the given UUID.
@item delete_filler
Deletes both filler NAL units and filler SEI messages.
@item display_orientation
Insert, extract or remove Display orientation SEI messages.
See H.264 section D.1.27 and D.2.27 for syntax and semantics.
@table @samp
@item pass
@item insert
@item remove
@item extract
@end table
Default is pass.
Insert mode works in conjunction with @code{rotate} and @code{flip} options.
Any pre-existing Display orientation messages will be removed in insert or remove mode.
Extract mode attaches the display matrix to the packet as side data.
@item rotate
Set rotation in display orientation SEI (anticlockwise angle in degrees).
Range is -360 to +360. Default is NaN.
@item flip
Set flip in display orientation SEI.
@table @samp
@item horizontal
@item vertical
@end table
Default is unset.
@item level
Set the level in the SPS. Refer to H.264 section A.3 and tables A-1
to A-5.
@ -343,8 +417,8 @@ Set the chroma sample location in the stream (see H.265 section
E.3.1 and figure E.1).
@item tick_rate
Set the tick rate in the VPS and VUI parameters (num_units_in_tick /
time_scale). Combined with @option{num_ticks_poc_diff_one}, this can
Set the tick rate in the VPS and VUI parameters (time_scale /
num_units_in_tick). Combined with @option{num_ticks_poc_diff_one}, this can
set a constant framerate in the stream. Note that it is likely to be
overridden by container parameters when the stream is in a container.
@ -525,25 +599,110 @@ container. Can be used for fuzzing or testing error resilience/concealment.
Parameters:
@table @option
@item amount
A numeral string, whose value is related to how often output bytes will
be modified. Therefore, values below or equal to 0 are forbidden, and
the lower the more frequent bytes will be modified, with 1 meaning
every byte is modified.
Accepts an expression whose evaluation per-packet determines how often bytes in that
packet will be modified. A value below 0 will result in a variable frequency.
Default is 0 which results in no modification. However, if neither amount nor drop is specified,
amount will be set to @var{-1}. See below for accepted variables.
@item drop
Accepts an expression evaluated per-packet whose value determines whether that packet is dropped.
Evaluation to a positive value results in the packet being dropped. Evaluation to a negative
value results in a variable chance of it being dropped, roughly inverse in proportion to the magnitude
of the value. Default is 0 which results in no drops. See below for accepted variables.
@item dropamount
A numeral string, whose value is related to how often packets will be dropped.
Therefore, values below or equal to 0 are forbidden, and the lower the more
frequent packets will be dropped, with 1 meaning every packet is dropped.
Accepts a non-negative integer, which assigns a variable chance of it being dropped, roughly inverse
in proportion to the value. Default is 0 which results in no drops. This option is kept for backwards
compatibility and is equivalent to setting drop to a negative value with the same magnitude
i.e. @code{dropamount=4} is the same as @code{drop=-4}. Ignored if drop is also specified.
@end table
The following example applies the modification to every byte but does not drop
any packets.
Both @code{amount} and @code{drop} accept expressions containing the following variables:
@table @samp
@item n
The index of the packet, starting from zero.
@item tb
The timebase for packet timestamps.
@item pts
Packet presentation timestamp.
@item dts
Packet decoding timestamp.
@item nopts
Constant representing AV_NOPTS_VALUE.
@item startpts
First non-AV_NOPTS_VALUE PTS seen in the stream.
@item startdts
First non-AV_NOPTS_VALUE DTS seen in the stream.
@item duration
@itemx d
Packet duration, in timebase units.
@item pos
Packet position in input; may be -1 when unknown or not set.
@item size
Packet size, in bytes.
@item key
Whether packet is marked as a keyframe.
@item state
A pseudo random integer, primarily derived from the content of packet payload.
@end table
@subsection Examples
Apply modification to every byte but don't drop any packets.
@example
ffmpeg -i INPUT -c copy -bsf noise[=1] output.mkv
ffmpeg -i INPUT -c copy -bsf noise=1 output.mkv
@end example
Drop every video packet not marked as a keyframe after timestamp 30s but do not
modify any of the remaining packets.
@example
ffmpeg -i INPUT -c copy -bsf:v noise=drop='gt(t\,30)*not(key)' output.mkv
@end example
Drop one second of audio every 10 seconds and add some random noise to the rest.
@example
ffmpeg -i INPUT -c copy -bsf:a noise=amount=-1:drop='between(mod(t\,10)\,9\,10)' output.mkv
@end example
@section null
This bitstream filter passes the packets through unchanged.
@section pcm_rechunk
Repacketize PCM audio to a fixed number of samples per packet or a fixed packet
rate per second. This is similar to the @ref{asetnsamples,,asetnsamples audio
filter,ffmpeg-filters} but works on audio packets instead of audio frames.
@table @option
@item nb_out_samples, n
Set the number of samples per each output audio packet. The number is intended
as the number of samples @emph{per each channel}. Default value is 1024.
@item pad, p
If set to 1, the filter will pad the last audio packet with silence, so that it
will contain the same number of samples (or roughly the same number of samples,
see @option{frame_rate}) as the previous ones. Default value is 1.
@item frame_rate, r
This option makes the filter output a fixed number of packets per second instead
of a fixed number of samples per packet. If the audio sample rate is not
divisible by the frame rate then the number of samples will not be constant but
will vary slightly so that each packet will start as close to the frame
boundary as possible. Using this option has precedence over @option{nb_out_samples}.
@end table
You can generate the well known 1602-1601-1602-1601-1602 pattern of 48kHz audio
for NTSC frame rate using the @option{frame_rate} option.
@example
ffmpeg -f lavfi -i sine=r=48000:d=1 -c pcm_s16le -bsf pcm_rechunk=r=30000/1001 -f framecrc -
@end example
@section pgs_frame_merge
Merge a sequence of PGS Subtitle segments ending with an "end of display set"
segment into a single packet.
This is required by some containers that support PGS subtitles
(muxer @code{matroska}).
@section prores_metadata
Modify color property metadata embedded in prores stream.
@ -585,6 +744,10 @@ Keep the same transfer characteristics property (default).
@item unknown
@item bt709
BT 601, BT 709, BT 2020
@item smpte2084
SMPTE ST 2084
@item arib-std-b67
ARIB STD-B67
@end table
@ -594,7 +757,7 @@ Available values are:
@table @samp
@item auto
Keep the same transfer characteristics property (default).
Keep the same colorspace property (default).
@item unknown
@item bt709
@ -610,6 +773,11 @@ Set Rec709 colorspace for each frame of the file
ffmpeg -i INPUT -c copy -bsf:v prores_metadata=color_primaries=bt709:color_trc=bt709:colorspace=bt709 output.mov
@end example
Set Hybrid Log-Gamma parameters for each frame of the file
@example
ffmpeg -i INPUT -c copy -bsf:v prores_metadata=color_primaries=bt2020:color_trc=arib-std-b67:colorspace=bt2020nc output.mov
@end example
@section remove_extra
Remove extradata from packets.
@ -632,6 +800,91 @@ Remove extradata from all frames.
@end table
@end table
@section setts
Set PTS and DTS in packets.
It accepts the following parameters:
@table @option
@item ts
@item pts
@item dts
Set expressions for PTS, DTS or both.
@item duration
Set expression for duration.
@item time_base
Set output time base.
@end table
The expressions are evaluated through the eval API and can contain the following
constants:
@table @option
@item N
The count of the input packet. Starting from 0.
@item TS
The demux timestamp in input in case of @code{ts} or @code{dts} option or presentation
timestamp in case of @code{pts} option.
@item POS
The original position in the file of the packet, or undefined if undefined
for the current packet
@item DTS
The demux timestamp in input.
@item PTS
The presentation timestamp in input.
@item DURATION
The duration in input.
@item STARTDTS
The DTS of the first packet.
@item STARTPTS
The PTS of the first packet.
@item PREV_INDTS
The previous input DTS.
@item PREV_INPTS
The previous input PTS.
@item PREV_INDURATION
The previous input duration.
@item PREV_OUTDTS
The previous output DTS.
@item PREV_OUTPTS
The previous output PTS.
@item PREV_OUTDURATION
The previous output duration.
@item NEXT_DTS
The next input DTS.
@item NEXT_PTS
The next input PTS.
@item NEXT_DURATION
The next input duration.
@item TB
The timebase of stream packet belongs.
@item TB_OUT
The output timebase.
@item SR
The sample rate of stream packet belongs.
@item NOPTS
The AV_NOPTS_VALUE constant.
@end table
@anchor{text2movsub}
@section text2movsub
@ -659,7 +912,9 @@ Modify metadata embedded in a VP9 stream.
@table @option
@item color_space
Set the color space value in the frame header.
Set the color space value in the frame header. Note that any frame
set to RGB will be implicitly set to PC range and that RGB is
incompatible with profiles 0 and 2.
@table @samp
@item unknown
@item bt601
@ -671,8 +926,8 @@ Set the color space value in the frame header.
@end table
@item color_range
Set the color range value in the frame header. Note that this cannot
be set in RGB streams.
Set the color range value in the frame header. Note that any value
imposed by the color space will take precedence over this value.
@table @samp
@item tv
@item pc

View File

@ -48,6 +48,8 @@ config
tools/target_dec_<decoder>_fuzzer
Build fuzzer to fuzz the specified decoder.
tools/target_bsf_<filter>_fuzzer
Build fuzzer to fuzz the specified bitstream filter.
Useful standard make commands:
make -t <target>

View File

@ -50,11 +50,10 @@ Use internal 2pass ratecontrol in first pass mode.
Use internal 2pass ratecontrol in second pass mode.
@item gray
Only decode/encode grayscale.
@item emu_edge
Do not draw edges.
@item psnr
Set error[?] variables during encoding.
@item truncated
Input bitstream might be randomly truncated.
@item drop_changed
Don't output frames whose parameters differ from first decoded frame in stream.
Error AVERROR_INPUT_CHANGED is returned when a frame is dropped.
@ -71,50 +70,14 @@ This ensures that file and data checksums are reproducible and match between
platforms. Its primary use is for regression testing.
@item aic
Apply H263 advanced intra coding / mpeg4 ac prediction.
@item cbp
Deprecated, use mpegvideo private options instead.
@item qprd
Deprecated, use mpegvideo private options instead.
@item ilme
Apply interlaced motion estimation.
@item cgop
Use closed gop.
@item output_corrupt
Output even potentially corrupted frames.
@end table
@item me_method @var{integer} (@emph{encoding,video})
Set motion estimation method.
Possible values:
@table @samp
@item zero
zero motion estimation (fastest)
@item full
full motion estimation (slowest)
@item epzs
EPZS motion estimation (default)
@item esa
esa motion estimation (alias for full)
@item tesa
tesa motion estimation
@item dia
dia motion estimation (alias for epzs)
@item log
log motion estimation
@item phods
phods motion estimation
@item x1
X1 motion estimation
@item hex
hex motion estimation
@item umh
umh motion estimation
@item iter
iter motion estimation
@end table
@item extradata_size @var{integer}
Set extradata size.
@item time_base @var{rational number}
Set codec time base.
@ -181,24 +144,6 @@ Default value is 0.
@item b_qfactor @var{float} (@emph{encoding,video})
Set qp factor between P and B frames.
@item rc_strategy @var{integer} (@emph{encoding,video})
Set ratecontrol method.
@item b_strategy @var{integer} (@emph{encoding,video})
Set strategy to choose between I/P/B-frames.
@item ps @var{integer} (@emph{encoding,video})
Set RTP payload size in bytes.
@item mv_bits @var{integer}
@item header_bits @var{integer}
@item i_tex_bits @var{integer}
@item p_tex_bits @var{integer}
@item i_count @var{integer}
@item p_count @var{integer}
@item skip_count @var{integer}
@item misc_bits @var{integer}
@item frame_bits @var{integer}
@item codec_tag @var{integer}
@item bug @var{flags} (@emph{decoding,video})
Workaround not auto detected encoder bugs.
@ -207,8 +152,6 @@ Possible values:
@table @samp
@item autodetect
@item old_msmpeg4
some old lavc generated msmpeg4v3 files (no autodetection)
@item xvid_ilace
Xvid interlacing bug (autodetected if fourcc==XVIX)
@item ump4
@ -217,8 +160,6 @@ Xvid interlacing bug (autodetected if fourcc==XVIX)
padding bug (autodetected)
@item amv
@item ac_vlc
illegal vlc bug (autodetected per fourcc)
@item qpel_chroma
@item std_qpel
@ -239,14 +180,6 @@ Workaround various bugs in microsoft broken decoders.
trancated frames
@end table
@item lelim @var{integer} (@emph{encoding,video})
Set single coefficient elimination threshold for luminance (negative
values also consider DC coefficient).
@item celim @var{integer} (@emph{encoding,video})
Set single coefficient elimination threshold for chrominance (negative
values also consider dc coefficient)
@item strict @var{integer} (@emph{decoding/encoding,audio,video})
Specify how strictly to follow the standards.
@ -300,29 +233,8 @@ consider things that a sane encoder should not do as an error
@item block_align @var{integer}
@item mpeg_quant @var{integer} (@emph{encoding,video})
Use MPEG quantizers instead of H.263.
@item qsquish @var{float} (@emph{encoding,video})
How to keep quantizer between qmin and qmax (0 = clip, 1 = use
differentiable function).
@item rc_qmod_amp @var{float} (@emph{encoding,video})
Set experimental quantizer modulation.
@item rc_qmod_freq @var{integer} (@emph{encoding,video})
Set experimental quantizer modulation.
@item rc_override_count @var{integer}
@item rc_eq @var{string} (@emph{encoding,video})
Set rate control equation. When computing the expression, besides the
standard functions defined in the section 'Expression Evaluation', the
following functions are available: bits2qp(bits), qp2bits(qp). Also
the following constants are available: iTex pTex tex mv fCode iCount
mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex
avgTex.
@item maxrate @var{integer} (@emph{encoding,audio,video})
Set max bitrate tolerance (in bits/s). Requires bufsize to be set.
@ -333,18 +245,12 @@ encode. It is of little use elsewise.
@item bufsize @var{integer} (@emph{encoding,audio,video})
Set ratecontrol buffer size (in bits).
@item rc_buf_aggressivity @var{float} (@emph{encoding,video})
Currently useless.
@item i_qfactor @var{float} (@emph{encoding,video})
Set QP factor between P and I frames.
@item i_qoffset @var{float} (@emph{encoding,video})
Set QP offset between P and I frames.
@item rc_init_cplx @var{float} (@emph{encoding,video})
Set initial complexity for 1-pass encoding.
@item dct @var{integer} (@emph{encoding,video})
Set DCT algorithm.
@ -409,11 +315,7 @@ Automatically pick a IDCT compatible with the simple one
@item simpleneon
@item simplealpha
@item ipp
@item xvidmmx
@item xvid
@item faani
floating point AAN IDCT
@ -436,19 +338,6 @@ favor predicting from the previous frame instead of the current
@item bits_per_coded_sample @var{integer}
@item pred @var{integer} (@emph{encoding,video})
Set prediction method.
Possible values:
@table @samp
@item left
@item plane
@item median
@end table
@item aspect @var{rational number} (@emph{encoding,video})
Set sample aspect ratio.
@ -643,13 +532,28 @@ noise preserving sum of squared differences
@item dia_size @var{integer} (@emph{encoding,video})
Set diamond type & size for motion estimation.
@table @samp
@item (1024, INT_MAX)
full motion estimation(slowest)
@item (768, 1024]
umh motion estimation
@item (512, 768]
hex motion estimation
@item (256, 512]
l2s diamond motion estimation
@item [2,256]
var diamond motion estimation
@item (-1, 2)
small diamond motion estimation
@item -1
funny diamond motion estimation
@item (INT_MIN, -1)
sab diamond motion estimation
@end table
@item last_pred @var{integer} (@emph{encoding,video})
Set amount of motion predictors from the previous frame.
@item preme @var{integer} (@emph{encoding,video})
Set pre motion estimation.
@item precmp @var{integer} (@emph{encoding,video})
Set pre motion estimation compare function.
@ -693,40 +597,11 @@ Set diamond type & size for motion estimation pre-pass.
@item subq @var{integer} (@emph{encoding,video})
Set sub pel motion estimation quality.
@item dtg_active_format @var{integer}
@item me_range @var{integer} (@emph{encoding,video})
Set limit motion vectors range (1023 for DivX player).
@item ibias @var{integer} (@emph{encoding,video})
Set intra quant bias.
@item pbias @var{integer} (@emph{encoding,video})
Set inter quant bias.
@item color_table_id @var{integer}
@item global_quality @var{integer} (@emph{encoding,audio,video})
@item coder @var{integer} (@emph{encoding,video})
Possible values:
@table @samp
@item vlc
variable length coder / huffman coder
@item ac
arithmetic coder
@item raw
raw (no encoding)
@item rle
run-length coder
@item deflate
deflate-based coder
@end table
@item context @var{integer} (@emph{encoding,video})
Set context model.
@item slice_flags @var{integer}
@item mbd @var{integer} (@emph{encoding,video})
@ -742,32 +617,16 @@ use fewest bits
use best rate distortion
@end table
@item stream_codec_tag @var{integer}
@item sc_threshold @var{integer} (@emph{encoding,video})
Set scene change threshold.
@item lmin @var{integer} (@emph{encoding,video})
Set min lagrange factor (VBR).
@item lmax @var{integer} (@emph{encoding,video})
Set max lagrange factor (VBR).
@item nr @var{integer} (@emph{encoding,video})
Set noise reduction.
@item rc_init_occupancy @var{integer} (@emph{encoding,video})
Set number of bits which should be loaded into the rc buffer before
decoding starts.
@item flags2 @var{flags} (@emph{decoding/encoding,audio,video})
@item flags2 @var{flags} (@emph{decoding/encoding,audio,video,subtitles})
Possible values:
@table @samp
@item fast
Allow non spec compliant speedup tricks.
@item sgop
Deprecated, use mpegvideo private options instead.
@item noout
Skip bitstream encoding.
@item ignorecrop
@ -781,12 +640,29 @@ Show all frames before the first keyframe.
@item export_mvs
Export motion vectors into frame side-data (see @code{AV_FRAME_DATA_MOTION_VECTORS})
for codecs that support it. See also @file{doc/examples/export_mvs.c}.
@item skip_manual
Do not skip samples and export skip information as frame side data.
@item ass_ro_flush_noop
Do not reset ASS ReadOrder field on flush.
@end table
@item error @var{integer} (@emph{encoding,video})
@item export_side_data @var{flags} (@emph{decoding/encoding,audio,video,subtitles})
@item qns @var{integer} (@emph{encoding,video})
Deprecated, use mpegvideo private options instead.
Possible values:
@table @samp
@item mvs
Export motion vectors into frame side-data (see @code{AV_FRAME_DATA_MOTION_VECTORS})
for codecs that support it. See also @file{doc/examples/export_mvs.c}.
@item prft
Export encoder Producer Reference Time into packet side-data (see @code{AV_PKT_DATA_PRFT})
for codecs that support it.
@item venc_params
Export video encoding parameters through frame side data (see @code{AV_FRAME_DATA_VIDEO_ENC_PARAMS})
for codecs that support it. At present, those are H.264 and VP9.
@item film_grain
Export film grain parameters through frame side data (see @code{AV_FRAME_DATA_FILM_GRAIN_PARAMS}).
Supported at present by AV1 decoders.
@end table
@item threads @var{integer} (@emph{decoding/encoding,video})
Set the number of threads to be used, in case the selected codec
@ -800,12 +676,6 @@ automatically select the number of threads to set
Default value is @samp{auto}.
@item me_threshold @var{integer} (@emph{encoding,video})
Set motion estimation threshold.
@item mb_threshold @var{integer} (@emph{encoding,video})
Set macroblock threshold.
@item dc @var{integer} (@emph{encoding,video})
Set intra_dc_precision.
@ -820,49 +690,8 @@ Set number of macroblock rows at the bottom which are skipped.
@item profile @var{integer} (@emph{encoding,audio,video})
Possible values:
@table @samp
@item unknown
@item aac_main
@item aac_low
@item aac_ssr
@item aac_ltp
@item aac_he
@item aac_he_v2
@item aac_ld
@item aac_eld
@item mpeg2_aac_low
@item mpeg2_aac_he
@item mpeg4_sp
@item mpeg4_core
@item mpeg4_main
@item mpeg4_asp
@item dts
@item dts_es
@item dts_96_24
@item dts_hd_hra
@item dts_hd_ma
@end table
Set encoder codec profile. Default value is @samp{unknown}. Encoder specific
profiles are documented in the relevant encoder documentation.
@item level @var{integer} (@emph{encoding,audio,video})
@ -875,67 +704,12 @@ Possible values:
@item lowres @var{integer} (@emph{decoding,audio,video})
Decode at 1= 1/2, 2=1/4, 3=1/8 resolutions.
@item skip_threshold @var{integer} (@emph{encoding,video})
Set frame skip threshold.
@item skip_factor @var{integer} (@emph{encoding,video})
Set frame skip factor.
@item skip_exp @var{integer} (@emph{encoding,video})
Set frame skip exponent.
Negative values behave identical to the corresponding positive ones, except
that the score is normalized.
Positive values exist primarily for compatibility reasons and are not so useful.
@item skipcmp @var{integer} (@emph{encoding,video})
Set frame skip compare function.
Possible values:
@table @samp
@item sad
sum of absolute differences, fast (default)
@item sse
sum of squared errors
@item satd
sum of absolute Hadamard transformed differences
@item dct
sum of absolute DCT transformed differences
@item psnr
sum of squared quantization errors (avoid, low quality)
@item bit
number of bits needed for the block
@item rd
rate distortion optimal, slow
@item zero
0
@item vsad
sum of absolute vertical differences
@item vsse
sum of squared vertical differences
@item nsse
noise preserving sum of squared differences
@item w53
5/3 wavelet, only used in snow
@item w97
9/7 wavelet, only used in snow
@item dctmax
@item chroma
@end table
@item border_mask @var{float} (@emph{encoding,video})
Increase the quantizer for macroblocks close to borders.
@item mblmin @var{integer} (@emph{encoding,video})
Set min macroblock lagrange factor (VBR).
@item mblmax @var{integer} (@emph{encoding,video})
Set max macroblock lagrange factor (VBR).
@item mepc @var{integer} (@emph{encoding,video})
Set motion estimation bitrate penalty compensation (1.0 = 256).
@item skip_loop_filter @var{integer} (@emph{decoding,video})
@item skip_idct @var{integer} (@emph{decoding,video})
@item skip_frame @var{integer} (@emph{decoding,video})
@ -975,34 +749,17 @@ Default value is @samp{default}.
@item bidir_refine @var{integer} (@emph{encoding,video})
Refine the two motion vectors used in bidirectional macroblocks.
@item brd_scale @var{integer} (@emph{encoding,video})
Downscale frames for dynamic B-frame decision.
@item keyint_min @var{integer} (@emph{encoding,video})
Set minimum interval between IDR-frames.
@item refs @var{integer} (@emph{encoding,video})
Set reference frames to consider for motion compensation.
@item chromaoffset @var{integer} (@emph{encoding,video})
Set chroma qp offset from luma.
@item trellis @var{integer} (@emph{encoding,audio,video})
Set rate-distortion optimal quantization.
@item mv0_threshold @var{integer} (@emph{encoding,video})
@item b_sensitivity @var{integer} (@emph{encoding,video})
Adjust sensitivity of b_frame_strategy 1.
@item compression_level @var{integer} (@emph{encoding,audio,video})
@item min_prediction_order @var{integer} (@emph{encoding,audio})
@item max_prediction_order @var{integer} (@emph{encoding,audio})
@item timecode_frame_start @var{integer} (@emph{encoding,video})
Set GOP timecode frame start number, in non drop frame format.
@item request_channels @var{integer} (@emph{decoding,audio})
Set desired number of audio channels.
@item bits_per_raw_sample @var{integer}
@item channel_layout @var{integer} (@emph{decoding/encoding,audio})
@ -1116,6 +873,12 @@ BT.2020 NCL
BT.2020 CL
@item smpte2085
SMPTE 2085
@item chroma-derived-nc
Chroma-derived NCL
@item chroma-derived-c
Chroma-derived CL
@item ictcp
ICtCp
@end table
@item color_range @var{integer} (@emph{decoding/encoding,video})

View File

@ -25,6 +25,19 @@ enabled decoders.
A description of some of the currently available video decoders
follows.
@section av1
AOMedia Video 1 (AV1) decoder.
@subsection Options
@table @option
@item operating_point
Select an operating point of a scalable AV1 bitstream (0 - 31). Default is 0.
@end table
@section rawvideo
Raw video decoder.
@ -57,19 +70,32 @@ You need to explicitly configure the build with @code{--enable-libdav1d}.
@subsection Options
The following option is supported by the libdav1d wrapper.
The following options are supported by the libdav1d wrapper.
@table @option
@item framethreads
Set amount of frame threads to use during decoding. The default value is 0 (autodetect).
This option is deprecated for libdav1d >= 1.0 and will be removed in the future. Use the
global option @code{threads} instead.
@item tilethreads
Set amount of tile threads to use during decoding. The default value is 0 (autodetect).
This option is deprecated for libdav1d >= 1.0 and will be removed in the future. Use the
global option @code{threads} instead.
@item filmgrain
Apply film grain to the decoded video if present in the bitstream. The default value
is true.
Apply film grain to the decoded video if present in the bitstream. Defaults to the
internal default of the library.
This option is deprecated and will be removed in the future. See the global option
@code{export_side_data} to export Film Grain parameters instead of applying it.
@item oppoint
Select an operating point of a scalable AV1 bitstream (0 - 31). Defaults to the
internal default of the library.
@item alllayers
Output all spatial layers of a scalable AV1 bitstream. The default value is false.
@end table
@ -81,6 +107,84 @@ This decoder allows libavcodec to decode AVS2 streams with davs2 library.
@c man end VIDEO DECODERS
@section libuavs3d
AVS3-P2/IEEE1857.10 video decoder.
libuavs3d allows libavcodec to decode AVS3 streams.
Requires the presence of the libuavs3d headers and library during configuration.
You need to explicitly configure the build with @code{--enable-libuavs3d}.
@subsection Options
The following option is supported by the libuavs3d wrapper.
@table @option
@item frame_threads
Set amount of frame threads to use during decoding. The default value is 0 (autodetect).
@end table
@section QSV Decoders
The family of Intel QuickSync Video decoders (VC1, MPEG-2, H.264, HEVC,
JPEG/MJPEG, VP8, VP9, AV1).
@subsection Common Options
The following options are supported by all qsv decoders.
@table @option
@item @var{async_depth}
Internal parallelization depth, the higher the value the higher the latency.
@item @var{gpu_copy}
A GPU-accelerated copy between video and system memory
@table @samp
@item default
@item on
@item off
@end table
@end table
@subsection HEVC Options
Extra options for hevc_qsv.
@table @option
@item @var{load_plugin}
A user plugin to load in an internal session
@table @samp
@item none
@item hevc_sw
@item hevc_hw
@end table
@item @var{load_plugins}
A :-separate list of hexadecimal plugin UIDs to load in an internal session
@end table
@section v210
Uncompressed 4:2:2 10-bit decoder.
@subsection Options
@table @option
@item custom_stride
Set the line size of the v210 data in bytes. The default value is 0
(autodetect). You can use the special -1 value for a strideless v210 as seen in
BOXX files.
@end table
@c man end VIDEO DECODERS
@chapter Audio Decoders
@c man begin AUDIO DECODERS
@ -100,7 +204,7 @@ the undocumented RealAudio 3 (a.k.a. dnet).
@item -drc_scale @var{value}
Dynamic Range Scale Factor. The factor to apply to dynamic range values
from the AC-3 stream. This factor is applied exponentially.
from the AC-3 stream. This factor is applied exponentially. The default value is 1.
There are 3 notable scale factor ranges:
@table @option
@item drc_scale == 0
@ -252,6 +356,8 @@ Enabled by default.
@table @option
@item compute_clut
@table @option
@item -2
Compute clut once if no matching CLUT is in the stream.
@item -1
Compute clut if no matching CLUT is in the stream.
@item 0
@ -280,7 +386,7 @@ palette is stored in the IFO file, and therefore not available when reading
from dumped VOB files.
The format for this option is a string containing 16 24-bits hexadecimal
numbers (without 0x prefix) separated by comas, for example @code{0d00ee,
numbers (without 0x prefix) separated by commas, for example @code{0d00ee,
ee450d, 101010, eaeaea, 0ce60b, ec14ed, ebff0b, 0d617a, 7b7b7b, d1d1d1,
7b2a0e, 0d950c, 0f007b, cf0dec, cfa80c, 7c127b}.
@ -309,6 +415,11 @@ List of teletext page numbers to decode. Pages that do not match the specified
list are dropped. You may use the special @code{*} string to match all pages,
or @code{subtitle} to match all subtitle pages.
Default value is *.
@item txt_default_region
Set default character set used for decoding, a value between 0 and 87 (see
ETS 300 706, Section 15, Table 32). Default value is -1, which does not
override the libzvbi default. This option is needed for some legacy level 1.0
transmissions which cannot signal the proper charset.
@item txt_chop_top
Discards the top teletext line. Default value is 1.
@item txt_format

View File

@ -25,6 +25,13 @@ Audible Format 2, 3, and 4 demuxer.
This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files.
@section aac
Raw Audio Data Transport Stream AAC demuxer.
This demuxer is used to demux an ADTS input containing a single AAC stream
alongwith any ID3v1/2 or APE tags in it.
@section apng
Animated Portable Network Graphics demuxer.
@ -37,12 +44,15 @@ between the last fcTL and IEND chunks.
@table @option
@item -ignore_loop @var{bool}
Ignore the loop variable in the file if set.
Ignore the loop variable in the file if set. Default is enabled.
@item -max_fps @var{int}
Maximum framerate in frames per second (0 for no limit).
Maximum framerate in frames per second. Default of 0 imposes no limit.
@item -default_fps @var{int}
Default framerate in frames per second when none is specified in the file
(0 meaning as fast as possible).
(0 meaning as fast as possible). Default is 15.
@end table
@section asf
@ -93,8 +103,7 @@ backslash or single quotes.
All subsequent file-related directives apply to that file.
@item @code{ffconcat version 1.0}
Identify the script type and version. It also sets the @option{safe} option
to 1 if it was -1.
Identify the script type and version.
To make FFmpeg recognize the format automatically, this directive must
appear exactly as is (no extra space or byte-order-mark) on the very first
@ -148,6 +157,16 @@ directive) will be reduced based on their specified Out point.
Metadata of the packets of the file. The specified metadata will be set for
each file packet. You can specify this directive multiple times to add multiple
metadata entries.
This directive is deprecated, use @code{file_packet_meta} instead.
@item @code{file_packet_meta @var{key} @var{value}}
Metadata of the packets of the file. The specified metadata will be set for
each file packet. You can specify this directive multiple times to add multiple
metadata entries.
@item @code{option @var{key} @var{value}}
Option to access, open and probe the file.
Can be present multiple times.
@item @code{stream}
Introduce a stream in the virtual file.
@ -165,6 +184,20 @@ subfiles will be used.
This is especially useful for MPEG-PS (VOB) files, where the order of the
streams is not reliable.
@item @code{stream_meta @var{key} @var{value}}
Metadata for the stream.
Can be present multiple times.
@item @code{stream_codec @var{value}}
Codec for the stream.
@item @code{stream_extradata @var{hex_string}}
Extradata for the string, encoded in hexadecimal.
@item @code{chapter @var{id} @var{start} @var{end}}
Add a chapter. @var{id} is an unique identifier, possibly small and
consecutive.
@end table
@subsection Options
@ -174,7 +207,8 @@ This demuxer accepts the following option:
@table @option
@item safe
If set to 1, reject unsafe file paths. A file path is considered safe if it
If set to 1, reject unsafe file paths and directives.
A file path is considered safe if it
does not contain a protocol specification and is relative and all components
only contain characters from the portable character set (letters, digits,
period, underscore and hyphen) and have no period at the beginning of a
@ -184,9 +218,6 @@ If set to 0, any file name is accepted.
The default is 1.
-1 is equivalent to 1 if the format was automatically
probed and 0 otherwise.
@item auto_convert
If set to 1, try to perform automatic conversions on packet data to make the
streams concatenable.
@ -243,11 +274,29 @@ which streams to actually receive.
Each stream mirrors the @code{id} and @code{bandwidth} properties from the
@code{<Representation>} as metadata keys named "id" and "variant_bitrate" respectively.
@section flv, live_flv
@subsection Options
This demuxer accepts the following option:
@table @option
@item cenc_decryption_key
16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
@end table
@section imf
Interoperable Master Format demuxer.
This demuxer presents audio and video streams found in an IMF Composition.
@section flv, live_flv, kux
Adobe Flash Video Format demuxer.
This demuxer is used to demux FLV files and RTMP network streams. In case of live network streams, if you force format, you may use live_flv option instead of flv to survive timestamp discontinuities.
KUX is a flv variant used on the Youku platform.
@example
ffmpeg -f flv -i myfile.flv ...
@ -324,6 +373,9 @@ It accepts the following options:
@item live_start_index
segment index to start live streams at (negative values are from the end).
@item prefer_x_start
prefer to use #EXT-X-START if it's in playlist instead of live_start_index.
@item allowed_extensions
',' separated list of file extensions that hls is allowed to access.
@ -331,6 +383,10 @@ segment index to start live streams at (negative values are from the end).
Maximum number of times a insufficient list is attempted to be reloaded.
Default value is 1000.
@item m3u8_hold_counters
The maximum number of times to load m3u8 when it refreshes without new segments.
Default value is 1000.
@item http_persistent
Use persistent HTTP connections. Applicable only for HTTP streams.
Enabled by default.
@ -338,6 +394,13 @@ Enabled by default.
@item http_multiple
Use multiple HTTP connections for downloading HTTP segments.
Enabled by default for HTTP/1.1 servers.
@item http_seekable
Use HTTP partial requests for downloading HTTP segments.
0 = disable, 1 = enable, -1 = auto, Default is auto.
@item seg_format_options
Set options for the demuxer of media segments using a list of key=value pairs separated by @code{:}.
@end table
@section image2
@ -448,6 +511,17 @@ nanosecond precision.
@item video_size
Set the video size of the images to read. If not specified the video
size is guessed from the first image file in the sequence.
@item export_path_metadata
If set to 1, will add two extra fields to the metadata found in input, making them
also available for other filters (see @var{drawtext} filter for examples). Default
value is 0. The extra fields are described below:
@table @option
@item lavf.image2dec.source_path
Corresponds to the full path to the input file being read.
@item lavf.image2dec.source_basename
Corresponds to the name of the file being read.
@end table
@end table
@subsection Examples
@ -585,9 +659,13 @@ Set the sample rate for libopenmpt to output.
Range is from 1000 to INT_MAX. The value default is 48000.
@end table
@section mov/mp4/3gp/QuickTime
@section mov/mp4/3gp
QuickTime / MP4 demuxer.
Demuxer for Quicktime File Format & ISO/IEC Base Media File Format (ISO/IEC 14496-12 or MPEG-4 Part 12, ISO/IEC 15444-12 or JPEG 2000 Part 12).
Registered extensions: mov, mp4, m4a, 3gp, 3g2, mj2, psp, m4b, ism, ismv, isma, f4v
@subsection Options
This demuxer accepts the following options:
@table @option
@ -598,10 +676,88 @@ Enabling this can theoretically leak information in some use cases.
@item use_absolute_path
Allows loading of external tracks via absolute paths, disabled by default.
Enabling this poses a security risk. It should only be enabled if the source
is known to be non malicious.
is known to be non-malicious.
@item seek_streams_individually
When seeking, identify the closest point in each stream individually and demux packets in
that stream from identified point. This can lead to a different sequence of packets compared
to demuxing linearly from the beginning. Default is true.
@item ignore_editlist
Ignore any edit list atoms. The demuxer, by default, modifies the stream index to reflect the
timeline described by the edit list. Default is false.
@item advanced_editlist
Modify the stream index to reflect the timeline described by the edit list. @code{ignore_editlist}
must be set to false for this option to be effective.
If both @code{ignore_editlist} and this option are set to false, then only the
start of the stream index is modified to reflect initial dwell time or starting timestamp
described by the edit list. Default is true.
@item ignore_chapters
Don't parse chapters. This includes GoPro 'HiLight' tags/moments. Note that chapters are
only parsed when input is seekable. Default is false.
@item use_mfra_for
For seekable fragmented input, set fragment's starting timestamp from media fragment random access box, if present.
Following options are available:
@table @samp
@item auto
Auto-detect whether to set mfra timestamps as PTS or DTS @emph{(default)}
@item dts
Set mfra timestamps as DTS
@item pts
Set mfra timestamps as PTS
@item 0
Don't use mfra box to set timestamps
@end table
@item use_tfdt
For fragmented input, set fragment's starting timestamp to @code{baseMediaDecodeTime} from the @code{tfdt} box.
Default is enabled, which will prefer to use the @code{tfdt} box to set DTS. Disable to use the @code{earliest_presentation_time} from the @code{sidx} box.
In either case, the timestamp from the @code{mfra} box will be used if it's available and @code{use_mfra_for} is
set to pts or dts.
@item export_all
Export unrecognized boxes within the @var{udta} box as metadata entries. The first four
characters of the box type are set as the key. Default is false.
@item export_xmp
Export entire contents of @var{XMP_} box and @var{uuid} box as a string with key @code{xmp}. Note that
if @code{export_all} is set and this option isn't, the contents of @var{XMP_} box are still exported
but with key @code{XMP_}. Default is false.
@item activation_bytes
4-byte key required to decrypt Audible AAX and AAX+ files. See Audible AAX subsection below.
@item audible_fixed_key
Fixed key used for handling Audible AAX/AAX+ files. It has been pre-set so should not be necessary to
specify.
@item decryption_key
16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
@item max_stts_delta
Very high sample deltas written in a trak's stts box may occasionally be intended but usually they are written in
error or used to store a negative value for dts correction when treated as signed 32-bit integers. This option lets
the user set an upper limit, beyond which the delta is clamped to 1. Values greater than the limit if negative when
cast to int32 are used to adjust onward dts.
Unit is the track time scale. Range is 0 to UINT_MAX. Default is @code{UINT_MAX - 48000*10} which allows upto
a 10 second dts correction for 48 kHz audio streams while accommodating 99.9% of @code{uint32} range.
@end table
@subsection Audible AAX
Audible AAX files are encrypted M4B files, and they can be decrypted by specifying a 4 byte activation secret.
@example
ffmpeg -activation_bytes 1CEB00DA -i test.aax -vn -c:a copy output.mp4
@end example
@section mpegts
MPEG-2 transport stream demuxer.
@ -633,6 +789,10 @@ disabled). Default value is -1.
@item merge_pmt_versions
Re-use existing streams when a PMT's version is updated and elementary
streams move to different PIDs. Default value is 0.
@item max_packet_size
Set maximum size, in bytes, of packet emitted by the demuxer. Payloads above this size
are split across multiple packets. Range is 1 to INT_MAX/2. Default is 204800 bytes.
@end table
@section mpjpeg

View File

@ -0,0 +1,79 @@
# FFmpeg project
## Organisation
The FFmpeg project is organized through a community working on global consensus.
Decisions are taken by the ensemble of active members, through voting and
are aided by two committees.
## General Assembly
The ensemble of active members is called the General Assembly (GA).
The General Assembly is sovereign and legitimate for all its decisions
regarding the FFmpeg project.
The General Assembly is made up of active contributors.
Contributors are considered "active contributors" if they have pushed more
than 20 patches in the last 36 months in the main FFmpeg repository, or
if they have been voted in by the GA.
Additional members are added to the General Assembly through a vote after
proposal by a member of the General Assembly.
They are part of the GA for two years, after which they need a confirmation by
the GA.
## Voting
Voting is done using a ranked voting system, currently running on https://vote.ffmpeg.org/ .
Majority vote means more than 50% of the expressed ballots.
## Technical Committee
The Technical Committee (TC) is here to arbitrate and make decisions when
technical conflicts occur in the project.
They will consider the merits of all the positions, judge them and make a
decision.
The TC resolves technical conflicts but is not a technical steering committee.
Decisions by the TC are binding for all the contributors.
Decisions made by the TC can be re-opened after 1 year or by a majority vote
of the General Assembly, requested by one of the member of the GA.
The TC is elected by the General Assembly for a duration of 1 year, and
is composed of 5 members.
Members can be re-elected if they wish. A majority vote in the General Assembly
can trigger a new election of the TC.
The members of the TC can be elected from outside of the GA.
Candidates for election can either be suggested or self-nominated.
The conflict resolution process is detailed in the [resolution process](resolution_process.md) document.
## Community committee
The Community Committee (CC) is here to arbitrage and make decisions when
inter-personal conflicts occur in the project. It will decide quickly and
take actions, for the sake of the project.
The CC can remove privileges of offending members, including removal of
commit access and temporary ban from the community.
Decisions made by the CC can be re-opened after 1 year or by a majority vote
of the General Assembly. Indefinite bans from the community must be confirmed
by the General Assembly, in a majority vote.
The CC is elected by the General Assembly for a duration of 1 year, and is
composed of 5 members.
Members can be re-elected if they wish. A majority vote in the General Assembly
can trigger a new election of the CC.
The members of the CC can be elected from outside of the GA.
Candidates for election can either be suggested or self-nominated.
The CC is governed by and responsible for enforcing the Code of Conduct.

View File

@ -0,0 +1,91 @@
# Technical Committee
_This document only makes sense with the rules from [the community document](community)_.
The Technical Committee (**TC**) is here to arbitrate and make decisions when
technical conflicts occur in the project.
The TC main role is to resolve technical conflicts.
It is therefore not a technical steering committee, but it is understood that
some decisions might impact the future of the project.
# Process
## Seizing
The TC can take possession of any technical matter that it sees fit.
To involve the TC in a matter, email tc@ or CC them on an ongoing discussion.
As members of TC are developers, they also can email tc@ to raise an issue.
## Announcement
The TC, once seized, must announce itself on the main mailing list, with a _[TC]_ tag.
The TC has 2 modes of operation: a RFC one and an internal one.
If the TC thinks it needs the input from the larger community, the TC can call
for a RFC. Else, it can decide by itself.
If the disagreement involves a member of the TC, that member should recuse
themselves from the decision.
The decision to use a RFC process or an internal discussion is a discretionary
decision of the TC.
The TC can also reject a seizure for a few reasons such as:
the matter was not discussed enough previously; it lacks expertise to reach a
beneficial decision on the matter; or the matter is too trivial.
### RFC call
In the RFC mode, one person from the TC posts on the mailing list the
technical question and will request input from the community.
The mail will have the following specification:
* a precise title
* a specific tag [TC RFC]
* a top-level email
* contain a precise question that does not exceed 100 words and that is answerable by developers
* may have an extra description, or a link to a previous discussion, if deemed necessary,
* contain a precise end date for the answers.
The answers from the community must be on the main mailing list and must have
the following specification:
* keep the tag and the title unchanged
* limited to 400 words
* a first-level, answering directly to the main email
* answering to the question.
Further replies to answers are permitted, as long as they conform to the
community standards of politeness, they are limited to 100 words, and are not
nested more than once. (max-depth=2)
After the end-date, mails on the thread will be ignored.
Violations of those rules will be escalated through the Community Committee.
After all the emails are in, the TC has 96 hours to give its final decision.
Exceptionally, the TC can request an extra delay, that will be notified on the
mailing list.
### Within TC
In the internal case, the TC has 96 hours to give its final decision.
Exceptionally, the TC can request an extra delay.
## Decisions
The decisions from the TC will be sent on the mailing list, with the _[TC]_ tag.
Internally, the TC should take decisions with a majority, or using
ranked-choice voting.
The decision from the TC should be published with a summary of the reasons that
lead to this decision.
The decisions from the TC are final, until the matters are reopened after
no less than one year.

View File

@ -131,6 +131,9 @@ 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
@ -491,6 +494,22 @@ patch is inline or attached per mail.
You can check @url{https://patchwork.ffmpeg.org}, if your patch does not show up, its mime type
likely was wrong.
@subheading Sending patches from email clients
Using @code{git send-email} might not be desirable for everyone. The
following trick allows to send patches via email clients in a safe
way. It has been tested with Outlook and Thunderbird (with X-Unsent
extension) and might work with other applications.
Create your patch like this:
@verbatim
git format-patch -s -o "outputfolder" --add-header "X-Unsent: 1" --suffix .eml --to ffmpeg-devel@ffmpeg.org -1 1a2b3c4d
@end verbatim
Now you'll just need to open the eml file with the email application
and execute 'Send'.
@subheading Reviews
Your patch will be reviewed on the mailing list. You will likely be asked
to make some changes and are expected to send in an improved version that
incorporates the requests from the review. This process may go through
@ -622,7 +641,7 @@ If the patch fixes a bug, did you provide a verbose analysis of the bug?
If the patch fixes a bug, did you provide enough information, including
a sample, so the bug can be reproduced and the fix can be verified?
Note please do not attach samples >100k to mails but rather provide a
URL, you can upload to ftp://upload.ffmpeg.org.
URL, you can upload to @url{https://streams.videolan.org/upload/}.
@item
Did you provide a verbose summary about what the patch does change?

View File

@ -1,10 +1,13 @@
#!/bin/sh
OUT_DIR="${1}"
DOXYFILE="${2}"
DOXYGEN="${3}"
SRC_DIR="${2}"
DOXYFILE="${3}"
DOXYGEN="${4}"
shift 3
shift 4
cd ${SRC_DIR}
if [ -e "VERSION" ]; then
VERSION=`cat "VERSION"`

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
EXAMPLES-$(CONFIG_AVIO_DIR_CMD_EXAMPLE) += avio_dir_cmd
EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir
EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading
EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio
EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video

View File

@ -11,7 +11,7 @@ CFLAGS += -Wall -g
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
EXAMPLES= avio_dir_cmd \
EXAMPLES= avio_list_dir \
avio_reading \
decode_audio \
decode_video \

View File

@ -102,38 +102,15 @@ static int list_op(const char *input_dir)
return ret;
}
static int del_op(const char *url)
{
int ret = avpriv_io_delete(url);
if (ret < 0)
av_log(NULL, AV_LOG_ERROR, "Cannot delete '%s': %s.\n", url, av_err2str(ret));
return ret;
}
static int move_op(const char *src, const char *dst)
{
int ret = avpriv_io_move(src, dst);
if (ret < 0)
av_log(NULL, AV_LOG_ERROR, "Cannot move '%s' into '%s': %s.\n", src, dst, av_err2str(ret));
return ret;
}
static void usage(const char *program_name)
{
fprintf(stderr, "usage: %s OPERATION entry1 [entry2]\n"
"API example program to show how to manipulate resources "
"accessed through AVIOContext.\n"
"OPERATIONS:\n"
"list list content of the directory\n"
"move rename content in directory\n"
"del delete content in directory\n",
program_name);
fprintf(stderr, "usage: %s input_dir\n"
"API example program to show how to list files in directory "
"accessed through AVIOContext.\n", program_name);
}
int main(int argc, char *argv[])
{
const char *op = NULL;
int ret;
av_log_set_level(AV_LOG_DEBUG);
@ -145,32 +122,7 @@ int main(int argc, char *argv[])
avformat_network_init();
op = argv[1];
if (strcmp(op, "list") == 0) {
if (argc < 3) {
av_log(NULL, AV_LOG_INFO, "Missing argument for list operation.\n");
ret = AVERROR(EINVAL);
} else {
ret = list_op(argv[2]);
}
} else if (strcmp(op, "del") == 0) {
if (argc < 3) {
av_log(NULL, AV_LOG_INFO, "Missing argument for del operation.\n");
ret = AVERROR(EINVAL);
} else {
ret = del_op(argv[2]);
}
} else if (strcmp(op, "move") == 0) {
if (argc < 4) {
av_log(NULL, AV_LOG_INFO, "Missing argument for move operation.\n");
ret = AVERROR(EINVAL);
} else {
ret = move_op(argv[2], argv[3]);
}
} else {
av_log(NULL, AV_LOG_INFO, "Invalid operation %s\n", op);
ret = AVERROR(EINVAL);
}
ret = list_op(argv[1]);
avformat_network_deinit();

View File

@ -39,6 +39,35 @@
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
static int get_format_from_sample_fmt(const char **fmt,
enum AVSampleFormat sample_fmt)
{
int i;
struct sample_fmt_entry {
enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
} sample_fmt_entries[] = {
{ AV_SAMPLE_FMT_U8, "u8", "u8" },
{ AV_SAMPLE_FMT_S16, "s16be", "s16le" },
{ AV_SAMPLE_FMT_S32, "s32be", "s32le" },
{ AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
{ AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
};
*fmt = NULL;
for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
struct sample_fmt_entry *entry = &sample_fmt_entries[i];
if (sample_fmt == entry->sample_fmt) {
*fmt = AV_NE(entry->fmt_be, entry->fmt_le);
return 0;
}
}
fprintf(stderr,
"sample format %s is not supported as output format\n",
av_get_sample_fmt_name(sample_fmt));
return -1;
}
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame,
FILE *outfile)
{
@ -68,7 +97,7 @@ static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame,
exit(1);
}
for (i = 0; i < frame->nb_samples; i++)
for (ch = 0; ch < dec_ctx->channels; ch++)
for (ch = 0; ch < dec_ctx->ch_layout.nb_channels; ch++)
fwrite(frame->data[ch] + data_size*i, 1, data_size, outfile);
}
}
@ -86,6 +115,9 @@ int main(int argc, char **argv)
size_t data_size;
AVPacket *pkt;
AVFrame *decoded_frame = NULL;
enum AVSampleFormat sfmt;
int n_channels = 0;
const char *fmt;
if (argc <= 2) {
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
@ -172,6 +204,26 @@ int main(int argc, char **argv)
pkt->size = 0;
decode(c, pkt, decoded_frame, outfile);
/* print output pcm infomations, because there have no metadata of pcm */
sfmt = c->sample_fmt;
if (av_sample_fmt_is_planar(sfmt)) {
const char *packed = av_get_sample_fmt_name(sfmt);
printf("Warning: the sample format the decoder produced is planar "
"(%s). This example will output the first channel only.\n",
packed ? packed : "?");
sfmt = av_get_packed_sample_fmt(sfmt);
}
n_channels = c->ch_layout.nb_channels;
if ((ret = get_format_from_sample_fmt(&fmt, sfmt)) < 0)
goto end;
printf("Play the output audio file with the command:\n"
"ffplay -f %s -ac %d -ar %d %s\n",
fmt, n_channels, c->sample_rate,
outfilename);
end:
fclose(outfile);
fclose(f);

View File

@ -41,7 +41,7 @@ static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
FILE *f;
int i;
f = fopen(filename,"w");
f = fopen(filename,"wb");
fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
for (i = 0; i < ysize; i++)
fwrite(buf + i * wrap, 1, xsize, f);
@ -92,10 +92,12 @@ int main(int argc, char **argv)
uint8_t *data;
size_t data_size;
int ret;
int eof;
AVPacket *pkt;
if (argc <= 2) {
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
fprintf(stderr, "Usage: %s <input file> <output file>\n"
"And check your input file is encoded by mpeg1video please.\n", argv[0]);
exit(0);
}
filename = argv[1];
@ -149,15 +151,16 @@ int main(int argc, char **argv)
exit(1);
}
while (!feof(f)) {
do {
/* read raw data from the input file */
data_size = fread(inbuf, 1, INBUF_SIZE, f);
if (!data_size)
if (ferror(f))
break;
eof = !data_size;
/* use the parser to split the data into frames */
data = inbuf;
while (data_size > 0) {
while (data_size > 0 || eof) {
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
if (ret < 0) {
@ -169,8 +172,10 @@ int main(int argc, char **argv)
if (pkt->size)
decode(c, frame, pkt, outfilename);
else if (eof)
break;
}
}
} while (!eof);
/* flush the decoder */
decode(c, frame, NULL, outfilename);

View File

@ -32,6 +32,7 @@
#include <libavutil/imgutils.h>
#include <libavutil/samplefmt.h>
#include <libavutil/timestamp.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
static AVFormatContext *fmt_ctx = NULL;
@ -51,99 +52,97 @@ static int video_dst_bufsize;
static int video_stream_idx = -1, audio_stream_idx = -1;
static AVFrame *frame = NULL;
static AVPacket pkt;
static AVPacket *pkt = NULL;
static int video_frame_count = 0;
static int audio_frame_count = 0;
/* Enable or disable frame reference counting. You are not supposed to support
* both paths in your application but pick the one most appropriate to your
* needs. Look for the use of refcount in this example to see what are the
* differences of API usage between them. */
static int refcount = 0;
static int decode_packet(int *got_frame, int cached)
static int output_video_frame(AVFrame *frame)
{
int ret = 0;
int decoded = pkt.size;
*got_frame = 0;
if (pkt.stream_index == video_stream_idx) {
/* decode video frame */
ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
if (ret < 0) {
fprintf(stderr, "Error decoding video frame (%s)\n", av_err2str(ret));
return ret;
}
if (*got_frame) {
if (frame->width != width || frame->height != height ||
frame->format != pix_fmt) {
/* To handle this change, one could call av_image_alloc again and
* decode the following frames into another rawvideo file. */
fprintf(stderr, "Error: Width, height and pixel format have to be "
"constant in a rawvideo file, but the width, height or "
"pixel format of the input video changed:\n"
"old: width = %d, height = %d, format = %s\n"
"new: width = %d, height = %d, format = %s\n",
width, height, av_get_pix_fmt_name(pix_fmt),
frame->width, frame->height,
av_get_pix_fmt_name(frame->format));
return -1;
}
printf("video_frame%s n:%d coded_n:%d\n",
cached ? "(cached)" : "",
video_frame_count++, frame->coded_picture_number);
/* copy decoded frame to destination buffer:
* this is required since rawvideo expects non aligned data */
av_image_copy(video_dst_data, video_dst_linesize,
(const uint8_t **)(frame->data), frame->linesize,
pix_fmt, width, height);
/* write to rawvideo file */
fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);
}
} else if (pkt.stream_index == audio_stream_idx) {
/* decode audio frame */
ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
if (ret < 0) {
fprintf(stderr, "Error decoding audio frame (%s)\n", av_err2str(ret));
return ret;
}
/* Some audio decoders decode only part of the packet, and have to be
* called again with the remainder of the packet data.
* Sample: fate-suite/lossless-audio/luckynight-partial.shn
* Also, some decoders might over-read the packet. */
decoded = FFMIN(ret, pkt.size);
if (*got_frame) {
size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(frame->format);
printf("audio_frame%s n:%d nb_samples:%d pts:%s\n",
cached ? "(cached)" : "",
audio_frame_count++, frame->nb_samples,
av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));
/* Write the raw audio data samples of the first plane. This works
* fine for packed formats (e.g. AV_SAMPLE_FMT_S16). However,
* most audio decoders output planar audio, which uses a separate
* plane of audio samples for each channel (e.g. AV_SAMPLE_FMT_S16P).
* In other words, this code will write only the first audio channel
* in these cases.
* You should use libswresample or libavfilter to convert the frame
* to packed data. */
fwrite(frame->extended_data[0], 1, unpadded_linesize, audio_dst_file);
}
if (frame->width != width || frame->height != height ||
frame->format != pix_fmt) {
/* To handle this change, one could call av_image_alloc again and
* decode the following frames into another rawvideo file. */
fprintf(stderr, "Error: Width, height and pixel format have to be "
"constant in a rawvideo file, but the width, height or "
"pixel format of the input video changed:\n"
"old: width = %d, height = %d, format = %s\n"
"new: width = %d, height = %d, format = %s\n",
width, height, av_get_pix_fmt_name(pix_fmt),
frame->width, frame->height,
av_get_pix_fmt_name(frame->format));
return -1;
}
/* If we use frame reference counting, we own the data and need
* to de-reference it when we don't use it anymore */
if (*got_frame && refcount)
av_frame_unref(frame);
printf("video_frame n:%d coded_n:%d\n",
video_frame_count++, frame->coded_picture_number);
return decoded;
/* copy decoded frame to destination buffer:
* this is required since rawvideo expects non aligned data */
av_image_copy(video_dst_data, video_dst_linesize,
(const uint8_t **)(frame->data), frame->linesize,
pix_fmt, width, height);
/* write to rawvideo file */
fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);
return 0;
}
static int output_audio_frame(AVFrame *frame)
{
size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(frame->format);
printf("audio_frame n:%d nb_samples:%d pts:%s\n",
audio_frame_count++, frame->nb_samples,
av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));
/* Write the raw audio data samples of the first plane. This works
* fine for packed formats (e.g. AV_SAMPLE_FMT_S16). However,
* most audio decoders output planar audio, which uses a separate
* plane of audio samples for each channel (e.g. AV_SAMPLE_FMT_S16P).
* In other words, this code will write only the first audio channel
* in these cases.
* You should use libswresample or libavfilter to convert the frame
* to packed data. */
fwrite(frame->extended_data[0], 1, unpadded_linesize, audio_dst_file);
return 0;
}
static int decode_packet(AVCodecContext *dec, const AVPacket *pkt)
{
int ret = 0;
// submit the packet to the decoder
ret = avcodec_send_packet(dec, pkt);
if (ret < 0) {
fprintf(stderr, "Error submitting a packet for decoding (%s)\n", av_err2str(ret));
return ret;
}
// get all the available frames from the decoder
while (ret >= 0) {
ret = avcodec_receive_frame(dec, frame);
if (ret < 0) {
// those two return values are special and mean there is no output
// frame available, but there were no errors during decoding
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
return 0;
fprintf(stderr, "Error during decoding (%s)\n", av_err2str(ret));
return ret;
}
// write the frame data to output file
if (dec->codec->type == AVMEDIA_TYPE_VIDEO)
ret = output_video_frame(frame);
else
ret = output_audio_frame(frame);
av_frame_unref(frame);
if (ret < 0)
return ret;
}
return 0;
}
static int open_codec_context(int *stream_idx,
@ -151,8 +150,7 @@ static int open_codec_context(int *stream_idx,
{
int ret, stream_index;
AVStream *st;
AVCodec *dec = NULL;
AVDictionary *opts = NULL;
const AVCodec *dec = NULL;
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
if (ret < 0) {
@ -186,9 +184,8 @@ static int open_codec_context(int *stream_idx,
return ret;
}
/* Init the decoders, with or without reference counting */
av_dict_set(&opts, "refcounted_frames", refcount ? "1" : "0", 0);
if ((ret = avcodec_open2(*dec_ctx, dec, &opts)) < 0) {
/* Init the decoders */
if ((ret = avcodec_open2(*dec_ctx, dec, NULL)) < 0) {
fprintf(stderr, "Failed to open %s codec\n",
av_get_media_type_string(type));
return ret;
@ -230,24 +227,17 @@ static int get_format_from_sample_fmt(const char **fmt,
int main (int argc, char **argv)
{
int ret = 0, got_frame;
int ret = 0;
if (argc != 4 && argc != 5) {
fprintf(stderr, "usage: %s [-refcount] input_file video_output_file audio_output_file\n"
if (argc != 4) {
fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"
"API example program to show how to read frames from an input file.\n"
"This program reads frames from a file, decodes them, and writes decoded\n"
"video frames to a rawvideo file named video_output_file, and decoded\n"
"audio frames to a rawaudio file named audio_output_file.\n\n"
"If the -refcount option is specified, the program use the\n"
"reference counting frame system which allows keeping a copy of\n"
"the data for longer than one decode call.\n"
"\n", argv[0]);
"audio frames to a rawaudio file named audio_output_file.\n",
argv[0]);
exit(1);
}
if (argc == 5 && !strcmp(argv[1], "-refcount")) {
refcount = 1;
argv++;
}
src_filename = argv[1];
video_dst_filename = argv[2];
audio_dst_filename = argv[3];
@ -313,10 +303,12 @@ int main (int argc, char **argv)
goto end;
}
/* initialize packet, set data to NULL, let the demuxer fill it */
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
pkt = av_packet_alloc();
if (!pkt) {
fprintf(stderr, "Could not allocate packet\n");
ret = AVERROR(ENOMEM);
goto end;
}
if (video_stream)
printf("Demuxing video from file '%s' into '%s'\n", src_filename, video_dst_filename);
@ -324,24 +316,23 @@ int main (int argc, char **argv)
printf("Demuxing audio from file '%s' into '%s'\n", src_filename, audio_dst_filename);
/* read frames from the file */
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
AVPacket orig_pkt = pkt;
do {
ret = decode_packet(&got_frame, 0);
if (ret < 0)
break;
pkt.data += ret;
pkt.size -= ret;
} while (pkt.size > 0);
av_packet_unref(&orig_pkt);
while (av_read_frame(fmt_ctx, pkt) >= 0) {
// check if the packet belongs to a stream we are interested in, otherwise
// skip it
if (pkt->stream_index == video_stream_idx)
ret = decode_packet(video_dec_ctx, pkt);
else if (pkt->stream_index == audio_stream_idx)
ret = decode_packet(audio_dec_ctx, pkt);
av_packet_unref(pkt);
if (ret < 0)
break;
}
/* flush cached frames */
pkt.data = NULL;
pkt.size = 0;
do {
decode_packet(&got_frame, 1);
} while (got_frame);
/* flush the decoders */
if (video_dec_ctx)
decode_packet(video_dec_ctx, NULL);
if (audio_dec_ctx)
decode_packet(audio_dec_ctx, NULL);
printf("Demuxing succeeded.\n");
@ -354,7 +345,7 @@ int main (int argc, char **argv)
if (audio_stream) {
enum AVSampleFormat sfmt = audio_dec_ctx->sample_fmt;
int n_channels = audio_dec_ctx->channels;
int n_channels = audio_dec_ctx->ch_layout.nb_channels;
const char *fmt;
if (av_sample_fmt_is_planar(sfmt)) {
@ -383,6 +374,7 @@ end:
fclose(video_dst_file);
if (audio_dst_file)
fclose(audio_dst_file);
av_packet_free(&pkt);
av_frame_free(&frame);
av_free(video_dst_data[0]);

View File

@ -70,26 +70,25 @@ static int select_sample_rate(const AVCodec *codec)
}
/* select layout with the highest channel count */
static int select_channel_layout(const AVCodec *codec)
static int select_channel_layout(const AVCodec *codec, AVChannelLayout *dst)
{
const uint64_t *p;
uint64_t best_ch_layout = 0;
const AVChannelLayout *p, *best_ch_layout;
int best_nb_channels = 0;
if (!codec->channel_layouts)
return AV_CH_LAYOUT_STEREO;
if (!codec->ch_layouts)
return av_channel_layout_copy(dst, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO);
p = codec->channel_layouts;
while (*p) {
int nb_channels = av_get_channel_layout_nb_channels(*p);
p = codec->ch_layouts;
while (p->nb_channels) {
int nb_channels = p->nb_channels;
if (nb_channels > best_nb_channels) {
best_ch_layout = *p;
best_ch_layout = p;
best_nb_channels = nb_channels;
}
p++;
}
return best_ch_layout;
return av_channel_layout_copy(dst, best_ch_layout);
}
static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt,
@ -164,8 +163,9 @@ int main(int argc, char **argv)
/* select other audio parameters supported by the encoder */
c->sample_rate = select_sample_rate(codec);
c->channel_layout = select_channel_layout(codec);
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
ret = select_channel_layout(codec, &c->ch_layout);
if (ret < 0)
exit(1);
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
@ -195,7 +195,9 @@ int main(int argc, char **argv)
frame->nb_samples = c->frame_size;
frame->format = c->sample_fmt;
frame->channel_layout = c->channel_layout;
ret = av_channel_layout_copy(&frame->ch_layout, &c->ch_layout);
if (ret < 0)
exit(1);
/* allocate the data buffers */
ret = av_frame_get_buffer(frame, 0);
@ -218,7 +220,7 @@ int main(int argc, char **argv)
for (j = 0; j < c->frame_size; j++) {
samples[2*j] = (int)(sin(t) * 10000);
for (k = 1; k < c->channels; k++)
for (k = 1; k < c->ch_layout.nb_channels; k++)
samples[2*j + k] = samples[2*j];
t += tincr;
}

View File

@ -145,7 +145,7 @@ int main(int argc, char **argv)
frame->width = c->width;
frame->height = c->height;
ret = av_frame_get_buffer(frame, 32);
ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {
fprintf(stderr, "Could not allocate the video frame data\n");
exit(1);
@ -155,12 +155,25 @@ int main(int argc, char **argv)
for (i = 0; i < 25; i++) {
fflush(stdout);
/* make sure the frame data is writable */
/* Make sure the frame data is writable.
On the first round, the frame is fresh from av_frame_get_buffer()
and therefore we know it is writable.
But on the next rounds, encode() will have called
avcodec_send_frame(), and the codec may have kept a reference to
the frame in its internal structures, that makes the frame
unwritable.
av_frame_make_writable() checks that and allocates a new buffer
for the frame only if necessary.
*/
ret = av_frame_make_writable(frame);
if (ret < 0)
exit(1);
/* prepare a dummy image */
/* Prepare a dummy image.
In real code, this is where you would have your own logic for
filling the frame. FFmpeg does not care what you put in the
frame.
*/
/* Y */
for (y = 0; y < c->height; y++) {
for (x = 0; x < c->width; x++) {
@ -185,8 +198,14 @@ int main(int argc, char **argv)
/* flush the encoder */
encode(c, NULL, pkt, f);
/* add sequence end code to have a real MPEG file */
fwrite(endcode, 1, sizeof(endcode), f);
/* Add sequence end code to have a real MPEG file.
It makes only sense because this tiny examples writes packets
directly. This is called "elementary stream" and only works for some
codecs. To create a valid file, you usually need to write packets
into a proper file format or protocol; see muxing.c.
*/
if (codec->id == AV_CODEC_ID_MPEG1VIDEO || codec->id == AV_CODEC_ID_MPEG2VIDEO)
fwrite(endcode, 1, sizeof(endcode), f);
fclose(f);
avcodec_free_context(&c);

View File

@ -22,6 +22,7 @@
*/
#include <libavutil/motion_vector.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
static AVFormatContext *fmt_ctx = NULL;
@ -78,7 +79,7 @@ static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
int ret;
AVStream *st;
AVCodecContext *dec_ctx = NULL;
AVCodec *dec = NULL;
const AVCodec *dec = NULL;
AVDictionary *opts = NULL;
ret = av_find_best_stream(fmt_ctx, type, -1, -1, &dec, 0);
@ -104,7 +105,9 @@ static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
/* Init the video decoder */
av_dict_set(&opts, "flags2", "+export_mvs", 0);
if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) {
ret = avcodec_open2(dec_ctx, dec, &opts);
av_dict_free(&opts);
if (ret < 0) {
fprintf(stderr, "Failed to open %s codec\n",
av_get_media_type_string(type));
return ret;
@ -121,7 +124,7 @@ static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
int main(int argc, char **argv)
{
int ret = 0;
AVPacket pkt = { 0 };
AVPacket *pkt = NULL;
if (argc != 2) {
fprintf(stderr, "Usage: %s <video>\n", argv[0]);
@ -156,13 +159,20 @@ int main(int argc, char **argv)
goto end;
}
pkt = av_packet_alloc();
if (!pkt) {
fprintf(stderr, "Could not allocate AVPacket\n");
ret = AVERROR(ENOMEM);
goto end;
}
printf("framenum,source,blockw,blockh,srcx,srcy,dstx,dsty,flags\n");
/* read frames from the file */
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
if (pkt.stream_index == video_stream_idx)
ret = decode_packet(&pkt);
av_packet_unref(&pkt);
while (av_read_frame(fmt_ctx, pkt) >= 0) {
if (pkt->stream_index == video_stream_idx)
ret = decode_packet(pkt);
av_packet_unref(pkt);
if (ret < 0)
break;
}
@ -174,5 +184,6 @@ end:
avcodec_free_context(&video_dec_ctx);
avformat_close_input(&fmt_ctx);
av_frame_free(&frame);
av_packet_free(&pkt);
return ret < 0;
}

View File

@ -55,7 +55,7 @@
#define INPUT_SAMPLERATE 48000
#define INPUT_FORMAT AV_SAMPLE_FMT_FLTP
#define INPUT_CHANNEL_LAYOUT AV_CH_LAYOUT_5POINT0
#define INPUT_CHANNEL_LAYOUT (AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0
#define VOLUME_VAL 0.90
@ -100,7 +100,7 @@ static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src,
}
/* Set the filter options through the AVOptions API. */
av_get_channel_layout_string(ch_layout, sizeof(ch_layout), 0, INPUT_CHANNEL_LAYOUT);
av_channel_layout_describe(&INPUT_CHANNEL_LAYOUT, ch_layout, sizeof(ch_layout));
av_opt_set (abuffer_ctx, "channel_layout", ch_layout, AV_OPT_SEARCH_CHILDREN);
av_opt_set (abuffer_ctx, "sample_fmt", av_get_sample_fmt_name(INPUT_FORMAT), AV_OPT_SEARCH_CHILDREN);
av_opt_set_q (abuffer_ctx, "time_base", (AVRational){ 1, INPUT_SAMPLERATE }, AV_OPT_SEARCH_CHILDREN);
@ -154,9 +154,8 @@ static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src,
/* A third way of passing the options is in a string of the form
* key1=value1:key2=value2.... */
snprintf(options_str, sizeof(options_str),
"sample_fmts=%s:sample_rates=%d:channel_layouts=0x%"PRIx64,
av_get_sample_fmt_name(AV_SAMPLE_FMT_S16), 44100,
(uint64_t)AV_CH_LAYOUT_STEREO);
"sample_fmts=%s:sample_rates=%d:channel_layouts=stereo",
av_get_sample_fmt_name(AV_SAMPLE_FMT_S16), 44100);
err = avfilter_init_str(aformat_ctx, options_str);
if (err < 0) {
av_log(NULL, AV_LOG_ERROR, "Could not initialize the aformat filter.\n");
@ -215,7 +214,7 @@ static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src,
static int process_output(struct AVMD5 *md5, AVFrame *frame)
{
int planar = av_sample_fmt_is_planar(frame->format);
int channels = av_get_channel_layout_nb_channels(frame->channel_layout);
int channels = frame->ch_layout.nb_channels;
int planes = planar ? channels : 1;
int bps = av_get_bytes_per_sample(frame->format);
int plane_size = bps * frame->nb_samples * (planar ? 1 : channels);
@ -248,7 +247,7 @@ static int get_input(AVFrame *frame, int frame_num)
/* Set up the frame properties and allocate the buffer for the data. */
frame->sample_rate = INPUT_SAMPLERATE;
frame->format = INPUT_FORMAT;
frame->channel_layout = INPUT_CHANNEL_LAYOUT;
av_channel_layout_copy(&frame->ch_layout, &INPUT_CHANNEL_LAYOUT);
frame->nb_samples = FRAME_SIZE;
frame->pts = frame_num * FRAME_SIZE;

View File

@ -34,6 +34,7 @@
#include <libavformat/avformat.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/channel_layout.h>
#include <libavutil/opt.h>
static const char *filter_descr = "aresample=8000,aformat=sample_fmts=s16:channel_layouts=mono";
@ -48,8 +49,8 @@ static int audio_stream_index = -1;
static int open_input_file(const char *filename)
{
const AVCodec *dec;
int ret;
AVCodec *dec;
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
@ -93,7 +94,6 @@ static int init_filters(const char *filters_descr)
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs = avfilter_inout_alloc();
static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 };
static const int64_t out_channel_layouts[] = { AV_CH_LAYOUT_MONO, -1 };
static const int out_sample_rates[] = { 8000, -1 };
const AVFilterLink *outlink;
AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base;
@ -105,12 +105,13 @@ static int init_filters(const char *filters_descr)
}
/* buffer audio source: the decoded frames from the decoder will be inserted here. */
if (!dec_ctx->channel_layout)
dec_ctx->channel_layout = av_get_default_channel_layout(dec_ctx->channels);
snprintf(args, sizeof(args),
"time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
if (dec_ctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
av_channel_layout_default(&dec_ctx->ch_layout, dec_ctx->ch_layout.nb_channels);
ret = snprintf(args, sizeof(args),
"time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=",
time_base.num, time_base.den, dec_ctx->sample_rate,
av_get_sample_fmt_name(dec_ctx->sample_fmt), dec_ctx->channel_layout);
av_get_sample_fmt_name(dec_ctx->sample_fmt));
av_channel_layout_describe(&dec_ctx->ch_layout, args + ret, sizeof(args) - ret);
ret = avfilter_graph_create_filter(&buffersrc_ctx, abuffersrc, "in",
args, NULL, filter_graph);
if (ret < 0) {
@ -133,7 +134,7 @@ static int init_filters(const char *filters_descr)
goto end;
}
ret = av_opt_set_int_list(buffersink_ctx, "channel_layouts", out_channel_layouts, -1,
ret = av_opt_set(buffersink_ctx, "ch_layouts", "mono",
AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
@ -184,7 +185,7 @@ static int init_filters(const char *filters_descr)
/* Print summary of the sink buffer
* Note: args buffer is reused to store channel layout string */
outlink = buffersink_ctx->inputs[0];
av_get_channel_layout_string(args, sizeof(args), -1, outlink->channel_layout);
av_channel_layout_describe(&outlink->ch_layout, args, sizeof(args));
av_log(NULL, AV_LOG_INFO, "Output: srate:%dHz fmt:%s chlayout:%s\n",
(int)outlink->sample_rate,
(char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"),
@ -199,7 +200,7 @@ end:
static void print_frame(const AVFrame *frame)
{
const int n = frame->nb_samples * av_get_channel_layout_nb_channels(frame->channel_layout);
const int n = frame->nb_samples * frame->ch_layout.nb_channels;
const uint16_t *p = (uint16_t*)frame->data[0];
const uint16_t *p_end = p + n;
@ -214,12 +215,12 @@ static void print_frame(const AVFrame *frame)
int main(int argc, char **argv)
{
int ret;
AVPacket packet;
AVPacket *packet = av_packet_alloc();
AVFrame *frame = av_frame_alloc();
AVFrame *filt_frame = av_frame_alloc();
if (!frame || !filt_frame) {
perror("Could not allocate frame");
if (!packet || !frame || !filt_frame) {
fprintf(stderr, "Could not allocate frame or packet\n");
exit(1);
}
if (argc != 2) {
@ -234,11 +235,11 @@ int main(int argc, char **argv)
/* read all packets */
while (1) {
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
if ((ret = av_read_frame(fmt_ctx, packet)) < 0)
break;
if (packet.stream_index == audio_stream_index) {
ret = avcodec_send_packet(dec_ctx, &packet);
if (packet->stream_index == audio_stream_index) {
ret = avcodec_send_packet(dec_ctx, packet);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");
break;
@ -274,12 +275,13 @@ int main(int argc, char **argv)
}
}
}
av_packet_unref(&packet);
av_packet_unref(packet);
}
end:
avfilter_graph_free(&filter_graph);
avcodec_free_context(&dec_ctx);
avformat_close_input(&fmt_ctx);
av_packet_free(&packet);
av_frame_free(&frame);
av_frame_free(&filt_frame);

View File

@ -53,8 +53,8 @@ static int64_t last_pts = AV_NOPTS_VALUE;
static int open_input_file(const char *filename)
{
const AVCodec *dec;
int ret;
AVCodec *dec;
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
@ -210,7 +210,7 @@ static void display_frame(const AVFrame *frame, AVRational time_base)
int main(int argc, char **argv)
{
int ret;
AVPacket packet;
AVPacket *packet;
AVFrame *frame;
AVFrame *filt_frame;
@ -221,8 +221,9 @@ int main(int argc, char **argv)
frame = av_frame_alloc();
filt_frame = av_frame_alloc();
if (!frame || !filt_frame) {
perror("Could not allocate frame");
packet = av_packet_alloc();
if (!frame || !filt_frame || !packet) {
fprintf(stderr, "Could not allocate frame or packet\n");
exit(1);
}
@ -233,11 +234,11 @@ int main(int argc, char **argv)
/* read all packets */
while (1) {
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
if ((ret = av_read_frame(fmt_ctx, packet)) < 0)
break;
if (packet.stream_index == video_stream_index) {
ret = avcodec_send_packet(dec_ctx, &packet);
if (packet->stream_index == video_stream_index) {
ret = avcodec_send_packet(dec_ctx, packet);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");
break;
@ -273,7 +274,7 @@ int main(int argc, char **argv)
av_frame_unref(frame);
}
}
av_packet_unref(&packet);
av_packet_unref(packet);
}
end:
avfilter_graph_free(&filter_graph);
@ -281,6 +282,7 @@ end:
avformat_close_input(&fmt_ctx);
av_frame_free(&frame);
av_frame_free(&filt_frame);
av_packet_free(&packet);
if (ret < 0 && ret != AVERROR_EOF) {
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));

View File

@ -152,8 +152,8 @@ int main(int argc, char *argv[])
int video_stream, ret;
AVStream *video = NULL;
AVCodecContext *decoder_ctx = NULL;
AVCodec *decoder = NULL;
AVPacket packet;
const AVCodec *decoder = NULL;
AVPacket *packet = NULL;
enum AVHWDeviceType type;
int i;
@ -172,6 +172,12 @@ int main(int argc, char *argv[])
return -1;
}
packet = av_packet_alloc();
if (!packet) {
fprintf(stderr, "Failed to allocate AVPacket\n");
return -1;
}
/* open the input file */
if (avformat_open_input(&input_ctx, argv[2], NULL, NULL) != 0) {
fprintf(stderr, "Cannot open input file '%s'\n", argv[2]);
@ -223,27 +229,25 @@ int main(int argc, char *argv[])
}
/* open the file to dump raw data */
output_file = fopen(argv[3], "w+");
output_file = fopen(argv[3], "w+b");
/* actual decoding and dump the raw data */
while (ret >= 0) {
if ((ret = av_read_frame(input_ctx, &packet)) < 0)
if ((ret = av_read_frame(input_ctx, packet)) < 0)
break;
if (video_stream == packet.stream_index)
ret = decode_write(decoder_ctx, &packet);
if (video_stream == packet->stream_index)
ret = decode_write(decoder_ctx, packet);
av_packet_unref(&packet);
av_packet_unref(packet);
}
/* flush the decoder */
packet.data = NULL;
packet.size = 0;
ret = decode_write(decoder_ctx, &packet);
av_packet_unref(&packet);
ret = decode_write(decoder_ctx, NULL);
if (output_file)
fclose(output_file);
av_packet_free(&packet);
avcodec_free_context(&decoder_ctx);
avformat_close_input(&input_ctx);
av_buffer_unref(&hw_device_ctx);

View File

@ -34,7 +34,7 @@
int main (int argc, char **argv)
{
AVFormatContext *fmt_ctx = NULL;
AVDictionaryEntry *tag = NULL;
const AVDictionaryEntry *tag = NULL;
int ret;
if (argc != 2) {

View File

@ -39,6 +39,7 @@
#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
#include <libavutil/timestamp.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libswresample/swresample.h>
@ -61,6 +62,8 @@ typedef struct OutputStream {
AVFrame *frame;
AVFrame *tmp_frame;
AVPacket *tmp_pkt;
float t, tincr, tincr2;
struct SwsContext *sws_ctx;
@ -78,20 +81,50 @@ static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)
pkt->stream_index);
}
static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
static int write_frame(AVFormatContext *fmt_ctx, AVCodecContext *c,
AVStream *st, AVFrame *frame, AVPacket *pkt)
{
/* rescale output packet timestamp values from codec to stream timebase */
av_packet_rescale_ts(pkt, *time_base, st->time_base);
pkt->stream_index = st->index;
int ret;
/* Write the compressed frame to the media file. */
log_packet(fmt_ctx, pkt);
return av_interleaved_write_frame(fmt_ctx, pkt);
// send the frame to the encoder
ret = avcodec_send_frame(c, frame);
if (ret < 0) {
fprintf(stderr, "Error sending a frame to the encoder: %s\n",
av_err2str(ret));
exit(1);
}
while (ret >= 0) {
ret = avcodec_receive_packet(c, pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
else if (ret < 0) {
fprintf(stderr, "Error encoding a frame: %s\n", av_err2str(ret));
exit(1);
}
/* rescale output packet timestamp values from codec to stream timebase */
av_packet_rescale_ts(pkt, c->time_base, st->time_base);
pkt->stream_index = st->index;
/* Write the compressed frame to the media file. */
log_packet(fmt_ctx, pkt);
ret = av_interleaved_write_frame(fmt_ctx, pkt);
/* pkt is now blank (av_interleaved_write_frame() takes ownership of
* its contents and resets pkt), so that no unreferencing is necessary.
* This would be different if one used av_write_frame(). */
if (ret < 0) {
fprintf(stderr, "Error while writing output packet: %s\n", av_err2str(ret));
exit(1);
}
}
return ret == AVERROR_EOF ? 1 : 0;
}
/* Add an output stream. */
static void add_stream(OutputStream *ost, AVFormatContext *oc,
AVCodec **codec,
const AVCodec **codec,
enum AVCodecID codec_id)
{
AVCodecContext *c;
@ -105,6 +138,12 @@ static void add_stream(OutputStream *ost, AVFormatContext *oc,
exit(1);
}
ost->tmp_pkt = av_packet_alloc();
if (!ost->tmp_pkt) {
fprintf(stderr, "Could not allocate AVPacket\n");
exit(1);
}
ost->st = avformat_new_stream(oc, NULL);
if (!ost->st) {
fprintf(stderr, "Could not allocate stream\n");
@ -131,16 +170,7 @@ static void add_stream(OutputStream *ost, AVFormatContext *oc,
c->sample_rate = 44100;
}
}
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
c->channel_layout = AV_CH_LAYOUT_STEREO;
if ((*codec)->channel_layouts) {
c->channel_layout = (*codec)->channel_layouts[0];
for (i = 0; (*codec)->channel_layouts[i]; i++) {
if ((*codec)->channel_layouts[i] == AV_CH_LAYOUT_STEREO)
c->channel_layout = AV_CH_LAYOUT_STEREO;
}
}
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
av_channel_layout_copy(&c->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO);
ost->st->time_base = (AVRational){ 1, c->sample_rate };
break;
@ -170,7 +200,7 @@ static void add_stream(OutputStream *ost, AVFormatContext *oc,
* the motion of the chroma plane does not match the luma plane. */
c->mb_decision = 2;
}
break;
break;
default:
break;
@ -185,7 +215,7 @@ static void add_stream(OutputStream *ost, AVFormatContext *oc,
/* audio output */
static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
uint64_t channel_layout,
const AVChannelLayout *channel_layout,
int sample_rate, int nb_samples)
{
AVFrame *frame = av_frame_alloc();
@ -197,7 +227,7 @@ static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
}
frame->format = sample_fmt;
frame->channel_layout = channel_layout;
av_channel_layout_copy(&frame->ch_layout, channel_layout);
frame->sample_rate = sample_rate;
frame->nb_samples = nb_samples;
@ -212,7 +242,8 @@ static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
return frame;
}
static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg)
static void open_audio(AVFormatContext *oc, const AVCodec *codec,
OutputStream *ost, AVDictionary *opt_arg)
{
AVCodecContext *c;
int nb_samples;
@ -241,9 +272,9 @@ static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, A
else
nb_samples = c->frame_size;
ost->frame = alloc_audio_frame(c->sample_fmt, c->channel_layout,
ost->frame = alloc_audio_frame(c->sample_fmt, &c->ch_layout,
c->sample_rate, nb_samples);
ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, c->channel_layout,
ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, &c->ch_layout,
c->sample_rate, nb_samples);
/* copy the stream parameters to the muxer */
@ -254,25 +285,25 @@ static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, A
}
/* create resampler context */
ost->swr_ctx = swr_alloc();
if (!ost->swr_ctx) {
fprintf(stderr, "Could not allocate resampler context\n");
exit(1);
}
ost->swr_ctx = swr_alloc();
if (!ost->swr_ctx) {
fprintf(stderr, "Could not allocate resampler context\n");
exit(1);
}
/* set options */
av_opt_set_int (ost->swr_ctx, "in_channel_count", c->channels, 0);
av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
av_opt_set_int (ost->swr_ctx, "out_channel_count", c->channels, 0);
av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
/* set options */
av_opt_set_chlayout (ost->swr_ctx, "in_chlayout", &c->ch_layout, 0);
av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
av_opt_set_chlayout (ost->swr_ctx, "out_chlayout", &c->ch_layout, 0);
av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
/* initialize the resampling context */
if ((ret = swr_init(ost->swr_ctx)) < 0) {
fprintf(stderr, "Failed to initialize the resampling context\n");
exit(1);
}
/* initialize the resampling context */
if ((ret = swr_init(ost->swr_ctx)) < 0) {
fprintf(stderr, "Failed to initialize the resampling context\n");
exit(1);
}
}
/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
@ -285,12 +316,12 @@ static AVFrame *get_audio_frame(OutputStream *ost)
/* check if we want to generate more frames */
if (av_compare_ts(ost->next_pts, ost->enc->time_base,
STREAM_DURATION, (AVRational){ 1, 1 }) >= 0)
STREAM_DURATION, (AVRational){ 1, 1 }) > 0)
return NULL;
for (j = 0; j <frame->nb_samples; j++) {
v = (int)(sin(ost->t) * 10000);
for (i = 0; i < ost->enc->channels; i++)
for (i = 0; i < ost->enc->ch_layout.nb_channels; i++)
*q++ = v;
ost->t += ost->tincr;
ost->tincr += ost->tincr2;
@ -309,23 +340,20 @@ static AVFrame *get_audio_frame(OutputStream *ost)
static int write_audio_frame(AVFormatContext *oc, OutputStream *ost)
{
AVCodecContext *c;
AVPacket pkt = { 0 }; // data and size must be 0;
AVFrame *frame;
int ret;
int got_packet;
int dst_nb_samples;
av_init_packet(&pkt);
c = ost->enc;
frame = get_audio_frame(ost);
if (frame) {
/* convert samples from native format to destination codec format, using the resampler */
/* compute destination number of samples */
dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples,
c->sample_rate, c->sample_rate, AV_ROUND_UP);
av_assert0(dst_nb_samples == frame->nb_samples);
/* compute destination number of samples */
dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples,
c->sample_rate, c->sample_rate, AV_ROUND_UP);
av_assert0(dst_nb_samples == frame->nb_samples);
/* when we pass a frame to the encoder, it may keep a reference to it
* internally;
@ -349,22 +377,7 @@ static int write_audio_frame(AVFormatContext *oc, OutputStream *ost)
ost->samples_count += dst_nb_samples;
}
ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet);
if (ret < 0) {
fprintf(stderr, "Error encoding audio frame: %s\n", av_err2str(ret));
exit(1);
}
if (got_packet) {
ret = write_frame(oc, &c->time_base, ost->st, &pkt);
if (ret < 0) {
fprintf(stderr, "Error while writing audio frame: %s\n",
av_err2str(ret));
exit(1);
}
}
return (frame || got_packet) ? 0 : 1;
return write_frame(oc, c, ost->st, frame, ost->tmp_pkt);
}
/**************************************************************/
@ -384,7 +397,7 @@ static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
picture->height = height;
/* allocate the buffers for the frame data */
ret = av_frame_get_buffer(picture, 32);
ret = av_frame_get_buffer(picture, 0);
if (ret < 0) {
fprintf(stderr, "Could not allocate frame data.\n");
exit(1);
@ -393,7 +406,8 @@ static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
return picture;
}
static void open_video(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg)
static void open_video(AVFormatContext *oc, const AVCodec *codec,
OutputStream *ost, AVDictionary *opt_arg)
{
int ret;
AVCodecContext *c = ost->enc;
@ -464,7 +478,7 @@ static AVFrame *get_video_frame(OutputStream *ost)
/* check if we want to generate more frames */
if (av_compare_ts(ost->next_pts, c->time_base,
STREAM_DURATION, (AVRational){ 1, 1 }) >= 0)
STREAM_DURATION, (AVRational){ 1, 1 }) > 0)
return NULL;
/* when we pass a frame to the encoder, it may keep a reference to it
@ -506,37 +520,7 @@ static AVFrame *get_video_frame(OutputStream *ost)
*/
static int write_video_frame(AVFormatContext *oc, OutputStream *ost)
{
int ret;
AVCodecContext *c;
AVFrame *frame;
int got_packet = 0;
AVPacket pkt = { 0 };
c = ost->enc;
frame = get_video_frame(ost);
av_init_packet(&pkt);
/* encode the image */
ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
if (ret < 0) {
fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));
exit(1);
}
if (got_packet) {
ret = write_frame(oc, &c->time_base, ost->st, &pkt);
} else {
ret = 0;
}
if (ret < 0) {
fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
exit(1);
}
return (frame || got_packet) ? 0 : 1;
return write_frame(oc, ost->enc, ost->st, get_video_frame(ost), ost->tmp_pkt);
}
static void close_stream(AVFormatContext *oc, OutputStream *ost)
@ -544,6 +528,7 @@ static void close_stream(AVFormatContext *oc, OutputStream *ost)
avcodec_free_context(&ost->enc);
av_frame_free(&ost->frame);
av_frame_free(&ost->tmp_frame);
av_packet_free(&ost->tmp_pkt);
sws_freeContext(ost->sws_ctx);
swr_free(&ost->swr_ctx);
}
@ -554,10 +539,10 @@ static void close_stream(AVFormatContext *oc, OutputStream *ost)
int main(int argc, char **argv)
{
OutputStream video_st = { 0 }, audio_st = { 0 };
const AVOutputFormat *fmt;
const char *filename;
AVOutputFormat *fmt;
AVFormatContext *oc;
AVCodec *audio_codec, *video_codec;
const AVCodec *audio_codec, *video_codec;
int ret;
int have_video = 0, have_audio = 0;
int encode_video = 0, encode_audio = 0;
@ -644,10 +629,6 @@ int main(int argc, char **argv)
}
}
/* Write the trailer, if any. The trailer must be written before you
* close the CodecContexts open when you wrote the header; otherwise
* av_write_trailer() may try to use memory that was freed on
* av_codec_close(). */
av_write_trailer(oc);
/* Close each codec. */

View File

@ -44,38 +44,10 @@
#include "libavutil/hwcontext_qsv.h"
#include "libavutil/mem.h"
typedef struct DecodeContext {
AVBufferRef *hw_device_ref;
} DecodeContext;
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) {
DecodeContext *decode = avctx->opaque;
AVHWFramesContext *frames_ctx;
AVQSVFramesContext *frames_hwctx;
int ret;
/* create a pool of surfaces to be used by the decoder */
avctx->hw_frames_ctx = av_hwframe_ctx_alloc(decode->hw_device_ref);
if (!avctx->hw_frames_ctx)
return AV_PIX_FMT_NONE;
frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
frames_hwctx = frames_ctx->hwctx;
frames_ctx->format = AV_PIX_FMT_QSV;
frames_ctx->sw_format = avctx->sw_pix_fmt;
frames_ctx->width = FFALIGN(avctx->coded_width, 32);
frames_ctx->height = FFALIGN(avctx->coded_height, 32);
frames_ctx->initial_pool_size = 32;
frames_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);
if (ret < 0)
return AV_PIX_FMT_NONE;
return AV_PIX_FMT_QSV;
}
@ -87,7 +59,7 @@ static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
return AV_PIX_FMT_NONE;
}
static int decode_packet(DecodeContext *decode, AVCodecContext *decoder_ctx,
static int decode_packet(AVCodecContext *decoder_ctx,
AVFrame *frame, AVFrame *sw_frame,
AVPacket *pkt, AVIOContext *output_ctx)
{
@ -141,15 +113,15 @@ int main(int argc, char **argv)
AVCodecContext *decoder_ctx = NULL;
const AVCodec *decoder;
AVPacket pkt = { 0 };
AVPacket *pkt = NULL;
AVFrame *frame = NULL, *sw_frame = NULL;
DecodeContext decode = { NULL };
AVIOContext *output_ctx = NULL;
int ret, i;
AVBufferRef *device_ref = NULL;
if (argc < 3) {
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
return 1;
@ -177,7 +149,7 @@ int main(int argc, char **argv)
}
/* open the hardware device */
ret = av_hwdevice_ctx_create(&decode.hw_device_ref, AV_HWDEVICE_TYPE_QSV,
ret = av_hwdevice_ctx_create(&device_ref, AV_HWDEVICE_TYPE_QSV,
"auto", NULL, 0);
if (ret < 0) {
fprintf(stderr, "Cannot open the hardware device\n");
@ -209,7 +181,8 @@ int main(int argc, char **argv)
decoder_ctx->extradata_size = video_st->codecpar->extradata_size;
}
decoder_ctx->opaque = &decode;
decoder_ctx->hw_device_ctx = av_buffer_ref(device_ref);
decoder_ctx->get_format = get_format;
ret = avcodec_open2(decoder_ctx, NULL, NULL);
@ -227,27 +200,26 @@ int main(int argc, char **argv)
frame = av_frame_alloc();
sw_frame = av_frame_alloc();
if (!frame || !sw_frame) {
pkt = av_packet_alloc();
if (!frame || !sw_frame || !pkt) {
ret = AVERROR(ENOMEM);
goto finish;
}
/* actual decoding */
while (ret >= 0) {
ret = av_read_frame(input_ctx, &pkt);
ret = av_read_frame(input_ctx, pkt);
if (ret < 0)
break;
if (pkt.stream_index == video_st->index)
ret = decode_packet(&decode, decoder_ctx, frame, sw_frame, &pkt, output_ctx);
if (pkt->stream_index == video_st->index)
ret = decode_packet(decoder_ctx, frame, sw_frame, pkt, output_ctx);
av_packet_unref(&pkt);
av_packet_unref(pkt);
}
/* flush the decoder */
pkt.data = NULL;
pkt.size = 0;
ret = decode_packet(&decode, decoder_ctx, frame, sw_frame, &pkt, output_ctx);
ret = decode_packet(decoder_ctx, frame, sw_frame, NULL, output_ctx);
finish:
if (ret < 0) {
@ -260,10 +232,11 @@ finish:
av_frame_free(&frame);
av_frame_free(&sw_frame);
av_packet_free(&pkt);
avcodec_free_context(&decoder_ctx);
av_buffer_unref(&decode.hw_device_ref);
av_buffer_unref(&device_ref);
avio_close(output_ctx);

View File

@ -45,9 +45,9 @@ static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt, cons
int main(int argc, char **argv)
{
AVOutputFormat *ofmt = NULL;
const AVOutputFormat *ofmt = NULL;
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
AVPacket pkt;
AVPacket *pkt = NULL;
const char *in_filename, *out_filename;
int ret, i;
int stream_index = 0;
@ -65,6 +65,12 @@ int main(int argc, char **argv)
in_filename = argv[1];
out_filename = argv[2];
pkt = av_packet_alloc();
if (!pkt) {
fprintf(stderr, "Could not allocate AVPacket\n");
return 1;
}
if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
fprintf(stderr, "Could not open input file '%s'", in_filename);
goto end;
@ -85,7 +91,7 @@ int main(int argc, char **argv)
}
stream_mapping_size = ifmt_ctx->nb_streams;
stream_mapping = av_mallocz_array(stream_mapping_size, sizeof(*stream_mapping));
stream_mapping = av_calloc(stream_mapping_size, sizeof(*stream_mapping));
if (!stream_mapping) {
ret = AVERROR(ENOMEM);
goto end;
@ -140,38 +146,39 @@ int main(int argc, char **argv)
while (1) {
AVStream *in_stream, *out_stream;
ret = av_read_frame(ifmt_ctx, &pkt);
ret = av_read_frame(ifmt_ctx, pkt);
if (ret < 0)
break;
in_stream = ifmt_ctx->streams[pkt.stream_index];
if (pkt.stream_index >= stream_mapping_size ||
stream_mapping[pkt.stream_index] < 0) {
av_packet_unref(&pkt);
in_stream = ifmt_ctx->streams[pkt->stream_index];
if (pkt->stream_index >= stream_mapping_size ||
stream_mapping[pkt->stream_index] < 0) {
av_packet_unref(pkt);
continue;
}
pkt.stream_index = stream_mapping[pkt.stream_index];
out_stream = ofmt_ctx->streams[pkt.stream_index];
log_packet(ifmt_ctx, &pkt, "in");
pkt->stream_index = stream_mapping[pkt->stream_index];
out_stream = ofmt_ctx->streams[pkt->stream_index];
log_packet(ifmt_ctx, pkt, "in");
/* copy packet */
pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
pkt.pos = -1;
log_packet(ofmt_ctx, &pkt, "out");
av_packet_rescale_ts(pkt, in_stream->time_base, out_stream->time_base);
pkt->pos = -1;
log_packet(ofmt_ctx, pkt, "out");
ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
ret = av_interleaved_write_frame(ofmt_ctx, pkt);
/* pkt is now blank (av_interleaved_write_frame() takes ownership of
* its contents and resets pkt), so that no unreferencing is necessary.
* This would be different if one used av_write_frame(). */
if (ret < 0) {
fprintf(stderr, "Error muxing packet\n");
break;
}
av_packet_unref(&pkt);
}
av_write_trailer(ofmt_ctx);
end:
av_packet_free(&pkt);
avformat_close_input(&ifmt_ctx);

View File

@ -80,7 +80,7 @@ static void fill_samples(double *dst, int nb_samples, int nb_channels, int sampl
int main(int argc, char **argv)
{
int64_t src_ch_layout = AV_CH_LAYOUT_STEREO, dst_ch_layout = AV_CH_LAYOUT_SURROUND;
AVChannelLayout src_ch_layout = AV_CHANNEL_LAYOUT_STEREO, dst_ch_layout = AV_CHANNEL_LAYOUT_SURROUND;
int src_rate = 48000, dst_rate = 44100;
uint8_t **src_data = NULL, **dst_data = NULL;
int src_nb_channels = 0, dst_nb_channels = 0;
@ -92,6 +92,7 @@ int main(int argc, char **argv)
int dst_bufsize;
const char *fmt;
struct SwrContext *swr_ctx;
char buf[64];
double t;
int ret;
@ -120,11 +121,11 @@ int main(int argc, char **argv)
}
/* set options */
av_opt_set_int(swr_ctx, "in_channel_layout", src_ch_layout, 0);
av_opt_set_chlayout(swr_ctx, "in_chlayout", &src_ch_layout, 0);
av_opt_set_int(swr_ctx, "in_sample_rate", src_rate, 0);
av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", src_sample_fmt, 0);
av_opt_set_int(swr_ctx, "out_channel_layout", dst_ch_layout, 0);
av_opt_set_chlayout(swr_ctx, "out_chlayout", &dst_ch_layout, 0);
av_opt_set_int(swr_ctx, "out_sample_rate", dst_rate, 0);
av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", dst_sample_fmt, 0);
@ -136,7 +137,7 @@ int main(int argc, char **argv)
/* allocate source and destination samples buffers */
src_nb_channels = av_get_channel_layout_nb_channels(src_ch_layout);
src_nb_channels = src_ch_layout.nb_channels;
ret = av_samples_alloc_array_and_samples(&src_data, &src_linesize, src_nb_channels,
src_nb_samples, src_sample_fmt, 0);
if (ret < 0) {
@ -151,7 +152,7 @@ int main(int argc, char **argv)
av_rescale_rnd(src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
/* buffer is going to be directly written to a rawaudio file, no alignment */
dst_nb_channels = av_get_channel_layout_nb_channels(dst_ch_layout);
dst_nb_channels = dst_ch_layout.nb_channels;
ret = av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, dst_nb_channels,
dst_nb_samples, dst_sample_fmt, 0);
if (ret < 0) {
@ -194,9 +195,10 @@ int main(int argc, char **argv)
if ((ret = get_format_from_sample_fmt(&fmt, dst_sample_fmt)) < 0)
goto end;
av_channel_layout_describe(&dst_ch_layout, buf, sizeof(buf));
fprintf(stderr, "Resampling succeeded. Play the output file with the command:\n"
"ffplay -f %s -channel_layout %"PRId64" -channels %d -ar %d %s\n",
fmt, dst_ch_layout, dst_nb_channels, dst_rate, dst_filename);
"ffplay -f %s -channel_layout %s -channels %d -ar %d %s\n",
fmt, buf, dst_nb_channels, dst_rate, dst_filename);
end:
fclose(dst_file);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2018 Andreas Unterweger
* Copyright (c) 2013-2022 Andreas Unterweger
*
* This file is part of FFmpeg.
*
@ -38,6 +38,7 @@
#include "libavutil/audio_fifo.h"
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/channel_layout.h"
#include "libavutil/frame.h"
#include "libavutil/opt.h"
@ -60,7 +61,8 @@ static int open_input_file(const char *filename,
AVCodecContext **input_codec_context)
{
AVCodecContext *avctx;
AVCodec *input_codec;
const AVCodec *input_codec;
const AVStream *stream;
int error;
/* Open the input file to read from it. */
@ -88,8 +90,10 @@ static int open_input_file(const char *filename,
return AVERROR_EXIT;
}
stream = (*input_format_context)->streams[0];
/* Find a decoder for the audio stream. */
if (!(input_codec = avcodec_find_decoder((*input_format_context)->streams[0]->codecpar->codec_id))) {
if (!(input_codec = avcodec_find_decoder(stream->codecpar->codec_id))) {
fprintf(stderr, "Could not find input codec\n");
avformat_close_input(input_format_context);
return AVERROR_EXIT;
@ -104,7 +108,7 @@ static int open_input_file(const char *filename,
}
/* Initialize the stream parameters with demuxer information. */
error = avcodec_parameters_to_context(avctx, (*input_format_context)->streams[0]->codecpar);
error = avcodec_parameters_to_context(avctx, stream->codecpar);
if (error < 0) {
avformat_close_input(input_format_context);
avcodec_free_context(&avctx);
@ -120,6 +124,9 @@ static int open_input_file(const char *filename,
return error;
}
/* Set the packet timebase for the decoder. */
avctx->pkt_timebase = stream->time_base;
/* Save the decoder context for easier access later. */
*input_codec_context = avctx;
@ -144,7 +151,7 @@ static int open_output_file(const char *filename,
AVCodecContext *avctx = NULL;
AVIOContext *output_io_context = NULL;
AVStream *stream = NULL;
AVCodec *output_codec = NULL;
const AVCodec *output_codec = NULL;
int error;
/* Open the output file to write to it. */
@ -199,15 +206,11 @@ static int open_output_file(const char *filename,
/* Set the basic encoder parameters.
* The input file's sample rate is used to avoid a sample rate conversion. */
avctx->channels = OUTPUT_CHANNELS;
avctx->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS);
av_channel_layout_default(&avctx->ch_layout, OUTPUT_CHANNELS);
avctx->sample_rate = input_codec_context->sample_rate;
avctx->sample_fmt = output_codec->sample_fmts[0];
avctx->bit_rate = OUTPUT_BIT_RATE;
/* Allow the use of the experimental AAC encoder. */
avctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
/* Set the sample rate for the container. */
stream->time_base.den = input_codec_context->sample_rate;
stream->time_base.num = 1;
@ -245,14 +248,16 @@ cleanup:
/**
* Initialize one data packet for reading or writing.
* @param packet Packet to be initialized
* @param[out] packet Packet to be initialized
* @return Error code (0 if successful)
*/
static void init_packet(AVPacket *packet)
static int init_packet(AVPacket **packet)
{
av_init_packet(packet);
/* Set the packet data and size so that it is recognized as being empty. */
packet->data = NULL;
packet->size = 0;
if (!(*packet = av_packet_alloc())) {
fprintf(stderr, "Could not allocate packet\n");
return AVERROR(ENOMEM);
}
return 0;
}
/**
@ -287,21 +292,18 @@ static int init_resampler(AVCodecContext *input_codec_context,
/*
* Create a resampler context for the conversion.
* Set the conversion parameters.
* Default channel layouts based on the number of channels
* are assumed for simplicity (they are sometimes not detected
* properly by the demuxer and/or decoder).
*/
*resample_context = swr_alloc_set_opts(NULL,
av_get_default_channel_layout(output_codec_context->channels),
error = swr_alloc_set_opts2(resample_context,
&output_codec_context->ch_layout,
output_codec_context->sample_fmt,
output_codec_context->sample_rate,
av_get_default_channel_layout(input_codec_context->channels),
&input_codec_context->ch_layout,
input_codec_context->sample_fmt,
input_codec_context->sample_rate,
0, NULL);
if (!*resample_context) {
if (error < 0) {
fprintf(stderr, "Could not allocate resample context\n");
return AVERROR(ENOMEM);
return error;
}
/*
* Perform a sanity check so that the number of converted samples is
@ -329,7 +331,7 @@ static int init_fifo(AVAudioFifo **fifo, AVCodecContext *output_codec_context)
{
/* Create the FIFO buffer based on the specified output sample format. */
if (!(*fifo = av_audio_fifo_alloc(output_codec_context->sample_fmt,
output_codec_context->channels, 1))) {
output_codec_context->ch_layout.nb_channels, 1))) {
fprintf(stderr, "Could not allocate FIFO\n");
return AVERROR(ENOMEM);
}
@ -371,28 +373,33 @@ static int decode_audio_frame(AVFrame *frame,
int *data_present, int *finished)
{
/* Packet used for temporary storage. */
AVPacket input_packet;
AVPacket *input_packet;
int error;
init_packet(&input_packet);
error = init_packet(&input_packet);
if (error < 0)
return error;
*data_present = 0;
*finished = 0;
/* Read one audio frame from the input file into a temporary packet. */
if ((error = av_read_frame(input_format_context, &input_packet)) < 0) {
if ((error = av_read_frame(input_format_context, input_packet)) < 0) {
/* If we are at the end of the file, flush the decoder below. */
if (error == AVERROR_EOF)
*finished = 1;
else {
fprintf(stderr, "Could not read frame (error '%s')\n",
av_err2str(error));
return error;
goto cleanup;
}
}
/* Send the audio frame stored in the temporary packet to the decoder.
* The input audio stream decoder is used to do this. */
if ((error = avcodec_send_packet(input_codec_context, &input_packet)) < 0) {
if ((error = avcodec_send_packet(input_codec_context, input_packet)) < 0) {
fprintf(stderr, "Could not send packet for decoding (error '%s')\n",
av_err2str(error));
return error;
goto cleanup;
}
/* Receive one frame from the decoder. */
@ -418,7 +425,7 @@ static int decode_audio_frame(AVFrame *frame,
}
cleanup:
av_packet_unref(&input_packet);
av_packet_free(&input_packet);
return error;
}
@ -444,7 +451,7 @@ static int init_converted_samples(uint8_t ***converted_input_samples,
* Each pointer will later point to the audio samples of the corresponding
* channels (although it may be NULL for interleaved formats).
*/
if (!(*converted_input_samples = calloc(output_codec_context->channels,
if (!(*converted_input_samples = calloc(output_codec_context->ch_layout.nb_channels,
sizeof(**converted_input_samples)))) {
fprintf(stderr, "Could not allocate converted input sample pointers\n");
return AVERROR(ENOMEM);
@ -453,7 +460,7 @@ static int init_converted_samples(uint8_t ***converted_input_samples,
/* Allocate memory for the samples of all channels in one consecutive
* block for convenience. */
if ((error = av_samples_alloc(*converted_input_samples, NULL,
output_codec_context->channels,
output_codec_context->ch_layout.nb_channels,
frame_size,
output_codec_context->sample_fmt, 0)) < 0) {
fprintf(stderr,
@ -553,7 +560,7 @@ static int read_decode_convert_and_store(AVAudioFifo *fifo,
AVFrame *input_frame = NULL;
/* Temporary storage for the converted input samples. */
uint8_t **converted_input_samples = NULL;
int data_present = 0;
int data_present;
int ret = AVERROR_EXIT;
/* Initialize temporary storage for one input frame. */
@ -627,7 +634,7 @@ static int init_output_frame(AVFrame **frame,
* Default channel layouts based on the number of channels
* are assumed for simplicity. */
(*frame)->nb_samples = frame_size;
(*frame)->channel_layout = output_codec_context->channel_layout;
av_channel_layout_copy(&(*frame)->ch_layout, &output_codec_context->ch_layout);
(*frame)->format = output_codec_context->sample_fmt;
(*frame)->sample_rate = output_codec_context->sample_rate;
@ -661,9 +668,12 @@ static int encode_audio_frame(AVFrame *frame,
int *data_present)
{
/* Packet used for temporary storage. */
AVPacket output_packet;
AVPacket *output_packet;
int error;
init_packet(&output_packet);
error = init_packet(&output_packet);
if (error < 0)
return error;
/* Set a timestamp based on the sample rate for the container. */
if (frame) {
@ -671,21 +681,20 @@ static int encode_audio_frame(AVFrame *frame,
pts += frame->nb_samples;
}
*data_present = 0;
/* Send the audio frame stored in the temporary packet to the encoder.
* The output audio stream encoder is used to do this. */
error = avcodec_send_frame(output_codec_context, frame);
/* The encoder signals that it has nothing more to encode. */
if (error == AVERROR_EOF) {
error = 0;
goto cleanup;
} else if (error < 0) {
fprintf(stderr, "Could not send packet for encoding (error '%s')\n",
av_err2str(error));
return error;
/* Check for errors, but proceed with fetching encoded samples if the
* encoder signals that it has nothing more to encode. */
if (error < 0 && error != AVERROR_EOF) {
fprintf(stderr, "Could not send packet for encoding (error '%s')\n",
av_err2str(error));
goto cleanup;
}
/* Receive one encoded frame from the encoder. */
error = avcodec_receive_packet(output_codec_context, &output_packet);
error = avcodec_receive_packet(output_codec_context, output_packet);
/* If the encoder asks for more data to be able to provide an
* encoded frame, return indicating that no data is present. */
if (error == AVERROR(EAGAIN)) {
@ -706,14 +715,14 @@ static int encode_audio_frame(AVFrame *frame,
/* Write one audio frame from the temporary packet to the output file. */
if (*data_present &&
(error = av_write_frame(output_format_context, &output_packet)) < 0) {
(error = av_write_frame(output_format_context, output_packet)) < 0) {
fprintf(stderr, "Could not write frame (error '%s')\n",
av_err2str(error));
goto cleanup;
}
cleanup:
av_packet_unref(&output_packet);
av_packet_free(&output_packet);
return error;
}
@ -852,7 +861,6 @@ int main(int argc, char **argv)
int data_written;
/* Flush the encoder as it may have delayed frames. */
do {
data_written = 0;
if (encode_audio_frame(NULL, output_format_context,
output_codec_context, &data_written))
goto cleanup;

View File

@ -32,6 +32,7 @@
#include <libavformat/avformat.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/channel_layout.h>
#include <libavutil/opt.h>
#include <libavutil/pixdesc.h>
@ -41,12 +42,17 @@ typedef struct FilteringContext {
AVFilterContext *buffersink_ctx;
AVFilterContext *buffersrc_ctx;
AVFilterGraph *filter_graph;
AVPacket *enc_pkt;
AVFrame *filtered_frame;
} FilteringContext;
static FilteringContext *filter_ctx;
typedef struct StreamContext {
AVCodecContext *dec_ctx;
AVCodecContext *enc_ctx;
AVFrame *dec_frame;
} StreamContext;
static StreamContext *stream_ctx;
@ -66,13 +72,13 @@ static int open_input_file(const char *filename)
return ret;
}
stream_ctx = av_mallocz_array(ifmt_ctx->nb_streams, sizeof(*stream_ctx));
stream_ctx = av_calloc(ifmt_ctx->nb_streams, sizeof(*stream_ctx));
if (!stream_ctx)
return AVERROR(ENOMEM);
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
AVStream *stream = ifmt_ctx->streams[i];
AVCodec *dec = avcodec_find_decoder(stream->codecpar->codec_id);
const AVCodec *dec = avcodec_find_decoder(stream->codecpar->codec_id);
AVCodecContext *codec_ctx;
if (!dec) {
av_log(NULL, AV_LOG_ERROR, "Failed to find decoder for stream #%u\n", i);
@ -102,6 +108,10 @@ static int open_input_file(const char *filename)
}
}
stream_ctx[i].dec_ctx = codec_ctx;
stream_ctx[i].dec_frame = av_frame_alloc();
if (!stream_ctx[i].dec_frame)
return AVERROR(ENOMEM);
}
av_dump_format(ifmt_ctx, 0, filename, 0);
@ -113,7 +123,7 @@ static int open_output_file(const char *filename)
AVStream *out_stream;
AVStream *in_stream;
AVCodecContext *dec_ctx, *enc_ctx;
AVCodec *encoder;
const AVCodec *encoder;
int ret;
unsigned int i;
@ -165,8 +175,9 @@ static int open_output_file(const char *filename)
enc_ctx->time_base = av_inv_q(dec_ctx->framerate);
} else {
enc_ctx->sample_rate = dec_ctx->sample_rate;
enc_ctx->channel_layout = dec_ctx->channel_layout;
enc_ctx->channels = av_get_channel_layout_nb_channels(enc_ctx->channel_layout);
ret = av_channel_layout_copy(&enc_ctx->ch_layout, &dec_ctx->ch_layout);
if (ret < 0)
return ret;
/* take first format from list of supported formats */
enc_ctx->sample_fmt = encoder->sample_fmts[0];
enc_ctx->time_base = (AVRational){1, enc_ctx->sample_rate};
@ -279,6 +290,7 @@ static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx,
goto end;
}
} else if (dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
char buf[64];
buffersrc = avfilter_get_by_name("abuffer");
buffersink = avfilter_get_by_name("abuffersink");
if (!buffersrc || !buffersink) {
@ -287,14 +299,14 @@ static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx,
goto end;
}
if (!dec_ctx->channel_layout)
dec_ctx->channel_layout =
av_get_default_channel_layout(dec_ctx->channels);
if (dec_ctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
av_channel_layout_default(&dec_ctx->ch_layout, dec_ctx->ch_layout.nb_channels);
av_channel_layout_describe(&dec_ctx->ch_layout, buf, sizeof(buf));
snprintf(args, sizeof(args),
"time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
"time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=%s",
dec_ctx->time_base.num, dec_ctx->time_base.den, dec_ctx->sample_rate,
av_get_sample_fmt_name(dec_ctx->sample_fmt),
dec_ctx->channel_layout);
buf);
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
args, NULL, filter_graph);
if (ret < 0) {
@ -317,9 +329,9 @@ static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx,
goto end;
}
ret = av_opt_set_bin(buffersink_ctx, "channel_layouts",
(uint8_t*)&enc_ctx->channel_layout,
sizeof(enc_ctx->channel_layout), AV_OPT_SEARCH_CHILDREN);
av_channel_layout_describe(&enc_ctx->ch_layout, buf, sizeof(buf));
ret = av_opt_set(buffersink_ctx, "ch_layouts",
buf, AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
goto end;
@ -398,54 +410,63 @@ static int init_filters(void)
stream_ctx[i].enc_ctx, filter_spec);
if (ret)
return ret;
filter_ctx[i].enc_pkt = av_packet_alloc();
if (!filter_ctx[i].enc_pkt)
return AVERROR(ENOMEM);
filter_ctx[i].filtered_frame = av_frame_alloc();
if (!filter_ctx[i].filtered_frame)
return AVERROR(ENOMEM);
}
return 0;
}
static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame) {
static int encode_write_frame(unsigned int stream_index, int flush)
{
StreamContext *stream = &stream_ctx[stream_index];
FilteringContext *filter = &filter_ctx[stream_index];
AVFrame *filt_frame = flush ? NULL : filter->filtered_frame;
AVPacket *enc_pkt = filter->enc_pkt;
int ret;
int got_frame_local;
AVPacket enc_pkt;
int (*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int *) =
(ifmt_ctx->streams[stream_index]->codecpar->codec_type ==
AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2;
if (!got_frame)
got_frame = &got_frame_local;
av_log(NULL, AV_LOG_INFO, "Encoding frame\n");
/* encode filtered frame */
enc_pkt.data = NULL;
enc_pkt.size = 0;
av_init_packet(&enc_pkt);
ret = enc_func(stream_ctx[stream_index].enc_ctx, &enc_pkt,
filt_frame, got_frame);
av_frame_free(&filt_frame);
av_packet_unref(enc_pkt);
ret = avcodec_send_frame(stream->enc_ctx, filt_frame);
if (ret < 0)
return ret;
if (!(*got_frame))
return 0;
/* prepare packet for muxing */
enc_pkt.stream_index = stream_index;
av_packet_rescale_ts(&enc_pkt,
stream_ctx[stream_index].enc_ctx->time_base,
ofmt_ctx->streams[stream_index]->time_base);
while (ret >= 0) {
ret = avcodec_receive_packet(stream->enc_ctx, enc_pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return 0;
/* prepare packet for muxing */
enc_pkt->stream_index = stream_index;
av_packet_rescale_ts(enc_pkt,
stream->enc_ctx->time_base,
ofmt_ctx->streams[stream_index]->time_base);
av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");
/* mux encoded frame */
ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt);
}
av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");
/* mux encoded frame */
ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
return ret;
}
static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
{
FilteringContext *filter = &filter_ctx[stream_index];
int ret;
AVFrame *filt_frame;
av_log(NULL, AV_LOG_INFO, "Pushing decoded frame to filters\n");
/* push the decoded frame into the filtergraph */
ret = av_buffersrc_add_frame_flags(filter_ctx[stream_index].buffersrc_ctx,
ret = av_buffersrc_add_frame_flags(filter->buffersrc_ctx,
frame, 0);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
@ -454,14 +475,9 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
/* pull filtered frames from the filtergraph */
while (1) {
filt_frame = av_frame_alloc();
if (!filt_frame) {
ret = AVERROR(ENOMEM);
break;
}
av_log(NULL, AV_LOG_INFO, "Pulling filtered frame from filters\n");
ret = av_buffersink_get_frame(filter_ctx[stream_index].buffersink_ctx,
filt_frame);
ret = av_buffersink_get_frame(filter->buffersink_ctx,
filter->filtered_frame);
if (ret < 0) {
/* if no more frames for output - returns AVERROR(EAGAIN)
* if flushed and no more frames for output - returns AVERROR_EOF
@ -469,12 +485,12 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
*/
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
ret = 0;
av_frame_free(&filt_frame);
break;
}
filt_frame->pict_type = AV_PICTURE_TYPE_NONE;
ret = encode_write_frame(filt_frame, stream_index, NULL);
filter->filtered_frame->pict_type = AV_PICTURE_TYPE_NONE;
ret = encode_write_frame(stream_index, 0);
av_frame_unref(filter->filtered_frame);
if (ret < 0)
break;
}
@ -484,34 +500,20 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
static int flush_encoder(unsigned int stream_index)
{
int ret;
int got_frame;
if (!(stream_ctx[stream_index].enc_ctx->codec->capabilities &
AV_CODEC_CAP_DELAY))
return 0;
while (1) {
av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index);
ret = encode_write_frame(NULL, stream_index, &got_frame);
if (ret < 0)
break;
if (!got_frame)
return 0;
}
return ret;
av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index);
return encode_write_frame(stream_index, 1);
}
int main(int argc, char **argv)
{
int ret;
AVPacket packet = { .data = NULL, .size = 0 };
AVFrame *frame = NULL;
enum AVMediaType type;
AVPacket *packet = NULL;
unsigned int stream_index;
unsigned int i;
int got_frame;
int (*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket *);
if (argc != 3) {
av_log(NULL, AV_LOG_ERROR, "Usage: %s <input file> <output file>\n", argv[0]);
@ -524,56 +526,54 @@ int main(int argc, char **argv)
goto end;
if ((ret = init_filters()) < 0)
goto end;
if (!(packet = av_packet_alloc()))
goto end;
/* read all packets */
while (1) {
if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0)
if ((ret = av_read_frame(ifmt_ctx, packet)) < 0)
break;
stream_index = packet.stream_index;
type = ifmt_ctx->streams[packet.stream_index]->codecpar->codec_type;
stream_index = packet->stream_index;
av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n",
stream_index);
if (filter_ctx[stream_index].filter_graph) {
StreamContext *stream = &stream_ctx[stream_index];
av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the frame\n");
frame = av_frame_alloc();
if (!frame) {
ret = AVERROR(ENOMEM);
break;
}
av_packet_rescale_ts(&packet,
av_packet_rescale_ts(packet,
ifmt_ctx->streams[stream_index]->time_base,
stream_ctx[stream_index].dec_ctx->time_base);
dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :
avcodec_decode_audio4;
ret = dec_func(stream_ctx[stream_index].dec_ctx, frame,
&got_frame, &packet);
stream->dec_ctx->time_base);
ret = avcodec_send_packet(stream->dec_ctx, packet);
if (ret < 0) {
av_frame_free(&frame);
av_log(NULL, AV_LOG_ERROR, "Decoding failed\n");
break;
}
if (got_frame) {
frame->pts = frame->best_effort_timestamp;
ret = filter_encode_write_frame(frame, stream_index);
av_frame_free(&frame);
while (ret >= 0) {
ret = avcodec_receive_frame(stream->dec_ctx, stream->dec_frame);
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
break;
else if (ret < 0)
goto end;
stream->dec_frame->pts = stream->dec_frame->best_effort_timestamp;
ret = filter_encode_write_frame(stream->dec_frame, stream_index);
if (ret < 0)
goto end;
} else {
av_frame_free(&frame);
}
} else {
/* remux this frame without reencoding */
av_packet_rescale_ts(&packet,
av_packet_rescale_ts(packet,
ifmt_ctx->streams[stream_index]->time_base,
ofmt_ctx->streams[stream_index]->time_base);
ret = av_interleaved_write_frame(ofmt_ctx, &packet);
ret = av_interleaved_write_frame(ofmt_ctx, packet);
if (ret < 0)
goto end;
}
av_packet_unref(&packet);
av_packet_unref(packet);
}
/* flush filters and encoders */
@ -597,14 +597,18 @@ int main(int argc, char **argv)
av_write_trailer(ofmt_ctx);
end:
av_packet_unref(&packet);
av_frame_free(&frame);
av_packet_free(&packet);
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
avcodec_free_context(&stream_ctx[i].dec_ctx);
if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && stream_ctx[i].enc_ctx)
avcodec_free_context(&stream_ctx[i].enc_ctx);
if (filter_ctx && filter_ctx[i].filter_graph)
if (filter_ctx && filter_ctx[i].filter_graph) {
avfilter_graph_free(&filter_ctx[i].filter_graph);
av_packet_free(&filter_ctx[i].enc_pkt);
av_frame_free(&filter_ctx[i].filtered_frame);
}
av_frame_free(&stream_ctx[i].dec_frame);
}
av_free(filter_ctx);
av_free(stream_ctx);

View File

@ -74,27 +74,27 @@ static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx)
static int encode_write(AVCodecContext *avctx, AVFrame *frame, FILE *fout)
{
int ret = 0;
AVPacket enc_pkt;
AVPacket *enc_pkt;
av_init_packet(&enc_pkt);
enc_pkt.data = NULL;
enc_pkt.size = 0;
if (!(enc_pkt = av_packet_alloc()))
return AVERROR(ENOMEM);
if ((ret = avcodec_send_frame(avctx, frame)) < 0) {
fprintf(stderr, "Error code: %s\n", av_err2str(ret));
goto end;
}
while (1) {
ret = avcodec_receive_packet(avctx, &enc_pkt);
ret = avcodec_receive_packet(avctx, enc_pkt);
if (ret)
break;
enc_pkt.stream_index = 0;
ret = fwrite(enc_pkt.data, enc_pkt.size, 1, fout);
av_packet_unref(&enc_pkt);
enc_pkt->stream_index = 0;
ret = fwrite(enc_pkt->data, enc_pkt->size, 1, fout);
av_packet_unref(enc_pkt);
}
end:
av_packet_free(&enc_pkt);
ret = ((ret == AVERROR(EAGAIN)) ? 0 : -1);
return ret;
}
@ -105,7 +105,7 @@ int main(int argc, char *argv[])
FILE *fin = NULL, *fout = NULL;
AVFrame *sw_frame = NULL, *hw_frame = NULL;
AVCodecContext *avctx = NULL;
AVCodec *codec = NULL;
const AVCodec *codec = NULL;
const char *enc_name = "h264_vaapi";
if (argc < 5) {
@ -172,7 +172,7 @@ int main(int argc, char *argv[])
sw_frame->width = width;
sw_frame->height = height;
sw_frame->format = AV_PIX_FMT_NV12;
if ((err = av_frame_get_buffer(sw_frame, 32)) < 0)
if ((err = av_frame_get_buffer(sw_frame, 0)) < 0)
goto close;
if ((err = fread((uint8_t*)(sw_frame->data[0]), size, 1, fin)) <= 0)
break;

View File

@ -62,7 +62,7 @@ static enum AVPixelFormat get_vaapi_format(AVCodecContext *ctx,
static int open_input_file(const char *filename)
{
int ret;
AVCodec *decoder = NULL;
const AVCodec *decoder = NULL;
AVStream *video = NULL;
if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {
@ -109,28 +109,25 @@ static int open_input_file(const char *filename)
return ret;
}
static int encode_write(AVFrame *frame)
static int encode_write(AVPacket *enc_pkt, AVFrame *frame)
{
int ret = 0;
AVPacket enc_pkt;
av_init_packet(&enc_pkt);
enc_pkt.data = NULL;
enc_pkt.size = 0;
av_packet_unref(enc_pkt);
if ((ret = avcodec_send_frame(encoder_ctx, frame)) < 0) {
fprintf(stderr, "Error during encoding. Error code: %s\n", av_err2str(ret));
goto end;
}
while (1) {
ret = avcodec_receive_packet(encoder_ctx, &enc_pkt);
ret = avcodec_receive_packet(encoder_ctx, enc_pkt);
if (ret)
break;
enc_pkt.stream_index = 0;
av_packet_rescale_ts(&enc_pkt, ifmt_ctx->streams[video_stream]->time_base,
enc_pkt->stream_index = 0;
av_packet_rescale_ts(enc_pkt, ifmt_ctx->streams[video_stream]->time_base,
ofmt_ctx->streams[0]->time_base);
ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt);
if (ret < 0) {
fprintf(stderr, "Error during writing data to output file. "
"Error code: %s\n", av_err2str(ret));
@ -145,7 +142,7 @@ end:
return ret;
}
static int dec_enc(AVPacket *pkt, AVCodec *enc_codec)
static int dec_enc(AVPacket *pkt, const AVCodec *enc_codec)
{
AVFrame *frame;
int ret = 0;
@ -216,7 +213,7 @@ static int dec_enc(AVPacket *pkt, AVCodec *enc_codec)
initialized = 1;
}
if ((ret = encode_write(frame)) < 0)
if ((ret = encode_write(pkt, frame)) < 0)
fprintf(stderr, "Error during encoding and writing.\n");
fail:
@ -229,9 +226,9 @@ fail:
int main(int argc, char **argv)
{
const AVCodec *enc_codec;
int ret = 0;
AVPacket dec_pkt;
AVCodec *enc_codec;
AVPacket *dec_pkt;
if (argc != 4) {
fprintf(stderr, "Usage: %s <input file> <encode codec> <output file>\n"
@ -246,6 +243,12 @@ int main(int argc, char **argv)
return -1;
}
dec_pkt = av_packet_alloc();
if (!dec_pkt) {
fprintf(stderr, "Failed to allocate decode packet\n");
goto end;
}
if ((ret = open_input_file(argv[1])) < 0)
goto end;
@ -275,23 +278,21 @@ int main(int argc, char **argv)
/* read all packets and only transcoding video */
while (ret >= 0) {
if ((ret = av_read_frame(ifmt_ctx, &dec_pkt)) < 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);
if (video_stream == dec_pkt->stream_index)
ret = dec_enc(dec_pkt, enc_codec);
av_packet_unref(&dec_pkt);
av_packet_unref(dec_pkt);
}
/* flush decoder */
dec_pkt.data = NULL;
dec_pkt.size = 0;
ret = dec_enc(&dec_pkt, enc_codec);
av_packet_unref(&dec_pkt);
av_packet_unref(dec_pkt);
ret = dec_enc(dec_pkt, enc_codec);
/* flush encoder */
ret = encode_write(NULL);
ret = encode_write(dec_pkt, NULL);
/* write the trailer for output stream */
av_write_trailer(ofmt_ctx);
@ -302,5 +303,6 @@ end:
avcodec_free_context(&decoder_ctx);
avcodec_free_context(&encoder_ctx);
av_buffer_unref(&hw_device_ctx);
av_packet_free(&dec_pkt);
return ret;
}

View File

@ -79,6 +79,21 @@ Do not put a '~' character in the samples path to indicate a home
directory. Because of shell nuances, this will cause FATE to fail.
@end float
To get the complete list of tests, run the command:
@example
make fate-list
@end example
You can specify a subset of tests to run by specifying the
corresponding elements from the list with the @code{fate-} prefix,
e.g. as in:
@example
make fate-ffprobe_compact fate-ffprobe_xml
@end example
This makes it easier to run a few tests in case of failure without
running the complete test suite.
To use a custom wrapper to run the test, pass @option{--target-exec} to
@command{configure} or set the @var{TARGET_EXEC} Make variable.
@ -149,6 +164,8 @@ the synchronisation of the samples directory.
@chapter Uploading new samples to the fate suite
If you need a sample uploaded send a mail to samples-request.
This is for developers who have an account on the fate suite server.
If you upload new samples, please make sure they are as small as possible,
space on each client, network bandwidth and so on benefit from smaller test cases.
@ -157,6 +174,8 @@ practice generally do not replace, remove or overwrite files as it likely would
break older checkouts or releases.
Also all needed samples for a commit should be uploaded, ideally 24
hours, before the push.
If you need an account for frequently uploading samples or you wish to help
others by doing that send a mail to ffmpeg-devel.
@example
#First update your local samples copy:

View File

@ -449,6 +449,11 @@ output file already exists.
Set number of times input stream shall be looped. Loop 0 means no loop,
loop -1 means infinite loop.
@item -recast_media (@emph{global})
Allow forcing a decoder of a different media type than the one
detected or designated by the demuxer. Useful for decoding media
data muxed as data streams.
@item -c[:@var{stream_specifier}] @var{codec} (@emph{input/output,per-stream})
@itemx -codec[:@var{stream_specifier}] @var{codec} (@emph{input/output,per-stream})
Select an encoder (when used before an output file) or a decoder (when used
@ -513,6 +518,21 @@ see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1)
Like the @code{-ss} option but relative to the "end of file". That is negative
values are earlier in the file, 0 is at EOF.
@item -isync @var{input_index} (@emph{input})
Assign an input as a sync source.
This will take the difference between the start times of the target and reference inputs and
offset the timestamps of the target file by that difference. The source timestamps of the two
inputs should derive from the same clock source for expected results. If @code{copyts} is set
then @code{start_at_zero} must also be set. If either of the inputs has no starting timestamp
then no sync adjustment is made.
Acceptable values are those that refer to a valid ffmpeg input index. If the sync reference is
the target index itself or @var{-1}, then no adjustment is made to target timestamps. A sync
reference may not itself be synced to any other input.
Default value is @var{-1}.
@item -itsoffset @var{offset} (@emph{input})
Set the input time offset.
@ -555,27 +575,22 @@ ffmpeg -i INPUT -metadata:s:a:0 language=eng OUTPUT
@item -disposition[:stream_specifier] @var{value} (@emph{output,per-stream})
Sets the disposition for a stream.
This option overrides the disposition copied from the input stream. It is also
possible to delete the disposition by setting it to 0.
By default, the disposition is copied from the input stream, unless the output
stream this option applies to is fed by a complex filtergraph - in that case the
disposition is unset by default.
The following dispositions are recognized:
@table @option
@item default
@item dub
@item original
@item comment
@item lyrics
@item karaoke
@item forced
@item hearing_impaired
@item visual_impaired
@item clean_effects
@item attached_pic
@item captions
@item descriptions
@item dependent
@item metadata
@end table
@var{value} is a sequence of items separated by '+' or '-'. The first item may
also be prefixed with '+' or '-', in which case this option modifies the default
value. Otherwise (the first item is not prefixed) this options overrides the
default value. A '+' prefix adds the given disposition, '-' removes it. It is
also possible to clear the disposition by setting it to 0.
If no @code{-disposition} options were specified for an output file, ffmpeg will
automatically set the 'default' disposition on the first stream of each type,
when there are multiple streams of this type in the output file and no stream of
that type is already marked as default.
The @code{-dispositions} option lists the known dispositions.
For example, to make the second audio stream the default stream:
@example
@ -617,6 +632,102 @@ they do not conflict with the standard, as in:
ffmpeg -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg
@end example
The parameters set for each target are as follows.
@strong{VCD}
@example
@var{pal}:
-f vcd -muxrate 1411200 -muxpreload 0.44 -packetsize 2324
-s 352x288 -r 25
-codec:v mpeg1video -g 15 -b:v 1150k -maxrate:v 1150k -minrate:v 1150k -bufsize:v 327680
-ar 44100 -ac 2
-codec:a mp2 -b:a 224k
@var{ntsc}:
-f vcd -muxrate 1411200 -muxpreload 0.44 -packetsize 2324
-s 352x240 -r 30000/1001
-codec:v mpeg1video -g 18 -b:v 1150k -maxrate:v 1150k -minrate:v 1150k -bufsize:v 327680
-ar 44100 -ac 2
-codec:a mp2 -b:a 224k
@var{film}:
-f vcd -muxrate 1411200 -muxpreload 0.44 -packetsize 2324
-s 352x240 -r 24000/1001
-codec:v mpeg1video -g 18 -b:v 1150k -maxrate:v 1150k -minrate:v 1150k -bufsize:v 327680
-ar 44100 -ac 2
-codec:a mp2 -b:a 224k
@end example
@strong{SVCD}
@example
@var{pal}:
-f svcd -packetsize 2324
-s 480x576 -pix_fmt yuv420p -r 25
-codec:v mpeg2video -g 15 -b:v 2040k -maxrate:v 2516k -minrate:v 0 -bufsize:v 1835008 -scan_offset 1
-ar 44100
-codec:a mp2 -b:a 224k
@var{ntsc}:
-f svcd -packetsize 2324
-s 480x480 -pix_fmt yuv420p -r 30000/1001
-codec:v mpeg2video -g 18 -b:v 2040k -maxrate:v 2516k -minrate:v 0 -bufsize:v 1835008 -scan_offset 1
-ar 44100
-codec:a mp2 -b:a 224k
@var{film}:
-f svcd -packetsize 2324
-s 480x480 -pix_fmt yuv420p -r 24000/1001
-codec:v mpeg2video -g 18 -b:v 2040k -maxrate:v 2516k -minrate:v 0 -bufsize:v 1835008 -scan_offset 1
-ar 44100
-codec:a mp2 -b:a 224k
@end example
@strong{DVD}
@example
@var{pal}:
-f dvd -muxrate 10080k -packetsize 2048
-s 720x576 -pix_fmt yuv420p -r 25
-codec:v mpeg2video -g 15 -b:v 6000k -maxrate:v 9000k -minrate:v 0 -bufsize:v 1835008
-ar 48000
-codec:a ac3 -b:a 448k
@var{ntsc}:
-f dvd -muxrate 10080k -packetsize 2048
-s 720x480 -pix_fmt yuv420p -r 30000/1001
-codec:v mpeg2video -g 18 -b:v 6000k -maxrate:v 9000k -minrate:v 0 -bufsize:v 1835008
-ar 48000
-codec:a ac3 -b:a 448k
@var{film}:
-f dvd -muxrate 10080k -packetsize 2048
-s 720x480 -pix_fmt yuv420p -r 24000/1001
-codec:v mpeg2video -g 18 -b:v 6000k -maxrate:v 9000k -minrate:v 0 -bufsize:v 1835008
-ar 48000
-codec:a ac3 -b:a 448k
@end example
@strong{DV}
@example
@var{pal}:
-f dv
-s 720x576 -pix_fmt yuv420p -r 25
-ar 48000 -ac 2
@var{ntsc}:
-f dv
-s 720x480 -pix_fmt yuv411p -r 30000/1001
-ar 48000 -ac 2
@var{film}:
-f dv
-s 720x480 -pix_fmt yuv411p -r 24000/1001
-ar 48000 -ac 2
@end example
The @code{dv50} target is identical to the @code{dv} target except that the pixel format set is @code{yuv422p} for all three standards.
Any user-set value for a parameter above will override the target preset value. In that case, the output may
not comply with the target standard.
@item -dn (@emph{input/output})
As an input option, blocks all data streams of a file from being filtered or
being automatically selected or mapped for any output. See @code{-discard}
@ -663,6 +774,16 @@ This option is similar to @option{-filter}, the only difference is that its
argument is the name of the file from which a filtergraph description is to be
read.
@item -reinit_filter[:@var{stream_specifier}] @var{integer} (@emph{input,per-stream})
This boolean option determines if the filtergraph(s) to which this stream is fed gets
reinitialized when input frame parameters change mid-stream. This option is enabled by
default as most video and all audio filters cannot handle deviation in input frame properties.
Upon reinitialization, existing filter state is lost, like e.g. the frame count @code{n}
reference available in some filters. Any frames buffered at time of reinitialization are lost.
The properties where a change triggers reinitialization are,
for video, frame resolution or pixel format;
for audio, sample format, sample rate, channel count or channel layout.
@item -filter_threads @var{nb_threads} (@emph{global})
Defines how many threads are used to process a filter pipeline. Each pipeline
will produce a thread pool with this many threads available for parallel processing.
@ -675,14 +796,19 @@ Specify the preset for matching stream(s).
Print encoding progress/statistics. It is on by default, to explicitly
disable it you need to specify @code{-nostats}.
@item -stats_period @var{time} (@emph{global})
Set period at which encoding progress/statistics are updated. Default is 0.5 seconds.
@item -progress @var{url} (@emph{global})
Send program-friendly progress information to @var{url}.
Progress information is written approximately every second and at the end of
Progress information is written periodically and at the end of
the encoding process. It is made of "@var{key}=@var{value}" lines. @var{key}
consists of only alphanumeric characters. The last key of a sequence of
progress information is always "progress".
The update period is set using @code{-stats_period}.
@anchor{stdin option}
@item -stdin
Enable interaction on standard input. On by default unless standard input is
@ -734,10 +860,6 @@ ffmpeg -dump_attachment:t "" -i INPUT
Technical note -- attachments are implemented as codec extradata, so this
option can actually be used to extract extradata from any stream, not just
attachments.
@item -noautorotate
Disable automatically rotating video based on file metadata.
@end table
@section Video Options
@ -758,6 +880,13 @@ If in doubt use @option{-framerate} instead of the input option @option{-r}.
As an output option, duplicate or drop input frames to achieve constant output
frame rate @var{fps}.
@item -fpsmax[:@var{stream_specifier}] @var{fps} (@emph{output,per-stream})
Set maximum frame rate (Hz value, fraction or abbreviation).
Clamps output frame rate when output framerate is auto-set and is higher than this value.
Useful in batch processing or when input framerate is wrongly detected as very high.
It cannot be set together with @code{-r}. It is ignored during streamcopy.
@item -s[:@var{stream_specifier}] @var{size} (@emph{input/output,per-stream})
Set frame size.
@ -819,6 +948,18 @@ Create the filtergraph specified by @var{filtergraph} and use it to
filter the stream.
This is an alias for @code{-filter:v}, see the @ref{filter_option,,-filter option}.
@item -autorotate
Automatically rotate the video according to file metadata. Enabled by
default, use @option{-noautorotate} to disable it.
@item -autoscale
Automatically scale the video according to the resolution of first frame.
Enabled by default, use @option{-noautoscale} to disable it. When autoscale is
disabled, all output frames of filter graph might not be in the same resolution
and may be inadequate for some encoder/muxer. Therefore, it is not recommended
to disable it unless you really know what you are doing.
Disable autoscale at your own risk.
@end table
@section Advanced Video options
@ -848,8 +989,8 @@ factor if negative.
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 with
@option{-deinterlace}, but deinterlacing introduces 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.
@item -vstats
@ -879,12 +1020,20 @@ Deprecated see -bsf
@item -force_key_frames[:@var{stream_specifier}] @var{time}[,@var{time}...] (@emph{output,per-stream})
@item -force_key_frames[:@var{stream_specifier}] expr:@var{expr} (@emph{output,per-stream})
Force key frames at the specified timestamps, more precisely at the first
frames after each specified time.
@item -force_key_frames[:@var{stream_specifier}] source (@emph{output,per-stream})
@item -force_key_frames[:@var{stream_specifier}] source_no_drop (@emph{output,per-stream})
If the argument is prefixed with @code{expr:}, the string @var{expr}
is interpreted like an expression and is evaluated for each frame. A
key frame is forced in case the evaluation is non-zero.
@var{force_key_frames} can take arguments of the following form:
@table @option
@item @var{time}[,@var{time}...]
If the argument consists of timestamps, ffmpeg will round the specified times to the nearest
output timestamp as per the encoder time base and force a keyframe at the first frame having
timestamp equal or greater than the computed timestamp. Note that if the encoder time base is too
coarse, then the keyframes may be forced on frames with timestamps lower than the specified time.
The default encoder time base is the inverse of the output framerate but may be set otherwise
via @code{-enc_time_base}.
If one of the times is "@code{chapters}[@var{delta}]", it is expanded into
the time of the beginning of all chapters in the file, shifted by
@ -898,6 +1047,11 @@ before the beginning of every chapter:
-force_key_frames 0:05:00,chapters-0.1
@end example
@item expr:@var{expr}
If the argument is prefixed with @code{expr:}, the string @var{expr}
is interpreted like an expression and is evaluated for each frame. A
key frame is forced in case the evaluation is non-zero.
The expression in @var{expr} can contain the following constants:
@table @option
@item n
@ -925,6 +1079,18 @@ starting from second 13:
-force_key_frames expr:if(isnan(prev_forced_t),gte(t,13),gte(t,prev_forced_t+5))
@end example
@item source
If the argument is @code{source}, ffmpeg will force a key frame if
the current frame being encoded is marked as a key frame in its source.
@item source_no_drop
If the argument is @code{source_no_drop}, ffmpeg will force a key frame if
the current frame being encoded is marked as a key frame in its source.
In cases where this particular source frame has to be dropped,
enforce the next available frame to become a key frame instead.
@end table
Note that forcing too many keyframes is very harmful for the lookahead
algorithms of certain encoders: using fixed-GOP options or similar
would be more efficient.
@ -945,9 +1111,27 @@ device type:
@item cuda
@var{device} is the number of the CUDA device.
The following options are recognized:
@table @option
@item primary_ctx
If set to 1, uses the primary device context instead of creating a new one.
@end table
Examples:
@table @emph
@item -init_hw_device cuda:1
Choose the second device on the system.
@item -init_hw_device cuda:0,primary_ctx=1
Choose the first device and use the primary device context.
@end table
@item dxva2
@var{device} is the number of the Direct3D 9 display adapter.
@item d3d11va
@var{device} is the number of the Direct3D 11 display adapter.
@item vaapi
@var{device} is either an X11 display name or a DRM render node.
If not specified, it will attempt to open the default X11 display (@emph{$DISPLAY})
@ -971,9 +1155,21 @@ If not specified, it will attempt to open the default X11 display (@emph{$DISPLA
@end table
If not specified, @samp{auto_any} is used.
(Note that it may be easier to achieve the desired result for QSV by creating the
platform-appropriate subdevice (@samp{dxva2} or @samp{vaapi}) and then deriving a
platform-appropriate subdevice (@samp{dxva2} or @samp{d3d11va} or @samp{vaapi}) and then deriving a
QSV device from that.)
Alternatively, @samp{child_device_type} helps to choose platform-appropriate subdevice type.
On Windows @samp{d3d11va} is used as default subdevice type.
Examples:
@table @emph
@item -init_hw_device qsv:hw,child_device_type=d3d11va
Choose the GPU subdevice with type @samp{d3d11va} and create QSV device with @samp{MFX_IMPL_HARDWARE}.
@item -init_hw_device qsv:hw,child_device_type=dxva2
Choose the GPU subdevice with type @samp{dxva2} and create QSV device with @samp{MFX_IMPL_HARDWARE}.
@end table
@item opencl
@var{device} selects the platform and device as @emph{platform_index.device_index}.
@ -1011,6 +1207,35 @@ Choose the GPU device on the second platform supporting the @emph{cl_khr_fp16}
extension.
@end table
@item vulkan
If @var{device} is an integer, it selects the device by its index in a
system-dependent list of devices. If @var{device} is any other string, it
selects the first device with a name containing that string as a substring.
The following options are recognized:
@table @option
@item debug
If set to 1, enables the validation layer, if installed.
@item linear_images
If set to 1, images allocated by the hwcontext will be linear and locally mappable.
@item instance_extensions
A plus separated list of additional instance extensions to enable.
@item device_extensions
A plus separated list of additional device extensions to enable.
@end table
Examples:
@table @emph
@item -init_hw_device vulkan:1
Choose the second device on the system.
@item -init_hw_device vulkan:RADV
Choose the first device with a name containing the string @emph{RADV}.
@item -init_hw_device vulkan:0,instance_extensions=VK_KHR_wayland_surface+VK_KHR_xcb_surface
Choose the first device and enable the Wayland and XCB instance extensions.
@end table
@end table
@item -init_hw_device @var{type}[=@var{name}]@@@var{source}
@ -1047,6 +1272,9 @@ Use VDPAU (Video Decode and Presentation API for Unix) hardware acceleration.
@item dxva2
Use DXVA2 (DirectX Video Acceleration) hardware acceleration.
@item d3d11va
Use D3D11VA (DirectX Video Acceleration) hardware acceleration.
@item vaapi
Use VAAPI (Video Acceleration API) hardware acceleration.
@ -1080,7 +1308,9 @@ by name, or it can create a new device as if
were called immediately before.
@item -hwaccels
List all hardware acceleration methods supported in this build of ffmpeg.
List all hardware acceleration components enabled in this build of ffmpeg.
Actual runtime availability depends on the hardware and its suitable driver
being installed.
@end table
@ -1383,38 +1613,49 @@ it will usually display as 0 if not supported.
Show benchmarking information during the encode.
Shows real, system and user time used in various steps (audio/video encode/decode).
@item -timelimit @var{duration} (@emph{global})
Exit after ffmpeg has been running for @var{duration} seconds.
Exit after ffmpeg has been running for @var{duration} seconds in CPU user time.
@item -dump (@emph{global})
Dump each input packet to stderr.
@item -hex (@emph{global})
When dumping packets, also dump the payload.
@item -readrate @var{speed} (@emph{input})
Limit input read speed.
Its value is a floating-point positive number which represents the maximum duration of
media, in seconds, that should be ingested in one second of wallclock time.
Default value is zero and represents no imposed limitation on speed of ingestion.
Value @code{1} represents real-time speed and is equivalent to @code{-re}.
Mainly used to simulate a capture device or live input stream (e.g. when reading from a file).
Should not be used with a low value when input is an actual capture device or live stream as
it may cause packet loss.
It is useful for when flow speed of output packets is important, such as live streaming.
@item -re (@emph{input})
Read input at native frame rate. Mainly used to simulate a grab device,
or live input stream (e.g. when reading from a file). Should not be used
with actual grab devices or live input streams (where it can cause packet
loss).
By default @command{ffmpeg} attempts to read the input(s) as fast as possible.
This option will slow down the reading of the input(s) to the native frame rate
of the input(s). It is useful for real-time output (e.g. live streaming).
@item -vsync @var{parameter}
Video sync method.
For compatibility reasons old values can be specified as numbers.
Newly added values will have to be specified as strings always.
Read input at native frame rate. This is equivalent to setting @code{-readrate 1}.
@item -vsync @var{parameter} (@emph{global})
@itemx -fps_mode[:@var{stream_specifier}] @var{parameter} (@emph{output,per-stream})
Set video sync method / framerate mode. vsync is applied to all output video streams
but can be overridden for a stream by setting fps_mode. vsync is deprecated and will be
removed in the future.
For compatibility reasons some of the values for vsync can be specified as numbers (shown
in parentheses in the following table).
@table @option
@item 0, passthrough
@item passthrough (0)
Each frame is passed with its timestamp from the demuxer to the muxer.
@item 1, cfr
@item cfr (1)
Frames will be duplicated and dropped to achieve exactly the requested
constant frame rate.
@item 2, vfr
@item vfr (2)
Frames are passed through with their timestamp or dropped so as to
prevent 2 frames from having the same timestamp.
@item drop
As passthrough but destroys all timestamps, making the muxer generate
fresh timestamps based on frame-rate.
@item -1, auto
Chooses between 1 and 2 depending on muxer capabilities. This is the
@item auto (-1)
Chooses between cfr and vfr depending on muxer capabilities. This is the
default method.
@end table
@ -1445,6 +1686,17 @@ 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
a threshold to select between hard (add/drop) and soft (squeeze/stretch) compensation.
@code{-async} must be set to a positive value.
@item -apad @var{parameters} (@emph{output,per-stream})
Pad the output audio stream(s). This is the same as applying @code{-af apad}.
Argument is a string of filter parameters composed the same as with the @code{apad} filter.
@code{-shortest} must be set for this output for the option to take effect.
@item -copyts
Do not process input timestamps, but keep their values without trying
to sanitize them. In particular, do not remove the initial start time
@ -1512,9 +1764,13 @@ Default value is 0.
@item -bitexact (@emph{input/output})
Enable bitexact mode for (de)muxer and (de/en)coder
@item -shortest (@emph{output})
Finish encoding when the shortest input stream ends.
Finish encoding when the shortest output stream ends.
@item -dts_delta_threshold
Timestamp discontinuity delta threshold.
@item -dts_error_threshold @var{seconds}
Timestamp error delta threshold. This threshold use to discard crazy/damaged
timestamps and the default is 30 hours which is arbitrarily picked and quite
conservative.
@item -muxdelay @var{seconds} (@emph{output})
Set the maximum demux-decode delay.
@item -muxpreload @var{seconds} (@emph{output})
@ -1595,6 +1851,22 @@ graph will be added to the output file automatically, so we can simply write
ffmpeg -i video.mkv -i image.png -filter_complex 'overlay' out.mkv
@end example
As a special exception, you can use a bitmap subtitle stream as input: it
will be converted into a video with the same size as the largest video in
the file, or 720x576 if no video is present. Note that this is an
experimental and temporary solution. It will be removed once libavfilter has
proper support for subtitles.
For example, to hardcode subtitles on top of a DVB-T recording stored in
MPEG-TS format, delaying the subtitles by 1 second:
@example
ffmpeg -i input.ts -filter_complex \
'[#0x2ef] setpts=PTS+1/TB [sub] ; [#0x2d0] [sub] overlay' \
-sn -map '#0x2dc' output.mkv
@end example
(0x2d0, 0x2dc and 0x2ef are the MPEG-TS PIDs of respectively the video,
audio and subtitles streams; 0:0, 0:3 and 0:7 would have worked too)
To generate 5 seconds of pure red video using lavfi @code{color} source:
@example
ffmpeg -filter_complex 'color=c=red' -t 5 out.mkv
@ -1630,8 +1902,9 @@ not start from timestamp 0, such as transport streams.
@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; raising this value can
avoid it.
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.
@item -sdp_file @var{file} (@emph{global})
Print sdp information for an output stream to @var{file}.
@ -1670,8 +1943,15 @@ Stop and abort on various conditions. The following flags are available:
@table @option
@item empty_output
No packets were passed to the muxer, the output is empty.
@item empty_output_stream
No packets were passed to the muxer in some of the output streams.
@end table
@item -max_error_rate (@emph{global})
Set fraction of decoding frame failures across all inputs which when crossed
ffmpeg will return exit code 69. Crossing this threshold does not terminate
processing. Range is a floating-point number between 0 to 1. Default is 2/3.
@item -xerror (@emph{global})
Stop and exit on error
@ -1684,24 +1964,30 @@ this buffer, in packets, for the matching output stream.
The default value of this option should be high enough for most uses, so only
touch this option if you are sure that you need it.
@item -muxing_queue_data_threshold @var{bytes} (@emph{output,per-stream})
This is a minimum threshold until which the muxing queue size is not taken into
account. Defaults to 50 megabytes per stream, and is based on the overall size
of packets passed to the muxer.
@item -auto_conversion_filters (@emph{global})
Enable automatically inserting format conversion filters in all filter
graphs, including those defined by @option{-vf}, @option{-af},
@option{-filter_complex} and @option{-lavfi}. If filter format negotiation
requires a conversion, the initialization of the filters will fail.
Conversions can still be performed by inserting the relevant conversion
filter (scale, aresample) in the graph.
On by default, to explicitly disable it you need to specify
@code{-noauto_conversion_filters}.
@item -bits_per_raw_sample[:@var{stream_specifier}] @var{value} (@emph{output,per-stream})
Declare the number of bits per raw sample in the given output stream to be
@var{value}. Note that this option sets the information provided to the
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.
@end table
As a special exception, you can use a bitmap subtitle stream as input: it
will be converted into a video with the same size as the largest video in
the file, or 720x576 if no video is present. Note that this is an
experimental and temporary solution. It will be removed once libavfilter has
proper support for subtitles.
For example, to hardcode subtitles on top of a DVB-T recording stored in
MPEG-TS format, delaying the subtitles by 1 second:
@example
ffmpeg -i input.ts -filter_complex \
'[#0x2ef] setpts=PTS+1/TB [sub] ; [#0x2d0] [sub] overlay' \
-sn -map '#0x2dc' output.mkv
@end example
(0x2d0, 0x2dc and 0x2ef are the MPEG-TS PIDs of respectively the video,
audio and subtitles streams; 0:0, 0:3 and 0:7 would have worked too)
@section Preset files
A preset file contains a sequence of @var{option}=@var{value} pairs,
one for each line, specifying a sequence of options which would be
@ -1978,6 +2264,7 @@ ffmpeg -i src.ext -lmax 21*QP2LAMBDA dst.ext
@ifset config-avfilter
@include filters.texi
@end ifset
@include general_contents.texi
@end ifset
@chapter See Also

View File

@ -34,10 +34,6 @@ various FFmpeg APIs.
Force displayed width.
@item -y @var{height}
Force displayed height.
@item -s @var{size}
Set frame size (WxH or abbreviation), needed for videos which do
not contain a header with the frame size like raw YUV. This option
has been deprecated in favor of private options, try -video_size.
@item -fs
Start in fullscreen mode.
@item -an
@ -126,15 +122,12 @@ Read @var{input_url}.
@section Advanced options
@table @option
@item -pix_fmt @var{format}
Set pixel format.
This option has been deprecated in favor of private options, try -pixel_format.
@item -stats
Print several playback statistics, in particular show the stream
duration, the codec parameters, the current position in the stream and
the audio/video synchronisation drift. It is on by default, to
explicitly disable it you need to specify @code{-nostats}.
the audio/video synchronisation drift. It is shown by default, unless the
log level is lower than @code{info}. Its display can be forced by manually
specifying this option. To disable it, you need to specify @code{-nostats}.
@item -fast
Non-spec-compliant optimizations.
@ -221,8 +214,6 @@ Pause.
Toggle mute.
@item 9, 0
Decrease and increase volume respectively.
@item /, *
Decrease and increase volume respectively.
@ -294,6 +285,7 @@ Toggle full screen.
@ifset config-avfilter
@include filters.texi
@end ifset
@include general_contents.texi
@end ifset
@chapter See Also

View File

@ -12,7 +12,7 @@
@chapter Synopsis
ffprobe [@var{options}] [@file{input_url}]
ffprobe [@var{options}] @file{input_url}
@chapter Description
@c man begin DESCRIPTION
@ -28,6 +28,9 @@ If a url is specified in input, ffprobe will try to open and
probe the url content. If the url cannot be opened or recognized as
a multimedia file, a positive exit code is returned.
If no output is specified as output with @option{o} ffprobe will write
to stdout.
ffprobe may be employed both as a standalone application or in
combination with a textual filter, which may perform more
sophisticated processing, e.g. statistical processing or plotting.
@ -335,6 +338,12 @@ Show information about all pixel formats supported by FFmpeg.
Pixel format information for each format is printed within a section
with name "PIXEL_FORMAT".
@item -show_optional_fields @var{value}
Some writers viz. JSON and XML, omit the printing of fields with invalid or non-applicable values,
while other writers always print them. This option enables one to control this behaviour.
Valid values are @code{always}/@code{1}, @code{never}/@code{0} and @code{auto}/@code{-1}.
Default is @var{auto}.
@item -bitexact
Force bitexact output, useful to produce output which is not dependent
on the specific build.
@ -342,6 +351,10 @@ on the specific build.
@item -i @var{input_url}
Read @var{input_url}.
@item -o @var{output_url}
Write output to @var{output_url}. If not specified, the output is sent
to stdout.
@end table
@c man end
@ -642,6 +655,7 @@ DV, GXF and AVI timecodes are available in format metadata
@ifset config-avfilter
@include filters.texi
@end ifset
@include general_contents.texi
@end ifset
@chapter See Also

View File

@ -29,22 +29,18 @@
</xsd:complexType>
<xsd:complexType name="framesType">
<xsd:sequence>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="frame" type="ffprobe:frameType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="subtitle" type="ffprobe:subtitleType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:choice>
</xsd:sequence>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="frame" type="ffprobe:frameType"/>
<xsd:element name="subtitle" type="ffprobe:subtitleType"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="packetsAndFramesType">
<xsd:sequence>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="packet" type="ffprobe:packetType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="frame" type="ffprobe:frameType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="subtitle" type="ffprobe:subtitleType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:choice>
</xsd:sequence>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="packet" type="ffprobe:packetType"/>
<xsd:element name="frame" type="ffprobe:frameType"/>
<xsd:element name="subtitle" type="ffprobe:subtitleType"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="packetType">
@ -61,8 +57,6 @@
<xsd:attribute name="dts_time" type="xsd:float" />
<xsd:attribute name="duration" type="xsd:long" />
<xsd:attribute name="duration_time" type="xsd:float" />
<xsd:attribute name="convergence_duration" type="xsd:long" />
<xsd:attribute name="convergence_duration_time" type="xsd:float" />
<xsd:attribute name="size" type="xsd:long" use="required" />
<xsd:attribute name="pos" type="xsd:long" />
<xsd:attribute name="flags" type="xsd:string" use="required" />
@ -92,8 +86,6 @@
<xsd:attribute name="key_frame" type="xsd:int" use="required"/>
<xsd:attribute name="pts" type="xsd:long" />
<xsd:attribute name="pts_time" type="xsd:float"/>
<xsd:attribute name="pkt_pts" type="xsd:long" />
<xsd:attribute name="pkt_pts_time" type="xsd:float"/>
<xsd:attribute name="pkt_dts" type="xsd:long" />
<xsd:attribute name="pkt_dts_time" type="xsd:float"/>
<xsd:attribute name="best_effort_timestamp" type="xsd:long" />
@ -201,6 +193,11 @@
<xsd:attribute name="clean_effects" type="xsd:int" use="required" />
<xsd:attribute name="attached_pic" type="xsd:int" use="required" />
<xsd:attribute name="timed_thumbnails" type="xsd:int" use="required" />
<xsd:attribute name="captions" type="xsd:int" use="required" />
<xsd:attribute name="descriptions" type="xsd:int" use="required" />
<xsd:attribute name="metadata" type="xsd:int" use="required" />
<xsd:attribute name="dependent" type="xsd:int" use="required" />
<xsd:attribute name="still_image" type="xsd:int" use="required" />
</xsd:complexType>
<xsd:complexType name="streamType">
@ -215,10 +212,10 @@
<xsd:attribute name="codec_long_name" type="xsd:string" />
<xsd:attribute name="profile" type="xsd:string" />
<xsd:attribute name="codec_type" type="xsd:string" />
<xsd:attribute name="codec_time_base" type="xsd:string" use="required"/>
<xsd:attribute name="codec_tag" type="xsd:string" use="required"/>
<xsd:attribute name="codec_tag_string" type="xsd:string" use="required"/>
<xsd:attribute name="extradata" type="xsd:string" />
<xsd:attribute name="extradata_size" type="xsd:int" />
<xsd:attribute name="extradata_hash" type="xsd:string" />
<!-- video attributes -->
@ -226,6 +223,8 @@
<xsd:attribute name="height" type="xsd:int"/>
<xsd:attribute name="coded_width" type="xsd:int"/>
<xsd:attribute name="coded_height" type="xsd:int"/>
<xsd:attribute name="closed_captions" type="xsd:boolean"/>
<xsd:attribute name="film_grain" type="xsd:boolean"/>
<xsd:attribute name="has_b_frames" type="xsd:int"/>
<xsd:attribute name="sample_aspect_ratio" type="xsd:string"/>
<xsd:attribute name="display_aspect_ratio" type="xsd:string"/>
@ -237,7 +236,6 @@
<xsd:attribute name="color_primaries" type="xsd:string"/>
<xsd:attribute name="chroma_location" type="xsd:string"/>
<xsd:attribute name="field_order" type="xsd:string"/>
<xsd:attribute name="timecode" type="xsd:string"/>
<xsd:attribute name="refs" type="xsd:int"/>
<!-- audio attributes -->
@ -272,10 +270,6 @@
<xsd:attribute name="program_id" type="xsd:int" use="required"/>
<xsd:attribute name="program_num" type="xsd:int" use="required"/>
<xsd:attribute name="nb_streams" type="xsd:int" use="required"/>
<xsd:attribute name="start_time" type="xsd:float"/>
<xsd:attribute name="start_pts" type="xsd:long"/>
<xsd:attribute name="end_time" type="xsd:float"/>
<xsd:attribute name="end_pts" type="xsd:long"/>
<xsd:attribute name="pmt_pid" type="xsd:int" use="required"/>
<xsd:attribute name="pcr_pid" type="xsd:int" use="required"/>
</xsd:complexType>
@ -357,7 +351,6 @@
<xsd:attribute name="hwaccel" type="xsd:int" use="required"/>
<xsd:attribute name="planar" type="xsd:int" use="required"/>
<xsd:attribute name="rgb" type="xsd:int" use="required"/>
<xsd:attribute name="pseudopal" type="xsd:int" use="required"/>
<xsd:attribute name="alpha" type="xsd:int" use="required"/>
</xsd:complexType>

View File

@ -107,17 +107,24 @@ Print detailed information about the muxer named @var{muxer_name}. Use the
@option{-formats} option to get a list of all muxers and demuxers.
@item filter=@var{filter_name}
Print detailed information about the filter name @var{filter_name}. Use the
Print detailed information about the filter named @var{filter_name}. Use the
@option{-filters} option to get a list of all filters.
@item bsf=@var{bitstream_filter_name}
Print detailed information about the bitstream filter name @var{bitstream_filter_name}.
Print detailed information about the bitstream filter named @var{bitstream_filter_name}.
Use the @option{-bsfs} option to get a list of all bitstream filters.
@item protocol=@var{protocol_name}
Print detailed information about the protocol named @var{protocol_name}.
Use the @option{-protocols} option to get a list of all protocols.
@end table
@item -version
Show version.
@item -buildconf
Show the build configuration, one option per line.
@item -formats
Show available formats (including devices).
@ -160,6 +167,9 @@ Show available sample formats.
@item -layouts
Show channel names and standard channel layouts.
@item -dispositions
Show stream dispositions.
@item -colors
Show recognized color names.
@ -236,13 +246,11 @@ ffmpeg [...] -loglevel +repeat
By default the program logs to stderr. If coloring is supported by the
terminal, colors are used to mark errors and warnings. Log coloring
can be disabled setting the environment variable
@env{AV_LOG_FORCE_NOCOLOR} or @env{NO_COLOR}, or can be forced setting
@env{AV_LOG_FORCE_NOCOLOR}, or can be forced setting
the environment variable @env{AV_LOG_FORCE_COLOR}.
The use of the environment variable @env{NO_COLOR} is deprecated and
will be dropped in a future FFmpeg version.
@item -report
Dump full command line and console output to a file named
Dump full command line and log output to a file named
@code{@var{program}-@var{YYYYMMDD}-@var{HHMMSS}.log} in the current
directory.
This file can be useful for bug reports.
@ -347,6 +355,19 @@ Possible flags for this option are:
@item k8
@end table
@end table
@item -cpucount @var{count} (@emph{global})
Override detection of CPU count. This option is intended
for testing. Do not use it unless you know what you're doing.
@example
ffmpeg -cpucount 2
@end example
@item -max_alloc @var{bytes}
Set the maximum size limit for allocating a block on the heap by ffmpeg's
family of malloc functions. Exercise @strong{extreme caution} when using
this option. Don't use if you do not understand the full consequence of doing so.
Default is INT_MAX.
@end table
@section AVOptions

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,10 @@ stream information. A higher value will enable detecting more
information in case it is dispersed into the stream, but will increase
latency. Must be an integer not lesser than 32. It is 5000000 by default.
@item max_probe_packets @var{integer} (@emph{input})
Set the maximum number of buffered packets when probing a codec.
Default is 2500 packets.
@item packetsize @var{integer} (@emph{output})
Set packet size.
@ -45,7 +49,6 @@ Generate missing PTS if DTS is present.
Ignore DTS if PTS is set. Inert when nofillin is set.
@item ignidx
Ignore index.
@item keepside (@emph{deprecated},@emph{inert})
@item nobuffer
Reduce the latency introduced by buffering during initial input streams analysis.
@item nofillin
@ -66,7 +69,6 @@ This ensures that file and data checksums are reproducible and match between
platforms. Its primary use is for regression testing.
@item flush_packets
Write out packets immediately.
@item latm (@emph{deprecated},@emph{inert})
@item shortest
Stop muxing at the end of the shortest stream.
It may be needed to increase max_interleave_delta to avoid flushing the longer
@ -139,7 +141,7 @@ Consider things that a sane encoder should not do as an error.
@item max_interleave_delta @var{integer} (@emph{output})
Set maximum buffering duration for interleaving. The duration is
expressed in microseconds, and defaults to 1000000 (1 second).
expressed in microseconds, and defaults to 10000000 (10 seconds).
To ensure all the streams are interleaved correctly, libavformat will
wait until it has at least one packet for each stream before actually

File diff suppressed because it is too large Load Diff

1459
doc/general_contents.texi Normal file

File diff suppressed because it is too large Load Diff

View File

@ -187,11 +187,18 @@ to make sure you don't have untracked files or deletions.
git add [-i|-p|-A] <filenames/dirnames>
@end example
Make sure you have told Git your name and email address
Make sure you have told Git your name, email address and GPG key
@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.
@ -217,16 +224,46 @@ git config --global core.editor
or set by one of the following environment variables:
@var{GIT_EDITOR}, @var{VISUAL} or @var{EDITOR}.
Log messages should be concise but descriptive. Explain why you made a change,
what you did will be obvious from the changes themselves most of the time.
Saying just "bug fix" or "10l" is bad. Remember that people of varying skill
levels look at and educate themselves while reading through your code. Don't
include filenames in log messages, Git provides that information.
@section Writing a commit message
Possibly make the commit message have a terse, descriptive first line, an
empty line and then a full description. The first line will be used to name
Log messages should be concise but descriptive.
The first line must contain the context, a colon and a very short
summary of what the commit does. Details can be added, if necessary,
separated by an empty line. These details should not exceed 60-72 characters
per line, except when containing code.
Example of a good commit message:
@example
avcodec/cbs: add a helper to read extradata within packet side data
Using ff_cbs_read() on the raw buffer will not parse it as extradata,
resulting in parsing errors for example when handling ISOBMFF avcC.
This helper works around that.
@end example
@example
ptr might be NULL
@end example
If the summary on the first line is not enough, in the body of the message,
explain why you made a change, what you did will be obvious from the changes
themselves most of the time. Saying just "bug fix" or "10l" is bad. Remember
that people of varying skill levels look at and educate themselves while
reading through your code. Don't include filenames in log messages except in
the context, Git provides that information.
If the commit fixes a registered issue, state it in a separate line of the
body: @code{Fix Trac ticket #42.}
The first line will be used to name
the patch by @command{git format-patch}.
Common mistakes for the first line, as seen in @command{git log --oneline}
include: missing context at the beginning; description of what the code did
before the patch; line too long or wrapped to the second line.
@section Preparing a patchset
@example
@ -393,6 +430,19 @@ 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,

View File

@ -277,8 +277,8 @@ audio track.
@item list_devices
If set to @option{true}, print a list of devices and exit.
Defaults to @option{false}. Alternatively you can use the @code{-sources}
option of ffmpeg to list the available input devices.
Defaults to @option{false}. This option is deprecated, please use the
@code{-sources} option of ffmpeg to list the available input devices.
@item list_formats
If set to @option{true}, print a list of supported formats and exit.
@ -292,25 +292,35 @@ as @option{pal} (3 letters).
Default behavior is autodetection of the input video format, if the hardware
supports it.
@item bm_v210
This is a deprecated option, you can use @option{raw_format} instead.
If set to @samp{1}, video is captured in 10 bit v210 instead
of uyvy422. Not all Blackmagic devices support this option.
@item raw_format
Set the pixel format of the captured video.
Available values are:
@table @samp
@item auto
This is the default which means 8-bit YUV 422 or 8-bit ARGB if format
autodetection is used, 8-bit YUV 422 otherwise.
@item uyvy422
8-bit YUV 422.
@item yuv422p10
10-bit YUV 422.
@item argb
8-bit RGB.
@item bgra
8-bit RGB.
@item rgb10
10-bit RGB.
@end table
@item teletext_lines
@ -334,14 +344,33 @@ Defines number of audio channels to capture. Must be @samp{2}, @samp{8} or @samp
Defaults to @samp{2}.
@item duplex_mode
Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.
Sets the decklink device duplex/profile mode. Must be @samp{unset}, @samp{half}, @samp{full},
@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
@samp{four_sub_device_half}
Defaults to @samp{unset}.
Note: DeckLink SDK 11.0 have replaced the duplex property by a profile property.
For the DeckLink Duo 2 and DeckLink Quad 2, a profile is shared between any 2
sub-devices that utilize the same connectors. For the DeckLink 8K Pro, a profile
is shared between all 4 sub-devices. So DeckLink 8K Pro support four profiles.
Valid profile modes for DeckLink 8K Pro(with DeckLink SDK >= 11.0):
@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
@samp{four_sub_device_half}
Valid profile modes for DeckLink Quad 2 and DeckLink Duo 2:
@samp{half}, @samp{full}
@item timecode_format
Timecode type to include in the frame and video stream metadata. Must be
@samp{none}, @samp{rp188vitc}, @samp{rp188vitc2}, @samp{rp188ltc},
@samp{rp188any}, @samp{vitc}, @samp{vitc2}, or @samp{serial}. Defaults to
@samp{none} (not included).
@samp{rp188hfr}, @samp{rp188any}, @samp{vitc}, @samp{vitc2}, or @samp{serial}.
Defaults to @samp{none} (not included).
In order to properly support 50/60 fps timecodes, the ordering of the queried
timecode types for @samp{rp188any} is HFR, VITC1, VITC2 and LTC for >30 fps
content. Note that this is slightly different to the ordering used by the
DeckLink API, which is HFR, VITC1, LTC, VITC2.
@item video_input
Sets the video input source. Must be @samp{unset}, @samp{sdi}, @samp{hdmi},
@ -395,6 +424,20 @@ Either sync could go wrong by 1 frame or in a rarer case
@option{timestamp_align} seconds.
Defaults to @samp{0}.
@item wait_for_tc (@emph{bool})
Drop frames till a frame with timecode is received. Sometimes serial timecode
isn't received with the first input frame. If that happens, the stored stream
timecode will be inaccurate. If this option is set to @option{true}, input frames
are dropped till a frame with timecode is received.
Option @var{timecode_format} must be specified.
Defaults to @option{false}.
@item enable_klv(@emph{bool})
If set to @option{true}, extracts KLV data from VANC and outputs KLV packets.
KLV VANC packets are joined based on MID and PSC fields and aggregated into
one KLV packet.
Defaults to @option{false}.
@end table
@subsection Examples
@ -404,7 +447,7 @@ Defaults to @samp{0}.
@item
List input devices:
@example
ffmpeg -f decklink -list_devices 1 -i dummy
ffmpeg -sources decklink
@end example
@item
@ -422,7 +465,7 @@ ffmpeg -format_code Hi50 -f decklink -i 'Intensity Pro' -c:a copy -c:v copy outp
@item
Capture video clip at 1080i50 10 bit:
@example
ffmpeg -bm_v210 1 -format_code Hi50 -f decklink -i 'UltraStudio Mini Recorder' -c:a copy -c:v copy output.avi
ffmpeg -raw_format yuv422p10 -format_code Hi50 -f decklink -i 'UltraStudio Mini Recorder' -c:a copy -c:v copy output.avi
@end example
@item
@ -582,6 +625,12 @@ Save the currently used video capture filter device and its
parameters (if the filter supports it) to a file.
If a file with the same name exists it will be overwritten.
@item use_video_device_timestamps
If set to @option{false}, the timestamp for video frames will be
derived from the wallclock instead of the timestamp provided by
the capture device. This allows working around devices that
provide unreliable timestamps.
@end table
@subsection Examples
@ -880,11 +929,15 @@ If you don't understand what all of that means, you probably don't want this. L
DRM device to capture on. Defaults to @option{/dev/dri/card0}.
@item format
Pixel format of the framebuffer. Defaults to @option{bgr0}.
Pixel format of the framebuffer. This can be autodetected if you are running Linux 5.7
or later, but needs to be provided for earlier versions. Defaults to @option{bgr0},
which is the most common format used by the Linux console and Xorg X server.
@item format_modifier
Format modifier to signal on output frames. This is necessary to import correctly into
some APIs, but can't be autodetected. See the libdrm documentation for possible values.
some APIs. It can be autodetected if you are running Linux 5.7 or later, but will need
to be provided explicitly when needed in earlier versions. See the libdrm documentation
for possible values.
@item crtc_id
KMS CRTC ID to define the capture source. The first active plane on the given CRTC
@ -1236,11 +1289,11 @@ Specify the samplerate in Hz, by default 48kHz is used.
Specify the channels in use, by default 2 (stereo) is set.
@item frame_size
Specify the number of bytes per frame, by default it is set to 1024.
This option does nothing and is deprecated.
@item fragment_size
Specify the minimal buffering fragment in PulseAudio, it will affect the
audio latency. By default it is unset.
Specify the size in bytes of the minimal buffering fragment in PulseAudio, it
will affect the audio latency. By default it is set to 50 ms amount of data.
@item wallclock
Set the initial PTS using the current time. Default is 1.
@ -1475,6 +1528,14 @@ ffmpeg -f x11grab -framerate 25 -video_size cif -i :0.0+10,20 out.mpg
@subsection Options
@table @option
@item select_region
Specify whether to select the grabbing area graphically using the pointer.
A value of @code{1} prompts the user to select the grabbing area graphically
by clicking and dragging. A single click with no dragging will select the
whole screen. A region with zero width or height will also select the whole
screen. This option overwrites the @var{video_size}, @var{grab_x}, and
@var{grab_y} options. Default value is @code{0}.
@item draw_mouse
Specify whether to draw the mouse pointer. A value of @code{0} specifies
not to draw the pointer. Default value is @code{1}.
@ -1523,8 +1584,21 @@ With @var{follow_mouse}:
ffmpeg -f x11grab -follow_mouse centered -show_region 1 -framerate 25 -video_size cif -i :0.0 out.mpg
@end example
@item window_id
Grab this window, instead of the whole screen. Default value is 0, which maps to
the whole screen (root window).
The id of a window can be found using the @command{xwininfo} program, possibly with options -tree and
-root.
If the window is later enlarged, the new area is not recorded. Video ends when
the window is closed, unmapped (i.e., iconified) or shrunk beyond the video
size (which defaults to the initial window size).
This option disables options @option{follow_mouse} and @option{select_region}.
@item video_size
Set the video frame size. Default value is @code{vga}.
Set the video frame size. Default is the full desktop or window.
@item grab_x
@item grab_y

View File

@ -116,7 +116,7 @@ or is abusive towards others).
@section How long does it take for my message in the moderation queue to be approved?
The queue is not checked on a regular basis. You can ask on the
@t{#ffmpeg-devel} IRC channel on Freenode for someone to approve your message.
@t{#ffmpeg-devel} IRC channel on Libera Chat for someone to approve your message.
@anchor{How do I delete my message in the moderation queue?}
@section How do I delete my message in the moderation queue?
@ -155,7 +155,7 @@ Perform a site search using your favorite search engine. Example:
@section Is there an alternative to the mailing list?
You can ask for help in the official @t{#ffmpeg} IRC channel on Freenode.
You can ask for help in the official @t{#ffmpeg} IRC channel on Libera Chat.
Some users prefer the third-party @url{http://www.ffmpeg-archive.org/, Nabble}
interface which presents the mailing lists in a typical forum layout.

View File

@ -20,8 +20,7 @@ Slice threading -
Frame threading -
* Restrictions with slice threading also apply.
* For best performance, the client should set thread_safe_callbacks if it
provides a thread-safe get_buffer() callback.
* Custom get_buffer2() and get_format() callbacks must be thread-safe.
* There is one frame of delay added for every thread beyond the first one.
Clients must be able to handle this; the pkt_dts and pkt_pts fields in
AVFrame will work as usual.
@ -51,16 +50,14 @@ the decode process starts. Call ff_thread_finish_setup() afterwards. If
some code can't be moved, have update_thread_context() run it in the next
thread.
If the codec allocates writable tables in its init(), add an init_thread_copy()
which re-allocates them for other threads.
Add AV_CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very little
speed gain at this point but it should work.
If there are inter-frame dependencies, so the codec calls
ff_thread_report/await_progress(), set AVCodecInternal.allocate_progress. The
ff_thread_report/await_progress(), set FF_CODEC_CAP_ALLOCATE_PROGRESS in
AVCodec.caps_internal and use ff_thread_get_buffer() to allocate frames. The
frames must then be freed with ff_thread_release_buffer().
Otherwise leave it at zero and decode directly into the user-supplied frames.
Otherwise decode directly into the user-supplied frames.
Call ff_thread_report_progress() after some part of the current picture has decoded.
A good place to put this is where draw_horiz_band() is called - add this if it isn't

File diff suppressed because it is too large Load Diff

View File

@ -38,6 +38,52 @@ ffmpeg -i INPUT -f alsa hw:1,7
@end example
@end itemize
@section AudioToolbox
AudioToolbox output device.
Allows native output to CoreAudio devices on OSX.
The output filename can be empty (or @code{-}) to refer to the default system output device or a number that refers to the device index as shown using: @code{-list_devices true}.
Alternatively, the audio input device can be chosen by index using the
@option{
-audio_device_index <INDEX>
}
, overriding any device name or index given in the input filename.
All available devices can be enumerated by using @option{-list_devices true}, listing
all device names, UIDs and corresponding indices.
@subsection Options
AudioToolbox supports the following options:
@table @option
@item -audio_device_index <INDEX>
Specify the audio device by its index. Overrides anything given in the output filename.
@end table
@subsection Examples
@itemize
@item
Print the list of supported devices and output a sine wave to the default device:
@example
$ ffmpeg -f lavfi -i sine=r=44100 -f audiotoolbox -list_devices true -
@end example
@item
Output a sine wave to the device with the index 2, overriding any output filename:
@example
$ ffmpeg -f lavfi -i sine=r=44100 -f audiotoolbox -audio_device_index 2 -
@end example
@end itemize
@section caca
CACA output device.
@ -140,8 +186,8 @@ device with @command{-list_formats 1}. Audio sample rate is always 48 kHz.
@item list_devices
If set to @option{true}, print a list of devices and exit.
Defaults to @option{false}. Alternatively you can use the @code{-sinks}
option of ffmpeg to list the available output devices.
Defaults to @option{false}. This option is deprecated, please use the
@code{-sinks} option of ffmpeg to list the available output devices.
@item list_formats
If set to @option{true}, print a list of supported formats and exit.
@ -152,13 +198,43 @@ Amount of time to preroll video in seconds.
Defaults to @option{0.5}.
@item duplex_mode
Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.
Sets the decklink device duplex/profile mode. Must be @samp{unset}, @samp{half}, @samp{full},
@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
@samp{four_sub_device_half}
Defaults to @samp{unset}.
Note: DeckLink SDK 11.0 have replaced the duplex property by a profile property.
For the DeckLink Duo 2 and DeckLink Quad 2, a profile is shared between any 2
sub-devices that utilize the same connectors. For the DeckLink 8K Pro, a profile
is shared between all 4 sub-devices. So DeckLink 8K Pro support four profiles.
Valid profile modes for DeckLink 8K Pro(with DeckLink SDK >= 11.0):
@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
@samp{four_sub_device_half}
Valid profile modes for DeckLink Quad 2 and DeckLink Duo 2:
@samp{half}, @samp{full}
@item timing_offset
Sets the genlock timing pixel offset on the used output.
Defaults to @samp{unset}.
@item link
Sets the SDI video link configuration on the used output. Must be
@samp{unset}, @samp{single} link SDI, @samp{dual} link SDI or @samp{quad} link
SDI.
Defaults to @samp{unset}.
@item sqd
Enable Square Division Quad Split mode for Quad-link SDI output.
Must be @samp{unset}, @samp{true} or @samp{false}.
Defaults to @option{unset}.
@item level_a
Enable SMPTE Level A mode on the used output.
Must be @samp{unset}, @samp{true} or @samp{false}.
Defaults to @option{unset}.
@end table
@subsection Examples
@ -168,7 +244,7 @@ Defaults to @samp{unset}.
@item
List output devices:
@example
ffmpeg -i test.avi -f decklink -list_devices 1 dummy
ffmpeg -sinks decklink
@end example
@item
@ -329,6 +405,8 @@ ffmpeg -i INPUT -f pulse "stream name"
SDL (Simple DirectMedia Layer) output device.
"sdl2" can be used as alias for "sdl".
This output device allows one to show a video stream in an SDL
window. Only one SDL window is allowed per application, so you can
have only one instance of this output device in an application.

View File

@ -51,6 +51,82 @@ in microseconds.
A description of the currently available protocols follows.
@section amqp
Advanced Message Queueing Protocol (AMQP) version 0-9-1 is a broker based
publish-subscribe communication protocol.
FFmpeg must be compiled with --enable-librabbitmq to support AMQP. A separate
AMQP broker must also be run. An example open-source AMQP broker is RabbitMQ.
After starting the broker, an FFmpeg client may stream data to the broker using
the command:
@example
ffmpeg -re -i input -f mpegts amqp://[[user]:[password]@@]hostname[:port][/vhost]
@end example
Where hostname and port (default is 5672) is the address of the broker. The
client may also set a user/password for authentication. The default for both
fields is "guest". Name of virtual host on broker can be set with vhost. The
default value is "/".
Muliple subscribers may stream from the broker using the command:
@example
ffplay amqp://[[user]:[password]@@]hostname[:port][/vhost]
@end example
In RabbitMQ all data published to the broker flows through a specific exchange,
and each subscribing client has an assigned queue/buffer. When a packet arrives
at an exchange, it may be copied to a client's queue depending on the exchange
and routing_key fields.
The following options are supported:
@table @option
@item exchange
Sets the exchange to use on the broker. RabbitMQ has several predefined
exchanges: "amq.direct" is the default exchange, where the publisher and
subscriber must have a matching routing_key; "amq.fanout" is the same as a
broadcast operation (i.e. the data is forwarded to all queues on the fanout
exchange independent of the routing_key); and "amq.topic" is similar to
"amq.direct", but allows for more complex pattern matching (refer to the RabbitMQ
documentation).
@item routing_key
Sets the routing key. The default value is "amqp". The routing key is used on
the "amq.direct" and "amq.topic" exchanges to decide whether packets are written
to the queue of a subscriber.
@item pkt_size
Maximum size of each packet sent/received to the broker. Default is 131072.
Minimum is 4096 and max is any large value (representable by an int). When
receiving packets, this sets an internal buffer size in FFmpeg. It should be
equal to or greater than the size of the published packets to the broker. Otherwise
the received message may be truncated causing decoding errors.
@item connection_timeout
The timeout in seconds during the initial connection to the broker. The
default value is rw_timeout, or 5 seconds if rw_timeout is not set.
@item delivery_mode @var{mode}
Sets the delivery mode of each message sent to broker.
The following values are accepted:
@table @samp
@item persistent
Delivery mode set to "persistent" (2). This is the default value.
Messages may be written to the broker's disk depending on its setup.
@item non-persistent
Delivery mode set to "non-persistent" (1).
Messages will stay in broker's memory unless the broker is under memory
pressure.
@end table
@end table
@section async
Asynchronous data filling wrapper for input stream.
@ -99,6 +175,16 @@ Caching wrapper for input stream.
Cache the input stream to temporary file. It brings seeking capability to live streams.
The accepted options are:
@table @option
@item read_ahead_limit
Amount in bytes that may be read ahead when seeking isn't supported. Range is -1 to INT_MAX.
-1 for unlimited. Default is 65536.
@end table
URL Syntax is
@example
cache:@var{URL}
@end example
@ -129,6 +215,38 @@ ffplay concat:split1.mpeg\|split2.mpeg\|split3.mpeg
Note that you may need to escape the character "|" which is special for
many shells.
@section concatf
Physical concatenation protocol using a line break delimited list of
resources.
Read and seek from many resources in sequence as if they were
a unique resource.
A URL accepted by this protocol has the syntax:
@example
concatf:@var{URL}
@end example
where @var{URL} is the url containing a line break delimited list of
resources to be concatenated, each one possibly specifying a distinct
protocol. Special characters must be escaped with backslash or single
quotes. See @ref{quoting_and_escaping,,the "Quoting and escaping"
section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
For example to read a sequence of files @file{split1.mpeg},
@file{split2.mpeg}, @file{split3.mpeg} listed in separate lines within
a file @file{split.txt} with @command{ffplay} use the command:
@example
ffplay concatf:split.txt
@end example
Where @file{split.txt} contains the lines:
@example
split1.mpeg
split2.mpeg
split3.mpeg
@end example
@section crypto
AES-encrypted stream reading protocol.
@ -228,6 +346,14 @@ Set timeout in microseconds of socket I/O operations used by the underlying low
operation. By default it is set to -1, which means that the timeout is
not specified.
@item ftp-user
Set a user to be used for authenticating to the FTP server. This is overridden by the
user in the FTP URL.
@item ftp-password
Set a password to be used for authenticating to the FTP server. This is overridden by
the password in the FTP URL, or by @option{ftp-anonymous-password} if no user is set.
@item ftp-anonymous-password
Password used when login as anonymous user. Typically an e-mail address
should be used.
@ -247,6 +373,12 @@ operation. ff* tools may produce incomplete content due to server limitations.
Gopher protocol.
@section gophers
Gophers protocol.
The Gopher protocol with TLS encapsulation.
@section hls
Read Apple HTTP Live Streaming compliant segmented stream as
@ -306,14 +438,6 @@ Set the Referer header. Include 'Referer: URL' header in HTTP request.
Override the User-Agent header. If not specified the protocol will use a
string describing the libavformat build. ("Lavf/<version>")
@item user-agent
This is a deprecated option, you can use user_agent instead it.
@item timeout
Set timeout in microseconds of socket I/O operations used by the underlying low level
operation. By default it is set to -1, which means that the timeout is
not specified.
@item reconnect_at_eof
If set then eof is treated like an error and causes reconnection, this is useful
for live / endless streams.
@ -321,6 +445,13 @@ for live / endless streams.
@item reconnect_streamed
If set then even streamed/non seekable streams will be reconnected on errors.
@item reconnect_on_network_error
Reconnect automatically in case of TCP/TLS errors during connect.
@item reconnect_on_http_error
A comma separated list of HTTP status codes to reconnect on. The list can
include specific status codes (e.g. '503') or the strings '4xx' / '5xx'.
@item reconnect_delay_max
Sets the maximum delay in seconds after which to give up reconnecting
@ -398,6 +529,28 @@ Send an Expect: 100-continue header for POST. If set to 1 it will send, if set
to 0 it won't, if set to -1 it will try to send if it is applicable. Default
value is -1.
@item auth_type
Set HTTP authentication type. No option for Digest, since this method requires
getting nonce parameters from the server first and can't be used straight away like
Basic.
@table @option
@item none
Choose the HTTP authentication type automatically. This is the default.
@item basic
Choose the HTTP basic authentication.
Basic authentication sends a Base64-encoded string that contains a user name and password
for the client. Base64 is not a form of encryption and should be considered the same as
sending the user name and password in clear text (Base64 is a reversible encoding).
If a resource needs to be protected, strongly consider using an authentication scheme
other than basic authentication. HTTPS/TLS should be used with basic authentication.
Without these additional security enhancements, basic authentication should not be used
to protect sensitive or valuable information.
@end table
@end table
@subsection HTTP Cookies
@ -452,12 +605,47 @@ audio/mpeg.
This enables support for Icecast versions < 2.4.0, that do not support the
HTTP PUT method but the SOURCE method.
@item tls
Establish a TLS (HTTPS) connection to Icecast.
@end table
@example
icecast://[@var{username}[:@var{password}]@@]@var{server}:@var{port}/@var{mountpoint}
@end example
@section ipfs
InterPlanetary File System (IPFS) protocol support. One can access files stored
on the IPFS network through so-called gateways. These are http(s) endpoints.
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
@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. 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://QmbGtJg23skhvFmu9mJiePVByhfzu5rwo74MEkVDYAmF5T
@end example
Or the IPNS protocol (IPNS is mutable IPFS):
@example
ffplay ipns://QmbGtJg23skhvFmu9mJiePVByhfzu5rwo74MEkVDYAmF5T
@end example
@section mmst
MMS (Microsoft Media Server) protocol over TCP.
@ -569,6 +757,50 @@ Example usage:
-f rtp_mpegts -fec prompeg=l=8:d=4 rtp://@var{hostname}:@var{port}
@end example
@section rist
Reliable Internet Streaming Transport protocol
The accepted options are:
@table @option
@item rist_profile
Supported values:
@table @samp
@item simple
@item main
This one is default.
@item advanced
@end table
@item buffer_size
Set internal RIST buffer size in milliseconds for retransmission of data.
Default value is 0 which means the librist default (1 sec). Maximum value is 30
seconds.
@item fifo_size
Size of the librist receiver output fifo in number of packets. This must be a
power of 2.
Defaults to 8192 (vs the librist default of 1024).
@item overrun_nonfatal=@var{1|0}
Survive in case of librist fifo buffer overrun. Default value is 0.
@item pkt_size
Set maximum packet size for sending data. 1316 by default.
@item log_level
Set loglevel for RIST logging messages. You only need to set this if you
explicitly want to enable debug level messages or packet loss simulation,
otherwise the regular loglevel is respected.
@item secret
Set override of encryption secret, by default is unset.
@item encryption
Set encryption type, by default is disabled.
Acceptable values are 128 and 256.
@end table
@section rtmp
Real-Time Messaging Protocol.
@ -683,6 +915,11 @@ URL to player swf file, compute hash/size automatically.
@item rtmp_tcurl
URL of the target stream. Defaults to proto://host[:port]/app.
@item tcp_nodelay=@var{1|0}
Set TCP_NODELAY to disable Nagle's algorithm. Default value is 0.
@emph{Remark: Writing to the socket is currently not optimized to minimize system calls and reduces the efficiency / effect of TCP_NODELAY.}
@end table
For example to read with @command{ffplay} a multimedia resource named
@ -870,6 +1107,9 @@ Set the local RTCP port to @var{n}.
@item pkt_size=@var{n}
Set max packet size (in bytes) to @var{n}.
@item buffer_size=@var{size}
Set the maximum UDP socket buffer size in bytes.
@item connect=0|1
Do a @code{connect()} on the UDP socket (if set to 1) or not (if set
to 0).
@ -887,6 +1127,13 @@ set to 1) or to a default remote address (if set to 0).
@item localport=@var{n}
Set the local RTP port to @var{n}.
@item localaddr=@var{addr}
Local IP address of a network interface used for sending packets or joining
multicast groups.
@item timeout=@var{n}
Set timeout (in microseconds) of socket I/O operations to @var{n}.
This is a deprecated option. Instead, @option{localrtpport} should be
used.
@ -995,19 +1242,18 @@ Set minimum local UDP port. Default value is 5000.
@item max_port
Set maximum local UDP port. Default value is 65000.
@item timeout
Set maximum timeout (in seconds) to wait for incoming connections.
A value of -1 means infinite (default). This option implies the
@option{rtsp_flags} set to @samp{listen}.
@item listen_timeout
Set maximum timeout (in seconds) to establish an initial connection. Setting
@option{listen_timeout} > 0 sets @option{rtsp_flags} to @samp{listen}. Default is -1
which means an infinite timeout when @samp{listen} mode is set.
@item reorder_queue_size
Set number of packets to buffer for handling of reordered packets.
@item stimeout
@item timeout
Set socket TCP I/O timeout in microseconds.
@item user-agent
@item user_agent
Override User-Agent header. If not specified, it defaults to the
libavformat identifier string.
@end table
@ -1187,7 +1433,7 @@ options.
This protocol accepts the following options.
@table @option
@item connect_timeout
@item connect_timeout=@var{milliseconds}
Connection timeout; SRT cannot connect for RTT > 1500 msec
(2 handshake exchanges) with the default connect timeout of
3 seconds. This option applies to the caller and rendezvous
@ -1218,7 +1464,7 @@ IP Type of Service. Applies to sender only. Default value is 0xB8.
@item ipttl=@var{ttl}
IP Time To Live. Applies to sender only. Default value is 64.
@item latency
@item latency=@var{microseconds}
Timestamp-based Packet Delivery Delay.
Used to absorb bursts of missed packet retransmissions.
This flag sets both @option{rcvlatency} and @option{peerlatency}
@ -1229,7 +1475,7 @@ when side is sender and @option{rcvlatency}
when side is receiver, and the bidirectional stream
sending is not supported.
@item listen_timeout
@item listen_timeout=@var{microseconds}
Set socket listen timeout.
@item maxbw=@var{bytes/seconds}
@ -1274,6 +1520,32 @@ only if @option{pbkeylen} is non-zero. It is used on
the receiver only if the received data is encrypted.
The configured passphrase cannot be recovered (write-only).
@item enforced_encryption=@var{1|0}
If true, both connection parties must have the same password
set (including empty, that is, with no encryption). If the
password doesn't match or only one side is unencrypted,
the connection is rejected. Default is true.
@item kmrefreshrate=@var{packets}
The number of packets to be transmitted after which the
encryption key is switched to a new key. Default is -1.
-1 means auto (0x1000000 in srt library). The range for
this option is integers in the 0 - @code{INT_MAX}.
@item kmpreannounce=@var{packets}
The interval between when a new encryption key is sent and
when switchover occurs. This value also applies to the
subsequent interval between when switchover occurs and
when the old encryption key is decommissioned. Default is -1.
-1 means auto (0x1000 in srt library). The range for
this option is integers in the 0 - @code{INT_MAX}.
@item snddropdelay=@var{microseconds}
The sender's extra delay before dropping packets. This delay is
added to the default drop delay time interval value.
Special value -1: Do not drop packets on the sender at all.
@item payload_size=@var{bytes}
Sets the maximum declared size of a packet transferred
during the single call to the sending function in Live
@ -1289,7 +1561,7 @@ use a bigger maximum frame size, though not greater than
@item pkt_size=@var{bytes}
Alias for @samp{payload_size}.
@item peerlatency
@item peerlatency=@var{microseconds}
The latency value (as described in @option{rcvlatency}) that is
set by the sender side as a minimum value for the receiver.
@ -1301,7 +1573,7 @@ Not required on receiver (set to 0),
key size obtained from sender in HaiCrypt handshake.
Default value is 0.
@item rcvlatency
@item rcvlatency=@var{microseconds}
The time that should elapse since the moment when the
packet was sent and the moment when it's delivered to
the receiver application in the receiving function.
@ -1319,12 +1591,10 @@ Set UDP receive buffer size, expressed in bytes.
@item send_buffer_size=@var{bytes}
Set UDP send buffer size, expressed in bytes.
@item rw_timeout
Set raise error timeout for read/write optations.
This option is only relevant in read mode:
if no data arrived in more than this time
interval, raise error.
@item timeout=@var{microseconds}
Set raise error timeouts for read, write and connect operations. Note that the
SRT library has internal timeouts which can be controlled separately, the
value set here is only a cap on those.
@item tlpktdrop=@var{1|0}
Too-late Packet Drop. When enabled on receiver, it skips
@ -1375,6 +1645,9 @@ This option doesnt make sense in Rendezvous connection; the result
might be that simply one side will override the value from the other
side and its the matter of luck which one would win
@item srt_streamid=@var{string}
Alias for @samp{streamid} to avoid conflict with ffmpeg command line option.
@item smoother=@var{live|file}
The type of Smoother used for the transmission for that socket, which
is responsible for the transmission and congestion control. The Smoother
@ -1418,6 +1691,17 @@ the overhead transmission (retransmitted and control packets).
file: Set options as for non-live transmission. See @option{messageapi}
for further explanations
@item linger=@var{seconds}
The number of seconds that the socket waits for unsent data when closing.
Default is -1. -1 means auto (off with 0 seconds in live mode, on with 180
seconds in file mode). The range for this option is integers in the
0 - @code{INT_MAX}.
@item tsbpd=@var{1|0}
When true, use Timestamp-based Packet Delivery mode. The default behavior
depends on the transmission type: enabled in live mode, disabled in file
mode.
@end table
For more information see: @url{https://github.com/Haivision/srt}.
@ -1504,8 +1788,9 @@ tcp://@var{hostname}:@var{port}[?@var{options}]
The list of supported options follows.
@table @option
@item listen=@var{1|0}
Listen for an incoming connection. Default value is 0.
@item listen=@var{2|1|0}
Listen for an incoming connection. 0 disables listen, 1 enables listen in
single client mode, 2 enables listen in multi-client mode. Default value is 0.
@item timeout=@var{microseconds}
Set raise error timeout, expressed in microseconds.
@ -1525,6 +1810,8 @@ Set send buffer size, expressed bytes.
@item tcp_nodelay=@var{1|0}
Set TCP_NODELAY to disable Nagle's algorithm. Default value is 0.
@emph{Remark: Writing to the socket is currently not optimized to minimize system calls and reduces the efficiency / effect of TCP_NODELAY.}
@item tcp_mss=@var{bytes}
Set maximum segment size for outgoing TCP packets, expressed in bytes.
@end table
@ -1581,6 +1868,10 @@ A file containing the private key for the certificate.
If enabled, listen for connections on the provided port, and assume
the server role in the handshake instead of the client role.
@item http_proxy
The HTTP proxy to tunnel through, e.g. @code{http://example.com:1234}.
The proxy must support the CONNECT method.
@end table
Example command lines:
@ -1619,7 +1910,7 @@ The list of supported options follows.
@item buffer_size=@var{size}
Set the UDP maximum socket buffer size in bytes. This is used to set either
the receive or send buffer size, depending on what the socket is used for.
Default is 64KB. See also @var{fifo_size}.
Default is 32 KB for output, 384 KB for input. See also @var{fifo_size}.
@item bitrate=@var{bitrate}
If set to nonzero, the output will have the specified constant bitrate if the
@ -1728,4 +2019,50 @@ Timeout in ms.
Create the Unix socket in listening mode.
@end table
@section zmq
ZeroMQ asynchronous messaging using the libzmq library.
This library supports unicast streaming to multiple clients without relying on
an external server.
The required syntax for streaming or connecting to a stream is:
@example
zmq:tcp://ip-address:port
@end example
Example:
Create a localhost stream on port 5555:
@example
ffmpeg -re -i input -f mpegts zmq:tcp://127.0.0.1:5555
@end example
Multiple clients may connect to the stream using:
@example
ffplay zmq:tcp://127.0.0.1:5555
@end example
Streaming to multiple clients is implemented using a ZeroMQ Pub-Sub pattern.
The server side binds to a port and publishes data. Clients connect to the
server (via IP address/port) and subscribe to the stream. The order in which
the server and client start generally does not matter.
ffmpeg must be compiled with the --enable-libzmq option to support
this protocol.
Options can be set on the @command{ffmpeg}/@command{ffplay} command
line. The following options are supported:
@table @option
@item pkt_size
Forces the maximum packet size for sending/receiving data. The default value is
131,072 bytes. On the server side, this sets the maximum size of sent packets
via ZeroMQ. On the clients, it sets an internal buffer size for receiving
packets. Note that pkt_size on the clients should be equal to or greater than
pkt_size on the server. Otherwise the received message may be truncated causing
decoding errors.
@end table
@c man end PROTOCOLS

View File

@ -126,8 +126,16 @@ 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
set_from_init_file('INLINE_CONTENTS', 1);
if ($program_version_6_8) {
set_from_init_file('CONTENTS_OUTPUT_LOCATION', 'inline');
} else {
set_from_init_file('INLINE_CONTENTS', 1);
}
# make chapters <h2>
set_from_init_file('CHAPTER_HEADER_LEVEL', 2);
@ -184,7 +192,11 @@ EOT
return $head1 . $head_title . $head2 . $head_title . $head3;
}
texinfo_register_formatting_function('begin_file', \&ffmpeg_begin_file);
if ($program_version_6_8) {
texinfo_register_formatting_function('format_begin_file', \&ffmpeg_begin_file);
} else {
texinfo_register_formatting_function('begin_file', \&ffmpeg_begin_file);
}
sub ffmpeg_program_string($)
{
@ -201,7 +213,11 @@ sub ffmpeg_program_string($)
$self->gdt('This document was generated automatically.'));
}
}
texinfo_register_formatting_function('program_string', \&ffmpeg_program_string);
if ($program_version_6_8) {
texinfo_register_formatting_function('format_program_string', \&ffmpeg_program_string);
} else {
texinfo_register_formatting_function('program_string', \&ffmpeg_program_string);
}
# Customized file ending
sub ffmpeg_end_file($)
@ -220,7 +236,11 @@ EOT
EOT
return $program_text . $footer;
}
texinfo_register_formatting_function('end_file', \&ffmpeg_end_file);
if ($program_version_6_8) {
texinfo_register_formatting_function('format_end_file', \&ffmpeg_end_file);
} else {
texinfo_register_formatting_function('end_file', \&ffmpeg_end_file);
}
# Dummy title command
# Ignore title. Title is handled through ffmpeg_begin_file().

View File

@ -172,6 +172,9 @@ INF: while(<$inf>) {
} elsif ($ended =~ /^(?:itemize|enumerate|(?:multi|[fv])?table)$/) {
$_ = "\n=back\n";
$ic = pop @icstack;
} elsif ($ended =~ /^float$/) {
$_ = "\n=back\n";
$ic = pop @icstack;
} else {
die "unknown command \@end $ended at line $.\n";
}
@ -297,6 +300,12 @@ INF: while(<$inf>) {
$_ = ""; # need a paragraph break
};
/^\@(float)\s+\w+/ and do {
push @endwstack, $endw;
$endw = $1;
$_ = "\n=over 4\n";
};
/^\@item\s+(.*\S)\s*$/ and $endw eq "multitable" and do {
my $columns = $1;
$columns =~ s/\@tab/ : /;

706
doc/transforms.md Normal file
View File

@ -0,0 +1,706 @@
The basis transforms used for FFT and various other derived functions are based
on the following unrollings.
The functions can be easily adapted to double precision floats as well.
# Parity permutation
The basis transforms described here all use the following permutation:
``` C
void ff_tx_gen_split_radix_parity_revtab(int *revtab, int len, int inv,
int basis, int dual_stride);
```
Parity means even and odd complex numbers will be split, e.g. the even
coefficients will come first, after which the odd coefficients will be
placed. For example, a 4-point transform's coefficients after reordering:
`z[0].re, z[0].im, z[2].re, z[2].im, z[1].re, z[1].im, z[3].re, z[3].im`
The basis argument is the length of the largest non-composite transform
supported, and also implies that the basis/2 transform is supported as well,
as the split-radix algorithm requires it to be.
The dual_stride argument indicates that both the basis, as well as the
basis/2 transforms support doing two transforms at once, and the coefficients
will be interleaved between each pair in a split-radix like so (stride == 2):
`tx1[0], tx1[2], tx2[0], tx2[2], tx1[1], tx1[3], tx2[1], tx2[3]`
A non-zero number switches this on, with the value indicating the stride
(how many values of 1 transform to put first before switching to the other).
Must be a power of two or 0. Must be less than the basis.
Value will be clipped to the transform size, so for a basis of 16 and a
dual_stride of 8, dual 8-point transforms will be laid out as if dual_stride
was set to 4.
Usually you'll set this to half the complex numbers that fit in a single
register or 0. This allows to reuse SSE functions as dual-transform
functions in AVX mode.
If length is smaller than basis/2 this function will not do anything.
# 4-point FFT transform
The only permutation this transform needs is to swap the `z[1]` and `z[2]`
elements when performing an inverse transform, which in the assembly code is
hardcoded with the function itself being templated and duplicated for each
direction.
``` C
static void fft4(FFTComplex *z)
{
FFTSample r1 = z[0].re - z[2].re;
FFTSample r2 = z[0].im - z[2].im;
FFTSample r3 = z[1].re - z[3].re;
FFTSample r4 = z[1].im - z[3].im;
/* r5-r8 second transform */
FFTSample t1 = z[0].re + z[2].re;
FFTSample t2 = z[0].im + z[2].im;
FFTSample t3 = z[1].re + z[3].re;
FFTSample t4 = z[1].im + z[3].im;
/* t5-t8 second transform */
/* 1sub + 1add = 2 instructions */
/* 2 shufs */
FFTSample a3 = t1 - t3;
FFTSample a4 = t2 - t4;
FFTSample b3 = r1 - r4;
FFTSample b2 = r2 - r3;
FFTSample a1 = t1 + t3;
FFTSample a2 = t2 + t4;
FFTSample b1 = r1 + r4;
FFTSample b4 = r2 + r3;
/* 1 add 1 sub 3 shufs */
z[0].re = a1;
z[0].im = a2;
z[2].re = a3;
z[2].im = a4;
z[1].re = b1;
z[1].im = b2;
z[3].re = b3;
z[3].im = b4;
}
```
# 8-point AVX FFT transform
Input must be pre-permuted using the parity lookup table, generated via
`ff_tx_gen_split_radix_parity_revtab`.
``` C
static void fft8(FFTComplex *z)
{
FFTSample r1 = z[0].re - z[4].re;
FFTSample r2 = z[0].im - z[4].im;
FFTSample r3 = z[1].re - z[5].re;
FFTSample r4 = z[1].im - z[5].im;
FFTSample r5 = z[2].re - z[6].re;
FFTSample r6 = z[2].im - z[6].im;
FFTSample r7 = z[3].re - z[7].re;
FFTSample r8 = z[3].im - z[7].im;
FFTSample q1 = z[0].re + z[4].re;
FFTSample q2 = z[0].im + z[4].im;
FFTSample q3 = z[1].re + z[5].re;
FFTSample q4 = z[1].im + z[5].im;
FFTSample q5 = z[2].re + z[6].re;
FFTSample q6 = z[2].im + z[6].im;
FFTSample q7 = z[3].re + z[7].re;
FFTSample q8 = z[3].im + z[7].im;
FFTSample s3 = q1 - q3;
FFTSample s1 = q1 + q3;
FFTSample s4 = q2 - q4;
FFTSample s2 = q2 + q4;
FFTSample s7 = q5 - q7;
FFTSample s5 = q5 + q7;
FFTSample s8 = q6 - q8;
FFTSample s6 = q6 + q8;
FFTSample e1 = s1 * -1;
FFTSample e2 = s2 * -1;
FFTSample e3 = s3 * -1;
FFTSample e4 = s4 * -1;
FFTSample e5 = s5 * 1;
FFTSample e6 = s6 * 1;
FFTSample e7 = s7 * -1;
FFTSample e8 = s8 * 1;
FFTSample w1 = e5 - e1;
FFTSample w2 = e6 - e2;
FFTSample w3 = e8 - e3;
FFTSample w4 = e7 - e4;
FFTSample w5 = s1 - e5;
FFTSample w6 = s2 - e6;
FFTSample w7 = s3 - e8;
FFTSample w8 = s4 - e7;
z[0].re = w1;
z[0].im = w2;
z[2].re = w3;
z[2].im = w4;
z[4].re = w5;
z[4].im = w6;
z[6].re = w7;
z[6].im = w8;
FFTSample z1 = r1 - r4;
FFTSample z2 = r1 + r4;
FFTSample z3 = r3 - r2;
FFTSample z4 = r3 + r2;
FFTSample z5 = r5 - r6;
FFTSample z6 = r5 + r6;
FFTSample z7 = r7 - r8;
FFTSample z8 = r7 + r8;
z3 *= -1;
z5 *= -M_SQRT1_2;
z6 *= -M_SQRT1_2;
z7 *= M_SQRT1_2;
z8 *= M_SQRT1_2;
FFTSample t5 = z7 - z6;
FFTSample t6 = z8 + z5;
FFTSample t7 = z8 - z5;
FFTSample t8 = z7 + z6;
FFTSample u1 = z2 + t5;
FFTSample u2 = z3 + t6;
FFTSample u3 = z1 - t7;
FFTSample u4 = z4 + t8;
FFTSample u5 = z2 - t5;
FFTSample u6 = z3 - t6;
FFTSample u7 = z1 + t7;
FFTSample u8 = z4 - t8;
z[1].re = u1;
z[1].im = u2;
z[3].re = u3;
z[3].im = u4;
z[5].re = u5;
z[5].im = u6;
z[7].re = u7;
z[7].im = u8;
}
```
As you can see, there are 2 independent paths, one for even and one for odd coefficients.
This theme continues throughout the document. Note that in the actual assembly code,
the paths are interleaved to improve unit saturation and CPU dependency tracking, so
to more clearly see them, you'll need to deinterleave the instructions.
# 8-point SSE/ARM64 FFT transform
Input must be pre-permuted using the parity lookup table, generated via
`ff_tx_gen_split_radix_parity_revtab`.
``` C
static void fft8(FFTComplex *z)
{
FFTSample r1 = z[0].re - z[4].re;
FFTSample r2 = z[0].im - z[4].im;
FFTSample r3 = z[1].re - z[5].re;
FFTSample r4 = z[1].im - z[5].im;
FFTSample j1 = z[2].re - z[6].re;
FFTSample j2 = z[2].im - z[6].im;
FFTSample j3 = z[3].re - z[7].re;
FFTSample j4 = z[3].im - z[7].im;
FFTSample q1 = z[0].re + z[4].re;
FFTSample q2 = z[0].im + z[4].im;
FFTSample q3 = z[1].re + z[5].re;
FFTSample q4 = z[1].im + z[5].im;
FFTSample k1 = z[2].re + z[6].re;
FFTSample k2 = z[2].im + z[6].im;
FFTSample k3 = z[3].re + z[7].re;
FFTSample k4 = z[3].im + z[7].im;
/* 2 add 2 sub = 4 */
/* 2 shufs, 1 add 1 sub = 4 */
FFTSample s1 = q1 + q3;
FFTSample s2 = q2 + q4;
FFTSample g1 = k3 + k1;
FFTSample g2 = k2 + k4;
FFTSample s3 = q1 - q3;
FFTSample s4 = q2 - q4;
FFTSample g4 = k3 - k1;
FFTSample g3 = k2 - k4;
/* 1 unpack + 1 shuffle = 2 */
/* 1 add */
FFTSample w1 = s1 + g1;
FFTSample w2 = s2 + g2;
FFTSample w3 = s3 + g3;
FFTSample w4 = s4 + g4;
/* 1 sub */
FFTSample h1 = s1 - g1;
FFTSample h2 = s2 - g2;
FFTSample h3 = s3 - g3;
FFTSample h4 = s4 - g4;
z[0].re = w1;
z[0].im = w2;
z[2].re = w3;
z[2].im = w4;
z[4].re = h1;
z[4].im = h2;
z[6].re = h3;
z[6].im = h4;
/* 1 shuf + 1 shuf + 1 xor + 1 addsub */
FFTSample z1 = r1 + r4;
FFTSample z2 = r2 - r3;
FFTSample z3 = r1 - r4;
FFTSample z4 = r2 + r3;
/* 1 mult */
j1 *= M_SQRT1_2;
j2 *= -M_SQRT1_2;
j3 *= -M_SQRT1_2;
j4 *= M_SQRT1_2;
/* 1 shuf + 1 addsub */
FFTSample l2 = j1 - j2;
FFTSample l1 = j2 + j1;
FFTSample l4 = j3 - j4;
FFTSample l3 = j4 + j3;
/* 1 shuf + 1 addsub */
FFTSample t1 = l3 - l2;
FFTSample t2 = l4 + l1;
FFTSample t3 = l1 - l4;
FFTSample t4 = l2 + l3;
/* 1 add */
FFTSample u1 = z1 - t1;
FFTSample u2 = z2 - t2;
FFTSample u3 = z3 - t3;
FFTSample u4 = z4 - t4;
/* 1 sub */
FFTSample o1 = z1 + t1;
FFTSample o2 = z2 + t2;
FFTSample o3 = z3 + t3;
FFTSample o4 = z4 + t4;
z[1].re = u1;
z[1].im = u2;
z[3].re = u3;
z[3].im = u4;
z[5].re = o1;
z[5].im = o2;
z[7].re = o3;
z[7].im = o4;
}
```
Most functions here are highly tuned to use x86's addsub instruction to save on
external sign mask loading.
# 16-point AVX FFT transform
This version expects the output of the 8 and 4-point transforms to follow the
even/odd convention established above.
``` C
static void fft16(FFTComplex *z)
{
FFTSample cos_16_1 = 0.92387950420379638671875f;
FFTSample cos_16_3 = 0.3826834261417388916015625f;
fft8(z);
fft4(z+8);
fft4(z+10);
FFTSample s[32];
/*
xorps m1, m1 - free
mulps m0
shufps m1, m1, m0
xorps
addsub
shufps
mulps
mulps
addps
or (fma3)
shufps
shufps
mulps
mulps
fma
fma
*/
s[0] = z[8].re*( 1) - z[8].im*( 0);
s[1] = z[8].im*( 1) + z[8].re*( 0);
s[2] = z[9].re*( 1) - z[9].im*(-1);
s[3] = z[9].im*( 1) + z[9].re*(-1);
s[4] = z[10].re*( 1) - z[10].im*( 0);
s[5] = z[10].im*( 1) + z[10].re*( 0);
s[6] = z[11].re*( 1) - z[11].im*( 1);
s[7] = z[11].im*( 1) + z[11].re*( 1);
s[8] = z[12].re*( cos_16_1) - z[12].im*( -cos_16_3);
s[9] = z[12].im*( cos_16_1) + z[12].re*( -cos_16_3);
s[10] = z[13].re*( cos_16_3) - z[13].im*( -cos_16_1);
s[11] = z[13].im*( cos_16_3) + z[13].re*( -cos_16_1);
s[12] = z[14].re*( cos_16_1) - z[14].im*( cos_16_3);
s[13] = z[14].im*( -cos_16_1) + z[14].re*( -cos_16_3);
s[14] = z[15].re*( cos_16_3) - z[15].im*( cos_16_1);
s[15] = z[15].im*( -cos_16_3) + z[15].re*( -cos_16_1);
s[2] *= M_SQRT1_2;
s[3] *= M_SQRT1_2;
s[5] *= -1;
s[6] *= M_SQRT1_2;
s[7] *= -M_SQRT1_2;
FFTSample w5 = s[0] + s[4];
FFTSample w6 = s[1] - s[5];
FFTSample x5 = s[2] + s[6];
FFTSample x6 = s[3] - s[7];
FFTSample w3 = s[4] - s[0];
FFTSample w4 = s[5] + s[1];
FFTSample x3 = s[6] - s[2];
FFTSample x4 = s[7] + s[3];
FFTSample y5 = s[8] + s[12];
FFTSample y6 = s[9] - s[13];
FFTSample u5 = s[10] + s[14];
FFTSample u6 = s[11] - s[15];
FFTSample y3 = s[12] - s[8];
FFTSample y4 = s[13] + s[9];
FFTSample u3 = s[14] - s[10];
FFTSample u4 = s[15] + s[11];
/* 2xorps, 2vperm2fs, 2 adds, 2 vpermilps = 8 */
FFTSample o1 = z[0].re + w5;
FFTSample o2 = z[0].im + w6;
FFTSample o5 = z[1].re + x5;
FFTSample o6 = z[1].im + x6;
FFTSample o9 = z[2].re + w4; //h
FFTSample o10 = z[2].im + w3;
FFTSample o13 = z[3].re + x4;
FFTSample o14 = z[3].im + x3;
FFTSample o17 = z[0].re - w5;
FFTSample o18 = z[0].im - w6;
FFTSample o21 = z[1].re - x5;
FFTSample o22 = z[1].im - x6;
FFTSample o25 = z[2].re - w4; //h
FFTSample o26 = z[2].im - w3;
FFTSample o29 = z[3].re - x4;
FFTSample o30 = z[3].im - x3;
FFTSample o3 = z[4].re + y5;
FFTSample o4 = z[4].im + y6;
FFTSample o7 = z[5].re + u5;
FFTSample o8 = z[5].im + u6;
FFTSample o11 = z[6].re + y4; //h
FFTSample o12 = z[6].im + y3;
FFTSample o15 = z[7].re + u4;
FFTSample o16 = z[7].im + u3;
FFTSample o19 = z[4].re - y5;
FFTSample o20 = z[4].im - y6;
FFTSample o23 = z[5].re - u5;
FFTSample o24 = z[5].im - u6;
FFTSample o27 = z[6].re - y4; //h
FFTSample o28 = z[6].im - y3;
FFTSample o31 = z[7].re - u4;
FFTSample o32 = z[7].im - u3;
/* This is just deinterleaving, happens separately */
z[0] = (FFTComplex){ o1, o2 };
z[1] = (FFTComplex){ o3, o4 };
z[2] = (FFTComplex){ o5, o6 };
z[3] = (FFTComplex){ o7, o8 };
z[4] = (FFTComplex){ o9, o10 };
z[5] = (FFTComplex){ o11, o12 };
z[6] = (FFTComplex){ o13, o14 };
z[7] = (FFTComplex){ o15, o16 };
z[8] = (FFTComplex){ o17, o18 };
z[9] = (FFTComplex){ o19, o20 };
z[10] = (FFTComplex){ o21, o22 };
z[11] = (FFTComplex){ o23, o24 };
z[12] = (FFTComplex){ o25, o26 };
z[13] = (FFTComplex){ o27, o28 };
z[14] = (FFTComplex){ o29, o30 };
z[15] = (FFTComplex){ o31, o32 };
}
```
# AVX split-radix synthesis
To create larger transforms, the following unrolling of the C split-radix
function is used.
``` C
#define BF(x, y, a, b) \
do { \
x = (a) - (b); \
y = (a) + (b); \
} while (0)
#define BUTTERFLIES(a0,a1,a2,a3) \
do { \
r0=a0.re; \
i0=a0.im; \
r1=a1.re; \
i1=a1.im; \
BF(q3, q5, q5, q1); \
BF(a2.re, a0.re, r0, q5); \
BF(a3.im, a1.im, i1, q3); \
BF(q4, q6, q2, q6); \
BF(a3.re, a1.re, r1, q4); \
BF(a2.im, a0.im, i0, q6); \
} while (0)
#undef TRANSFORM
#define TRANSFORM(a0,a1,a2,a3,wre,wim) \
do { \
CMUL(q1, q2, a2.re, a2.im, wre, -wim); \
CMUL(q5, q6, a3.re, a3.im, wre, wim); \
BUTTERFLIES(a0, a1, a2, a3); \
} while (0)
#define CMUL(dre, dim, are, aim, bre, bim) \
do { \
(dre) = (are) * (bre) - (aim) * (bim); \
(dim) = (are) * (bim) + (aim) * (bre); \
} while (0)
static void recombine(FFTComplex *z, const FFTSample *cos,
unsigned int n)
{
const int o1 = 2*n;
const int o2 = 4*n;
const int o3 = 6*n;
const FFTSample *wim = cos + o1 - 7;
FFTSample q1, q2, q3, q4, q5, q6, r0, i0, r1, i1;
#if 0
for (int i = 0; i < n; i += 4) {
#endif
#if 0
TRANSFORM(z[ 0 + 0], z[ 0 + 4], z[o2 + 0], z[o2 + 2], cos[0], wim[7]);
TRANSFORM(z[ 0 + 1], z[ 0 + 5], z[o2 + 1], z[o2 + 3], cos[2], wim[5]);
TRANSFORM(z[ 0 + 2], z[ 0 + 6], z[o2 + 4], z[o2 + 6], cos[4], wim[3]);
TRANSFORM(z[ 0 + 3], z[ 0 + 7], z[o2 + 5], z[o2 + 7], cos[6], wim[1]);
TRANSFORM(z[o1 + 0], z[o1 + 4], z[o3 + 0], z[o3 + 2], cos[1], wim[6]);
TRANSFORM(z[o1 + 1], z[o1 + 5], z[o3 + 1], z[o3 + 3], cos[3], wim[4]);
TRANSFORM(z[o1 + 2], z[o1 + 6], z[o3 + 4], z[o3 + 6], cos[5], wim[2]);
TRANSFORM(z[o1 + 3], z[o1 + 7], z[o3 + 5], z[o3 + 7], cos[7], wim[0]);
#else
FFTSample h[8], j[8], r[8], w[8];
FFTSample t[8];
FFTComplex *m0 = &z[0];
FFTComplex *m1 = &z[4];
FFTComplex *m2 = &z[o2 + 0];
FFTComplex *m3 = &z[o2 + 4];
const FFTSample *t1 = &cos[0];
const FFTSample *t2 = &wim[0];
/* 2 loads (tabs) */
/* 2 vperm2fs, 2 shufs (im), 2 shufs (tabs) */
/* 1 xor, 1 add, 1 sub, 4 mults OR 2 mults, 2 fmas */
/* 13 OR 10ish (-2 each for second passovers!) */
w[0] = m2[0].im*t1[0] - m2[0].re*t2[7];
w[1] = m2[0].re*t1[0] + m2[0].im*t2[7];
w[2] = m2[1].im*t1[2] - m2[1].re*t2[5];
w[3] = m2[1].re*t1[2] + m2[1].im*t2[5];
w[4] = m3[0].im*t1[4] - m3[0].re*t2[3];
w[5] = m3[0].re*t1[4] + m3[0].im*t2[3];
w[6] = m3[1].im*t1[6] - m3[1].re*t2[1];
w[7] = m3[1].re*t1[6] + m3[1].im*t2[1];
j[0] = m2[2].im*t1[0] + m2[2].re*t2[7];
j[1] = m2[2].re*t1[0] - m2[2].im*t2[7];
j[2] = m2[3].im*t1[2] + m2[3].re*t2[5];
j[3] = m2[3].re*t1[2] - m2[3].im*t2[5];
j[4] = m3[2].im*t1[4] + m3[2].re*t2[3];
j[5] = m3[2].re*t1[4] - m3[2].im*t2[3];
j[6] = m3[3].im*t1[6] + m3[3].re*t2[1];
j[7] = m3[3].re*t1[6] - m3[3].im*t2[1];
/* 1 add + 1 shuf */
t[1] = j[0] + w[0];
t[0] = j[1] + w[1];
t[3] = j[2] + w[2];
t[2] = j[3] + w[3];
t[5] = j[4] + w[4];
t[4] = j[5] + w[5];
t[7] = j[6] + w[6];
t[6] = j[7] + w[7];
/* 1 sub + 1 xor */
r[0] = (w[0] - j[0]);
r[1] = -(w[1] - j[1]);
r[2] = (w[2] - j[2]);
r[3] = -(w[3] - j[3]);
r[4] = (w[4] - j[4]);
r[5] = -(w[5] - j[5]);
r[6] = (w[6] - j[6]);
r[7] = -(w[7] - j[7]);
/* Min: 2 subs, 2 adds, 2 vperm2fs (OPTIONAL) */
m2[0].re = m0[0].re - t[0];
m2[0].im = m0[0].im - t[1];
m2[1].re = m0[1].re - t[2];
m2[1].im = m0[1].im - t[3];
m3[0].re = m0[2].re - t[4];
m3[0].im = m0[2].im - t[5];
m3[1].re = m0[3].re - t[6];
m3[1].im = m0[3].im - t[7];
m2[2].re = m1[0].re - r[0];
m2[2].im = m1[0].im - r[1];
m2[3].re = m1[1].re - r[2];
m2[3].im = m1[1].im - r[3];
m3[2].re = m1[2].re - r[4];
m3[2].im = m1[2].im - r[5];
m3[3].re = m1[3].re - r[6];
m3[3].im = m1[3].im - r[7];
m0[0].re = m0[0].re + t[0];
m0[0].im = m0[0].im + t[1];
m0[1].re = m0[1].re + t[2];
m0[1].im = m0[1].im + t[3];
m0[2].re = m0[2].re + t[4];
m0[2].im = m0[2].im + t[5];
m0[3].re = m0[3].re + t[6];
m0[3].im = m0[3].im + t[7];
m1[0].re = m1[0].re + r[0];
m1[0].im = m1[0].im + r[1];
m1[1].re = m1[1].re + r[2];
m1[1].im = m1[1].im + r[3];
m1[2].re = m1[2].re + r[4];
m1[2].im = m1[2].im + r[5];
m1[3].re = m1[3].re + r[6];
m1[3].im = m1[3].im + r[7];
/* Identical for below, but with the following parameters */
m0 = &z[o1];
m1 = &z[o1 + 4];
m2 = &z[o3 + 0];
m3 = &z[o3 + 4];
t1 = &cos[1];
t2 = &wim[-1];
w[0] = m2[0].im*t1[0] - m2[0].re*t2[7];
w[1] = m2[0].re*t1[0] + m2[0].im*t2[7];
w[2] = m2[1].im*t1[2] - m2[1].re*t2[5];
w[3] = m2[1].re*t1[2] + m2[1].im*t2[5];
w[4] = m3[0].im*t1[4] - m3[0].re*t2[3];
w[5] = m3[0].re*t1[4] + m3[0].im*t2[3];
w[6] = m3[1].im*t1[6] - m3[1].re*t2[1];
w[7] = m3[1].re*t1[6] + m3[1].im*t2[1];
j[0] = m2[2].im*t1[0] + m2[2].re*t2[7];
j[1] = m2[2].re*t1[0] - m2[2].im*t2[7];
j[2] = m2[3].im*t1[2] + m2[3].re*t2[5];
j[3] = m2[3].re*t1[2] - m2[3].im*t2[5];
j[4] = m3[2].im*t1[4] + m3[2].re*t2[3];
j[5] = m3[2].re*t1[4] - m3[2].im*t2[3];
j[6] = m3[3].im*t1[6] + m3[3].re*t2[1];
j[7] = m3[3].re*t1[6] - m3[3].im*t2[1];
/* 1 add + 1 shuf */
t[1] = j[0] + w[0];
t[0] = j[1] + w[1];
t[3] = j[2] + w[2];
t[2] = j[3] + w[3];
t[5] = j[4] + w[4];
t[4] = j[5] + w[5];
t[7] = j[6] + w[6];
t[6] = j[7] + w[7];
/* 1 sub + 1 xor */
r[0] = (w[0] - j[0]);
r[1] = -(w[1] - j[1]);
r[2] = (w[2] - j[2]);
r[3] = -(w[3] - j[3]);
r[4] = (w[4] - j[4]);
r[5] = -(w[5] - j[5]);
r[6] = (w[6] - j[6]);
r[7] = -(w[7] - j[7]);
/* Min: 2 subs, 2 adds, 2 vperm2fs (OPTIONAL) */
m2[0].re = m0[0].re - t[0];
m2[0].im = m0[0].im - t[1];
m2[1].re = m0[1].re - t[2];
m2[1].im = m0[1].im - t[3];
m3[0].re = m0[2].re - t[4];
m3[0].im = m0[2].im - t[5];
m3[1].re = m0[3].re - t[6];
m3[1].im = m0[3].im - t[7];
m2[2].re = m1[0].re - r[0];
m2[2].im = m1[0].im - r[1];
m2[3].re = m1[1].re - r[2];
m2[3].im = m1[1].im - r[3];
m3[2].re = m1[2].re - r[4];
m3[2].im = m1[2].im - r[5];
m3[3].re = m1[3].re - r[6];
m3[3].im = m1[3].im - r[7];
m0[0].re = m0[0].re + t[0];
m0[0].im = m0[0].im + t[1];
m0[1].re = m0[1].re + t[2];
m0[1].im = m0[1].im + t[3];
m0[2].re = m0[2].re + t[4];
m0[2].im = m0[2].im + t[5];
m0[3].re = m0[3].re + t[6];
m0[3].im = m0[3].im + t[7];
m1[0].re = m1[0].re + r[0];
m1[0].im = m1[0].im + r[1];
m1[1].re = m1[1].re + r[2];
m1[1].im = m1[1].im + r[3];
m1[2].re = m1[2].re + r[4];
m1[2].im = m1[2].im + r[5];
m1[3].re = m1[3].re + r[6];
m1[3].im = m1[3].im + r[7];
#endif
#if 0
z += 4; // !!!
cos += 2*4;
wim -= 2*4;
}
#endif
}
```
The macros used are identical to those in the generic C version, only with all
variable declarations exported to the function body.
An important point here is that the high frequency registers (m2 and m3) have
their high and low halves swapped in the output. This is intentional, as the
inputs must also have the same layout, and therefore, the input swapping is only
performed once for the bottom-most basis transform, with all subsequent combinations
using the already swapped halves.
Also note that this function requires a special iteration way, due to coefficients
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.

View File

@ -110,11 +110,13 @@ maximum of 2 digits. The @var{m} at the end expresses decimal value for
@emph{or}
@example
[-]@var{S}+[.@var{m}...]
[-]@var{S}+[.@var{m}...][s|ms|us]
@end example
@var{S} expresses the number of seconds, with the optional decimal part
@var{m}.
@var{m}. The optional literal suffixes @samp{s}, @samp{ms} or @samp{us}
indicate to interpret the value as seconds, milliseconds or microseconds,
respectively.
In both expressions, the optional @samp{-} indicates negative duration.
@ -126,6 +128,15 @@ The following examples are all valid time duration:
@item 55
55 seconds
@item 0.2
0.2 seconds
@item 200ms
200 milliseconds, that's 0.2s
@item 200000us
200000 microseconds, that's 0.2s
@item 12:03:45
12 hours, 03 minutes and 45 seconds
@ -704,24 +715,36 @@ FL+FR+FC+LFE+BL+BR+FLC+FRC
FL+FR+FC+LFE+FLC+FRC+SL+SR
@item octagonal
FL+FR+FC+BL+BR+BC+SL+SR
@item hexadecagonal
FL+FR+FC+BL+BR+BC+SL+SR+WL+WR+TBL+TBR+TBC+TFC+TFL+TFR
@item downmix
DL+DR
@item 22.2
FL+FR+FC+LFE+BL+BR+FLC+FRC+BC+SL+SR+TC+TFL+TFC+TFR+TBL+TBC+TBR+LFE2+TSL+TSR+BFC+BFL+BFR
@end table
A custom channel layout can be specified as a sequence of terms, separated by
'+' or '|'. Each term can be:
A custom channel layout can be specified as a sequence of terms, separated by '+'.
Each term can be:
@itemize
@item
the name of a single channel (e.g. @samp{FL}, @samp{FR}, @samp{FC}, @samp{LFE}, etc.),
each optionally containing a custom name after a '@@', (e.g. @samp{FL@@Left},
@samp{FR@@Right}, @samp{FC@@Center}, @samp{LFE@@Low_Frequency}, etc.)
@end itemize
A standard channel layout can be specified by the following:
@itemize
@item
the name of a single channel (e.g. @samp{FL}, @samp{FR}, @samp{FC}, @samp{LFE}, etc.)
@item
the name of a standard channel layout (e.g. @samp{mono},
@samp{stereo}, @samp{4.0}, @samp{quad}, @samp{5.0}, etc.)
@item
the name of a single channel (e.g. @samp{FL}, @samp{FR}, @samp{FC}, @samp{LFE}, etc.)
@item
a number of channels, in decimal, followed by 'c', yielding the default channel
layout for that number of channels (see the function
@code{av_get_default_channel_layout}). Note that not all channel counts have a
@code{av_channel_layout_default}). Note that not all channel counts have a
default layout.
@item
@ -738,7 +761,7 @@ Before libavutil version 53 the trailing character "c" to specify a number of
channels was optional, but now it is required, while a channel layout mask can
also be specified as a decimal number (if and only if not followed by "c" or "C").
See also the function @code{av_get_channel_layout} defined in
See also the function @code{av_channel_layout_from_string} defined in
@file{libavutil/channel_layout.h}.
@c man end SYNTAX
@ -920,6 +943,9 @@ corresponding input value will be returned.
@item round(expr)
Round the value of expression @var{expr} to the nearest integer. For example, "round(1.5)" is "2.0".
@item sgn(x)
Compute sign of @var{x}.
@item sin(x)
Compute sine of @var{x}.

View File

@ -418,4 +418,4 @@ done:
When all of this is done, you can submit your patch to the ffmpeg-devel
mailing-list for review. If you need any help, feel free to come on our IRC
channel, #ffmpeg-devel on irc.freenode.net.
channel, #ffmpeg-devel on irc.libera.chat.

View File

@ -8,7 +8,9 @@ OBJS-$(HAVE_MIPSFPU) += $(MIPSFPU-OBJS) $(MIPSFPU-OBJS-yes)
OBJS-$(HAVE_MIPSDSP) += $(MIPSDSP-OBJS) $(MIPSDSP-OBJS-yes)
OBJS-$(HAVE_MIPSDSPR2) += $(MIPSDSPR2-OBJS) $(MIPSDSPR2-OBJS-yes)
OBJS-$(HAVE_MSA) += $(MSA-OBJS) $(MSA-OBJS-yes)
OBJS-$(HAVE_MMI) += $(MMI-OBJS) $(MMI-OBJS-yes)
OBJS-$(HAVE_MMI) += $(MMI-OBJS) $(MMI-OBJS-yes)
OBJS-$(HAVE_LSX) += $(LSX-OBJS) $(LSX-OBJS-yes)
OBJS-$(HAVE_LASX) += $(LASX-OBJS) $(LASX-OBJS-yes)
OBJS-$(HAVE_ALTIVEC) += $(ALTIVEC-OBJS) $(ALTIVEC-OBJS-yes)
OBJS-$(HAVE_VSX) += $(VSX-OBJS) $(VSX-OBJS-yes)

76
ffbuild/bin2c.c Normal file
View File

@ -0,0 +1,76 @@
/*
* This file is part of FFmpeg.
*
* 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.
*/
#include <string.h>
#include <stdio.h>
int main(int argc, char **argv)
{
const char *name;
FILE *input, *output;
unsigned int length = 0;
unsigned char data;
if (argc < 3 || argc > 4)
return 1;
input = fopen(argv[1], "rb");
if (!input)
return -1;
output = fopen(argv[2], "wb");
if (!output)
return -1;
if (argc == 4) {
name = argv[3];
} else {
size_t arglen = strlen(argv[1]);
name = argv[1];
for (int i = 0; i < arglen; i++) {
if (argv[1][i] == '.')
argv[1][i] = '_';
else if (argv[1][i] == '/')
name = &argv[1][i+1];
}
}
fprintf(output, "const unsigned char ff_%s_data[] = { ", name);
while (fread(&data, 1, 1, input) > 0) {
fprintf(output, "0x%02x, ", data);
length++;
}
fprintf(output, "0x00 };\n");
fprintf(output, "const unsigned int ff_%s_len = %u;\n", name, length);
fclose(output);
if (ferror(input) || !feof(input))
return -1;
fclose(input);
return 0;
}

View File

@ -12,10 +12,13 @@ endif
ifndef SUBDIR
BIN2CEXE = ffbuild/bin2c$(HOSTEXESUF)
BIN2C = $(BIN2CEXE)
ifndef V
Q = @
ECHO = printf "$(1)\t%s\n" $(2)
BRIEF = CC CXX OBJCC HOSTCC HOSTLD AS X86ASM AR LD STRIP CP WINDRES NVCC
BRIEF = CC CXX OBJCC HOSTCC HOSTLD AS X86ASM AR LD STRIP CP WINDRES NVCC BIN2C
SILENT = DEPCC DEPHOSTCC DEPAS DEPX86ASM RANLIB RM
MSG = $@
@ -26,7 +29,8 @@ $(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR))))
$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL))
endif
ALLFFLIBS = avcodec avdevice avfilter avformat avresample avutil postproc swscale swresample
# Prepend to a recursively expanded variable without making it simply expanded.
PREPEND = $(eval $(1) = $(patsubst %,$$(%), $(2)) $(value $(1)))
# NASM requires -I path terminated with /
IFLAGS := -I. -I$(SRC_LINK)/
@ -36,7 +40,9 @@ CCFLAGS = $(CPPFLAGS) $(CFLAGS)
OBJCFLAGS += $(EOBJCFLAGS)
OBJCCFLAGS = $(CPPFLAGS) $(CFLAGS) $(OBJCFLAGS)
ASFLAGS := $(CPPFLAGS) $(ASFLAGS)
CXXFLAGS := $(CPPFLAGS) $(CFLAGS) $(CXXFLAGS)
# Use PREPEND here so that later (target-dependent) additions to CPPFLAGS
# end up in CXXFLAGS.
$(call PREPEND,CXXFLAGS, CPPFLAGS CFLAGS)
X86ASMFLAGS += $(IFLAGS:%=%/) -I$(<D)/ -Pconfig.asm
HOSTCCFLAGS = $(IFLAGS) $(HOSTCPPFLAGS) $(HOSTCFLAGS)
@ -44,7 +50,7 @@ LDFLAGS := $(ALLFFLIBS:%=$(LD_PATH)lib%) $(LDFLAGS)
define COMPILE
$(call $(1)DEP,$(1))
$($(1)) $($(1)FLAGS) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<)
$($(1)) $($(1)FLAGS) $($(2)) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<)
endef
COMPILE_C = $(call COMPILE,CC)
@ -54,6 +60,22 @@ COMPILE_M = $(call COMPILE,OBJCC)
COMPILE_X86ASM = $(call COMPILE,X86ASM)
COMPILE_HOSTC = $(call COMPILE,HOSTCC)
COMPILE_NVCC = $(call COMPILE,NVCC)
COMPILE_MMI = $(call COMPILE,CC,MMIFLAGS)
COMPILE_MSA = $(call COMPILE,CC,MSAFLAGS)
COMPILE_LSX = $(call COMPILE,CC,LSXFLAGS)
COMPILE_LASX = $(call COMPILE,CC,LASXFLAGS)
%_mmi.o: %_mmi.c
$(COMPILE_MMI)
%_msa.o: %_msa.c
$(COMPILE_MSA)
%_lsx.o: %_lsx.c
$(COMPILE_LSX)
%_lasx.o: %_lasx.c
$(COMPILE_LASX)
%.o: %.c
$(COMPILE_C)
@ -82,7 +104,7 @@ COMPILE_NVCC = $(call COMPILE,NVCC)
-$(if $(ASMSTRIPFLAGS), $(STRIP) $(ASMSTRIPFLAGS) $@)
%.o: %.rc
$(WINDRES) $(IFLAGS) --preprocessor "$(DEPWINDRES) -E -xc-header -DRC_INVOKED $(CC_DEPFLAGS)" -o $@ $<
$(WINDRES) $(IFLAGS) $(foreach ARG,$(CC_DEPFLAGS),--preprocessor-arg "$(ARG)") -o $@ $<
%.i: %.c
$(CC) $(CCFLAGS) $(CC_E) $<
@ -90,16 +112,40 @@ COMPILE_NVCC = $(call COMPILE,NVCC)
%.h.c:
$(Q)echo '#include "$*.h"' >$@
$(BIN2CEXE): ffbuild/bin2c_host.o
$(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTEXTRALIBS)
%.metal.air: %.metal
$(METALCC) $< -o $@
%.metallib: %.metal.air
$(METALLIB) --split-module-without-linking $< -o $@
%.metallib.c: %.metallib $(BIN2CEXE)
$(BIN2C) $< $@ $(subst .,_,$(basename $(notdir $@)))
%.ptx: %.cu $(SRC_PATH)/compat/cuda/cuda_runtime.h
$(COMPILE_NVCC)
%.ptx.c: %.ptx
$(Q)sh $(SRC_PATH)/compat/cuda/ptx2c.sh $@ $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<)
ifdef CONFIG_PTX_COMPRESSION
%.ptx.gz: TAG = GZIP
%.ptx.gz: %.ptx
$(M)gzip -c9 $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) >$@
%.ptx.c: %.ptx.gz $(BIN2CEXE)
$(BIN2C) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) $@ $(subst .,_,$(basename $(notdir $@)))
else
%.ptx.c: %.ptx $(BIN2CEXE)
$(BIN2C) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) $@ $(subst .,_,$(basename $(notdir $@)))
endif
clean::
$(RM) $(BIN2CEXE)
%.c %.h %.pc %.ver %.version: TAG = GEN
# Dummy rule to stop make trying to rebuild removed or renamed headers
%.h:
%.h %_template.c:
@:
# Disable suffix rules. Most of the builtin rules are suffix rules,
@ -114,6 +160,8 @@ include $(SRC_PATH)/ffbuild/arch.mak
OBJS += $(OBJS-yes)
SLIBOBJS += $(SLIBOBJS-yes)
SHLIBOBJS += $(SHLIBOBJS-yes)
STLIBOBJS += $(STLIBOBJS-yes)
FFLIBS := $($(NAME)_FFLIBS) $(FFLIBS-yes) $(FFLIBS)
TESTPROGS += $(TESTPROGS-yes)
@ -122,6 +170,8 @@ FFEXTRALIBS := $(LDLIBS:%=$(LD_LIB)) $(foreach lib,EXTRALIBS-$(NAME) $(FFLIBS:%=
OBJS := $(sort $(OBJS:%=$(SUBDIR)%))
SLIBOBJS := $(sort $(SLIBOBJS:%=$(SUBDIR)%))
SHLIBOBJS := $(sort $(SHLIBOBJS:%=$(SUBDIR)%))
STLIBOBJS := $(sort $(STLIBOBJS:%=$(SUBDIR)%))
TESTOBJS := $(TESTOBJS:%=$(SUBDIR)tests/%) $(TESTPROGS:%=$(SUBDIR)tests/%.o)
TESTPROGS := $(TESTPROGS:%=$(SUBDIR)tests/%$(EXESUF))
HOSTOBJS := $(HOSTPROGS:%=$(SUBDIR)%.o)
@ -143,7 +193,7 @@ HOBJS = $(filter-out $(SKIPHEADERS:.h=.h.o),$(ALLHEADERS:.h=.h.o))
PTXOBJS = $(filter %.ptx.o,$(OBJS))
$(HOBJS): CCFLAGS += $(CFLAGS_HEADERS)
checkheaders: $(HOBJS)
.SECONDARY: $(HOBJS:.o=.c) $(PTXOBJS:.o=.c) $(PTXOBJS:.o=)
.SECONDARY: $(HOBJS:.o=.c) $(PTXOBJS:.o=.c) $(PTXOBJS:.o=.gz) $(PTXOBJS:.o=)
alltools: $(TOOLS)
@ -157,12 +207,14 @@ $(OBJS): | $(sort $(dir $(OBJS)))
$(HOBJS): | $(sort $(dir $(HOBJS)))
$(HOSTOBJS): | $(sort $(dir $(HOSTOBJS)))
$(SLIBOBJS): | $(sort $(dir $(SLIBOBJS)))
$(SHLIBOBJS): | $(sort $(dir $(SHLIBOBJS)))
$(STLIBOBJS): | $(sort $(dir $(STLIBOBJS)))
$(TESTOBJS): | $(sort $(dir $(TESTOBJS)))
$(TOOLOBJS): | tools
OUTDIRS := $(OUTDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(SLIBOBJS) $(TESTOBJS))
OUTDIRS := $(OUTDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(SLIBOBJS) $(SHLIBOBJS) $(STLIBOBJS) $(TESTOBJS))
CLEANSUFFIXES = *.d *.gcda *.gcno *.h.c *.ho *.map *.o *.pc *.ptx *.ptx.c *.ver *.version *$(DEFAULT_X86ASMD).asm *~
CLEANSUFFIXES = *.d *.gcda *.gcno *.h.c *.ho *.map *.o *.pc *.ptx *.ptx.gz *.ptx.c *.ver *.version *$(DEFAULT_X86ASMD).asm *~ *.ilk *.pdb
LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a
define RULES
@ -172,4 +224,4 @@ endef
$(eval $(RULES))
-include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d) $(SLIBOBJS:.o=.d)) $(OBJS:.o=$(DEFAULT_X86ASMD).d)
-include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d) $(SHLIBOBJS:.o=.d) $(STLIBOBJS:.o=.d) $(SLIBOBJS:.o=.d)) $(OBJS:.o=$(DEFAULT_X86ASMD).d)

View File

@ -14,10 +14,26 @@ INSTHEADERS := $(INSTHEADERS) $(HEADERS:%=$(SUBDIR)%)
all-$(CONFIG_STATIC): $(SUBDIR)$(LIBNAME) $(SUBDIR)lib$(FULLNAME).pc
all-$(CONFIG_SHARED): $(SUBDIR)$(SLIBNAME) $(SUBDIR)lib$(FULLNAME).pc
LIBOBJS := $(OBJS) $(SUBDIR)%.h.o $(TESTOBJS)
LIBOBJS := $(OBJS) $(SHLIBOBJS) $(STLIBOBJS) $(SUBDIR)%.h.o $(TESTOBJS)
$(LIBOBJS) $(LIBOBJS:.o=.s) $(LIBOBJS:.o=.i): CPPFLAGS += -DHAVE_AV_CONFIG_H
$(SUBDIR)$(LIBNAME): $(OBJS)
ifdef CONFIG_SHARED
# In case both shared libs and static libs are enabled, it can happen
# that a user might want to link e.g. libavformat statically, but
# libavcodec and the other libs dynamically. In this case
# libavformat won't be able to access libavcodec's internal symbols,
# so that they have to be duplicated into the archive just like
# for purely shared builds.
# Test programs are always statically linked against their library
# to be able to access their library's internals, even with shared builds.
# Yet linking against dependend libraries still uses dynamic linking.
# This means that we are in the scenario described above.
# In case only static libs are used, the linker will only use
# one of these copies; this depends on the duplicated object files
# containing exactly the same symbols.
OBJS += $(SHLIBOBJS)
endif
$(SUBDIR)$(LIBNAME): $(OBJS) $(STLIBOBJS)
$(RM) $@
$(AR) $(ARFLAGS) $(AR_O) $^
$(RANLIB) $@
@ -36,8 +52,8 @@ $(LIBOBJS): CPPFLAGS += -DBUILDING_$(NAME)
$(TESTPROGS) $(TOOLS): %$(EXESUF): %.o
$$(LD) $(LDFLAGS) $(LDEXEFLAGS) $$(LD_O) $$(filter %.o,$$^) $$(THISLIB) $(FFEXTRALIBS) $$(EXTRALIBS-$$(*F)) $$(ELIBS)
$(SUBDIR)lib$(NAME).version: $(SUBDIR)version.h | $(SUBDIR)
$$(M) $$(SRC_PATH)/ffbuild/libversion.sh $(NAME) $$< > $$@
$(SUBDIR)lib$(NAME).version: $(SUBDIR)version.h $(SUBDIR)version_major.h | $(SUBDIR)
$$(M) $$(SRC_PATH)/ffbuild/libversion.sh $(NAME) $$^ > $$@
$(SUBDIR)lib$(FULLNAME).pc: $(SUBDIR)version.h ffbuild/config.sh | $(SUBDIR)
$$(M) $$(SRC_PATH)/ffbuild/pkgconfig_generate.sh $(NAME) "$(DESC)"
@ -48,7 +64,7 @@ $(SUBDIR)lib$(NAME).ver: $(SUBDIR)lib$(NAME).v $(OBJS)
$(SUBDIR)$(SLIBNAME): $(SUBDIR)$(SLIBNAME_WITH_MAJOR)
$(Q)cd ./$(SUBDIR) && $(LN_S) $(SLIBNAME_WITH_MAJOR) $(SLIBNAME)
$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SLIBOBJS) $(SUBDIR)lib$(NAME).ver
$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SHLIBOBJS) $(SLIBOBJS) $(SUBDIR)lib$(NAME).ver
$(SLIB_CREATE_DEF_CMD)
$$(LD) $(SHFLAGS) $(LDFLAGS) $(LDSOFLAGS) $$(LD_O) $$(filter %.o,$$^) $(FFEXTRALIBS)
$(SLIB_EXTRA_CMD)

View File

@ -5,8 +5,12 @@ toupper(){
name=lib$1
ucname=$(toupper ${name})
file=$2
file2=$3
eval $(awk "/#define ${ucname}_VERSION_M/ { print \$2 \"=\" \$3 }" "$file")
if [ -f "$file2" ]; then
eval $(awk "/#define ${ucname}_VERSION_M/ { print \$2 \"=\" \$3 }" "$file2")
fi
eval ${ucname}_VERSION=\$${ucname}_VERSION_MAJOR.\$${ucname}_VERSION_MINOR.\$${ucname}_VERSION_MICRO
eval echo "${name}_VERSION=\$${ucname}_VERSION"
eval echo "${name}_VERSION_MAJOR=\$${ucname}_VERSION_MAJOR"

View File

@ -9,16 +9,14 @@ AVBASENAMES = ffmpeg ffplay ffprobe
ALLAVPROGS = $(AVBASENAMES:%=%$(PROGSSUF)$(EXESUF))
ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
OBJS-ffmpeg += fftools/ffmpeg_opt.o fftools/ffmpeg_filter.o fftools/ffmpeg_hw.o
OBJS-ffmpeg-$(CONFIG_CUVID) += fftools/ffmpeg_cuvid.o
OBJS-ffmpeg-$(CONFIG_LIBMFX) += fftools/ffmpeg_qsv.o
ifndef CONFIG_VIDEOTOOLBOX
OBJS-ffmpeg-$(CONFIG_VDA) += fftools/ffmpeg_videotoolbox.o
endif
OBJS-ffmpeg-$(CONFIG_VIDEOTOOLBOX) += fftools/ffmpeg_videotoolbox.o
OBJS-ffmpeg += \
fftools/ffmpeg_filter.o \
fftools/ffmpeg_hw.o \
fftools/ffmpeg_mux.o \
fftools/ffmpeg_opt.o \
define DOFFTOOL
OBJS-$(1) += fftools/cmdutils.o fftools/$(1).o $(OBJS-$(1)-yes)
OBJS-$(1) += fftools/cmdutils.o fftools/opt_common.o fftools/$(1).o $(OBJS-$(1)-yes)
$(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1))
$$(OBJS-$(1)): | fftools
$$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1))

File diff suppressed because it is too large Load Diff

View File

@ -44,11 +44,9 @@ extern const char program_name[];
*/
extern const int program_birth_year;
extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
extern AVFormatContext *avformat_opts;
extern AVDictionary *sws_dict;
extern AVDictionary *swr_opts;
extern AVDictionary *format_opts, *codec_opts, *resample_opts;
extern AVDictionary *format_opts, *codec_opts;
extern int hide_banner;
/**
@ -66,11 +64,6 @@ void exit_program(int ret) av_noreturn;
*/
void init_dynload(void);
/**
* Initialize the cmdutils option system, in particular
* allocate the *_opts contexts.
*/
void init_opts(void);
/**
* Uninitialize the cmdutils option system, in particular
* free the *_opts contexts and their contents.
@ -83,28 +76,12 @@ void uninit_opts(void);
*/
void log_callback_help(void* ptr, int level, const char* fmt, va_list vl);
/**
* Override the cpuflags.
*/
int opt_cpuflags(void *optctx, const char *opt, const char *arg);
/**
* Fallback for options that are not explicitly handled, these will be
* parsed through AVOptions.
*/
int opt_default(void *optctx, const char *opt, const char *arg);
/**
* Set the libav* libraries log level.
*/
int opt_loglevel(void *optctx, const char *opt, const char *arg);
int opt_report(const char *opt);
int opt_max_alloc(void *optctx, const char *opt, const char *arg);
int opt_codec_debug(void *optctx, const char *opt, const char *arg);
/**
* Limit the execution time.
*/
@ -201,47 +178,6 @@ typedef struct OptionDef {
void show_help_options(const OptionDef *options, const char *msg, int req_flags,
int rej_flags, int alt_flags);
#if CONFIG_AVDEVICE
#define CMDUTILS_COMMON_OPTIONS_AVDEVICE \
{ "sources" , OPT_EXIT | HAS_ARG, { .func_arg = show_sources }, \
"list sources of the input device", "device" }, \
{ "sinks" , OPT_EXIT | HAS_ARG, { .func_arg = show_sinks }, \
"list sinks of the output device", "device" }, \
#else
#define CMDUTILS_COMMON_OPTIONS_AVDEVICE
#endif
#define CMDUTILS_COMMON_OPTIONS \
{ "L", OPT_EXIT, { .func_arg = show_license }, "show license" }, \
{ "h", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" }, \
{ "?", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" }, \
{ "help", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" }, \
{ "-help", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" }, \
{ "version", OPT_EXIT, { .func_arg = show_version }, "show version" }, \
{ "buildconf", OPT_EXIT, { .func_arg = show_buildconf }, "show build configuration" }, \
{ "formats", OPT_EXIT, { .func_arg = show_formats }, "show available formats" }, \
{ "muxers", OPT_EXIT, { .func_arg = show_muxers }, "show available muxers" }, \
{ "demuxers", OPT_EXIT, { .func_arg = show_demuxers }, "show available demuxers" }, \
{ "devices", OPT_EXIT, { .func_arg = show_devices }, "show available devices" }, \
{ "codecs", OPT_EXIT, { .func_arg = show_codecs }, "show available codecs" }, \
{ "decoders", OPT_EXIT, { .func_arg = show_decoders }, "show available decoders" }, \
{ "encoders", OPT_EXIT, { .func_arg = show_encoders }, "show available encoders" }, \
{ "bsfs", OPT_EXIT, { .func_arg = show_bsfs }, "show available bit stream filters" }, \
{ "protocols", OPT_EXIT, { .func_arg = show_protocols }, "show available protocols" }, \
{ "filters", OPT_EXIT, { .func_arg = show_filters }, "show available filters" }, \
{ "pix_fmts", OPT_EXIT, { .func_arg = show_pix_fmts }, "show available pixel formats" }, \
{ "layouts", OPT_EXIT, { .func_arg = show_layouts }, "show standard channel layouts" }, \
{ "sample_fmts", OPT_EXIT, { .func_arg = show_sample_fmts }, "show available audio sample formats" }, \
{ "colors", OPT_EXIT, { .func_arg = show_colors }, "show available color names" }, \
{ "loglevel", HAS_ARG, { .func_arg = opt_loglevel }, "set logging level", "loglevel" }, \
{ "v", HAS_ARG, { .func_arg = opt_loglevel }, "set logging level", "loglevel" }, \
{ "report", 0, { (void*)opt_report }, "generate a report" }, \
{ "max_alloc", HAS_ARG, { .func_arg = opt_max_alloc }, "set maximum size of a single allocated block", "bytes" }, \
{ "cpuflags", HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpuflags }, "force specific cpu flags", "flags" }, \
{ "hide_banner", OPT_BOOL | OPT_EXPERT, {&hide_banner}, "do not show program banner", "hide_banner" }, \
CMDUTILS_COMMON_OPTIONS_AVDEVICE \
/**
* Show help for all options with given flags in class and all its
* children.
@ -254,11 +190,6 @@ void show_help_children(const AVClass *class, int flags);
*/
void show_help_default(const char *opt, const char *arg);
/**
* Generic -h handler common to all fftools.
*/
int show_help(void *optctx, const char *opt, const char *arg);
/**
* Parse the command line arguments.
*
@ -317,7 +248,6 @@ typedef struct OptionGroup {
AVDictionary *codec_opts;
AVDictionary *format_opts;
AVDictionary *resample_opts;
AVDictionary *sws_dict;
AVDictionary *swr_opts;
} OptionGroup;
@ -414,7 +344,7 @@ int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec);
* @return a pointer to the created dictionary
*/
AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
AVFormatContext *s, AVStream *st, AVCodec *codec);
AVFormatContext *s, AVStream *st, const AVCodec *codec);
/**
* Setup AVCodecContext options for avformat_find_stream_info().
@ -424,8 +354,8 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
* Each dictionary will contain the options from codec_opts which can
* be applied to the corresponding stream codec context.
*
* @return pointer to the created array of dictionaries, NULL if it
* cannot be created
* @return pointer to the created array of dictionaries.
* Calls exit() on failure.
*/
AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
AVDictionary *codec_opts);
@ -448,136 +378,6 @@ void print_error(const char *filename, int err);
*/
void show_banner(int argc, char **argv, const OptionDef *options);
/**
* Print the version of the program to stdout. The version message
* depends on the current versions of the repository and of the libav*
* libraries.
* This option processing function does not utilize the arguments.
*/
int show_version(void *optctx, const char *opt, const char *arg);
/**
* Print the build configuration of the program to stdout. The contents
* depend on the definition of FFMPEG_CONFIGURATION.
* This option processing function does not utilize the arguments.
*/
int show_buildconf(void *optctx, const char *opt, const char *arg);
/**
* Print the license of the program to stdout. The license depends on
* the license of the libraries compiled into the program.
* This option processing function does not utilize the arguments.
*/
int show_license(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the formats supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_formats(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the muxers supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_muxers(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the demuxer supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_demuxers(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the devices supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_devices(void *optctx, const char *opt, const char *arg);
#if CONFIG_AVDEVICE
/**
* Print a listing containing autodetected sinks of the output device.
* Device name with options may be passed as an argument to limit results.
*/
int show_sinks(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing autodetected sources of the input device.
* Device name with options may be passed as an argument to limit results.
*/
int show_sources(void *optctx, const char *opt, const char *arg);
#endif
/**
* Print a listing containing all the codecs supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_codecs(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the decoders supported by the
* program.
*/
int show_decoders(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the encoders supported by the
* program.
*/
int show_encoders(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the filters supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_filters(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the bit stream filters supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_bsfs(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the protocols supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_protocols(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the pixel formats supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_pix_fmts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the standard channel layouts supported by
* the program.
* This option processing function does not utilize the arguments.
*/
int show_layouts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the sample formats supported by the
* program.
*/
int show_sample_fmts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the color names and values recognized
* by the program.
*/
int show_colors(void *optctx, const char *opt, const char *arg);
/**
* Return a positive value if a line read from standard input
* starts with [yY], otherwise return 0.
@ -617,11 +417,26 @@ FILE *get_preset_file(char *filename, size_t filename_size,
*/
void *grow_array(void *array, int elem_size, int *size, int new_size);
#define media_type_string av_get_media_type_string
/**
* Atomically add a new element to an array of pointers, i.e. allocate
* a new entry, reallocate the array of pointers and make the new last
* member of this array point to the newly allocated buffer.
* Calls exit() on failure.
*
* @param array array of pointers to reallocate
* @param elem_size size of the new element to allocate
* @param nb_elems pointer to the number of elements of the array array;
* *nb_elems will be incremented by one by this function.
* @return pointer to the newly allocated entry
*/
void *allocate_array_elem(void *array, size_t elem_size, int *nb_elems);
#define GROW_ARRAY(array, nb_elems)\
array = grow_array(array, sizeof(*array), &nb_elems, nb_elems + 1)
#define ALLOC_ARRAY_ELEM(array, nb_elems)\
allocate_array_elem(&array, sizeof(*array[0]), &nb_elems)
#define GET_PIX_FMT_NAME(pix_fmt)\
const char *name = av_get_pix_fmt_name(pix_fmt);
@ -635,14 +450,6 @@ void *grow_array(void *array, int elem_size, int *size, int new_size);
char name[16];\
snprintf(name, sizeof(name), "%d", rate);
#define GET_CH_LAYOUT_NAME(ch_layout)\
char name[16];\
snprintf(name, sizeof(name), "0x%"PRIx64, ch_layout);
#define GET_CH_LAYOUT_DESC(ch_layout)\
char name[128];\
av_get_channel_layout_string(name, sizeof(name), 0, ch_layout);
double get_rotation(AVStream *st);
double get_rotation(int32_t *displaymatrix);
#endif /* FFTOOLS_CMDUTILS_H */

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@
#include "libavformat/avio.h"
#include "libavcodec/avcodec.h"
#include "libavcodec/bsf.h"
#include "libavfilter/avfilter.h"
@ -46,12 +47,14 @@
#include "libswresample/swresample.h"
#define VSYNC_AUTO -1
#define VSYNC_PASSTHROUGH 0
#define VSYNC_CFR 1
#define VSYNC_VFR 2
#define VSYNC_VSCFR 0xfe
#define VSYNC_DROP 0xff
enum VideoSyncMethod {
VSYNC_AUTO = -1,
VSYNC_PASSTHROUGH,
VSYNC_CFR,
VSYNC_VFR,
VSYNC_VSCFR,
VSYNC_DROP,
};
#define MAX_STREAMS 1024 /* arbitrary sanity check value */
@ -59,18 +62,8 @@ enum HWAccelID {
HWACCEL_NONE = 0,
HWACCEL_AUTO,
HWACCEL_GENERIC,
HWACCEL_VIDEOTOOLBOX,
HWACCEL_QSV,
HWACCEL_CUVID,
};
typedef struct HWAccel {
const char *name;
int (*init)(AVCodecContext *s);
enum HWAccelID id;
enum AVPixelFormat pix_fmt;
} HWAccel;
typedef struct HWDevice {
const char *name;
enum AVHWDeviceType type;
@ -103,12 +96,16 @@ typedef struct OptionsContext {
SpecifierOpt *codec_names;
int nb_codec_names;
SpecifierOpt *audio_ch_layouts;
int nb_audio_ch_layouts;
SpecifierOpt *audio_channels;
int nb_audio_channels;
SpecifierOpt *audio_sample_rate;
int nb_audio_sample_rate;
SpecifierOpt *frame_rates;
int nb_frame_rates;
SpecifierOpt *max_frame_rates;
int nb_max_frame_rates;
SpecifierOpt *frame_sizes;
int nb_frame_sizes;
SpecifierOpt *frame_pix_fmts;
@ -118,8 +115,10 @@ typedef struct OptionsContext {
int64_t input_ts_offset;
int loop;
int rate_emu;
float readrate;
int accurate_seek;
int thread_queue_size;
int input_sync_ref;
SpecifierOpt *ts_scale;
int nb_ts_scale;
@ -178,6 +177,8 @@ typedef struct OptionsContext {
int nb_qscale;
SpecifierOpt *forced_key_frames;
int nb_forced_key_frames;
SpecifierOpt *fps_mode;
int nb_fps_mode;
SpecifierOpt *force_fps;
int nb_force_fps;
SpecifierOpt *frame_aspect_ratios;
@ -216,6 +217,8 @@ typedef struct OptionsContext {
int nb_passlogfiles;
SpecifierOpt *max_muxing_queue_size;
int nb_max_muxing_queue_size;
SpecifierOpt *muxing_queue_data_threshold;
int nb_muxing_queue_data_threshold;
SpecifierOpt *guess_layout_max;
int nb_guess_layout_max;
SpecifierOpt *apad;
@ -230,6 +233,10 @@ typedef struct OptionsContext {
int nb_time_bases;
SpecifierOpt *enc_time_bases;
int nb_enc_time_bases;
SpecifierOpt *autoscale;
int nb_autoscale;
SpecifierOpt *bits_per_raw_sample;
int nb_bits_per_raw_sample;
} OptionsContext;
typedef struct InputFilter {
@ -239,7 +246,7 @@ typedef struct InputFilter {
uint8_t *name;
enum AVMediaType type; // AVMEDIA_TYPE_SUBTITLE for sub2video
AVFifoBuffer *frame_queue;
AVFifo *frame_queue;
// parameters configured for this input
int format;
@ -248,10 +255,10 @@ typedef struct InputFilter {
AVRational sample_aspect_ratio;
int sample_rate;
int channels;
uint64_t channel_layout;
AVChannelLayout ch_layout;
AVBufferRef *hw_frames_ctx;
int32_t *displaymatrix;
int eof;
} InputFilter;
@ -271,12 +278,13 @@ typedef struct OutputFilter {
AVRational frame_rate;
int format;
int sample_rate;
uint64_t channel_layout;
AVChannelLayout ch_layout;
// those are only set if no format is specified and the encoder gives us multiple options
int *formats;
uint64_t *channel_layouts;
int *sample_rates;
// They point directly to the relevant lists of the encoder.
const int *formats;
const AVChannelLayout *ch_layouts;
const int *sample_rates;
} OutputFilter;
typedef struct FilterGraph {
@ -285,6 +293,9 @@ typedef struct FilterGraph {
AVFilterGraph *graph;
int reconfiguration;
// true when the filtergraph contains only meta filters
// that do not modify the frame data
int is_meta;
InputFilter **inputs;
int nb_inputs;
@ -300,16 +311,19 @@ typedef struct InputStream {
int decoding_needed; /* non zero if the packets must be decoded in 'raw_fifo', see DECODING_FOR_* */
#define DECODING_FOR_OST 1
#define DECODING_FOR_FILTER 2
int processing_needed; /* non zero if the packets must be processed */
AVCodecContext *dec_ctx;
AVCodec *dec;
const AVCodec *dec;
AVFrame *decoded_frame;
AVFrame *filter_frame; /* a ref of decoded_frame, to be sent to filters */
AVPacket *pkt;
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
* several frames in a packet) of the next frame in current packet (in AV_TIME_BASE units) */
int64_t next_dts;
int64_t first_dts; ///< dts of the first packet read for this stream (in AV_TIME_BASE units)
int64_t dts; ///< dts of the last packet read for this stream (in AV_TIME_BASE units)
int64_t next_pts; ///< synthetic pts for the next decode frame (in AV_TIME_BASE units)
@ -346,13 +360,12 @@ typedef struct InputStream {
struct sub2video {
int64_t last_pts;
int64_t end_pts;
AVFifoBuffer *sub_queue; ///< queue of AVSubtitle* before filter init
AVFifo *sub_queue; ///< queue of AVSubtitle* before filter init
AVFrame *frame;
int w, h;
unsigned int initialize; ///< marks if sub2video_update should force an initialization
} sub2video;
int dr1;
/* decoded data from this stream goes into all those filters
* currently video and audio only */
InputFilter **filters;
@ -369,11 +382,9 @@ typedef struct InputStream {
/* hwaccel context */
void *hwaccel_ctx;
void (*hwaccel_uninit)(AVCodecContext *s);
int (*hwaccel_get_buffer)(AVCodecContext *s, AVFrame *frame, int flags);
int (*hwaccel_retrieve_data)(AVCodecContext *s, AVFrame *frame);
enum AVPixelFormat hwaccel_pix_fmt;
enum AVPixelFormat hwaccel_retrieved_pix_fmt;
AVBufferRef *hw_frames_ctx;
/* stats */
// combined size of all the packets read
@ -400,18 +411,21 @@ typedef struct InputFile {
at the moment when looping happens */
AVRational time_base; /* time base of the duration */
int64_t input_ts_offset;
int input_sync_ref;
int64_t ts_offset;
int64_t last_ts;
int64_t start_time; /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */
int seek_timestamp;
int64_t recording_time;
int nb_streams; /* number of stream that ffmpeg is aware of; may be different
from ctx.nb_streams if new streams appear during av_read_frame() */
int nb_streams_warn; /* number of streams that the user was warned of */
int rate_emu;
float readrate;
int accurate_seek;
AVPacket *pkt;
#if HAVE_THREADS
AVThreadMessageQueue *in_thread_queue;
pthread_t thread; /* thread reading from this file */
@ -430,7 +444,8 @@ enum forced_keyframes_const {
FKF_NB
};
#define ABORT_ON_FLAG_EMPTY_OUTPUT (1 << 0)
#define ABORT_ON_FLAG_EMPTY_OUTPUT (1 << 0)
#define ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM (1 << 1)
extern const char *const forced_keyframes_const_names[];
@ -445,7 +460,7 @@ typedef struct OutputStream {
int source_index; /* InputStream index */
AVStream *st; /* stream in the output file */
int encoding_needed; /* true if encoding needed for this stream */
int frame_number;
int64_t frame_number;
/* input pts and corresponding output pts
for A/V sync */
struct InputStream *sync_ist; /* input stream to sync against */
@ -459,26 +474,31 @@ typedef struct OutputStream {
AVRational mux_timebase;
AVRational enc_timebase;
int nb_bitstream_filters;
AVBSFContext **bsf_ctx;
AVBSFContext *bsf_ctx;
AVCodecContext *enc_ctx;
AVCodecParameters *ref_par; /* associated input codec parameters with encoders options applied */
AVCodec *enc;
const AVCodec *enc;
int64_t max_frames;
AVFrame *filtered_frame;
AVFrame *last_frame;
int last_dropped;
int last_nb0_frames[3];
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;
int rotate_overridden;
int autoscale;
int bits_per_raw_sample;
double rotate_override_value;
AVRational frame_aspect_ratio;
@ -491,6 +511,7 @@ typedef struct OutputStream {
char *forced_keyframes;
AVExpr *forced_keyframes_pexpr;
double forced_keyframes_expr_const_values[FKF_NB];
int dropped_keyframe;
/* audio only */
int *audio_channels_map; /* list of the channels id to pick from the source stream */
@ -507,7 +528,6 @@ typedef struct OutputStream {
AVDictionary *encoder_opts;
AVDictionary *sws_dict;
AVDictionary *swr_opts;
AVDictionary *resample_opts;
char *apad;
OSTFinished finished; /* no more packets should be written for this stream */
int unavailable; /* true if the steram is unavailable (possibly temporarily) */
@ -521,6 +541,7 @@ typedef struct OutputStream {
int inputs_done;
const char *attachment_filename;
int streamcopy_started;
int copy_initial_nonkeyframes;
int copy_prior_start;
char *disposition;
@ -535,6 +556,8 @@ typedef struct OutputStream {
// number of frames/samples sent to the encoder
uint64_t frames_encoded;
uint64_t samples_encoded;
// number of packets received from the encoder
uint64_t packets_encoded;
/* packet quality factor */
int quality;
@ -542,7 +565,16 @@ typedef struct OutputStream {
int max_muxing_queue_size;
/* the packets are buffered here until the muxer is ready to be initialized */
AVFifoBuffer *muxing_queue;
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;
@ -552,6 +584,10 @@ typedef struct OutputStream {
} OutputStream;
typedef struct OutputFile {
int index;
const AVOutputFormat *format;
AVFormatContext *ctx;
AVDictionary *opts;
int ost_index; /* index of the first stream in output_streams */
@ -586,7 +622,7 @@ extern float dts_error_threshold;
extern int audio_volume;
extern int audio_sync_method;
extern int video_sync_method;
extern enum VideoSyncMethod video_sync_method;
extern float frame_drop_threshold;
extern int do_benchmark;
extern int do_benchmark_all;
@ -600,53 +636,48 @@ extern int debug_ts;
extern int exit_on_error;
extern int abort_on_flags;
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;
extern char *videotoolbox_pixfmt;
extern int filter_nbthreads;
extern char *filter_nbthreads;
extern int filter_complex_nbthreads;
extern int vstats_version;
extern int auto_conversion_filters;
extern const AVIOInterruptCB int_cb;
extern const OptionDef options[];
extern const HWAccel hwaccels[];
extern AVBufferRef *hw_device_ctx;
#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;
void term_init(void);
void term_exit(void);
void reset_options(OptionsContext *o, int is_input);
void show_usage(void);
void opt_output_file(void *optctx, const char *filename);
void remove_avoptions(AVDictionary **a, AVDictionary *b);
void assert_avoptions(AVDictionary *m);
int guess_input_channel_layout(InputStream *ist);
enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *avctx, AVCodec *codec, enum AVPixelFormat target);
void choose_sample_fmt(AVStream *st, AVCodec *codec);
int configure_filtergraph(FilterGraph *fg);
int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out);
void check_filter_outputs(void);
int ist_in_filtergraph(FilterGraph *fg, InputStream *ist);
int filtergraph_is_simple(FilterGraph *fg);
int init_simple_filtergraph(InputStream *ist, OutputStream *ost);
int init_complex_filtergraph(FilterGraph *fg);
void sub2video_update(InputStream *ist, AVSubtitle *sub);
void sub2video_update(InputStream *ist, int64_t heartbeat_pts, AVSubtitle *sub);
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame);
@ -654,7 +685,6 @@ int ffmpeg_parse_options(int argc, char **argv);
int videotoolbox_init(AVCodecContext *s);
int qsv_init(AVCodecContext *s);
int cuvid_init(AVCodecContext *s);
HWDevice *hw_device_get_by_name(const char *name);
int hw_device_init_from_string(const char *arg, HWDevice **dev);
@ -662,7 +692,16 @@ void hw_device_free_all(void);
int hw_device_setup_for_decode(InputStream *ist);
int hw_device_setup_for_encode(OutputStream *ost);
int hw_device_setup_for_filter(FilterGraph *fg);
int hwaccel_decode_init(AVCodecContext *avctx);
/* open the muxer when all the streams are initialized */
int of_check_init(OutputFile *of);
int of_write_trailer(OutputFile *of);
void of_close(OutputFile **pof);
void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
int unqueue);
#endif /* FFTOOLS_FFMPEG_H */

View File

@ -1,73 +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 "libavutil/hwcontext.h"
#include "libavutil/pixdesc.h"
#include "ffmpeg.h"
static void cuvid_uninit(AVCodecContext *avctx)
{
InputStream *ist = avctx->opaque;
av_buffer_unref(&ist->hw_frames_ctx);
}
int cuvid_init(AVCodecContext *avctx)
{
InputStream *ist = avctx->opaque;
AVHWFramesContext *frames_ctx;
int ret;
av_log(avctx, AV_LOG_VERBOSE, "Initializing cuvid hwaccel\n");
if (!hw_device_ctx) {
ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_CUDA,
ist->hwaccel_device, NULL, 0);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error creating a CUDA device\n");
return ret;
}
}
av_buffer_unref(&ist->hw_frames_ctx);
ist->hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx);
if (!ist->hw_frames_ctx) {
av_log(avctx, AV_LOG_ERROR, "Error creating a CUDA frames context\n");
return AVERROR(ENOMEM);
}
frames_ctx = (AVHWFramesContext*)ist->hw_frames_ctx->data;
frames_ctx->format = AV_PIX_FMT_CUDA;
frames_ctx->sw_format = avctx->sw_pix_fmt;
frames_ctx->width = avctx->width;
frames_ctx->height = avctx->height;
av_log(avctx, AV_LOG_DEBUG, "Initializing CUDA frames context: sw_format = %s, width = %d, height = %d\n",
av_get_pix_fmt_name(frames_ctx->sw_format), frames_ctx->width, frames_ctx->height);
ret = av_hwframe_ctx_init(ist->hw_frames_ctx);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error initializing a CUDA frame pool\n");
return ret;
}
ist->hwaccel_uninit = cuvid_uninit;
return 0;
}

View File

@ -26,8 +26,6 @@
#include "libavfilter/buffersink.h"
#include "libavfilter/buffersrc.h"
#include "libavresample/avresample.h"
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/bprint.h"
@ -39,28 +37,23 @@
#include "libavutil/imgutils.h"
#include "libavutil/samplefmt.h"
static const enum AVPixelFormat *get_compliance_unofficial_pix_fmts(enum AVCodecID codec_id, const enum AVPixelFormat default_formats[])
// FIXME: YUV420P etc. are actually supported with full color range,
// yet the latter information isn't available here.
static const enum AVPixelFormat *get_compliance_normal_pix_fmts(const AVCodec *codec, const enum AVPixelFormat default_formats[])
{
static const enum AVPixelFormat mjpeg_formats[] =
{ AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P,
AV_PIX_FMT_NONE };
static const enum AVPixelFormat ljpeg_formats[] =
{ AV_PIX_FMT_BGR24 , AV_PIX_FMT_BGRA , AV_PIX_FMT_BGR0,
AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P,
AV_PIX_FMT_YUV420P , AV_PIX_FMT_YUV444P , AV_PIX_FMT_YUV422P,
AV_PIX_FMT_NONE};
if (codec_id == AV_CODEC_ID_MJPEG) {
if (!strcmp(codec->name, "mjpeg")) {
return mjpeg_formats;
} else if (codec_id == AV_CODEC_ID_LJPEG) {
return ljpeg_formats;
} else {
return default_formats;
}
}
enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCodec *codec, enum AVPixelFormat target)
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;
@ -69,11 +62,11 @@ enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCod
int has_alpha = desc ? desc->nb_components % 2 == 0 : 0;
enum AVPixelFormat best= AV_PIX_FMT_NONE;
if (enc_ctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
p = get_compliance_unofficial_pix_fmts(enc_ctx->codec_id, p);
if (enc_ctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
p = get_compliance_normal_pix_fmts(codec, p);
}
for (; *p != AV_PIX_FMT_NONE; p++) {
best= avcodec_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL);
best = av_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL);
if (*p == target)
break;
}
@ -90,32 +83,13 @@ enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCod
return target;
}
void choose_sample_fmt(AVStream *st, AVCodec *codec)
{
if (codec && codec->sample_fmts) {
const enum AVSampleFormat *p = codec->sample_fmts;
for (; *p != -1; p++) {
if (*p == st->codecpar->format)
break;
}
if (*p == -1) {
if((codec->capabilities & AV_CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codecpar->format) > av_get_sample_fmt_name(codec->sample_fmts[0]))
av_log(NULL, AV_LOG_ERROR, "Conversion will not be lossless.\n");
if(av_get_sample_fmt_name(st->codecpar->format))
av_log(NULL, AV_LOG_WARNING,
"Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n",
av_get_sample_fmt_name(st->codecpar->format),
codec->name,
av_get_sample_fmt_name(codec->sample_fmts[0]));
st->codecpar->format = codec->sample_fmts[0];
}
}
}
static char *choose_pix_fmts(OutputFilter *ofilter)
/* May return NULL (no pixel format found), a static string or a string
* backed by the bprint. Nothing has been written to the AVBPrint in case
* NULL is returned. The AVBPrint provided should be clean. */
static const char *choose_pix_fmts(OutputFilter *ofilter, AVBPrint *bprint)
{
OutputStream *ost = ofilter->ost;
AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, "strict", NULL, 0);
const AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, "strict", NULL, 0);
if (strict_dict)
// used by choose_pixel_fmt() and below
av_opt_set(ost->enc_ctx, "strict", strict_dict->value, 0);
@ -125,105 +99,108 @@ static char *choose_pix_fmts(OutputFilter *ofilter)
AVFILTER_AUTO_CONVERT_NONE);
if (ost->enc_ctx->pix_fmt == AV_PIX_FMT_NONE)
return NULL;
return av_strdup(av_get_pix_fmt_name(ost->enc_ctx->pix_fmt));
return av_get_pix_fmt_name(ost->enc_ctx->pix_fmt);
}
if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
return av_strdup(av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc_ctx, ost->enc, ost->enc_ctx->pix_fmt)));
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;
AVIOContext *s = NULL;
uint8_t *ret;
int len;
if (avio_open_dyn_buf(&s) < 0)
exit_program(1);
p = ost->enc->pix_fmts;
if (ost->enc_ctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
p = get_compliance_unofficial_pix_fmts(ost->enc_ctx->codec_id, p);
if (ost->enc_ctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
p = get_compliance_normal_pix_fmts(ost->enc, p);
}
for (; *p != AV_PIX_FMT_NONE; p++) {
const char *name = av_get_pix_fmt_name(*p);
avio_printf(s, "%s|", name);
av_bprintf(bprint, "%s%c", name, p[1] == AV_PIX_FMT_NONE ? '\0' : '|');
}
len = avio_close_dyn_buf(s, &ret);
ret[len - 1] = 0;
return ret;
if (!av_bprint_is_complete(bprint))
exit_program(1);
return bprint->str;
} else
return NULL;
}
/* Define a function for building a string containing a list of
* allowed formats. */
#define DEF_CHOOSE_FORMAT(suffix, type, var, supported_list, none, get_name) \
static char *choose_ ## suffix (OutputFilter *ofilter) \
/* Define a function for appending a list of allowed formats
* to an AVBPrint. If nonempty, the list will have a header. */
#define DEF_CHOOSE_FORMAT(name, type, var, supported_list, none, printf_format, get_name) \
static void choose_ ## name (OutputFilter *ofilter, AVBPrint *bprint) \
{ \
if (ofilter->var == none && !ofilter->supported_list) \
return; \
av_bprintf(bprint, #name "="); \
if (ofilter->var != none) { \
get_name(ofilter->var); \
return av_strdup(name); \
} else if (ofilter->supported_list) { \
av_bprintf(bprint, printf_format, get_name(ofilter->var)); \
} else { \
const type *p; \
AVIOContext *s = NULL; \
uint8_t *ret; \
int len; \
\
if (avio_open_dyn_buf(&s) < 0) \
exit_program(1); \
\
for (p = ofilter->supported_list; *p != none; p++) { \
get_name(*p); \
avio_printf(s, "%s|", name); \
av_bprintf(bprint, printf_format "|", get_name(*p)); \
} \
len = avio_close_dyn_buf(s, &ret); \
ret[len - 1] = 0; \
return ret; \
} else \
return NULL; \
if (bprint->len > 0) \
bprint->str[--bprint->len] = '\0'; \
} \
av_bprint_chars(bprint, ':', 1); \
}
//DEF_CHOOSE_FORMAT(pix_fmts, enum AVPixelFormat, format, formats, AV_PIX_FMT_NONE,
// GET_PIX_FMT_NAME)
DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME)
AV_SAMPLE_FMT_NONE, "%s", av_get_sample_fmt_name)
DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
GET_SAMPLE_RATE_NAME)
"%d", )
DEF_CHOOSE_FORMAT(channel_layouts, uint64_t, channel_layout, channel_layouts, 0,
GET_CH_LAYOUT_NAME)
static void choose_channel_layouts(OutputFilter *ofilter, AVBPrint *bprint)
{
if (av_channel_layout_check(&ofilter->ch_layout)) {
av_bprintf(bprint, "channel_layouts=");
av_channel_layout_describe_bprint(&ofilter->ch_layout, bprint);
} else if (ofilter->ch_layouts) {
const AVChannelLayout *p;
av_bprintf(bprint, "channel_layouts=");
for (p = ofilter->ch_layouts; p->nb_channels; p++) {
av_channel_layout_describe_bprint(p, bprint);
av_bprintf(bprint, "|");
}
if (bprint->len > 0)
bprint->str[--bprint->len] = '\0';
} else
return;
av_bprint_chars(bprint, ':', 1);
}
int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
{
FilterGraph *fg = av_mallocz(sizeof(*fg));
OutputFilter *ofilter;
InputFilter *ifilter;
if (!fg)
exit_program(1);
fg->index = nb_filtergraphs;
GROW_ARRAY(fg->outputs, fg->nb_outputs);
if (!(fg->outputs[0] = av_mallocz(sizeof(*fg->outputs[0]))))
exit_program(1);
fg->outputs[0]->ost = ost;
fg->outputs[0]->graph = fg;
fg->outputs[0]->format = -1;
ofilter = ALLOC_ARRAY_ELEM(fg->outputs, fg->nb_outputs);
ofilter->ost = ost;
ofilter->graph = fg;
ofilter->format = -1;
ost->filter = fg->outputs[0];
ost->filter = ofilter;
GROW_ARRAY(fg->inputs, fg->nb_inputs);
if (!(fg->inputs[0] = av_mallocz(sizeof(*fg->inputs[0]))))
exit_program(1);
fg->inputs[0]->ist = ist;
fg->inputs[0]->graph = fg;
fg->inputs[0]->format = -1;
ifilter = ALLOC_ARRAY_ELEM(fg->inputs, fg->nb_inputs);
ifilter->ist = ist;
ifilter->graph = fg;
ifilter->format = -1;
fg->inputs[0]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*));
if (!fg->inputs[0]->frame_queue)
ifilter->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
if (!ifilter->frame_queue)
exit_program(1);
GROW_ARRAY(ist->filters, ist->nb_filters);
ist->filters[ist->nb_filters - 1] = fg->inputs[0];
ist->filters[ist->nb_filters - 1] = ifilter;
GROW_ARRAY(filtergraphs, nb_filtergraphs);
filtergraphs[nb_filtergraphs - 1] = fg;
@ -236,17 +213,15 @@ static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
AVFilterContext *ctx = inout->filter_ctx;
AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads;
int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs;
AVIOContext *pb;
uint8_t *res = NULL;
char *res;
if (avio_open_dyn_buf(&pb) < 0)
exit_program(1);
avio_printf(pb, "%s", ctx->filter->name);
if (nb_pads > 1)
avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx));
avio_w8(pb, 0);
avio_close_dyn_buf(pb, &res);
res = av_strdup(ctx->filter->name);
else
res = av_asprintf("%s:%s", ctx->filter->name,
avfilter_pad_get_name(pads, inout->pad_idx));
if (!res)
exit_program(1);
return res;
}
@ -254,6 +229,7 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
{
InputStream *ist = NULL;
enum AVMediaType type = avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx);
InputFilter *ifilter;
int i;
// TODO: support other filter types
@ -318,23 +294,22 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
ist->discard = 0;
ist->decoding_needed |= DECODING_FOR_FILTER;
ist->processing_needed = 1;
ist->st->discard = AVDISCARD_NONE;
GROW_ARRAY(fg->inputs, fg->nb_inputs);
if (!(fg->inputs[fg->nb_inputs - 1] = av_mallocz(sizeof(*fg->inputs[0]))))
exit_program(1);
fg->inputs[fg->nb_inputs - 1]->ist = ist;
fg->inputs[fg->nb_inputs - 1]->graph = fg;
fg->inputs[fg->nb_inputs - 1]->format = -1;
fg->inputs[fg->nb_inputs - 1]->type = ist->st->codecpar->codec_type;
fg->inputs[fg->nb_inputs - 1]->name = describe_filter_link(fg, in, 1);
ifilter = ALLOC_ARRAY_ELEM(fg->inputs, fg->nb_inputs);
ifilter->ist = ist;
ifilter->graph = fg;
ifilter->format = -1;
ifilter->type = ist->st->codecpar->codec_type;
ifilter->name = describe_filter_link(fg, in, 1);
fg->inputs[fg->nb_inputs - 1]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*));
if (!fg->inputs[fg->nb_inputs - 1]->frame_queue)
ifilter->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
if (!ifilter->frame_queue)
exit_program(1);
GROW_ARRAY(ist->filters, ist->nb_filters);
ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
ist->filters[ist->nb_filters - 1] = ifilter;
}
int init_complex_filtergraph(FilterGraph *fg)
@ -358,18 +333,15 @@ int init_complex_filtergraph(FilterGraph *fg)
init_input_filter(fg, cur);
for (cur = outputs; cur;) {
GROW_ARRAY(fg->outputs, fg->nb_outputs);
fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0]));
if (!fg->outputs[fg->nb_outputs - 1])
exit_program(1);
OutputFilter *const ofilter = ALLOC_ARRAY_ELEM(fg->outputs, fg->nb_outputs);
fg->outputs[fg->nb_outputs - 1]->graph = fg;
fg->outputs[fg->nb_outputs - 1]->out_tmp = cur;
fg->outputs[fg->nb_outputs - 1]->type = avfilter_pad_get_type(cur->filter_ctx->output_pads,
ofilter->graph = fg;
ofilter->out_tmp = cur;
ofilter->type = avfilter_pad_get_type(cur->filter_ctx->output_pads,
cur->pad_idx);
fg->outputs[fg->nb_outputs - 1]->name = describe_filter_link(fg, cur, 0);
ofilter->name = describe_filter_link(fg, cur, 0);
cur = cur->next;
fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL;
ofilter->out_tmp->next = NULL;
}
fail:
@ -453,12 +425,13 @@ static int insert_filter(AVFilterContext **last_filter, int *pad_idx,
static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
{
char *pix_fmts;
OutputStream *ost = ofilter->ost;
OutputFile *of = output_files[ost->file_index];
AVFilterContext *last_filter = out->filter_ctx;
AVBPrint bprint;
int pad_idx = out->pad_idx;
int ret;
const char *pix_fmts;
char name[255];
snprintf(name, sizeof(name), "out_%d_%d", ost->file_index, ost->index);
@ -469,10 +442,10 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
if (ret < 0)
return ret;
if (ofilter->width || ofilter->height) {
if ((ofilter->width || ofilter->height) && ofilter->ost->autoscale) {
char args[255];
AVFilterContext *filter;
AVDictionaryEntry *e = NULL;
const AVDictionaryEntry *e = NULL;
snprintf(args, sizeof(args), "%d:%d",
ofilter->width, ofilter->height);
@ -494,14 +467,14 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
pad_idx = 0;
}
if ((pix_fmts = choose_pix_fmts(ofilter))) {
av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
if ((pix_fmts = choose_pix_fmts(ofilter, &bprint))) {
AVFilterContext *filter;
snprintf(name, sizeof(name), "format_out_%d_%d",
ost->file_index, ost->index);
ret = avfilter_graph_create_filter(&filter,
avfilter_get_by_name("format"),
"format", pix_fmts, NULL, fg->graph);
av_freep(&pix_fmts);
av_bprint_finalize(&bprint, NULL);
if (ret < 0)
return ret;
if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
@ -552,7 +525,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
AVCodecContext *codec = ost->enc_ctx;
AVFilterContext *last_filter = out->filter_ctx;
int pad_idx = out->pad_idx;
char *sample_fmts, *sample_rates, *channel_layouts;
AVBPrint args;
char name[255];
int ret;
@ -575,79 +548,59 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
avfilter_get_by_name(filter_name), \
filter_name, arg, NULL, fg->graph); \
if (ret < 0) \
return ret; \
goto fail; \
\
ret = avfilter_link(last_filter, pad_idx, filt_ctx, 0); \
if (ret < 0) \
return ret; \
goto fail; \
\
last_filter = filt_ctx; \
pad_idx = 0; \
} while (0)
av_bprint_init(&args, 0, AV_BPRINT_SIZE_UNLIMITED);
if (ost->audio_channels_mapped) {
AVChannelLayout mapped_layout = { 0 };
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));
av_channel_layout_default(&mapped_layout, ost->audio_channels_mapped);
av_channel_layout_describe_bprint(&mapped_layout, &args);
for (i = 0; i < ost->audio_channels_mapped; i++)
if (ost->audio_channels_map[i] != -1)
av_bprintf(&pan_buf, "|c%d=c%d", i, ost->audio_channels_map[i]);
av_bprintf(&args, "|c%d=c%d", i, ost->audio_channels_map[i]);
AUTO_INSERT_FILTER("-map_channel", "pan", pan_buf.str);
av_bprint_finalize(&pan_buf, NULL);
AUTO_INSERT_FILTER("-map_channel", "pan", args.str);
av_bprint_clear(&args);
}
if (codec->channels && !codec->channel_layout)
codec->channel_layout = av_get_default_channel_layout(codec->channels);
if (codec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
av_channel_layout_default(&codec->ch_layout, codec->ch_layout.nb_channels);
sample_fmts = choose_sample_fmts(ofilter);
sample_rates = choose_sample_rates(ofilter);
channel_layouts = choose_channel_layouts(ofilter);
if (sample_fmts || sample_rates || channel_layouts) {
choose_sample_fmts(ofilter, &args);
choose_sample_rates(ofilter, &args);
choose_channel_layouts(ofilter, &args);
if (!av_bprint_is_complete(&args)) {
ret = AVERROR(ENOMEM);
goto fail;
}
if (args.len) {
AVFilterContext *format;
char args[256];
args[0] = 0;
if (sample_fmts)
av_strlcatf(args, sizeof(args), "sample_fmts=%s:",
sample_fmts);
if (sample_rates)
av_strlcatf(args, sizeof(args), "sample_rates=%s:",
sample_rates);
if (channel_layouts)
av_strlcatf(args, sizeof(args), "channel_layouts=%s:",
channel_layouts);
av_freep(&sample_fmts);
av_freep(&sample_rates);
av_freep(&channel_layouts);
snprintf(name, sizeof(name), "format_out_%d_%d",
ost->file_index, ost->index);
ret = avfilter_graph_create_filter(&format,
avfilter_get_by_name("aformat"),
name, args, NULL, fg->graph);
name, args.str, NULL, fg->graph);
if (ret < 0)
return ret;
goto fail;
ret = avfilter_link(last_filter, pad_idx, format, 0);
if (ret < 0)
return ret;
goto fail;
last_filter = format;
pad_idx = 0;
}
if (audio_volume != 256 && 0) {
char args[256];
snprintf(args, sizeof(args), "%f", audio_volume / 256.);
AUTO_INSERT_FILTER("-vol", "volume", args);
}
if (ost->apad && of->shortest) {
char args[256];
int i;
for (i=0; i<of->ctx->nb_streams; i++)
@ -655,8 +608,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
break;
if (i<of->ctx->nb_streams) {
snprintf(args, sizeof(args), "%s", ost->apad);
AUTO_INSERT_FILTER("-apad", "apad", args);
AUTO_INSERT_FILTER("-apad", "apad", ost->apad);
}
}
@ -665,15 +617,18 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
ret = insert_trim(of->start_time, of->recording_time,
&last_filter, &pad_idx, name);
if (ret < 0)
return ret;
goto fail;
if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
return ret;
goto fail;
fail:
av_bprint_finalize(&args, NULL);
return 0;
return ret;
}
int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
static int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter,
AVFilterInOut *out)
{
if (!ofilter->ost) {
av_log(NULL, AV_LOG_FATAL, "Filter %s has an unconnected output\n", ofilter->name);
@ -683,7 +638,7 @@ int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOu
switch (avfilter_pad_get_type(out->filter_ctx->output_pads, out->pad_idx)) {
case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fg, ofilter, out);
case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fg, ofilter, out);
default: av_assert0(0);
default: av_assert0(0); return 0;
}
}
@ -740,6 +695,12 @@ static int sub2video_prepare(InputStream *ist, InputFilter *ifilter)
return AVERROR(ENOMEM);
ist->sub2video.last_pts = INT64_MIN;
ist->sub2video.end_pts = INT64_MIN;
/* sub2video structure has been (re-)initialized.
Mark it as such so that the system will be
initialized with the first received heartbeat. */
ist->sub2video.initialize = 1;
return 0;
}
@ -748,6 +709,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
{
AVFilterContext *last_filter;
const AVFilter *buffer_filt = avfilter_get_by_name("buffer");
const AVPixFmtDescriptor *desc;
InputStream *ist = ifilter->ist;
InputFile *f = input_files[ist->file_index];
AVRational tb = ist->framerate.num ? av_inv_q(ist->framerate) :
@ -786,10 +748,9 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
av_bprintf(&args,
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:"
"pixel_aspect=%d/%d:sws_param=flags=%d",
"pixel_aspect=%d/%d",
ifilter->width, ifilter->height, ifilter->format,
tb.num, tb.den, sar.num, sar.den,
SWS_BILINEAR + ((ist->dec_ctx->flags&AV_CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0));
tb.num, tb.den, sar.num, sar.den);
if (fr.num && fr.den)
av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den);
snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
@ -806,44 +767,46 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
av_freep(&par);
last_filter = ifilter->filter;
if (ist->autorotate) {
double theta = get_rotation(ist->st);
desc = av_pix_fmt_desc_get(ifilter->format);
av_assert0(desc);
// TODO: insert hwaccel enabled filters like transpose_vaapi into the graph
if (ist->autorotate && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
int32_t *displaymatrix = ifilter->displaymatrix;
double theta;
if (!displaymatrix)
displaymatrix = (int32_t *)av_stream_get_side_data(ist->st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
theta = get_rotation(displaymatrix);
if (fabs(theta - 90) < 1.0) {
ret = insert_filter(&last_filter, &pad_idx, "transpose", "clock");
ret = insert_filter(&last_filter, &pad_idx, "transpose",
displaymatrix[3] > 0 ? "cclock_flip" : "clock");
} else if (fabs(theta - 180) < 1.0) {
ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
if (ret < 0)
return ret;
ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
if (displaymatrix[0] < 0) {
ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
if (ret < 0)
return ret;
}
if (displaymatrix[4] < 0) {
ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
}
} else if (fabs(theta - 270) < 1.0) {
ret = insert_filter(&last_filter, &pad_idx, "transpose", "cclock");
ret = insert_filter(&last_filter, &pad_idx, "transpose",
displaymatrix[3] < 0 ? "clock_flip" : "cclock");
} else if (fabs(theta) > 1.0) {
char rotate_buf[64];
snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
ret = insert_filter(&last_filter, &pad_idx, "rotate", rotate_buf);
} else if (fabs(theta) < 1.0) {
if (displaymatrix && displaymatrix[4] < 0) {
ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
}
}
if (ret < 0)
return ret;
}
if (do_deinterlace) {
AVFilterContext *yadif;
snprintf(name, sizeof(name), "deinterlace_in_%d_%d",
ist->file_index, ist->st->index);
if ((ret = avfilter_graph_create_filter(&yadif,
avfilter_get_by_name("yadif"),
name, "", NULL,
fg->graph)) < 0)
return ret;
if ((ret = avfilter_link(last_filter, 0, yadif, 0)) < 0)
return ret;
last_filter = yadif;
}
snprintf(name, sizeof(name), "trim_in_%d_%d",
ist->file_index, ist->st->index);
if (copy_ts) {
@ -888,11 +851,12 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
1, ifilter->sample_rate,
ifilter->sample_rate,
av_get_sample_fmt_name(ifilter->format));
if (ifilter->channel_layout)
av_bprintf(&args, ":channel_layout=0x%"PRIx64,
ifilter->channel_layout);
else
av_bprintf(&args, ":channels=%d", ifilter->channels);
if (av_channel_layout_check(&ifilter->ch_layout) &&
ifilter->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
av_bprintf(&args, ":channel_layout=");
av_channel_layout_describe_bprint(&ifilter->ch_layout, &args);
} else
av_bprintf(&args, ":channels=%d", ifilter->ch_layout.nb_channels);
snprintf(name, sizeof(name), "graph_%d_in_%d_%d", fg->index,
ist->file_index, ist->st->index);
@ -988,7 +952,7 @@ static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter,
switch (avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx)) {
case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, ifilter, in);
case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, ifilter, in);
default: av_assert0(0);
default: av_assert0(0); return 0;
}
}
@ -1002,6 +966,30 @@ static void cleanup_filtergraph(FilterGraph *fg)
avfilter_graph_free(&fg->graph);
}
static int filter_is_buffersrc(const AVFilterContext *f)
{
return f->nb_inputs == 0 &&
(!strcmp(f->filter->name, "buffer") ||
!strcmp(f->filter->name, "abuffer"));
}
static int graph_is_meta(AVFilterGraph *graph)
{
for (unsigned i = 0; i < graph->nb_filters; i++) {
const AVFilterContext *f = graph->filters[i];
/* in addition to filters flagged as meta, also
* disregard sinks and buffersources (but not other sources,
* since they introduce data we are not aware of)
*/
if (!((f->filter->flags & AVFILTER_FLAG_METADATA_ONLY) ||
f->nb_outputs == 0 ||
filter_is_buffersrc(f)))
return 0;
}
return 1;
}
int configure_filtergraph(FilterGraph *fg)
{
AVFilterInOut *inputs, *outputs, *cur;
@ -1016,20 +1004,31 @@ int configure_filtergraph(FilterGraph *fg)
if (simple) {
OutputStream *ost = fg->outputs[0]->ost;
char args[512];
AVDictionaryEntry *e = NULL;
const AVDictionaryEntry *e = NULL;
fg->graph->nb_threads = filter_nbthreads;
if (filter_nbthreads) {
ret = av_opt_set(fg->graph, "threads", filter_nbthreads, 0);
if (ret < 0)
goto fail;
} else {
e = av_dict_get(ost->encoder_opts, "threads", NULL, 0);
if (e)
av_opt_set(fg->graph, "threads", e->value, 0);
}
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))
if (strlen(args)) {
args[strlen(args)-1] = 0;
fg->graph->scale_sws_opts = av_strdup(args);
fg->graph->scale_sws_opts = av_strdup(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);
@ -1037,18 +1036,6 @@ int configure_filtergraph(FilterGraph *fg)
if (strlen(args))
args[strlen(args)-1] = 0;
av_opt_set(fg->graph, "aresample_swr_opts", args, 0);
args[0] = '\0';
while ((e = av_dict_get(fg->outputs[0]->ost->resample_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';
e = av_dict_get(ost->encoder_opts, "threads", NULL, 0);
if (e)
av_opt_set(fg->graph, "threads", e->value, 0);
} else {
fg->graph->nb_threads = filter_complex_nbthreads;
}
@ -1056,17 +1043,9 @@ int configure_filtergraph(FilterGraph *fg)
if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
goto fail;
if (filter_hw_device || hw_device_ctx) {
AVBufferRef *device = filter_hw_device ? filter_hw_device->device_ref
: hw_device_ctx;
for (i = 0; i < fg->graph->nb_filters; i++) {
fg->graph->filters[i]->hw_device_ctx = av_buffer_ref(device);
if (!fg->graph->filters[i]->hw_device_ctx) {
ret = AVERROR(ENOMEM);
goto fail;
}
}
}
ret = hw_device_setup_for_filter(fg);
if (ret < 0)
goto fail;
if (simple && (!inputs || inputs->next || !outputs || outputs->next)) {
const char *num_inputs;
@ -1106,9 +1085,13 @@ int configure_filtergraph(FilterGraph *fg)
configure_output_filter(fg, fg->outputs[i], cur);
avfilter_inout_free(&outputs);
if (!auto_conversion_filters)
avfilter_graph_set_auto_convert(fg->graph, AVFILTER_AUTO_CONVERT_NONE);
if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
goto fail;
fg->is_meta = graph_is_meta(fg->graph);
/* limit the lists of allowed formats to the ones selected, to
* make sure they stay the same if the filtergraph is reconfigured later */
for (i = 0; i < fg->nb_outputs; i++) {
@ -1121,7 +1104,10 @@ int configure_filtergraph(FilterGraph *fg)
ofilter->height = av_buffersink_get_h(sink);
ofilter->sample_rate = av_buffersink_get_sample_rate(sink);
ofilter->channel_layout = av_buffersink_get_channel_layout(sink);
av_channel_layout_uninit(&ofilter->ch_layout);
ret = av_buffersink_get_ch_layout(sink, &ofilter->ch_layout);
if (ret < 0)
goto fail;
}
fg->reconfiguration = 1;
@ -1143,9 +1129,8 @@ int configure_filtergraph(FilterGraph *fg)
}
for (i = 0; i < fg->nb_inputs; i++) {
while (av_fifo_size(fg->inputs[i]->frame_queue)) {
AVFrame *tmp;
av_fifo_generic_read(fg->inputs[i]->frame_queue, &tmp, sizeof(tmp), NULL);
AVFrame *tmp;
while (av_fifo_read(fg->inputs[i]->frame_queue, &tmp, 1) >= 0) {
ret = av_buffersrc_add_frame(fg->inputs[i]->filter, tmp);
av_frame_free(&tmp);
if (ret < 0)
@ -1166,10 +1151,9 @@ int configure_filtergraph(FilterGraph *fg)
for (i = 0; i < fg->nb_inputs; i++) {
InputStream *ist = fg->inputs[i]->ist;
if (ist->sub2video.sub_queue && ist->sub2video.frame) {
while (av_fifo_size(ist->sub2video.sub_queue)) {
AVSubtitle tmp;
av_fifo_generic_read(ist->sub2video.sub_queue, &tmp, sizeof(tmp), NULL);
sub2video_update(ist, &tmp);
AVSubtitle tmp;
while (av_fifo_read(ist->sub2video.sub_queue, &tmp, 1) >= 0) {
sub2video_update(ist, INT64_MIN, &tmp);
avsubtitle_free(&tmp);
}
}
@ -1184,6 +1168,9 @@ fail:
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
{
AVFrameSideData *sd;
int ret;
av_buffer_unref(&ifilter->hw_frames_ctx);
ifilter->format = frame->format;
@ -1193,8 +1180,14 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
ifilter->sample_aspect_ratio = frame->sample_aspect_ratio;
ifilter->sample_rate = frame->sample_rate;
ifilter->channels = frame->channels;
ifilter->channel_layout = frame->channel_layout;
ret = av_channel_layout_copy(&ifilter->ch_layout, &frame->ch_layout);
if (ret < 0)
return ret;
av_freep(&ifilter->displaymatrix);
sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
if (sd)
ifilter->displaymatrix = av_memdup(sd->data, sizeof(int32_t) * 9);
if (frame->hw_frames_ctx) {
ifilter->hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx);
@ -1205,15 +1198,6 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
return 0;
}
int ist_in_filtergraph(FilterGraph *fg, InputStream *ist)
{
int i;
for (i = 0; i < fg->nb_inputs; i++)
if (fg->inputs[i]->ist == ist)
return 1;
return 0;
}
int filtergraph_is_simple(FilterGraph *fg)
{
return !fg->graph_desc;

View File

@ -19,6 +19,8 @@
#include <string.h>
#include "libavutil/avstring.h"
#include "libavutil/pixdesc.h"
#include "libavfilter/buffersink.h"
#include "ffmpeg.h"
@ -91,6 +93,8 @@ static char *hw_device_default_name(enum AVHWDeviceType type)
int hw_device_init_from_string(const char *arg, HWDevice **dev_out)
{
// "type=name"
// "type=name,key=value,key2=value2"
// "type=name:device,key=value,key2=value2"
// "type:device,key=value,key2=value2"
// -> av_hwdevice_ctx_create()
@ -122,7 +126,7 @@ int hw_device_init_from_string(const char *arg, HWDevice **dev_out)
}
if (*p == '=') {
k = strcspn(p + 1, ":@");
k = strcspn(p + 1, ":@,");
name = av_strndup(p + 1, k);
if (!name) {
@ -188,6 +192,18 @@ int hw_device_init_from_string(const char *arg, HWDevice **dev_out)
src->device_ref, 0);
if (err < 0)
goto fail;
} else if (*p == ',') {
err = av_dict_parse_string(&options, p + 1, "=", ",", 0);
if (err < 0) {
errmsg = "failed to parse options";
goto invalid;
}
err = av_hwdevice_ctx_create(&device_ref, type,
NULL, options, 0);
if (err < 0)
goto fail;
} else {
errmsg = "parse error";
goto invalid;
@ -337,6 +353,18 @@ int hw_device_setup_for_decode(InputStream *ist)
} else if (ist->hwaccel_id == HWACCEL_GENERIC) {
type = ist->hwaccel_device_type;
dev = hw_device_get_by_type(type);
// When "-qsv_device device" is used, an internal QSV device named
// as "__qsv_device" is created. Another QSV device is created too
// if "-init_hw_device qsv=name:device" is used. There are 2 QSV devices
// if both "-qsv_device device" and "-init_hw_device qsv=name:device"
// are used, hw_device_get_by_type(AV_HWDEVICE_TYPE_QSV) returns NULL.
// To keep back-compatibility with the removed ad-hoc libmfx setup code,
// call hw_device_get_by_name("__qsv_device") to select the internal QSV
// device.
if (!dev && type == AV_HWDEVICE_TYPE_QSV)
dev = hw_device_get_by_name("__qsv_device");
if (!dev)
err = hw_device_init_from_type(type, NULL, &dev);
} else {
@ -416,18 +444,57 @@ int hw_device_setup_for_decode(InputStream *ist)
int hw_device_setup_for_encode(OutputStream *ost)
{
HWDevice *dev;
const AVCodecHWConfig *config;
HWDevice *dev = NULL;
AVBufferRef *frames_ref = NULL;
int i;
if (ost->filter) {
frames_ref = av_buffersink_get_hw_frames_ctx(ost->filter->filter);
if (frames_ref &&
((AVHWFramesContext*)frames_ref->data)->format ==
ost->enc_ctx->pix_fmt) {
// Matching format, will try to use hw_frames_ctx.
} else {
frames_ref = NULL;
}
}
for (i = 0;; i++) {
config = avcodec_get_hw_config(ost->enc, i);
if (!config)
break;
if (frames_ref &&
config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX &&
(config->pix_fmt == AV_PIX_FMT_NONE ||
config->pix_fmt == ost->enc_ctx->pix_fmt)) {
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->name);
ost->enc_ctx->hw_frames_ctx = av_buffer_ref(frames_ref);
if (!ost->enc_ctx->hw_frames_ctx)
return AVERROR(ENOMEM);
return 0;
}
if (!dev &&
config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)
dev = hw_device_get_by_type(config->device_type);
}
dev = hw_device_match_by_codec(ost->enc);
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->name);
ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
if (!ost->enc_ctx->hw_device_ctx)
return AVERROR(ENOMEM);
return 0;
} else {
// No device required, or no device available.
return 0;
}
return 0;
}
static int hwaccel_retrieve_data(AVCodecContext *avctx, AVFrame *input)
@ -480,3 +547,37 @@ int hwaccel_decode_init(AVCodecContext *avctx)
return 0;
}
int hw_device_setup_for_filter(FilterGraph *fg)
{
HWDevice *dev;
int i;
// Pick the last hardware device if the user doesn't pick the device for
// filters explicitly with the filter_hw_device option.
if (filter_hw_device)
dev = filter_hw_device;
else if (nb_hw_devices > 0) {
dev = hw_devices[nb_hw_devices - 1];
if (nb_hw_devices > 1)
av_log(NULL, AV_LOG_WARNING, "There are %d hardware devices. device "
"%s of type %s is picked for filters by default. Set hardware "
"device explicitly with the filter_hw_device option if device "
"%s is not usable for filters.\n",
nb_hw_devices, dev->name,
av_hwdevice_get_type_name(dev->type), dev->name);
} else
dev = NULL;
if (dev) {
for (i = 0; i < fg->graph->nb_filters; i++) {
fg->graph->filters[i]->hw_device_ctx =
av_buffer_ref(dev->device_ref);
if (!fg->graph->filters[i]->hw_device_ctx)
return AVERROR(ENOMEM);
}
}
return 0;
}

317
fftools/ffmpeg_mux.c Normal file
View File

@ -0,0 +1,317 @@
/*
* 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 <stdio.h>
#include <string.h>
#include "ffmpeg.h"
#include "libavutil/fifo.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/mem.h"
#include "libavutil/timestamp.h"
#include "libavcodec/packet.h"
#include "libavformat/avformat.h"
#include "libavformat/avio.h"
static void close_all_output_streams(OutputStream *ost, OSTFinished this_stream, OSTFinished others)
{
int i;
for (i = 0; i < nb_output_streams; i++) {
OutputStream *ost2 = output_streams[i];
ost2->finished |= ost == ost2 ? this_stream : others;
}
}
void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
int unqueue)
{
AVFormatContext *s = of->ctx;
AVStream *st = ost->st;
int ret;
/*
* 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 (!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(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),
ost->mux_timebase);
}
}
av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base);
if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
if (pkt->dts != AV_NOPTS_VALUE &&
pkt->pts != AV_NOPTS_VALUE &&
pkt->dts > pkt->pts) {
av_log(s, AV_LOG_WARNING, "Invalid DTS: %"PRId64" PTS: %"PRId64" in output stream %d:%d, replacing by guess\n",
pkt->dts, pkt->pts,
ost->file_index, ost->st->index);
pkt->pts =
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 &&
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, ost->last_mux_dts, pkt->dts);
if (exit_on_error) {
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);
if (pkt->pts >= pkt->dts)
pkt->pts = FFMAX(pkt->pts, max);
pkt->dts = max;
}
}
}
ost->last_mux_dts = pkt->dts;
ost->data_size += pkt->size;
ost->packets_written++;
pkt->stream_index = ost->index;
if (debug_ts) {
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(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),
pkt->size
);
}
ret = av_interleaved_write_frame(s, pkt);
if (ret < 0) {
print_error("av_interleaved_write_frame()", ret);
main_return_code = 1;
close_all_output_streams(ost, MUXER_FINISHED | ENCODER_FINISHED, ENCODER_FINISHED);
}
}
static int print_sdp(void)
{
char sdp[16384];
int i;
int j, ret;
AVIOContext *sdp_pb;
AVFormatContext **avc;
for (i = 0; i < nb_output_files; i++) {
if (!output_files[i]->header_written)
return 0;
}
avc = av_malloc_array(nb_output_files, sizeof(*avc));
if (!avc)
exit_program(1);
for (i = 0, j = 0; i < nb_output_files; i++) {
if (!strcmp(output_files[i]->ctx->oformat->name, "rtp")) {
avc[j] = output_files[i]->ctx;
j++;
}
}
if (!j) {
av_log(NULL, AV_LOG_ERROR, "No output streams in the SDP.\n");
ret = AVERROR(EINVAL);
goto fail;
}
ret = av_sdp_create(avc, j, sdp, sizeof(sdp));
if (ret < 0)
goto fail;
if (!sdp_filename) {
printf("SDP:\n%s\n", sdp);
fflush(stdout);
} else {
ret = avio_open2(&sdp_pb, sdp_filename, AVIO_FLAG_WRITE, &int_cb, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Failed to open sdp file '%s'\n", sdp_filename);
goto fail;
}
avio_print(sdp_pb, sdp);
avio_closep(&sdp_pb);
av_freep(&sdp_filename);
}
fail:
av_freep(&avc);
return ret;
}
/* open the muxer when all the streams are initialized */
int of_check_init(OutputFile *of)
{
int ret, 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(of->ctx, &of->opts);
if (ret < 0) {
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);
of->header_written = 1;
av_dump_format(of->ctx, of->index, of->ctx->url, 1);
nb_output_dumped++;
if (sdp_filename || want_sdp) {
ret = print_sdp();
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error writing the SDP.\n");
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;
}
int of_write_trailer(OutputFile *of)
{
int ret;
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 = av_write_trailer(of->ctx);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", of->ctx->url, av_err2str(ret));
return ret;
}
return 0;
}
void of_close(OutputFile **pof)
{
OutputFile *of = *pof;
AVFormatContext *s;
if (!of)
return;
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);
}

Some files were not shown because too many files have changed in this diff Show More