mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-08 07:49:59 +01:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18ce5a4d1b | ||
|
|
cf09348b9e | ||
|
|
970f2ad966 | ||
|
|
104c357b6a | ||
|
|
b2a74dd629 | ||
|
|
182cfe4832 | ||
|
|
e5d434b840 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1,2 +1 @@
|
|||||||
*.pnm -diff -text
|
*.pnm -diff -text
|
||||||
tests/ref/fate/sub-scc eol=crlf
|
|
||||||
|
|||||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -18,13 +18,6 @@
|
|||||||
*.so.*
|
*.so.*
|
||||||
*.swp
|
*.swp
|
||||||
*.ver
|
*.ver
|
||||||
*.version
|
|
||||||
*.metal.air
|
|
||||||
*.metallib
|
|
||||||
*.metallib.c
|
|
||||||
*.ptx
|
|
||||||
*.ptx.c
|
|
||||||
*.ptx.gz
|
|
||||||
*_g
|
*_g
|
||||||
\#*
|
\#*
|
||||||
.\#*
|
.\#*
|
||||||
@@ -33,11 +26,10 @@
|
|||||||
/ffmpeg
|
/ffmpeg
|
||||||
/ffplay
|
/ffplay
|
||||||
/ffprobe
|
/ffprobe
|
||||||
/config.asm
|
/ffserver
|
||||||
/config.h
|
/config.*
|
||||||
/coverage.info
|
/coverage.info
|
||||||
/avversion.h
|
/avversion.h
|
||||||
/lcov/
|
/lcov/
|
||||||
/src
|
/src
|
||||||
/mapfile
|
/mapfile
|
||||||
/tools/python/__pycache__/
|
|
||||||
|
|||||||
25
.mailmap
25
.mailmap
@@ -1,25 +0,0 @@
|
|||||||
<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>
|
|
||||||
10
.travis.yml
10
.travis.yml
@@ -6,22 +6,18 @@ os:
|
|||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- nasm
|
- yasm
|
||||||
- diffutils
|
- diffutils
|
||||||
compiler:
|
compiler:
|
||||||
- clang
|
- clang
|
||||||
- gcc
|
- gcc
|
||||||
matrix:
|
|
||||||
exclude:
|
|
||||||
- os: osx
|
|
||||||
compiler: gcc
|
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
- ffmpeg-samples
|
- ffmpeg-samples
|
||||||
before_install:
|
before_install:
|
||||||
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update; fi
|
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update --all; fi
|
||||||
install:
|
install:
|
||||||
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install nasm; fi
|
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install yasm; fi
|
||||||
script:
|
script:
|
||||||
- mkdir -p ffmpeg-samples
|
- mkdir -p ffmpeg-samples
|
||||||
- ./configure --samples=ffmpeg-samples --cc=$CC
|
- ./configure --samples=ffmpeg-samples --cc=$CC
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
# Note to Github users
|
|
||||||
Patches should be submitted to the [ffmpeg-devel mailing list](https://ffmpeg.org/mailman/listinfo/ffmpeg-devel) using `git format-patch` or `git send-email`. Github pull requests should be avoided because they are not part of our review process and **will be ignored**.
|
|
||||||
|
|
||||||
See [https://ffmpeg.org/developer.html#Contributing](https://ffmpeg.org/developer.html#Contributing) for more information.
|
|
||||||
651
Changelog
651
Changelog
@@ -1,655 +1,7 @@
|
|||||||
Entries are sorted chronologically from oldest to youngest within each release,
|
Entries are sorted chronologically from oldest to youngest within each release,
|
||||||
releases are sorted from youngest to oldest.
|
releases are sorted from youngest to oldest.
|
||||||
|
|
||||||
version 5.0.2:
|
version <next>:
|
||||||
- swscale: aarch64: Fix yuv2rgb with negative strides
|
|
||||||
- avcodec/atrac3plusdec: fix compilation failure after last commit
|
|
||||||
- avcodec/atrac3plus: reorder channels to match the output layout
|
|
||||||
- avcodec/aacdec: fix parsing streams with channel configuration 11
|
|
||||||
- Changelog: update
|
|
||||||
- avcodec/speexdec: Check channels > 2
|
|
||||||
- avformat/vividas: Check packet size
|
|
||||||
- avcodec/dstdec: Check for overflow in build_filter()
|
|
||||||
- avformat/spdifdec: Use 64bit to compute bit rate
|
|
||||||
- avformat/rpl: Use 64bit for duration computation
|
|
||||||
- avformat/xwma: Use av_rescale() for duration computation
|
|
||||||
- avformat/sdsdec: Use av_rescale() to avoid intermediate overflow in duration calculation
|
|
||||||
- avformat/sbgdec: Check ts_int in genrate_intervals
|
|
||||||
- avformat/sbgdec: clamp end_ts
|
|
||||||
- avformat/rmdec: check tag_size
|
|
||||||
- avformat/nutdec: Check fields
|
|
||||||
- avformat/flvdec: Use 64bit for sum_flv_tag_size
|
|
||||||
- avformat/jacosubdec: Fix overflow in get_shift()
|
|
||||||
- avformat/dxa: avoid bpc overflows
|
|
||||||
- avformat/dhav: Use 64bit seek_back
|
|
||||||
- avformat/cafdec: Check that nb_frasmes fits within 64bit
|
|
||||||
- avformat/asfdec_o: Limit packet offset
|
|
||||||
- avformat/ape: Check frames size
|
|
||||||
- avformat/icodec: Check nb_pal
|
|
||||||
- avformat/aiffdec: Use 64bit for block_duration use
|
|
||||||
- avformat/aiffdec: Check block_duration
|
|
||||||
- avformat/mxfdec: only probe max run in
|
|
||||||
- avformat/mxfdec: Check run_in is within 65536
|
|
||||||
- avcodec/mjpegdec: Check for unsupported bayer case
|
|
||||||
- avcodec/apedec: Fix integer overflow in filter_3800()
|
|
||||||
- avcodec/tta: Check 24bit scaling for overflow
|
|
||||||
- avcodec/mobiclip: Check quantizer for overflow
|
|
||||||
- avcodec/exr: Check preview psize
|
|
||||||
- avcodec/tiff: Fix loop detection
|
|
||||||
- libavformat/hls: Free keys
|
|
||||||
- avcodec/fmvc: Move frame allocation to a later stage
|
|
||||||
- avfilter/vf_showinfo: remove backspaces
|
|
||||||
- avcodec/speedhq: Check width
|
|
||||||
- avcodec/bink: disallow odd positioned scaled blocks
|
|
||||||
- libswscale: force a minimum size of the slide for bayer sources
|
|
||||||
- lavc/videotoolbox: do not pass AVCodecContext to decoder output callback
|
|
||||||
- lavc/pthread_frame: always transfer stashed hwaccel state
|
|
||||||
- avformat/cafenc: derive Opus frame size from the relevant stream parameters
|
|
||||||
- avcodec/arm/sbcenc: avoid callee preserved vfp registers
|
|
||||||
- avfilter/vf_scale: overwrite the width and height expressions with the original values
|
|
||||||
- lavc/pthread_frame: avoid leaving stale hwaccel state in worker threads
|
|
||||||
- Update for 5.0.2
|
|
||||||
- avformat/asfdec_o: limit recursion depth in asf_read_unknown()
|
|
||||||
- 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/hevc_filter: copy_CTB() only within width&height
|
|
||||||
- avcodec/tiff: Check tile_length and tile_width
|
|
||||||
- avcodec/mss4: Check image size with av_image_check_size2()
|
|
||||||
- avformat/flvdec: Check for EOF in index reading
|
|
||||||
- avformat/nutdec: Check get_packetheader() in mainheader
|
|
||||||
- avformat/asfdec_f: Use 64bit for packet start time
|
|
||||||
- avcodec/exr: Check x/ysize
|
|
||||||
- tools/target_dec_fuzzer: Adjust threshold for MMVIDEO
|
|
||||||
- avcodec/lagarith: Check dst/src in zero run code
|
|
||||||
- avcodec/h264dec: Skip late SEI
|
|
||||||
- avcodec/sbrdsp_fixed: Fix integer overflows in sbr_qmf_deint_neg_c()
|
|
||||||
- avfilter/vf_signature: Fix integer overflow in filter_frame()
|
|
||||||
- avformat/rtsp: break on unknown protocols
|
|
||||||
- avcodec/hevcdsp_template: stay within tables in sao_band_filter()
|
|
||||||
- avcodec/tiff: Check pixel format types for dng
|
|
||||||
- avcodec/qpeldsp: copy less for the mc0x cases
|
|
||||||
- avformat/aaxdec: Check for empty segments
|
|
||||||
- avcodec/ffv1dec: Limit golomb rice coded slices to width 8M
|
|
||||||
- avformat/iff: simplify duration calculation
|
|
||||||
- avcodec/wnv1: Check for width =1
|
|
||||||
- avcodec/ffv1dec_template: fix indention
|
|
||||||
- avformat/sctp: close socket on errors
|
|
||||||
- avformat/cinedec: Check size and pos more
|
|
||||||
- avcodec/aasc: Fix indention
|
|
||||||
- avcodec/qdrw: adjust max colors to array size
|
|
||||||
- avcodec/alacdsp: Make intermediates unsigned
|
|
||||||
- avformat/aiffdec: cleanup size handling for extreem cases
|
|
||||||
- avformat/matroskadec: avoid integer overflows in SAR computation
|
|
||||||
- avcodec/jpeglsdec: fix end check for xfrm
|
|
||||||
- avcodec/cdgraphics: limit scrolling to the line
|
|
||||||
- avformat/hls: Limit start_seq_no to one bit less
|
|
||||||
- avformat/aiffdec: avoid integer overflow in get_meta()
|
|
||||||
- avformat/aaxdec: Check for overlaping segments
|
|
||||||
- avformat/ape: more bits in size for less overflows
|
|
||||||
- avformat/aviobuf: Check buf_size in ffio_ensure_seekback()
|
|
||||||
- avformat/bfi: Check offsets better
|
|
||||||
- avformat/asfdec_f: Check packet_frag_timestamp
|
|
||||||
- avcodec/texturedspenc: Fix indexing in color distribution determination
|
|
||||||
- avformat/act: Check ff_get_wav_header() for failure
|
|
||||||
- avcodec/libxavs2: Improve r redundancy in occured
|
|
||||||
- avformat/libzmq: Improve r redundancy in occured
|
|
||||||
- avfilter/vf_libplacebo: Match AV_OPT_TYPE_FLOAT to dbl
|
|
||||||
- avfilter/vsrc_mandelbrot: Check for malloc failure
|
|
||||||
- avfilter/vf_frei0r: Copy to frame allocated according to frei0r requirements
|
|
||||||
- avfilter/video: Add ff_default_get_video_buffer2() to set specific alignment
|
|
||||||
- avformat/genh: Check sample rate
|
|
||||||
- avformat/demux: Use unsigned to check duration vs duration_text
|
|
||||||
- avutil/hwcontext_d3d11va: fix texture_infos writes on non-fixed-size pools
|
|
||||||
- avcodec/cuviddec: fix null pointer dereference
|
|
||||||
- avcodec/cuviddec: fix AV1 decoding error
|
|
||||||
- configure: extend SDL check to accept all 2.x versions
|
|
||||||
- lavf/tls_mbedtls: add support for mbedtls version 3
|
|
||||||
- fate: update reference files after the recent dash manifest muxer changes
|
|
||||||
- avformat/webmdashenc: fix on-demand profile string
|
|
||||||
- avcodec/libdav1d: don't depend on the event flags API to init sequence params the first time
|
|
||||||
|
|
||||||
version 5.0.1:
|
|
||||||
- avcodec/exr: Avoid signed overflow in displayWindow
|
|
||||||
- avcodec/diracdec: avoid signed integer overflow in global mv
|
|
||||||
- avcodec/takdsp: Fix integer overflow in decorrelate_sf()
|
|
||||||
- avcodec/apedec: fix a integer overflow in long_filter_high_3800()
|
|
||||||
- avdevice/dshow: fix regression
|
|
||||||
- avfilter/vf_subtitles: pass storage size to libass
|
|
||||||
- avcodec/vp9_superframe_split_bsf: Don't read inexistent data
|
|
||||||
- avcodec/vp9_superframe_split_bsf: Discard invalid zero-sized frames
|
|
||||||
- avcodec/vp9_superframe_bsf: Check for existence of data before reading it
|
|
||||||
- avcodec/vp9_raw_reorder_bsf: Check for existence of data before reading it
|
|
||||||
- avformat/imf: fix packet pts, dts and muxing
|
|
||||||
- avformat/imf: open resources only when first needed
|
|
||||||
- avformat/imf: cosmetics
|
|
||||||
- avformat/imf_cpl: do not use filesize when reading XML file
|
|
||||||
- avformat/imfdec: Use proper logcontext
|
|
||||||
- avformat/imfdec: do not use filesize when reading XML file
|
|
||||||
- doc/utils: add missing 22.2 layout entry
|
|
||||||
- avcodec/av1: only set the private context pix_fmt field if get_pixel_format() succeeds
|
|
||||||
- avformat/aqtitledec: Skip unrepresentable durations
|
|
||||||
- avformat/cafdec: Do not store empty keys in read_info_chunk()
|
|
||||||
- avformat/mxfdec: Do not clear array in mxf_read_strong_ref_array() before writing
|
|
||||||
- avformat/mxfdec: Check for avio_read() failure in mxf_read_strong_ref_array()
|
|
||||||
- avformat/mxfdec: Check count in mxf_read_strong_ref_array()
|
|
||||||
- avformat/hls: Check target_duration
|
|
||||||
- avcodec/pixlet: Avoid signed integer overflow in scaling in filterfn()
|
|
||||||
- avformat/matroskadec: Check pre_ns
|
|
||||||
- avcodec/sonic: Use unsigned for predictor_k to avoid undefined behavior
|
|
||||||
- avcodec/libuavs3d: Check ff_set_dimensions() for failure
|
|
||||||
- avcodec/speexdec: Align some comments
|
|
||||||
- avcodec/speexdec: Use correct doxygen comments
|
|
||||||
- avcodec/mjpegbdec: Set buf_size
|
|
||||||
- avformat/matroskadec: Use rounded down duration in get_cue_desc() check
|
|
||||||
- avcodec/argo: Check packet size
|
|
||||||
- avcodec/g729_parser: Check channels
|
|
||||||
- avformat/avidec: Check height
|
|
||||||
- avformat/rmdec: Better duplicate tags check
|
|
||||||
- avformat/mov: Disallow empty sidx
|
|
||||||
- avformat/argo_cvg:: Fix order of operations in error check in argo_cvg_write_trailer()
|
|
||||||
- avformat/argo_asf: Fix order of operations in error check in argo_asf_write_trailer()
|
|
||||||
- avcodec/movtextdec: add () to CMP() macro to avoid unexpected behavior
|
|
||||||
- avformat/matroskadec: Check duration
|
|
||||||
- avformat/mov: Corner case encryption error cleanup in mov_read_senc()
|
|
||||||
- avcodec/jpeglsdec: Fix if( code style
|
|
||||||
- avcodec/jpeglsdec: Check get_ur_golomb_jpegls() for error
|
|
||||||
- avcodec/motion_est: fix indention of ff_get_best_fcode()
|
|
||||||
- avcodec/motion_est: Fix xy indexing on range violation in ff_get_best_fcode()
|
|
||||||
- avformat/hls: Use unsigned for iv computation
|
|
||||||
- avcodec/jpeglsdec: Increase range for N in ls_get_code_runterm() by using unsigned
|
|
||||||
- avformat/matroskadec: Check desc_bytes
|
|
||||||
- avformat/utils: Fix invalid NULL pointer operation in ff_parse_key_value()
|
|
||||||
- avformat/matroskadec: Fix infinite loop with bz decompression
|
|
||||||
- avformat/utils: keep chapter monotonicity on chapter updates
|
|
||||||
- avformat/mov: Check size before subtraction
|
|
||||||
- avcodec/cfhd: Avoid signed integer overflow in coeff
|
|
||||||
- avcodec/libdav1d: free the Dav1dData packet on dav1d_send_data() failure
|
|
||||||
- avcodec/h264_parser: don't alter decoder private data
|
|
||||||
- configure: link to libatomic when it's present
|
|
||||||
- fate/ffmpeg: add missing samples dependency to fate-shortest
|
|
||||||
|
|
||||||
|
|
||||||
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:
|
|
||||||
- tpad filter
|
|
||||||
- AV1 decoding support through libdav1d
|
|
||||||
- dedot filter
|
|
||||||
- chromashift and rgbashift filters
|
|
||||||
- freezedetect filter
|
|
||||||
- truehd_core bitstream filter
|
|
||||||
- dhav demuxer
|
|
||||||
- PCM-DVD encoder
|
|
||||||
- GIF parser
|
|
||||||
- vividas demuxer
|
|
||||||
- hymt decoder
|
|
||||||
- anlmdn filter
|
|
||||||
- maskfun filter
|
|
||||||
- hcom demuxer and decoder
|
|
||||||
- ARBC decoder
|
|
||||||
- libaribb24 based ARIB STD-B24 caption support (profiles A and C)
|
|
||||||
- Support decoding of HEVC 4:4:4 content in nvdec and cuviddec
|
|
||||||
- removed libndi-newtek
|
|
||||||
- agm decoder
|
|
||||||
- KUX demuxer
|
|
||||||
- AV1 frame split bitstream filter
|
|
||||||
- lscr decoder
|
|
||||||
- lagfun filter
|
|
||||||
- asoftclip filter
|
|
||||||
- Support decoding of HEVC 4:4:4 content in vdpau
|
|
||||||
- colorhold filter
|
|
||||||
- xmedian filter
|
|
||||||
- asr filter
|
|
||||||
- showspatial multimedia filter
|
|
||||||
- VP4 video decoder
|
|
||||||
- IFV demuxer
|
|
||||||
- derain filter
|
|
||||||
- deesser filter
|
|
||||||
- mov muxer writes tracks with unspecified language instead of English by default
|
|
||||||
- add support for using clang to compile CUDA kernels
|
|
||||||
|
|
||||||
|
|
||||||
version 4.1:
|
|
||||||
- deblock filter
|
|
||||||
- tmix filter
|
|
||||||
- amplify filter
|
|
||||||
- fftdnoiz filter
|
|
||||||
- aderivative and aintegral audio filters
|
|
||||||
- pal75bars and pal100bars video filter sources
|
|
||||||
- support mbedTLS based TLS
|
|
||||||
- adeclick filter
|
|
||||||
- adeclip filter
|
|
||||||
- libtensorflow backend for DNN based filters like srcnn
|
|
||||||
- vc1 decoder is now bit-exact
|
|
||||||
- ATRAC9 decoder
|
|
||||||
- lensfun wrapper filter
|
|
||||||
- colorconstancy filter
|
|
||||||
- AVS2 video decoder via libdavs2
|
|
||||||
- IMM4 video decoder
|
|
||||||
- Brooktree ProSumer video decoder
|
|
||||||
- MatchWare Screen Capture Codec decoder
|
|
||||||
- WinCam Motion Video decoder
|
|
||||||
- 1D LUT filter (lut1d)
|
|
||||||
- RemotelyAnywhere Screen Capture decoder
|
|
||||||
- cue and acue filters
|
|
||||||
- support for AV1 in MP4
|
|
||||||
- transpose_npp filter
|
|
||||||
- AVS2 video encoder via libxavs2
|
|
||||||
- amultiply filter
|
|
||||||
- Block-Matching 3d (bm3d) denoising filter
|
|
||||||
- acrossover filter
|
|
||||||
- ilbc decoder
|
|
||||||
- audio denoiser as afftdn filter
|
|
||||||
- AV1 parser
|
|
||||||
- SER demuxer
|
|
||||||
- sinc audio filter source
|
|
||||||
- chromahold filter
|
|
||||||
- setparams filter
|
|
||||||
- vibrance filter
|
|
||||||
- decoding S12M timecode in h264
|
|
||||||
- xstack filter
|
|
||||||
- pcm vidc decoder and encoder
|
|
||||||
- (a)graphmonitor filter
|
|
||||||
- yadif_cuda filter
|
|
||||||
|
|
||||||
|
|
||||||
version 4.0:
|
|
||||||
- Bitstream filters for editing metadata in H.264, HEVC and MPEG-2 streams
|
|
||||||
- Dropped support for OpenJPEG versions 2.0 and below. Using OpenJPEG now
|
|
||||||
requires 2.1 (or later) and pkg-config.
|
|
||||||
- VDA dropped (use VideoToolbox instead)
|
|
||||||
- MagicYUV encoder
|
|
||||||
- Raw AMR-NB and AMR-WB demuxers
|
|
||||||
- TiVo ty/ty+ demuxer
|
|
||||||
- Intel QSV-accelerated MJPEG encoding
|
|
||||||
- PCE support for extended channel layouts in the AAC encoder
|
|
||||||
- native aptX and aptX HD encoder and decoder
|
|
||||||
- Raw aptX and aptX HD muxer and demuxer
|
|
||||||
- NVIDIA NVDEC-accelerated H.264, HEVC, MJPEG, MPEG-1/2/4, VC1, VP8/9 hwaccel decoding
|
|
||||||
- Intel QSV-accelerated overlay filter
|
|
||||||
- mcompand audio filter
|
|
||||||
- acontrast audio filter
|
|
||||||
- OpenCL overlay filter
|
|
||||||
- video mix filter
|
|
||||||
- video normalize filter
|
|
||||||
- audio lv2 wrapper filter
|
|
||||||
- VAAPI MJPEG and VP8 decoding
|
|
||||||
- AMD AMF H.264 and HEVC encoders
|
|
||||||
- video fillborders filter
|
|
||||||
- video setrange filter
|
|
||||||
- nsp demuxer
|
|
||||||
- support LibreSSL (via libtls)
|
|
||||||
- AVX-512/ZMM support added
|
|
||||||
- Dropped support for building for Windows XP. The minimum supported Windows
|
|
||||||
version is Windows Vista.
|
|
||||||
- deconvolve video filter
|
|
||||||
- entropy video filter
|
|
||||||
- hilbert audio filter source
|
|
||||||
- aiir audio filter
|
|
||||||
- aiff: add support for CD-ROM XA ADPCM
|
|
||||||
- Removed the ffserver program
|
|
||||||
- Removed the ffmenc and ffmdec muxer and demuxer
|
|
||||||
- VideoToolbox HEVC encoder and hwaccel
|
|
||||||
- VAAPI-accelerated ProcAmp (color balance), denoise and sharpness filters
|
|
||||||
- Add android_camera indev
|
|
||||||
- codec2 en/decoding via libcodec2
|
|
||||||
- muxer/demuxer for raw codec2 files and .c2 files
|
|
||||||
- Moved nvidia codec headers into an external repository.
|
|
||||||
They can be found at http://git.videolan.org/?p=ffmpeg/nv-codec-headers.git
|
|
||||||
- native SBC encoder and decoder
|
|
||||||
- drmeter audio filter
|
|
||||||
- hapqa_extract bitstream filter
|
|
||||||
- filter_units bitstream filter
|
|
||||||
- AV1 Support through libaom
|
|
||||||
- E-AC-3 dependent frames support
|
|
||||||
- bitstream filter for extracting E-AC-3 core
|
|
||||||
- Haivision SRT protocol via libsrt
|
|
||||||
- segafilm muxer
|
|
||||||
- vfrdet filter
|
|
||||||
- SRCNN filter
|
|
||||||
|
|
||||||
|
|
||||||
version 3.4:
|
|
||||||
- deflicker video filter
|
|
||||||
- doubleweave video filter
|
|
||||||
- lumakey video filter
|
|
||||||
- pixscope video filter
|
|
||||||
- oscilloscope video filter
|
|
||||||
- config.log and other configuration files moved into ffbuild/ directory
|
|
||||||
- update cuvid/nvenc headers to Video Codec SDK 8.0.14
|
|
||||||
- afir audio filter
|
|
||||||
- scale_cuda CUDA based video scale filter
|
|
||||||
- librsvg support for svg rasterization
|
|
||||||
- crossfeed audio filter
|
|
||||||
- spec compliant VP9 muxing support in MP4
|
|
||||||
- remove the libnut muxer/demuxer wrappers
|
|
||||||
- remove the libschroedinger encoder/decoder wrappers
|
|
||||||
- surround audio filter
|
|
||||||
- sofalizer filter switched to libmysofa
|
|
||||||
- Gremlin Digital Video demuxer and decoder
|
|
||||||
- headphone audio filter
|
|
||||||
- superequalizer audio filter
|
|
||||||
- roberts video filter
|
|
||||||
- The x86 assembler default switched from yasm to nasm, pass
|
|
||||||
--x86asmexe=yasm to configure to restore the old behavior.
|
|
||||||
- additional frame format support for Interplay MVE movies
|
|
||||||
- support for decoding through D3D11VA in ffmpeg
|
|
||||||
- limiter video filter
|
|
||||||
- libvmaf video filter
|
|
||||||
- Dolby E decoder and SMPTE 337M demuxer
|
|
||||||
- unpremultiply video filter
|
|
||||||
- tlut2 video filter
|
|
||||||
- floodfill video filter
|
|
||||||
- pseudocolor video filter
|
|
||||||
- raw G.726 muxer and demuxer, left- and right-justified
|
|
||||||
- NewTek NDI input/output device
|
|
||||||
- Some video filters with several inputs now use a common set of options:
|
|
||||||
blend, libvmaf, lut3d, overlay, psnr, ssim.
|
|
||||||
They must always be used by name.
|
|
||||||
- FITS demuxer and decoder
|
|
||||||
- FITS muxer and encoder
|
|
||||||
- add --disable-autodetect build switch
|
|
||||||
- drop deprecated qtkit input device (use avfoundation instead)
|
|
||||||
- despill video filter
|
|
||||||
- haas audio filter
|
|
||||||
- SUP/PGS subtitle muxer
|
|
||||||
- convolve video filter
|
|
||||||
- VP9 tile threading support
|
|
||||||
- KMS screen grabber
|
|
||||||
- CUDA thumbnail filter
|
|
||||||
- V4L2 mem2mem HW assisted codecs
|
|
||||||
- Rockchip MPP hardware decoding
|
|
||||||
- vmafmotion video filter
|
|
||||||
- use MIME type "G726" for little-endian G.726, "AAL2-G726" for big-endian G.726
|
|
||||||
|
|
||||||
|
|
||||||
version 3.3:
|
|
||||||
- CrystalHD decoder moved to new decode API
|
|
||||||
- add internal ebur128 library, remove external libebur128 dependency
|
|
||||||
- Pro-MPEG CoP #3-R2 FEC protocol
|
|
||||||
- premultiply video filter
|
|
||||||
- Support for spherical videos
|
|
||||||
- configure now fails if autodetect-libraries are requested but not found
|
|
||||||
- PSD Decoder
|
|
||||||
- 16.8 floating point pcm decoder
|
|
||||||
- 24.0 floating point pcm decoder
|
|
||||||
- Apple Pixlet decoder
|
|
||||||
- QDMC audio decoder
|
|
||||||
- NewTek SpeedHQ decoder
|
|
||||||
- MIDI Sample Dump Standard demuxer
|
|
||||||
- readeia608 filter
|
|
||||||
- Sample Dump eXchange demuxer
|
|
||||||
- abitscope multimedia filter
|
|
||||||
- Scenarist Closed Captions demuxer and muxer
|
|
||||||
- threshold filter
|
|
||||||
- midequalizer filter
|
|
||||||
- Optimal Huffman tables for (M)JPEG encoding
|
|
||||||
- VAAPI-accelerated MPEG-2 and VP8 encoding
|
|
||||||
- FM Screen Capture Codec decoder
|
|
||||||
- native Opus encoder
|
|
||||||
- ScreenPressor decoder
|
|
||||||
- incomplete ClearVideo decoder
|
|
||||||
- Intel QSV video scaling and deinterlacing filters
|
|
||||||
- Support MOV with multiple sample description tables
|
|
||||||
- XPM decoder
|
|
||||||
- Removed the legacy X11 screen grabber, use XCB instead
|
|
||||||
- MPEG-7 Video Signature filter
|
|
||||||
- Removed asyncts filter (use af_aresample instead)
|
|
||||||
- Intel QSV-accelerated VP8 video decoding
|
|
||||||
- VAAPI-accelerated deinterlacing
|
|
||||||
|
|
||||||
|
|
||||||
version 3.2:
|
|
||||||
- libopenmpt demuxer
|
|
||||||
- tee protocol
|
|
||||||
- Changed metadata print option to accept general urls
|
|
||||||
- Alias muxer for Ogg Video (.ogv)
|
|
||||||
- VP8 in Ogg muxing
|
|
||||||
- curves filter doesn't automatically insert points at x=0 and x=1 anymore
|
|
||||||
- 16-bit support in curves filter and selectivecolor filter
|
|
||||||
- OpenH264 decoder wrapper
|
|
||||||
- MediaCodec H.264/HEVC/MPEG-4/VP8/VP9 hwaccel
|
|
||||||
- True Audio (TTA) muxer
|
|
||||||
- crystalizer audio filter
|
|
||||||
- acrusher audio filter
|
|
||||||
- bitplanenoise video filter
|
|
||||||
- floating point support in als decoder
|
|
||||||
- fifo muxer
|
|
||||||
- maskedclamp filter
|
|
||||||
- hysteresis filter
|
|
||||||
- lut2 filter
|
|
||||||
- yuvtestsrc filter
|
|
||||||
- CUDA CUVID H.263/VP8/VP9/10 bit HEVC (Dithered) Decoding
|
|
||||||
- vaguedenoiser filter
|
|
||||||
- added threads option per filter instance
|
|
||||||
- weave filter
|
|
||||||
- gblur filter
|
|
||||||
- avgblur filter
|
|
||||||
- sobel and prewitt filter
|
|
||||||
- MediaCodec HEVC/MPEG-4/VP8/VP9 decoding
|
|
||||||
- Meridian Lossless Packing (MLP) / TrueHD encoder
|
|
||||||
- Non-Local Means (nlmeans) denoising filter
|
|
||||||
- sdl2 output device and ffplay support
|
|
||||||
- sdl1 output device and sdl1 support removed
|
|
||||||
- extended mov edit list support
|
|
||||||
- libfaac encoder removed
|
|
||||||
- Matroska muxer now writes CRC32 elements by default in all Level 1 elements
|
|
||||||
- sidedata video and asidedata audio filter
|
|
||||||
- Changed mapping of rtp MIME type G726 to codec g726le.
|
|
||||||
- spec compliant VAAPI/DXVA2 VC-1 decoding of slices in frame-coded images
|
|
||||||
|
|
||||||
|
|
||||||
version 3.1:
|
version 3.1:
|
||||||
@@ -696,7 +48,6 @@ version 3.1:
|
|||||||
- 10-bit depth support in native utvideo decoder
|
- 10-bit depth support in native utvideo decoder
|
||||||
- libutvideo wrapper removed
|
- libutvideo wrapper removed
|
||||||
- YUY2 Lossless Codec decoder
|
- YUY2 Lossless Codec decoder
|
||||||
- VideoToolbox H.264 encoder
|
|
||||||
|
|
||||||
|
|
||||||
version 3.0:
|
version 3.0:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
## Installing FFmpeg
|
#Installing FFmpeg:
|
||||||
|
|
||||||
1. Type `./configure` to create the configuration. A list of configure
|
1. Type `./configure` to create the configuration. A list of configure
|
||||||
options is printed by running `configure --help`.
|
options is printed by running `configure --help`.
|
||||||
|
|||||||
45
LICENSE.md
45
LICENSE.md
@@ -17,15 +17,16 @@ Specifically, the GPL parts of FFmpeg are:
|
|||||||
- `libavcodec/x86/flac_dsp_gpl.asm`
|
- `libavcodec/x86/flac_dsp_gpl.asm`
|
||||||
- `libavcodec/x86/idct_mmx.c`
|
- `libavcodec/x86/idct_mmx.c`
|
||||||
- `libavfilter/x86/vf_removegrain.asm`
|
- `libavfilter/x86/vf_removegrain.asm`
|
||||||
|
- the X11 grabber in `libavdevice/x11grab.c`
|
||||||
- the following building and testing tools
|
- the following building and testing tools
|
||||||
- `compat/solaris/make_sunver.pl`
|
- `compat/solaris/make_sunver.pl`
|
||||||
- `doc/t2h.pm`
|
- `doc/t2h.pm`
|
||||||
- `doc/texi2pod.pl`
|
- `doc/texi2pod.pl`
|
||||||
- `libswresample/tests/swresample.c`
|
- `libswresample/swresample-test.c`
|
||||||
- `tests/checkasm/*`
|
- `tests/checkasm/*`
|
||||||
- `tests/tiny_ssim.c`
|
- `tests/tiny_ssim.c`
|
||||||
- the following filters in libavfilter:
|
- the following filters in libavfilter:
|
||||||
- `signature_lookup.c`
|
- `f_ebur128.c`
|
||||||
- `vf_blackframe.c`
|
- `vf_blackframe.c`
|
||||||
- `vf_boxblur.c`
|
- `vf_boxblur.c`
|
||||||
- `vf_colormatrix.c`
|
- `vf_colormatrix.c`
|
||||||
@@ -35,13 +36,13 @@ Specifically, the GPL parts of FFmpeg are:
|
|||||||
- `vf_eq.c`
|
- `vf_eq.c`
|
||||||
- `vf_find_rect.c`
|
- `vf_find_rect.c`
|
||||||
- `vf_fspp.c`
|
- `vf_fspp.c`
|
||||||
|
- `vf_geq.c`
|
||||||
- `vf_histeq.c`
|
- `vf_histeq.c`
|
||||||
- `vf_hqdn3d.c`
|
- `vf_hqdn3d.c`
|
||||||
|
- `vf_interlace.c`
|
||||||
- `vf_kerndeint.c`
|
- `vf_kerndeint.c`
|
||||||
- `vf_lensfun.c` (GPL version 3 or later)
|
|
||||||
- `vf_mcdeint.c`
|
- `vf_mcdeint.c`
|
||||||
- `vf_mpdecimate.c`
|
- `vf_mpdecimate.c`
|
||||||
- `vf_nnedi.c`
|
|
||||||
- `vf_owdenoise.c`
|
- `vf_owdenoise.c`
|
||||||
- `vf_perspective.c`
|
- `vf_perspective.c`
|
||||||
- `vf_phase.c`
|
- `vf_phase.c`
|
||||||
@@ -50,14 +51,12 @@ Specifically, the GPL parts of FFmpeg are:
|
|||||||
- `vf_pullup.c`
|
- `vf_pullup.c`
|
||||||
- `vf_repeatfields.c`
|
- `vf_repeatfields.c`
|
||||||
- `vf_sab.c`
|
- `vf_sab.c`
|
||||||
- `vf_signature.c`
|
|
||||||
- `vf_smartblur.c`
|
- `vf_smartblur.c`
|
||||||
- `vf_spp.c`
|
- `vf_spp.c`
|
||||||
- `vf_stereo3d.c`
|
- `vf_stereo3d.c`
|
||||||
- `vf_super2xsai.c`
|
- `vf_super2xsai.c`
|
||||||
- `vf_tinterlace.c`
|
- `vf_tinterlace.c`
|
||||||
- `vf_uspp.c`
|
- `vf_uspp.c`
|
||||||
- `vf_vaguedenoiser.c`
|
|
||||||
- `vsrc_mptestsrc.c`
|
- `vsrc_mptestsrc.c`
|
||||||
|
|
||||||
Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then
|
Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then
|
||||||
@@ -83,47 +82,43 @@ affect the licensing of binaries resulting from the combination.
|
|||||||
|
|
||||||
### Compatible libraries
|
### Compatible libraries
|
||||||
|
|
||||||
The following libraries are under GPL version 2:
|
The following libraries are under GPL:
|
||||||
- avisynth
|
|
||||||
- frei0r
|
- frei0r
|
||||||
- libcdio
|
- libcdio
|
||||||
- libdavs2
|
|
||||||
- librubberband
|
- librubberband
|
||||||
- libvidstab
|
- libvidstab
|
||||||
- libx264
|
- libx264
|
||||||
- libx265
|
- libx265
|
||||||
- libxavs
|
- libxavs
|
||||||
- libxavs2
|
|
||||||
- libxvid
|
- libxvid
|
||||||
|
|
||||||
When combining them with FFmpeg, FFmpeg needs to be licensed as GPL as well by
|
When combining them with FFmpeg, FFmpeg needs to be licensed as GPL as well by
|
||||||
passing `--enable-gpl` to configure.
|
passing `--enable-gpl` to configure.
|
||||||
|
|
||||||
The following libraries are under LGPL version 3:
|
The OpenCORE and VisualOn libraries are under the Apache License 2.0. That
|
||||||
- gmp
|
license is incompatible with the LGPL v2.1 and the GPL v2, but not with
|
||||||
- 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
|
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.
|
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
|
### Incompatible libraries
|
||||||
|
|
||||||
There are certain libraries you can combine with FFmpeg whose licenses are not
|
There are certain libraries you can combine with FFmpeg whose licenses are not
|
||||||
compatible with the GPL and/or the LGPL. If you wish to enable these
|
compatible with the GPL and/or the LGPL. If you wish to enable these
|
||||||
libraries, even in circumstances that their license may be incompatible, pass
|
libraries, even in circumstances that their license may be incompatible, pass
|
||||||
`--enable-nonfree` to configure. This will cause the resulting binary to be
|
`--enable-nonfree` to configure. But note that if you enable any of these
|
||||||
|
libraries the resulting binary will be under a complex license mix that is
|
||||||
|
more restrictive than the LGPL and that may result in additional obligations.
|
||||||
|
It is possible that these restrictions cause the resulting binary to be
|
||||||
unredistributable.
|
unredistributable.
|
||||||
|
|
||||||
The Fraunhofer FDK AAC and OpenSSL libraries are under licenses which are
|
The Fraunhofer FDK AAC and OpenSSL libraries are under licenses which are
|
||||||
incompatible with the GPLv2 and v3. To the best of our knowledge, they are
|
incompatible with the GPLv2 and v3. To the best of our knowledge, they are
|
||||||
compatible with the LGPL.
|
compatible with the LGPL.
|
||||||
|
|
||||||
|
The FAAC library is incompatible with all versions of GPL and LGPL.
|
||||||
|
|
||||||
|
The NVENC library, while its header file is licensed under the compatible MIT
|
||||||
|
license, requires a proprietary binary blob at run time, and is deemed to be
|
||||||
|
incompatible with the GPL. We are not certain if it is compatible with the
|
||||||
|
LGPL, but we require `--enable-nonfree` even with LGPL configurations in case
|
||||||
|
it is not.
|
||||||
|
|||||||
173
MAINTAINERS
173
MAINTAINERS
@@ -29,6 +29,9 @@ ffplay:
|
|||||||
ffprobe:
|
ffprobe:
|
||||||
ffprobe.c Stefano Sabatini
|
ffprobe.c Stefano Sabatini
|
||||||
|
|
||||||
|
ffserver:
|
||||||
|
ffserver.c Reynaldo H. Verdejo Pinochet
|
||||||
|
|
||||||
Commandline utility code:
|
Commandline utility code:
|
||||||
cmdutils.c, cmdutils.h Michael Niedermayer
|
cmdutils.c, cmdutils.h Michael Niedermayer
|
||||||
|
|
||||||
@@ -39,12 +42,11 @@ QuickTime faststart:
|
|||||||
Miscellaneous Areas
|
Miscellaneous Areas
|
||||||
===================
|
===================
|
||||||
|
|
||||||
documentation Stefano Sabatini, Mike Melanson, Timothy Gu, Gyan Doshi
|
documentation Stefano Sabatini, Mike Melanson, Timothy Gu, Lou Logan
|
||||||
project server Árpád Gereöffy, Michael Niedermayer, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov
|
project server Árpád Gereöffy, Michael Niedermayer, Reimar Doeffinger, Alexander Strasser
|
||||||
presets Robert Swain
|
presets Robert Swain
|
||||||
metadata subsystem Aurelien Jacobs
|
metadata subsystem Aurelien Jacobs
|
||||||
release management Michael Niedermayer
|
release management Michael Niedermayer
|
||||||
API tests Ludmila Glinskih
|
|
||||||
|
|
||||||
|
|
||||||
Communication
|
Communication
|
||||||
@@ -52,12 +54,11 @@ Communication
|
|||||||
|
|
||||||
website Deby Barbara Lepage
|
website Deby Barbara Lepage
|
||||||
fate.ffmpeg.org Timothy Gu
|
fate.ffmpeg.org Timothy Gu
|
||||||
Trac bug tracker Alexander Strasser, Michael Niedermayer, Carl Eugen Hoyos
|
Trac bug tracker Alexander Strasser, Michael Niedermayer, Carl Eugen Hoyos, Lou Logan
|
||||||
Patchwork Andriy Gelman
|
mailing lists Baptiste Coudurier, Lou Logan
|
||||||
mailing lists Baptiste Coudurier
|
Google+ Paul B Mahol, Michael Niedermayer, Alexander Strasser
|
||||||
Twitter Reynaldo H. Verdejo Pinochet
|
Twitter Lou Logan, Reynaldo H. Verdejo Pinochet
|
||||||
Launchpad Timothy Gu
|
Launchpad Timothy Gu
|
||||||
ffmpeg-security Andreas Cadhalpun, Carl Eugen Hoyos, Clément Bœsch, Michael Niedermayer, Reimar Doeffinger, rcombs, wm4
|
|
||||||
|
|
||||||
|
|
||||||
libavutil
|
libavutil
|
||||||
@@ -77,8 +78,6 @@ Other:
|
|||||||
eval.c, eval.h Michael Niedermayer
|
eval.c, eval.h Michael Niedermayer
|
||||||
float_dsp Loren Merritt
|
float_dsp Loren Merritt
|
||||||
hash Reimar Doeffinger
|
hash Reimar Doeffinger
|
||||||
hwcontext_cuda* Timo Rothenpieler
|
|
||||||
hwcontext_vulkan* Lynne
|
|
||||||
intfloat* Michael Niedermayer
|
intfloat* Michael Niedermayer
|
||||||
integer.c, integer.h Michael Niedermayer
|
integer.c, integer.h Michael Niedermayer
|
||||||
lzo Reimar Doeffinger
|
lzo Reimar Doeffinger
|
||||||
@@ -89,7 +88,6 @@ Other:
|
|||||||
rational.c, rational.h Michael Niedermayer
|
rational.c, rational.h Michael Niedermayer
|
||||||
rc4 Reimar Doeffinger
|
rc4 Reimar Doeffinger
|
||||||
ripemd.c, ripemd.h James Almer
|
ripemd.c, ripemd.h James Almer
|
||||||
tx* Lynne
|
|
||||||
|
|
||||||
|
|
||||||
libavcodec
|
libavcodec
|
||||||
@@ -115,14 +113,13 @@ Generic Parts:
|
|||||||
lzw.* Michael Niedermayer
|
lzw.* Michael Niedermayer
|
||||||
floating point AAN DCT:
|
floating point AAN DCT:
|
||||||
faandct.c, faandct.h Michael Niedermayer
|
faandct.c, faandct.h Michael Niedermayer
|
||||||
Non-power-of-two MDCT:
|
|
||||||
mdct15.c, mdct15.h Rostislav Pehlivanov
|
|
||||||
Golomb coding:
|
Golomb coding:
|
||||||
golomb.c, golomb.h Michael Niedermayer
|
golomb.c, golomb.h Michael Niedermayer
|
||||||
motion estimation:
|
motion estimation:
|
||||||
motion* Michael Niedermayer
|
motion* Michael Niedermayer
|
||||||
rate control:
|
rate control:
|
||||||
ratecontrol.c Michael Niedermayer
|
ratecontrol.c Michael Niedermayer
|
||||||
|
libxvid_rc.c Michael Niedermayer
|
||||||
simple IDCT:
|
simple IDCT:
|
||||||
simple_idct.c, simple_idct.h Michael Niedermayer
|
simple_idct.c, simple_idct.h Michael Niedermayer
|
||||||
postprocessing:
|
postprocessing:
|
||||||
@@ -138,15 +135,11 @@ Codecs:
|
|||||||
8bps.c Roberto Togni
|
8bps.c Roberto Togni
|
||||||
8svx.c Jaikrishnan Menon
|
8svx.c Jaikrishnan Menon
|
||||||
aacenc*, aaccoder.c Rostislav Pehlivanov
|
aacenc*, aaccoder.c Rostislav Pehlivanov
|
||||||
adpcm.c Zane van Iperen
|
|
||||||
alacenc.c Jaikrishnan Menon
|
alacenc.c Jaikrishnan Menon
|
||||||
alsdec.c Thilo Borgmann, Umair Khan
|
alsdec.c Thilo Borgmann
|
||||||
aptx.c Aurelien Jacobs
|
|
||||||
ass* Aurelien Jacobs
|
ass* Aurelien Jacobs
|
||||||
asv* Michael Niedermayer
|
asv* Michael Niedermayer
|
||||||
atrac3plus* Maxim Poliakovski
|
atrac3plus* Maxim Poliakovski
|
||||||
audiotoolbox* rcombs
|
|
||||||
avs2* Huiwen Ren
|
|
||||||
bgmc.c, bgmc.h Thilo Borgmann
|
bgmc.c, bgmc.h Thilo Borgmann
|
||||||
binkaudio.c Peter Ross
|
binkaudio.c Peter Ross
|
||||||
cavs* Stefan Gehrer
|
cavs* Stefan Gehrer
|
||||||
@@ -154,16 +147,14 @@ Codecs:
|
|||||||
celp_filters.* Vitor Sessak
|
celp_filters.* Vitor Sessak
|
||||||
cinepak.c Roberto Togni
|
cinepak.c Roberto Togni
|
||||||
cinepakenc.c Rl / Aetey G.T. AB
|
cinepakenc.c Rl / Aetey G.T. AB
|
||||||
ccaption_dec.c Anshul Maheshwari, Aman Gupta
|
ccaption_dec.c Anshul Maheshwari
|
||||||
cljr Alex Beregszaszi
|
cljr Alex Beregszaszi
|
||||||
cpia.c Stephan Hilb
|
cpia.c Stephan Hilb
|
||||||
crystalhd.c Philip Langdale
|
crystalhd.c Philip Langdale
|
||||||
cscd.c Reimar Doeffinger
|
cscd.c Reimar Doeffinger
|
||||||
cuviddec.c Timo Rothenpieler
|
cuvid.c Timo Rothenpieler
|
||||||
dca* foo86
|
|
||||||
dirac* Rostislav Pehlivanov
|
dirac* Rostislav Pehlivanov
|
||||||
dnxhd* Baptiste Coudurier
|
dnxhd* Baptiste Coudurier
|
||||||
dolby_e* foo86
|
|
||||||
dpcm.c Mike Melanson
|
dpcm.c Mike Melanson
|
||||||
dss_sp.c Oleksij Rempel
|
dss_sp.c Oleksij Rempel
|
||||||
dv.c Roman Shaposhnik
|
dv.c Roman Shaposhnik
|
||||||
@@ -173,7 +164,6 @@ Codecs:
|
|||||||
exif.c, exif.h Thilo Borgmann
|
exif.c, exif.h Thilo Borgmann
|
||||||
ffv1* Michael Niedermayer
|
ffv1* Michael Niedermayer
|
||||||
ffwavesynth.c Nicolas George
|
ffwavesynth.c Nicolas George
|
||||||
fifo.c Jan Sebechlebsky
|
|
||||||
flicvideo.c Mike Melanson
|
flicvideo.c Mike Melanson
|
||||||
g722.c Martin Storsjo
|
g722.c Martin Storsjo
|
||||||
g726.c Roman Shaposhnik
|
g726.c Roman Shaposhnik
|
||||||
@@ -182,7 +172,7 @@ Codecs:
|
|||||||
h263* Michael Niedermayer
|
h263* Michael Niedermayer
|
||||||
h264* Loren Merritt, Michael Niedermayer
|
h264* Loren Merritt, Michael Niedermayer
|
||||||
hap* Tom Butterworth
|
hap* Tom Butterworth
|
||||||
huffyuv* Michael Niedermayer
|
huffyuv* Michael Niedermayer, Christophe Gisquet
|
||||||
idcinvideo.c Mike Melanson
|
idcinvideo.c Mike Melanson
|
||||||
interplayvideo.c Mike Melanson
|
interplayvideo.c Mike Melanson
|
||||||
jni*, ffjni* Matthieu Bouron
|
jni*, ffjni* Matthieu Bouron
|
||||||
@@ -190,25 +180,22 @@ Codecs:
|
|||||||
jvdec.c Peter Ross
|
jvdec.c Peter Ross
|
||||||
lcl*.c Roberto Togni, Reimar Doeffinger
|
lcl*.c Roberto Togni, Reimar Doeffinger
|
||||||
libcelt_dec.c Nicolas George
|
libcelt_dec.c Nicolas George
|
||||||
libcodec2.c Tomas Härdin
|
|
||||||
libdirac* David Conrad
|
libdirac* David Conrad
|
||||||
libdavs2.c Huiwen Ren
|
|
||||||
libgsm.c Michel Bardiaux
|
libgsm.c Michel Bardiaux
|
||||||
libkvazaar.c Arttu Ylä-Outinen
|
libkvazaar.c Arttu Ylä-Outinen
|
||||||
libopenh264enc.c Martin Storsjo, Linjie Fu
|
|
||||||
libopenjpeg.c Jaikrishnan Menon
|
libopenjpeg.c Jaikrishnan Menon
|
||||||
libopenjpegenc.c Michael Bradshaw
|
libopenjpegenc.c Michael Bradshaw
|
||||||
|
libschroedinger* David Conrad
|
||||||
libtheoraenc.c David Conrad
|
libtheoraenc.c David Conrad
|
||||||
libvorbis.c David Conrad
|
libvorbis.c David Conrad
|
||||||
libvpx* James Zern
|
libvpx* James Zern
|
||||||
libxavs.c Stefan Gehrer
|
libxavs.c Stefan Gehrer
|
||||||
libxavs2.c Huiwen Ren
|
|
||||||
libzvbi-teletextdec.c Marton Balint
|
libzvbi-teletextdec.c Marton Balint
|
||||||
lzo.h, lzo.c Reimar Doeffinger
|
lzo.h, lzo.c Reimar Doeffinger
|
||||||
mdec.c Michael Niedermayer
|
mdec.c Michael Niedermayer
|
||||||
mimic.c Ramiro Polla
|
mimic.c Ramiro Polla
|
||||||
mjpeg*.c Michael Niedermayer
|
mjpeg*.c Michael Niedermayer
|
||||||
mlp* Ramiro Polla, Jai Luthra
|
mlp* Ramiro Polla
|
||||||
mmvideo.c Peter Ross
|
mmvideo.c Peter Ross
|
||||||
mpeg12.c, mpeg12data.h Michael Niedermayer
|
mpeg12.c, mpeg12data.h Michael Niedermayer
|
||||||
mpegvideo.c, mpegvideo.h Michael Niedermayer
|
mpegvideo.c, mpegvideo.h Michael Niedermayer
|
||||||
@@ -217,16 +204,14 @@ Codecs:
|
|||||||
msrle.c Mike Melanson
|
msrle.c Mike Melanson
|
||||||
msvideo1.c Mike Melanson
|
msvideo1.c Mike Melanson
|
||||||
nuv.c Reimar Doeffinger
|
nuv.c Reimar Doeffinger
|
||||||
nvdec*, nvenc* Timo Rothenpieler
|
nvenc* Timo Rothenpieler
|
||||||
omx.c Martin Storsjo, Aman Gupta
|
|
||||||
opus* Rostislav Pehlivanov
|
|
||||||
paf.* Paul B Mahol
|
paf.* Paul B Mahol
|
||||||
pcx.c Ivo van Poorten
|
pcx.c Ivo van Poorten
|
||||||
pgssubdec.c Reimar Doeffinger
|
pgssubdec.c Reimar Doeffinger
|
||||||
ptx.c Ivo van Poorten
|
ptx.c Ivo van Poorten
|
||||||
qcelp* Reynaldo H. Verdejo Pinochet
|
qcelp* Reynaldo H. Verdejo Pinochet
|
||||||
qdm2.c, qdm2data.h Roberto Togni
|
qdm2.c, qdm2data.h Roberto Togni
|
||||||
qsv* Mark Thompson, Zhong Li, Haihao Xiang
|
qsv* Ivan Uskov
|
||||||
qtrle.c Mike Melanson
|
qtrle.c Mike Melanson
|
||||||
ra144.c, ra144.h, ra288.c, ra288.h Roberto Togni
|
ra144.c, ra144.h, ra288.c, ra288.h Roberto Togni
|
||||||
resample2.c Michael Niedermayer
|
resample2.c Michael Niedermayer
|
||||||
@@ -234,11 +219,12 @@ Codecs:
|
|||||||
rpza.c Roberto Togni
|
rpza.c Roberto Togni
|
||||||
rtjpeg.c, rtjpeg.h Reimar Doeffinger
|
rtjpeg.c, rtjpeg.h Reimar Doeffinger
|
||||||
rv10.c Michael Niedermayer
|
rv10.c Michael Niedermayer
|
||||||
|
rv4* Christophe Gisquet
|
||||||
s3tc* Ivo van Poorten
|
s3tc* Ivo van Poorten
|
||||||
smc.c Mike Melanson
|
smc.c Mike Melanson
|
||||||
|
smvjpegdec.c Ash Hughes
|
||||||
snow* Michael Niedermayer, Loren Merritt
|
snow* Michael Niedermayer, Loren Merritt
|
||||||
sonic.c Alex Beregszaszi
|
sonic.c Alex Beregszaszi
|
||||||
speedhq.c Steinar H. Gunderson
|
|
||||||
srt* Aurelien Jacobs
|
srt* Aurelien Jacobs
|
||||||
sunrast.c Ivo van Poorten
|
sunrast.c Ivo van Poorten
|
||||||
svq3.c Michael Niedermayer
|
svq3.c Michael Niedermayer
|
||||||
@@ -247,10 +233,11 @@ Codecs:
|
|||||||
tta.c Alex Beregszaszi, Jaikrishnan Menon
|
tta.c Alex Beregszaszi, Jaikrishnan Menon
|
||||||
ttaenc.c Paul B Mahol
|
ttaenc.c Paul B Mahol
|
||||||
txd.c Ivo van Poorten
|
txd.c Ivo van Poorten
|
||||||
v4l2_* Jorge Ramirez-Ortiz
|
vc1* Christophe Gisquet
|
||||||
vc2* Rostislav Pehlivanov
|
vc2* Rostislav Pehlivanov
|
||||||
vcr1.c Michael Niedermayer
|
vcr1.c Michael Niedermayer
|
||||||
videotoolboxenc.c Rick Kern, Aman Gupta
|
vda_h264_dec.c Xidorn Quan
|
||||||
|
videotoolboxenc.c Rick Kern
|
||||||
vima.c Paul B Mahol
|
vima.c Paul B Mahol
|
||||||
vorbisdec.c Denes Balatoni, David Conrad
|
vorbisdec.c Denes Balatoni, David Conrad
|
||||||
vorbisenc.c Oded Shimon
|
vorbisenc.c Oded Shimon
|
||||||
@@ -271,13 +258,12 @@ Codecs:
|
|||||||
|
|
||||||
Hardware acceleration:
|
Hardware acceleration:
|
||||||
crystalhd.c Philip Langdale
|
crystalhd.c Philip Langdale
|
||||||
dxva2* Hendrik Leppkes, Laurent Aimar, Steve Lhomme
|
dxva2* Hendrik Leppkes, Laurent Aimar
|
||||||
d3d11va* Steve Lhomme
|
mediacodec* Matthieu Bouron
|
||||||
mediacodec* Matthieu Bouron, Aman Gupta
|
vaapi* Gwenole Beauchesne
|
||||||
vaapi* Haihao Xiang
|
vaapi_encode* Mark Thompson
|
||||||
vaapi_encode* Mark Thompson, Haihao Xiang
|
|
||||||
vdpau* Philip Langdale, Carl Eugen Hoyos
|
vdpau* Philip Langdale, Carl Eugen Hoyos
|
||||||
videotoolbox* Rick Kern, Aman Gupta
|
videotoolbox* Rick Kern
|
||||||
|
|
||||||
|
|
||||||
libavdevice
|
libavdevice
|
||||||
@@ -287,8 +273,7 @@ libavdevice
|
|||||||
|
|
||||||
|
|
||||||
avfoundation.m Thilo Borgmann
|
avfoundation.m Thilo Borgmann
|
||||||
android_camera.c Felix Matouschek
|
decklink* Deti Fliegl
|
||||||
decklink* Marton Balint
|
|
||||||
dshow.c Roger Pack (CC rogerdpack@gmail.com)
|
dshow.c Roger Pack (CC rogerdpack@gmail.com)
|
||||||
fbdev_enc.c Lukasz Marek
|
fbdev_enc.c Lukasz Marek
|
||||||
gdigrab.c Roger Pack (CC rogerdpack@gmail.com)
|
gdigrab.c Roger Pack (CC rogerdpack@gmail.com)
|
||||||
@@ -297,8 +282,8 @@ libavdevice
|
|||||||
libdc1394.c Roman Shaposhnik
|
libdc1394.c Roman Shaposhnik
|
||||||
opengl_enc.c Lukasz Marek
|
opengl_enc.c Lukasz Marek
|
||||||
pulse_audio_enc.c Lukasz Marek
|
pulse_audio_enc.c Lukasz Marek
|
||||||
|
qtkit.m Thilo Borgmann
|
||||||
sdl Stefano Sabatini
|
sdl Stefano Sabatini
|
||||||
sdl2.c Josh de Kock
|
|
||||||
v4l2.c Giorgio Vazzana
|
v4l2.c Giorgio Vazzana
|
||||||
vfwcap.c Ramiro Polla
|
vfwcap.c Ramiro Polla
|
||||||
xv.c Lukasz Marek
|
xv.c Lukasz Marek
|
||||||
@@ -309,8 +294,6 @@ libavfilter
|
|||||||
Generic parts:
|
Generic parts:
|
||||||
graphdump.c Nicolas George
|
graphdump.c Nicolas George
|
||||||
|
|
||||||
motion_estimation.c Davinder Singh
|
|
||||||
|
|
||||||
Filters:
|
Filters:
|
||||||
f_drawgraph.c Paul B Mahol
|
f_drawgraph.c Paul B Mahol
|
||||||
af_adelay.c Paul B Mahol
|
af_adelay.c Paul B Mahol
|
||||||
@@ -325,7 +308,6 @@ Filters:
|
|||||||
af_chorus.c Paul B Mahol
|
af_chorus.c Paul B Mahol
|
||||||
af_compand.c Paul B Mahol
|
af_compand.c Paul B Mahol
|
||||||
af_firequalizer.c Muhammad Faiz
|
af_firequalizer.c Muhammad Faiz
|
||||||
af_hdcd.c Burt P.
|
|
||||||
af_ladspa.c Paul B Mahol
|
af_ladspa.c Paul B Mahol
|
||||||
af_loudnorm.c Kyle Swanson
|
af_loudnorm.c Kyle Swanson
|
||||||
af_pan.c Nicolas George
|
af_pan.c Nicolas George
|
||||||
@@ -335,10 +317,8 @@ Filters:
|
|||||||
avf_avectorscope.c Paul B Mahol
|
avf_avectorscope.c Paul B Mahol
|
||||||
avf_showcqt.c Muhammad Faiz
|
avf_showcqt.c Muhammad Faiz
|
||||||
vf_blend.c Paul B Mahol
|
vf_blend.c Paul B Mahol
|
||||||
vf_bwdif Thomas Mundt (CC <thomas.mundt@hr.de>)
|
|
||||||
vf_chromakey.c Timo Rothenpieler
|
vf_chromakey.c Timo Rothenpieler
|
||||||
vf_colorchannelmixer.c Paul B Mahol
|
vf_colorchannelmixer.c Paul B Mahol
|
||||||
vf_colorconstancy.c Mina Sami (CC <minas.gorgy@gmail.com>)
|
|
||||||
vf_colorbalance.c Paul B Mahol
|
vf_colorbalance.c Paul B Mahol
|
||||||
vf_colorkey.c Timo Rothenpieler
|
vf_colorkey.c Timo Rothenpieler
|
||||||
vf_colorlevels.c Paul B Mahol
|
vf_colorlevels.c Paul B Mahol
|
||||||
@@ -352,11 +332,8 @@ Filters:
|
|||||||
vf_hqx.c Clément Bœsch
|
vf_hqx.c Clément Bœsch
|
||||||
vf_idet.c Pascal Massimino
|
vf_idet.c Pascal Massimino
|
||||||
vf_il.c Paul B Mahol
|
vf_il.c Paul B Mahol
|
||||||
vf_(t)interlace Thomas Mundt (CC <thomas.mundt@hr.de>)
|
|
||||||
vf_lenscorrection.c Daniel Oberhoff
|
vf_lenscorrection.c Daniel Oberhoff
|
||||||
vf_mergeplanes.c Paul B Mahol
|
vf_mergeplanes.c Paul B Mahol
|
||||||
vf_mestimate.c Davinder Singh
|
|
||||||
vf_minterpolate.c Davinder Singh
|
|
||||||
vf_neighbor.c Paul B Mahol
|
vf_neighbor.c Paul B Mahol
|
||||||
vf_psnr.c Paul B Mahol
|
vf_psnr.c Paul B Mahol
|
||||||
vf_random.c Paul B Mahol
|
vf_random.c Paul B Mahol
|
||||||
@@ -366,15 +343,12 @@ Filters:
|
|||||||
vf_ssim.c Paul B Mahol
|
vf_ssim.c Paul B Mahol
|
||||||
vf_stereo3d.c Paul B Mahol
|
vf_stereo3d.c Paul B Mahol
|
||||||
vf_telecine.c Paul B Mahol
|
vf_telecine.c Paul B Mahol
|
||||||
vf_tonemap_opencl.c Ruiling Song
|
|
||||||
vf_yadif.c Michael Niedermayer
|
vf_yadif.c Michael Niedermayer
|
||||||
vf_zoompan.c Paul B Mahol
|
vf_zoompan.c Paul B Mahol
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
vsrc_mandelbrot.c Michael Niedermayer
|
vsrc_mandelbrot.c Michael Niedermayer
|
||||||
|
|
||||||
dnn Yejun Guo
|
|
||||||
|
|
||||||
libavformat
|
libavformat
|
||||||
===========
|
===========
|
||||||
|
|
||||||
@@ -393,42 +367,31 @@ Muxers/Demuxers:
|
|||||||
afc.c Paul B Mahol
|
afc.c Paul B Mahol
|
||||||
aiffdec.c Baptiste Coudurier, Matthieu Bouron
|
aiffdec.c Baptiste Coudurier, Matthieu Bouron
|
||||||
aiffenc.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
|
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
|
ass* Aurelien Jacobs
|
||||||
astdec.c Paul B Mahol
|
astdec.c Paul B Mahol
|
||||||
astenc.c James Almer
|
astenc.c James Almer
|
||||||
avi* Michael Niedermayer
|
avi* Michael Niedermayer
|
||||||
avisynth.c Stephen Hutchinson
|
avisynth.c AvxSynth Team (avxsynth.testing at gmail dot com)
|
||||||
avr.c Paul B Mahol
|
avr.c Paul B Mahol
|
||||||
bink.c Peter Ross
|
bink.c Peter Ross
|
||||||
boadec.c Michael Niedermayer
|
|
||||||
brstm.c Paul B Mahol
|
brstm.c Paul B Mahol
|
||||||
caf* Peter Ross
|
caf* Peter Ross
|
||||||
cdxl.c Paul B Mahol
|
cdxl.c Paul B Mahol
|
||||||
codec2.c Tomas Härdin
|
|
||||||
crc.c Michael Niedermayer
|
crc.c Michael Niedermayer
|
||||||
dashdec.c Steven Liu
|
|
||||||
dashenc.c Karthick Jeyapal
|
|
||||||
daud.c Reimar Doeffinger
|
daud.c Reimar Doeffinger
|
||||||
dss.c Oleksij Rempel
|
dss.c Oleksij Rempel
|
||||||
dtsdec.c foo86
|
|
||||||
dtshddec.c Paul B Mahol
|
dtshddec.c Paul B Mahol
|
||||||
dv.c Roman Shaposhnik
|
dv.c Roman Shaposhnik
|
||||||
electronicarts.c Peter Ross
|
electronicarts.c Peter Ross
|
||||||
epafdec.c Paul B Mahol
|
epafdec.c Paul B Mahol
|
||||||
ffm* Baptiste Coudurier
|
ffm* Baptiste Coudurier
|
||||||
flic.c Mike Melanson
|
flic.c Mike Melanson
|
||||||
flvdec.c Michael Niedermayer
|
flvdec.c, flvenc.c Michael Niedermayer
|
||||||
flvenc.c Michael Niedermayer, Steven Liu
|
|
||||||
gxf.c Reimar Doeffinger
|
gxf.c Reimar Doeffinger
|
||||||
gxfenc.c Baptiste Coudurier
|
gxfenc.c Baptiste Coudurier
|
||||||
hlsenc.c Christian Suloway, Steven Liu
|
hls.c Anssi Hannula
|
||||||
|
hls encryption (hlsenc.c) Christian Suloway
|
||||||
idcin.c Mike Melanson
|
idcin.c Mike Melanson
|
||||||
idroqdec.c Mike Melanson
|
idroqdec.c Mike Melanson
|
||||||
iff.c Jaikrishnan Menon
|
iff.c Jaikrishnan Menon
|
||||||
@@ -437,15 +400,14 @@ Muxers/Demuxers:
|
|||||||
ircam* Paul B Mahol
|
ircam* Paul B Mahol
|
||||||
iss.c Stefan Gehrer
|
iss.c Stefan Gehrer
|
||||||
jvdec.c Peter Ross
|
jvdec.c Peter Ross
|
||||||
kvag.c Zane van Iperen
|
|
||||||
libmodplug.c Clément Bœsch
|
libmodplug.c Clément Bœsch
|
||||||
libopenmpt.c Josh de Kock
|
libnut.c Oded Shimon
|
||||||
lmlm4.c Ivo van Poorten
|
lmlm4.c Ivo van Poorten
|
||||||
lvfdec.c Paul B Mahol
|
lvfdec.c Paul B Mahol
|
||||||
lxfdec.c Tomas Härdin
|
lxfdec.c Tomas Härdin
|
||||||
matroska.c Aurelien Jacobs, Andreas Rheinhardt
|
matroska.c Aurelien Jacobs
|
||||||
matroskadec.c Aurelien Jacobs, Andreas Rheinhardt
|
matroskadec.c Aurelien Jacobs
|
||||||
matroskaenc.c David Conrad, Andreas Rheinhardt
|
matroskaenc.c David Conrad
|
||||||
matroska subtitles (matroskaenc.c) John Peebles
|
matroska subtitles (matroskaenc.c) John Peebles
|
||||||
metadata* Aurelien Jacobs
|
metadata* Aurelien Jacobs
|
||||||
mgsts.c Paul B Mahol
|
mgsts.c Paul B Mahol
|
||||||
@@ -460,7 +422,8 @@ Muxers/Demuxers:
|
|||||||
mpegtsenc.c Baptiste Coudurier
|
mpegtsenc.c Baptiste Coudurier
|
||||||
msnwc_tcp.c Ramiro Polla
|
msnwc_tcp.c Ramiro Polla
|
||||||
mtv.c Reynaldo H. Verdejo Pinochet
|
mtv.c Reynaldo H. Verdejo Pinochet
|
||||||
mxf* Baptiste Coudurier, Tomas Härdin
|
mxf* Baptiste Coudurier
|
||||||
|
mxfdec.c Tomas Härdin
|
||||||
nistspheredec.c Paul B Mahol
|
nistspheredec.c Paul B Mahol
|
||||||
nsvdec.c Francois Revol
|
nsvdec.c Francois Revol
|
||||||
nut* Michael Niedermayer
|
nut* Michael Niedermayer
|
||||||
@@ -468,9 +431,9 @@ Muxers/Demuxers:
|
|||||||
oggdec.c, oggdec.h David Conrad
|
oggdec.c, oggdec.h David Conrad
|
||||||
oggenc.c Baptiste Coudurier
|
oggenc.c Baptiste Coudurier
|
||||||
oggparse*.c David Conrad
|
oggparse*.c David Conrad
|
||||||
|
oggparsedaala* Rostislav Pehlivanov
|
||||||
oma.c Maxim Poliakovski
|
oma.c Maxim Poliakovski
|
||||||
paf.c Paul B Mahol
|
paf.c Paul B Mahol
|
||||||
pp_bnk.c Zane van Iperen
|
|
||||||
psxstr.c Mike Melanson
|
psxstr.c Mike Melanson
|
||||||
pva.c Ivo van Poorten
|
pva.c Ivo van Poorten
|
||||||
pvfdec.c Paul B Mahol
|
pvfdec.c Paul B Mahol
|
||||||
@@ -489,7 +452,6 @@ Muxers/Demuxers:
|
|||||||
rtpdec_vc2hq.*, rtpenc_vc2hq.* Thomas Volkert
|
rtpdec_vc2hq.*, rtpenc_vc2hq.* Thomas Volkert
|
||||||
rtpdec_vp9.c Thomas Volkert
|
rtpdec_vp9.c Thomas Volkert
|
||||||
rtpenc_mpv.*, rtpenc_aac.* Martin Storsjo
|
rtpenc_mpv.*, rtpenc_aac.* Martin Storsjo
|
||||||
s337m.c foo86
|
|
||||||
sbgdec.c Nicolas George
|
sbgdec.c Nicolas George
|
||||||
sdp.c Martin Storsjo
|
sdp.c Martin Storsjo
|
||||||
segafilm.c Mike Melanson
|
segafilm.c Mike Melanson
|
||||||
@@ -516,7 +478,6 @@ Protocols:
|
|||||||
ftp.c Lukasz Marek
|
ftp.c Lukasz Marek
|
||||||
http.c Ronald S. Bultje
|
http.c Ronald S. Bultje
|
||||||
libssh.c Lukasz Marek
|
libssh.c Lukasz Marek
|
||||||
libzmq.c Andriy Gelman
|
|
||||||
mms*.c Ronald S. Bultje
|
mms*.c Ronald S. Bultje
|
||||||
udp.c Luca Abeni
|
udp.c Luca Abeni
|
||||||
icecast.c Marvin Scholz
|
icecast.c Marvin Scholz
|
||||||
@@ -540,10 +501,9 @@ Operating systems / CPU architectures
|
|||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
Alpha Falk Hueffner
|
Alpha Falk Hueffner
|
||||||
MIPS Manojkumar Bhosale, Shiyou Yin
|
MIPS Nedeljko Babic
|
||||||
Mac OS X / PowerPC Romain Dolbeau, Guillaume Poirier
|
Mac OS X / PowerPC Romain Dolbeau, Guillaume Poirier
|
||||||
Amiga / PowerPC Colin Ward
|
Amiga / PowerPC Colin Ward
|
||||||
Linux / PowerPC Lauri Kasanen
|
|
||||||
Windows MinGW Alex Beregszaszi, Ramiro Polla
|
Windows MinGW Alex Beregszaszi, Ramiro Polla
|
||||||
Windows Cygwin Victor Paesa
|
Windows Cygwin Victor Paesa
|
||||||
Windows MSVC Matthew Oliver, Hendrik Leppkes
|
Windows MSVC Matthew Oliver, Hendrik Leppkes
|
||||||
@@ -553,35 +513,6 @@ Sparc Roman Shaposhnik
|
|||||||
OS/2 KO Myung-Hun
|
OS/2 KO Myung-Hun
|
||||||
|
|
||||||
|
|
||||||
Developers with git write access who are currently not maintaining any specific part
|
|
||||||
====================================================================================
|
|
||||||
Alex Converse
|
|
||||||
Andreas Cadhalpun
|
|
||||||
Anuradha Suraparaju
|
|
||||||
Ben Littler
|
|
||||||
Benjamin Larsson
|
|
||||||
Bobby Bingham
|
|
||||||
Daniel Verkamp
|
|
||||||
Derek Buitenhuis
|
|
||||||
Ganesh Ajjanagadde
|
|
||||||
Henrik Gramner
|
|
||||||
Ivan Uskov
|
|
||||||
James Darnley
|
|
||||||
Jan Ekström
|
|
||||||
Joakim Plate
|
|
||||||
Jun Zhao
|
|
||||||
Kieran Kunhya
|
|
||||||
Kirill Gavrilov
|
|
||||||
Limin Wang
|
|
||||||
Martin Storsjö
|
|
||||||
Panagiotis Issaris
|
|
||||||
Pedro Arthur
|
|
||||||
Sebastien Zwickert
|
|
||||||
Vittorio Giovara
|
|
||||||
wm4
|
|
||||||
(this list is incomplete)
|
|
||||||
|
|
||||||
|
|
||||||
Releases
|
Releases
|
||||||
========
|
========
|
||||||
|
|
||||||
@@ -589,15 +520,13 @@ Releases
|
|||||||
2.7 Michael Niedermayer
|
2.7 Michael Niedermayer
|
||||||
2.6 Michael Niedermayer
|
2.6 Michael Niedermayer
|
||||||
2.5 Michael Niedermayer
|
2.5 Michael Niedermayer
|
||||||
|
2.4 Michael Niedermayer
|
||||||
|
|
||||||
If you want to maintain an older release, please contact us
|
If you want to maintain an older release, please contact us
|
||||||
|
|
||||||
|
|
||||||
GnuPG Fingerprints and IRC nicknames of maintainers and contributors
|
GnuPG Fingerprints of maintainers and contributors
|
||||||
====================================================================
|
==================================================
|
||||||
|
|
||||||
IRC nicknames are in parentheses. These apply
|
|
||||||
to the IRC channels listed on the website.
|
|
||||||
|
|
||||||
Alexander Strasser 1C96 78B7 83CB 8AA7 9AF5 D1EB A7D8 A57B A876 E58F
|
Alexander Strasser 1C96 78B7 83CB 8AA7 9AF5 D1EB A7D8 A57B A876 E58F
|
||||||
Anssi Hannula 1A92 FF42 2DD9 8D2E 8AF7 65A9 4278 C520 513D F3CB
|
Anssi Hannula 1A92 FF42 2DD9 8D2E 8AF7 65A9 4278 C520 513D F3CB
|
||||||
@@ -611,31 +540,23 @@ 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
|
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
|
Ganesh Ajjanagadde C96A 848E 97C3 CEA2 AB72 5CE4 45F9 6A2D 3C36 FB1B
|
||||||
Gwenole Beauchesne 2E63 B3A6 3E44 37E2 017D 2704 53C7 6266 B153 99C4
|
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
|
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
|
Jean Delvare 7CA6 9F44 60F1 BDC4 1FD2 C858 A552 6B9B B3CD 4E6A
|
||||||
Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE
|
Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE
|
||||||
Lynne FE50 139C 6805 72CA FD52 1F8D A2FE A5F0 3F03 4464
|
Lou Logan 7D68 DC73 CBEF EABB 671A B6CF 621C 2E28 82F8 DC3A
|
||||||
Michael Niedermayer 9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB
|
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
|
Nicolas George 24CE 01CE 9ACC 5CEB 74D8 8D9D B063 D997 36E5 4C93
|
||||||
Nikolay Aleksandrov 8978 1D8C FB71 588E 4B27 EAA8 C4F0 B5FC E011 13B1
|
|
||||||
Panagiotis Issaris 6571 13A3 33D9 3726 F728 AA98 F643 B12E ECF3 E029
|
Panagiotis Issaris 6571 13A3 33D9 3726 F728 AA98 F643 B12E ECF3 E029
|
||||||
Peter Ross A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B
|
Peter Ross A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B
|
||||||
Philip Langdale 5DC5 8D66 5FBA 3A43 18EC 045E F8D6 B194 6A75 682E
|
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
|
Reimar Doeffinger C61D 16E5 9E2C D10C 8958 38A4 0899 A2B9 06D4 D9C7
|
||||||
Reinhard Tartler 9300 5DC2 7E87 6C37 ED7B CA9A 9808 3544 9453 48A4
|
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
|
Reynaldo H. Verdejo Pinochet 6E27 CD34 170C C78E 4D4F 5F40 C18E 077F 3114 452A
|
||||||
Robert Swain EE7A 56EA 4A81 A7B5 2001 A521 67FA 362D A2FC 3E71
|
Robert Swain EE7A 56EA 4A81 A7B5 2001 A521 67FA 362D A2FC 3E71
|
||||||
Sascha Sommer 38A0 F88B 868E 9D3A 97D4 D6A0 E823 706F 1E07 0D3C
|
Sascha Sommer 38A0 F88B 868E 9D3A 97D4 D6A0 E823 706F 1E07 0D3C
|
||||||
Stefano Sabatini 0D0B AD6B 5330 BBAD D3D6 6A0C 719C 2839 FC43 2D5F
|
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
|
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
|
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
|
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
|
Tomas Härdin A79D 4E3D F38F 763F 91F5 8B33 A01E 8AE0 41BB 2551
|
||||||
Wei Gao 4269 7741 857A 0E60 9EC5 08D2 4744 4EFA 62C1 87B9
|
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
|
|
||||||
|
|||||||
168
Makefile
168
Makefile
@@ -1,5 +1,5 @@
|
|||||||
MAIN_MAKEFILE=1
|
MAIN_MAKEFILE=1
|
||||||
include ffbuild/config.mak
|
include config.mak
|
||||||
|
|
||||||
vpath %.c $(SRC_PATH)
|
vpath %.c $(SRC_PATH)
|
||||||
vpath %.cpp $(SRC_PATH)
|
vpath %.cpp $(SRC_PATH)
|
||||||
@@ -11,19 +11,47 @@ vpath %.asm $(SRC_PATH)
|
|||||||
vpath %.rc $(SRC_PATH)
|
vpath %.rc $(SRC_PATH)
|
||||||
vpath %.v $(SRC_PATH)
|
vpath %.v $(SRC_PATH)
|
||||||
vpath %.texi $(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)
|
vpath %/fate_config.sh.template $(SRC_PATH)
|
||||||
|
|
||||||
|
AVPROGS-$(CONFIG_FFMPEG) += ffmpeg
|
||||||
|
AVPROGS-$(CONFIG_FFPLAY) += ffplay
|
||||||
|
AVPROGS-$(CONFIG_FFPROBE) += ffprobe
|
||||||
|
AVPROGS-$(CONFIG_FFSERVER) += ffserver
|
||||||
|
|
||||||
|
AVPROGS := $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
|
||||||
|
INSTPROGS = $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
|
||||||
|
PROGS += $(AVPROGS)
|
||||||
|
|
||||||
|
AVBASENAMES = ffmpeg ffplay ffprobe ffserver
|
||||||
|
ALLAVPROGS = $(AVBASENAMES:%=%$(PROGSSUF)$(EXESUF))
|
||||||
|
ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
|
||||||
|
|
||||||
|
$(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog) += cmdutils.o))
|
||||||
|
$(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog)-$(CONFIG_OPENCL) += cmdutils_opencl.o))
|
||||||
|
|
||||||
|
OBJS-ffmpeg += ffmpeg_opt.o ffmpeg_filter.o
|
||||||
|
OBJS-ffmpeg-$(CONFIG_VIDEOTOOLBOX) += ffmpeg_videotoolbox.o
|
||||||
|
OBJS-ffmpeg-$(CONFIG_LIBMFX) += ffmpeg_qsv.o
|
||||||
|
OBJS-ffmpeg-$(CONFIG_VAAPI) += ffmpeg_vaapi.o
|
||||||
|
ifndef CONFIG_VIDEOTOOLBOX
|
||||||
|
OBJS-ffmpeg-$(CONFIG_VDA) += ffmpeg_videotoolbox.o
|
||||||
|
endif
|
||||||
|
OBJS-ffmpeg-$(CONFIG_CUVID) += ffmpeg_cuvid.o
|
||||||
|
OBJS-ffmpeg-$(HAVE_DXVA2_LIB) += ffmpeg_dxva2.o
|
||||||
|
OBJS-ffmpeg-$(HAVE_VDPAU_X11) += ffmpeg_vdpau.o
|
||||||
|
OBJS-ffserver += ffserver_config.o
|
||||||
|
|
||||||
TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64 audiomatch
|
TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64 audiomatch
|
||||||
HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options
|
HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options
|
||||||
|
TOOLS = qt-faststart trasher uncoded_frame
|
||||||
|
TOOLS-$(CONFIG_ZLIB) += cws2fws
|
||||||
|
|
||||||
# $(FFLIBS-yes) needs to be in linking order
|
# $(FFLIBS-yes) needs to be in linking order
|
||||||
FFLIBS-$(CONFIG_AVDEVICE) += avdevice
|
FFLIBS-$(CONFIG_AVDEVICE) += avdevice
|
||||||
FFLIBS-$(CONFIG_AVFILTER) += avfilter
|
FFLIBS-$(CONFIG_AVFILTER) += avfilter
|
||||||
FFLIBS-$(CONFIG_AVFORMAT) += avformat
|
FFLIBS-$(CONFIG_AVFORMAT) += avformat
|
||||||
FFLIBS-$(CONFIG_AVCODEC) += avcodec
|
FFLIBS-$(CONFIG_AVCODEC) += avcodec
|
||||||
|
FFLIBS-$(CONFIG_AVRESAMPLE) += avresample
|
||||||
FFLIBS-$(CONFIG_POSTPROC) += postproc
|
FFLIBS-$(CONFIG_POSTPROC) += postproc
|
||||||
FFLIBS-$(CONFIG_SWRESAMPLE) += swresample
|
FFLIBS-$(CONFIG_SWRESAMPLE) += swresample
|
||||||
FFLIBS-$(CONFIG_SWSCALE) += swscale
|
FFLIBS-$(CONFIG_SWSCALE) += swscale
|
||||||
@@ -31,67 +59,38 @@ FFLIBS-$(CONFIG_SWSCALE) += swscale
|
|||||||
FFLIBS := avutil
|
FFLIBS := avutil
|
||||||
|
|
||||||
DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.ffpreset) $(SRC_PATH)/doc/ffprobe.xsd
|
DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.ffpreset) $(SRC_PATH)/doc/ffprobe.xsd
|
||||||
|
EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/Makefile $(SRC_PATH)/doc/examples/README
|
||||||
|
|
||||||
SKIPHEADERS = compat/w32pthreads.h
|
SKIPHEADERS = cmdutils_common_opts.h \
|
||||||
|
compat/w32pthreads.h
|
||||||
|
|
||||||
# first so "all" becomes default target
|
include $(SRC_PATH)/common.mak
|
||||||
all: all-yes
|
|
||||||
|
|
||||||
include $(SRC_PATH)/tools/Makefile
|
|
||||||
include $(SRC_PATH)/ffbuild/common.mak
|
|
||||||
|
|
||||||
FF_EXTRALIBS := $(FFEXTRALIBS)
|
FF_EXTRALIBS := $(FFEXTRALIBS)
|
||||||
FF_DEP_LIBS := $(DEP_LIBS)
|
FF_DEP_LIBS := $(DEP_LIBS)
|
||||||
FF_STATIC_DEP_LIBS := $(STATIC_DEP_LIBS)
|
FF_STATIC_DEP_LIBS := $(STATIC_DEP_LIBS)
|
||||||
|
|
||||||
$(TOOLS): %$(EXESUF): %.o
|
all: $(AVPROGS)
|
||||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(EXTRALIBS-$(*F)) $(EXTRALIBS) $(ELIBS)
|
|
||||||
|
|
||||||
target_dec_%_fuzzer$(EXESUF): target_dec_%_fuzzer.o $(FF_DEP_LIBS)
|
$(TOOLS): %$(EXESUF): %.o $(EXEOBJS)
|
||||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS)
|
||||||
|
|
||||||
tools/target_bsf_%_fuzzer$(EXESUF): tools/target_bsf_%_fuzzer.o $(FF_DEP_LIBS)
|
tools/cws2fws$(EXESUF): ELIBS = $(ZLIB)
|
||||||
$(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): $(FF_DEP_LIBS)
|
||||||
tools/uncoded_frame$(EXESUF): ELIBS = $(FF_EXTRALIBS)
|
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 = \
|
config.h: .config
|
||||||
$(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c)) \
|
.config: $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c))
|
||||||
$(SRC_PATH)/libavcodec/bitstream_filters.c \
|
|
||||||
$(SRC_PATH)/libavcodec/parsers.c \
|
|
||||||
$(SRC_PATH)/libavformat/protocols.c \
|
|
||||||
|
|
||||||
config.h: ffbuild/.config
|
|
||||||
ffbuild/.config: $(CONFIGURABLE_COMPONENTS)
|
|
||||||
@-tput bold 2>/dev/null
|
@-tput bold 2>/dev/null
|
||||||
@-printf '\nWARNING: $(?) newer than config.h, rerun configure\n\n'
|
@-printf '\nWARNING: $(?F) newer than config.h, rerun configure\n\n'
|
||||||
@-tput sgr0 2>/dev/null
|
@-tput sgr0 2>/dev/null
|
||||||
|
|
||||||
SUBDIR_VARS := CLEANFILES FFLIBS HOSTPROGS TESTPROGS TOOLS \
|
SUBDIR_VARS := CLEANFILES EXAMPLES FFLIBS HOSTPROGS TESTPROGS TOOLS \
|
||||||
HEADERS ARCH_HEADERS BUILT_HEADERS SKIPHEADERS \
|
HEADERS ARCH_HEADERS BUILT_HEADERS SKIPHEADERS \
|
||||||
ARMV5TE-OBJS ARMV6-OBJS ARMV8-OBJS VFP-OBJS NEON-OBJS \
|
ARMV5TE-OBJS ARMV6-OBJS ARMV8-OBJS VFP-OBJS NEON-OBJS \
|
||||||
ALTIVEC-OBJS VSX-OBJS MMX-OBJS X86ASM-OBJS \
|
ALTIVEC-OBJS MMX-OBJS YASM-OBJS \
|
||||||
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSP-OBJS MSA-OBJS \
|
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSP-OBJS MSA-OBJS \
|
||||||
MMI-OBJS LSX-OBJS LASX-OBJS OBJS SLIBOBJS SHLIBOBJS \
|
MMI-OBJS OBJS SLIBOBJS HOSTOBJS TESTOBJS
|
||||||
STLIBOBJS HOSTOBJS TESTOBJS
|
|
||||||
|
|
||||||
define RESET
|
define RESET
|
||||||
$(1) :=
|
$(1) :=
|
||||||
@@ -104,32 +103,41 @@ SUBDIR := $(1)/
|
|||||||
include $(SRC_PATH)/$(1)/Makefile
|
include $(SRC_PATH)/$(1)/Makefile
|
||||||
-include $(SRC_PATH)/$(1)/$(ARCH)/Makefile
|
-include $(SRC_PATH)/$(1)/$(ARCH)/Makefile
|
||||||
-include $(SRC_PATH)/$(1)/$(INTRINSICS)/Makefile
|
-include $(SRC_PATH)/$(1)/$(INTRINSICS)/Makefile
|
||||||
include $(SRC_PATH)/ffbuild/library.mak
|
include $(SRC_PATH)/library.mak
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D))))
|
$(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D))))
|
||||||
|
|
||||||
include $(SRC_PATH)/fftools/Makefile
|
|
||||||
include $(SRC_PATH)/doc/Makefile
|
include $(SRC_PATH)/doc/Makefile
|
||||||
include $(SRC_PATH)/doc/examples/Makefile
|
|
||||||
|
|
||||||
libavcodec/avcodec.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
|
define DOPROG
|
||||||
|
OBJS-$(1) += $(1).o $(EXEOBJS) $(OBJS-$(1)-yes)
|
||||||
|
$(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1))
|
||||||
|
$$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1))
|
||||||
|
$(1)$(PROGSSUF)_g$(EXESUF): LDFLAGS += $(LDFLAGS-$(1))
|
||||||
|
$(1)$(PROGSSUF)_g$(EXESUF): FF_EXTRALIBS += $(LIBS-$(1))
|
||||||
|
-include $$(OBJS-$(1):.o=.d)
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(foreach P,$(PROGS),$(eval $(call DOPROG,$(P:$(PROGSSUF)$(EXESUF)=))))
|
||||||
|
|
||||||
|
ffprobe.o cmdutils.o 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
|
||||||
|
|
||||||
$(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF)
|
$(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF)
|
||||||
ifeq ($(STRIPTYPE),direct)
|
|
||||||
$(STRIP) -o $@ $<
|
|
||||||
else
|
|
||||||
$(CP) $< $@
|
$(CP) $< $@
|
||||||
$(STRIP) $@
|
$(STRIP) $@
|
||||||
endif
|
|
||||||
|
|
||||||
%$(PROGSSUF)_g$(EXESUF): $(FF_DEP_LIBS)
|
%$(PROGSSUF)_g$(EXESUF): %.o $(FF_DEP_LIBS)
|
||||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS)
|
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS)
|
||||||
|
|
||||||
VERSION_SH = $(SRC_PATH)/ffbuild/version.sh
|
OBJDIRS += tools
|
||||||
|
|
||||||
|
-include $(wildcard tools/*.d)
|
||||||
|
|
||||||
|
VERSION_SH = $(SRC_PATH)/version.sh
|
||||||
GIT_LOG = $(SRC_PATH)/.git/logs/HEAD
|
GIT_LOG = $(SRC_PATH)/.git/logs/HEAD
|
||||||
|
|
||||||
.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) ffbuild/config.mak
|
.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) config.mak
|
||||||
.version: M=@
|
.version: M=@
|
||||||
|
|
||||||
libavutil/ffversion.h .version:
|
libavutil/ffversion.h .version:
|
||||||
@@ -139,33 +147,44 @@ libavutil/ffversion.h .version:
|
|||||||
# force version.sh to run whenever version might have changed
|
# force version.sh to run whenever version might have changed
|
||||||
-include .version
|
-include .version
|
||||||
|
|
||||||
|
ifdef AVPROGS
|
||||||
|
install: install-progs install-data
|
||||||
|
endif
|
||||||
|
|
||||||
install: install-libs install-headers
|
install: install-libs install-headers
|
||||||
|
|
||||||
install-libs: install-libs-yes
|
install-libs: install-libs-yes
|
||||||
|
|
||||||
install-data: $(DATA_FILES)
|
install-progs-yes:
|
||||||
$(Q)mkdir -p "$(DATADIR)"
|
install-progs-$(CONFIG_SHARED): install-libs
|
||||||
$(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)"
|
|
||||||
|
|
||||||
uninstall: uninstall-data uninstall-headers uninstall-libs uninstall-pkgconfig
|
install-progs: install-progs-yes $(AVPROGS)
|
||||||
|
$(Q)mkdir -p "$(BINDIR)"
|
||||||
|
$(INSTALL) -c -m 755 $(INSTPROGS) "$(BINDIR)"
|
||||||
|
|
||||||
|
install-data: $(DATA_FILES) $(EXAMPLES_FILES)
|
||||||
|
$(Q)mkdir -p "$(DATADIR)/examples"
|
||||||
|
$(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)"
|
||||||
|
$(INSTALL) -m 644 $(EXAMPLES_FILES) "$(DATADIR)/examples"
|
||||||
|
|
||||||
|
uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data
|
||||||
|
|
||||||
|
uninstall-progs:
|
||||||
|
$(RM) $(addprefix "$(BINDIR)/", $(ALLAVPROGS))
|
||||||
|
|
||||||
uninstall-data:
|
uninstall-data:
|
||||||
$(RM) -r "$(DATADIR)"
|
$(RM) -r "$(DATADIR)"
|
||||||
|
|
||||||
clean::
|
clean::
|
||||||
|
$(RM) $(ALLAVPROGS) $(ALLAVPROGS_G)
|
||||||
$(RM) $(CLEANSUFFIXES)
|
$(RM) $(CLEANSUFFIXES)
|
||||||
$(RM) $(addprefix compat/,$(CLEANSUFFIXES)) $(addprefix compat/*/,$(CLEANSUFFIXES)) $(addprefix compat/*/*/,$(CLEANSUFFIXES))
|
$(RM) $(CLEANSUFFIXES:%=tools/%)
|
||||||
$(RM) -r coverage-html
|
$(RM) -r coverage-html
|
||||||
$(RM) -rf coverage.info coverage.info.in lcov
|
$(RM) -rf coverage.info coverage.info.in lcov
|
||||||
|
|
||||||
distclean:: clean
|
distclean::
|
||||||
$(RM) .version avversion.h config.asm config.h mapfile \
|
$(RM) $(DISTCLEANSUFFIXES)
|
||||||
ffbuild/.config ffbuild/config.* libavutil/avconfig.h \
|
$(RM) config.* .config libavutil/avconfig.h .version mapfile avversion.h version.h libavutil/ffversion.h libavcodec/codec_names.h libavcodec/bsf_list.c libavformat/protocol_list.c
|
||||||
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)
|
ifeq ($(SRC_LINK),src)
|
||||||
$(RM) src
|
$(RM) src
|
||||||
endif
|
endif
|
||||||
@@ -174,12 +193,11 @@ endif
|
|||||||
config:
|
config:
|
||||||
$(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION)
|
$(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION)
|
||||||
|
|
||||||
build: all alltools examples testprogs
|
|
||||||
check: all alltools examples testprogs fate
|
check: all alltools examples testprogs fate
|
||||||
|
|
||||||
include $(SRC_PATH)/tests/Makefile
|
include $(SRC_PATH)/tests/Makefile
|
||||||
|
|
||||||
$(sort $(OUTDIRS)):
|
$(sort $(OBJDIRS)):
|
||||||
$(Q)mkdir -p $@
|
$(Q)mkdir -p $@
|
||||||
|
|
||||||
# Dummy rule to stop make trying to rebuild removed or renamed headers
|
# Dummy rule to stop make trying to rebuild removed or renamed headers
|
||||||
@@ -190,5 +208,5 @@ $(sort $(OUTDIRS)):
|
|||||||
# so this saves some time on slow systems.
|
# so this saves some time on slow systems.
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
|
|
||||||
.PHONY: all all-yes alltools build check config testprogs
|
.PHONY: all all-yes alltools check *clean config install*
|
||||||
.PHONY: *clean install* uninstall*
|
.PHONY: testprogs uninstall*
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ such as audio, video, subtitles and related metadata.
|
|||||||
* `libavcodec` provides implementation of a wider range of codecs.
|
* `libavcodec` provides implementation of a wider range of codecs.
|
||||||
* `libavformat` implements streaming protocols, container formats and basic I/O access.
|
* `libavformat` implements streaming protocols, container formats and basic I/O access.
|
||||||
* `libavutil` includes hashers, decompressors and miscellaneous utility functions.
|
* `libavutil` includes hashers, decompressors and miscellaneous utility functions.
|
||||||
* `libavfilter` provides means to alter decoded audio and video through a directed graph of connected filters.
|
* `libavfilter` provides a mean to alter decoded Audio and Video through chain of filters.
|
||||||
* `libavdevice` provides an abstraction to access capture and playback devices.
|
* `libavdevice` provides an abstraction to access capture and playback devices.
|
||||||
* `libswresample` implements audio mixing and resampling routines.
|
* `libswresample` implements audio mixing and resampling routines.
|
||||||
* `libswscale` implements color conversion and scaling routines.
|
* `libswscale` implements color conversion and scaling routines.
|
||||||
@@ -21,6 +21,8 @@ such as audio, video, subtitles and related metadata.
|
|||||||
* [ffplay](https://ffmpeg.org/ffplay.html) is a minimalistic multimedia player.
|
* [ffplay](https://ffmpeg.org/ffplay.html) is a minimalistic multimedia player.
|
||||||
* [ffprobe](https://ffmpeg.org/ffprobe.html) is a simple analysis tool to inspect
|
* [ffprobe](https://ffmpeg.org/ffprobe.html) is a simple analysis tool to inspect
|
||||||
multimedia content.
|
multimedia content.
|
||||||
|
* [ffserver](https://ffmpeg.org/ffserver.html) is a multimedia streaming server
|
||||||
|
for live broadcasts.
|
||||||
* Additional small tools such as `aviocat`, `ismindex` and `qt-faststart`.
|
* Additional small tools such as `aviocat`, `ismindex` and `qt-faststart`.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
@@ -43,4 +45,5 @@ GPL. Please refer to the LICENSE file for detailed information.
|
|||||||
|
|
||||||
Patches should be submitted to the ffmpeg-devel mailing list using
|
Patches should be submitted to the ffmpeg-devel mailing list using
|
||||||
`git format-patch` or `git send-email`. Github pull requests should be
|
`git format-patch` or `git send-email`. Github pull requests should be
|
||||||
avoided because they are not part of our review process and will be ignored.
|
avoided because they are not part of our review process. Few developers
|
||||||
|
follow pull requests so they will likely be ignored.
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
|
|
||||||
┌────────────────────────────────────────┐
|
┌────────────────────────────────────────┐
|
||||||
│ RELEASE NOTES for FFmpeg 5.0 "Lorentz" │
|
│ RELEASE NOTES for FFmpeg 3.1 "Laplace" │
|
||||||
└────────────────────────────────────────┘
|
└────────────────────────────────────────┘
|
||||||
|
|
||||||
The FFmpeg Project proudly presents FFmpeg 5.0 "Lorentz", about 9
|
The FFmpeg Project proudly presents FFmpeg 3.1 "Laplace", about 4
|
||||||
months after the release of FFmpeg 4.4.
|
months after the release of FFmpeg 3.0.
|
||||||
|
|
||||||
A complete Changelog is available at the root of the project, and the
|
A complete Changelog is available at the root of the project, and the
|
||||||
complete Git history on https://git.ffmpeg.org/gitweb/ffmpeg.git
|
complete Git history on http://source.ffmpeg.org.
|
||||||
|
|
||||||
We hope you will like this release as much as we enjoyed working on it, and
|
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,
|
as usual, if you have any questions about it, or any FFmpeg related topic,
|
||||||
feel free to join us on the #ffmpeg IRC channel (on irc.libera.chat) or ask
|
feel free to join us on the #ffmpeg IRC channel (on irc.freenode.net) or ask
|
||||||
on the mailing-lists.
|
on the mailing-lists.
|
||||||
|
|||||||
@@ -8,12 +8,10 @@ OBJS-$(HAVE_MIPSFPU) += $(MIPSFPU-OBJS) $(MIPSFPU-OBJS-yes)
|
|||||||
OBJS-$(HAVE_MIPSDSP) += $(MIPSDSP-OBJS) $(MIPSDSP-OBJS-yes)
|
OBJS-$(HAVE_MIPSDSP) += $(MIPSDSP-OBJS) $(MIPSDSP-OBJS-yes)
|
||||||
OBJS-$(HAVE_MIPSDSPR2) += $(MIPSDSPR2-OBJS) $(MIPSDSPR2-OBJS-yes)
|
OBJS-$(HAVE_MIPSDSPR2) += $(MIPSDSPR2-OBJS) $(MIPSDSPR2-OBJS-yes)
|
||||||
OBJS-$(HAVE_MSA) += $(MSA-OBJS) $(MSA-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_ALTIVEC) += $(ALTIVEC-OBJS) $(ALTIVEC-OBJS-yes)
|
||||||
OBJS-$(HAVE_VSX) += $(VSX-OBJS) $(VSX-OBJS-yes)
|
OBJS-$(HAVE_VSX) += $(VSX-OBJS) $(VSX-OBJS-yes)
|
||||||
|
|
||||||
OBJS-$(HAVE_MMX) += $(MMX-OBJS) $(MMX-OBJS-yes)
|
OBJS-$(HAVE_MMX) += $(MMX-OBJS) $(MMX-OBJS-yes)
|
||||||
OBJS-$(HAVE_X86ASM) += $(X86ASM-OBJS) $(X86ASM-OBJS-yes)
|
OBJS-$(HAVE_YASM) += $(YASM-OBJS) $(YASM-OBJS-yes)
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -19,8 +19,8 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FFTOOLS_CMDUTILS_H
|
#ifndef CMDUTILS_H
|
||||||
#define FFTOOLS_CMDUTILS_H
|
#define CMDUTILS_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
|
|||||||
extern AVFormatContext *avformat_opts;
|
extern AVFormatContext *avformat_opts;
|
||||||
extern AVDictionary *sws_dict;
|
extern AVDictionary *sws_dict;
|
||||||
extern AVDictionary *swr_opts;
|
extern AVDictionary *swr_opts;
|
||||||
extern AVDictionary *format_opts, *codec_opts;
|
extern AVDictionary *format_opts, *codec_opts, *resample_opts;
|
||||||
extern int hide_banner;
|
extern int hide_banner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,11 +61,6 @@ void register_exit(void (*cb)(int ret));
|
|||||||
*/
|
*/
|
||||||
void exit_program(int ret) av_noreturn;
|
void exit_program(int ret) av_noreturn;
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize dynamic library loading
|
|
||||||
*/
|
|
||||||
void init_dynload(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the cmdutils option system, in particular
|
* Initialize the cmdutils option system, in particular
|
||||||
* allocate the *_opts contexts.
|
* allocate the *_opts contexts.
|
||||||
@@ -88,11 +83,6 @@ void log_callback_help(void* ptr, int level, const char* fmt, va_list vl);
|
|||||||
*/
|
*/
|
||||||
int opt_cpuflags(void *optctx, const char *opt, const char *arg);
|
int opt_cpuflags(void *optctx, const char *opt, const char *arg);
|
||||||
|
|
||||||
/**
|
|
||||||
* Override the cpucount.
|
|
||||||
*/
|
|
||||||
int opt_cpucount(void *optctx, const char *opt, const char *arg);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fallback for options that are not explicitly handled, these will be
|
* Fallback for options that are not explicitly handled, these will be
|
||||||
* parsed through AVOptions.
|
* parsed through AVOptions.
|
||||||
@@ -104,12 +94,18 @@ int opt_default(void *optctx, const char *opt, const char *arg);
|
|||||||
*/
|
*/
|
||||||
int opt_loglevel(void *optctx, const char *opt, const char *arg);
|
int opt_loglevel(void *optctx, const char *opt, const char *arg);
|
||||||
|
|
||||||
int opt_report(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_max_alloc(void *optctx, const char *opt, const char *arg);
|
||||||
|
|
||||||
int opt_codec_debug(void *optctx, const char *opt, const char *arg);
|
int opt_codec_debug(void *optctx, const char *opt, const char *arg);
|
||||||
|
|
||||||
|
#if CONFIG_OPENCL
|
||||||
|
int opt_opencl(void *optctx, const char *opt, const char *arg);
|
||||||
|
|
||||||
|
int opt_opencl_bench(void *optctx, const char *opt, const char *arg);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Limit the execution time.
|
* Limit the execution time.
|
||||||
*/
|
*/
|
||||||
@@ -154,7 +150,6 @@ typedef struct SpecifierOpt {
|
|||||||
uint8_t *str;
|
uint8_t *str;
|
||||||
int i;
|
int i;
|
||||||
int64_t i64;
|
int64_t i64;
|
||||||
uint64_t ui64;
|
|
||||||
float f;
|
float f;
|
||||||
double dbl;
|
double dbl;
|
||||||
} u;
|
} u;
|
||||||
@@ -206,49 +201,6 @@ typedef struct OptionDef {
|
|||||||
void show_help_options(const OptionDef *options, const char *msg, int req_flags,
|
void show_help_options(const OptionDef *options, const char *msg, int req_flags,
|
||||||
int rej_flags, int alt_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" }, \
|
|
||||||
{ "dispositions", OPT_EXIT, { .func_arg = show_dispositions}, "show available stream dispositions" }, \
|
|
||||||
{ "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, { .func_arg = 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" }, \
|
|
||||||
{ "cpucount", HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpucount }, "force specific cpu count", "count" }, \
|
|
||||||
{ "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
|
* Show help for all options with given flags in class and all its
|
||||||
* children.
|
* children.
|
||||||
@@ -324,6 +276,7 @@ typedef struct OptionGroup {
|
|||||||
|
|
||||||
AVDictionary *codec_opts;
|
AVDictionary *codec_opts;
|
||||||
AVDictionary *format_opts;
|
AVDictionary *format_opts;
|
||||||
|
AVDictionary *resample_opts;
|
||||||
AVDictionary *sws_dict;
|
AVDictionary *sws_dict;
|
||||||
AVDictionary *swr_opts;
|
AVDictionary *swr_opts;
|
||||||
} OptionGroup;
|
} OptionGroup;
|
||||||
@@ -420,7 +373,7 @@ int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec);
|
|||||||
* @return a pointer to the created dictionary
|
* @return a pointer to the created dictionary
|
||||||
*/
|
*/
|
||||||
AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
|
AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
|
||||||
AVFormatContext *s, AVStream *st, const AVCodec *codec);
|
AVFormatContext *s, AVStream *st, AVCodec *codec);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup AVCodecContext options for avformat_find_stream_info().
|
* Setup AVCodecContext options for avformat_find_stream_info().
|
||||||
@@ -430,8 +383,8 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
|
|||||||
* Each dictionary will contain the options from codec_opts which can
|
* Each dictionary will contain the options from codec_opts which can
|
||||||
* be applied to the corresponding stream codec context.
|
* be applied to the corresponding stream codec context.
|
||||||
*
|
*
|
||||||
* @return pointer to the created array of dictionaries.
|
* @return pointer to the created array of dictionaries, NULL if it
|
||||||
* Calls exit() on failure.
|
* cannot be created
|
||||||
*/
|
*/
|
||||||
AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
|
AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
|
||||||
AVDictionary *codec_opts);
|
AVDictionary *codec_opts);
|
||||||
@@ -483,20 +436,6 @@ int show_license(void *optctx, const char *opt, const char *arg);
|
|||||||
*/
|
*/
|
||||||
int show_formats(void *optctx, const char *opt, const char *arg);
|
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
|
* Print a listing containing all the devices supported by the
|
||||||
* program.
|
* program.
|
||||||
@@ -506,13 +445,13 @@ int show_devices(void *optctx, const char *opt, const char *arg);
|
|||||||
|
|
||||||
#if CONFIG_AVDEVICE
|
#if CONFIG_AVDEVICE
|
||||||
/**
|
/**
|
||||||
* Print a listing containing autodetected sinks of the output device.
|
* Print a listing containing audodetected sinks of the output device.
|
||||||
* Device name with options may be passed as an argument to limit results.
|
* Device name with options may be passed as an argument to limit results.
|
||||||
*/
|
*/
|
||||||
int show_sinks(void *optctx, const char *opt, const char *arg);
|
int show_sinks(void *optctx, const char *opt, const char *arg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print a listing containing autodetected sources of the input device.
|
* Print a listing containing audodetected sources of the input device.
|
||||||
* Device name with options may be passed as an argument to limit results.
|
* Device name with options may be passed as an argument to limit results.
|
||||||
*/
|
*/
|
||||||
int show_sources(void *optctx, const char *opt, const char *arg);
|
int show_sources(void *optctx, const char *opt, const char *arg);
|
||||||
@@ -578,11 +517,6 @@ int show_layouts(void *optctx, const char *opt, const char *arg);
|
|||||||
*/
|
*/
|
||||||
int show_sample_fmts(void *optctx, const char *opt, const char *arg);
|
int show_sample_fmts(void *optctx, const char *opt, const char *arg);
|
||||||
|
|
||||||
/**
|
|
||||||
* Print a listing containing all supported stream dispositions.
|
|
||||||
*/
|
|
||||||
int show_dispositions(void *optctx, const char *opt, const char *arg);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print a listing containing all the color names and values recognized
|
* Print a listing containing all the color names and values recognized
|
||||||
* by the program.
|
* by the program.
|
||||||
@@ -628,34 +562,14 @@ FILE *get_preset_file(char *filename, size_t filename_size,
|
|||||||
*/
|
*/
|
||||||
void *grow_array(void *array, int elem_size, int *size, int new_size);
|
void *grow_array(void *array, int elem_size, int *size, int new_size);
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 media_type_string av_get_media_type_string
|
#define media_type_string av_get_media_type_string
|
||||||
|
|
||||||
#define GROW_ARRAY(array, nb_elems)\
|
#define GROW_ARRAY(array, nb_elems)\
|
||||||
array = grow_array(array, sizeof(*array), &nb_elems, nb_elems + 1)
|
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)\
|
#define GET_PIX_FMT_NAME(pix_fmt)\
|
||||||
const char *name = av_get_pix_fmt_name(pix_fmt);
|
const char *name = av_get_pix_fmt_name(pix_fmt);
|
||||||
|
|
||||||
#define GET_CODEC_NAME(id)\
|
|
||||||
const char *name = avcodec_descriptor_get(id)->name;
|
|
||||||
|
|
||||||
#define GET_SAMPLE_FMT_NAME(sample_fmt)\
|
#define GET_SAMPLE_FMT_NAME(sample_fmt)\
|
||||||
const char *name = av_get_sample_fmt_name(sample_fmt)
|
const char *name = av_get_sample_fmt_name(sample_fmt)
|
||||||
|
|
||||||
@@ -671,6 +585,6 @@ void *allocate_array_elem(void *array, size_t elem_size, int *nb_elems);
|
|||||||
char name[128];\
|
char name[128];\
|
||||||
av_get_channel_layout_string(name, sizeof(name), 0, ch_layout);
|
av_get_channel_layout_string(name, sizeof(name), 0, ch_layout);
|
||||||
|
|
||||||
double get_rotation(int32_t *displaymatrix);
|
double get_rotation(AVStream *st);
|
||||||
|
|
||||||
#endif /* FFTOOLS_CMDUTILS_H */
|
#endif /* CMDUTILS_H */
|
||||||
35
cmdutils_common_opts.h
Normal file
35
cmdutils_common_opts.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{ "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" },
|
||||||
|
{ "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" },
|
||||||
|
#if CONFIG_OPENCL
|
||||||
|
{ "opencl_bench", OPT_EXIT, {.func_arg = opt_opencl_bench}, "run benchmark on all OpenCL devices and show results" },
|
||||||
|
{ "opencl_options", HAS_ARG, {.func_arg = opt_opencl}, "set OpenCL environment options" },
|
||||||
|
#endif
|
||||||
|
#if CONFIG_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" },
|
||||||
|
#endif
|
||||||
278
cmdutils_opencl.c
Normal file
278
cmdutils_opencl.c
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 Lenny Wang
|
||||||
|
*
|
||||||
|
* This file is part of FFmpeg.
|
||||||
|
*
|
||||||
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FFmpeg is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with FFmpeg; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libavutil/opt.h"
|
||||||
|
#include "libavutil/time.h"
|
||||||
|
#include "libavutil/log.h"
|
||||||
|
#include "libavutil/opencl.h"
|
||||||
|
#include "libavutil/avstring.h"
|
||||||
|
#include "cmdutils.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int platform_idx;
|
||||||
|
int device_idx;
|
||||||
|
char device_name[64];
|
||||||
|
int64_t runtime;
|
||||||
|
} OpenCLDeviceBenchmark;
|
||||||
|
|
||||||
|
const char *ocl_bench_source = AV_OPENCL_KERNEL(
|
||||||
|
inline unsigned char clip_uint8(int a)
|
||||||
|
{
|
||||||
|
if (a & (~0xFF))
|
||||||
|
return (-a)>>31;
|
||||||
|
else
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
kernel void unsharp_bench(
|
||||||
|
global unsigned char *src,
|
||||||
|
global unsigned char *dst,
|
||||||
|
global int *mask,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
int i, j, local_idx, lc_idx, sum = 0;
|
||||||
|
int2 thread_idx, block_idx, global_idx, lm_idx;
|
||||||
|
thread_idx.x = get_local_id(0);
|
||||||
|
thread_idx.y = get_local_id(1);
|
||||||
|
block_idx.x = get_group_id(0);
|
||||||
|
block_idx.y = get_group_id(1);
|
||||||
|
global_idx.x = get_global_id(0);
|
||||||
|
global_idx.y = get_global_id(1);
|
||||||
|
local uchar data[32][32];
|
||||||
|
local int lc[128];
|
||||||
|
|
||||||
|
for (i = 0; i <= 1; i++) {
|
||||||
|
lm_idx.y = -8 + (block_idx.y + i) * 16 + thread_idx.y;
|
||||||
|
lm_idx.y = lm_idx.y < 0 ? 0 : lm_idx.y;
|
||||||
|
lm_idx.y = lm_idx.y >= height ? height - 1: lm_idx.y;
|
||||||
|
for (j = 0; j <= 1; j++) {
|
||||||
|
lm_idx.x = -8 + (block_idx.x + j) * 16 + thread_idx.x;
|
||||||
|
lm_idx.x = lm_idx.x < 0 ? 0 : lm_idx.x;
|
||||||
|
lm_idx.x = lm_idx.x >= width ? width - 1: lm_idx.x;
|
||||||
|
data[i*16 + thread_idx.y][j*16 + thread_idx.x] = src[lm_idx.y*width + lm_idx.x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
local_idx = thread_idx.y*16 + thread_idx.x;
|
||||||
|
if (local_idx < 128)
|
||||||
|
lc[local_idx] = mask[local_idx];
|
||||||
|
barrier(CLK_LOCAL_MEM_FENCE);
|
||||||
|
|
||||||
|
\n#pragma unroll\n
|
||||||
|
for (i = -4; i <= 4; i++) {
|
||||||
|
lm_idx.y = 8 + i + thread_idx.y;
|
||||||
|
\n#pragma unroll\n
|
||||||
|
for (j = -4; j <= 4; j++) {
|
||||||
|
lm_idx.x = 8 + j + thread_idx.x;
|
||||||
|
lc_idx = (i + 4)*8 + j + 4;
|
||||||
|
sum += (int)data[lm_idx.y][lm_idx.x] * lc[lc_idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int temp = (int)data[thread_idx.y + 8][thread_idx.x + 8];
|
||||||
|
int res = temp + (((temp - (int)((sum + 1<<15) >> 16))) >> 16);
|
||||||
|
if (global_idx.x < width && global_idx.y < height)
|
||||||
|
dst[global_idx.x + global_idx.y*width] = clip_uint8(res);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
#define OCLCHECK(method, ... ) \
|
||||||
|
do { \
|
||||||
|
status = method(__VA_ARGS__); \
|
||||||
|
if (status != CL_SUCCESS) { \
|
||||||
|
av_log(NULL, AV_LOG_ERROR, # method " error '%s'\n", \
|
||||||
|
av_opencl_errstr(status)); \
|
||||||
|
ret = AVERROR_EXTERNAL; \
|
||||||
|
goto end; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CREATEBUF(out, flags, size) \
|
||||||
|
do { \
|
||||||
|
out = clCreateBuffer(ext_opencl_env->context, flags, size, NULL, &status); \
|
||||||
|
if (status != CL_SUCCESS) { \
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "Could not create OpenCL buffer\n"); \
|
||||||
|
ret = AVERROR_EXTERNAL; \
|
||||||
|
goto end; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static void fill_rand_int(int *data, int n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
srand(av_gettime());
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
data[i] = rand();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OPENCL_NB_ITER 5
|
||||||
|
static int64_t run_opencl_bench(AVOpenCLExternalEnv *ext_opencl_env)
|
||||||
|
{
|
||||||
|
int i, arg = 0, width = 1920, height = 1088;
|
||||||
|
int64_t start, ret = 0;
|
||||||
|
cl_int status;
|
||||||
|
size_t kernel_len;
|
||||||
|
char *inbuf;
|
||||||
|
int *mask;
|
||||||
|
int buf_size = width * height * sizeof(char);
|
||||||
|
int mask_size = sizeof(uint32_t) * 128;
|
||||||
|
|
||||||
|
cl_mem cl_mask, cl_inbuf, cl_outbuf;
|
||||||
|
cl_kernel kernel = NULL;
|
||||||
|
cl_program program = NULL;
|
||||||
|
size_t local_work_size_2d[2] = {16, 16};
|
||||||
|
size_t global_work_size_2d[2] = {(size_t)width, (size_t)height};
|
||||||
|
|
||||||
|
if (!(inbuf = av_malloc(buf_size)) || !(mask = av_malloc(mask_size))) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
fill_rand_int((int*)inbuf, buf_size/4);
|
||||||
|
fill_rand_int(mask, mask_size/4);
|
||||||
|
|
||||||
|
CREATEBUF(cl_mask, CL_MEM_READ_ONLY, mask_size);
|
||||||
|
CREATEBUF(cl_inbuf, CL_MEM_READ_ONLY, buf_size);
|
||||||
|
CREATEBUF(cl_outbuf, CL_MEM_READ_WRITE, buf_size);
|
||||||
|
|
||||||
|
kernel_len = strlen(ocl_bench_source);
|
||||||
|
program = clCreateProgramWithSource(ext_opencl_env->context, 1, &ocl_bench_source,
|
||||||
|
&kernel_len, &status);
|
||||||
|
if (status != CL_SUCCESS || !program) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "OpenCL unable to create benchmark program\n");
|
||||||
|
ret = AVERROR_EXTERNAL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
status = clBuildProgram(program, 1, &(ext_opencl_env->device_id), NULL, NULL, NULL);
|
||||||
|
if (status != CL_SUCCESS) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "OpenCL unable to build benchmark program\n");
|
||||||
|
ret = AVERROR_EXTERNAL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
kernel = clCreateKernel(program, "unsharp_bench", &status);
|
||||||
|
if (status != CL_SUCCESS) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "OpenCL unable to create benchmark kernel\n");
|
||||||
|
ret = AVERROR_EXTERNAL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
OCLCHECK(clEnqueueWriteBuffer, ext_opencl_env->command_queue, cl_inbuf, CL_TRUE, 0,
|
||||||
|
buf_size, inbuf, 0, NULL, NULL);
|
||||||
|
OCLCHECK(clEnqueueWriteBuffer, ext_opencl_env->command_queue, cl_mask, CL_TRUE, 0,
|
||||||
|
mask_size, mask, 0, NULL, NULL);
|
||||||
|
OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &cl_inbuf);
|
||||||
|
OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &cl_outbuf);
|
||||||
|
OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &cl_mask);
|
||||||
|
OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_int), &width);
|
||||||
|
OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_int), &height);
|
||||||
|
|
||||||
|
start = av_gettime_relative();
|
||||||
|
for (i = 0; i < OPENCL_NB_ITER; i++)
|
||||||
|
OCLCHECK(clEnqueueNDRangeKernel, ext_opencl_env->command_queue, kernel, 2, NULL,
|
||||||
|
global_work_size_2d, local_work_size_2d, 0, NULL, NULL);
|
||||||
|
clFinish(ext_opencl_env->command_queue);
|
||||||
|
ret = (av_gettime_relative() - start)/OPENCL_NB_ITER;
|
||||||
|
end:
|
||||||
|
if (kernel)
|
||||||
|
clReleaseKernel(kernel);
|
||||||
|
if (program)
|
||||||
|
clReleaseProgram(program);
|
||||||
|
if (cl_inbuf)
|
||||||
|
clReleaseMemObject(cl_inbuf);
|
||||||
|
if (cl_outbuf)
|
||||||
|
clReleaseMemObject(cl_outbuf);
|
||||||
|
if (cl_mask)
|
||||||
|
clReleaseMemObject(cl_mask);
|
||||||
|
av_free(inbuf);
|
||||||
|
av_free(mask);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int compare_ocl_device_desc(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const OpenCLDeviceBenchmark* va = (const OpenCLDeviceBenchmark*)a;
|
||||||
|
const OpenCLDeviceBenchmark* vb = (const OpenCLDeviceBenchmark*)b;
|
||||||
|
return FFDIFFSIGN(va->runtime , vb->runtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
int opt_opencl_bench(void *optctx, const char *opt, const char *arg)
|
||||||
|
{
|
||||||
|
int i, j, nb_devices = 0, count = 0;
|
||||||
|
int64_t score = 0;
|
||||||
|
AVOpenCLDeviceList *device_list;
|
||||||
|
AVOpenCLDeviceNode *device_node = NULL;
|
||||||
|
OpenCLDeviceBenchmark *devices = NULL;
|
||||||
|
cl_platform_id platform;
|
||||||
|
|
||||||
|
av_opencl_get_device_list(&device_list);
|
||||||
|
for (i = 0; i < device_list->platform_num; i++)
|
||||||
|
nb_devices += device_list->platform_node[i]->device_num;
|
||||||
|
if (!nb_devices) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "No OpenCL device detected!\n");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
if (!(devices = av_malloc_array(nb_devices, sizeof(OpenCLDeviceBenchmark)))) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "Could not allocate buffer\n");
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < device_list->platform_num; i++) {
|
||||||
|
for (j = 0; j < device_list->platform_node[i]->device_num; j++) {
|
||||||
|
device_node = device_list->platform_node[i]->device_node[j];
|
||||||
|
platform = device_list->platform_node[i]->platform_id;
|
||||||
|
score = av_opencl_benchmark(device_node, platform, run_opencl_bench);
|
||||||
|
if (score > 0) {
|
||||||
|
devices[count].platform_idx = i;
|
||||||
|
devices[count].device_idx = j;
|
||||||
|
devices[count].runtime = score;
|
||||||
|
av_strlcpy(devices[count].device_name, device_node->device_name,
|
||||||
|
sizeof(devices[count].device_name));
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qsort(devices, count, sizeof(OpenCLDeviceBenchmark), compare_ocl_device_desc);
|
||||||
|
fprintf(stderr, "platform_idx\tdevice_idx\tdevice_name\truntime\n");
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
fprintf(stdout, "%d\t%d\t%s\t%"PRId64"\n",
|
||||||
|
devices[i].platform_idx, devices[i].device_idx,
|
||||||
|
devices[i].device_name, devices[i].runtime);
|
||||||
|
|
||||||
|
av_opencl_free_device_list(&device_list);
|
||||||
|
av_free(devices);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int opt_opencl(void *optctx, const char *opt, const char *arg)
|
||||||
|
{
|
||||||
|
char *key, *value;
|
||||||
|
const char *opts = arg;
|
||||||
|
int ret = 0;
|
||||||
|
while (*opts) {
|
||||||
|
ret = av_opt_get_key_value(&opts, "=", ":", 0, &key, &value);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = av_opencl_set_option(key, value);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
if (*opts)
|
||||||
|
opts++;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -2,24 +2,24 @@
|
|||||||
# common bits used by all libraries
|
# common bits used by all libraries
|
||||||
#
|
#
|
||||||
|
|
||||||
DEFAULT_X86ASMD=.dbg
|
# first so "all" becomes default target
|
||||||
|
all: all-yes
|
||||||
|
|
||||||
|
DEFAULT_YASMD=.dbg
|
||||||
|
|
||||||
ifeq ($(DBG),1)
|
ifeq ($(DBG),1)
|
||||||
X86ASMD=$(DEFAULT_X86ASMD)
|
YASMD=$(DEFAULT_YASMD)
|
||||||
else
|
else
|
||||||
X86ASMD=
|
YASMD=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef SUBDIR
|
ifndef SUBDIR
|
||||||
|
|
||||||
BIN2CEXE = ffbuild/bin2c$(HOSTEXESUF)
|
|
||||||
BIN2C = $(BIN2CEXE)
|
|
||||||
|
|
||||||
ifndef V
|
ifndef V
|
||||||
Q = @
|
Q = @
|
||||||
ECHO = printf "$(1)\t%s\n" $(2)
|
ECHO = printf "$(1)\t%s\n" $(2)
|
||||||
BRIEF = CC CXX OBJCC HOSTCC HOSTLD AS X86ASM AR LD STRIP CP WINDRES NVCC BIN2C
|
BRIEF = CC CXX OBJCC HOSTCC HOSTLD AS YASM AR LD STRIP CP WINDRES
|
||||||
SILENT = DEPCC DEPHOSTCC DEPAS DEPX86ASM RANLIB RM
|
SILENT = DEPCC DEPHOSTCC DEPAS DEPYASM RANLIB RM
|
||||||
|
|
||||||
MSG = $@
|
MSG = $@
|
||||||
M = @$(call ECHO,$(TAG),$@);
|
M = @$(call ECHO,$(TAG),$@);
|
||||||
@@ -29,7 +29,7 @@ $(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR))))
|
|||||||
$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL))
|
$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale swresample
|
ALLFFLIBS = avcodec avdevice avfilter avformat avresample avutil postproc swscale swresample
|
||||||
|
|
||||||
# NASM requires -I path terminated with /
|
# NASM requires -I path terminated with /
|
||||||
IFLAGS := -I. -I$(SRC_LINK)/
|
IFLAGS := -I. -I$(SRC_LINK)/
|
||||||
@@ -40,39 +40,21 @@ OBJCFLAGS += $(EOBJCFLAGS)
|
|||||||
OBJCCFLAGS = $(CPPFLAGS) $(CFLAGS) $(OBJCFLAGS)
|
OBJCCFLAGS = $(CPPFLAGS) $(CFLAGS) $(OBJCFLAGS)
|
||||||
ASFLAGS := $(CPPFLAGS) $(ASFLAGS)
|
ASFLAGS := $(CPPFLAGS) $(ASFLAGS)
|
||||||
CXXFLAGS := $(CPPFLAGS) $(CFLAGS) $(CXXFLAGS)
|
CXXFLAGS := $(CPPFLAGS) $(CFLAGS) $(CXXFLAGS)
|
||||||
X86ASMFLAGS += $(IFLAGS:%=%/) -I$(<D)/ -Pconfig.asm
|
YASMFLAGS += $(IFLAGS:%=%/) -Pconfig.asm
|
||||||
|
|
||||||
HOSTCCFLAGS = $(IFLAGS) $(HOSTCPPFLAGS) $(HOSTCFLAGS)
|
HOSTCCFLAGS = $(IFLAGS) $(HOSTCPPFLAGS) $(HOSTCFLAGS)
|
||||||
LDFLAGS := $(ALLFFLIBS:%=$(LD_PATH)lib%) $(LDFLAGS)
|
LDFLAGS := $(ALLFFLIBS:%=$(LD_PATH)lib%) $(LDFLAGS)
|
||||||
|
|
||||||
define COMPILE
|
define COMPILE
|
||||||
$(call $(1)DEP,$(1))
|
$(call $(1)DEP,$(1))
|
||||||
$($(1)) $($(1)FLAGS) $($(2)) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<)
|
$($(1)) $($(1)FLAGS) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
COMPILE_C = $(call COMPILE,CC)
|
COMPILE_C = $(call COMPILE,CC)
|
||||||
COMPILE_CXX = $(call COMPILE,CXX)
|
COMPILE_CXX = $(call COMPILE,CXX)
|
||||||
COMPILE_S = $(call COMPILE,AS)
|
COMPILE_S = $(call COMPILE,AS)
|
||||||
COMPILE_M = $(call COMPILE,OBJCC)
|
COMPILE_M = $(call COMPILE,OBJCC)
|
||||||
COMPILE_X86ASM = $(call COMPILE,X86ASM)
|
|
||||||
COMPILE_HOSTC = $(call COMPILE,HOSTCC)
|
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
|
%.o: %.c
|
||||||
$(COMPILE_C)
|
$(COMPILE_C)
|
||||||
@@ -92,16 +74,8 @@ COMPILE_LASX = $(call COMPILE,CC,LASXFLAGS)
|
|||||||
%_host.o: %.c
|
%_host.o: %.c
|
||||||
$(COMPILE_HOSTC)
|
$(COMPILE_HOSTC)
|
||||||
|
|
||||||
%$(DEFAULT_X86ASMD).asm: %.asm
|
|
||||||
$(DEPX86ASM) $(X86ASMFLAGS) -M -o $@ $< > $(@:.asm=.d)
|
|
||||||
$(X86ASM) $(X86ASMFLAGS) -e $< | sed '/^%/d;/^$$/d;' > $@
|
|
||||||
|
|
||||||
%.o: %.asm
|
|
||||||
$(COMPILE_X86ASM)
|
|
||||||
-$(if $(ASMSTRIPFLAGS), $(STRIP) $(ASMSTRIPFLAGS) $@)
|
|
||||||
|
|
||||||
%.o: %.rc
|
%.o: %.rc
|
||||||
$(WINDRES) $(IFLAGS) $(foreach ARG,$(CC_DEPFLAGS),--preprocessor-arg "$(ARG)") -o $@ $<
|
$(WINDRES) $(IFLAGS) --preprocessor "$(DEPWINDRES) -E -xc-header -DRC_INVOKED $(CC_DEPFLAGS)" -o $@ $<
|
||||||
|
|
||||||
%.i: %.c
|
%.i: %.c
|
||||||
$(CC) $(CCFLAGS) $(CC_E) $<
|
$(CC) $(CCFLAGS) $(CC_E) $<
|
||||||
@@ -109,40 +83,15 @@ COMPILE_LASX = $(call COMPILE,CC,LASXFLAGS)
|
|||||||
%.h.c:
|
%.h.c:
|
||||||
$(Q)echo '#include "$*.h"' >$@
|
$(Q)echo '#include "$*.h"' >$@
|
||||||
|
|
||||||
$(BIN2CEXE): ffbuild/bin2c_host.o
|
%.ver: %.v
|
||||||
$(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTEXTRALIBS)
|
$(Q)sed 's/$$MAJOR/$($(basename $(@F))_VERSION_MAJOR)/' $^ | sed -e 's/:/:\
|
||||||
|
/' -e 's/; /;\
|
||||||
|
/g' > $@
|
||||||
|
|
||||||
%.metal.air: %.metal
|
%.c %.h: TAG = GEN
|
||||||
$(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)
|
|
||||||
|
|
||||||
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
|
# Dummy rule to stop make trying to rebuild removed or renamed headers
|
||||||
%.h %_template.c:
|
%.h:
|
||||||
@:
|
@:
|
||||||
|
|
||||||
# Disable suffix rules. Most of the builtin rules are suffix rules,
|
# Disable suffix rules. Most of the builtin rules are suffix rules,
|
||||||
@@ -153,22 +102,18 @@ clean::
|
|||||||
$(OBJS):
|
$(OBJS):
|
||||||
endif
|
endif
|
||||||
|
|
||||||
include $(SRC_PATH)/ffbuild/arch.mak
|
include $(SRC_PATH)/arch.mak
|
||||||
|
|
||||||
OBJS += $(OBJS-yes)
|
OBJS += $(OBJS-yes)
|
||||||
SLIBOBJS += $(SLIBOBJS-yes)
|
SLIBOBJS += $(SLIBOBJS-yes)
|
||||||
SHLIBOBJS += $(SHLIBOBJS-yes)
|
|
||||||
STLIBOBJS += $(STLIBOBJS-yes)
|
|
||||||
FFLIBS := $($(NAME)_FFLIBS) $(FFLIBS-yes) $(FFLIBS)
|
FFLIBS := $($(NAME)_FFLIBS) $(FFLIBS-yes) $(FFLIBS)
|
||||||
TESTPROGS += $(TESTPROGS-yes)
|
TESTPROGS += $(TESTPROGS-yes)
|
||||||
|
|
||||||
LDLIBS = $(FFLIBS:%=%$(BUILDSUF))
|
LDLIBS = $(FFLIBS:%=%$(BUILDSUF))
|
||||||
FFEXTRALIBS := $(LDLIBS:%=$(LD_LIB)) $(foreach lib,EXTRALIBS-$(NAME) $(FFLIBS:%=EXTRALIBS-%),$($(lib))) $(EXTRALIBS)
|
FFEXTRALIBS := $(LDLIBS:%=$(LD_LIB)) $(EXTRALIBS)
|
||||||
|
|
||||||
OBJS := $(sort $(OBJS:%=$(SUBDIR)%))
|
OBJS := $(sort $(OBJS:%=$(SUBDIR)%))
|
||||||
SLIBOBJS := $(sort $(SLIBOBJS:%=$(SUBDIR)%))
|
SLIBOBJS := $(sort $(SLIBOBJS:%=$(SUBDIR)%))
|
||||||
SHLIBOBJS := $(sort $(SHLIBOBJS:%=$(SUBDIR)%))
|
|
||||||
STLIBOBJS := $(sort $(STLIBOBJS:%=$(SUBDIR)%))
|
|
||||||
TESTOBJS := $(TESTOBJS:%=$(SUBDIR)tests/%) $(TESTPROGS:%=$(SUBDIR)tests/%.o)
|
TESTOBJS := $(TESTOBJS:%=$(SUBDIR)tests/%) $(TESTPROGS:%=$(SUBDIR)tests/%.o)
|
||||||
TESTPROGS := $(TESTPROGS:%=$(SUBDIR)tests/%$(EXESUF))
|
TESTPROGS := $(TESTPROGS:%=$(SUBDIR)tests/%$(EXESUF))
|
||||||
HOSTOBJS := $(HOSTPROGS:%=$(SUBDIR)%.o)
|
HOSTOBJS := $(HOSTPROGS:%=$(SUBDIR)%.o)
|
||||||
@@ -187,10 +132,8 @@ ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)
|
|||||||
SKIPHEADERS += $(ARCH_HEADERS:%=$(ARCH)/%) $(SKIPHEADERS-)
|
SKIPHEADERS += $(ARCH_HEADERS:%=$(ARCH)/%) $(SKIPHEADERS-)
|
||||||
SKIPHEADERS := $(SKIPHEADERS:%=$(SUBDIR)%)
|
SKIPHEADERS := $(SKIPHEADERS:%=$(SUBDIR)%)
|
||||||
HOBJS = $(filter-out $(SKIPHEADERS:.h=.h.o),$(ALLHEADERS:.h=.h.o))
|
HOBJS = $(filter-out $(SKIPHEADERS:.h=.h.o),$(ALLHEADERS:.h=.h.o))
|
||||||
PTXOBJS = $(filter %.ptx.o,$(OBJS))
|
|
||||||
$(HOBJS): CCFLAGS += $(CFLAGS_HEADERS)
|
|
||||||
checkheaders: $(HOBJS)
|
checkheaders: $(HOBJS)
|
||||||
.SECONDARY: $(HOBJS:.o=.c) $(PTXOBJS:.o=.c) $(PTXOBJS:.o=.gz) $(PTXOBJS:.o=)
|
.SECONDARY: $(HOBJS:.o=.c)
|
||||||
|
|
||||||
alltools: $(TOOLS)
|
alltools: $(TOOLS)
|
||||||
|
|
||||||
@@ -198,20 +141,19 @@ $(HOSTOBJS): %.o: %.c
|
|||||||
$(COMPILE_HOSTC)
|
$(COMPILE_HOSTC)
|
||||||
|
|
||||||
$(HOSTPROGS): %$(HOSTEXESUF): %.o
|
$(HOSTPROGS): %$(HOSTEXESUF): %.o
|
||||||
$(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTEXTRALIBS)
|
$(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTLIBS)
|
||||||
|
|
||||||
$(OBJS): | $(sort $(dir $(OBJS)))
|
$(OBJS): | $(sort $(dir $(OBJS)))
|
||||||
$(HOBJS): | $(sort $(dir $(HOBJS)))
|
$(HOBJS): | $(sort $(dir $(HOBJS)))
|
||||||
$(HOSTOBJS): | $(sort $(dir $(HOSTOBJS)))
|
$(HOSTOBJS): | $(sort $(dir $(HOSTOBJS)))
|
||||||
$(SLIBOBJS): | $(sort $(dir $(SLIBOBJS)))
|
$(SLIBOBJS): | $(sort $(dir $(SLIBOBJS)))
|
||||||
$(SHLIBOBJS): | $(sort $(dir $(SHLIBOBJS)))
|
|
||||||
$(STLIBOBJS): | $(sort $(dir $(STLIBOBJS)))
|
|
||||||
$(TESTOBJS): | $(sort $(dir $(TESTOBJS)))
|
$(TESTOBJS): | $(sort $(dir $(TESTOBJS)))
|
||||||
$(TOOLOBJS): | tools
|
$(TOOLOBJS): | tools
|
||||||
|
|
||||||
OUTDIRS := $(OUTDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(SLIBOBJS) $(SHLIBOBJS) $(STLIBOBJS) $(TESTOBJS))
|
OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(SLIBOBJS) $(TESTOBJS))
|
||||||
|
|
||||||
CLEANSUFFIXES = *.d *.gcda *.gcno *.h.c *.ho *.map *.o *.pc *.ptx *.ptx.gz *.ptx.c *.ver *.version *$(DEFAULT_X86ASMD).asm *~ *.ilk *.pdb
|
CLEANSUFFIXES = *.d *.o *~ *.h.c *.map *.ver *.ver-sol2 *.ho *.gcno *.gcda *$(DEFAULT_YASMD).asm
|
||||||
|
DISTCLEANSUFFIXES = *.pc
|
||||||
LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a
|
LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a
|
||||||
|
|
||||||
define RULES
|
define RULES
|
||||||
@@ -221,4 +163,4 @@ endef
|
|||||||
|
|
||||||
$(eval $(RULES))
|
$(eval $(RULES))
|
||||||
|
|
||||||
-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)
|
-include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d) $(SLIBOBJS:.o=.d)) $(OBJS:.o=$(DEFAULT_YASMD).d)
|
||||||
@@ -1,176 +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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* based on vlc_atomic.h from VLC
|
|
||||||
* Copyright (C) 2010 Rémi Denis-Courmont
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMPAT_ATOMICS_DUMMY_STDATOMIC_H
|
|
||||||
#define COMPAT_ATOMICS_DUMMY_STDATOMIC_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define ATOMIC_FLAG_INIT 0
|
|
||||||
|
|
||||||
#define ATOMIC_VAR_INIT(value) (value)
|
|
||||||
|
|
||||||
#define atomic_init(obj, value) \
|
|
||||||
do { \
|
|
||||||
*(obj) = (value); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define kill_dependency(y) ((void)0)
|
|
||||||
|
|
||||||
#define atomic_thread_fence(order) \
|
|
||||||
((void)0)
|
|
||||||
|
|
||||||
#define atomic_signal_fence(order) \
|
|
||||||
((void)0)
|
|
||||||
|
|
||||||
#define atomic_is_lock_free(obj) 0
|
|
||||||
|
|
||||||
typedef intptr_t atomic_flag;
|
|
||||||
typedef intptr_t atomic_bool;
|
|
||||||
typedef intptr_t atomic_char;
|
|
||||||
typedef intptr_t atomic_schar;
|
|
||||||
typedef intptr_t atomic_uchar;
|
|
||||||
typedef intptr_t atomic_short;
|
|
||||||
typedef intptr_t atomic_ushort;
|
|
||||||
typedef intptr_t atomic_int;
|
|
||||||
typedef intptr_t atomic_uint;
|
|
||||||
typedef intptr_t atomic_long;
|
|
||||||
typedef intptr_t atomic_ulong;
|
|
||||||
typedef intptr_t atomic_llong;
|
|
||||||
typedef intptr_t atomic_ullong;
|
|
||||||
typedef intptr_t atomic_wchar_t;
|
|
||||||
typedef intptr_t atomic_int_least8_t;
|
|
||||||
typedef intptr_t atomic_uint_least8_t;
|
|
||||||
typedef intptr_t atomic_int_least16_t;
|
|
||||||
typedef intptr_t atomic_uint_least16_t;
|
|
||||||
typedef intptr_t atomic_int_least32_t;
|
|
||||||
typedef intptr_t atomic_uint_least32_t;
|
|
||||||
typedef intptr_t atomic_int_least64_t;
|
|
||||||
typedef intptr_t atomic_uint_least64_t;
|
|
||||||
typedef intptr_t atomic_int_fast8_t;
|
|
||||||
typedef intptr_t atomic_uint_fast8_t;
|
|
||||||
typedef intptr_t atomic_int_fast16_t;
|
|
||||||
typedef intptr_t atomic_uint_fast16_t;
|
|
||||||
typedef intptr_t atomic_int_fast32_t;
|
|
||||||
typedef intptr_t atomic_uint_fast32_t;
|
|
||||||
typedef intptr_t atomic_int_fast64_t;
|
|
||||||
typedef intptr_t atomic_uint_fast64_t;
|
|
||||||
typedef intptr_t atomic_intptr_t;
|
|
||||||
typedef intptr_t atomic_uintptr_t;
|
|
||||||
typedef intptr_t atomic_size_t;
|
|
||||||
typedef intptr_t atomic_ptrdiff_t;
|
|
||||||
typedef intptr_t atomic_intmax_t;
|
|
||||||
typedef intptr_t atomic_uintmax_t;
|
|
||||||
|
|
||||||
#define atomic_store(object, desired) \
|
|
||||||
do { \
|
|
||||||
*(object) = (desired); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define atomic_store_explicit(object, desired, order) \
|
|
||||||
atomic_store(object, desired)
|
|
||||||
|
|
||||||
#define atomic_load(object) \
|
|
||||||
(*(object))
|
|
||||||
|
|
||||||
#define atomic_load_explicit(object, order) \
|
|
||||||
atomic_load(object)
|
|
||||||
|
|
||||||
static inline intptr_t atomic_exchange(intptr_t *object, intptr_t desired)
|
|
||||||
{
|
|
||||||
intptr_t ret = *object;
|
|
||||||
*object = desired;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_exchange_explicit(object, desired, order) \
|
|
||||||
atomic_exchange(object, desired)
|
|
||||||
|
|
||||||
static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected,
|
|
||||||
intptr_t desired)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
if (*object == *expected) {
|
|
||||||
*object = desired;
|
|
||||||
ret = 1;
|
|
||||||
} else {
|
|
||||||
*expected = *object;
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
|
||||||
atomic_compare_exchange_strong(object, expected, desired)
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
|
||||||
atomic_compare_exchange_strong(object, expected, desired)
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
|
||||||
atomic_compare_exchange_weak(object, expected, desired)
|
|
||||||
|
|
||||||
#define FETCH_MODIFY(opname, op) \
|
|
||||||
static inline intptr_t atomic_fetch_ ## opname(intptr_t *object, intptr_t operand) \
|
|
||||||
{ \
|
|
||||||
intptr_t ret; \
|
|
||||||
ret = *object; \
|
|
||||||
*object = *object op operand; \
|
|
||||||
return ret; \
|
|
||||||
}
|
|
||||||
|
|
||||||
FETCH_MODIFY(add, +)
|
|
||||||
FETCH_MODIFY(sub, -)
|
|
||||||
FETCH_MODIFY(or, |)
|
|
||||||
FETCH_MODIFY(xor, ^)
|
|
||||||
FETCH_MODIFY(and, &)
|
|
||||||
|
|
||||||
#undef FETCH_MODIFY
|
|
||||||
|
|
||||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_add(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_sub(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_or(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_xor(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_and(object, operand)
|
|
||||||
|
|
||||||
#define atomic_flag_test_and_set(object) \
|
|
||||||
atomic_exchange(object, 1)
|
|
||||||
|
|
||||||
#define atomic_flag_test_and_set_explicit(object, order) \
|
|
||||||
atomic_flag_test_and_set(object)
|
|
||||||
|
|
||||||
#define atomic_flag_clear(object) \
|
|
||||||
atomic_store(object, 0)
|
|
||||||
|
|
||||||
#define atomic_flag_clear_explicit(object, order) \
|
|
||||||
atomic_flag_clear(object)
|
|
||||||
|
|
||||||
#endif /* COMPAT_ATOMICS_DUMMY_STDATOMIC_H */
|
|
||||||
@@ -1,173 +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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* based on vlc_atomic.h from VLC
|
|
||||||
* Copyright (C) 2010 Rémi Denis-Courmont
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMPAT_ATOMICS_GCC_STDATOMIC_H
|
|
||||||
#define COMPAT_ATOMICS_GCC_STDATOMIC_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define ATOMIC_FLAG_INIT 0
|
|
||||||
|
|
||||||
#define ATOMIC_VAR_INIT(value) (value)
|
|
||||||
|
|
||||||
#define atomic_init(obj, value) \
|
|
||||||
do { \
|
|
||||||
*(obj) = (value); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define kill_dependency(y) ((void)0)
|
|
||||||
|
|
||||||
#define atomic_thread_fence(order) \
|
|
||||||
__sync_synchronize()
|
|
||||||
|
|
||||||
#define atomic_signal_fence(order) \
|
|
||||||
((void)0)
|
|
||||||
|
|
||||||
#define atomic_is_lock_free(obj) 0
|
|
||||||
|
|
||||||
typedef _Bool atomic_flag;
|
|
||||||
typedef _Bool atomic_bool;
|
|
||||||
typedef char atomic_char;
|
|
||||||
typedef signed char atomic_schar;
|
|
||||||
typedef unsigned char atomic_uchar;
|
|
||||||
typedef short atomic_short;
|
|
||||||
typedef unsigned short atomic_ushort;
|
|
||||||
typedef int atomic_int;
|
|
||||||
typedef unsigned int atomic_uint;
|
|
||||||
typedef long atomic_long;
|
|
||||||
typedef unsigned long atomic_ulong;
|
|
||||||
typedef long long atomic_llong;
|
|
||||||
typedef unsigned long long atomic_ullong;
|
|
||||||
typedef wchar_t atomic_wchar_t;
|
|
||||||
typedef int_least8_t atomic_int_least8_t;
|
|
||||||
typedef uint_least8_t atomic_uint_least8_t;
|
|
||||||
typedef int_least16_t atomic_int_least16_t;
|
|
||||||
typedef uint_least16_t atomic_uint_least16_t;
|
|
||||||
typedef int_least32_t atomic_int_least32_t;
|
|
||||||
typedef uint_least32_t atomic_uint_least32_t;
|
|
||||||
typedef int_least64_t atomic_int_least64_t;
|
|
||||||
typedef uint_least64_t atomic_uint_least64_t;
|
|
||||||
typedef int_fast8_t atomic_int_fast8_t;
|
|
||||||
typedef uint_fast8_t atomic_uint_fast8_t;
|
|
||||||
typedef int_fast16_t atomic_int_fast16_t;
|
|
||||||
typedef uint_fast16_t atomic_uint_fast16_t;
|
|
||||||
typedef int_fast32_t atomic_int_fast32_t;
|
|
||||||
typedef uint_fast32_t atomic_uint_fast32_t;
|
|
||||||
typedef int_fast64_t atomic_int_fast64_t;
|
|
||||||
typedef uint_fast64_t atomic_uint_fast64_t;
|
|
||||||
typedef intptr_t atomic_intptr_t;
|
|
||||||
typedef uintptr_t atomic_uintptr_t;
|
|
||||||
typedef size_t atomic_size_t;
|
|
||||||
typedef ptrdiff_t atomic_ptrdiff_t;
|
|
||||||
typedef intmax_t atomic_intmax_t;
|
|
||||||
typedef uintmax_t atomic_uintmax_t;
|
|
||||||
|
|
||||||
#define atomic_store(object, desired) \
|
|
||||||
do { \
|
|
||||||
*(object) = (desired); \
|
|
||||||
__sync_synchronize(); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define atomic_store_explicit(object, desired, order) \
|
|
||||||
atomic_store(object, desired)
|
|
||||||
|
|
||||||
#define atomic_load(object) \
|
|
||||||
(__sync_synchronize(), *(object))
|
|
||||||
|
|
||||||
#define atomic_load_explicit(object, order) \
|
|
||||||
atomic_load(object)
|
|
||||||
|
|
||||||
#define atomic_exchange(object, desired) \
|
|
||||||
({ \
|
|
||||||
__typeof__(object) _obj = (object); \
|
|
||||||
__typeof__(*object) _old; \
|
|
||||||
do \
|
|
||||||
_old = atomic_load(_obj); \
|
|
||||||
while (!__sync_bool_compare_and_swap(_obj, _old, (desired))); \
|
|
||||||
_old; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define atomic_exchange_explicit(object, desired, order) \
|
|
||||||
atomic_exchange(object, desired)
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_strong(object, expected, desired) \
|
|
||||||
({ \
|
|
||||||
__typeof__(object) _exp = (expected); \
|
|
||||||
__typeof__(*object) _old = *_exp; \
|
|
||||||
*_exp = __sync_val_compare_and_swap((object), _old, (desired)); \
|
|
||||||
*_exp == _old; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
|
||||||
atomic_compare_exchange_strong(object, expected, desired)
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
|
||||||
atomic_compare_exchange_strong(object, expected, desired)
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
|
||||||
atomic_compare_exchange_weak(object, expected, desired)
|
|
||||||
|
|
||||||
#define atomic_fetch_add(object, operand) \
|
|
||||||
__sync_fetch_and_add(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_add(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_sub(object, operand) \
|
|
||||||
__sync_fetch_and_sub(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_sub(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_or(object, operand) \
|
|
||||||
__sync_fetch_and_or(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_or(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_xor(object, operand) \
|
|
||||||
__sync_fetch_and_xor(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_xor(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_and(object, operand) \
|
|
||||||
__sync_fetch_and_and(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_and(object, operand)
|
|
||||||
|
|
||||||
#define atomic_flag_test_and_set(object) \
|
|
||||||
atomic_exchange(object, 1)
|
|
||||||
|
|
||||||
#define atomic_flag_test_and_set_explicit(object, order) \
|
|
||||||
atomic_flag_test_and_set(object)
|
|
||||||
|
|
||||||
#define atomic_flag_clear(object) \
|
|
||||||
atomic_store(object, 0)
|
|
||||||
|
|
||||||
#define atomic_flag_clear_explicit(object, order) \
|
|
||||||
atomic_flag_clear(object)
|
|
||||||
|
|
||||||
#endif /* COMPAT_ATOMICS_GCC_STDATOMIC_H */
|
|
||||||
@@ -1,197 +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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* based on vlc_atomic.h from VLC
|
|
||||||
* Copyright (C) 2010 Rémi Denis-Courmont
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMPAT_ATOMICS_PTHREAD_STDATOMIC_H
|
|
||||||
#define COMPAT_ATOMICS_PTHREAD_STDATOMIC_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define ATOMIC_FLAG_INIT 0
|
|
||||||
|
|
||||||
#define ATOMIC_VAR_INIT(value) (value)
|
|
||||||
|
|
||||||
#define atomic_init(obj, value) \
|
|
||||||
do { \
|
|
||||||
*(obj) = (value); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define kill_dependency(y) ((void)0)
|
|
||||||
|
|
||||||
#define atomic_signal_fence(order) \
|
|
||||||
((void)0)
|
|
||||||
|
|
||||||
#define atomic_is_lock_free(obj) 0
|
|
||||||
|
|
||||||
typedef intptr_t atomic_flag;
|
|
||||||
typedef intptr_t atomic_bool;
|
|
||||||
typedef intptr_t atomic_char;
|
|
||||||
typedef intptr_t atomic_schar;
|
|
||||||
typedef intptr_t atomic_uchar;
|
|
||||||
typedef intptr_t atomic_short;
|
|
||||||
typedef intptr_t atomic_ushort;
|
|
||||||
typedef intptr_t atomic_int;
|
|
||||||
typedef intptr_t atomic_uint;
|
|
||||||
typedef intptr_t atomic_long;
|
|
||||||
typedef intptr_t atomic_ulong;
|
|
||||||
typedef intptr_t atomic_llong;
|
|
||||||
typedef intptr_t atomic_ullong;
|
|
||||||
typedef intptr_t atomic_wchar_t;
|
|
||||||
typedef intptr_t atomic_int_least8_t;
|
|
||||||
typedef intptr_t atomic_uint_least8_t;
|
|
||||||
typedef intptr_t atomic_int_least16_t;
|
|
||||||
typedef intptr_t atomic_uint_least16_t;
|
|
||||||
typedef intptr_t atomic_int_least32_t;
|
|
||||||
typedef intptr_t atomic_uint_least32_t;
|
|
||||||
typedef intptr_t atomic_int_least64_t;
|
|
||||||
typedef intptr_t atomic_uint_least64_t;
|
|
||||||
typedef intptr_t atomic_int_fast8_t;
|
|
||||||
typedef intptr_t atomic_uint_fast8_t;
|
|
||||||
typedef intptr_t atomic_int_fast16_t;
|
|
||||||
typedef intptr_t atomic_uint_fast16_t;
|
|
||||||
typedef intptr_t atomic_int_fast32_t;
|
|
||||||
typedef intptr_t atomic_uint_fast32_t;
|
|
||||||
typedef intptr_t atomic_int_fast64_t;
|
|
||||||
typedef intptr_t atomic_uint_fast64_t;
|
|
||||||
typedef intptr_t atomic_intptr_t;
|
|
||||||
typedef intptr_t atomic_uintptr_t;
|
|
||||||
typedef intptr_t atomic_size_t;
|
|
||||||
typedef intptr_t atomic_ptrdiff_t;
|
|
||||||
typedef intptr_t atomic_intmax_t;
|
|
||||||
typedef intptr_t atomic_uintmax_t;
|
|
||||||
|
|
||||||
void avpriv_atomic_lock(void);
|
|
||||||
void avpriv_atomic_unlock(void);
|
|
||||||
|
|
||||||
static inline void atomic_thread_fence(int order)
|
|
||||||
{
|
|
||||||
avpriv_atomic_lock();
|
|
||||||
avpriv_atomic_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void atomic_store(intptr_t *object, intptr_t desired)
|
|
||||||
{
|
|
||||||
avpriv_atomic_lock();
|
|
||||||
*object = desired;
|
|
||||||
avpriv_atomic_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_store_explicit(object, desired, order) \
|
|
||||||
atomic_store(object, desired)
|
|
||||||
|
|
||||||
static inline intptr_t atomic_load(intptr_t *object)
|
|
||||||
{
|
|
||||||
intptr_t ret;
|
|
||||||
avpriv_atomic_lock();
|
|
||||||
ret = *object;
|
|
||||||
avpriv_atomic_unlock();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_load_explicit(object, order) \
|
|
||||||
atomic_load(object)
|
|
||||||
|
|
||||||
static inline intptr_t atomic_exchange(intptr_t *object, intptr_t desired)
|
|
||||||
{
|
|
||||||
intptr_t ret;
|
|
||||||
avpriv_atomic_lock();
|
|
||||||
ret = *object;
|
|
||||||
*object = desired;
|
|
||||||
avpriv_atomic_unlock();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_exchange_explicit(object, desired, order) \
|
|
||||||
atomic_exchange(object, desired)
|
|
||||||
|
|
||||||
static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected,
|
|
||||||
intptr_t desired)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
avpriv_atomic_lock();
|
|
||||||
if (*object == *expected) {
|
|
||||||
ret = 1;
|
|
||||||
*object = desired;
|
|
||||||
} else {
|
|
||||||
ret = 0;
|
|
||||||
*expected = *object;
|
|
||||||
}
|
|
||||||
avpriv_atomic_unlock();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
|
||||||
atomic_compare_exchange_strong(object, expected, desired)
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
|
||||||
atomic_compare_exchange_strong(object, expected, desired)
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
|
||||||
atomic_compare_exchange_weak(object, expected, desired)
|
|
||||||
|
|
||||||
#define FETCH_MODIFY(opname, op) \
|
|
||||||
static inline intptr_t atomic_fetch_ ## opname(intptr_t *object, intptr_t operand) \
|
|
||||||
{ \
|
|
||||||
intptr_t ret; \
|
|
||||||
avpriv_atomic_lock(); \
|
|
||||||
ret = *object; \
|
|
||||||
*object = *object op operand; \
|
|
||||||
avpriv_atomic_unlock(); \
|
|
||||||
return ret; \
|
|
||||||
}
|
|
||||||
|
|
||||||
FETCH_MODIFY(add, +)
|
|
||||||
FETCH_MODIFY(sub, -)
|
|
||||||
FETCH_MODIFY(or, |)
|
|
||||||
FETCH_MODIFY(xor, ^)
|
|
||||||
FETCH_MODIFY(and, &)
|
|
||||||
|
|
||||||
#undef FETCH_MODIFY
|
|
||||||
|
|
||||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_add(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_sub(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_or(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_xor(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_and(object, operand)
|
|
||||||
|
|
||||||
#define atomic_flag_test_and_set(object) \
|
|
||||||
atomic_exchange(object, 1)
|
|
||||||
|
|
||||||
#define atomic_flag_test_and_set_explicit(object, order) \
|
|
||||||
atomic_flag_test_and_set(object)
|
|
||||||
|
|
||||||
#define atomic_flag_clear(object) \
|
|
||||||
atomic_store(object, 0)
|
|
||||||
|
|
||||||
#define atomic_flag_clear_explicit(object, order) \
|
|
||||||
atomic_flag_clear(object)
|
|
||||||
|
|
||||||
#endif /* COMPAT_ATOMICS_PTHREAD_STDATOMIC_H */
|
|
||||||
@@ -1,186 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of FFmpeg.
|
|
||||||
*
|
|
||||||
* FFmpeg is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* FFmpeg is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with FFmpeg; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMPAT_ATOMICS_SUNCC_STDATOMIC_H
|
|
||||||
#define COMPAT_ATOMICS_SUNCC_STDATOMIC_H
|
|
||||||
|
|
||||||
#include <atomic.h>
|
|
||||||
#include <mbarrier.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define ATOMIC_FLAG_INIT 0
|
|
||||||
|
|
||||||
#define ATOMIC_VAR_INIT(value) (value)
|
|
||||||
|
|
||||||
#define atomic_init(obj, value) \
|
|
||||||
do { \
|
|
||||||
*(obj) = (value); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define kill_dependency(y) ((void)0)
|
|
||||||
|
|
||||||
#define atomic_thread_fence(order) \
|
|
||||||
__machine_rw_barrier();
|
|
||||||
|
|
||||||
#define atomic_signal_fence(order) \
|
|
||||||
((void)0)
|
|
||||||
|
|
||||||
#define atomic_is_lock_free(obj) 0
|
|
||||||
|
|
||||||
typedef intptr_t atomic_flag;
|
|
||||||
typedef intptr_t atomic_bool;
|
|
||||||
typedef intptr_t atomic_char;
|
|
||||||
typedef intptr_t atomic_schar;
|
|
||||||
typedef intptr_t atomic_uchar;
|
|
||||||
typedef intptr_t atomic_short;
|
|
||||||
typedef intptr_t atomic_ushort;
|
|
||||||
typedef intptr_t atomic_int;
|
|
||||||
typedef intptr_t atomic_uint;
|
|
||||||
typedef intptr_t atomic_long;
|
|
||||||
typedef intptr_t atomic_ulong;
|
|
||||||
typedef intptr_t atomic_llong;
|
|
||||||
typedef intptr_t atomic_ullong;
|
|
||||||
typedef intptr_t atomic_wchar_t;
|
|
||||||
typedef intptr_t atomic_int_least8_t;
|
|
||||||
typedef intptr_t atomic_uint_least8_t;
|
|
||||||
typedef intptr_t atomic_int_least16_t;
|
|
||||||
typedef intptr_t atomic_uint_least16_t;
|
|
||||||
typedef intptr_t atomic_int_least32_t;
|
|
||||||
typedef intptr_t atomic_uint_least32_t;
|
|
||||||
typedef intptr_t atomic_int_least64_t;
|
|
||||||
typedef intptr_t atomic_uint_least64_t;
|
|
||||||
typedef intptr_t atomic_int_fast8_t;
|
|
||||||
typedef intptr_t atomic_uint_fast8_t;
|
|
||||||
typedef intptr_t atomic_int_fast16_t;
|
|
||||||
typedef intptr_t atomic_uint_fast16_t;
|
|
||||||
typedef intptr_t atomic_int_fast32_t;
|
|
||||||
typedef intptr_t atomic_uint_fast32_t;
|
|
||||||
typedef intptr_t atomic_int_fast64_t;
|
|
||||||
typedef intptr_t atomic_uint_fast64_t;
|
|
||||||
typedef intptr_t atomic_intptr_t;
|
|
||||||
typedef intptr_t atomic_uintptr_t;
|
|
||||||
typedef intptr_t atomic_size_t;
|
|
||||||
typedef intptr_t atomic_ptrdiff_t;
|
|
||||||
typedef intptr_t atomic_intmax_t;
|
|
||||||
typedef intptr_t atomic_uintmax_t;
|
|
||||||
|
|
||||||
static inline void atomic_store(intptr_t *object, intptr_t desired)
|
|
||||||
{
|
|
||||||
*object = desired;
|
|
||||||
__machine_rw_barrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_store_explicit(object, desired, order) \
|
|
||||||
atomic_store(object, desired)
|
|
||||||
|
|
||||||
static inline intptr_t atomic_load(intptr_t *object)
|
|
||||||
{
|
|
||||||
__machine_rw_barrier();
|
|
||||||
return *object;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_load_explicit(object, order) \
|
|
||||||
atomic_load(object)
|
|
||||||
|
|
||||||
#define atomic_exchange(object, desired) \
|
|
||||||
atomic_swap_ptr(object, desired)
|
|
||||||
|
|
||||||
#define atomic_exchange_explicit(object, desired, order) \
|
|
||||||
atomic_exchange(object, desired)
|
|
||||||
|
|
||||||
static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected,
|
|
||||||
intptr_t desired)
|
|
||||||
{
|
|
||||||
intptr_t old = *expected;
|
|
||||||
*expected = (intptr_t)atomic_cas_ptr(object, (void *)old, (void *)desired);
|
|
||||||
return *expected == old;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
|
||||||
atomic_compare_exchange_strong(object, expected, desired)
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
|
||||||
atomic_compare_exchange_strong(object, expected, desired)
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
|
||||||
atomic_compare_exchange_weak(object, expected, desired)
|
|
||||||
|
|
||||||
static inline intptr_t atomic_fetch_add(intptr_t *object, intptr_t operand)
|
|
||||||
{
|
|
||||||
return atomic_add_ptr_nv(object, operand) - operand;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_fetch_sub(object, operand) \
|
|
||||||
atomic_fetch_add(object, -(operand))
|
|
||||||
|
|
||||||
static inline intptr_t atomic_fetch_or(intptr_t *object, intptr_t operand)
|
|
||||||
{
|
|
||||||
intptr_t old;
|
|
||||||
do {
|
|
||||||
old = atomic_load(object);
|
|
||||||
} while (!atomic_compare_exchange_strong(object, old, old | operand));
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline intptr_t atomic_fetch_xor(intptr_t *object, intptr_t operand)
|
|
||||||
{
|
|
||||||
intptr_t old;
|
|
||||||
do {
|
|
||||||
old = atomic_load(object);
|
|
||||||
} while (!atomic_compare_exchange_strong(object, old, old ^ operand));
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline intptr_t atomic_fetch_and(intptr_t *object, intptr_t operand)
|
|
||||||
{
|
|
||||||
intptr_t old;
|
|
||||||
do {
|
|
||||||
old = atomic_load(object);
|
|
||||||
} while (!atomic_compare_exchange_strong(object, old, old & operand));
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_add(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_sub(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_or(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_xor(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_and(object, operand)
|
|
||||||
|
|
||||||
#define atomic_flag_test_and_set(object) \
|
|
||||||
atomic_exchange(object, 1)
|
|
||||||
|
|
||||||
#define atomic_flag_test_and_set_explicit(object, order) \
|
|
||||||
atomic_flag_test_and_set(object)
|
|
||||||
|
|
||||||
#define atomic_flag_clear(object) \
|
|
||||||
atomic_store(object, 0)
|
|
||||||
|
|
||||||
#define atomic_flag_clear_explicit(object, order) \
|
|
||||||
atomic_flag_clear(object)
|
|
||||||
|
|
||||||
#endif /* COMPAT_ATOMICS_SUNCC_STDATOMIC_H */
|
|
||||||
@@ -1,181 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of FFmpeg.
|
|
||||||
*
|
|
||||||
* FFmpeg is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* FFmpeg is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with FFmpeg; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMPAT_ATOMICS_WIN32_STDATOMIC_H
|
|
||||||
#define COMPAT_ATOMICS_WIN32_STDATOMIC_H
|
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#define ATOMIC_FLAG_INIT 0
|
|
||||||
|
|
||||||
#define ATOMIC_VAR_INIT(value) (value)
|
|
||||||
|
|
||||||
#define atomic_init(obj, value) \
|
|
||||||
do { \
|
|
||||||
*(obj) = (value); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define kill_dependency(y) ((void)0)
|
|
||||||
|
|
||||||
#define atomic_thread_fence(order) \
|
|
||||||
MemoryBarrier();
|
|
||||||
|
|
||||||
#define atomic_signal_fence(order) \
|
|
||||||
((void)0)
|
|
||||||
|
|
||||||
#define atomic_is_lock_free(obj) 0
|
|
||||||
|
|
||||||
typedef intptr_t atomic_flag;
|
|
||||||
typedef intptr_t atomic_bool;
|
|
||||||
typedef intptr_t atomic_char;
|
|
||||||
typedef intptr_t atomic_schar;
|
|
||||||
typedef intptr_t atomic_uchar;
|
|
||||||
typedef intptr_t atomic_short;
|
|
||||||
typedef intptr_t atomic_ushort;
|
|
||||||
typedef intptr_t atomic_int;
|
|
||||||
typedef intptr_t atomic_uint;
|
|
||||||
typedef intptr_t atomic_long;
|
|
||||||
typedef intptr_t atomic_ulong;
|
|
||||||
typedef intptr_t atomic_llong;
|
|
||||||
typedef intptr_t atomic_ullong;
|
|
||||||
typedef intptr_t atomic_wchar_t;
|
|
||||||
typedef intptr_t atomic_int_least8_t;
|
|
||||||
typedef intptr_t atomic_uint_least8_t;
|
|
||||||
typedef intptr_t atomic_int_least16_t;
|
|
||||||
typedef intptr_t atomic_uint_least16_t;
|
|
||||||
typedef intptr_t atomic_int_least32_t;
|
|
||||||
typedef intptr_t atomic_uint_least32_t;
|
|
||||||
typedef intptr_t atomic_int_least64_t;
|
|
||||||
typedef intptr_t atomic_uint_least64_t;
|
|
||||||
typedef intptr_t atomic_int_fast8_t;
|
|
||||||
typedef intptr_t atomic_uint_fast8_t;
|
|
||||||
typedef intptr_t atomic_int_fast16_t;
|
|
||||||
typedef intptr_t atomic_uint_fast16_t;
|
|
||||||
typedef intptr_t atomic_int_fast32_t;
|
|
||||||
typedef intptr_t atomic_uint_fast32_t;
|
|
||||||
typedef intptr_t atomic_int_fast64_t;
|
|
||||||
typedef intptr_t atomic_uint_fast64_t;
|
|
||||||
typedef intptr_t atomic_intptr_t;
|
|
||||||
typedef intptr_t atomic_uintptr_t;
|
|
||||||
typedef intptr_t atomic_size_t;
|
|
||||||
typedef intptr_t atomic_ptrdiff_t;
|
|
||||||
typedef intptr_t atomic_intmax_t;
|
|
||||||
typedef intptr_t atomic_uintmax_t;
|
|
||||||
|
|
||||||
#define atomic_store(object, desired) \
|
|
||||||
do { \
|
|
||||||
*(object) = (desired); \
|
|
||||||
MemoryBarrier(); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define atomic_store_explicit(object, desired, order) \
|
|
||||||
atomic_store(object, desired)
|
|
||||||
|
|
||||||
#define atomic_load(object) \
|
|
||||||
(MemoryBarrier(), *(object))
|
|
||||||
|
|
||||||
#define atomic_load_explicit(object, order) \
|
|
||||||
atomic_load(object)
|
|
||||||
|
|
||||||
#define atomic_exchange(object, desired) \
|
|
||||||
InterlockedExchangePointer((PVOID volatile *)object, (PVOID)desired)
|
|
||||||
|
|
||||||
#define atomic_exchange_explicit(object, desired, order) \
|
|
||||||
atomic_exchange(object, desired)
|
|
||||||
|
|
||||||
static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected,
|
|
||||||
intptr_t desired)
|
|
||||||
{
|
|
||||||
intptr_t old = *expected;
|
|
||||||
*expected = (intptr_t)InterlockedCompareExchangePointer(
|
|
||||||
(PVOID *)object, (PVOID)desired, (PVOID)old);
|
|
||||||
return *expected == old;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
|
||||||
atomic_compare_exchange_strong(object, expected, desired)
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
|
||||||
atomic_compare_exchange_strong(object, expected, desired)
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
|
||||||
atomic_compare_exchange_weak(object, expected, desired)
|
|
||||||
|
|
||||||
#ifdef _WIN64
|
|
||||||
#define atomic_fetch_add(object, operand) \
|
|
||||||
InterlockedExchangeAdd64(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_sub(object, operand) \
|
|
||||||
InterlockedExchangeAdd64(object, -(operand))
|
|
||||||
|
|
||||||
#define atomic_fetch_or(object, operand) \
|
|
||||||
InterlockedOr64(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_xor(object, operand) \
|
|
||||||
InterlockedXor64(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_and(object, operand) \
|
|
||||||
InterlockedAnd64(object, operand)
|
|
||||||
#else
|
|
||||||
#define atomic_fetch_add(object, operand) \
|
|
||||||
InterlockedExchangeAdd(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_sub(object, operand) \
|
|
||||||
InterlockedExchangeAdd(object, -(operand))
|
|
||||||
|
|
||||||
#define atomic_fetch_or(object, operand) \
|
|
||||||
InterlockedOr(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_xor(object, operand) \
|
|
||||||
InterlockedXor(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_and(object, operand) \
|
|
||||||
InterlockedAnd(object, operand)
|
|
||||||
#endif /* _WIN64 */
|
|
||||||
|
|
||||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_add(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_sub(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_or(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_xor(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_and(object, operand)
|
|
||||||
|
|
||||||
#define atomic_flag_test_and_set(object) \
|
|
||||||
atomic_exchange(object, 1)
|
|
||||||
|
|
||||||
#define atomic_flag_test_and_set_explicit(object, order) \
|
|
||||||
atomic_flag_test_and_set(object)
|
|
||||||
|
|
||||||
#define atomic_flag_clear(object) \
|
|
||||||
atomic_store(object, 0)
|
|
||||||
|
|
||||||
#define atomic_flag_clear_explicit(object, order) \
|
|
||||||
atomic_flag_clear(object)
|
|
||||||
|
|
||||||
#endif /* COMPAT_ATOMICS_WIN32_STDATOMIC_H */
|
|
||||||
882
compat/avisynth/avisynth_c.h
Normal file
882
compat/avisynth/avisynth_c.h
Normal file
@@ -0,0 +1,882 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// NOTE: this is a partial update of the Avisynth C interface to recognize
|
||||||
|
// new color spaces added in Avisynth 2.60. By no means is this document
|
||||||
|
// completely Avisynth 2.60 compliant.
|
||||||
|
|
||||||
|
#ifndef __AVISYNTH_C__
|
||||||
|
#define __AVISYNTH_C__
|
||||||
|
|
||||||
|
#include "avs/config.h"
|
||||||
|
#include "avs/capi.h"
|
||||||
|
#include "avs/types.h"
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Constants
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __AVISYNTH_6_H__
|
||||||
|
enum { AVISYNTH_INTERFACE_VERSION = 6 };
|
||||||
|
#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,
|
||||||
|
AVS_PLANAR_A=1<<4,
|
||||||
|
AVS_PLANAR_R=1<<5,
|
||||||
|
AVS_PLANAR_G=1<<6,
|
||||||
|
AVS_PLANAR_B=1<<7,
|
||||||
|
AVS_PLANAR_A_ALIGNED=AVS_PLANAR_A|AVS_PLANAR_ALIGNED,
|
||||||
|
AVS_PLANAR_R_ALIGNED=AVS_PLANAR_R|AVS_PLANAR_ALIGNED,
|
||||||
|
AVS_PLANAR_G_ALIGNED=AVS_PLANAR_G|AVS_PLANAR_ALIGNED,
|
||||||
|
AVS_PLANAR_B_ALIGNED=AVS_PLANAR_B|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,
|
||||||
|
|
||||||
|
AVS_CS_SHIFT_SUB_WIDTH = 0,
|
||||||
|
AVS_CS_SHIFT_SUB_HEIGHT = 8,
|
||||||
|
AVS_CS_SHIFT_SAMPLE_BITS = 16,
|
||||||
|
|
||||||
|
AVS_CS_SUB_WIDTH_MASK = 7 << AVS_CS_SHIFT_SUB_WIDTH,
|
||||||
|
AVS_CS_SUB_WIDTH_1 = 3 << AVS_CS_SHIFT_SUB_WIDTH, // YV24
|
||||||
|
AVS_CS_SUB_WIDTH_2 = 0 << AVS_CS_SHIFT_SUB_WIDTH, // YV12, I420, YV16
|
||||||
|
AVS_CS_SUB_WIDTH_4 = 1 << AVS_CS_SHIFT_SUB_WIDTH, // YUV9, YV411
|
||||||
|
|
||||||
|
AVS_CS_VPLANEFIRST = 1 << 3, // YV12, YV16, YV24, YV411, YUV9
|
||||||
|
AVS_CS_UPLANEFIRST = 1 << 4, // I420
|
||||||
|
|
||||||
|
AVS_CS_SUB_HEIGHT_MASK = 7 << AVS_CS_SHIFT_SUB_HEIGHT,
|
||||||
|
AVS_CS_SUB_HEIGHT_1 = 3 << AVS_CS_SHIFT_SUB_HEIGHT, // YV16, YV24, YV411
|
||||||
|
AVS_CS_SUB_HEIGHT_2 = 0 << AVS_CS_SHIFT_SUB_HEIGHT, // YV12, I420
|
||||||
|
AVS_CS_SUB_HEIGHT_4 = 1 << AVS_CS_SHIFT_SUB_HEIGHT, // YUV9
|
||||||
|
|
||||||
|
AVS_CS_SAMPLE_BITS_MASK = 7 << AVS_CS_SHIFT_SAMPLE_BITS,
|
||||||
|
AVS_CS_SAMPLE_BITS_8 = 0 << AVS_CS_SHIFT_SAMPLE_BITS,
|
||||||
|
AVS_CS_SAMPLE_BITS_16 = 1 << AVS_CS_SHIFT_SAMPLE_BITS,
|
||||||
|
AVS_CS_SAMPLE_BITS_32 = 2 << AVS_CS_SHIFT_SAMPLE_BITS,
|
||||||
|
|
||||||
|
AVS_CS_PLANAR_MASK = AVS_CS_PLANAR | AVS_CS_INTERLEAVED | AVS_CS_YUV | AVS_CS_BGR | AVS_CS_SAMPLE_BITS_MASK | AVS_CS_SUB_HEIGHT_MASK | AVS_CS_SUB_WIDTH_MASK,
|
||||||
|
AVS_CS_PLANAR_FILTER = ~( AVS_CS_VPLANEFIRST | AVS_CS_UPLANEFIRST )};
|
||||||
|
|
||||||
|
// 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 Reserved
|
||||||
|
// AVS_CS_I420 = 1<<4 Reserved
|
||||||
|
AVS_CS_RAW32 = 1<<5 | AVS_CS_INTERLEAVED,
|
||||||
|
|
||||||
|
AVS_CS_YV24 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_1, // YVU 4:4:4 planar
|
||||||
|
AVS_CS_YV16 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_2, // YVU 4:2:2 planar
|
||||||
|
AVS_CS_YV12 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_2 | AVS_CS_SUB_WIDTH_2, // YVU 4:2:0 planar
|
||||||
|
AVS_CS_I420 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_UPLANEFIRST | AVS_CS_SUB_HEIGHT_2 | AVS_CS_SUB_WIDTH_2, // YUV 4:2:0 planar
|
||||||
|
AVS_CS_IYUV = AVS_CS_I420,
|
||||||
|
AVS_CS_YV411 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_4, // YVU 4:1:1 planar
|
||||||
|
AVS_CS_YUV9 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_4 | AVS_CS_SUB_WIDTH_4, // YVU 4:1:0 planar
|
||||||
|
AVS_CS_Y8 = AVS_CS_PLANAR | AVS_CS_INTERLEAVED | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 // Y 4:0:0 planar
|
||||||
|
};
|
||||||
|
|
||||||
|
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 {
|
||||||
|
// New 2.6 explicitly defined cache hints.
|
||||||
|
AVS_CACHE_NOTHING=10, // Do not cache video.
|
||||||
|
AVS_CACHE_WINDOW=11, // Hard protect upto X frames within a range of X from the current frame N.
|
||||||
|
AVS_CACHE_GENERIC=12, // LRU cache upto X frames.
|
||||||
|
AVS_CACHE_FORCE_GENERIC=13, // LRU cache upto X frames, override any previous CACHE_WINDOW.
|
||||||
|
|
||||||
|
AVS_CACHE_GET_POLICY=30, // Get the current policy.
|
||||||
|
AVS_CACHE_GET_WINDOW=31, // Get the current window h_span.
|
||||||
|
AVS_CACHE_GET_RANGE=32, // Get the current generic frame range.
|
||||||
|
|
||||||
|
AVS_CACHE_AUDIO=50, // Explicitly do cache audio, X byte cache.
|
||||||
|
AVS_CACHE_AUDIO_NOTHING=51, // Explicitly do not cache audio.
|
||||||
|
AVS_CACHE_AUDIO_NONE=52, // Audio cache off (auto mode), X byte intial cache.
|
||||||
|
AVS_CACHE_AUDIO_AUTO=53, // Audio cache on (auto mode), X byte intial cache.
|
||||||
|
|
||||||
|
AVS_CACHE_GET_AUDIO_POLICY=70, // Get the current audio policy.
|
||||||
|
AVS_CACHE_GET_AUDIO_SIZE=71, // Get the current audio cache size.
|
||||||
|
|
||||||
|
AVS_CACHE_PREFETCH_FRAME=100, // Queue request to prefetch frame N.
|
||||||
|
AVS_CACHE_PREFETCH_GO=101, // Action video prefetches.
|
||||||
|
|
||||||
|
AVS_CACHE_PREFETCH_AUDIO_BEGIN=120, // Begin queue request transaction to prefetch audio (take critical section).
|
||||||
|
AVS_CACHE_PREFETCH_AUDIO_STARTLO=121, // Set low 32 bits of start.
|
||||||
|
AVS_CACHE_PREFETCH_AUDIO_STARTHI=122, // Set high 32 bits of start.
|
||||||
|
AVS_CACHE_PREFETCH_AUDIO_COUNT=123, // Set low 32 bits of length.
|
||||||
|
AVS_CACHE_PREFETCH_AUDIO_COMMIT=124, // Enqueue request transaction to prefetch audio (release critical section).
|
||||||
|
AVS_CACHE_PREFETCH_AUDIO_GO=125, // Action audio prefetches.
|
||||||
|
|
||||||
|
AVS_CACHE_GETCHILD_CACHE_MODE=200, // Cache ask Child for desired video cache mode.
|
||||||
|
AVS_CACHE_GETCHILD_CACHE_SIZE=201, // Cache ask Child for desired video cache size.
|
||||||
|
AVS_CACHE_GETCHILD_AUDIO_MODE=202, // Cache ask Child for desired audio cache mode.
|
||||||
|
AVS_CACHE_GETCHILD_AUDIO_SIZE=203, // Cache ask Child for desired audio cache size.
|
||||||
|
|
||||||
|
AVS_CACHE_GETCHILD_COST=220, // Cache ask Child for estimated processing cost.
|
||||||
|
AVS_CACHE_COST_ZERO=221, // Child response of zero cost (ptr arithmetic only).
|
||||||
|
AVS_CACHE_COST_UNIT=222, // Child response of unit cost (less than or equal 1 full frame blit).
|
||||||
|
AVS_CACHE_COST_LOW=223, // Child response of light cost. (Fast)
|
||||||
|
AVS_CACHE_COST_MED=224, // Child response of medium cost. (Real time)
|
||||||
|
AVS_CACHE_COST_HI=225, // Child response of heavy cost. (Slow)
|
||||||
|
|
||||||
|
AVS_CACHE_GETCHILD_THREAD_MODE=240, // Cache ask Child for thread safetyness.
|
||||||
|
AVS_CACHE_THREAD_UNSAFE=241, // Only 1 thread allowed for all instances. 2.5 filters default!
|
||||||
|
AVS_CACHE_THREAD_CLASS=242, // Only 1 thread allowed for each instance. 2.6 filters default!
|
||||||
|
AVS_CACHE_THREAD_SAFE=243, // Allow all threads in any instance.
|
||||||
|
AVS_CACHE_THREAD_OWN=244, // Safe but limit to 1 thread, internally threaded.
|
||||||
|
|
||||||
|
AVS_CACHE_GETCHILD_ACCESS_COST=260, // Cache ask Child for preferred access pattern.
|
||||||
|
AVS_CACHE_ACCESS_RAND=261, // Filter is access order agnostic.
|
||||||
|
AVS_CACHE_ACCESS_SEQ0=262, // Filter prefers sequential access (low cost)
|
||||||
|
AVS_CACHE_ACCESS_SEQ1=263, // Filter needs sequential access (high cost)
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef BUILDING_AVSCORE
|
||||||
|
struct AVS_ScriptEnvironment {
|
||||||
|
IScriptEnvironment * env;
|
||||||
|
const char * error;
|
||||||
|
AVS_ScriptEnvironment(IScriptEnvironment * e = 0)
|
||||||
|
: env(e), error(0) {}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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_API(int, avs_is_yv24)(const AVS_VideoInfo * p);
|
||||||
|
|
||||||
|
AVSC_API(int, avs_is_yv16)(const AVS_VideoInfo * p);
|
||||||
|
|
||||||
|
AVSC_API(int, avs_is_yv12)(const AVS_VideoInfo * p) ;
|
||||||
|
|
||||||
|
AVSC_API(int, avs_is_yv411)(const AVS_VideoInfo * p);
|
||||||
|
|
||||||
|
AVSC_API(int, avs_is_y8)(const AVS_VideoInfo * p);
|
||||||
|
|
||||||
|
AVSC_INLINE int avs_is_property(const AVS_VideoInfo * p, int property)
|
||||||
|
{ return ((p->image_type & property)==property ); }
|
||||||
|
|
||||||
|
AVSC_INLINE int avs_is_planar(const AVS_VideoInfo * p)
|
||||||
|
{ return !!(p->pixel_type & AVS_CS_PLANAR); }
|
||||||
|
|
||||||
|
AVSC_API(int, avs_is_color_space)(const AVS_VideoInfo * p, int c_space);
|
||||||
|
|
||||||
|
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_API(int, avs_get_plane_width_subsampling)(const AVS_VideoInfo * p, int plane);
|
||||||
|
|
||||||
|
AVSC_API(int, avs_get_plane_height_subsampling)(const AVS_VideoInfo * p, int plane);
|
||||||
|
|
||||||
|
|
||||||
|
AVSC_API(int, avs_bits_per_pixel)(const AVS_VideoInfo * p);
|
||||||
|
|
||||||
|
AVSC_API(int, avs_bytes_from_pixels)(const AVS_VideoInfo * p, int pixels);
|
||||||
|
|
||||||
|
AVSC_API(int, avs_row_size)(const AVS_VideoInfo * p, int plane);
|
||||||
|
|
||||||
|
AVSC_API(int, avs_bmp_size)(const AVS_VideoInfo * vi);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef AVS_IMPLICIT_FUNCTION_DECLARATION_ERROR
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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 {
|
||||||
|
BYTE * 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.
|
||||||
|
volatile long sequence_number;
|
||||||
|
|
||||||
|
volatile 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 {
|
||||||
|
volatile long refcount;
|
||||||
|
AVS_VideoFrameBuffer * vfb;
|
||||||
|
int offset, pitch, row_size, height, offsetU, offsetV, pitchUV; // U&V offsets are from top of picture.
|
||||||
|
int row_sizeUV, heightUV;
|
||||||
|
} AVS_VideoFrame;
|
||||||
|
|
||||||
|
// Access functions for AVS_VideoFrame
|
||||||
|
AVSC_API(int, avs_get_pitch_p)(const AVS_VideoFrame * p, int plane);
|
||||||
|
|
||||||
|
#ifdef AVS_IMPLICIT_FUNCTION_DECLARATION_ERROR
|
||||||
|
AVSC_INLINE int avs_get_pitch(const AVS_VideoFrame * p) {
|
||||||
|
return avs_get_pitch_p(p, 0);}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AVSC_API(int, avs_get_row_size_p)(const AVS_VideoFrame * p, int plane);
|
||||||
|
|
||||||
|
AVSC_INLINE int avs_get_row_size(const AVS_VideoFrame * p) {
|
||||||
|
return p->row_size; }
|
||||||
|
|
||||||
|
AVSC_API(int, avs_get_height_p)(const AVS_VideoFrame * p, int plane);
|
||||||
|
|
||||||
|
AVSC_INLINE int avs_get_height(const AVS_VideoFrame * p) {
|
||||||
|
return p->height;}
|
||||||
|
|
||||||
|
AVSC_API(const BYTE *, avs_get_read_ptr_p)(const AVS_VideoFrame * p, int plane);
|
||||||
|
|
||||||
|
#ifdef AVS_IMPLICIT_FUNCTION_DECLARATION_ERROR
|
||||||
|
AVSC_INLINE const BYTE* avs_get_read_ptr(const AVS_VideoFrame * p) {
|
||||||
|
return avs_get_read_ptr_p(p, 0);}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AVSC_API(int, avs_is_writable)(const AVS_VideoFrame * p);
|
||||||
|
|
||||||
|
AVSC_API(BYTE *, avs_get_write_ptr_p)(const AVS_VideoFrame * p, int plane);
|
||||||
|
|
||||||
|
#ifdef AVS_IMPLICIT_FUNCTION_DECLARATION_ERROR
|
||||||
|
AVSC_INLINE BYTE* avs_get_write_ptr(const AVS_VideoFrame * p) {
|
||||||
|
return avs_get_write_ptr_p(p, 0);}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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 *);
|
||||||
|
|
||||||
|
#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;
|
||||||
|
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'; }
|
||||||
|
|
||||||
|
AVSC_API(AVS_Clip *, avs_take_clip)(AVS_Value, AVS_ScriptEnvironment *);
|
||||||
|
AVSC_API(void, avs_set_to_clip)(AVS_Value *, AVS_Clip *);
|
||||||
|
|
||||||
|
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 an 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; 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; v.type = 'i'; v.d.integer = v0; return v; }
|
||||||
|
AVSC_INLINE AVS_Value avs_new_value_string(const char * v0)
|
||||||
|
{ AVS_Value v; v.type = 's'; v.d.string = v0; return v; }
|
||||||
|
AVSC_INLINE AVS_Value avs_new_value_float(float v0)
|
||||||
|
{ AVS_Value v; v.type = 'f'; v.d.floating_pt = v0; return v;}
|
||||||
|
AVSC_INLINE AVS_Value avs_new_value_error(const char * v0)
|
||||||
|
{ AVS_Value v; 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; 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; v.type = 'a'; v.d.array = v0; v.array_size = size; return v; }
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// AVS_Clip
|
||||||
|
//
|
||||||
|
|
||||||
|
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, int frame_range);
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
AVSC_API(AVS_Clip *, avs_new_c_filter)(AVS_ScriptEnvironment * e,
|
||||||
|
AVS_FilterInfo * * fi,
|
||||||
|
AVS_Value child, int store_child);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
AVS_CPUF_SSE3 = 0x100, // PIV+, K8 Venice
|
||||||
|
AVS_CPUF_SSSE3 = 0x200, // Core 2
|
||||||
|
AVS_CPUF_SSE4 = 0x400, // Penryn, Wolfdale, Yorkfield
|
||||||
|
AVS_CPUF_SSE4_1 = 0x400,
|
||||||
|
//AVS_CPUF_AVX = 0x800, // Sandy Bridge, Bulldozer
|
||||||
|
AVS_CPUF_SSE4_2 = 0x1000, // Nehalem
|
||||||
|
//AVS_CPUF_AVX2 = 0x2000, // Haswell
|
||||||
|
//AVS_CPUF_AVX512 = 0x4000, // Knights Landing
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
AVSC_API(const char *, avs_get_error)(AVS_ScriptEnvironment *); // return 0 if no error
|
||||||
|
|
||||||
|
AVSC_API(int, 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, void* 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
|
||||||
|
|
||||||
|
#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,FRAME_ALIGN);}
|
||||||
|
|
||||||
|
AVSC_INLINE
|
||||||
|
AVS_VideoFrame * avs_new_frame(AVS_ScriptEnvironment * env,
|
||||||
|
const AVS_VideoInfo * vi)
|
||||||
|
{return avs_new_video_frame_a(env,vi,FRAME_ALIGN);}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
AVSC_API(int, avs_make_writable)(AVS_ScriptEnvironment *, AVS_VideoFrame * * pvf);
|
||||||
|
|
||||||
|
AVSC_API(void, avs_bit_blt)(AVS_ScriptEnvironment *, BYTE* dstp, int dst_pitch, const BYTE* 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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
#ifdef AVSC_NO_DECLSPEC
|
||||||
|
// use LoadLibrary and related functions to dynamically load Avisynth instead of declspec(dllimport)
|
||||||
|
/*
|
||||||
|
The following functions needs to have been declared, probably from windows.h
|
||||||
|
|
||||||
|
void* malloc(size_t)
|
||||||
|
void free(void*);
|
||||||
|
|
||||||
|
HMODULE LoadLibrary(const char*);
|
||||||
|
void* GetProcAddress(HMODULE, const char*);
|
||||||
|
FreeLibrary(HMODULE);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct AVS_Library AVS_Library;
|
||||||
|
|
||||||
|
#define AVSC_DECLARE_FUNC(name) name##_func name
|
||||||
|
|
||||||
|
struct AVS_Library {
|
||||||
|
HMODULE handle;
|
||||||
|
|
||||||
|
AVSC_DECLARE_FUNC(avs_add_function);
|
||||||
|
AVSC_DECLARE_FUNC(avs_at_exit);
|
||||||
|
AVSC_DECLARE_FUNC(avs_bit_blt);
|
||||||
|
AVSC_DECLARE_FUNC(avs_check_version);
|
||||||
|
AVSC_DECLARE_FUNC(avs_clip_get_error);
|
||||||
|
AVSC_DECLARE_FUNC(avs_copy_clip);
|
||||||
|
AVSC_DECLARE_FUNC(avs_copy_value);
|
||||||
|
AVSC_DECLARE_FUNC(avs_copy_video_frame);
|
||||||
|
AVSC_DECLARE_FUNC(avs_create_script_environment);
|
||||||
|
AVSC_DECLARE_FUNC(avs_delete_script_environment);
|
||||||
|
AVSC_DECLARE_FUNC(avs_function_exists);
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_audio);
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_cpu_flags);
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_frame);
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_parity);
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_var);
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_version);
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_video_info);
|
||||||
|
AVSC_DECLARE_FUNC(avs_invoke);
|
||||||
|
AVSC_DECLARE_FUNC(avs_make_writable);
|
||||||
|
AVSC_DECLARE_FUNC(avs_new_c_filter);
|
||||||
|
AVSC_DECLARE_FUNC(avs_new_video_frame_a);
|
||||||
|
AVSC_DECLARE_FUNC(avs_release_clip);
|
||||||
|
AVSC_DECLARE_FUNC(avs_release_value);
|
||||||
|
AVSC_DECLARE_FUNC(avs_release_video_frame);
|
||||||
|
AVSC_DECLARE_FUNC(avs_save_string);
|
||||||
|
AVSC_DECLARE_FUNC(avs_set_cache_hints);
|
||||||
|
AVSC_DECLARE_FUNC(avs_set_global_var);
|
||||||
|
AVSC_DECLARE_FUNC(avs_set_memory_max);
|
||||||
|
AVSC_DECLARE_FUNC(avs_set_to_clip);
|
||||||
|
AVSC_DECLARE_FUNC(avs_set_var);
|
||||||
|
AVSC_DECLARE_FUNC(avs_set_working_dir);
|
||||||
|
AVSC_DECLARE_FUNC(avs_sprintf);
|
||||||
|
AVSC_DECLARE_FUNC(avs_subframe);
|
||||||
|
AVSC_DECLARE_FUNC(avs_subframe_planar);
|
||||||
|
AVSC_DECLARE_FUNC(avs_take_clip);
|
||||||
|
AVSC_DECLARE_FUNC(avs_vsprintf);
|
||||||
|
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_error);
|
||||||
|
AVSC_DECLARE_FUNC(avs_is_yv24);
|
||||||
|
AVSC_DECLARE_FUNC(avs_is_yv16);
|
||||||
|
AVSC_DECLARE_FUNC(avs_is_yv12);
|
||||||
|
AVSC_DECLARE_FUNC(avs_is_yv411);
|
||||||
|
AVSC_DECLARE_FUNC(avs_is_y8);
|
||||||
|
AVSC_DECLARE_FUNC(avs_is_color_space);
|
||||||
|
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_plane_width_subsampling);
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_plane_height_subsampling);
|
||||||
|
AVSC_DECLARE_FUNC(avs_bits_per_pixel);
|
||||||
|
AVSC_DECLARE_FUNC(avs_bytes_from_pixels);
|
||||||
|
AVSC_DECLARE_FUNC(avs_row_size);
|
||||||
|
AVSC_DECLARE_FUNC(avs_bmp_size);
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_pitch_p);
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_row_size_p);
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_height_p);
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_read_ptr_p);
|
||||||
|
AVSC_DECLARE_FUNC(avs_is_writable);
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_write_ptr_p);
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef AVSC_DECLARE_FUNC
|
||||||
|
|
||||||
|
|
||||||
|
AVSC_INLINE AVS_Library * avs_load_library() {
|
||||||
|
AVS_Library *library = (AVS_Library *)malloc(sizeof(AVS_Library));
|
||||||
|
if (library == NULL)
|
||||||
|
return NULL;
|
||||||
|
library->handle = LoadLibrary("avisynth");
|
||||||
|
if (library->handle == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
#define __AVSC_STRINGIFY(x) #x
|
||||||
|
#define AVSC_STRINGIFY(x) __AVSC_STRINGIFY(x)
|
||||||
|
#define AVSC_LOAD_FUNC(name) {\
|
||||||
|
library->name = (name##_func) GetProcAddress(library->handle, AVSC_STRINGIFY(name));\
|
||||||
|
if (library->name == NULL)\
|
||||||
|
goto fail;\
|
||||||
|
}
|
||||||
|
|
||||||
|
AVSC_LOAD_FUNC(avs_add_function);
|
||||||
|
AVSC_LOAD_FUNC(avs_at_exit);
|
||||||
|
AVSC_LOAD_FUNC(avs_bit_blt);
|
||||||
|
AVSC_LOAD_FUNC(avs_check_version);
|
||||||
|
AVSC_LOAD_FUNC(avs_clip_get_error);
|
||||||
|
AVSC_LOAD_FUNC(avs_copy_clip);
|
||||||
|
AVSC_LOAD_FUNC(avs_copy_value);
|
||||||
|
AVSC_LOAD_FUNC(avs_copy_video_frame);
|
||||||
|
AVSC_LOAD_FUNC(avs_create_script_environment);
|
||||||
|
AVSC_LOAD_FUNC(avs_delete_script_environment);
|
||||||
|
AVSC_LOAD_FUNC(avs_function_exists);
|
||||||
|
AVSC_LOAD_FUNC(avs_get_audio);
|
||||||
|
AVSC_LOAD_FUNC(avs_get_cpu_flags);
|
||||||
|
AVSC_LOAD_FUNC(avs_get_frame);
|
||||||
|
AVSC_LOAD_FUNC(avs_get_parity);
|
||||||
|
AVSC_LOAD_FUNC(avs_get_var);
|
||||||
|
AVSC_LOAD_FUNC(avs_get_version);
|
||||||
|
AVSC_LOAD_FUNC(avs_get_video_info);
|
||||||
|
AVSC_LOAD_FUNC(avs_invoke);
|
||||||
|
AVSC_LOAD_FUNC(avs_make_writable);
|
||||||
|
AVSC_LOAD_FUNC(avs_new_c_filter);
|
||||||
|
AVSC_LOAD_FUNC(avs_new_video_frame_a);
|
||||||
|
AVSC_LOAD_FUNC(avs_release_clip);
|
||||||
|
AVSC_LOAD_FUNC(avs_release_value);
|
||||||
|
AVSC_LOAD_FUNC(avs_release_video_frame);
|
||||||
|
AVSC_LOAD_FUNC(avs_save_string);
|
||||||
|
AVSC_LOAD_FUNC(avs_set_cache_hints);
|
||||||
|
AVSC_LOAD_FUNC(avs_set_global_var);
|
||||||
|
AVSC_LOAD_FUNC(avs_set_memory_max);
|
||||||
|
AVSC_LOAD_FUNC(avs_set_to_clip);
|
||||||
|
AVSC_LOAD_FUNC(avs_set_var);
|
||||||
|
AVSC_LOAD_FUNC(avs_set_working_dir);
|
||||||
|
AVSC_LOAD_FUNC(avs_sprintf);
|
||||||
|
AVSC_LOAD_FUNC(avs_subframe);
|
||||||
|
AVSC_LOAD_FUNC(avs_subframe_planar);
|
||||||
|
AVSC_LOAD_FUNC(avs_take_clip);
|
||||||
|
AVSC_LOAD_FUNC(avs_vsprintf);
|
||||||
|
|
||||||
|
AVSC_LOAD_FUNC(avs_get_error);
|
||||||
|
AVSC_LOAD_FUNC(avs_is_yv24);
|
||||||
|
AVSC_LOAD_FUNC(avs_is_yv16);
|
||||||
|
AVSC_LOAD_FUNC(avs_is_yv12);
|
||||||
|
AVSC_LOAD_FUNC(avs_is_yv411);
|
||||||
|
AVSC_LOAD_FUNC(avs_is_y8);
|
||||||
|
AVSC_LOAD_FUNC(avs_is_color_space);
|
||||||
|
|
||||||
|
AVSC_LOAD_FUNC(avs_get_plane_width_subsampling);
|
||||||
|
AVSC_LOAD_FUNC(avs_get_plane_height_subsampling);
|
||||||
|
AVSC_LOAD_FUNC(avs_bits_per_pixel);
|
||||||
|
AVSC_LOAD_FUNC(avs_bytes_from_pixels);
|
||||||
|
AVSC_LOAD_FUNC(avs_row_size);
|
||||||
|
AVSC_LOAD_FUNC(avs_bmp_size);
|
||||||
|
AVSC_LOAD_FUNC(avs_get_pitch_p);
|
||||||
|
AVSC_LOAD_FUNC(avs_get_row_size_p);
|
||||||
|
AVSC_LOAD_FUNC(avs_get_height_p);
|
||||||
|
AVSC_LOAD_FUNC(avs_get_read_ptr_p);
|
||||||
|
AVSC_LOAD_FUNC(avs_is_writable);
|
||||||
|
AVSC_LOAD_FUNC(avs_get_write_ptr_p);
|
||||||
|
|
||||||
|
#undef __AVSC_STRINGIFY
|
||||||
|
#undef AVSC_STRINGIFY
|
||||||
|
#undef AVSC_LOAD_FUNC
|
||||||
|
|
||||||
|
return library;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
free(library);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
AVSC_INLINE void avs_free_library(AVS_Library *library) {
|
||||||
|
if (library == NULL)
|
||||||
|
return;
|
||||||
|
FreeLibrary(library->handle);
|
||||||
|
free(library);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
62
compat/avisynth/avs/capi.h
Normal file
62
compat/avisynth/avs/capi.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
// 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
|
||||||
|
|
||||||
|
#ifndef AVSC_USE_STDCALL
|
||||||
|
# define AVSC_CC __cdecl
|
||||||
|
#else
|
||||||
|
# define AVSC_CC __stdcall
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AVSC_INLINE static __inline
|
||||||
|
|
||||||
|
#ifdef BUILDING_AVSCORE
|
||||||
|
# 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
|
||||||
|
|
||||||
|
#endif //AVS_CAPI_H
|
||||||
55
compat/avisynth/avs/config.h
Normal file
55
compat/avisynth/avs/config.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
// 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 32
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
#endif //AVS_CONFIG_H
|
||||||
51
compat/avisynth/avs/types.h
Normal file
51
compat/avisynth/avs/types.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
// 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
|
||||||
|
|
||||||
|
// 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
|
||||||
728
compat/avisynth/avxsynth_c.h
Normal file
728
compat/avisynth/avxsynth_c.h
Normal file
@@ -0,0 +1,728 @@
|
|||||||
|
// 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__
|
||||||
85
compat/avisynth/windowsPorts/basicDataTypeConversions.h
Normal file
85
compat/avisynth/windowsPorts/basicDataTypeConversions.h
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
#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__
|
||||||
77
compat/avisynth/windowsPorts/windows2linux.h
Normal file
77
compat/avisynth/windowsPorts/windows2linux.h
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
#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__
|
||||||
@@ -1,189 +0,0 @@
|
|||||||
/*
|
|
||||||
* Minimum CUDA compatibility definitions header
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019 rcombs
|
|
||||||
*
|
|
||||||
* This file is part of FFmpeg.
|
|
||||||
*
|
|
||||||
* FFmpeg is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* FFmpeg is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with FFmpeg; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMPAT_CUDA_CUDA_RUNTIME_H
|
|
||||||
#define COMPAT_CUDA_CUDA_RUNTIME_H
|
|
||||||
|
|
||||||
// Common macros
|
|
||||||
#define __global__ __attribute__((global))
|
|
||||||
#define __device__ __attribute__((device))
|
|
||||||
#define __device_builtin__ __attribute__((device_builtin))
|
|
||||||
#define __align__(N) __attribute__((aligned(N)))
|
|
||||||
#define __inline__ __inline__ __attribute__((always_inline))
|
|
||||||
|
|
||||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
|
||||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
|
||||||
#define abs(x) ((x) < 0 ? -(x) : (x))
|
|
||||||
|
|
||||||
#define atomicAdd(a, b) (__atomic_fetch_add(a, b, __ATOMIC_SEQ_CST))
|
|
||||||
|
|
||||||
// Basic typedefs
|
|
||||||
typedef __device_builtin__ unsigned long long cudaTextureObject_t;
|
|
||||||
|
|
||||||
typedef struct __device_builtin__ __align__(2) uchar2
|
|
||||||
{
|
|
||||||
unsigned char x, y;
|
|
||||||
} uchar2;
|
|
||||||
|
|
||||||
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;
|
|
||||||
} uint3;
|
|
||||||
|
|
||||||
typedef struct uint3 dim3;
|
|
||||||
|
|
||||||
typedef struct __device_builtin__ __align__(4) uchar4
|
|
||||||
{
|
|
||||||
unsigned char x, y, z, w;
|
|
||||||
} uchar4;
|
|
||||||
|
|
||||||
typedef struct __device_builtin__ __align__(8) ushort4
|
|
||||||
{
|
|
||||||
unsigned short x, y, z, w;
|
|
||||||
} ushort4;
|
|
||||||
|
|
||||||
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)); \
|
|
||||||
ret.comp = tmp;
|
|
||||||
|
|
||||||
#define GET(name, reg) static inline __device__ uint3 name() {\
|
|
||||||
uint3 ret; \
|
|
||||||
unsigned tmp; \
|
|
||||||
GETCOMP(reg, x) \
|
|
||||||
GETCOMP(reg, y) \
|
|
||||||
GETCOMP(reg, z) \
|
|
||||||
return ret; \
|
|
||||||
}
|
|
||||||
|
|
||||||
GET(getBlockIdx, ctaid)
|
|
||||||
GET(getBlockDim, ntid)
|
|
||||||
GET(getThreadIdx, tid)
|
|
||||||
|
|
||||||
// Instead of externs for these registers, we turn access to them into calls into trivial ASM
|
|
||||||
#define blockIdx (getBlockIdx())
|
|
||||||
#define blockDim (getBlockDim())
|
|
||||||
#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<typename T>
|
|
||||||
inline __device__ T tex2D(cudaTextureObject_t texObject, float x, float y)
|
|
||||||
{
|
|
||||||
T ret;
|
|
||||||
unsigned ret1, ret2, ret3, ret4;
|
|
||||||
asm("tex.2d.v4.u32.f32 {%0, %1, %2, %3}, [%4, {%5, %6}];" :
|
|
||||||
"=r"(ret1), "=r"(ret2), "=r"(ret3), "=r"(ret4) :
|
|
||||||
"l"(texObject), "f"(x), "f"(y));
|
|
||||||
conv(&ret, ret1, ret2, ret3, ret4);
|
|
||||||
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 __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 */
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of FFmpeg.
|
|
||||||
*
|
|
||||||
* FFmpeg is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* FFmpeg is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with FFmpeg; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMPAT_CUDA_DYNLINK_LOADER_H
|
|
||||||
#define COMPAT_CUDA_DYNLINK_LOADER_H
|
|
||||||
|
|
||||||
#include "libavutil/log.h"
|
|
||||||
#include "compat/w32dlfcn.h"
|
|
||||||
|
|
||||||
#define FFNV_LOAD_FUNC(path) dlopen((path), RTLD_LAZY)
|
|
||||||
#define FFNV_SYM_FUNC(lib, sym) dlsym((lib), (sym))
|
|
||||||
#define FFNV_FREE_FUNC(lib) dlclose(lib)
|
|
||||||
#define FFNV_LOG_FUNC(logctx, msg, ...) av_log(logctx, AV_LOG_ERROR, msg, __VA_ARGS__)
|
|
||||||
#define FFNV_DEBUG_LOG_FUNC(logctx, msg, ...) av_log(logctx, AV_LOG_DEBUG, msg, __VA_ARGS__)
|
|
||||||
|
|
||||||
#include <ffnvcodec/dynlink_loader.h>
|
|
||||||
|
|
||||||
#endif /* COMPAT_CUDA_DYNLINK_LOADER_H */
|
|
||||||
@@ -1,47 +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 <math.h>
|
|
||||||
|
|
||||||
#define FUN(name, type, op) \
|
|
||||||
type name(type x, type y) \
|
|
||||||
{ \
|
|
||||||
if (fpclassify(x) == FP_NAN) return y; \
|
|
||||||
if (fpclassify(y) == FP_NAN) return x; \
|
|
||||||
return x op y ? x : y; \
|
|
||||||
}
|
|
||||||
|
|
||||||
FUN(fmin, double, <)
|
|
||||||
FUN(fmax, double, >)
|
|
||||||
FUN(fminf, float, <)
|
|
||||||
FUN(fmaxf, float, >)
|
|
||||||
|
|
||||||
long double fmodl(long double x, long double y)
|
|
||||||
{
|
|
||||||
return fmod(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
long double scalbnl(long double x, int exp)
|
|
||||||
{
|
|
||||||
return scalbn(x, exp);
|
|
||||||
}
|
|
||||||
|
|
||||||
long double copysignl(long double x, long double y)
|
|
||||||
{
|
|
||||||
return copysign(x, y);
|
|
||||||
}
|
|
||||||
@@ -1,25 +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
|
|
||||||
*/
|
|
||||||
|
|
||||||
double fmin(double, double);
|
|
||||||
double fmax(double, double);
|
|
||||||
float fminf(float, float);
|
|
||||||
float fmaxf(float, float);
|
|
||||||
long double fmodl(long double, long double);
|
|
||||||
long double scalbnl(long double, int);
|
|
||||||
long double copysignl(long double, long double);
|
|
||||||
@@ -59,7 +59,7 @@ int avpriv_vsnprintf(char *s, size_t n, const char *fmt,
|
|||||||
* recommends to provide _snprintf/_vsnprintf() a buffer size that
|
* recommends to provide _snprintf/_vsnprintf() a buffer size that
|
||||||
* is one less than the actual buffer, and zero it before calling
|
* is one less than the actual buffer, and zero it before calling
|
||||||
* _snprintf/_vsnprintf() to workaround this problem.
|
* _snprintf/_vsnprintf() to workaround this problem.
|
||||||
* See https://web.archive.org/web/20151214111935/http://msdn.microsoft.com/en-us/library/1kt27hek(v=vs.80).aspx */
|
* See http://msdn.microsoft.com/en-us/library/1kt27hek(v=vs.80).aspx */
|
||||||
memset(s, 0, n);
|
memset(s, 0, n);
|
||||||
va_copy(ap_copy, ap);
|
va_copy(ap_copy, ap);
|
||||||
ret = _vsnprintf(s, n - 1, fmt, ap_copy);
|
ret = _vsnprintf(s, n - 1, fmt, ap_copy);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011-2017 KO Myung-Hun <komh@chollian.net>
|
* Copyright (c) 2011 KO Myung-Hun <komh@chollian.net>
|
||||||
*
|
*
|
||||||
* This file is part of FFmpeg.
|
* This file is part of FFmpeg.
|
||||||
*
|
*
|
||||||
@@ -27,19 +27,15 @@
|
|||||||
#define COMPAT_OS2THREADS_H
|
#define COMPAT_OS2THREADS_H
|
||||||
|
|
||||||
#define INCL_DOS
|
#define INCL_DOS
|
||||||
#define INCL_DOSERRORS
|
|
||||||
#include <os2.h>
|
#include <os2.h>
|
||||||
|
|
||||||
#undef __STRICT_ANSI__ /* for _beginthread() */
|
#undef __STRICT_ANSI__ /* for _beginthread() */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include <sys/builtin.h>
|
#include <sys/builtin.h>
|
||||||
#include <sys/fmutex.h>
|
#include <sys/fmutex.h>
|
||||||
|
|
||||||
#include "libavutil/attributes.h"
|
#include "libavutil/attributes.h"
|
||||||
#include "libavutil/common.h"
|
|
||||||
#include "libavutil/time.h"
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
TID tid;
|
TID tid;
|
||||||
@@ -50,11 +46,9 @@ typedef struct {
|
|||||||
|
|
||||||
typedef void pthread_attr_t;
|
typedef void pthread_attr_t;
|
||||||
|
|
||||||
typedef _fmutex pthread_mutex_t;
|
typedef HMTX pthread_mutex_t;
|
||||||
typedef void pthread_mutexattr_t;
|
typedef void pthread_mutexattr_t;
|
||||||
|
|
||||||
#define PTHREAD_MUTEX_INITIALIZER _FMUTEX_INITIALIZER
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
HEV event_sem;
|
HEV event_sem;
|
||||||
HEV ack_sem;
|
HEV ack_sem;
|
||||||
@@ -104,28 +98,28 @@ static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
|
|||||||
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex,
|
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex,
|
||||||
const pthread_mutexattr_t *attr)
|
const pthread_mutexattr_t *attr)
|
||||||
{
|
{
|
||||||
_fmutex_create(mutex, 0);
|
DosCreateMutexSem(NULL, (PHMTX)mutex, 0, FALSE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
|
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
|
||||||
{
|
{
|
||||||
_fmutex_close(mutex);
|
DosCloseMutexSem(*(PHMTX)mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
|
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
|
||||||
{
|
{
|
||||||
_fmutex_request(mutex, 0);
|
DosRequestMutexSem(*(PHMTX)mutex, SEM_INDEFINITE_WAIT);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
|
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
|
||||||
{
|
{
|
||||||
_fmutex_release(mutex);
|
DosReleaseMutexSem(*(PHMTX)mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -167,28 +161,6 @@ static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
|
|||||||
return 0;
|
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,
|
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond,
|
||||||
pthread_mutex_t *mutex)
|
pthread_mutex_t *mutex)
|
||||||
{
|
{
|
||||||
|
|||||||
10
compat/plan9/head
Executable file
10
compat/plan9/head
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
n=10
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
-n) n=$2; shift 2 ;;
|
||||||
|
-n*) n=${1#-n}; shift ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exec sed ${n}q "$@"
|
||||||
@@ -1,7 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* DVD subtitle decoding/encoding
|
|
||||||
* Copyright (c) 2005 Fabrice Bellard
|
|
||||||
*
|
|
||||||
* This file is part of FFmpeg.
|
* This file is part of FFmpeg.
|
||||||
*
|
*
|
||||||
* FFmpeg is free software; you can redistribute it and/or
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
@@ -19,15 +16,19 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "internal.h"
|
int plan9_main(int argc, char **argv);
|
||||||
#include "libavutil/avstring.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
void ff_dvdsub_parse_palette(uint32_t *palette, const char *p)
|
#undef main
|
||||||
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 16; i++) {
|
/* The setfcr() function in lib9 is broken, must use asm. */
|
||||||
palette[i] = strtoul(p, (char **)&p, 16);
|
#ifdef __i386
|
||||||
while (*p == ',' || av_isspace(*p))
|
short fcr;
|
||||||
p++;
|
__asm__ volatile ("fstcw %0 \n"
|
||||||
}
|
"or $63, %0 \n"
|
||||||
|
"fldcw %0 \n"
|
||||||
|
: "=m"(fcr));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return plan9_main(argc, argv);
|
||||||
}
|
}
|
||||||
2
compat/plan9/printf
Executable file
2
compat/plan9/printf
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
exec awk "BEGIN { for (i = 2; i < ARGC; i++) printf \"$1\", ARGV[i] }" "$@"
|
||||||
@@ -25,9 +25,9 @@
|
|||||||
#include "libavutil/avstring.h"
|
#include "libavutil/avstring.h"
|
||||||
#include "libavutil/mathematics.h"
|
#include "libavutil/mathematics.h"
|
||||||
|
|
||||||
static const char *check_nan_suffix(const char *s)
|
static char *check_nan_suffix(char *s)
|
||||||
{
|
{
|
||||||
const char *start = s;
|
char *start = s;
|
||||||
|
|
||||||
if (*s++ != '(')
|
if (*s++ != '(')
|
||||||
return start;
|
return start;
|
||||||
@@ -44,7 +44,7 @@ double strtod(const char *, char **);
|
|||||||
|
|
||||||
double avpriv_strtod(const char *nptr, char **endptr)
|
double avpriv_strtod(const char *nptr, char **endptr)
|
||||||
{
|
{
|
||||||
const char *end;
|
char *end;
|
||||||
double res;
|
double res;
|
||||||
|
|
||||||
/* Skip leading spaces */
|
/* Skip leading spaces */
|
||||||
@@ -81,13 +81,13 @@ double avpriv_strtod(const char *nptr, char **endptr)
|
|||||||
!av_strncasecmp(nptr, "+0x", 3)) {
|
!av_strncasecmp(nptr, "+0x", 3)) {
|
||||||
/* FIXME this doesn't handle exponents, non-integers (float/double)
|
/* FIXME this doesn't handle exponents, non-integers (float/double)
|
||||||
* and numbers too large for long long */
|
* and numbers too large for long long */
|
||||||
res = strtoll(nptr, (char **)&end, 16);
|
res = strtoll(nptr, &end, 16);
|
||||||
} else {
|
} else {
|
||||||
res = strtod(nptr, (char **)&end);
|
res = strtod(nptr, &end);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endptr)
|
if (endptr)
|
||||||
*endptr = (char *)end;
|
*endptr = end;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,15 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef AVUTIL_MIPS_CPU_H
|
#ifndef COMPAT_TMS470_MATH_H
|
||||||
#define AVUTIL_MIPS_CPU_H
|
#define COMPAT_TMS470_MATH_H
|
||||||
|
|
||||||
#include "libavutil/cpu.h"
|
#include_next <math.h>
|
||||||
#include "libavutil/cpu_internal.h"
|
|
||||||
|
|
||||||
#define have_mmi(flags) CPUEXT(flags, MMI)
|
#undef INFINITY
|
||||||
#define have_msa(flags) CPUEXT(flags, MSA)
|
#undef NAN
|
||||||
|
|
||||||
#endif /* AVUTIL_MIPS_CPU_H */
|
#define INFINITY (*(const float*)((const unsigned []){ 0x7f800000 }))
|
||||||
|
#define NAN (*(const float*)((const unsigned []){ 0x7fc00000 }))
|
||||||
|
|
||||||
|
#endif /* COMPAT_TMS470_MATH_H */
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of FFmpeg.
|
|
||||||
*
|
|
||||||
* FFmpeg is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* FFmpeg is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with FFmpeg; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMPAT_W32DLFCN_H
|
|
||||||
#define COMPAT_W32DLFCN_H
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#include "config.h"
|
|
||||||
#if (_WIN32_WINNT < 0x0602) || HAVE_WINRT
|
|
||||||
#include "libavutil/wchar_filename.h"
|
|
||||||
#endif
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
* executable or system directory are allowed to be loaded.
|
|
||||||
* @param name The dynamic lib name.
|
|
||||||
* @return A handle to the opened lib.
|
|
||||||
*/
|
|
||||||
static inline HMODULE win32_dlopen(const char *name)
|
|
||||||
{
|
|
||||||
#if _WIN32_WINNT < 0x0602
|
|
||||||
// Need to 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))
|
|
||||||
goto exit;
|
|
||||||
path = (wchar_t *)av_calloc(MAX_PATH, sizeof(wchar_t));
|
|
||||||
// Try local directory first
|
|
||||||
pathlen = GetModuleFileNameW(NULL, path, MAX_PATH);
|
|
||||||
pathlen = wcsrchr(path, '\\') - path;
|
|
||||||
if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH)
|
|
||||||
goto exit;
|
|
||||||
path[pathlen] = '\\';
|
|
||||||
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)
|
|
||||||
goto exit;
|
|
||||||
path[pathlen] = '\\';
|
|
||||||
wcscpy(path + pathlen + 1, name_w);
|
|
||||||
module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
|
||||||
}
|
|
||||||
exit:
|
|
||||||
av_free(path);
|
|
||||||
av_free(name_w);
|
|
||||||
return module;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifndef LOAD_LIBRARY_SEARCH_APPLICATION_DIR
|
|
||||||
# define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x00000200
|
|
||||||
#endif
|
|
||||||
#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32
|
|
||||||
# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
|
|
||||||
#endif
|
|
||||||
#if HAVE_WINRT
|
|
||||||
wchar_t *name_w = NULL;
|
|
||||||
int ret;
|
|
||||||
if (utf8towchar(name, &name_w))
|
|
||||||
return NULL;
|
|
||||||
ret = LoadPackagedLibrary(name_w, 0);
|
|
||||||
av_free(name_w);
|
|
||||||
return ret;
|
|
||||||
#else
|
|
||||||
return LoadLibraryExA(name, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#define dlopen(name, flags) win32_dlopen(name)
|
|
||||||
#define dlclose FreeLibrary
|
|
||||||
#define dlsym GetProcAddress
|
|
||||||
#else
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* COMPAT_W32DLFCN_H */
|
|
||||||
@@ -38,13 +38,16 @@
|
|||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <time.h>
|
|
||||||
|
#if _WIN32_WINNT < 0x0600 && defined(__MINGW32__)
|
||||||
|
#undef MemoryBarrier
|
||||||
|
#define MemoryBarrier __sync_synchronize
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libavutil/attributes.h"
|
#include "libavutil/attributes.h"
|
||||||
#include "libavutil/common.h"
|
#include "libavutil/common.h"
|
||||||
#include "libavutil/internal.h"
|
#include "libavutil/internal.h"
|
||||||
#include "libavutil/mem.h"
|
#include "libavutil/mem.h"
|
||||||
#include "libavutil/time.h"
|
|
||||||
|
|
||||||
typedef struct pthread_t {
|
typedef struct pthread_t {
|
||||||
void *handle;
|
void *handle;
|
||||||
@@ -53,22 +56,28 @@ typedef struct pthread_t {
|
|||||||
void *ret;
|
void *ret;
|
||||||
} pthread_t;
|
} pthread_t;
|
||||||
|
|
||||||
/* use light weight mutex/condition variable API for Windows Vista and later */
|
/* the conditional variable api for windows 6.0+ uses critical sections and
|
||||||
typedef SRWLOCK pthread_mutex_t;
|
* not mutexes */
|
||||||
|
typedef CRITICAL_SECTION pthread_mutex_t;
|
||||||
|
|
||||||
|
/* This is the CONDITION_VARIABLE typedef for using Windows' native
|
||||||
|
* conditional variables on kernels 6.0+. */
|
||||||
|
#if HAVE_CONDITION_VARIABLE_PTR
|
||||||
typedef CONDITION_VARIABLE pthread_cond_t;
|
typedef CONDITION_VARIABLE pthread_cond_t;
|
||||||
|
#else
|
||||||
|
typedef struct pthread_cond_t {
|
||||||
|
void *Ptr;
|
||||||
|
} pthread_cond_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PTHREAD_MUTEX_INITIALIZER SRWLOCK_INIT
|
#if _WIN32_WINNT >= 0x0600
|
||||||
#define PTHREAD_COND_INITIALIZER CONDITION_VARIABLE_INIT
|
|
||||||
|
|
||||||
#define InitializeCriticalSection(x) InitializeCriticalSectionEx(x, 0, 0)
|
#define InitializeCriticalSection(x) InitializeCriticalSectionEx(x, 0, 0)
|
||||||
#define WaitForSingleObject(a, b) WaitForSingleObjectEx(a, b, FALSE)
|
#define WaitForSingleObject(a, b) WaitForSingleObjectEx(a, b, FALSE)
|
||||||
|
#endif
|
||||||
#define PTHREAD_CANCEL_ENABLE 1
|
|
||||||
#define PTHREAD_CANCEL_DISABLE 0
|
|
||||||
|
|
||||||
static av_unused unsigned __stdcall attribute_align_arg win32thread_worker(void *arg)
|
static av_unused unsigned __stdcall attribute_align_arg win32thread_worker(void *arg)
|
||||||
{
|
{
|
||||||
pthread_t *h = (pthread_t*)arg;
|
pthread_t *h = arg;
|
||||||
h->ret = h->func(h->arg);
|
h->ret = h->func(h->arg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -105,25 +114,26 @@ static av_unused int pthread_join(pthread_t thread, void **value_ptr)
|
|||||||
|
|
||||||
static inline int pthread_mutex_init(pthread_mutex_t *m, void* attr)
|
static inline int pthread_mutex_init(pthread_mutex_t *m, void* attr)
|
||||||
{
|
{
|
||||||
InitializeSRWLock(m);
|
InitializeCriticalSection(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static inline int pthread_mutex_destroy(pthread_mutex_t *m)
|
static inline int pthread_mutex_destroy(pthread_mutex_t *m)
|
||||||
{
|
{
|
||||||
/* Unlocked SWR locks use no resources */
|
DeleteCriticalSection(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static inline int pthread_mutex_lock(pthread_mutex_t *m)
|
static inline int pthread_mutex_lock(pthread_mutex_t *m)
|
||||||
{
|
{
|
||||||
AcquireSRWLockExclusive(m);
|
EnterCriticalSection(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static inline int pthread_mutex_unlock(pthread_mutex_t *m)
|
static inline int pthread_mutex_unlock(pthread_mutex_t *m)
|
||||||
{
|
{
|
||||||
ReleaseSRWLockExclusive(m);
|
LeaveCriticalSection(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if _WIN32_WINNT >= 0x0600
|
||||||
typedef INIT_ONCE pthread_once_t;
|
typedef INIT_ONCE pthread_once_t;
|
||||||
#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
|
#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
|
||||||
|
|
||||||
@@ -157,23 +167,7 @@ static inline int pthread_cond_broadcast(pthread_cond_t *cond)
|
|||||||
|
|
||||||
static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||||
{
|
{
|
||||||
SleepConditionVariableSRW(cond, mutex, INFINITE, 0);
|
SleepConditionVariableCS(cond, mutex, INFINITE);
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,9 +177,242 @@ static inline int pthread_cond_signal(pthread_cond_t *cond)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int pthread_setcancelstate(int state, int *oldstate)
|
#else // _WIN32_WINNT < 0x0600
|
||||||
|
|
||||||
|
/* atomic init state of dynamically loaded functions */
|
||||||
|
static LONG w32thread_init_state = 0;
|
||||||
|
static av_unused void w32thread_init(void);
|
||||||
|
|
||||||
|
/* for pre-Windows 6.0 platforms, define INIT_ONCE struct,
|
||||||
|
* compatible to the one used in the native API */
|
||||||
|
|
||||||
|
typedef union pthread_once_t {
|
||||||
|
void * Ptr; ///< For the Windows 6.0+ native functions
|
||||||
|
LONG state; ///< For the pre-Windows 6.0 compat code
|
||||||
|
} pthread_once_t;
|
||||||
|
|
||||||
|
#define PTHREAD_ONCE_INIT {0}
|
||||||
|
|
||||||
|
/* function pointers to init once API on windows 6.0+ kernels */
|
||||||
|
static BOOL (WINAPI *initonce_begin)(pthread_once_t *lpInitOnce, DWORD dwFlags, BOOL *fPending, void **lpContext);
|
||||||
|
static BOOL (WINAPI *initonce_complete)(pthread_once_t *lpInitOnce, DWORD dwFlags, void *lpContext);
|
||||||
|
|
||||||
|
/* pre-Windows 6.0 compat using a spin-lock */
|
||||||
|
static inline void w32thread_once_fallback(LONG volatile *state, void (*init_routine)(void))
|
||||||
{
|
{
|
||||||
|
switch (InterlockedCompareExchange(state, 1, 0)) {
|
||||||
|
/* Initial run */
|
||||||
|
case 0:
|
||||||
|
init_routine();
|
||||||
|
InterlockedExchange(state, 2);
|
||||||
|
break;
|
||||||
|
/* Another thread is running init */
|
||||||
|
case 1:
|
||||||
|
while (1) {
|
||||||
|
MemoryBarrier();
|
||||||
|
if (*state == 2)
|
||||||
|
break;
|
||||||
|
Sleep(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
/* Initialization complete */
|
||||||
|
case 2:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static av_unused int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
|
||||||
|
{
|
||||||
|
w32thread_once_fallback(&w32thread_init_state, w32thread_init);
|
||||||
|
|
||||||
|
/* Use native functions on Windows 6.0+ */
|
||||||
|
if (initonce_begin && initonce_complete) {
|
||||||
|
BOOL pending = FALSE;
|
||||||
|
initonce_begin(once_control, 0, &pending, NULL);
|
||||||
|
if (pending)
|
||||||
|
init_routine();
|
||||||
|
initonce_complete(once_control, 0, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
w32thread_once_fallback(&once_control->state, init_routine);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* for pre-Windows 6.0 platforms we need to define and use our own condition
|
||||||
|
* variable and api */
|
||||||
|
|
||||||
|
typedef struct win32_cond_t {
|
||||||
|
pthread_mutex_t mtx_broadcast;
|
||||||
|
pthread_mutex_t mtx_waiter_count;
|
||||||
|
volatile int waiter_count;
|
||||||
|
HANDLE semaphore;
|
||||||
|
HANDLE waiters_done;
|
||||||
|
volatile int is_broadcast;
|
||||||
|
} win32_cond_t;
|
||||||
|
|
||||||
|
/* function pointers to conditional variable API on windows 6.0+ kernels */
|
||||||
|
static void (WINAPI *cond_broadcast)(pthread_cond_t *cond);
|
||||||
|
static void (WINAPI *cond_init)(pthread_cond_t *cond);
|
||||||
|
static void (WINAPI *cond_signal)(pthread_cond_t *cond);
|
||||||
|
static BOOL (WINAPI *cond_wait)(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||||
|
DWORD milliseconds);
|
||||||
|
|
||||||
|
static av_unused int pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
|
||||||
|
{
|
||||||
|
win32_cond_t *win32_cond = NULL;
|
||||||
|
|
||||||
|
w32thread_once_fallback(&w32thread_init_state, w32thread_init);
|
||||||
|
|
||||||
|
if (cond_init) {
|
||||||
|
cond_init(cond);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* non native condition variables */
|
||||||
|
win32_cond = av_mallocz(sizeof(win32_cond_t));
|
||||||
|
if (!win32_cond)
|
||||||
|
return ENOMEM;
|
||||||
|
cond->Ptr = win32_cond;
|
||||||
|
win32_cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
|
||||||
|
if (!win32_cond->semaphore)
|
||||||
|
return ENOMEM;
|
||||||
|
win32_cond->waiters_done = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
if (!win32_cond->waiters_done)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
pthread_mutex_init(&win32_cond->mtx_waiter_count, NULL);
|
||||||
|
pthread_mutex_init(&win32_cond->mtx_broadcast, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static av_unused int pthread_cond_destroy(pthread_cond_t *cond)
|
||||||
|
{
|
||||||
|
win32_cond_t *win32_cond = cond->Ptr;
|
||||||
|
/* native condition variables do not destroy */
|
||||||
|
if (cond_init)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* non native condition variables */
|
||||||
|
CloseHandle(win32_cond->semaphore);
|
||||||
|
CloseHandle(win32_cond->waiters_done);
|
||||||
|
pthread_mutex_destroy(&win32_cond->mtx_waiter_count);
|
||||||
|
pthread_mutex_destroy(&win32_cond->mtx_broadcast);
|
||||||
|
av_freep(&win32_cond);
|
||||||
|
cond->Ptr = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static av_unused int pthread_cond_broadcast(pthread_cond_t *cond)
|
||||||
|
{
|
||||||
|
win32_cond_t *win32_cond = cond->Ptr;
|
||||||
|
int have_waiter;
|
||||||
|
|
||||||
|
if (cond_broadcast) {
|
||||||
|
cond_broadcast(cond);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* non native condition variables */
|
||||||
|
pthread_mutex_lock(&win32_cond->mtx_broadcast);
|
||||||
|
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
|
||||||
|
have_waiter = 0;
|
||||||
|
|
||||||
|
if (win32_cond->waiter_count) {
|
||||||
|
win32_cond->is_broadcast = 1;
|
||||||
|
have_waiter = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_waiter) {
|
||||||
|
ReleaseSemaphore(win32_cond->semaphore, win32_cond->waiter_count, NULL);
|
||||||
|
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||||
|
WaitForSingleObject(win32_cond->waiters_done, INFINITE);
|
||||||
|
ResetEvent(win32_cond->waiters_done);
|
||||||
|
win32_cond->is_broadcast = 0;
|
||||||
|
} else
|
||||||
|
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||||
|
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static av_unused int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
win32_cond_t *win32_cond = cond->Ptr;
|
||||||
|
int last_waiter;
|
||||||
|
if (cond_wait) {
|
||||||
|
cond_wait(cond, mutex, INFINITE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* non native condition variables */
|
||||||
|
pthread_mutex_lock(&win32_cond->mtx_broadcast);
|
||||||
|
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
|
||||||
|
win32_cond->waiter_count++;
|
||||||
|
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||||
|
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
|
||||||
|
|
||||||
|
// unlock the external mutex
|
||||||
|
pthread_mutex_unlock(mutex);
|
||||||
|
WaitForSingleObject(win32_cond->semaphore, INFINITE);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
|
||||||
|
win32_cond->waiter_count--;
|
||||||
|
last_waiter = !win32_cond->waiter_count || !win32_cond->is_broadcast;
|
||||||
|
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||||
|
|
||||||
|
if (last_waiter)
|
||||||
|
SetEvent(win32_cond->waiters_done);
|
||||||
|
|
||||||
|
// lock the external mutex
|
||||||
|
return pthread_mutex_lock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static av_unused int pthread_cond_signal(pthread_cond_t *cond)
|
||||||
|
{
|
||||||
|
win32_cond_t *win32_cond = cond->Ptr;
|
||||||
|
int have_waiter;
|
||||||
|
if (cond_signal) {
|
||||||
|
cond_signal(cond);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&win32_cond->mtx_broadcast);
|
||||||
|
|
||||||
|
/* non-native condition variables */
|
||||||
|
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
|
||||||
|
have_waiter = win32_cond->waiter_count;
|
||||||
|
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||||
|
|
||||||
|
if (have_waiter) {
|
||||||
|
ReleaseSemaphore(win32_cond->semaphore, 1, NULL);
|
||||||
|
WaitForSingleObject(win32_cond->waiters_done, INFINITE);
|
||||||
|
ResetEvent(win32_cond->waiters_done);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static av_unused void w32thread_init(void)
|
||||||
|
{
|
||||||
|
#if _WIN32_WINNT < 0x0600
|
||||||
|
HANDLE kernel_dll = GetModuleHandle(TEXT("kernel32.dll"));
|
||||||
|
/* if one is available, then they should all be available */
|
||||||
|
cond_init =
|
||||||
|
(void*)GetProcAddress(kernel_dll, "InitializeConditionVariable");
|
||||||
|
cond_broadcast =
|
||||||
|
(void*)GetProcAddress(kernel_dll, "WakeAllConditionVariable");
|
||||||
|
cond_signal =
|
||||||
|
(void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
|
||||||
|
cond_wait =
|
||||||
|
(void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
|
||||||
|
initonce_begin =
|
||||||
|
(void*)GetProcAddress(kernel_dll, "InitOnceBeginInitialize");
|
||||||
|
initonce_complete =
|
||||||
|
(void*)GetProcAddress(kernel_dll, "InitOnceComplete");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* COMPAT_W32PTHREADS_H */
|
#endif /* COMPAT_W32PTHREADS_H */
|
||||||
|
|||||||
@@ -45,11 +45,7 @@ libname=$(mktemp -u "library").lib
|
|||||||
|
|
||||||
trap 'rm -f -- $libname' EXIT
|
trap 'rm -f -- $libname' EXIT
|
||||||
|
|
||||||
if [ -n "$AR" ]; then
|
lib -out:${libname} $@ >/dev/null
|
||||||
$AR rcs ${libname} $@ >/dev/null
|
|
||||||
else
|
|
||||||
lib.exe -out:${libname} $@ >/dev/null
|
|
||||||
fi
|
|
||||||
if [ $? != 0 ]; then
|
if [ $? != 0 ]; then
|
||||||
echo "Could not create temporary library." >&2
|
echo "Could not create temporary library." >&2
|
||||||
exit 1
|
exit 1
|
||||||
@@ -58,7 +54,23 @@ fi
|
|||||||
IFS='
|
IFS='
|
||||||
'
|
'
|
||||||
|
|
||||||
prefix="$EXTERN_PREFIX"
|
# Determine if we're building for x86 or x86_64 and
|
||||||
|
# set the symbol prefix accordingly.
|
||||||
|
prefix=""
|
||||||
|
arch=$(dumpbin -headers ${libname} |
|
||||||
|
tr '\t' ' ' |
|
||||||
|
grep '^ \+.\+machine \+(.\+)' |
|
||||||
|
head -1 |
|
||||||
|
sed -e 's/^ \{1,\}.\{1,\} \{1,\}machine \{1,\}(\(...\)).*/\1/')
|
||||||
|
|
||||||
|
if [ "${arch}" = "x86" ]; then
|
||||||
|
prefix="_"
|
||||||
|
else
|
||||||
|
if [ "${arch}" != "ARM" ] && [ "${arch}" != "x64" ]; then
|
||||||
|
echo "Unknown machine type." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
started=0
|
started=0
|
||||||
regex="none"
|
regex="none"
|
||||||
@@ -100,19 +112,7 @@ for line in $(cat ${vscript} | tr '\t' ' '); do
|
|||||||
'
|
'
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ -n "$NM" ]; then
|
dump=$(dumpbin -linkermember:1 ${libname})
|
||||||
# Use eval, since NM="nm -g"
|
|
||||||
dump=$(eval "$NM --defined-only -g ${libname}" |
|
|
||||||
grep -v : |
|
|
||||||
grep -v ^$ |
|
|
||||||
cut -d' ' -f3 |
|
|
||||||
sed -e "s/^${prefix}//")
|
|
||||||
else
|
|
||||||
dump=$(dumpbin.exe -linkermember:1 ${libname} |
|
|
||||||
sed -e '/public symbols/,$!d' -e '/^ \{1,\}Summary/,$d' -e "s/ \{1,\}${prefix}/ /" -e 's/ \{1,\}/ /g' |
|
|
||||||
tail -n +2 |
|
|
||||||
cut -d' ' -f3)
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm ${libname}
|
rm ${libname}
|
||||||
|
|
||||||
@@ -121,6 +121,9 @@ list=""
|
|||||||
for exp in ${regex}; do
|
for exp in ${regex}; do
|
||||||
list="${list}"'
|
list="${list}"'
|
||||||
'$(echo "${dump}" |
|
'$(echo "${dump}" |
|
||||||
|
sed -e '/public symbols/,$!d' -e '/^ \{1,\}Summary/,$d' -e "s/ \{1,\}${prefix}/ /" -e 's/ \{1,\}/ /g' |
|
||||||
|
tail -n +2 |
|
||||||
|
cut -d' ' -f3 |
|
||||||
grep "^${exp}" |
|
grep "^${exp}" |
|
||||||
sed -e 's/^/ /')
|
sed -e 's/^/ /')
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ LINK_EXE_PATH=$(dirname "$(command -v cl)")/link
|
|||||||
if [ -x "$LINK_EXE_PATH" ]; then
|
if [ -x "$LINK_EXE_PATH" ]; then
|
||||||
"$LINK_EXE_PATH" $@
|
"$LINK_EXE_PATH" $@
|
||||||
else
|
else
|
||||||
link.exe $@
|
link $@
|
||||||
fi
|
fi
|
||||||
exit $?
|
exit $?
|
||||||
|
|||||||
970
doc/APIchanges
970
doc/APIchanges
@@ -2,967 +2,19 @@ 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.
|
since the last major version increase or the API was added.
|
||||||
|
|
||||||
The last version increases were:
|
The last version increases were:
|
||||||
libavcodec: 2021-04-27
|
libavcodec: 2015-08-28
|
||||||
libavdevice: 2021-04-27
|
libavdevice: 2015-08-28
|
||||||
libavfilter: 2021-04-27
|
libavfilter: 2015-08-28
|
||||||
libavformat: 2021-04-27
|
libavformat: 2015-08-28
|
||||||
libpostproc: 2021-04-27
|
libavresample: 2015-08-28
|
||||||
libswresample: 2021-04-27
|
libpostproc: 2015-08-28
|
||||||
libswscale: 2021-04-27
|
libswresample: 2015-08-28
|
||||||
libavutil: 2021-04-27
|
libswscale: 2015-08-28
|
||||||
|
libavutil: 2015-08-28
|
||||||
|
|
||||||
|
|
||||||
API changes, most recent first:
|
API changes, most recent first:
|
||||||
|
|
||||||
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
|
|
||||||
Add FF_DECODE_ERROR_DECODE_SLICES
|
|
||||||
|
|
||||||
2019-06-14 - edfced8c04 - lavu 56.29.100 - frame.h
|
|
||||||
Add FF_DECODE_ERROR_CONCEALMENT_ACTIVE
|
|
||||||
|
|
||||||
2019-05-15 - b79b29ddb1 - lavu 56.28.100 - tx.h
|
|
||||||
Add av_tx_init(), av_tx_uninit() and related definitions.
|
|
||||||
|
|
||||||
2019-04-20 - 3153a6502a - lavc 58.52.100 - avcodec.h
|
|
||||||
Add AV_CODEC_FLAG_DROPCHANGED to allow avcodec_receive_frame to drop
|
|
||||||
frames whose parameters differ from first decoded frame in stream.
|
|
||||||
|
|
||||||
2019-04-12 - abfeba9724 - lavf 58.27.102
|
|
||||||
Rename hls,applehttp demuxer to hls
|
|
||||||
|
|
||||||
2019-01-27 - 5bcefceec8 - lavc 58.46.100 - avcodec.h
|
|
||||||
Add discard_damaged_percentage
|
|
||||||
|
|
||||||
2019-01-08 - 1ef4828276 - lavu 56.26.100 - frame.h
|
|
||||||
Add AV_FRAME_DATA_REGIONS_OF_INTEREST
|
|
||||||
|
|
||||||
2018-12-21 - 2744d6b364 - lavu 56.25.100 - hdr_dynamic_metadata.h
|
|
||||||
Add AV_FRAME_DATA_DYNAMIC_HDR_PLUS enum value, av_dynamic_hdr_plus_alloc(),
|
|
||||||
av_dynamic_hdr_plus_create_side_data() functions, and related structs.
|
|
||||||
|
|
||||||
-------- 8< --------- FFmpeg 4.1 was cut here -------- 8< ---------
|
|
||||||
|
|
||||||
2018-10-27 - 718044dc19 - lavu 56.21.100 - pixdesc.h
|
|
||||||
Add av_read_image_line2(), av_write_image_line2()
|
|
||||||
|
|
||||||
2018-10-24 - f9d4126f28 - lavu 56.20.100 - frame.h
|
|
||||||
Add AV_FRAME_DATA_S12M_TIMECODE
|
|
||||||
|
|
||||||
2018-10-11 - f6d48b618a - lavc 58.33.100 - mediacodec.h
|
|
||||||
Add av_mediacodec_render_buffer_at_time().
|
|
||||||
|
|
||||||
2018-09-09 - 35498c124a - lavc 58.29.100 - avcodec.h
|
|
||||||
Add AV_PKT_DATA_AFD
|
|
||||||
|
|
||||||
2018-08-16 - b33f5299a5 - lavc 58.23.100 - avcodec.h
|
|
||||||
Add av_bsf_flush().
|
|
||||||
|
|
||||||
2018-05-18 - 2b2f2f65f3 - lavf 58.15.100 - avformat.h
|
|
||||||
Add pmt_version field to AVProgram
|
|
||||||
|
|
||||||
2018-05-17 - 5dfeb7f081 - lavf 58.14.100 - avformat.h
|
|
||||||
Add AV_DISPOSITION_STILL_IMAGE
|
|
||||||
|
|
||||||
2018-05-10 - c855683427 - lavu 56.18.101 - hwcontext_cuda.h
|
|
||||||
Add AVCUDADeviceContext.stream.
|
|
||||||
|
|
||||||
2018-04-30 - 56b081da57 - lavu 56.18.100 - pixdesc.h
|
|
||||||
Add AV_PIX_FMT_FLAG_ALPHA to AV_PIX_FMT_PAL8.
|
|
||||||
|
|
||||||
2018-04-26 - 5be0410cb3 - lavu 56.17.100 - opt.h
|
|
||||||
Add AV_OPT_FLAG_DEPRECATED.
|
|
||||||
|
|
||||||
2018-04-26 - 71fa82bed6 - lavu 56.16.100 - threadmessage.h
|
|
||||||
Add av_thread_message_queue_nb_elems().
|
|
||||||
|
|
||||||
-------- 8< --------- FFmpeg 4.0 was cut here -------- 8< ---------
|
|
||||||
|
|
||||||
2018-04-03 - d6fc031caf - lavu 56.13.100 - pixdesc.h
|
|
||||||
Deprecate AV_PIX_FMT_FLAG_PSEUDOPAL and make allocating a pseudo palette
|
|
||||||
optional for API users (see AV_PIX_FMT_FLAG_PSEUDOPAL doxygen for details).
|
|
||||||
|
|
||||||
2018-04-01 - 860086ee16 - lavc 58.17.100 - avcodec.h
|
|
||||||
Add av_packet_make_refcounted().
|
|
||||||
|
|
||||||
2018-04-01 - f1805d160d - lavfi 7.14.100 - avfilter.h
|
|
||||||
Deprecate use of avfilter_register(), avfilter_register_all(),
|
|
||||||
avfilter_next(). Add av_filter_iterate().
|
|
||||||
|
|
||||||
2018-03-25 - b7d0d912ef - lavc 58.16.100 - avcodec.h
|
|
||||||
Add FF_SUB_CHARENC_MODE_IGNORE.
|
|
||||||
|
|
||||||
2018-03-23 - db2a7c947e - lavu 56.12.100 - encryption_info.h
|
|
||||||
Add AVEncryptionInitInfo and AVEncryptionInfo structures to hold new side-data
|
|
||||||
for encryption info.
|
|
||||||
|
|
||||||
2018-03-21 - f14ca60001 - lavc 58.15.100 - avcodec.h
|
|
||||||
Add av_packet_make_writable().
|
|
||||||
|
|
||||||
2018-03-18 - 4b86ac27a0 - lavu 56.11.100 - frame.h
|
|
||||||
Add AV_FRAME_DATA_QP_TABLE_PROPERTIES and AV_FRAME_DATA_QP_TABLE_DATA.
|
|
||||||
|
|
||||||
2018-03-15 - e0e72539cf - lavu 56.10.100 - opt.h
|
|
||||||
Add AV_OPT_FLAG_BSF_PARAM
|
|
||||||
|
|
||||||
2018-03-07 - 950170bd3b - lavu 56.9.100 - crc.h
|
|
||||||
Add AV_CRC_8_EBU crc variant.
|
|
||||||
|
|
||||||
2018-03-07 - 2a0eb86857 - lavc 58.14.100 - mediacodec.h
|
|
||||||
Change the default behavior of avcodec_flush() on mediacodec
|
|
||||||
video decoders. To restore the previous behavior, use the new
|
|
||||||
delay_flush=1 option.
|
|
||||||
|
|
||||||
2018-03-01 - 6731f60598 - lavu 56.8.100 - frame.h
|
|
||||||
Add av_frame_new_side_data_from_buf().
|
|
||||||
|
|
||||||
2018-02-15 - 8a8d0b319a
|
|
||||||
Change av_ripemd_update(), av_murmur3_update() and av_hash_update() length
|
|
||||||
parameter type to size_t at next major bump.
|
|
||||||
|
|
||||||
2018-02-12 - bcab11a1a2 - lavfi 7.12.100 - avfilter.h
|
|
||||||
Add AVFilterContext.extra_hw_frames.
|
|
||||||
|
|
||||||
2018-02-12 - d23fff0d8a - lavc 58.11.100 - avcodec.h
|
|
||||||
Add AVCodecContext.extra_hw_frames.
|
|
||||||
|
|
||||||
2018-02-06 - 0694d87024 - lavf 58.9.100 - avformat.h
|
|
||||||
Deprecate use of av_register_input_format(), av_register_output_format(),
|
|
||||||
av_register_all(), av_iformat_next(), av_oformat_next().
|
|
||||||
Add av_demuxer_iterate(), and av_muxer_iterate().
|
|
||||||
|
|
||||||
2018-02-06 - 36c85d6e77 - lavc 58.10.100 - avcodec.h
|
|
||||||
Deprecate use of avcodec_register(), avcodec_register_all(),
|
|
||||||
av_codec_next(), av_register_codec_parser(), and av_parser_next().
|
|
||||||
Add av_codec_iterate() and av_parser_iterate().
|
|
||||||
|
|
||||||
2018-02-04 - ff46124b0d - lavf 58.8.100 - avformat.h
|
|
||||||
Deprecate the current names of the RTSP "timeout", "stimeout", "user-agent"
|
|
||||||
options. Introduce "listen_timeout" as replacement for the current "timeout"
|
|
||||||
option, and "user_agent" as replacement for "user-agent". Once the deprecation
|
|
||||||
is over, the old "timeout" option will be removed, and "stimeout" will be
|
|
||||||
renamed to "stimeout" (the "timeout" option will essentially change semantics).
|
|
||||||
|
|
||||||
2018-01-28 - ea3672b7d6 - lavf 58.7.100 - avformat.h
|
|
||||||
Deprecate AVFormatContext filename field which had limited length, use the
|
|
||||||
new dynamically allocated url field instead.
|
|
||||||
|
|
||||||
2018-01-28 - ea3672b7d6 - lavf 58.7.100 - avformat.h
|
|
||||||
Add url field to AVFormatContext and add ff_format_set_url helper function.
|
|
||||||
|
|
||||||
2018-01-27 - 6194d7e564 - lavf 58.6.100 - avformat.h
|
|
||||||
Add AVFMTCTX_UNSEEKABLE (for HLS demuxer).
|
|
||||||
|
|
||||||
2018-01-23 - 9f07cf7c00 - lavu 56.9.100 - aes_ctr.h
|
|
||||||
Add method to set the 16-byte IV.
|
|
||||||
|
|
||||||
2018-01-16 - 631c56a8e4 - lavf 58.5.100 - avformat.h
|
|
||||||
Explicitly make avformat_network_init() and avformat_network_deinit() optional.
|
|
||||||
If these are not called, network initialization and deinitialization is
|
|
||||||
automatic, and unlike in older versions, fully supported, unless libavformat
|
|
||||||
is linked to ancient GnuTLS and OpenSSL.
|
|
||||||
|
|
||||||
2018-01-16 - 6512ff72f9 - lavf 58.4.100 - avformat.h
|
|
||||||
Deprecate AVStream.recommended_encoder_configuration. It was useful only for
|
|
||||||
FFserver, which has been removed.
|
|
||||||
|
|
||||||
2018-01-05 - 798dcf2432 - lavfi 7.11.101 - avfilter.h
|
|
||||||
Deprecate avfilter_link_get_channels(). Use av_buffersink_get_channels().
|
|
||||||
|
|
||||||
2017-01-04 - c29038f304 - lavr 4.0.0 - avresample.h
|
|
||||||
Deprecate the entire library. Merged years ago to provide compatibility
|
|
||||||
with Libav, it remained unmaintained by the FFmpeg project and duplicated
|
|
||||||
functionality provided by libswresample.
|
|
||||||
|
|
||||||
In order to improve consistency and reduce attack surface, it has been deprecated.
|
|
||||||
Users of this library are asked to migrate to libswresample, which, as well as
|
|
||||||
providing more functionality, is faster and has higher accuracy.
|
|
||||||
|
|
||||||
2017-12-26 - a04c2c707d - lavc 58.9.100 - avcodec.h
|
|
||||||
Deprecate av_lockmgr_register(). You need to build FFmpeg with threading
|
|
||||||
support enabled to get basic thread-safety (which is the default build
|
|
||||||
configuration).
|
|
||||||
|
|
||||||
2017-12-24 - 8b81eabe57 - lavu 56.7.100 - cpu.h
|
|
||||||
AVX-512 flags added.
|
|
||||||
|
|
||||||
2017-12-16 - 8bf4e6d3ce - lavc 58.8.100 - avcodec.h
|
|
||||||
The MediaCodec decoders now support AVCodecContext.hw_device_ctx.
|
|
||||||
|
|
||||||
2017-12-16 - e4d9f05ca7 - lavu 56.6.100 - hwcontext.h hwcontext_mediacodec.h
|
|
||||||
Add AV_HWDEVICE_TYPE_MEDIACODEC and a new installed header with
|
|
||||||
MediaCodec-specific hwcontext definitions.
|
|
||||||
|
|
||||||
2017-12-14 - b945fed629 - lavc 58.7.100 - avcodec.h
|
|
||||||
Add AV_CODEC_CAP_HARDWARE, AV_CODEC_CAP_HYBRID, and AVCodec.wrapper_name,
|
|
||||||
and mark all AVCodecs accordingly.
|
|
||||||
|
|
||||||
2017-11-29 - d268094f88 - lavu 56.4.100 / 56.7.0 - stereo3d.h
|
|
||||||
Add view field to AVStereo3D structure and AVStereo3DView enum.
|
|
||||||
|
|
||||||
2017-11-26 - 3a71bcc213 - lavc 58.6.100 - avcodec.h
|
|
||||||
Add const to AVCodecContext.hwaccel.
|
|
||||||
|
|
||||||
2017-11-26 - 3536a3efb9 - lavc 58.5.100 - avcodec.h
|
|
||||||
Deprecate user visibility of the AVHWAccel structure and the functions
|
|
||||||
av_register_hwaccel() and av_hwaccel_next().
|
|
||||||
|
|
||||||
2017-11-26 - 24cc0a53e9 - lavc 58.4.100 - avcodec.h
|
|
||||||
Add AVCodecHWConfig and avcodec_get_hw_config().
|
|
||||||
|
|
||||||
2017-11-22 - 3650cb2dfa - lavu 56.3.100 - opencl.h
|
|
||||||
Remove experimental OpenCL API (av_opencl_*).
|
|
||||||
|
|
||||||
2017-11-22 - b25d8ef0a7 - lavu 56.2.100 - hwcontext.h hwcontext_opencl.h
|
|
||||||
Add AV_HWDEVICE_TYPE_OPENCL and a new installed header with
|
|
||||||
OpenCL-specific hwcontext definitions.
|
|
||||||
|
|
||||||
2017-11-22 - a050f56c09 - lavu 56.1.100 - pixfmt.h
|
|
||||||
Add AV_PIX_FMT_OPENCL.
|
|
||||||
|
|
||||||
2017-11-11 - 48e4eda11d - lavc 58.3.100 - avcodec.h
|
|
||||||
Add avcodec_get_hw_frames_parameters().
|
|
||||||
|
|
||||||
-------- 8< --------- FFmpeg 3.4 was cut here -------- 8< ---------
|
|
||||||
|
|
||||||
2017-09-28 - b6cf66ae1c - lavc 57.106.104 - avcodec.h
|
|
||||||
Add AV_PKT_DATA_A53_CC packet side data, to export closed captions
|
|
||||||
|
|
||||||
2017-09-27 - 7aa6b8a68f - lavu 55.77.101 / lavu 55.31.1 - frame.h
|
|
||||||
Allow passing the value of 0 (meaning "automatic") as the required alignment
|
|
||||||
to av_frame_get_buffer().
|
|
||||||
|
|
||||||
2017-09-27 - 522f877086 - lavu 55.77.100 / lavu 55.31.0 - cpu.h
|
|
||||||
Add av_cpu_max_align() for querying maximum required data alignment.
|
|
||||||
|
|
||||||
2017-09-26 - b1cf151c4d - lavc 57.106.102 - avcodec.h
|
|
||||||
Deprecate AVCodecContext.refcounted_frames. This was useful for deprecated
|
|
||||||
API only (avcodec_decode_video2/avcodec_decode_audio4). The new decode APIs
|
|
||||||
(avcodec_send_packet/avcodec_receive_frame) always work with reference
|
|
||||||
counted frames.
|
|
||||||
|
|
||||||
2017-09-21 - 6f15f1cdc8 - lavu 55.76.100 / 56.6.0 - pixdesc.h
|
|
||||||
Add av_color_range_from_name(), av_color_primaries_from_name(),
|
|
||||||
av_color_transfer_from_name(), av_color_space_from_name(), and
|
|
||||||
av_chroma_location_from_name().
|
|
||||||
|
|
||||||
2017-09-13 - 82342cead1 - lavc 57.106.100 - avcodec.h
|
|
||||||
Add AV_PKT_FLAG_TRUSTED.
|
|
||||||
|
|
||||||
2017-09-13 - 9cb23cd9fe - lavu 55.75.100 - hwcontext.h hwcontext_drm.h
|
|
||||||
Add AV_HWDEVICE_TYPE_DRM and implementation.
|
|
||||||
|
|
||||||
2017-09-08 - 5ba2aef6ec - lavfi 6.103.100 - buffersrc.h
|
|
||||||
Add av_buffersrc_close().
|
|
||||||
|
|
||||||
2017-09-04 - 6cadbb16e9 - lavc 57.105.100 - avcodec.h
|
|
||||||
Add AV_HWACCEL_CODEC_CAP_EXPERIMENTAL, replacing the deprecated
|
|
||||||
HWACCEL_CODEC_CAP_EXPERIMENTAL flag.
|
|
||||||
|
|
||||||
2017-09-01 - 5d76674756 - lavf 57.81.100 - avio.h
|
|
||||||
Add avio_read_partial().
|
|
||||||
|
|
||||||
2017-09-01 - xxxxxxx - lavf 57.80.100 / 57.11.0 - avio.h
|
|
||||||
Add avio_context_free(). From now on it must be used for freeing AVIOContext.
|
|
||||||
|
|
||||||
2017-08-08 - 1460408703 - lavu 55.74.100 - pixdesc.h
|
|
||||||
Add AV_PIX_FMT_FLAG_FLOAT pixel format flag.
|
|
||||||
|
|
||||||
2017-08-08 - 463b81de2b - lavu 55.72.100 - imgutils.h
|
|
||||||
Add av_image_fill_black().
|
|
||||||
|
|
||||||
2017-08-08 - caa12027ba - lavu 55.71.100 - frame.h
|
|
||||||
Add av_frame_apply_cropping().
|
|
||||||
|
|
||||||
2017-07-25 - 24de4fddca - lavu 55.69.100 - frame.h
|
|
||||||
Add AV_FRAME_DATA_ICC_PROFILE side data type.
|
|
||||||
|
|
||||||
2017-06-27 - 70143a3954 - lavc 57.100.100 - avcodec.h
|
|
||||||
DXVA2 and D3D11 hardware accelerated decoding now supports the new hwaccel API,
|
|
||||||
which can create the decoder context and allocate hardware frame automatically.
|
|
||||||
See AVCodecContext.hw_device_ctx and AVCodecContext.hw_frames_ctx. For D3D11,
|
|
||||||
the new AV_PIX_FMT_D3D11 pixfmt must be used with the new API.
|
|
||||||
|
|
||||||
2017-06-27 - 3303511f33 - lavu 56.67.100 - hwcontext.h
|
|
||||||
Add AV_HWDEVICE_TYPE_D3D11VA and AV_PIX_FMT_D3D11.
|
|
||||||
|
|
||||||
2017-06-24 - 09891c5391 - lavf 57.75.100 - avio.h
|
|
||||||
Add AVIO_DATA_MARKER_FLUSH_POINT to signal preferred flush points to aviobuf.
|
|
||||||
|
|
||||||
2017-06-14 - d59c6a3aeb - lavu 55.66.100 - hwcontext.h
|
|
||||||
av_hwframe_ctx_create_derived() now takes some AV_HWFRAME_MAP_* combination
|
|
||||||
as its flags argument (which was previously unused).
|
|
||||||
|
|
||||||
2017-06-14 - 49ae8a5e87 - lavc 57.99.100 - avcodec.h
|
|
||||||
Add AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH.
|
|
||||||
|
|
||||||
2017-06-14 - 0b1794a43e - lavu 55.65.100 - hwcontext.h
|
|
||||||
Add AV_HWDEVICE_TYPE_NONE, av_hwdevice_find_type_by_name(),
|
|
||||||
av_hwdevice_get_type_name() and av_hwdevice_iterate_types().
|
|
||||||
|
|
||||||
2017-06-14 - b22172f6f3 - lavu 55.64.100 - hwcontext.h
|
|
||||||
Add av_hwdevice_ctx_create_derived().
|
|
||||||
|
|
||||||
2017-05-15 - 532b23f079 - lavc 57.96.100 - avcodec.h
|
|
||||||
VideoToolbox hardware-accelerated decoding now supports the new hwaccel API,
|
|
||||||
which can create the decoder context and allocate hardware frames automatically.
|
|
||||||
See AVCodecContext.hw_device_ctx and AVCodecContext.hw_frames_ctx.
|
|
||||||
|
|
||||||
2017-05-15 - 532b23f079 - lavu 57.63.100 - hwcontext.h
|
|
||||||
Add AV_HWDEVICE_TYPE_VIDEOTOOLBOX and implementation.
|
|
||||||
|
|
||||||
2017-05-08 - f089e02fa2 - lavc 57.95.100 / 57.31.0 - avcodec.h
|
|
||||||
Add AVCodecContext.apply_cropping to control whether cropping
|
|
||||||
is handled by libavcodec or the caller.
|
|
||||||
|
|
||||||
2017-05-08 - a47bd5d77e - lavu 55.62.100 / 55.30.0 - frame.h
|
|
||||||
Add AVFrame.crop_left/right/top/bottom fields for attaching cropping
|
|
||||||
information to video frames.
|
|
||||||
|
|
||||||
2017-xx-xx - xxxxxxxxxx
|
|
||||||
Change av_sha_update(), av_sha512_update() and av_md5_sum()/av_md5_update() length
|
|
||||||
parameter type to size_t at next major bump.
|
|
||||||
|
|
||||||
2017-05-05 - c0f17a905f - lavc 57.94.100 - avcodec.h
|
|
||||||
The cuvid decoders now support AVCodecContext.hw_device_ctx, which removes
|
|
||||||
the requirement to set an incomplete AVCodecContext.hw_frames_ctx only to
|
|
||||||
set the Cuda device handle.
|
|
||||||
|
|
||||||
2017-04-11 - 8378466507 - lavu 55.61.100 - avstring.h
|
|
||||||
Add av_strireplace().
|
|
||||||
|
|
||||||
2016-04-06 - 157e57a181 - lavc 57.92.100 - avcodec.h
|
|
||||||
Add AV_PKT_DATA_CONTENT_LIGHT_LEVEL packet side data.
|
|
||||||
|
|
||||||
2016-04-06 - b378f5bd64 - lavu 55.60.100 - mastering_display_metadata.h
|
|
||||||
Add AV_FRAME_DATA_CONTENT_LIGHT_LEVEL value, av_content_light_metadata_alloc()
|
|
||||||
and av_content_light_metadata_create_side_data() API, and AVContentLightMetadata
|
|
||||||
type to export content light level video properties.
|
|
||||||
|
|
||||||
2017-03-31 - 9033e8723c - lavu 55.57.100 - spherical.h
|
|
||||||
Add av_spherical_projection_name().
|
|
||||||
Add av_spherical_from_name().
|
|
||||||
|
|
||||||
2017-03-30 - 4cda23f1f1 - lavu 55.53.100 / 55.27.0 - hwcontext.h
|
|
||||||
Add av_hwframe_map() and associated AV_HWFRAME_MAP_* flags.
|
|
||||||
Add av_hwframe_ctx_create_derived().
|
|
||||||
|
|
||||||
2017-03-29 - bfdcdd6d82 - lavu 55.52.100 - avutil.h
|
|
||||||
add av_fourcc_make_string() function and av_fourcc2str() macro to replace
|
|
||||||
av_get_codec_tag_string() from lavc.
|
|
||||||
|
|
||||||
2017-03-27 - ddef3d902f - lavf 57.68.100 - avformat.h
|
|
||||||
Deprecate that demuxers export the stream rotation angle in AVStream.metadata
|
|
||||||
(via an entry named "rotate"). Use av_stream_get_side_data() with
|
|
||||||
AV_PKT_DATA_DISPLAYMATRIX instead, and read the rotation angle with
|
|
||||||
av_display_rotation_get(). The same is done for muxing. Instead of adding a
|
|
||||||
"rotate" entry to AVStream.metadata, AV_PKT_DATA_DISPLAYMATRIX side data has
|
|
||||||
to be added to the AVStream.
|
|
||||||
|
|
||||||
2017-03-23 - 7e4ba776a2 - lavc 57.85.101 - avcodec.h
|
|
||||||
vdpau hardware accelerated decoding now supports the new hwaccel API, which
|
|
||||||
can create the decoder context and allocate hardware frame automatically.
|
|
||||||
See AVCodecContext.hw_device_ctx and AVCodecContext.hw_frames_ctx.
|
|
||||||
|
|
||||||
2017-03-23 - 156bd8278f - lavc 57.85.100 - avcodec.h
|
|
||||||
Add AVCodecContext.hwaccel_flags field. This will control some hwaccels at
|
|
||||||
a later point.
|
|
||||||
|
|
||||||
2017-03-21 - fc9f14c7de - lavf 57.67.100 / 57.08.0 - avio.h
|
|
||||||
Add AVIO_SEEKABLE_TIME flag.
|
|
||||||
|
|
||||||
2017-03-21 - d682ae70b4 - lavf 57.66.105, lavc 57.83.101 - avformat.h, avcodec.h
|
|
||||||
Deprecate AVFMT_FLAG_KEEP_SIDE_DATA. It will be ignored after the next major
|
|
||||||
bump, and libavformat will behave as if it were always set.
|
|
||||||
Deprecate av_packet_merge_side_data() and av_packet_split_side_data().
|
|
||||||
|
|
||||||
2016-03-20 - 8200b16a9c - lavu 55.50.100 / 55.21.0 - imgutils.h
|
|
||||||
Add av_image_copy_uc_from(), a version of av_image_copy() for copying
|
|
||||||
from GPU mapped memory.
|
|
||||||
|
|
||||||
2017-03-20 - 9c2436e - lavu 55.49.100 - pixdesc.h
|
|
||||||
Add AV_PIX_FMT_FLAG_BAYER pixel format flag.
|
|
||||||
|
|
||||||
2017-03-18 - 3796fb2692 - lavfi 6.77.100 - avfilter.h
|
|
||||||
Deprecate AVFilterGraph.resample_lavr_opts
|
|
||||||
It's never been used by avfilter nor passed to anything.
|
|
||||||
|
|
||||||
2017-02-10 - 1b7ffddb3a - lavu 55.48.100 / 55.33.0 - spherical.h
|
|
||||||
Add AV_SPHERICAL_EQUIRECTANGULAR_TILE, av_spherical_tile_bounds(),
|
|
||||||
and projection-specific properties (bound_left, bound_top, bound_right,
|
|
||||||
bound_bottom, padding) to AVSphericalMapping.
|
|
||||||
|
|
||||||
2017-03-02 - ade7c1a232 - lavc 57.81.104 - videotoolbox.h
|
|
||||||
AVVideotoolboxContext.cv_pix_fmt_type can now be set to 0 to output the
|
|
||||||
native decoder format. (The default value is not changed.)
|
|
||||||
|
|
||||||
2017-03-02 - 554bc4eea8 - lavu 55.47.101, lavc 57.81.102, lavf 57.66.103
|
|
||||||
Remove requirement to use AVOption or accessors to access certain fields
|
|
||||||
in AVFrame, AVCodecContext, and AVFormatContext that were previously
|
|
||||||
documented as "no direct access" allowed.
|
|
||||||
|
|
||||||
2017-02-13 - c1a5fca06f - lavc 57.80.100 - avcodec.h
|
|
||||||
Add AVCodecContext.hw_device_ctx.
|
|
||||||
|
|
||||||
2017-02-11 - e3af49b14b - lavu 55.47.100 - frame.h
|
|
||||||
Add AVFrame.opaque_ref.
|
|
||||||
|
|
||||||
2017-01-31 - 2eab48177d - lavu 55.46.100 / 55.20.0 - cpu.h
|
|
||||||
Add AV_CPU_FLAG_SSSE3SLOW.
|
|
||||||
|
|
||||||
2017-01-24 - c4618f842a - lavu 55.45.100 - channel_layout.h
|
|
||||||
Add av_get_extended_channel_layout()
|
|
||||||
|
|
||||||
2017-01-22 - 76c5a69e26 - lavu 55.44.100 - lfg.h
|
|
||||||
Add av_lfg_init_from_data().
|
|
||||||
|
|
||||||
2017-01-17 - 2a4a8653b6 - lavc 57.74.100 - vaapi.h
|
|
||||||
Deprecate struct vaapi_context and the vaapi.h installed header.
|
|
||||||
Callers should set AVCodecContext.hw_frames_ctx instead.
|
|
||||||
|
|
||||||
2017-01-12 - dbe9dbed31 - lavfi 6.69.100 - buffersink.h
|
|
||||||
Add av_buffersink_get_*() functions.
|
|
||||||
|
|
||||||
2017-01-06 - 9488032e10 - lavf 57.62.100 - avio.h
|
|
||||||
Add avio_get_dyn_buf()
|
|
||||||
|
|
||||||
2016-12-10 - f542b152aa - lavu 55.43.100 - imgutils.h
|
|
||||||
Add av_image_check_size2()
|
|
||||||
|
|
||||||
2016-12-07 - e7a6f8c972 - lavc 57.67.100 / 57.29.0 - avcodec.h
|
|
||||||
Add AV_PKT_DATA_SPHERICAL packet side data to export AVSphericalMapping
|
|
||||||
information from containers.
|
|
||||||
|
|
||||||
2016-12-07 - 8f58ecc344 - lavu 55.42.100 / 55.30.0 - spherical.h
|
|
||||||
Add AV_FRAME_DATA_SPHERICAL value, av_spherical_alloc() API and
|
|
||||||
AVSphericalMapping type to export and describe spherical video properties.
|
|
||||||
|
|
||||||
2016-11-18 - 2ab50647ff - lavf 57.58.100 - avformat.h
|
|
||||||
Add av_stream_add_side_data().
|
|
||||||
|
|
||||||
2016-11-13 - 775a8477b7 - lavu 55.39.100 - hwcontext_vaapi.h
|
|
||||||
Add AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE.
|
|
||||||
|
|
||||||
2016-11-13 - a8d51bb424 - lavu 55.38.100 - hwcontext_vaapi.h
|
|
||||||
Add driver quirks field to VAAPI-specific hwdevice and enum with
|
|
||||||
members AV_VAAPI_DRIVER_QUIRK_* to represent its values.
|
|
||||||
|
|
||||||
2016-11-10 - 638b216d4f - lavu 55.36.100 - pixfmt.h
|
|
||||||
Add AV_PIX_FMT_GRAY12(LE/BE).
|
|
||||||
|
|
||||||
-------- 8< --------- FFmpeg 3.2 was cut here -------- 8< ---------
|
|
||||||
|
|
||||||
2016-10-24 - 73ead47 - lavf 57.55.100 - avformat.h
|
|
||||||
Add AV_DISPOSITION_TIMED_THUMBNAILS
|
|
||||||
|
|
||||||
2016-10-24 - a246fef - lavf 57.54.100 - avformat.h
|
|
||||||
Add avformat_init_output() and AVSTREAM_INIT_IN_ macros
|
|
||||||
|
|
||||||
2016-10-22 - f5495c9 - lavu 55.33.100 - avassert.h
|
|
||||||
Add av_assert0_fpu() / av_assert2_fpu()
|
|
||||||
|
|
||||||
2016-10-07 - 3f9137c / 32c8359 - lavc 57.61.100 / 57.24.0 - avcodec.h
|
|
||||||
Decoders now export the frame timestamp as AVFrame.pts. It was
|
|
||||||
previously exported as AVFrame.pkt_pts, which is now deprecated.
|
|
||||||
|
|
||||||
Note: When decoding, AVFrame.pts uses the stream/packet timebase,
|
|
||||||
and not the codec timebase.
|
|
||||||
|
|
||||||
2016-09-28 - eba0414 - lavu 55.32.100 / 55.16.0 - hwcontext.h hwcontext_qsv.h
|
|
||||||
Add AV_HWDEVICE_TYPE_QSV and a new installed header with QSV-specific
|
|
||||||
hwcontext definitions.
|
|
||||||
|
|
||||||
2016-09-26 - 32c25f0 - lavc 57.59.100 / 57.23.0 - avcodec.h
|
|
||||||
AVCodecContext.hw_frames_ctx now may be used by decoders.
|
|
||||||
|
|
||||||
2016-09-27 - f0b6f72 - lavf 57.51.100 - avformat.h
|
|
||||||
Add av_stream_get_codec_timebase()
|
|
||||||
|
|
||||||
2016-09-27 - 23c0779 - lswr 2.2.100 - swresample.h
|
|
||||||
Add swr_build_matrix().
|
|
||||||
|
|
||||||
2016-09-23 - 30d3e36 - lavc 57.58.100 - avcodec.h
|
|
||||||
Add AV_CODEC_CAP_AVOID_PROBING codec capability flag.
|
|
||||||
|
|
||||||
2016-09-14 - ae1dd0c - lavf 57.49.100 - avformat.h
|
|
||||||
Add avformat_transfer_internal_stream_timing_info helper to help with stream
|
|
||||||
copy.
|
|
||||||
|
|
||||||
2016-08-29 - 4493390 - lavfi 6.58.100 - avfilter.h
|
|
||||||
Add AVFilterContext.nb_threads.
|
|
||||||
|
|
||||||
2016-08-15 - c3c4c72 - lavc 57.53.100 - avcodec.h
|
|
||||||
Add trailing_padding to AVCodecContext to match the corresponding
|
|
||||||
field in AVCodecParameters.
|
|
||||||
|
|
||||||
2016-08-15 - b746ed7 - lavc 57.52.100 - avcodec.h
|
|
||||||
Add a new API for chained BSF filters and passthrough (null) BSF --
|
|
||||||
av_bsf_list_alloc(), av_bsf_list_free(), av_bsf_list_append(),
|
|
||||||
av_bsf_list_append2(), av_bsf_list_finalize(), av_bsf_list_parse_str()
|
|
||||||
and av_bsf_get_null_filter().
|
|
||||||
|
|
||||||
2016-08-04 - 82a33c8 - lavf 57.46.100 - avformat.h
|
|
||||||
Add av_get_frame_filename2()
|
|
||||||
|
|
||||||
2016-07-09 - 775389f / 90f469a - lavc 57.50.100 / 57.20.0 - avcodec.h
|
|
||||||
Add FF_PROFILE_H264_MULTIVIEW_HIGH and FF_PROFILE_H264_STEREO_HIGH.
|
|
||||||
|
|
||||||
2016-06-30 - c1c7e0ab - lavf 57.41.100 - avformat.h
|
|
||||||
Moved codecpar field from AVStream to the end of the struct, so that
|
|
||||||
the following private fields are in the same location as in FFmpeg 3.0 (lavf 57.25.100).
|
|
||||||
|
|
||||||
2016-06-30 - 042fb69d - lavu 55.28.100 - frame.h
|
|
||||||
Moved hw_frames_ctx field from AVFrame to the end of the struct, so that
|
|
||||||
the following private fields are in the same location as in FFmpeg 3.0 (lavu 55.17.103).
|
|
||||||
|
|
||||||
2016-06-29 - 1a751455 - lavfi 6.47.100 - avfilter.h
|
|
||||||
Fix accidental ABI breakage in AVFilterContext.
|
|
||||||
ABI was broken in 8688d3a, lavfi 6.42.100 and released as ffmpeg 3.1.
|
|
||||||
|
|
||||||
Because of this, ffmpeg and ffplay built against lavfi>=6.42.100 will not be
|
|
||||||
compatible with lavfi>=6.47.100. Potentially also affects other users of
|
|
||||||
libavfilter if they are using one of the affected fields.
|
|
||||||
|
|
||||||
-------- 8< --------- FFmpeg 3.1 was cut here -------- 8< ---------
|
-------- 8< --------- FFmpeg 3.1 was cut here -------- 8< ---------
|
||||||
|
|
||||||
2016-06-26 - 481f320 / 1c9e861 - lavu 55.27.100 / 55.13.0 - hwcontext.h
|
2016-06-26 - 481f320 / 1c9e861 - lavu 55.27.100 / 55.13.0 - hwcontext.h
|
||||||
@@ -1390,7 +442,7 @@ API changes, most recent first:
|
|||||||
Add av_opt_get_dict_val/set_dict_val with AV_OPT_TYPE_DICT to support
|
Add av_opt_get_dict_val/set_dict_val with AV_OPT_TYPE_DICT to support
|
||||||
dictionary types being set as options.
|
dictionary types being set as options.
|
||||||
|
|
||||||
2014-08-13 - afbd4b7e09 - lavf 56.01.0 - avformat.h
|
2014-08-13 - afbd4b8 - lavf 56.01.0 - avformat.h
|
||||||
Add AVFormatContext.event_flags and AVStream.event_flags for signaling to
|
Add AVFormatContext.event_flags and AVStream.event_flags for signaling to
|
||||||
the user when events happen in the file/stream.
|
the user when events happen in the file/stream.
|
||||||
|
|
||||||
@@ -1407,7 +459,7 @@ API changes, most recent first:
|
|||||||
2014-08-08 - 5c3c671 - lavf 55.53.100 - avio.h
|
2014-08-08 - 5c3c671 - lavf 55.53.100 - avio.h
|
||||||
Add avio_feof() and deprecate url_feof().
|
Add avio_feof() and deprecate url_feof().
|
||||||
|
|
||||||
2014-08-07 - bb789016d4 - lsws 2.1.3 - swscale.h
|
2014-08-07 - bb78903 - lsws 2.1.3 - swscale.h
|
||||||
sws_getContext is not going to be removed in the future.
|
sws_getContext is not going to be removed in the future.
|
||||||
|
|
||||||
2014-08-07 - a561662 / ad1ee5f - lavc 55.73.101 / 55.57.3 - avcodec.h
|
2014-08-07 - a561662 / ad1ee5f - lavc 55.73.101 / 55.57.3 - avcodec.h
|
||||||
|
|||||||
2422
doc/Doxyfile
2422
doc/Doxyfile
File diff suppressed because it is too large
Load Diff
41
doc/Makefile
41
doc/Makefile
@@ -24,7 +24,6 @@ HTMLPAGES = $(AVPROGS-yes:%=doc/%.html) $(AVPROGS-yes:%=doc/%-all.html) $(COMP
|
|||||||
doc/fate.html \
|
doc/fate.html \
|
||||||
doc/general.html \
|
doc/general.html \
|
||||||
doc/git-howto.html \
|
doc/git-howto.html \
|
||||||
doc/mailing-list-faq.html \
|
|
||||||
doc/nut.html \
|
doc/nut.html \
|
||||||
doc/platform.html \
|
doc/platform.html \
|
||||||
|
|
||||||
@@ -37,6 +36,30 @@ DOCS-$(CONFIG_MANPAGES) += $(MANPAGES)
|
|||||||
DOCS-$(CONFIG_TXTPAGES) += $(TXTPAGES)
|
DOCS-$(CONFIG_TXTPAGES) += $(TXTPAGES)
|
||||||
DOCS = $(DOCS-yes)
|
DOCS = $(DOCS-yes)
|
||||||
|
|
||||||
|
DOC_EXAMPLES-$(CONFIG_AVIO_DIR_CMD_EXAMPLE) += avio_dir_cmd
|
||||||
|
DOC_EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading
|
||||||
|
DOC_EXAMPLES-$(CONFIG_AVCODEC_EXAMPLE) += avcodec
|
||||||
|
DOC_EXAMPLES-$(CONFIG_DECODING_ENCODING_EXAMPLE) += decoding_encoding
|
||||||
|
DOC_EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
|
||||||
|
DOC_EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE) += extract_mvs
|
||||||
|
DOC_EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio
|
||||||
|
DOC_EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE) += filtering_audio
|
||||||
|
DOC_EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE) += filtering_video
|
||||||
|
DOC_EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata
|
||||||
|
DOC_EXAMPLES-$(CONFIG_MUXING_EXAMPLE) += muxing
|
||||||
|
DOC_EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec
|
||||||
|
DOC_EXAMPLES-$(CONFIG_REMUXING_EXAMPLE) += remuxing
|
||||||
|
DOC_EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio
|
||||||
|
DOC_EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
|
||||||
|
DOC_EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
|
||||||
|
DOC_EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE) += transcoding
|
||||||
|
ALL_DOC_EXAMPLES_LIST = $(DOC_EXAMPLES-) $(DOC_EXAMPLES-yes)
|
||||||
|
|
||||||
|
DOC_EXAMPLES := $(DOC_EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
|
||||||
|
ALL_DOC_EXAMPLES := $(ALL_DOC_EXAMPLES_LIST:%=doc/examples/%$(PROGSSUF)$(EXESUF))
|
||||||
|
ALL_DOC_EXAMPLES_G := $(ALL_DOC_EXAMPLES_LIST:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
|
||||||
|
PROGS += $(DOC_EXAMPLES)
|
||||||
|
|
||||||
all-$(CONFIG_DOC): doc
|
all-$(CONFIG_DOC): doc
|
||||||
|
|
||||||
doc: documentation
|
doc: documentation
|
||||||
@@ -44,6 +67,8 @@ doc: documentation
|
|||||||
apidoc: doc/doxy/html
|
apidoc: doc/doxy/html
|
||||||
documentation: $(DOCS)
|
documentation: $(DOCS)
|
||||||
|
|
||||||
|
examples: $(DOC_EXAMPLES)
|
||||||
|
|
||||||
TEXIDEP = perl $(SRC_PATH)/doc/texidep.pl $(SRC_PATH) $< $@ >$(@:%=%.d)
|
TEXIDEP = perl $(SRC_PATH)/doc/texidep.pl $(SRC_PATH) $< $@ >$(@:%=%.d)
|
||||||
|
|
||||||
doc/%.txt: TAG = TXT
|
doc/%.txt: TAG = TXT
|
||||||
@@ -96,13 +121,15 @@ doc/%.3: doc/%.pod $(GENTEXI)
|
|||||||
$(M)pod2man --section=3 --center=" " --release=" " --date=" " $< > $@
|
$(M)pod2man --section=3 --center=" " --release=" " --date=" " $< > $@
|
||||||
|
|
||||||
$(DOCS) doc/doxy/html: | doc/
|
$(DOCS) doc/doxy/html: | doc/
|
||||||
|
$(DOC_EXAMPLES:%$(EXESUF)=%.o): | doc/examples
|
||||||
|
OBJDIRS += doc/examples
|
||||||
|
|
||||||
DOXY_INPUT = $(INSTHEADERS)
|
DOXY_INPUT = $(INSTHEADERS) $(DOC_EXAMPLES:%$(EXESUF)=%.c) $(LIB_EXAMPLES:%$(EXESUF)=%.c)
|
||||||
DOXY_INPUT_DEPS = $(addprefix $(SRC_PATH)/, $(DOXY_INPUT)) ffbuild/config.mak
|
DOXY_INPUT_DEPS = $(addprefix $(SRC_PATH)/, $(DOXY_INPUT))
|
||||||
|
|
||||||
doc/doxy/html: TAG = DOXY
|
doc/doxy/html: TAG = DOXY
|
||||||
doc/doxy/html: $(SRC_PATH)/doc/Doxyfile $(SRC_PATH)/doc/doxy-wrapper.sh $(DOXY_INPUT_DEPS)
|
doc/doxy/html: $(SRC_PATH)/doc/Doxyfile $(SRC_PATH)/doc/doxy-wrapper.sh $(DOXY_INPUT_DEPS)
|
||||||
$(M)$(SRC_PATH)/doc/doxy-wrapper.sh $$PWD/doc/doxy $(SRC_PATH) doc/Doxyfile $(DOXYGEN) $(DOXY_INPUT);
|
$(M)OUT_DIR=$$PWD/doc/doxy; cd $(SRC_PATH); ./doc/doxy-wrapper.sh $$OUT_DIR $< $(DOXYGEN) $(DOXY_INPUT);
|
||||||
|
|
||||||
install-doc: install-html install-man
|
install-doc: install-html install-man
|
||||||
|
|
||||||
@@ -144,7 +171,11 @@ clean:: docclean
|
|||||||
distclean:: docclean
|
distclean:: docclean
|
||||||
$(RM) doc/config.texi
|
$(RM) doc/config.texi
|
||||||
|
|
||||||
docclean::
|
examplesclean:
|
||||||
|
$(RM) $(ALL_DOC_EXAMPLES) $(ALL_DOC_EXAMPLES_G)
|
||||||
|
$(RM) $(CLEANSUFFIXES:%=doc/examples/%)
|
||||||
|
|
||||||
|
docclean: examplesclean
|
||||||
$(RM) $(CLEANSUFFIXES:%=doc/%)
|
$(RM) $(CLEANSUFFIXES:%=doc/%)
|
||||||
$(RM) $(TXTPAGES) doc/*.html doc/*.pod doc/*.1 doc/*.3 doc/avoptions_*.texi
|
$(RM) $(TXTPAGES) doc/*.html doc/*.pod doc/*.1 doc/*.3 doc/avoptions_*.texi
|
||||||
$(RM) -r doc/doxy/html
|
$(RM) -r doc/doxy/html
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ comma-separated list of filters, whose parameters follow the filter
|
|||||||
name after a '='.
|
name after a '='.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
ffmpeg -i INPUT -c:v copy -bsf:v filter1[=opt1=str1:opt2=str2][,filter2] OUTPUT
|
ffmpeg -i INPUT -c:v copy -bsf:v filter1[=opt1=str1/opt2=str2][,filter2] OUTPUT
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Below is a description of the currently available bitstream filters,
|
Below is a description of the currently available bitstream filters,
|
||||||
@@ -26,101 +26,36 @@ with their parameters, if any.
|
|||||||
|
|
||||||
@section aac_adtstoasc
|
@section aac_adtstoasc
|
||||||
|
|
||||||
Convert MPEG-2/4 AAC ADTS to an MPEG-4 Audio Specific Configuration
|
Convert MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration
|
||||||
bitstream.
|
bitstream filter.
|
||||||
|
|
||||||
This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4
|
This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4
|
||||||
ADTS header and removes the ADTS header.
|
ADTS header and removes the ADTS header.
|
||||||
|
|
||||||
This filter is required for example when copying an AAC stream from a
|
This is required for example when copying an AAC stream from a raw
|
||||||
raw ADTS AAC or an MPEG-TS container to MP4A-LATM, to an FLV file, or
|
ADTS AAC container to a FLV or a MOV/MP4 file.
|
||||||
to MOV/MP4 files and related formats such as 3GP or M4A. Please note
|
|
||||||
that it is auto-inserted for MP4A-LATM and MOV/MP4 and related formats.
|
|
||||||
|
|
||||||
@section av1_metadata
|
|
||||||
|
|
||||||
Modify metadata embedded in an AV1 stream.
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item td
|
|
||||||
Insert or remove temporal delimiter OBUs in all temporal units of the
|
|
||||||
stream.
|
|
||||||
|
|
||||||
@table @samp
|
|
||||||
@item insert
|
|
||||||
Insert a TD at the beginning of every TU which does not already have one.
|
|
||||||
@item remove
|
|
||||||
Remove the TD from the beginning of every TU which has one.
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@item color_primaries
|
|
||||||
@item transfer_characteristics
|
|
||||||
@item matrix_coefficients
|
|
||||||
Set the color description fields in the stream (see AV1 section 6.4.2).
|
|
||||||
|
|
||||||
@item color_range
|
|
||||||
Set the color range in the stream (see AV1 section 6.4.2; note that
|
|
||||||
this cannot be set for streams using BT.709 primaries, sRGB transfer
|
|
||||||
characteristic and identity (RGB) matrix coefficients).
|
|
||||||
@table @samp
|
|
||||||
@item tv
|
|
||||||
Limited range.
|
|
||||||
@item pc
|
|
||||||
Full range.
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@item chroma_sample_position
|
|
||||||
Set the chroma sample location in the stream (see AV1 section 6.4.2).
|
|
||||||
This can only be set for 4:2:0 streams.
|
|
||||||
|
|
||||||
@table @samp
|
|
||||||
@item vertical
|
|
||||||
Left position (matching the default in MPEG-2 and H.264).
|
|
||||||
@item colocated
|
|
||||||
Top-left position.
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@item tick_rate
|
|
||||||
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
|
|
||||||
has a fixed framerate. Ignored if @option{tick_rate} is not also set.
|
|
||||||
|
|
||||||
@item delete_padding
|
|
||||||
Deletes Padding OBUs.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section chomp
|
@section chomp
|
||||||
|
|
||||||
Remove zero padding at the end of a packet.
|
Remove zero padding at the end of a packet.
|
||||||
|
|
||||||
@section dca_core
|
|
||||||
|
|
||||||
Extract the core from a DCA/DTS stream, dropping extensions such as
|
|
||||||
DTS-HD.
|
|
||||||
|
|
||||||
@section dump_extra
|
@section dump_extra
|
||||||
|
|
||||||
Add extradata to the beginning of the filtered packets except when
|
Add extradata to the beginning of the filtered packets.
|
||||||
said packets already exactly begin with the extradata that is intended
|
|
||||||
to be added.
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item freq
|
|
||||||
The additional argument specifies which packets should be filtered.
|
The additional argument specifies which packets should be filtered.
|
||||||
It accepts the values:
|
It accepts the values:
|
||||||
@table @samp
|
@table @samp
|
||||||
|
@item a
|
||||||
|
add extradata to all key packets, but only if @var{local_header} is
|
||||||
|
set in the @option{flags2} codec context field
|
||||||
|
|
||||||
@item k
|
@item k
|
||||||
@item keyframe
|
|
||||||
add extradata to all key packets
|
add extradata to all key packets
|
||||||
|
|
||||||
@item e
|
@item e
|
||||||
@item all
|
|
||||||
add extradata to all packets
|
add extradata to all packets
|
||||||
@end table
|
@end table
|
||||||
@end table
|
|
||||||
|
|
||||||
If not specified it is assumed @samp{k}.
|
If not specified it is assumed @samp{k}.
|
||||||
|
|
||||||
@@ -132,165 +67,9 @@ 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
|
ffmpeg -i INPUT -map 0 -flags:v +global_header -c:v libx264 -bsf:v dump_extra out.ts
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@section eac3_core
|
@section dca_core
|
||||||
|
|
||||||
Extract the core from a E-AC-3 stream, dropping extra channels.
|
Extract DCA core from DTS-HD streams.
|
||||||
|
|
||||||
@section extract_extradata
|
|
||||||
|
|
||||||
Extract the in-band extradata.
|
|
||||||
|
|
||||||
Certain codecs allow the long-term headers (e.g. MPEG-2 sequence headers,
|
|
||||||
or H.264/HEVC (VPS/)SPS/PPS) to be transmitted either "in-band" (i.e. as a part
|
|
||||||
of the bitstream containing the coded frames) or "out of band" (e.g. on the
|
|
||||||
container level). This latter form is called "extradata" in FFmpeg terminology.
|
|
||||||
|
|
||||||
This bitstream filter detects the in-band headers and makes them available as
|
|
||||||
extradata.
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item remove
|
|
||||||
When this option is enabled, the long-term headers are removed from the
|
|
||||||
bitstream after extraction.
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section filter_units
|
|
||||||
|
|
||||||
Remove units with types in or not in a given set from the stream.
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item pass_types
|
|
||||||
List of unit types or ranges of unit types to pass through while removing
|
|
||||||
all others. This is specified as a '|'-separated list of unit type values
|
|
||||||
or ranges of values with '-'.
|
|
||||||
|
|
||||||
@item remove_types
|
|
||||||
Identical to @option{pass_types}, except the units in the given set
|
|
||||||
removed and all others passed through.
|
|
||||||
@end table
|
|
||||||
|
|
||||||
Extradata is unchanged by this transformation, but note that if the stream
|
|
||||||
contains inline parameter sets then the output may be unusable if they are
|
|
||||||
removed.
|
|
||||||
|
|
||||||
For example, to remove all non-VCL NAL units from an H.264 stream:
|
|
||||||
@example
|
|
||||||
ffmpeg -i INPUT -c:v copy -bsf:v 'filter_units=pass_types=1-5' OUTPUT
|
|
||||||
@end example
|
|
||||||
|
|
||||||
To remove all AUDs, SEI and filler from an H.265 stream:
|
|
||||||
@example
|
|
||||||
ffmpeg -i INPUT -c:v copy -bsf:v 'filter_units=remove_types=35|38-40' OUTPUT
|
|
||||||
@end example
|
|
||||||
|
|
||||||
@section hapqa_extract
|
|
||||||
|
|
||||||
Extract Rgb or Alpha part of an HAPQA file, without recompression, in order to create an HAPQ or an HAPAlphaOnly file.
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item texture
|
|
||||||
Specifies the texture to keep.
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item color
|
|
||||||
@item alpha
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
Convert HAPQA to HAPQ
|
|
||||||
@example
|
|
||||||
ffmpeg -i hapqa_inputfile.mov -c copy -bsf:v hapqa_extract=texture=color -tag:v HapY -metadata:s:v:0 encoder="HAPQ" hapq_file.mov
|
|
||||||
@end example
|
|
||||||
|
|
||||||
Convert HAPQA to HAPAlphaOnly
|
|
||||||
@example
|
|
||||||
ffmpeg -i hapqa_inputfile.mov -c copy -bsf:v hapqa_extract=texture=alpha -tag:v HapA -metadata:s:v:0 encoder="HAPAlpha Only" hapalphaonly_file.mov
|
|
||||||
@end example
|
|
||||||
|
|
||||||
@section h264_metadata
|
|
||||||
|
|
||||||
Modify metadata embedded in an H.264 stream.
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item aud
|
|
||||||
Insert or remove AUD NAL units in all access units of the stream.
|
|
||||||
|
|
||||||
@table @samp
|
|
||||||
@item insert
|
|
||||||
@item remove
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@item sample_aspect_ratio
|
|
||||||
Set the sample aspect ratio of the stream in the VUI parameters.
|
|
||||||
|
|
||||||
@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
|
|
||||||
Set the video format in the stream (see H.264 section E.2.1 and
|
|
||||||
table E-2).
|
|
||||||
|
|
||||||
@item colour_primaries
|
|
||||||
@item transfer_characteristics
|
|
||||||
@item matrix_coefficients
|
|
||||||
Set the colour description in the stream (see H.264 section E.2.1
|
|
||||||
and tables E-3, E-4 and E-5).
|
|
||||||
|
|
||||||
@item chroma_sample_loc_type
|
|
||||||
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 (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).
|
|
||||||
@item fixed_frame_rate_flag
|
|
||||||
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
|
|
||||||
@item crop_top
|
|
||||||
@item crop_bottom
|
|
||||||
Set the frame cropping offsets in the SPS. These values will replace
|
|
||||||
the current ones if the stream is already cropped.
|
|
||||||
|
|
||||||
These fields are set in pixels. Note that some sizes may not be
|
|
||||||
representable if the chroma is subsampled or the stream is interlaced
|
|
||||||
(see H.264 section 7.4.2.1.1).
|
|
||||||
|
|
||||||
@item sei_user_data
|
|
||||||
Insert a string as SEI unregistered user data. The argument must
|
|
||||||
be of the form @emph{UUID+string}, where the UUID is as hex digits
|
|
||||||
possibly separated by hyphens, and the string can be anything.
|
|
||||||
|
|
||||||
For example, @samp{086f3693-b7b3-4f2c-9653-21492feee5b8+hello} will
|
|
||||||
insert the string ``hello'' associated with the given UUID.
|
|
||||||
|
|
||||||
@item delete_filler
|
|
||||||
Deletes both filler NAL units and filler SEI messages.
|
|
||||||
|
|
||||||
@item level
|
|
||||||
Set the level in the SPS. Refer to H.264 section A.3 and tables A-1
|
|
||||||
to A-5.
|
|
||||||
|
|
||||||
The argument must be the name of a level (for example, @samp{4.2}), a
|
|
||||||
level_idc value (for example, @samp{42}), or the special name @samp{auto}
|
|
||||||
indicating that the filter should attempt to guess the level from the
|
|
||||||
input stream properties.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section h264_mp4toannexb
|
@section h264_mp4toannexb
|
||||||
|
|
||||||
@@ -299,7 +78,7 @@ prefixed mode (as defined in the Annex B of the ITU-T H.264
|
|||||||
specification).
|
specification).
|
||||||
|
|
||||||
This is required by some streaming formats, typically the MPEG-2
|
This is required by some streaming formats, typically the MPEG-2
|
||||||
transport stream format (muxer @code{mpegts}).
|
transport stream format ("mpegts").
|
||||||
|
|
||||||
For example to remux an MP4 file containing an H.264 stream to mpegts
|
For example to remux an MP4 file containing an H.264 stream to mpegts
|
||||||
format with @command{ffmpeg}, you can use the command:
|
format with @command{ffmpeg}, you can use the command:
|
||||||
@@ -308,101 +87,6 @@ format with @command{ffmpeg}, you can use the command:
|
|||||||
ffmpeg -i INPUT.mp4 -codec copy -bsf:v h264_mp4toannexb OUTPUT.ts
|
ffmpeg -i INPUT.mp4 -codec copy -bsf:v h264_mp4toannexb OUTPUT.ts
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Please note that this filter is auto-inserted for MPEG-TS (muxer
|
|
||||||
@code{mpegts}) and raw H.264 (muxer @code{h264}) output formats.
|
|
||||||
|
|
||||||
@section h264_redundant_pps
|
|
||||||
|
|
||||||
This applies a specific fixup to some Blu-ray streams which contain
|
|
||||||
redundant PPSs modifying irrelevant parameters of the stream which
|
|
||||||
confuse other transformations which require correct extradata.
|
|
||||||
|
|
||||||
A new single global PPS is created, and all of the redundant PPSs
|
|
||||||
within the stream are removed.
|
|
||||||
|
|
||||||
@section hevc_metadata
|
|
||||||
|
|
||||||
Modify metadata embedded in an HEVC stream.
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item aud
|
|
||||||
Insert or remove AUD NAL units in all access units of the stream.
|
|
||||||
|
|
||||||
@table @samp
|
|
||||||
@item insert
|
|
||||||
@item remove
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@item sample_aspect_ratio
|
|
||||||
Set the sample aspect ratio in the stream in the VUI parameters.
|
|
||||||
|
|
||||||
@item video_format
|
|
||||||
@item video_full_range_flag
|
|
||||||
Set the video format in the stream (see H.265 section E.3.1 and
|
|
||||||
table E.2).
|
|
||||||
|
|
||||||
@item colour_primaries
|
|
||||||
@item transfer_characteristics
|
|
||||||
@item matrix_coefficients
|
|
||||||
Set the colour description in the stream (see H.265 section E.3.1
|
|
||||||
and tables E.3, E.4 and E.5).
|
|
||||||
|
|
||||||
@item chroma_sample_loc_type
|
|
||||||
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 (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.
|
|
||||||
|
|
||||||
@item num_ticks_poc_diff_one
|
|
||||||
Set poc_proportional_to_timing_flag in VPS and VUI and use this value
|
|
||||||
to set num_ticks_poc_diff_one_minus1 (see H.265 sections 7.4.3.1 and
|
|
||||||
E.3.1). Ignored if @option{tick_rate} is not also set.
|
|
||||||
|
|
||||||
@item crop_left
|
|
||||||
@item crop_right
|
|
||||||
@item crop_top
|
|
||||||
@item crop_bottom
|
|
||||||
Set the conformance window cropping offsets in the SPS. These values
|
|
||||||
will replace the current ones if the stream is already cropped.
|
|
||||||
|
|
||||||
These fields are set in pixels. Note that some sizes may not be
|
|
||||||
representable if the chroma is subsampled (H.265 section 7.4.3.2.1).
|
|
||||||
|
|
||||||
@item level
|
|
||||||
Set the level in the VPS and SPS. See H.265 section A.4 and tables
|
|
||||||
A.6 and A.7.
|
|
||||||
|
|
||||||
The argument must be the name of a level (for example, @samp{5.1}), a
|
|
||||||
@emph{general_level_idc} value (for example, @samp{153} for level 5.1),
|
|
||||||
or the special name @samp{auto} indicating that the filter should
|
|
||||||
attempt to guess the level from the input stream properties.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section hevc_mp4toannexb
|
|
||||||
|
|
||||||
Convert an HEVC/H.265 bitstream from length prefixed mode to start code
|
|
||||||
prefixed mode (as defined in the Annex B of the ITU-T H.265
|
|
||||||
specification).
|
|
||||||
|
|
||||||
This is required by some streaming formats, typically the MPEG-2
|
|
||||||
transport stream format (muxer @code{mpegts}).
|
|
||||||
|
|
||||||
For example to remux an MP4 file containing an HEVC stream to mpegts
|
|
||||||
format with @command{ffmpeg}, you can use the command:
|
|
||||||
|
|
||||||
@example
|
|
||||||
ffmpeg -i INPUT.mp4 -codec copy -bsf:v hevc_mp4toannexb OUTPUT.ts
|
|
||||||
@end example
|
|
||||||
|
|
||||||
Please note that this filter is auto-inserted for MPEG-TS (muxer
|
|
||||||
@code{mpegts}) and raw HEVC/H.265 (muxer @code{h265} or
|
|
||||||
@code{hevc}) output formats.
|
|
||||||
|
|
||||||
@section imxdump
|
@section imxdump
|
||||||
|
|
||||||
Modifies the bitstream to fit in MOV and to be usable by the Final Cut
|
Modifies the bitstream to fit in MOV and to be usable by the Final Cut
|
||||||
@@ -453,58 +137,11 @@ exiftran -i -9 frame*.jpg
|
|||||||
ffmpeg -i frame_%d.jpg -c:v copy rotated.avi
|
ffmpeg -i frame_%d.jpg -c:v copy rotated.avi
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@section mjpegadump
|
@section mjpega_dump_header
|
||||||
|
|
||||||
Add an MJPEG A header to the bitstream, to enable decoding by
|
@section movsub
|
||||||
Quicktime.
|
|
||||||
|
|
||||||
@anchor{mov2textsub}
|
@section mp3_header_decompress
|
||||||
@section mov2textsub
|
|
||||||
|
|
||||||
Extract a representable text file from MOV subtitles, stripping the
|
|
||||||
metadata header from each subtitle packet.
|
|
||||||
|
|
||||||
See also the @ref{text2movsub} filter.
|
|
||||||
|
|
||||||
@section mp3decomp
|
|
||||||
|
|
||||||
Decompress non-standard compressed MP3 audio headers.
|
|
||||||
|
|
||||||
@section mpeg2_metadata
|
|
||||||
|
|
||||||
Modify metadata embedded in an MPEG-2 stream.
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item display_aspect_ratio
|
|
||||||
Set the display aspect ratio in the stream.
|
|
||||||
|
|
||||||
The following fixed values are supported:
|
|
||||||
@table @option
|
|
||||||
@item 4/3
|
|
||||||
@item 16/9
|
|
||||||
@item 221/100
|
|
||||||
@end table
|
|
||||||
Any other value will result in square pixels being signalled instead
|
|
||||||
(see H.262 section 6.3.3 and table 6-3).
|
|
||||||
|
|
||||||
@item frame_rate
|
|
||||||
Set the frame rate in the stream. This is constructed from a table
|
|
||||||
of known values combined with a small multiplier and divisor - if
|
|
||||||
the supplied value is not exactly representable, the nearest
|
|
||||||
representable value will be used instead (see H.262 section 6.3.3
|
|
||||||
and table 6-4).
|
|
||||||
|
|
||||||
@item video_format
|
|
||||||
Set the video format in the stream (see H.262 section 6.3.6 and
|
|
||||||
table 6-6).
|
|
||||||
|
|
||||||
@item colour_primaries
|
|
||||||
@item transfer_characteristics
|
|
||||||
@item matrix_coefficients
|
|
||||||
Set the colour description in the stream (see H.262 section 6.3.6
|
|
||||||
and tables 6-7, 6-8 and 6-9).
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section mpeg4_unpack_bframes
|
@section mpeg4_unpack_bframes
|
||||||
|
|
||||||
@@ -528,327 +165,20 @@ ffmpeg -i INPUT.avi -codec copy -bsf:v mpeg4_unpack_bframes OUTPUT.avi
|
|||||||
|
|
||||||
@section noise
|
@section noise
|
||||||
|
|
||||||
Damages the contents of packets or simply drops them without damaging the
|
Damages the contents of packets without damaging the container. Can be
|
||||||
container. Can be used for fuzzing or testing error resilience/concealment.
|
used for fuzzing or testing error resilience/concealment.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
@table @option
|
A numeral string, whose value is related to how often output bytes will
|
||||||
@item amount
|
be modified. Therefore, values below or equal to 0 are forbidden, and
|
||||||
Accepts an expression whose evaluation per-packet determines how often bytes in that
|
the lower the more frequent bytes will be modified, with 1 meaning
|
||||||
packet will be modified. A value below 0 will result in a variable frequency.
|
every byte is modified.
|
||||||
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
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
@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 prores_metadata
|
|
||||||
|
|
||||||
Modify color property metadata embedded in prores stream.
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item color_primaries
|
|
||||||
Set the color primaries.
|
|
||||||
Available values are:
|
|
||||||
|
|
||||||
@table @samp
|
|
||||||
@item auto
|
|
||||||
Keep the same color primaries property (default).
|
|
||||||
|
|
||||||
@item unknown
|
|
||||||
@item bt709
|
|
||||||
@item bt470bg
|
|
||||||
BT601 625
|
|
||||||
|
|
||||||
@item smpte170m
|
|
||||||
BT601 525
|
|
||||||
|
|
||||||
@item bt2020
|
|
||||||
@item smpte431
|
|
||||||
DCI P3
|
|
||||||
|
|
||||||
@item smpte432
|
|
||||||
P3 D65
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@item transfer_characteristics
|
|
||||||
Set the color transfer.
|
|
||||||
Available values are:
|
|
||||||
|
|
||||||
@table @samp
|
|
||||||
@item auto
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
@item matrix_coefficients
|
|
||||||
Set the matrix coefficient.
|
|
||||||
Available values are:
|
|
||||||
|
|
||||||
@table @samp
|
|
||||||
@item auto
|
|
||||||
Keep the same colorspace property (default).
|
|
||||||
|
|
||||||
@item unknown
|
|
||||||
@item bt709
|
|
||||||
@item smpte170m
|
|
||||||
BT 601
|
|
||||||
|
|
||||||
@item bt2020nc
|
|
||||||
@end table
|
|
||||||
@end table
|
|
||||||
|
|
||||||
Set Rec709 colorspace for each frame of the file
|
|
||||||
@example
|
|
||||||
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
|
@end example
|
||||||
|
applies the modification to every byte.
|
||||||
|
|
||||||
@section remove_extra
|
@section remove_extra
|
||||||
|
|
||||||
Remove extradata from packets.
|
|
||||||
|
|
||||||
It accepts the following parameter:
|
|
||||||
@table @option
|
|
||||||
@item freq
|
|
||||||
Set which frame types to remove extradata from.
|
|
||||||
|
|
||||||
@table @samp
|
|
||||||
@item k
|
|
||||||
Remove extradata from non-keyframes only.
|
|
||||||
|
|
||||||
@item keyframe
|
|
||||||
Remove extradata from keyframes only.
|
|
||||||
|
|
||||||
@item e, all
|
|
||||||
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.
|
|
||||||
@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 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_OUTDTS
|
|
||||||
The previous output DTS.
|
|
||||||
|
|
||||||
@item PREV_OUTPTS
|
|
||||||
The previous output PTS.
|
|
||||||
|
|
||||||
@item TB
|
|
||||||
The timebase of stream packet belongs.
|
|
||||||
|
|
||||||
@item SR
|
|
||||||
The sample rate of stream packet belongs.
|
|
||||||
|
|
||||||
@item NOPTS
|
|
||||||
The AV_NOPTS_VALUE constant.
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@anchor{text2movsub}
|
|
||||||
@section text2movsub
|
|
||||||
|
|
||||||
Convert text subtitles to MOV subtitles (as used by the @code{mov_text}
|
|
||||||
codec) with metadata headers.
|
|
||||||
|
|
||||||
See also the @ref{mov2textsub} filter.
|
|
||||||
|
|
||||||
@section trace_headers
|
|
||||||
|
|
||||||
Log trace output containing all syntax elements in the coded stream
|
|
||||||
headers (everything above the level of individual coded blocks).
|
|
||||||
This can be useful for debugging low-level stream issues.
|
|
||||||
|
|
||||||
Supports AV1, H.264, H.265, (M)JPEG, MPEG-2 and VP9, but depending
|
|
||||||
on the build only a subset of these may be available.
|
|
||||||
|
|
||||||
@section truehd_core
|
|
||||||
|
|
||||||
Extract the core from a TrueHD stream, dropping ATMOS data.
|
|
||||||
|
|
||||||
@section vp9_metadata
|
|
||||||
|
|
||||||
Modify metadata embedded in a VP9 stream.
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item color_space
|
|
||||||
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
|
|
||||||
@item bt709
|
|
||||||
@item smpte170
|
|
||||||
@item smpte240
|
|
||||||
@item bt2020
|
|
||||||
@item rgb
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@item color_range
|
|
||||||
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
|
|
||||||
@end table
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section vp9_superframe
|
|
||||||
|
|
||||||
Merge VP9 invisible (alt-ref) frames back into VP9 superframes. This
|
|
||||||
fixes merging of split/segmented VP9 streams where the alt-ref frame
|
|
||||||
was split from its visible counterpart.
|
|
||||||
|
|
||||||
@section vp9_superframe_split
|
|
||||||
|
|
||||||
Split VP9 superframes into single frames.
|
|
||||||
|
|
||||||
@section vp9_raw_reorder
|
|
||||||
|
|
||||||
Given a VP9 stream with correct timestamps but possibly out of order,
|
|
||||||
insert additional show-existing-frame packets to correct the ordering.
|
|
||||||
|
|
||||||
@c man end BITSTREAM FILTERS
|
@c man end BITSTREAM FILTERS
|
||||||
|
|||||||
@@ -36,20 +36,15 @@ install
|
|||||||
examples
|
examples
|
||||||
Build all examples located in doc/examples.
|
Build all examples located in doc/examples.
|
||||||
|
|
||||||
checkheaders
|
libavformat/output-example
|
||||||
Check headers dependencies.
|
Build the libavformat basic example.
|
||||||
|
|
||||||
alltools
|
libswscale/swscale-test
|
||||||
Build all tools in tools directory.
|
Build the swscale self-test (useful also as an example).
|
||||||
|
|
||||||
config
|
config
|
||||||
Reconfigure the project with the current configuration.
|
Reconfigure the project with the current configuration.
|
||||||
|
|
||||||
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:
|
Useful standard make commands:
|
||||||
make -t <target>
|
make -t <target>
|
||||||
|
|||||||
517
doc/codecs.texi
517
doc/codecs.texi
@@ -44,20 +44,26 @@ Use 1/4 pel motion compensation.
|
|||||||
Use loop filter.
|
Use loop filter.
|
||||||
@item qscale
|
@item qscale
|
||||||
Use fixed qscale.
|
Use fixed qscale.
|
||||||
|
@item gmc
|
||||||
|
Use gmc.
|
||||||
|
@item mv0
|
||||||
|
Always try a mb with mv=<0,0>.
|
||||||
|
@item input_preserved
|
||||||
|
|
||||||
@item pass1
|
@item pass1
|
||||||
Use internal 2pass ratecontrol in first pass mode.
|
Use internal 2pass ratecontrol in first pass mode.
|
||||||
@item pass2
|
@item pass2
|
||||||
Use internal 2pass ratecontrol in second pass mode.
|
Use internal 2pass ratecontrol in second pass mode.
|
||||||
@item gray
|
@item gray
|
||||||
Only decode/encode grayscale.
|
Only decode/encode grayscale.
|
||||||
|
@item emu_edge
|
||||||
|
Do not draw edges.
|
||||||
@item psnr
|
@item psnr
|
||||||
Set error[?] variables during encoding.
|
Set error[?] variables during encoding.
|
||||||
@item truncated
|
@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.
|
|
||||||
|
|
||||||
|
@item naq
|
||||||
|
Normalize adaptive quantization.
|
||||||
@item ildct
|
@item ildct
|
||||||
Use interlaced DCT.
|
Use interlaced DCT.
|
||||||
@item low_delay
|
@item low_delay
|
||||||
@@ -70,14 +76,50 @@ This ensures that file and data checksums are reproducible and match between
|
|||||||
platforms. Its primary use is for regression testing.
|
platforms. Its primary use is for regression testing.
|
||||||
@item aic
|
@item aic
|
||||||
Apply H263 advanced intra coding / mpeg4 ac prediction.
|
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
|
@item ilme
|
||||||
Apply interlaced motion estimation.
|
Apply interlaced motion estimation.
|
||||||
@item cgop
|
@item cgop
|
||||||
Use closed gop.
|
Use closed gop.
|
||||||
@item output_corrupt
|
|
||||||
Output even potentially corrupted frames.
|
|
||||||
@end table
|
@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}
|
@item time_base @var{rational number}
|
||||||
Set codec time base.
|
Set codec time base.
|
||||||
|
|
||||||
@@ -96,8 +138,7 @@ Set audio sampling rate (in Hz).
|
|||||||
Set number of audio channels.
|
Set number of audio channels.
|
||||||
|
|
||||||
@item cutoff @var{integer} (@emph{encoding,audio})
|
@item cutoff @var{integer} (@emph{encoding,audio})
|
||||||
Set cutoff bandwidth. (Supported only by selected encoders, see
|
Set cutoff bandwidth.
|
||||||
their respective documentation sections.)
|
|
||||||
|
|
||||||
@item frame_size @var{integer} (@emph{encoding,audio})
|
@item frame_size @var{integer} (@emph{encoding,audio})
|
||||||
Set audio frame size.
|
Set audio frame size.
|
||||||
@@ -144,6 +185,24 @@ Default value is 0.
|
|||||||
@item b_qfactor @var{float} (@emph{encoding,video})
|
@item b_qfactor @var{float} (@emph{encoding,video})
|
||||||
Set qp factor between P and B frames.
|
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 codec_tag @var{integer}
|
||||||
@item bug @var{flags} (@emph{decoding,video})
|
@item bug @var{flags} (@emph{decoding,video})
|
||||||
Workaround not auto detected encoder bugs.
|
Workaround not auto detected encoder bugs.
|
||||||
@@ -152,6 +211,8 @@ Possible values:
|
|||||||
@table @samp
|
@table @samp
|
||||||
@item autodetect
|
@item autodetect
|
||||||
|
|
||||||
|
@item old_msmpeg4
|
||||||
|
some old lavc generated msmpeg4v3 files (no autodetection)
|
||||||
@item xvid_ilace
|
@item xvid_ilace
|
||||||
Xvid interlacing bug (autodetected if fourcc==XVIX)
|
Xvid interlacing bug (autodetected if fourcc==XVIX)
|
||||||
@item ump4
|
@item ump4
|
||||||
@@ -160,6 +221,8 @@ Xvid interlacing bug (autodetected if fourcc==XVIX)
|
|||||||
padding bug (autodetected)
|
padding bug (autodetected)
|
||||||
@item amv
|
@item amv
|
||||||
|
|
||||||
|
@item ac_vlc
|
||||||
|
illegal vlc bug (autodetected per fourcc)
|
||||||
@item qpel_chroma
|
@item qpel_chroma
|
||||||
|
|
||||||
@item std_qpel
|
@item std_qpel
|
||||||
@@ -180,6 +243,14 @@ Workaround various bugs in microsoft broken decoders.
|
|||||||
trancated frames
|
trancated frames
|
||||||
@end table
|
@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})
|
@item strict @var{integer} (@emph{decoding/encoding,audio,video})
|
||||||
Specify how strictly to follow the standards.
|
Specify how strictly to follow the standards.
|
||||||
|
|
||||||
@@ -233,8 +304,29 @@ consider things that a sane encoder should not do as an error
|
|||||||
|
|
||||||
@item block_align @var{integer}
|
@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_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})
|
@item maxrate @var{integer} (@emph{encoding,audio,video})
|
||||||
Set max bitrate tolerance (in bits/s). Requires bufsize to be set.
|
Set max bitrate tolerance (in bits/s). Requires bufsize to be set.
|
||||||
|
|
||||||
@@ -245,12 +337,18 @@ encode. It is of little use elsewise.
|
|||||||
@item bufsize @var{integer} (@emph{encoding,audio,video})
|
@item bufsize @var{integer} (@emph{encoding,audio,video})
|
||||||
Set ratecontrol buffer size (in bits).
|
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})
|
@item i_qfactor @var{float} (@emph{encoding,video})
|
||||||
Set QP factor between P and I frames.
|
Set QP factor between P and I frames.
|
||||||
|
|
||||||
@item i_qoffset @var{float} (@emph{encoding,video})
|
@item i_qoffset @var{float} (@emph{encoding,video})
|
||||||
Set QP offset between P and I frames.
|
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})
|
@item dct @var{integer} (@emph{encoding,video})
|
||||||
Set DCT algorithm.
|
Set DCT algorithm.
|
||||||
|
|
||||||
@@ -315,7 +413,11 @@ Automatically pick a IDCT compatible with the simple one
|
|||||||
|
|
||||||
@item simpleneon
|
@item simpleneon
|
||||||
|
|
||||||
@item xvid
|
@item simplealpha
|
||||||
|
|
||||||
|
@item ipp
|
||||||
|
|
||||||
|
@item xvidmmx
|
||||||
|
|
||||||
@item faani
|
@item faani
|
||||||
floating point AAN IDCT
|
floating point AAN IDCT
|
||||||
@@ -338,6 +440,19 @@ favor predicting from the previous frame instead of the current
|
|||||||
|
|
||||||
@item bits_per_coded_sample @var{integer}
|
@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})
|
@item aspect @var{rational number} (@emph{encoding,video})
|
||||||
Set sample aspect ratio.
|
Set sample aspect ratio.
|
||||||
|
|
||||||
@@ -359,6 +474,8 @@ rate control
|
|||||||
macroblock (MB) type
|
macroblock (MB) type
|
||||||
@item qp
|
@item qp
|
||||||
per-block quantization parameter (QP)
|
per-block quantization parameter (QP)
|
||||||
|
@item mv
|
||||||
|
motion vector
|
||||||
@item dct_coeff
|
@item dct_coeff
|
||||||
|
|
||||||
@item green_metadata
|
@item green_metadata
|
||||||
@@ -368,12 +485,18 @@ display complexity metadata for the upcoming frame, GoP or for a given duration.
|
|||||||
|
|
||||||
@item startcode
|
@item startcode
|
||||||
|
|
||||||
|
@item pts
|
||||||
|
|
||||||
@item er
|
@item er
|
||||||
error recognition
|
error recognition
|
||||||
@item mmco
|
@item mmco
|
||||||
memory management control operations (H.264)
|
memory management control operations (H.264)
|
||||||
@item bugs
|
@item bugs
|
||||||
|
|
||||||
|
@item vis_qp
|
||||||
|
visualize quantization parameter (QP), lower QP are tinted greener
|
||||||
|
@item vis_mb_type
|
||||||
|
visualize block types
|
||||||
@item buffers
|
@item buffers
|
||||||
picture buffer allocations
|
picture buffer allocations
|
||||||
@item thread_ops
|
@item thread_ops
|
||||||
@@ -382,6 +505,21 @@ threading operations
|
|||||||
skip motion compensation
|
skip motion compensation
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@item vismv @var{integer} (@emph{decoding,video})
|
||||||
|
Visualize motion vectors (MVs).
|
||||||
|
|
||||||
|
This option is deprecated, see the codecview filter instead.
|
||||||
|
|
||||||
|
Possible values:
|
||||||
|
@table @samp
|
||||||
|
@item pf
|
||||||
|
forward predicted MVs of P-frames
|
||||||
|
@item bf
|
||||||
|
forward predicted MVs of B-frames
|
||||||
|
@item bb
|
||||||
|
backward predicted MVs of B-frames
|
||||||
|
@end table
|
||||||
|
|
||||||
@item cmp @var{integer} (@emph{encoding,video})
|
@item cmp @var{integer} (@emph{encoding,video})
|
||||||
Set full pel me compare function.
|
Set full pel me compare function.
|
||||||
|
|
||||||
@@ -532,28 +670,13 @@ noise preserving sum of squared differences
|
|||||||
|
|
||||||
@item dia_size @var{integer} (@emph{encoding,video})
|
@item dia_size @var{integer} (@emph{encoding,video})
|
||||||
Set diamond type & size for motion estimation.
|
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})
|
@item last_pred @var{integer} (@emph{encoding,video})
|
||||||
Set amount of motion predictors from the previous frame.
|
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})
|
@item precmp @var{integer} (@emph{encoding,video})
|
||||||
Set pre motion estimation compare function.
|
Set pre motion estimation compare function.
|
||||||
|
|
||||||
@@ -597,13 +720,44 @@ Set diamond type & size for motion estimation pre-pass.
|
|||||||
@item subq @var{integer} (@emph{encoding,video})
|
@item subq @var{integer} (@emph{encoding,video})
|
||||||
Set sub pel motion estimation quality.
|
Set sub pel motion estimation quality.
|
||||||
|
|
||||||
|
@item dtg_active_format @var{integer}
|
||||||
|
|
||||||
@item me_range @var{integer} (@emph{encoding,video})
|
@item me_range @var{integer} (@emph{encoding,video})
|
||||||
Set limit motion vectors range (1023 for DivX player).
|
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 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 slice_flags @var{integer}
|
||||||
|
|
||||||
|
@item xvmc_acceleration @var{integer}
|
||||||
|
|
||||||
@item mbd @var{integer} (@emph{encoding,video})
|
@item mbd @var{integer} (@emph{encoding,video})
|
||||||
Set macroblock decision algorithm (high quality mode).
|
Set macroblock decision algorithm (high quality mode).
|
||||||
|
|
||||||
@@ -617,16 +771,32 @@ use fewest bits
|
|||||||
use best rate distortion
|
use best rate distortion
|
||||||
@end table
|
@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})
|
@item rc_init_occupancy @var{integer} (@emph{encoding,video})
|
||||||
Set number of bits which should be loaded into the rc buffer before
|
Set number of bits which should be loaded into the rc buffer before
|
||||||
decoding starts.
|
decoding starts.
|
||||||
|
|
||||||
@item flags2 @var{flags} (@emph{decoding/encoding,audio,video,subtitles})
|
@item flags2 @var{flags} (@emph{decoding/encoding,audio,video})
|
||||||
|
|
||||||
Possible values:
|
Possible values:
|
||||||
@table @samp
|
@table @samp
|
||||||
@item fast
|
@item fast
|
||||||
Allow non spec compliant speedup tricks.
|
Allow non spec compliant speedup tricks.
|
||||||
|
@item sgop
|
||||||
|
Deprecated, use mpegvideo private options instead.
|
||||||
@item noout
|
@item noout
|
||||||
Skip bitstream encoding.
|
Skip bitstream encoding.
|
||||||
@item ignorecrop
|
@item ignorecrop
|
||||||
@@ -637,32 +807,17 @@ Place global headers at every keyframe instead of in extradata.
|
|||||||
Frame data might be split into multiple chunks.
|
Frame data might be split into multiple chunks.
|
||||||
@item showall
|
@item showall
|
||||||
Show all frames before the first keyframe.
|
Show all frames before the first keyframe.
|
||||||
|
@item skiprd
|
||||||
|
Deprecated, use mpegvideo private options instead.
|
||||||
@item export_mvs
|
@item export_mvs
|
||||||
Export motion vectors into frame side-data (see @code{AV_FRAME_DATA_MOTION_VECTORS})
|
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}.
|
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
|
@end table
|
||||||
|
|
||||||
@item export_side_data @var{flags} (@emph{decoding/encoding,audio,video,subtitles})
|
@item error @var{integer} (@emph{encoding,video})
|
||||||
|
|
||||||
Possible values:
|
@item qns @var{integer} (@emph{encoding,video})
|
||||||
@table @samp
|
Deprecated, use mpegvideo private options instead.
|
||||||
@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})
|
@item threads @var{integer} (@emph{decoding/encoding,video})
|
||||||
Set the number of threads to be used, in case the selected codec
|
Set the number of threads to be used, in case the selected codec
|
||||||
@@ -676,6 +831,12 @@ automatically select the number of threads to set
|
|||||||
|
|
||||||
Default value is @samp{auto}.
|
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})
|
@item dc @var{integer} (@emph{encoding,video})
|
||||||
Set intra_dc_precision.
|
Set intra_dc_precision.
|
||||||
|
|
||||||
@@ -690,8 +851,49 @@ Set number of macroblock rows at the bottom which are skipped.
|
|||||||
|
|
||||||
@item profile @var{integer} (@emph{encoding,audio,video})
|
@item profile @var{integer} (@emph{encoding,audio,video})
|
||||||
|
|
||||||
Set encoder codec profile. Default value is @samp{unknown}. Encoder specific
|
Possible values:
|
||||||
profiles are documented in the relevant encoder documentation.
|
@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
|
||||||
|
|
||||||
@item level @var{integer} (@emph{encoding,audio,video})
|
@item level @var{integer} (@emph{encoding,audio,video})
|
||||||
|
|
||||||
@@ -704,12 +906,67 @@ Possible values:
|
|||||||
@item lowres @var{integer} (@emph{decoding,audio,video})
|
@item lowres @var{integer} (@emph{decoding,audio,video})
|
||||||
Decode at 1= 1/2, 2=1/4, 3=1/8 resolutions.
|
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})
|
@item mblmin @var{integer} (@emph{encoding,video})
|
||||||
Set min macroblock lagrange factor (VBR).
|
Set min macroblock lagrange factor (VBR).
|
||||||
|
|
||||||
@item mblmax @var{integer} (@emph{encoding,video})
|
@item mblmax @var{integer} (@emph{encoding,video})
|
||||||
Set max macroblock lagrange factor (VBR).
|
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_loop_filter @var{integer} (@emph{decoding,video})
|
||||||
@item skip_idct @var{integer} (@emph{decoding,video})
|
@item skip_idct @var{integer} (@emph{decoding,video})
|
||||||
@item skip_frame @var{integer} (@emph{decoding,video})
|
@item skip_frame @var{integer} (@emph{decoding,video})
|
||||||
@@ -737,9 +994,6 @@ Discard all bidirectional frames.
|
|||||||
@item nokey
|
@item nokey
|
||||||
Discard all frames excepts keyframes.
|
Discard all frames excepts keyframes.
|
||||||
|
|
||||||
@item nointra
|
|
||||||
Discard all frames except I frames.
|
|
||||||
|
|
||||||
@item all
|
@item all
|
||||||
Discard all frames.
|
Discard all frames.
|
||||||
@end table
|
@end table
|
||||||
@@ -749,17 +1003,38 @@ Default value is @samp{default}.
|
|||||||
@item bidir_refine @var{integer} (@emph{encoding,video})
|
@item bidir_refine @var{integer} (@emph{encoding,video})
|
||||||
Refine the two motion vectors used in bidirectional macroblocks.
|
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})
|
@item keyint_min @var{integer} (@emph{encoding,video})
|
||||||
Set minimum interval between IDR-frames.
|
Set minimum interval between IDR-frames.
|
||||||
|
|
||||||
@item refs @var{integer} (@emph{encoding,video})
|
@item refs @var{integer} (@emph{encoding,video})
|
||||||
Set reference frames to consider for motion compensation.
|
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})
|
@item trellis @var{integer} (@emph{encoding,audio,video})
|
||||||
Set rate-distortion optimal quantization.
|
Set rate-distortion optimal quantization.
|
||||||
|
|
||||||
|
@item sc_factor @var{integer} (@emph{encoding,video})
|
||||||
|
Set value multiplied by qscale for each frame and added to
|
||||||
|
scene_change_score.
|
||||||
|
|
||||||
@item mv0_threshold @var{integer} (@emph{encoding,video})
|
@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 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 bits_per_raw_sample @var{integer}
|
||||||
@item channel_layout @var{integer} (@emph{decoding/encoding,audio})
|
@item channel_layout @var{integer} (@emph{decoding/encoding,audio})
|
||||||
|
|
||||||
@@ -774,34 +1049,7 @@ Possible values:
|
|||||||
@item rc_max_vbv_use @var{float} (@emph{encoding,video})
|
@item rc_max_vbv_use @var{float} (@emph{encoding,video})
|
||||||
@item rc_min_vbv_use @var{float} (@emph{encoding,video})
|
@item rc_min_vbv_use @var{float} (@emph{encoding,video})
|
||||||
@item ticks_per_frame @var{integer} (@emph{decoding/encoding,audio,video})
|
@item ticks_per_frame @var{integer} (@emph{decoding/encoding,audio,video})
|
||||||
|
|
||||||
@item color_primaries @var{integer} (@emph{decoding/encoding,video})
|
@item color_primaries @var{integer} (@emph{decoding/encoding,video})
|
||||||
Possible values:
|
|
||||||
@table @samp
|
|
||||||
@item bt709
|
|
||||||
BT.709
|
|
||||||
@item bt470m
|
|
||||||
BT.470 M
|
|
||||||
@item bt470bg
|
|
||||||
BT.470 BG
|
|
||||||
@item smpte170m
|
|
||||||
SMPTE 170 M
|
|
||||||
@item smpte240m
|
|
||||||
SMPTE 240 M
|
|
||||||
@item film
|
|
||||||
Film
|
|
||||||
@item bt2020
|
|
||||||
BT.2020
|
|
||||||
@item smpte428
|
|
||||||
@item smpte428_1
|
|
||||||
SMPTE ST 428-1
|
|
||||||
@item smpte431
|
|
||||||
SMPTE 431-2
|
|
||||||
@item smpte432
|
|
||||||
SMPTE 432-1
|
|
||||||
@item jedec-p22
|
|
||||||
JEDEC P22
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@item color_trc @var{integer} (@emph{decoding/encoding,video})
|
@item color_trc @var{integer} (@emph{decoding/encoding,video})
|
||||||
Possible values:
|
Possible values:
|
||||||
@@ -812,104 +1060,35 @@ BT.709
|
|||||||
BT.470 M
|
BT.470 M
|
||||||
@item gamma28
|
@item gamma28
|
||||||
BT.470 BG
|
BT.470 BG
|
||||||
@item smpte170m
|
|
||||||
SMPTE 170 M
|
|
||||||
@item smpte240m
|
|
||||||
SMPTE 240 M
|
|
||||||
@item linear
|
@item linear
|
||||||
Linear
|
SMPTE 170 M
|
||||||
@item log
|
@item log
|
||||||
@item log100
|
SMPTE 240 M
|
||||||
Log
|
|
||||||
@item log_sqrt
|
@item log_sqrt
|
||||||
@item log316
|
Linear
|
||||||
Log square root
|
|
||||||
@item iec61966_2_4
|
@item iec61966_2_4
|
||||||
@item iec61966-2-4
|
Log
|
||||||
IEC 61966-2-4
|
|
||||||
@item bt1361
|
@item bt1361
|
||||||
@item bt1361e
|
Log square root
|
||||||
BT.1361
|
|
||||||
@item iec61966_2_1
|
@item iec61966_2_1
|
||||||
@item iec61966-2-1
|
IEC 61966-2-4
|
||||||
IEC 61966-2-1
|
|
||||||
@item bt2020_10
|
|
||||||
@item bt2020_10bit
|
@item bt2020_10bit
|
||||||
BT.2020 - 10 bit
|
BT.1361
|
||||||
@item bt2020_12
|
|
||||||
@item bt2020_12bit
|
@item bt2020_12bit
|
||||||
BT.2020 - 12 bit
|
IEC 61966-2-1
|
||||||
@item smpte2084
|
@item smpte2084
|
||||||
SMPTE ST 2084
|
BT.2020 - 10 bit
|
||||||
@item smpte428
|
|
||||||
@item smpte428_1
|
@item smpte428_1
|
||||||
SMPTE ST 428-1
|
BT.2020 - 12 bit
|
||||||
@item arib-std-b67
|
|
||||||
ARIB STD-B67
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@item colorspace @var{integer} (@emph{decoding/encoding,video})
|
@item colorspace @var{integer} (@emph{decoding/encoding,video})
|
||||||
Possible values:
|
|
||||||
@table @samp
|
|
||||||
@item rgb
|
|
||||||
RGB
|
|
||||||
@item bt709
|
|
||||||
BT.709
|
|
||||||
@item fcc
|
|
||||||
FCC
|
|
||||||
@item bt470bg
|
|
||||||
BT.470 BG
|
|
||||||
@item smpte170m
|
|
||||||
SMPTE 170 M
|
|
||||||
@item smpte240m
|
|
||||||
SMPTE 240 M
|
|
||||||
@item ycocg
|
|
||||||
YCOCG
|
|
||||||
@item bt2020nc
|
|
||||||
@item bt2020_ncl
|
|
||||||
BT.2020 NCL
|
|
||||||
@item bt2020c
|
|
||||||
@item bt2020_cl
|
|
||||||
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})
|
@item color_range @var{integer} (@emph{decoding/encoding,video})
|
||||||
If used as input parameter, it serves as a hint to the decoder, which
|
If used as input parameter, it serves as a hint to the decoder, which
|
||||||
color_range the input has.
|
color_range the input has.
|
||||||
Possible values:
|
|
||||||
@table @samp
|
|
||||||
@item tv
|
|
||||||
@item mpeg
|
|
||||||
MPEG (219*2^(n-8))
|
|
||||||
@item pc
|
|
||||||
@item jpeg
|
|
||||||
JPEG (2^n-1)
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@item chroma_sample_location @var{integer} (@emph{decoding/encoding,video})
|
@item chroma_sample_location @var{integer} (@emph{decoding/encoding,video})
|
||||||
Possible values:
|
|
||||||
@table @samp
|
|
||||||
@item left
|
|
||||||
|
|
||||||
@item center
|
|
||||||
|
|
||||||
@item topleft
|
|
||||||
|
|
||||||
@item top
|
|
||||||
|
|
||||||
@item bottomleft
|
|
||||||
|
|
||||||
@item bottom
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@item log_level_offset @var{integer}
|
@item log_level_offset @var{integer}
|
||||||
Set the log level offset.
|
Set the log level offset.
|
||||||
@@ -988,37 +1167,23 @@ Interlaced video, top coded first, bottom displayed first
|
|||||||
Interlaced video, bottom coded first, top displayed first
|
Interlaced video, bottom coded first, top displayed first
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@item skip_alpha @var{bool} (@emph{decoding,video})
|
@item skip_alpha @var{integer} (@emph{decoding,video})
|
||||||
Set to 1 to disable processing alpha (transparency). This works like the
|
Set to 1 to disable processing alpha (transparency). This works like the
|
||||||
@samp{gray} flag in the @option{flags} option which skips chroma information
|
@samp{gray} flag in the @option{flags} option which skips chroma information
|
||||||
instead of alpha. Default is 0.
|
instead of alpha. Default is 0.
|
||||||
|
|
||||||
@item codec_whitelist @var{list} (@emph{input})
|
@item codec_whitelist @var{list} (@emph{input})
|
||||||
"," separated list of allowed decoders. By default all are allowed.
|
"," separated List of allowed decoders. By default all are allowed.
|
||||||
|
|
||||||
@item dump_separator @var{string} (@emph{input})
|
@item dump_separator @var{string} (@emph{input})
|
||||||
Separator used to separate the fields printed on the command line about the
|
Separator used to separate the fields printed on the command line about the
|
||||||
Stream parameters.
|
Stream parameters.
|
||||||
For example, to separate the fields with newlines and indentation:
|
For example to separate the fields with newlines and indention:
|
||||||
@example
|
@example
|
||||||
ffprobe -dump_separator "
|
ffprobe -dump_separator "
|
||||||
" -i ~/videos/matrixbench_mpeg2.mpg
|
" -i ~/videos/matrixbench_mpeg2.mpg
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@item max_pixels @var{integer} (@emph{decoding/encoding,video})
|
|
||||||
Maximum number of pixels per image. This value can be used to avoid out of
|
|
||||||
memory failures due to large images.
|
|
||||||
|
|
||||||
@item apply_cropping @var{bool} (@emph{decoding,video})
|
|
||||||
Enable cropping if cropping parameters are multiples of the required
|
|
||||||
alignment for the left and top parameters. If the alignment is not met the
|
|
||||||
cropping will be partially applied to maintain alignment.
|
|
||||||
Default is 1 (enabled).
|
|
||||||
Note: The required alignment depends on if @code{AV_CODEC_FLAG_UNALIGNED} is set and the
|
|
||||||
CPU. @code{AV_CODEC_FLAG_UNALIGNED} cannot be changed from the command line. Also hardware
|
|
||||||
decoders will not apply left/top Cropping.
|
|
||||||
|
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@c man end CODEC OPTIONS
|
@c man end CODEC OPTIONS
|
||||||
|
|||||||
@@ -25,18 +25,12 @@ enabled decoders.
|
|||||||
A description of some of the currently available video decoders
|
A description of some of the currently available video decoders
|
||||||
follows.
|
follows.
|
||||||
|
|
||||||
@section av1
|
@section hevc
|
||||||
|
|
||||||
AOMedia Video 1 (AV1) decoder.
|
HEVC / H.265 decoder.
|
||||||
|
|
||||||
@subsection Options
|
Note: the @option{skip_loop_filter} option has effect only at level
|
||||||
|
@code{all}.
|
||||||
@table @option
|
|
||||||
|
|
||||||
@item operating_point
|
|
||||||
Select an operating point of a scalable AV1 bitstream (0 - 31). Default is 0.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section rawvideo
|
@section rawvideo
|
||||||
|
|
||||||
@@ -60,72 +54,6 @@ top-field-first is assumed
|
|||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@section libdav1d
|
|
||||||
|
|
||||||
dav1d AV1 decoder.
|
|
||||||
|
|
||||||
libdav1d allows libavcodec to decode the AOMedia Video 1 (AV1) codec.
|
|
||||||
Requires the presence of the libdav1d headers and library during configuration.
|
|
||||||
You need to explicitly configure the build with @code{--enable-libdav1d}.
|
|
||||||
|
|
||||||
@subsection Options
|
|
||||||
|
|
||||||
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. 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
|
|
||||||
|
|
||||||
@section libdavs2
|
|
||||||
|
|
||||||
AVS2-P2/IEEE1857.4 video decoder wrapper.
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
@c man end VIDEO DECODERS
|
@c man end VIDEO DECODERS
|
||||||
|
|
||||||
@chapter Audio Decoders
|
@chapter Audio Decoders
|
||||||
@@ -147,7 +75,7 @@ the undocumented RealAudio 3 (a.k.a. dnet).
|
|||||||
|
|
||||||
@item -drc_scale @var{value}
|
@item -drc_scale @var{value}
|
||||||
Dynamic Range Scale Factor. The factor to apply to dynamic range values
|
Dynamic Range Scale Factor. The factor to apply to dynamic range values
|
||||||
from the AC-3 stream. This factor is applied exponentially. The default value is 1.
|
from the AC-3 stream. This factor is applied exponentially.
|
||||||
There are 3 notable scale factor ranges:
|
There are 3 notable scale factor ranges:
|
||||||
@table @option
|
@table @option
|
||||||
@item drc_scale == 0
|
@item drc_scale == 0
|
||||||
@@ -181,7 +109,7 @@ correctly by using lavc's old buggy lpc logic for decoding.
|
|||||||
|
|
||||||
@section ffwavesynth
|
@section ffwavesynth
|
||||||
|
|
||||||
Internal wave synthesizer.
|
Internal wave synthetizer.
|
||||||
|
|
||||||
This decoder generates wave patterns according to predefined sequences. Its
|
This decoder generates wave patterns according to predefined sequences. Its
|
||||||
use is purely internal and the format of the data it accepts is not publicly
|
use is purely internal and the format of the data it accepts is not publicly
|
||||||
@@ -267,31 +195,6 @@ without this library.
|
|||||||
@chapter Subtitles Decoders
|
@chapter Subtitles Decoders
|
||||||
@c man begin SUBTILES DECODERS
|
@c man begin SUBTILES DECODERS
|
||||||
|
|
||||||
@section libaribb24
|
|
||||||
|
|
||||||
ARIB STD-B24 caption decoder.
|
|
||||||
|
|
||||||
Implements profiles A and C of the ARIB STD-B24 standard.
|
|
||||||
|
|
||||||
@subsection libaribb24 Decoder Options
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
|
|
||||||
@item -aribb24-base-path @var{path}
|
|
||||||
Sets the base path for the libaribb24 library. This is utilized for reading of
|
|
||||||
configuration files (for custom unicode conversions), and for dumping of
|
|
||||||
non-text symbols as images under that location.
|
|
||||||
|
|
||||||
Unset by default.
|
|
||||||
|
|
||||||
@item -aribb24-skip-ruby-text @var{boolean}
|
|
||||||
Tells the decoder wrapper to skip text blocks that contain half-height ruby
|
|
||||||
text.
|
|
||||||
|
|
||||||
Enabled by default.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section dvbsub
|
@section dvbsub
|
||||||
|
|
||||||
@subsection Options
|
@subsection Options
|
||||||
@@ -299,8 +202,6 @@ Enabled by default.
|
|||||||
@table @option
|
@table @option
|
||||||
@item compute_clut
|
@item compute_clut
|
||||||
@table @option
|
@table @option
|
||||||
@item -2
|
|
||||||
Compute clut once if no matching CLUT is in the stream.
|
|
||||||
@item -1
|
@item -1
|
||||||
Compute clut if no matching CLUT is in the stream.
|
Compute clut if no matching CLUT is in the stream.
|
||||||
@item 0
|
@item 0
|
||||||
@@ -329,7 +230,7 @@ palette is stored in the IFO file, and therefore not available when reading
|
|||||||
from dumped VOB files.
|
from dumped VOB files.
|
||||||
|
|
||||||
The format for this option is a string containing 16 24-bits hexadecimal
|
The format for this option is a string containing 16 24-bits hexadecimal
|
||||||
numbers (without 0x prefix) separated by commas, for example @code{0d00ee,
|
numbers (without 0x prefix) separated by comas, for example @code{0d00ee,
|
||||||
ee450d, 101010, eaeaea, 0ce60b, ec14ed, ebff0b, 0d617a, 7b7b7b, d1d1d1,
|
ee450d, 101010, eaeaea, 0ce60b, ec14ed, ebff0b, 0d617a, 7b7b7b, d1d1d1,
|
||||||
7b2a0e, 0d950c, 0f007b, cf0dec, cfa80c, 7c127b}.
|
7b2a0e, 0d950c, 0f007b, cf0dec, cfa80c, 7c127b}.
|
||||||
|
|
||||||
@@ -354,30 +255,18 @@ configuration. You need to explicitly configure the build with
|
|||||||
|
|
||||||
@table @option
|
@table @option
|
||||||
@item txt_page
|
@item txt_page
|
||||||
List of teletext page numbers to decode. Pages that do not match the specified
|
List of teletext page numbers to decode. You may use the special * string to
|
||||||
list are dropped. You may use the special @code{*} string to match all pages,
|
match all pages. Pages that do not match the specified list are dropped.
|
||||||
or @code{subtitle} to match all subtitle pages.
|
|
||||||
Default value is *.
|
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
|
@item txt_chop_top
|
||||||
Discards the top teletext line. Default value is 1.
|
Discards the top teletext line. Default value is 1.
|
||||||
@item txt_format
|
@item txt_format
|
||||||
Specifies the format of the decoded subtitles.
|
Specifies the format of the decoded subtitles. The teletext decoder is capable
|
||||||
@table @option
|
of decoding the teletext pages to bitmaps or to simple text, you should use
|
||||||
@item bitmap
|
"bitmap" for teletext pages, because certain graphics and colors cannot be
|
||||||
The default format, you should use this for teletext pages, because certain
|
expressed in simple text. You might use "text" for teletext based subtitles if
|
||||||
graphics and colors cannot be expressed in simple text or even ASS.
|
your application can handle simple text based subtitles. Default value is
|
||||||
@item text
|
bitmap.
|
||||||
Simple text based output without formatting.
|
|
||||||
@item ass
|
|
||||||
Formatted ASS output, subtitle pages and teletext pages are returned in
|
|
||||||
different styles, subtitle pages are stripped down to text, but an effort is
|
|
||||||
made to keep the text alignment and the formatting.
|
|
||||||
@end table
|
|
||||||
@item txt_left
|
@item txt_left
|
||||||
X offset of generated bitmaps, default is 0.
|
X offset of generated bitmaps, default is 0.
|
||||||
@item txt_top
|
@item txt_top
|
||||||
@@ -386,12 +275,11 @@ Y offset of generated bitmaps, default is 0.
|
|||||||
Chops leading and trailing spaces and removes empty lines from the generated
|
Chops leading and trailing spaces and removes empty lines from the generated
|
||||||
text. This option is useful for teletext based subtitles where empty spaces may
|
text. This option is useful for teletext based subtitles where empty spaces may
|
||||||
be present at the start or at the end of the lines or empty lines may be
|
be present at the start or at the end of the lines or empty lines may be
|
||||||
present between the subtitle lines because of double-sized teletext characters.
|
present between the subtitle lines because of double-sized teletext charactes.
|
||||||
Default value is 1.
|
Default value is 1.
|
||||||
@item txt_duration
|
@item txt_duration
|
||||||
Sets the display duration of the decoded teletext pages or subtitles in
|
Sets the display duration of the decoded teletext pages or subtitles in
|
||||||
milliseconds. Default value is -1 which means infinity or until the next
|
miliseconds. Default value is 30000 which is 30 seconds.
|
||||||
subtitle event comes.
|
|
||||||
@item txt_transparent
|
@item txt_transparent
|
||||||
Force transparent background of the generated teletext bitmaps. Default value
|
Force transparent background of the generated teletext bitmaps. Default value
|
||||||
is 0 which means an opaque background.
|
is 0 which means an opaque background.
|
||||||
|
|||||||
@@ -13,9 +13,8 @@ You can disable all the demuxers using the configure option
|
|||||||
the option @code{--enable-demuxer=@var{DEMUXER}}, or disable it
|
the option @code{--enable-demuxer=@var{DEMUXER}}, or disable it
|
||||||
with the option @code{--disable-demuxer=@var{DEMUXER}}.
|
with the option @code{--disable-demuxer=@var{DEMUXER}}.
|
||||||
|
|
||||||
The option @code{-demuxers} of the ff* tools will display the list of
|
The option @code{-formats} of the ff* tools will display the list of
|
||||||
enabled demuxers. Use @code{-formats} to view a combined list of
|
enabled demuxers.
|
||||||
enabled demuxers and muxers.
|
|
||||||
|
|
||||||
The description of some of the currently available demuxers follows.
|
The description of some of the currently available demuxers follows.
|
||||||
|
|
||||||
@@ -25,12 +24,16 @@ Audible Format 2, 3, and 4 demuxer.
|
|||||||
|
|
||||||
This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files.
|
This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files.
|
||||||
|
|
||||||
@section aac
|
@section applehttp
|
||||||
|
|
||||||
Raw Audio Data Transport Stream AAC demuxer.
|
Apple HTTP Live Streaming demuxer.
|
||||||
|
|
||||||
This demuxer is used to demux an ADTS input containing a single AAC stream
|
This demuxer presents all AVStreams from all variant streams.
|
||||||
alongwith any ID3v1/2 or APE tags in it.
|
The id field is set to the bitrate variant index number. By setting
|
||||||
|
the discard flags on AVStreams (by pressing 'a' or 'v' in ffplay),
|
||||||
|
the caller can decide which variant streams to actually receive.
|
||||||
|
The total bitrate of the variant that the stream belongs to is
|
||||||
|
available in a metadata key named "variant_bitrate".
|
||||||
|
|
||||||
@section apng
|
@section apng
|
||||||
|
|
||||||
@@ -44,15 +47,12 @@ between the last fcTL and IEND chunks.
|
|||||||
|
|
||||||
@table @option
|
@table @option
|
||||||
@item -ignore_loop @var{bool}
|
@item -ignore_loop @var{bool}
|
||||||
Ignore the loop variable in the file if set. Default is enabled.
|
Ignore the loop variable in the file if set.
|
||||||
|
|
||||||
@item -max_fps @var{int}
|
@item -max_fps @var{int}
|
||||||
Maximum framerate in frames per second. Default of 0 imposes no limit.
|
Maximum framerate in frames per second (0 for no limit).
|
||||||
|
|
||||||
@item -default_fps @var{int}
|
@item -default_fps @var{int}
|
||||||
Default framerate in frames per second when none is specified in the file
|
Default framerate in frames per second when none is specified in the file
|
||||||
(0 meaning as fast as possible). Default is 15.
|
(0 meaning as fast as possible).
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@section asf
|
@section asf
|
||||||
@@ -72,7 +72,7 @@ Do not try to resynchronize by looking for a certain optional start code.
|
|||||||
Virtual concatenation script demuxer.
|
Virtual concatenation script demuxer.
|
||||||
|
|
||||||
This demuxer reads a list of files and other directives from a text file and
|
This demuxer reads a list of files and other directives from a text file and
|
||||||
demuxes them one after the other, as if all their packets had been muxed
|
demuxes them one after the other, as if all their packet had been muxed
|
||||||
together.
|
together.
|
||||||
|
|
||||||
The timestamps in the files are adjusted so that the first file starts at 0
|
The timestamps in the files are adjusted so that the first file starts at 0
|
||||||
@@ -103,10 +103,11 @@ backslash or single quotes.
|
|||||||
All subsequent file-related directives apply to that file.
|
All subsequent file-related directives apply to that file.
|
||||||
|
|
||||||
@item @code{ffconcat version 1.0}
|
@item @code{ffconcat version 1.0}
|
||||||
Identify the script type and version.
|
Identify the script type and version. It also sets the @option{safe} option
|
||||||
|
to 1 if it was -1.
|
||||||
|
|
||||||
To make FFmpeg recognize the format automatically, this directive must
|
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
|
appears exactly as is (no extra space or byte-order-mark) on the very first
|
||||||
line of the script.
|
line of the script.
|
||||||
|
|
||||||
@item @code{duration @var{dur}}
|
@item @code{duration @var{dur}}
|
||||||
@@ -157,16 +158,6 @@ directive) will be reduced based on their specified Out point.
|
|||||||
Metadata of the packets of the file. The specified metadata will be set for
|
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
|
each file packet. You can specify this directive multiple times to add multiple
|
||||||
metadata entries.
|
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}
|
@item @code{stream}
|
||||||
Introduce a stream in the virtual file.
|
Introduce a stream in the virtual file.
|
||||||
@@ -184,20 +175,6 @@ subfiles will be used.
|
|||||||
This is especially useful for MPEG-PS (VOB) files, where the order of the
|
This is especially useful for MPEG-PS (VOB) files, where the order of the
|
||||||
streams is not reliable.
|
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
|
@end table
|
||||||
|
|
||||||
@subsection Options
|
@subsection Options
|
||||||
@@ -207,8 +184,7 @@ This demuxer accepts the following option:
|
|||||||
@table @option
|
@table @option
|
||||||
|
|
||||||
@item safe
|
@item safe
|
||||||
If set to 1, reject unsafe file paths and directives.
|
If set to 1, reject unsafe file paths. A file path is considered safe if it
|
||||||
A file path is considered safe if it
|
|
||||||
does not contain a protocol specification and is relative and all components
|
does not contain a protocol specification and is relative and all components
|
||||||
only contain characters from the portable character set (letters, digits,
|
only contain characters from the portable character set (letters, digits,
|
||||||
period, underscore and hyphen) and have no period at the beginning of a
|
period, underscore and hyphen) and have no period at the beginning of a
|
||||||
@@ -218,6 +194,9 @@ If set to 0, any file name is accepted.
|
|||||||
|
|
||||||
The default is 1.
|
The default is 1.
|
||||||
|
|
||||||
|
-1 is equivalent to 1 if the format was automatically
|
||||||
|
probed and 0 otherwise.
|
||||||
|
|
||||||
@item auto_convert
|
@item auto_convert
|
||||||
If set to 1, try to perform automatic conversions on packet data to make the
|
If set to 1, try to perform automatic conversions on packet data to make the
|
||||||
streams concatenable.
|
streams concatenable.
|
||||||
@@ -264,46 +243,30 @@ file subdir/file-2.wav
|
|||||||
@end example
|
@end example
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@section dash
|
@section flv
|
||||||
|
|
||||||
Dynamic Adaptive Streaming over HTTP demuxer.
|
|
||||||
|
|
||||||
This demuxer presents all AVStreams found in the manifest.
|
|
||||||
By setting the discard flags on AVStreams the caller can decide
|
|
||||||
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 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.
|
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.
|
This demuxer is used to demux FLV files and RTMP network streams.
|
||||||
KUX is a flv variant used on the Youku platform.
|
|
||||||
|
|
||||||
@example
|
|
||||||
ffmpeg -f flv -i myfile.flv ...
|
|
||||||
ffmpeg -f live_flv -i rtmp://<any.server>/anything/key ....
|
|
||||||
@end example
|
|
||||||
|
|
||||||
|
|
||||||
@table @option
|
@table @option
|
||||||
@item -flv_metadata @var{bool}
|
@item -flv_metadata @var{bool}
|
||||||
Allocate the streams according to the onMetaData array content.
|
Allocate the streams according to the onMetaData array content.
|
||||||
|
|
||||||
@item -flv_ignore_prevtag @var{bool}
|
|
||||||
Ignore the size of previous tag value.
|
|
||||||
|
|
||||||
@item -flv_full_metadata @var{bool}
|
|
||||||
Output all context of the onMetadata.
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@section libgme
|
||||||
|
|
||||||
|
The Game Music Emu library is a collection of video game music file emulators.
|
||||||
|
|
||||||
|
See @url{http://code.google.com/p/game-music-emu/} for more information.
|
||||||
|
|
||||||
|
Some files have multiple tracks. The demuxer will pick the first track by
|
||||||
|
default. The @option{track_index} option can be used to select a different
|
||||||
|
track. Track indexes start at 0. The demuxer exports the number of tracks as
|
||||||
|
@var{tracks} meta data entry.
|
||||||
|
|
||||||
|
For very large files, the @option{max_size} option may have to be adjusted.
|
||||||
|
|
||||||
@section gif
|
@section gif
|
||||||
|
|
||||||
Animated GIF demuxer.
|
Animated GIF demuxer.
|
||||||
@@ -343,52 +306,6 @@ used to end the output video at the length of the shortest input file,
|
|||||||
which in this case is @file{input.mp4} as the GIF in this example loops
|
which in this case is @file{input.mp4} as the GIF in this example loops
|
||||||
infinitely.
|
infinitely.
|
||||||
|
|
||||||
@section hls
|
|
||||||
|
|
||||||
HLS demuxer
|
|
||||||
|
|
||||||
Apple HTTP Live Streaming demuxer.
|
|
||||||
|
|
||||||
This demuxer presents all AVStreams from all variant streams.
|
|
||||||
The id field is set to the bitrate variant index number. By setting
|
|
||||||
the discard flags on AVStreams (by pressing 'a' or 'v' in ffplay),
|
|
||||||
the caller can decide which variant streams to actually receive.
|
|
||||||
The total bitrate of the variant that the stream belongs to is
|
|
||||||
available in a metadata key named "variant_bitrate".
|
|
||||||
|
|
||||||
It accepts the following options:
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item live_start_index
|
|
||||||
segment index to start live streams at (negative values are from the end).
|
|
||||||
|
|
||||||
@item allowed_extensions
|
|
||||||
',' separated list of file extensions that hls is allowed to access.
|
|
||||||
|
|
||||||
@item max_reload
|
|
||||||
Maximum number of times a insufficient list is attempted to be reloaded.
|
|
||||||
Default value is 1000.
|
|
||||||
|
|
||||||
@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.
|
|
||||||
|
|
||||||
@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
|
@section image2
|
||||||
|
|
||||||
Image file demuxer.
|
Image file demuxer.
|
||||||
@@ -497,17 +414,6 @@ nanosecond precision.
|
|||||||
@item video_size
|
@item video_size
|
||||||
Set the video size of the images to read. If not specified the video
|
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.
|
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
|
@end table
|
||||||
|
|
||||||
@subsection Examples
|
@subsection Examples
|
||||||
@@ -535,123 +441,9 @@ ffmpeg -framerate 10 -pattern_type glob -i "*.png" out.mkv
|
|||||||
@end example
|
@end example
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@section libgme
|
@section mov/mp4/3gp/QuickTime
|
||||||
|
|
||||||
The Game Music Emu library is a collection of video game music file emulators.
|
QuickTime / MP4 demuxer.
|
||||||
|
|
||||||
See @url{https://bitbucket.org/mpyne/game-music-emu/overview} for more information.
|
|
||||||
|
|
||||||
It accepts the following options:
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
|
|
||||||
@item track_index
|
|
||||||
Set the index of which track to demux. The demuxer can only export one track.
|
|
||||||
Track indexes start at 0. Default is to pick the first track. Number of tracks
|
|
||||||
is exported as @var{tracks} metadata entry.
|
|
||||||
|
|
||||||
@item sample_rate
|
|
||||||
Set the sampling rate of the exported track. Range is 1000 to 999999. Default is 44100.
|
|
||||||
|
|
||||||
@item max_size @emph{(bytes)}
|
|
||||||
The demuxer buffers the entire file into memory. Adjust this value to set the maximum buffer size,
|
|
||||||
which in turn, acts as a ceiling for the size of files that can be read.
|
|
||||||
Default is 50 MiB.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section libmodplug
|
|
||||||
|
|
||||||
ModPlug based module demuxer
|
|
||||||
|
|
||||||
See @url{https://github.com/Konstanty/libmodplug}
|
|
||||||
|
|
||||||
It will export one 2-channel 16-bit 44.1 kHz audio stream.
|
|
||||||
Optionally, a @code{pal8} 16-color video stream can be exported with or without printed metadata.
|
|
||||||
|
|
||||||
It accepts the following options:
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item noise_reduction
|
|
||||||
Apply a simple low-pass filter. Can be 1 (on) or 0 (off). Default is 0.
|
|
||||||
|
|
||||||
@item reverb_depth
|
|
||||||
Set amount of reverb. Range 0-100. Default is 0.
|
|
||||||
|
|
||||||
@item reverb_delay
|
|
||||||
Set delay in ms, clamped to 40-250 ms. Default is 0.
|
|
||||||
|
|
||||||
@item bass_amount
|
|
||||||
Apply bass expansion a.k.a. XBass or megabass. Range is 0 (quiet) to 100 (loud). Default is 0.
|
|
||||||
|
|
||||||
@item bass_range
|
|
||||||
Set cutoff i.e. upper-bound for bass frequencies. Range is 10-100 Hz. Default is 0.
|
|
||||||
|
|
||||||
@item surround_depth
|
|
||||||
Apply a Dolby Pro-Logic surround effect. Range is 0 (quiet) to 100 (heavy). Default is 0.
|
|
||||||
|
|
||||||
@item surround_delay
|
|
||||||
Set surround delay in ms, clamped to 5-40 ms. Default is 0.
|
|
||||||
|
|
||||||
@item max_size
|
|
||||||
The demuxer buffers the entire file into memory. Adjust this value to set the maximum buffer size,
|
|
||||||
which in turn, acts as a ceiling for the size of files that can be read. Range is 0 to 100 MiB.
|
|
||||||
0 removes buffer size limit (not recommended). Default is 5 MiB.
|
|
||||||
|
|
||||||
@item video_stream_expr
|
|
||||||
String which is evaluated using the eval API to assign colors to the generated video stream.
|
|
||||||
Variables which can be used are @code{x}, @code{y}, @code{w}, @code{h}, @code{t}, @code{speed},
|
|
||||||
@code{tempo}, @code{order}, @code{pattern} and @code{row}.
|
|
||||||
|
|
||||||
@item video_stream
|
|
||||||
Generate video stream. Can be 1 (on) or 0 (off). Default is 0.
|
|
||||||
|
|
||||||
@item video_stream_w
|
|
||||||
Set video frame width in 'chars' where one char indicates 8 pixels. Range is 20-512. Default is 30.
|
|
||||||
|
|
||||||
@item video_stream_h
|
|
||||||
Set video frame height in 'chars' where one char indicates 8 pixels. Range is 20-512. Default is 30.
|
|
||||||
|
|
||||||
@item video_stream_ptxt
|
|
||||||
Print metadata on video stream. Includes @code{speed}, @code{tempo}, @code{order}, @code{pattern},
|
|
||||||
@code{row} and @code{ts} (time in ms). Can be 1 (on) or 0 (off). Default is 1.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section libopenmpt
|
|
||||||
|
|
||||||
libopenmpt based module demuxer
|
|
||||||
|
|
||||||
See @url{https://lib.openmpt.org/libopenmpt/} for more information.
|
|
||||||
|
|
||||||
Some files have multiple subsongs (tracks) this can be set with the @option{subsong}
|
|
||||||
option.
|
|
||||||
|
|
||||||
It accepts the following options:
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item subsong
|
|
||||||
Set the subsong index. This can be either 'all', 'auto', or the index of the
|
|
||||||
subsong. Subsong indexes start at 0. The default is 'auto'.
|
|
||||||
|
|
||||||
The default value is to let libopenmpt choose.
|
|
||||||
|
|
||||||
@item layout
|
|
||||||
Set the channel layout. Valid values are 1, 2, and 4 channel layouts.
|
|
||||||
The default value is STEREO.
|
|
||||||
|
|
||||||
@item sample_rate
|
|
||||||
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
|
|
||||||
|
|
||||||
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:
|
This demuxer accepts the following options:
|
||||||
@table @option
|
@table @option
|
||||||
@@ -662,88 +454,10 @@ Enabling this can theoretically leak information in some use cases.
|
|||||||
@item use_absolute_path
|
@item use_absolute_path
|
||||||
Allows loading of external tracks via absolute paths, disabled by default.
|
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
|
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
|
@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
|
@section mpegts
|
||||||
|
|
||||||
MPEG-2 transport stream demuxer.
|
MPEG-2 transport stream demuxer.
|
||||||
@@ -754,9 +468,6 @@ This demuxer accepts the following options:
|
|||||||
Set size limit for looking up a new synchronization. Default value is
|
Set size limit for looking up a new synchronization. Default value is
|
||||||
65536.
|
65536.
|
||||||
|
|
||||||
@item skip_unknown_pmt
|
|
||||||
Skip PMTs for programs not defined in the PAT. Default value is 0.
|
|
||||||
|
|
||||||
@item fix_teletext_pts
|
@item fix_teletext_pts
|
||||||
Override teletext packet PTS and DTS values with the timestamps calculated
|
Override teletext packet PTS and DTS values with the timestamps calculated
|
||||||
from the PCR of the first program which the teletext stream is part of and is
|
from the PCR of the first program which the teletext stream is part of and is
|
||||||
@@ -771,10 +482,6 @@ Show the detected raw packet size, cannot be set by the user.
|
|||||||
Scan and combine all PMTs. The value is an integer with value from -1
|
Scan and combine all PMTs. The value is an integer with value from -1
|
||||||
to 1 (-1 means automatic setting, 1 means enabled, 0 means
|
to 1 (-1 means automatic setting, 1 means enabled, 0 means
|
||||||
disabled). Default value is -1.
|
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.
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@section mpjpeg
|
@section mpjpeg
|
||||||
@@ -872,20 +579,4 @@ Example: convert the captions to a format most players understand:
|
|||||||
ffmpeg -i http://www.ted.com/talks/subtitles/id/1/lang/en talk1-en.srt
|
ffmpeg -i http://www.ted.com/talks/subtitles/id/1/lang/en talk1-en.srt
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@section vapoursynth
|
|
||||||
|
|
||||||
Vapoursynth wrapper.
|
|
||||||
|
|
||||||
Due to security concerns, Vapoursynth scripts will not
|
|
||||||
be autodetected so the input format has to be forced. For ff* CLI tools,
|
|
||||||
add @code{-f vapoursynth} before the input @code{-i yourscript.vpy}.
|
|
||||||
|
|
||||||
This demuxer accepts the following option:
|
|
||||||
@table @option
|
|
||||||
@item max_script_size
|
|
||||||
The demuxer buffers the entire script into memory. Adjust this value to set the maximum buffer size,
|
|
||||||
which in turn, acts as a ceiling for the size of scripts that can be read.
|
|
||||||
Default is 1 MiB.
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@c man end DEMUXERS
|
@c man end DEMUXERS
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
# 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.
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
# 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.
|
|
||||||
|
|
||||||
@@ -10,7 +10,9 @@
|
|||||||
|
|
||||||
@contents
|
@contents
|
||||||
|
|
||||||
@chapter Notes for external developers
|
@chapter Developers Guide
|
||||||
|
|
||||||
|
@section Notes for external developers
|
||||||
|
|
||||||
This document is mostly useful for internal FFmpeg developers.
|
This document is mostly useful for internal FFmpeg developers.
|
||||||
External developers who need to use the API in their application should
|
External developers who need to use the API in their application should
|
||||||
@@ -28,13 +30,15 @@ For more detailed legal information about the use of FFmpeg in
|
|||||||
external programs read the @file{LICENSE} file in the source tree and
|
external programs read the @file{LICENSE} file in the source tree and
|
||||||
consult @url{https://ffmpeg.org/legal.html}.
|
consult @url{https://ffmpeg.org/legal.html}.
|
||||||
|
|
||||||
@chapter Contributing
|
@section Contributing
|
||||||
|
|
||||||
There are 2 ways by which code gets into FFmpeg:
|
There are 3 ways by which code gets into FFmpeg.
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item Submitting patches to the ffmpeg-devel mailing list.
|
@item Submitting patches to the main developer mailing list.
|
||||||
See @ref{Submitting patches} for details.
|
See @ref{Submitting patches} for details.
|
||||||
@item Directly committing changes to the main tree.
|
@item Directly committing changes to the main tree.
|
||||||
|
@item Committing changes to a git clone, for example on github.com or
|
||||||
|
gitorious.org. And asking us to merge these changes.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
Whichever way, changes should be reviewed by the maintainer of the code
|
Whichever way, changes should be reviewed by the maintainer of the code
|
||||||
@@ -43,9 +47,9 @@ The developer making the commit and the author are responsible for their changes
|
|||||||
and should try to fix issues their commit causes.
|
and should try to fix issues their commit causes.
|
||||||
|
|
||||||
@anchor{Coding Rules}
|
@anchor{Coding Rules}
|
||||||
@chapter Coding Rules
|
@section Coding Rules
|
||||||
|
|
||||||
@section Code formatting conventions
|
@subsection Code formatting conventions
|
||||||
|
|
||||||
There are the following guidelines regarding the indentation in files:
|
There are the following guidelines regarding the indentation in files:
|
||||||
|
|
||||||
@@ -70,7 +74,7 @@ The presentation is one inspired by 'indent -i4 -kr -nut'.
|
|||||||
The main priority in FFmpeg is simplicity and small code size in order to
|
The main priority in FFmpeg is simplicity and small code size in order to
|
||||||
minimize the bug count.
|
minimize the bug count.
|
||||||
|
|
||||||
@section Comments
|
@subsection Comments
|
||||||
Use the JavaDoc/Doxygen format (see examples below) so that code documentation
|
Use the JavaDoc/Doxygen format (see examples below) so that code documentation
|
||||||
can be generated automatically. All nontrivial functions should have a comment
|
can be generated automatically. All nontrivial functions should have a comment
|
||||||
above them explaining what the function does, even if it is just one sentence.
|
above them explaining what the function does, even if it is just one sentence.
|
||||||
@@ -110,7 +114,7 @@ int myfunc(int my_parameter)
|
|||||||
...
|
...
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@section C language features
|
@subsection C language features
|
||||||
|
|
||||||
FFmpeg is programmed in the ISO C90 language with a few additional
|
FFmpeg is programmed in the ISO C90 language with a few additional
|
||||||
features from ISO C99, namely:
|
features from ISO C99, namely:
|
||||||
@@ -127,17 +131,6 @@ designated struct initializers (@samp{struct s x = @{ .i = 17 @};});
|
|||||||
|
|
||||||
@item
|
@item
|
||||||
compound literals (@samp{x = (struct s) @{ 17, 23 @};}).
|
compound literals (@samp{x = (struct s) @{ 17, 23 @};}).
|
||||||
|
|
||||||
@item
|
|
||||||
for loops with variable definition (@samp{for (int i = 0; i < 8; i++)});
|
|
||||||
|
|
||||||
@item
|
|
||||||
Variadic macros (@samp{#define ARRAY(nb, ...) (int[nb + 1])@{ nb, __VA_ARGS__ @}});
|
|
||||||
|
|
||||||
@item
|
|
||||||
Implementation defined behavior for signed integers is assumed to match the
|
|
||||||
expected behavior for two's complement. Non representable values in integer
|
|
||||||
casts are binary truncated. Shift right of signed values uses sign extension.
|
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
These features are supported by all compilers we care about, so we will not
|
These features are supported by all compilers we care about, so we will not
|
||||||
@@ -162,7 +155,7 @@ mixing statements and declarations;
|
|||||||
GCC statement expressions (@samp{(x = (@{ int y = 4; y; @})}).
|
GCC statement expressions (@samp{(x = (@{ int y = 4; y; @})}).
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@section Naming conventions
|
@subsection Naming conventions
|
||||||
All names should be composed with underscores (_), not CamelCase. For example,
|
All names should be composed with underscores (_), not CamelCase. For example,
|
||||||
@samp{avfilter_get_video_buffer} is an acceptable function name and
|
@samp{avfilter_get_video_buffer} is an acceptable function name and
|
||||||
@samp{AVFilterGetVideo} is not. The exception from this are type names, like
|
@samp{AVFilterGetVideo} is not. The exception from this are type names, like
|
||||||
@@ -186,7 +179,7 @@ e.g. @samp{ff_w64_demuxer}.
|
|||||||
@item
|
@item
|
||||||
For variables and functions visible outside of file scope, used internally
|
For variables and functions visible outside of file scope, used internally
|
||||||
across multiple libraries, use @code{avpriv_} as prefix, for example,
|
across multiple libraries, use @code{avpriv_} as prefix, for example,
|
||||||
@samp{avpriv_report_missing_feature}.
|
@samp{avpriv_aac_parse_header}.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Each library has its own prefix for public symbols, in addition to the
|
Each library has its own prefix for public symbols, in addition to the
|
||||||
@@ -206,7 +199,7 @@ letter as they are reserved by the C standard. Names starting with @code{_}
|
|||||||
are reserved at the file level and may not be used for externally visible
|
are reserved at the file level and may not be used for externally visible
|
||||||
symbols. If in doubt, just avoid names starting with @code{_} altogether.
|
symbols. If in doubt, just avoid names starting with @code{_} altogether.
|
||||||
|
|
||||||
@section Miscellaneous conventions
|
@subsection Miscellaneous conventions
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
@@ -218,7 +211,7 @@ Casts should be used only when necessary. Unneeded parentheses
|
|||||||
should also be avoided if they don't make the code easier to understand.
|
should also be avoided if they don't make the code easier to understand.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@section Editor configuration
|
@subsection Editor configuration
|
||||||
In order to configure Vim to follow FFmpeg formatting conventions, paste
|
In order to configure Vim to follow FFmpeg formatting conventions, paste
|
||||||
the following snippet into your @file{.vimrc}:
|
the following snippet into your @file{.vimrc}:
|
||||||
@example
|
@example
|
||||||
@@ -251,10 +244,10 @@ For Emacs, add these roughly equivalent lines to your @file{.emacs.d/init.el}:
|
|||||||
(setq c-default-style "ffmpeg")
|
(setq c-default-style "ffmpeg")
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
@chapter Development Policy
|
@section Development Policy
|
||||||
|
|
||||||
@section Patches/Committing
|
@enumerate
|
||||||
@subheading Licenses for patches must be compatible with FFmpeg.
|
@item
|
||||||
Contributions should be licensed under the
|
Contributions should be licensed under the
|
||||||
@uref{http://www.gnu.org/licenses/lgpl-2.1.html, LGPL 2.1},
|
@uref{http://www.gnu.org/licenses/lgpl-2.1.html, LGPL 2.1},
|
||||||
including an "or any later version" clause, or, if you prefer
|
including an "or any later version" clause, or, if you prefer
|
||||||
@@ -267,15 +260,15 @@ preferred.
|
|||||||
If you add a new file, give it a proper license header. Do not copy and
|
If you add a new file, give it a proper license header. Do not copy and
|
||||||
paste it from a random place, use an existing file as template.
|
paste it from a random place, use an existing file as template.
|
||||||
|
|
||||||
@subheading You must not commit code which breaks FFmpeg!
|
@item
|
||||||
This means unfinished code which is enabled and breaks compilation,
|
You must not commit code which breaks FFmpeg! (Meaning unfinished but
|
||||||
or compiles but does not work/breaks the regression tests. Code which
|
enabled code which breaks compilation or compiles but does not work or
|
||||||
is unfinished but disabled may be permitted under-circumstances, like
|
breaks the regression tests)
|
||||||
missing samples or an implementation with a small subset of features.
|
You can commit unfinished stuff (for testing etc), but it must be disabled
|
||||||
Always check the mailing list for any reviewers with issues and test
|
(#ifdef etc) by default so it does not interfere with other developers'
|
||||||
FATE before you push.
|
work.
|
||||||
|
|
||||||
@subheading Keep the main commit message short with an extended description below.
|
@item
|
||||||
The commit message should have a short first line in the form of
|
The commit message should have a short first line in the form of
|
||||||
a @samp{topic: short description} as a header, separated by a newline
|
a @samp{topic: short description} as a header, separated by a newline
|
||||||
from the body consisting of an explanation of why the change is necessary.
|
from the body consisting of an explanation of why the change is necessary.
|
||||||
@@ -283,24 +276,30 @@ If the commit fixes a known bug on the bug tracker, the commit message
|
|||||||
should include its bug ID. Referring to the issue on the bug tracker does
|
should include its bug ID. Referring to the issue on the bug tracker does
|
||||||
not exempt you from writing an excerpt of the bug in the commit message.
|
not exempt you from writing an excerpt of the bug in the commit message.
|
||||||
|
|
||||||
@subheading Testing must be adequate but not excessive.
|
@item
|
||||||
If it works for you, others, and passes FATE then it should be OK to commit
|
You do not have to over-test things. If it works for you, and you think it
|
||||||
it, provided it fits the other committing criteria. You should not worry about
|
should work for others, then commit. If your code has problems
|
||||||
over-testing things. If your code has problems (portability, triggers
|
(portability, triggers compiler bugs, unusual environment etc) they will be
|
||||||
compiler bugs, unusual environment etc) they will be reported and eventually
|
reported and eventually fixed.
|
||||||
fixed.
|
|
||||||
|
|
||||||
@subheading Do not commit unrelated changes together.
|
@item
|
||||||
They should be split them into self-contained pieces. Also do not forget
|
Do not commit unrelated changes together, split them into self-contained
|
||||||
that if part B depends on part A, but A does not depend on B, then A can
|
pieces. Also do not forget that if part B depends on part A, but A does not
|
||||||
and should be committed first and separate from B. Keeping changes well
|
depend on B, then A can and should be committed first and separate from B.
|
||||||
split into self-contained parts makes reviewing and understanding them on
|
Keeping changes well split into self-contained parts makes reviewing and
|
||||||
the commit log mailing list easier. This also helps in case of debugging
|
understanding them on the commit log mailing list easier. This also helps
|
||||||
later on.
|
in case of debugging later on.
|
||||||
Also if you have doubts about splitting or not splitting, do not hesitate to
|
Also if you have doubts about splitting or not splitting, do not hesitate to
|
||||||
ask/discuss it on the developer mailing list.
|
ask/discuss it on the developer mailing list.
|
||||||
|
|
||||||
@subheading Ask before you change the build system (configure, etc).
|
@item
|
||||||
|
Do not change behavior of the programs (renaming options etc) or public
|
||||||
|
API or ABI without first discussing it on the ffmpeg-devel mailing list.
|
||||||
|
Do not remove functionality from the code. Just improve!
|
||||||
|
|
||||||
|
Note: Redundant code can be removed.
|
||||||
|
|
||||||
|
@item
|
||||||
Do not commit changes to the build system (Makefiles, configure script)
|
Do not commit changes to the build system (Makefiles, configure script)
|
||||||
which change behavior, defaults etc, without asking first. The same
|
which change behavior, defaults etc, without asking first. The same
|
||||||
applies to compiler warning fixes, trivial looking fixes and to code
|
applies to compiler warning fixes, trivial looking fixes and to code
|
||||||
@@ -309,7 +308,7 @@ the way we do. Send your changes as patches to the ffmpeg-devel mailing
|
|||||||
list, and if the code maintainers say OK, you may commit. This does not
|
list, and if the code maintainers say OK, you may commit. This does not
|
||||||
apply to files you wrote and/or maintain.
|
apply to files you wrote and/or maintain.
|
||||||
|
|
||||||
@subheading Cosmetic changes should be kept in separate patches.
|
@item
|
||||||
We refuse source indentation and other cosmetic changes if they are mixed
|
We refuse source indentation and other cosmetic changes if they are mixed
|
||||||
with functional changes, such commits will be rejected and removed. Every
|
with functional changes, such commits will be rejected and removed. Every
|
||||||
developer has his own indentation style, you should not change it. Of course
|
developer has his own indentation style, you should not change it. Of course
|
||||||
@@ -323,7 +322,7 @@ NOTE: If you had to put if()@{ .. @} over a large (> 5 lines) chunk of code,
|
|||||||
then either do NOT change the indentation of the inner part within (do not
|
then either do NOT change the indentation of the inner part within (do not
|
||||||
move it to the right)! or do so in a separate commit
|
move it to the right)! or do so in a separate commit
|
||||||
|
|
||||||
@subheading Commit messages should always be filled out properly.
|
@item
|
||||||
Always fill out the commit log message. Describe in a few lines what you
|
Always fill out the commit log message. Describe in a few lines what you
|
||||||
changed and why. You can refer to mailing list postings if you fix a
|
changed and why. You can refer to mailing list postings if you fix a
|
||||||
particular bug. Comments such as "fixed!" or "Changed it." are unacceptable.
|
particular bug. Comments such as "fixed!" or "Changed it." are unacceptable.
|
||||||
@@ -335,31 +334,47 @@ area changed: Short 1 line description
|
|||||||
details describing what and why and giving references.
|
details describing what and why and giving references.
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@subheading Credit the author of the patch.
|
@item
|
||||||
Make sure the author of the commit is set correctly. (see git commit --author)
|
Make sure the author of the commit is set correctly. (see git commit --author)
|
||||||
If you apply a patch, send an
|
If you apply a patch, send an
|
||||||
answer to ffmpeg-devel (or wherever you got the patch from) saying that
|
answer to ffmpeg-devel (or wherever you got the patch from) saying that
|
||||||
you applied the patch.
|
you applied the patch.
|
||||||
|
|
||||||
@subheading Complex patches should refer to discussion surrounding them.
|
@item
|
||||||
When applying patches that have been discussed (at length) on the mailing
|
When applying patches that have been discussed (at length) on the mailing
|
||||||
list, reference the thread in the log message.
|
list, reference the thread in the log message.
|
||||||
|
|
||||||
@subheading Always wait long enough before pushing changes
|
@item
|
||||||
Do NOT commit to code actively maintained by others without permission.
|
Do NOT commit to code actively maintained by others without permission.
|
||||||
Send a patch to ffmpeg-devel. If no one answers within a reasonable
|
Send a patch to ffmpeg-devel instead. If no one answers within a reasonable
|
||||||
time-frame (12h for build failures and security fixes, 3 days small changes,
|
timeframe (12h for build failures and security fixes, 3 days small changes,
|
||||||
1 week for big patches) then commit your patch if you think it is OK.
|
1 week for big patches) then commit your patch if you think it is OK.
|
||||||
Also note, the maintainer can simply ask for more time to review!
|
Also note, the maintainer can simply ask for more time to review!
|
||||||
|
|
||||||
@section Code
|
@item
|
||||||
@subheading API/ABI changes should be discussed before they are made.
|
Subscribe to the ffmpeg-cvslog mailing list. The diffs of all commits
|
||||||
Do not change behavior of the programs (renaming options etc) or public
|
are sent there and reviewed by all the other developers. Bugs and possible
|
||||||
API or ABI without first discussing it on the ffmpeg-devel mailing list.
|
improvements or general questions regarding commits are discussed there. We
|
||||||
Do not remove widely used functionality or features (redundant code can be removed).
|
expect you to react if problems with your code are uncovered.
|
||||||
|
|
||||||
@subheading Remember to check if you need to bump versions for libav*.
|
@item
|
||||||
Depending on the change, you may need to change the version integer.
|
Update the documentation if you change behavior or add features. If you are
|
||||||
|
unsure how best to do this, send a patch to ffmpeg-devel, the documentation
|
||||||
|
maintainer(s) will review and commit your stuff.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Try to keep important discussions and requests (also) on the public
|
||||||
|
developer mailing list, so that all developers can benefit from them.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Never write to unallocated memory, never write over the end of arrays,
|
||||||
|
always check values read from some untrusted source before using them
|
||||||
|
as array index or other risky things.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Remember to check if you need to bump versions for the specific libav*
|
||||||
|
parts (libavutil, libavcodec, libavformat) you are changing. You need
|
||||||
|
to change the version integer.
|
||||||
Incrementing the first component means no backward compatibility to
|
Incrementing the first component means no backward compatibility to
|
||||||
previous versions (e.g. removal of a function from the public API).
|
previous versions (e.g. removal of a function from the public API).
|
||||||
Incrementing the second component means backward compatible change
|
Incrementing the second component means backward compatible change
|
||||||
@@ -369,7 +384,7 @@ Incrementing the third component means a noteworthy binary compatible
|
|||||||
change (e.g. encoder bug fix that matters for the decoder). The third
|
change (e.g. encoder bug fix that matters for the decoder). The third
|
||||||
component always starts at 100 to distinguish FFmpeg from Libav.
|
component always starts at 100 to distinguish FFmpeg from Libav.
|
||||||
|
|
||||||
@subheading Warnings for correct code may be disabled if there is no other option.
|
@item
|
||||||
Compiler warnings indicate potential bugs or code with bad style. If a type of
|
Compiler warnings indicate potential bugs or code with bad style. If a type of
|
||||||
warning always points to correct and clean code, that warning should
|
warning always points to correct and clean code, that warning should
|
||||||
be disabled, not the code changed.
|
be disabled, not the code changed.
|
||||||
@@ -378,54 +393,17 @@ If it is a bug, the bug has to be fixed. If it is not, the code should
|
|||||||
be changed to not generate a warning unless that causes a slowdown
|
be changed to not generate a warning unless that causes a slowdown
|
||||||
or obfuscates the code.
|
or obfuscates the code.
|
||||||
|
|
||||||
@subheading Check untrusted input properly.
|
@item
|
||||||
Never write to unallocated memory, never write over the end of arrays,
|
|
||||||
always check values read from some untrusted source before using them
|
|
||||||
as array index or other risky things.
|
|
||||||
|
|
||||||
@section Documentation/Other
|
|
||||||
@subheading Subscribe to the ffmpeg-devel mailing list.
|
|
||||||
It is important to be subscribed to the
|
|
||||||
@uref{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel, ffmpeg-devel}
|
|
||||||
mailing list. Almost any non-trivial patch is to be sent there for review.
|
|
||||||
Other developers may have comments about your contribution. We expect you see
|
|
||||||
those comments, and to improve it if requested. (N.B. Experienced committers
|
|
||||||
have other channels, and may sometimes skip review for trivial fixes.) Also,
|
|
||||||
discussion here about bug fixes and FFmpeg improvements by other developers may
|
|
||||||
be helpful information for you. Finally, by being a list subscriber, your
|
|
||||||
contribution will be posted immediately to the list, without the moderation
|
|
||||||
hold which messages from non-subscribers experience.
|
|
||||||
|
|
||||||
However, it is more important to the project that we receive your patch than
|
|
||||||
that you be subscribed to the ffmpeg-devel list. If you have a patch, and don't
|
|
||||||
want to subscribe and discuss the patch, then please do send it to the list
|
|
||||||
anyway.
|
|
||||||
|
|
||||||
@subheading Subscribe to the ffmpeg-cvslog mailing list.
|
|
||||||
Diffs of all commits are sent to the
|
|
||||||
@uref{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-cvslog, ffmpeg-cvslog}
|
|
||||||
mailing list. Some developers read this list to review all code base changes
|
|
||||||
from all sources. Subscribing to this list is not mandatory.
|
|
||||||
|
|
||||||
@subheading Keep the documentation up to date.
|
|
||||||
Update the documentation if you change behavior or add features. If you are
|
|
||||||
unsure how best to do this, send a patch to ffmpeg-devel, the documentation
|
|
||||||
maintainer(s) will review and commit your stuff.
|
|
||||||
|
|
||||||
@subheading Important discussions should be accessible to all.
|
|
||||||
Try to keep important discussions and requests (also) on the public
|
|
||||||
developer mailing list, so that all developers can benefit from them.
|
|
||||||
|
|
||||||
@subheading Check your entries in MAINTAINERS.
|
|
||||||
Make sure that no parts of the codebase that you maintain are missing from the
|
Make sure that no parts of the codebase that you maintain are missing from the
|
||||||
@file{MAINTAINERS} file. If something that you want to maintain is missing add it with
|
@file{MAINTAINERS} file. If something that you want to maintain is missing add it with
|
||||||
your name after it.
|
your name after it.
|
||||||
If at some point you no longer want to maintain some code, then please help in
|
If at some point you no longer want to maintain some code, then please help in
|
||||||
finding a new maintainer and also don't forget to update the @file{MAINTAINERS} file.
|
finding a new maintainer and also don't forget to update the @file{MAINTAINERS} file.
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
We think our rules are not too hard. If you have comments, contact us.
|
We think our rules are not too hard. If you have comments, contact us.
|
||||||
|
|
||||||
@chapter Code of conduct
|
@section Code of conduct
|
||||||
|
|
||||||
Be friendly and respectful towards others and third parties.
|
Be friendly and respectful towards others and third parties.
|
||||||
Treat others the way you yourself want to be treated.
|
Treat others the way you yourself want to be treated.
|
||||||
@@ -455,7 +433,7 @@ Finally, keep in mind the immortal words of Bill and Ted,
|
|||||||
"Be excellent to each other."
|
"Be excellent to each other."
|
||||||
|
|
||||||
@anchor{Submitting patches}
|
@anchor{Submitting patches}
|
||||||
@chapter Submitting patches
|
@section Submitting patches
|
||||||
|
|
||||||
First, read the @ref{Coding Rules} above if you did not yet, in particular
|
First, read the @ref{Coding Rules} above if you did not yet, in particular
|
||||||
the rules regarding patch submission.
|
the rules regarding patch submission.
|
||||||
@@ -488,28 +466,8 @@ Patches should be posted to the
|
|||||||
mailing list. Use @code{git send-email} when possible since it will properly
|
mailing list. Use @code{git send-email} when possible since it will properly
|
||||||
send patches without requiring extra care. If you cannot, then send patches
|
send patches without requiring extra care. If you cannot, then send patches
|
||||||
as base64-encoded attachments, so your patch is not trashed during
|
as base64-encoded attachments, so your patch is not trashed during
|
||||||
transmission. Also ensure the correct mime type is used
|
transmission.
|
||||||
(text/x-diff or text/x-patch or at least text/plain) and that only one
|
|
||||||
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
|
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
|
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
|
incorporates the requests from the review. This process may go through
|
||||||
@@ -520,7 +478,7 @@ Give us a few days to react. But if some time passes without reaction,
|
|||||||
send a reminder by email. Your patch should eventually be dealt with.
|
send a reminder by email. Your patch should eventually be dealt with.
|
||||||
|
|
||||||
|
|
||||||
@chapter New codecs or formats checklist
|
@section New codecs or formats checklist
|
||||||
|
|
||||||
@enumerate
|
@enumerate
|
||||||
@item
|
@item
|
||||||
@@ -572,7 +530,7 @@ Did you make sure it compiles standalone, i.e. with
|
|||||||
@end enumerate
|
@end enumerate
|
||||||
|
|
||||||
|
|
||||||
@chapter Patch submission checklist
|
@section patch submission checklist
|
||||||
|
|
||||||
@enumerate
|
@enumerate
|
||||||
@item
|
@item
|
||||||
@@ -582,9 +540,9 @@ Does @code{make fate} pass with the patch applied?
|
|||||||
Was the patch generated with git format-patch or send-email?
|
Was the patch generated with git format-patch or send-email?
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Did you sign-off your patch? (@code{git commit -s})
|
Did you sign off your patch? (git commit -s)
|
||||||
See @uref{https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/process/submitting-patches.rst, Sign your work} for the meaning
|
See @url{http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob_plain;f=Documentation/SubmittingPatches} for the meaning
|
||||||
of @dfn{sign-off}.
|
of sign off.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Did you provide a clear git commit log message?
|
Did you provide a clear git commit log message?
|
||||||
@@ -641,7 +599,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
|
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?
|
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
|
Note please do not attach samples >100k to mails but rather provide a
|
||||||
URL, you can upload to @url{https://streams.videolan.org/upload/}.
|
URL, you can upload to ftp://upload.ffmpeg.org.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Did you provide a verbose summary about what the patch does change?
|
Did you provide a verbose summary about what the patch does change?
|
||||||
@@ -685,7 +643,7 @@ Test your code with valgrind and or Address Sanitizer to ensure it's free
|
|||||||
of leaks, out of array accesses, etc.
|
of leaks, out of array accesses, etc.
|
||||||
@end enumerate
|
@end enumerate
|
||||||
|
|
||||||
@chapter Patch review process
|
@section Patch review process
|
||||||
|
|
||||||
All patches posted to ffmpeg-devel will be reviewed, unless they contain a
|
All patches posted to ffmpeg-devel will be reviewed, unless they contain a
|
||||||
clear note that the patch is not for the git master branch.
|
clear note that the patch is not for the git master branch.
|
||||||
@@ -716,7 +674,7 @@ to be reviewed, please consider helping to review other patches, that is a great
|
|||||||
way to get everyone's patches reviewed sooner.
|
way to get everyone's patches reviewed sooner.
|
||||||
|
|
||||||
@anchor{Regression tests}
|
@anchor{Regression tests}
|
||||||
@chapter Regression tests
|
@section Regression tests
|
||||||
|
|
||||||
Before submitting a patch (or committing to the repository), you should at least
|
Before submitting a patch (or committing to the repository), you should at least
|
||||||
test that you did not break anything.
|
test that you did not break anything.
|
||||||
@@ -727,7 +685,7 @@ Running 'make fate' accomplishes this, please see @url{fate.html} for details.
|
|||||||
this case, the reference results of the regression tests shall be modified
|
this case, the reference results of the regression tests shall be modified
|
||||||
accordingly].
|
accordingly].
|
||||||
|
|
||||||
@section Adding files to the fate-suite dataset
|
@subsection Adding files to the fate-suite dataset
|
||||||
|
|
||||||
When there is no muxer or encoder available to generate test media for a
|
When there is no muxer or encoder available to generate test media for a
|
||||||
specific test then the media has to be included in the fate-suite.
|
specific test then the media has to be included in the fate-suite.
|
||||||
@@ -738,7 +696,7 @@ Once you have a working fate test and fate sample, provide in the commit
|
|||||||
message or introductory message for the patch series that you post to
|
message or introductory message for the patch series that you post to
|
||||||
the ffmpeg-devel mailing list, a direct link to download the sample media.
|
the ffmpeg-devel mailing list, a direct link to download the sample media.
|
||||||
|
|
||||||
@section Visualizing Test Coverage
|
@subsection Visualizing Test Coverage
|
||||||
|
|
||||||
The FFmpeg build system allows visualizing the test coverage in an easy
|
The FFmpeg build system allows visualizing the test coverage in an easy
|
||||||
manner with the coverage tools @code{gcov}/@code{lcov}. This involves
|
manner with the coverage tools @code{gcov}/@code{lcov}. This involves
|
||||||
@@ -765,7 +723,7 @@ You can use the command @code{make lcov-reset} to reset the coverage
|
|||||||
measurements. You will need to rerun @code{make lcov} after running a
|
measurements. You will need to rerun @code{make lcov} after running a
|
||||||
new test.
|
new test.
|
||||||
|
|
||||||
@section Using Valgrind
|
@subsection Using Valgrind
|
||||||
|
|
||||||
The configure script provides a shortcut for using valgrind to spot bugs
|
The configure script provides a shortcut for using valgrind to spot bugs
|
||||||
related to memory handling. Just add the option
|
related to memory handling. Just add the option
|
||||||
@@ -779,7 +737,7 @@ In case you need finer control over how valgrind is invoked, use the
|
|||||||
your configure line instead.
|
your configure line instead.
|
||||||
|
|
||||||
@anchor{Release process}
|
@anchor{Release process}
|
||||||
@chapter Release process
|
@section Release process
|
||||||
|
|
||||||
FFmpeg maintains a set of @strong{release branches}, which are the
|
FFmpeg maintains a set of @strong{release branches}, which are the
|
||||||
recommended deliverable for system integrators and distributors (such as
|
recommended deliverable for system integrators and distributors (such as
|
||||||
@@ -811,7 +769,7 @@ adjustments to the symbol versioning file. Please discuss such changes
|
|||||||
on the @strong{ffmpeg-devel} mailing list in time to allow forward planning.
|
on the @strong{ffmpeg-devel} mailing list in time to allow forward planning.
|
||||||
|
|
||||||
@anchor{Criteria for Point Releases}
|
@anchor{Criteria for Point Releases}
|
||||||
@section Criteria for Point Releases
|
@subsection Criteria for Point Releases
|
||||||
|
|
||||||
Changes that match the following criteria are valid candidates for
|
Changes that match the following criteria are valid candidates for
|
||||||
inclusion into a point release:
|
inclusion into a point release:
|
||||||
@@ -835,7 +793,7 @@ point releases of the same release branch.
|
|||||||
The order for checking the rules is (1 OR 2 OR 3) AND 4.
|
The order for checking the rules is (1 OR 2 OR 3) AND 4.
|
||||||
|
|
||||||
|
|
||||||
@section Release Checklist
|
@subsection Release Checklist
|
||||||
|
|
||||||
The release process involves the following steps:
|
The release process involves the following steps:
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
OUT_DIR="${1}"
|
OUT_DIR="${1}"
|
||||||
SRC_DIR="${2}"
|
DOXYFILE="${2}"
|
||||||
DOXYFILE="${3}"
|
DOXYGEN="${3}"
|
||||||
DOXYGEN="${4}"
|
|
||||||
|
|
||||||
shift 4
|
shift 3
|
||||||
|
|
||||||
cd ${SRC_DIR}
|
|
||||||
|
|
||||||
if [ -e "VERSION" ]; then
|
if [ -e "VERSION" ]; then
|
||||||
VERSION=`cat "VERSION"`
|
VERSION=`cat "VERSION"`
|
||||||
|
|||||||
1526
doc/encoders.texi
1526
doc/encoders.texi
File diff suppressed because it is too large
Load Diff
12
doc/examples/.gitignore
vendored
12
doc/examples/.gitignore
vendored
@@ -1,24 +1,16 @@
|
|||||||
/avio_list_dir
|
/avio_dir_cmd
|
||||||
/avio_reading
|
/avio_reading
|
||||||
/decode_audio
|
/decoding_encoding
|
||||||
/decode_video
|
|
||||||
/demuxing_decoding
|
/demuxing_decoding
|
||||||
/encode_audio
|
|
||||||
/encode_video
|
|
||||||
/extract_mvs
|
/extract_mvs
|
||||||
/filter_audio
|
/filter_audio
|
||||||
/filtering_audio
|
/filtering_audio
|
||||||
/filtering_video
|
/filtering_video
|
||||||
/http_multiclient
|
|
||||||
/hw_decode
|
|
||||||
/metadata
|
/metadata
|
||||||
/muxing
|
/muxing
|
||||||
/pc-uninstalled
|
/pc-uninstalled
|
||||||
/qsvdec
|
|
||||||
/remuxing
|
/remuxing
|
||||||
/resampling_audio
|
/resampling_audio
|
||||||
/scaling_video
|
/scaling_video
|
||||||
/transcode_aac
|
/transcode_aac
|
||||||
/transcoding
|
/transcoding
|
||||||
/vaapi_encode
|
|
||||||
/vaapi_transcode
|
|
||||||
|
|||||||
@@ -1,64 +1,46 @@
|
|||||||
EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir
|
# use pkg-config for getting CFLAGS and LDLIBS
|
||||||
EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading
|
FFMPEG_LIBS= libavdevice \
|
||||||
EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio
|
libavformat \
|
||||||
EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video
|
libavfilter \
|
||||||
EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
|
libavcodec \
|
||||||
EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio
|
libswresample \
|
||||||
EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video
|
libswscale \
|
||||||
EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE) += extract_mvs
|
libavutil \
|
||||||
EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio
|
|
||||||
EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE) += filtering_audio
|
|
||||||
EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE) += filtering_video
|
|
||||||
EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE) += http_multiclient
|
|
||||||
EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode
|
|
||||||
EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata
|
|
||||||
EXAMPLES-$(CONFIG_MUXING_EXAMPLE) += muxing
|
|
||||||
EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec
|
|
||||||
EXAMPLES-$(CONFIG_REMUXING_EXAMPLE) += remuxing
|
|
||||||
EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio
|
|
||||||
EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
|
|
||||||
EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
|
|
||||||
EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE) += transcoding
|
|
||||||
EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE) += vaapi_encode
|
|
||||||
EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE) += vaapi_transcode
|
|
||||||
|
|
||||||
EXAMPLES := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
|
CFLAGS += -Wall -g
|
||||||
EXAMPLES_G := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
|
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
|
||||||
ALL_EXAMPLES := $(EXAMPLES) $(EXAMPLES-:%=doc/examples/%$(PROGSSUF)$(EXESUF))
|
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
|
||||||
ALL_EXAMPLES_G := $(EXAMPLES_G) $(EXAMPLES-:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
|
|
||||||
PROGS += $(EXAMPLES)
|
|
||||||
|
|
||||||
EXAMPLE_MAKEFILE := $(SRC_PATH)/doc/examples/Makefile
|
EXAMPLES= avio_dir_cmd \
|
||||||
EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/README $(EXAMPLE_MAKEFILE)
|
avio_reading \
|
||||||
|
decoding_encoding \
|
||||||
|
demuxing_decoding \
|
||||||
|
extract_mvs \
|
||||||
|
filtering_video \
|
||||||
|
filtering_audio \
|
||||||
|
http_multiclient \
|
||||||
|
metadata \
|
||||||
|
muxing \
|
||||||
|
remuxing \
|
||||||
|
resampling_audio \
|
||||||
|
scaling_video \
|
||||||
|
transcode_aac \
|
||||||
|
transcoding \
|
||||||
|
|
||||||
$(foreach P,$(EXAMPLES),$(eval OBJS-$(P:%$(PROGSSUF)$(EXESUF)=%) = $(P:%$(PROGSSUF)$(EXESUF)=%).o))
|
OBJS=$(addsuffix .o,$(EXAMPLES))
|
||||||
$(EXAMPLES_G): %$(PROGSSUF)_g$(EXESUF): %.o
|
|
||||||
|
|
||||||
examples: $(EXAMPLES)
|
# the following examples make explicit use of the math library
|
||||||
|
avcodec: LDLIBS += -lm
|
||||||
|
decoding_encoding: LDLIBS += -lm
|
||||||
|
muxing: LDLIBS += -lm
|
||||||
|
resampling_audio: LDLIBS += -lm
|
||||||
|
|
||||||
$(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.o): | doc/examples
|
.phony: all clean-test clean
|
||||||
OUTDIRS += doc/examples
|
|
||||||
|
|
||||||
DOXY_INPUT += $(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.c)
|
all: $(OBJS) $(EXAMPLES)
|
||||||
|
|
||||||
install: install-examples
|
clean-test:
|
||||||
|
$(RM) test*.pgm test.h264 test.mp2 test.sw test.mpg
|
||||||
|
|
||||||
install-examples: $(EXAMPLES_FILES)
|
clean: clean-test
|
||||||
$(Q)mkdir -p "$(DATADIR)/examples"
|
$(RM) $(EXAMPLES) $(OBJS)
|
||||||
$(INSTALL) -m 644 $(EXAMPLES_FILES) "$(DATADIR)/examples"
|
|
||||||
$(INSTALL) -m 644 $(EXAMPLE_MAKEFILE:%=%.example) "$(DATADIR)/examples/Makefile"
|
|
||||||
|
|
||||||
uninstall: uninstall-examples
|
|
||||||
|
|
||||||
uninstall-examples:
|
|
||||||
$(RM) -r "$(DATADIR)/examples"
|
|
||||||
|
|
||||||
examplesclean:
|
|
||||||
$(RM) $(ALL_EXAMPLES) $(ALL_EXAMPLES_G)
|
|
||||||
$(RM) $(CLEANSUFFIXES:%=doc/examples/%)
|
|
||||||
|
|
||||||
docclean:: examplesclean
|
|
||||||
|
|
||||||
-include $(wildcard $(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.d))
|
|
||||||
|
|
||||||
.PHONY: examples
|
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
# use pkg-config for getting CFLAGS and LDLIBS
|
|
||||||
FFMPEG_LIBS= libavdevice \
|
|
||||||
libavformat \
|
|
||||||
libavfilter \
|
|
||||||
libavcodec \
|
|
||||||
libswresample \
|
|
||||||
libswscale \
|
|
||||||
libavutil \
|
|
||||||
|
|
||||||
CFLAGS += -Wall -g
|
|
||||||
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
|
|
||||||
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
|
|
||||||
|
|
||||||
EXAMPLES= avio_list_dir \
|
|
||||||
avio_reading \
|
|
||||||
decode_audio \
|
|
||||||
decode_video \
|
|
||||||
demuxing_decoding \
|
|
||||||
encode_audio \
|
|
||||||
encode_video \
|
|
||||||
extract_mvs \
|
|
||||||
filtering_video \
|
|
||||||
filtering_audio \
|
|
||||||
http_multiclient \
|
|
||||||
hw_decode \
|
|
||||||
metadata \
|
|
||||||
muxing \
|
|
||||||
remuxing \
|
|
||||||
resampling_audio \
|
|
||||||
scaling_video \
|
|
||||||
transcode_aac \
|
|
||||||
transcoding \
|
|
||||||
|
|
||||||
OBJS=$(addsuffix .o,$(EXAMPLES))
|
|
||||||
|
|
||||||
# the following examples make explicit use of the math library
|
|
||||||
avcodec: LDLIBS += -lm
|
|
||||||
encode_audio: LDLIBS += -lm
|
|
||||||
muxing: LDLIBS += -lm
|
|
||||||
resampling_audio: LDLIBS += -lm
|
|
||||||
|
|
||||||
.phony: all clean-test clean
|
|
||||||
|
|
||||||
all: $(OBJS) $(EXAMPLES)
|
|
||||||
|
|
||||||
clean-test:
|
|
||||||
$(RM) test*.pgm test.h264 test.mp2 test.sw test.mpg
|
|
||||||
|
|
||||||
clean: clean-test
|
|
||||||
$(RM) $(EXAMPLES) $(OBJS)
|
|
||||||
@@ -102,15 +102,38 @@ static int list_op(const char *input_dir)
|
|||||||
return ret;
|
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)
|
static void usage(const char *program_name)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "usage: %s input_dir\n"
|
fprintf(stderr, "usage: %s OPERATION entry1 [entry2]\n"
|
||||||
"API example program to show how to list files in directory "
|
"API example program to show how to manipulate resources "
|
||||||
"accessed through AVIOContext.\n", program_name);
|
"accessed through AVIOContext.\n"
|
||||||
|
"OPERATIONS:\n"
|
||||||
|
"list list content of the directory\n"
|
||||||
|
"move rename content in directory\n"
|
||||||
|
"del delete content in directory\n",
|
||||||
|
program_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
const char *op = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
av_log_set_level(AV_LOG_DEBUG);
|
av_log_set_level(AV_LOG_DEBUG);
|
||||||
@@ -120,9 +143,36 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* register codecs and formats and other lavf/lavc components*/
|
||||||
|
av_register_all();
|
||||||
avformat_network_init();
|
avformat_network_init();
|
||||||
|
|
||||||
ret = list_op(argv[1]);
|
op = argv[1];
|
||||||
|
if (strcmp(op, "list") == 0) {
|
||||||
|
if (argc < 3) {
|
||||||
|
av_log(NULL, AV_LOG_INFO, "Missing argument for list operation.\n");
|
||||||
|
ret = AVERROR(EINVAL);
|
||||||
|
} else {
|
||||||
|
ret = list_op(argv[2]);
|
||||||
|
}
|
||||||
|
} else if (strcmp(op, "del") == 0) {
|
||||||
|
if (argc < 3) {
|
||||||
|
av_log(NULL, AV_LOG_INFO, "Missing argument for del operation.\n");
|
||||||
|
ret = AVERROR(EINVAL);
|
||||||
|
} else {
|
||||||
|
ret = del_op(argv[2]);
|
||||||
|
}
|
||||||
|
} else if (strcmp(op, "move") == 0) {
|
||||||
|
if (argc < 4) {
|
||||||
|
av_log(NULL, AV_LOG_INFO, "Missing argument for move operation.\n");
|
||||||
|
ret = AVERROR(EINVAL);
|
||||||
|
} else {
|
||||||
|
ret = move_op(argv[2], argv[3]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
av_log(NULL, AV_LOG_INFO, "Invalid operation %s\n", op);
|
||||||
|
ret = AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
avformat_network_deinit();
|
avformat_network_deinit();
|
||||||
|
|
||||||
@@ -44,8 +44,6 @@ static int read_packet(void *opaque, uint8_t *buf, int buf_size)
|
|||||||
struct buffer_data *bd = (struct buffer_data *)opaque;
|
struct buffer_data *bd = (struct buffer_data *)opaque;
|
||||||
buf_size = FFMIN(buf_size, bd->size);
|
buf_size = FFMIN(buf_size, bd->size);
|
||||||
|
|
||||||
if (!buf_size)
|
|
||||||
return AVERROR_EOF;
|
|
||||||
printf("ptr:%p size:%zu\n", bd->ptr, bd->size);
|
printf("ptr:%p size:%zu\n", bd->ptr, bd->size);
|
||||||
|
|
||||||
/* copy internal buffer data to buf */
|
/* copy internal buffer data to buf */
|
||||||
@@ -74,6 +72,9 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
input_filename = argv[1];
|
input_filename = argv[1];
|
||||||
|
|
||||||
|
/* register codecs and formats and other lavf/lavc components*/
|
||||||
|
av_register_all();
|
||||||
|
|
||||||
/* slurp file content into buffer */
|
/* slurp file content into buffer */
|
||||||
ret = av_file_map(input_filename, &buffer, &buffer_size, 0, NULL);
|
ret = av_file_map(input_filename, &buffer, &buffer_size, 0, NULL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -117,12 +118,11 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
end:
|
end:
|
||||||
avformat_close_input(&fmt_ctx);
|
avformat_close_input(&fmt_ctx);
|
||||||
|
|
||||||
/* note: the internal buffer could have changed, and be != avio_ctx_buffer */
|
/* note: the internal buffer could have changed, and be != avio_ctx_buffer */
|
||||||
if (avio_ctx)
|
if (avio_ctx) {
|
||||||
av_freep(&avio_ctx->buffer);
|
av_freep(&avio_ctx->buffer);
|
||||||
avio_context_free(&avio_ctx);
|
av_freep(&avio_ctx);
|
||||||
|
}
|
||||||
av_file_unmap(buffer, buffer_size);
|
av_file_unmap(buffer, buffer_size);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|||||||
@@ -1,236 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2001 Fabrice Bellard
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* audio decoding with libavcodec API example
|
|
||||||
*
|
|
||||||
* @example decode_audio.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <libavutil/frame.h>
|
|
||||||
#include <libavutil/mem.h>
|
|
||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
|
||||||
|
|
||||||
#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)
|
|
||||||
{
|
|
||||||
int i, ch;
|
|
||||||
int ret, data_size;
|
|
||||||
|
|
||||||
/* send the packet with the compressed data to the decoder */
|
|
||||||
ret = avcodec_send_packet(dec_ctx, pkt);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error submitting the packet to the decoder\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read all the output frames (in general there may be any number of them */
|
|
||||||
while (ret >= 0) {
|
|
||||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
|
||||||
return;
|
|
||||||
else if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error during decoding\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
data_size = av_get_bytes_per_sample(dec_ctx->sample_fmt);
|
|
||||||
if (data_size < 0) {
|
|
||||||
/* This should not occur, checking just for paranoia */
|
|
||||||
fprintf(stderr, "Failed to calculate data size\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
for (i = 0; i < frame->nb_samples; i++)
|
|
||||||
for (ch = 0; ch < dec_ctx->channels; ch++)
|
|
||||||
fwrite(frame->data[ch] + data_size*i, 1, data_size, outfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
const char *outfilename, *filename;
|
|
||||||
const AVCodec *codec;
|
|
||||||
AVCodecContext *c= NULL;
|
|
||||||
AVCodecParserContext *parser = NULL;
|
|
||||||
int len, ret;
|
|
||||||
FILE *f, *outfile;
|
|
||||||
uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
|
||||||
uint8_t *data;
|
|
||||||
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]);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
filename = argv[1];
|
|
||||||
outfilename = argv[2];
|
|
||||||
|
|
||||||
pkt = av_packet_alloc();
|
|
||||||
|
|
||||||
/* find the MPEG audio decoder */
|
|
||||||
codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
|
|
||||||
if (!codec) {
|
|
||||||
fprintf(stderr, "Codec not found\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
parser = av_parser_init(codec->id);
|
|
||||||
if (!parser) {
|
|
||||||
fprintf(stderr, "Parser not found\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
c = avcodec_alloc_context3(codec);
|
|
||||||
if (!c) {
|
|
||||||
fprintf(stderr, "Could not allocate audio codec context\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* open it */
|
|
||||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
|
||||||
fprintf(stderr, "Could not open codec\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
f = fopen(filename, "rb");
|
|
||||||
if (!f) {
|
|
||||||
fprintf(stderr, "Could not open %s\n", filename);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
outfile = fopen(outfilename, "wb");
|
|
||||||
if (!outfile) {
|
|
||||||
av_free(c);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* decode until eof */
|
|
||||||
data = inbuf;
|
|
||||||
data_size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
|
|
||||||
|
|
||||||
while (data_size > 0) {
|
|
||||||
if (!decoded_frame) {
|
|
||||||
if (!(decoded_frame = av_frame_alloc())) {
|
|
||||||
fprintf(stderr, "Could not allocate audio frame\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
|
|
||||||
data, data_size,
|
|
||||||
AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error while parsing\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
data += ret;
|
|
||||||
data_size -= ret;
|
|
||||||
|
|
||||||
if (pkt->size)
|
|
||||||
decode(c, pkt, decoded_frame, outfile);
|
|
||||||
|
|
||||||
if (data_size < AUDIO_REFILL_THRESH) {
|
|
||||||
memmove(inbuf, data, data_size);
|
|
||||||
data = inbuf;
|
|
||||||
len = fread(data + data_size, 1,
|
|
||||||
AUDIO_INBUF_SIZE - data_size, f);
|
|
||||||
if (len > 0)
|
|
||||||
data_size += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flush the decoder */
|
|
||||||
pkt->data = NULL;
|
|
||||||
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->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);
|
|
||||||
|
|
||||||
avcodec_free_context(&c);
|
|
||||||
av_parser_close(parser);
|
|
||||||
av_frame_free(&decoded_frame);
|
|
||||||
av_packet_free(&pkt);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2001 Fabrice Bellard
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* video decoding with libavcodec API example
|
|
||||||
*
|
|
||||||
* @example decode_video.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
|
||||||
|
|
||||||
#define INBUF_SIZE 4096
|
|
||||||
|
|
||||||
static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
|
|
||||||
char *filename)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
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);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
|
|
||||||
const char *filename)
|
|
||||||
{
|
|
||||||
char buf[1024];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = avcodec_send_packet(dec_ctx, pkt);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error sending a packet for decoding\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (ret >= 0) {
|
|
||||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
|
||||||
return;
|
|
||||||
else if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error during decoding\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("saving frame %3d\n", dec_ctx->frame_number);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
/* the picture is allocated by the decoder. no need to
|
|
||||||
free it */
|
|
||||||
snprintf(buf, sizeof(buf), "%s-%d", filename, dec_ctx->frame_number);
|
|
||||||
pgm_save(frame->data[0], frame->linesize[0],
|
|
||||||
frame->width, frame->height, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
const char *filename, *outfilename;
|
|
||||||
const AVCodec *codec;
|
|
||||||
AVCodecParserContext *parser;
|
|
||||||
AVCodecContext *c= NULL;
|
|
||||||
FILE *f;
|
|
||||||
AVFrame *frame;
|
|
||||||
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
|
||||||
uint8_t *data;
|
|
||||||
size_t data_size;
|
|
||||||
int ret;
|
|
||||||
AVPacket *pkt;
|
|
||||||
|
|
||||||
if (argc <= 2) {
|
|
||||||
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];
|
|
||||||
outfilename = argv[2];
|
|
||||||
|
|
||||||
pkt = av_packet_alloc();
|
|
||||||
if (!pkt)
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
/* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */
|
|
||||||
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
|
||||||
|
|
||||||
/* find the MPEG-1 video decoder */
|
|
||||||
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
|
|
||||||
if (!codec) {
|
|
||||||
fprintf(stderr, "Codec not found\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
parser = av_parser_init(codec->id);
|
|
||||||
if (!parser) {
|
|
||||||
fprintf(stderr, "parser not found\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
c = avcodec_alloc_context3(codec);
|
|
||||||
if (!c) {
|
|
||||||
fprintf(stderr, "Could not allocate video codec context\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For some codecs, such as msmpeg4 and mpeg4, width and height
|
|
||||||
MUST be initialized there because this information is not
|
|
||||||
available in the bitstream. */
|
|
||||||
|
|
||||||
/* open it */
|
|
||||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
|
||||||
fprintf(stderr, "Could not open codec\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
f = fopen(filename, "rb");
|
|
||||||
if (!f) {
|
|
||||||
fprintf(stderr, "Could not open %s\n", filename);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
frame = av_frame_alloc();
|
|
||||||
if (!frame) {
|
|
||||||
fprintf(stderr, "Could not allocate video frame\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!feof(f)) {
|
|
||||||
/* read raw data from the input file */
|
|
||||||
data_size = fread(inbuf, 1, INBUF_SIZE, f);
|
|
||||||
if (!data_size)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* use the parser to split the data into frames */
|
|
||||||
data = inbuf;
|
|
||||||
while (data_size > 0) {
|
|
||||||
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
|
|
||||||
data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error while parsing\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
data += ret;
|
|
||||||
data_size -= ret;
|
|
||||||
|
|
||||||
if (pkt->size)
|
|
||||||
decode(c, frame, pkt, outfilename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flush the decoder */
|
|
||||||
decode(c, frame, NULL, outfilename);
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
av_parser_close(parser);
|
|
||||||
avcodec_free_context(&c);
|
|
||||||
av_frame_free(&frame);
|
|
||||||
av_packet_free(&pkt);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
665
doc/examples/decoding_encoding.c
Normal file
665
doc/examples/decoding_encoding.c
Normal file
@@ -0,0 +1,665 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2001 Fabrice Bellard
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* libavcodec API use example.
|
||||||
|
*
|
||||||
|
* @example decoding_encoding.c
|
||||||
|
* Note that libavcodec only handles codecs (MPEG, MPEG-4, etc...),
|
||||||
|
* not file formats (AVI, VOB, MP4, MOV, MKV, MXF, FLV, MPEG-TS, MPEG-PS, etc...).
|
||||||
|
* See library 'libavformat' for the format handling
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <libavutil/opt.h>
|
||||||
|
#include <libavcodec/avcodec.h>
|
||||||
|
#include <libavutil/channel_layout.h>
|
||||||
|
#include <libavutil/common.h>
|
||||||
|
#include <libavutil/imgutils.h>
|
||||||
|
#include <libavutil/mathematics.h>
|
||||||
|
#include <libavutil/samplefmt.h>
|
||||||
|
|
||||||
|
#define INBUF_SIZE 4096
|
||||||
|
#define AUDIO_INBUF_SIZE 20480
|
||||||
|
#define AUDIO_REFILL_THRESH 4096
|
||||||
|
|
||||||
|
/* check that a given sample format is supported by the encoder */
|
||||||
|
static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
|
||||||
|
{
|
||||||
|
const enum AVSampleFormat *p = codec->sample_fmts;
|
||||||
|
|
||||||
|
while (*p != AV_SAMPLE_FMT_NONE) {
|
||||||
|
if (*p == sample_fmt)
|
||||||
|
return 1;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* just pick the highest supported samplerate */
|
||||||
|
static int select_sample_rate(AVCodec *codec)
|
||||||
|
{
|
||||||
|
const int *p;
|
||||||
|
int best_samplerate = 0;
|
||||||
|
|
||||||
|
if (!codec->supported_samplerates)
|
||||||
|
return 44100;
|
||||||
|
|
||||||
|
p = codec->supported_samplerates;
|
||||||
|
while (*p) {
|
||||||
|
best_samplerate = FFMAX(*p, best_samplerate);
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
return best_samplerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* select layout with the highest channel count */
|
||||||
|
static int select_channel_layout(AVCodec *codec)
|
||||||
|
{
|
||||||
|
const uint64_t *p;
|
||||||
|
uint64_t best_ch_layout = 0;
|
||||||
|
int best_nb_channels = 0;
|
||||||
|
|
||||||
|
if (!codec->channel_layouts)
|
||||||
|
return AV_CH_LAYOUT_STEREO;
|
||||||
|
|
||||||
|
p = codec->channel_layouts;
|
||||||
|
while (*p) {
|
||||||
|
int nb_channels = av_get_channel_layout_nb_channels(*p);
|
||||||
|
|
||||||
|
if (nb_channels > best_nb_channels) {
|
||||||
|
best_ch_layout = *p;
|
||||||
|
best_nb_channels = nb_channels;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
return best_ch_layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Audio encoding example
|
||||||
|
*/
|
||||||
|
static void audio_encode_example(const char *filename)
|
||||||
|
{
|
||||||
|
AVCodec *codec;
|
||||||
|
AVCodecContext *c= NULL;
|
||||||
|
AVFrame *frame;
|
||||||
|
AVPacket pkt;
|
||||||
|
int i, j, k, ret, got_output;
|
||||||
|
int buffer_size;
|
||||||
|
FILE *f;
|
||||||
|
uint16_t *samples;
|
||||||
|
float t, tincr;
|
||||||
|
|
||||||
|
printf("Encode audio file %s\n", filename);
|
||||||
|
|
||||||
|
/* find the MP2 encoder */
|
||||||
|
codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
|
||||||
|
if (!codec) {
|
||||||
|
fprintf(stderr, "Codec not found\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
c = avcodec_alloc_context3(codec);
|
||||||
|
if (!c) {
|
||||||
|
fprintf(stderr, "Could not allocate audio codec context\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* put sample parameters */
|
||||||
|
c->bit_rate = 64000;
|
||||||
|
|
||||||
|
/* check that the encoder supports s16 pcm input */
|
||||||
|
c->sample_fmt = AV_SAMPLE_FMT_S16;
|
||||||
|
if (!check_sample_fmt(codec, c->sample_fmt)) {
|
||||||
|
fprintf(stderr, "Encoder does not support sample format %s",
|
||||||
|
av_get_sample_fmt_name(c->sample_fmt));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* open it */
|
||||||
|
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||||
|
fprintf(stderr, "Could not open codec\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
f = fopen(filename, "wb");
|
||||||
|
if (!f) {
|
||||||
|
fprintf(stderr, "Could not open %s\n", filename);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* frame containing input raw audio */
|
||||||
|
frame = av_frame_alloc();
|
||||||
|
if (!frame) {
|
||||||
|
fprintf(stderr, "Could not allocate audio frame\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->nb_samples = c->frame_size;
|
||||||
|
frame->format = c->sample_fmt;
|
||||||
|
frame->channel_layout = c->channel_layout;
|
||||||
|
|
||||||
|
/* the codec gives us the frame size, in samples,
|
||||||
|
* we calculate the size of the samples buffer in bytes */
|
||||||
|
buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
|
||||||
|
c->sample_fmt, 0);
|
||||||
|
if (buffer_size < 0) {
|
||||||
|
fprintf(stderr, "Could not get sample buffer size\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
samples = av_malloc(buffer_size);
|
||||||
|
if (!samples) {
|
||||||
|
fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
|
||||||
|
buffer_size);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/* setup the data pointers in the AVFrame */
|
||||||
|
ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
|
||||||
|
(const uint8_t*)samples, buffer_size, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Could not setup audio frame\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* encode a single tone sound */
|
||||||
|
t = 0;
|
||||||
|
tincr = 2 * M_PI * 440.0 / c->sample_rate;
|
||||||
|
for (i = 0; i < 200; i++) {
|
||||||
|
av_init_packet(&pkt);
|
||||||
|
pkt.data = NULL; // packet data will be allocated by the encoder
|
||||||
|
pkt.size = 0;
|
||||||
|
|
||||||
|
for (j = 0; j < c->frame_size; j++) {
|
||||||
|
samples[2*j] = (int)(sin(t) * 10000);
|
||||||
|
|
||||||
|
for (k = 1; k < c->channels; k++)
|
||||||
|
samples[2*j + k] = samples[2*j];
|
||||||
|
t += tincr;
|
||||||
|
}
|
||||||
|
/* encode the samples */
|
||||||
|
ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Error encoding audio frame\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (got_output) {
|
||||||
|
fwrite(pkt.data, 1, pkt.size, f);
|
||||||
|
av_packet_unref(&pkt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the delayed frames */
|
||||||
|
for (got_output = 1; got_output; i++) {
|
||||||
|
ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Error encoding frame\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (got_output) {
|
||||||
|
fwrite(pkt.data, 1, pkt.size, f);
|
||||||
|
av_packet_unref(&pkt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
av_freep(&samples);
|
||||||
|
av_frame_free(&frame);
|
||||||
|
avcodec_close(c);
|
||||||
|
av_free(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Audio decoding.
|
||||||
|
*/
|
||||||
|
static void audio_decode_example(const char *outfilename, const char *filename)
|
||||||
|
{
|
||||||
|
AVCodec *codec;
|
||||||
|
AVCodecContext *c= NULL;
|
||||||
|
int len;
|
||||||
|
FILE *f, *outfile;
|
||||||
|
uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||||
|
AVPacket avpkt;
|
||||||
|
AVFrame *decoded_frame = NULL;
|
||||||
|
|
||||||
|
av_init_packet(&avpkt);
|
||||||
|
|
||||||
|
printf("Decode audio file %s to %s\n", filename, outfilename);
|
||||||
|
|
||||||
|
/* find the MPEG audio decoder */
|
||||||
|
codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
|
||||||
|
if (!codec) {
|
||||||
|
fprintf(stderr, "Codec not found\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
c = avcodec_alloc_context3(codec);
|
||||||
|
if (!c) {
|
||||||
|
fprintf(stderr, "Could not allocate audio codec context\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open it */
|
||||||
|
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||||
|
fprintf(stderr, "Could not open codec\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
f = fopen(filename, "rb");
|
||||||
|
if (!f) {
|
||||||
|
fprintf(stderr, "Could not open %s\n", filename);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
outfile = fopen(outfilename, "wb");
|
||||||
|
if (!outfile) {
|
||||||
|
av_free(c);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* decode until eof */
|
||||||
|
avpkt.data = inbuf;
|
||||||
|
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
|
||||||
|
|
||||||
|
while (avpkt.size > 0) {
|
||||||
|
int i, ch;
|
||||||
|
int got_frame = 0;
|
||||||
|
|
||||||
|
if (!decoded_frame) {
|
||||||
|
if (!(decoded_frame = av_frame_alloc())) {
|
||||||
|
fprintf(stderr, "Could not allocate audio frame\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
|
||||||
|
if (len < 0) {
|
||||||
|
fprintf(stderr, "Error while decoding\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (got_frame) {
|
||||||
|
/* if a frame has been decoded, output it */
|
||||||
|
int data_size = av_get_bytes_per_sample(c->sample_fmt);
|
||||||
|
if (data_size < 0) {
|
||||||
|
/* This should not occur, checking just for paranoia */
|
||||||
|
fprintf(stderr, "Failed to calculate data size\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
for (i=0; i<decoded_frame->nb_samples; i++)
|
||||||
|
for (ch=0; ch<c->channels; ch++)
|
||||||
|
fwrite(decoded_frame->data[ch] + data_size*i, 1, data_size, outfile);
|
||||||
|
}
|
||||||
|
avpkt.size -= len;
|
||||||
|
avpkt.data += len;
|
||||||
|
avpkt.dts =
|
||||||
|
avpkt.pts = AV_NOPTS_VALUE;
|
||||||
|
if (avpkt.size < AUDIO_REFILL_THRESH) {
|
||||||
|
/* Refill the input buffer, to avoid trying to decode
|
||||||
|
* incomplete frames. Instead of this, one could also use
|
||||||
|
* a parser, or use a proper container format through
|
||||||
|
* libavformat. */
|
||||||
|
memmove(inbuf, avpkt.data, avpkt.size);
|
||||||
|
avpkt.data = inbuf;
|
||||||
|
len = fread(avpkt.data + avpkt.size, 1,
|
||||||
|
AUDIO_INBUF_SIZE - avpkt.size, f);
|
||||||
|
if (len > 0)
|
||||||
|
avpkt.size += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(outfile);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
avcodec_close(c);
|
||||||
|
av_free(c);
|
||||||
|
av_frame_free(&decoded_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Video encoding example
|
||||||
|
*/
|
||||||
|
static void video_encode_example(const char *filename, int codec_id)
|
||||||
|
{
|
||||||
|
AVCodec *codec;
|
||||||
|
AVCodecContext *c= NULL;
|
||||||
|
int i, ret, x, y, got_output;
|
||||||
|
FILE *f;
|
||||||
|
AVFrame *frame;
|
||||||
|
AVPacket pkt;
|
||||||
|
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
|
||||||
|
|
||||||
|
printf("Encode video file %s\n", filename);
|
||||||
|
|
||||||
|
/* find the video encoder */
|
||||||
|
codec = avcodec_find_encoder(codec_id);
|
||||||
|
if (!codec) {
|
||||||
|
fprintf(stderr, "Codec not found\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
c = avcodec_alloc_context3(codec);
|
||||||
|
if (!c) {
|
||||||
|
fprintf(stderr, "Could not allocate video codec context\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* put sample parameters */
|
||||||
|
c->bit_rate = 400000;
|
||||||
|
/* resolution must be a multiple of two */
|
||||||
|
c->width = 352;
|
||||||
|
c->height = 288;
|
||||||
|
/* frames per second */
|
||||||
|
c->time_base = (AVRational){1,25};
|
||||||
|
/* emit one intra frame every ten frames
|
||||||
|
* check frame pict_type before passing frame
|
||||||
|
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
|
||||||
|
* then gop_size is ignored and the output of encoder
|
||||||
|
* will always be I frame irrespective to gop_size
|
||||||
|
*/
|
||||||
|
c->gop_size = 10;
|
||||||
|
c->max_b_frames = 1;
|
||||||
|
c->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||||
|
|
||||||
|
if (codec_id == AV_CODEC_ID_H264)
|
||||||
|
av_opt_set(c->priv_data, "preset", "slow", 0);
|
||||||
|
|
||||||
|
/* open it */
|
||||||
|
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||||
|
fprintf(stderr, "Could not open codec\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
f = fopen(filename, "wb");
|
||||||
|
if (!f) {
|
||||||
|
fprintf(stderr, "Could not open %s\n", filename);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame = av_frame_alloc();
|
||||||
|
if (!frame) {
|
||||||
|
fprintf(stderr, "Could not allocate video frame\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
frame->format = c->pix_fmt;
|
||||||
|
frame->width = c->width;
|
||||||
|
frame->height = c->height;
|
||||||
|
|
||||||
|
/* the image can be allocated by any means and av_image_alloc() is
|
||||||
|
* just the most convenient way if av_malloc() is to be used */
|
||||||
|
ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
|
||||||
|
c->pix_fmt, 32);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Could not allocate raw picture buffer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* encode 1 second of video */
|
||||||
|
for (i = 0; i < 25; i++) {
|
||||||
|
av_init_packet(&pkt);
|
||||||
|
pkt.data = NULL; // packet data will be allocated by the encoder
|
||||||
|
pkt.size = 0;
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
/* prepare a dummy image */
|
||||||
|
/* Y */
|
||||||
|
for (y = 0; y < c->height; y++) {
|
||||||
|
for (x = 0; x < c->width; x++) {
|
||||||
|
frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cb and Cr */
|
||||||
|
for (y = 0; y < c->height/2; y++) {
|
||||||
|
for (x = 0; x < c->width/2; x++) {
|
||||||
|
frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
|
||||||
|
frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->pts = i;
|
||||||
|
|
||||||
|
/* encode the image */
|
||||||
|
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Error encoding frame\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (got_output) {
|
||||||
|
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
|
||||||
|
fwrite(pkt.data, 1, pkt.size, f);
|
||||||
|
av_packet_unref(&pkt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the delayed frames */
|
||||||
|
for (got_output = 1; got_output; i++) {
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Error encoding frame\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (got_output) {
|
||||||
|
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
|
||||||
|
fwrite(pkt.data, 1, pkt.size, f);
|
||||||
|
av_packet_unref(&pkt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add sequence end code to have a real MPEG file */
|
||||||
|
fwrite(endcode, 1, sizeof(endcode), f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
avcodec_close(c);
|
||||||
|
av_free(c);
|
||||||
|
av_freep(&frame->data[0]);
|
||||||
|
av_frame_free(&frame);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Video decoding example
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
|
||||||
|
char *filename)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
f = fopen(filename,"w");
|
||||||
|
fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
|
||||||
|
for (i = 0; i < ysize; i++)
|
||||||
|
fwrite(buf + i * wrap, 1, xsize, f);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int decode_write_frame(const char *outfilename, AVCodecContext *avctx,
|
||||||
|
AVFrame *frame, int *frame_count, AVPacket *pkt, int last)
|
||||||
|
{
|
||||||
|
int len, got_frame;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
len = avcodec_decode_video2(avctx, frame, &got_frame, pkt);
|
||||||
|
if (len < 0) {
|
||||||
|
fprintf(stderr, "Error while decoding frame %d\n", *frame_count);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
if (got_frame) {
|
||||||
|
printf("Saving %sframe %3d\n", last ? "last " : "", *frame_count);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
/* the picture is allocated by the decoder, no need to free it */
|
||||||
|
snprintf(buf, sizeof(buf), outfilename, *frame_count);
|
||||||
|
pgm_save(frame->data[0], frame->linesize[0],
|
||||||
|
frame->width, frame->height, buf);
|
||||||
|
(*frame_count)++;
|
||||||
|
}
|
||||||
|
if (pkt->data) {
|
||||||
|
pkt->size -= len;
|
||||||
|
pkt->data += len;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void video_decode_example(const char *outfilename, const char *filename)
|
||||||
|
{
|
||||||
|
AVCodec *codec;
|
||||||
|
AVCodecContext *c= NULL;
|
||||||
|
int frame_count;
|
||||||
|
FILE *f;
|
||||||
|
AVFrame *frame;
|
||||||
|
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||||
|
AVPacket avpkt;
|
||||||
|
|
||||||
|
av_init_packet(&avpkt);
|
||||||
|
|
||||||
|
/* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */
|
||||||
|
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
|
|
||||||
|
printf("Decode video file %s to %s\n", filename, outfilename);
|
||||||
|
|
||||||
|
/* find the MPEG-1 video decoder */
|
||||||
|
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
|
||||||
|
if (!codec) {
|
||||||
|
fprintf(stderr, "Codec not found\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
c = avcodec_alloc_context3(codec);
|
||||||
|
if (!c) {
|
||||||
|
fprintf(stderr, "Could not allocate video codec context\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
|
||||||
|
c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames
|
||||||
|
|
||||||
|
/* For some codecs, such as msmpeg4 and mpeg4, width and height
|
||||||
|
MUST be initialized there because this information is not
|
||||||
|
available in the bitstream. */
|
||||||
|
|
||||||
|
/* open it */
|
||||||
|
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||||
|
fprintf(stderr, "Could not open codec\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
f = fopen(filename, "rb");
|
||||||
|
if (!f) {
|
||||||
|
fprintf(stderr, "Could not open %s\n", filename);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame = av_frame_alloc();
|
||||||
|
if (!frame) {
|
||||||
|
fprintf(stderr, "Could not allocate video frame\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_count = 0;
|
||||||
|
for (;;) {
|
||||||
|
avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
|
||||||
|
if (avpkt.size == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
|
||||||
|
and this is the only method to use them because you cannot
|
||||||
|
know the compressed data size before analysing it.
|
||||||
|
|
||||||
|
BUT some other codecs (msmpeg4, mpeg4) are inherently frame
|
||||||
|
based, so you must call them with all the data for one
|
||||||
|
frame exactly. You must also initialize 'width' and
|
||||||
|
'height' before initializing them. */
|
||||||
|
|
||||||
|
/* NOTE2: some codecs allow the raw parameters (frame size,
|
||||||
|
sample rate) to be changed at any frame. We handle this, so
|
||||||
|
you should also take care of it */
|
||||||
|
|
||||||
|
/* here, we use a stream based decoder (mpeg1video), so we
|
||||||
|
feed decoder and see if it could decode a frame */
|
||||||
|
avpkt.data = inbuf;
|
||||||
|
while (avpkt.size > 0)
|
||||||
|
if (decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 0) < 0)
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some codecs, such as MPEG, transmit the I- and P-frame with a
|
||||||
|
latency of one frame. You must do the following to have a
|
||||||
|
chance to get the last frame of the video. */
|
||||||
|
avpkt.data = NULL;
|
||||||
|
avpkt.size = 0;
|
||||||
|
decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 1);
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
avcodec_close(c);
|
||||||
|
av_free(c);
|
||||||
|
av_frame_free(&frame);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *output_type;
|
||||||
|
|
||||||
|
/* register all the codecs */
|
||||||
|
avcodec_register_all();
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
printf("usage: %s output_type\n"
|
||||||
|
"API example program to decode/encode a media stream with libavcodec.\n"
|
||||||
|
"This program generates a synthetic stream and encodes it to a file\n"
|
||||||
|
"named test.h264, test.mp2 or test.mpg depending on output_type.\n"
|
||||||
|
"The encoded stream is then decoded and written to a raw data output.\n"
|
||||||
|
"output_type must be chosen between 'h264', 'mp2', 'mpg'.\n",
|
||||||
|
argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
output_type = argv[1];
|
||||||
|
|
||||||
|
if (!strcmp(output_type, "h264")) {
|
||||||
|
video_encode_example("test.h264", AV_CODEC_ID_H264);
|
||||||
|
} else if (!strcmp(output_type, "mp2")) {
|
||||||
|
audio_encode_example("test.mp2");
|
||||||
|
audio_decode_example("test.pcm", "test.mp2");
|
||||||
|
} else if (!strcmp(output_type, "mpg")) {
|
||||||
|
video_encode_example("test.mpg", AV_CODEC_ID_MPEG1VIDEO);
|
||||||
|
video_decode_example("test%02d.pgm", "test.mpg");
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Invalid output type '%s', choose between 'h264', 'mp2', or 'mpg'\n",
|
||||||
|
output_type);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -32,7 +32,6 @@
|
|||||||
#include <libavutil/imgutils.h>
|
#include <libavutil/imgutils.h>
|
||||||
#include <libavutil/samplefmt.h>
|
#include <libavutil/samplefmt.h>
|
||||||
#include <libavutil/timestamp.h>
|
#include <libavutil/timestamp.h>
|
||||||
#include <libavcodec/avcodec.h>
|
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
|
|
||||||
static AVFormatContext *fmt_ctx = NULL;
|
static AVFormatContext *fmt_ctx = NULL;
|
||||||
@@ -52,105 +51,110 @@ static int video_dst_bufsize;
|
|||||||
|
|
||||||
static int video_stream_idx = -1, audio_stream_idx = -1;
|
static int video_stream_idx = -1, audio_stream_idx = -1;
|
||||||
static AVFrame *frame = NULL;
|
static AVFrame *frame = NULL;
|
||||||
static AVPacket *pkt = NULL;
|
static AVPacket pkt;
|
||||||
static int video_frame_count = 0;
|
static int video_frame_count = 0;
|
||||||
static int audio_frame_count = 0;
|
static int audio_frame_count = 0;
|
||||||
|
|
||||||
static int output_video_frame(AVFrame *frame)
|
/* 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
|
||||||
if (frame->width != width || frame->height != height ||
|
* needs. Look for the use of refcount in this example to see what are the
|
||||||
frame->format != pix_fmt) {
|
* differences of API usage between them. */
|
||||||
/* To handle this change, one could call av_image_alloc again and
|
static int refcount = 0;
|
||||||
* 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 n:%d coded_n:%d\n",
|
static int decode_packet(int *got_frame, int 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);
|
|
||||||
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;
|
int ret = 0;
|
||||||
|
int decoded = pkt.size;
|
||||||
|
|
||||||
// submit the packet to the decoder
|
*got_frame = 0;
|
||||||
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
|
if (pkt.stream_index == video_stream_idx) {
|
||||||
while (ret >= 0) {
|
/* decode video frame */
|
||||||
ret = avcodec_receive_frame(dec, frame);
|
ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
// those two return values are special and mean there is no output
|
fprintf(stderr, "Error decoding video frame (%s)\n", av_err2str(ret));
|
||||||
// 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write the frame data to output file
|
if (*got_frame) {
|
||||||
if (dec->codec->type == AVMEDIA_TYPE_VIDEO)
|
|
||||||
ret = output_video_frame(frame);
|
|
||||||
else
|
|
||||||
ret = output_audio_frame(frame);
|
|
||||||
|
|
||||||
av_frame_unref(frame);
|
if (frame->width != width || frame->height != height ||
|
||||||
if (ret < 0)
|
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 pts:%s\n",
|
||||||
|
cached ? "(cached)" : "",
|
||||||
|
video_frame_count++, frame->coded_picture_number,
|
||||||
|
av_ts2timestr(frame->pts, &video_dec_ctx->time_base));
|
||||||
|
|
||||||
|
/* 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;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
/* 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);
|
||||||
|
|
||||||
|
return decoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int open_codec_context(int *stream_idx,
|
static int open_codec_context(int *stream_idx,
|
||||||
AVCodecContext **dec_ctx, AVFormatContext *fmt_ctx, enum AVMediaType type)
|
AVFormatContext *fmt_ctx, enum AVMediaType type)
|
||||||
{
|
{
|
||||||
int ret, stream_index;
|
int ret, stream_index;
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
const AVCodec *dec = NULL;
|
AVCodecContext *dec_ctx = NULL;
|
||||||
|
AVCodec *dec = NULL;
|
||||||
|
AVDictionary *opts = NULL;
|
||||||
|
|
||||||
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
|
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -162,30 +166,17 @@ static int open_codec_context(int *stream_idx,
|
|||||||
st = fmt_ctx->streams[stream_index];
|
st = fmt_ctx->streams[stream_index];
|
||||||
|
|
||||||
/* find decoder for the stream */
|
/* find decoder for the stream */
|
||||||
dec = avcodec_find_decoder(st->codecpar->codec_id);
|
dec_ctx = st->codec;
|
||||||
|
dec = avcodec_find_decoder(dec_ctx->codec_id);
|
||||||
if (!dec) {
|
if (!dec) {
|
||||||
fprintf(stderr, "Failed to find %s codec\n",
|
fprintf(stderr, "Failed to find %s codec\n",
|
||||||
av_get_media_type_string(type));
|
av_get_media_type_string(type));
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a codec context for the decoder */
|
/* Init the decoders, with or without reference counting */
|
||||||
*dec_ctx = avcodec_alloc_context3(dec);
|
av_dict_set(&opts, "refcounted_frames", refcount ? "1" : "0", 0);
|
||||||
if (!*dec_ctx) {
|
if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) {
|
||||||
fprintf(stderr, "Failed to allocate the %s codec context\n",
|
|
||||||
av_get_media_type_string(type));
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy codec parameters from input stream to output codec context */
|
|
||||||
if ((ret = avcodec_parameters_to_context(*dec_ctx, st->codecpar)) < 0) {
|
|
||||||
fprintf(stderr, "Failed to copy %s codec parameters to decoder context\n",
|
|
||||||
av_get_media_type_string(type));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Init the decoders */
|
|
||||||
if ((ret = avcodec_open2(*dec_ctx, dec, NULL)) < 0) {
|
|
||||||
fprintf(stderr, "Failed to open %s codec\n",
|
fprintf(stderr, "Failed to open %s codec\n",
|
||||||
av_get_media_type_string(type));
|
av_get_media_type_string(type));
|
||||||
return ret;
|
return ret;
|
||||||
@@ -227,21 +218,31 @@ static int get_format_from_sample_fmt(const char **fmt,
|
|||||||
|
|
||||||
int main (int argc, char **argv)
|
int main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0, got_frame;
|
||||||
|
|
||||||
if (argc != 4) {
|
if (argc != 4 && argc != 5) {
|
||||||
fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"
|
fprintf(stderr, "usage: %s [-refcount] input_file video_output_file audio_output_file\n"
|
||||||
"API example program to show how to read frames from an input 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"
|
"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"
|
"video frames to a rawvideo file named video_output_file, and decoded\n"
|
||||||
"audio frames to a rawaudio file named audio_output_file.\n",
|
"audio frames to a rawaudio file named audio_output_file.\n\n"
|
||||||
argv[0]);
|
"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]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if (argc == 5 && !strcmp(argv[1], "-refcount")) {
|
||||||
|
refcount = 1;
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
src_filename = argv[1];
|
src_filename = argv[1];
|
||||||
video_dst_filename = argv[2];
|
video_dst_filename = argv[2];
|
||||||
audio_dst_filename = argv[3];
|
audio_dst_filename = argv[3];
|
||||||
|
|
||||||
|
/* register all formats and codecs */
|
||||||
|
av_register_all();
|
||||||
|
|
||||||
/* open input file, and allocate format context */
|
/* open input file, and allocate format context */
|
||||||
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
|
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
|
||||||
fprintf(stderr, "Could not open source file %s\n", src_filename);
|
fprintf(stderr, "Could not open source file %s\n", src_filename);
|
||||||
@@ -254,8 +255,9 @@ int main (int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open_codec_context(&video_stream_idx, &video_dec_ctx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {
|
if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {
|
||||||
video_stream = fmt_ctx->streams[video_stream_idx];
|
video_stream = fmt_ctx->streams[video_stream_idx];
|
||||||
|
video_dec_ctx = video_stream->codec;
|
||||||
|
|
||||||
video_dst_file = fopen(video_dst_filename, "wb");
|
video_dst_file = fopen(video_dst_filename, "wb");
|
||||||
if (!video_dst_file) {
|
if (!video_dst_file) {
|
||||||
@@ -277,8 +279,9 @@ int main (int argc, char **argv)
|
|||||||
video_dst_bufsize = ret;
|
video_dst_bufsize = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open_codec_context(&audio_stream_idx, &audio_dec_ctx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {
|
if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {
|
||||||
audio_stream = fmt_ctx->streams[audio_stream_idx];
|
audio_stream = fmt_ctx->streams[audio_stream_idx];
|
||||||
|
audio_dec_ctx = audio_stream->codec;
|
||||||
audio_dst_file = fopen(audio_dst_filename, "wb");
|
audio_dst_file = fopen(audio_dst_filename, "wb");
|
||||||
if (!audio_dst_file) {
|
if (!audio_dst_file) {
|
||||||
fprintf(stderr, "Could not open destination file %s\n", audio_dst_filename);
|
fprintf(stderr, "Could not open destination file %s\n", audio_dst_filename);
|
||||||
@@ -303,12 +306,10 @@ int main (int argc, char **argv)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
pkt = av_packet_alloc();
|
/* initialize packet, set data to NULL, let the demuxer fill it */
|
||||||
if (!pkt) {
|
av_init_packet(&pkt);
|
||||||
fprintf(stderr, "Could not allocate packet\n");
|
pkt.data = NULL;
|
||||||
ret = AVERROR(ENOMEM);
|
pkt.size = 0;
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (video_stream)
|
if (video_stream)
|
||||||
printf("Demuxing video from file '%s' into '%s'\n", src_filename, video_dst_filename);
|
printf("Demuxing video from file '%s' into '%s'\n", src_filename, video_dst_filename);
|
||||||
@@ -316,23 +317,24 @@ int main (int argc, char **argv)
|
|||||||
printf("Demuxing audio from file '%s' into '%s'\n", src_filename, audio_dst_filename);
|
printf("Demuxing audio from file '%s' into '%s'\n", src_filename, audio_dst_filename);
|
||||||
|
|
||||||
/* read frames from the file */
|
/* read frames from the file */
|
||||||
while (av_read_frame(fmt_ctx, pkt) >= 0) {
|
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
|
||||||
// check if the packet belongs to a stream we are interested in, otherwise
|
AVPacket orig_pkt = pkt;
|
||||||
// skip it
|
do {
|
||||||
if (pkt->stream_index == video_stream_idx)
|
ret = decode_packet(&got_frame, 0);
|
||||||
ret = decode_packet(video_dec_ctx, pkt);
|
if (ret < 0)
|
||||||
else if (pkt->stream_index == audio_stream_idx)
|
break;
|
||||||
ret = decode_packet(audio_dec_ctx, pkt);
|
pkt.data += ret;
|
||||||
av_packet_unref(pkt);
|
pkt.size -= ret;
|
||||||
if (ret < 0)
|
} while (pkt.size > 0);
|
||||||
break;
|
av_packet_unref(&orig_pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* flush the decoders */
|
/* flush cached frames */
|
||||||
if (video_dec_ctx)
|
pkt.data = NULL;
|
||||||
decode_packet(video_dec_ctx, NULL);
|
pkt.size = 0;
|
||||||
if (audio_dec_ctx)
|
do {
|
||||||
decode_packet(audio_dec_ctx, NULL);
|
decode_packet(&got_frame, 1);
|
||||||
|
} while (got_frame);
|
||||||
|
|
||||||
printf("Demuxing succeeded.\n");
|
printf("Demuxing succeeded.\n");
|
||||||
|
|
||||||
@@ -367,14 +369,13 @@ int main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
avcodec_free_context(&video_dec_ctx);
|
avcodec_close(video_dec_ctx);
|
||||||
avcodec_free_context(&audio_dec_ctx);
|
avcodec_close(audio_dec_ctx);
|
||||||
avformat_close_input(&fmt_ctx);
|
avformat_close_input(&fmt_ctx);
|
||||||
if (video_dst_file)
|
if (video_dst_file)
|
||||||
fclose(video_dst_file);
|
fclose(video_dst_file);
|
||||||
if (audio_dst_file)
|
if (audio_dst_file)
|
||||||
fclose(audio_dst_file);
|
fclose(audio_dst_file);
|
||||||
av_packet_free(&pkt);
|
|
||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
av_free(video_dst_data[0]);
|
av_free(video_dst_data[0]);
|
||||||
|
|
||||||
|
|||||||
@@ -1,238 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2001 Fabrice Bellard
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* audio encoding with libavcodec API example.
|
|
||||||
*
|
|
||||||
* @example encode_audio.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
|
||||||
|
|
||||||
#include <libavutil/channel_layout.h>
|
|
||||||
#include <libavutil/common.h>
|
|
||||||
#include <libavutil/frame.h>
|
|
||||||
#include <libavutil/samplefmt.h>
|
|
||||||
|
|
||||||
/* check that a given sample format is supported by the encoder */
|
|
||||||
static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt)
|
|
||||||
{
|
|
||||||
const enum AVSampleFormat *p = codec->sample_fmts;
|
|
||||||
|
|
||||||
while (*p != AV_SAMPLE_FMT_NONE) {
|
|
||||||
if (*p == sample_fmt)
|
|
||||||
return 1;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* just pick the highest supported samplerate */
|
|
||||||
static int select_sample_rate(const AVCodec *codec)
|
|
||||||
{
|
|
||||||
const int *p;
|
|
||||||
int best_samplerate = 0;
|
|
||||||
|
|
||||||
if (!codec->supported_samplerates)
|
|
||||||
return 44100;
|
|
||||||
|
|
||||||
p = codec->supported_samplerates;
|
|
||||||
while (*p) {
|
|
||||||
if (!best_samplerate || abs(44100 - *p) < abs(44100 - best_samplerate))
|
|
||||||
best_samplerate = *p;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
return best_samplerate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* select layout with the highest channel count */
|
|
||||||
static int select_channel_layout(const AVCodec *codec)
|
|
||||||
{
|
|
||||||
const uint64_t *p;
|
|
||||||
uint64_t best_ch_layout = 0;
|
|
||||||
int best_nb_channels = 0;
|
|
||||||
|
|
||||||
if (!codec->channel_layouts)
|
|
||||||
return AV_CH_LAYOUT_STEREO;
|
|
||||||
|
|
||||||
p = codec->channel_layouts;
|
|
||||||
while (*p) {
|
|
||||||
int nb_channels = av_get_channel_layout_nb_channels(*p);
|
|
||||||
|
|
||||||
if (nb_channels > best_nb_channels) {
|
|
||||||
best_ch_layout = *p;
|
|
||||||
best_nb_channels = nb_channels;
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
return best_ch_layout;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt,
|
|
||||||
FILE *output)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* send the frame for encoding */
|
|
||||||
ret = avcodec_send_frame(ctx, frame);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error sending the frame to the encoder\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read all the available output packets (in general there may be any
|
|
||||||
* number of them */
|
|
||||||
while (ret >= 0) {
|
|
||||||
ret = avcodec_receive_packet(ctx, pkt);
|
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
|
||||||
return;
|
|
||||||
else if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error encoding audio frame\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
fwrite(pkt->data, 1, pkt->size, output);
|
|
||||||
av_packet_unref(pkt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
const char *filename;
|
|
||||||
const AVCodec *codec;
|
|
||||||
AVCodecContext *c= NULL;
|
|
||||||
AVFrame *frame;
|
|
||||||
AVPacket *pkt;
|
|
||||||
int i, j, k, ret;
|
|
||||||
FILE *f;
|
|
||||||
uint16_t *samples;
|
|
||||||
float t, tincr;
|
|
||||||
|
|
||||||
if (argc <= 1) {
|
|
||||||
fprintf(stderr, "Usage: %s <output file>\n", argv[0]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
filename = argv[1];
|
|
||||||
|
|
||||||
/* find the MP2 encoder */
|
|
||||||
codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
|
|
||||||
if (!codec) {
|
|
||||||
fprintf(stderr, "Codec not found\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
c = avcodec_alloc_context3(codec);
|
|
||||||
if (!c) {
|
|
||||||
fprintf(stderr, "Could not allocate audio codec context\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* put sample parameters */
|
|
||||||
c->bit_rate = 64000;
|
|
||||||
|
|
||||||
/* check that the encoder supports s16 pcm input */
|
|
||||||
c->sample_fmt = AV_SAMPLE_FMT_S16;
|
|
||||||
if (!check_sample_fmt(codec, c->sample_fmt)) {
|
|
||||||
fprintf(stderr, "Encoder does not support sample format %s",
|
|
||||||
av_get_sample_fmt_name(c->sample_fmt));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
/* open it */
|
|
||||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
|
||||||
fprintf(stderr, "Could not open codec\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
f = fopen(filename, "wb");
|
|
||||||
if (!f) {
|
|
||||||
fprintf(stderr, "Could not open %s\n", filename);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* packet for holding encoded output */
|
|
||||||
pkt = av_packet_alloc();
|
|
||||||
if (!pkt) {
|
|
||||||
fprintf(stderr, "could not allocate the packet\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* frame containing input raw audio */
|
|
||||||
frame = av_frame_alloc();
|
|
||||||
if (!frame) {
|
|
||||||
fprintf(stderr, "Could not allocate audio frame\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->nb_samples = c->frame_size;
|
|
||||||
frame->format = c->sample_fmt;
|
|
||||||
frame->channel_layout = c->channel_layout;
|
|
||||||
|
|
||||||
/* allocate the data buffers */
|
|
||||||
ret = av_frame_get_buffer(frame, 0);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Could not allocate audio data buffers\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* encode a single tone sound */
|
|
||||||
t = 0;
|
|
||||||
tincr = 2 * M_PI * 440.0 / c->sample_rate;
|
|
||||||
for (i = 0; i < 200; i++) {
|
|
||||||
/* make sure the frame is writable -- makes a copy if the encoder
|
|
||||||
* kept a reference internally */
|
|
||||||
ret = av_frame_make_writable(frame);
|
|
||||||
if (ret < 0)
|
|
||||||
exit(1);
|
|
||||||
samples = (uint16_t*)frame->data[0];
|
|
||||||
|
|
||||||
for (j = 0; j < c->frame_size; j++) {
|
|
||||||
samples[2*j] = (int)(sin(t) * 10000);
|
|
||||||
|
|
||||||
for (k = 1; k < c->channels; k++)
|
|
||||||
samples[2*j + k] = samples[2*j];
|
|
||||||
t += tincr;
|
|
||||||
}
|
|
||||||
encode(c, frame, pkt, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flush the encoder */
|
|
||||||
encode(c, NULL, pkt, f);
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
av_frame_free(&frame);
|
|
||||||
av_packet_free(&pkt);
|
|
||||||
avcodec_free_context(&c);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,216 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2001 Fabrice Bellard
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* video encoding with libavcodec API example
|
|
||||||
*
|
|
||||||
* @example encode_video.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
|
||||||
|
|
||||||
#include <libavutil/opt.h>
|
|
||||||
#include <libavutil/imgutils.h>
|
|
||||||
|
|
||||||
static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,
|
|
||||||
FILE *outfile)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* send the frame to the encoder */
|
|
||||||
if (frame)
|
|
||||||
printf("Send frame %3"PRId64"\n", frame->pts);
|
|
||||||
|
|
||||||
ret = avcodec_send_frame(enc_ctx, frame);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error sending a frame for encoding\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (ret >= 0) {
|
|
||||||
ret = avcodec_receive_packet(enc_ctx, pkt);
|
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
|
||||||
return;
|
|
||||||
else if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error during encoding\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size);
|
|
||||||
fwrite(pkt->data, 1, pkt->size, outfile);
|
|
||||||
av_packet_unref(pkt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
const char *filename, *codec_name;
|
|
||||||
const AVCodec *codec;
|
|
||||||
AVCodecContext *c= NULL;
|
|
||||||
int i, ret, x, y;
|
|
||||||
FILE *f;
|
|
||||||
AVFrame *frame;
|
|
||||||
AVPacket *pkt;
|
|
||||||
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
|
|
||||||
|
|
||||||
if (argc <= 2) {
|
|
||||||
fprintf(stderr, "Usage: %s <output file> <codec name>\n", argv[0]);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
filename = argv[1];
|
|
||||||
codec_name = argv[2];
|
|
||||||
|
|
||||||
/* find the mpeg1video encoder */
|
|
||||||
codec = avcodec_find_encoder_by_name(codec_name);
|
|
||||||
if (!codec) {
|
|
||||||
fprintf(stderr, "Codec '%s' not found\n", codec_name);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
c = avcodec_alloc_context3(codec);
|
|
||||||
if (!c) {
|
|
||||||
fprintf(stderr, "Could not allocate video codec context\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pkt = av_packet_alloc();
|
|
||||||
if (!pkt)
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
/* put sample parameters */
|
|
||||||
c->bit_rate = 400000;
|
|
||||||
/* resolution must be a multiple of two */
|
|
||||||
c->width = 352;
|
|
||||||
c->height = 288;
|
|
||||||
/* frames per second */
|
|
||||||
c->time_base = (AVRational){1, 25};
|
|
||||||
c->framerate = (AVRational){25, 1};
|
|
||||||
|
|
||||||
/* emit one intra frame every ten frames
|
|
||||||
* check frame pict_type before passing frame
|
|
||||||
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
|
|
||||||
* then gop_size is ignored and the output of encoder
|
|
||||||
* will always be I frame irrespective to gop_size
|
|
||||||
*/
|
|
||||||
c->gop_size = 10;
|
|
||||||
c->max_b_frames = 1;
|
|
||||||
c->pix_fmt = AV_PIX_FMT_YUV420P;
|
|
||||||
|
|
||||||
if (codec->id == AV_CODEC_ID_H264)
|
|
||||||
av_opt_set(c->priv_data, "preset", "slow", 0);
|
|
||||||
|
|
||||||
/* open it */
|
|
||||||
ret = avcodec_open2(c, codec, NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
f = fopen(filename, "wb");
|
|
||||||
if (!f) {
|
|
||||||
fprintf(stderr, "Could not open %s\n", filename);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
frame = av_frame_alloc();
|
|
||||||
if (!frame) {
|
|
||||||
fprintf(stderr, "Could not allocate video frame\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
frame->format = c->pix_fmt;
|
|
||||||
frame->width = c->width;
|
|
||||||
frame->height = c->height;
|
|
||||||
|
|
||||||
ret = av_frame_get_buffer(frame, 0);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Could not allocate the video frame data\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* encode 1 second of video */
|
|
||||||
for (i = 0; i < 25; i++) {
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
/* 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.
|
|
||||||
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++) {
|
|
||||||
frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cb and Cr */
|
|
||||||
for (y = 0; y < c->height/2; y++) {
|
|
||||||
for (x = 0; x < c->width/2; x++) {
|
|
||||||
frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
|
|
||||||
frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->pts = i;
|
|
||||||
|
|
||||||
/* encode the image */
|
|
||||||
encode(c, frame, pkt, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flush the encoder */
|
|
||||||
encode(c, NULL, pkt, 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);
|
|
||||||
av_frame_free(&frame);
|
|
||||||
av_packet_free(&pkt);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -22,7 +22,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libavutil/motion_vector.h>
|
#include <libavutil/motion_vector.h>
|
||||||
#include <libavcodec/avcodec.h>
|
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
|
|
||||||
static AVFormatContext *fmt_ctx = NULL;
|
static AVFormatContext *fmt_ctx = NULL;
|
||||||
@@ -32,26 +31,23 @@ static const char *src_filename = NULL;
|
|||||||
|
|
||||||
static int video_stream_idx = -1;
|
static int video_stream_idx = -1;
|
||||||
static AVFrame *frame = NULL;
|
static AVFrame *frame = NULL;
|
||||||
|
static AVPacket pkt;
|
||||||
static int video_frame_count = 0;
|
static int video_frame_count = 0;
|
||||||
|
|
||||||
static int decode_packet(const AVPacket *pkt)
|
static int decode_packet(int *got_frame, int cached)
|
||||||
{
|
{
|
||||||
int ret = avcodec_send_packet(video_dec_ctx, pkt);
|
int decoded = pkt.size;
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error while sending a packet to the decoder: %s\n", av_err2str(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (ret >= 0) {
|
*got_frame = 0;
|
||||||
ret = avcodec_receive_frame(video_dec_ctx, frame);
|
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
if (pkt.stream_index == video_stream_idx) {
|
||||||
break;
|
int ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
|
||||||
} else if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Error while receiving a frame from the decoder: %s\n", av_err2str(ret));
|
fprintf(stderr, "Error decoding video frame (%s)\n", av_err2str(ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret >= 0) {
|
if (*got_frame) {
|
||||||
int i;
|
int i;
|
||||||
AVFrameSideData *sd;
|
AVFrameSideData *sd;
|
||||||
|
|
||||||
@@ -62,60 +58,51 @@ static int decode_packet(const AVPacket *pkt)
|
|||||||
for (i = 0; i < sd->size / sizeof(*mvs); i++) {
|
for (i = 0; i < sd->size / sizeof(*mvs); i++) {
|
||||||
const AVMotionVector *mv = &mvs[i];
|
const AVMotionVector *mv = &mvs[i];
|
||||||
printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64"\n",
|
printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64"\n",
|
||||||
video_frame_count, mv->source,
|
video_frame_count, mv->source,
|
||||||
mv->w, mv->h, mv->src_x, mv->src_y,
|
mv->w, mv->h, mv->src_x, mv->src_y,
|
||||||
mv->dst_x, mv->dst_y, mv->flags);
|
mv->dst_x, mv->dst_y, mv->flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
av_frame_unref(frame);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return decoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
|
static int open_codec_context(int *stream_idx,
|
||||||
|
AVFormatContext *fmt_ctx, enum AVMediaType type)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
AVCodecContext *dec_ctx = NULL;
|
AVCodecContext *dec_ctx = NULL;
|
||||||
const AVCodec *dec = NULL;
|
AVCodec *dec = NULL;
|
||||||
AVDictionary *opts = NULL;
|
AVDictionary *opts = NULL;
|
||||||
|
|
||||||
ret = av_find_best_stream(fmt_ctx, type, -1, -1, &dec, 0);
|
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Could not find %s stream in input file '%s'\n",
|
fprintf(stderr, "Could not find %s stream in input file '%s'\n",
|
||||||
av_get_media_type_string(type), src_filename);
|
av_get_media_type_string(type), src_filename);
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
int stream_idx = ret;
|
*stream_idx = ret;
|
||||||
st = fmt_ctx->streams[stream_idx];
|
st = fmt_ctx->streams[*stream_idx];
|
||||||
|
|
||||||
dec_ctx = avcodec_alloc_context3(dec);
|
/* find decoder for the stream */
|
||||||
if (!dec_ctx) {
|
dec_ctx = st->codec;
|
||||||
fprintf(stderr, "Failed to allocate codec\n");
|
dec = avcodec_find_decoder(dec_ctx->codec_id);
|
||||||
|
if (!dec) {
|
||||||
|
fprintf(stderr, "Failed to find %s codec\n",
|
||||||
|
av_get_media_type_string(type));
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = avcodec_parameters_to_context(dec_ctx, st->codecpar);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Failed to copy codec parameters to codec context\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Init the video decoder */
|
/* Init the video decoder */
|
||||||
av_dict_set(&opts, "flags2", "+export_mvs", 0);
|
av_dict_set(&opts, "flags2", "+export_mvs", 0);
|
||||||
ret = avcodec_open2(dec_ctx, dec, &opts);
|
if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) {
|
||||||
av_dict_free(&opts);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Failed to open %s codec\n",
|
fprintf(stderr, "Failed to open %s codec\n",
|
||||||
av_get_media_type_string(type));
|
av_get_media_type_string(type));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
video_stream_idx = stream_idx;
|
|
||||||
video_stream = fmt_ctx->streams[video_stream_idx];
|
|
||||||
video_dec_ctx = dec_ctx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -123,8 +110,7 @@ static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0, got_frame;
|
||||||
AVPacket *pkt = NULL;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
fprintf(stderr, "Usage: %s <video>\n", argv[0]);
|
fprintf(stderr, "Usage: %s <video>\n", argv[0]);
|
||||||
@@ -132,6 +118,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
src_filename = argv[1];
|
src_filename = argv[1];
|
||||||
|
|
||||||
|
av_register_all();
|
||||||
|
|
||||||
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
|
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
|
||||||
fprintf(stderr, "Could not open source file %s\n", src_filename);
|
fprintf(stderr, "Could not open source file %s\n", src_filename);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -142,7 +130,10 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
open_codec_context(fmt_ctx, AVMEDIA_TYPE_VIDEO);
|
if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {
|
||||||
|
video_stream = fmt_ctx->streams[video_stream_idx];
|
||||||
|
video_dec_ctx = video_stream->codec;
|
||||||
|
}
|
||||||
|
|
||||||
av_dump_format(fmt_ctx, 0, src_filename, 0);
|
av_dump_format(fmt_ctx, 0, src_filename, 0);
|
||||||
|
|
||||||
@@ -159,31 +150,36 @@ int main(int argc, char **argv)
|
|||||||
goto end;
|
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");
|
printf("framenum,source,blockw,blockh,srcx,srcy,dstx,dsty,flags\n");
|
||||||
|
|
||||||
|
/* initialize packet, set data to NULL, let the demuxer fill it */
|
||||||
|
av_init_packet(&pkt);
|
||||||
|
pkt.data = NULL;
|
||||||
|
pkt.size = 0;
|
||||||
|
|
||||||
/* read frames from the file */
|
/* read frames from the file */
|
||||||
while (av_read_frame(fmt_ctx, pkt) >= 0) {
|
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
|
||||||
if (pkt->stream_index == video_stream_idx)
|
AVPacket orig_pkt = pkt;
|
||||||
ret = decode_packet(pkt);
|
do {
|
||||||
av_packet_unref(pkt);
|
ret = decode_packet(&got_frame, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
|
pkt.data += ret;
|
||||||
|
pkt.size -= ret;
|
||||||
|
} while (pkt.size > 0);
|
||||||
|
av_packet_unref(&orig_pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* flush cached frames */
|
/* flush cached frames */
|
||||||
decode_packet(NULL);
|
pkt.data = NULL;
|
||||||
|
pkt.size = 0;
|
||||||
|
do {
|
||||||
|
decode_packet(&got_frame, 1);
|
||||||
|
} while (got_frame);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
avcodec_free_context(&video_dec_ctx);
|
avcodec_close(video_dec_ctx);
|
||||||
avformat_close_input(&fmt_ctx);
|
avformat_close_input(&fmt_ctx);
|
||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
av_packet_free(&pkt);
|
|
||||||
return ret < 0;
|
return ret < 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,13 +64,13 @@ static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src,
|
|||||||
{
|
{
|
||||||
AVFilterGraph *filter_graph;
|
AVFilterGraph *filter_graph;
|
||||||
AVFilterContext *abuffer_ctx;
|
AVFilterContext *abuffer_ctx;
|
||||||
const AVFilter *abuffer;
|
AVFilter *abuffer;
|
||||||
AVFilterContext *volume_ctx;
|
AVFilterContext *volume_ctx;
|
||||||
const AVFilter *volume;
|
AVFilter *volume;
|
||||||
AVFilterContext *aformat_ctx;
|
AVFilterContext *aformat_ctx;
|
||||||
const AVFilter *aformat;
|
AVFilter *aformat;
|
||||||
AVFilterContext *abuffersink_ctx;
|
AVFilterContext *abuffersink_ctx;
|
||||||
const AVFilter *abuffersink;
|
AVFilter *abuffersink;
|
||||||
|
|
||||||
AVDictionary *options_dict = NULL;
|
AVDictionary *options_dict = NULL;
|
||||||
uint8_t options_str[1024];
|
uint8_t options_str[1024];
|
||||||
@@ -289,6 +289,8 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
avfilter_register_all();
|
||||||
|
|
||||||
/* Allocate the frame we will be using to store the data. */
|
/* Allocate the frame we will be using to store the data. */
|
||||||
frame = av_frame_alloc();
|
frame = av_frame_alloc();
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
|
|||||||
@@ -32,9 +32,9 @@
|
|||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
|
#include <libavfilter/avfiltergraph.h>
|
||||||
#include <libavfilter/buffersink.h>
|
#include <libavfilter/buffersink.h>
|
||||||
#include <libavfilter/buffersrc.h>
|
#include <libavfilter/buffersrc.h>
|
||||||
#include <libavutil/channel_layout.h>
|
|
||||||
#include <libavutil/opt.h>
|
#include <libavutil/opt.h>
|
||||||
|
|
||||||
static const char *filter_descr = "aresample=8000,aformat=sample_fmts=s16:channel_layouts=mono";
|
static const char *filter_descr = "aresample=8000,aformat=sample_fmts=s16:channel_layouts=mono";
|
||||||
@@ -49,8 +49,8 @@ static int audio_stream_index = -1;
|
|||||||
|
|
||||||
static int open_input_file(const char *filename)
|
static int open_input_file(const char *filename)
|
||||||
{
|
{
|
||||||
const AVCodec *dec;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
AVCodec *dec;
|
||||||
|
|
||||||
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
|
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
|
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
|
||||||
@@ -69,12 +69,8 @@ static int open_input_file(const char *filename)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
audio_stream_index = ret;
|
audio_stream_index = ret;
|
||||||
|
dec_ctx = fmt_ctx->streams[audio_stream_index]->codec;
|
||||||
/* create decoding context */
|
av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);
|
||||||
dec_ctx = avcodec_alloc_context3(dec);
|
|
||||||
if (!dec_ctx)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[audio_stream_index]->codecpar);
|
|
||||||
|
|
||||||
/* init the audio decoder */
|
/* init the audio decoder */
|
||||||
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
||||||
@@ -89,8 +85,8 @@ static int init_filters(const char *filters_descr)
|
|||||||
{
|
{
|
||||||
char args[512];
|
char args[512];
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
const AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
|
AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
|
||||||
const AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
|
AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
|
||||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||||
AVFilterInOut *inputs = avfilter_inout_alloc();
|
AVFilterInOut *inputs = avfilter_inout_alloc();
|
||||||
static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 };
|
static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 };
|
||||||
@@ -200,7 +196,7 @@ end:
|
|||||||
|
|
||||||
static void print_frame(const AVFrame *frame)
|
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 * av_get_channel_layout_nb_channels(av_frame_get_channel_layout(frame));
|
||||||
const uint16_t *p = (uint16_t*)frame->data[0];
|
const uint16_t *p = (uint16_t*)frame->data[0];
|
||||||
const uint16_t *p_end = p + n;
|
const uint16_t *p_end = p + n;
|
||||||
|
|
||||||
@@ -215,12 +211,13 @@ static void print_frame(const AVFrame *frame)
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
AVPacket *packet = av_packet_alloc();
|
AVPacket packet0, packet;
|
||||||
AVFrame *frame = av_frame_alloc();
|
AVFrame *frame = av_frame_alloc();
|
||||||
AVFrame *filt_frame = av_frame_alloc();
|
AVFrame *filt_frame = av_frame_alloc();
|
||||||
|
int got_frame;
|
||||||
|
|
||||||
if (!packet || !frame || !filt_frame) {
|
if (!frame || !filt_frame) {
|
||||||
fprintf(stderr, "Could not allocate frame or packet\n");
|
perror("Could not allocate frame");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
@@ -228,60 +225,64 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
av_register_all();
|
||||||
|
avfilter_register_all();
|
||||||
|
|
||||||
if ((ret = open_input_file(argv[1])) < 0)
|
if ((ret = open_input_file(argv[1])) < 0)
|
||||||
goto end;
|
goto end;
|
||||||
if ((ret = init_filters(filter_descr)) < 0)
|
if ((ret = init_filters(filter_descr)) < 0)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* read all packets */
|
/* read all packets */
|
||||||
|
packet0.data = NULL;
|
||||||
|
packet.data = NULL;
|
||||||
while (1) {
|
while (1) {
|
||||||
if ((ret = av_read_frame(fmt_ctx, packet)) < 0)
|
if (!packet0.data) {
|
||||||
break;
|
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
|
||||||
|
|
||||||
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;
|
break;
|
||||||
}
|
packet0 = packet;
|
||||||
|
}
|
||||||
while (ret >= 0) {
|
|
||||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
if (packet.stream_index == audio_stream_index) {
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
got_frame = 0;
|
||||||
break;
|
ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, &packet);
|
||||||
} else if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n");
|
av_log(NULL, AV_LOG_ERROR, "Error decoding audio\n");
|
||||||
goto end;
|
continue;
|
||||||
}
|
}
|
||||||
|
packet.size -= ret;
|
||||||
if (ret >= 0) {
|
packet.data += ret;
|
||||||
/* push the audio data from decoded frame into the filtergraph */
|
|
||||||
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
|
if (got_frame) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n");
|
/* push the audio data from decoded frame into the filtergraph */
|
||||||
break;
|
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, 0) < 0) {
|
||||||
}
|
av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n");
|
||||||
|
break;
|
||||||
/* pull filtered audio from the filtergraph */
|
}
|
||||||
while (1) {
|
|
||||||
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
|
/* pull filtered audio from the filtergraph */
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
while (1) {
|
||||||
break;
|
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
|
||||||
if (ret < 0)
|
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||||
goto end;
|
break;
|
||||||
print_frame(filt_frame);
|
if (ret < 0)
|
||||||
av_frame_unref(filt_frame);
|
goto end;
|
||||||
}
|
print_frame(filt_frame);
|
||||||
av_frame_unref(frame);
|
av_frame_unref(filt_frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (packet.size <= 0)
|
||||||
|
av_packet_unref(&packet0);
|
||||||
|
} else {
|
||||||
|
/* discard non-wanted packets */
|
||||||
|
av_packet_unref(&packet0);
|
||||||
}
|
}
|
||||||
av_packet_unref(packet);
|
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
avfilter_graph_free(&filter_graph);
|
avfilter_graph_free(&filter_graph);
|
||||||
avcodec_free_context(&dec_ctx);
|
avcodec_close(dec_ctx);
|
||||||
avformat_close_input(&fmt_ctx);
|
avformat_close_input(&fmt_ctx);
|
||||||
av_packet_free(&packet);
|
|
||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
av_frame_free(&filt_frame);
|
av_frame_free(&filt_frame);
|
||||||
|
|
||||||
|
|||||||
@@ -29,11 +29,10 @@
|
|||||||
|
|
||||||
#define _XOPEN_SOURCE 600 /* for usleep */
|
#define _XOPEN_SOURCE 600 /* for usleep */
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
|
#include <libavfilter/avfiltergraph.h>
|
||||||
#include <libavfilter/buffersink.h>
|
#include <libavfilter/buffersink.h>
|
||||||
#include <libavfilter/buffersrc.h>
|
#include <libavfilter/buffersrc.h>
|
||||||
#include <libavutil/opt.h>
|
#include <libavutil/opt.h>
|
||||||
@@ -53,8 +52,8 @@ static int64_t last_pts = AV_NOPTS_VALUE;
|
|||||||
|
|
||||||
static int open_input_file(const char *filename)
|
static int open_input_file(const char *filename)
|
||||||
{
|
{
|
||||||
const AVCodec *dec;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
AVCodec *dec;
|
||||||
|
|
||||||
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
|
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
|
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
|
||||||
@@ -73,12 +72,8 @@ static int open_input_file(const char *filename)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
video_stream_index = ret;
|
video_stream_index = ret;
|
||||||
|
dec_ctx = fmt_ctx->streams[video_stream_index]->codec;
|
||||||
/* create decoding context */
|
av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);
|
||||||
dec_ctx = avcodec_alloc_context3(dec);
|
|
||||||
if (!dec_ctx)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[video_stream_index]->codecpar);
|
|
||||||
|
|
||||||
/* init the video decoder */
|
/* init the video decoder */
|
||||||
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
||||||
@@ -93,8 +88,8 @@ static int init_filters(const char *filters_descr)
|
|||||||
{
|
{
|
||||||
char args[512];
|
char args[512];
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
const AVFilter *buffersrc = avfilter_get_by_name("buffer");
|
AVFilter *buffersrc = avfilter_get_by_name("buffer");
|
||||||
const AVFilter *buffersink = avfilter_get_by_name("buffersink");
|
AVFilter *buffersink = avfilter_get_by_name("buffersink");
|
||||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||||
AVFilterInOut *inputs = avfilter_inout_alloc();
|
AVFilterInOut *inputs = avfilter_inout_alloc();
|
||||||
AVRational time_base = fmt_ctx->streams[video_stream_index]->time_base;
|
AVRational time_base = fmt_ctx->streams[video_stream_index]->time_base;
|
||||||
@@ -210,22 +205,22 @@ static void display_frame(const AVFrame *frame, AVRational time_base)
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
AVPacket *packet;
|
AVPacket packet;
|
||||||
AVFrame *frame;
|
AVFrame *frame = av_frame_alloc();
|
||||||
AVFrame *filt_frame;
|
AVFrame *filt_frame = av_frame_alloc();
|
||||||
|
int got_frame;
|
||||||
|
|
||||||
|
if (!frame || !filt_frame) {
|
||||||
|
perror("Could not allocate frame");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
fprintf(stderr, "Usage: %s file\n", argv[0]);
|
fprintf(stderr, "Usage: %s file\n", argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = av_frame_alloc();
|
av_register_all();
|
||||||
filt_frame = av_frame_alloc();
|
avfilter_register_all();
|
||||||
packet = av_packet_alloc();
|
|
||||||
if (!frame || !filt_frame || !packet) {
|
|
||||||
fprintf(stderr, "Could not allocate frame or packet\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = open_input_file(argv[1])) < 0)
|
if ((ret = open_input_file(argv[1])) < 0)
|
||||||
goto end;
|
goto end;
|
||||||
@@ -234,26 +229,19 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* read all packets */
|
/* read all packets */
|
||||||
while (1) {
|
while (1) {
|
||||||
if ((ret = av_read_frame(fmt_ctx, packet)) < 0)
|
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (packet->stream_index == video_stream_index) {
|
if (packet.stream_index == video_stream_index) {
|
||||||
ret = avcodec_send_packet(dec_ctx, packet);
|
got_frame = 0;
|
||||||
|
ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, &packet);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");
|
av_log(NULL, AV_LOG_ERROR, "Error decoding video\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (ret >= 0) {
|
if (got_frame) {
|
||||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
frame->pts = av_frame_get_best_effort_timestamp(frame);
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
|
||||||
break;
|
|
||||||
} else if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->pts = frame->best_effort_timestamp;
|
|
||||||
|
|
||||||
/* push the decoded frame into the filtergraph */
|
/* push the decoded frame into the filtergraph */
|
||||||
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
|
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
|
||||||
@@ -274,15 +262,14 @@ int main(int argc, char **argv)
|
|||||||
av_frame_unref(frame);
|
av_frame_unref(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
av_packet_unref(packet);
|
av_packet_unref(&packet);
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
avfilter_graph_free(&filter_graph);
|
avfilter_graph_free(&filter_graph);
|
||||||
avcodec_free_context(&dec_ctx);
|
avcodec_close(dec_ctx);
|
||||||
avformat_close_input(&fmt_ctx);
|
avformat_close_input(&fmt_ctx);
|
||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
av_frame_free(&filt_frame);
|
av_frame_free(&filt_frame);
|
||||||
av_packet_free(&packet);
|
|
||||||
|
|
||||||
if (ret < 0 && ret != AVERROR_EOF) {
|
if (ret < 0 && ret != AVERROR_EOF) {
|
||||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||||
|
|||||||
@@ -33,19 +33,18 @@
|
|||||||
#include <libavutil/opt.h>
|
#include <libavutil/opt.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
static void process_client(AVIOContext *client, const char *in_uri)
|
void process_client(AVIOContext *client, const char *in_uri)
|
||||||
{
|
{
|
||||||
AVIOContext *input = NULL;
|
AVIOContext *input = NULL;
|
||||||
uint8_t buf[1024];
|
uint8_t buf[1024];
|
||||||
int ret, n, reply_code;
|
int ret, n, reply_code;
|
||||||
uint8_t *resource = NULL;
|
char *resource = NULL;
|
||||||
while ((ret = avio_handshake(client)) > 0) {
|
while ((ret = avio_handshake(client)) > 0) {
|
||||||
av_opt_get(client, "resource", AV_OPT_SEARCH_CHILDREN, &resource);
|
av_opt_get(client, "resource", AV_OPT_SEARCH_CHILDREN, &resource);
|
||||||
// check for strlen(resource) is necessary, because av_opt_get()
|
// check for strlen(resource) is necessary, because av_opt_get()
|
||||||
// may return empty string.
|
// may return empty string.
|
||||||
if (resource && strlen(resource))
|
if (resource && strlen(resource))
|
||||||
break;
|
break;
|
||||||
av_freep(&resource);
|
|
||||||
}
|
}
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto end;
|
goto end;
|
||||||
@@ -94,16 +93,15 @@ end:
|
|||||||
avio_close(client);
|
avio_close(client);
|
||||||
fprintf(stderr, "Closing input\n");
|
fprintf(stderr, "Closing input\n");
|
||||||
avio_close(input);
|
avio_close(input);
|
||||||
av_freep(&resource);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
av_log_set_level(AV_LOG_TRACE);
|
||||||
AVDictionary *options = NULL;
|
AVDictionary *options = NULL;
|
||||||
AVIOContext *client = NULL, *server = NULL;
|
AVIOContext *client = NULL, *server = NULL;
|
||||||
const char *in_uri, *out_uri;
|
const char *in_uri, *out_uri;
|
||||||
int ret, pid;
|
int ret, pid;
|
||||||
av_log_set_level(AV_LOG_TRACE);
|
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
printf("usage: %s input http://hostname[:port]\n"
|
printf("usage: %s input http://hostname[:port]\n"
|
||||||
"API example program to serve http to multiple clients.\n"
|
"API example program to serve http to multiple clients.\n"
|
||||||
@@ -114,6 +112,7 @@ int main(int argc, char **argv)
|
|||||||
in_uri = argv[1];
|
in_uri = argv[1];
|
||||||
out_uri = argv[2];
|
out_uri = argv[2];
|
||||||
|
|
||||||
|
av_register_all();
|
||||||
avformat_network_init();
|
avformat_network_init();
|
||||||
|
|
||||||
if ((ret = av_dict_set(&options, "listen", "2", 0)) < 0) {
|
if ((ret = av_dict_set(&options, "listen", "2", 0)) < 0) {
|
||||||
|
|||||||
@@ -1,256 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017 Jun Zhao
|
|
||||||
* Copyright (c) 2017 Kaixuan Liu
|
|
||||||
*
|
|
||||||
* HW Acceleration API (video decoding) decode sample
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* HW-Accelerated decoding example.
|
|
||||||
*
|
|
||||||
* @example hw_decode.c
|
|
||||||
* This example shows how to do HW-accelerated decoding with output
|
|
||||||
* frames from the HW video surfaces.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
|
||||||
#include <libavformat/avformat.h>
|
|
||||||
#include <libavutil/pixdesc.h>
|
|
||||||
#include <libavutil/hwcontext.h>
|
|
||||||
#include <libavutil/opt.h>
|
|
||||||
#include <libavutil/avassert.h>
|
|
||||||
#include <libavutil/imgutils.h>
|
|
||||||
|
|
||||||
static AVBufferRef *hw_device_ctx = NULL;
|
|
||||||
static enum AVPixelFormat hw_pix_fmt;
|
|
||||||
static FILE *output_file = NULL;
|
|
||||||
|
|
||||||
static int hw_decoder_init(AVCodecContext *ctx, const enum AVHWDeviceType type)
|
|
||||||
{
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
if ((err = av_hwdevice_ctx_create(&hw_device_ctx, type,
|
|
||||||
NULL, NULL, 0)) < 0) {
|
|
||||||
fprintf(stderr, "Failed to create specified HW device.\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum AVPixelFormat get_hw_format(AVCodecContext *ctx,
|
|
||||||
const enum AVPixelFormat *pix_fmts)
|
|
||||||
{
|
|
||||||
const enum AVPixelFormat *p;
|
|
||||||
|
|
||||||
for (p = pix_fmts; *p != -1; p++) {
|
|
||||||
if (*p == hw_pix_fmt)
|
|
||||||
return *p;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "Failed to get HW surface format.\n");
|
|
||||||
return AV_PIX_FMT_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int decode_write(AVCodecContext *avctx, AVPacket *packet)
|
|
||||||
{
|
|
||||||
AVFrame *frame = NULL, *sw_frame = NULL;
|
|
||||||
AVFrame *tmp_frame = NULL;
|
|
||||||
uint8_t *buffer = NULL;
|
|
||||||
int size;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
ret = avcodec_send_packet(avctx, packet);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error during decoding\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
if (!(frame = av_frame_alloc()) || !(sw_frame = av_frame_alloc())) {
|
|
||||||
fprintf(stderr, "Can not alloc frame\n");
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = avcodec_receive_frame(avctx, frame);
|
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
|
||||||
av_frame_free(&frame);
|
|
||||||
av_frame_free(&sw_frame);
|
|
||||||
return 0;
|
|
||||||
} else if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error while decoding\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frame->format == hw_pix_fmt) {
|
|
||||||
/* retrieve data from GPU to CPU */
|
|
||||||
if ((ret = av_hwframe_transfer_data(sw_frame, frame, 0)) < 0) {
|
|
||||||
fprintf(stderr, "Error transferring the data to system memory\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
tmp_frame = sw_frame;
|
|
||||||
} else
|
|
||||||
tmp_frame = frame;
|
|
||||||
|
|
||||||
size = av_image_get_buffer_size(tmp_frame->format, tmp_frame->width,
|
|
||||||
tmp_frame->height, 1);
|
|
||||||
buffer = av_malloc(size);
|
|
||||||
if (!buffer) {
|
|
||||||
fprintf(stderr, "Can not alloc buffer\n");
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
ret = av_image_copy_to_buffer(buffer, size,
|
|
||||||
(const uint8_t * const *)tmp_frame->data,
|
|
||||||
(const int *)tmp_frame->linesize, tmp_frame->format,
|
|
||||||
tmp_frame->width, tmp_frame->height, 1);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Can not copy image to buffer\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = fwrite(buffer, 1, size, output_file)) < 0) {
|
|
||||||
fprintf(stderr, "Failed to dump raw data.\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
fail:
|
|
||||||
av_frame_free(&frame);
|
|
||||||
av_frame_free(&sw_frame);
|
|
||||||
av_freep(&buffer);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
AVFormatContext *input_ctx = NULL;
|
|
||||||
int video_stream, ret;
|
|
||||||
AVStream *video = NULL;
|
|
||||||
AVCodecContext *decoder_ctx = NULL;
|
|
||||||
const AVCodec *decoder = NULL;
|
|
||||||
AVPacket *packet = NULL;
|
|
||||||
enum AVHWDeviceType type;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (argc < 4) {
|
|
||||||
fprintf(stderr, "Usage: %s <device type> <input file> <output file>\n", argv[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
type = av_hwdevice_find_type_by_name(argv[1]);
|
|
||||||
if (type == AV_HWDEVICE_TYPE_NONE) {
|
|
||||||
fprintf(stderr, "Device type %s is not supported.\n", argv[1]);
|
|
||||||
fprintf(stderr, "Available device types:");
|
|
||||||
while((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE)
|
|
||||||
fprintf(stderr, " %s", av_hwdevice_get_type_name(type));
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
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]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (avformat_find_stream_info(input_ctx, NULL) < 0) {
|
|
||||||
fprintf(stderr, "Cannot find input stream information.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find the video stream information */
|
|
||||||
ret = av_find_best_stream(input_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Cannot find a video stream in the input file\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
video_stream = ret;
|
|
||||||
|
|
||||||
for (i = 0;; i++) {
|
|
||||||
const AVCodecHWConfig *config = avcodec_get_hw_config(decoder, i);
|
|
||||||
if (!config) {
|
|
||||||
fprintf(stderr, "Decoder %s does not support device type %s.\n",
|
|
||||||
decoder->name, av_hwdevice_get_type_name(type));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
|
|
||||||
config->device_type == type) {
|
|
||||||
hw_pix_fmt = config->pix_fmt;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(decoder_ctx = avcodec_alloc_context3(decoder)))
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
|
|
||||||
video = input_ctx->streams[video_stream];
|
|
||||||
if (avcodec_parameters_to_context(decoder_ctx, video->codecpar) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
decoder_ctx->get_format = get_hw_format;
|
|
||||||
|
|
||||||
if (hw_decoder_init(decoder_ctx, type) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((ret = avcodec_open2(decoder_ctx, decoder, NULL)) < 0) {
|
|
||||||
fprintf(stderr, "Failed to open codec for stream #%u\n", video_stream);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* open the file to dump raw data */
|
|
||||||
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)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (video_stream == packet->stream_index)
|
|
||||||
ret = decode_write(decoder_ctx, packet);
|
|
||||||
|
|
||||||
av_packet_unref(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flush the decoder */
|
|
||||||
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);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
int main (int argc, char **argv)
|
int main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
AVFormatContext *fmt_ctx = NULL;
|
AVFormatContext *fmt_ctx = NULL;
|
||||||
const AVDictionaryEntry *tag = NULL;
|
AVDictionaryEntry *tag = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
@@ -44,14 +44,10 @@ int main (int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
av_register_all();
|
||||||
if ((ret = avformat_open_input(&fmt_ctx, argv[1], NULL, NULL)))
|
if ((ret = avformat_open_input(&fmt_ctx, argv[1], NULL, NULL)))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
|
while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
|
||||||
printf("%s=%s\n", tag->key, tag->value);
|
printf("%s=%s\n", tag->key, tag->value);
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,6 @@
|
|||||||
#include <libavutil/opt.h>
|
#include <libavutil/opt.h>
|
||||||
#include <libavutil/mathematics.h>
|
#include <libavutil/mathematics.h>
|
||||||
#include <libavutil/timestamp.h>
|
#include <libavutil/timestamp.h>
|
||||||
#include <libavcodec/avcodec.h>
|
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
#include <libswscale/swscale.h>
|
#include <libswscale/swscale.h>
|
||||||
#include <libswresample/swresample.h>
|
#include <libswresample/swresample.h>
|
||||||
@@ -62,8 +61,6 @@ typedef struct OutputStream {
|
|||||||
AVFrame *frame;
|
AVFrame *frame;
|
||||||
AVFrame *tmp_frame;
|
AVFrame *tmp_frame;
|
||||||
|
|
||||||
AVPacket *tmp_pkt;
|
|
||||||
|
|
||||||
float t, tincr, tincr2;
|
float t, tincr, tincr2;
|
||||||
|
|
||||||
struct SwsContext *sws_ctx;
|
struct SwsContext *sws_ctx;
|
||||||
@@ -81,50 +78,20 @@ static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)
|
|||||||
pkt->stream_index);
|
pkt->stream_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_frame(AVFormatContext *fmt_ctx, AVCodecContext *c,
|
static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
|
||||||
AVStream *st, AVFrame *frame, AVPacket *pkt)
|
|
||||||
{
|
{
|
||||||
int ret;
|
/* 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;
|
||||||
|
|
||||||
// send the frame to the encoder
|
/* Write the compressed frame to the media file. */
|
||||||
ret = avcodec_send_frame(c, frame);
|
log_packet(fmt_ctx, pkt);
|
||||||
if (ret < 0) {
|
return av_interleaved_write_frame(fmt_ctx, pkt);
|
||||||
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. */
|
/* Add an output stream. */
|
||||||
static void add_stream(OutputStream *ost, AVFormatContext *oc,
|
static void add_stream(OutputStream *ost, AVFormatContext *oc,
|
||||||
const AVCodec **codec,
|
AVCodec **codec,
|
||||||
enum AVCodecID codec_id)
|
enum AVCodecID codec_id)
|
||||||
{
|
{
|
||||||
AVCodecContext *c;
|
AVCodecContext *c;
|
||||||
@@ -138,12 +105,6 @@ static void add_stream(OutputStream *ost, AVFormatContext *oc,
|
|||||||
exit(1);
|
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);
|
ost->st = avformat_new_stream(oc, NULL);
|
||||||
if (!ost->st) {
|
if (!ost->st) {
|
||||||
fprintf(stderr, "Could not allocate stream\n");
|
fprintf(stderr, "Could not allocate stream\n");
|
||||||
@@ -209,7 +170,7 @@ static void add_stream(OutputStream *ost, AVFormatContext *oc,
|
|||||||
* the motion of the chroma plane does not match the luma plane. */
|
* the motion of the chroma plane does not match the luma plane. */
|
||||||
c->mb_decision = 2;
|
c->mb_decision = 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -251,8 +212,7 @@ static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void open_audio(AVFormatContext *oc, const AVCodec *codec,
|
static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg)
|
||||||
OutputStream *ost, AVDictionary *opt_arg)
|
|
||||||
{
|
{
|
||||||
AVCodecContext *c;
|
AVCodecContext *c;
|
||||||
int nb_samples;
|
int nb_samples;
|
||||||
@@ -294,25 +254,25 @@ static void open_audio(AVFormatContext *oc, const AVCodec *codec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* create resampler context */
|
/* create resampler context */
|
||||||
ost->swr_ctx = swr_alloc();
|
ost->swr_ctx = swr_alloc();
|
||||||
if (!ost->swr_ctx) {
|
if (!ost->swr_ctx) {
|
||||||
fprintf(stderr, "Could not allocate resampler context\n");
|
fprintf(stderr, "Could not allocate resampler context\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set options */
|
/* set options */
|
||||||
av_opt_set_int (ost->swr_ctx, "in_channel_count", c->channels, 0);
|
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_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_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_channel_count", c->channels, 0);
|
||||||
av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 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);
|
av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
|
||||||
|
|
||||||
/* initialize the resampling context */
|
/* initialize the resampling context */
|
||||||
if ((ret = swr_init(ost->swr_ctx)) < 0) {
|
if ((ret = swr_init(ost->swr_ctx)) < 0) {
|
||||||
fprintf(stderr, "Failed to initialize the resampling context\n");
|
fprintf(stderr, "Failed to initialize the resampling context\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
|
/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
|
||||||
@@ -325,7 +285,7 @@ static AVFrame *get_audio_frame(OutputStream *ost)
|
|||||||
|
|
||||||
/* check if we want to generate more frames */
|
/* check if we want to generate more frames */
|
||||||
if (av_compare_ts(ost->next_pts, ost->enc->time_base,
|
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;
|
return NULL;
|
||||||
|
|
||||||
for (j = 0; j <frame->nb_samples; j++) {
|
for (j = 0; j <frame->nb_samples; j++) {
|
||||||
@@ -349,20 +309,23 @@ static AVFrame *get_audio_frame(OutputStream *ost)
|
|||||||
static int write_audio_frame(AVFormatContext *oc, OutputStream *ost)
|
static int write_audio_frame(AVFormatContext *oc, OutputStream *ost)
|
||||||
{
|
{
|
||||||
AVCodecContext *c;
|
AVCodecContext *c;
|
||||||
|
AVPacket pkt = { 0 }; // data and size must be 0;
|
||||||
AVFrame *frame;
|
AVFrame *frame;
|
||||||
int ret;
|
int ret;
|
||||||
|
int got_packet;
|
||||||
int dst_nb_samples;
|
int dst_nb_samples;
|
||||||
|
|
||||||
|
av_init_packet(&pkt);
|
||||||
c = ost->enc;
|
c = ost->enc;
|
||||||
|
|
||||||
frame = get_audio_frame(ost);
|
frame = get_audio_frame(ost);
|
||||||
|
|
||||||
if (frame) {
|
if (frame) {
|
||||||
/* convert samples from native format to destination codec format, using the resampler */
|
/* convert samples from native format to destination codec format, using the resampler */
|
||||||
/* compute destination number of samples */
|
/* compute destination number of samples */
|
||||||
dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_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);
|
c->sample_rate, c->sample_rate, AV_ROUND_UP);
|
||||||
av_assert0(dst_nb_samples == frame->nb_samples);
|
av_assert0(dst_nb_samples == frame->nb_samples);
|
||||||
|
|
||||||
/* when we pass a frame to the encoder, it may keep a reference to it
|
/* when we pass a frame to the encoder, it may keep a reference to it
|
||||||
* internally;
|
* internally;
|
||||||
@@ -372,21 +335,36 @@ static int write_audio_frame(AVFormatContext *oc, OutputStream *ost)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
/* convert to destination format */
|
/* convert to destination format */
|
||||||
ret = swr_convert(ost->swr_ctx,
|
ret = swr_convert(ost->swr_ctx,
|
||||||
ost->frame->data, dst_nb_samples,
|
ost->frame->data, dst_nb_samples,
|
||||||
(const uint8_t **)frame->data, frame->nb_samples);
|
(const uint8_t **)frame->data, frame->nb_samples);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Error while converting\n");
|
fprintf(stderr, "Error while converting\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
frame = ost->frame;
|
frame = ost->frame;
|
||||||
|
|
||||||
frame->pts = av_rescale_q(ost->samples_count, (AVRational){1, c->sample_rate}, c->time_base);
|
frame->pts = av_rescale_q(ost->samples_count, (AVRational){1, c->sample_rate}, c->time_base);
|
||||||
ost->samples_count += dst_nb_samples;
|
ost->samples_count += dst_nb_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
return write_frame(oc, c, ost->st, frame, ost->tmp_pkt);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
@@ -406,7 +384,7 @@ static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
|
|||||||
picture->height = height;
|
picture->height = height;
|
||||||
|
|
||||||
/* allocate the buffers for the frame data */
|
/* allocate the buffers for the frame data */
|
||||||
ret = av_frame_get_buffer(picture, 0);
|
ret = av_frame_get_buffer(picture, 32);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Could not allocate frame data.\n");
|
fprintf(stderr, "Could not allocate frame data.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -415,8 +393,7 @@ static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
|
|||||||
return picture;
|
return picture;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void open_video(AVFormatContext *oc, const AVCodec *codec,
|
static void open_video(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg)
|
||||||
OutputStream *ost, AVDictionary *opt_arg)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
AVCodecContext *c = ost->enc;
|
AVCodecContext *c = ost->enc;
|
||||||
@@ -463,7 +440,15 @@ static void open_video(AVFormatContext *oc, const AVCodec *codec,
|
|||||||
static void fill_yuv_image(AVFrame *pict, int frame_index,
|
static void fill_yuv_image(AVFrame *pict, int frame_index,
|
||||||
int width, int height)
|
int width, int height)
|
||||||
{
|
{
|
||||||
int x, y, i;
|
int x, y, i, ret;
|
||||||
|
|
||||||
|
/* when we pass a frame to the encoder, it may keep a reference to it
|
||||||
|
* internally;
|
||||||
|
* make sure we do not overwrite it here
|
||||||
|
*/
|
||||||
|
ret = av_frame_make_writable(pict);
|
||||||
|
if (ret < 0)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
i = frame_index;
|
i = frame_index;
|
||||||
|
|
||||||
@@ -487,14 +472,9 @@ static AVFrame *get_video_frame(OutputStream *ost)
|
|||||||
|
|
||||||
/* check if we want to generate more frames */
|
/* check if we want to generate more frames */
|
||||||
if (av_compare_ts(ost->next_pts, c->time_base,
|
if (av_compare_ts(ost->next_pts, c->time_base,
|
||||||
STREAM_DURATION, (AVRational){ 1, 1 }) > 0)
|
STREAM_DURATION, (AVRational){ 1, 1 }) >= 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* when we pass a frame to the encoder, it may keep a reference to it
|
|
||||||
* internally; make sure we do not overwrite it here */
|
|
||||||
if (av_frame_make_writable(ost->frame) < 0)
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
|
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
|
||||||
/* as we only generate a YUV420P picture, we must convert it
|
/* as we only generate a YUV420P picture, we must convert it
|
||||||
* to the codec pixel format if needed */
|
* to the codec pixel format if needed */
|
||||||
@@ -511,9 +491,9 @@ static AVFrame *get_video_frame(OutputStream *ost)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fill_yuv_image(ost->tmp_frame, ost->next_pts, c->width, c->height);
|
fill_yuv_image(ost->tmp_frame, ost->next_pts, c->width, c->height);
|
||||||
sws_scale(ost->sws_ctx, (const uint8_t * const *) ost->tmp_frame->data,
|
sws_scale(ost->sws_ctx,
|
||||||
ost->tmp_frame->linesize, 0, c->height, ost->frame->data,
|
(const uint8_t * const *)ost->tmp_frame->data, ost->tmp_frame->linesize,
|
||||||
ost->frame->linesize);
|
0, c->height, ost->frame->data, ost->frame->linesize);
|
||||||
} else {
|
} else {
|
||||||
fill_yuv_image(ost->frame, ost->next_pts, c->width, c->height);
|
fill_yuv_image(ost->frame, ost->next_pts, c->width, c->height);
|
||||||
}
|
}
|
||||||
@@ -529,7 +509,37 @@ static AVFrame *get_video_frame(OutputStream *ost)
|
|||||||
*/
|
*/
|
||||||
static int write_video_frame(AVFormatContext *oc, OutputStream *ost)
|
static int write_video_frame(AVFormatContext *oc, OutputStream *ost)
|
||||||
{
|
{
|
||||||
return write_frame(oc, ost->enc, ost->st, get_video_frame(ost), ost->tmp_pkt);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void close_stream(AVFormatContext *oc, OutputStream *ost)
|
static void close_stream(AVFormatContext *oc, OutputStream *ost)
|
||||||
@@ -537,7 +547,6 @@ static void close_stream(AVFormatContext *oc, OutputStream *ost)
|
|||||||
avcodec_free_context(&ost->enc);
|
avcodec_free_context(&ost->enc);
|
||||||
av_frame_free(&ost->frame);
|
av_frame_free(&ost->frame);
|
||||||
av_frame_free(&ost->tmp_frame);
|
av_frame_free(&ost->tmp_frame);
|
||||||
av_packet_free(&ost->tmp_pkt);
|
|
||||||
sws_freeContext(ost->sws_ctx);
|
sws_freeContext(ost->sws_ctx);
|
||||||
swr_free(&ost->swr_ctx);
|
swr_free(&ost->swr_ctx);
|
||||||
}
|
}
|
||||||
@@ -548,16 +557,19 @@ static void close_stream(AVFormatContext *oc, OutputStream *ost)
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
OutputStream video_st = { 0 }, audio_st = { 0 };
|
OutputStream video_st = { 0 }, audio_st = { 0 };
|
||||||
const AVOutputFormat *fmt;
|
|
||||||
const char *filename;
|
const char *filename;
|
||||||
|
AVOutputFormat *fmt;
|
||||||
AVFormatContext *oc;
|
AVFormatContext *oc;
|
||||||
const AVCodec *audio_codec, *video_codec;
|
AVCodec *audio_codec, *video_codec;
|
||||||
int ret;
|
int ret;
|
||||||
int have_video = 0, have_audio = 0;
|
int have_video = 0, have_audio = 0;
|
||||||
int encode_video = 0, encode_audio = 0;
|
int encode_video = 0, encode_audio = 0;
|
||||||
AVDictionary *opt = NULL;
|
AVDictionary *opt = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* Initialize libavcodec, and register all codecs and formats. */
|
||||||
|
av_register_all();
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
printf("usage: %s output_file\n"
|
printf("usage: %s output_file\n"
|
||||||
"API example program to output a media file with libavformat.\n"
|
"API example program to output a media file with libavformat.\n"
|
||||||
|
|||||||
@@ -26,28 +26,186 @@
|
|||||||
*
|
*
|
||||||
* @example qsvdec.c
|
* @example qsvdec.c
|
||||||
* This example shows how to do QSV-accelerated H.264 decoding with output
|
* This example shows how to do QSV-accelerated H.264 decoding with output
|
||||||
* frames in the GPU video surfaces.
|
* frames in the VA-API video surfaces.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <mfx/mfxvideo.h>
|
||||||
|
|
||||||
|
#include <va/va.h>
|
||||||
|
#include <va/va_x11.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
#include "libavformat/avformat.h"
|
#include "libavformat/avformat.h"
|
||||||
#include "libavformat/avio.h"
|
#include "libavformat/avio.h"
|
||||||
|
|
||||||
#include "libavcodec/avcodec.h"
|
#include "libavcodec/avcodec.h"
|
||||||
|
#include "libavcodec/qsv.h"
|
||||||
|
|
||||||
#include "libavutil/buffer.h"
|
|
||||||
#include "libavutil/error.h"
|
#include "libavutil/error.h"
|
||||||
#include "libavutil/hwcontext.h"
|
|
||||||
#include "libavutil/hwcontext_qsv.h"
|
|
||||||
#include "libavutil/mem.h"
|
#include "libavutil/mem.h"
|
||||||
|
|
||||||
|
typedef struct DecodeContext {
|
||||||
|
mfxSession mfx_session;
|
||||||
|
VADisplay va_dpy;
|
||||||
|
|
||||||
|
VASurfaceID *surfaces;
|
||||||
|
mfxMemId *surface_ids;
|
||||||
|
int *surface_used;
|
||||||
|
int nb_surfaces;
|
||||||
|
|
||||||
|
mfxFrameInfo frame_info;
|
||||||
|
} DecodeContext;
|
||||||
|
|
||||||
|
static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
|
||||||
|
mfxFrameAllocResponse *resp)
|
||||||
|
{
|
||||||
|
DecodeContext *decode = pthis;
|
||||||
|
int err, i;
|
||||||
|
|
||||||
|
if (decode->surfaces) {
|
||||||
|
fprintf(stderr, "Multiple allocation requests.\n");
|
||||||
|
return MFX_ERR_MEMORY_ALLOC;
|
||||||
|
}
|
||||||
|
if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)) {
|
||||||
|
fprintf(stderr, "Unsupported surface type: %d\n", req->Type);
|
||||||
|
return MFX_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
if (req->Info.BitDepthLuma != 8 || req->Info.BitDepthChroma != 8 ||
|
||||||
|
req->Info.Shift || req->Info.FourCC != MFX_FOURCC_NV12 ||
|
||||||
|
req->Info.ChromaFormat != MFX_CHROMAFORMAT_YUV420) {
|
||||||
|
fprintf(stderr, "Unsupported surface properties.\n");
|
||||||
|
return MFX_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
decode->surfaces = av_malloc_array (req->NumFrameSuggested, sizeof(*decode->surfaces));
|
||||||
|
decode->surface_ids = av_malloc_array (req->NumFrameSuggested, sizeof(*decode->surface_ids));
|
||||||
|
decode->surface_used = av_mallocz_array(req->NumFrameSuggested, sizeof(*decode->surface_used));
|
||||||
|
if (!decode->surfaces || !decode->surface_ids || !decode->surface_used)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
err = vaCreateSurfaces(decode->va_dpy, VA_RT_FORMAT_YUV420,
|
||||||
|
req->Info.Width, req->Info.Height,
|
||||||
|
decode->surfaces, req->NumFrameSuggested,
|
||||||
|
NULL, 0);
|
||||||
|
if (err != VA_STATUS_SUCCESS) {
|
||||||
|
fprintf(stderr, "Error allocating VA surfaces\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
decode->nb_surfaces = req->NumFrameSuggested;
|
||||||
|
|
||||||
|
for (i = 0; i < decode->nb_surfaces; i++)
|
||||||
|
decode->surface_ids[i] = &decode->surfaces[i];
|
||||||
|
|
||||||
|
resp->mids = decode->surface_ids;
|
||||||
|
resp->NumFrameActual = decode->nb_surfaces;
|
||||||
|
|
||||||
|
decode->frame_info = req->Info;
|
||||||
|
|
||||||
|
return MFX_ERR_NONE;
|
||||||
|
fail:
|
||||||
|
av_freep(&decode->surfaces);
|
||||||
|
av_freep(&decode->surface_ids);
|
||||||
|
av_freep(&decode->surface_used);
|
||||||
|
|
||||||
|
return MFX_ERR_MEMORY_ALLOC;
|
||||||
|
}
|
||||||
|
|
||||||
|
static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
|
||||||
|
{
|
||||||
|
return MFX_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
|
||||||
|
{
|
||||||
|
return MFX_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
|
||||||
|
{
|
||||||
|
return MFX_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
|
||||||
|
{
|
||||||
|
*hdl = mid;
|
||||||
|
return MFX_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_surfaces(DecodeContext *decode)
|
||||||
|
{
|
||||||
|
if (decode->surfaces)
|
||||||
|
vaDestroySurfaces(decode->va_dpy, decode->surfaces, decode->nb_surfaces);
|
||||||
|
av_freep(&decode->surfaces);
|
||||||
|
av_freep(&decode->surface_ids);
|
||||||
|
av_freep(&decode->surface_used);
|
||||||
|
decode->nb_surfaces = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_buffer(void *opaque, uint8_t *data)
|
||||||
|
{
|
||||||
|
int *used = opaque;
|
||||||
|
*used = 0;
|
||||||
|
av_freep(&data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
|
||||||
|
{
|
||||||
|
DecodeContext *decode = avctx->opaque;
|
||||||
|
|
||||||
|
mfxFrameSurface1 *surf;
|
||||||
|
AVBufferRef *surf_buf;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
for (idx = 0; idx < decode->nb_surfaces; idx++) {
|
||||||
|
if (!decode->surface_used[idx])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (idx == decode->nb_surfaces) {
|
||||||
|
fprintf(stderr, "No free surfaces\n");
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
surf = av_mallocz(sizeof(*surf));
|
||||||
|
if (!surf)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
surf_buf = av_buffer_create((uint8_t*)surf, sizeof(*surf), free_buffer,
|
||||||
|
&decode->surface_used[idx], AV_BUFFER_FLAG_READONLY);
|
||||||
|
if (!surf_buf) {
|
||||||
|
av_freep(&surf);
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
surf->Info = decode->frame_info;
|
||||||
|
surf->Data.MemId = &decode->surfaces[idx];
|
||||||
|
|
||||||
|
frame->buf[0] = surf_buf;
|
||||||
|
frame->data[3] = (uint8_t*)surf;
|
||||||
|
|
||||||
|
decode->surface_used[idx] = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
|
static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
|
||||||
{
|
{
|
||||||
while (*pix_fmts != AV_PIX_FMT_NONE) {
|
while (*pix_fmts != AV_PIX_FMT_NONE) {
|
||||||
if (*pix_fmts == AV_PIX_FMT_QSV) {
|
if (*pix_fmts == AV_PIX_FMT_QSV) {
|
||||||
|
if (!avctx->hwaccel_context) {
|
||||||
|
DecodeContext *decode = avctx->opaque;
|
||||||
|
AVQSVContext *qsv = av_qsv_alloc_context();
|
||||||
|
if (!qsv)
|
||||||
|
return AV_PIX_FMT_NONE;
|
||||||
|
|
||||||
|
qsv->session = decode->mfx_session;
|
||||||
|
qsv->iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
|
||||||
|
|
||||||
|
avctx->hwaccel_context = qsv;
|
||||||
|
}
|
||||||
|
|
||||||
return AV_PIX_FMT_QSV;
|
return AV_PIX_FMT_QSV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,48 +217,87 @@ static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
|
|||||||
return AV_PIX_FMT_NONE;
|
return AV_PIX_FMT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_packet(AVCodecContext *decoder_ctx,
|
static int decode_packet(DecodeContext *decode, AVCodecContext *decoder_ctx,
|
||||||
AVFrame *frame, AVFrame *sw_frame,
|
AVFrame *frame, AVPacket *pkt,
|
||||||
AVPacket *pkt, AVIOContext *output_ctx)
|
AVIOContext *output_ctx)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
int got_frame = 1;
|
||||||
|
|
||||||
ret = avcodec_send_packet(decoder_ctx, pkt);
|
while (pkt->size > 0 || (!pkt->data && got_frame)) {
|
||||||
if (ret < 0) {
|
ret = avcodec_decode_video2(decoder_ctx, frame, &got_frame, pkt);
|
||||||
fprintf(stderr, "Error during decoding\n");
|
if (ret < 0) {
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (ret >= 0) {
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
ret = avcodec_receive_frame(decoder_ctx, frame);
|
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
|
||||||
break;
|
|
||||||
else if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error during decoding\n");
|
fprintf(stderr, "Error during decoding\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pkt->data += ret;
|
||||||
|
pkt->size -= ret;
|
||||||
|
|
||||||
/* A real program would do something useful with the decoded frame here.
|
/* A real program would do something useful with the decoded frame here.
|
||||||
* We just retrieve the raw data and write it to a file, which is rather
|
* We just retrieve the raw data and write it to a file, which is rather
|
||||||
* useless but pedagogic. */
|
* useless but pedagogic. */
|
||||||
ret = av_hwframe_transfer_data(sw_frame, frame, 0);
|
if (got_frame) {
|
||||||
if (ret < 0) {
|
mfxFrameSurface1 *surf = (mfxFrameSurface1*)frame->data[3];
|
||||||
fprintf(stderr, "Error transferring the data to system memory\n");
|
VASurfaceID surface = *(VASurfaceID*)surf->Data.MemId;
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < FF_ARRAY_ELEMS(sw_frame->data) && sw_frame->data[i]; i++)
|
VAImageFormat img_fmt = {
|
||||||
for (j = 0; j < (sw_frame->height >> (i > 0)); j++)
|
.fourcc = VA_FOURCC_NV12,
|
||||||
avio_write(output_ctx, sw_frame->data[i] + j * sw_frame->linesize[i], sw_frame->width);
|
.byte_order = VA_LSB_FIRST,
|
||||||
|
.bits_per_pixel = 8,
|
||||||
|
.depth = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
VAImage img;
|
||||||
|
|
||||||
|
VAStatus err;
|
||||||
|
uint8_t *data;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
img.buf = VA_INVALID_ID;
|
||||||
|
img.image_id = VA_INVALID_ID;
|
||||||
|
|
||||||
|
err = vaCreateImage(decode->va_dpy, &img_fmt,
|
||||||
|
frame->width, frame->height, &img);
|
||||||
|
if (err != VA_STATUS_SUCCESS) {
|
||||||
|
fprintf(stderr, "Error creating an image: %s\n",
|
||||||
|
vaErrorStr(err));
|
||||||
|
ret = AVERROR_UNKNOWN;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = vaGetImage(decode->va_dpy, surface, 0, 0,
|
||||||
|
frame->width, frame->height,
|
||||||
|
img.image_id);
|
||||||
|
if (err != VA_STATUS_SUCCESS) {
|
||||||
|
fprintf(stderr, "Error getting an image: %s\n",
|
||||||
|
vaErrorStr(err));
|
||||||
|
ret = AVERROR_UNKNOWN;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = vaMapBuffer(decode->va_dpy, img.buf, (void**)&data);
|
||||||
|
if (err != VA_STATUS_SUCCESS) {
|
||||||
|
fprintf(stderr, "Error mapping the image buffer: %s\n",
|
||||||
|
vaErrorStr(err));
|
||||||
|
ret = AVERROR_UNKNOWN;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < img.num_planes; i++)
|
||||||
|
for (j = 0; j < (img.height >> (i > 0)); j++)
|
||||||
|
avio_write(output_ctx, data + img.offsets[i] + j * img.pitches[i], img.width);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
av_frame_unref(sw_frame);
|
if (img.buf != VA_INVALID_ID)
|
||||||
av_frame_unref(frame);
|
vaUnmapBuffer(decode->va_dpy, img.buf);
|
||||||
|
if (img.image_id != VA_INVALID_ID)
|
||||||
|
vaDestroyImage(decode->va_dpy, img.image_id);
|
||||||
|
av_frame_unref(frame);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -113,14 +310,31 @@ int main(int argc, char **argv)
|
|||||||
AVCodecContext *decoder_ctx = NULL;
|
AVCodecContext *decoder_ctx = NULL;
|
||||||
const AVCodec *decoder;
|
const AVCodec *decoder;
|
||||||
|
|
||||||
AVPacket *pkt = NULL;
|
AVPacket pkt = { 0 };
|
||||||
AVFrame *frame = NULL, *sw_frame = NULL;
|
AVFrame *frame = NULL;
|
||||||
|
|
||||||
|
DecodeContext decode = { NULL };
|
||||||
|
|
||||||
|
Display *dpy = NULL;
|
||||||
|
int va_ver_major, va_ver_minor;
|
||||||
|
|
||||||
|
mfxIMPL mfx_impl = MFX_IMPL_AUTO_ANY;
|
||||||
|
mfxVersion mfx_ver = { { 1, 1 } };
|
||||||
|
|
||||||
|
mfxFrameAllocator frame_allocator = {
|
||||||
|
.pthis = &decode,
|
||||||
|
.Alloc = frame_alloc,
|
||||||
|
.Lock = frame_lock,
|
||||||
|
.Unlock = frame_unlock,
|
||||||
|
.GetHDL = frame_get_hdl,
|
||||||
|
.Free = frame_free,
|
||||||
|
};
|
||||||
|
|
||||||
AVIOContext *output_ctx = NULL;
|
AVIOContext *output_ctx = NULL;
|
||||||
|
|
||||||
int ret, i;
|
int ret, i, err;
|
||||||
|
|
||||||
AVBufferRef *device_ref = NULL;
|
av_register_all();
|
||||||
|
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||||
@@ -148,13 +362,34 @@ int main(int argc, char **argv)
|
|||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open the hardware device */
|
/* initialize VA-API */
|
||||||
ret = av_hwdevice_ctx_create(&device_ref, AV_HWDEVICE_TYPE_QSV,
|
dpy = XOpenDisplay(NULL);
|
||||||
"auto", NULL, 0);
|
if (!dpy) {
|
||||||
if (ret < 0) {
|
fprintf(stderr, "Cannot open the X display\n");
|
||||||
fprintf(stderr, "Cannot open the hardware device\n");
|
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
decode.va_dpy = vaGetDisplay(dpy);
|
||||||
|
if (!decode.va_dpy) {
|
||||||
|
fprintf(stderr, "Cannot open the VA display\n");
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = vaInitialize(decode.va_dpy, &va_ver_major, &va_ver_minor);
|
||||||
|
if (err != VA_STATUS_SUCCESS) {
|
||||||
|
fprintf(stderr, "Cannot initialize VA: %s\n", vaErrorStr(err));
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Initialized VA v%d.%d\n", va_ver_major, va_ver_minor);
|
||||||
|
|
||||||
|
/* initialize an MFX session */
|
||||||
|
err = MFXInit(mfx_impl, &mfx_ver, &decode.mfx_session);
|
||||||
|
if (err != MFX_ERR_NONE) {
|
||||||
|
fprintf(stderr, "Error initializing an MFX session\n");
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
MFXVideoCORE_SetHandle(decode.mfx_session, MFX_HANDLE_VA_DISPLAY, decode.va_dpy);
|
||||||
|
MFXVideoCORE_SetFrameAllocator(decode.mfx_session, &frame_allocator);
|
||||||
|
|
||||||
/* initialize the decoder */
|
/* initialize the decoder */
|
||||||
decoder = avcodec_find_decoder_by_name("h264_qsv");
|
decoder = avcodec_find_decoder_by_name("h264_qsv");
|
||||||
@@ -180,9 +415,10 @@ int main(int argc, char **argv)
|
|||||||
video_st->codecpar->extradata_size);
|
video_st->codecpar->extradata_size);
|
||||||
decoder_ctx->extradata_size = video_st->codecpar->extradata_size;
|
decoder_ctx->extradata_size = video_st->codecpar->extradata_size;
|
||||||
}
|
}
|
||||||
|
decoder_ctx->refcounted_frames = 1;
|
||||||
|
|
||||||
|
decoder_ctx->opaque = &decode;
|
||||||
decoder_ctx->hw_device_ctx = av_buffer_ref(device_ref);
|
decoder_ctx->get_buffer2 = get_buffer;
|
||||||
decoder_ctx->get_format = get_format;
|
decoder_ctx->get_format = get_format;
|
||||||
|
|
||||||
ret = avcodec_open2(decoder_ctx, NULL, NULL);
|
ret = avcodec_open2(decoder_ctx, NULL, NULL);
|
||||||
@@ -198,28 +434,28 @@ int main(int argc, char **argv)
|
|||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = av_frame_alloc();
|
frame = av_frame_alloc();
|
||||||
sw_frame = av_frame_alloc();
|
if (!frame) {
|
||||||
pkt = av_packet_alloc();
|
|
||||||
if (!frame || !sw_frame || !pkt) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
ret = AVERROR(ENOMEM);
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* actual decoding */
|
/* actual decoding */
|
||||||
while (ret >= 0) {
|
while (ret >= 0) {
|
||||||
ret = av_read_frame(input_ctx, pkt);
|
ret = av_read_frame(input_ctx, &pkt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (pkt->stream_index == video_st->index)
|
if (pkt.stream_index == video_st->index)
|
||||||
ret = decode_packet(decoder_ctx, frame, sw_frame, pkt, output_ctx);
|
ret = decode_packet(&decode, decoder_ctx, frame, &pkt, output_ctx);
|
||||||
|
|
||||||
av_packet_unref(pkt);
|
av_packet_unref(&pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* flush the decoder */
|
/* flush the decoder */
|
||||||
ret = decode_packet(decoder_ctx, frame, sw_frame, NULL, output_ctx);
|
pkt.data = NULL;
|
||||||
|
pkt.size = 0;
|
||||||
|
ret = decode_packet(&decode, decoder_ctx, frame, &pkt, output_ctx);
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -231,12 +467,19 @@ finish:
|
|||||||
avformat_close_input(&input_ctx);
|
avformat_close_input(&input_ctx);
|
||||||
|
|
||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
av_frame_free(&sw_frame);
|
|
||||||
av_packet_free(&pkt);
|
|
||||||
|
|
||||||
|
if (decoder_ctx)
|
||||||
|
av_freep(&decoder_ctx->hwaccel_context);
|
||||||
avcodec_free_context(&decoder_ctx);
|
avcodec_free_context(&decoder_ctx);
|
||||||
|
|
||||||
av_buffer_unref(&device_ref);
|
free_surfaces(&decode);
|
||||||
|
|
||||||
|
if (decode.mfx_session)
|
||||||
|
MFXClose(decode.mfx_session);
|
||||||
|
if (decode.va_dpy)
|
||||||
|
vaTerminate(decode.va_dpy);
|
||||||
|
if (dpy)
|
||||||
|
XCloseDisplay(dpy);
|
||||||
|
|
||||||
avio_close(output_ctx);
|
avio_close(output_ctx);
|
||||||
|
|
||||||
|
|||||||
@@ -45,14 +45,11 @@ static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt, cons
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const AVOutputFormat *ofmt = NULL;
|
AVOutputFormat *ofmt = NULL;
|
||||||
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
|
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
|
||||||
AVPacket *pkt = NULL;
|
AVPacket pkt;
|
||||||
const char *in_filename, *out_filename;
|
const char *in_filename, *out_filename;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
int stream_index = 0;
|
|
||||||
int *stream_mapping = NULL;
|
|
||||||
int stream_mapping_size = 0;
|
|
||||||
|
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
printf("usage: %s input output\n"
|
printf("usage: %s input output\n"
|
||||||
@@ -65,11 +62,7 @@ int main(int argc, char **argv)
|
|||||||
in_filename = argv[1];
|
in_filename = argv[1];
|
||||||
out_filename = argv[2];
|
out_filename = argv[2];
|
||||||
|
|
||||||
pkt = av_packet_alloc();
|
av_register_all();
|
||||||
if (!pkt) {
|
|
||||||
fprintf(stderr, "Could not allocate AVPacket\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
|
if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
|
||||||
fprintf(stderr, "Could not open input file '%s'", in_filename);
|
fprintf(stderr, "Could not open input file '%s'", in_filename);
|
||||||
@@ -90,42 +83,25 @@ int main(int argc, char **argv)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_mapping_size = ifmt_ctx->nb_streams;
|
|
||||||
stream_mapping = av_calloc(stream_mapping_size, sizeof(*stream_mapping));
|
|
||||||
if (!stream_mapping) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
ofmt = ofmt_ctx->oformat;
|
ofmt = ofmt_ctx->oformat;
|
||||||
|
|
||||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||||
AVStream *out_stream;
|
|
||||||
AVStream *in_stream = ifmt_ctx->streams[i];
|
AVStream *in_stream = ifmt_ctx->streams[i];
|
||||||
AVCodecParameters *in_codecpar = in_stream->codecpar;
|
AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
|
||||||
|
|
||||||
if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
|
|
||||||
in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
|
|
||||||
in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
|
|
||||||
stream_mapping[i] = -1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream_mapping[i] = stream_index++;
|
|
||||||
|
|
||||||
out_stream = avformat_new_stream(ofmt_ctx, NULL);
|
|
||||||
if (!out_stream) {
|
if (!out_stream) {
|
||||||
fprintf(stderr, "Failed allocating output stream\n");
|
fprintf(stderr, "Failed allocating output stream\n");
|
||||||
ret = AVERROR_UNKNOWN;
|
ret = AVERROR_UNKNOWN;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar);
|
ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Failed to copy codec parameters\n");
|
fprintf(stderr, "Failed to copy context from input to output stream codec context\n");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
out_stream->codecpar->codec_tag = 0;
|
out_stream->codec->codec_tag = 0;
|
||||||
|
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
||||||
|
out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||||
}
|
}
|
||||||
av_dump_format(ofmt_ctx, 0, out_filename, 1);
|
av_dump_format(ofmt_ctx, 0, out_filename, 1);
|
||||||
|
|
||||||
@@ -146,39 +122,32 @@ int main(int argc, char **argv)
|
|||||||
while (1) {
|
while (1) {
|
||||||
AVStream *in_stream, *out_stream;
|
AVStream *in_stream, *out_stream;
|
||||||
|
|
||||||
ret = av_read_frame(ifmt_ctx, pkt);
|
ret = av_read_frame(ifmt_ctx, &pkt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
in_stream = ifmt_ctx->streams[pkt->stream_index];
|
in_stream = ifmt_ctx->streams[pkt.stream_index];
|
||||||
if (pkt->stream_index >= stream_mapping_size ||
|
out_stream = ofmt_ctx->streams[pkt.stream_index];
|
||||||
stream_mapping[pkt->stream_index] < 0) {
|
|
||||||
av_packet_unref(pkt);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
pkt->stream_index = stream_mapping[pkt->stream_index];
|
log_packet(ifmt_ctx, &pkt, "in");
|
||||||
out_stream = ofmt_ctx->streams[pkt->stream_index];
|
|
||||||
log_packet(ifmt_ctx, pkt, "in");
|
|
||||||
|
|
||||||
/* copy packet */
|
/* copy packet */
|
||||||
av_packet_rescale_ts(pkt, in_stream->time_base, out_stream->time_base);
|
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->pos = -1;
|
pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
|
||||||
log_packet(ofmt_ctx, pkt, "out");
|
pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
|
||||||
|
pkt.pos = -1;
|
||||||
|
log_packet(ofmt_ctx, &pkt, "out");
|
||||||
|
|
||||||
ret = av_interleaved_write_frame(ofmt_ctx, pkt);
|
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) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Error muxing packet\n");
|
fprintf(stderr, "Error muxing packet\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
av_packet_unref(&pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
av_write_trailer(ofmt_ctx);
|
av_write_trailer(ofmt_ctx);
|
||||||
end:
|
end:
|
||||||
av_packet_free(&pkt);
|
|
||||||
|
|
||||||
avformat_close_input(&ifmt_ctx);
|
avformat_close_input(&ifmt_ctx);
|
||||||
|
|
||||||
@@ -187,8 +156,6 @@ end:
|
|||||||
avio_closep(&ofmt_ctx->pb);
|
avio_closep(&ofmt_ctx->pb);
|
||||||
avformat_free_context(ofmt_ctx);
|
avformat_free_context(ofmt_ctx);
|
||||||
|
|
||||||
av_freep(&stream_mapping);
|
|
||||||
|
|
||||||
if (ret < 0 && ret != AVERROR_EOF) {
|
if (ret < 0 && ret != AVERROR_EOF) {
|
||||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2018 Andreas Unterweger
|
|
||||||
*
|
|
||||||
* This file is part of FFmpeg.
|
* This file is part of FFmpeg.
|
||||||
*
|
*
|
||||||
* FFmpeg is free software; you can redistribute it and/or
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
@@ -10,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* FFmpeg is distributed in the hope that it will be useful,
|
* FFmpeg is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
@@ -20,11 +18,10 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* Simple audio converter
|
* simple audio converter
|
||||||
*
|
*
|
||||||
* @example transcode_aac.c
|
* @example transcode_aac.c
|
||||||
* Convert an input audio file to AAC in an MP4 container using FFmpeg.
|
* Convert an input audio file to AAC in an MP4 container using FFmpeg.
|
||||||
* Formats other than MP4 are supported based on the output file extension.
|
|
||||||
* @author Andreas Unterweger (dustsigns@gmail.com)
|
* @author Andreas Unterweger (dustsigns@gmail.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -38,50 +35,55 @@
|
|||||||
#include "libavutil/audio_fifo.h"
|
#include "libavutil/audio_fifo.h"
|
||||||
#include "libavutil/avassert.h"
|
#include "libavutil/avassert.h"
|
||||||
#include "libavutil/avstring.h"
|
#include "libavutil/avstring.h"
|
||||||
#include "libavutil/channel_layout.h"
|
|
||||||
#include "libavutil/frame.h"
|
#include "libavutil/frame.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
|
|
||||||
#include "libswresample/swresample.h"
|
#include "libswresample/swresample.h"
|
||||||
|
|
||||||
/* The output bit rate in bit/s */
|
/** The output bit rate in kbit/s */
|
||||||
#define OUTPUT_BIT_RATE 96000
|
#define OUTPUT_BIT_RATE 96000
|
||||||
/* The number of output channels */
|
/** The number of output channels */
|
||||||
#define OUTPUT_CHANNELS 2
|
#define OUTPUT_CHANNELS 2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open an input file and the required decoder.
|
* Convert an error code into a text message.
|
||||||
* @param filename File to be opened
|
* @param error Error code to be converted
|
||||||
* @param[out] input_format_context Format context of opened file
|
* @return Corresponding error text (not thread-safe)
|
||||||
* @param[out] input_codec_context Codec context of opened file
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
*/
|
||||||
|
static const char *get_error_text(const int error)
|
||||||
|
{
|
||||||
|
static char error_buffer[255];
|
||||||
|
av_strerror(error, error_buffer, sizeof(error_buffer));
|
||||||
|
return error_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Open an input file and the required decoder. */
|
||||||
static int open_input_file(const char *filename,
|
static int open_input_file(const char *filename,
|
||||||
AVFormatContext **input_format_context,
|
AVFormatContext **input_format_context,
|
||||||
AVCodecContext **input_codec_context)
|
AVCodecContext **input_codec_context)
|
||||||
{
|
{
|
||||||
AVCodecContext *avctx;
|
AVCodecContext *avctx;
|
||||||
const AVCodec *input_codec;
|
AVCodec *input_codec;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* Open the input file to read from it. */
|
/** Open the input file to read from it. */
|
||||||
if ((error = avformat_open_input(input_format_context, filename, NULL,
|
if ((error = avformat_open_input(input_format_context, filename, NULL,
|
||||||
NULL)) < 0) {
|
NULL)) < 0) {
|
||||||
fprintf(stderr, "Could not open input file '%s' (error '%s')\n",
|
fprintf(stderr, "Could not open input file '%s' (error '%s')\n",
|
||||||
filename, av_err2str(error));
|
filename, get_error_text(error));
|
||||||
*input_format_context = NULL;
|
*input_format_context = NULL;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get information on the input file (number of streams etc.). */
|
/** Get information on the input file (number of streams etc.). */
|
||||||
if ((error = avformat_find_stream_info(*input_format_context, NULL)) < 0) {
|
if ((error = avformat_find_stream_info(*input_format_context, NULL)) < 0) {
|
||||||
fprintf(stderr, "Could not open find stream info (error '%s')\n",
|
fprintf(stderr, "Could not open find stream info (error '%s')\n",
|
||||||
av_err2str(error));
|
get_error_text(error));
|
||||||
avformat_close_input(input_format_context);
|
avformat_close_input(input_format_context);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure that there is only one stream in the input file. */
|
/** Make sure that there is only one stream in the input file. */
|
||||||
if ((*input_format_context)->nb_streams != 1) {
|
if ((*input_format_context)->nb_streams != 1) {
|
||||||
fprintf(stderr, "Expected one audio input stream, but found %d\n",
|
fprintf(stderr, "Expected one audio input stream, but found %d\n",
|
||||||
(*input_format_context)->nb_streams);
|
(*input_format_context)->nb_streams);
|
||||||
@@ -89,14 +91,14 @@ static int open_input_file(const char *filename,
|
|||||||
return AVERROR_EXIT;
|
return AVERROR_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find a decoder for the audio stream. */
|
/** 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((*input_format_context)->streams[0]->codecpar->codec_id))) {
|
||||||
fprintf(stderr, "Could not find input codec\n");
|
fprintf(stderr, "Could not find input codec\n");
|
||||||
avformat_close_input(input_format_context);
|
avformat_close_input(input_format_context);
|
||||||
return AVERROR_EXIT;
|
return AVERROR_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a new decoding context. */
|
/** allocate a new decoding context */
|
||||||
avctx = avcodec_alloc_context3(input_codec);
|
avctx = avcodec_alloc_context3(input_codec);
|
||||||
if (!avctx) {
|
if (!avctx) {
|
||||||
fprintf(stderr, "Could not allocate a decoding context\n");
|
fprintf(stderr, "Could not allocate a decoding context\n");
|
||||||
@@ -104,7 +106,7 @@ static int open_input_file(const char *filename,
|
|||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the stream parameters with demuxer information. */
|
/** 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, (*input_format_context)->streams[0]->codecpar);
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
avformat_close_input(input_format_context);
|
avformat_close_input(input_format_context);
|
||||||
@@ -112,16 +114,16 @@ static int open_input_file(const char *filename,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open the decoder for the audio stream to use it later. */
|
/** Open the decoder for the audio stream to use it later. */
|
||||||
if ((error = avcodec_open2(avctx, input_codec, NULL)) < 0) {
|
if ((error = avcodec_open2(avctx, input_codec, NULL)) < 0) {
|
||||||
fprintf(stderr, "Could not open input codec (error '%s')\n",
|
fprintf(stderr, "Could not open input codec (error '%s')\n",
|
||||||
av_err2str(error));
|
get_error_text(error));
|
||||||
avcodec_free_context(&avctx);
|
avcodec_free_context(&avctx);
|
||||||
avformat_close_input(input_format_context);
|
avformat_close_input(input_format_context);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the decoder context for easier access later. */
|
/** Save the decoder context for easier access later. */
|
||||||
*input_codec_context = avctx;
|
*input_codec_context = avctx;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -131,11 +133,6 @@ static int open_input_file(const char *filename,
|
|||||||
* Open an output file and the required encoder.
|
* Open an output file and the required encoder.
|
||||||
* Also set some basic encoder parameters.
|
* Also set some basic encoder parameters.
|
||||||
* Some of these parameters are based on the input file's parameters.
|
* Some of these parameters are based on the input file's parameters.
|
||||||
* @param filename File to be opened
|
|
||||||
* @param input_codec_context Codec context of input file
|
|
||||||
* @param[out] output_format_context Format context of output file
|
|
||||||
* @param[out] output_codec_context Codec context of output file
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
*/
|
||||||
static int open_output_file(const char *filename,
|
static int open_output_file(const char *filename,
|
||||||
AVCodecContext *input_codec_context,
|
AVCodecContext *input_codec_context,
|
||||||
@@ -145,46 +142,43 @@ static int open_output_file(const char *filename,
|
|||||||
AVCodecContext *avctx = NULL;
|
AVCodecContext *avctx = NULL;
|
||||||
AVIOContext *output_io_context = NULL;
|
AVIOContext *output_io_context = NULL;
|
||||||
AVStream *stream = NULL;
|
AVStream *stream = NULL;
|
||||||
const AVCodec *output_codec = NULL;
|
AVCodec *output_codec = NULL;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* Open the output file to write to it. */
|
/** Open the output file to write to it. */
|
||||||
if ((error = avio_open(&output_io_context, filename,
|
if ((error = avio_open(&output_io_context, filename,
|
||||||
AVIO_FLAG_WRITE)) < 0) {
|
AVIO_FLAG_WRITE)) < 0) {
|
||||||
fprintf(stderr, "Could not open output file '%s' (error '%s')\n",
|
fprintf(stderr, "Could not open output file '%s' (error '%s')\n",
|
||||||
filename, av_err2str(error));
|
filename, get_error_text(error));
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new format context for the output container format. */
|
/** Create a new format context for the output container format. */
|
||||||
if (!(*output_format_context = avformat_alloc_context())) {
|
if (!(*output_format_context = avformat_alloc_context())) {
|
||||||
fprintf(stderr, "Could not allocate output format context\n");
|
fprintf(stderr, "Could not allocate output format context\n");
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Associate the output file (pointer) with the container format context. */
|
/** Associate the output file (pointer) with the container format context. */
|
||||||
(*output_format_context)->pb = output_io_context;
|
(*output_format_context)->pb = output_io_context;
|
||||||
|
|
||||||
/* Guess the desired container format based on the file extension. */
|
/** Guess the desired container format based on the file extension. */
|
||||||
if (!((*output_format_context)->oformat = av_guess_format(NULL, filename,
|
if (!((*output_format_context)->oformat = av_guess_format(NULL, filename,
|
||||||
NULL))) {
|
NULL))) {
|
||||||
fprintf(stderr, "Could not find output file format\n");
|
fprintf(stderr, "Could not find output file format\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!((*output_format_context)->url = av_strdup(filename))) {
|
av_strlcpy((*output_format_context)->filename, filename,
|
||||||
fprintf(stderr, "Could not allocate url.\n");
|
sizeof((*output_format_context)->filename));
|
||||||
error = AVERROR(ENOMEM);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the encoder to be used by its name. */
|
/** Find the encoder to be used by its name. */
|
||||||
if (!(output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC))) {
|
if (!(output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC))) {
|
||||||
fprintf(stderr, "Could not find an AAC encoder.\n");
|
fprintf(stderr, "Could not find an AAC encoder.\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new audio stream in the output file container. */
|
/** Create a new audio stream in the output file container. */
|
||||||
if (!(stream = avformat_new_stream(*output_format_context, NULL))) {
|
if (!(stream = avformat_new_stream(*output_format_context, NULL))) {
|
||||||
fprintf(stderr, "Could not create new stream\n");
|
fprintf(stderr, "Could not create new stream\n");
|
||||||
error = AVERROR(ENOMEM);
|
error = AVERROR(ENOMEM);
|
||||||
@@ -198,30 +192,34 @@ static int open_output_file(const char *filename,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the basic encoder parameters.
|
/**
|
||||||
* The input file's sample rate is used to avoid a sample rate conversion. */
|
* Set the basic encoder parameters.
|
||||||
|
* The input file's sample rate is used to avoid a sample rate conversion.
|
||||||
|
*/
|
||||||
avctx->channels = OUTPUT_CHANNELS;
|
avctx->channels = OUTPUT_CHANNELS;
|
||||||
avctx->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS);
|
avctx->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS);
|
||||||
avctx->sample_rate = input_codec_context->sample_rate;
|
avctx->sample_rate = input_codec_context->sample_rate;
|
||||||
avctx->sample_fmt = output_codec->sample_fmts[0];
|
avctx->sample_fmt = output_codec->sample_fmts[0];
|
||||||
avctx->bit_rate = OUTPUT_BIT_RATE;
|
avctx->bit_rate = OUTPUT_BIT_RATE;
|
||||||
|
|
||||||
/* Allow the use of the experimental AAC encoder. */
|
/** Allow the use of the experimental AAC encoder */
|
||||||
avctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
|
avctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
|
||||||
|
|
||||||
/* Set the sample rate for the container. */
|
/** Set the sample rate for the container. */
|
||||||
stream->time_base.den = input_codec_context->sample_rate;
|
stream->time_base.den = input_codec_context->sample_rate;
|
||||||
stream->time_base.num = 1;
|
stream->time_base.num = 1;
|
||||||
|
|
||||||
/* Some container formats (like MP4) require global headers to be present.
|
/**
|
||||||
* Mark the encoder so that it behaves accordingly. */
|
* Some container formats (like MP4) require global headers to be present
|
||||||
|
* Mark the encoder so that it behaves accordingly.
|
||||||
|
*/
|
||||||
if ((*output_format_context)->oformat->flags & AVFMT_GLOBALHEADER)
|
if ((*output_format_context)->oformat->flags & AVFMT_GLOBALHEADER)
|
||||||
avctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
avctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||||
|
|
||||||
/* Open the encoder for the audio stream to use it later. */
|
/** Open the encoder for the audio stream to use it later. */
|
||||||
if ((error = avcodec_open2(avctx, output_codec, NULL)) < 0) {
|
if ((error = avcodec_open2(avctx, output_codec, NULL)) < 0) {
|
||||||
fprintf(stderr, "Could not open output codec (error '%s')\n",
|
fprintf(stderr, "Could not open output codec (error '%s')\n",
|
||||||
av_err2str(error));
|
get_error_text(error));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +229,7 @@ static int open_output_file(const char *filename,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the encoder context for easier access later. */
|
/** Save the encoder context for easier access later. */
|
||||||
*output_codec_context = avctx;
|
*output_codec_context = avctx;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -244,25 +242,16 @@ cleanup:
|
|||||||
return error < 0 ? error : AVERROR_EXIT;
|
return error < 0 ? error : AVERROR_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Initialize one data packet for reading or writing. */
|
||||||
* Initialize one data packet for reading or writing.
|
static void init_packet(AVPacket *packet)
|
||||||
* @param[out] packet Packet to be initialized
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
|
||||||
static int init_packet(AVPacket **packet)
|
|
||||||
{
|
{
|
||||||
if (!(*packet = av_packet_alloc())) {
|
av_init_packet(packet);
|
||||||
fprintf(stderr, "Could not allocate packet\n");
|
/** Set the packet data and size so that it is recognized as being empty. */
|
||||||
return AVERROR(ENOMEM);
|
packet->data = NULL;
|
||||||
}
|
packet->size = 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Initialize one audio frame for reading from the input file */
|
||||||
* Initialize one audio frame for reading from the input file.
|
|
||||||
* @param[out] frame Frame to be initialized
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
|
||||||
static int init_input_frame(AVFrame **frame)
|
static int init_input_frame(AVFrame **frame)
|
||||||
{
|
{
|
||||||
if (!(*frame = av_frame_alloc())) {
|
if (!(*frame = av_frame_alloc())) {
|
||||||
@@ -276,10 +265,6 @@ static int init_input_frame(AVFrame **frame)
|
|||||||
* Initialize the audio resampler based on the input and output codec settings.
|
* Initialize the audio resampler based on the input and output codec settings.
|
||||||
* If the input and output sample formats differ, a conversion is required
|
* If the input and output sample formats differ, a conversion is required
|
||||||
* libswresample takes care of this, but requires initialization.
|
* libswresample takes care of this, but requires initialization.
|
||||||
* @param input_codec_context Codec context of the input file
|
|
||||||
* @param output_codec_context Codec context of the output file
|
|
||||||
* @param[out] resample_context Resample context for the required conversion
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
*/
|
||||||
static int init_resampler(AVCodecContext *input_codec_context,
|
static int init_resampler(AVCodecContext *input_codec_context,
|
||||||
AVCodecContext *output_codec_context,
|
AVCodecContext *output_codec_context,
|
||||||
@@ -287,7 +272,7 @@ static int init_resampler(AVCodecContext *input_codec_context,
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Create a resampler context for the conversion.
|
* Create a resampler context for the conversion.
|
||||||
* Set the conversion parameters.
|
* Set the conversion parameters.
|
||||||
* Default channel layouts based on the number of channels
|
* Default channel layouts based on the number of channels
|
||||||
@@ -306,14 +291,14 @@ static int init_resampler(AVCodecContext *input_codec_context,
|
|||||||
fprintf(stderr, "Could not allocate resample context\n");
|
fprintf(stderr, "Could not allocate resample context\n");
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
/*
|
/**
|
||||||
* Perform a sanity check so that the number of converted samples is
|
* Perform a sanity check so that the number of converted samples is
|
||||||
* not greater than the number of samples to be converted.
|
* not greater than the number of samples to be converted.
|
||||||
* If the sample rates differ, this case has to be handled differently
|
* If the sample rates differ, this case has to be handled differently
|
||||||
*/
|
*/
|
||||||
av_assert0(output_codec_context->sample_rate == input_codec_context->sample_rate);
|
av_assert0(output_codec_context->sample_rate == input_codec_context->sample_rate);
|
||||||
|
|
||||||
/* Open the resampler with the specified parameters. */
|
/** Open the resampler with the specified parameters. */
|
||||||
if ((error = swr_init(*resample_context)) < 0) {
|
if ((error = swr_init(*resample_context)) < 0) {
|
||||||
fprintf(stderr, "Could not open resample context\n");
|
fprintf(stderr, "Could not open resample context\n");
|
||||||
swr_free(resample_context);
|
swr_free(resample_context);
|
||||||
@@ -322,15 +307,10 @@ static int init_resampler(AVCodecContext *input_codec_context,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Initialize a FIFO buffer for the audio samples to be encoded. */
|
||||||
* Initialize a FIFO buffer for the audio samples to be encoded.
|
|
||||||
* @param[out] fifo Sample buffer
|
|
||||||
* @param output_codec_context Codec context of the output file
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
|
||||||
static int init_fifo(AVAudioFifo **fifo, AVCodecContext *output_codec_context)
|
static int init_fifo(AVAudioFifo **fifo, AVCodecContext *output_codec_context)
|
||||||
{
|
{
|
||||||
/* Create the FIFO buffer based on the specified output sample format. */
|
/** Create the FIFO buffer based on the specified output sample format. */
|
||||||
if (!(*fifo = av_audio_fifo_alloc(output_codec_context->sample_fmt,
|
if (!(*fifo = av_audio_fifo_alloc(output_codec_context->sample_fmt,
|
||||||
output_codec_context->channels, 1))) {
|
output_codec_context->channels, 1))) {
|
||||||
fprintf(stderr, "Could not allocate FIFO\n");
|
fprintf(stderr, "Could not allocate FIFO\n");
|
||||||
@@ -339,106 +319,69 @@ static int init_fifo(AVAudioFifo **fifo, AVCodecContext *output_codec_context)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Write the header of the output file container. */
|
||||||
* Write the header of the output file container.
|
|
||||||
* @param output_format_context Format context of the output file
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
|
||||||
static int write_output_file_header(AVFormatContext *output_format_context)
|
static int write_output_file_header(AVFormatContext *output_format_context)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
if ((error = avformat_write_header(output_format_context, NULL)) < 0) {
|
if ((error = avformat_write_header(output_format_context, NULL)) < 0) {
|
||||||
fprintf(stderr, "Could not write output file header (error '%s')\n",
|
fprintf(stderr, "Could not write output file header (error '%s')\n",
|
||||||
av_err2str(error));
|
get_error_text(error));
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Decode one audio frame from the input file. */
|
||||||
* Decode one audio frame from the input file.
|
|
||||||
* @param frame Audio frame to be decoded
|
|
||||||
* @param input_format_context Format context of the input file
|
|
||||||
* @param input_codec_context Codec context of the input file
|
|
||||||
* @param[out] data_present Indicates whether data has been decoded
|
|
||||||
* @param[out] finished Indicates whether the end of file has
|
|
||||||
* been reached and all data has been
|
|
||||||
* decoded. If this flag is false, there
|
|
||||||
* is more data to be decoded, i.e., this
|
|
||||||
* function has to be called again.
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
|
||||||
static int decode_audio_frame(AVFrame *frame,
|
static int decode_audio_frame(AVFrame *frame,
|
||||||
AVFormatContext *input_format_context,
|
AVFormatContext *input_format_context,
|
||||||
AVCodecContext *input_codec_context,
|
AVCodecContext *input_codec_context,
|
||||||
int *data_present, int *finished)
|
int *data_present, int *finished)
|
||||||
{
|
{
|
||||||
/* Packet used for temporary storage. */
|
/** Packet used for temporary storage. */
|
||||||
AVPacket *input_packet;
|
AVPacket input_packet;
|
||||||
int error;
|
int error;
|
||||||
|
init_packet(&input_packet);
|
||||||
|
|
||||||
error = init_packet(&input_packet);
|
/** Read one audio frame from the input file into a temporary packet. */
|
||||||
if (error < 0)
|
if ((error = av_read_frame(input_format_context, &input_packet)) < 0) {
|
||||||
return error;
|
/** If we are at the end of the file, flush the decoder below. */
|
||||||
|
|
||||||
/* Read one audio frame from the input file into a temporary packet. */
|
|
||||||
if ((error = av_read_frame(input_format_context, input_packet)) < 0) {
|
|
||||||
/* If we are at the end of the file, flush the decoder below. */
|
|
||||||
if (error == AVERROR_EOF)
|
if (error == AVERROR_EOF)
|
||||||
*finished = 1;
|
*finished = 1;
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "Could not read frame (error '%s')\n",
|
fprintf(stderr, "Could not read frame (error '%s')\n",
|
||||||
av_err2str(error));
|
get_error_text(error));
|
||||||
goto cleanup;
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send the audio frame stored in the temporary packet to the decoder.
|
/**
|
||||||
* The input audio stream decoder is used to do this. */
|
* Decode the audio frame stored in the temporary packet.
|
||||||
if ((error = avcodec_send_packet(input_codec_context, input_packet)) < 0) {
|
* The input audio stream decoder is used to do this.
|
||||||
fprintf(stderr, "Could not send packet for decoding (error '%s')\n",
|
* If we are at the end of the file, pass an empty packet to the decoder
|
||||||
av_err2str(error));
|
* to flush it.
|
||||||
goto cleanup;
|
*/
|
||||||
}
|
if ((error = avcodec_decode_audio4(input_codec_context, frame,
|
||||||
|
data_present, &input_packet)) < 0) {
|
||||||
/* Receive one frame from the decoder. */
|
|
||||||
error = avcodec_receive_frame(input_codec_context, frame);
|
|
||||||
/* If the decoder asks for more data to be able to decode a frame,
|
|
||||||
* return indicating that no data is present. */
|
|
||||||
if (error == AVERROR(EAGAIN)) {
|
|
||||||
error = 0;
|
|
||||||
goto cleanup;
|
|
||||||
/* If the end of the input file is reached, stop decoding. */
|
|
||||||
} else if (error == AVERROR_EOF) {
|
|
||||||
*finished = 1;
|
|
||||||
error = 0;
|
|
||||||
goto cleanup;
|
|
||||||
} else if (error < 0) {
|
|
||||||
fprintf(stderr, "Could not decode frame (error '%s')\n",
|
fprintf(stderr, "Could not decode frame (error '%s')\n",
|
||||||
av_err2str(error));
|
get_error_text(error));
|
||||||
goto cleanup;
|
av_packet_unref(&input_packet);
|
||||||
/* Default case: Return decoded data. */
|
return error;
|
||||||
} else {
|
|
||||||
*data_present = 1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
/**
|
||||||
av_packet_free(&input_packet);
|
* If the decoder has not been flushed completely, we are not finished,
|
||||||
return error;
|
* so that this function has to be called again.
|
||||||
|
*/
|
||||||
|
if (*finished && *data_present)
|
||||||
|
*finished = 0;
|
||||||
|
av_packet_unref(&input_packet);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize a temporary storage for the specified number of audio samples.
|
* Initialize a temporary storage for the specified number of audio samples.
|
||||||
* The conversion requires temporary storage due to the different format.
|
* The conversion requires temporary storage due to the different format.
|
||||||
* The number of audio samples to be allocated is specified in frame_size.
|
* The number of audio samples to be allocated is specified in frame_size.
|
||||||
* @param[out] converted_input_samples Array of converted samples. The
|
|
||||||
* dimensions are reference, channel
|
|
||||||
* (for multi-channel audio), sample.
|
|
||||||
* @param output_codec_context Codec context of the output file
|
|
||||||
* @param frame_size Number of samples to be converted in
|
|
||||||
* each round
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
*/
|
||||||
static int init_converted_samples(uint8_t ***converted_input_samples,
|
static int init_converted_samples(uint8_t ***converted_input_samples,
|
||||||
AVCodecContext *output_codec_context,
|
AVCodecContext *output_codec_context,
|
||||||
@@ -446,7 +389,8 @@ static int init_converted_samples(uint8_t ***converted_input_samples,
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* Allocate as many pointers as there are audio channels.
|
/**
|
||||||
|
* Allocate as many pointers as there are audio channels.
|
||||||
* Each pointer will later point to the audio samples of the corresponding
|
* Each pointer will later point to the audio samples of the corresponding
|
||||||
* channels (although it may be NULL for interleaved formats).
|
* channels (although it may be NULL for interleaved formats).
|
||||||
*/
|
*/
|
||||||
@@ -456,15 +400,17 @@ static int init_converted_samples(uint8_t ***converted_input_samples,
|
|||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate memory for the samples of all channels in one consecutive
|
/**
|
||||||
* block for convenience. */
|
* Allocate memory for the samples of all channels in one consecutive
|
||||||
|
* block for convenience.
|
||||||
|
*/
|
||||||
if ((error = av_samples_alloc(*converted_input_samples, NULL,
|
if ((error = av_samples_alloc(*converted_input_samples, NULL,
|
||||||
output_codec_context->channels,
|
output_codec_context->channels,
|
||||||
frame_size,
|
frame_size,
|
||||||
output_codec_context->sample_fmt, 0)) < 0) {
|
output_codec_context->sample_fmt, 0)) < 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Could not allocate converted input samples (error '%s')\n",
|
"Could not allocate converted input samples (error '%s')\n",
|
||||||
av_err2str(error));
|
get_error_text(error));
|
||||||
av_freep(&(*converted_input_samples)[0]);
|
av_freep(&(*converted_input_samples)[0]);
|
||||||
free(*converted_input_samples);
|
free(*converted_input_samples);
|
||||||
return error;
|
return error;
|
||||||
@@ -474,15 +420,8 @@ static int init_converted_samples(uint8_t ***converted_input_samples,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the input audio samples into the output sample format.
|
* Convert the input audio samples into the output sample format.
|
||||||
* The conversion happens on a per-frame basis, the size of which is
|
* The conversion happens on a per-frame basis, the size of which is specified
|
||||||
* specified by frame_size.
|
* by frame_size.
|
||||||
* @param input_data Samples to be decoded. The dimensions are
|
|
||||||
* channel (for multi-channel audio), sample.
|
|
||||||
* @param[out] converted_data Converted samples. The dimensions are channel
|
|
||||||
* (for multi-channel audio), sample.
|
|
||||||
* @param frame_size Number of samples to be converted
|
|
||||||
* @param resample_context Resample context for the conversion
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
*/
|
||||||
static int convert_samples(const uint8_t **input_data,
|
static int convert_samples(const uint8_t **input_data,
|
||||||
uint8_t **converted_data, const int frame_size,
|
uint8_t **converted_data, const int frame_size,
|
||||||
@@ -490,40 +429,35 @@ static int convert_samples(const uint8_t **input_data,
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* Convert the samples using the resampler. */
|
/** Convert the samples using the resampler. */
|
||||||
if ((error = swr_convert(resample_context,
|
if ((error = swr_convert(resample_context,
|
||||||
converted_data, frame_size,
|
converted_data, frame_size,
|
||||||
input_data , frame_size)) < 0) {
|
input_data , frame_size)) < 0) {
|
||||||
fprintf(stderr, "Could not convert input samples (error '%s')\n",
|
fprintf(stderr, "Could not convert input samples (error '%s')\n",
|
||||||
av_err2str(error));
|
get_error_text(error));
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Add converted input audio samples to the FIFO buffer for later processing. */
|
||||||
* Add converted input audio samples to the FIFO buffer for later processing.
|
|
||||||
* @param fifo Buffer to add the samples to
|
|
||||||
* @param converted_input_samples Samples to be added. The dimensions are channel
|
|
||||||
* (for multi-channel audio), sample.
|
|
||||||
* @param frame_size Number of samples to be converted
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
|
||||||
static int add_samples_to_fifo(AVAudioFifo *fifo,
|
static int add_samples_to_fifo(AVAudioFifo *fifo,
|
||||||
uint8_t **converted_input_samples,
|
uint8_t **converted_input_samples,
|
||||||
const int frame_size)
|
const int frame_size)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* Make the FIFO as large as it needs to be to hold both,
|
/**
|
||||||
* the old and the new samples. */
|
* Make the FIFO as large as it needs to be to hold both,
|
||||||
|
* the old and the new samples.
|
||||||
|
*/
|
||||||
if ((error = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame_size)) < 0) {
|
if ((error = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame_size)) < 0) {
|
||||||
fprintf(stderr, "Could not reallocate FIFO\n");
|
fprintf(stderr, "Could not reallocate FIFO\n");
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the new samples in the FIFO buffer. */
|
/** Store the new samples in the FIFO buffer. */
|
||||||
if (av_audio_fifo_write(fifo, (void **)converted_input_samples,
|
if (av_audio_fifo_write(fifo, (void **)converted_input_samples,
|
||||||
frame_size) < frame_size) {
|
frame_size) < frame_size) {
|
||||||
fprintf(stderr, "Could not write data to FIFO\n");
|
fprintf(stderr, "Could not write data to FIFO\n");
|
||||||
@@ -533,20 +467,8 @@ static int add_samples_to_fifo(AVAudioFifo *fifo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read one audio frame from the input file, decode, convert and store
|
* Read one audio frame from the input file, decodes, converts and stores
|
||||||
* it in the FIFO buffer.
|
* it in the FIFO buffer.
|
||||||
* @param fifo Buffer used for temporary storage
|
|
||||||
* @param input_format_context Format context of the input file
|
|
||||||
* @param input_codec_context Codec context of the input file
|
|
||||||
* @param output_codec_context Codec context of the output file
|
|
||||||
* @param resampler_context Resample context for the conversion
|
|
||||||
* @param[out] finished Indicates whether the end of file has
|
|
||||||
* been reached and all data has been
|
|
||||||
* decoded. If this flag is false,
|
|
||||||
* there is more data to be decoded,
|
|
||||||
* i.e., this function has to be called
|
|
||||||
* again.
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
*/
|
||||||
static int read_decode_convert_and_store(AVAudioFifo *fifo,
|
static int read_decode_convert_and_store(AVAudioFifo *fifo,
|
||||||
AVFormatContext *input_format_context,
|
AVFormatContext *input_format_context,
|
||||||
@@ -555,41 +477,45 @@ static int read_decode_convert_and_store(AVAudioFifo *fifo,
|
|||||||
SwrContext *resampler_context,
|
SwrContext *resampler_context,
|
||||||
int *finished)
|
int *finished)
|
||||||
{
|
{
|
||||||
/* Temporary storage of the input samples of the frame read from the file. */
|
/** Temporary storage of the input samples of the frame read from the file. */
|
||||||
AVFrame *input_frame = NULL;
|
AVFrame *input_frame = NULL;
|
||||||
/* Temporary storage for the converted input samples. */
|
/** Temporary storage for the converted input samples. */
|
||||||
uint8_t **converted_input_samples = NULL;
|
uint8_t **converted_input_samples = NULL;
|
||||||
int data_present = 0;
|
int data_present;
|
||||||
int ret = AVERROR_EXIT;
|
int ret = AVERROR_EXIT;
|
||||||
|
|
||||||
/* Initialize temporary storage for one input frame. */
|
/** Initialize temporary storage for one input frame. */
|
||||||
if (init_input_frame(&input_frame))
|
if (init_input_frame(&input_frame))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
/* Decode one frame worth of audio samples. */
|
/** Decode one frame worth of audio samples. */
|
||||||
if (decode_audio_frame(input_frame, input_format_context,
|
if (decode_audio_frame(input_frame, input_format_context,
|
||||||
input_codec_context, &data_present, finished))
|
input_codec_context, &data_present, finished))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
/* If we are at the end of the file and there are no more samples
|
/**
|
||||||
|
* If we are at the end of the file and there are no more samples
|
||||||
* in the decoder which are delayed, we are actually finished.
|
* in the decoder which are delayed, we are actually finished.
|
||||||
* This must not be treated as an error. */
|
* This must not be treated as an error.
|
||||||
if (*finished) {
|
*/
|
||||||
|
if (*finished && !data_present) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
/* If there is decoded data, convert and store it. */
|
/** If there is decoded data, convert and store it */
|
||||||
if (data_present) {
|
if (data_present) {
|
||||||
/* Initialize the temporary storage for the converted input samples. */
|
/** Initialize the temporary storage for the converted input samples. */
|
||||||
if (init_converted_samples(&converted_input_samples, output_codec_context,
|
if (init_converted_samples(&converted_input_samples, output_codec_context,
|
||||||
input_frame->nb_samples))
|
input_frame->nb_samples))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* Convert the input samples to the desired output sample format.
|
/**
|
||||||
* This requires a temporary storage provided by converted_input_samples. */
|
* Convert the input samples to the desired output sample format.
|
||||||
|
* This requires a temporary storage provided by converted_input_samples.
|
||||||
|
*/
|
||||||
if (convert_samples((const uint8_t**)input_frame->extended_data, converted_input_samples,
|
if (convert_samples((const uint8_t**)input_frame->extended_data, converted_input_samples,
|
||||||
input_frame->nb_samples, resampler_context))
|
input_frame->nb_samples, resampler_context))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* Add the converted input samples to the FIFO buffer for later processing. */
|
/** Add the converted input samples to the FIFO buffer for later processing. */
|
||||||
if (add_samples_to_fifo(fifo, converted_input_samples,
|
if (add_samples_to_fifo(fifo, converted_input_samples,
|
||||||
input_frame->nb_samples))
|
input_frame->nb_samples))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -610,10 +536,6 @@ cleanup:
|
|||||||
/**
|
/**
|
||||||
* Initialize one input frame for writing to the output file.
|
* Initialize one input frame for writing to the output file.
|
||||||
* The frame will be exactly frame_size samples large.
|
* The frame will be exactly frame_size samples large.
|
||||||
* @param[out] frame Frame to be initialized
|
|
||||||
* @param output_codec_context Codec context of the output file
|
|
||||||
* @param frame_size Size of the frame
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
*/
|
||||||
static int init_output_frame(AVFrame **frame,
|
static int init_output_frame(AVFrame **frame,
|
||||||
AVCodecContext *output_codec_context,
|
AVCodecContext *output_codec_context,
|
||||||
@@ -621,27 +543,31 @@ static int init_output_frame(AVFrame **frame,
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* Create a new frame to store the audio samples. */
|
/** Create a new frame to store the audio samples. */
|
||||||
if (!(*frame = av_frame_alloc())) {
|
if (!(*frame = av_frame_alloc())) {
|
||||||
fprintf(stderr, "Could not allocate output frame\n");
|
fprintf(stderr, "Could not allocate output frame\n");
|
||||||
return AVERROR_EXIT;
|
return AVERROR_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the frame's parameters, especially its size and format.
|
/**
|
||||||
|
* Set the frame's parameters, especially its size and format.
|
||||||
* av_frame_get_buffer needs this to allocate memory for the
|
* av_frame_get_buffer needs this to allocate memory for the
|
||||||
* audio samples of the frame.
|
* audio samples of the frame.
|
||||||
* Default channel layouts based on the number of channels
|
* Default channel layouts based on the number of channels
|
||||||
* are assumed for simplicity. */
|
* are assumed for simplicity.
|
||||||
|
*/
|
||||||
(*frame)->nb_samples = frame_size;
|
(*frame)->nb_samples = frame_size;
|
||||||
(*frame)->channel_layout = output_codec_context->channel_layout;
|
(*frame)->channel_layout = output_codec_context->channel_layout;
|
||||||
(*frame)->format = output_codec_context->sample_fmt;
|
(*frame)->format = output_codec_context->sample_fmt;
|
||||||
(*frame)->sample_rate = output_codec_context->sample_rate;
|
(*frame)->sample_rate = output_codec_context->sample_rate;
|
||||||
|
|
||||||
/* Allocate the samples of the created frame. This call will make
|
/**
|
||||||
* sure that the audio frame can hold as many samples as specified. */
|
* Allocate the samples of the created frame. This call will make
|
||||||
|
* sure that the audio frame can hold as many samples as specified.
|
||||||
|
*/
|
||||||
if ((error = av_frame_get_buffer(*frame, 0)) < 0) {
|
if ((error = av_frame_get_buffer(*frame, 0)) < 0) {
|
||||||
fprintf(stderr, "Could not allocate output frame samples (error '%s')\n",
|
fprintf(stderr, "Could allocate output frame samples (error '%s')\n",
|
||||||
av_err2str(error));
|
get_error_text(error));
|
||||||
av_frame_free(frame);
|
av_frame_free(frame);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -649,117 +575,87 @@ static int init_output_frame(AVFrame **frame,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Global timestamp for the audio frames. */
|
/** Global timestamp for the audio frames */
|
||||||
static int64_t pts = 0;
|
static int64_t pts = 0;
|
||||||
|
|
||||||
/**
|
/** Encode one frame worth of audio to the output file. */
|
||||||
* Encode one frame worth of audio to the output file.
|
|
||||||
* @param frame Samples to be encoded
|
|
||||||
* @param output_format_context Format context of the output file
|
|
||||||
* @param output_codec_context Codec context of the output file
|
|
||||||
* @param[out] data_present Indicates whether data has been
|
|
||||||
* encoded
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
|
||||||
static int encode_audio_frame(AVFrame *frame,
|
static int encode_audio_frame(AVFrame *frame,
|
||||||
AVFormatContext *output_format_context,
|
AVFormatContext *output_format_context,
|
||||||
AVCodecContext *output_codec_context,
|
AVCodecContext *output_codec_context,
|
||||||
int *data_present)
|
int *data_present)
|
||||||
{
|
{
|
||||||
/* Packet used for temporary storage. */
|
/** Packet used for temporary storage. */
|
||||||
AVPacket *output_packet;
|
AVPacket output_packet;
|
||||||
int error;
|
int error;
|
||||||
|
init_packet(&output_packet);
|
||||||
|
|
||||||
error = init_packet(&output_packet);
|
/** Set a timestamp based on the sample rate for the container. */
|
||||||
if (error < 0)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
/* Set a timestamp based on the sample rate for the container. */
|
|
||||||
if (frame) {
|
if (frame) {
|
||||||
frame->pts = pts;
|
frame->pts = pts;
|
||||||
pts += frame->nb_samples;
|
pts += frame->nb_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send the audio frame stored in the temporary packet to the encoder.
|
/**
|
||||||
* The output audio stream encoder is used to do this. */
|
* Encode the audio frame and store it in the temporary packet.
|
||||||
error = avcodec_send_frame(output_codec_context, frame);
|
* The output audio stream encoder is used to do this.
|
||||||
/* The encoder signals that it has nothing more to encode. */
|
*/
|
||||||
if (error == AVERROR_EOF) {
|
if ((error = avcodec_encode_audio2(output_codec_context, &output_packet,
|
||||||
error = 0;
|
frame, data_present)) < 0) {
|
||||||
goto cleanup;
|
|
||||||
} else if (error < 0) {
|
|
||||||
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);
|
|
||||||
/* 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)) {
|
|
||||||
error = 0;
|
|
||||||
goto cleanup;
|
|
||||||
/* If the last frame has been encoded, stop encoding. */
|
|
||||||
} else if (error == AVERROR_EOF) {
|
|
||||||
error = 0;
|
|
||||||
goto cleanup;
|
|
||||||
} else if (error < 0) {
|
|
||||||
fprintf(stderr, "Could not encode frame (error '%s')\n",
|
fprintf(stderr, "Could not encode frame (error '%s')\n",
|
||||||
av_err2str(error));
|
get_error_text(error));
|
||||||
goto cleanup;
|
av_packet_unref(&output_packet);
|
||||||
/* Default case: Return encoded data. */
|
return error;
|
||||||
} else {
|
|
||||||
*data_present = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write one audio frame from the temporary packet to the output file. */
|
/** Write one audio frame from the temporary packet to the output file. */
|
||||||
if (*data_present &&
|
if (*data_present) {
|
||||||
(error = av_write_frame(output_format_context, output_packet)) < 0) {
|
if ((error = av_write_frame(output_format_context, &output_packet)) < 0) {
|
||||||
fprintf(stderr, "Could not write frame (error '%s')\n",
|
fprintf(stderr, "Could not write frame (error '%s')\n",
|
||||||
av_err2str(error));
|
get_error_text(error));
|
||||||
goto cleanup;
|
av_packet_unref(&output_packet);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
av_packet_unref(&output_packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
return 0;
|
||||||
av_packet_free(&output_packet);
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load one audio frame from the FIFO buffer, encode and write it to the
|
* Load one audio frame from the FIFO buffer, encode and write it to the
|
||||||
* output file.
|
* output file.
|
||||||
* @param fifo Buffer used for temporary storage
|
|
||||||
* @param output_format_context Format context of the output file
|
|
||||||
* @param output_codec_context Codec context of the output file
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
*/
|
||||||
static int load_encode_and_write(AVAudioFifo *fifo,
|
static int load_encode_and_write(AVAudioFifo *fifo,
|
||||||
AVFormatContext *output_format_context,
|
AVFormatContext *output_format_context,
|
||||||
AVCodecContext *output_codec_context)
|
AVCodecContext *output_codec_context)
|
||||||
{
|
{
|
||||||
/* Temporary storage of the output samples of the frame written to the file. */
|
/** Temporary storage of the output samples of the frame written to the file. */
|
||||||
AVFrame *output_frame;
|
AVFrame *output_frame;
|
||||||
/* Use the maximum number of possible samples per frame.
|
/**
|
||||||
|
* Use the maximum number of possible samples per frame.
|
||||||
* If there is less than the maximum possible frame size in the FIFO
|
* If there is less than the maximum possible frame size in the FIFO
|
||||||
* buffer use this number. Otherwise, use the maximum possible frame size. */
|
* buffer use this number. Otherwise, use the maximum possible frame size
|
||||||
|
*/
|
||||||
const int frame_size = FFMIN(av_audio_fifo_size(fifo),
|
const int frame_size = FFMIN(av_audio_fifo_size(fifo),
|
||||||
output_codec_context->frame_size);
|
output_codec_context->frame_size);
|
||||||
int data_written;
|
int data_written;
|
||||||
|
|
||||||
/* Initialize temporary storage for one output frame. */
|
/** Initialize temporary storage for one output frame. */
|
||||||
if (init_output_frame(&output_frame, output_codec_context, frame_size))
|
if (init_output_frame(&output_frame, output_codec_context, frame_size))
|
||||||
return AVERROR_EXIT;
|
return AVERROR_EXIT;
|
||||||
|
|
||||||
/* Read as many samples from the FIFO buffer as required to fill the frame.
|
/**
|
||||||
* The samples are stored in the frame temporarily. */
|
* Read as many samples from the FIFO buffer as required to fill the frame.
|
||||||
|
* The samples are stored in the frame temporarily.
|
||||||
|
*/
|
||||||
if (av_audio_fifo_read(fifo, (void **)output_frame->data, frame_size) < frame_size) {
|
if (av_audio_fifo_read(fifo, (void **)output_frame->data, frame_size) < frame_size) {
|
||||||
fprintf(stderr, "Could not read data from FIFO\n");
|
fprintf(stderr, "Could not read data from FIFO\n");
|
||||||
av_frame_free(&output_frame);
|
av_frame_free(&output_frame);
|
||||||
return AVERROR_EXIT;
|
return AVERROR_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encode one frame worth of audio samples. */
|
/** Encode one frame worth of audio samples. */
|
||||||
if (encode_audio_frame(output_frame, output_format_context,
|
if (encode_audio_frame(output_frame, output_format_context,
|
||||||
output_codec_context, &data_written)) {
|
output_codec_context, &data_written)) {
|
||||||
av_frame_free(&output_frame);
|
av_frame_free(&output_frame);
|
||||||
@@ -769,22 +665,19 @@ static int load_encode_and_write(AVAudioFifo *fifo,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Write the trailer of the output file container. */
|
||||||
* Write the trailer of the output file container.
|
|
||||||
* @param output_format_context Format context of the output file
|
|
||||||
* @return Error code (0 if successful)
|
|
||||||
*/
|
|
||||||
static int write_output_file_trailer(AVFormatContext *output_format_context)
|
static int write_output_file_trailer(AVFormatContext *output_format_context)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
if ((error = av_write_trailer(output_format_context)) < 0) {
|
if ((error = av_write_trailer(output_format_context)) < 0) {
|
||||||
fprintf(stderr, "Could not write output file trailer (error '%s')\n",
|
fprintf(stderr, "Could not write output file trailer (error '%s')\n",
|
||||||
av_err2str(error));
|
get_error_text(error));
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Convert an audio file to an AAC file in an MP4 container. */
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
AVFormatContext *input_format_context = NULL, *output_format_context = NULL;
|
AVFormatContext *input_format_context = NULL, *output_format_context = NULL;
|
||||||
@@ -793,75 +686,90 @@ int main(int argc, char **argv)
|
|||||||
AVAudioFifo *fifo = NULL;
|
AVAudioFifo *fifo = NULL;
|
||||||
int ret = AVERROR_EXIT;
|
int ret = AVERROR_EXIT;
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open the input file for reading. */
|
/** Register all codecs and formats so that they can be used. */
|
||||||
|
av_register_all();
|
||||||
|
/** Open the input file for reading. */
|
||||||
if (open_input_file(argv[1], &input_format_context,
|
if (open_input_file(argv[1], &input_format_context,
|
||||||
&input_codec_context))
|
&input_codec_context))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
/* Open the output file for writing. */
|
/** Open the output file for writing. */
|
||||||
if (open_output_file(argv[2], input_codec_context,
|
if (open_output_file(argv[2], input_codec_context,
|
||||||
&output_format_context, &output_codec_context))
|
&output_format_context, &output_codec_context))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
/* Initialize the resampler to be able to convert audio sample formats. */
|
/** Initialize the resampler to be able to convert audio sample formats. */
|
||||||
if (init_resampler(input_codec_context, output_codec_context,
|
if (init_resampler(input_codec_context, output_codec_context,
|
||||||
&resample_context))
|
&resample_context))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
/* Initialize the FIFO buffer to store audio samples to be encoded. */
|
/** Initialize the FIFO buffer to store audio samples to be encoded. */
|
||||||
if (init_fifo(&fifo, output_codec_context))
|
if (init_fifo(&fifo, output_codec_context))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
/* Write the header of the output file container. */
|
/** Write the header of the output file container. */
|
||||||
if (write_output_file_header(output_format_context))
|
if (write_output_file_header(output_format_context))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* Loop as long as we have input samples to read or output samples
|
/**
|
||||||
* to write; abort as soon as we have neither. */
|
* Loop as long as we have input samples to read or output samples
|
||||||
|
* to write; abort as soon as we have neither.
|
||||||
|
*/
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Use the encoder's desired frame size for processing. */
|
/** Use the encoder's desired frame size for processing. */
|
||||||
const int output_frame_size = output_codec_context->frame_size;
|
const int output_frame_size = output_codec_context->frame_size;
|
||||||
int finished = 0;
|
int finished = 0;
|
||||||
|
|
||||||
/* Make sure that there is one frame worth of samples in the FIFO
|
/**
|
||||||
|
* Make sure that there is one frame worth of samples in the FIFO
|
||||||
* buffer so that the encoder can do its work.
|
* buffer so that the encoder can do its work.
|
||||||
* Since the decoder's and the encoder's frame size may differ, we
|
* Since the decoder's and the encoder's frame size may differ, we
|
||||||
* need to FIFO buffer to store as many frames worth of input samples
|
* need to FIFO buffer to store as many frames worth of input samples
|
||||||
* that they make up at least one frame worth of output samples. */
|
* that they make up at least one frame worth of output samples.
|
||||||
|
*/
|
||||||
while (av_audio_fifo_size(fifo) < output_frame_size) {
|
while (av_audio_fifo_size(fifo) < output_frame_size) {
|
||||||
/* Decode one frame worth of audio samples, convert it to the
|
/**
|
||||||
* output sample format and put it into the FIFO buffer. */
|
* Decode one frame worth of audio samples, convert it to the
|
||||||
|
* output sample format and put it into the FIFO buffer.
|
||||||
|
*/
|
||||||
if (read_decode_convert_and_store(fifo, input_format_context,
|
if (read_decode_convert_and_store(fifo, input_format_context,
|
||||||
input_codec_context,
|
input_codec_context,
|
||||||
output_codec_context,
|
output_codec_context,
|
||||||
resample_context, &finished))
|
resample_context, &finished))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* If we are at the end of the input file, we continue
|
/**
|
||||||
* encoding the remaining audio samples to the output file. */
|
* If we are at the end of the input file, we continue
|
||||||
|
* encoding the remaining audio samples to the output file.
|
||||||
|
*/
|
||||||
if (finished)
|
if (finished)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have enough samples for the encoder, we encode them.
|
/**
|
||||||
|
* If we have enough samples for the encoder, we encode them.
|
||||||
* At the end of the file, we pass the remaining samples to
|
* At the end of the file, we pass the remaining samples to
|
||||||
* the encoder. */
|
* the encoder.
|
||||||
|
*/
|
||||||
while (av_audio_fifo_size(fifo) >= output_frame_size ||
|
while (av_audio_fifo_size(fifo) >= output_frame_size ||
|
||||||
(finished && av_audio_fifo_size(fifo) > 0))
|
(finished && av_audio_fifo_size(fifo) > 0))
|
||||||
/* Take one frame worth of audio samples from the FIFO buffer,
|
/**
|
||||||
* encode it and write it to the output file. */
|
* Take one frame worth of audio samples from the FIFO buffer,
|
||||||
|
* encode it and write it to the output file.
|
||||||
|
*/
|
||||||
if (load_encode_and_write(fifo, output_format_context,
|
if (load_encode_and_write(fifo, output_format_context,
|
||||||
output_codec_context))
|
output_codec_context))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* If we are at the end of the input file and have encoded
|
/**
|
||||||
* all remaining samples, we can exit this loop and finish. */
|
* If we are at the end of the input file and have encoded
|
||||||
|
* all remaining samples, we can exit this loop and finish.
|
||||||
|
*/
|
||||||
if (finished) {
|
if (finished) {
|
||||||
int data_written;
|
int data_written;
|
||||||
/* Flush the encoder as it may have delayed frames. */
|
/** Flush the encoder as it may have delayed frames. */
|
||||||
do {
|
do {
|
||||||
data_written = 0;
|
|
||||||
if (encode_audio_frame(NULL, output_format_context,
|
if (encode_audio_frame(NULL, output_format_context,
|
||||||
output_codec_context, &data_written))
|
output_codec_context, &data_written))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -870,7 +778,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the trailer of the output file container. */
|
/** Write the trailer of the output file container. */
|
||||||
if (write_output_file_trailer(output_format_context))
|
if (write_output_file_trailer(output_format_context))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|||||||
@@ -30,9 +30,9 @@
|
|||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
|
#include <libavfilter/avfiltergraph.h>
|
||||||
#include <libavfilter/buffersink.h>
|
#include <libavfilter/buffersink.h>
|
||||||
#include <libavfilter/buffersrc.h>
|
#include <libavfilter/buffersrc.h>
|
||||||
#include <libavutil/channel_layout.h>
|
|
||||||
#include <libavutil/opt.h>
|
#include <libavutil/opt.h>
|
||||||
#include <libavutil/pixdesc.h>
|
#include <libavutil/pixdesc.h>
|
||||||
|
|
||||||
@@ -42,20 +42,9 @@ typedef struct FilteringContext {
|
|||||||
AVFilterContext *buffersink_ctx;
|
AVFilterContext *buffersink_ctx;
|
||||||
AVFilterContext *buffersrc_ctx;
|
AVFilterContext *buffersrc_ctx;
|
||||||
AVFilterGraph *filter_graph;
|
AVFilterGraph *filter_graph;
|
||||||
|
|
||||||
AVPacket *enc_pkt;
|
|
||||||
AVFrame *filtered_frame;
|
|
||||||
} FilteringContext;
|
} FilteringContext;
|
||||||
static FilteringContext *filter_ctx;
|
static FilteringContext *filter_ctx;
|
||||||
|
|
||||||
typedef struct StreamContext {
|
|
||||||
AVCodecContext *dec_ctx;
|
|
||||||
AVCodecContext *enc_ctx;
|
|
||||||
|
|
||||||
AVFrame *dec_frame;
|
|
||||||
} StreamContext;
|
|
||||||
static StreamContext *stream_ctx;
|
|
||||||
|
|
||||||
static int open_input_file(const char *filename)
|
static int open_input_file(const char *filename)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -72,46 +61,22 @@ static int open_input_file(const char *filename)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
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++) {
|
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||||
AVStream *stream = ifmt_ctx->streams[i];
|
AVStream *stream;
|
||||||
const AVCodec *dec = avcodec_find_decoder(stream->codecpar->codec_id);
|
|
||||||
AVCodecContext *codec_ctx;
|
AVCodecContext *codec_ctx;
|
||||||
if (!dec) {
|
stream = ifmt_ctx->streams[i];
|
||||||
av_log(NULL, AV_LOG_ERROR, "Failed to find decoder for stream #%u\n", i);
|
codec_ctx = stream->codec;
|
||||||
return AVERROR_DECODER_NOT_FOUND;
|
|
||||||
}
|
|
||||||
codec_ctx = avcodec_alloc_context3(dec);
|
|
||||||
if (!codec_ctx) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Failed to allocate the decoder context for stream #%u\n", i);
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
ret = avcodec_parameters_to_context(codec_ctx, stream->codecpar);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Failed to copy decoder parameters to input decoder context "
|
|
||||||
"for stream #%u\n", i);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
/* Reencode video & audio and remux subtitles etc. */
|
/* Reencode video & audio and remux subtitles etc. */
|
||||||
if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
|
if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
|
||||||
|| codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
|| codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||||
if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
|
|
||||||
codec_ctx->framerate = av_guess_frame_rate(ifmt_ctx, stream, NULL);
|
|
||||||
/* Open decoder */
|
/* Open decoder */
|
||||||
ret = avcodec_open2(codec_ctx, dec, NULL);
|
ret = avcodec_open2(codec_ctx,
|
||||||
|
avcodec_find_decoder(codec_ctx->codec_id), NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i);
|
av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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);
|
av_dump_format(ifmt_ctx, 0, filename, 0);
|
||||||
@@ -123,7 +88,7 @@ static int open_output_file(const char *filename)
|
|||||||
AVStream *out_stream;
|
AVStream *out_stream;
|
||||||
AVStream *in_stream;
|
AVStream *in_stream;
|
||||||
AVCodecContext *dec_ctx, *enc_ctx;
|
AVCodecContext *dec_ctx, *enc_ctx;
|
||||||
const AVCodec *encoder;
|
AVCodec *encoder;
|
||||||
int ret;
|
int ret;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
@@ -143,7 +108,8 @@ static int open_output_file(const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
in_stream = ifmt_ctx->streams[i];
|
in_stream = ifmt_ctx->streams[i];
|
||||||
dec_ctx = stream_ctx[i].dec_ctx;
|
dec_ctx = in_stream->codec;
|
||||||
|
enc_ctx = out_stream->codec;
|
||||||
|
|
||||||
if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
|
if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
|
||||||
|| dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
|| dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||||
@@ -153,11 +119,6 @@ static int open_output_file(const char *filename)
|
|||||||
av_log(NULL, AV_LOG_FATAL, "Necessary encoder not found\n");
|
av_log(NULL, AV_LOG_FATAL, "Necessary encoder not found\n");
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
enc_ctx = avcodec_alloc_context3(encoder);
|
|
||||||
if (!enc_ctx) {
|
|
||||||
av_log(NULL, AV_LOG_FATAL, "Failed to allocate the encoder context\n");
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In this example, we transcode to same properties (picture size,
|
/* In this example, we transcode to same properties (picture size,
|
||||||
* sample rate etc.). These properties can be changed for output
|
* sample rate etc.). These properties can be changed for output
|
||||||
@@ -172,7 +133,7 @@ static int open_output_file(const char *filename)
|
|||||||
else
|
else
|
||||||
enc_ctx->pix_fmt = dec_ctx->pix_fmt;
|
enc_ctx->pix_fmt = dec_ctx->pix_fmt;
|
||||||
/* video time_base can be set to whatever is handy and supported by encoder */
|
/* video time_base can be set to whatever is handy and supported by encoder */
|
||||||
enc_ctx->time_base = av_inv_q(dec_ctx->framerate);
|
enc_ctx->time_base = dec_ctx->time_base;
|
||||||
} else {
|
} else {
|
||||||
enc_ctx->sample_rate = dec_ctx->sample_rate;
|
enc_ctx->sample_rate = dec_ctx->sample_rate;
|
||||||
enc_ctx->channel_layout = dec_ctx->channel_layout;
|
enc_ctx->channel_layout = dec_ctx->channel_layout;
|
||||||
@@ -182,36 +143,28 @@ static int open_output_file(const char *filename)
|
|||||||
enc_ctx->time_base = (AVRational){1, enc_ctx->sample_rate};
|
enc_ctx->time_base = (AVRational){1, enc_ctx->sample_rate};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
|
||||||
enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
|
||||||
|
|
||||||
/* Third parameter can be used to pass settings to encoder */
|
/* Third parameter can be used to pass settings to encoder */
|
||||||
ret = avcodec_open2(enc_ctx, encoder, NULL);
|
ret = avcodec_open2(enc_ctx, encoder, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i);
|
av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = avcodec_parameters_from_context(out_stream->codecpar, enc_ctx);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Failed to copy encoder parameters to output stream #%u\n", i);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
out_stream->time_base = enc_ctx->time_base;
|
|
||||||
stream_ctx[i].enc_ctx = enc_ctx;
|
|
||||||
} else if (dec_ctx->codec_type == AVMEDIA_TYPE_UNKNOWN) {
|
} else if (dec_ctx->codec_type == AVMEDIA_TYPE_UNKNOWN) {
|
||||||
av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d is of unknown type, cannot proceed\n", i);
|
av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d is of unknown type, cannot proceed\n", i);
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
} else {
|
} else {
|
||||||
/* if this stream must be remuxed */
|
/* if this stream must be remuxed */
|
||||||
ret = avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar);
|
ret = avcodec_copy_context(ofmt_ctx->streams[i]->codec,
|
||||||
|
ifmt_ctx->streams[i]->codec);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Copying parameters for stream #%u failed\n", i);
|
av_log(NULL, AV_LOG_ERROR, "Copying stream context failed\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
out_stream->time_base = in_stream->time_base;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
||||||
|
enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||||
|
|
||||||
}
|
}
|
||||||
av_dump_format(ofmt_ctx, 0, filename, 1);
|
av_dump_format(ofmt_ctx, 0, filename, 1);
|
||||||
|
|
||||||
@@ -238,8 +191,8 @@ static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx,
|
|||||||
{
|
{
|
||||||
char args[512];
|
char args[512];
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
const AVFilter *buffersrc = NULL;
|
AVFilter *buffersrc = NULL;
|
||||||
const AVFilter *buffersink = NULL;
|
AVFilter *buffersink = NULL;
|
||||||
AVFilterContext *buffersrc_ctx = NULL;
|
AVFilterContext *buffersrc_ctx = NULL;
|
||||||
AVFilterContext *buffersink_ctx = NULL;
|
AVFilterContext *buffersink_ctx = NULL;
|
||||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||||
@@ -395,76 +348,67 @@ static int init_filters(void)
|
|||||||
filter_ctx[i].buffersrc_ctx = NULL;
|
filter_ctx[i].buffersrc_ctx = NULL;
|
||||||
filter_ctx[i].buffersink_ctx = NULL;
|
filter_ctx[i].buffersink_ctx = NULL;
|
||||||
filter_ctx[i].filter_graph = NULL;
|
filter_ctx[i].filter_graph = NULL;
|
||||||
if (!(ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO
|
if (!(ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO
|
||||||
|| ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO))
|
|| ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
|
if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||||
filter_spec = "null"; /* passthrough (dummy) filter for video */
|
filter_spec = "null"; /* passthrough (dummy) filter for video */
|
||||||
else
|
else
|
||||||
filter_spec = "anull"; /* passthrough (dummy) filter for audio */
|
filter_spec = "anull"; /* passthrough (dummy) filter for audio */
|
||||||
ret = init_filter(&filter_ctx[i], stream_ctx[i].dec_ctx,
|
ret = init_filter(&filter_ctx[i], ifmt_ctx->streams[i]->codec,
|
||||||
stream_ctx[i].enc_ctx, filter_spec);
|
ofmt_ctx->streams[i]->codec, filter_spec);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encode_write_frame(unsigned int stream_index, int flush)
|
static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame) {
|
||||||
{
|
|
||||||
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 ret;
|
||||||
|
int got_frame_local;
|
||||||
|
AVPacket enc_pkt;
|
||||||
|
int (*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int *) =
|
||||||
|
(ifmt_ctx->streams[stream_index]->codec->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");
|
av_log(NULL, AV_LOG_INFO, "Encoding frame\n");
|
||||||
/* encode filtered frame */
|
/* encode filtered frame */
|
||||||
av_packet_unref(enc_pkt);
|
enc_pkt.data = NULL;
|
||||||
|
enc_pkt.size = 0;
|
||||||
ret = avcodec_send_frame(stream->enc_ctx, filt_frame);
|
av_init_packet(&enc_pkt);
|
||||||
|
ret = enc_func(ofmt_ctx->streams[stream_index]->codec, &enc_pkt,
|
||||||
|
filt_frame, got_frame);
|
||||||
|
av_frame_free(&filt_frame);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
if (!(*got_frame))
|
||||||
|
return 0;
|
||||||
|
|
||||||
while (ret >= 0) {
|
/* prepare packet for muxing */
|
||||||
ret = avcodec_receive_packet(stream->enc_ctx, enc_pkt);
|
enc_pkt.stream_index = stream_index;
|
||||||
|
av_packet_rescale_ts(&enc_pkt,
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
ofmt_ctx->streams[stream_index]->codec->time_base,
|
||||||
return 0;
|
ofmt_ctx->streams[stream_index]->time_base);
|
||||||
|
|
||||||
/* 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
|
static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
|
||||||
{
|
{
|
||||||
FilteringContext *filter = &filter_ctx[stream_index];
|
|
||||||
int ret;
|
int ret;
|
||||||
|
AVFrame *filt_frame;
|
||||||
|
|
||||||
av_log(NULL, AV_LOG_INFO, "Pushing decoded frame to filters\n");
|
av_log(NULL, AV_LOG_INFO, "Pushing decoded frame to filters\n");
|
||||||
/* push the decoded frame into the filtergraph */
|
/* push the decoded frame into the filtergraph */
|
||||||
ret = av_buffersrc_add_frame_flags(filter->buffersrc_ctx,
|
ret = av_buffersrc_add_frame_flags(filter_ctx[stream_index].buffersrc_ctx,
|
||||||
frame, 0);
|
frame, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
|
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
|
||||||
@@ -473,9 +417,14 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
|
|||||||
|
|
||||||
/* pull filtered frames from the filtergraph */
|
/* pull filtered frames from the filtergraph */
|
||||||
while (1) {
|
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");
|
av_log(NULL, AV_LOG_INFO, "Pulling filtered frame from filters\n");
|
||||||
ret = av_buffersink_get_frame(filter->buffersink_ctx,
|
ret = av_buffersink_get_frame(filter_ctx[stream_index].buffersink_ctx,
|
||||||
filter->filtered_frame);
|
filt_frame);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* if no more frames for output - returns AVERROR(EAGAIN)
|
/* if no more frames for output - returns AVERROR(EAGAIN)
|
||||||
* if flushed and no more frames for output - returns AVERROR_EOF
|
* if flushed and no more frames for output - returns AVERROR_EOF
|
||||||
@@ -483,12 +432,12 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
|
|||||||
*/
|
*/
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
av_frame_free(&filt_frame);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
filter->filtered_frame->pict_type = AV_PICTURE_TYPE_NONE;
|
filt_frame->pict_type = AV_PICTURE_TYPE_NONE;
|
||||||
ret = encode_write_frame(stream_index, 0);
|
ret = encode_write_frame(filt_frame, stream_index, NULL);
|
||||||
av_frame_unref(filter->filtered_frame);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -498,80 +447,99 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
|
|||||||
|
|
||||||
static int flush_encoder(unsigned int stream_index)
|
static int flush_encoder(unsigned int stream_index)
|
||||||
{
|
{
|
||||||
if (!(stream_ctx[stream_index].enc_ctx->codec->capabilities &
|
int ret;
|
||||||
|
int got_frame;
|
||||||
|
|
||||||
|
if (!(ofmt_ctx->streams[stream_index]->codec->codec->capabilities &
|
||||||
AV_CODEC_CAP_DELAY))
|
AV_CODEC_CAP_DELAY))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index);
|
while (1) {
|
||||||
return encode_write_frame(stream_index, 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
AVPacket *packet = NULL;
|
AVPacket packet = { .data = NULL, .size = 0 };
|
||||||
|
AVFrame *frame = NULL;
|
||||||
|
enum AVMediaType type;
|
||||||
unsigned int stream_index;
|
unsigned int stream_index;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
int got_frame;
|
||||||
|
int (*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket *);
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Usage: %s <input file> <output file>\n", argv[0]);
|
av_log(NULL, AV_LOG_ERROR, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
av_register_all();
|
||||||
|
avfilter_register_all();
|
||||||
|
|
||||||
if ((ret = open_input_file(argv[1])) < 0)
|
if ((ret = open_input_file(argv[1])) < 0)
|
||||||
goto end;
|
goto end;
|
||||||
if ((ret = open_output_file(argv[2])) < 0)
|
if ((ret = open_output_file(argv[2])) < 0)
|
||||||
goto end;
|
goto end;
|
||||||
if ((ret = init_filters()) < 0)
|
if ((ret = init_filters()) < 0)
|
||||||
goto end;
|
goto end;
|
||||||
if (!(packet = av_packet_alloc()))
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
/* read all packets */
|
/* read all packets */
|
||||||
while (1) {
|
while (1) {
|
||||||
if ((ret = av_read_frame(ifmt_ctx, packet)) < 0)
|
if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0)
|
||||||
break;
|
break;
|
||||||
stream_index = packet->stream_index;
|
stream_index = packet.stream_index;
|
||||||
|
type = ifmt_ctx->streams[packet.stream_index]->codec->codec_type;
|
||||||
av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n",
|
av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n",
|
||||||
stream_index);
|
stream_index);
|
||||||
|
|
||||||
if (filter_ctx[stream_index].filter_graph) {
|
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");
|
av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the frame\n");
|
||||||
|
frame = av_frame_alloc();
|
||||||
av_packet_rescale_ts(packet,
|
if (!frame) {
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
av_packet_rescale_ts(&packet,
|
||||||
ifmt_ctx->streams[stream_index]->time_base,
|
ifmt_ctx->streams[stream_index]->time_base,
|
||||||
stream->dec_ctx->time_base);
|
ifmt_ctx->streams[stream_index]->codec->time_base);
|
||||||
ret = avcodec_send_packet(stream->dec_ctx, packet);
|
dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :
|
||||||
|
avcodec_decode_audio4;
|
||||||
|
ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame,
|
||||||
|
&got_frame, &packet);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
av_frame_free(&frame);
|
||||||
av_log(NULL, AV_LOG_ERROR, "Decoding failed\n");
|
av_log(NULL, AV_LOG_ERROR, "Decoding failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (ret >= 0) {
|
if (got_frame) {
|
||||||
ret = avcodec_receive_frame(stream->dec_ctx, stream->dec_frame);
|
frame->pts = av_frame_get_best_effort_timestamp(frame);
|
||||||
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
|
ret = filter_encode_write_frame(frame, stream_index);
|
||||||
break;
|
av_frame_free(&frame);
|
||||||
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)
|
if (ret < 0)
|
||||||
goto end;
|
goto end;
|
||||||
|
} else {
|
||||||
|
av_frame_free(&frame);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* remux this frame without reencoding */
|
/* remux this frame without reencoding */
|
||||||
av_packet_rescale_ts(packet,
|
av_packet_rescale_ts(&packet,
|
||||||
ifmt_ctx->streams[stream_index]->time_base,
|
ifmt_ctx->streams[stream_index]->time_base,
|
||||||
ofmt_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)
|
if (ret < 0)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
av_packet_unref(packet);
|
av_packet_unref(&packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* flush filters and encoders */
|
/* flush filters and encoders */
|
||||||
@@ -595,21 +563,16 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
av_write_trailer(ofmt_ctx);
|
av_write_trailer(ofmt_ctx);
|
||||||
end:
|
end:
|
||||||
av_packet_free(&packet);
|
av_packet_unref(&packet);
|
||||||
|
av_frame_free(&frame);
|
||||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||||
avcodec_free_context(&stream_ctx[i].dec_ctx);
|
avcodec_close(ifmt_ctx->streams[i]->codec);
|
||||||
if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && stream_ctx[i].enc_ctx)
|
if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && ofmt_ctx->streams[i]->codec)
|
||||||
avcodec_free_context(&stream_ctx[i].enc_ctx);
|
avcodec_close(ofmt_ctx->streams[i]->codec);
|
||||||
if (filter_ctx && filter_ctx[i].filter_graph) {
|
if (filter_ctx && filter_ctx[i].filter_graph)
|
||||||
avfilter_graph_free(&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(filter_ctx);
|
||||||
av_free(stream_ctx);
|
|
||||||
avformat_close_input(&ifmt_ctx);
|
avformat_close_input(&ifmt_ctx);
|
||||||
if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
|
if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
|
||||||
avio_closep(&ofmt_ctx->pb);
|
avio_closep(&ofmt_ctx->pb);
|
||||||
|
|||||||
@@ -1,224 +0,0 @@
|
|||||||
/*
|
|
||||||
* Video Acceleration API (video encoding) encode sample
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* Intel VAAPI-accelerated encoding example.
|
|
||||||
*
|
|
||||||
* @example vaapi_encode.c
|
|
||||||
* This example shows how to do VAAPI-accelerated encoding. now only support NV12
|
|
||||||
* raw file, usage like: vaapi_encode 1920 1080 input.yuv output.h264
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
|
||||||
#include <libavutil/pixdesc.h>
|
|
||||||
#include <libavutil/hwcontext.h>
|
|
||||||
|
|
||||||
static int width, height;
|
|
||||||
static AVBufferRef *hw_device_ctx = NULL;
|
|
||||||
|
|
||||||
static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx)
|
|
||||||
{
|
|
||||||
AVBufferRef *hw_frames_ref;
|
|
||||||
AVHWFramesContext *frames_ctx = NULL;
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx))) {
|
|
||||||
fprintf(stderr, "Failed to create VAAPI frame context.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
|
|
||||||
frames_ctx->format = AV_PIX_FMT_VAAPI;
|
|
||||||
frames_ctx->sw_format = AV_PIX_FMT_NV12;
|
|
||||||
frames_ctx->width = width;
|
|
||||||
frames_ctx->height = height;
|
|
||||||
frames_ctx->initial_pool_size = 20;
|
|
||||||
if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0) {
|
|
||||||
fprintf(stderr, "Failed to initialize VAAPI frame context."
|
|
||||||
"Error code: %s\n",av_err2str(err));
|
|
||||||
av_buffer_unref(&hw_frames_ref);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ref);
|
|
||||||
if (!ctx->hw_frames_ctx)
|
|
||||||
err = AVERROR(ENOMEM);
|
|
||||||
|
|
||||||
av_buffer_unref(&hw_frames_ref);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int encode_write(AVCodecContext *avctx, AVFrame *frame, FILE *fout)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
AVPacket *enc_pkt;
|
|
||||||
|
|
||||||
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);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int size, err;
|
|
||||||
FILE *fin = NULL, *fout = NULL;
|
|
||||||
AVFrame *sw_frame = NULL, *hw_frame = NULL;
|
|
||||||
AVCodecContext *avctx = NULL;
|
|
||||||
const AVCodec *codec = NULL;
|
|
||||||
const char *enc_name = "h264_vaapi";
|
|
||||||
|
|
||||||
if (argc < 5) {
|
|
||||||
fprintf(stderr, "Usage: %s <width> <height> <input file> <output file>\n", argv[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
width = atoi(argv[1]);
|
|
||||||
height = atoi(argv[2]);
|
|
||||||
size = width * height;
|
|
||||||
|
|
||||||
if (!(fin = fopen(argv[3], "r"))) {
|
|
||||||
fprintf(stderr, "Fail to open input file : %s\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!(fout = fopen(argv[4], "w+b"))) {
|
|
||||||
fprintf(stderr, "Fail to open output file : %s\n", strerror(errno));
|
|
||||||
err = -1;
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI,
|
|
||||||
NULL, NULL, 0);
|
|
||||||
if (err < 0) {
|
|
||||||
fprintf(stderr, "Failed to create a VAAPI device. Error code: %s\n", av_err2str(err));
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(codec = avcodec_find_encoder_by_name(enc_name))) {
|
|
||||||
fprintf(stderr, "Could not find encoder.\n");
|
|
||||||
err = -1;
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(avctx = avcodec_alloc_context3(codec))) {
|
|
||||||
err = AVERROR(ENOMEM);
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
|
|
||||||
avctx->width = width;
|
|
||||||
avctx->height = height;
|
|
||||||
avctx->time_base = (AVRational){1, 25};
|
|
||||||
avctx->framerate = (AVRational){25, 1};
|
|
||||||
avctx->sample_aspect_ratio = (AVRational){1, 1};
|
|
||||||
avctx->pix_fmt = AV_PIX_FMT_VAAPI;
|
|
||||||
|
|
||||||
/* set hw_frames_ctx for encoder's AVCodecContext */
|
|
||||||
if ((err = set_hwframe_ctx(avctx, hw_device_ctx)) < 0) {
|
|
||||||
fprintf(stderr, "Failed to set hwframe context.\n");
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = avcodec_open2(avctx, codec, NULL)) < 0) {
|
|
||||||
fprintf(stderr, "Cannot open video encoder codec. Error code: %s\n", av_err2str(err));
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
if (!(sw_frame = av_frame_alloc())) {
|
|
||||||
err = AVERROR(ENOMEM);
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
/* read data into software frame, and transfer them into hw frame */
|
|
||||||
sw_frame->width = width;
|
|
||||||
sw_frame->height = height;
|
|
||||||
sw_frame->format = AV_PIX_FMT_NV12;
|
|
||||||
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;
|
|
||||||
if ((err = fread((uint8_t*)(sw_frame->data[1]), size/2, 1, fin)) <= 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!(hw_frame = av_frame_alloc())) {
|
|
||||||
err = AVERROR(ENOMEM);
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
if ((err = av_hwframe_get_buffer(avctx->hw_frames_ctx, hw_frame, 0)) < 0) {
|
|
||||||
fprintf(stderr, "Error code: %s.\n", av_err2str(err));
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
if (!hw_frame->hw_frames_ctx) {
|
|
||||||
err = AVERROR(ENOMEM);
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
if ((err = av_hwframe_transfer_data(hw_frame, sw_frame, 0)) < 0) {
|
|
||||||
fprintf(stderr, "Error while transferring frame data to surface."
|
|
||||||
"Error code: %s.\n", av_err2str(err));
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = (encode_write(avctx, hw_frame, fout))) < 0) {
|
|
||||||
fprintf(stderr, "Failed to encode.\n");
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
av_frame_free(&hw_frame);
|
|
||||||
av_frame_free(&sw_frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flush encoder */
|
|
||||||
err = encode_write(avctx, NULL, fout);
|
|
||||||
if (err == AVERROR_EOF)
|
|
||||||
err = 0;
|
|
||||||
|
|
||||||
close:
|
|
||||||
if (fin)
|
|
||||||
fclose(fin);
|
|
||||||
if (fout)
|
|
||||||
fclose(fout);
|
|
||||||
av_frame_free(&sw_frame);
|
|
||||||
av_frame_free(&hw_frame);
|
|
||||||
avcodec_free_context(&avctx);
|
|
||||||
av_buffer_unref(&hw_device_ctx);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
@@ -1,308 +0,0 @@
|
|||||||
/*
|
|
||||||
* Video Acceleration API (video transcoding) transcode sample
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* Intel VAAPI-accelerated transcoding example.
|
|
||||||
*
|
|
||||||
* @example vaapi_transcode.c
|
|
||||||
* This example shows how to do VAAPI-accelerated transcoding.
|
|
||||||
* Usage: vaapi_transcode input_stream codec output_stream
|
|
||||||
* e.g: - vaapi_transcode input.mp4 h264_vaapi output_h264.mp4
|
|
||||||
* - vaapi_transcode input.mp4 vp9_vaapi output_vp9.ivf
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <libavutil/hwcontext.h>
|
|
||||||
#include <libavcodec/avcodec.h>
|
|
||||||
#include <libavformat/avformat.h>
|
|
||||||
|
|
||||||
static AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
|
|
||||||
static AVBufferRef *hw_device_ctx = NULL;
|
|
||||||
static AVCodecContext *decoder_ctx = NULL, *encoder_ctx = NULL;
|
|
||||||
static int video_stream = -1;
|
|
||||||
static AVStream *ost;
|
|
||||||
static int initialized = 0;
|
|
||||||
|
|
||||||
static enum AVPixelFormat get_vaapi_format(AVCodecContext *ctx,
|
|
||||||
const enum AVPixelFormat *pix_fmts)
|
|
||||||
{
|
|
||||||
const enum AVPixelFormat *p;
|
|
||||||
|
|
||||||
for (p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) {
|
|
||||||
if (*p == AV_PIX_FMT_VAAPI)
|
|
||||||
return *p;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "Unable to decode this file using VA-API.\n");
|
|
||||||
return AV_PIX_FMT_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int open_input_file(const char *filename)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
const AVCodec *decoder = NULL;
|
|
||||||
AVStream *video = NULL;
|
|
||||||
|
|
||||||
if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {
|
|
||||||
fprintf(stderr, "Cannot open input file '%s', Error code: %s\n",
|
|
||||||
filename, av_err2str(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
|
|
||||||
fprintf(stderr, "Cannot find input stream information. Error code: %s\n",
|
|
||||||
av_err2str(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Cannot find a video stream in the input file. "
|
|
||||||
"Error code: %s\n", av_err2str(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
video_stream = ret;
|
|
||||||
|
|
||||||
if (!(decoder_ctx = avcodec_alloc_context3(decoder)))
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
|
|
||||||
video = ifmt_ctx->streams[video_stream];
|
|
||||||
if ((ret = avcodec_parameters_to_context(decoder_ctx, video->codecpar)) < 0) {
|
|
||||||
fprintf(stderr, "avcodec_parameters_to_context error. Error code: %s\n",
|
|
||||||
av_err2str(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
decoder_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
|
|
||||||
if (!decoder_ctx->hw_device_ctx) {
|
|
||||||
fprintf(stderr, "A hardware device reference create failed.\n");
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
decoder_ctx->get_format = get_vaapi_format;
|
|
||||||
|
|
||||||
if ((ret = avcodec_open2(decoder_ctx, decoder, NULL)) < 0)
|
|
||||||
fprintf(stderr, "Failed to open codec for decoding. Error code: %s\n",
|
|
||||||
av_err2str(ret));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int encode_write(AVPacket *enc_pkt, AVFrame *frame)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
av_packet_unref(enc_pkt);
|
|
||||||
|
|
||||||
if ((ret = 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);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
|
|
||||||
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);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error during writing data to output file. "
|
|
||||||
"Error code: %s\n", av_err2str(ret));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
if (ret == AVERROR_EOF)
|
|
||||||
return 0;
|
|
||||||
ret = ((ret == AVERROR(EAGAIN)) ? 0:-1);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dec_enc(AVPacket *pkt, const AVCodec *enc_codec)
|
|
||||||
{
|
|
||||||
AVFrame *frame;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
ret = avcodec_send_packet(decoder_ctx, pkt);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error during decoding. Error code: %s\n", av_err2str(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (ret >= 0) {
|
|
||||||
if (!(frame = av_frame_alloc()))
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
|
|
||||||
ret = avcodec_receive_frame(decoder_ctx, frame);
|
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
|
||||||
av_frame_free(&frame);
|
|
||||||
return 0;
|
|
||||||
} else if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error while decoding. Error code: %s\n", av_err2str(ret));
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!initialized) {
|
|
||||||
/* we need to ref hw_frames_ctx of decoder to initialize encoder's codec.
|
|
||||||
Only after we get a decoded frame, can we obtain its hw_frames_ctx */
|
|
||||||
encoder_ctx->hw_frames_ctx = av_buffer_ref(decoder_ctx->hw_frames_ctx);
|
|
||||||
if (!encoder_ctx->hw_frames_ctx) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* set AVCodecContext Parameters for encoder, here we keep them stay
|
|
||||||
* the same as decoder.
|
|
||||||
* xxx: now the sample can't handle resolution change case.
|
|
||||||
*/
|
|
||||||
encoder_ctx->time_base = av_inv_q(decoder_ctx->framerate);
|
|
||||||
encoder_ctx->pix_fmt = AV_PIX_FMT_VAAPI;
|
|
||||||
encoder_ctx->width = decoder_ctx->width;
|
|
||||||
encoder_ctx->height = decoder_ctx->height;
|
|
||||||
|
|
||||||
if ((ret = avcodec_open2(encoder_ctx, enc_codec, NULL)) < 0) {
|
|
||||||
fprintf(stderr, "Failed to open encode codec. Error code: %s\n",
|
|
||||||
av_err2str(ret));
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(ost = avformat_new_stream(ofmt_ctx, enc_codec))) {
|
|
||||||
fprintf(stderr, "Failed to allocate stream for output format.\n");
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
ost->time_base = encoder_ctx->time_base;
|
|
||||||
ret = avcodec_parameters_from_context(ost->codecpar, encoder_ctx);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Failed to copy the stream parameters. "
|
|
||||||
"Error code: %s\n", av_err2str(ret));
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* write the stream header */
|
|
||||||
if ((ret = avformat_write_header(ofmt_ctx, NULL)) < 0) {
|
|
||||||
fprintf(stderr, "Error while writing stream header. "
|
|
||||||
"Error code: %s\n", av_err2str(ret));
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
initialized = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = encode_write(pkt, frame)) < 0)
|
|
||||||
fprintf(stderr, "Error during encoding and writing.\n");
|
|
||||||
|
|
||||||
fail:
|
|
||||||
av_frame_free(&frame);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
const AVCodec *enc_codec;
|
|
||||||
int ret = 0;
|
|
||||||
AVPacket *dec_pkt;
|
|
||||||
|
|
||||||
if (argc != 4) {
|
|
||||||
fprintf(stderr, "Usage: %s <input file> <encode codec> <output file>\n"
|
|
||||||
"The output format is guessed according to the file extension.\n"
|
|
||||||
"\n", argv[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, NULL, NULL, 0);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Failed to create a VAAPI device. Error code: %s\n", av_err2str(ret));
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (!(enc_codec = avcodec_find_encoder_by_name(argv[2]))) {
|
|
||||||
fprintf(stderr, "Could not find encoder '%s'\n", argv[2]);
|
|
||||||
ret = -1;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = (avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, argv[3]))) < 0) {
|
|
||||||
fprintf(stderr, "Failed to deduce output format from file extension. Error code: "
|
|
||||||
"%s\n", av_err2str(ret));
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(encoder_ctx = avcodec_alloc_context3(enc_codec))) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = avio_open(&ofmt_ctx->pb, argv[3], AVIO_FLAG_WRITE);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Cannot open output file. "
|
|
||||||
"Error code: %s\n", av_err2str(ret));
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read all packets and only transcoding video */
|
|
||||||
while (ret >= 0) {
|
|
||||||
if ((ret = av_read_frame(ifmt_ctx, dec_pkt)) < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (video_stream == dec_pkt->stream_index)
|
|
||||||
ret = dec_enc(dec_pkt, enc_codec);
|
|
||||||
|
|
||||||
av_packet_unref(dec_pkt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flush decoder */
|
|
||||||
av_packet_unref(dec_pkt);
|
|
||||||
ret = dec_enc(dec_pkt, enc_codec);
|
|
||||||
|
|
||||||
/* flush encoder */
|
|
||||||
ret = encode_write(dec_pkt, NULL);
|
|
||||||
|
|
||||||
/* write the trailer for output stream */
|
|
||||||
av_write_trailer(ofmt_ctx);
|
|
||||||
|
|
||||||
end:
|
|
||||||
avformat_close_input(&ifmt_ctx);
|
|
||||||
avformat_close_input(&ofmt_ctx);
|
|
||||||
avcodec_free_context(&decoder_ctx);
|
|
||||||
avcodec_free_context(&encoder_ctx);
|
|
||||||
av_buffer_unref(&hw_device_ctx);
|
|
||||||
av_packet_free(&dec_pkt);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
95
doc/faq.texi
95
doc/faq.texi
@@ -76,7 +76,7 @@ the gcc developers. Note that we will not add workarounds for gcc bugs.
|
|||||||
|
|
||||||
Also note that (some of) the gcc developers believe this is not a bug or
|
Also note that (some of) the gcc developers believe this is not a bug or
|
||||||
not a bug they should fix:
|
not a bug they should fix:
|
||||||
@url{https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11203}.
|
@url{http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11203}.
|
||||||
Then again, some of them do not know the difference between an undecidable
|
Then again, some of them do not know the difference between an undecidable
|
||||||
problem and an NP-hard problem...
|
problem and an NP-hard problem...
|
||||||
|
|
||||||
@@ -257,13 +257,13 @@ default.
|
|||||||
@section Which are good parameters for encoding high quality MPEG-4?
|
@section Which are good parameters for encoding high quality MPEG-4?
|
||||||
|
|
||||||
'-mbd rd -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -g 300 -pass 1/2',
|
'-mbd rd -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -g 300 -pass 1/2',
|
||||||
things to try: '-bf 2', '-mpv_flags qp_rd', '-mpv_flags mv0', '-mpv_flags skip_rd'.
|
things to try: '-bf 2', '-flags qprd', '-flags mv0', '-flags skiprd'.
|
||||||
|
|
||||||
@section Which are good parameters for encoding high quality MPEG-1/MPEG-2?
|
@section Which are good parameters for encoding high quality MPEG-1/MPEG-2?
|
||||||
|
|
||||||
'-mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -pass 1/2'
|
'-mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -pass 1/2'
|
||||||
but beware the '-g 100' might cause problems with some decoders.
|
but beware the '-g 100' might cause problems with some decoders.
|
||||||
Things to try: '-bf 2', '-mpv_flags qp_rd', '-mpv_flags mv0', '-mpv_flags skip_rd'.
|
Things to try: '-bf 2', '-flags qprd', '-flags mv0', '-flags skiprd.
|
||||||
|
|
||||||
@section Interlaced video looks very bad when encoded with ffmpeg, what is wrong?
|
@section Interlaced video looks very bad when encoded with ffmpeg, what is wrong?
|
||||||
|
|
||||||
@@ -311,18 +311,18 @@ invoking ffmpeg with several @option{-i} options.
|
|||||||
For audio, to put all channels together in a single stream (example: two
|
For audio, to put all channels together in a single stream (example: two
|
||||||
mono streams into one stereo stream): this is sometimes called to
|
mono streams into one stereo stream): this is sometimes called to
|
||||||
@emph{merge} them, and can be done using the
|
@emph{merge} them, and can be done using the
|
||||||
@url{ffmpeg-filters.html#amerge, @code{amerge}} filter.
|
@url{https://ffmpeg.org/ffmpeg-filters.html#amerge, @code{amerge}} filter.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
For audio, to play one on top of the other: this is called to @emph{mix}
|
For audio, to play one on top of the other: this is called to @emph{mix}
|
||||||
them, and can be done by first merging them into a single stream and then
|
them, and can be done by first merging them into a single stream and then
|
||||||
using the @url{ffmpeg-filters.html#pan, @code{pan}} filter to mix
|
using the @url{https://ffmpeg.org/ffmpeg-filters.html#pan, @code{pan}} filter to mix
|
||||||
the channels at will.
|
the channels at will.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
For video, to display both together, side by side or one on top of a part of
|
For video, to display both together, side by side or one on top of a part of
|
||||||
the other; it can be done using the
|
the other; it can be done using the
|
||||||
@url{ffmpeg-filters.html#overlay, @code{overlay}} video filter.
|
@url{https://ffmpeg.org/ffmpeg-filters.html#overlay, @code{overlay}} video filter.
|
||||||
|
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@@ -333,19 +333,19 @@ There are several solutions, depending on the exact circumstances.
|
|||||||
|
|
||||||
@subsection Concatenating using the concat @emph{filter}
|
@subsection Concatenating using the concat @emph{filter}
|
||||||
|
|
||||||
FFmpeg has a @url{ffmpeg-filters.html#concat,
|
FFmpeg has a @url{https://ffmpeg.org/ffmpeg-filters.html#concat,
|
||||||
@code{concat}} filter designed specifically for that, with examples in the
|
@code{concat}} filter designed specifically for that, with examples in the
|
||||||
documentation. This operation is recommended if you need to re-encode.
|
documentation. This operation is recommended if you need to re-encode.
|
||||||
|
|
||||||
@subsection Concatenating using the concat @emph{demuxer}
|
@subsection Concatenating using the concat @emph{demuxer}
|
||||||
|
|
||||||
FFmpeg has a @url{ffmpeg-formats.html#concat,
|
FFmpeg has a @url{https://www.ffmpeg.org/ffmpeg-formats.html#concat,
|
||||||
@code{concat}} demuxer which you can use when you want to avoid a re-encode and
|
@code{concat}} demuxer which you can use when you want to avoid a re-encode and
|
||||||
your format doesn't support file level concatenation.
|
your format doesn't support file level concatenation.
|
||||||
|
|
||||||
@subsection Concatenating using the concat @emph{protocol} (file level)
|
@subsection Concatenating using the concat @emph{protocol} (file level)
|
||||||
|
|
||||||
FFmpeg has a @url{ffmpeg-protocols.html#concat,
|
FFmpeg has a @url{https://ffmpeg.org/ffmpeg-protocols.html#concat,
|
||||||
@code{concat}} protocol designed specifically for that, with examples in the
|
@code{concat}} protocol designed specifically for that, with examples in the
|
||||||
documentation.
|
documentation.
|
||||||
|
|
||||||
@@ -385,7 +385,7 @@ mkfifo intermediate2.mpg
|
|||||||
ffmpeg -i input1.avi -qscale:v 1 -y intermediate1.mpg < /dev/null &
|
ffmpeg -i input1.avi -qscale:v 1 -y intermediate1.mpg < /dev/null &
|
||||||
ffmpeg -i input2.avi -qscale:v 1 -y intermediate2.mpg < /dev/null &
|
ffmpeg -i input2.avi -qscale:v 1 -y intermediate2.mpg < /dev/null &
|
||||||
cat intermediate1.mpg intermediate2.mpg |\
|
cat intermediate1.mpg intermediate2.mpg |\
|
||||||
ffmpeg -f mpeg -i - -c:v mpeg4 -c:a libmp3lame output.avi
|
ffmpeg -f mpeg -i - -c:v mpeg4 -acodec libmp3lame output.avi
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@subsection Concatenating using raw audio and video
|
@subsection Concatenating using raw audio and video
|
||||||
@@ -407,13 +407,13 @@ mkfifo temp2.a
|
|||||||
mkfifo temp2.v
|
mkfifo temp2.v
|
||||||
mkfifo all.a
|
mkfifo all.a
|
||||||
mkfifo all.v
|
mkfifo all.v
|
||||||
ffmpeg -i input1.flv -vn -f u16le -c:a pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null &
|
ffmpeg -i input1.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null &
|
||||||
ffmpeg -i input2.flv -vn -f u16le -c:a pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null &
|
ffmpeg -i input2.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null &
|
||||||
ffmpeg -i input1.flv -an -f yuv4mpegpipe - > temp1.v < /dev/null &
|
ffmpeg -i input1.flv -an -f yuv4mpegpipe - > temp1.v < /dev/null &
|
||||||
@{ ffmpeg -i input2.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v ; @} &
|
@{ ffmpeg -i input2.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v ; @} &
|
||||||
cat temp1.a temp2.a > all.a &
|
cat temp1.a temp2.a > all.a &
|
||||||
cat temp1.v temp2.v > all.v &
|
cat temp1.v temp2.v > all.v &
|
||||||
ffmpeg -f u16le -c:a pcm_s16le -ac 2 -ar 44100 -i all.a \
|
ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \
|
||||||
-f yuv4mpegpipe -i all.v \
|
-f yuv4mpegpipe -i all.v \
|
||||||
-y output.flv
|
-y output.flv
|
||||||
rm temp[12].[av] all.[av]
|
rm temp[12].[av] all.[av]
|
||||||
@@ -485,7 +485,7 @@ scaling adjusts the SAR to keep the DAR constant.
|
|||||||
|
|
||||||
If you want to stretch, or “unstretch”, the image, you need to override the
|
If you want to stretch, or “unstretch”, the image, you need to override the
|
||||||
information with the
|
information with the
|
||||||
@url{ffmpeg-filters.html#setdar_002c-setsar, @code{setdar or setsar filters}}.
|
@url{https://ffmpeg.org/ffmpeg-filters.html#setdar_002c-setsar, @code{setdar or setsar filters}}.
|
||||||
|
|
||||||
Do not forget to examine carefully the original video to check whether the
|
Do not forget to examine carefully the original video to check whether the
|
||||||
stretching comes from the image or from the aspect ratio information.
|
stretching comes from the image or from the aspect ratio information.
|
||||||
@@ -501,71 +501,6 @@ ffmpeg -i ega_screen.nut -vf setdar=4/3 ega_screen_anamorphic.nut
|
|||||||
ffmpeg -i ega_screen.nut -aspect 4/3 -c copy ega_screen_overridden.nut
|
ffmpeg -i ega_screen.nut -aspect 4/3 -c copy ega_screen_overridden.nut
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@anchor{background task}
|
|
||||||
@section How do I run ffmpeg as a background task?
|
|
||||||
|
|
||||||
ffmpeg normally checks the console input, for entries like "q" to stop
|
|
||||||
and "?" to give help, while performing operations. ffmpeg does not have a way of
|
|
||||||
detecting when it is running as a background task.
|
|
||||||
When it checks the console input, that can cause the process running ffmpeg
|
|
||||||
in the background to suspend.
|
|
||||||
|
|
||||||
To prevent those input checks, allowing ffmpeg to run as a background task,
|
|
||||||
use the @url{ffmpeg.html#stdin-option, @code{-nostdin} option}
|
|
||||||
in the ffmpeg invocation. This is effective whether you run ffmpeg in a shell
|
|
||||||
or invoke ffmpeg in its own process via an operating system API.
|
|
||||||
|
|
||||||
As an alternative, when you are running ffmpeg in a shell, you can redirect
|
|
||||||
standard input to @code{/dev/null} (on Linux and macOS)
|
|
||||||
or @code{NUL} (on Windows). You can do this redirect either
|
|
||||||
on the ffmpeg invocation, or from a shell script which calls ffmpeg.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
@example
|
|
||||||
ffmpeg -nostdin -i INPUT OUTPUT
|
|
||||||
@end example
|
|
||||||
|
|
||||||
or (on Linux, macOS, and other UNIX-like shells):
|
|
||||||
|
|
||||||
@example
|
|
||||||
ffmpeg -i INPUT OUTPUT </dev/null
|
|
||||||
@end example
|
|
||||||
|
|
||||||
or (on Windows):
|
|
||||||
|
|
||||||
@example
|
|
||||||
ffmpeg -i INPUT OUTPUT <NUL
|
|
||||||
@end example
|
|
||||||
|
|
||||||
@section How do I prevent ffmpeg from suspending with a message like @emph{suspended (tty output)}?
|
|
||||||
|
|
||||||
If you run ffmpeg in the background, you may find that its process suspends.
|
|
||||||
There may be a message like @emph{suspended (tty output)}. The question is how
|
|
||||||
to prevent the process from being suspended.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
@example
|
|
||||||
% ffmpeg -i INPUT OUTPUT &> ~/tmp/log.txt &
|
|
||||||
[1] 93352
|
|
||||||
%
|
|
||||||
[1] + suspended (tty output) ffmpeg -i INPUT OUTPUT &>
|
|
||||||
@end example
|
|
||||||
|
|
||||||
The message "tty output" notwithstanding, the problem here is that
|
|
||||||
ffmpeg normally checks the console input when it runs. The operating system
|
|
||||||
detects this, and suspends the process until you can bring it to the
|
|
||||||
foreground and attend to it.
|
|
||||||
|
|
||||||
The solution is to use the right techniques to tell ffmpeg not to consult
|
|
||||||
console input. You can use the
|
|
||||||
@url{ffmpeg.html#stdin-option, @code{-nostdin} option},
|
|
||||||
or redirect standard input with @code{< /dev/null}.
|
|
||||||
See FAQ
|
|
||||||
@ref{background task, @emph{How do I run ffmpeg as a background task?}}
|
|
||||||
for details.
|
|
||||||
|
|
||||||
@chapter Development
|
@chapter Development
|
||||||
|
|
||||||
@section Are there examples illustrating how to use the FFmpeg libraries, particularly libavcodec and libavformat?
|
@section Are there examples illustrating how to use the FFmpeg libraries, particularly libavcodec and libavformat?
|
||||||
@@ -601,7 +536,7 @@ No. These tools are too bloated and they complicate the build.
|
|||||||
FFmpeg is already organized in a highly modular manner and does not need to
|
FFmpeg is already organized in a highly modular manner and does not need to
|
||||||
be rewritten in a formal object language. Further, many of the developers
|
be rewritten in a formal object language. Further, many of the developers
|
||||||
favor straight C; it works for them. For more arguments on this matter,
|
favor straight C; it works for them. For more arguments on this matter,
|
||||||
read @uref{https://web.archive.org/web/20111004021423/http://kernel.org/pub/linux/docs/lkml/#s15, "Programming Religion"}.
|
read @uref{http://www.tux.org/lkml/#s15, "Programming Religion"}.
|
||||||
|
|
||||||
@section Why are the ffmpeg programs devoid of debugging symbols?
|
@section Why are the ffmpeg programs devoid of debugging symbols?
|
||||||
|
|
||||||
|
|||||||
@@ -147,32 +147,6 @@ process.
|
|||||||
The only thing left is to automate the execution of the fate.sh script and
|
The only thing left is to automate the execution of the fate.sh script and
|
||||||
the synchronisation of the samples directory.
|
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.
|
|
||||||
Also keep in mind older checkouts use existing sample files, that means in
|
|
||||||
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:
|
|
||||||
rsync -vauL --chmod=Dg+s,Duo+x,ug+rw,o+r,o-w,+X fate-suite.ffmpeg.org:/home/samples/fate-suite/ ~/fate-suite
|
|
||||||
|
|
||||||
#Then do a dry run checking what would be uploaded:
|
|
||||||
rsync -vanL --no-g --chmod=Dg+s,Duo+x,ug+rw,o+r,o-w,+X ~/fate-suite/ fate-suite.ffmpeg.org:/home/samples/fate-suite
|
|
||||||
|
|
||||||
#Upload the files:
|
|
||||||
rsync -vaL --no-g --chmod=Dg+s,Duo+x,ug+rw,o+r,o-w,+X ~/fate-suite/ fate-suite.ffmpeg.org:/home/samples/fate-suite
|
|
||||||
@end example
|
|
||||||
|
|
||||||
|
|
||||||
@chapter FATE makefile targets and variables
|
@chapter FATE makefile targets and variables
|
||||||
|
|
||||||
@@ -223,16 +197,6 @@ through @command{ssh}.
|
|||||||
|
|
||||||
@item GEN
|
@item GEN
|
||||||
Set to @samp{1} to generate the missing or mismatched references.
|
Set to @samp{1} to generate the missing or mismatched references.
|
||||||
|
|
||||||
@item HWACCEL
|
|
||||||
Specify which hardware acceleration to use while running regression tests,
|
|
||||||
by default @samp{none} is used.
|
|
||||||
|
|
||||||
@item KEEP
|
|
||||||
Set to @samp{1} to keep temp files generated by fate test(s) when test is successful.
|
|
||||||
Default is @samp{0}, which removes these files. Files are always kept when a test
|
|
||||||
fails.
|
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@section Examples
|
@section Examples
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ workdir= # directory in which to do all the work
|
|||||||
#fate_recv="ssh -T fate@fate.ffmpeg.org" # command to submit report
|
#fate_recv="ssh -T fate@fate.ffmpeg.org" # command to submit report
|
||||||
comment= # optional description
|
comment= # optional description
|
||||||
build_only= # set to "yes" for a compile-only instance that skips tests
|
build_only= # set to "yes" for a compile-only instance that skips tests
|
||||||
ignore_tests=
|
|
||||||
|
|
||||||
# the following are optional and map to configure options
|
# the following are optional and map to configure options
|
||||||
arch=
|
arch=
|
||||||
@@ -27,7 +26,5 @@ extra_conf= # extra configure options not covered above
|
|||||||
|
|
||||||
#make= # name of GNU make if not 'make'
|
#make= # name of GNU make if not 'make'
|
||||||
makeopts= # extra options passed to 'make'
|
makeopts= # extra options passed to 'make'
|
||||||
#makeopts_fate= # extra options passed to 'make' when running tests,
|
|
||||||
# defaulting to makeopts above if this is not set
|
|
||||||
#tar= # command to create a tar archive from its arguments on stdout,
|
#tar= # command to create a tar archive from its arguments on stdout,
|
||||||
# defaults to 'tar c'
|
# defaults to 'tar c'
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ bitstream level modifications without performing decoding.
|
|||||||
@chapter See Also
|
@chapter See Also
|
||||||
|
|
||||||
@ifhtml
|
@ifhtml
|
||||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||||
@url{libavcodec.html,libavcodec}
|
@url{libavcodec.html,libavcodec}
|
||||||
@end ifhtml
|
@end ifhtml
|
||||||
|
|
||||||
@ifnothtml
|
@ifnothtml
|
||||||
ffmpeg(1), ffplay(1), ffprobe(1), libavcodec(3)
|
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavcodec(3)
|
||||||
@end ifnothtml
|
@end ifnothtml
|
||||||
|
|
||||||
@include authors.texi
|
@include authors.texi
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ the libavcodec library.
|
|||||||
@chapter See Also
|
@chapter See Also
|
||||||
|
|
||||||
@ifhtml
|
@ifhtml
|
||||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||||
@url{libavcodec.html,libavcodec}
|
@url{libavcodec.html,libavcodec}
|
||||||
@end ifhtml
|
@end ifhtml
|
||||||
|
|
||||||
@ifnothtml
|
@ifnothtml
|
||||||
ffmpeg(1), ffplay(1), ffprobe(1), libavcodec(3)
|
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavcodec(3)
|
||||||
@end ifnothtml
|
@end ifnothtml
|
||||||
|
|
||||||
@include authors.texi
|
@include authors.texi
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ libavdevice library.
|
|||||||
@chapter See Also
|
@chapter See Also
|
||||||
|
|
||||||
@ifhtml
|
@ifhtml
|
||||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||||
@url{libavdevice.html,libavdevice}
|
@url{libavdevice.html,libavdevice}
|
||||||
@end ifhtml
|
@end ifhtml
|
||||||
|
|
||||||
@ifnothtml
|
@ifnothtml
|
||||||
ffmpeg(1), ffplay(1), ffprobe(1), libavdevice(3)
|
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavdevice(3)
|
||||||
@end ifnothtml
|
@end ifnothtml
|
||||||
|
|
||||||
@include authors.texi
|
@include authors.texi
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ libavfilter library.
|
|||||||
@chapter See Also
|
@chapter See Also
|
||||||
|
|
||||||
@ifhtml
|
@ifhtml
|
||||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||||
@url{libavfilter.html,libavfilter}
|
@url{libavfilter.html,libavfilter}
|
||||||
@end ifhtml
|
@end ifhtml
|
||||||
|
|
||||||
@ifnothtml
|
@ifnothtml
|
||||||
ffmpeg(1), ffplay(1), ffprobe(1), libavfilter(3)
|
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavfilter(3)
|
||||||
@end ifnothtml
|
@end ifnothtml
|
||||||
|
|
||||||
@include authors.texi
|
@include authors.texi
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ provided by the libavformat library.
|
|||||||
@chapter See Also
|
@chapter See Also
|
||||||
|
|
||||||
@ifhtml
|
@ifhtml
|
||||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||||
@url{libavformat.html,libavformat}
|
@url{libavformat.html,libavformat}
|
||||||
@end ifhtml
|
@end ifhtml
|
||||||
|
|
||||||
@ifnothtml
|
@ifnothtml
|
||||||
ffmpeg(1), ffplay(1), ffprobe(1), libavformat(3)
|
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavformat(3)
|
||||||
@end ifnothtml
|
@end ifnothtml
|
||||||
|
|
||||||
@include authors.texi
|
@include authors.texi
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ libavformat library.
|
|||||||
@chapter See Also
|
@chapter See Also
|
||||||
|
|
||||||
@ifhtml
|
@ifhtml
|
||||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||||
@url{libavformat.html,libavformat}
|
@url{libavformat.html,libavformat}
|
||||||
@end ifhtml
|
@end ifhtml
|
||||||
|
|
||||||
@ifnothtml
|
@ifnothtml
|
||||||
ffmpeg(1), ffplay(1), ffprobe(1), libavformat(3)
|
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavformat(3)
|
||||||
@end ifnothtml
|
@end ifnothtml
|
||||||
|
|
||||||
@include authors.texi
|
@include authors.texi
|
||||||
|
|||||||
@@ -25,12 +25,12 @@ and convert audio format and packing layout.
|
|||||||
@chapter See Also
|
@chapter See Also
|
||||||
|
|
||||||
@ifhtml
|
@ifhtml
|
||||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||||
@url{libswresample.html,libswresample}
|
@url{libswresample.html,libswresample}
|
||||||
@end ifhtml
|
@end ifhtml
|
||||||
|
|
||||||
@ifnothtml
|
@ifnothtml
|
||||||
ffmpeg(1), ffplay(1), ffprobe(1), libswresample(3)
|
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libswresample(3)
|
||||||
@end ifnothtml
|
@end ifnothtml
|
||||||
|
|
||||||
@include authors.texi
|
@include authors.texi
|
||||||
|
|||||||
@@ -24,12 +24,12 @@ image rescaling and pixel format conversion.
|
|||||||
@chapter See Also
|
@chapter See Also
|
||||||
|
|
||||||
@ifhtml
|
@ifhtml
|
||||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||||
@url{libswscale.html,libswscale}
|
@url{libswscale.html,libswscale}
|
||||||
@end ifhtml
|
@end ifhtml
|
||||||
|
|
||||||
@ifnothtml
|
@ifnothtml
|
||||||
ffmpeg(1), ffplay(1), ffprobe(1), libswscale(3)
|
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libswscale(3)
|
||||||
@end ifnothtml
|
@end ifnothtml
|
||||||
|
|
||||||
@include authors.texi
|
@include authors.texi
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ by the libavutil library.
|
|||||||
@chapter See Also
|
@chapter See Also
|
||||||
|
|
||||||
@ifhtml
|
@ifhtml
|
||||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe},
|
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||||
@url{libavutil.html,libavutil}
|
@url{libavutil.html,libavutil}
|
||||||
@end ifhtml
|
@end ifhtml
|
||||||
|
|
||||||
@ifnothtml
|
@ifnothtml
|
||||||
ffmpeg(1), ffplay(1), ffprobe(1), libavutil(3)
|
ffmpeg(1), ffplay(1), ffprobe(1), ffserver(1), libavutil(3)
|
||||||
@end ifnothtml
|
@end ifnothtml
|
||||||
|
|
||||||
@include authors.texi
|
@include authors.texi
|
||||||
|
|||||||
953
doc/ffmpeg.texi
953
doc/ffmpeg.texi
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
@chapter Synopsis
|
@chapter Synopsis
|
||||||
|
|
||||||
ffplay [@var{options}] [@file{input_url}]
|
ffplay [@var{options}] [@file{input_file}]
|
||||||
|
|
||||||
@chapter Description
|
@chapter Description
|
||||||
@c man begin DESCRIPTION
|
@c man begin DESCRIPTION
|
||||||
@@ -60,26 +60,12 @@ Play @var{duration} seconds of audio/video.
|
|||||||
see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||||
@item -bytes
|
@item -bytes
|
||||||
Seek by bytes.
|
Seek by bytes.
|
||||||
@item -seek_interval
|
|
||||||
Set custom interval, in seconds, for seeking using left/right keys. Default is 10 seconds.
|
|
||||||
@item -nodisp
|
@item -nodisp
|
||||||
Disable graphical display.
|
Disable graphical display.
|
||||||
@item -noborder
|
|
||||||
Borderless window.
|
|
||||||
@item -alwaysontop
|
|
||||||
Window always on top. Available on: X11 with SDL >= 2.0.5, Windows SDL >= 2.0.6.
|
|
||||||
@item -volume
|
|
||||||
Set the startup volume. 0 means silence, 100 means no volume reduction or
|
|
||||||
amplification. Negative values are treated as 0, values above 100 are treated
|
|
||||||
as 100.
|
|
||||||
@item -f @var{fmt}
|
@item -f @var{fmt}
|
||||||
Force format.
|
Force format.
|
||||||
@item -window_title @var{title}
|
@item -window_title @var{title}
|
||||||
Set window title (default is the input filename).
|
Set window title (default is the input filename).
|
||||||
@item -left @var{title}
|
|
||||||
Set the x position for the left of the window (default is a centered window).
|
|
||||||
@item -top @var{title}
|
|
||||||
Set the y position for the top of the window (default is a centered window).
|
|
||||||
@item -loop @var{number}
|
@item -loop @var{number}
|
||||||
Loops movie playback <number> times. 0 means forever.
|
Loops movie playback <number> times. 0 means forever.
|
||||||
@item -showmode @var{mode}
|
@item -showmode @var{mode}
|
||||||
@@ -120,8 +106,8 @@ the input audio.
|
|||||||
Use the option "-filters" to show all the available filters (including
|
Use the option "-filters" to show all the available filters (including
|
||||||
sources and sinks).
|
sources and sinks).
|
||||||
|
|
||||||
@item -i @var{input_url}
|
@item -i @var{input_file}
|
||||||
Read @var{input_url}.
|
Read @var{input_file}.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@section Advanced options
|
@section Advanced options
|
||||||
@@ -133,9 +119,8 @@ This option has been deprecated in favor of private options, try -pixel_format.
|
|||||||
@item -stats
|
@item -stats
|
||||||
Print several playback statistics, in particular show the stream
|
Print several playback statistics, in particular show the stream
|
||||||
duration, the codec parameters, the current position in the stream and
|
duration, the codec parameters, the current position in the stream and
|
||||||
the audio/video synchronisation drift. It is shown by default, unless the
|
the audio/video synchronisation drift. It is on by default, to
|
||||||
log level is lower than @code{info}. Its display can be forced by manually
|
explicitly disable it you need to specify @code{-nostats}.
|
||||||
specifying this option. To disable it, you need to specify @code{-nostats}.
|
|
||||||
|
|
||||||
@item -fast
|
@item -fast
|
||||||
Non-spec-compliant optimizations.
|
Non-spec-compliant optimizations.
|
||||||
@@ -198,12 +183,6 @@ input as soon as possible. Enabled by default for realtime streams, where data
|
|||||||
may be dropped if not read in time. Use this option to enable infinite buffers
|
may be dropped if not read in time. Use this option to enable infinite buffers
|
||||||
for all inputs, use @option{-noinfbuf} to disable it.
|
for all inputs, use @option{-noinfbuf} to disable it.
|
||||||
|
|
||||||
@item -filter_threads @var{nb_threads}
|
|
||||||
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. The default is 0 which means that the thread count will be
|
|
||||||
determined by the number of available CPUs.
|
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@section While playing
|
@section While playing
|
||||||
@@ -295,7 +274,6 @@ Toggle full screen.
|
|||||||
@ifset config-avfilter
|
@ifset config-avfilter
|
||||||
@include filters.texi
|
@include filters.texi
|
||||||
@end ifset
|
@end ifset
|
||||||
@include general_contents.texi
|
|
||||||
@end ifset
|
@end ifset
|
||||||
|
|
||||||
@chapter See Also
|
@chapter See Also
|
||||||
@@ -307,7 +285,7 @@ Toggle full screen.
|
|||||||
@ifset config-not-all
|
@ifset config-not-all
|
||||||
@url{ffplay-all.html,ffmpeg-all},
|
@url{ffplay-all.html,ffmpeg-all},
|
||||||
@end ifset
|
@end ifset
|
||||||
@url{ffmpeg.html,ffmpeg}, @url{ffprobe.html,ffprobe},
|
@url{ffmpeg.html,ffmpeg}, @url{ffprobe.html,ffprobe}, @url{ffserver.html,ffserver},
|
||||||
@url{ffmpeg-utils.html,ffmpeg-utils},
|
@url{ffmpeg-utils.html,ffmpeg-utils},
|
||||||
@url{ffmpeg-scaler.html,ffmpeg-scaler},
|
@url{ffmpeg-scaler.html,ffmpeg-scaler},
|
||||||
@url{ffmpeg-resampler.html,ffmpeg-resampler},
|
@url{ffmpeg-resampler.html,ffmpeg-resampler},
|
||||||
@@ -326,7 +304,7 @@ ffplay(1),
|
|||||||
@ifset config-not-all
|
@ifset config-not-all
|
||||||
ffplay-all(1),
|
ffplay-all(1),
|
||||||
@end ifset
|
@end ifset
|
||||||
ffmpeg(1), ffprobe(1),
|
ffmpeg(1), ffprobe(1), ffserver(1),
|
||||||
ffmpeg-utils(1), ffmpeg-scaler(1), ffmpeg-resampler(1),
|
ffmpeg-utils(1), ffmpeg-scaler(1), ffmpeg-resampler(1),
|
||||||
ffmpeg-codecs(1), ffmpeg-bitstream-filters(1), ffmpeg-formats(1),
|
ffmpeg-codecs(1), ffmpeg-bitstream-filters(1), ffmpeg-formats(1),
|
||||||
ffmpeg-devices(1), ffmpeg-protocols(1), ffmpeg-filters(1)
|
ffmpeg-devices(1), ffmpeg-protocols(1), ffmpeg-filters(1)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
@chapter Synopsis
|
@chapter Synopsis
|
||||||
|
|
||||||
ffprobe [@var{options}] [@file{input_url}]
|
ffprobe [@var{options}] [@file{input_file}]
|
||||||
|
|
||||||
@chapter Description
|
@chapter Description
|
||||||
@c man begin DESCRIPTION
|
@c man begin DESCRIPTION
|
||||||
@@ -24,8 +24,8 @@ For example it can be used to check the format of the container used
|
|||||||
by a multimedia stream and the format and type of each media stream
|
by a multimedia stream and the format and type of each media stream
|
||||||
contained in it.
|
contained in it.
|
||||||
|
|
||||||
If a url is specified in input, ffprobe will try to open and
|
If a filename is specified in input, ffprobe will try to open and
|
||||||
probe the url content. If the url cannot be opened or recognized as
|
probe the file content. If the file cannot be opened or recognized as
|
||||||
a multimedia file, a positive exit code is returned.
|
a multimedia file, a positive exit code is returned.
|
||||||
|
|
||||||
ffprobe may be employed both as a standalone application or in
|
ffprobe may be employed both as a standalone application or in
|
||||||
@@ -208,13 +208,6 @@ multimedia stream.
|
|||||||
The information for each single frame is printed within a dedicated
|
The information for each single frame is printed within a dedicated
|
||||||
section with name "FRAME" or "SUBTITLE".
|
section with name "FRAME" or "SUBTITLE".
|
||||||
|
|
||||||
@item -show_log @var{loglevel}
|
|
||||||
Show logging information from the decoder about each frame according to
|
|
||||||
the value set in @var{loglevel}, (see @code{-loglevel}). This option requires @code{-show_frames}.
|
|
||||||
|
|
||||||
The information for each log message is printed within a dedicated
|
|
||||||
section with name "LOG".
|
|
||||||
|
|
||||||
@item -show_streams
|
@item -show_streams
|
||||||
Show information about each media stream contained in the input
|
Show information about each media stream contained in the input
|
||||||
multimedia stream.
|
multimedia stream.
|
||||||
@@ -252,7 +245,7 @@ continue reading from that.
|
|||||||
Each interval is specified by two optional parts, separated by "%".
|
Each interval is specified by two optional parts, separated by "%".
|
||||||
|
|
||||||
The first part specifies the interval start position. It is
|
The first part specifies the interval start position. It is
|
||||||
interpreted as an absolute position, or as a relative offset from the
|
interpreted as an abolute position, or as a relative offset from the
|
||||||
current position if it is preceded by the "+" character. If this first
|
current position if it is preceded by the "+" character. If this first
|
||||||
part is not specified, no seeking will be performed when reading this
|
part is not specified, no seeking will be performed when reading this
|
||||||
interval.
|
interval.
|
||||||
@@ -335,18 +328,12 @@ Show information about all pixel formats supported by FFmpeg.
|
|||||||
Pixel format information for each format is printed within a section
|
Pixel format information for each format is printed within a section
|
||||||
with name "PIXEL_FORMAT".
|
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
|
@item -bitexact
|
||||||
Force bitexact output, useful to produce output which is not dependent
|
Force bitexact output, useful to produce output which is not dependent
|
||||||
on the specific build.
|
on the specific build.
|
||||||
|
|
||||||
@item -i @var{input_url}
|
@item -i @var{input_file}
|
||||||
Read @var{input_url}.
|
Read @var{input_file}.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
@c man end
|
@c man end
|
||||||
@@ -431,7 +418,7 @@ The @code{csv} writer is equivalent to @code{compact}, but supports
|
|||||||
different defaults.
|
different defaults.
|
||||||
|
|
||||||
Each section is printed on a single line.
|
Each section is printed on a single line.
|
||||||
If no option is specified, the output has the form:
|
If no option is specifid, the output has the form:
|
||||||
@example
|
@example
|
||||||
section|key1=val1| ... |keyN=valN
|
section|key1=val1| ... |keyN=valN
|
||||||
@end example
|
@end example
|
||||||
@@ -477,7 +464,7 @@ Perform no escaping.
|
|||||||
@end table
|
@end table
|
||||||
|
|
||||||
@item print_section, p
|
@item print_section, p
|
||||||
Print the section name at the beginning of each line if the value is
|
Print the section name at the begin of each line if the value is
|
||||||
@code{1}, disable it with value set to @code{0}. Default value is
|
@code{1}, disable it with value set to @code{0}. Default value is
|
||||||
@code{1}.
|
@code{1}.
|
||||||
|
|
||||||
@@ -590,14 +577,14 @@ value is 0.
|
|||||||
This is required for generating an XML file which can be validated
|
This is required for generating an XML file which can be validated
|
||||||
through an XSD file.
|
through an XSD file.
|
||||||
|
|
||||||
@item xsd_strict, x
|
@item xsd_compliant, x
|
||||||
If set to 1 perform more checks for ensuring that the output is XSD
|
If set to 1 perform more checks for ensuring that the output is XSD
|
||||||
compliant. Default value is 0.
|
compliant. Default value is 0.
|
||||||
This option automatically sets @option{fully_qualified} to 1.
|
This option automatically sets @option{fully_qualified} to 1.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
For more information about the XML format, see
|
For more information about the XML format, see
|
||||||
@url{https://www.w3.org/XML/}.
|
@url{http://www.w3.org/XML/}.
|
||||||
@c man end WRITERS
|
@c man end WRITERS
|
||||||
|
|
||||||
@chapter Timecode
|
@chapter Timecode
|
||||||
@@ -648,7 +635,6 @@ DV, GXF and AVI timecodes are available in format metadata
|
|||||||
@ifset config-avfilter
|
@ifset config-avfilter
|
||||||
@include filters.texi
|
@include filters.texi
|
||||||
@end ifset
|
@end ifset
|
||||||
@include general_contents.texi
|
|
||||||
@end ifset
|
@end ifset
|
||||||
|
|
||||||
@chapter See Also
|
@chapter See Also
|
||||||
@@ -660,7 +646,7 @@ DV, GXF and AVI timecodes are available in format metadata
|
|||||||
@ifset config-not-all
|
@ifset config-not-all
|
||||||
@url{ffprobe-all.html,ffprobe-all},
|
@url{ffprobe-all.html,ffprobe-all},
|
||||||
@end ifset
|
@end ifset
|
||||||
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay},
|
@url{ffmpeg.html,ffmpeg}, @url{ffplay.html,ffplay}, @url{ffserver.html,ffserver},
|
||||||
@url{ffmpeg-utils.html,ffmpeg-utils},
|
@url{ffmpeg-utils.html,ffmpeg-utils},
|
||||||
@url{ffmpeg-scaler.html,ffmpeg-scaler},
|
@url{ffmpeg-scaler.html,ffmpeg-scaler},
|
||||||
@url{ffmpeg-resampler.html,ffmpeg-resampler},
|
@url{ffmpeg-resampler.html,ffmpeg-resampler},
|
||||||
@@ -679,7 +665,7 @@ ffprobe(1),
|
|||||||
@ifset config-not-all
|
@ifset config-not-all
|
||||||
ffprobe-all(1),
|
ffprobe-all(1),
|
||||||
@end ifset
|
@end ifset
|
||||||
ffmpeg(1), ffplay(1),
|
ffmpeg(1), ffplay(1), ffserver(1),
|
||||||
ffmpeg-utils(1), ffmpeg-scaler(1), ffmpeg-resampler(1),
|
ffmpeg-utils(1), ffmpeg-scaler(1), ffmpeg-resampler(1),
|
||||||
ffmpeg-codecs(1), ffmpeg-bitstream-filters(1), ffmpeg-formats(1),
|
ffmpeg-codecs(1), ffmpeg-bitstream-filters(1), ffmpeg-formats(1),
|
||||||
ffmpeg-devices(1), ffmpeg-protocols(1), ffmpeg-filters(1)
|
ffmpeg-devices(1), ffmpeg-protocols(1), ffmpeg-filters(1)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user