mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-07 07:19:59 +01:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35a7b73590 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1 +0,0 @@
|
|||||||
*.pnm -diff -text
|
|
||||||
58
.gitignore
vendored
58
.gitignore
vendored
@@ -1,6 +1,5 @@
|
|||||||
*.a
|
*.a
|
||||||
*.o
|
*.o
|
||||||
*.o.*
|
|
||||||
*.d
|
*.d
|
||||||
*.def
|
*.def
|
||||||
*.dll
|
*.dll
|
||||||
@@ -16,11 +15,10 @@
|
|||||||
*.pdb
|
*.pdb
|
||||||
*.so
|
*.so
|
||||||
*.so.*
|
*.so.*
|
||||||
*.swp
|
|
||||||
*.ver
|
*.ver
|
||||||
|
*-example
|
||||||
|
*-test
|
||||||
*_g
|
*_g
|
||||||
\#*
|
|
||||||
.\#*
|
|
||||||
/.config
|
/.config
|
||||||
/.version
|
/.version
|
||||||
/ffmpeg
|
/ffmpeg
|
||||||
@@ -29,7 +27,53 @@
|
|||||||
/ffserver
|
/ffserver
|
||||||
/config.*
|
/config.*
|
||||||
/coverage.info
|
/coverage.info
|
||||||
/avversion.h
|
/version.h
|
||||||
|
/doc/*.1
|
||||||
|
/doc/*.3
|
||||||
|
/doc/*.html
|
||||||
|
/doc/*.pod
|
||||||
|
/doc/config.texi
|
||||||
|
/doc/avoptions_codec.texi
|
||||||
|
/doc/avoptions_format.texi
|
||||||
|
/doc/examples/decoding_encoding
|
||||||
|
/doc/examples/demuxing
|
||||||
|
/doc/examples/filtering_audio
|
||||||
|
/doc/examples/filtering_video
|
||||||
|
/doc/examples/metadata
|
||||||
|
/doc/examples/muxing
|
||||||
|
/doc/examples/pc-uninstalled
|
||||||
|
/doc/examples/resampling_audio
|
||||||
|
/doc/examples/scaling_video
|
||||||
|
/doc/fate.txt
|
||||||
|
/doc/doxy/html/
|
||||||
|
/doc/print_options
|
||||||
/lcov/
|
/lcov/
|
||||||
/src
|
/libavcodec/*_tablegen
|
||||||
/mapfile
|
/libavcodec/*_tables.c
|
||||||
|
/libavcodec/*_tables.h
|
||||||
|
/libavutil/avconfig.h
|
||||||
|
/tests/audiogen
|
||||||
|
/tests/base64
|
||||||
|
/tests/data/
|
||||||
|
/tests/rotozoom
|
||||||
|
/tests/tiny_psnr
|
||||||
|
/tests/tiny_ssim
|
||||||
|
/tests/videogen
|
||||||
|
/tests/vsynth1/
|
||||||
|
/tools/aviocat
|
||||||
|
/tools/ffbisect
|
||||||
|
/tools/bisect.need
|
||||||
|
/tools/crypto_bench
|
||||||
|
/tools/cws2fws
|
||||||
|
/tools/fourcc2pixfmt
|
||||||
|
/tools/ffescape
|
||||||
|
/tools/ffeval
|
||||||
|
/tools/ffhash
|
||||||
|
/tools/graph2dot
|
||||||
|
/tools/ismindex
|
||||||
|
/tools/pktdumper
|
||||||
|
/tools/probetest
|
||||||
|
/tools/qt-faststart
|
||||||
|
/tools/trasher
|
||||||
|
/tools/seek_print
|
||||||
|
/tools/zmqsend
|
||||||
|
|||||||
26
.travis.yml
26
.travis.yml
@@ -1,26 +0,0 @@
|
|||||||
language: c
|
|
||||||
sudo: false
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
- osx
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- yasm
|
|
||||||
- diffutils
|
|
||||||
compiler:
|
|
||||||
- clang
|
|
||||||
- gcc
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- ffmpeg-samples
|
|
||||||
before_install:
|
|
||||||
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update --all; fi
|
|
||||||
install:
|
|
||||||
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install yasm; fi
|
|
||||||
script:
|
|
||||||
- mkdir -p ffmpeg-samples
|
|
||||||
- ./configure --samples=ffmpeg-samples --cc=$CC
|
|
||||||
- make -j 8
|
|
||||||
- make fate-rsync
|
|
||||||
- make check -j 8
|
|
||||||
@@ -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.
|
|
||||||
464
Changelog
464
Changelog
@@ -1,447 +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 3.2.1:
|
version <next>
|
||||||
- avcodec/aac_adtstoasc_bsf: validate and forward extradata if the stream is already ASC
|
|
||||||
- mss2: only use error correction for matching block counts
|
|
||||||
- softfloat: decrease MIN_EXP to cover full float range
|
|
||||||
- libopusdec: default to stereo for invalid number of channels
|
|
||||||
- flvdec: require need_context_update when changing codec id
|
|
||||||
- pgssubdec: only set w/h/linesize when allocating data
|
|
||||||
- sbgdec: prevent NULL pointer access
|
|
||||||
- rmdec: validate block alignment
|
|
||||||
- smacker: limit recursion depth of smacker_decode_bigtree
|
|
||||||
- mxfdec: fix NULL pointer dereference in mxf_read_packet_old
|
|
||||||
- ffmdec: validate codec parameters
|
|
||||||
- avformat/mpeg: Adjust vid probe threshold to correct mis-detection
|
|
||||||
- avcodec/ass_split: Change order of operations in ass_split_section()
|
|
||||||
- avcodec/rawdec: check for side data before checking its size
|
|
||||||
- avcodec/avpacket: fix leak on realloc in av_packet_add_side_data()
|
|
||||||
- avformat/apngenc: use the stream parameters extradata if available
|
|
||||||
- Revert "apngdec: use side data to pass extradata to the decoder"
|
|
||||||
- ffprobe: fix crash in case -of is specified with an empty string
|
|
||||||
- libavcodec/exr : fix channel size calculation for uint32 channel
|
|
||||||
- exr: fix out-of-bounds read
|
|
||||||
- libschroedingerdec: fix leaking of framewithpts
|
|
||||||
- libschroedingerdec: don't produce empty frames
|
|
||||||
- dds: limit 4 bpp handling to AV_PIX_FMT_PAL8
|
|
||||||
- mlz: limit next_code to data buffer size
|
|
||||||
- softfloat: handle -INT_MAX correctly
|
|
||||||
- filmstripdec: correctly check image dimensions
|
|
||||||
- pnmdec: make sure v is capped by maxval
|
|
||||||
- smvjpegdec: make sure cur_frame is not negative
|
|
||||||
- icodec: correctly check avio_read return value
|
|
||||||
- icodec: fix leaking pkt on error
|
|
||||||
- dvbsubdec: fix division by zero in compute_default_clut
|
|
||||||
- proresdec_lgpl: explicitly check coff[3] against slice_data_size
|
|
||||||
- escape124: reject codebook size 0
|
|
||||||
- mpegts: prevent division by zero
|
|
||||||
- matroskadec: fix NULL pointer dereference in webm_dash_manifest_read_header
|
|
||||||
- mpegaudio_parser: don't return AVERROR_PATCHWELCOME
|
|
||||||
- mxfdec: fix NULL pointer dereference
|
|
||||||
- lzf: update pointer p after realloc
|
|
||||||
- diracdec: check return code of get_buffer_with_edge
|
|
||||||
- diracdec: clear slice_params_num_buf on allocation failure
|
|
||||||
- diracdec: use correct buffer for slice_params_buf realloc
|
|
||||||
- ppc: pixblockdsp: do unaligned block accesses correctly again
|
|
||||||
- avformat: close parser if codec changed
|
|
||||||
- fate: add streamcopy test for apng
|
|
||||||
- apngdec: use side data to pass extradata to the decoder
|
|
||||||
- mov: immediately return from mov_fix_index without old index entries
|
|
||||||
- interplayacm: increase bitstream buffer size by AV_INPUT_BUFFER_PADDING_SIZE
|
|
||||||
- interplayacm: validate number of channels
|
|
||||||
- interplayacm: check for too large b
|
|
||||||
- doc: fix spelling errors
|
|
||||||
- configure: make sure LTO does not optimize out the test functions
|
|
||||||
- fate: add apng encoding/muxing test
|
|
||||||
- apng: use side data to pass extradata to muxer
|
|
||||||
- avcodec/mpeg4videodec: Workaround interlaced mpeg4 edge MC bug
|
|
||||||
- avcodec/mpegvideo: Fix edge emu buffer overlap with interlaced mpeg4
|
|
||||||
- avcodec/rv40: Test remaining space in loop of get_dimension()
|
|
||||||
- avcodec/ituh263dec: Avoid spending a long time in slice sync
|
|
||||||
- avcodec/movtextdec: Add error message for tsmb_size check
|
|
||||||
- avcodec/movtextdec: Fix tsmb_size check==0 check
|
|
||||||
- avcodec/movtextdec: Fix potential integer overflow
|
|
||||||
- ffmpeg: Fix bsf corrupting merged side data
|
|
||||||
- avcodec/sunrast: Fix input buffer pointer check
|
|
||||||
- avcodec/tscc: Check side data size before use
|
|
||||||
- avcodec/rscc: Fix constant
|
|
||||||
- avcodec/rawdec: Check side data size before use
|
|
||||||
- avcodec/rscc: Check side data size before use
|
|
||||||
- avcodec/msvideo1: Check side data size before use
|
|
||||||
- avcodec/qpeg: Check side data size before use
|
|
||||||
- avcodec/qtrle: Check side data size before use
|
|
||||||
- avcodec/msrle: Check side data size before use
|
|
||||||
- avcodec/kmvc: Check side data size before use
|
|
||||||
- avcodec/idcinvideo: Check side data size before use
|
|
||||||
- avcodec/cinepak: Check side data size before use
|
|
||||||
- avcodec/8bps: Check side data size before use
|
|
||||||
- avformat/flvdec: Fix regression losing streams
|
|
||||||
- avformat/hls: Add missing error check for avcodec_parameters_copy()
|
|
||||||
- avformat/hls: Fix probing mpegts audio streams that use probing
|
|
||||||
- avformat/hls: Factor copying stream info to a separate function
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
version 3.1:
|
|
||||||
- DXVA2-accelerated HEVC Main10 decoding
|
|
||||||
- fieldhint filter
|
|
||||||
- loop video filter and aloop audio filter
|
|
||||||
- Bob Weaver deinterlacing filter
|
|
||||||
- firequalizer filter
|
|
||||||
- datascope filter
|
|
||||||
- bench and abench filters
|
|
||||||
- ciescope filter
|
|
||||||
- protocol blacklisting API
|
|
||||||
- MediaCodec H264 decoding
|
|
||||||
- VC-2 HQ RTP payload format (draft v1) depacketizer and packetizer
|
|
||||||
- VP9 RTP payload format (draft v2) packetizer
|
|
||||||
- AudioToolbox audio decoders
|
|
||||||
- AudioToolbox audio encoders
|
|
||||||
- coreimage filter (GPU based image filtering on OSX)
|
|
||||||
- libdcadec removed
|
|
||||||
- bitstream filter for extracting DTS core
|
|
||||||
- ADPCM IMA DAT4 decoder
|
|
||||||
- musx demuxer
|
|
||||||
- aix demuxer
|
|
||||||
- remap filter
|
|
||||||
- hash and framehash muxers
|
|
||||||
- colorspace filter
|
|
||||||
- hdcd filter
|
|
||||||
- readvitc filter
|
|
||||||
- VAAPI-accelerated format conversion and scaling
|
|
||||||
- libnpp/CUDA-accelerated format conversion and scaling
|
|
||||||
- Duck TrueMotion 2.0 Real Time decoder
|
|
||||||
- Wideband Single-bit Data (WSD) demuxer
|
|
||||||
- VAAPI-accelerated H.264/HEVC/MJPEG encoding
|
|
||||||
- DTS Express (LBR) decoder
|
|
||||||
- Generic OpenMAX IL encoder with support for Raspberry Pi
|
|
||||||
- IFF ANIM demuxer & decoder
|
|
||||||
- Direct Stream Transfer (DST) decoder
|
|
||||||
- loudnorm filter
|
|
||||||
- MTAF demuxer and decoder
|
|
||||||
- MagicYUV decoder
|
|
||||||
- OpenExr improvements (tile data and B44/B44A support)
|
|
||||||
- BitJazz SheerVideo decoder
|
|
||||||
- CUDA CUVID H264/HEVC decoder
|
|
||||||
- 10-bit depth support in native utvideo decoder
|
|
||||||
- libutvideo wrapper removed
|
|
||||||
- YUY2 Lossless Codec decoder
|
|
||||||
- VideoToolbox H.264 encoder
|
|
||||||
|
|
||||||
|
|
||||||
version 3.0:
|
|
||||||
- Common Encryption (CENC) MP4 encoding and decoding support
|
|
||||||
- DXV decoding
|
|
||||||
- extrastereo filter
|
|
||||||
- ocr filter
|
|
||||||
- alimiter filter
|
|
||||||
- stereowiden filter
|
|
||||||
- stereotools filter
|
|
||||||
- rubberband filter
|
|
||||||
- tremolo filter
|
|
||||||
- agate filter
|
|
||||||
- chromakey filter
|
|
||||||
- maskedmerge filter
|
|
||||||
- Screenpresso SPV1 decoding
|
|
||||||
- chromaprint fingerprinting muxer
|
|
||||||
- ffplay dynamic volume control
|
|
||||||
- displace filter
|
|
||||||
- selectivecolor filter
|
|
||||||
- extensive native AAC encoder improvements and removal of experimental flag
|
|
||||||
- ADPCM PSX decoder
|
|
||||||
- 3dostr, dcstr, fsb, genh, vag, xvag, ads, msf, svag & vpk demuxer
|
|
||||||
- zscale filter
|
|
||||||
- wve demuxer
|
|
||||||
- zero-copy Intel QSV transcoding in ffmpeg
|
|
||||||
- shuffleframes filter
|
|
||||||
- SDX2 DPCM decoder
|
|
||||||
- vibrato filter
|
|
||||||
- innoHeim/Rsupport Screen Capture Codec decoder
|
|
||||||
- ADPCM AICA decoder
|
|
||||||
- Interplay ACM demuxer and audio decoder
|
|
||||||
- XMA1 & XMA2 decoder
|
|
||||||
- realtime filter
|
|
||||||
- anoisesrc audio filter source
|
|
||||||
- IVR demuxer
|
|
||||||
- compensationdelay filter
|
|
||||||
- acompressor filter
|
|
||||||
- support encoding 16-bit RLE SGI images
|
|
||||||
- apulsator filter
|
|
||||||
- sidechaingate audio filter
|
|
||||||
- mipsdspr1 option has been renamed to mipsdsp
|
|
||||||
- aemphasis filter
|
|
||||||
- mips32r5 option has been removed
|
|
||||||
- mips64r6 option has been removed
|
|
||||||
- DXVA2-accelerated VP9 decoding
|
|
||||||
- SOFAlizer: virtual binaural acoustics filter
|
|
||||||
- VAAPI VP9 hwaccel
|
|
||||||
- audio high-order multiband parametric equalizer
|
|
||||||
- automatic bitstream filtering
|
|
||||||
- showspectrumpic filter
|
|
||||||
- libstagefright support removed
|
|
||||||
- spectrumsynth filter
|
|
||||||
- ahistogram filter
|
|
||||||
- only seek with the right mouse button in ffplay
|
|
||||||
- toggle full screen when double-clicking with the left mouse button in ffplay
|
|
||||||
- afftfilt filter
|
|
||||||
- convolution filter
|
|
||||||
- libquvi support removed
|
|
||||||
- support for dvaudio in wav and avi
|
|
||||||
- libaacplus and libvo-aacenc support removed
|
|
||||||
- Cineform HD decoder
|
|
||||||
- new DCA decoder with full support for DTS-HD extensions
|
|
||||||
- significant performance improvements in Windows Television (WTV) demuxer
|
|
||||||
- nnedi deinterlacer
|
|
||||||
- streamselect video and astreamselect audio filter
|
|
||||||
- swaprect filter
|
|
||||||
- metadata video and ametadata audio filter
|
|
||||||
- SMPTE VC-2 HQ profile support for the Dirac decoder
|
|
||||||
- SMPTE VC-2 native encoder supporting the HQ profile
|
|
||||||
|
|
||||||
|
|
||||||
version 2.8:
|
|
||||||
- colorkey video filter
|
|
||||||
- BFSTM/BCSTM demuxer
|
|
||||||
- little-endian ADPCM_THP decoder
|
|
||||||
- Hap decoder and encoder
|
|
||||||
- DirectDraw Surface image/texture decoder
|
|
||||||
- ssim filter
|
|
||||||
- optional new ASF demuxer
|
|
||||||
- showvolume filter
|
|
||||||
- Many improvements to the JPEG 2000 decoder
|
|
||||||
- Go2Meeting decoding support
|
|
||||||
- adrawgraph audio and drawgraph video filter
|
|
||||||
- removegrain video filter
|
|
||||||
- Intel QSV-accelerated MPEG-2 video and HEVC encoding
|
|
||||||
- Intel QSV-accelerated MPEG-2 video and HEVC decoding
|
|
||||||
- Intel QSV-accelerated VC-1 video decoding
|
|
||||||
- libkvazaar HEVC encoder
|
|
||||||
- erosion, dilation, deflate and inflate video filters
|
|
||||||
- Dynamic Audio Normalizer as dynaudnorm filter
|
|
||||||
- Reverse video and areverse audio filter
|
|
||||||
- Random filter
|
|
||||||
- deband filter
|
|
||||||
- AAC fixed-point decoding
|
|
||||||
- sidechaincompress audio filter
|
|
||||||
- bitstream filter for converting HEVC from MP4 to Annex B
|
|
||||||
- acrossfade audio filter
|
|
||||||
- allyuv and allrgb video sources
|
|
||||||
- atadenoise video filter
|
|
||||||
- OS X VideoToolbox support
|
|
||||||
- aphasemeter filter
|
|
||||||
- showfreqs filter
|
|
||||||
- vectorscope filter
|
|
||||||
- waveform filter
|
|
||||||
- hstack and vstack filter
|
|
||||||
- Support DNx100 (1440x1080@8)
|
|
||||||
- VAAPI hevc hwaccel
|
|
||||||
- VDPAU hevc hwaccel
|
|
||||||
- framerate filter
|
|
||||||
- Switched default encoders for webm to VP9 and Opus
|
|
||||||
- Removed experimental flag from the JPEG 2000 encoder
|
|
||||||
|
|
||||||
|
|
||||||
version 2.7:
|
|
||||||
- FFT video filter
|
|
||||||
- TDSC decoder
|
|
||||||
- DTS lossless extension (XLL) decoding (not lossless, disabled by default)
|
|
||||||
- showwavespic filter
|
|
||||||
- DTS decoding through libdcadec
|
|
||||||
- Drop support for nvenc API before 5.0
|
|
||||||
- nvenc HEVC encoder
|
|
||||||
- Detelecine filter
|
|
||||||
- Intel QSV-accelerated H.264 encoding
|
|
||||||
- MMAL-accelerated H.264 decoding
|
|
||||||
- basic APNG encoder and muxer with default extension "apng"
|
|
||||||
- unpack DivX-style packed B-frames in MPEG-4 bitstream filter
|
|
||||||
- WebM Live Chunk Muxer
|
|
||||||
- nvenc level and tier options
|
|
||||||
- chorus filter
|
|
||||||
- Canopus HQ/HQA decoder
|
|
||||||
- Automatically rotate videos based on metadata in ffmpeg
|
|
||||||
- improved Quickdraw compatibility
|
|
||||||
- VP9 high bit-depth and extended colorspaces decoding support
|
|
||||||
- WebPAnimEncoder API when available for encoding and muxing WebP
|
|
||||||
- Direct3D11-accelerated decoding
|
|
||||||
- Support Secure Transport
|
|
||||||
- Multipart JPEG demuxer
|
|
||||||
|
|
||||||
|
|
||||||
version 2.6:
|
|
||||||
- nvenc encoder
|
|
||||||
- 10bit spp filter
|
|
||||||
- colorlevels filter
|
|
||||||
- RIFX format for *.wav files
|
|
||||||
- RTP/mpegts muxer
|
|
||||||
- non continuous cache protocol support
|
|
||||||
- tblend filter
|
|
||||||
- cropdetect support for non 8bpp, absolute (if limit >= 1) and relative (if limit < 1.0) threshold
|
|
||||||
- Camellia symmetric block cipher
|
|
||||||
- OpenH264 encoder wrapper
|
|
||||||
- VOC seeking support
|
|
||||||
- Closed caption Decoder
|
|
||||||
- fspp, uspp, pp7 MPlayer postprocessing filters ported to native filters
|
|
||||||
- showpalette filter
|
|
||||||
- Twofish symmetric block cipher
|
|
||||||
- Support DNx100 (960x720@8)
|
|
||||||
- eq2 filter ported from libmpcodecs as eq filter
|
|
||||||
- removed libmpcodecs
|
|
||||||
- Changed default DNxHD colour range in QuickTime .mov derivatives to mpeg range
|
|
||||||
- ported softpulldown filter from libmpcodecs as repeatfields filter
|
|
||||||
- dcshift filter
|
|
||||||
- RTP depacketizer for loss tolerant payload format for MP3 audio (RFC 5219)
|
|
||||||
- RTP depacketizer for AC3 payload format (RFC 4184)
|
|
||||||
- palettegen and paletteuse filters
|
|
||||||
- VP9 RTP payload format (draft 0) experimental depacketizer
|
|
||||||
- RTP depacketizer for DV (RFC 6469)
|
|
||||||
- DXVA2-accelerated HEVC decoding
|
|
||||||
- AAC ELD 480 decoding
|
|
||||||
- Intel QSV-accelerated H.264 decoding
|
|
||||||
- DSS SP decoder and DSS demuxer
|
|
||||||
- Fix stsd atom corruption in DNxHD QuickTimes
|
|
||||||
- Canopus HQX decoder
|
|
||||||
- RTP depacketization of T.140 text (RFC 4103)
|
|
||||||
- Port MIPS optimizations to 64-bit
|
|
||||||
|
|
||||||
|
|
||||||
version 2.5:
|
|
||||||
- HEVC/H.265 RTP payload format (draft v6) packetizer
|
|
||||||
- SUP/PGS subtitle demuxer
|
|
||||||
- ffprobe -show_pixel_formats option
|
|
||||||
- CAST128 symmetric block cipher, ECB mode
|
|
||||||
- STL subtitle demuxer and decoder
|
|
||||||
- libutvideo YUV 4:2:2 10bit support
|
|
||||||
- XCB-based screen-grabber
|
|
||||||
- UDP-Lite support (RFC 3828)
|
|
||||||
- xBR scaling filter
|
|
||||||
- AVFoundation screen capturing support
|
|
||||||
- ffserver supports codec private options
|
|
||||||
- creating DASH compatible fragmented MP4, MPEG-DASH segmenting muxer
|
|
||||||
- WebP muxer with animated WebP support
|
|
||||||
- zygoaudio decoding support
|
|
||||||
- APNG demuxer
|
|
||||||
- postproc visualization support
|
|
||||||
|
|
||||||
|
|
||||||
version 2.4:
|
|
||||||
- Icecast protocol
|
|
||||||
- ported lenscorrection filter from frei0r filter
|
|
||||||
- large optimizations in dctdnoiz to make it usable
|
|
||||||
- ICY metadata are now requested by default with the HTTP protocol
|
|
||||||
- support for using metadata in stream specifiers in fftools
|
|
||||||
- LZMA compression support in TIFF decoder
|
|
||||||
- H.261 RTP payload format (RFC 4587) depacketizer and experimental packetizer
|
|
||||||
- HEVC/H.265 RTP payload format (draft v6) depacketizer
|
|
||||||
- added codecview filter to visualize information exported by some codecs
|
|
||||||
- Matroska 3D support thorugh side data
|
|
||||||
- HTML generation using texi2html is deprecated in favor of makeinfo/texi2any
|
|
||||||
- silenceremove filter
|
|
||||||
|
|
||||||
|
|
||||||
version 2.3:
|
|
||||||
- AC3 fixed-point decoding
|
|
||||||
- shuffleplanes filter
|
|
||||||
- subfile protocol
|
|
||||||
- Phantom Cine demuxer
|
|
||||||
- replaygain data export
|
|
||||||
- VP7 video decoder
|
|
||||||
- Alias PIX image encoder and decoder
|
|
||||||
- Improvements to the BRender PIX image decoder
|
|
||||||
- Improvements to the XBM decoder
|
|
||||||
- QTKit input device
|
|
||||||
- improvements to OpenEXR image decoder
|
|
||||||
- support decoding 16-bit RLE SGI images
|
|
||||||
- GDI screen grabbing for Windows
|
|
||||||
- alternative rendition support for HTTP Live Streaming
|
|
||||||
- AVFoundation input device
|
|
||||||
- Direct Stream Digital (DSD) decoder
|
|
||||||
- Magic Lantern Video (MLV) demuxer
|
|
||||||
- On2 AVC (Audio for Video) decoder
|
|
||||||
- support for decoding through DXVA2 in ffmpeg
|
|
||||||
- libbs2b-based stereo-to-binaural audio filter
|
|
||||||
- libx264 reference frames count limiting depending on level
|
|
||||||
- native Opus decoder
|
|
||||||
- display matrix export and rotation API
|
|
||||||
- WebVTT encoder
|
|
||||||
- showcqt multimedia filter
|
|
||||||
- zoompan filter
|
|
||||||
- signalstats filter
|
|
||||||
- hqx filter (hq2x, hq3x, hq4x)
|
|
||||||
- flanger filter
|
|
||||||
- Image format auto-detection
|
|
||||||
- LRC demuxer and muxer
|
|
||||||
- Samba protocol (via libsmbclient)
|
|
||||||
- WebM DASH Manifest muxer
|
|
||||||
- libfribidi support in drawtext
|
|
||||||
|
|
||||||
|
|
||||||
version 2.2:
|
|
||||||
|
|
||||||
- HNM version 4 demuxer and video decoder
|
|
||||||
- Live HDS muxer
|
|
||||||
- setsar/setdar filters now support variables in ratio expressions
|
|
||||||
- elbg filter
|
|
||||||
- string validation in ffprobe
|
|
||||||
- support for decoding through VDPAU in ffmpeg (the -hwaccel option)
|
|
||||||
- complete Voxware MetaSound decoder
|
|
||||||
- remove mp3_header_compress bitstream filter
|
|
||||||
- Windows resource files for shared libraries
|
|
||||||
- aeval filter
|
|
||||||
- stereoscopic 3d metadata handling
|
|
||||||
- WebP encoding via libwebp
|
|
||||||
- ATRAC3+ decoder
|
|
||||||
- VP8 in Ogg demuxing
|
|
||||||
- side & metadata support in NUT
|
|
||||||
- framepack filter
|
|
||||||
- XYZ12 rawvideo support in NUT
|
|
||||||
- Exif metadata support in WebP decoder
|
|
||||||
- OpenGL device
|
|
||||||
- Use metadata_header_padding to control padding in ID3 tags (currently used in
|
|
||||||
MP3, AIFF, and OMA files), FLAC header, and the AVI "junk" block.
|
|
||||||
- Mirillis FIC video decoder
|
|
||||||
- Support DNx444
|
|
||||||
- libx265 encoder
|
|
||||||
- dejudder filter
|
|
||||||
- Autodetect VDA like all other hardware accelerations
|
|
||||||
- aliases and defaults for Ogg subtypes (opus, spx)
|
|
||||||
|
|
||||||
|
|
||||||
version 2.1:
|
version 2.1:
|
||||||
@@ -486,8 +46,7 @@ version 2.1:
|
|||||||
- ReplayGain scanner
|
- ReplayGain scanner
|
||||||
- Enhanced Low Delay AAC (ER AAC ELD) decoding (no LD SBR support)
|
- Enhanced Low Delay AAC (ER AAC ELD) decoding (no LD SBR support)
|
||||||
- Linux framebuffer output device
|
- Linux framebuffer output device
|
||||||
- HEVC decoder
|
- HEVC decoder, raw HEVC demuxer, HEVC demuxing in TS, Matroska and MP4
|
||||||
- raw HEVC, HEVC in MOV/MP4, HEVC in Matroska, HEVC in MPEG-TS demuxing
|
|
||||||
- mergeplanes filter
|
- mergeplanes filter
|
||||||
|
|
||||||
|
|
||||||
@@ -503,7 +62,7 @@ version 2.0:
|
|||||||
- 10% faster aac encoding on x86 and MIPS
|
- 10% faster aac encoding on x86 and MIPS
|
||||||
- sine audio filter source
|
- sine audio filter source
|
||||||
- WebP demuxing and decoding support
|
- WebP demuxing and decoding support
|
||||||
- ffmpeg options -filter_script and -filter_complex_script, which allow a
|
- new ffmpeg options -filter_script and -filter_complex_script, which allow a
|
||||||
filtergraph description to be read from a file
|
filtergraph description to be read from a file
|
||||||
- OpenCL support
|
- OpenCL support
|
||||||
- audio phaser filter
|
- audio phaser filter
|
||||||
@@ -511,7 +70,7 @@ version 2.0:
|
|||||||
- libquvi demuxer
|
- libquvi demuxer
|
||||||
- uniform options syntax across all filters
|
- uniform options syntax across all filters
|
||||||
- telecine filter
|
- telecine filter
|
||||||
- interlace filter
|
- new interlace filter
|
||||||
- smptehdbars source
|
- smptehdbars source
|
||||||
- inverse telecine filters (fieldmatch and decimate)
|
- inverse telecine filters (fieldmatch and decimate)
|
||||||
- colorbalance filter
|
- colorbalance filter
|
||||||
@@ -629,7 +188,7 @@ version 1.1:
|
|||||||
- JSON captions for TED talks decoding support
|
- JSON captions for TED talks decoding support
|
||||||
- SOX Resampler support in libswresample
|
- SOX Resampler support in libswresample
|
||||||
- aselect filter
|
- aselect filter
|
||||||
- SGI RLE 8-bit / Silicon Graphics RLE 8-bit video decoder
|
- SGI RLE 8-bit decoder
|
||||||
- Silicon Graphics Motion Video Compressor 1 & 2 decoder
|
- Silicon Graphics Motion Video Compressor 1 & 2 decoder
|
||||||
- Silicon Graphics Movie demuxer
|
- Silicon Graphics Movie demuxer
|
||||||
- apad filter
|
- apad filter
|
||||||
@@ -673,9 +232,7 @@ version 1.0:
|
|||||||
- RTMPE protocol support
|
- RTMPE protocol support
|
||||||
- RTMPTE protocol support
|
- RTMPTE protocol support
|
||||||
- showwaves and showspectrum filter
|
- showwaves and showspectrum filter
|
||||||
- LucasArts SMUSH SANM playback support
|
- LucasArts SMUSH playback support
|
||||||
- LucasArts SMUSH VIMA audio decoder (ADPCM)
|
|
||||||
- LucasArts SMUSH demuxer
|
|
||||||
- SAMI, RealText and SubViewer demuxers and decoders
|
- SAMI, RealText and SubViewer demuxers and decoders
|
||||||
- Heart Of Darkness PAF playback support
|
- Heart Of Darkness PAF playback support
|
||||||
- iec61883 device
|
- iec61883 device
|
||||||
@@ -799,7 +356,6 @@ version 0.10:
|
|||||||
- ffwavesynth decoder
|
- ffwavesynth decoder
|
||||||
- aviocat tool
|
- aviocat tool
|
||||||
- ffeval tool
|
- ffeval tool
|
||||||
- support encoding and decoding 4-channel SGI images
|
|
||||||
|
|
||||||
|
|
||||||
version 0.9:
|
version 0.9:
|
||||||
@@ -848,7 +404,7 @@ easier to use. The changes are:
|
|||||||
all the stream in the first input file, except for the second audio
|
all the stream in the first input file, except for the second audio
|
||||||
stream'.
|
stream'.
|
||||||
* There is a new option -c (or -codec) for choosing the decoder/encoder to
|
* There is a new option -c (or -codec) for choosing the decoder/encoder to
|
||||||
use, which makes it possible to precisely specify target stream(s) consistently with
|
use, which allows to precisely specify target stream(s) consistently with
|
||||||
other options. E.g. -c:v lib264 sets the codec for all video streams, -c:a:0
|
other options. E.g. -c:v lib264 sets the codec for all video streams, -c:a:0
|
||||||
libvorbis sets the codec for the first audio stream and -c copy copies all
|
libvorbis sets the codec for the first audio stream and -c copy copies all
|
||||||
the streams without reencoding. Old -vcodec/-acodec/-scodec options are now
|
the streams without reencoding. Old -vcodec/-acodec/-scodec options are now
|
||||||
@@ -1037,8 +593,8 @@ version 0.8:
|
|||||||
- showinfo filter added
|
- showinfo filter added
|
||||||
- SMPTE 302M AES3 audio decoder
|
- SMPTE 302M AES3 audio decoder
|
||||||
- Apple Core Audio Format muxer
|
- Apple Core Audio Format muxer
|
||||||
- 9 bits and 10 bits per sample support in the H.264 decoder
|
- 9bit and 10bit per sample support in the H.264 decoder
|
||||||
- 9 bits and 10 bits FFV1 encoding / decoding
|
- 9bit and 10bit FFV1 encoding / decoding
|
||||||
- split filter added
|
- split filter added
|
||||||
- select filter added
|
- select filter added
|
||||||
- sdl output device added
|
- sdl output device added
|
||||||
@@ -1331,7 +887,7 @@ version 0.4.9-pre1:
|
|||||||
- rate distorted optimal lambda->qp support
|
- rate distorted optimal lambda->qp support
|
||||||
- AAC encoding with libfaac
|
- AAC encoding with libfaac
|
||||||
- Sunplus JPEG codec (SP5X) support
|
- Sunplus JPEG codec (SP5X) support
|
||||||
- use Lagrange multiplier instead of QP for ratecontrol
|
- use Lagrange multipler instead of QP for ratecontrol
|
||||||
- Theora/VP3 decoding support
|
- Theora/VP3 decoding support
|
||||||
- XA and ADX ADPCM codecs
|
- XA and ADX ADPCM codecs
|
||||||
- export MPEG-2 active display area / pan scan
|
- export MPEG-2 active display area / pan scan
|
||||||
|
|||||||
15
INSTALL
Normal file
15
INSTALL
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
1) Type './configure' to create the configuration. A list of configure
|
||||||
|
options is printed by running 'configure --help'.
|
||||||
|
|
||||||
|
'configure' can be launched from a directory different from the FFmpeg
|
||||||
|
sources to build the objects out of tree. To do this, use an absolute
|
||||||
|
path when launching 'configure', e.g. '/ffmpegdir/ffmpeg/configure'.
|
||||||
|
|
||||||
|
2) Then type 'make' to build FFmpeg. GNU Make 3.81 or later is required.
|
||||||
|
|
||||||
|
3) Type 'make install' to install all binaries and libraries you built.
|
||||||
|
|
||||||
|
NOTICE
|
||||||
|
|
||||||
|
- Non system dependencies (e.g. libx264, libvpx) are disabled by default.
|
||||||
17
INSTALL.md
17
INSTALL.md
@@ -1,17 +0,0 @@
|
|||||||
#Installing FFmpeg:
|
|
||||||
|
|
||||||
1. Type `./configure` to create the configuration. A list of configure
|
|
||||||
options is printed by running `configure --help`.
|
|
||||||
|
|
||||||
`configure` can be launched from a directory different from the FFmpeg
|
|
||||||
sources to build the objects out of tree. To do this, use an absolute
|
|
||||||
path when launching `configure`, e.g. `/ffmpegdir/ffmpeg/configure`.
|
|
||||||
|
|
||||||
2. Then type `make` to build FFmpeg. GNU Make 3.81 or later is required.
|
|
||||||
|
|
||||||
3. Type `make install` to install all binaries and libraries you built.
|
|
||||||
|
|
||||||
NOTICE
|
|
||||||
------
|
|
||||||
|
|
||||||
- Non system dependencies (e.g. libx264, libvpx) are disabled by default.
|
|
||||||
103
LICENSE
Normal file
103
LICENSE
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
FFmpeg:
|
||||||
|
|
||||||
|
Most files in FFmpeg are under the GNU Lesser General Public License version 2.1
|
||||||
|
or later (LGPL v2.1+). Read the file COPYING.LGPLv2.1 for details. Some other
|
||||||
|
files have MIT/X11/BSD-style licenses. In combination the LGPL v2.1+ applies to
|
||||||
|
FFmpeg.
|
||||||
|
|
||||||
|
Some optional parts of FFmpeg are licensed under the GNU General Public License
|
||||||
|
version 2 or later (GPL v2+). See the file COPYING.GPLv2 for details. None of
|
||||||
|
these parts are used by default, you have to explicitly pass --enable-gpl to
|
||||||
|
configure to activate them. In this case, FFmpeg's license changes to GPL v2+.
|
||||||
|
|
||||||
|
Specifically, the GPL parts of FFmpeg are
|
||||||
|
|
||||||
|
- libpostproc
|
||||||
|
- libmpcodecs
|
||||||
|
- optional x86 optimizations in the files
|
||||||
|
libavcodec/x86/idct_mmx.c
|
||||||
|
- libutvideo encoding/decoding wrappers in
|
||||||
|
libavcodec/libutvideo*.cpp
|
||||||
|
- the X11 grabber in libavdevice/x11grab.c
|
||||||
|
- the swresample test app in
|
||||||
|
libswresample/swresample-test.c
|
||||||
|
- the texi2pod.pl tool
|
||||||
|
- the following filters in libavfilter:
|
||||||
|
- f_ebur128.c
|
||||||
|
- vf_blackframe.c
|
||||||
|
- vf_boxblur.c
|
||||||
|
- vf_colormatrix.c
|
||||||
|
- vf_cropdetect.c
|
||||||
|
- vf_decimate.c
|
||||||
|
- vf_delogo.c
|
||||||
|
- vf_geq.c
|
||||||
|
- vf_histeq.c
|
||||||
|
- vf_hqdn3d.c
|
||||||
|
- vf_kerndeint.c
|
||||||
|
- vf_mcdeint.c
|
||||||
|
- vf_mp.c
|
||||||
|
- vf_owdenoise.c
|
||||||
|
- vf_perspective.c
|
||||||
|
- vf_phase.c
|
||||||
|
- vf_pp.c
|
||||||
|
- vf_pullup.c
|
||||||
|
- vf_sab.c
|
||||||
|
- vf_smartblur.c
|
||||||
|
- vf_spp.c
|
||||||
|
- vf_stereo3d.c
|
||||||
|
- vf_super2xsai.c
|
||||||
|
- vf_tinterlace.c
|
||||||
|
- vf_yadif.c
|
||||||
|
- vsrc_mptestsrc.c
|
||||||
|
|
||||||
|
Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then
|
||||||
|
the configure parameter --enable-version3 will activate this licensing option
|
||||||
|
for you. Read the file COPYING.LGPLv3 or, if you have enabled GPL parts,
|
||||||
|
COPYING.GPLv3 to learn the exact legal terms that apply in this case.
|
||||||
|
|
||||||
|
There are a handful of files under other licensing terms, namely:
|
||||||
|
|
||||||
|
* The files libavcodec/jfdctfst.c, libavcodec/jfdctint_template.c and
|
||||||
|
libavcodec/jrevdct.c are taken from libjpeg, see the top of the files for
|
||||||
|
licensing details. Specifically note that you must credit the IJG in the
|
||||||
|
documentation accompanying your program if you only distribute executables.
|
||||||
|
You must also indicate any changes including additions and deletions to
|
||||||
|
those three files in the documentation.
|
||||||
|
|
||||||
|
|
||||||
|
external libraries
|
||||||
|
==================
|
||||||
|
|
||||||
|
FFmpeg can be combined with a number of external libraries, which sometimes
|
||||||
|
affect the licensing of binaries resulting from the combination.
|
||||||
|
|
||||||
|
compatible libraries
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
The following libraries are under GPL:
|
||||||
|
- frei0r
|
||||||
|
- libcdio
|
||||||
|
- libutvideo
|
||||||
|
- libvidstab
|
||||||
|
- libx264
|
||||||
|
- libxavs
|
||||||
|
- libxvid
|
||||||
|
When combining them with FFmpeg, FFmpeg needs to be licensed as GPL as well by
|
||||||
|
passing --enable-gpl to configure.
|
||||||
|
|
||||||
|
The OpenCORE and VisualOn libraries are under the Apache License 2.0. That
|
||||||
|
license is incompatible with the LGPL v2.1 and the GPL v2, but not with
|
||||||
|
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.
|
||||||
|
|
||||||
|
incompatible libraries
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
The Fraunhofer AAC library, FAAC and aacplus are under licenses which
|
||||||
|
are incompatible with the GPLv2 and v3. We do not know for certain if their
|
||||||
|
licenses are compatible with the LGPL.
|
||||||
|
If you wish to enable these libraries, pass --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 unredistributeable.
|
||||||
122
LICENSE.md
122
LICENSE.md
@@ -1,122 +0,0 @@
|
|||||||
# License
|
|
||||||
|
|
||||||
Most files in FFmpeg are under the GNU Lesser General Public License version 2.1
|
|
||||||
or later (LGPL v2.1+). Read the file `COPYING.LGPLv2.1` for details. Some other
|
|
||||||
files have MIT/X11/BSD-style licenses. In combination the LGPL v2.1+ applies to
|
|
||||||
FFmpeg.
|
|
||||||
|
|
||||||
Some optional parts of FFmpeg are licensed under the GNU General Public License
|
|
||||||
version 2 or later (GPL v2+). See the file `COPYING.GPLv2` for details. None of
|
|
||||||
these parts are used by default, you have to explicitly pass `--enable-gpl` to
|
|
||||||
configure to activate them. In this case, FFmpeg's license changes to GPL v2+.
|
|
||||||
|
|
||||||
Specifically, the GPL parts of FFmpeg are:
|
|
||||||
|
|
||||||
- libpostproc
|
|
||||||
- optional x86 optimization in the files
|
|
||||||
- `libavcodec/x86/flac_dsp_gpl.asm`
|
|
||||||
- `libavcodec/x86/idct_mmx.c`
|
|
||||||
- `libavfilter/x86/vf_removegrain.asm`
|
|
||||||
- the X11 grabber in `libavdevice/x11grab.c`
|
|
||||||
- the following building and testing tools
|
|
||||||
- `compat/solaris/make_sunver.pl`
|
|
||||||
- `doc/t2h.pm`
|
|
||||||
- `doc/texi2pod.pl`
|
|
||||||
- `libswresample/swresample-test.c`
|
|
||||||
- `tests/checkasm/*`
|
|
||||||
- `tests/tiny_ssim.c`
|
|
||||||
- the following filters in libavfilter:
|
|
||||||
- `f_ebur128.c`
|
|
||||||
- `vf_blackframe.c`
|
|
||||||
- `vf_boxblur.c`
|
|
||||||
- `vf_colormatrix.c`
|
|
||||||
- `vf_cover_rect.c`
|
|
||||||
- `vf_cropdetect.c`
|
|
||||||
- `vf_delogo.c`
|
|
||||||
- `vf_eq.c`
|
|
||||||
- `vf_find_rect.c`
|
|
||||||
- `vf_fspp.c`
|
|
||||||
- `vf_geq.c`
|
|
||||||
- `vf_histeq.c`
|
|
||||||
- `vf_hqdn3d.c`
|
|
||||||
- `vf_interlace.c`
|
|
||||||
- `vf_kerndeint.c`
|
|
||||||
- `vf_mcdeint.c`
|
|
||||||
- `vf_mpdecimate.c`
|
|
||||||
- `vf_owdenoise.c`
|
|
||||||
- `vf_perspective.c`
|
|
||||||
- `vf_phase.c`
|
|
||||||
- `vf_pp.c`
|
|
||||||
- `vf_pp7.c`
|
|
||||||
- `vf_pullup.c`
|
|
||||||
- `vf_repeatfields.c`
|
|
||||||
- `vf_sab.c`
|
|
||||||
- `vf_smartblur.c`
|
|
||||||
- `vf_spp.c`
|
|
||||||
- `vf_stereo3d.c`
|
|
||||||
- `vf_super2xsai.c`
|
|
||||||
- `vf_tinterlace.c`
|
|
||||||
- `vf_uspp.c`
|
|
||||||
- `vsrc_mptestsrc.c`
|
|
||||||
|
|
||||||
Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then
|
|
||||||
the configure parameter `--enable-version3` will activate this licensing option
|
|
||||||
for you. Read the file `COPYING.LGPLv3` or, if you have enabled GPL parts,
|
|
||||||
`COPYING.GPLv3` to learn the exact legal terms that apply in this case.
|
|
||||||
|
|
||||||
There are a handful of files under other licensing terms, namely:
|
|
||||||
|
|
||||||
* The files `libavcodec/jfdctfst.c`, `libavcodec/jfdctint_template.c` and
|
|
||||||
`libavcodec/jrevdct.c` are taken from libjpeg, see the top of the files for
|
|
||||||
licensing details. Specifically note that you must credit the IJG in the
|
|
||||||
documentation accompanying your program if you only distribute executables.
|
|
||||||
You must also indicate any changes including additions and deletions to
|
|
||||||
those three files in the documentation.
|
|
||||||
* `tests/reference.pnm` is under the expat license.
|
|
||||||
|
|
||||||
|
|
||||||
## External libraries
|
|
||||||
|
|
||||||
FFmpeg can be combined with a number of external libraries, which sometimes
|
|
||||||
affect the licensing of binaries resulting from the combination.
|
|
||||||
|
|
||||||
### Compatible libraries
|
|
||||||
|
|
||||||
The following libraries are under GPL:
|
|
||||||
- frei0r
|
|
||||||
- libcdio
|
|
||||||
- librubberband
|
|
||||||
- libvidstab
|
|
||||||
- libx264
|
|
||||||
- libx265
|
|
||||||
- libxavs
|
|
||||||
- libxvid
|
|
||||||
|
|
||||||
When combining them with FFmpeg, FFmpeg needs to be licensed as GPL as well by
|
|
||||||
passing `--enable-gpl` to configure.
|
|
||||||
|
|
||||||
The OpenCORE and VisualOn libraries are under the Apache License 2.0. That
|
|
||||||
license is incompatible with the LGPL v2.1 and the GPL v2, but not with
|
|
||||||
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.
|
|
||||||
|
|
||||||
### Incompatible libraries
|
|
||||||
|
|
||||||
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
|
|
||||||
libraries, even in circumstances that their license may be incompatible, pass
|
|
||||||
`--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.
|
|
||||||
|
|
||||||
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
|
|
||||||
compatible with the 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.
|
|
||||||
234
MAINTAINERS
234
MAINTAINERS
@@ -14,6 +14,7 @@ patches and related discussions.
|
|||||||
Project Leader
|
Project Leader
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
Michael Niedermayer
|
||||||
final design decisions
|
final design decisions
|
||||||
|
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ ffprobe:
|
|||||||
ffprobe.c Stefano Sabatini
|
ffprobe.c Stefano Sabatini
|
||||||
|
|
||||||
ffserver:
|
ffserver:
|
||||||
ffserver.c Reynaldo H. Verdejo Pinochet
|
ffserver.c, ffserver.h Baptiste Coudurier
|
||||||
|
|
||||||
Commandline utility code:
|
Commandline utility code:
|
||||||
cmdutils.c, cmdutils.h Michael Niedermayer
|
cmdutils.c, cmdutils.h Michael Niedermayer
|
||||||
@@ -42,8 +43,9 @@ QuickTime faststart:
|
|||||||
Miscellaneous Areas
|
Miscellaneous Areas
|
||||||
===================
|
===================
|
||||||
|
|
||||||
documentation Stefano Sabatini, Mike Melanson, Timothy Gu, Lou Logan
|
documentation Stefano Sabatini, Mike Melanson, Timothy Gu
|
||||||
project server Árpád Gereöffy, Michael Niedermayer, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov
|
build system (configure,Makefiles) Diego Biurrun, Mans Rullgard
|
||||||
|
project server Árpád Gereöffy, Michael Niedermayer, Reimar Döffinger, Alexander Strasser
|
||||||
presets Robert Swain
|
presets Robert Swain
|
||||||
metadata subsystem Aurelien Jacobs
|
metadata subsystem Aurelien Jacobs
|
||||||
release management Michael Niedermayer
|
release management Michael Niedermayer
|
||||||
@@ -52,12 +54,10 @@ release management Michael Niedermayer
|
|||||||
Communication
|
Communication
|
||||||
=============
|
=============
|
||||||
|
|
||||||
website Deby Barbara Lepage
|
website Robert Swain, Lou Logan
|
||||||
fate.ffmpeg.org Timothy Gu
|
mailinglists Michael Niedermayer, Baptiste Coudurier, Lou Logan
|
||||||
Trac bug tracker Alexander Strasser, Michael Niedermayer, Carl Eugen Hoyos, Lou Logan
|
|
||||||
mailing lists Baptiste Coudurier, Lou Logan
|
|
||||||
Google+ Paul B Mahol, Michael Niedermayer, Alexander Strasser
|
Google+ Paul B Mahol, Michael Niedermayer, Alexander Strasser
|
||||||
Twitter Lou Logan, Reynaldo H. Verdejo Pinochet
|
Twitter Lou Logan
|
||||||
Launchpad Timothy Gu
|
Launchpad Timothy Gu
|
||||||
|
|
||||||
|
|
||||||
@@ -70,15 +70,12 @@ Internal Interfaces:
|
|||||||
libavutil/common.h Michael Niedermayer
|
libavutil/common.h Michael Niedermayer
|
||||||
|
|
||||||
Other:
|
Other:
|
||||||
aes_ctr.c, aes_ctr.h Eran Kornblau
|
|
||||||
bprint Nicolas George
|
bprint Nicolas George
|
||||||
bswap.h
|
bswap.h
|
||||||
des Reimar Doeffinger
|
des Reimar Doeffinger
|
||||||
dynarray.h Nicolas George
|
|
||||||
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
|
|
||||||
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,6 +86,7 @@ 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
|
||||||
|
timecode Clément Bœsch
|
||||||
|
|
||||||
|
|
||||||
libavcodec
|
libavcodec
|
||||||
@@ -116,6 +114,8 @@ Generic Parts:
|
|||||||
faandct.c, faandct.h Michael Niedermayer
|
faandct.c, faandct.h Michael Niedermayer
|
||||||
Golomb coding:
|
Golomb coding:
|
||||||
golomb.c, golomb.h Michael Niedermayer
|
golomb.c, golomb.h Michael Niedermayer
|
||||||
|
LPC:
|
||||||
|
lpc.c, lpc.h Justin Ruggles
|
||||||
motion estimation:
|
motion estimation:
|
||||||
motion* Michael Niedermayer
|
motion* Michael Niedermayer
|
||||||
rate control:
|
rate control:
|
||||||
@@ -129,44 +129,44 @@ Generic Parts:
|
|||||||
tableprint.c, tableprint.h Reimar Doeffinger
|
tableprint.c, tableprint.h Reimar Doeffinger
|
||||||
fixed point FFT:
|
fixed point FFT:
|
||||||
fft* Zeljko Lukac
|
fft* Zeljko Lukac
|
||||||
Text Subtitles Clément Bœsch
|
|
||||||
|
|
||||||
Codecs:
|
Codecs:
|
||||||
4xm.c Michael Niedermayer
|
4xm.c Michael Niedermayer
|
||||||
8bps.c Roberto Togni
|
8bps.c Roberto Togni
|
||||||
8svx.c Jaikrishnan Menon
|
8svx.c Jaikrishnan Menon
|
||||||
aacenc*, aaccoder.c Rostislav Pehlivanov
|
aasc.c Kostya Shishkov
|
||||||
|
ac3* Justin Ruggles
|
||||||
alacenc.c Jaikrishnan Menon
|
alacenc.c Jaikrishnan Menon
|
||||||
alsdec.c Thilo Borgmann, Umair Khan
|
alsdec.c Thilo Borgmann
|
||||||
|
apedec.c Kostya Shishkov
|
||||||
ass* Aurelien Jacobs
|
ass* Aurelien Jacobs
|
||||||
asv* Michael Niedermayer
|
asv* Michael Niedermayer
|
||||||
atrac3plus* Maxim Poliakovski
|
atrac3* Benjamin Larsson
|
||||||
audiotoolbox* Rodger Combs
|
|
||||||
bgmc.c, bgmc.h Thilo Borgmann
|
bgmc.c, bgmc.h Thilo Borgmann
|
||||||
|
bink.c Kostya Shishkov
|
||||||
binkaudio.c Peter Ross
|
binkaudio.c Peter Ross
|
||||||
|
bmp.c Mans Rullgard, Kostya Shishkov
|
||||||
cavs* Stefan Gehrer
|
cavs* Stefan Gehrer
|
||||||
cdxl.c Paul B Mahol
|
cdxl.c Paul B Mahol
|
||||||
celp_filters.* Vitor Sessak
|
celp_filters.* Vitor Sessak
|
||||||
cinepak.c Roberto Togni
|
cinepak.c Roberto Togni
|
||||||
cinepakenc.c Rl / Aetey G.T. AB
|
|
||||||
ccaption_dec.c Anshul Maheshwari, Aman Gupta
|
|
||||||
cljr Alex Beregszaszi
|
cljr Alex Beregszaszi
|
||||||
|
cllc.c Derek Buitenhuis
|
||||||
|
cook.c, cookdata.h Benjamin Larsson
|
||||||
cpia.c Stephan Hilb
|
cpia.c Stephan Hilb
|
||||||
crystalhd.c Philip Langdale
|
crystalhd.c Philip Langdale
|
||||||
cscd.c Reimar Doeffinger
|
cscd.c Reimar Doeffinger
|
||||||
cuvid.c Timo Rothenpieler
|
dca.c Kostya Shishkov, Benjamin Larsson
|
||||||
dirac* Rostislav Pehlivanov
|
|
||||||
dnxhd* Baptiste Coudurier
|
dnxhd* Baptiste Coudurier
|
||||||
dpcm.c Mike Melanson
|
dpcm.c Mike Melanson
|
||||||
dss_sp.c Oleksij Rempel
|
|
||||||
dv.c Roman Shaposhnik
|
dv.c Roman Shaposhnik
|
||||||
dvbsubdec.c Anshul Maheshwari
|
dxa.c Kostya Shishkov
|
||||||
eacmv*, eaidct*, eat* Peter Ross
|
eacmv*, eaidct*, eat* Peter Ross
|
||||||
evrc* Paul B Mahol
|
|
||||||
exif.c, exif.h Thilo Borgmann
|
exif.c, exif.h Thilo Borgmann
|
||||||
ffv1* Michael Niedermayer
|
ffv1.c Michael Niedermayer
|
||||||
ffwavesynth.c Nicolas George
|
ffwavesynth.c Nicolas George
|
||||||
fifo.c Jan Sebechlebsky
|
flac* Justin Ruggles
|
||||||
|
flashsv* Benjamin Larsson
|
||||||
flicvideo.c Mike Melanson
|
flicvideo.c Mike Melanson
|
||||||
g722.c Martin Storsjo
|
g722.c Martin Storsjo
|
||||||
g726.c Roman Shaposhnik
|
g726.c Roman Shaposhnik
|
||||||
@@ -174,47 +174,55 @@ Codecs:
|
|||||||
h261* Michael Niedermayer
|
h261* Michael Niedermayer
|
||||||
h263* Michael Niedermayer
|
h263* Michael Niedermayer
|
||||||
h264* Loren Merritt, Michael Niedermayer
|
h264* Loren Merritt, Michael Niedermayer
|
||||||
hap* Tom Butterworth
|
huffyuv.c Michael Niedermayer
|
||||||
huffyuv* Michael Niedermayer, Christophe Gisquet
|
|
||||||
idcinvideo.c Mike Melanson
|
idcinvideo.c Mike Melanson
|
||||||
|
imc* Benjamin Larsson
|
||||||
|
indeo2* Kostya Shishkov
|
||||||
|
indeo5* Kostya Shishkov
|
||||||
interplayvideo.c Mike Melanson
|
interplayvideo.c Mike Melanson
|
||||||
jni*, ffjni* Matthieu Bouron
|
ivi* Kostya Shishkov
|
||||||
|
jacosub* Clément Bœsch
|
||||||
jpeg2000* Nicolas Bertrand
|
jpeg2000* Nicolas Bertrand
|
||||||
|
jpeg_ls.c Kostya Shishkov
|
||||||
jvdec.c Peter Ross
|
jvdec.c Peter Ross
|
||||||
|
kmvc.c Kostya Shishkov
|
||||||
lcl*.c Roberto Togni, Reimar Doeffinger
|
lcl*.c Roberto Togni, Reimar Doeffinger
|
||||||
libcelt_dec.c Nicolas George
|
libcelt_dec.c Nicolas George
|
||||||
libdirac* David Conrad
|
libdirac* David Conrad
|
||||||
libgsm.c Michel Bardiaux
|
libgsm.c Michel Bardiaux
|
||||||
libkvazaar.c Arttu Ylä-Outinen
|
|
||||||
libopenjpeg.c Jaikrishnan Menon
|
libopenjpeg.c Jaikrishnan Menon
|
||||||
libopenjpegenc.c Michael Bradshaw
|
libopenjpegenc.c Michael Bradshaw
|
||||||
libschroedinger* David Conrad
|
libschroedinger* David Conrad
|
||||||
|
libspeexdec.c Justin Ruggles
|
||||||
libtheoraenc.c David Conrad
|
libtheoraenc.c David Conrad
|
||||||
|
libutvideo* Derek Buitenhuis
|
||||||
libvorbis.c David Conrad
|
libvorbis.c David Conrad
|
||||||
libvpx* James Zern
|
libx264.c Mans Rullgard, Jason Garrett-Glaser
|
||||||
libxavs.c Stefan Gehrer
|
libxavs.c Stefan Gehrer
|
||||||
libzvbi-teletextdec.c Marton Balint
|
loco.c Kostya Shishkov
|
||||||
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
|
||||||
|
mpc* Kostya Shishkov
|
||||||
mpeg12.c, mpeg12data.h Michael Niedermayer
|
mpeg12.c, mpeg12data.h Michael Niedermayer
|
||||||
mpegvideo.c, mpegvideo.h Michael Niedermayer
|
mpegvideo.c, mpegvideo.h Michael Niedermayer
|
||||||
mqc* Nicolas Bertrand
|
mqc* Nicolas Bertrand
|
||||||
msmpeg4.c, msmpeg4data.h Michael Niedermayer
|
msmpeg4.c, msmpeg4data.h Michael Niedermayer
|
||||||
msrle.c Mike Melanson
|
msrle.c Mike Melanson
|
||||||
msvideo1.c Mike Melanson
|
msvideo1.c Mike Melanson
|
||||||
|
nellymoserdec.c Benjamin Larsson
|
||||||
nuv.c Reimar Doeffinger
|
nuv.c Reimar Doeffinger
|
||||||
nvenc* Timo Rothenpieler
|
|
||||||
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, Benjamin Larsson
|
||||||
qsv* Ivan Uskov
|
qdrw.c Kostya Shishkov
|
||||||
|
qpeg.c Kostya Shishkov
|
||||||
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
|
||||||
@@ -222,51 +230,64 @@ 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
|
rv3* Kostya Shishkov
|
||||||
|
rv4* Kostya Shishkov
|
||||||
s3tc* Ivo van Poorten
|
s3tc* Ivo van Poorten
|
||||||
|
smacker.c Kostya Shishkov
|
||||||
smc.c Mike Melanson
|
smc.c Mike Melanson
|
||||||
smvjpegdec.c Ash Hughes
|
smvjpegdec.c Ash Hughes
|
||||||
snow* Michael Niedermayer, Loren Merritt
|
snow.c Michael Niedermayer, Loren Merritt
|
||||||
sonic.c Alex Beregszaszi
|
sonic.c Alex Beregszaszi
|
||||||
srt* Aurelien Jacobs
|
srt* Aurelien Jacobs
|
||||||
sunrast.c Ivo van Poorten
|
sunrast.c Ivo van Poorten
|
||||||
svq3.c Michael Niedermayer
|
svq3.c Michael Niedermayer
|
||||||
tak* Paul B Mahol
|
tak* Paul B Mahol
|
||||||
|
targa.c Kostya Shishkov
|
||||||
|
tiff.c Kostya Shishkov
|
||||||
truemotion1* Mike Melanson
|
truemotion1* Mike Melanson
|
||||||
|
truemotion2* Kostya Shishkov
|
||||||
|
truespeech.c Kostya Shishkov
|
||||||
|
tscc.c Kostya Shishkov
|
||||||
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
|
||||||
vc1* Christophe Gisquet
|
ulti* Kostya Shishkov
|
||||||
vc2* Rostislav Pehlivanov
|
v410*.c Derek Buitenhuis
|
||||||
|
vb.c Kostya Shishkov
|
||||||
|
vble.c Derek Buitenhuis
|
||||||
|
vc1* Kostya Shishkov
|
||||||
vcr1.c Michael Niedermayer
|
vcr1.c Michael Niedermayer
|
||||||
vda_h264_dec.c Xidorn Quan
|
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
|
vmnc.c Kostya Shishkov
|
||||||
vorbisenc.c Oded Shimon
|
vorbis_dec.c Denes Balatoni, David Conrad
|
||||||
|
vorbis_enc.c Oded Shimon
|
||||||
vp3* Mike Melanson
|
vp3* Mike Melanson
|
||||||
vp5 Aurelien Jacobs
|
vp5 Aurelien Jacobs
|
||||||
vp6 Aurelien Jacobs
|
vp6 Aurelien Jacobs
|
||||||
vp8 David Conrad, Ronald Bultje
|
vp8 David Conrad, Jason Garrett-Glaser, Ronald Bultje
|
||||||
vp9 Ronald Bultje
|
|
||||||
vqavideo.c Mike Melanson
|
vqavideo.c Mike Melanson
|
||||||
|
wavpack.c Kostya Shishkov
|
||||||
wmaprodec.c Sascha Sommer
|
wmaprodec.c Sascha Sommer
|
||||||
wmavoice.c Ronald S. Bultje
|
wmavoice.c Ronald S. Bultje
|
||||||
wmv2.c Michael Niedermayer
|
wmv2.c Michael Niedermayer
|
||||||
|
wnv1.c Kostya Shishkov
|
||||||
xan.c Mike Melanson
|
xan.c Mike Melanson
|
||||||
xbm* Paul B Mahol
|
xbm* Paul B Mahol
|
||||||
xface Stefano Sabatini
|
xface Stefano Sabatini
|
||||||
|
xl.c Kostya Shishkov
|
||||||
xvmc.c Ivan Kalvachev
|
xvmc.c Ivan Kalvachev
|
||||||
xwd* Paul B Mahol
|
xwd* Paul B Mahol
|
||||||
|
zerocodec.c Derek Buitenhuis
|
||||||
|
zmbv* Kostya Shishkov
|
||||||
|
|
||||||
Hardware acceleration:
|
Hardware acceleration:
|
||||||
crystalhd.c Philip Langdale
|
crystalhd.c Philip Langdale
|
||||||
dxva2* Hendrik Leppkes, Laurent Aimar
|
dxva2* Laurent Aimar
|
||||||
mediacodec* Matthieu Bouron
|
libstagefright.cpp Mohamed Naufal
|
||||||
vaapi* Gwenole Beauchesne
|
vaapi* Gwenole Beauchesne
|
||||||
vaapi_encode* Mark Thompson
|
vda* Sebastien Zwickert
|
||||||
vdpau* Philip Langdale, Carl Eugen Hoyos
|
vdpau* Carl Eugen Hoyos
|
||||||
videotoolbox* Rick Kern
|
|
||||||
|
|
||||||
|
|
||||||
libavdevice
|
libavdevice
|
||||||
@@ -275,22 +296,15 @@ libavdevice
|
|||||||
libavdevice/avdevice.h
|
libavdevice/avdevice.h
|
||||||
|
|
||||||
|
|
||||||
avfoundation.m Thilo Borgmann
|
dshow.c Roger Pack
|
||||||
decklink* Deti Fliegl
|
|
||||||
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)
|
|
||||||
iec61883.c Georg Lippitsch
|
iec61883.c Georg Lippitsch
|
||||||
lavfi Stefano Sabatini
|
lavfi Stefano Sabatini
|
||||||
libdc1394.c Roman Shaposhnik
|
libdc1394.c Roman Shaposhnik
|
||||||
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 Luca Abeni
|
||||||
v4l2.c Giorgio Vazzana
|
|
||||||
vfwcap.c Ramiro Polla
|
vfwcap.c Ramiro Polla
|
||||||
xv.c Lukasz Marek
|
|
||||||
|
|
||||||
libavfilter
|
libavfilter
|
||||||
===========
|
===========
|
||||||
@@ -298,10 +312,7 @@ 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
|
|
||||||
af_adelay.c Paul B Mahol
|
af_adelay.c Paul B Mahol
|
||||||
af_aecho.c Paul B Mahol
|
af_aecho.c Paul B Mahol
|
||||||
af_afade.c Paul B Mahol
|
af_afade.c Paul B Mahol
|
||||||
@@ -309,51 +320,27 @@ Filters:
|
|||||||
af_aphaser.c Paul B Mahol
|
af_aphaser.c Paul B Mahol
|
||||||
af_aresample.c Michael Niedermayer
|
af_aresample.c Michael Niedermayer
|
||||||
af_astats.c Paul B Mahol
|
af_astats.c Paul B Mahol
|
||||||
|
af_astreamsync.c Nicolas George
|
||||||
af_atempo.c Pavel Koshevoy
|
af_atempo.c Pavel Koshevoy
|
||||||
af_biquads.c Paul B Mahol
|
af_biquads.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_hdcd.c Burt P.
|
|
||||||
af_ladspa.c Paul B Mahol
|
af_ladspa.c Paul B Mahol
|
||||||
af_loudnorm.c Kyle Swanson
|
|
||||||
af_pan.c Nicolas George
|
af_pan.c Nicolas George
|
||||||
af_sidechaincompress.c Paul B Mahol
|
|
||||||
af_silenceremove.c Paul B Mahol
|
|
||||||
avf_aphasemeter.c Paul B Mahol
|
|
||||||
avf_avectorscope.c Paul B Mahol
|
avf_avectorscope.c Paul B Mahol
|
||||||
avf_showcqt.c Muhammad Faiz
|
|
||||||
vf_blend.c Paul B Mahol
|
vf_blend.c Paul B Mahol
|
||||||
vf_chromakey.c Timo Rothenpieler
|
|
||||||
vf_colorchannelmixer.c Paul B Mahol
|
|
||||||
vf_colorbalance.c Paul B Mahol
|
vf_colorbalance.c Paul B Mahol
|
||||||
vf_colorkey.c Timo Rothenpieler
|
vf_delogo.c Jean Delvare (CC <khali@linux-fr.org>)
|
||||||
vf_colorlevels.c Paul B Mahol
|
|
||||||
vf_coreimage.m Thilo Borgmann
|
|
||||||
vf_deband.c Paul B Mahol
|
|
||||||
vf_dejudder.c Nicholas Robbins
|
|
||||||
vf_delogo.c Jean Delvare (CC <jdelvare@suse.com>)
|
|
||||||
vf_drawbox.c/drawgrid Andrey Utkin
|
vf_drawbox.c/drawgrid Andrey Utkin
|
||||||
vf_extractplanes.c Paul B Mahol
|
vf_extractplanes.c Paul B Mahol
|
||||||
vf_histogram.c Paul B Mahol
|
vf_histogram.c Paul B Mahol
|
||||||
vf_hqx.c Clément Bœsch
|
|
||||||
vf_idet.c Pascal Massimino
|
|
||||||
vf_il.c Paul B Mahol
|
vf_il.c Paul B Mahol
|
||||||
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_psnr.c Paul B Mahol
|
vf_psnr.c Paul B Mahol
|
||||||
vf_random.c Paul B Mahol
|
|
||||||
vf_readvitc.c Tobias Rapp (CC t.rapp at noa-archive dot com)
|
|
||||||
vf_scale.c Michael Niedermayer
|
vf_scale.c Michael Niedermayer
|
||||||
vf_separatefields.c Paul B Mahol
|
vf_separatefields.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_yadif.c Michael Niedermayer
|
vf_yadif.c Michael Niedermayer
|
||||||
vf_zoompan.c Paul B Mahol
|
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
vsrc_mandelbrot.c Michael Niedermayer
|
vsrc_mandelbrot.c Michael Niedermayer
|
||||||
@@ -366,22 +353,20 @@ Generic parts:
|
|||||||
libavformat/avformat.h Michael Niedermayer
|
libavformat/avformat.h Michael Niedermayer
|
||||||
Utility Code:
|
Utility Code:
|
||||||
libavformat/utils.c Michael Niedermayer
|
libavformat/utils.c Michael Niedermayer
|
||||||
Text Subtitles Clément Bœsch
|
|
||||||
|
|
||||||
|
|
||||||
Muxers/Demuxers:
|
Muxers/Demuxers:
|
||||||
4xm.c Mike Melanson
|
4xm.c Mike Melanson
|
||||||
aadec.c Vesselin Bontchev (vesselin.bontchev at yandex dot com)
|
|
||||||
adtsenc.c Robert Swain
|
adtsenc.c Robert Swain
|
||||||
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
|
||||||
apngdec.c Benoit Fouet
|
ape.c Kostya Shishkov
|
||||||
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
|
||||||
brstm.c Paul B Mahol
|
brstm.c Paul B Mahol
|
||||||
@@ -389,18 +374,17 @@ Muxers/Demuxers:
|
|||||||
cdxl.c Paul B Mahol
|
cdxl.c Paul B Mahol
|
||||||
crc.c Michael Niedermayer
|
crc.c Michael Niedermayer
|
||||||
daud.c Reimar Doeffinger
|
daud.c Reimar Doeffinger
|
||||||
dss.c Oleksij Rempel
|
|
||||||
dtshddec.c Paul B Mahol
|
dtshddec.c Paul B Mahol
|
||||||
dv.c Roman Shaposhnik
|
dv.c Roman Shaposhnik
|
||||||
|
dxa.c Kostya Shishkov
|
||||||
electronicarts.c Peter Ross
|
electronicarts.c Peter Ross
|
||||||
epafdec.c Paul B Mahol
|
epafdec.c Paul B Mahol
|
||||||
ffm* Baptiste Coudurier
|
ffm* Baptiste Coudurier
|
||||||
|
flac* Justin Ruggles
|
||||||
flic.c Mike Melanson
|
flic.c Mike Melanson
|
||||||
flvdec.c, flvenc.c Michael Niedermayer
|
flvdec.c, flvenc.c Michael Niedermayer
|
||||||
gxf.c Reimar Doeffinger
|
gxf.c Reimar Doeffinger
|
||||||
gxfenc.c Baptiste Coudurier
|
gxfenc.c Baptiste Coudurier
|
||||||
hls.c Anssi Hannula
|
|
||||||
hls encryption (hlsenc.c) Christian Suloway, Steven Liu
|
|
||||||
idcin.c Mike Melanson
|
idcin.c Mike Melanson
|
||||||
idroqdec.c Mike Melanson
|
idroqdec.c Mike Melanson
|
||||||
iff.c Jaikrishnan Menon
|
iff.c Jaikrishnan Menon
|
||||||
@@ -408,40 +392,37 @@ Muxers/Demuxers:
|
|||||||
ipmovie.c Mike Melanson
|
ipmovie.c Mike Melanson
|
||||||
ircam* Paul B Mahol
|
ircam* Paul B Mahol
|
||||||
iss.c Stefan Gehrer
|
iss.c Stefan Gehrer
|
||||||
|
jacosub* Clément Bœsch
|
||||||
jvdec.c Peter Ross
|
jvdec.c Peter Ross
|
||||||
libmodplug.c Clément Bœsch
|
libmodplug.c Clément Bœsch
|
||||||
libnut.c Oded Shimon
|
libnut.c Oded Shimon
|
||||||
libopenmpt.c Josh de Kock
|
|
||||||
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
|
matroska.c Aurelien Jacobs
|
||||||
matroskadec.c Aurelien Jacobs
|
matroskadec.c Aurelien Jacobs
|
||||||
matroskaenc.c David Conrad
|
matroskaenc.c David Conrad
|
||||||
matroska subtitles (matroskaenc.c) John Peebles
|
|
||||||
metadata* Aurelien Jacobs
|
metadata* Aurelien Jacobs
|
||||||
mgsts.c Paul B Mahol
|
mgsts.c Paul B Mahol
|
||||||
microdvd* Aurelien Jacobs
|
microdvd* Aurelien Jacobs
|
||||||
mm.c Peter Ross
|
mm.c Peter Ross
|
||||||
mov.c Baptiste Coudurier
|
mov.c Michael Niedermayer, Baptiste Coudurier
|
||||||
movenc.c Baptiste Coudurier, Matthieu Bouron
|
movenc.c Baptiste Coudurier, Matthieu Bouron
|
||||||
movenccenc.c Eran Kornblau
|
mpc.c Kostya Shishkov
|
||||||
mpeg.c Michael Niedermayer
|
mpeg.c Michael Niedermayer
|
||||||
mpegenc.c Michael Niedermayer
|
mpegenc.c Michael Niedermayer
|
||||||
mpegts.c Marton Balint
|
mpegts* 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
|
mxf* Baptiste Coudurier
|
||||||
mxfdec.c Tomas Härdin
|
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.c Michael Niedermayer
|
||||||
nuv.c Reimar Doeffinger
|
nuv.c Reimar Doeffinger
|
||||||
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
|
||||||
psxstr.c Mike Melanson
|
psxstr.c Mike Melanson
|
||||||
@@ -451,23 +432,18 @@ Muxers/Demuxers:
|
|||||||
raw.c Michael Niedermayer
|
raw.c Michael Niedermayer
|
||||||
rdt.c Ronald S. Bultje
|
rdt.c Ronald S. Bultje
|
||||||
rl2.c Sascha Sommer
|
rl2.c Sascha Sommer
|
||||||
rmdec.c, rmenc.c Ronald S. Bultje
|
rmdec.c, rmenc.c Ronald S. Bultje, Kostya Shishkov
|
||||||
|
rtmp* Kostya Shishkov
|
||||||
rtp.c, rtpenc.c Martin Storsjo
|
rtp.c, rtpenc.c Martin Storsjo
|
||||||
rtpdec_ac3.* Gilles Chanteperdrix
|
|
||||||
rtpdec_dv.* Thomas Volkert
|
|
||||||
rtpdec_h261.*, rtpenc_h261.* Thomas Volkert
|
|
||||||
rtpdec_hevc.*, rtpenc_hevc.* Thomas Volkert
|
|
||||||
rtpdec_mpa_robust.* Gilles Chanteperdrix
|
|
||||||
rtpdec_asf.* Ronald S. Bultje
|
rtpdec_asf.* Ronald S. Bultje
|
||||||
rtpdec_vc2hq.*, rtpenc_vc2hq.* Thomas Volkert
|
|
||||||
rtpdec_vp9.c Thomas Volkert
|
|
||||||
rtpenc_mpv.*, rtpenc_aac.* Martin Storsjo
|
rtpenc_mpv.*, rtpenc_aac.* Martin Storsjo
|
||||||
|
rtsp.c Luca Barbato
|
||||||
sbgdec.c Nicolas George
|
sbgdec.c Nicolas George
|
||||||
sdp.c Martin Storsjo
|
sdp.c Martin Storsjo
|
||||||
segafilm.c Mike Melanson
|
segafilm.c Mike Melanson
|
||||||
segment.c Stefano Sabatini
|
siff.c Kostya Shishkov
|
||||||
|
smacker.c Kostya Shishkov
|
||||||
smjpeg* Paul B Mahol
|
smjpeg* Paul B Mahol
|
||||||
spdif* Anssi Hannula
|
|
||||||
srtdec.c Aurelien Jacobs
|
srtdec.c Aurelien Jacobs
|
||||||
swf.c Baptiste Coudurier
|
swf.c Baptiste Coudurier
|
||||||
takdec.c Paul B Mahol
|
takdec.c Paul B Mahol
|
||||||
@@ -476,21 +452,19 @@ Muxers/Demuxers:
|
|||||||
voc.c Aurelien Jacobs
|
voc.c Aurelien Jacobs
|
||||||
wav.c Michael Niedermayer
|
wav.c Michael Niedermayer
|
||||||
wc3movie.c Mike Melanson
|
wc3movie.c Mike Melanson
|
||||||
webm dash (matroskaenc.c) Vignesh Venkatasubramanian
|
|
||||||
webvtt* Matthew J Heaney
|
webvtt* Matthew J Heaney
|
||||||
westwood.c Mike Melanson
|
westwood.c Mike Melanson
|
||||||
wtv.c Peter Ross
|
wtv.c Peter Ross
|
||||||
|
wv.c Kostya Shishkov
|
||||||
wvenc.c Paul B Mahol
|
wvenc.c Paul B Mahol
|
||||||
|
|
||||||
Protocols:
|
Protocols:
|
||||||
async.c Zhang Rui
|
|
||||||
bluray.c Petri Hintukainen
|
bluray.c Petri Hintukainen
|
||||||
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
|
||||||
mms*.c Ronald S. Bultje
|
mms*.c Ronald S. Bultje
|
||||||
udp.c Luca Abeni
|
udp.c Luca Abeni
|
||||||
icecast.c Marvin Scholz
|
|
||||||
|
|
||||||
|
|
||||||
libswresample
|
libswresample
|
||||||
@@ -510,26 +484,25 @@ Resamplers:
|
|||||||
Operating systems / CPU architectures
|
Operating systems / CPU architectures
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
Alpha Falk Hueffner
|
Alpha Mans Rullgard, Falk Hueffner
|
||||||
MIPS Nedeljko Babic
|
ARM Mans Rullgard
|
||||||
|
AVR32 Mans Rullgard
|
||||||
|
MIPS Mans Rullgard, 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 Luca Barbato
|
||||||
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 ICL Matthew Oliver
|
|
||||||
ADI/Blackfin DSP Marc Hoffman
|
ADI/Blackfin DSP Marc Hoffman
|
||||||
Sparc Roman Shaposhnik
|
Sparc Roman Shaposhnik
|
||||||
OS/2 KO Myung-Hun
|
x86 Michael Niedermayer
|
||||||
|
|
||||||
|
|
||||||
Releases
|
Releases
|
||||||
========
|
========
|
||||||
|
|
||||||
2.8 Michael Niedermayer
|
2.1 Michael Niedermayer
|
||||||
2.7 Michael Niedermayer
|
2.0 Michael Niedermayer
|
||||||
2.6 Michael Niedermayer
|
|
||||||
2.5 Michael Niedermayer
|
|
||||||
|
|
||||||
If you want to maintain an older release, please contact us
|
If you want to maintain an older release, please contact us
|
||||||
|
|
||||||
@@ -539,34 +512,33 @@ GnuPG Fingerprints of maintainers and contributors
|
|||||||
|
|
||||||
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
|
||||||
|
Anton Khirnov 6D0C 6625 56F8 65D1 E5F5 814B B50A 1241 C067 07AB
|
||||||
Ash Hughes 694D 43D2 D180 C7C7 6421 ABD3 A641 D0B7 623D 6029
|
Ash Hughes 694D 43D2 D180 C7C7 6421 ABD3 A641 D0B7 623D 6029
|
||||||
Attila Kinali 11F0 F9A6 A1D2 11F6 C745 D10C 6520 BCDD F2DF E765
|
Attila Kinali 11F0 F9A6 A1D2 11F6 C745 D10C 6520 BCDD F2DF E765
|
||||||
Baptiste Coudurier 8D77 134D 20CC 9220 201F C5DB 0AC9 325C 5C1A BAAA
|
Baptiste Coudurier 8D77 134D 20CC 9220 201F C5DB 0AC9 325C 5C1A BAAA
|
||||||
Ben Littler 3EE3 3723 E560 3214 A8CD 4DEB 2CDB FCE7 768C 8D2C
|
Ben Littler 3EE3 3723 E560 3214 A8CD 4DEB 2CDB FCE7 768C 8D2C
|
||||||
Benoit Fouet B22A 4F4F 43EF 636B BB66 FCDC 0023 AE1E 2985 49C8
|
Benoit Fouet B22A 4F4F 43EF 636B BB66 FCDC 0023 AE1E 2985 49C8
|
||||||
Clément Bœsch 52D0 3A82 D445 F194 DB8B 2B16 87EE 2CB8 F4B8 FCF9
|
Bœsch Clément 52D0 3A82 D445 F194 DB8B 2B16 87EE 2CB8 F4B8 FCF9
|
||||||
Daniel Verkamp 78A6 07ED 782C 653E C628 B8B9 F0EB 8DD8 2F0E 21C7
|
Daniel Verkamp 78A6 07ED 782C 653E C628 B8B9 F0EB 8DD8 2F0E 21C7
|
||||||
|
Diego Biurrun 8227 1E31 B6D9 4994 7427 E220 9CAE D6CC 4757 FCC5
|
||||||
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
|
|
||||||
Gwenole Beauchesne 2E63 B3A6 3E44 37E2 017D 2704 53C7 6266 B153 99C4
|
Gwenole Beauchesne 2E63 B3A6 3E44 37E2 017D 2704 53C7 6266 B153 99C4
|
||||||
Jaikrishnan Menon 61A1 F09F 01C9 2D45 78E1 C862 25DC 8831 AF70 D368
|
Jaikrishnan Menon 61A1 F09F 01C9 2D45 78E1 C862 25DC 8831 AF70 D368
|
||||||
Jean Delvare 7CA6 9F44 60F1 BDC4 1FD2 C858 A552 6B9B B3CD 4E6A
|
Jean Delvare 7CA6 9F44 60F1 BDC4 1FD2 C858 A552 6B9B B3CD 4E6A
|
||||||
|
Justin Ruggles 3136 ECC0 C10D 6C04 5F43 CA29 FCBE CD2A 3787 1EBF
|
||||||
Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE
|
Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE
|
||||||
Lou Logan 7D68 DC73 CBEF EABB 671A B6CF 621C 2E28 82F8 DC3A
|
Lou Logan 7D68 DC73 CBEF EABB 671A B6CF 621C 2E28 82F8 DC3A
|
||||||
|
Luca Barbato 6677 4209 213C 8843 5B67 29E7 E84C 78C2 84E9 0E34
|
||||||
Michael Niedermayer 9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB
|
Michael Niedermayer 9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB
|
||||||
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
|
Reimar Döffinger 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
|
||||||
Stephan Hilb 4F38 0B3A 5F39 B99B F505 E562 8D5C 5554 4E17 8863
|
Stephan Hilb 4F38 0B3A 5F39 B99B F505 E562 8D5C 5554 4E17 8863
|
||||||
Tiancheng "Timothy" Gu 9456 AFC0 814A 8139 E994 8351 7FE6 B095 B582 B0D4
|
|
||||||
Tim Nicholson 38CF DB09 3ED0 F607 8B67 6CED 0C0B FC44 8B0B FC83
|
|
||||||
Tomas Härdin 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
|
||||||
|
|||||||
119
Makefile
119
Makefile
@@ -4,80 +4,62 @@ include config.mak
|
|||||||
vpath %.c $(SRC_PATH)
|
vpath %.c $(SRC_PATH)
|
||||||
vpath %.cpp $(SRC_PATH)
|
vpath %.cpp $(SRC_PATH)
|
||||||
vpath %.h $(SRC_PATH)
|
vpath %.h $(SRC_PATH)
|
||||||
vpath %.inc $(SRC_PATH)
|
|
||||||
vpath %.m $(SRC_PATH)
|
|
||||||
vpath %.S $(SRC_PATH)
|
vpath %.S $(SRC_PATH)
|
||||||
vpath %.asm $(SRC_PATH)
|
vpath %.asm $(SRC_PATH)
|
||||||
vpath %.rc $(SRC_PATH)
|
|
||||||
vpath %.v $(SRC_PATH)
|
vpath %.v $(SRC_PATH)
|
||||||
vpath %.texi $(SRC_PATH)
|
vpath %.texi $(SRC_PATH)
|
||||||
vpath %/fate_config.sh.template $(SRC_PATH)
|
vpath %/fate_config.sh.template $(SRC_PATH)
|
||||||
|
|
||||||
AVPROGS-$(CONFIG_FFMPEG) += ffmpeg
|
PROGS-$(CONFIG_FFMPEG) += ffmpeg
|
||||||
AVPROGS-$(CONFIG_FFPLAY) += ffplay
|
PROGS-$(CONFIG_FFPLAY) += ffplay
|
||||||
AVPROGS-$(CONFIG_FFPROBE) += ffprobe
|
PROGS-$(CONFIG_FFPROBE) += ffprobe
|
||||||
AVPROGS-$(CONFIG_FFSERVER) += ffserver
|
PROGS-$(CONFIG_FFSERVER) += ffserver
|
||||||
|
|
||||||
AVPROGS := $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
|
PROGS := $(PROGS-yes:%=%$(PROGSSUF)$(EXESUF))
|
||||||
INSTPROGS = $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
|
INSTPROGS = $(PROGS-yes:%=%$(PROGSSUF)$(EXESUF))
|
||||||
PROGS += $(AVPROGS)
|
|
||||||
|
|
||||||
AVBASENAMES = ffmpeg ffplay ffprobe ffserver
|
OBJS = cmdutils.o $(EXEOBJS)
|
||||||
ALLAVPROGS = $(AVBASENAMES:%=%$(PROGSSUF)$(EXESUF))
|
OBJS-ffmpeg = ffmpeg_opt.o ffmpeg_filter.o
|
||||||
ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
|
TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64
|
||||||
|
|
||||||
$(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
|
|
||||||
HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options
|
HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options
|
||||||
TOOLS = qt-faststart trasher uncoded_frame
|
TOOLS = qt-faststart trasher
|
||||||
TOOLS-$(CONFIG_ZLIB) += cws2fws
|
TOOLS-$(CONFIG_ZLIB) += cws2fws
|
||||||
|
|
||||||
# $(FFLIBS-yes) needs to be in linking order
|
BASENAMES = ffmpeg ffplay ffprobe ffserver
|
||||||
FFLIBS-$(CONFIG_AVDEVICE) += avdevice
|
ALLPROGS = $(BASENAMES:%=%$(PROGSSUF)$(EXESUF))
|
||||||
FFLIBS-$(CONFIG_AVFILTER) += avfilter
|
ALLPROGS_G = $(BASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
|
||||||
FFLIBS-$(CONFIG_AVFORMAT) += avformat
|
|
||||||
FFLIBS-$(CONFIG_AVCODEC) += avcodec
|
FFLIBS-$(CONFIG_AVDEVICE) += avdevice
|
||||||
|
FFLIBS-$(CONFIG_AVFILTER) += avfilter
|
||||||
|
FFLIBS-$(CONFIG_AVFORMAT) += avformat
|
||||||
FFLIBS-$(CONFIG_AVRESAMPLE) += avresample
|
FFLIBS-$(CONFIG_AVRESAMPLE) += avresample
|
||||||
FFLIBS-$(CONFIG_POSTPROC) += postproc
|
FFLIBS-$(CONFIG_AVCODEC) += avcodec
|
||||||
FFLIBS-$(CONFIG_SWRESAMPLE) += swresample
|
FFLIBS-$(CONFIG_POSTPROC) += postproc
|
||||||
FFLIBS-$(CONFIG_SWSCALE) += swscale
|
FFLIBS-$(CONFIG_SWRESAMPLE)+= swresample
|
||||||
|
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
|
EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/Makefile $(SRC_PATH)/doc/examples/README
|
||||||
|
|
||||||
SKIPHEADERS = cmdutils_common_opts.h \
|
SKIPHEADERS = cmdutils_common_opts.h compat/w32pthreads.h
|
||||||
compat/w32pthreads.h
|
|
||||||
|
|
||||||
include $(SRC_PATH)/common.mak
|
include $(SRC_PATH)/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)
|
|
||||||
|
|
||||||
all: $(AVPROGS)
|
all: $(PROGS)
|
||||||
|
|
||||||
|
$(PROGS): %$(EXESUF): %_g$(EXESUF)
|
||||||
|
$(CP) $< $@
|
||||||
|
$(STRIP) $@
|
||||||
|
|
||||||
$(TOOLS): %$(EXESUF): %.o $(EXEOBJS)
|
$(TOOLS): %$(EXESUF): %.o $(EXEOBJS)
|
||||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS)
|
$(LD) $(LDFLAGS) $(LD_O) $^ $(ELIBS)
|
||||||
|
|
||||||
tools/cws2fws$(EXESUF): ELIBS = $(ZLIB)
|
tools/cws2fws$(EXESUF): ELIBS = $(ZLIB)
|
||||||
tools/uncoded_frame$(EXESUF): $(FF_DEP_LIBS)
|
|
||||||
tools/uncoded_frame$(EXESUF): ELIBS = $(FF_EXTRALIBS)
|
|
||||||
|
|
||||||
config.h: .config
|
config.h: .config
|
||||||
.config: $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c))
|
.config: $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c))
|
||||||
@@ -87,10 +69,11 @@ config.h: .config
|
|||||||
|
|
||||||
SUBDIR_VARS := CLEANFILES EXAMPLES 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 VFP-OBJS NEON-OBJS \
|
||||||
ALTIVEC-OBJS MMX-OBJS YASM-OBJS \
|
ALTIVEC-OBJS VIS-OBJS \
|
||||||
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSP-OBJS MSA-OBJS \
|
MMX-OBJS YASM-OBJS \
|
||||||
MMI-OBJS OBJS SLIBOBJS HOSTOBJS TESTOBJS
|
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSPR1-OBJS MIPS32R2-OBJS \
|
||||||
|
OBJS HOSTOBJS TESTOBJS
|
||||||
|
|
||||||
define RESET
|
define RESET
|
||||||
$(1) :=
|
$(1) :=
|
||||||
@@ -102,16 +85,13 @@ $(foreach V,$(SUBDIR_VARS),$(eval $(call RESET,$(V))))
|
|||||||
SUBDIR := $(1)/
|
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)/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)/doc/Makefile
|
|
||||||
|
|
||||||
define DOPROG
|
define DOPROG
|
||||||
OBJS-$(1) += $(1).o $(EXEOBJS) $(OBJS-$(1)-yes)
|
OBJS-$(1) += $(1).o cmdutils.o $(EXEOBJS)
|
||||||
$(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1))
|
$(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1))
|
||||||
$$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1))
|
$$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1))
|
||||||
$(1)$(PROGSSUF)_g$(EXESUF): LDFLAGS += $(LDFLAGS-$(1))
|
$(1)$(PROGSSUF)_g$(EXESUF): LDFLAGS += $(LDFLAGS-$(1))
|
||||||
@@ -119,16 +99,10 @@ $(1)$(PROGSSUF)_g$(EXESUF): FF_EXTRALIBS += $(LIBS-$(1))
|
|||||||
-include $$(OBJS-$(1):.o=.d)
|
-include $$(OBJS-$(1):.o=.d)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(foreach P,$(PROGS),$(eval $(call DOPROG,$(P:$(PROGSSUF)$(EXESUF)=))))
|
$(foreach P,$(PROGS-yes),$(eval $(call DOPROG,$(P))))
|
||||||
|
|
||||||
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)
|
|
||||||
$(CP) $< $@
|
|
||||||
$(STRIP) $@
|
|
||||||
|
|
||||||
%$(PROGSSUF)_g$(EXESUF): %.o $(FF_DEP_LIBS)
|
%$(PROGSSUF)_g$(EXESUF): %.o $(FF_DEP_LIBS)
|
||||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS)
|
$(LD) $(LDFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS)
|
||||||
|
|
||||||
OBJDIRS += tools
|
OBJDIRS += tools
|
||||||
|
|
||||||
@@ -140,14 +114,14 @@ GIT_LOG = $(SRC_PATH)/.git/logs/HEAD
|
|||||||
.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) config.mak
|
.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) config.mak
|
||||||
.version: M=@
|
.version: M=@
|
||||||
|
|
||||||
libavutil/ffversion.h .version:
|
version.h .version:
|
||||||
$(M)$(VERSION_SH) $(SRC_PATH) libavutil/ffversion.h $(EXTRA_VERSION)
|
$(M)$(VERSION_SH) $(SRC_PATH) version.h $(EXTRA_VERSION)
|
||||||
$(Q)touch .version
|
$(Q)touch .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
|
ifdef PROGS
|
||||||
install: install-progs install-data
|
install: install-progs install-data
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -158,7 +132,7 @@ install-libs: install-libs-yes
|
|||||||
install-progs-yes:
|
install-progs-yes:
|
||||||
install-progs-$(CONFIG_SHARED): install-libs
|
install-progs-$(CONFIG_SHARED): install-libs
|
||||||
|
|
||||||
install-progs: install-progs-yes $(AVPROGS)
|
install-progs: install-progs-yes $(PROGS)
|
||||||
$(Q)mkdir -p "$(BINDIR)"
|
$(Q)mkdir -p "$(BINDIR)"
|
||||||
$(INSTALL) -c -m 755 $(INSTPROGS) "$(BINDIR)"
|
$(INSTALL) -c -m 755 $(INSTPROGS) "$(BINDIR)"
|
||||||
|
|
||||||
@@ -170,31 +144,28 @@ install-data: $(DATA_FILES) $(EXAMPLES_FILES)
|
|||||||
uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data
|
uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data
|
||||||
|
|
||||||
uninstall-progs:
|
uninstall-progs:
|
||||||
$(RM) $(addprefix "$(BINDIR)/", $(ALLAVPROGS))
|
$(RM) $(addprefix "$(BINDIR)/", $(ALLPROGS))
|
||||||
|
|
||||||
uninstall-data:
|
uninstall-data:
|
||||||
$(RM) -r "$(DATADIR)"
|
$(RM) -r "$(DATADIR)"
|
||||||
|
|
||||||
clean::
|
clean::
|
||||||
$(RM) $(ALLAVPROGS) $(ALLAVPROGS_G)
|
$(RM) $(ALLPROGS) $(ALLPROGS_G)
|
||||||
$(RM) $(CLEANSUFFIXES)
|
$(RM) $(CLEANSUFFIXES)
|
||||||
$(RM) $(CLEANSUFFIXES:%=tools/%)
|
$(RM) $(CLEANSUFFIXES:%=tools/%)
|
||||||
$(RM) -r coverage-html
|
$(RM) -r coverage-html
|
||||||
$(RM) -rf coverage.info coverage.info.in lcov
|
$(RM) -rf coverage.info lcov
|
||||||
|
|
||||||
distclean::
|
distclean::
|
||||||
$(RM) $(DISTCLEANSUFFIXES)
|
$(RM) $(DISTCLEANSUFFIXES)
|
||||||
$(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
|
$(RM) config.* .config libavutil/avconfig.h .version version.h libavcodec/codec_names.h
|
||||||
ifeq ($(SRC_LINK),src)
|
|
||||||
$(RM) src
|
|
||||||
endif
|
|
||||||
$(RM) -rf doc/examples/pc-uninstalled
|
|
||||||
|
|
||||||
config:
|
config:
|
||||||
$(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION)
|
$(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION)
|
||||||
|
|
||||||
check: all alltools examples testprogs fate
|
check: all alltools examples testprogs fate
|
||||||
|
|
||||||
|
include $(SRC_PATH)/doc/Makefile
|
||||||
include $(SRC_PATH)/tests/Makefile
|
include $(SRC_PATH)/tests/Makefile
|
||||||
|
|
||||||
$(sort $(OBJDIRS)):
|
$(sort $(OBJDIRS)):
|
||||||
|
|||||||
18
README
Normal file
18
README
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
FFmpeg README
|
||||||
|
-------------
|
||||||
|
|
||||||
|
1) Documentation
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* Read the documentation in the doc/ directory in git.
|
||||||
|
You can also view it online at http://ffmpeg.org/documentation.html
|
||||||
|
|
||||||
|
2) Licensing
|
||||||
|
------------
|
||||||
|
|
||||||
|
* See the LICENSE file.
|
||||||
|
|
||||||
|
3) Build and Install
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* See the INSTALL file.
|
||||||
48
README.md
48
README.md
@@ -1,48 +0,0 @@
|
|||||||
FFmpeg README
|
|
||||||
=============
|
|
||||||
|
|
||||||
FFmpeg is a collection of libraries and tools to process multimedia content
|
|
||||||
such as audio, video, subtitles and related metadata.
|
|
||||||
|
|
||||||
## Libraries
|
|
||||||
|
|
||||||
* `libavcodec` provides implementation of a wider range of codecs.
|
|
||||||
* `libavformat` implements streaming protocols, container formats and basic I/O access.
|
|
||||||
* `libavutil` includes hashers, decompressors and miscellaneous utility functions.
|
|
||||||
* `libavfilter` provides a mean to alter decoded Audio and Video through chain of filters.
|
|
||||||
* `libavdevice` provides an abstraction to access capture and playback devices.
|
|
||||||
* `libswresample` implements audio mixing and resampling routines.
|
|
||||||
* `libswscale` implements color conversion and scaling routines.
|
|
||||||
|
|
||||||
## Tools
|
|
||||||
|
|
||||||
* [ffmpeg](https://ffmpeg.org/ffmpeg.html) is a command line toolbox to
|
|
||||||
manipulate, convert and stream multimedia content.
|
|
||||||
* [ffplay](https://ffmpeg.org/ffplay.html) is a minimalistic multimedia player.
|
|
||||||
* [ffprobe](https://ffmpeg.org/ffprobe.html) is a simple analysis tool to inspect
|
|
||||||
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`.
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
The offline documentation is available in the **doc/** directory.
|
|
||||||
|
|
||||||
The online documentation is available in the main [website](https://ffmpeg.org)
|
|
||||||
and in the [wiki](https://trac.ffmpeg.org).
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
|
|
||||||
Coding examples are available in the **doc/examples** directory.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
FFmpeg codebase is mainly LGPL-licensed with optional components licensed under
|
|
||||||
GPL. Please refer to the LICENSE file for detailed information.
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Patches should be submitted to the ffmpeg-devel mailing list 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.
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
|
|
||||||
┌────────────────────────────────────────┐
|
|
||||||
│ RELEASE NOTES for FFmpeg 3.2 "Hypatia" │
|
|
||||||
└────────────────────────────────────────┘
|
|
||||||
|
|
||||||
The FFmpeg Project proudly presents FFmpeg 3.2 "Hypatia", about 4
|
|
||||||
months after the release of FFmpeg 3.1.
|
|
||||||
|
|
||||||
A complete Changelog is available at the root of the project, and the
|
|
||||||
complete Git history on http://source.ffmpeg.org.
|
|
||||||
|
|
||||||
We hope you will like this release as much as we enjoyed working on it, and
|
|
||||||
as usual, if you have any questions about it, or any FFmpeg related topic,
|
|
||||||
feel free to join us on the #ffmpeg IRC channel (on irc.freenode.net) or ask
|
|
||||||
on the mailing-lists.
|
|
||||||
9
arch.mak
9
arch.mak
@@ -1,17 +1,16 @@
|
|||||||
OBJS-$(HAVE_ARMV5TE) += $(ARMV5TE-OBJS) $(ARMV5TE-OBJS-yes)
|
OBJS-$(HAVE_ARMV5TE) += $(ARMV5TE-OBJS) $(ARMV5TE-OBJS-yes)
|
||||||
OBJS-$(HAVE_ARMV6) += $(ARMV6-OBJS) $(ARMV6-OBJS-yes)
|
OBJS-$(HAVE_ARMV6) += $(ARMV6-OBJS) $(ARMV6-OBJS-yes)
|
||||||
OBJS-$(HAVE_ARMV8) += $(ARMV8-OBJS) $(ARMV8-OBJS-yes)
|
|
||||||
OBJS-$(HAVE_VFP) += $(VFP-OBJS) $(VFP-OBJS-yes)
|
OBJS-$(HAVE_VFP) += $(VFP-OBJS) $(VFP-OBJS-yes)
|
||||||
OBJS-$(HAVE_NEON) += $(NEON-OBJS) $(NEON-OBJS-yes)
|
OBJS-$(HAVE_NEON) += $(NEON-OBJS) $(NEON-OBJS-yes)
|
||||||
|
|
||||||
OBJS-$(HAVE_MIPSFPU) += $(MIPSFPU-OBJS) $(MIPSFPU-OBJS-yes)
|
OBJS-$(HAVE_MIPSFPU) += $(MIPSFPU-OBJS) $(MIPSFPU-OBJS-yes)
|
||||||
OBJS-$(HAVE_MIPSDSP) += $(MIPSDSP-OBJS) $(MIPSDSP-OBJS-yes)
|
OBJS-$(HAVE_MIPS32R2) += $(MIPS32R2-OBJS) $(MIPS32R2-OBJS-yes)
|
||||||
|
OBJS-$(HAVE_MIPSDSPR1) += $(MIPSDSPR1-OBJS) $(MIPSDSPR1-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_MMI) += $(MMI-OBJS) $(MMI-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_VIS) += $(VIS-OBJS) $(VIS-OBJS-yes)
|
||||||
|
|
||||||
OBJS-$(HAVE_MMX) += $(MMX-OBJS) $(MMX-OBJS-yes)
|
OBJS-$(HAVE_MMX) += $(MMX-OBJS) $(MMX-OBJS-yes)
|
||||||
OBJS-$(HAVE_YASM) += $(YASM-OBJS) $(YASM-OBJS-yes)
|
OBJS-$(HAVE_YASM) += $(YASM-OBJS) $(YASM-OBJS-yes)
|
||||||
|
|||||||
599
cmdutils.c
599
cmdutils.c
File diff suppressed because it is too large
Load Diff
74
cmdutils.h
74
cmdutils.h
@@ -19,18 +19,17 @@
|
|||||||
* 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 CMDUTILS_H
|
#ifndef FFMPEG_CMDUTILS_H
|
||||||
#define CMDUTILS_H
|
#define FFMPEG_CMDUTILS_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "libavcodec/avcodec.h"
|
#include "libavcodec/avcodec.h"
|
||||||
#include "libavfilter/avfilter.h"
|
#include "libavfilter/avfilter.h"
|
||||||
#include "libavformat/avformat.h"
|
#include "libavformat/avformat.h"
|
||||||
#include "libswscale/swscale.h"
|
#include "libswscale/swscale.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef __MINGW32__
|
||||||
#undef main /* We don't want SDL to override our main() */
|
#undef main /* We don't want SDL to override our main() */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -44,12 +43,16 @@ extern const char program_name[];
|
|||||||
*/
|
*/
|
||||||
extern const int program_birth_year;
|
extern const int program_birth_year;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this year, defined by the program for show_banner()
|
||||||
|
*/
|
||||||
|
extern const int this_year;
|
||||||
|
|
||||||
extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
|
extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
|
||||||
extern AVFormatContext *avformat_opts;
|
extern AVFormatContext *avformat_opts;
|
||||||
extern AVDictionary *sws_dict;
|
extern struct SwsContext *sws_opts;
|
||||||
extern AVDictionary *swr_opts;
|
extern AVDictionary *swr_opts;
|
||||||
extern AVDictionary *format_opts, *codec_opts, *resample_opts;
|
extern AVDictionary *format_opts, *codec_opts, *resample_opts;
|
||||||
extern int hide_banner;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a program-specific cleanup routine.
|
* Register a program-specific cleanup routine.
|
||||||
@@ -59,12 +62,7 @@ void register_exit(void (*cb)(int ret));
|
|||||||
/**
|
/**
|
||||||
* Wraps exit with a program-specific cleanup routine.
|
* Wraps exit with a program-specific cleanup routine.
|
||||||
*/
|
*/
|
||||||
void exit_program(int ret) av_noreturn;
|
void exit_program(int ret);
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize dynamic library loading
|
|
||||||
*/
|
|
||||||
void init_dynload(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the cmdutils option system, in particular
|
* Initialize the cmdutils option system, in particular
|
||||||
@@ -105,12 +103,8 @@ 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(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.
|
||||||
*/
|
*/
|
||||||
@@ -282,7 +276,7 @@ typedef struct OptionGroup {
|
|||||||
AVDictionary *codec_opts;
|
AVDictionary *codec_opts;
|
||||||
AVDictionary *format_opts;
|
AVDictionary *format_opts;
|
||||||
AVDictionary *resample_opts;
|
AVDictionary *resample_opts;
|
||||||
AVDictionary *sws_dict;
|
struct SwsContext *sws_opts;
|
||||||
AVDictionary *swr_opts;
|
AVDictionary *swr_opts;
|
||||||
} OptionGroup;
|
} OptionGroup;
|
||||||
|
|
||||||
@@ -420,13 +414,6 @@ void show_banner(int argc, char **argv, const OptionDef *options);
|
|||||||
*/
|
*/
|
||||||
int show_version(void *optctx, const char *opt, const char *arg);
|
int show_version(void *optctx, const char *opt, const char *arg);
|
||||||
|
|
||||||
/**
|
|
||||||
* Print the build configuration of the program to stdout. The contents
|
|
||||||
* depend on the definition of FFMPEG_CONFIGURATION.
|
|
||||||
* This option processing function does not utilize the arguments.
|
|
||||||
*/
|
|
||||||
int show_buildconf(void *optctx, const char *opt, const char *arg);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print the license of the program to stdout. The license depends on
|
* Print the license of the program to stdout. The license depends on
|
||||||
* the license of the libraries compiled into the program.
|
* the license of the libraries compiled into the program.
|
||||||
@@ -436,31 +423,10 @@ int show_license(void *optctx, const char *opt, const char *arg);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Print a listing containing all the formats supported by the
|
* Print a listing containing all the formats supported by the
|
||||||
* program (including devices).
|
|
||||||
* This option processing function does not utilize the arguments.
|
|
||||||
*/
|
|
||||||
int show_formats(void *optctx, const char *opt, const char *arg);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print a listing containing all the devices supported by the
|
|
||||||
* program.
|
* program.
|
||||||
* This option processing function does not utilize the arguments.
|
* This option processing function does not utilize the arguments.
|
||||||
*/
|
*/
|
||||||
int show_devices(void *optctx, const char *opt, const char *arg);
|
int show_formats(void *optctx, const char *opt, const char *arg);
|
||||||
|
|
||||||
#if CONFIG_AVDEVICE
|
|
||||||
/**
|
|
||||||
* Print a listing containing autodetected sinks of the output device.
|
|
||||||
* Device name with options may be passed as an argument to limit results.
|
|
||||||
*/
|
|
||||||
int show_sinks(void *optctx, const char *opt, const char *arg);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print a listing containing autodetected sources of the input device.
|
|
||||||
* Device name with options may be passed as an argument to limit results.
|
|
||||||
*/
|
|
||||||
int show_sources(void *optctx, const char *opt, const char *arg);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print a listing containing all the codecs supported by the
|
* Print a listing containing all the codecs supported by the
|
||||||
@@ -526,7 +492,7 @@ int show_sample_fmts(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.
|
||||||
*/
|
*/
|
||||||
int show_colors(void *optctx, const char *opt, const char *arg);
|
void show_colors(void *optctx, const char *opt, const char *arg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a positive value if a line read from standard input
|
* Return a positive value if a line read from standard input
|
||||||
@@ -534,6 +500,18 @@ int show_colors(void *optctx, const char *opt, const char *arg);
|
|||||||
*/
|
*/
|
||||||
int read_yesno(void);
|
int read_yesno(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the file with name filename, and put its content in a newly
|
||||||
|
* allocated 0-terminated buffer.
|
||||||
|
*
|
||||||
|
* @param filename file to read from
|
||||||
|
* @param bufptr location where pointer to buffer is returned
|
||||||
|
* @param size location where size of buffer is returned
|
||||||
|
* @return >= 0 in case of success, a negative value corresponding to an
|
||||||
|
* AVERROR error code in case of failure.
|
||||||
|
*/
|
||||||
|
int cmdutils_read_file(const char *filename, char **bufptr, size_t *size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a file corresponding to a preset file.
|
* Get a file corresponding to a preset file.
|
||||||
*
|
*
|
||||||
@@ -590,6 +568,4 @@ void *grow_array(void *array, int elem_size, int *size, int new_size);
|
|||||||
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(AVStream *st);
|
|
||||||
|
|
||||||
#endif /* CMDUTILS_H */
|
#endif /* CMDUTILS_H */
|
||||||
|
|||||||
@@ -4,9 +4,7 @@
|
|||||||
{ "help" , 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" },
|
{ "-help" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" },
|
||||||
{ "version" , OPT_EXIT, {.func_arg = show_version}, "show version" },
|
{ "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" },
|
{ "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" },
|
{ "codecs" , OPT_EXIT, {.func_arg = show_codecs }, "show available codecs" },
|
||||||
{ "decoders" , OPT_EXIT, {.func_arg = show_decoders }, "show available decoders" },
|
{ "decoders" , OPT_EXIT, {.func_arg = show_decoders }, "show available decoders" },
|
||||||
{ "encoders" , OPT_EXIT, {.func_arg = show_encoders }, "show available encoders" },
|
{ "encoders" , OPT_EXIT, {.func_arg = show_encoders }, "show available encoders" },
|
||||||
@@ -22,14 +20,6 @@
|
|||||||
{ "report" , 0, {(void*)opt_report}, "generate a report" },
|
{ "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" },
|
{ "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" },
|
{ "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
|
#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" },
|
{ "opencl_options", HAS_ARG, {.func_arg = opt_opencl}, "set OpenCL environment options" },
|
||||||
#endif
|
#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
|
|
||||||
|
|||||||
@@ -1,278 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
65
common.mak
65
common.mak
@@ -5,20 +5,12 @@
|
|||||||
# first so "all" becomes default target
|
# first so "all" becomes default target
|
||||||
all: all-yes
|
all: all-yes
|
||||||
|
|
||||||
DEFAULT_YASMD=.dbg
|
|
||||||
|
|
||||||
ifeq ($(DBG),1)
|
|
||||||
YASMD=$(DEFAULT_YASMD)
|
|
||||||
else
|
|
||||||
YASMD=
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifndef SUBDIR
|
ifndef SUBDIR
|
||||||
|
|
||||||
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 YASM AR LD STRIP CP WINDRES
|
BRIEF = CC CXX HOSTCC HOSTLD AS YASM AR LD STRIP CP
|
||||||
SILENT = DEPCC DEPHOSTCC DEPAS DEPYASM RANLIB RM
|
SILENT = DEPCC DEPHOSTCC DEPAS DEPYASM RANLIB RM
|
||||||
|
|
||||||
MSG = $@
|
MSG = $@
|
||||||
@@ -32,14 +24,12 @@ endif
|
|||||||
ALLFFLIBS = avcodec avdevice avfilter avformat avresample 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_PATH)/
|
||||||
CPPFLAGS := $(IFLAGS) $(CPPFLAGS)
|
CPPFLAGS := $(IFLAGS) $(CPPFLAGS)
|
||||||
CFLAGS += $(ECFLAGS)
|
CFLAGS += $(ECFLAGS)
|
||||||
CCFLAGS = $(CPPFLAGS) $(CFLAGS)
|
CCFLAGS = $(CPPFLAGS) $(CFLAGS)
|
||||||
OBJCFLAGS += $(EOBJCFLAGS)
|
|
||||||
OBJCCFLAGS = $(CPPFLAGS) $(CFLAGS) $(OBJCFLAGS)
|
|
||||||
ASFLAGS := $(CPPFLAGS) $(ASFLAGS)
|
ASFLAGS := $(CPPFLAGS) $(ASFLAGS)
|
||||||
CXXFLAGS := $(CPPFLAGS) $(CFLAGS) $(CXXFLAGS)
|
CXXFLAGS += $(CPPFLAGS) $(CFLAGS)
|
||||||
YASMFLAGS += $(IFLAGS:%=%/) -Pconfig.asm
|
YASMFLAGS += $(IFLAGS:%=%/) -Pconfig.asm
|
||||||
|
|
||||||
HOSTCCFLAGS = $(IFLAGS) $(HOSTCPPFLAGS) $(HOSTCFLAGS)
|
HOSTCCFLAGS = $(IFLAGS) $(HOSTCPPFLAGS) $(HOSTCFLAGS)
|
||||||
@@ -47,14 +37,12 @@ LDFLAGS := $(ALLFFLIBS:%=$(LD_PATH)lib%) $(LDFLAGS)
|
|||||||
|
|
||||||
define COMPILE
|
define COMPILE
|
||||||
$(call $(1)DEP,$(1))
|
$(call $(1)DEP,$(1))
|
||||||
$($(1)) $($(1)FLAGS) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<)
|
$($(1)) $($(1)FLAGS) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $<
|
||||||
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_HOSTC = $(call COMPILE,HOSTCC)
|
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(COMPILE_C)
|
$(COMPILE_C)
|
||||||
@@ -62,28 +50,22 @@ COMPILE_HOSTC = $(call COMPILE,HOSTCC)
|
|||||||
%.o: %.cpp
|
%.o: %.cpp
|
||||||
$(COMPILE_CXX)
|
$(COMPILE_CXX)
|
||||||
|
|
||||||
%.o: %.m
|
|
||||||
$(COMPILE_M)
|
|
||||||
|
|
||||||
%.s: %.c
|
%.s: %.c
|
||||||
$(CC) $(CCFLAGS) -S -o $@ $<
|
$(CC) $(CPPFLAGS) $(CFLAGS) -S -o $@ $<
|
||||||
|
|
||||||
%.o: %.S
|
%.o: %.S
|
||||||
$(COMPILE_S)
|
$(COMPILE_S)
|
||||||
|
|
||||||
%_host.o: %.c
|
|
||||||
$(COMPILE_HOSTC)
|
|
||||||
|
|
||||||
%.o: %.rc
|
|
||||||
$(WINDRES) $(IFLAGS) --preprocessor "$(DEPWINDRES) -E -xc-header -DRC_INVOKED $(CC_DEPFLAGS)" -o $@ $<
|
|
||||||
|
|
||||||
%.i: %.c
|
%.i: %.c
|
||||||
$(CC) $(CCFLAGS) $(CC_E) $<
|
$(CC) $(CCFLAGS) $(CC_E) $<
|
||||||
|
|
||||||
%.h.c:
|
%.h.c:
|
||||||
$(Q)echo '#include "$*.h"' >$@
|
$(Q)echo '#include "$*.h"' >$@
|
||||||
|
|
||||||
%.c %.h %.ver: TAG = GEN
|
%.ver: %.v
|
||||||
|
$(Q)sed 's/$$MAJOR/$($(basename $(@F))_VERSION_MAJOR)/' $^ > $@
|
||||||
|
|
||||||
|
%.c %.h: 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:
|
%.h:
|
||||||
@@ -100,17 +82,16 @@ endif
|
|||||||
include $(SRC_PATH)/arch.mak
|
include $(SRC_PATH)/arch.mak
|
||||||
|
|
||||||
OBJS += $(OBJS-yes)
|
OBJS += $(OBJS-yes)
|
||||||
SLIBOBJS += $(SLIBOBJS-yes)
|
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)) $(EXTRALIBS)
|
FFEXTRALIBS := $(LDLIBS:%=$(LD_LIB)) $(EXTRALIBS)
|
||||||
|
|
||||||
|
EXAMPLES := $(EXAMPLES:%=$(SUBDIR)%-example$(EXESUF))
|
||||||
OBJS := $(sort $(OBJS:%=$(SUBDIR)%))
|
OBJS := $(sort $(OBJS:%=$(SUBDIR)%))
|
||||||
SLIBOBJS := $(sort $(SLIBOBJS:%=$(SUBDIR)%))
|
TESTOBJS := $(TESTOBJS:%=$(SUBDIR)%) $(TESTPROGS:%=$(SUBDIR)%-test.o)
|
||||||
TESTOBJS := $(TESTOBJS:%=$(SUBDIR)tests/%) $(TESTPROGS:%=$(SUBDIR)tests/%.o)
|
TESTPROGS := $(TESTPROGS:%=$(SUBDIR)%-test$(EXESUF))
|
||||||
TESTPROGS := $(TESTPROGS:%=$(SUBDIR)tests/%$(EXESUF))
|
|
||||||
HOSTOBJS := $(HOSTPROGS:%=$(SUBDIR)%.o)
|
HOSTOBJS := $(HOSTPROGS:%=$(SUBDIR)%.o)
|
||||||
HOSTPROGS := $(HOSTPROGS:%=$(SUBDIR)%$(HOSTEXESUF))
|
HOSTPROGS := $(HOSTPROGS:%=$(SUBDIR)%$(HOSTEXESUF))
|
||||||
TOOLS += $(TOOLS-yes)
|
TOOLS += $(TOOLS-yes)
|
||||||
@@ -118,9 +99,8 @@ TOOLOBJS := $(TOOLS:%=tools/%.o)
|
|||||||
TOOLS := $(TOOLS:%=tools/%$(EXESUF))
|
TOOLS := $(TOOLS:%=tools/%$(EXESUF))
|
||||||
HEADERS += $(HEADERS-yes)
|
HEADERS += $(HEADERS-yes)
|
||||||
|
|
||||||
PATH_LIBNAME = $(foreach NAME,$(1),lib$(NAME)/$($(2)LIBNAME))
|
PATH_LIBNAME = $(foreach NAME,$(1),lib$(NAME)/$($(CONFIG_SHARED:yes=S)LIBNAME))
|
||||||
DEP_LIBS := $(foreach lib,$(FFLIBS),$(call PATH_LIBNAME,$(lib),$(CONFIG_SHARED:yes=S)))
|
DEP_LIBS := $(foreach lib,$(FFLIBS),$(call PATH_LIBNAME,$(lib)))
|
||||||
STATIC_DEP_LIBS := $(foreach lib,$(FFLIBS),$(call PATH_LIBNAME,$(lib)))
|
|
||||||
|
|
||||||
SRC_DIR := $(SRC_PATH)/lib$(NAME)
|
SRC_DIR := $(SRC_PATH)/lib$(NAME)
|
||||||
ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)/$(ARCH)/*.h))
|
ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)/$(ARCH)/*.h))
|
||||||
@@ -133,29 +113,30 @@ checkheaders: $(HOBJS)
|
|||||||
alltools: $(TOOLS)
|
alltools: $(TOOLS)
|
||||||
|
|
||||||
$(HOSTOBJS): %.o: %.c
|
$(HOSTOBJS): %.o: %.c
|
||||||
$(COMPILE_HOSTC)
|
$(call COMPILE,HOSTCC)
|
||||||
|
|
||||||
$(HOSTPROGS): %$(HOSTEXESUF): %.o
|
$(HOSTPROGS): %$(HOSTEXESUF): %.o
|
||||||
$(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTLIBS)
|
$(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)))
|
|
||||||
$(TESTOBJS): | $(sort $(dir $(TESTOBJS)))
|
$(TESTOBJS): | $(sort $(dir $(TESTOBJS)))
|
||||||
$(TOOLOBJS): | tools
|
$(TOOLOBJS): | tools
|
||||||
|
|
||||||
OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(SLIBOBJS) $(TESTOBJS))
|
OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(TESTOBJS))
|
||||||
|
|
||||||
CLEANSUFFIXES = *.d *.o *~ *.h.c *.gcda *.gcno *.map *.ver *.ho *$(DEFAULT_YASMD).asm
|
CLEANSUFFIXES = *.d *.o *~ *.h.c *.map *.ver *.ho *.gcno *.gcda
|
||||||
DISTCLEANSUFFIXES = *.pc
|
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
|
||||||
clean::
|
clean::
|
||||||
$(RM) $(HOSTPROGS) $(TESTPROGS) $(TOOLS)
|
$(RM) $(OBJS) $(OBJS:.o=.d)
|
||||||
|
$(RM) $(HOSTPROGS)
|
||||||
|
$(RM) $(TOOLS)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(RULES))
|
$(eval $(RULES))
|
||||||
|
|
||||||
-include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d) $(SLIBOBJS:.o=.d)) $(OBJS:.o=$(DEFAULT_YASMD).d)
|
-include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d))
|
||||||
|
|||||||
@@ -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 COMPAT_AIX_MATH_H
|
#ifndef FFMPEG_COMPAT_AIX_MATH_H
|
||||||
#define COMPAT_AIX_MATH_H
|
#define FFMPEG_COMPAT_AIX_MATH_H
|
||||||
|
|
||||||
#define class class_in_math_h_causes_problems
|
#define class class_in_math_h_causes_problems
|
||||||
|
|
||||||
@@ -28,4 +28,4 @@
|
|||||||
|
|
||||||
#undef class
|
#undef class
|
||||||
|
|
||||||
#endif /* COMPAT_AIX_MATH_H */
|
#endif /* FFMPEG_COMPAT_AIX_MATH_H */
|
||||||
|
|||||||
@@ -13,8 +13,7 @@
|
|||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
|
||||||
// MA 02110-1301 USA, or visit
|
|
||||||
// http://www.gnu.org/copyleft/gpl.html .
|
// http://www.gnu.org/copyleft/gpl.html .
|
||||||
//
|
//
|
||||||
// As a special exception, I give you permission to link to the
|
// As a special exception, I give you permission to link to the
|
||||||
@@ -38,9 +37,40 @@
|
|||||||
#ifndef __AVISYNTH_C__
|
#ifndef __AVISYNTH_C__
|
||||||
#define __AVISYNTH_C__
|
#define __AVISYNTH_C__
|
||||||
|
|
||||||
#include "avs/config.h"
|
#ifdef __cplusplus
|
||||||
#include "avs/capi.h"
|
# define EXTERN_C extern "C"
|
||||||
#include "avs/types.h"
|
#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
|
||||||
|
|
||||||
|
typedef unsigned char BYTE;
|
||||||
|
#ifdef __GNUC__
|
||||||
|
typedef long long int INT64;
|
||||||
|
#else
|
||||||
|
typedef __int64 INT64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
@@ -48,8 +78,8 @@
|
|||||||
// Constants
|
// Constants
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef __AVISYNTH_6_H__
|
#ifndef __AVISYNTH_H__
|
||||||
enum { AVISYNTH_INTERFACE_VERSION = 6 };
|
enum { AVISYNTH_INTERFACE_VERSION = 4 };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum {AVS_SAMPLE_INT8 = 1<<0,
|
enum {AVS_SAMPLE_INT8 = 1<<0,
|
||||||
@@ -75,149 +105,54 @@ enum {AVS_PLANAR_Y=1<<0,
|
|||||||
AVS_PLANAR_B_ALIGNED=AVS_PLANAR_B|AVS_PLANAR_ALIGNED};
|
AVS_PLANAR_B_ALIGNED=AVS_PLANAR_B|AVS_PLANAR_ALIGNED};
|
||||||
|
|
||||||
// Colorspace properties.
|
// Colorspace properties.
|
||||||
enum {
|
enum {AVS_CS_BGR = 1<<28,
|
||||||
AVS_CS_YUVA = 1 << 27,
|
AVS_CS_YUV = 1<<29,
|
||||||
AVS_CS_BGR = 1 << 28,
|
AVS_CS_INTERLEAVED = 1<<30,
|
||||||
AVS_CS_YUV = 1 << 29,
|
AVS_CS_PLANAR = 1<<31,
|
||||||
AVS_CS_INTERLEAVED = 1 << 30,
|
|
||||||
AVS_CS_PLANAR = 1 << 31,
|
|
||||||
|
|
||||||
AVS_CS_SHIFT_SUB_WIDTH = 0,
|
AVS_CS_SHIFT_SUB_WIDTH = 0,
|
||||||
AVS_CS_SHIFT_SUB_HEIGHT = 8,
|
AVS_CS_SHIFT_SUB_HEIGHT = 1 << 3,
|
||||||
AVS_CS_SHIFT_SAMPLE_BITS = 16,
|
AVS_CS_SHIFT_SAMPLE_BITS = 1 << 4,
|
||||||
|
|
||||||
AVS_CS_SUB_WIDTH_MASK = 7 << AVS_CS_SHIFT_SUB_WIDTH,
|
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_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_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_SUB_WIDTH_4 = 1 << AVS_CS_SHIFT_SUB_WIDTH, // YUV9, YV411
|
||||||
|
|
||||||
AVS_CS_VPLANEFIRST = 1 << 3, // YV12, YV16, YV24, YV411, YUV9
|
AVS_CS_VPLANEFIRST = 1 << 3, // YV12, YV16, YV24, YV411, YUV9
|
||||||
AVS_CS_UPLANEFIRST = 1 << 4, // I420
|
AVS_CS_UPLANEFIRST = 1 << 4, // I420
|
||||||
|
|
||||||
AVS_CS_SUB_HEIGHT_MASK = 7 << AVS_CS_SHIFT_SUB_HEIGHT,
|
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_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_2 = 0 << AVS_CS_SHIFT_SUB_HEIGHT, // YV12, I420
|
||||||
AVS_CS_SUB_HEIGHT_4 = 1 << AVS_CS_SHIFT_SUB_HEIGHT, // YUV9
|
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_MASK = 7 << AVS_CS_SHIFT_SAMPLE_BITS,
|
||||||
AVS_CS_SAMPLE_BITS_8 = 0 << AVS_CS_SHIFT_SAMPLE_BITS,
|
AVS_CS_SAMPLE_BITS_8 = 0 << AVS_CS_SHIFT_SAMPLE_BITS,
|
||||||
AVS_CS_SAMPLE_BITS_10 = 5 << AVS_CS_SHIFT_SAMPLE_BITS,
|
AVS_CS_SAMPLE_BITS_16 = 1 << AVS_CS_SHIFT_SAMPLE_BITS,
|
||||||
AVS_CS_SAMPLE_BITS_12 = 6 << AVS_CS_SHIFT_SAMPLE_BITS,
|
AVS_CS_SAMPLE_BITS_32 = 2 << AVS_CS_SHIFT_SAMPLE_BITS,
|
||||||
AVS_CS_SAMPLE_BITS_14 = 7 << 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_YUVA | 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),
|
|
||||||
|
|
||||||
AVS_CS_RGB_TYPE = 1 << 0,
|
|
||||||
AVS_CS_RGBA_TYPE = 1 << 1,
|
|
||||||
|
|
||||||
AVS_CS_GENERIC_YUV420 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_2 | AVS_CS_SUB_WIDTH_2, // 4:2:0 planar
|
|
||||||
AVS_CS_GENERIC_YUV422 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_2, // 4:2:2 planar
|
|
||||||
AVS_CS_GENERIC_YUV444 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_1, // 4:4:4 planar
|
|
||||||
AVS_CS_GENERIC_Y = AVS_CS_PLANAR | AVS_CS_INTERLEAVED | AVS_CS_YUV, // Y only (4:0:0)
|
|
||||||
AVS_CS_GENERIC_RGBP = AVS_CS_PLANAR | AVS_CS_BGR | AVS_CS_RGB_TYPE, // planar RGB
|
|
||||||
AVS_CS_GENERIC_RGBAP = AVS_CS_PLANAR | AVS_CS_BGR | AVS_CS_RGBA_TYPE, // planar RGBA
|
|
||||||
AVS_CS_GENERIC_YUVA420 = AVS_CS_PLANAR | AVS_CS_YUVA | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_2 | AVS_CS_SUB_WIDTH_2, // 4:2:0:A planar
|
|
||||||
AVS_CS_GENERIC_YUVA422 = AVS_CS_PLANAR | AVS_CS_YUVA | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_2, // 4:2:2:A planar
|
|
||||||
AVS_CS_GENERIC_YUVA444 = AVS_CS_PLANAR | AVS_CS_YUVA | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_1 }; // 4:4:4:A planar
|
|
||||||
|
|
||||||
|
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
|
// Specific colorformats
|
||||||
enum {
|
enum {
|
||||||
AVS_CS_UNKNOWN = 0,
|
AVS_CS_UNKNOWN = 0,
|
||||||
AVS_CS_BGR24 = AVS_CS_RGB_TYPE | AVS_CS_BGR | AVS_CS_INTERLEAVED,
|
AVS_CS_BGR24 = 1<<0 | AVS_CS_BGR | AVS_CS_INTERLEAVED,
|
||||||
AVS_CS_BGR32 = AVS_CS_RGBA_TYPE | 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_YUY2 = 1<<2 | AVS_CS_YUV | AVS_CS_INTERLEAVED,
|
||||||
// AVS_CS_YV12 = 1<<3 Reserved
|
// AVS_CS_YV12 = 1<<3 Reserved
|
||||||
// AVS_CS_I420 = 1<<4 Reserved
|
// AVS_CS_I420 = 1<<4 Reserved
|
||||||
AVS_CS_RAW32 = 1<<5 | AVS_CS_INTERLEAVED,
|
AVS_CS_RAW32 = 1<<5 | AVS_CS_INTERLEAVED,
|
||||||
|
|
||||||
AVS_CS_YV24 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_8, // YVU 4:4:4 planar
|
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_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_8, // YVU 4:2:2 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_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_8, // YVU 4:2:0 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_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_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_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_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_GENERIC_Y | AVS_CS_SAMPLE_BITS_8, // Y 4:0:0 planar
|
AVS_CS_Y8 = AVS_CS_PLANAR | AVS_CS_INTERLEAVED | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 // Y 4:0:0 planar
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
// AVS16: new planar constants go live! Experimental PF 160613
|
|
||||||
// 10-12-14 bit + planar RGB + BRG48/64 160725
|
|
||||||
AVS_CS_YUV444P10 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_10, // YUV 4:4:4 10bit samples
|
|
||||||
AVS_CS_YUV422P10 = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_10, // YUV 4:2:2 10bit samples
|
|
||||||
AVS_CS_YUV420P10 = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_10, // YUV 4:2:0 10bit samples
|
|
||||||
AVS_CS_Y10 = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_10, // Y 4:0:0 10bit samples
|
|
||||||
|
|
||||||
AVS_CS_YUV444P12 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_12, // YUV 4:4:4 12bit samples
|
|
||||||
AVS_CS_YUV422P12 = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_12, // YUV 4:2:2 12bit samples
|
|
||||||
AVS_CS_YUV420P12 = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_12, // YUV 4:2:0 12bit samples
|
|
||||||
AVS_CS_Y12 = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_12, // Y 4:0:0 12bit samples
|
|
||||||
|
|
||||||
AVS_CS_YUV444P14 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_14, // YUV 4:4:4 14bit samples
|
|
||||||
AVS_CS_YUV422P14 = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_14, // YUV 4:2:2 14bit samples
|
|
||||||
AVS_CS_YUV420P14 = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_14, // YUV 4:2:0 14bit samples
|
|
||||||
AVS_CS_Y14 = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_14, // Y 4:0:0 14bit samples
|
|
||||||
|
|
||||||
AVS_CS_YUV444P16 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_16, // YUV 4:4:4 16bit samples
|
|
||||||
AVS_CS_YUV422P16 = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_16, // YUV 4:2:2 16bit samples
|
|
||||||
AVS_CS_YUV420P16 = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_16, // YUV 4:2:0 16bit samples
|
|
||||||
AVS_CS_Y16 = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_16, // Y 4:0:0 16bit samples
|
|
||||||
|
|
||||||
// 32 bit samples (float)
|
|
||||||
AVS_CS_YUV444PS = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_32, // YUV 4:4:4 32bit samples
|
|
||||||
AVS_CS_YUV422PS = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_32, // YUV 4:2:2 32bit samples
|
|
||||||
AVS_CS_YUV420PS = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_32, // YUV 4:2:0 32bit samples
|
|
||||||
AVS_CS_Y32 = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_32, // Y 4:0:0 32bit samples
|
|
||||||
|
|
||||||
// RGB packed
|
|
||||||
AVS_CS_BGR48 = AVS_CS_RGB_TYPE | AVS_CS_BGR | AVS_CS_INTERLEAVED | AVS_CS_SAMPLE_BITS_16, // BGR 3x16 bit
|
|
||||||
AVS_CS_BGR64 = AVS_CS_RGBA_TYPE | AVS_CS_BGR | AVS_CS_INTERLEAVED | AVS_CS_SAMPLE_BITS_16, // BGR 4x16 bit
|
|
||||||
// no packed 32 bit (float) support for these legacy types
|
|
||||||
|
|
||||||
// RGB planar
|
|
||||||
AVS_CS_RGBP = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_8, // Planar RGB 8 bit samples
|
|
||||||
AVS_CS_RGBP10 = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_10, // Planar RGB 10bit samples
|
|
||||||
AVS_CS_RGBP12 = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_12, // Planar RGB 12bit samples
|
|
||||||
AVS_CS_RGBP14 = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_14, // Planar RGB 14bit samples
|
|
||||||
AVS_CS_RGBP16 = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_16, // Planar RGB 16bit samples
|
|
||||||
AVS_CS_RGBPS = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_32, // Planar RGB 32bit samples
|
|
||||||
|
|
||||||
// RGBA planar
|
|
||||||
AVS_CS_RGBAP = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_8, // Planar RGBA 8 bit samples
|
|
||||||
AVS_CS_RGBAP10 = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_10, // Planar RGBA 10bit samples
|
|
||||||
AVS_CS_RGBAP12 = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_12, // Planar RGBA 12bit samples
|
|
||||||
AVS_CS_RGBAP14 = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_14, // Planar RGBA 14bit samples
|
|
||||||
AVS_CS_RGBAP16 = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_16, // Planar RGBA 16bit samples
|
|
||||||
AVS_CS_RGBAPS = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_32, // Planar RGBA 32bit samples
|
|
||||||
|
|
||||||
// Planar YUVA
|
|
||||||
AVS_CS_YUVA444 = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_8, // YUVA 4:4:4 8bit samples
|
|
||||||
AVS_CS_YUVA422 = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_8, // YUVA 4:2:2 8bit samples
|
|
||||||
AVS_CS_YUVA420 = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_8, // YUVA 4:2:0 8bit samples
|
|
||||||
|
|
||||||
AVS_CS_YUVA444P10 = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_10, // YUVA 4:4:4 10bit samples
|
|
||||||
AVS_CS_YUVA422P10 = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_10, // YUVA 4:2:2 10bit samples
|
|
||||||
AVS_CS_YUVA420P10 = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_10, // YUVA 4:2:0 10bit samples
|
|
||||||
|
|
||||||
AVS_CS_YUVA444P12 = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_12, // YUVA 4:4:4 12bit samples
|
|
||||||
AVS_CS_YUVA422P12 = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_12, // YUVA 4:2:2 12bit samples
|
|
||||||
AVS_CS_YUVA420P12 = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_12, // YUVA 4:2:0 12bit samples
|
|
||||||
|
|
||||||
AVS_CS_YUVA444P14 = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_14, // YUVA 4:4:4 14bit samples
|
|
||||||
AVS_CS_YUVA422P14 = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_14, // YUVA 4:2:2 14bit samples
|
|
||||||
AVS_CS_YUVA420P14 = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_14, // YUVA 4:2:0 14bit samples
|
|
||||||
|
|
||||||
AVS_CS_YUVA444P16 = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_16, // YUVA 4:4:4 16bit samples
|
|
||||||
AVS_CS_YUVA422P16 = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_16, // YUVA 4:2:2 16bit samples
|
|
||||||
AVS_CS_YUVA420P16 = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_16, // YUVA 4:2:0 16bit samples
|
|
||||||
|
|
||||||
AVS_CS_YUVA444PS = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_32, // YUVA 4:4:4 32bit samples
|
|
||||||
AVS_CS_YUVA422PS = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_32, // YUVA 4:2:2 32bit samples
|
|
||||||
AVS_CS_YUVA420PS = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_32, // YUVA 4:2:0 32bit samples
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -244,66 +179,15 @@ enum { //SUBTYPES
|
|||||||
AVS_FILTER_OUTPUT_TYPE_DIFFERENT=4};
|
AVS_FILTER_OUTPUT_TYPE_DIFFERENT=4};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
// New 2.6 explicitly defined cache hints.
|
AVS_CACHE_NOTHING=0,
|
||||||
AVS_CACHE_NOTHING=10, // Do not cache video.
|
AVS_CACHE_RANGE=1,
|
||||||
AVS_CACHE_WINDOW=11, // Hard protect upto X frames within a range of X from the current frame N.
|
AVS_CACHE_ALL=2,
|
||||||
AVS_CACHE_GENERIC=12, // LRU cache upto X frames.
|
AVS_CACHE_AUDIO=3,
|
||||||
AVS_CACHE_FORCE_GENERIC=13, // LRU cache upto X frames, override any previous CACHE_WINDOW.
|
AVS_CACHE_AUDIO_NONE=4,
|
||||||
|
AVS_CACHE_AUDIO_AUTO=5
|
||||||
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
|
#define AVS_FRAME_ALIGN 16
|
||||||
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_Clip AVS_Clip;
|
||||||
typedef struct AVS_ScriptEnvironment AVS_ScriptEnvironment;
|
typedef struct AVS_ScriptEnvironment AVS_ScriptEnvironment;
|
||||||
@@ -342,10 +226,10 @@ AVSC_INLINE int avs_is_rgb(const AVS_VideoInfo * p)
|
|||||||
{ return !!(p->pixel_type&AVS_CS_BGR); }
|
{ return !!(p->pixel_type&AVS_CS_BGR); }
|
||||||
|
|
||||||
AVSC_INLINE int avs_is_rgb24(const AVS_VideoInfo * p)
|
AVSC_INLINE int avs_is_rgb24(const AVS_VideoInfo * p)
|
||||||
{ return ((p->pixel_type&AVS_CS_BGR24)==AVS_CS_BGR24) && ((p->pixel_type & AVS_CS_SAMPLE_BITS_MASK) == AVS_CS_SAMPLE_BITS_8); }
|
{ return (p->pixel_type&AVS_CS_BGR24)==AVS_CS_BGR24; } // Clear out additional properties
|
||||||
|
|
||||||
AVSC_INLINE int avs_is_rgb32(const AVS_VideoInfo * p)
|
AVSC_INLINE int avs_is_rgb32(const AVS_VideoInfo * p)
|
||||||
{ return ((p->pixel_type&AVS_CS_BGR32)==AVS_CS_BGR32) && ((p->pixel_type & AVS_CS_SAMPLE_BITS_MASK) == AVS_CS_SAMPLE_BITS_8); }
|
{ return (p->pixel_type & AVS_CS_BGR32) == AVS_CS_BGR32 ; }
|
||||||
|
|
||||||
AVSC_INLINE int avs_is_yuv(const AVS_VideoInfo * p)
|
AVSC_INLINE int avs_is_yuv(const AVS_VideoInfo * p)
|
||||||
{ return !!(p->pixel_type&AVS_CS_YUV ); }
|
{ return !!(p->pixel_type&AVS_CS_YUV ); }
|
||||||
@@ -353,59 +237,29 @@ AVSC_INLINE int avs_is_yuv(const AVS_VideoInfo * p)
|
|||||||
AVSC_INLINE int avs_is_yuy2(const AVS_VideoInfo * p)
|
AVSC_INLINE int avs_is_yuy2(const AVS_VideoInfo * p)
|
||||||
{ return (p->pixel_type & AVS_CS_YUY2) == AVS_CS_YUY2; }
|
{ return (p->pixel_type & AVS_CS_YUY2) == AVS_CS_YUY2; }
|
||||||
|
|
||||||
AVSC_API(int, avs_is_rgb48)(const AVS_VideoInfo * p);
|
AVSC_INLINE int avs_is_yv24(const AVS_VideoInfo * p)
|
||||||
|
{ return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV24 & AVS_CS_PLANAR_FILTER); }
|
||||||
|
|
||||||
AVSC_API(int, avs_is_rgb64)(const AVS_VideoInfo * p);
|
AVSC_INLINE int avs_is_yv16(const AVS_VideoInfo * p)
|
||||||
|
{ return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV16 & AVS_CS_PLANAR_FILTER); }
|
||||||
|
|
||||||
AVSC_API(int, avs_is_yv24)(const AVS_VideoInfo * p);
|
AVSC_INLINE int avs_is_yv12(const AVS_VideoInfo * p)
|
||||||
|
{ return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV12 & AVS_CS_PLANAR_FILTER); }
|
||||||
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_API(int, avs_is_yuv444p16)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_yuv422p16)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_yuv420p16)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_y16)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_yuv444ps)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_yuv422ps)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_yuv420ps)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_y32)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_444)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_422)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_420)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_y)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_yuva)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_planar_rgb)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_planar_rgba)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
|
AVSC_INLINE int avs_is_yv411(const AVS_VideoInfo * p)
|
||||||
|
{ return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV411 & AVS_CS_PLANAR_FILTER); }
|
||||||
|
|
||||||
|
AVSC_INLINE int avs_is_y8(const AVS_VideoInfo * p)
|
||||||
|
{ return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_Y8 & AVS_CS_PLANAR_FILTER); }
|
||||||
|
|
||||||
AVSC_INLINE int avs_is_property(const AVS_VideoInfo * p, int property)
|
AVSC_INLINE int avs_is_property(const AVS_VideoInfo * p, int property)
|
||||||
{ return ((p->image_type & property)==property ); }
|
{ return ((p->pixel_type & property)==property ); }
|
||||||
|
|
||||||
AVSC_INLINE int avs_is_planar(const AVS_VideoInfo * p)
|
AVSC_INLINE int avs_is_planar(const AVS_VideoInfo * p)
|
||||||
{ return !!(p->pixel_type & AVS_CS_PLANAR); }
|
{ 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_color_space(const AVS_VideoInfo * p, int c_space)
|
||||||
|
{ return avs_is_planar(p) ? ((p->pixel_type & AVS_CS_PLANAR_MASK) == (c_space & AVS_CS_PLANAR_FILTER)) : ((p->pixel_type & c_space) == c_space); }
|
||||||
|
|
||||||
AVSC_INLINE int avs_is_field_based(const AVS_VideoInfo * p)
|
AVSC_INLINE int avs_is_field_based(const AVS_VideoInfo * p)
|
||||||
{ return !!(p->image_type & AVS_IT_FIELDBASED); }
|
{ return !!(p->image_type & AVS_IT_FIELDBASED); }
|
||||||
@@ -419,18 +273,25 @@ AVSC_INLINE int avs_is_bff(const AVS_VideoInfo * p)
|
|||||||
AVSC_INLINE int avs_is_tff(const AVS_VideoInfo * p)
|
AVSC_INLINE int avs_is_tff(const AVS_VideoInfo * p)
|
||||||
{ return !!(p->image_type & AVS_IT_TFF); }
|
{ return !!(p->image_type & AVS_IT_TFF); }
|
||||||
|
|
||||||
AVSC_API(int, avs_get_plane_width_subsampling)(const AVS_VideoInfo * p, int plane);
|
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_API(int, avs_get_plane_height_subsampling)(const AVS_VideoInfo * p, int plane);
|
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)
|
||||||
AVSC_API(int, avs_bits_per_pixel)(const AVS_VideoInfo * p);
|
{ 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_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)
|
AVSC_INLINE int avs_samples_per_second(const AVS_VideoInfo * p)
|
||||||
{ return p->audio_samples_per_second; }
|
{ return p->audio_samples_per_second; }
|
||||||
@@ -488,19 +349,11 @@ AVSC_INLINE void avs_set_fps(AVS_VideoInfo * p, unsigned numerator, unsigned den
|
|||||||
p->fps_denominator = denominator/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)
|
AVSC_INLINE int avs_is_same_colorspace(AVS_VideoInfo * x, AVS_VideoInfo * y)
|
||||||
{
|
{
|
||||||
return (x->pixel_type == y->pixel_type)
|
return (x->pixel_type == y->pixel_type)
|
||||||
|| (avs_is_yv12(x) && avs_is_yv12(y));
|
|| (avs_is_yv12(x) && avs_is_yv12(y));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
AVSC_API(int, avs_num_components)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_component_size)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
AVSC_API(int, avs_bits_per_component)(const AVS_VideoInfo * p);
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@@ -537,38 +390,89 @@ typedef struct AVS_VideoFrame {
|
|||||||
} AVS_VideoFrame;
|
} AVS_VideoFrame;
|
||||||
|
|
||||||
// Access functions for 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) {
|
AVSC_INLINE int avs_get_pitch(const AVS_VideoFrame * p) {
|
||||||
return avs_get_pitch_p(p, 0);}
|
return p->pitch;}
|
||||||
#endif
|
|
||||||
|
|
||||||
AVSC_API(int, avs_get_row_size_p)(const AVS_VideoFrame * p, int plane);
|
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) {
|
AVSC_INLINE int avs_get_row_size(const AVS_VideoFrame * p) {
|
||||||
return p->row_size; }
|
return p->row_size; }
|
||||||
|
|
||||||
AVSC_API(int, avs_get_height_p)(const AVS_VideoFrame * p, int plane);
|
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_sizeUV;
|
||||||
|
else return 0;
|
||||||
|
case AVS_PLANAR_U_ALIGNED: case AVS_PLANAR_V_ALIGNED:
|
||||||
|
if (p->pitchUV) {
|
||||||
|
r = (p->row_sizeUV+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)); // Aligned rowsize
|
||||||
|
if (r < p->pitchUV)
|
||||||
|
return r;
|
||||||
|
return p->row_sizeUV;
|
||||||
|
} 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) {
|
AVSC_INLINE int avs_get_height(const AVS_VideoFrame * p) {
|
||||||
return p->height;}
|
return p->height;}
|
||||||
|
|
||||||
AVSC_API(const BYTE *, avs_get_read_ptr_p)(const AVS_VideoFrame * p, int plane);
|
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->heightUV;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return p->height;}
|
||||||
|
|
||||||
#ifdef AVS_IMPLICIT_FUNCTION_DECLARATION_ERROR
|
|
||||||
AVSC_INLINE const BYTE* avs_get_read_ptr(const AVS_VideoFrame * p) {
|
AVSC_INLINE const BYTE* avs_get_read_ptr(const AVS_VideoFrame * p) {
|
||||||
return avs_get_read_ptr_p(p, 0);}
|
return p->vfb->data + p->offset;}
|
||||||
#endif
|
|
||||||
|
|
||||||
AVSC_API(int, avs_is_writable)(const AVS_VideoFrame * p);
|
AVSC_INLINE const BYTE* 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_API(BYTE *, avs_get_write_ptr_p)(const AVS_VideoFrame * p, int plane);
|
AVSC_INLINE int avs_is_writable(const AVS_VideoFrame * p) {
|
||||||
|
return (p->refcount == 1 && p->vfb->refcount == 1);}
|
||||||
|
|
||||||
|
AVSC_INLINE BYTE* 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 BYTE* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#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 *);
|
AVSC_API(void, avs_release_video_frame)(AVS_VideoFrame *);
|
||||||
// makes a shallow copy of a video frame
|
// makes a shallow copy of a video frame
|
||||||
@@ -665,7 +569,7 @@ AVSC_INLINE AVS_Value avs_new_value_clip(AVS_Clip * v0)
|
|||||||
{ AVS_Value v; avs_set_to_clip(&v, v0); return v; }
|
{ AVS_Value v; avs_set_to_clip(&v, v0); return v; }
|
||||||
#endif
|
#endif
|
||||||
AVSC_INLINE AVS_Value avs_new_value_array(AVS_Value * v0, int size)
|
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 = (short)size; return v; }
|
{ AVS_Value v; v.type = 'a'; v.d.array = v0; v.array_size = size; return v; }
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@@ -753,16 +657,12 @@ enum {
|
|||||||
AVS_CPUF_SSSE3 = 0x200, // Core 2
|
AVS_CPUF_SSSE3 = 0x200, // Core 2
|
||||||
AVS_CPUF_SSE4 = 0x400, // Penryn, Wolfdale, Yorkfield
|
AVS_CPUF_SSE4 = 0x400, // Penryn, Wolfdale, Yorkfield
|
||||||
AVS_CPUF_SSE4_1 = 0x400,
|
AVS_CPUF_SSE4_1 = 0x400,
|
||||||
//AVS_CPUF_AVX = 0x800, // Sandy Bridge, Bulldozer
|
AVS_CPUF_SSE4_2 = 0x800, // Nehalem
|
||||||
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(const char *, avs_get_error)(AVS_ScriptEnvironment *); // return 0 if no error
|
||||||
|
|
||||||
AVSC_API(int, avs_get_cpu_flags)(AVS_ScriptEnvironment *);
|
AVSC_API(long, avs_get_cpu_flags)(AVS_ScriptEnvironment *);
|
||||||
AVSC_API(int, avs_check_version)(AVS_ScriptEnvironment *, int version);
|
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_save_string)(AVS_ScriptEnvironment *, const char* s, int length);
|
||||||
@@ -799,12 +699,12 @@ AVSC_API(AVS_VideoFrame *, avs_new_video_frame_a)(AVS_ScriptEnvironment *,
|
|||||||
AVSC_INLINE
|
AVSC_INLINE
|
||||||
AVS_VideoFrame * avs_new_video_frame(AVS_ScriptEnvironment * env,
|
AVS_VideoFrame * avs_new_video_frame(AVS_ScriptEnvironment * env,
|
||||||
const AVS_VideoInfo * vi)
|
const AVS_VideoInfo * vi)
|
||||||
{return avs_new_video_frame_a(env,vi,FRAME_ALIGN);}
|
{return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);}
|
||||||
|
|
||||||
AVSC_INLINE
|
AVSC_INLINE
|
||||||
AVS_VideoFrame * avs_new_frame(AVS_ScriptEnvironment * env,
|
AVS_VideoFrame * avs_new_frame(AVS_ScriptEnvironment * env,
|
||||||
const AVS_VideoInfo * vi)
|
const AVS_VideoInfo * vi)
|
||||||
{return avs_new_video_frame_a(env,vi,FRAME_ALIGN);}
|
{return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -872,6 +772,7 @@ struct AVS_Library {
|
|||||||
AVSC_DECLARE_FUNC(avs_function_exists);
|
AVSC_DECLARE_FUNC(avs_function_exists);
|
||||||
AVSC_DECLARE_FUNC(avs_get_audio);
|
AVSC_DECLARE_FUNC(avs_get_audio);
|
||||||
AVSC_DECLARE_FUNC(avs_get_cpu_flags);
|
AVSC_DECLARE_FUNC(avs_get_cpu_flags);
|
||||||
|
AVSC_DECLARE_FUNC(avs_get_error);
|
||||||
AVSC_DECLARE_FUNC(avs_get_frame);
|
AVSC_DECLARE_FUNC(avs_get_frame);
|
||||||
AVSC_DECLARE_FUNC(avs_get_parity);
|
AVSC_DECLARE_FUNC(avs_get_parity);
|
||||||
AVSC_DECLARE_FUNC(avs_get_var);
|
AVSC_DECLARE_FUNC(avs_get_var);
|
||||||
@@ -896,49 +797,6 @@ struct AVS_Library {
|
|||||||
AVSC_DECLARE_FUNC(avs_subframe_planar);
|
AVSC_DECLARE_FUNC(avs_subframe_planar);
|
||||||
AVSC_DECLARE_FUNC(avs_take_clip);
|
AVSC_DECLARE_FUNC(avs_take_clip);
|
||||||
AVSC_DECLARE_FUNC(avs_vsprintf);
|
AVSC_DECLARE_FUNC(avs_vsprintf);
|
||||||
|
|
||||||
AVSC_DECLARE_FUNC(avs_get_error);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_rgb48);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_rgb64);
|
|
||||||
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_yuv444p16);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_yuv422p16);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_yuv420p16);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_y16);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_yuv444ps);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_yuv422ps);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_yuv420ps);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_y32);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_444);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_422);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_420);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_y);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_yuva);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_planar_rgb);
|
|
||||||
AVSC_DECLARE_FUNC(avs_is_planar_rgba);
|
|
||||||
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);
|
|
||||||
|
|
||||||
AVSC_DECLARE_FUNC(avs_num_components);
|
|
||||||
AVSC_DECLARE_FUNC(avs_component_size);
|
|
||||||
AVSC_DECLARE_FUNC(avs_bits_per_component);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef AVSC_DECLARE_FUNC
|
#undef AVSC_DECLARE_FUNC
|
||||||
@@ -973,6 +831,7 @@ AVSC_INLINE AVS_Library * avs_load_library() {
|
|||||||
AVSC_LOAD_FUNC(avs_function_exists);
|
AVSC_LOAD_FUNC(avs_function_exists);
|
||||||
AVSC_LOAD_FUNC(avs_get_audio);
|
AVSC_LOAD_FUNC(avs_get_audio);
|
||||||
AVSC_LOAD_FUNC(avs_get_cpu_flags);
|
AVSC_LOAD_FUNC(avs_get_cpu_flags);
|
||||||
|
AVSC_LOAD_FUNC(avs_get_error);
|
||||||
AVSC_LOAD_FUNC(avs_get_frame);
|
AVSC_LOAD_FUNC(avs_get_frame);
|
||||||
AVSC_LOAD_FUNC(avs_get_parity);
|
AVSC_LOAD_FUNC(avs_get_parity);
|
||||||
AVSC_LOAD_FUNC(avs_get_var);
|
AVSC_LOAD_FUNC(avs_get_var);
|
||||||
@@ -998,50 +857,6 @@ AVSC_INLINE AVS_Library * avs_load_library() {
|
|||||||
AVSC_LOAD_FUNC(avs_take_clip);
|
AVSC_LOAD_FUNC(avs_take_clip);
|
||||||
AVSC_LOAD_FUNC(avs_vsprintf);
|
AVSC_LOAD_FUNC(avs_vsprintf);
|
||||||
|
|
||||||
AVSC_LOAD_FUNC(avs_get_error);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_rgb48);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_rgb64);
|
|
||||||
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_yuv444p16);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_yuv422p16);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_yuv420p16);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_y16);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_yuv444ps);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_yuv422ps);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_yuv420ps);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_y32);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_444);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_422);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_420);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_y);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_yuva);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_planar_rgb);
|
|
||||||
AVSC_LOAD_FUNC(avs_is_planar_rgba);
|
|
||||||
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);
|
|
||||||
|
|
||||||
AVSC_LOAD_FUNC(avs_num_components);
|
|
||||||
AVSC_LOAD_FUNC(avs_component_size);
|
|
||||||
AVSC_LOAD_FUNC(avs_bits_per_component);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#undef __AVSC_STRINGIFY
|
#undef __AVSC_STRINGIFY
|
||||||
#undef AVSC_STRINGIFY
|
#undef AVSC_STRINGIFY
|
||||||
#undef AVSC_LOAD_FUNC
|
#undef AVSC_LOAD_FUNC
|
||||||
|
|||||||
68
compat/avisynth/avisynth_c_25.h
Normal file
68
compat/avisynth/avisynth_c_25.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (c) 2011 FFmpegSource Project
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
/* these are defines/functions that are used and were changed in the switch to 2.6
|
||||||
|
* and are needed to maintain full compatility with 2.5 */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AVS_CS_YV12_25 = 1<<3 | AVS_CS_YUV | AVS_CS_PLANAR, // y-v-u, planar
|
||||||
|
AVS_CS_I420_25 = 1<<4 | AVS_CS_YUV | AVS_CS_PLANAR, // y-u-v, planar
|
||||||
|
};
|
||||||
|
|
||||||
|
AVSC_INLINE int avs_get_height_p_25(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 int avs_get_row_size_p_25(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_is_yv12_25(const AVS_VideoInfo * p)
|
||||||
|
{ return ((p->pixel_type & AVS_CS_YV12_25) == AVS_CS_YV12_25)||((p->pixel_type & AVS_CS_I420_25) == AVS_CS_I420_25); }
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
// Avisynth C Interface Version 0.20
|
|
||||||
// Copyright 2003 Kevin Atkinson
|
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
|
|
||||||
// http://www.gnu.org/copyleft/gpl.html .
|
|
||||||
//
|
|
||||||
// As a special exception, I give you permission to link to the
|
|
||||||
// Avisynth C interface with independent modules that communicate with
|
|
||||||
// the Avisynth C interface solely through the interfaces defined in
|
|
||||||
// avisynth_c.h, regardless of the license terms of these independent
|
|
||||||
// modules, and to copy and distribute the resulting combined work
|
|
||||||
// under terms of your choice, provided that every copy of the
|
|
||||||
// combined work is accompanied by a complete copy of the source code
|
|
||||||
// of the Avisynth C interface and Avisynth itself (with the version
|
|
||||||
// used to produce the combined work), being distributed under the
|
|
||||||
// terms of the GNU General Public License plus this exception. An
|
|
||||||
// independent module is a module which is not derived from or based
|
|
||||||
// on Avisynth C Interface, such as 3rd-party filters, import and
|
|
||||||
// export plugins, or graphical user interfaces.
|
|
||||||
|
|
||||||
#ifndef AVS_CAPI_H
|
|
||||||
#define AVS_CAPI_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
# define EXTERN_C extern "C"
|
|
||||||
#else
|
|
||||||
# define EXTERN_C
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
// Avisynth C Interface Version 0.20
|
|
||||||
// Copyright 2003 Kevin Atkinson
|
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
|
|
||||||
// http://www.gnu.org/copyleft/gpl.html .
|
|
||||||
//
|
|
||||||
// As a special exception, I give you permission to link to the
|
|
||||||
// Avisynth C interface with independent modules that communicate with
|
|
||||||
// the Avisynth C interface solely through the interfaces defined in
|
|
||||||
// avisynth_c.h, regardless of the license terms of these independent
|
|
||||||
// modules, and to copy and distribute the resulting combined work
|
|
||||||
// under terms of your choice, provided that every copy of the
|
|
||||||
// combined work is accompanied by a complete copy of the source code
|
|
||||||
// of the Avisynth C interface and Avisynth itself (with the version
|
|
||||||
// used to produce the combined work), being distributed under the
|
|
||||||
// terms of the GNU General Public License plus this exception. An
|
|
||||||
// independent module is a module which is not derived from or based
|
|
||||||
// on Avisynth C Interface, such as 3rd-party filters, import and
|
|
||||||
// export plugins, or graphical user interfaces.
|
|
||||||
|
|
||||||
#ifndef AVS_CONFIG_H
|
|
||||||
#define AVS_CONFIG_H
|
|
||||||
|
|
||||||
// Undefine this to get cdecl calling convention
|
|
||||||
#define AVSC_USE_STDCALL 1
|
|
||||||
|
|
||||||
// NOTE TO PLUGIN AUTHORS:
|
|
||||||
// Because FRAME_ALIGN can be substantially higher than the alignment
|
|
||||||
// a plugin actually needs, plugins should not use FRAME_ALIGN to check for
|
|
||||||
// alignment. They should always request the exact alignment value they need.
|
|
||||||
// This is to make sure that plugins work over the widest range of AviSynth
|
|
||||||
// builds possible.
|
|
||||||
#define FRAME_ALIGN 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
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
// Avisynth C Interface Version 0.20
|
|
||||||
// Copyright 2003 Kevin Atkinson
|
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
|
|
||||||
// http://www.gnu.org/copyleft/gpl.html .
|
|
||||||
//
|
|
||||||
// As a special exception, I give you permission to link to the
|
|
||||||
// Avisynth C interface with independent modules that communicate with
|
|
||||||
// the Avisynth C interface solely through the interfaces defined in
|
|
||||||
// avisynth_c.h, regardless of the license terms of these independent
|
|
||||||
// modules, and to copy and distribute the resulting combined work
|
|
||||||
// under terms of your choice, provided that every copy of the
|
|
||||||
// combined work is accompanied by a complete copy of the source code
|
|
||||||
// of the Avisynth C interface and Avisynth itself (with the version
|
|
||||||
// used to produce the combined work), being distributed under the
|
|
||||||
// terms of the GNU General Public License plus this exception. An
|
|
||||||
// independent module is a module which is not derived from or based
|
|
||||||
// on Avisynth C Interface, such as 3rd-party filters, import and
|
|
||||||
// export plugins, or graphical user interfaces.
|
|
||||||
|
|
||||||
#ifndef AVS_TYPES_H
|
|
||||||
#define AVS_TYPES_H
|
|
||||||
|
|
||||||
// Define all types necessary for interfacing with avisynth.dll
|
|
||||||
|
|
||||||
// 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
|
|
||||||
@@ -13,8 +13,7 @@
|
|||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
|
||||||
// MA 02110-1301 USA, or visit
|
|
||||||
// http://www.gnu.org/copyleft/gpl.html .
|
// http://www.gnu.org/copyleft/gpl.html .
|
||||||
//
|
//
|
||||||
// As a special exception, I give you permission to link to the
|
// As a special exception, I give you permission to link to the
|
||||||
@@ -513,21 +512,21 @@ AVSC_INLINE AVS_Value avs_array_elt(AVS_Value v, int index)
|
|||||||
// only use these functions on am AVS_Value that does not already have
|
// only use these functions on am AVS_Value that does not already have
|
||||||
// an active value. Remember, treat AVS_Value as a fat pointer.
|
// an active value. Remember, treat AVS_Value as a fat pointer.
|
||||||
AVSC_INLINE AVS_Value avs_new_value_bool(int v0)
|
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; }
|
{ 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)
|
AVSC_INLINE AVS_Value avs_new_value_int(int v0)
|
||||||
{ AVS_Value v = {0}; v.type = 'i'; v.d.integer = v0; return v; }
|
{ AVS_Value v; v.type = 'i'; v.d.integer = v0; return v; }
|
||||||
AVSC_INLINE AVS_Value avs_new_value_string(const char * v0)
|
AVSC_INLINE AVS_Value avs_new_value_string(const char * v0)
|
||||||
{ AVS_Value v = {0}; v.type = 's'; v.d.string = v0; return v; }
|
{ AVS_Value v; v.type = 's'; v.d.string = v0; return v; }
|
||||||
AVSC_INLINE AVS_Value avs_new_value_float(float v0)
|
AVSC_INLINE AVS_Value avs_new_value_float(float v0)
|
||||||
{ AVS_Value v = {0}; v.type = 'f'; v.d.floating_pt = v0; return v;}
|
{ AVS_Value v; v.type = 'f'; v.d.floating_pt = v0; return v;}
|
||||||
AVSC_INLINE AVS_Value avs_new_value_error(const char * v0)
|
AVSC_INLINE AVS_Value avs_new_value_error(const char * v0)
|
||||||
{ AVS_Value v = {0}; v.type = 'e'; v.d.string = v0; return v; }
|
{ AVS_Value v; v.type = 'e'; v.d.string = v0; return v; }
|
||||||
#ifndef AVSC_NO_DECLSPEC
|
#ifndef AVSC_NO_DECLSPEC
|
||||||
AVSC_INLINE AVS_Value avs_new_value_clip(AVS_Clip * v0)
|
AVSC_INLINE AVS_Value avs_new_value_clip(AVS_Clip * v0)
|
||||||
{ AVS_Value v = {0}; avs_set_to_clip(&v, v0); return v; }
|
{ AVS_Value v; avs_set_to_clip(&v, v0); return v; }
|
||||||
#endif
|
#endif
|
||||||
AVSC_INLINE AVS_Value avs_new_value_array(AVS_Value * v0, int size)
|
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_Value v; v.type = 'a'; v.d.array = v0; v.array_size = size; return v; }
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ namespace avxsynth {
|
|||||||
//
|
//
|
||||||
// Functions
|
// Functions
|
||||||
//
|
//
|
||||||
#define MAKEDWORD(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
|
#define MAKEDWORD(a,b,c,d) ((a << 24) | (b << 16) | (c << 8) | (d))
|
||||||
#define MAKEWORD(a,b) (((a) << 8) | (b))
|
#define MAKEWORD(a,b) ((a << 8) | (b))
|
||||||
|
|
||||||
#define lstrlen strlen
|
#define lstrlen strlen
|
||||||
#define lstrcpy strcpy
|
#define lstrcpy strcpy
|
||||||
|
|||||||
@@ -1,827 +0,0 @@
|
|||||||
/*
|
|
||||||
* This copyright notice applies to this header file only:
|
|
||||||
*
|
|
||||||
* Copyright (c) 2010-2016 NVIDIA Corporation
|
|
||||||
*
|
|
||||||
* 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 cuviddec.h
|
|
||||||
* NvCuvid API provides Video Decoding interface to NVIDIA GPU devices.
|
|
||||||
* \date 2015-2016
|
|
||||||
* This file contains constants, structure definitions and function prototypes used for decoding.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(__CUDA_VIDEO_H__)
|
|
||||||
#define __CUDA_VIDEO_H__
|
|
||||||
|
|
||||||
#ifndef __cuda_cuda_h__
|
|
||||||
#include <cuda.h>
|
|
||||||
#endif // __cuda_cuda_h__
|
|
||||||
|
|
||||||
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
|
|
||||||
#if (CUDA_VERSION >= 3020) && (!defined(CUDA_FORCE_API_VERSION) || (CUDA_FORCE_API_VERSION >= 3020))
|
|
||||||
#define __CUVID_DEVPTR64
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
typedef void *CUvideodecoder;
|
|
||||||
typedef struct _CUcontextlock_st *CUvideoctxlock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \addtogroup VIDEO_DECODER Video Decoder
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \enum cudaVideoCodec
|
|
||||||
* Video Codec Enums
|
|
||||||
*/
|
|
||||||
typedef enum cudaVideoCodec_enum {
|
|
||||||
cudaVideoCodec_MPEG1=0, /**< MPEG1 */
|
|
||||||
cudaVideoCodec_MPEG2, /**< MPEG2 */
|
|
||||||
cudaVideoCodec_MPEG4, /**< MPEG4 */
|
|
||||||
cudaVideoCodec_VC1, /**< VC1 */
|
|
||||||
cudaVideoCodec_H264, /**< H264 */
|
|
||||||
cudaVideoCodec_JPEG, /**< JPEG */
|
|
||||||
cudaVideoCodec_H264_SVC, /**< H264-SVC */
|
|
||||||
cudaVideoCodec_H264_MVC, /**< H264-MVC */
|
|
||||||
cudaVideoCodec_HEVC, /**< HEVC */
|
|
||||||
cudaVideoCodec_VP8, /**< VP8 */
|
|
||||||
cudaVideoCodec_VP9, /**< VP9 */
|
|
||||||
cudaVideoCodec_NumCodecs, /**< Max COdecs */
|
|
||||||
// Uncompressed YUV
|
|
||||||
cudaVideoCodec_YUV420 = (('I'<<24)|('Y'<<16)|('U'<<8)|('V')), /**< Y,U,V (4:2:0) */
|
|
||||||
cudaVideoCodec_YV12 = (('Y'<<24)|('V'<<16)|('1'<<8)|('2')), /**< Y,V,U (4:2:0) */
|
|
||||||
cudaVideoCodec_NV12 = (('N'<<24)|('V'<<16)|('1'<<8)|('2')), /**< Y,UV (4:2:0) */
|
|
||||||
cudaVideoCodec_YUYV = (('Y'<<24)|('U'<<16)|('Y'<<8)|('V')), /**< YUYV/YUY2 (4:2:2) */
|
|
||||||
cudaVideoCodec_UYVY = (('U'<<24)|('Y'<<16)|('V'<<8)|('Y')) /**< UYVY (4:2:2) */
|
|
||||||
} cudaVideoCodec;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \enum cudaVideoSurfaceFormat
|
|
||||||
* Video Surface Formats Enums
|
|
||||||
*/
|
|
||||||
typedef enum cudaVideoSurfaceFormat_enum {
|
|
||||||
cudaVideoSurfaceFormat_NV12=0 /**< NV12 (currently the only supported output format) */
|
|
||||||
} cudaVideoSurfaceFormat;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \enum cudaVideoDeinterlaceMode
|
|
||||||
* Deinterlacing Modes Enums
|
|
||||||
*/
|
|
||||||
typedef enum cudaVideoDeinterlaceMode_enum {
|
|
||||||
cudaVideoDeinterlaceMode_Weave=0, /**< Weave both fields (no deinterlacing) */
|
|
||||||
cudaVideoDeinterlaceMode_Bob, /**< Drop one field */
|
|
||||||
cudaVideoDeinterlaceMode_Adaptive /**< Adaptive deinterlacing */
|
|
||||||
} cudaVideoDeinterlaceMode;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \enum cudaVideoChromaFormat
|
|
||||||
* Chroma Formats Enums
|
|
||||||
*/
|
|
||||||
typedef enum cudaVideoChromaFormat_enum {
|
|
||||||
cudaVideoChromaFormat_Monochrome=0, /**< MonoChrome */
|
|
||||||
cudaVideoChromaFormat_420, /**< 4:2:0 */
|
|
||||||
cudaVideoChromaFormat_422, /**< 4:2:2 */
|
|
||||||
cudaVideoChromaFormat_444 /**< 4:4:4 */
|
|
||||||
} cudaVideoChromaFormat;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \enum cudaVideoCreateFlags
|
|
||||||
* Decoder Flags Enums
|
|
||||||
*/
|
|
||||||
typedef enum cudaVideoCreateFlags_enum {
|
|
||||||
cudaVideoCreate_Default = 0x00, /**< Default operation mode: use dedicated video engines */
|
|
||||||
cudaVideoCreate_PreferCUDA = 0x01, /**< Use a CUDA-based decoder if faster than dedicated engines (requires a valid vidLock object for multi-threading) */
|
|
||||||
cudaVideoCreate_PreferDXVA = 0x02, /**< Go through DXVA internally if possible (requires D3D9 interop) */
|
|
||||||
cudaVideoCreate_PreferCUVID = 0x04 /**< Use dedicated video engines directly */
|
|
||||||
} cudaVideoCreateFlags;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDDECODECREATEINFO
|
|
||||||
* Struct used in create decoder
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDDECODECREATEINFO
|
|
||||||
{
|
|
||||||
unsigned long ulWidth; /**< Coded Sequence Width */
|
|
||||||
unsigned long ulHeight; /**< Coded Sequence Height */
|
|
||||||
unsigned long ulNumDecodeSurfaces; /**< Maximum number of internal decode surfaces */
|
|
||||||
cudaVideoCodec CodecType; /**< cudaVideoCodec_XXX */
|
|
||||||
cudaVideoChromaFormat ChromaFormat; /**< cudaVideoChromaFormat_XXX (only 4:2:0 is currently supported) */
|
|
||||||
unsigned long ulCreationFlags; /**< Decoder creation flags (cudaVideoCreateFlags_XXX) */
|
|
||||||
unsigned long bitDepthMinus8;
|
|
||||||
unsigned long Reserved1[4]; /**< Reserved for future use - set to zero */
|
|
||||||
/**
|
|
||||||
* area of the frame that should be displayed
|
|
||||||
*/
|
|
||||||
struct {
|
|
||||||
short left;
|
|
||||||
short top;
|
|
||||||
short right;
|
|
||||||
short bottom;
|
|
||||||
} display_area;
|
|
||||||
|
|
||||||
cudaVideoSurfaceFormat OutputFormat; /**< cudaVideoSurfaceFormat_XXX */
|
|
||||||
cudaVideoDeinterlaceMode DeinterlaceMode; /**< cudaVideoDeinterlaceMode_XXX */
|
|
||||||
unsigned long ulTargetWidth; /**< Post-processed Output Width (Should be aligned to 2) */
|
|
||||||
unsigned long ulTargetHeight; /**< Post-processed Output Height (Should be aligbed to 2) */
|
|
||||||
unsigned long ulNumOutputSurfaces; /**< Maximum number of output surfaces simultaneously mapped */
|
|
||||||
CUvideoctxlock vidLock; /**< If non-NULL, context lock used for synchronizing ownership of the cuda context */
|
|
||||||
/**
|
|
||||||
* target rectangle in the output frame (for aspect ratio conversion)
|
|
||||||
* if a null rectangle is specified, {0,0,ulTargetWidth,ulTargetHeight} will be used
|
|
||||||
*/
|
|
||||||
struct {
|
|
||||||
short left;
|
|
||||||
short top;
|
|
||||||
short right;
|
|
||||||
short bottom;
|
|
||||||
} target_rect;
|
|
||||||
unsigned long Reserved2[5]; /**< Reserved for future use - set to zero */
|
|
||||||
} CUVIDDECODECREATEINFO;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDH264DPBENTRY
|
|
||||||
* H.264 DPB Entry
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDH264DPBENTRY
|
|
||||||
{
|
|
||||||
int PicIdx; /**< picture index of reference frame */
|
|
||||||
int FrameIdx; /**< frame_num(short-term) or LongTermFrameIdx(long-term) */
|
|
||||||
int is_long_term; /**< 0=short term reference, 1=long term reference */
|
|
||||||
int not_existing; /**< non-existing reference frame (corresponding PicIdx should be set to -1) */
|
|
||||||
int used_for_reference; /**< 0=unused, 1=top_field, 2=bottom_field, 3=both_fields */
|
|
||||||
int FieldOrderCnt[2]; /**< field order count of top and bottom fields */
|
|
||||||
} CUVIDH264DPBENTRY;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDH264MVCEXT
|
|
||||||
* H.264 MVC Picture Parameters Ext
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDH264MVCEXT
|
|
||||||
{
|
|
||||||
int num_views_minus1;
|
|
||||||
int view_id;
|
|
||||||
unsigned char inter_view_flag;
|
|
||||||
unsigned char num_inter_view_refs_l0;
|
|
||||||
unsigned char num_inter_view_refs_l1;
|
|
||||||
unsigned char MVCReserved8Bits;
|
|
||||||
int InterViewRefsL0[16];
|
|
||||||
int InterViewRefsL1[16];
|
|
||||||
} CUVIDH264MVCEXT;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDH264SVCEXT
|
|
||||||
* H.264 SVC Picture Parameters Ext
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDH264SVCEXT
|
|
||||||
{
|
|
||||||
unsigned char profile_idc;
|
|
||||||
unsigned char level_idc;
|
|
||||||
unsigned char DQId;
|
|
||||||
unsigned char DQIdMax;
|
|
||||||
unsigned char disable_inter_layer_deblocking_filter_idc;
|
|
||||||
unsigned char ref_layer_chroma_phase_y_plus1;
|
|
||||||
signed char inter_layer_slice_alpha_c0_offset_div2;
|
|
||||||
signed char inter_layer_slice_beta_offset_div2;
|
|
||||||
|
|
||||||
unsigned short DPBEntryValidFlag;
|
|
||||||
unsigned char inter_layer_deblocking_filter_control_present_flag;
|
|
||||||
unsigned char extended_spatial_scalability_idc;
|
|
||||||
unsigned char adaptive_tcoeff_level_prediction_flag;
|
|
||||||
unsigned char slice_header_restriction_flag;
|
|
||||||
unsigned char chroma_phase_x_plus1_flag;
|
|
||||||
unsigned char chroma_phase_y_plus1;
|
|
||||||
|
|
||||||
unsigned char tcoeff_level_prediction_flag;
|
|
||||||
unsigned char constrained_intra_resampling_flag;
|
|
||||||
unsigned char ref_layer_chroma_phase_x_plus1_flag;
|
|
||||||
unsigned char store_ref_base_pic_flag;
|
|
||||||
unsigned char Reserved8BitsA;
|
|
||||||
unsigned char Reserved8BitsB;
|
|
||||||
// For the 4 scaled_ref_layer_XX fields below,
|
|
||||||
// if (extended_spatial_scalability_idc == 1), SPS field, G.7.3.2.1.4, add prefix "seq_"
|
|
||||||
// if (extended_spatial_scalability_idc == 2), SLH field, G.7.3.3.4,
|
|
||||||
short scaled_ref_layer_left_offset;
|
|
||||||
short scaled_ref_layer_top_offset;
|
|
||||||
short scaled_ref_layer_right_offset;
|
|
||||||
short scaled_ref_layer_bottom_offset;
|
|
||||||
unsigned short Reserved16Bits;
|
|
||||||
struct _CUVIDPICPARAMS *pNextLayer; /**< Points to the picparams for the next layer to be decoded. Linked list ends at the target layer. */
|
|
||||||
int bRefBaseLayer; /**< whether to store ref base pic */
|
|
||||||
} CUVIDH264SVCEXT;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDH264PICPARAMS
|
|
||||||
* H.264 Picture Parameters
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDH264PICPARAMS
|
|
||||||
{
|
|
||||||
// SPS
|
|
||||||
int log2_max_frame_num_minus4;
|
|
||||||
int pic_order_cnt_type;
|
|
||||||
int log2_max_pic_order_cnt_lsb_minus4;
|
|
||||||
int delta_pic_order_always_zero_flag;
|
|
||||||
int frame_mbs_only_flag;
|
|
||||||
int direct_8x8_inference_flag;
|
|
||||||
int num_ref_frames; // NOTE: shall meet level 4.1 restrictions
|
|
||||||
unsigned char residual_colour_transform_flag;
|
|
||||||
unsigned char bit_depth_luma_minus8; // Must be 0 (only 8-bit supported)
|
|
||||||
unsigned char bit_depth_chroma_minus8; // Must be 0 (only 8-bit supported)
|
|
||||||
unsigned char qpprime_y_zero_transform_bypass_flag;
|
|
||||||
// PPS
|
|
||||||
int entropy_coding_mode_flag;
|
|
||||||
int pic_order_present_flag;
|
|
||||||
int num_ref_idx_l0_active_minus1;
|
|
||||||
int num_ref_idx_l1_active_minus1;
|
|
||||||
int weighted_pred_flag;
|
|
||||||
int weighted_bipred_idc;
|
|
||||||
int pic_init_qp_minus26;
|
|
||||||
int deblocking_filter_control_present_flag;
|
|
||||||
int redundant_pic_cnt_present_flag;
|
|
||||||
int transform_8x8_mode_flag;
|
|
||||||
int MbaffFrameFlag;
|
|
||||||
int constrained_intra_pred_flag;
|
|
||||||
int chroma_qp_index_offset;
|
|
||||||
int second_chroma_qp_index_offset;
|
|
||||||
int ref_pic_flag;
|
|
||||||
int frame_num;
|
|
||||||
int CurrFieldOrderCnt[2];
|
|
||||||
// DPB
|
|
||||||
CUVIDH264DPBENTRY dpb[16]; // List of reference frames within the DPB
|
|
||||||
// Quantization Matrices (raster-order)
|
|
||||||
unsigned char WeightScale4x4[6][16];
|
|
||||||
unsigned char WeightScale8x8[2][64];
|
|
||||||
// FMO/ASO
|
|
||||||
unsigned char fmo_aso_enable;
|
|
||||||
unsigned char num_slice_groups_minus1;
|
|
||||||
unsigned char slice_group_map_type;
|
|
||||||
signed char pic_init_qs_minus26;
|
|
||||||
unsigned int slice_group_change_rate_minus1;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
unsigned long long slice_group_map_addr;
|
|
||||||
const unsigned char *pMb2SliceGroupMap;
|
|
||||||
} fmo;
|
|
||||||
unsigned int Reserved[12];
|
|
||||||
// SVC/MVC
|
|
||||||
union
|
|
||||||
{
|
|
||||||
CUVIDH264MVCEXT mvcext;
|
|
||||||
CUVIDH264SVCEXT svcext;
|
|
||||||
};
|
|
||||||
} CUVIDH264PICPARAMS;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDMPEG2PICPARAMS
|
|
||||||
* MPEG-2 Picture Parameters
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDMPEG2PICPARAMS
|
|
||||||
{
|
|
||||||
int ForwardRefIdx; // Picture index of forward reference (P/B-frames)
|
|
||||||
int BackwardRefIdx; // Picture index of backward reference (B-frames)
|
|
||||||
int picture_coding_type;
|
|
||||||
int full_pel_forward_vector;
|
|
||||||
int full_pel_backward_vector;
|
|
||||||
int f_code[2][2];
|
|
||||||
int intra_dc_precision;
|
|
||||||
int frame_pred_frame_dct;
|
|
||||||
int concealment_motion_vectors;
|
|
||||||
int q_scale_type;
|
|
||||||
int intra_vlc_format;
|
|
||||||
int alternate_scan;
|
|
||||||
int top_field_first;
|
|
||||||
// Quantization matrices (raster order)
|
|
||||||
unsigned char QuantMatrixIntra[64];
|
|
||||||
unsigned char QuantMatrixInter[64];
|
|
||||||
} CUVIDMPEG2PICPARAMS;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// MPEG-4 Picture Parameters
|
|
||||||
//
|
|
||||||
|
|
||||||
// MPEG-4 has VOP types instead of Picture types
|
|
||||||
#define I_VOP 0
|
|
||||||
#define P_VOP 1
|
|
||||||
#define B_VOP 2
|
|
||||||
#define S_VOP 3
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDMPEG4PICPARAMS
|
|
||||||
* MPEG-4 Picture Parameters
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDMPEG4PICPARAMS
|
|
||||||
{
|
|
||||||
int ForwardRefIdx; // Picture index of forward reference (P/B-frames)
|
|
||||||
int BackwardRefIdx; // Picture index of backward reference (B-frames)
|
|
||||||
// VOL
|
|
||||||
int video_object_layer_width;
|
|
||||||
int video_object_layer_height;
|
|
||||||
int vop_time_increment_bitcount;
|
|
||||||
int top_field_first;
|
|
||||||
int resync_marker_disable;
|
|
||||||
int quant_type;
|
|
||||||
int quarter_sample;
|
|
||||||
int short_video_header;
|
|
||||||
int divx_flags;
|
|
||||||
// VOP
|
|
||||||
int vop_coding_type;
|
|
||||||
int vop_coded;
|
|
||||||
int vop_rounding_type;
|
|
||||||
int alternate_vertical_scan_flag;
|
|
||||||
int interlaced;
|
|
||||||
int vop_fcode_forward;
|
|
||||||
int vop_fcode_backward;
|
|
||||||
int trd[2];
|
|
||||||
int trb[2];
|
|
||||||
// Quantization matrices (raster order)
|
|
||||||
unsigned char QuantMatrixIntra[64];
|
|
||||||
unsigned char QuantMatrixInter[64];
|
|
||||||
int gmc_enabled;
|
|
||||||
} CUVIDMPEG4PICPARAMS;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDVC1PICPARAMS
|
|
||||||
* VC1 Picture Parameters
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDVC1PICPARAMS
|
|
||||||
{
|
|
||||||
int ForwardRefIdx; /**< Picture index of forward reference (P/B-frames) */
|
|
||||||
int BackwardRefIdx; /**< Picture index of backward reference (B-frames) */
|
|
||||||
int FrameWidth; /**< Actual frame width */
|
|
||||||
int FrameHeight; /**< Actual frame height */
|
|
||||||
// PICTURE
|
|
||||||
int intra_pic_flag; /**< Set to 1 for I,BI frames */
|
|
||||||
int ref_pic_flag; /**< Set to 1 for I,P frames */
|
|
||||||
int progressive_fcm; /**< Progressive frame */
|
|
||||||
// SEQUENCE
|
|
||||||
int profile;
|
|
||||||
int postprocflag;
|
|
||||||
int pulldown;
|
|
||||||
int interlace;
|
|
||||||
int tfcntrflag;
|
|
||||||
int finterpflag;
|
|
||||||
int psf;
|
|
||||||
int multires;
|
|
||||||
int syncmarker;
|
|
||||||
int rangered;
|
|
||||||
int maxbframes;
|
|
||||||
// ENTRYPOINT
|
|
||||||
int panscan_flag;
|
|
||||||
int refdist_flag;
|
|
||||||
int extended_mv;
|
|
||||||
int dquant;
|
|
||||||
int vstransform;
|
|
||||||
int loopfilter;
|
|
||||||
int fastuvmc;
|
|
||||||
int overlap;
|
|
||||||
int quantizer;
|
|
||||||
int extended_dmv;
|
|
||||||
int range_mapy_flag;
|
|
||||||
int range_mapy;
|
|
||||||
int range_mapuv_flag;
|
|
||||||
int range_mapuv;
|
|
||||||
int rangeredfrm; // range reduction state
|
|
||||||
} CUVIDVC1PICPARAMS;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDJPEGPICPARAMS
|
|
||||||
* JPEG Picture Parameters
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDJPEGPICPARAMS
|
|
||||||
{
|
|
||||||
int Reserved;
|
|
||||||
} CUVIDJPEGPICPARAMS;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDHEVCPICPARAMS
|
|
||||||
* HEVC Picture Parameters
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDHEVCPICPARAMS
|
|
||||||
{
|
|
||||||
// sps
|
|
||||||
int pic_width_in_luma_samples;
|
|
||||||
int pic_height_in_luma_samples;
|
|
||||||
unsigned char log2_min_luma_coding_block_size_minus3;
|
|
||||||
unsigned char log2_diff_max_min_luma_coding_block_size;
|
|
||||||
unsigned char log2_min_transform_block_size_minus2;
|
|
||||||
unsigned char log2_diff_max_min_transform_block_size;
|
|
||||||
unsigned char pcm_enabled_flag;
|
|
||||||
unsigned char log2_min_pcm_luma_coding_block_size_minus3;
|
|
||||||
unsigned char log2_diff_max_min_pcm_luma_coding_block_size;
|
|
||||||
unsigned char pcm_sample_bit_depth_luma_minus1;
|
|
||||||
|
|
||||||
unsigned char pcm_sample_bit_depth_chroma_minus1;
|
|
||||||
unsigned char pcm_loop_filter_disabled_flag;
|
|
||||||
unsigned char strong_intra_smoothing_enabled_flag;
|
|
||||||
unsigned char max_transform_hierarchy_depth_intra;
|
|
||||||
unsigned char max_transform_hierarchy_depth_inter;
|
|
||||||
unsigned char amp_enabled_flag;
|
|
||||||
unsigned char separate_colour_plane_flag;
|
|
||||||
unsigned char log2_max_pic_order_cnt_lsb_minus4;
|
|
||||||
|
|
||||||
unsigned char num_short_term_ref_pic_sets;
|
|
||||||
unsigned char long_term_ref_pics_present_flag;
|
|
||||||
unsigned char num_long_term_ref_pics_sps;
|
|
||||||
unsigned char sps_temporal_mvp_enabled_flag;
|
|
||||||
unsigned char sample_adaptive_offset_enabled_flag;
|
|
||||||
unsigned char scaling_list_enable_flag;
|
|
||||||
unsigned char IrapPicFlag;
|
|
||||||
unsigned char IdrPicFlag;
|
|
||||||
|
|
||||||
unsigned char bit_depth_luma_minus8;
|
|
||||||
unsigned char bit_depth_chroma_minus8;
|
|
||||||
unsigned char reserved1[14];
|
|
||||||
|
|
||||||
// pps
|
|
||||||
unsigned char dependent_slice_segments_enabled_flag;
|
|
||||||
unsigned char slice_segment_header_extension_present_flag;
|
|
||||||
unsigned char sign_data_hiding_enabled_flag;
|
|
||||||
unsigned char cu_qp_delta_enabled_flag;
|
|
||||||
unsigned char diff_cu_qp_delta_depth;
|
|
||||||
signed char init_qp_minus26;
|
|
||||||
signed char pps_cb_qp_offset;
|
|
||||||
signed char pps_cr_qp_offset;
|
|
||||||
|
|
||||||
unsigned char constrained_intra_pred_flag;
|
|
||||||
unsigned char weighted_pred_flag;
|
|
||||||
unsigned char weighted_bipred_flag;
|
|
||||||
unsigned char transform_skip_enabled_flag;
|
|
||||||
unsigned char transquant_bypass_enabled_flag;
|
|
||||||
unsigned char entropy_coding_sync_enabled_flag;
|
|
||||||
unsigned char log2_parallel_merge_level_minus2;
|
|
||||||
unsigned char num_extra_slice_header_bits;
|
|
||||||
|
|
||||||
unsigned char loop_filter_across_tiles_enabled_flag;
|
|
||||||
unsigned char loop_filter_across_slices_enabled_flag;
|
|
||||||
unsigned char output_flag_present_flag;
|
|
||||||
unsigned char num_ref_idx_l0_default_active_minus1;
|
|
||||||
unsigned char num_ref_idx_l1_default_active_minus1;
|
|
||||||
unsigned char lists_modification_present_flag;
|
|
||||||
unsigned char cabac_init_present_flag;
|
|
||||||
unsigned char pps_slice_chroma_qp_offsets_present_flag;
|
|
||||||
|
|
||||||
unsigned char deblocking_filter_override_enabled_flag;
|
|
||||||
unsigned char pps_deblocking_filter_disabled_flag;
|
|
||||||
signed char pps_beta_offset_div2;
|
|
||||||
signed char pps_tc_offset_div2;
|
|
||||||
unsigned char tiles_enabled_flag;
|
|
||||||
unsigned char uniform_spacing_flag;
|
|
||||||
unsigned char num_tile_columns_minus1;
|
|
||||||
unsigned char num_tile_rows_minus1;
|
|
||||||
|
|
||||||
unsigned short column_width_minus1[21];
|
|
||||||
unsigned short row_height_minus1[21];
|
|
||||||
unsigned int reserved3[15];
|
|
||||||
|
|
||||||
// RefPicSets
|
|
||||||
int NumBitsForShortTermRPSInSlice;
|
|
||||||
int NumDeltaPocsOfRefRpsIdx;
|
|
||||||
int NumPocTotalCurr;
|
|
||||||
int NumPocStCurrBefore;
|
|
||||||
int NumPocStCurrAfter;
|
|
||||||
int NumPocLtCurr;
|
|
||||||
int CurrPicOrderCntVal;
|
|
||||||
int RefPicIdx[16]; // [refpic] Indices of valid reference pictures (-1 if unused for reference)
|
|
||||||
int PicOrderCntVal[16]; // [refpic]
|
|
||||||
unsigned char IsLongTerm[16]; // [refpic] 0=not a long-term reference, 1=long-term reference
|
|
||||||
unsigned char RefPicSetStCurrBefore[8]; // [0..NumPocStCurrBefore-1] -> refpic (0..15)
|
|
||||||
unsigned char RefPicSetStCurrAfter[8]; // [0..NumPocStCurrAfter-1] -> refpic (0..15)
|
|
||||||
unsigned char RefPicSetLtCurr[8]; // [0..NumPocLtCurr-1] -> refpic (0..15)
|
|
||||||
unsigned char RefPicSetInterLayer0[8];
|
|
||||||
unsigned char RefPicSetInterLayer1[8];
|
|
||||||
unsigned int reserved4[12];
|
|
||||||
|
|
||||||
// scaling lists (diag order)
|
|
||||||
unsigned char ScalingList4x4[6][16]; // [matrixId][i]
|
|
||||||
unsigned char ScalingList8x8[6][64]; // [matrixId][i]
|
|
||||||
unsigned char ScalingList16x16[6][64]; // [matrixId][i]
|
|
||||||
unsigned char ScalingList32x32[2][64]; // [matrixId][i]
|
|
||||||
unsigned char ScalingListDCCoeff16x16[6]; // [matrixId]
|
|
||||||
unsigned char ScalingListDCCoeff32x32[2]; // [matrixId]
|
|
||||||
} CUVIDHEVCPICPARAMS;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDVP8PICPARAMS
|
|
||||||
* VP8 Picture Parameters
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDVP8PICPARAMS
|
|
||||||
{
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
unsigned int first_partition_size;
|
|
||||||
//Frame Indexes
|
|
||||||
unsigned char LastRefIdx;
|
|
||||||
unsigned char GoldenRefIdx;
|
|
||||||
unsigned char AltRefIdx;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
unsigned char frame_type : 1; /**< 0 = KEYFRAME, 1 = INTERFRAME */
|
|
||||||
unsigned char version : 3;
|
|
||||||
unsigned char show_frame : 1;
|
|
||||||
unsigned char update_mb_segmentation_data : 1; /**< Must be 0 if segmentation is not enabled */
|
|
||||||
unsigned char Reserved2Bits : 2;
|
|
||||||
};
|
|
||||||
unsigned char wFrameTagFlags;
|
|
||||||
};
|
|
||||||
unsigned char Reserved1[4];
|
|
||||||
unsigned int Reserved2[3];
|
|
||||||
} CUVIDVP8PICPARAMS;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDVP9PICPARAMS
|
|
||||||
* VP9 Picture Parameters
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDVP9PICPARAMS
|
|
||||||
{
|
|
||||||
unsigned int width;
|
|
||||||
unsigned int height;
|
|
||||||
|
|
||||||
//Frame Indices
|
|
||||||
unsigned char LastRefIdx;
|
|
||||||
unsigned char GoldenRefIdx;
|
|
||||||
unsigned char AltRefIdx;
|
|
||||||
unsigned char colorSpace;
|
|
||||||
|
|
||||||
unsigned short profile : 3;
|
|
||||||
unsigned short frameContextIdx : 2;
|
|
||||||
unsigned short frameType : 1;
|
|
||||||
unsigned short showFrame : 1;
|
|
||||||
unsigned short errorResilient : 1;
|
|
||||||
unsigned short frameParallelDecoding : 1;
|
|
||||||
unsigned short subSamplingX : 1;
|
|
||||||
unsigned short subSamplingY : 1;
|
|
||||||
unsigned short intraOnly : 1;
|
|
||||||
unsigned short allow_high_precision_mv : 1;
|
|
||||||
unsigned short refreshEntropyProbs : 1;
|
|
||||||
unsigned short reserved2Bits : 2;
|
|
||||||
|
|
||||||
unsigned short reserved16Bits;
|
|
||||||
|
|
||||||
unsigned char refFrameSignBias[4];
|
|
||||||
|
|
||||||
unsigned char bitDepthMinus8Luma;
|
|
||||||
unsigned char bitDepthMinus8Chroma;
|
|
||||||
unsigned char loopFilterLevel;
|
|
||||||
unsigned char loopFilterSharpness;
|
|
||||||
|
|
||||||
unsigned char modeRefLfEnabled;
|
|
||||||
unsigned char log2_tile_columns;
|
|
||||||
unsigned char log2_tile_rows;
|
|
||||||
|
|
||||||
unsigned char segmentEnabled : 1;
|
|
||||||
unsigned char segmentMapUpdate : 1;
|
|
||||||
unsigned char segmentMapTemporalUpdate : 1;
|
|
||||||
unsigned char segmentFeatureMode : 1;
|
|
||||||
unsigned char reserved4Bits : 4;
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char segmentFeatureEnable[8][4];
|
|
||||||
short segmentFeatureData[8][4];
|
|
||||||
unsigned char mb_segment_tree_probs[7];
|
|
||||||
unsigned char segment_pred_probs[3];
|
|
||||||
unsigned char reservedSegment16Bits[2];
|
|
||||||
|
|
||||||
int qpYAc;
|
|
||||||
int qpYDc;
|
|
||||||
int qpChDc;
|
|
||||||
int qpChAc;
|
|
||||||
|
|
||||||
unsigned int activeRefIdx[3];
|
|
||||||
unsigned int resetFrameContext;
|
|
||||||
unsigned int mcomp_filter_type;
|
|
||||||
unsigned int mbRefLfDelta[4];
|
|
||||||
unsigned int mbModeLfDelta[2];
|
|
||||||
unsigned int frameTagSize;
|
|
||||||
unsigned int offsetToDctParts;
|
|
||||||
unsigned int reserved128Bits[4];
|
|
||||||
|
|
||||||
} CUVIDVP9PICPARAMS;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDPICPARAMS
|
|
||||||
* Picture Parameters for Decoding
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDPICPARAMS
|
|
||||||
{
|
|
||||||
int PicWidthInMbs; /**< Coded Frame Size */
|
|
||||||
int FrameHeightInMbs; /**< Coded Frame Height */
|
|
||||||
int CurrPicIdx; /**< Output index of the current picture */
|
|
||||||
int field_pic_flag; /**< 0=frame picture, 1=field picture */
|
|
||||||
int bottom_field_flag; /**< 0=top field, 1=bottom field (ignored if field_pic_flag=0) */
|
|
||||||
int second_field; /**< Second field of a complementary field pair */
|
|
||||||
// Bitstream data
|
|
||||||
unsigned int nBitstreamDataLen; /**< Number of bytes in bitstream data buffer */
|
|
||||||
const unsigned char *pBitstreamData; /**< Ptr to bitstream data for this picture (slice-layer) */
|
|
||||||
unsigned int nNumSlices; /**< Number of slices in this picture */
|
|
||||||
const unsigned int *pSliceDataOffsets; /**< nNumSlices entries, contains offset of each slice within the bitstream data buffer */
|
|
||||||
int ref_pic_flag; /**< This picture is a reference picture */
|
|
||||||
int intra_pic_flag; /**< This picture is entirely intra coded */
|
|
||||||
unsigned int Reserved[30]; /**< Reserved for future use */
|
|
||||||
// Codec-specific data
|
|
||||||
union {
|
|
||||||
CUVIDMPEG2PICPARAMS mpeg2; /**< Also used for MPEG-1 */
|
|
||||||
CUVIDH264PICPARAMS h264;
|
|
||||||
CUVIDVC1PICPARAMS vc1;
|
|
||||||
CUVIDMPEG4PICPARAMS mpeg4;
|
|
||||||
CUVIDJPEGPICPARAMS jpeg;
|
|
||||||
CUVIDHEVCPICPARAMS hevc;
|
|
||||||
CUVIDVP8PICPARAMS vp8;
|
|
||||||
CUVIDVP9PICPARAMS vp9;
|
|
||||||
unsigned int CodecReserved[1024];
|
|
||||||
} CodecSpecific;
|
|
||||||
} CUVIDPICPARAMS;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDPROCPARAMS
|
|
||||||
* Picture Parameters for Postprocessing
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDPROCPARAMS
|
|
||||||
{
|
|
||||||
int progressive_frame; /**< Input is progressive (deinterlace_mode will be ignored) */
|
|
||||||
int second_field; /**< Output the second field (ignored if deinterlace mode is Weave) */
|
|
||||||
int top_field_first; /**< Input frame is top field first (1st field is top, 2nd field is bottom) */
|
|
||||||
int unpaired_field; /**< Input only contains one field (2nd field is invalid) */
|
|
||||||
// The fields below are used for raw YUV input
|
|
||||||
unsigned int reserved_flags; /**< Reserved for future use (set to zero) */
|
|
||||||
unsigned int reserved_zero; /**< Reserved (set to zero) */
|
|
||||||
unsigned long long raw_input_dptr; /**< Input CUdeviceptr for raw YUV extensions */
|
|
||||||
unsigned int raw_input_pitch; /**< pitch in bytes of raw YUV input (should be aligned appropriately) */
|
|
||||||
unsigned int raw_input_format; /**< Reserved for future use (set to zero) */
|
|
||||||
unsigned long long raw_output_dptr; /**< Reserved for future use (set to zero) */
|
|
||||||
unsigned int raw_output_pitch; /**< Reserved for future use (set to zero) */
|
|
||||||
unsigned int Reserved[48];
|
|
||||||
void *Reserved3[3];
|
|
||||||
} CUVIDPROCPARAMS;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* In order to minimize decode latencies, there should be always at least 2 pictures in the decode
|
|
||||||
* queue at any time, in order to make sure that all decode engines are always busy.
|
|
||||||
*
|
|
||||||
* Overall data flow:
|
|
||||||
* - cuvidCreateDecoder(...)
|
|
||||||
* For each picture:
|
|
||||||
* - cuvidDecodePicture(N)
|
|
||||||
* - cuvidMapVideoFrame(N-4)
|
|
||||||
* - do some processing in cuda
|
|
||||||
* - cuvidUnmapVideoFrame(N-4)
|
|
||||||
* - cuvidDecodePicture(N+1)
|
|
||||||
* - cuvidMapVideoFrame(N-3)
|
|
||||||
* ...
|
|
||||||
* - cuvidDestroyDecoder(...)
|
|
||||||
*
|
|
||||||
* NOTE:
|
|
||||||
* - When the cuda context is created from a D3D device, the D3D device must also be created
|
|
||||||
* with the D3DCREATE_MULTITHREADED flag.
|
|
||||||
* - There is a limit to how many pictures can be mapped simultaneously (ulNumOutputSurfaces)
|
|
||||||
* - cuVidDecodePicture may block the calling thread if there are too many pictures pending
|
|
||||||
* in the decode queue
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidCreateDecoder(CUvideodecoder *phDecoder, CUVIDDECODECREATEINFO *pdci)
|
|
||||||
* Create the decoder object
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidCreateDecoder(CUvideodecoder *phDecoder, CUVIDDECODECREATEINFO *pdci);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidDestroyDecoder(CUvideodecoder hDecoder)
|
|
||||||
* Destroy the decoder object
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidDestroyDecoder(CUvideodecoder hDecoder);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidDecodePicture(CUvideodecoder hDecoder, CUVIDPICPARAMS *pPicParams)
|
|
||||||
* Decode a single picture (field or frame)
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidDecodePicture(CUvideodecoder hDecoder, CUVIDPICPARAMS *pPicParams);
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined(__CUVID_DEVPTR64) || defined(__CUVID_INTERNAL)
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidMapVideoFrame(CUvideodecoder hDecoder, int nPicIdx, unsigned int *pDevPtr, unsigned int *pPitch, CUVIDPROCPARAMS *pVPP);
|
|
||||||
* Post-process and map a video frame for use in cuda
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidMapVideoFrame(CUvideodecoder hDecoder, int nPicIdx,
|
|
||||||
unsigned int *pDevPtr, unsigned int *pPitch,
|
|
||||||
CUVIDPROCPARAMS *pVPP);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidUnmapVideoFrame(CUvideodecoder hDecoder, unsigned int DevPtr)
|
|
||||||
* Unmap a previously mapped video frame
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidUnmapVideoFrame(CUvideodecoder hDecoder, unsigned int DevPtr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(WIN64) || defined(_WIN64) || defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidMapVideoFrame64(CUvideodecoder hDecoder, int nPicIdx, unsigned long long *pDevPtr, unsigned int *pPitch, CUVIDPROCPARAMS *pVPP);
|
|
||||||
* map a video frame
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidMapVideoFrame64(CUvideodecoder hDecoder, int nPicIdx, unsigned long long *pDevPtr,
|
|
||||||
unsigned int *pPitch, CUVIDPROCPARAMS *pVPP);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidUnmapVideoFrame64(CUvideodecoder hDecoder, unsigned long long DevPtr);
|
|
||||||
* Unmap a previously mapped video frame
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidUnmapVideoFrame64(CUvideodecoder hDecoder, unsigned long long DevPtr);
|
|
||||||
|
|
||||||
#if defined(__CUVID_DEVPTR64) && !defined(__CUVID_INTERNAL)
|
|
||||||
#define cuvidMapVideoFrame cuvidMapVideoFrame64
|
|
||||||
#define cuvidUnmapVideoFrame cuvidUnmapVideoFrame64
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Context-locking: to facilitate multi-threaded implementations, the following 4 functions
|
|
||||||
* provide a simple mutex-style host synchronization. If a non-NULL context is specified
|
|
||||||
* in CUVIDDECODECREATEINFO, the codec library will acquire the mutex associated with the given
|
|
||||||
* context before making any cuda calls.
|
|
||||||
* A multi-threaded application could create a lock associated with a context handle so that
|
|
||||||
* multiple threads can safely share the same cuda context:
|
|
||||||
* - use cuCtxPopCurrent immediately after context creation in order to create a 'floating' context
|
|
||||||
* that can be passed to cuvidCtxLockCreate.
|
|
||||||
* - When using a floating context, all cuda calls should only be made within a cuvidCtxLock/cuvidCtxUnlock section.
|
|
||||||
*
|
|
||||||
* NOTE: This is a safer alternative to cuCtxPushCurrent and cuCtxPopCurrent, and is not related to video
|
|
||||||
* decoder in any way (implemented as a critical section associated with cuCtx{Push|Pop}Current calls).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidCtxLockCreate(CUvideoctxlock *pLock, CUcontext ctx)
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidCtxLockCreate(CUvideoctxlock *pLock, CUcontext ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidCtxLockDestroy(CUvideoctxlock lck)
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidCtxLockDestroy(CUvideoctxlock lck);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidCtxLock(CUvideoctxlock lck, unsigned int reserved_flags)
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidCtxLock(CUvideoctxlock lck, unsigned int reserved_flags);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidCtxUnlock(CUvideoctxlock lck, unsigned int reserved_flags)
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidCtxUnlock(CUvideoctxlock lck, unsigned int reserved_flags);
|
|
||||||
|
|
||||||
/** @} */ /* End VIDEO_DECODER */
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
|
|
||||||
// Auto-lock helper for C++ applications
|
|
||||||
class CCtxAutoLock
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
CUvideoctxlock m_ctx;
|
|
||||||
public:
|
|
||||||
CCtxAutoLock(CUvideoctxlock ctx);
|
|
||||||
~CCtxAutoLock();
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#endif // __CUDA_VIDEO_H__
|
|
||||||
|
|
||||||
@@ -1,321 +0,0 @@
|
|||||||
/*
|
|
||||||
* This copyright notice applies to this header file only:
|
|
||||||
*
|
|
||||||
* Copyright (c) 2010-2016 NVIDIA Corporation
|
|
||||||
*
|
|
||||||
* 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 nvcuvid.h
|
|
||||||
* NvCuvid API provides Video Decoding interface to NVIDIA GPU devices.
|
|
||||||
* \date 2015-2015
|
|
||||||
* This file contains the interface constants, structure definitions and function prototypes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(__NVCUVID_H__)
|
|
||||||
#define __NVCUVID_H__
|
|
||||||
|
|
||||||
#include "compat/cuda/cuviddec.h"
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
/*********************************
|
|
||||||
** Initialization
|
|
||||||
*********************************/
|
|
||||||
CUresult CUDAAPI cuvidInit(unsigned int Flags);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// High-level helper APIs for video sources
|
|
||||||
//
|
|
||||||
|
|
||||||
typedef void *CUvideosource;
|
|
||||||
typedef void *CUvideoparser;
|
|
||||||
typedef long long CUvideotimestamp;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \addtogroup VIDEO_PARSER Video Parser
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \enum cudaVideoState
|
|
||||||
* Video Source State
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
cudaVideoState_Error = -1, /**< Error state (invalid source) */
|
|
||||||
cudaVideoState_Stopped = 0, /**< Source is stopped (or reached end-of-stream) */
|
|
||||||
cudaVideoState_Started = 1 /**< Source is running and delivering data */
|
|
||||||
} cudaVideoState;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \enum cudaAudioCodec
|
|
||||||
* Audio compression
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
cudaAudioCodec_MPEG1=0, /**< MPEG-1 Audio */
|
|
||||||
cudaAudioCodec_MPEG2, /**< MPEG-2 Audio */
|
|
||||||
cudaAudioCodec_MP3, /**< MPEG-1 Layer III Audio */
|
|
||||||
cudaAudioCodec_AC3, /**< Dolby Digital (AC3) Audio */
|
|
||||||
cudaAudioCodec_LPCM /**< PCM Audio */
|
|
||||||
} cudaAudioCodec;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDEOFORMAT
|
|
||||||
* Video format
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
cudaVideoCodec codec; /**< Compression format */
|
|
||||||
/**
|
|
||||||
* frame rate = numerator / denominator (for example: 30000/1001)
|
|
||||||
*/
|
|
||||||
struct {
|
|
||||||
unsigned int numerator; /**< frame rate numerator (0 = unspecified or variable frame rate) */
|
|
||||||
unsigned int denominator; /**< frame rate denominator (0 = unspecified or variable frame rate) */
|
|
||||||
} frame_rate;
|
|
||||||
unsigned char progressive_sequence; /**< 0=interlaced, 1=progressive */
|
|
||||||
unsigned char bit_depth_luma_minus8; /**< high bit depth Luma */
|
|
||||||
unsigned char bit_depth_chroma_minus8; /**< high bit depth Chroma */
|
|
||||||
unsigned char reserved1; /**< Reserved for future use */
|
|
||||||
unsigned int coded_width; /**< coded frame width */
|
|
||||||
unsigned int coded_height; /**< coded frame height */
|
|
||||||
/**
|
|
||||||
* area of the frame that should be displayed
|
|
||||||
* typical example:
|
|
||||||
* coded_width = 1920, coded_height = 1088
|
|
||||||
* display_area = { 0,0,1920,1080 }
|
|
||||||
*/
|
|
||||||
struct {
|
|
||||||
int left; /**< left position of display rect */
|
|
||||||
int top; /**< top position of display rect */
|
|
||||||
int right; /**< right position of display rect */
|
|
||||||
int bottom; /**< bottom position of display rect */
|
|
||||||
} display_area;
|
|
||||||
cudaVideoChromaFormat chroma_format; /**< Chroma format */
|
|
||||||
unsigned int bitrate; /**< video bitrate (bps, 0=unknown) */
|
|
||||||
/**
|
|
||||||
* Display Aspect Ratio = x:y (4:3, 16:9, etc)
|
|
||||||
*/
|
|
||||||
struct {
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
} display_aspect_ratio;
|
|
||||||
/**
|
|
||||||
* Video Signal Description
|
|
||||||
*/
|
|
||||||
struct {
|
|
||||||
unsigned char video_format : 3;
|
|
||||||
unsigned char video_full_range_flag : 1;
|
|
||||||
unsigned char reserved_zero_bits : 4;
|
|
||||||
unsigned char color_primaries;
|
|
||||||
unsigned char transfer_characteristics;
|
|
||||||
unsigned char matrix_coefficients;
|
|
||||||
} video_signal_description;
|
|
||||||
unsigned int seqhdr_data_length; /**< Additional bytes following (CUVIDEOFORMATEX) */
|
|
||||||
} CUVIDEOFORMAT;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDEOFORMATEX
|
|
||||||
* Video format including raw sequence header information
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
CUVIDEOFORMAT format;
|
|
||||||
unsigned char raw_seqhdr_data[1024];
|
|
||||||
} CUVIDEOFORMATEX;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUAUDIOFORMAT
|
|
||||||
* Audio Formats
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
cudaAudioCodec codec; /**< Compression format */
|
|
||||||
unsigned int channels; /**< number of audio channels */
|
|
||||||
unsigned int samplespersec; /**< sampling frequency */
|
|
||||||
unsigned int bitrate; /**< For uncompressed, can also be used to determine bits per sample */
|
|
||||||
unsigned int reserved1; /**< Reserved for future use */
|
|
||||||
unsigned int reserved2; /**< Reserved for future use */
|
|
||||||
} CUAUDIOFORMAT;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \enum CUvideopacketflags
|
|
||||||
* Data packet flags
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
CUVID_PKT_ENDOFSTREAM = 0x01, /**< Set when this is the last packet for this stream */
|
|
||||||
CUVID_PKT_TIMESTAMP = 0x02, /**< Timestamp is valid */
|
|
||||||
CUVID_PKT_DISCONTINUITY = 0x04 /**< Set when a discontinuity has to be signalled */
|
|
||||||
} CUvideopacketflags;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDSOURCEDATAPACKET
|
|
||||||
* Data Packet
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDSOURCEDATAPACKET
|
|
||||||
{
|
|
||||||
unsigned long flags; /**< Combination of CUVID_PKT_XXX flags */
|
|
||||||
unsigned long payload_size; /**< number of bytes in the payload (may be zero if EOS flag is set) */
|
|
||||||
const unsigned char *payload; /**< Pointer to packet payload data (may be NULL if EOS flag is set) */
|
|
||||||
CUvideotimestamp timestamp; /**< Presentation timestamp (10MHz clock), only valid if CUVID_PKT_TIMESTAMP flag is set */
|
|
||||||
} CUVIDSOURCEDATAPACKET;
|
|
||||||
|
|
||||||
// Callback for packet delivery
|
|
||||||
typedef int (CUDAAPI *PFNVIDSOURCECALLBACK)(void *, CUVIDSOURCEDATAPACKET *);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \struct CUVIDSOURCEPARAMS
|
|
||||||
* Source Params
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDSOURCEPARAMS
|
|
||||||
{
|
|
||||||
unsigned int ulClockRate; /**< Timestamp units in Hz (0=default=10000000Hz) */
|
|
||||||
unsigned int uReserved1[7]; /**< Reserved for future use - set to zero */
|
|
||||||
void *pUserData; /**< Parameter passed in to the data handlers */
|
|
||||||
PFNVIDSOURCECALLBACK pfnVideoDataHandler; /**< Called to deliver audio packets */
|
|
||||||
PFNVIDSOURCECALLBACK pfnAudioDataHandler; /**< Called to deliver video packets */
|
|
||||||
void *pvReserved2[8]; /**< Reserved for future use - set to NULL */
|
|
||||||
} CUVIDSOURCEPARAMS;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \enum CUvideosourceformat_flags
|
|
||||||
* CUvideosourceformat_flags
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
CUVID_FMT_EXTFORMATINFO = 0x100 /**< Return extended format structure (CUVIDEOFORMATEX) */
|
|
||||||
} CUvideosourceformat_flags;
|
|
||||||
|
|
||||||
#if !defined(__APPLE__)
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidCreateVideoSource(CUvideosource *pObj, const char *pszFileName, CUVIDSOURCEPARAMS *pParams)
|
|
||||||
* Create Video Source
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidCreateVideoSource(CUvideosource *pObj, const char *pszFileName, CUVIDSOURCEPARAMS *pParams);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidCreateVideoSourceW(CUvideosource *pObj, const wchar_t *pwszFileName, CUVIDSOURCEPARAMS *pParams)
|
|
||||||
* Create Video Source
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidCreateVideoSourceW(CUvideosource *pObj, const wchar_t *pwszFileName, CUVIDSOURCEPARAMS *pParams);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidDestroyVideoSource(CUvideosource obj)
|
|
||||||
* Destroy Video Source
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidDestroyVideoSource(CUvideosource obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidSetVideoSourceState(CUvideosource obj, cudaVideoState state)
|
|
||||||
* Set Video Source state
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidSetVideoSourceState(CUvideosource obj, cudaVideoState state);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn cudaVideoState CUDAAPI cuvidGetVideoSourceState(CUvideosource obj)
|
|
||||||
* Get Video Source state
|
|
||||||
*/
|
|
||||||
cudaVideoState CUDAAPI cuvidGetVideoSourceState(CUvideosource obj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidGetSourceVideoFormat(CUvideosource obj, CUVIDEOFORMAT *pvidfmt, unsigned int flags)
|
|
||||||
* Get Video Source Format
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidGetSourceVideoFormat(CUvideosource obj, CUVIDEOFORMAT *pvidfmt, unsigned int flags);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidGetSourceAudioFormat(CUvideosource obj, CUAUDIOFORMAT *paudfmt, unsigned int flags)
|
|
||||||
* Set Video Source state
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidGetSourceAudioFormat(CUvideosource obj, CUAUDIOFORMAT *paudfmt, unsigned int flags);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \struct CUVIDPARSERDISPINFO
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDPARSERDISPINFO
|
|
||||||
{
|
|
||||||
int picture_index; /**< */
|
|
||||||
int progressive_frame; /**< */
|
|
||||||
int top_field_first; /**< */
|
|
||||||
int repeat_first_field; /**< Number of additional fields (1=ivtc, 2=frame doubling, 4=frame tripling, -1=unpaired field) */
|
|
||||||
CUvideotimestamp timestamp; /**< */
|
|
||||||
} CUVIDPARSERDISPINFO;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Parser callbacks
|
|
||||||
// The parser will call these synchronously from within cuvidParseVideoData(), whenever a picture is ready to
|
|
||||||
// be decoded and/or displayed.
|
|
||||||
//
|
|
||||||
typedef int (CUDAAPI *PFNVIDSEQUENCECALLBACK)(void *, CUVIDEOFORMAT *);
|
|
||||||
typedef int (CUDAAPI *PFNVIDDECODECALLBACK)(void *, CUVIDPICPARAMS *);
|
|
||||||
typedef int (CUDAAPI *PFNVIDDISPLAYCALLBACK)(void *, CUVIDPARSERDISPINFO *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \struct CUVIDPARSERPARAMS
|
|
||||||
*/
|
|
||||||
typedef struct _CUVIDPARSERPARAMS
|
|
||||||
{
|
|
||||||
cudaVideoCodec CodecType; /**< cudaVideoCodec_XXX */
|
|
||||||
unsigned int ulMaxNumDecodeSurfaces; /**< Max # of decode surfaces (parser will cycle through these) */
|
|
||||||
unsigned int ulClockRate; /**< Timestamp units in Hz (0=default=10000000Hz) */
|
|
||||||
unsigned int ulErrorThreshold; /**< % Error threshold (0-100) for calling pfnDecodePicture (100=always call pfnDecodePicture even if picture bitstream is fully corrupted) */
|
|
||||||
unsigned int ulMaxDisplayDelay; /**< Max display queue delay (improves pipelining of decode with display) - 0=no delay (recommended values: 2..4) */
|
|
||||||
unsigned int uReserved1[5]; /**< Reserved for future use - set to 0 */
|
|
||||||
void *pUserData; /**< User data for callbacks */
|
|
||||||
PFNVIDSEQUENCECALLBACK pfnSequenceCallback; /**< Called before decoding frames and/or whenever there is a format change */
|
|
||||||
PFNVIDDECODECALLBACK pfnDecodePicture; /**< Called when a picture is ready to be decoded (decode order) */
|
|
||||||
PFNVIDDISPLAYCALLBACK pfnDisplayPicture; /**< Called whenever a picture is ready to be displayed (display order) */
|
|
||||||
void *pvReserved2[7]; /**< Reserved for future use - set to NULL */
|
|
||||||
CUVIDEOFORMATEX *pExtVideoInfo; /**< [Optional] sequence header data from system layer */
|
|
||||||
} CUVIDPARSERPARAMS;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidCreateVideoParser(CUvideoparser *pObj, CUVIDPARSERPARAMS *pParams)
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidCreateVideoParser(CUvideoparser *pObj, CUVIDPARSERPARAMS *pParams);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidParseVideoData(CUvideoparser obj, CUVIDSOURCEDATAPACKET *pPacket)
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidParseVideoData(CUvideoparser obj, CUVIDSOURCEDATAPACKET *pPacket);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn CUresult CUDAAPI cuvidDestroyVideoParser(CUvideoparser obj)
|
|
||||||
*/
|
|
||||||
CUresult CUDAAPI cuvidDestroyVideoParser(CUvideoparser obj);
|
|
||||||
|
|
||||||
/** @} */ /* END VIDEO_PARSER */
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#endif // __NVCUVID_H__
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,42 +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_DISPATCH_SEMAPHORE_SEMAPHORE_H
|
|
||||||
#define COMPAT_DISPATCH_SEMAPHORE_SEMAPHORE_H
|
|
||||||
|
|
||||||
#include <dispatch/dispatch.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#define sem_t dispatch_semaphore_t
|
|
||||||
#define sem_post(psem) dispatch_semaphore_signal(*psem)
|
|
||||||
#define sem_wait(psem) dispatch_semaphore_wait(*psem, DISPATCH_TIME_FOREVER)
|
|
||||||
#define sem_timedwait(psem, val) dispatch_semaphore_wait(*psem, dispatch_walltime(val, 0))
|
|
||||||
#define sem_destroy(psem) dispatch_release(*psem)
|
|
||||||
|
|
||||||
static inline int compat_sem_init(dispatch_semaphore_t *psem,
|
|
||||||
int unused, int val)
|
|
||||||
{
|
|
||||||
int ret = !!(*psem = dispatch_semaphore_create(val)) - 1;
|
|
||||||
if (ret < 0)
|
|
||||||
errno = ENOMEM;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define sem_init compat_sem_init
|
|
||||||
|
|
||||||
#endif /* COMPAT_DISPATCH_SEMAPHORE_SEMAPHORE_H */
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Work around broken floating point limits on some systems.
|
|
||||||
*
|
|
||||||
* 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_next <float.h>
|
|
||||||
|
|
||||||
#ifdef FLT_MAX
|
|
||||||
#undef FLT_MAX
|
|
||||||
#define FLT_MAX 3.40282346638528859812e+38F
|
|
||||||
|
|
||||||
#undef FLT_MIN
|
|
||||||
#define FLT_MIN 1.17549435082228750797e-38F
|
|
||||||
|
|
||||||
#undef DBL_MAX
|
|
||||||
#define DBL_MAX ((double)1.79769313486231570815e+308L)
|
|
||||||
|
|
||||||
#undef DBL_MIN
|
|
||||||
#define DBL_MIN ((double)2.22507385850720138309e-308L)
|
|
||||||
#endif
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* Work around broken floating point limits on some systems.
|
|
||||||
*
|
|
||||||
* 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_next <limits.h>
|
|
||||||
#include <float.h>
|
|
||||||
@@ -38,6 +38,8 @@ static int optind = 1;
|
|||||||
static int optopt;
|
static int optopt;
|
||||||
static char *optarg;
|
static char *optarg;
|
||||||
|
|
||||||
|
#undef fprintf
|
||||||
|
|
||||||
static int getopt(int argc, char *argv[], char *opts)
|
static int getopt(int argc, char *argv[], char *opts)
|
||||||
{
|
{
|
||||||
static int sp = 1;
|
static int sp = 1;
|
||||||
@@ -54,7 +56,7 @@ static int getopt(int argc, char *argv[], char *opts)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
optopt = c = argv[optind][sp];
|
optopt = c = argv[optind][sp];
|
||||||
if (c == ':' || !(cp = strchr(opts, c))) {
|
if (c == ':' || (cp = strchr(opts, c)) == NULL) {
|
||||||
fprintf(stderr, ": illegal option -- %c\n", c);
|
fprintf(stderr, ": illegal option -- %c\n", c);
|
||||||
if (argv[optind][++sp] == '\0') {
|
if (argv[optind][++sp] == '\0') {
|
||||||
optind++;
|
optind++;
|
||||||
|
|||||||
@@ -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 COMPAT_MSVCRT_SNPRINTF_H
|
#ifndef COMPAT_SNPRINTF_H
|
||||||
#define COMPAT_MSVCRT_SNPRINTF_H
|
#define COMPAT_SNPRINTF_H
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -35,4 +35,4 @@ int avpriv_vsnprintf(char *s, size_t n, const char *fmt, va_list ap);
|
|||||||
#define _snprintf avpriv_snprintf
|
#define _snprintf avpriv_snprintf
|
||||||
#define vsnprintf avpriv_vsnprintf
|
#define vsnprintf avpriv_vsnprintf
|
||||||
|
|
||||||
#endif /* COMPAT_MSVCRT_SNPRINTF_H */
|
#endif /* COMPAT_SNPRINTF_H */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -23,8 +23,8 @@
|
|||||||
* os2threads to pthreads wrapper
|
* os2threads to pthreads wrapper
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef COMPAT_OS2THREADS_H
|
#ifndef AVCODEC_OS2PTHREADS_H
|
||||||
#define COMPAT_OS2THREADS_H
|
#define AVCODEC_OS2PTHREADS_H
|
||||||
|
|
||||||
#define INCL_DOS
|
#define INCL_DOS
|
||||||
#include <os2.h>
|
#include <os2.h>
|
||||||
@@ -32,71 +32,55 @@
|
|||||||
#undef __STRICT_ANSI__ /* for _beginthread() */
|
#undef __STRICT_ANSI__ /* for _beginthread() */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <sys/builtin.h>
|
typedef TID pthread_t;
|
||||||
#include <sys/fmutex.h>
|
|
||||||
|
|
||||||
#include "libavutil/attributes.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
TID tid;
|
|
||||||
void *(*start_routine)(void *);
|
|
||||||
void *arg;
|
|
||||||
void *result;
|
|
||||||
} pthread_t;
|
|
||||||
|
|
||||||
typedef void pthread_attr_t;
|
typedef void pthread_attr_t;
|
||||||
|
|
||||||
typedef HMTX pthread_mutex_t;
|
typedef HMTX pthread_mutex_t;
|
||||||
typedef void pthread_mutexattr_t;
|
typedef void pthread_mutexattr_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
HEV event_sem;
|
HEV event_sem;
|
||||||
HEV ack_sem;
|
int wait_count;
|
||||||
volatile unsigned wait_count;
|
|
||||||
} pthread_cond_t;
|
} pthread_cond_t;
|
||||||
|
|
||||||
typedef void pthread_condattr_t;
|
typedef void pthread_condattr_t;
|
||||||
|
|
||||||
typedef struct {
|
struct thread_arg {
|
||||||
volatile int done;
|
void *(*start_routine)(void *);
|
||||||
_fmutex mtx;
|
void *arg;
|
||||||
} pthread_once_t;
|
};
|
||||||
|
|
||||||
#define PTHREAD_ONCE_INIT {0, _FMUTEX_INITIALIZER}
|
|
||||||
|
|
||||||
static void thread_entry(void *arg)
|
static void thread_entry(void *arg)
|
||||||
{
|
{
|
||||||
pthread_t *thread = arg;
|
struct thread_arg *thread_arg = arg;
|
||||||
|
|
||||||
thread->result = thread->start_routine(thread->arg);
|
thread_arg->start_routine(thread_arg->arg);
|
||||||
|
|
||||||
|
av_free(thread_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_always_inline int pthread_create(pthread_t *thread,
|
static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg)
|
||||||
const pthread_attr_t *attr,
|
|
||||||
void *(*start_routine)(void*),
|
|
||||||
void *arg)
|
|
||||||
{
|
{
|
||||||
thread->start_routine = start_routine;
|
struct thread_arg *thread_arg;
|
||||||
thread->arg = arg;
|
|
||||||
thread->result = NULL;
|
|
||||||
|
|
||||||
thread->tid = _beginthread(thread_entry, NULL, 1024 * 1024, thread);
|
thread_arg = av_mallocz(sizeof(struct thread_arg));
|
||||||
|
|
||||||
|
thread_arg->start_routine = start_routine;
|
||||||
|
thread_arg->arg = arg;
|
||||||
|
|
||||||
|
*thread = _beginthread(thread_entry, NULL, 256 * 1024, thread_arg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
|
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
|
||||||
{
|
{
|
||||||
DosWaitThread(&thread.tid, DCWW_WAIT);
|
DosWaitThread((PTID)&thread, DCWW_WAIT);
|
||||||
|
|
||||||
if (value_ptr)
|
|
||||||
*value_ptr = thread.result;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
DosCreateMutexSem(NULL, (PHMTX)mutex, 0, FALSE);
|
DosCreateMutexSem(NULL, (PHMTX)mutex, 0, FALSE);
|
||||||
|
|
||||||
@@ -124,11 +108,9 @@ static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_always_inline int pthread_cond_init(pthread_cond_t *cond,
|
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
|
||||||
const pthread_condattr_t *attr)
|
|
||||||
{
|
{
|
||||||
DosCreateEventSem(NULL, &cond->event_sem, DCE_POSTONE, FALSE);
|
DosCreateEventSem(NULL, &cond->event_sem, DCE_POSTONE, FALSE);
|
||||||
DosCreateEventSem(NULL, &cond->ack_sem, DCE_POSTONE, FALSE);
|
|
||||||
|
|
||||||
cond->wait_count = 0;
|
cond->wait_count = 0;
|
||||||
|
|
||||||
@@ -138,16 +120,16 @@ static av_always_inline int pthread_cond_init(pthread_cond_t *cond,
|
|||||||
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
|
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
|
||||||
{
|
{
|
||||||
DosCloseEventSem(cond->event_sem);
|
DosCloseEventSem(cond->event_sem);
|
||||||
DosCloseEventSem(cond->ack_sem);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
|
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
|
||||||
{
|
{
|
||||||
if (!__atomic_cmpxchg32(&cond->wait_count, 0, 0)) {
|
if (cond->wait_count > 0) {
|
||||||
DosPostEventSem(cond->event_sem);
|
DosPostEventSem(cond->event_sem);
|
||||||
DosWaitEventSem(cond->ack_sem, SEM_INDEFINITE_WAIT);
|
|
||||||
|
cond->wait_count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -155,47 +137,26 @@ static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
|
|||||||
|
|
||||||
static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
|
static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
|
||||||
{
|
{
|
||||||
while (!__atomic_cmpxchg32(&cond->wait_count, 0, 0))
|
while (cond->wait_count > 0) {
|
||||||
pthread_cond_signal(cond);
|
DosPostEventSem(cond->event_sem);
|
||||||
|
|
||||||
|
cond->wait_count--;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 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)
|
|
||||||
{
|
{
|
||||||
__atomic_increment(&cond->wait_count);
|
cond->wait_count++;
|
||||||
|
|
||||||
pthread_mutex_unlock(mutex);
|
pthread_mutex_unlock(mutex);
|
||||||
|
|
||||||
DosWaitEventSem(cond->event_sem, SEM_INDEFINITE_WAIT);
|
DosWaitEventSem(cond->event_sem, SEM_INDEFINITE_WAIT);
|
||||||
|
|
||||||
__atomic_decrement(&cond->wait_count);
|
|
||||||
|
|
||||||
DosPostEventSem(cond->ack_sem);
|
|
||||||
|
|
||||||
pthread_mutex_lock(mutex);
|
pthread_mutex_lock(mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_always_inline int pthread_once(pthread_once_t *once_control,
|
#endif /* AVCODEC_OS2PTHREADS_H */
|
||||||
void (*init_routine)(void))
|
|
||||||
{
|
|
||||||
if (!once_control->done)
|
|
||||||
{
|
|
||||||
_fmutex_request(&once_control->mtx, 0);
|
|
||||||
|
|
||||||
if (!once_control->done)
|
|
||||||
{
|
|
||||||
init_routine();
|
|
||||||
|
|
||||||
once_control->done = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_fmutex_release(&once_control->mtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* COMPAT_OS2THREADS_H */
|
|
||||||
|
|||||||
@@ -1,352 +0,0 @@
|
|||||||
#!/usr/bin/env perl
|
|
||||||
|
|
||||||
# make_sunver.pl
|
|
||||||
#
|
|
||||||
# Copyright (C) 2010, 2011, 2012, 2013
|
|
||||||
# Free Software Foundation, Inc.
|
|
||||||
#
|
|
||||||
# This file 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 3 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; see the file COPYING.GPLv3. If not see
|
|
||||||
# <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# This script takes at least two arguments, a GNU style version script and
|
|
||||||
# a list of object and archive files, and generates a corresponding Sun
|
|
||||||
# style version script as follows:
|
|
||||||
#
|
|
||||||
# Each glob pattern, C++ mangled pattern or literal in the input script is
|
|
||||||
# matched against all global symbols in the input objects, emitting those
|
|
||||||
# that matched (or nothing if no match was found).
|
|
||||||
# A comment with the original pattern and its type is left in the output
|
|
||||||
# file to make it easy to understand the matches.
|
|
||||||
#
|
|
||||||
# It uses elfdump when present (native), GNU readelf otherwise.
|
|
||||||
# It depends on the GNU version of c++filt, since it must understand the
|
|
||||||
# GNU mangling style.
|
|
||||||
|
|
||||||
use FileHandle;
|
|
||||||
use IPC::Open2;
|
|
||||||
|
|
||||||
# Enforce C locale.
|
|
||||||
$ENV{'LC_ALL'} = "C";
|
|
||||||
$ENV{'LANG'} = "C";
|
|
||||||
|
|
||||||
# Input version script, GNU style.
|
|
||||||
my $symvers = shift;
|
|
||||||
|
|
||||||
##########
|
|
||||||
# Get all the symbols from the library, match them, and add them to a hash.
|
|
||||||
|
|
||||||
my %sym_hash = ();
|
|
||||||
|
|
||||||
# List of objects and archives to process.
|
|
||||||
my @OBJECTS = ();
|
|
||||||
|
|
||||||
# List of shared objects to omit from processing.
|
|
||||||
my @SHAREDOBJS = ();
|
|
||||||
|
|
||||||
# Filter out those input archives that have corresponding shared objects to
|
|
||||||
# avoid adding all symbols matched in the archive to the output map.
|
|
||||||
foreach $file (@ARGV) {
|
|
||||||
if (($so = $file) =~ s/\.a$/.so/ && -e $so) {
|
|
||||||
printf STDERR "omitted $file -> $so\n";
|
|
||||||
push (@SHAREDOBJS, $so);
|
|
||||||
} else {
|
|
||||||
push (@OBJECTS, $file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# We need to detect and ignore hidden symbols. Solaris nm can only detect
|
|
||||||
# this in the harder to parse default output format, and GNU nm not at all,
|
|
||||||
# so use elfdump -s in the native case and GNU readelf -s otherwise.
|
|
||||||
# GNU objdump -t cannot be used since it produces a variable number of
|
|
||||||
# columns.
|
|
||||||
|
|
||||||
# The path to elfdump.
|
|
||||||
my $elfdump = "/usr/ccs/bin/elfdump";
|
|
||||||
|
|
||||||
if (-f $elfdump) {
|
|
||||||
open ELFDUMP,$elfdump.' -s '.(join ' ',@OBJECTS).'|' or die $!;
|
|
||||||
my $skip_arsym = 0;
|
|
||||||
|
|
||||||
while (<ELFDUMP>) {
|
|
||||||
chomp;
|
|
||||||
|
|
||||||
# Ignore empty lines.
|
|
||||||
if (/^$/) {
|
|
||||||
# End of archive symbol table, stop skipping.
|
|
||||||
$skip_arsym = 0 if $skip_arsym;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Keep skipping until end of archive symbol table.
|
|
||||||
next if ($skip_arsym);
|
|
||||||
|
|
||||||
# Ignore object name header for individual objects and archives.
|
|
||||||
next if (/:$/);
|
|
||||||
|
|
||||||
# Ignore table header lines.
|
|
||||||
next if (/^Symbol Table Section:/);
|
|
||||||
next if (/index.*value.*size/);
|
|
||||||
|
|
||||||
# Start of archive symbol table: start skipping.
|
|
||||||
if (/^Symbol Table: \(archive/) {
|
|
||||||
$skip_arsym = 1;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Split table.
|
|
||||||
(undef, undef, undef, undef, $bind, $oth, undef, $shndx, $name) = split;
|
|
||||||
|
|
||||||
# Error out for unknown input.
|
|
||||||
die "unknown input line:\n$_" unless defined($bind);
|
|
||||||
|
|
||||||
# Ignore local symbols.
|
|
||||||
next if ($bind eq "LOCL");
|
|
||||||
# Ignore hidden symbols.
|
|
||||||
next if ($oth eq "H");
|
|
||||||
# Ignore undefined symbols.
|
|
||||||
next if ($shndx eq "UNDEF");
|
|
||||||
# Error out for unhandled cases.
|
|
||||||
if ($bind !~ /^(GLOB|WEAK)/ or $oth ne "D") {
|
|
||||||
die "unhandled symbol:\n$_";
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remember symbol.
|
|
||||||
$sym_hash{$name}++;
|
|
||||||
}
|
|
||||||
close ELFDUMP or die "$elfdump error";
|
|
||||||
} else {
|
|
||||||
open READELF, 'readelf -s -W '.(join ' ',@OBJECTS).'|' or die $!;
|
|
||||||
# Process each symbol.
|
|
||||||
while (<READELF>) {
|
|
||||||
chomp;
|
|
||||||
|
|
||||||
# Ignore empty lines.
|
|
||||||
next if (/^$/);
|
|
||||||
|
|
||||||
# Ignore object name header.
|
|
||||||
next if (/^File: .*$/);
|
|
||||||
|
|
||||||
# Ignore table header lines.
|
|
||||||
next if (/^Symbol table.*contains.*:/);
|
|
||||||
next if (/Num:.*Value.*Size/);
|
|
||||||
|
|
||||||
# Split table.
|
|
||||||
(undef, undef, undef, undef, $bind, $vis, $ndx, $name) = split;
|
|
||||||
|
|
||||||
# Error out for unknown input.
|
|
||||||
die "unknown input line:\n$_" unless defined($bind);
|
|
||||||
|
|
||||||
# Ignore local symbols.
|
|
||||||
next if ($bind eq "LOCAL");
|
|
||||||
# Ignore hidden symbols.
|
|
||||||
next if ($vis eq "HIDDEN");
|
|
||||||
# Ignore undefined symbols.
|
|
||||||
next if ($ndx eq "UND");
|
|
||||||
# Error out for unhandled cases.
|
|
||||||
if ($bind !~ /^(GLOBAL|WEAK)/ or $vis ne "DEFAULT") {
|
|
||||||
die "unhandled symbol:\n$_";
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remember symbol.
|
|
||||||
$sym_hash{$name}++;
|
|
||||||
}
|
|
||||||
close READELF or die "readelf error";
|
|
||||||
}
|
|
||||||
|
|
||||||
##########
|
|
||||||
# The various types of glob patterns.
|
|
||||||
#
|
|
||||||
# A glob pattern that is to be applied to the demangled name: 'cxx'.
|
|
||||||
# A glob patterns that applies directly to the name in the .o files: 'glob'.
|
|
||||||
# This pattern is ignored; used for local variables (usually just '*'): 'ign'.
|
|
||||||
|
|
||||||
# The type of the current pattern.
|
|
||||||
my $glob = 'glob';
|
|
||||||
|
|
||||||
# We're currently inside `extern "C++"', which Sun ld doesn't understand.
|
|
||||||
my $in_extern = 0;
|
|
||||||
|
|
||||||
# The c++filt command to use. This *must* be GNU c++filt; the Sun Studio
|
|
||||||
# c++filt doesn't handle the GNU mangling style.
|
|
||||||
my $cxxfilt = $ENV{'CXXFILT'} || "c++filt";
|
|
||||||
|
|
||||||
# The current version name.
|
|
||||||
my $current_version = "";
|
|
||||||
|
|
||||||
# Was there any attempt to match a symbol to this version?
|
|
||||||
my $matches_attempted;
|
|
||||||
|
|
||||||
# The number of versions which matched this symbol.
|
|
||||||
my $matched_symbols;
|
|
||||||
|
|
||||||
open F,$symvers or die $!;
|
|
||||||
|
|
||||||
# Print information about generating this file
|
|
||||||
print "# This file was generated by make_sunver.pl. DO NOT EDIT!\n";
|
|
||||||
print "# It was generated by:\n";
|
|
||||||
printf "# %s %s %s\n", $0, $symvers, (join ' ',@ARGV);
|
|
||||||
printf "# Omitted archives with corresponding shared libraries: %s\n",
|
|
||||||
(join ' ', @SHAREDOBJS) if $#SHAREDOBJS >= 0;
|
|
||||||
print "#\n\n";
|
|
||||||
|
|
||||||
print "\$mapfile_version 2\n";
|
|
||||||
|
|
||||||
while (<F>) {
|
|
||||||
# Lines of the form '};'
|
|
||||||
if (/^([ \t]*)(\}[ \t]*;[ \t]*)$/) {
|
|
||||||
$glob = 'glob';
|
|
||||||
if ($in_extern) {
|
|
||||||
$in_extern--;
|
|
||||||
print "$1##$2\n";
|
|
||||||
} else {
|
|
||||||
print;
|
|
||||||
}
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Lines of the form '} SOME_VERSION_NAME_1.0;'
|
|
||||||
if (/^[ \t]*\}[ \tA-Z0-9_.a-z]+;[ \t]*$/) {
|
|
||||||
$glob = 'glob';
|
|
||||||
# We tried to match symbols agains this version, but none matched.
|
|
||||||
# Emit dummy hidden symbol to avoid marking this version WEAK.
|
|
||||||
if ($matches_attempted && $matched_symbols == 0) {
|
|
||||||
print " hidden:\n";
|
|
||||||
print " .force_WEAK_off_$current_version = DATA S0x0 V0x0;\n";
|
|
||||||
}
|
|
||||||
print; next;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Comment and blank lines
|
|
||||||
if (/^[ \t]*\#/) { print; next; }
|
|
||||||
if (/^[ \t]*$/) { print; next; }
|
|
||||||
|
|
||||||
# Lines of the form '{'
|
|
||||||
if (/^([ \t]*){$/) {
|
|
||||||
if ($in_extern) {
|
|
||||||
print "$1##{\n";
|
|
||||||
} else {
|
|
||||||
print;
|
|
||||||
}
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Lines of the form 'SOME_VERSION_NAME_1.1 {'
|
|
||||||
if (/^([A-Z0-9_.]+)[ \t]+{$/) {
|
|
||||||
# Record version name.
|
|
||||||
$current_version = $1;
|
|
||||||
# Reset match attempts, #matched symbols for this version.
|
|
||||||
$matches_attempted = 0;
|
|
||||||
$matched_symbols = 0;
|
|
||||||
print "SYMBOL_VERSION $1 {\n";
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Ignore 'global:'
|
|
||||||
if (/^[ \t]*global:$/) { print; next; }
|
|
||||||
|
|
||||||
# After 'local:', globs should be ignored, they won't be exported.
|
|
||||||
if (/^[ \t]*local:$/) {
|
|
||||||
$glob = 'ign';
|
|
||||||
print;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
# After 'extern "C++"', globs are C++ patterns
|
|
||||||
if (/^([ \t]*)(extern \"C\+\+\"[ \t]*)$/) {
|
|
||||||
$in_extern++;
|
|
||||||
$glob = 'cxx';
|
|
||||||
# Need to comment, Sun ld cannot handle this.
|
|
||||||
print "$1##$2\n"; next;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Chomp newline now we're done with passing through the input file.
|
|
||||||
chomp;
|
|
||||||
|
|
||||||
# Catch globs. Note that '{}' is not allowed in globs by this script,
|
|
||||||
# so only '*' and '[]' are available.
|
|
||||||
if (/^([ \t]*)([^ \t;{}#]+);?[ \t]*$/) {
|
|
||||||
my $ws = $1;
|
|
||||||
my $ptn = $2;
|
|
||||||
# Turn the glob into a regex by replacing '*' with '.*', '?' with '.'.
|
|
||||||
# Keep $ptn so we can still print the original form.
|
|
||||||
($pattern = $ptn) =~ s/\*/\.\*/g;
|
|
||||||
$pattern =~ s/\?/\./g;
|
|
||||||
|
|
||||||
if ($glob eq 'ign') {
|
|
||||||
# We're in a local: * section; just continue.
|
|
||||||
print "$_\n";
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Print the glob commented for human readers.
|
|
||||||
print "$ws##$ptn ($glob)\n";
|
|
||||||
# We tried to match a symbol to this version.
|
|
||||||
$matches_attempted++;
|
|
||||||
|
|
||||||
if ($glob eq 'glob') {
|
|
||||||
my %ptn_syms = ();
|
|
||||||
|
|
||||||
# Match ptn against symbols in %sym_hash.
|
|
||||||
foreach my $sym (keys %sym_hash) {
|
|
||||||
# Maybe it matches one of the patterns based on the symbol in
|
|
||||||
# the .o file.
|
|
||||||
$ptn_syms{$sym}++ if ($sym =~ /^$pattern$/);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach my $sym (sort keys(%ptn_syms)) {
|
|
||||||
$matched_symbols++;
|
|
||||||
print "$ws$sym;\n";
|
|
||||||
}
|
|
||||||
} elsif ($glob eq 'cxx') {
|
|
||||||
my %dem_syms = ();
|
|
||||||
|
|
||||||
# Verify that we're actually using GNU c++filt. Other versions
|
|
||||||
# most likely cannot handle GNU style symbol mangling.
|
|
||||||
my $cxxout = `$cxxfilt --version 2>&1`;
|
|
||||||
$cxxout =~ m/GNU/ or die "$0 requires GNU c++filt to function";
|
|
||||||
|
|
||||||
# Talk to c++filt through a pair of file descriptors.
|
|
||||||
# Need to start a fresh instance per pattern, otherwise the
|
|
||||||
# process grows to 500+ MB.
|
|
||||||
my $pid = open2(*FILTIN, *FILTOUT, $cxxfilt) or die $!;
|
|
||||||
|
|
||||||
# Match ptn against symbols in %sym_hash.
|
|
||||||
foreach my $sym (keys %sym_hash) {
|
|
||||||
# No? Well, maybe its demangled form matches one of those
|
|
||||||
# patterns.
|
|
||||||
printf FILTOUT "%s\n",$sym;
|
|
||||||
my $dem = <FILTIN>;
|
|
||||||
chomp $dem;
|
|
||||||
$dem_syms{$sym}++ if ($dem =~ /^$pattern$/);
|
|
||||||
}
|
|
||||||
|
|
||||||
close FILTOUT or die "c++filt error";
|
|
||||||
close FILTIN or die "c++filt error";
|
|
||||||
# Need to wait for the c++filt process to avoid lots of zombies.
|
|
||||||
waitpid $pid, 0;
|
|
||||||
|
|
||||||
foreach my $sym (sort keys(%dem_syms)) {
|
|
||||||
$matched_symbols++;
|
|
||||||
print "$ws$sym;\n";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
# No? Well, then ignore it.
|
|
||||||
}
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
# Important sanity check. This script can't handle lots of formats
|
|
||||||
# that GNU ld can, so be sure to error out if one is seen!
|
|
||||||
die "strange line `$_'";
|
|
||||||
}
|
|
||||||
close F;
|
|
||||||
@@ -16,8 +16,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 COMPAT_TMS470_MATH_H
|
#ifndef FFMPEG_COMPAT_TMS470_MATH_H
|
||||||
#define COMPAT_TMS470_MATH_H
|
#define FFMPEG_COMPAT_TMS470_MATH_H
|
||||||
|
|
||||||
#include_next <math.h>
|
#include_next <math.h>
|
||||||
|
|
||||||
@@ -27,4 +27,4 @@
|
|||||||
#define INFINITY (*(const float*)((const unsigned []){ 0x7f800000 }))
|
#define INFINITY (*(const float*)((const unsigned []){ 0x7f800000 }))
|
||||||
#define NAN (*(const float*)((const unsigned []){ 0x7fc00000 }))
|
#define NAN (*(const float*)((const unsigned []){ 0x7fc00000 }))
|
||||||
|
|
||||||
#endif /* COMPAT_TMS470_MATH_H */
|
#endif /* FFMPEG_COMPAT_TMS470_MATH_H */
|
||||||
|
|||||||
@@ -19,16 +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 COMPAT_VA_COPY_H
|
|
||||||
#define COMPAT_VA_COPY_H
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#if !defined(va_copy) && defined(_MSC_VER)
|
#if !defined(va_copy) && defined(_MSC_VER)
|
||||||
#define va_copy(dst, src) ((dst) = (src))
|
#define va_copy(dst, src) ((dst) = (src))
|
||||||
#endif
|
#endif
|
||||||
#if !defined(va_copy) && defined(__GNUC__) && __GNUC__ < 3
|
|
||||||
#define va_copy(dst, src) __va_copy(dst, src)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* COMPAT_VA_COPY_H */
|
|
||||||
|
|||||||
@@ -26,8 +26,8 @@
|
|||||||
* w32threads to pthreads wrapper
|
* w32threads to pthreads wrapper
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef COMPAT_W32PTHREADS_H
|
#ifndef FFMPEG_COMPAT_W32PTHREADS_H
|
||||||
#define COMPAT_W32PTHREADS_H
|
#define FFMPEG_COMPAT_W32PTHREADS_H
|
||||||
|
|
||||||
/* Build up a pthread-like API using underlying Windows API. Have only static
|
/* Build up a pthread-like API using underlying Windows API. Have only static
|
||||||
* methods so as to not conflict with a potentially linked in pthread-win32
|
* methods so as to not conflict with a potentially linked in pthread-win32
|
||||||
@@ -39,12 +39,6 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
|
||||||
#if _WIN32_WINNT < 0x0600 && defined(__MINGW32__)
|
|
||||||
#undef MemoryBarrier
|
|
||||||
#define MemoryBarrier __sync_synchronize
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#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"
|
||||||
@@ -60,56 +54,52 @@ typedef struct pthread_t {
|
|||||||
* not mutexes */
|
* not mutexes */
|
||||||
typedef CRITICAL_SECTION pthread_mutex_t;
|
typedef CRITICAL_SECTION pthread_mutex_t;
|
||||||
|
|
||||||
/* This is the CONDITION_VARIABLE typedef for using Windows' native
|
/* This is the CONDITIONAL_VARIABLE typedef for using Window's native
|
||||||
* conditional variables on kernels 6.0+. */
|
* conditional variables on kernels 6.0+.
|
||||||
#if HAVE_CONDITION_VARIABLE_PTR
|
* MinGW does not currently have this typedef. */
|
||||||
typedef CONDITION_VARIABLE pthread_cond_t;
|
|
||||||
#else
|
|
||||||
typedef struct pthread_cond_t {
|
typedef struct pthread_cond_t {
|
||||||
void *Ptr;
|
void *ptr;
|
||||||
} pthread_cond_t;
|
} pthread_cond_t;
|
||||||
|
|
||||||
|
/* function pointers to conditional variable API on windows 6.0+ kernels */
|
||||||
|
#if _WIN32_WINNT < 0x0600
|
||||||
|
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);
|
||||||
|
#else
|
||||||
|
#define cond_init InitializeConditionVariable
|
||||||
|
#define cond_broadcast WakeAllConditionVariable
|
||||||
|
#define cond_signal WakeConditionVariable
|
||||||
|
#define cond_wait SleepConditionVariableCS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _WIN32_WINNT >= 0x0600
|
static unsigned __stdcall attribute_align_arg win32thread_worker(void *arg)
|
||||||
#define InitializeCriticalSection(x) InitializeCriticalSectionEx(x, 0, 0)
|
|
||||||
#define WaitForSingleObject(a, b) WaitForSingleObjectEx(a, b, FALSE)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static av_unused unsigned __stdcall attribute_align_arg win32thread_worker(void *arg)
|
|
||||||
{
|
{
|
||||||
pthread_t *h = arg;
|
pthread_t *h = arg;
|
||||||
h->ret = h->func(h->arg);
|
h->ret = h->func(h->arg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_unused int pthread_create(pthread_t *thread, const void *unused_attr,
|
static int pthread_create(pthread_t *thread, const void *unused_attr,
|
||||||
void *(*start_routine)(void*), void *arg)
|
void *(*start_routine)(void*), void *arg)
|
||||||
{
|
{
|
||||||
thread->func = start_routine;
|
thread->func = start_routine;
|
||||||
thread->arg = arg;
|
thread->arg = arg;
|
||||||
#if HAVE_WINRT
|
|
||||||
thread->handle = (void*)CreateThread(NULL, 0, win32thread_worker, thread,
|
|
||||||
0, NULL);
|
|
||||||
#else
|
|
||||||
thread->handle = (void*)_beginthreadex(NULL, 0, win32thread_worker, thread,
|
thread->handle = (void*)_beginthreadex(NULL, 0, win32thread_worker, thread,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
#endif
|
|
||||||
return !thread->handle;
|
return !thread->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_unused int pthread_join(pthread_t thread, void **value_ptr)
|
static void pthread_join(pthread_t thread, void **value_ptr)
|
||||||
{
|
{
|
||||||
DWORD ret = WaitForSingleObject(thread.handle, INFINITE);
|
DWORD ret = WaitForSingleObject(thread.handle, INFINITE);
|
||||||
if (ret != WAIT_OBJECT_0) {
|
if (ret != WAIT_OBJECT_0)
|
||||||
if (ret == WAIT_ABANDONED)
|
return;
|
||||||
return EINVAL;
|
|
||||||
else
|
|
||||||
return EDEADLK;
|
|
||||||
}
|
|
||||||
if (value_ptr)
|
if (value_ptr)
|
||||||
*value_ptr = thread.ret;
|
*value_ptr = thread.ret;
|
||||||
CloseHandle(thread.handle);
|
CloseHandle(thread.handle);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int pthread_mutex_init(pthread_mutex_t *m, void* attr)
|
static inline int pthread_mutex_init(pthread_mutex_t *m, void* attr)
|
||||||
@@ -133,115 +123,8 @@ static inline int pthread_mutex_unlock(pthread_mutex_t *m)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _WIN32_WINNT >= 0x0600
|
|
||||||
typedef INIT_ONCE pthread_once_t;
|
|
||||||
#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
|
|
||||||
|
|
||||||
static av_unused int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
|
|
||||||
{
|
|
||||||
BOOL pending = FALSE;
|
|
||||||
InitOnceBeginInitialize(once_control, 0, &pending, NULL);
|
|
||||||
if (pending)
|
|
||||||
init_routine();
|
|
||||||
InitOnceComplete(once_control, 0, NULL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
|
|
||||||
{
|
|
||||||
InitializeConditionVariable(cond);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* native condition variables do not destroy */
|
|
||||||
static inline int pthread_cond_destroy(pthread_cond_t *cond)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int pthread_cond_broadcast(pthread_cond_t *cond)
|
|
||||||
{
|
|
||||||
WakeAllConditionVariable(cond);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
|
||||||
{
|
|
||||||
SleepConditionVariableCS(cond, mutex, INFINITE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int pthread_cond_signal(pthread_cond_t *cond)
|
|
||||||
{
|
|
||||||
WakeConditionVariable(cond);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* for pre-Windows 6.0 platforms we need to define and use our own condition
|
/* for pre-Windows 6.0 platforms we need to define and use our own condition
|
||||||
* variable and api */
|
* variable and api */
|
||||||
|
|
||||||
typedef struct win32_cond_t {
|
typedef struct win32_cond_t {
|
||||||
pthread_mutex_t mtx_broadcast;
|
pthread_mutex_t mtx_broadcast;
|
||||||
pthread_mutex_t mtx_waiter_count;
|
pthread_mutex_t mtx_waiter_count;
|
||||||
@@ -251,47 +134,36 @@ typedef struct win32_cond_t {
|
|||||||
volatile int is_broadcast;
|
volatile int is_broadcast;
|
||||||
} win32_cond_t;
|
} win32_cond_t;
|
||||||
|
|
||||||
/* function pointers to conditional variable API on windows 6.0+ kernels */
|
static void pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
|
||||||
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;
|
win32_cond_t *win32_cond = NULL;
|
||||||
|
|
||||||
w32thread_once_fallback(&w32thread_init_state, w32thread_init);
|
|
||||||
|
|
||||||
if (cond_init) {
|
if (cond_init) {
|
||||||
cond_init(cond);
|
cond_init(cond);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* non native condition variables */
|
/* non native condition variables */
|
||||||
win32_cond = av_mallocz(sizeof(win32_cond_t));
|
win32_cond = av_mallocz(sizeof(win32_cond_t));
|
||||||
if (!win32_cond)
|
if (!win32_cond)
|
||||||
return ENOMEM;
|
return;
|
||||||
cond->Ptr = win32_cond;
|
cond->ptr = win32_cond;
|
||||||
win32_cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
|
win32_cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
|
||||||
if (!win32_cond->semaphore)
|
if (!win32_cond->semaphore)
|
||||||
return ENOMEM;
|
return;
|
||||||
win32_cond->waiters_done = CreateEvent(NULL, TRUE, FALSE, NULL);
|
win32_cond->waiters_done = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
if (!win32_cond->waiters_done)
|
if (!win32_cond->waiters_done)
|
||||||
return ENOMEM;
|
return;
|
||||||
|
|
||||||
pthread_mutex_init(&win32_cond->mtx_waiter_count, NULL);
|
pthread_mutex_init(&win32_cond->mtx_waiter_count, NULL);
|
||||||
pthread_mutex_init(&win32_cond->mtx_broadcast, NULL);
|
pthread_mutex_init(&win32_cond->mtx_broadcast, NULL);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_unused int pthread_cond_destroy(pthread_cond_t *cond)
|
static void pthread_cond_destroy(pthread_cond_t *cond)
|
||||||
{
|
{
|
||||||
win32_cond_t *win32_cond = cond->Ptr;
|
win32_cond_t *win32_cond = cond->ptr;
|
||||||
/* native condition variables do not destroy */
|
/* native condition variables do not destroy */
|
||||||
if (cond_init)
|
if (cond_init)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
/* non native condition variables */
|
/* non native condition variables */
|
||||||
CloseHandle(win32_cond->semaphore);
|
CloseHandle(win32_cond->semaphore);
|
||||||
@@ -299,18 +171,17 @@ static av_unused int pthread_cond_destroy(pthread_cond_t *cond)
|
|||||||
pthread_mutex_destroy(&win32_cond->mtx_waiter_count);
|
pthread_mutex_destroy(&win32_cond->mtx_waiter_count);
|
||||||
pthread_mutex_destroy(&win32_cond->mtx_broadcast);
|
pthread_mutex_destroy(&win32_cond->mtx_broadcast);
|
||||||
av_freep(&win32_cond);
|
av_freep(&win32_cond);
|
||||||
cond->Ptr = NULL;
|
cond->ptr = NULL;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_unused int pthread_cond_broadcast(pthread_cond_t *cond)
|
static void pthread_cond_broadcast(pthread_cond_t *cond)
|
||||||
{
|
{
|
||||||
win32_cond_t *win32_cond = cond->Ptr;
|
win32_cond_t *win32_cond = cond->ptr;
|
||||||
int have_waiter;
|
int have_waiter;
|
||||||
|
|
||||||
if (cond_broadcast) {
|
if (cond_broadcast) {
|
||||||
cond_broadcast(cond);
|
cond_broadcast(cond);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* non native condition variables */
|
/* non native condition variables */
|
||||||
@@ -332,12 +203,11 @@ static av_unused int pthread_cond_broadcast(pthread_cond_t *cond)
|
|||||||
} else
|
} else
|
||||||
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||||
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
|
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_unused int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
static int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||||
{
|
{
|
||||||
win32_cond_t *win32_cond = cond->Ptr;
|
win32_cond_t *win32_cond = cond->ptr;
|
||||||
int last_waiter;
|
int last_waiter;
|
||||||
if (cond_wait) {
|
if (cond_wait) {
|
||||||
cond_wait(cond, mutex, INFINITE);
|
cond_wait(cond, mutex, INFINITE);
|
||||||
@@ -367,13 +237,13 @@ static av_unused int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mu
|
|||||||
return pthread_mutex_lock(mutex);
|
return pthread_mutex_lock(mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_unused int pthread_cond_signal(pthread_cond_t *cond)
|
static void pthread_cond_signal(pthread_cond_t *cond)
|
||||||
{
|
{
|
||||||
win32_cond_t *win32_cond = cond->Ptr;
|
win32_cond_t *win32_cond = cond->ptr;
|
||||||
int have_waiter;
|
int have_waiter;
|
||||||
if (cond_signal) {
|
if (cond_signal) {
|
||||||
cond_signal(cond);
|
cond_signal(cond);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&win32_cond->mtx_broadcast);
|
pthread_mutex_lock(&win32_cond->mtx_broadcast);
|
||||||
@@ -390,11 +260,9 @@ static av_unused int pthread_cond_signal(pthread_cond_t *cond)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
|
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static av_unused void w32thread_init(void)
|
static void w32thread_init(void)
|
||||||
{
|
{
|
||||||
#if _WIN32_WINNT < 0x0600
|
#if _WIN32_WINNT < 0x0600
|
||||||
HANDLE kernel_dll = GetModuleHandle(TEXT("kernel32.dll"));
|
HANDLE kernel_dll = GetModuleHandle(TEXT("kernel32.dll"));
|
||||||
@@ -407,12 +275,8 @@ static av_unused void w32thread_init(void)
|
|||||||
(void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
|
(void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
|
||||||
cond_wait =
|
cond_wait =
|
||||||
(void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
|
(void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
|
||||||
initonce_begin =
|
|
||||||
(void*)GetProcAddress(kernel_dll, "InitOnceBeginInitialize");
|
|
||||||
initonce_complete =
|
|
||||||
(void*)GetProcAddress(kernel_dll, "InitOnceComplete");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* COMPAT_W32PTHREADS_H */
|
#endif /* FFMPEG_COMPAT_W32PTHREADS_H */
|
||||||
|
|||||||
@@ -1,132 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Copyright (c) 2013, Derek Buitenhuis
|
|
||||||
#
|
|
||||||
# Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
# purpose with or without fee is hereby granted, provided that the above
|
|
||||||
# copyright notice and this permission notice appear in all copies.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
# mktemp isn't POSIX, so supply an implementation
|
|
||||||
mktemp() {
|
|
||||||
echo "${2%%XXX*}.${HOSTNAME}.${UID}.$$"
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ $# -lt 2 ]; then
|
|
||||||
echo "Usage: makedef <version_script> <objects>" >&2
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
vscript=$1
|
|
||||||
shift
|
|
||||||
|
|
||||||
if [ ! -f "$vscript" ]; then
|
|
||||||
echo "Version script does not exist" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
for object in "$@"; do
|
|
||||||
if [ ! -f "$object" ]; then
|
|
||||||
echo "Object does not exist: ${object}" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Create a lib temporarily to dump symbols from.
|
|
||||||
# It's just much easier to do it this way
|
|
||||||
libname=$(mktemp -u "library").lib
|
|
||||||
|
|
||||||
trap 'rm -f -- $libname' EXIT
|
|
||||||
|
|
||||||
lib -out:${libname} $@ >/dev/null
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "Could not create temporary library." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
IFS='
|
|
||||||
'
|
|
||||||
|
|
||||||
# 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
|
|
||||||
regex="none"
|
|
||||||
|
|
||||||
for line in $(cat ${vscript} | tr '\t' ' '); do
|
|
||||||
# We only care about global symbols
|
|
||||||
echo "${line}" | grep -q '^ \+global:'
|
|
||||||
if [ $? = 0 ]; then
|
|
||||||
started=1
|
|
||||||
line=$(echo "${line}" | sed -e 's/^ \{1,\}global: *//')
|
|
||||||
else
|
|
||||||
echo "${line}" | grep -q '^ \+local:'
|
|
||||||
if [ $? = 0 ]; then
|
|
||||||
started=0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ${started} = 0 ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Handle multiple symbols on one line
|
|
||||||
IFS=';'
|
|
||||||
|
|
||||||
# Work around stupid expansion to filenames
|
|
||||||
line=$(echo "${line}" | sed -e 's/\*/.\\+/g')
|
|
||||||
for exp in ${line}; do
|
|
||||||
# Remove leading and trailing whitespace
|
|
||||||
exp=$(echo "${exp}" | sed -e 's/^ *//' -e 's/ *$//')
|
|
||||||
|
|
||||||
if [ "${regex}" = "none" ]; then
|
|
||||||
regex="${exp}"
|
|
||||||
else
|
|
||||||
regex="${regex};${exp}"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
IFS='
|
|
||||||
'
|
|
||||||
done
|
|
||||||
|
|
||||||
dump=$(dumpbin -linkermember:1 ${libname})
|
|
||||||
|
|
||||||
rm ${libname}
|
|
||||||
|
|
||||||
IFS=';'
|
|
||||||
list=""
|
|
||||||
for exp in ${regex}; do
|
|
||||||
list="${list}"'
|
|
||||||
'$(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}" |
|
|
||||||
sed -e 's/^/ /')
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "EXPORTS"
|
|
||||||
echo "${list}" | sort | uniq | tail -n +2
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
LINK_EXE_PATH=$(dirname "$(command -v cl)")/link
|
|
||||||
if [ -x "$LINK_EXE_PATH" ]; then
|
|
||||||
"$LINK_EXE_PATH" $@
|
|
||||||
else
|
|
||||||
link $@
|
|
||||||
fi
|
|
||||||
exit $?
|
|
||||||
9
doc/.gitignore
vendored
9
doc/.gitignore
vendored
@@ -1,9 +0,0 @@
|
|||||||
/*.1
|
|
||||||
/*.3
|
|
||||||
/*.html
|
|
||||||
/*.pod
|
|
||||||
/config.texi
|
|
||||||
/avoptions_codec.texi
|
|
||||||
/avoptions_format.texi
|
|
||||||
/fate.txt
|
|
||||||
/print_options
|
|
||||||
999
doc/APIchanges
999
doc/APIchanges
File diff suppressed because it is too large
Load Diff
2433
doc/Doxyfile
2433
doc/Doxyfile
File diff suppressed because it is too large
Load Diff
72
doc/Makefile
72
doc/Makefile
@@ -14,11 +14,11 @@ COMPONENTS-$(CONFIG_AVFORMAT) += ffmpeg-formats ffmpeg-protocols
|
|||||||
COMPONENTS-$(CONFIG_AVDEVICE) += ffmpeg-devices
|
COMPONENTS-$(CONFIG_AVDEVICE) += ffmpeg-devices
|
||||||
COMPONENTS-$(CONFIG_AVFILTER) += ffmpeg-filters
|
COMPONENTS-$(CONFIG_AVFILTER) += ffmpeg-filters
|
||||||
|
|
||||||
MANPAGES1 = $(AVPROGS-yes:%=doc/%.1) $(AVPROGS-yes:%=doc/%-all.1) $(COMPONENTS-yes:%=doc/%.1)
|
MANPAGES1 = $(PROGS-yes:%=doc/%.1) $(PROGS-yes:%=doc/%-all.1) $(COMPONENTS-yes:%=doc/%.1)
|
||||||
MANPAGES3 = $(LIBRARIES-yes:%=doc/%.3)
|
MANPAGES3 = $(LIBRARIES-yes:%=doc/%.3)
|
||||||
MANPAGES = $(MANPAGES1) $(MANPAGES3)
|
MANPAGES = $(MANPAGES1) $(MANPAGES3)
|
||||||
PODPAGES = $(AVPROGS-yes:%=doc/%.pod) $(AVPROGS-yes:%=doc/%-all.pod) $(COMPONENTS-yes:%=doc/%.pod) $(LIBRARIES-yes:%=doc/%.pod)
|
PODPAGES = $(PROGS-yes:%=doc/%.pod) $(PROGS-yes:%=doc/%-all.pod) $(COMPONENTS-yes:%=doc/%.pod) $(LIBRARIES-yes:%=doc/%.pod)
|
||||||
HTMLPAGES = $(AVPROGS-yes:%=doc/%.html) $(AVPROGS-yes:%=doc/%-all.html) $(COMPONENTS-yes:%=doc/%.html) $(LIBRARIES-yes:%=doc/%.html) \
|
HTMLPAGES = $(PROGS-yes:%=doc/%.html) $(PROGS-yes:%=doc/%-all.html) $(COMPONENTS-yes:%=doc/%.html) $(LIBRARIES-yes:%=doc/%.html) \
|
||||||
doc/developer.html \
|
doc/developer.html \
|
||||||
doc/faq.html \
|
doc/faq.html \
|
||||||
doc/fate.html \
|
doc/fate.html \
|
||||||
@@ -36,30 +36,6 @@ 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_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_HTTP_MULTICLIENT_EXAMPLE) += http_multiclient
|
|
||||||
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
|
||||||
@@ -67,9 +43,7 @@ doc: documentation
|
|||||||
apidoc: doc/doxy/html
|
apidoc: doc/doxy/html
|
||||||
documentation: $(DOCS)
|
documentation: $(DOCS)
|
||||||
|
|
||||||
examples: $(DOC_EXAMPLES)
|
TEXIDEP = awk '/^@(verbatim)?include/ { printf "$@: $(@D)/%s\n", $$2 }' <$< >$(@:%=%.d)
|
||||||
|
|
||||||
TEXIDEP = perl $(SRC_PATH)/doc/texidep.pl $(SRC_PATH) $< $@ >$(@:%=%.d)
|
|
||||||
|
|
||||||
doc/%.txt: TAG = TXT
|
doc/%.txt: TAG = TXT
|
||||||
doc/%.txt: doc/%.texi
|
doc/%.txt: doc/%.texi
|
||||||
@@ -84,25 +58,14 @@ $(GENTEXI): doc/avoptions_%.texi: doc/print_options$(HOSTEXESUF)
|
|||||||
$(M)doc/print_options $* > $@
|
$(M)doc/print_options $* > $@
|
||||||
|
|
||||||
doc/%.html: TAG = HTML
|
doc/%.html: TAG = HTML
|
||||||
doc/%-all.html: TAG = HTML
|
|
||||||
|
|
||||||
ifdef HAVE_MAKEINFO_HTML
|
|
||||||
doc/%.html: doc/%.texi $(SRC_PATH)/doc/t2h.pm $(GENTEXI)
|
|
||||||
$(Q)$(TEXIDEP)
|
|
||||||
$(M)makeinfo --html -I doc --no-split -D config-not-all --init-file=$(SRC_PATH)/doc/t2h.pm --output $@ $<
|
|
||||||
|
|
||||||
doc/%-all.html: doc/%.texi $(SRC_PATH)/doc/t2h.pm $(GENTEXI)
|
|
||||||
$(Q)$(TEXIDEP)
|
|
||||||
$(M)makeinfo --html -I doc --no-split -D config-all --init-file=$(SRC_PATH)/doc/t2h.pm --output $@ $<
|
|
||||||
else
|
|
||||||
doc/%.html: doc/%.texi $(SRC_PATH)/doc/t2h.init $(GENTEXI)
|
doc/%.html: doc/%.texi $(SRC_PATH)/doc/t2h.init $(GENTEXI)
|
||||||
$(Q)$(TEXIDEP)
|
$(Q)$(TEXIDEP)
|
||||||
$(M)texi2html -I doc -monolithic --D=config-not-all --init-file $(SRC_PATH)/doc/t2h.init --output $@ $<
|
$(M)texi2html -I doc -monolithic --D=config-not-all --init-file $(SRC_PATH)/doc/t2h.init --output $@ $<
|
||||||
|
|
||||||
|
doc/%-all.html: TAG = HTML
|
||||||
doc/%-all.html: doc/%.texi $(SRC_PATH)/doc/t2h.init $(GENTEXI)
|
doc/%-all.html: doc/%.texi $(SRC_PATH)/doc/t2h.init $(GENTEXI)
|
||||||
$(Q)$(TEXIDEP)
|
$(Q)$(TEXIDEP)
|
||||||
$(M)texi2html -I doc -monolithic --D=config-all --init-file $(SRC_PATH)/doc/t2h.init --output $@ $<
|
$(M)texi2html -I doc -monolithic --D=config-all --init-file $(SRC_PATH)/doc/t2h.init --output $@ $<
|
||||||
endif
|
|
||||||
|
|
||||||
doc/%.pod: TAG = POD
|
doc/%.pod: TAG = POD
|
||||||
doc/%.pod: doc/%.texi $(SRC_PATH)/doc/texi2pod.pl $(GENTEXI)
|
doc/%.pod: doc/%.texi $(SRC_PATH)/doc/texi2pod.pl $(GENTEXI)
|
||||||
@@ -116,20 +79,14 @@ doc/%-all.pod: doc/%.texi $(SRC_PATH)/doc/texi2pod.pl $(GENTEXI)
|
|||||||
|
|
||||||
doc/%.1 doc/%.3: TAG = MAN
|
doc/%.1 doc/%.3: TAG = MAN
|
||||||
doc/%.1: doc/%.pod $(GENTEXI)
|
doc/%.1: doc/%.pod $(GENTEXI)
|
||||||
$(M)pod2man --section=1 --center=" " --release=" " --date=" " $< > $@
|
$(M)pod2man --section=1 --center=" " --release=" " $< > $@
|
||||||
doc/%.3: doc/%.pod $(GENTEXI)
|
doc/%.3: doc/%.pod $(GENTEXI)
|
||||||
$(M)pod2man --section=3 --center=" " --release=" " --date=" " $< > $@
|
$(M)pod2man --section=3 --center=" " --release=" " $< > $@
|
||||||
|
|
||||||
$(DOCS) doc/doxy/html: | doc/
|
$(DOCS) doc/doxy/html: | doc/
|
||||||
$(DOC_EXAMPLES:%$(EXESUF)=%.o): | doc/examples
|
|
||||||
OBJDIRS += doc/examples
|
|
||||||
|
|
||||||
DOXY_INPUT = $(INSTHEADERS) $(DOC_EXAMPLES:%$(EXESUF)=%.c) $(LIB_EXAMPLES:%$(EXESUF)=%.c)
|
doc/doxy/html: $(SRC_PATH)/doc/Doxyfile $(INSTHEADERS)
|
||||||
DOXY_INPUT_DEPS = $(addprefix $(SRC_PATH)/, $(DOXY_INPUT)) config.mak
|
$(M)$(SRC_PATH)/doc/doxy-wrapper.sh $(SRC_PATH) $^
|
||||||
|
|
||||||
doc/doxy/html: TAG = DOXY
|
|
||||||
doc/doxy/html: $(SRC_PATH)/doc/Doxyfile $(SRC_PATH)/doc/doxy-wrapper.sh $(DOXY_INPUT_DEPS)
|
|
||||||
$(M)OUT_DIR=$$PWD/doc/doxy; cd $(SRC_PATH); ./doc/doxy-wrapper.sh $$OUT_DIR $< $(DOXYGEN) $(DOXY_INPUT);
|
|
||||||
|
|
||||||
install-doc: install-html install-man
|
install-doc: install-html install-man
|
||||||
|
|
||||||
@@ -163,7 +120,7 @@ uninstall-html:
|
|||||||
$(RM) -r "$(DOCDIR)"
|
$(RM) -r "$(DOCDIR)"
|
||||||
|
|
||||||
uninstall-man:
|
uninstall-man:
|
||||||
$(RM) $(addprefix "$(MANDIR)/man1/",$(AVPROGS-yes:%=%.1) $(AVPROGS-yes:%=%-all.1) $(COMPONENTS-yes:%=%.1))
|
$(RM) $(addprefix "$(MANDIR)/man1/",$(PROGS-yes:%=%.1) $(PROGS-yes:%=%-all.1) $(COMPONENTS-yes:%=%.1))
|
||||||
$(RM) $(addprefix "$(MANDIR)/man3/",$(LIBRARIES-yes:%=%.3))
|
$(RM) $(addprefix "$(MANDIR)/man3/",$(LIBRARIES-yes:%=%.3))
|
||||||
|
|
||||||
clean:: docclean
|
clean:: docclean
|
||||||
@@ -171,13 +128,8 @@ clean:: docclean
|
|||||||
distclean:: docclean
|
distclean:: docclean
|
||||||
$(RM) doc/config.texi
|
$(RM) doc/config.texi
|
||||||
|
|
||||||
examplesclean:
|
docclean:
|
||||||
$(RM) $(ALL_DOC_EXAMPLES) $(ALL_DOC_EXAMPLES_G)
|
$(RM) $(TXTPAGES) doc/*.html doc/*.pod doc/*.1 doc/*.3 $(CLEANSUFFIXES:%=doc/%) doc/avoptions_*.texi
|
||||||
$(RM) $(CLEANSUFFIXES:%=doc/examples/%)
|
|
||||||
|
|
||||||
docclean: examplesclean
|
|
||||||
$(RM) $(CLEANSUFFIXES:%=doc/%)
|
|
||||||
$(RM) $(TXTPAGES) doc/*.html doc/*.pod doc/*.1 doc/*.3 doc/avoptions_*.texi
|
|
||||||
$(RM) -r doc/doxy/html
|
$(RM) -r doc/doxy/html
|
||||||
|
|
||||||
-include $(wildcard $(DOCS:%=%.d))
|
-include $(wildcard $(DOCS:%=%.d))
|
||||||
|
|||||||
16
doc/RELEASE_NOTES
Normal file
16
doc/RELEASE_NOTES
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Release Notes
|
||||||
|
=============
|
||||||
|
|
||||||
|
* 2.1 "Fourier" October, 2013
|
||||||
|
|
||||||
|
|
||||||
|
General notes
|
||||||
|
-------------
|
||||||
|
See the Changelog file for a list of significant changes. Note, there
|
||||||
|
are many more new features and bugfixes than whats listed there.
|
||||||
|
|
||||||
|
Bugreports against FFmpeg git master or the most recent FFmpeg release are
|
||||||
|
accepted. If you are experiencing issues with any formally released version of
|
||||||
|
FFmpeg, please try git master to check if the issue still exists. If it does,
|
||||||
|
make your report against the development code following the usual bug reporting
|
||||||
|
guidelines.
|
||||||
36
doc/avutil.txt
Normal file
36
doc/avutil.txt
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
AVUtil
|
||||||
|
======
|
||||||
|
libavutil is a small lightweight library of generally useful functions.
|
||||||
|
It is not a library for code needed by both libavcodec and libavformat.
|
||||||
|
|
||||||
|
|
||||||
|
Overview:
|
||||||
|
=========
|
||||||
|
adler32.c adler32 checksum
|
||||||
|
aes.c AES encryption and decryption
|
||||||
|
fifo.c resizeable first in first out buffer
|
||||||
|
intfloat_readwrite.c portable reading and writing of floating point values
|
||||||
|
log.c "printf" with context and level
|
||||||
|
md5.c MD5 Message-Digest Algorithm
|
||||||
|
rational.c code to perform exact calculations with rational numbers
|
||||||
|
tree.c generic AVL tree
|
||||||
|
crc.c generic CRC checksumming code
|
||||||
|
integer.c 128bit integer math
|
||||||
|
lls.c
|
||||||
|
mathematics.c greatest common divisor, integer sqrt, integer log2, ...
|
||||||
|
mem.c memory allocation routines with guaranteed alignment
|
||||||
|
|
||||||
|
Headers:
|
||||||
|
bswap.h big/little/native-endian conversion code
|
||||||
|
x86_cpu.h a few useful macros for unifying x86-64 and x86-32 code
|
||||||
|
avutil.h
|
||||||
|
common.h
|
||||||
|
intreadwrite.h reading and writing of unaligned big/little/native-endian integers
|
||||||
|
|
||||||
|
|
||||||
|
Goals:
|
||||||
|
======
|
||||||
|
* Modular (few interdependencies and the possibility of disabling individual parts during ./configure)
|
||||||
|
* Small (source and object)
|
||||||
|
* Efficient (low CPU and memory usage)
|
||||||
|
* Useful (avoid useless features almost no one needs)
|
||||||
@@ -13,16 +13,7 @@ bitstream filter using the option @code{--disable-bsf=BSF}.
|
|||||||
The option @code{-bsfs} of the ff* tools will display the list of
|
The option @code{-bsfs} of the ff* tools will display the list of
|
||||||
all the supported bitstream filters included in your build.
|
all the supported bitstream filters included in your build.
|
||||||
|
|
||||||
The ff* tools have a -bsf option applied per stream, taking a
|
Below is a description of the currently available bitstream filters.
|
||||||
comma-separated list of filters, whose parameters follow the filter
|
|
||||||
name after a '='.
|
|
||||||
|
|
||||||
@example
|
|
||||||
ffmpeg -i INPUT -c:v copy -bsf:v filter1[=opt1=str1:opt2=str2][,filter2] OUTPUT
|
|
||||||
@end example
|
|
||||||
|
|
||||||
Below is a description of the currently available bitstream filters,
|
|
||||||
with their parameters, if any.
|
|
||||||
|
|
||||||
@section aac_adtstoasc
|
@section aac_adtstoasc
|
||||||
|
|
||||||
@@ -67,10 +58,6 @@ 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 dca_core
|
|
||||||
|
|
||||||
Extract DCA core from DTS-HD streams.
|
|
||||||
|
|
||||||
@section h264_mp4toannexb
|
@section h264_mp4toannexb
|
||||||
|
|
||||||
Convert an H.264 bitstream from length prefixed mode to start code
|
Convert an H.264 bitstream from length prefixed mode to start code
|
||||||
@@ -87,18 +74,7 @@ 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
|
||||||
|
|
||||||
@section imxdump
|
@section imx_dump_header
|
||||||
|
|
||||||
Modifies the bitstream to fit in MOV and to be usable by the Final Cut
|
|
||||||
Pro decoder. This filter only applies to the mpeg2video codec, and is
|
|
||||||
likely not needed for Final Cut Pro 7 and newer with the appropriate
|
|
||||||
@option{-tag:v}.
|
|
||||||
|
|
||||||
For example, to remux 30 MB/sec NTSC IMX to MOV:
|
|
||||||
|
|
||||||
@example
|
|
||||||
ffmpeg -i input.mxf -c copy -bsf:v imxdump -tag:v mx3n output.mov
|
|
||||||
@end example
|
|
||||||
|
|
||||||
@section mjpeg2jpeg
|
@section mjpeg2jpeg
|
||||||
|
|
||||||
@@ -141,44 +117,12 @@ ffmpeg -i frame_%d.jpg -c:v copy rotated.avi
|
|||||||
|
|
||||||
@section movsub
|
@section movsub
|
||||||
|
|
||||||
|
@section mp3_header_compress
|
||||||
|
|
||||||
@section mp3_header_decompress
|
@section mp3_header_decompress
|
||||||
|
|
||||||
@section mpeg4_unpack_bframes
|
|
||||||
|
|
||||||
Unpack DivX-style packed B-frames.
|
|
||||||
|
|
||||||
DivX-style packed B-frames are not valid MPEG-4 and were only a
|
|
||||||
workaround for the broken Video for Windows subsystem.
|
|
||||||
They use more space, can cause minor AV sync issues, require more
|
|
||||||
CPU power to decode (unless the player has some decoded picture queue
|
|
||||||
to compensate the 2,0,2,0 frame per packet style) and cause
|
|
||||||
trouble if copied into a standard container like mp4 or mpeg-ps/ts,
|
|
||||||
because MPEG-4 decoders may not be able to decode them, since they are
|
|
||||||
not valid MPEG-4.
|
|
||||||
|
|
||||||
For example to fix an AVI file containing an MPEG-4 stream with
|
|
||||||
DivX-style packed B-frames using @command{ffmpeg}, you can use the command:
|
|
||||||
|
|
||||||
@example
|
|
||||||
ffmpeg -i INPUT.avi -codec copy -bsf:v mpeg4_unpack_bframes OUTPUT.avi
|
|
||||||
@end example
|
|
||||||
|
|
||||||
@section noise
|
@section noise
|
||||||
|
|
||||||
Damages the contents of packets without damaging the container. Can be
|
|
||||||
used for fuzzing or testing error resilience/concealment.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
A numeral string, whose value is related to how often output bytes will
|
|
||||||
be modified. Therefore, values below or equal to 0 are forbidden, and
|
|
||||||
the lower the more frequent bytes will be modified, with 1 meaning
|
|
||||||
every byte is modified.
|
|
||||||
|
|
||||||
@example
|
|
||||||
ffmpeg -i INPUT -c copy -bsf noise[=1] output.mkv
|
|
||||||
@end example
|
|
||||||
applies the modification to every byte.
|
|
||||||
|
|
||||||
@section remove_extra
|
@section remove_extra
|
||||||
|
|
||||||
@c man end BITSTREAM FILTERS
|
@c man end BITSTREAM FILTERS
|
||||||
|
|||||||
5
doc/bootstrap.min.css
vendored
5
doc/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
@@ -7,55 +7,44 @@ V
|
|||||||
Disable the default terse mode, the full command issued by make and its
|
Disable the default terse mode, the full command issued by make and its
|
||||||
output will be shown on the screen.
|
output will be shown on the screen.
|
||||||
|
|
||||||
DBG
|
|
||||||
Preprocess x86 external assembler files to a .dbg.asm file in the object
|
|
||||||
directory, which then gets compiled. Helps in developing those assembler
|
|
||||||
files.
|
|
||||||
|
|
||||||
DESTDIR
|
DESTDIR
|
||||||
Destination directory for the install targets, useful to prepare packages
|
Destination directory for the install targets, useful to prepare packages
|
||||||
or install FFmpeg in cross-environments.
|
or install FFmpeg in cross-environments.
|
||||||
|
|
||||||
GEN
|
|
||||||
Set to ‘1’ to generate the missing or mismatched references.
|
|
||||||
|
|
||||||
Makefile targets:
|
Makefile targets:
|
||||||
|
|
||||||
all
|
all
|
||||||
Default target, builds all the libraries and the executables.
|
Default target, builds all the libraries and the executables.
|
||||||
|
|
||||||
fate
|
fate
|
||||||
Run the fate test suite, note that you must have installed it.
|
Run the fate test suite, note you must have installed it
|
||||||
|
|
||||||
fate-list
|
fate-list
|
||||||
List all fate/regression test targets.
|
Will list all fate/regression test targets
|
||||||
|
|
||||||
install
|
install
|
||||||
Install headers, libraries and programs.
|
Install headers, libraries and programs.
|
||||||
|
|
||||||
examples
|
|
||||||
Build all examples located in doc/examples.
|
|
||||||
|
|
||||||
libavformat/output-example
|
libavformat/output-example
|
||||||
Build the libavformat basic example.
|
Build the libavformat basic example.
|
||||||
|
|
||||||
libswscale/swscale-test
|
libavcodec/api-example
|
||||||
Build the swscale self-test (useful also as an example).
|
Build the libavcodec basic example.
|
||||||
|
|
||||||
config
|
libswscale/swscale-test
|
||||||
Reconfigure the project with the current configuration.
|
Build the swscale self-test (useful also as example).
|
||||||
|
|
||||||
|
|
||||||
Useful standard make commands:
|
Useful standard make commands:
|
||||||
make -t <target>
|
make -t <target>
|
||||||
Touch all files that otherwise would be built, this is useful to reduce
|
Touch all files that otherwise would be build, this is useful to reduce
|
||||||
unneeded rebuilding when changing headers, but note that you must force rebuilds
|
unneeded rebuilding when changing headers, but note you must force rebuilds
|
||||||
of files that actually need it by hand then.
|
of files that actually need it by hand then.
|
||||||
|
|
||||||
make -j<num>
|
make -j<num>
|
||||||
Rebuild with multiple jobs at the same time. Faster on multi processor systems.
|
rebuild with multiple jobs at the same time. Faster on multi processor systems
|
||||||
|
|
||||||
make -k
|
make -k
|
||||||
Continue build in case of errors, this is useful for the regression tests
|
continue build in case of errors, this is useful for the regression tests
|
||||||
sometimes but note that it will still not run all reg tests.
|
sometimes but note it will still not run all reg tests.
|
||||||
|
|
||||||
|
|||||||
180
doc/codecs.texi
180
doc/codecs.texi
@@ -7,7 +7,7 @@ all the encoders and decoders. In addition each codec may support
|
|||||||
so-called private options, which are specific for a given codec.
|
so-called private options, which are specific for a given codec.
|
||||||
|
|
||||||
Sometimes, a global option may only affect a specific kind of codec,
|
Sometimes, a global option may only affect a specific kind of codec,
|
||||||
and may be nonsensical or ignored by another, so you need to be aware
|
and may be unsensical or ignored by another, so you need to be aware
|
||||||
of the meaning of the specified options. Also some options are
|
of the meaning of the specified options. Also some options are
|
||||||
meant only for decoding or encoding.
|
meant only for decoding or encoding.
|
||||||
|
|
||||||
@@ -71,9 +71,7 @@ Force low delay.
|
|||||||
@item global_header
|
@item global_header
|
||||||
Place global headers in extradata instead of every keyframe.
|
Place global headers in extradata instead of every keyframe.
|
||||||
@item bitexact
|
@item bitexact
|
||||||
Only write platform-, build- and time-independent data. (except (I)DCT).
|
Use only bitexact stuff (except (I)DCT).
|
||||||
This ensures that file and data checksums are reproducible and match between
|
|
||||||
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
|
@item cbp
|
||||||
@@ -129,7 +127,7 @@ should be @code{1 / frame_rate} and timestamp increments should be
|
|||||||
identically 1.
|
identically 1.
|
||||||
|
|
||||||
@item g @var{integer} (@emph{encoding,video})
|
@item g @var{integer} (@emph{encoding,video})
|
||||||
Set the group of picture (GOP) size. Default value is 12.
|
Set the group of picture size. Default value is 12.
|
||||||
|
|
||||||
@item ar @var{integer} (@emph{decoding/encoding,audio})
|
@item ar @var{integer} (@emph{decoding/encoding,audio})
|
||||||
Set audio sampling rate (in Hz).
|
Set audio sampling rate (in Hz).
|
||||||
@@ -174,13 +172,7 @@ Set max video quantizer scale (VBR). Must be included between -1 and
|
|||||||
Set max difference between the quantizer scale (VBR).
|
Set max difference between the quantizer scale (VBR).
|
||||||
|
|
||||||
@item bf @var{integer} (@emph{encoding,video})
|
@item bf @var{integer} (@emph{encoding,video})
|
||||||
Set max number of B frames between non-B-frames.
|
Set max number of B frames.
|
||||||
|
|
||||||
Must be an integer between -1 and 16. 0 means that B-frames are
|
|
||||||
disabled. If a value of -1 is used, it will choose an automatic value
|
|
||||||
depending on the encoder.
|
|
||||||
|
|
||||||
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.
|
||||||
@@ -257,7 +249,7 @@ Specify how strictly to follow the standards.
|
|||||||
Possible values:
|
Possible values:
|
||||||
@table @samp
|
@table @samp
|
||||||
@item very
|
@item very
|
||||||
strictly conform to an older more strict version of the spec or reference software
|
strictly conform to a older more strict version of the spec or reference software
|
||||||
@item strict
|
@item strict
|
||||||
strictly conform to all the things in the spec no matter what consequences
|
strictly conform to all the things in the spec no matter what consequences
|
||||||
@item normal
|
@item normal
|
||||||
@@ -287,11 +279,6 @@ detect bitstream specification deviations
|
|||||||
detect improper bitstream length
|
detect improper bitstream length
|
||||||
@item explode
|
@item explode
|
||||||
abort decoding on minor error detection
|
abort decoding on minor error detection
|
||||||
@item ignore_err
|
|
||||||
ignore decoding errors, and continue decoding.
|
|
||||||
This is useful if you want to analyze the content of a video and thus want
|
|
||||||
everything to be decoded no matter what. This option will not result in a video
|
|
||||||
that is pleasing to watch in case of errors.
|
|
||||||
@item careful
|
@item careful
|
||||||
consider things that violate the spec and have not been seen in the wild as errors
|
consider things that violate the spec and have not been seen in the wild as errors
|
||||||
@item compliant
|
@item compliant
|
||||||
@@ -396,9 +383,6 @@ Possible values:
|
|||||||
|
|
||||||
@item simplemmx
|
@item simplemmx
|
||||||
|
|
||||||
@item simpleauto
|
|
||||||
Automatically pick a IDCT compatible with the simple one
|
|
||||||
|
|
||||||
@item arm
|
@item arm
|
||||||
|
|
||||||
@item altivec
|
@item altivec
|
||||||
@@ -434,8 +418,6 @@ Possible values:
|
|||||||
iterative motion vector (MV) search (slow)
|
iterative motion vector (MV) search (slow)
|
||||||
@item deblock
|
@item deblock
|
||||||
use strong deblock filter for damaged MBs
|
use strong deblock filter for damaged MBs
|
||||||
@item favor_inter
|
|
||||||
favor predicting from the previous frame instead of the current
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@item bits_per_coded_sample @var{integer}
|
@item bits_per_coded_sample @var{integer}
|
||||||
@@ -456,9 +438,6 @@ Possible values:
|
|||||||
@item aspect @var{rational number} (@emph{encoding,video})
|
@item aspect @var{rational number} (@emph{encoding,video})
|
||||||
Set sample aspect ratio.
|
Set sample aspect ratio.
|
||||||
|
|
||||||
@item sar @var{rational number} (@emph{encoding,video})
|
|
||||||
Set sample aspect ratio. Alias to @var{aspect}.
|
|
||||||
|
|
||||||
@item debug @var{flags} (@emph{decoding/encoding,audio,video,subtitles})
|
@item debug @var{flags} (@emph{decoding/encoding,audio,video,subtitles})
|
||||||
Print specific debug info.
|
Print specific debug info.
|
||||||
|
|
||||||
@@ -478,9 +457,6 @@ per-block quantization parameter (QP)
|
|||||||
motion vector
|
motion vector
|
||||||
@item dct_coeff
|
@item dct_coeff
|
||||||
|
|
||||||
@item green_metadata
|
|
||||||
display complexity metadata for the upcoming frame, GoP or for a given duration.
|
|
||||||
|
|
||||||
@item skip
|
@item skip
|
||||||
|
|
||||||
@item startcode
|
@item startcode
|
||||||
@@ -501,15 +477,11 @@ visualize block types
|
|||||||
picture buffer allocations
|
picture buffer allocations
|
||||||
@item thread_ops
|
@item thread_ops
|
||||||
threading operations
|
threading operations
|
||||||
@item nomc
|
|
||||||
skip motion compensation
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@item vismv @var{integer} (@emph{decoding,video})
|
@item vismv @var{integer} (@emph{decoding,video})
|
||||||
Visualize motion vectors (MVs).
|
Visualize motion vectors (MVs).
|
||||||
|
|
||||||
This option is deprecated, see the codecview filter instead.
|
|
||||||
|
|
||||||
Possible values:
|
Possible values:
|
||||||
@table @samp
|
@table @samp
|
||||||
@item pf
|
@item pf
|
||||||
@@ -809,9 +781,6 @@ Frame data might be split into multiple chunks.
|
|||||||
Show all frames before the first keyframe.
|
Show all frames before the first keyframe.
|
||||||
@item skiprd
|
@item skiprd
|
||||||
Deprecated, use mpegvideo private options instead.
|
Deprecated, use mpegvideo private options instead.
|
||||||
@item export_mvs
|
|
||||||
Export motion vectors into frame side-data (see @code{AV_FRAME_DATA_MOTION_VECTORS})
|
|
||||||
for codecs that support it. See also @file{doc/examples/export_mvs.c}.
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@item error @var{integer} (@emph{encoding,video})
|
@item error @var{integer} (@emph{encoding,video})
|
||||||
@@ -820,17 +789,13 @@ for codecs that support it. See also @file{doc/examples/export_mvs.c}.
|
|||||||
Deprecated, use mpegvideo private options instead.
|
Deprecated, use mpegvideo private options instead.
|
||||||
|
|
||||||
@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
|
|
||||||
implementation supports multi-threading.
|
|
||||||
|
|
||||||
Possible values:
|
Possible values:
|
||||||
@table @samp
|
@table @samp
|
||||||
@item auto, 0
|
@item auto
|
||||||
automatically select the number of threads to set
|
detect a good number of threads
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
Default value is @samp{auto}.
|
|
||||||
|
|
||||||
@item me_threshold @var{integer} (@emph{encoding,video})
|
@item me_threshold @var{integer} (@emph{encoding,video})
|
||||||
Set motion estimation threshold.
|
Set motion estimation threshold.
|
||||||
|
|
||||||
@@ -875,14 +840,6 @@ Possible values:
|
|||||||
|
|
||||||
@item mpeg2_aac_he
|
@item mpeg2_aac_he
|
||||||
|
|
||||||
@item mpeg4_sp
|
|
||||||
|
|
||||||
@item mpeg4_core
|
|
||||||
|
|
||||||
@item mpeg4_main
|
|
||||||
|
|
||||||
@item mpeg4_asp
|
|
||||||
|
|
||||||
@item dts
|
@item dts
|
||||||
|
|
||||||
@item dts_es
|
@item dts_es
|
||||||
@@ -914,9 +871,6 @@ Set frame skip factor.
|
|||||||
|
|
||||||
@item skip_exp @var{integer} (@emph{encoding,video})
|
@item skip_exp @var{integer} (@emph{encoding,video})
|
||||||
Set frame skip exponent.
|
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})
|
@item skipcmp @var{integer} (@emph{encoding,video})
|
||||||
Set frame skip compare function.
|
Set frame skip compare function.
|
||||||
@@ -1049,98 +1003,10 @@ 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_1
|
|
||||||
SMPTE ST 428-1
|
|
||||||
@item smpte431
|
|
||||||
SMPTE 431-2
|
|
||||||
@item smpte432
|
|
||||||
SMPTE 432-1
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@item color_trc @var{integer} (@emph{decoding/encoding,video})
|
@item color_trc @var{integer} (@emph{decoding/encoding,video})
|
||||||
Possible values:
|
|
||||||
@table @samp
|
|
||||||
@item bt709
|
|
||||||
BT.709
|
|
||||||
@item gamma22
|
|
||||||
BT.470 M
|
|
||||||
@item gamma28
|
|
||||||
BT.470 BG
|
|
||||||
@item smpte170m
|
|
||||||
SMPTE 170 M
|
|
||||||
@item smpte240m
|
|
||||||
SMPTE 240 M
|
|
||||||
@item linear
|
|
||||||
Linear
|
|
||||||
@item log
|
|
||||||
Log
|
|
||||||
@item log_sqrt
|
|
||||||
Log square root
|
|
||||||
@item iec61966_2_4
|
|
||||||
IEC 61966-2-4
|
|
||||||
@item bt1361
|
|
||||||
BT.1361
|
|
||||||
@item iec61966_2_1
|
|
||||||
IEC 61966-2-1
|
|
||||||
@item bt2020_10bit
|
|
||||||
BT.2020 - 10 bit
|
|
||||||
@item bt2020_12bit
|
|
||||||
BT.2020 - 12 bit
|
|
||||||
@item smpte2084
|
|
||||||
SMPTE ST 2084
|
|
||||||
@item smpte428_1
|
|
||||||
SMPTE ST 428-1
|
|
||||||
@item arib-std-b67
|
|
||||||
ARIB STD-B67
|
|
||||||
@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 bt2020_ncl
|
|
||||||
BT.2020 NCL
|
|
||||||
@item bt2020_cl
|
|
||||||
BT.2020 CL
|
|
||||||
@item smpte2085
|
|
||||||
SMPTE 2085
|
|
||||||
@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
|
|
||||||
color_range the input has.
|
|
||||||
|
|
||||||
@item chroma_sample_location @var{integer} (@emph{decoding/encoding,video})
|
@item chroma_sample_location @var{integer} (@emph{decoding/encoding,video})
|
||||||
|
|
||||||
@item log_level_offset @var{integer}
|
@item log_level_offset @var{integer}
|
||||||
@@ -1150,26 +1016,15 @@ Set the log level offset.
|
|||||||
Number of slices, used in parallelized encoding.
|
Number of slices, used in parallelized encoding.
|
||||||
|
|
||||||
@item thread_type @var{flags} (@emph{decoding/encoding,video})
|
@item thread_type @var{flags} (@emph{decoding/encoding,video})
|
||||||
Select which multithreading methods to use.
|
Select multithreading type.
|
||||||
|
|
||||||
Use of @samp{frame} will increase decoding delay by one frame per
|
|
||||||
thread, so clients which cannot provide future frames should not use
|
|
||||||
it.
|
|
||||||
|
|
||||||
Possible values:
|
Possible values:
|
||||||
@table @samp
|
@table @samp
|
||||||
@item slice
|
@item slice
|
||||||
Decode more than one part of a single frame at once.
|
|
||||||
|
|
||||||
Multithreading using slices works only when the video was encoded with
|
|
||||||
slices.
|
|
||||||
|
|
||||||
@item frame
|
@item frame
|
||||||
Decode more than one frame at once.
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
Default value is @samp{slice+frame}.
|
|
||||||
|
|
||||||
@item audio_service_type @var{integer} (@emph{encoding,audio})
|
@item audio_service_type @var{integer} (@emph{encoding,audio})
|
||||||
Set audio service type.
|
Set audio service type.
|
||||||
|
|
||||||
@@ -1224,26 +1079,9 @@ Interlaced video, bottom coded first, top displayed first
|
|||||||
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})
|
|
||||||
"," separated list of allowed decoders. By default all are allowed.
|
|
||||||
|
|
||||||
@item dump_separator @var{string} (@emph{input})
|
|
||||||
Separator used to separate the fields printed on the command line about the
|
|
||||||
Stream parameters.
|
|
||||||
For example to separate the fields with newlines and indention:
|
|
||||||
@example
|
|
||||||
ffprobe -dump_separator "
|
|
||||||
" -i ~/videos/matrixbench_mpeg2.mpg
|
|
||||||
@end example
|
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@c man end CODEC OPTIONS
|
@c man end CODEC OPTIONS
|
||||||
|
|
||||||
@ifclear config-writeonly
|
|
||||||
@include decoders.texi
|
@include decoders.texi
|
||||||
@end ifclear
|
|
||||||
@ifclear config-readonly
|
|
||||||
@include encoders.texi
|
@include encoders.texi
|
||||||
@end ifclear
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ You can disable all the decoders with the configure option
|
|||||||
with the options @code{--enable-decoder=@var{DECODER}} /
|
with the options @code{--enable-decoder=@var{DECODER}} /
|
||||||
@code{--disable-decoder=@var{DECODER}}.
|
@code{--disable-decoder=@var{DECODER}}.
|
||||||
|
|
||||||
The option @code{-decoders} of the ff* tools will display the list of
|
The option @code{-codecs} of the ff* tools will display the list of
|
||||||
enabled decoders.
|
enabled decoders.
|
||||||
|
|
||||||
@c man end DECODERS
|
@c man end DECODERS
|
||||||
@@ -25,13 +25,6 @@ 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 hevc
|
|
||||||
|
|
||||||
HEVC / H.265 decoder.
|
|
||||||
|
|
||||||
Note: the @option{skip_loop_filter} option has effect only at level
|
|
||||||
@code{all}.
|
|
||||||
|
|
||||||
@section rawvideo
|
@section rawvideo
|
||||||
|
|
||||||
Raw video decoder.
|
Raw video decoder.
|
||||||
@@ -59,54 +52,6 @@ top-field-first is assumed
|
|||||||
@chapter Audio Decoders
|
@chapter Audio Decoders
|
||||||
@c man begin AUDIO DECODERS
|
@c man begin AUDIO DECODERS
|
||||||
|
|
||||||
A description of some of the currently available audio decoders
|
|
||||||
follows.
|
|
||||||
|
|
||||||
@section ac3
|
|
||||||
|
|
||||||
AC-3 audio decoder.
|
|
||||||
|
|
||||||
This decoder implements part of ATSC A/52:2010 and ETSI TS 102 366, as well as
|
|
||||||
the undocumented RealAudio 3 (a.k.a. dnet).
|
|
||||||
|
|
||||||
@subsection AC-3 Decoder Options
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
|
|
||||||
@item -drc_scale @var{value}
|
|
||||||
Dynamic Range Scale Factor. The factor to apply to dynamic range values
|
|
||||||
from the AC-3 stream. This factor is applied exponentially.
|
|
||||||
There are 3 notable scale factor ranges:
|
|
||||||
@table @option
|
|
||||||
@item drc_scale == 0
|
|
||||||
DRC disabled. Produces full range audio.
|
|
||||||
@item 0 < drc_scale <= 1
|
|
||||||
DRC enabled. Applies a fraction of the stream DRC value.
|
|
||||||
Audio reproduction is between full range and full compression.
|
|
||||||
@item drc_scale > 1
|
|
||||||
DRC enabled. Applies drc_scale asymmetrically.
|
|
||||||
Loud sounds are fully compressed. Soft sounds are enhanced.
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section flac
|
|
||||||
|
|
||||||
FLAC audio decoder.
|
|
||||||
|
|
||||||
This decoder aims to implement the complete FLAC specification from Xiph.
|
|
||||||
|
|
||||||
@subsection FLAC Decoder options
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
|
|
||||||
@item -use_buggy_lpc
|
|
||||||
The lavc FLAC encoder used to produce buggy streams with high lpc values
|
|
||||||
(like the default value). This option makes it possible to decode such streams
|
|
||||||
correctly by using lavc's old buggy lpc logic for decoding.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section ffwavesynth
|
@section ffwavesynth
|
||||||
|
|
||||||
Internal wave synthetizer.
|
Internal wave synthetizer.
|
||||||
@@ -187,33 +132,11 @@ Requires the presence of the libopus headers and library during
|
|||||||
configuration. You need to explicitly configure the build with
|
configuration. You need to explicitly configure the build with
|
||||||
@code{--enable-libopus}.
|
@code{--enable-libopus}.
|
||||||
|
|
||||||
An FFmpeg native decoder for Opus exists, so users can decode Opus
|
|
||||||
without this library.
|
|
||||||
|
|
||||||
@c man end AUDIO DECODERS
|
@c man end AUDIO DECODERS
|
||||||
|
|
||||||
@chapter Subtitles Decoders
|
@chapter Subtitles Decoders
|
||||||
@c man begin SUBTILES DECODERS
|
@c man begin SUBTILES DECODERS
|
||||||
|
|
||||||
@section dvbsub
|
|
||||||
|
|
||||||
@subsection Options
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item compute_clut
|
|
||||||
@table @option
|
|
||||||
@item -1
|
|
||||||
Compute clut if no matching CLUT is in the stream.
|
|
||||||
@item 0
|
|
||||||
Never compute CLUT
|
|
||||||
@item 1
|
|
||||||
Always compute CLUT and override the one provided in the stream.
|
|
||||||
@end table
|
|
||||||
@item dvb_substream
|
|
||||||
Selects the dvb substream, or all substreams if -1 which is default.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section dvdsub
|
@section dvdsub
|
||||||
|
|
||||||
This codec decodes the bitmap subtitles used in DVDs; the same subtitles can
|
This codec decodes the bitmap subtitles used in DVDs; the same subtitles can
|
||||||
@@ -233,15 +156,6 @@ The format for this option is a string containing 16 24-bits hexadecimal
|
|||||||
numbers (without 0x prefix) separated by comas, for example @code{0d00ee,
|
numbers (without 0x prefix) separated by 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}.
|
||||||
|
|
||||||
@item ifo_palette
|
|
||||||
Specify the IFO file from which the global palette is obtained.
|
|
||||||
(experimental)
|
|
||||||
|
|
||||||
@item forced_subs_only
|
|
||||||
Only decode subtitle entries marked as forced. Some titles have forced
|
|
||||||
and non-forced subtitles in the same track. Setting this flag to @code{1}
|
|
||||||
will only keep the forced subtitles. Default value is @code{0}.
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@section libzvbi-teletext
|
@section libzvbi-teletext
|
||||||
@@ -279,16 +193,10 @@ 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 30000 which is 30 seconds.
|
miliseconds. Default value is 30000 which is 30 seconds.
|
||||||
@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 (black) background.
|
||||||
@item txt_opacity
|
|
||||||
Sets the opacity (0-255) of the teletext background. If
|
|
||||||
@option{txt_transparent} is not set, it only affects characters between a start
|
|
||||||
box and an end box, typically subtitles. Default value is 0 if
|
|
||||||
@option{txt_transparent} is set, 255 otherwise.
|
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@c man end SUBTILES DECODERS
|
@c man end SUBTILES DECODERS
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ a:visited {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#banner img {
|
#banner img {
|
||||||
margin-bottom: 1px;
|
padding-bottom: 1px;
|
||||||
margin-top: 5px;
|
padding-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#body {
|
#body {
|
||||||
|
|||||||
@@ -18,12 +18,6 @@ enabled demuxers.
|
|||||||
|
|
||||||
The description of some of the currently available demuxers follows.
|
The description of some of the currently available demuxers follows.
|
||||||
|
|
||||||
@section aa
|
|
||||||
|
|
||||||
Audible Format 2, 3, and 4 demuxer.
|
|
||||||
|
|
||||||
This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files.
|
|
||||||
|
|
||||||
@section applehttp
|
@section applehttp
|
||||||
|
|
||||||
Apple HTTP Live Streaming demuxer.
|
Apple HTTP Live Streaming demuxer.
|
||||||
@@ -35,26 +29,6 @@ the caller can decide which variant streams to actually receive.
|
|||||||
The total bitrate of the variant that the stream belongs to is
|
The total bitrate of the variant that the stream belongs to is
|
||||||
available in a metadata key named "variant_bitrate".
|
available in a metadata key named "variant_bitrate".
|
||||||
|
|
||||||
@section apng
|
|
||||||
|
|
||||||
Animated Portable Network Graphics demuxer.
|
|
||||||
|
|
||||||
This demuxer is used to demux APNG files.
|
|
||||||
All headers, but the PNG signature, up to (but not including) the first
|
|
||||||
fcTL chunk are transmitted as extradata.
|
|
||||||
Frames are then split as being all the chunks between two fcTL ones, or
|
|
||||||
between the last fcTL and IEND chunks.
|
|
||||||
|
|
||||||
@table @option
|
|
||||||
@item -ignore_loop @var{bool}
|
|
||||||
Ignore the loop variable in the file if set.
|
|
||||||
@item -max_fps @var{int}
|
|
||||||
Maximum framerate in frames per second (0 for no limit).
|
|
||||||
@item -default_fps @var{int}
|
|
||||||
Default framerate in frames per second when none is specified in the file
|
|
||||||
(0 meaning as fast as possible).
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section asf
|
@section asf
|
||||||
|
|
||||||
Advanced Systems Format demuxer.
|
Advanced Systems Format demuxer.
|
||||||
@@ -72,7 +46,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
|
||||||
@@ -100,14 +74,14 @@ following directive is recognized:
|
|||||||
Path to a file to read; special characters and spaces must be escaped with
|
Path to a file to read; special characters and spaces must be escaped with
|
||||||
backslash or single quotes.
|
backslash or single quotes.
|
||||||
|
|
||||||
All subsequent file-related directives apply to that file.
|
All subsequent directives apply to that file.
|
||||||
|
|
||||||
@item @code{ffconcat version 1.0}
|
@item @code{ffconcat version 1.0}
|
||||||
Identify the script type and version. It also sets the @option{safe} option
|
Identify the script type and version. It also sets the @option{safe} option
|
||||||
to 1 if it was -1.
|
to 1 if it was to its default -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}}
|
||||||
@@ -118,63 +92,6 @@ file is not available or accurate.
|
|||||||
If the duration is set for all files, then it is possible to seek in the
|
If the duration is set for all files, then it is possible to seek in the
|
||||||
whole concatenated video.
|
whole concatenated video.
|
||||||
|
|
||||||
@item @code{inpoint @var{timestamp}}
|
|
||||||
In point of the file. When the demuxer opens the file it instantly seeks to the
|
|
||||||
specified timestamp. Seeking is done so that all streams can be presented
|
|
||||||
successfully at In point.
|
|
||||||
|
|
||||||
This directive works best with intra frame codecs, because for non-intra frame
|
|
||||||
ones you will usually get extra packets before the actual In point and the
|
|
||||||
decoded content will most likely contain frames before In point too.
|
|
||||||
|
|
||||||
For each file, packets before the file In point will have timestamps less than
|
|
||||||
the calculated start timestamp of the file (negative in case of the first
|
|
||||||
file), and the duration of the files (if not specified by the @code{duration}
|
|
||||||
directive) will be reduced based on their specified In point.
|
|
||||||
|
|
||||||
Because of potential packets before the specified In point, packet timestamps
|
|
||||||
may overlap between two concatenated files.
|
|
||||||
|
|
||||||
@item @code{outpoint @var{timestamp}}
|
|
||||||
Out point of the file. When the demuxer reaches the specified decoding
|
|
||||||
timestamp in any of the streams, it handles it as an end of file condition and
|
|
||||||
skips the current and all the remaining packets from all streams.
|
|
||||||
|
|
||||||
Out point is exclusive, which means that the demuxer will not output packets
|
|
||||||
with a decoding timestamp greater or equal to Out point.
|
|
||||||
|
|
||||||
This directive works best with intra frame codecs and formats where all streams
|
|
||||||
are tightly interleaved. For non-intra frame codecs you will usually get
|
|
||||||
additional packets with presentation timestamp after Out point therefore the
|
|
||||||
decoded content will most likely contain frames after Out point too. If your
|
|
||||||
streams are not tightly interleaved you may not get all the packets from all
|
|
||||||
streams before Out point and you may only will be able to decode the earliest
|
|
||||||
stream until Out point.
|
|
||||||
|
|
||||||
The duration of the files (if not specified by the @code{duration}
|
|
||||||
directive) will be reduced based on their specified Out point.
|
|
||||||
|
|
||||||
@item @code{file_packet_metadata @var{key=value}}
|
|
||||||
Metadata of the packets of the file. The specified metadata will be set for
|
|
||||||
each file packet. You can specify this directive multiple times to add multiple
|
|
||||||
metadata entries.
|
|
||||||
|
|
||||||
@item @code{stream}
|
|
||||||
Introduce a stream in the virtual file.
|
|
||||||
All subsequent stream-related directives apply to the last introduced
|
|
||||||
stream.
|
|
||||||
Some streams properties must be set in order to allow identifying the
|
|
||||||
matching streams in the subfiles.
|
|
||||||
If no streams are defined in the script, the streams from the first file are
|
|
||||||
copied.
|
|
||||||
|
|
||||||
@item @code{exact_stream_id @var{id}}
|
|
||||||
Set the id of the stream.
|
|
||||||
If this directive is given, the string with the corresponding id in the
|
|
||||||
subfiles will be used.
|
|
||||||
This is especially useful for MPEG-PS (VOB) files, where the order of the
|
|
||||||
streams is not reliable.
|
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@subsection Options
|
@subsection Options
|
||||||
@@ -192,57 +109,11 @@ component.
|
|||||||
|
|
||||||
If set to 0, any file name is accepted.
|
If set to 0, any file name is accepted.
|
||||||
|
|
||||||
The default is 1.
|
The default is -1, it is equivalent to 1 if the format was automatically
|
||||||
|
|
||||||
-1 is equivalent to 1 if the format was automatically
|
|
||||||
probed and 0 otherwise.
|
probed and 0 otherwise.
|
||||||
|
|
||||||
@item auto_convert
|
|
||||||
If set to 1, try to perform automatic conversions on packet data to make the
|
|
||||||
streams concatenable.
|
|
||||||
The default is 1.
|
|
||||||
|
|
||||||
Currently, the only conversion is adding the h264_mp4toannexb bitstream
|
|
||||||
filter to H.264 streams in MP4 format. This is necessary in particular if
|
|
||||||
there are resolution changes.
|
|
||||||
|
|
||||||
@item segment_time_metadata
|
|
||||||
If set to 1, every packet will contain the @var{lavf.concat.start_time} and the
|
|
||||||
@var{lavf.concat.duration} packet metadata values which are the start_time and
|
|
||||||
the duration of the respective file segments in the concatenated output
|
|
||||||
expressed in microseconds. The duration metadata is only set if it is known
|
|
||||||
based on the concat file.
|
|
||||||
The default is 0.
|
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@subsection Examples
|
|
||||||
|
|
||||||
@itemize
|
|
||||||
@item
|
|
||||||
Use absolute filenames and include some comments:
|
|
||||||
@example
|
|
||||||
# my first filename
|
|
||||||
file /mnt/share/file-1.wav
|
|
||||||
# my second filename including whitespace
|
|
||||||
file '/mnt/share/file 2.wav'
|
|
||||||
# my third filename including whitespace plus single quote
|
|
||||||
file '/mnt/share/file 3'\''.wav'
|
|
||||||
@end example
|
|
||||||
|
|
||||||
@item
|
|
||||||
Allow for input format auto-probing, use safe filenames and set the duration of
|
|
||||||
the first file:
|
|
||||||
@example
|
|
||||||
ffconcat version 1.0
|
|
||||||
|
|
||||||
file file-1.wav
|
|
||||||
duration 20.0
|
|
||||||
|
|
||||||
file subdir/file-2.wav
|
|
||||||
@end example
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
@section flv
|
@section flv
|
||||||
|
|
||||||
Adobe Flash Video Format demuxer.
|
Adobe Flash Video Format demuxer.
|
||||||
@@ -254,44 +125,30 @@ This demuxer is used to demux FLV files and RTMP network streams.
|
|||||||
Allocate the streams according to the onMetaData array content.
|
Allocate the streams according to the onMetaData array content.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@section gif
|
@section libgme
|
||||||
|
|
||||||
Animated GIF demuxer.
|
The Game Music Emu library is a collection of video game music file emulators.
|
||||||
|
|
||||||
It accepts the following options:
|
See @url{http://code.google.com/p/game-music-emu/} for more information.
|
||||||
|
|
||||||
@table @option
|
Some files have multiple tracks. The demuxer will pick the first track by
|
||||||
@item min_delay
|
default. The @option{track_index} option can be used to select a different
|
||||||
Set the minimum valid delay between frames in hundredths of seconds.
|
track. Track indexes start at 0. The demuxer exports the number of tracks as
|
||||||
Range is 0 to 6000. Default value is 2.
|
@var{tracks} meta data entry.
|
||||||
|
|
||||||
@item max_gif_delay
|
For very large files, the @option{max_size} option may have to be adjusted.
|
||||||
Set the maximum valid delay between frames in hundredth of seconds.
|
|
||||||
Range is 0 to 65535. Default value is 65535 (nearly eleven minutes),
|
|
||||||
the maximum value allowed by the specification.
|
|
||||||
|
|
||||||
@item default_delay
|
@section libquvi
|
||||||
Set the default delay between frames in hundredths of seconds.
|
|
||||||
Range is 0 to 6000. Default value is 10.
|
|
||||||
|
|
||||||
@item ignore_loop
|
Play media from Internet services using the quvi project.
|
||||||
GIF files can contain information to loop a certain number of times (or
|
|
||||||
infinitely). If @option{ignore_loop} is set to 1, then the loop setting
|
|
||||||
from the input will be ignored and looping will not occur. If set to 0,
|
|
||||||
then looping will occur and will cycle the number of times according to
|
|
||||||
the GIF. Default value is 1.
|
|
||||||
@end table
|
|
||||||
|
|
||||||
For example, with the overlay filter, place an infinitely looping GIF
|
The demuxer accepts a @option{format} option to request a specific quality. It
|
||||||
over another video:
|
is by default set to @var{best}.
|
||||||
@example
|
|
||||||
ffmpeg -i input.mp4 -ignore_loop 0 -i input.gif -filter_complex overlay=shortest=1 out.mkv
|
|
||||||
@end example
|
|
||||||
|
|
||||||
Note that in the above example the shortest option for overlay filter is
|
See @url{http://quvi.sourceforge.net/} for more information.
|
||||||
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
|
FFmpeg needs to be built with @code{--enable-libquvi} for this demuxer to be
|
||||||
infinitely.
|
enabled.
|
||||||
|
|
||||||
@section image2
|
@section image2
|
||||||
|
|
||||||
@@ -318,10 +175,6 @@ Select the pattern type used to interpret the provided filename.
|
|||||||
|
|
||||||
@var{pattern_type} accepts one of the following values.
|
@var{pattern_type} accepts one of the following values.
|
||||||
@table @option
|
@table @option
|
||||||
@item none
|
|
||||||
Disable pattern matching, therefore the video will only contain the specified
|
|
||||||
image. You should use this option if you do not want to create sequences from
|
|
||||||
multiple images and your filenames may contain special pattern characters.
|
|
||||||
@item sequence
|
@item sequence
|
||||||
Select a sequence pattern type, used to specify a sequence of files
|
Select a sequence pattern type, used to specify a sequence of files
|
||||||
indexed by sequential numbers.
|
indexed by sequential numbers.
|
||||||
@@ -396,8 +249,6 @@ is 5.
|
|||||||
If set to 1, will set frame timestamp to modification time of image file. Note
|
If set to 1, will set frame timestamp to modification time of image file. Note
|
||||||
that monotonity of timestamps is not provided: images go in the same order as
|
that monotonity of timestamps is not provided: images go in the same order as
|
||||||
without this option. Default value is 0.
|
without this option. Default value is 0.
|
||||||
If set to 2, will set frame timestamp to the modification time of the image file in
|
|
||||||
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.
|
||||||
@@ -428,109 +279,24 @@ ffmpeg -framerate 10 -pattern_type glob -i "*.png" out.mkv
|
|||||||
@end example
|
@end example
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@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 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/QuickTime
|
|
||||||
|
|
||||||
QuickTime / MP4 demuxer.
|
|
||||||
|
|
||||||
This demuxer accepts the following options:
|
|
||||||
@table @option
|
|
||||||
@item enable_drefs
|
|
||||||
Enable loading of external tracks, disabled by default.
|
|
||||||
Enabling this can theoretically leak information in some use cases.
|
|
||||||
|
|
||||||
@item use_absolute_path
|
|
||||||
Allows loading of external tracks via absolute paths, disabled by default.
|
|
||||||
Enabling this poses a security risk. It should only be enabled if the source
|
|
||||||
is known to be non malicious.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section mpegts
|
@section mpegts
|
||||||
|
|
||||||
MPEG-2 transport stream demuxer.
|
MPEG-2 transport stream demuxer.
|
||||||
|
|
||||||
This demuxer accepts the following options:
|
|
||||||
@table @option
|
@table @option
|
||||||
@item resync_size
|
|
||||||
Set size limit for looking up a new synchronization. Default value is
|
|
||||||
65536.
|
|
||||||
|
|
||||||
@item fix_teletext_pts
|
@item fix_teletext_pts
|
||||||
Override teletext packet PTS and DTS values with the timestamps calculated
|
Overrides teletext packet PTS and DTS values with the timestamps calculated
|
||||||
from the PCR of the first program which the teletext stream is part of and is
|
from the PCR of the first program which the teletext stream is part of and is
|
||||||
not discarded. Default value is 1, set this option to 0 if you want your
|
not discarded. Default value is 1, set this option to 0 if you want your
|
||||||
teletext packet PTS and DTS values untouched.
|
teletext packet PTS and DTS values untouched.
|
||||||
|
|
||||||
@item ts_packetsize
|
|
||||||
Output option carrying the raw packet size in bytes.
|
|
||||||
Show the detected raw packet size, cannot be set by the user.
|
|
||||||
|
|
||||||
@item scan_all_pmts
|
|
||||||
Scan and combine all PMTs. The value is an integer with value from -1
|
|
||||||
to 1 (-1 means automatic setting, 1 means enabled, 0 means
|
|
||||||
disabled). Default value is -1.
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section mpjpeg
|
|
||||||
|
|
||||||
MJPEG encapsulated in multi-part MIME demuxer.
|
|
||||||
|
|
||||||
This demuxer allows reading of MJPEG, where each frame is represented as a part of
|
|
||||||
multipart/x-mixed-replace stream.
|
|
||||||
@table @option
|
|
||||||
|
|
||||||
@item strict_mime_boundary
|
|
||||||
Default implementation applies a relaxed standard to multi-part MIME boundary detection,
|
|
||||||
to prevent regression with numerous existing endpoints not generating a proper MIME
|
|
||||||
MJPEG stream. Turning this option on by setting it to 1 will result in a stricter check
|
|
||||||
of the boundary value.
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@section rawvideo
|
@section rawvideo
|
||||||
|
|
||||||
Raw video demuxer.
|
Raw video demuxer.
|
||||||
|
|
||||||
This demuxer allows one to read raw video data. Since there is no header
|
This demuxer allows to read raw video data. Since there is no header
|
||||||
specifying the assumed video parameters, the user must specify them
|
specifying the assumed video parameters, the user must specify them
|
||||||
in order to be able to decode the data correctly.
|
in order to be able to decode the data correctly.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
\input texinfo @c -*- texinfo -*-
|
\input texinfo @c -*- texinfo -*-
|
||||||
@documentencoding UTF-8
|
|
||||||
|
|
||||||
@settitle Developer Documentation
|
@settitle Developer Documentation
|
||||||
@titlepage
|
@titlepage
|
||||||
@@ -28,14 +27,14 @@ this document.
|
|||||||
|
|
||||||
For more detailed legal information about the use of FFmpeg in
|
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{http://ffmpeg.org/legal.html}.
|
||||||
|
|
||||||
@section Contributing
|
@section Contributing
|
||||||
|
|
||||||
There are 3 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 main developer 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
|
@item Committing changes to a git clone, for example on github.com or
|
||||||
gitorious.org. And asking us to merge these changes.
|
gitorious.org. And asking us to merge these changes.
|
||||||
@@ -65,9 +64,6 @@ rejected by the git repository.
|
|||||||
@item
|
@item
|
||||||
You should try to limit your code lines to 80 characters; however, do so if
|
You should try to limit your code lines to 80 characters; however, do so if
|
||||||
and only if this improves readability.
|
and only if this improves readability.
|
||||||
|
|
||||||
@item
|
|
||||||
K&R coding style is used.
|
|
||||||
@end itemize
|
@end itemize
|
||||||
The presentation is one inspired by 'indent -i4 -kr -nut'.
|
The presentation is one inspired by 'indent -i4 -kr -nut'.
|
||||||
|
|
||||||
@@ -96,7 +92,7 @@ for markup commands, i.e. use @code{@@param} and not @code{\param}.
|
|||||||
* more text ...
|
* more text ...
|
||||||
* ...
|
* ...
|
||||||
*/
|
*/
|
||||||
typedef struct Foobar @{
|
typedef struct Foobar@{
|
||||||
int var1; /**< var1 description */
|
int var1; /**< var1 description */
|
||||||
int var2; ///< var2 description
|
int var2; ///< var2 description
|
||||||
/** var3 description */
|
/** var3 description */
|
||||||
@@ -127,10 +123,10 @@ the @samp{inline} keyword;
|
|||||||
@samp{//} comments;
|
@samp{//} comments;
|
||||||
|
|
||||||
@item
|
@item
|
||||||
designated struct initializers (@samp{struct s x = @{ .i = 17 @};});
|
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 @};})
|
||||||
@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
|
||||||
@@ -159,7 +155,7 @@ GCC statement expressions (@samp{(x = (@{ int y = 4; y; @})}).
|
|||||||
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
|
||||||
for example structs and enums; they should always be in CamelCase.
|
for example structs and enums; they should always be in the CamelCase
|
||||||
|
|
||||||
There are the following conventions for naming variables and functions:
|
There are the following conventions for naming variables and functions:
|
||||||
|
|
||||||
@@ -231,7 +227,7 @@ autocmd InsertEnter * match ForbiddenWhitespace /\t\|\s\+\%#\@@<!$/
|
|||||||
@end example
|
@end example
|
||||||
|
|
||||||
For Emacs, add these roughly equivalent lines to your @file{.emacs.d/init.el}:
|
For Emacs, add these roughly equivalent lines to your @file{.emacs.d/init.el}:
|
||||||
@lisp
|
@example
|
||||||
(c-add-style "ffmpeg"
|
(c-add-style "ffmpeg"
|
||||||
'("k&r"
|
'("k&r"
|
||||||
(c-basic-offset . 4)
|
(c-basic-offset . 4)
|
||||||
@@ -242,17 +238,17 @@ 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 example
|
||||||
|
|
||||||
@section Development Policy
|
@section Development Policy
|
||||||
|
|
||||||
@subsection 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
|
||||||
a gift-style license, the
|
a gift-style license, the
|
||||||
@uref{http://opensource.org/licenses/isc-license.txt, ISC} or
|
@uref{http://www.isc.org/software/license/, ISC} or
|
||||||
@uref{http://mit-license.org/, MIT} license.
|
@uref{http://mit-license.org/, MIT} license.
|
||||||
@uref{http://www.gnu.org/licenses/gpl-2.0.html, GPL 2} including
|
@uref{http://www.gnu.org/licenses/gpl-2.0.html, GPL 2} including
|
||||||
an "or any later version" clause is also acceptable, but LGPL is
|
an "or any later version" clause is also acceptable, but LGPL is
|
||||||
@@ -260,15 +256,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.
|
||||||
@@ -276,24 +272,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
|
||||||
@@ -302,7 +304,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
|
||||||
@@ -316,43 +318,56 @@ 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.
|
||||||
Recommended format:
|
Recommended format:
|
||||||
|
|
||||||
@example
|
|
||||||
area changed: Short 1 line description
|
area changed: Short 1 line description
|
||||||
|
|
||||||
details describing what and why and giving references.
|
details describing what and why and giving references.
|
||||||
@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!
|
||||||
|
|
||||||
@subsection 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
|
||||||
@@ -362,7 +377,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.
|
||||||
@@ -371,65 +386,16 @@ 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.
|
|
||||||
|
|
||||||
@subsection Documentation/Other
|
|
||||||
@subheading Subscribe to the ffmpeg-cvslog mailing list.
|
|
||||||
It is important to do this as the diffs of all commits are sent there and
|
|
||||||
reviewed by all the other developers. Bugs and possible improvements or
|
|
||||||
general questions regarding commits are discussed there. We expect you to
|
|
||||||
react if problems with your code are uncovered.
|
|
||||||
|
|
||||||
@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
|
||||||
finding a new maintainer and also don't forget to update the @file{MAINTAINERS} file.
|
finding a new maintainer and also don't forget updating 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.
|
||||||
|
|
||||||
@section Code of conduct
|
|
||||||
|
|
||||||
Be friendly and respectful towards others and third parties.
|
|
||||||
Treat others the way you yourself want to be treated.
|
|
||||||
|
|
||||||
Be considerate. Not everyone shares the same viewpoint and priorities as you do.
|
|
||||||
Different opinions and interpretations help the project.
|
|
||||||
Looking at issues from a different perspective assists development.
|
|
||||||
|
|
||||||
Do not assume malice for things that can be attributed to incompetence. Even if
|
|
||||||
it is malice, it's rarely good to start with that as initial assumption.
|
|
||||||
|
|
||||||
Stay friendly even if someone acts contrarily. Everyone has a bad day
|
|
||||||
once in a while.
|
|
||||||
If you yourself have a bad day or are angry then try to take a break and reply
|
|
||||||
once you are calm and without anger if you have to.
|
|
||||||
|
|
||||||
Try to help other team members and cooperate if you can.
|
|
||||||
|
|
||||||
The goal of software development is to create technical excellence, not for any
|
|
||||||
individual to be better and "win" against the others. Large software projects
|
|
||||||
are only possible and successful through teamwork.
|
|
||||||
|
|
||||||
If someone struggles do not put them down. Give them a helping hand
|
|
||||||
instead and point them in the right direction.
|
|
||||||
|
|
||||||
Finally, keep in mind the immortal words of Bill and Ted,
|
|
||||||
"Be excellent to each other."
|
|
||||||
|
|
||||||
@anchor{Submitting patches}
|
@anchor{Submitting patches}
|
||||||
@section Submitting patches
|
@section Submitting patches
|
||||||
|
|
||||||
@@ -437,7 +403,7 @@ First, read the @ref{Coding Rules} above if you did not yet, in particular
|
|||||||
the rules regarding patch submission.
|
the rules regarding patch submission.
|
||||||
|
|
||||||
When you submit your patch, please use @code{git format-patch} or
|
When you submit your patch, please use @code{git format-patch} or
|
||||||
@code{git send-email}. We cannot read other diffs :-).
|
@code{git send-email}. We cannot read other diffs :-)
|
||||||
|
|
||||||
Also please do not submit a patch which contains several unrelated changes.
|
Also please do not submit a patch which contains several unrelated changes.
|
||||||
Split it into separate, self-contained pieces. This does not mean splitting
|
Split it into separate, self-contained pieces. This does not mean splitting
|
||||||
@@ -460,15 +426,11 @@ Also please if you send several patches, send each patch as a separate mail,
|
|||||||
do not attach several unrelated patches to the same mail.
|
do not attach several unrelated patches to the same mail.
|
||||||
|
|
||||||
Patches should be posted to the
|
Patches should be posted to the
|
||||||
@uref{https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel, ffmpeg-devel}
|
@uref{http://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel, ffmpeg-devel}
|
||||||
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.
|
|
||||||
|
|
||||||
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
|
||||||
@@ -577,10 +539,6 @@ tools/trasher, the noise bitstream filter, and
|
|||||||
should not crash, end in a (near) infinite loop, or allocate ridiculous
|
should not crash, end in a (near) infinite loop, or allocate ridiculous
|
||||||
amounts of memory when fed damaged data.
|
amounts of memory when fed damaged data.
|
||||||
|
|
||||||
@item
|
|
||||||
Did you test your decoder or demuxer against sample files?
|
|
||||||
Samples may be obtained at @url{https://samples.ffmpeg.org}.
|
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Does the patch not mix functional and cosmetic changes?
|
Does the patch not mix functional and cosmetic changes?
|
||||||
|
|
||||||
@@ -601,7 +559,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 ftp://upload.ffmpeg.org.
|
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?
|
||||||
@@ -630,10 +588,10 @@ Lines with similar content should be aligned vertically when doing so
|
|||||||
improves readability.
|
improves readability.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Consider adding a regression test for your code.
|
Consider to add a regression test for your code.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
If you added YASM code please check that things still work with --disable-yasm.
|
If you added YASM code please check that things still work with --disable-yasm
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Make sure you check the return values of function and return appropriate
|
Make sure you check the return values of function and return appropriate
|
||||||
@@ -671,10 +629,6 @@ not related to the comments received during review. Such patches will
|
|||||||
be rejected. Instead, submit significant changes or new features as
|
be rejected. Instead, submit significant changes or new features as
|
||||||
separate patches.
|
separate patches.
|
||||||
|
|
||||||
Everyone is welcome to review patches. Also if you are waiting for your patch
|
|
||||||
to be reviewed, please consider helping to review other patches, that is a great
|
|
||||||
way to get everyone's patches reviewed sooner.
|
|
||||||
|
|
||||||
@anchor{Regression tests}
|
@anchor{Regression tests}
|
||||||
@section Regression tests
|
@section Regression tests
|
||||||
|
|
||||||
@@ -690,14 +644,15 @@ accordingly].
|
|||||||
@subsection 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 inlcuded in the fate-suite.
|
||||||
First please make sure that the sample file is as small as possible to test the
|
First please make sure that the sample file is as small as possible to test the
|
||||||
respective decoder or demuxer sufficiently. Large files increase network
|
respective decoder or demuxer sufficiently. Large files increase network
|
||||||
bandwidth and disk space requirements.
|
bandwidth and disk space requirements.
|
||||||
Once you have a working fate test and fate sample, provide in the commit
|
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 introductionary 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.
|
||||||
|
|
||||||
|
|
||||||
@subsection 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
|
||||||
@@ -745,7 +700,7 @@ 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
|
||||||
Linux distributions, etc.). At regular times, a @strong{release
|
Linux distributions, etc.). At regular times, a @strong{release
|
||||||
manager} prepares, tests and publishes tarballs on the
|
manager} prepares, tests and publishes tarballs on the
|
||||||
@url{https://ffmpeg.org} website.
|
@url{http://ffmpeg.org} website.
|
||||||
|
|
||||||
There are two kinds of releases:
|
There are two kinds of releases:
|
||||||
|
|
||||||
@@ -824,7 +779,7 @@ Prepare the release tarballs in @code{bz2} and @code{gz} formats, and
|
|||||||
supplementing files that contain @code{gpg} signatures
|
supplementing files that contain @code{gpg} signatures
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Publish the tarballs at @url{https://ffmpeg.org/releases}. Create and
|
Publish the tarballs at @url{http://ffmpeg.org/releases}. Create and
|
||||||
push an annotated tag in the form @code{nX}, with @code{X}
|
push an annotated tag in the form @code{nX}, with @code{X}
|
||||||
containing the version number.
|
containing the version number.
|
||||||
|
|
||||||
@@ -836,7 +791,7 @@ with a news entry for the website.
|
|||||||
Publish the news entry.
|
Publish the news entry.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Send an announcement to the mailing list.
|
Send announcement to the mailing list.
|
||||||
@end enumerate
|
@end enumerate
|
||||||
|
|
||||||
@bye
|
@bye
|
||||||
|
|||||||
@@ -17,9 +17,5 @@ for programmatic use.
|
|||||||
|
|
||||||
@c man end DEVICE OPTIONS
|
@c man end DEVICE OPTIONS
|
||||||
|
|
||||||
@ifclear config-writeonly
|
|
||||||
@include indevs.texi
|
@include indevs.texi
|
||||||
@end ifclear
|
|
||||||
@ifclear config-readonly
|
|
||||||
@include outdevs.texi
|
@include outdevs.texi
|
||||||
@end ifclear
|
|
||||||
|
|||||||
@@ -1,21 +1,14 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
OUT_DIR="${1}"
|
SRC_PATH="${1}"
|
||||||
DOXYFILE="${2}"
|
DOXYFILE="${2}"
|
||||||
DOXYGEN="${3}"
|
|
||||||
|
|
||||||
shift 3
|
shift 2
|
||||||
|
|
||||||
if [ -e "VERSION" ]; then
|
doxygen - <<EOF
|
||||||
VERSION=`cat "VERSION"`
|
|
||||||
else
|
|
||||||
VERSION=`git describe`
|
|
||||||
fi
|
|
||||||
|
|
||||||
$DOXYGEN - <<EOF
|
|
||||||
@INCLUDE = ${DOXYFILE}
|
@INCLUDE = ${DOXYFILE}
|
||||||
INPUT = $@
|
INPUT = $@
|
||||||
HTML_TIMESTAMP = NO
|
HTML_HEADER = ${SRC_PATH}/doc/doxy/header.html
|
||||||
PROJECT_NUMBER = $VERSION
|
HTML_FOOTER = ${SRC_PATH}/doc/doxy/footer.html
|
||||||
OUTPUT_DIRECTORY = $OUT_DIR
|
HTML_STYLESHEET = ${SRC_PATH}/doc/doxy/doxy_stylesheet.css
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
1
doc/doxy/.gitignore
vendored
1
doc/doxy/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
/html/
|
|
||||||
2019
doc/doxy/doxy_stylesheet.css
Normal file
2019
doc/doxy/doxy_stylesheet.css
Normal file
File diff suppressed because it is too large
Load Diff
9
doc/doxy/footer.html
Normal file
9
doc/doxy/footer.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
<footer class="footer pagination-right">
|
||||||
|
<span class="label label-info">
|
||||||
|
Generated on $datetime for $projectname by <a href="http://www.doxygen.org/index.html">doxygen</a> $doxygenversion
|
||||||
|
</span>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
16
doc/doxy/header.html
Normal file
16
doc/doxy/header.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||||
|
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
|
||||||
|
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
|
||||||
|
<link href="$relpath$doxy_stylesheet.css" rel="stylesheet" type="text/css" />
|
||||||
|
<!--Header replace -->
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<!--Header replace -->
|
||||||
|
<div class="menu">
|
||||||
1230
doc/encoders.texi
1230
doc/encoders.texi
File diff suppressed because it is too large
Load Diff
@@ -76,7 +76,7 @@ EMFILE POSIX ++++++ Too many open files
|
|||||||
EMLINK POSIX ++++++ Too many links
|
EMLINK POSIX ++++++ Too many links
|
||||||
EMSGSIZE POSIX +++..+ Message too long
|
EMSGSIZE POSIX +++..+ Message too long
|
||||||
EMULTIHOP POSIX ++4... Multihop attempted
|
EMULTIHOP POSIX ++4... Multihop attempted
|
||||||
ENAMETOOLONG POSIX - ++++++ File name too long
|
ENAMETOOLONG POSIX - ++++++ Filen ame too long
|
||||||
ENAVAIL +..... No XENIX semaphores available
|
ENAVAIL +..... No XENIX semaphores available
|
||||||
ENEEDAUTH .++... Need authenticator
|
ENEEDAUTH .++... Need authenticator
|
||||||
ENETDOWN POSIX +++..+ Network is down
|
ENETDOWN POSIX +++..+ Network is down
|
||||||
|
|||||||
18
doc/examples/.gitignore
vendored
18
doc/examples/.gitignore
vendored
@@ -1,18 +0,0 @@
|
|||||||
/avio_dir_cmd
|
|
||||||
/avio_reading
|
|
||||||
/decoding_encoding
|
|
||||||
/demuxing_decoding
|
|
||||||
/extract_mvs
|
|
||||||
/filter_audio
|
|
||||||
/filtering_audio
|
|
||||||
/filtering_video
|
|
||||||
/http_multiclient
|
|
||||||
/metadata
|
|
||||||
/muxing
|
|
||||||
/pc-uninstalled
|
|
||||||
/qsvdec
|
|
||||||
/remuxing
|
|
||||||
/resampling_audio
|
|
||||||
/scaling_video
|
|
||||||
/transcode_aac
|
|
||||||
/transcoding
|
|
||||||
@@ -11,26 +11,18 @@ CFLAGS += -Wall -g
|
|||||||
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
|
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
|
||||||
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
|
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
|
||||||
|
|
||||||
EXAMPLES= avio_dir_cmd \
|
EXAMPLES= decoding_encoding \
|
||||||
avio_reading \
|
demuxing \
|
||||||
decoding_encoding \
|
|
||||||
demuxing_decoding \
|
|
||||||
extract_mvs \
|
|
||||||
filtering_video \
|
filtering_video \
|
||||||
filtering_audio \
|
filtering_audio \
|
||||||
http_multiclient \
|
|
||||||
metadata \
|
metadata \
|
||||||
muxing \
|
muxing \
|
||||||
remuxing \
|
|
||||||
resampling_audio \
|
resampling_audio \
|
||||||
scaling_video \
|
scaling_video \
|
||||||
transcode_aac \
|
|
||||||
transcoding \
|
|
||||||
|
|
||||||
OBJS=$(addsuffix .o,$(EXAMPLES))
|
OBJS=$(addsuffix .o,$(EXAMPLES))
|
||||||
|
|
||||||
# the following examples make explicit use of the math library
|
# the following examples make explicit use of the math library
|
||||||
avcodec: LDLIBS += -lm
|
|
||||||
decoding_encoding: LDLIBS += -lm
|
decoding_encoding: LDLIBS += -lm
|
||||||
muxing: LDLIBS += -lm
|
muxing: LDLIBS += -lm
|
||||||
resampling_audio: LDLIBS += -lm
|
resampling_audio: LDLIBS += -lm
|
||||||
|
|||||||
@@ -5,19 +5,14 @@ Both following use cases rely on pkg-config and make, thus make sure
|
|||||||
that you have them installed and working on your system.
|
that you have them installed and working on your system.
|
||||||
|
|
||||||
|
|
||||||
Method 1: build the installed examples in a generic read/write user directory
|
1) Build the installed examples in a generic read/write user directory
|
||||||
|
|
||||||
Copy to a read/write user directory and just use "make", it will link
|
Copy to a read/write user directory and just use "make", it will link
|
||||||
to the libraries on your system, assuming the PKG_CONFIG_PATH is
|
to the libraries on your system, assuming the PKG_CONFIG_PATH is
|
||||||
correctly configured.
|
correctly configured.
|
||||||
|
|
||||||
Method 2: build the examples in-tree
|
2) Build the examples in-tree
|
||||||
|
|
||||||
Assuming you are in the source FFmpeg checkout directory, you need to build
|
Assuming you are in the source FFmpeg checkout directory, you need to build
|
||||||
FFmpeg (no need to make install in any prefix). Then just run "make examples".
|
FFmpeg (no need to make install in any prefix). Then you can go into
|
||||||
This will build the examples using the FFmpeg build system. You can clean those
|
doc/examples and run a command such as PKG_CONFIG_PATH=pc-uninstalled make.
|
||||||
examples using "make examplesclean"
|
|
||||||
|
|
||||||
If you want to try the dedicated Makefile examples (to emulate the first
|
|
||||||
method), go into doc/examples and run a command such as
|
|
||||||
PKG_CONFIG_PATH=pc-uninstalled make.
|
|
||||||
|
|||||||
@@ -1,180 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014 Lukasz Marek
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
|
||||||
#include <libavformat/avformat.h>
|
|
||||||
#include <libavformat/avio.h>
|
|
||||||
|
|
||||||
static const char *type_string(int type)
|
|
||||||
{
|
|
||||||
switch (type) {
|
|
||||||
case AVIO_ENTRY_DIRECTORY:
|
|
||||||
return "<DIR>";
|
|
||||||
case AVIO_ENTRY_FILE:
|
|
||||||
return "<FILE>";
|
|
||||||
case AVIO_ENTRY_BLOCK_DEVICE:
|
|
||||||
return "<BLOCK DEVICE>";
|
|
||||||
case AVIO_ENTRY_CHARACTER_DEVICE:
|
|
||||||
return "<CHARACTER DEVICE>";
|
|
||||||
case AVIO_ENTRY_NAMED_PIPE:
|
|
||||||
return "<PIPE>";
|
|
||||||
case AVIO_ENTRY_SYMBOLIC_LINK:
|
|
||||||
return "<LINK>";
|
|
||||||
case AVIO_ENTRY_SOCKET:
|
|
||||||
return "<SOCKET>";
|
|
||||||
case AVIO_ENTRY_SERVER:
|
|
||||||
return "<SERVER>";
|
|
||||||
case AVIO_ENTRY_SHARE:
|
|
||||||
return "<SHARE>";
|
|
||||||
case AVIO_ENTRY_WORKGROUP:
|
|
||||||
return "<WORKGROUP>";
|
|
||||||
case AVIO_ENTRY_UNKNOWN:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return "<UNKNOWN>";
|
|
||||||
}
|
|
||||||
|
|
||||||
static int list_op(const char *input_dir)
|
|
||||||
{
|
|
||||||
AVIODirEntry *entry = NULL;
|
|
||||||
AVIODirContext *ctx = NULL;
|
|
||||||
int cnt, ret;
|
|
||||||
char filemode[4], uid_and_gid[20];
|
|
||||||
|
|
||||||
if ((ret = avio_open_dir(&ctx, input_dir, NULL)) < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot open directory: %s.\n", av_err2str(ret));
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
cnt = 0;
|
|
||||||
for (;;) {
|
|
||||||
if ((ret = avio_read_dir(ctx, &entry)) < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot list directory: %s.\n", av_err2str(ret));
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (!entry)
|
|
||||||
break;
|
|
||||||
if (entry->filemode == -1) {
|
|
||||||
snprintf(filemode, 4, "???");
|
|
||||||
} else {
|
|
||||||
snprintf(filemode, 4, "%3"PRIo64, entry->filemode);
|
|
||||||
}
|
|
||||||
snprintf(uid_and_gid, 20, "%"PRId64"(%"PRId64")", entry->user_id, entry->group_id);
|
|
||||||
if (cnt == 0)
|
|
||||||
av_log(NULL, AV_LOG_INFO, "%-9s %12s %30s %10s %s %16s %16s %16s\n",
|
|
||||||
"TYPE", "SIZE", "NAME", "UID(GID)", "UGO", "MODIFIED",
|
|
||||||
"ACCESSED", "STATUS_CHANGED");
|
|
||||||
av_log(NULL, AV_LOG_INFO, "%-9s %12"PRId64" %30s %10s %s %16"PRId64" %16"PRId64" %16"PRId64"\n",
|
|
||||||
type_string(entry->type),
|
|
||||||
entry->size,
|
|
||||||
entry->name,
|
|
||||||
uid_and_gid,
|
|
||||||
filemode,
|
|
||||||
entry->modification_timestamp,
|
|
||||||
entry->access_timestamp,
|
|
||||||
entry->status_change_timestamp);
|
|
||||||
avio_free_directory_entry(&entry);
|
|
||||||
cnt++;
|
|
||||||
};
|
|
||||||
|
|
||||||
fail:
|
|
||||||
avio_close_dir(&ctx);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int del_op(const char *url)
|
|
||||||
{
|
|
||||||
int ret = avpriv_io_delete(url);
|
|
||||||
if (ret < 0)
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot delete '%s': %s.\n", url, av_err2str(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int move_op(const char *src, const char *dst)
|
|
||||||
{
|
|
||||||
int ret = avpriv_io_move(src, dst);
|
|
||||||
if (ret < 0)
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot move '%s' into '%s': %s.\n", src, dst, av_err2str(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void usage(const char *program_name)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "usage: %s OPERATION entry1 [entry2]\n"
|
|
||||||
"API example program to show how to manipulate resources "
|
|
||||||
"accessed through AVIOContext.\n"
|
|
||||||
"OPERATIONS:\n"
|
|
||||||
"list list content of the directory\n"
|
|
||||||
"move rename content in directory\n"
|
|
||||||
"del delete content in directory\n",
|
|
||||||
program_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
const char *op = NULL;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
av_log_set_level(AV_LOG_DEBUG);
|
|
||||||
|
|
||||||
if (argc < 2) {
|
|
||||||
usage(argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* register codecs and formats and other lavf/lavc components*/
|
|
||||||
av_register_all();
|
|
||||||
avformat_network_init();
|
|
||||||
|
|
||||||
op = argv[1];
|
|
||||||
if (strcmp(op, "list") == 0) {
|
|
||||||
if (argc < 3) {
|
|
||||||
av_log(NULL, AV_LOG_INFO, "Missing argument for list operation.\n");
|
|
||||||
ret = AVERROR(EINVAL);
|
|
||||||
} else {
|
|
||||||
ret = list_op(argv[2]);
|
|
||||||
}
|
|
||||||
} else if (strcmp(op, "del") == 0) {
|
|
||||||
if (argc < 3) {
|
|
||||||
av_log(NULL, AV_LOG_INFO, "Missing argument for del operation.\n");
|
|
||||||
ret = AVERROR(EINVAL);
|
|
||||||
} else {
|
|
||||||
ret = del_op(argv[2]);
|
|
||||||
}
|
|
||||||
} else if (strcmp(op, "move") == 0) {
|
|
||||||
if (argc < 4) {
|
|
||||||
av_log(NULL, AV_LOG_INFO, "Missing argument for move operation.\n");
|
|
||||||
ret = AVERROR(EINVAL);
|
|
||||||
} else {
|
|
||||||
ret = move_op(argv[2], argv[3]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
av_log(NULL, AV_LOG_INFO, "Invalid operation %s\n", op);
|
|
||||||
ret = AVERROR(EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
avformat_network_deinit();
|
|
||||||
|
|
||||||
return ret < 0 ? 1 : 0;
|
|
||||||
}
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014 Stefano Sabatini
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* libavformat AVIOContext API example.
|
|
||||||
*
|
|
||||||
* Make libavformat demuxer access media content through a custom
|
|
||||||
* AVIOContext read callback.
|
|
||||||
* @example avio_reading.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
|
||||||
#include <libavformat/avformat.h>
|
|
||||||
#include <libavformat/avio.h>
|
|
||||||
#include <libavutil/file.h>
|
|
||||||
|
|
||||||
struct buffer_data {
|
|
||||||
uint8_t *ptr;
|
|
||||||
size_t size; ///< size left in the buffer
|
|
||||||
};
|
|
||||||
|
|
||||||
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
|
|
||||||
{
|
|
||||||
struct buffer_data *bd = (struct buffer_data *)opaque;
|
|
||||||
buf_size = FFMIN(buf_size, bd->size);
|
|
||||||
|
|
||||||
printf("ptr:%p size:%zu\n", bd->ptr, bd->size);
|
|
||||||
|
|
||||||
/* copy internal buffer data to buf */
|
|
||||||
memcpy(buf, bd->ptr, buf_size);
|
|
||||||
bd->ptr += buf_size;
|
|
||||||
bd->size -= buf_size;
|
|
||||||
|
|
||||||
return buf_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
AVFormatContext *fmt_ctx = NULL;
|
|
||||||
AVIOContext *avio_ctx = NULL;
|
|
||||||
uint8_t *buffer = NULL, *avio_ctx_buffer = NULL;
|
|
||||||
size_t buffer_size, avio_ctx_buffer_size = 4096;
|
|
||||||
char *input_filename = NULL;
|
|
||||||
int ret = 0;
|
|
||||||
struct buffer_data bd = { 0 };
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
fprintf(stderr, "usage: %s input_file\n"
|
|
||||||
"API example program to show how to read from a custom buffer "
|
|
||||||
"accessed through AVIOContext.\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
input_filename = argv[1];
|
|
||||||
|
|
||||||
/* register codecs and formats and other lavf/lavc components*/
|
|
||||||
av_register_all();
|
|
||||||
|
|
||||||
/* slurp file content into buffer */
|
|
||||||
ret = av_file_map(input_filename, &buffer, &buffer_size, 0, NULL);
|
|
||||||
if (ret < 0)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
/* fill opaque structure used by the AVIOContext read callback */
|
|
||||||
bd.ptr = buffer;
|
|
||||||
bd.size = buffer_size;
|
|
||||||
|
|
||||||
if (!(fmt_ctx = avformat_alloc_context())) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
avio_ctx_buffer = av_malloc(avio_ctx_buffer_size);
|
|
||||||
if (!avio_ctx_buffer) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,
|
|
||||||
0, &bd, &read_packet, NULL, NULL);
|
|
||||||
if (!avio_ctx) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
fmt_ctx->pb = avio_ctx;
|
|
||||||
|
|
||||||
ret = avformat_open_input(&fmt_ctx, NULL, NULL, NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Could not open input\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = avformat_find_stream_info(fmt_ctx, NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Could not find stream information\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
av_dump_format(fmt_ctx, 0, input_filename, 0);
|
|
||||||
|
|
||||||
end:
|
|
||||||
avformat_close_input(&fmt_ctx);
|
|
||||||
/* note: the internal buffer could have changed, and be != avio_ctx_buffer */
|
|
||||||
if (avio_ctx) {
|
|
||||||
av_freep(&avio_ctx->buffer);
|
|
||||||
av_freep(&avio_ctx);
|
|
||||||
}
|
|
||||||
av_file_unmap(buffer, buffer_size);
|
|
||||||
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -24,10 +24,10 @@
|
|||||||
* @file
|
* @file
|
||||||
* libavcodec API use example.
|
* libavcodec API use example.
|
||||||
*
|
*
|
||||||
* @example decoding_encoding.c
|
* Note that libavcodec only handles codecs (mpeg, mpeg4, etc...),
|
||||||
* Note that libavcodec only handles codecs (MPEG, MPEG-4, etc...),
|
* not file formats (avi, vob, mp4, mov, mkv, mxf, flv, mpegts, mpegps, etc...). See library 'libavformat' for the
|
||||||
* not file formats (AVI, VOB, MP4, MOV, MKV, MXF, FLV, MPEG-TS, MPEG-PS, etc...).
|
* format handling
|
||||||
* See library 'libavformat' for the format handling
|
* @example doc/examples/decoding_encoding.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@@ -156,7 +156,7 @@ static void audio_encode_example(const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* frame containing input raw audio */
|
/* frame containing input raw audio */
|
||||||
frame = av_frame_alloc();
|
frame = avcodec_alloc_frame();
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
fprintf(stderr, "Could not allocate audio frame\n");
|
fprintf(stderr, "Could not allocate audio frame\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -170,10 +170,6 @@ static void audio_encode_example(const char *filename)
|
|||||||
* we calculate the size of the samples buffer in bytes */
|
* we calculate the size of the samples buffer in bytes */
|
||||||
buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
|
buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
|
||||||
c->sample_fmt, 0);
|
c->sample_fmt, 0);
|
||||||
if (buffer_size < 0) {
|
|
||||||
fprintf(stderr, "Could not get sample buffer size\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
samples = av_malloc(buffer_size);
|
samples = av_malloc(buffer_size);
|
||||||
if (!samples) {
|
if (!samples) {
|
||||||
fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
|
fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
|
||||||
@@ -191,7 +187,7 @@ static void audio_encode_example(const char *filename)
|
|||||||
/* encode a single tone sound */
|
/* encode a single tone sound */
|
||||||
t = 0;
|
t = 0;
|
||||||
tincr = 2 * M_PI * 440.0 / c->sample_rate;
|
tincr = 2 * M_PI * 440.0 / c->sample_rate;
|
||||||
for (i = 0; i < 200; i++) {
|
for(i=0;i<200;i++) {
|
||||||
av_init_packet(&pkt);
|
av_init_packet(&pkt);
|
||||||
pkt.data = NULL; // packet data will be allocated by the encoder
|
pkt.data = NULL; // packet data will be allocated by the encoder
|
||||||
pkt.size = 0;
|
pkt.size = 0;
|
||||||
@@ -211,7 +207,7 @@ static void audio_encode_example(const char *filename)
|
|||||||
}
|
}
|
||||||
if (got_output) {
|
if (got_output) {
|
||||||
fwrite(pkt.data, 1, pkt.size, f);
|
fwrite(pkt.data, 1, pkt.size, f);
|
||||||
av_packet_unref(&pkt);
|
av_free_packet(&pkt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,13 +221,13 @@ static void audio_encode_example(const char *filename)
|
|||||||
|
|
||||||
if (got_output) {
|
if (got_output) {
|
||||||
fwrite(pkt.data, 1, pkt.size, f);
|
fwrite(pkt.data, 1, pkt.size, f);
|
||||||
av_packet_unref(&pkt);
|
av_free_packet(&pkt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
av_freep(&samples);
|
av_freep(&samples);
|
||||||
av_frame_free(&frame);
|
avcodec_free_frame(&frame);
|
||||||
avcodec_close(c);
|
avcodec_close(c);
|
||||||
av_free(c);
|
av_free(c);
|
||||||
}
|
}
|
||||||
@@ -245,7 +241,7 @@ static void audio_decode_example(const char *outfilename, const char *filename)
|
|||||||
AVCodecContext *c= NULL;
|
AVCodecContext *c= NULL;
|
||||||
int len;
|
int len;
|
||||||
FILE *f, *outfile;
|
FILE *f, *outfile;
|
||||||
uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
|
||||||
AVPacket avpkt;
|
AVPacket avpkt;
|
||||||
AVFrame *decoded_frame = NULL;
|
AVFrame *decoded_frame = NULL;
|
||||||
|
|
||||||
@@ -253,7 +249,7 @@ static void audio_decode_example(const char *outfilename, const char *filename)
|
|||||||
|
|
||||||
printf("Decode audio file %s to %s\n", filename, outfilename);
|
printf("Decode audio file %s to %s\n", filename, outfilename);
|
||||||
|
|
||||||
/* find the MPEG audio decoder */
|
/* find the mpeg audio decoder */
|
||||||
codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
|
codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
|
||||||
if (!codec) {
|
if (!codec) {
|
||||||
fprintf(stderr, "Codec not found\n");
|
fprintf(stderr, "Codec not found\n");
|
||||||
@@ -288,15 +284,15 @@ static void audio_decode_example(const char *outfilename, const char *filename)
|
|||||||
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
|
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
|
||||||
|
|
||||||
while (avpkt.size > 0) {
|
while (avpkt.size > 0) {
|
||||||
int i, ch;
|
|
||||||
int got_frame = 0;
|
int got_frame = 0;
|
||||||
|
|
||||||
if (!decoded_frame) {
|
if (!decoded_frame) {
|
||||||
if (!(decoded_frame = av_frame_alloc())) {
|
if (!(decoded_frame = avcodec_alloc_frame())) {
|
||||||
fprintf(stderr, "Could not allocate audio frame\n");
|
fprintf(stderr, "Could not allocate audio frame\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
|
avcodec_get_frame_defaults(decoded_frame);
|
||||||
|
|
||||||
len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
|
len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
@@ -305,15 +301,10 @@ static void audio_decode_example(const char *outfilename, const char *filename)
|
|||||||
}
|
}
|
||||||
if (got_frame) {
|
if (got_frame) {
|
||||||
/* if a frame has been decoded, output it */
|
/* if a frame has been decoded, output it */
|
||||||
int data_size = av_get_bytes_per_sample(c->sample_fmt);
|
int data_size = av_samples_get_buffer_size(NULL, c->channels,
|
||||||
if (data_size < 0) {
|
decoded_frame->nb_samples,
|
||||||
/* This should not occur, checking just for paranoia */
|
c->sample_fmt, 1);
|
||||||
fprintf(stderr, "Failed to calculate data size\n");
|
fwrite(decoded_frame->data[0], 1, data_size, outfile);
|
||||||
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.size -= len;
|
||||||
avpkt.data += len;
|
avpkt.data += len;
|
||||||
@@ -338,7 +329,7 @@ static void audio_decode_example(const char *outfilename, const char *filename)
|
|||||||
|
|
||||||
avcodec_close(c);
|
avcodec_close(c);
|
||||||
av_free(c);
|
av_free(c);
|
||||||
av_frame_free(&decoded_frame);
|
avcodec_free_frame(&decoded_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -356,7 +347,7 @@ static void video_encode_example(const char *filename, int codec_id)
|
|||||||
|
|
||||||
printf("Encode video file %s\n", filename);
|
printf("Encode video file %s\n", filename);
|
||||||
|
|
||||||
/* find the video encoder */
|
/* find the mpeg1 video encoder */
|
||||||
codec = avcodec_find_encoder(codec_id);
|
codec = avcodec_find_encoder(codec_id);
|
||||||
if (!codec) {
|
if (!codec) {
|
||||||
fprintf(stderr, "Codec not found\n");
|
fprintf(stderr, "Codec not found\n");
|
||||||
@@ -375,18 +366,12 @@ static void video_encode_example(const char *filename, int codec_id)
|
|||||||
c->width = 352;
|
c->width = 352;
|
||||||
c->height = 288;
|
c->height = 288;
|
||||||
/* frames per second */
|
/* frames per second */
|
||||||
c->time_base = (AVRational){1,25};
|
c->time_base= (AVRational){1,25};
|
||||||
/* emit one intra frame every ten frames
|
c->gop_size = 10; /* emit one intra frame every ten frames */
|
||||||
* check frame pict_type before passing frame
|
c->max_b_frames=1;
|
||||||
* 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;
|
c->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||||
|
|
||||||
if (codec_id == AV_CODEC_ID_H264)
|
if(codec_id == AV_CODEC_ID_H264)
|
||||||
av_opt_set(c->priv_data, "preset", "slow", 0);
|
av_opt_set(c->priv_data, "preset", "slow", 0);
|
||||||
|
|
||||||
/* open it */
|
/* open it */
|
||||||
@@ -401,7 +386,7 @@ static void video_encode_example(const char *filename, int codec_id)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = av_frame_alloc();
|
frame = avcodec_alloc_frame();
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
fprintf(stderr, "Could not allocate video frame\n");
|
fprintf(stderr, "Could not allocate video frame\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -420,7 +405,7 @@ static void video_encode_example(const char *filename, int codec_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* encode 1 second of video */
|
/* encode 1 second of video */
|
||||||
for (i = 0; i < 25; i++) {
|
for(i=0;i<25;i++) {
|
||||||
av_init_packet(&pkt);
|
av_init_packet(&pkt);
|
||||||
pkt.data = NULL; // packet data will be allocated by the encoder
|
pkt.data = NULL; // packet data will be allocated by the encoder
|
||||||
pkt.size = 0;
|
pkt.size = 0;
|
||||||
@@ -428,15 +413,15 @@ static void video_encode_example(const char *filename, int codec_id)
|
|||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
/* prepare a dummy image */
|
/* prepare a dummy image */
|
||||||
/* Y */
|
/* Y */
|
||||||
for (y = 0; y < c->height; y++) {
|
for(y=0;y<c->height;y++) {
|
||||||
for (x = 0; x < c->width; x++) {
|
for(x=0;x<c->width;x++) {
|
||||||
frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
|
frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cb and Cr */
|
/* Cb and Cr */
|
||||||
for (y = 0; y < c->height/2; y++) {
|
for(y=0;y<c->height/2;y++) {
|
||||||
for (x = 0; x < c->width/2; x++) {
|
for(x=0;x<c->width/2;x++) {
|
||||||
frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
|
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->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
|
||||||
}
|
}
|
||||||
@@ -454,7 +439,7 @@ static void video_encode_example(const char *filename, int codec_id)
|
|||||||
if (got_output) {
|
if (got_output) {
|
||||||
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
|
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
|
||||||
fwrite(pkt.data, 1, pkt.size, f);
|
fwrite(pkt.data, 1, pkt.size, f);
|
||||||
av_packet_unref(&pkt);
|
av_free_packet(&pkt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,18 +456,18 @@ static void video_encode_example(const char *filename, int codec_id)
|
|||||||
if (got_output) {
|
if (got_output) {
|
||||||
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
|
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
|
||||||
fwrite(pkt.data, 1, pkt.size, f);
|
fwrite(pkt.data, 1, pkt.size, f);
|
||||||
av_packet_unref(&pkt);
|
av_free_packet(&pkt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add sequence end code to have a real MPEG file */
|
/* add sequence end code to have a real mpeg file */
|
||||||
fwrite(endcode, 1, sizeof(endcode), f);
|
fwrite(endcode, 1, sizeof(endcode), f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
avcodec_close(c);
|
avcodec_close(c);
|
||||||
av_free(c);
|
av_free(c);
|
||||||
av_freep(&frame->data[0]);
|
av_freep(&frame->data[0]);
|
||||||
av_frame_free(&frame);
|
avcodec_free_frame(&frame);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,10 +481,10 @@ static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
|
|||||||
FILE *f;
|
FILE *f;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
f = fopen(filename,"w");
|
f=fopen(filename,"w");
|
||||||
fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
|
fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
|
||||||
for (i = 0; i < ysize; i++)
|
for(i=0;i<ysize;i++)
|
||||||
fwrite(buf + i * wrap, 1, xsize, f);
|
fwrite(buf + i * wrap,1,xsize,f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,7 +506,7 @@ static int decode_write_frame(const char *outfilename, AVCodecContext *avctx,
|
|||||||
/* the picture is allocated by the decoder, no need to free it */
|
/* the picture is allocated by the decoder, no need to free it */
|
||||||
snprintf(buf, sizeof(buf), outfilename, *frame_count);
|
snprintf(buf, sizeof(buf), outfilename, *frame_count);
|
||||||
pgm_save(frame->data[0], frame->linesize[0],
|
pgm_save(frame->data[0], frame->linesize[0],
|
||||||
frame->width, frame->height, buf);
|
avctx->width, avctx->height, buf);
|
||||||
(*frame_count)++;
|
(*frame_count)++;
|
||||||
}
|
}
|
||||||
if (pkt->data) {
|
if (pkt->data) {
|
||||||
@@ -538,17 +523,17 @@ static void video_decode_example(const char *outfilename, const char *filename)
|
|||||||
int frame_count;
|
int frame_count;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
AVFrame *frame;
|
AVFrame *frame;
|
||||||
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
|
||||||
AVPacket avpkt;
|
AVPacket avpkt;
|
||||||
|
|
||||||
av_init_packet(&avpkt);
|
av_init_packet(&avpkt);
|
||||||
|
|
||||||
/* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */
|
/* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
|
||||||
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||||
|
|
||||||
printf("Decode video file %s to %s\n", filename, outfilename);
|
printf("Decode video file %s to %s\n", filename, outfilename);
|
||||||
|
|
||||||
/* find the MPEG-1 video decoder */
|
/* find the mpeg1 video decoder */
|
||||||
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
|
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
|
||||||
if (!codec) {
|
if (!codec) {
|
||||||
fprintf(stderr, "Codec not found\n");
|
fprintf(stderr, "Codec not found\n");
|
||||||
@@ -561,8 +546,8 @@ static void video_decode_example(const char *outfilename, const char *filename)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
|
if(codec->capabilities&CODEC_CAP_TRUNCATED)
|
||||||
c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames
|
c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
|
||||||
|
|
||||||
/* For some codecs, such as msmpeg4 and mpeg4, width and height
|
/* For some codecs, such as msmpeg4 and mpeg4, width and height
|
||||||
MUST be initialized there because this information is not
|
MUST be initialized there because this information is not
|
||||||
@@ -580,14 +565,14 @@ static void video_decode_example(const char *outfilename, const char *filename)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = av_frame_alloc();
|
frame = avcodec_alloc_frame();
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
fprintf(stderr, "Could not allocate video frame\n");
|
fprintf(stderr, "Could not allocate video frame\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_count = 0;
|
frame_count = 0;
|
||||||
for (;;) {
|
for(;;) {
|
||||||
avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
|
avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
|
||||||
if (avpkt.size == 0)
|
if (avpkt.size == 0)
|
||||||
break;
|
break;
|
||||||
@@ -613,9 +598,9 @@ static void video_decode_example(const char *outfilename, const char *filename)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some codecs, such as MPEG, transmit the I- and P-frame with a
|
/* 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
|
latency of one frame. You must do the following to have a
|
||||||
chance to get the last frame of the video. */
|
chance to get the last frame of the video */
|
||||||
avpkt.data = NULL;
|
avpkt.data = NULL;
|
||||||
avpkt.size = 0;
|
avpkt.size = 0;
|
||||||
decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 1);
|
decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 1);
|
||||||
@@ -624,7 +609,7 @@ static void video_decode_example(const char *outfilename, const char *filename)
|
|||||||
|
|
||||||
avcodec_close(c);
|
avcodec_close(c);
|
||||||
av_free(c);
|
av_free(c);
|
||||||
av_frame_free(&frame);
|
avcodec_free_frame(&frame);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -641,7 +626,7 @@ int main(int argc, char **argv)
|
|||||||
"This program generates a synthetic stream and encodes it to a file\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"
|
"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"
|
"The encoded stream is then decoded and written to a raw data output.\n"
|
||||||
"output_type must be chosen between 'h264', 'mp2', 'mpg'.\n",
|
"output_type must be choosen between 'h264', 'mp2', 'mpg'.\n",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -651,7 +636,7 @@ int main(int argc, char **argv)
|
|||||||
video_encode_example("test.h264", AV_CODEC_ID_H264);
|
video_encode_example("test.h264", AV_CODEC_ID_H264);
|
||||||
} else if (!strcmp(output_type, "mp2")) {
|
} else if (!strcmp(output_type, "mp2")) {
|
||||||
audio_encode_example("test.mp2");
|
audio_encode_example("test.mp2");
|
||||||
audio_decode_example("test.pcm", "test.mp2");
|
audio_decode_example("test.sw", "test.mp2");
|
||||||
} else if (!strcmp(output_type, "mpg")) {
|
} else if (!strcmp(output_type, "mpg")) {
|
||||||
video_encode_example("test.mpg", AV_CODEC_ID_MPEG1VIDEO);
|
video_encode_example("test.mpg", AV_CODEC_ID_MPEG1VIDEO);
|
||||||
video_decode_example("test%02d.pgm", "test.mpg");
|
video_decode_example("test%02d.pgm", "test.mpg");
|
||||||
|
|||||||
@@ -22,11 +22,11 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* Demuxing and decoding example.
|
* libavformat demuxing API use example.
|
||||||
*
|
*
|
||||||
* Show how to use the libavformat and libavcodec API to demux and
|
* Show how to use the libavformat and libavcodec API to demux and
|
||||||
* decode audio and video data.
|
* decode audio and video data.
|
||||||
* @example demuxing_decoding.c
|
* @example doc/examples/demuxing.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libavutil/imgutils.h>
|
#include <libavutil/imgutils.h>
|
||||||
@@ -36,8 +36,6 @@
|
|||||||
|
|
||||||
static AVFormatContext *fmt_ctx = NULL;
|
static AVFormatContext *fmt_ctx = NULL;
|
||||||
static AVCodecContext *video_dec_ctx = NULL, *audio_dec_ctx;
|
static AVCodecContext *video_dec_ctx = NULL, *audio_dec_ctx;
|
||||||
static int width, height;
|
|
||||||
static enum AVPixelFormat pix_fmt;
|
|
||||||
static AVStream *video_stream = NULL, *audio_stream = NULL;
|
static AVStream *video_stream = NULL, *audio_stream = NULL;
|
||||||
static const char *src_filename = NULL;
|
static const char *src_filename = NULL;
|
||||||
static const char *video_dst_filename = NULL;
|
static const char *video_dst_filename = NULL;
|
||||||
@@ -55,53 +53,30 @@ 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;
|
||||||
|
|
||||||
/* Enable or disable frame reference counting. You are not supposed to support
|
|
||||||
* both paths in your application but pick the one most appropriate to your
|
|
||||||
* needs. Look for the use of refcount in this example to see what are the
|
|
||||||
* differences of API usage between them. */
|
|
||||||
static int refcount = 0;
|
|
||||||
|
|
||||||
static int decode_packet(int *got_frame, int cached)
|
static int decode_packet(int *got_frame, int cached)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int decoded = pkt.size;
|
int decoded = pkt.size;
|
||||||
|
|
||||||
*got_frame = 0;
|
|
||||||
|
|
||||||
if (pkt.stream_index == video_stream_idx) {
|
if (pkt.stream_index == video_stream_idx) {
|
||||||
/* decode video frame */
|
/* decode video frame */
|
||||||
ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
|
ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Error decoding video frame (%s)\n", av_err2str(ret));
|
fprintf(stderr, "Error decoding video frame\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*got_frame) {
|
if (*got_frame) {
|
||||||
|
printf("video_frame%s n:%d coded_n:%d pts:%s\n",
|
||||||
if (frame->width != width || frame->height != height ||
|
|
||||||
frame->format != pix_fmt) {
|
|
||||||
/* To handle this change, one could call av_image_alloc again and
|
|
||||||
* decode the following frames into another rawvideo file. */
|
|
||||||
fprintf(stderr, "Error: Width, height and pixel format have to be "
|
|
||||||
"constant in a rawvideo file, but the width, height or "
|
|
||||||
"pixel format of the input video changed:\n"
|
|
||||||
"old: width = %d, height = %d, format = %s\n"
|
|
||||||
"new: width = %d, height = %d, format = %s\n",
|
|
||||||
width, height, av_get_pix_fmt_name(pix_fmt),
|
|
||||||
frame->width, frame->height,
|
|
||||||
av_get_pix_fmt_name(frame->format));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("video_frame%s n:%d coded_n:%d\n",
|
|
||||||
cached ? "(cached)" : "",
|
cached ? "(cached)" : "",
|
||||||
video_frame_count++, frame->coded_picture_number);
|
video_frame_count++, frame->coded_picture_number,
|
||||||
|
av_ts2timestr(frame->pts, &video_dec_ctx->time_base));
|
||||||
|
|
||||||
/* copy decoded frame to destination buffer:
|
/* copy decoded frame to destination buffer:
|
||||||
* this is required since rawvideo expects non aligned data */
|
* this is required since rawvideo expects non aligned data */
|
||||||
av_image_copy(video_dst_data, video_dst_linesize,
|
av_image_copy(video_dst_data, video_dst_linesize,
|
||||||
(const uint8_t **)(frame->data), frame->linesize,
|
(const uint8_t **)(frame->data), frame->linesize,
|
||||||
pix_fmt, width, height);
|
video_dec_ctx->pix_fmt, video_dec_ctx->width, video_dec_ctx->height);
|
||||||
|
|
||||||
/* write to rawvideo file */
|
/* write to rawvideo file */
|
||||||
fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);
|
fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);
|
||||||
@@ -110,7 +85,7 @@ static int decode_packet(int *got_frame, int cached)
|
|||||||
/* decode audio frame */
|
/* decode audio frame */
|
||||||
ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
|
ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Error decoding audio frame (%s)\n", av_err2str(ret));
|
fprintf(stderr, "Error decoding audio frame\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/* Some audio decoders decode only part of the packet, and have to be
|
/* Some audio decoders decode only part of the packet, and have to be
|
||||||
@@ -138,21 +113,16 @@ static int decode_packet(int *got_frame, int cached)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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;
|
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;
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
|
AVCodecContext *dec_ctx = NULL;
|
||||||
AVCodec *dec = 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) {
|
||||||
@@ -160,40 +130,23 @@ static int open_codec_context(int *stream_idx,
|
|||||||
av_get_media_type_string(type), src_filename);
|
av_get_media_type_string(type), src_filename);
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
stream_index = ret;
|
*stream_idx = ret;
|
||||||
st = fmt_ctx->streams[stream_index];
|
st = fmt_ctx->streams[*stream_idx];
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate a codec context for the decoder */
|
|
||||||
*dec_ctx = avcodec_alloc_context3(dec);
|
|
||||||
if (!*dec_ctx) {
|
|
||||||
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init the decoders, with or without reference counting */
|
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
||||||
av_dict_set(&opts, "refcounted_frames", refcount ? "1" : "0", 0);
|
|
||||||
if ((ret = avcodec_open2(*dec_ctx, dec, &opts)) < 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;
|
||||||
}
|
}
|
||||||
*stream_idx = stream_index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -232,22 +185,15 @@ int main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int ret = 0, got_frame;
|
int ret = 0, got_frame;
|
||||||
|
|
||||||
if (argc != 4 && argc != 5) {
|
if (argc != 4) {
|
||||||
fprintf(stderr, "usage: %s [-refcount] input_file video_output_file audio_output_file\n"
|
fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"
|
||||||
"API example program to show how to read frames from an input file.\n"
|
"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\n"
|
"audio frames to a rawaudio file named audio_output_file.\n"
|
||||||
"If the -refcount option is specified, the program use the\n"
|
|
||||||
"reference counting frame system which allows keeping a copy of\n"
|
|
||||||
"the data for longer than one decode call.\n"
|
|
||||||
"\n", argv[0]);
|
"\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];
|
||||||
@@ -267,8 +213,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) {
|
||||||
@@ -278,11 +225,9 @@ int main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* allocate image where the decoded image will be put */
|
/* allocate image where the decoded image will be put */
|
||||||
width = video_dec_ctx->width;
|
|
||||||
height = video_dec_ctx->height;
|
|
||||||
pix_fmt = video_dec_ctx->pix_fmt;
|
|
||||||
ret = av_image_alloc(video_dst_data, video_dst_linesize,
|
ret = av_image_alloc(video_dst_data, video_dst_linesize,
|
||||||
width, height, pix_fmt, 1);
|
video_dec_ctx->width, video_dec_ctx->height,
|
||||||
|
video_dec_ctx->pix_fmt, 1);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Could not allocate raw video buffer\n");
|
fprintf(stderr, "Could not allocate raw video buffer\n");
|
||||||
goto end;
|
goto end;
|
||||||
@@ -290,11 +235,12 @@ 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", video_dst_filename);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -309,7 +255,7 @@ int main (int argc, char **argv)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = av_frame_alloc();
|
frame = avcodec_alloc_frame();
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
fprintf(stderr, "Could not allocate frame\n");
|
fprintf(stderr, "Could not allocate frame\n");
|
||||||
ret = AVERROR(ENOMEM);
|
ret = AVERROR(ENOMEM);
|
||||||
@@ -336,7 +282,7 @@ int main (int argc, char **argv)
|
|||||||
pkt.data += ret;
|
pkt.data += ret;
|
||||||
pkt.size -= ret;
|
pkt.size -= ret;
|
||||||
} while (pkt.size > 0);
|
} while (pkt.size > 0);
|
||||||
av_packet_unref(&orig_pkt);
|
av_free_packet(&orig_pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* flush cached frames */
|
/* flush cached frames */
|
||||||
@@ -351,7 +297,7 @@ int main (int argc, char **argv)
|
|||||||
if (video_stream) {
|
if (video_stream) {
|
||||||
printf("Play the output video file with the command:\n"
|
printf("Play the output video file with the command:\n"
|
||||||
"ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
|
"ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
|
||||||
av_get_pix_fmt_name(pix_fmt), width, height,
|
av_get_pix_fmt_name(video_dec_ctx->pix_fmt), video_dec_ctx->width, video_dec_ctx->height,
|
||||||
video_dst_filename);
|
video_dst_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,14 +325,16 @@ int main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
avcodec_free_context(&video_dec_ctx);
|
if (video_dec_ctx)
|
||||||
avcodec_free_context(&audio_dec_ctx);
|
avcodec_close(video_dec_ctx);
|
||||||
|
if (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_frame_free(&frame);
|
av_free(frame);
|
||||||
av_free(video_dst_data[0]);
|
av_free(video_dst_data[0]);
|
||||||
|
|
||||||
return ret < 0;
|
return ret < 0;
|
||||||
@@ -1,185 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 Stefano Sabatini
|
|
||||||
* Copyright (c) 2014 Clément Bœsch
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <libavutil/motion_vector.h>
|
|
||||||
#include <libavformat/avformat.h>
|
|
||||||
|
|
||||||
static AVFormatContext *fmt_ctx = NULL;
|
|
||||||
static AVCodecContext *video_dec_ctx = NULL;
|
|
||||||
static AVStream *video_stream = NULL;
|
|
||||||
static const char *src_filename = NULL;
|
|
||||||
|
|
||||||
static int video_stream_idx = -1;
|
|
||||||
static AVFrame *frame = NULL;
|
|
||||||
static AVPacket pkt;
|
|
||||||
static int video_frame_count = 0;
|
|
||||||
|
|
||||||
static int decode_packet(int *got_frame, int cached)
|
|
||||||
{
|
|
||||||
int decoded = pkt.size;
|
|
||||||
|
|
||||||
*got_frame = 0;
|
|
||||||
|
|
||||||
if (pkt.stream_index == video_stream_idx) {
|
|
||||||
int ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error decoding video frame (%s)\n", av_err2str(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*got_frame) {
|
|
||||||
int i;
|
|
||||||
AVFrameSideData *sd;
|
|
||||||
|
|
||||||
video_frame_count++;
|
|
||||||
sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS);
|
|
||||||
if (sd) {
|
|
||||||
const AVMotionVector *mvs = (const AVMotionVector *)sd->data;
|
|
||||||
for (i = 0; i < sd->size / sizeof(*mvs); i++) {
|
|
||||||
const AVMotionVector *mv = &mvs[i];
|
|
||||||
printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64"\n",
|
|
||||||
video_frame_count, mv->source,
|
|
||||||
mv->w, mv->h, mv->src_x, mv->src_y,
|
|
||||||
mv->dst_x, mv->dst_y, mv->flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return decoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int open_codec_context(int *stream_idx,
|
|
||||||
AVFormatContext *fmt_ctx, enum AVMediaType type)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
AVStream *st;
|
|
||||||
AVCodecContext *dec_ctx = NULL;
|
|
||||||
AVCodec *dec = NULL;
|
|
||||||
AVDictionary *opts = NULL;
|
|
||||||
|
|
||||||
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Could not find %s stream in input file '%s'\n",
|
|
||||||
av_get_media_type_string(type), src_filename);
|
|
||||||
return ret;
|
|
||||||
} else {
|
|
||||||
*stream_idx = ret;
|
|
||||||
st = fmt_ctx->streams[*stream_idx];
|
|
||||||
|
|
||||||
/* find decoder for the stream */
|
|
||||||
dec_ctx = st->codec;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Init the video decoder */
|
|
||||||
av_dict_set(&opts, "flags2", "+export_mvs", 0);
|
|
||||||
if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) {
|
|
||||||
fprintf(stderr, "Failed to open %s codec\n",
|
|
||||||
av_get_media_type_string(type));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int ret = 0, got_frame;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
fprintf(stderr, "Usage: %s <video>\n", argv[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
src_filename = argv[1];
|
|
||||||
|
|
||||||
av_register_all();
|
|
||||||
|
|
||||||
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
|
|
||||||
fprintf(stderr, "Could not open source file %s\n", src_filename);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
|
|
||||||
fprintf(stderr, "Could not find stream information\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (!video_stream) {
|
|
||||||
fprintf(stderr, "Could not find video stream in the input, aborting\n");
|
|
||||||
ret = 1;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
frame = av_frame_alloc();
|
|
||||||
if (!frame) {
|
|
||||||
fprintf(stderr, "Could not allocate frame\n");
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 */
|
|
||||||
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
|
|
||||||
AVPacket orig_pkt = pkt;
|
|
||||||
do {
|
|
||||||
ret = decode_packet(&got_frame, 0);
|
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
pkt.data += ret;
|
|
||||||
pkt.size -= ret;
|
|
||||||
} while (pkt.size > 0);
|
|
||||||
av_packet_unref(&orig_pkt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flush cached frames */
|
|
||||||
pkt.data = NULL;
|
|
||||||
pkt.size = 0;
|
|
||||||
do {
|
|
||||||
decode_packet(&got_frame, 1);
|
|
||||||
} while (got_frame);
|
|
||||||
|
|
||||||
end:
|
|
||||||
avcodec_close(video_dec_ctx);
|
|
||||||
avformat_close_input(&fmt_ctx);
|
|
||||||
av_frame_free(&frame);
|
|
||||||
return ret < 0;
|
|
||||||
}
|
|
||||||
@@ -1,365 +0,0 @@
|
|||||||
/*
|
|
||||||
* copyright (c) 2013 Andrew Kelley
|
|
||||||
*
|
|
||||||
* This file is part of FFmpeg.
|
|
||||||
*
|
|
||||||
* FFmpeg is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* FFmpeg is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with FFmpeg; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* libavfilter API usage example.
|
|
||||||
*
|
|
||||||
* @example filter_audio.c
|
|
||||||
* This example will generate a sine wave audio,
|
|
||||||
* pass it through a simple filter chain, and then compute the MD5 checksum of
|
|
||||||
* the output data.
|
|
||||||
*
|
|
||||||
* The filter chain it uses is:
|
|
||||||
* (input) -> abuffer -> volume -> aformat -> abuffersink -> (output)
|
|
||||||
*
|
|
||||||
* abuffer: This provides the endpoint where you can feed the decoded samples.
|
|
||||||
* volume: In this example we hardcode it to 0.90.
|
|
||||||
* aformat: This converts the samples to the samplefreq, channel layout,
|
|
||||||
* and sample format required by the audio device.
|
|
||||||
* abuffersink: This provides the endpoint where you can read the samples after
|
|
||||||
* they have passed through the filter chain.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "libavutil/channel_layout.h"
|
|
||||||
#include "libavutil/md5.h"
|
|
||||||
#include "libavutil/mem.h"
|
|
||||||
#include "libavutil/opt.h"
|
|
||||||
#include "libavutil/samplefmt.h"
|
|
||||||
|
|
||||||
#include "libavfilter/avfilter.h"
|
|
||||||
#include "libavfilter/buffersink.h"
|
|
||||||
#include "libavfilter/buffersrc.h"
|
|
||||||
|
|
||||||
#define INPUT_SAMPLERATE 48000
|
|
||||||
#define INPUT_FORMAT AV_SAMPLE_FMT_FLTP
|
|
||||||
#define INPUT_CHANNEL_LAYOUT AV_CH_LAYOUT_5POINT0
|
|
||||||
|
|
||||||
#define VOLUME_VAL 0.90
|
|
||||||
|
|
||||||
static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src,
|
|
||||||
AVFilterContext **sink)
|
|
||||||
{
|
|
||||||
AVFilterGraph *filter_graph;
|
|
||||||
AVFilterContext *abuffer_ctx;
|
|
||||||
AVFilter *abuffer;
|
|
||||||
AVFilterContext *volume_ctx;
|
|
||||||
AVFilter *volume;
|
|
||||||
AVFilterContext *aformat_ctx;
|
|
||||||
AVFilter *aformat;
|
|
||||||
AVFilterContext *abuffersink_ctx;
|
|
||||||
AVFilter *abuffersink;
|
|
||||||
|
|
||||||
AVDictionary *options_dict = NULL;
|
|
||||||
uint8_t options_str[1024];
|
|
||||||
uint8_t ch_layout[64];
|
|
||||||
|
|
||||||
int err;
|
|
||||||
|
|
||||||
/* Create a new filtergraph, which will contain all the filters. */
|
|
||||||
filter_graph = avfilter_graph_alloc();
|
|
||||||
if (!filter_graph) {
|
|
||||||
fprintf(stderr, "Unable to create filter graph.\n");
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the abuffer filter;
|
|
||||||
* it will be used for feeding the data into the graph. */
|
|
||||||
abuffer = avfilter_get_by_name("abuffer");
|
|
||||||
if (!abuffer) {
|
|
||||||
fprintf(stderr, "Could not find the abuffer filter.\n");
|
|
||||||
return AVERROR_FILTER_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
abuffer_ctx = avfilter_graph_alloc_filter(filter_graph, abuffer, "src");
|
|
||||||
if (!abuffer_ctx) {
|
|
||||||
fprintf(stderr, "Could not allocate the abuffer instance.\n");
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the filter options through the AVOptions API. */
|
|
||||||
av_get_channel_layout_string(ch_layout, sizeof(ch_layout), 0, INPUT_CHANNEL_LAYOUT);
|
|
||||||
av_opt_set (abuffer_ctx, "channel_layout", ch_layout, AV_OPT_SEARCH_CHILDREN);
|
|
||||||
av_opt_set (abuffer_ctx, "sample_fmt", av_get_sample_fmt_name(INPUT_FORMAT), AV_OPT_SEARCH_CHILDREN);
|
|
||||||
av_opt_set_q (abuffer_ctx, "time_base", (AVRational){ 1, INPUT_SAMPLERATE }, AV_OPT_SEARCH_CHILDREN);
|
|
||||||
av_opt_set_int(abuffer_ctx, "sample_rate", INPUT_SAMPLERATE, AV_OPT_SEARCH_CHILDREN);
|
|
||||||
|
|
||||||
/* Now initialize the filter; we pass NULL options, since we have already
|
|
||||||
* set all the options above. */
|
|
||||||
err = avfilter_init_str(abuffer_ctx, NULL);
|
|
||||||
if (err < 0) {
|
|
||||||
fprintf(stderr, "Could not initialize the abuffer filter.\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create volume filter. */
|
|
||||||
volume = avfilter_get_by_name("volume");
|
|
||||||
if (!volume) {
|
|
||||||
fprintf(stderr, "Could not find the volume filter.\n");
|
|
||||||
return AVERROR_FILTER_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
volume_ctx = avfilter_graph_alloc_filter(filter_graph, volume, "volume");
|
|
||||||
if (!volume_ctx) {
|
|
||||||
fprintf(stderr, "Could not allocate the volume instance.\n");
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A different way of passing the options is as key/value pairs in a
|
|
||||||
* dictionary. */
|
|
||||||
av_dict_set(&options_dict, "volume", AV_STRINGIFY(VOLUME_VAL), 0);
|
|
||||||
err = avfilter_init_dict(volume_ctx, &options_dict);
|
|
||||||
av_dict_free(&options_dict);
|
|
||||||
if (err < 0) {
|
|
||||||
fprintf(stderr, "Could not initialize the volume filter.\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the aformat filter;
|
|
||||||
* it ensures that the output is of the format we want. */
|
|
||||||
aformat = avfilter_get_by_name("aformat");
|
|
||||||
if (!aformat) {
|
|
||||||
fprintf(stderr, "Could not find the aformat filter.\n");
|
|
||||||
return AVERROR_FILTER_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
aformat_ctx = avfilter_graph_alloc_filter(filter_graph, aformat, "aformat");
|
|
||||||
if (!aformat_ctx) {
|
|
||||||
fprintf(stderr, "Could not allocate the aformat instance.\n");
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A third way of passing the options is in a string of the form
|
|
||||||
* key1=value1:key2=value2.... */
|
|
||||||
snprintf(options_str, sizeof(options_str),
|
|
||||||
"sample_fmts=%s:sample_rates=%d:channel_layouts=0x%"PRIx64,
|
|
||||||
av_get_sample_fmt_name(AV_SAMPLE_FMT_S16), 44100,
|
|
||||||
(uint64_t)AV_CH_LAYOUT_STEREO);
|
|
||||||
err = avfilter_init_str(aformat_ctx, options_str);
|
|
||||||
if (err < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Could not initialize the aformat filter.\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally create the abuffersink filter;
|
|
||||||
* it will be used to get the filtered data out of the graph. */
|
|
||||||
abuffersink = avfilter_get_by_name("abuffersink");
|
|
||||||
if (!abuffersink) {
|
|
||||||
fprintf(stderr, "Could not find the abuffersink filter.\n");
|
|
||||||
return AVERROR_FILTER_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
abuffersink_ctx = avfilter_graph_alloc_filter(filter_graph, abuffersink, "sink");
|
|
||||||
if (!abuffersink_ctx) {
|
|
||||||
fprintf(stderr, "Could not allocate the abuffersink instance.\n");
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This filter takes no options. */
|
|
||||||
err = avfilter_init_str(abuffersink_ctx, NULL);
|
|
||||||
if (err < 0) {
|
|
||||||
fprintf(stderr, "Could not initialize the abuffersink instance.\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Connect the filters;
|
|
||||||
* in this simple case the filters just form a linear chain. */
|
|
||||||
err = avfilter_link(abuffer_ctx, 0, volume_ctx, 0);
|
|
||||||
if (err >= 0)
|
|
||||||
err = avfilter_link(volume_ctx, 0, aformat_ctx, 0);
|
|
||||||
if (err >= 0)
|
|
||||||
err = avfilter_link(aformat_ctx, 0, abuffersink_ctx, 0);
|
|
||||||
if (err < 0) {
|
|
||||||
fprintf(stderr, "Error connecting filters\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure the graph. */
|
|
||||||
err = avfilter_graph_config(filter_graph, NULL);
|
|
||||||
if (err < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Error configuring the filter graph\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
*graph = filter_graph;
|
|
||||||
*src = abuffer_ctx;
|
|
||||||
*sink = abuffersink_ctx;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do something useful with the filtered data: this simple
|
|
||||||
* example just prints the MD5 checksum of each plane to stdout. */
|
|
||||||
static int process_output(struct AVMD5 *md5, AVFrame *frame)
|
|
||||||
{
|
|
||||||
int planar = av_sample_fmt_is_planar(frame->format);
|
|
||||||
int channels = av_get_channel_layout_nb_channels(frame->channel_layout);
|
|
||||||
int planes = planar ? channels : 1;
|
|
||||||
int bps = av_get_bytes_per_sample(frame->format);
|
|
||||||
int plane_size = bps * frame->nb_samples * (planar ? 1 : channels);
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
for (i = 0; i < planes; i++) {
|
|
||||||
uint8_t checksum[16];
|
|
||||||
|
|
||||||
av_md5_init(md5);
|
|
||||||
av_md5_sum(checksum, frame->extended_data[i], plane_size);
|
|
||||||
|
|
||||||
fprintf(stdout, "plane %d: 0x", i);
|
|
||||||
for (j = 0; j < sizeof(checksum); j++)
|
|
||||||
fprintf(stdout, "%02X", checksum[j]);
|
|
||||||
fprintf(stdout, "\n");
|
|
||||||
}
|
|
||||||
fprintf(stdout, "\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Construct a frame of audio data to be filtered;
|
|
||||||
* this simple example just synthesizes a sine wave. */
|
|
||||||
static int get_input(AVFrame *frame, int frame_num)
|
|
||||||
{
|
|
||||||
int err, i, j;
|
|
||||||
|
|
||||||
#define FRAME_SIZE 1024
|
|
||||||
|
|
||||||
/* Set up the frame properties and allocate the buffer for the data. */
|
|
||||||
frame->sample_rate = INPUT_SAMPLERATE;
|
|
||||||
frame->format = INPUT_FORMAT;
|
|
||||||
frame->channel_layout = INPUT_CHANNEL_LAYOUT;
|
|
||||||
frame->nb_samples = FRAME_SIZE;
|
|
||||||
frame->pts = frame_num * FRAME_SIZE;
|
|
||||||
|
|
||||||
err = av_frame_get_buffer(frame, 0);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
/* Fill the data for each channel. */
|
|
||||||
for (i = 0; i < 5; i++) {
|
|
||||||
float *data = (float*)frame->extended_data[i];
|
|
||||||
|
|
||||||
for (j = 0; j < frame->nb_samples; j++)
|
|
||||||
data[j] = sin(2 * M_PI * (frame_num + j) * (i + 1) / FRAME_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
struct AVMD5 *md5;
|
|
||||||
AVFilterGraph *graph;
|
|
||||||
AVFilterContext *src, *sink;
|
|
||||||
AVFrame *frame;
|
|
||||||
uint8_t errstr[1024];
|
|
||||||
float duration;
|
|
||||||
int err, nb_frames, i;
|
|
||||||
|
|
||||||
if (argc < 2) {
|
|
||||||
fprintf(stderr, "Usage: %s <duration>\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
duration = atof(argv[1]);
|
|
||||||
nb_frames = duration * INPUT_SAMPLERATE / FRAME_SIZE;
|
|
||||||
if (nb_frames <= 0) {
|
|
||||||
fprintf(stderr, "Invalid duration: %s\n", argv[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
avfilter_register_all();
|
|
||||||
|
|
||||||
/* Allocate the frame we will be using to store the data. */
|
|
||||||
frame = av_frame_alloc();
|
|
||||||
if (!frame) {
|
|
||||||
fprintf(stderr, "Error allocating the frame\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
md5 = av_md5_alloc();
|
|
||||||
if (!md5) {
|
|
||||||
fprintf(stderr, "Error allocating the MD5 context\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set up the filtergraph. */
|
|
||||||
err = init_filter_graph(&graph, &src, &sink);
|
|
||||||
if (err < 0) {
|
|
||||||
fprintf(stderr, "Unable to init filter graph:");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the main filtering loop */
|
|
||||||
for (i = 0; i < nb_frames; i++) {
|
|
||||||
/* get an input frame to be filtered */
|
|
||||||
err = get_input(frame, i);
|
|
||||||
if (err < 0) {
|
|
||||||
fprintf(stderr, "Error generating input frame:");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send the frame to the input of the filtergraph. */
|
|
||||||
err = av_buffersrc_add_frame(src, frame);
|
|
||||||
if (err < 0) {
|
|
||||||
av_frame_unref(frame);
|
|
||||||
fprintf(stderr, "Error submitting the frame to the filtergraph:");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get all the filtered output that is available. */
|
|
||||||
while ((err = av_buffersink_get_frame(sink, frame)) >= 0) {
|
|
||||||
/* now do something with our filtered frame */
|
|
||||||
err = process_output(md5, frame);
|
|
||||||
if (err < 0) {
|
|
||||||
fprintf(stderr, "Error processing the filtered frame:");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
av_frame_unref(frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err == AVERROR(EAGAIN)) {
|
|
||||||
/* Need to feed more frames in. */
|
|
||||||
continue;
|
|
||||||
} else if (err == AVERROR_EOF) {
|
|
||||||
/* Nothing more to do, finish. */
|
|
||||||
break;
|
|
||||||
} else if (err < 0) {
|
|
||||||
/* An error occurred. */
|
|
||||||
fprintf(stderr, "Error filtering the data:");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
avfilter_graph_free(&graph);
|
|
||||||
av_frame_free(&frame);
|
|
||||||
av_freep(&md5);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
av_strerror(err, errstr, sizeof(errstr));
|
|
||||||
fprintf(stderr, "%s\n", errstr);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* API example for audio decoding and filtering
|
* API example for audio decoding and filtering
|
||||||
* @example filtering_audio.c
|
* @example doc/examples/filtering_audio.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
#include <libavfilter/avfiltergraph.h>
|
#include <libavfilter/avfiltergraph.h>
|
||||||
|
#include <libavfilter/avcodec.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>
|
||||||
@@ -65,7 +66,7 @@ static int open_input_file(const char *filename)
|
|||||||
/* select the audio stream */
|
/* select the audio stream */
|
||||||
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0);
|
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot find an audio stream in the input file\n");
|
av_log(NULL, AV_LOG_ERROR, "Cannot find a audio stream in the input file\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
audio_stream_index = ret;
|
audio_stream_index = ret;
|
||||||
@@ -84,7 +85,7 @@ static int open_input_file(const char *filename)
|
|||||||
static int init_filters(const char *filters_descr)
|
static int init_filters(const char *filters_descr)
|
||||||
{
|
{
|
||||||
char args[512];
|
char args[512];
|
||||||
int ret = 0;
|
int ret;
|
||||||
AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
|
AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
|
||||||
AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
|
AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
|
||||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||||
@@ -96,10 +97,6 @@ static int init_filters(const char *filters_descr)
|
|||||||
AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base;
|
AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base;
|
||||||
|
|
||||||
filter_graph = avfilter_graph_alloc();
|
filter_graph = avfilter_graph_alloc();
|
||||||
if (!outputs || !inputs || !filter_graph) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* buffer audio source: the decoded frames from the decoder will be inserted here. */
|
/* buffer audio source: the decoded frames from the decoder will be inserted here. */
|
||||||
if (!dec_ctx->channel_layout)
|
if (!dec_ctx->channel_layout)
|
||||||
@@ -112,7 +109,7 @@ static int init_filters(const char *filters_descr)
|
|||||||
args, NULL, filter_graph);
|
args, NULL, filter_graph);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
|
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
|
||||||
goto end;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* buffer audio sink: to terminate the filter chain. */
|
/* buffer audio sink: to terminate the filter chain. */
|
||||||
@@ -120,63 +117,47 @@ static int init_filters(const char *filters_descr)
|
|||||||
NULL, NULL, filter_graph);
|
NULL, NULL, filter_graph);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");
|
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");
|
||||||
goto end;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = av_opt_set_int_list(buffersink_ctx, "sample_fmts", out_sample_fmts, -1,
|
ret = av_opt_set_int_list(buffersink_ctx, "sample_fmts", out_sample_fmts, -1,
|
||||||
AV_OPT_SEARCH_CHILDREN);
|
AV_OPT_SEARCH_CHILDREN);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n");
|
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n");
|
||||||
goto end;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = av_opt_set_int_list(buffersink_ctx, "channel_layouts", out_channel_layouts, -1,
|
ret = av_opt_set_int_list(buffersink_ctx, "channel_layouts", out_channel_layouts, -1,
|
||||||
AV_OPT_SEARCH_CHILDREN);
|
AV_OPT_SEARCH_CHILDREN);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
|
av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
|
||||||
goto end;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = av_opt_set_int_list(buffersink_ctx, "sample_rates", out_sample_rates, -1,
|
ret = av_opt_set_int_list(buffersink_ctx, "sample_rates", out_sample_rates, -1,
|
||||||
AV_OPT_SEARCH_CHILDREN);
|
AV_OPT_SEARCH_CHILDREN);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");
|
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");
|
||||||
goto end;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Endpoints for the filter graph. */
|
||||||
* Set the endpoints for the filter graph. The filter_graph will
|
|
||||||
* be linked to the graph described by filters_descr.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The buffer source output must be connected to the input pad of
|
|
||||||
* the first filter described by filters_descr; since the first
|
|
||||||
* filter input label is not specified, it is set to "in" by
|
|
||||||
* default.
|
|
||||||
*/
|
|
||||||
outputs->name = av_strdup("in");
|
outputs->name = av_strdup("in");
|
||||||
outputs->filter_ctx = buffersrc_ctx;
|
outputs->filter_ctx = buffersrc_ctx;
|
||||||
outputs->pad_idx = 0;
|
outputs->pad_idx = 0;
|
||||||
outputs->next = NULL;
|
outputs->next = NULL;
|
||||||
|
|
||||||
/*
|
|
||||||
* The buffer sink input must be connected to the output pad of
|
|
||||||
* the last filter described by filters_descr; since the last
|
|
||||||
* filter output label is not specified, it is set to "out" by
|
|
||||||
* default.
|
|
||||||
*/
|
|
||||||
inputs->name = av_strdup("out");
|
inputs->name = av_strdup("out");
|
||||||
inputs->filter_ctx = buffersink_ctx;
|
inputs->filter_ctx = buffersink_ctx;
|
||||||
inputs->pad_idx = 0;
|
inputs->pad_idx = 0;
|
||||||
inputs->next = NULL;
|
inputs->next = NULL;
|
||||||
|
|
||||||
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
|
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
|
||||||
&inputs, &outputs, NULL)) < 0)
|
&inputs, &outputs, NULL)) < 0)
|
||||||
goto end;
|
return ret;
|
||||||
|
|
||||||
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
|
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
|
||||||
goto end;
|
return ret;
|
||||||
|
|
||||||
/* Print summary of the sink buffer
|
/* Print summary of the sink buffer
|
||||||
* Note: args buffer is reused to store channel layout string */
|
* Note: args buffer is reused to store channel layout string */
|
||||||
@@ -187,11 +168,7 @@ static int init_filters(const char *filters_descr)
|
|||||||
(char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"),
|
(char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"),
|
||||||
args);
|
args);
|
||||||
|
|
||||||
end:
|
return 0;
|
||||||
avfilter_inout_free(&inputs);
|
|
||||||
avfilter_inout_free(&outputs);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_frame(const AVFrame *frame)
|
static void print_frame(const AVFrame *frame)
|
||||||
@@ -211,7 +188,7 @@ static void print_frame(const AVFrame *frame)
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
AVPacket packet0, packet;
|
AVPacket 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;
|
int got_frame;
|
||||||
@@ -225,6 +202,7 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
avcodec_register_all();
|
||||||
av_register_all();
|
av_register_all();
|
||||||
avfilter_register_all();
|
avfilter_register_all();
|
||||||
|
|
||||||
@@ -234,24 +212,18 @@ int main(int argc, char **argv)
|
|||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* read all packets */
|
/* read all packets */
|
||||||
packet0.data = NULL;
|
|
||||||
packet.data = NULL;
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!packet0.data) {
|
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
|
||||||
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
|
break;
|
||||||
break;
|
|
||||||
packet0 = packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packet.stream_index == audio_stream_index) {
|
if (packet.stream_index == audio_stream_index) {
|
||||||
|
avcodec_get_frame_defaults(frame);
|
||||||
got_frame = 0;
|
got_frame = 0;
|
||||||
ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, &packet);
|
ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, &packet);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Error decoding audio\n");
|
av_log(NULL, AV_LOG_ERROR, "Error decoding audio\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
packet.size -= ret;
|
|
||||||
packet.data += ret;
|
|
||||||
|
|
||||||
if (got_frame) {
|
if (got_frame) {
|
||||||
/* push the audio data from decoded frame into the filtergraph */
|
/* push the audio data from decoded frame into the filtergraph */
|
||||||
@@ -263,31 +235,29 @@ int main(int argc, char **argv)
|
|||||||
/* pull filtered audio from the filtergraph */
|
/* pull filtered audio from the filtergraph */
|
||||||
while (1) {
|
while (1) {
|
||||||
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
|
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||||
break;
|
break;
|
||||||
if (ret < 0)
|
if(ret < 0)
|
||||||
goto end;
|
goto end;
|
||||||
print_frame(filt_frame);
|
print_frame(filt_frame);
|
||||||
av_frame_unref(filt_frame);
|
av_frame_unref(filt_frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet.size <= 0)
|
|
||||||
av_packet_unref(&packet0);
|
|
||||||
} else {
|
|
||||||
/* discard non-wanted packets */
|
|
||||||
av_packet_unref(&packet0);
|
|
||||||
}
|
}
|
||||||
|
av_free_packet(&packet);
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
avfilter_graph_free(&filter_graph);
|
avfilter_graph_free(&filter_graph);
|
||||||
avcodec_close(dec_ctx);
|
if (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);
|
||||||
|
|
||||||
if (ret < 0 && ret != AVERROR_EOF) {
|
if (ret < 0 && ret != AVERROR_EOF) {
|
||||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
char buf[1024];
|
||||||
|
av_strerror(ret, buf, sizeof(buf));
|
||||||
|
fprintf(stderr, "Error occurred: %s\n", buf);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* API example for decoding and filtering
|
* API example for decoding and filtering
|
||||||
* @example filtering_video.c
|
* @example doc/examples/filtering_video.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _XOPEN_SOURCE 600 /* for usleep */
|
#define _XOPEN_SOURCE 600 /* for usleep */
|
||||||
@@ -33,14 +33,11 @@
|
|||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
#include <libavfilter/avfiltergraph.h>
|
#include <libavfilter/avfiltergraph.h>
|
||||||
|
#include <libavfilter/avcodec.h>
|
||||||
#include <libavfilter/buffersink.h>
|
#include <libavfilter/buffersink.h>
|
||||||
#include <libavfilter/buffersrc.h>
|
#include <libavfilter/buffersrc.h>
|
||||||
#include <libavutil/opt.h>
|
|
||||||
|
|
||||||
const char *filter_descr = "scale=78:24,transpose=cclock";
|
const char *filter_descr = "scale=78:24";
|
||||||
/* other way:
|
|
||||||
scale=78:24 [scl]; [scl] transpose=cclock // assumes "[in]" and "[out]" to be input output pads respectively
|
|
||||||
*/
|
|
||||||
|
|
||||||
static AVFormatContext *fmt_ctx;
|
static AVFormatContext *fmt_ctx;
|
||||||
static AVCodecContext *dec_ctx;
|
static AVCodecContext *dec_ctx;
|
||||||
@@ -73,7 +70,6 @@ static int open_input_file(const char *filename)
|
|||||||
}
|
}
|
||||||
video_stream_index = ret;
|
video_stream_index = ret;
|
||||||
dec_ctx = fmt_ctx->streams[video_stream_index]->codec;
|
dec_ctx = fmt_ctx->streams[video_stream_index]->codec;
|
||||||
av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);
|
|
||||||
|
|
||||||
/* 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) {
|
||||||
@@ -87,71 +83,47 @@ static int open_input_file(const char *filename)
|
|||||||
static int init_filters(const char *filters_descr)
|
static int init_filters(const char *filters_descr)
|
||||||
{
|
{
|
||||||
char args[512];
|
char args[512];
|
||||||
int ret = 0;
|
int ret;
|
||||||
AVFilter *buffersrc = avfilter_get_by_name("buffer");
|
AVFilter *buffersrc = avfilter_get_by_name("buffer");
|
||||||
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;
|
|
||||||
enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };
|
enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };
|
||||||
|
AVBufferSinkParams *buffersink_params;
|
||||||
|
|
||||||
filter_graph = avfilter_graph_alloc();
|
filter_graph = avfilter_graph_alloc();
|
||||||
if (!outputs || !inputs || !filter_graph) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* buffer video source: the decoded frames from the decoder will be inserted here. */
|
/* buffer video source: the decoded frames from the decoder will be inserted here. */
|
||||||
snprintf(args, sizeof(args),
|
snprintf(args, sizeof(args),
|
||||||
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
|
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
|
||||||
dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
|
dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
|
||||||
time_base.num, time_base.den,
|
dec_ctx->time_base.num, dec_ctx->time_base.den,
|
||||||
dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);
|
dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);
|
||||||
|
|
||||||
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
|
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
|
||||||
args, NULL, filter_graph);
|
args, NULL, filter_graph);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
|
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
|
||||||
goto end;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* buffer video sink: to terminate the filter chain. */
|
/* buffer video sink: to terminate the filter chain. */
|
||||||
|
buffersink_params = av_buffersink_params_alloc();
|
||||||
|
buffersink_params->pixel_fmts = pix_fmts;
|
||||||
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
|
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
|
||||||
NULL, NULL, filter_graph);
|
NULL, buffersink_params, filter_graph);
|
||||||
|
av_free(buffersink_params);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
|
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
|
||||||
goto end;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts,
|
/* Endpoints for the filter graph. */
|
||||||
AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the endpoints for the filter graph. The filter_graph will
|
|
||||||
* be linked to the graph described by filters_descr.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The buffer source output must be connected to the input pad of
|
|
||||||
* the first filter described by filters_descr; since the first
|
|
||||||
* filter input label is not specified, it is set to "in" by
|
|
||||||
* default.
|
|
||||||
*/
|
|
||||||
outputs->name = av_strdup("in");
|
outputs->name = av_strdup("in");
|
||||||
outputs->filter_ctx = buffersrc_ctx;
|
outputs->filter_ctx = buffersrc_ctx;
|
||||||
outputs->pad_idx = 0;
|
outputs->pad_idx = 0;
|
||||||
outputs->next = NULL;
|
outputs->next = NULL;
|
||||||
|
|
||||||
/*
|
|
||||||
* The buffer sink input must be connected to the output pad of
|
|
||||||
* the last filter described by filters_descr; since the last
|
|
||||||
* filter output label is not specified, it is set to "out" by
|
|
||||||
* default.
|
|
||||||
*/
|
|
||||||
inputs->name = av_strdup("out");
|
inputs->name = av_strdup("out");
|
||||||
inputs->filter_ctx = buffersink_ctx;
|
inputs->filter_ctx = buffersink_ctx;
|
||||||
inputs->pad_idx = 0;
|
inputs->pad_idx = 0;
|
||||||
@@ -159,16 +131,11 @@ static int init_filters(const char *filters_descr)
|
|||||||
|
|
||||||
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
|
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
|
||||||
&inputs, &outputs, NULL)) < 0)
|
&inputs, &outputs, NULL)) < 0)
|
||||||
goto end;
|
return ret;
|
||||||
|
|
||||||
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
|
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
|
||||||
goto end;
|
return ret;
|
||||||
|
return 0;
|
||||||
end:
|
|
||||||
avfilter_inout_free(&inputs);
|
|
||||||
avfilter_inout_free(&outputs);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void display_frame(const AVFrame *frame, AVRational time_base)
|
static void display_frame(const AVFrame *frame, AVRational time_base)
|
||||||
@@ -219,6 +186,7 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
avcodec_register_all();
|
||||||
av_register_all();
|
av_register_all();
|
||||||
avfilter_register_all();
|
avfilter_register_all();
|
||||||
|
|
||||||
@@ -233,6 +201,7 @@ int main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (packet.stream_index == video_stream_index) {
|
if (packet.stream_index == video_stream_index) {
|
||||||
|
avcodec_get_frame_defaults(frame);
|
||||||
got_frame = 0;
|
got_frame = 0;
|
||||||
ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, &packet);
|
ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, &packet);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -259,20 +228,22 @@ int main(int argc, char **argv)
|
|||||||
display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
|
display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
|
||||||
av_frame_unref(filt_frame);
|
av_frame_unref(filt_frame);
|
||||||
}
|
}
|
||||||
av_frame_unref(frame);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
av_packet_unref(&packet);
|
av_free_packet(&packet);
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
avfilter_graph_free(&filter_graph);
|
avfilter_graph_free(&filter_graph);
|
||||||
avcodec_close(dec_ctx);
|
if (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);
|
||||||
|
|
||||||
if (ret < 0 && ret != AVERROR_EOF) {
|
if (ret < 0 && ret != AVERROR_EOF) {
|
||||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
char buf[1024];
|
||||||
|
av_strerror(ret, buf, sizeof(buf));
|
||||||
|
fprintf(stderr, "Error occurred: %s\n", buf);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,155 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015 Stephan Holljes
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* libavformat multi-client network API usage example.
|
|
||||||
*
|
|
||||||
* @example http_multiclient.c
|
|
||||||
* This example will serve a file without decoding or demuxing it over http.
|
|
||||||
* Multiple clients can connect and will receive the same file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <libavformat/avformat.h>
|
|
||||||
#include <libavutil/opt.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static void process_client(AVIOContext *client, const char *in_uri)
|
|
||||||
{
|
|
||||||
AVIOContext *input = NULL;
|
|
||||||
uint8_t buf[1024];
|
|
||||||
int ret, n, reply_code;
|
|
||||||
uint8_t *resource = NULL;
|
|
||||||
while ((ret = avio_handshake(client)) > 0) {
|
|
||||||
av_opt_get(client, "resource", AV_OPT_SEARCH_CHILDREN, &resource);
|
|
||||||
// check for strlen(resource) is necessary, because av_opt_get()
|
|
||||||
// may return empty string.
|
|
||||||
if (resource && strlen(resource))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ret < 0)
|
|
||||||
goto end;
|
|
||||||
av_log(client, AV_LOG_TRACE, "resource=%p\n", resource);
|
|
||||||
if (resource && resource[0] == '/' && !strcmp((resource + 1), in_uri)) {
|
|
||||||
reply_code = 200;
|
|
||||||
} else {
|
|
||||||
reply_code = AVERROR_HTTP_NOT_FOUND;
|
|
||||||
}
|
|
||||||
if ((ret = av_opt_set_int(client, "reply_code", reply_code, AV_OPT_SEARCH_CHILDREN)) < 0) {
|
|
||||||
av_log(client, AV_LOG_ERROR, "Failed to set reply_code: %s.\n", av_err2str(ret));
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
av_log(client, AV_LOG_TRACE, "Set reply code to %d\n", reply_code);
|
|
||||||
|
|
||||||
while ((ret = avio_handshake(client)) > 0);
|
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
fprintf(stderr, "Handshake performed.\n");
|
|
||||||
if (reply_code != 200)
|
|
||||||
goto end;
|
|
||||||
fprintf(stderr, "Opening input file.\n");
|
|
||||||
if ((ret = avio_open2(&input, in_uri, AVIO_FLAG_READ, NULL, NULL)) < 0) {
|
|
||||||
av_log(input, AV_LOG_ERROR, "Failed to open input: %s: %s.\n", in_uri,
|
|
||||||
av_err2str(ret));
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
for(;;) {
|
|
||||||
n = avio_read(input, buf, sizeof(buf));
|
|
||||||
if (n < 0) {
|
|
||||||
if (n == AVERROR_EOF)
|
|
||||||
break;
|
|
||||||
av_log(input, AV_LOG_ERROR, "Error reading from input: %s.\n",
|
|
||||||
av_err2str(n));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
avio_write(client, buf, n);
|
|
||||||
avio_flush(client);
|
|
||||||
}
|
|
||||||
end:
|
|
||||||
fprintf(stderr, "Flushing client\n");
|
|
||||||
avio_flush(client);
|
|
||||||
fprintf(stderr, "Closing client\n");
|
|
||||||
avio_close(client);
|
|
||||||
fprintf(stderr, "Closing input\n");
|
|
||||||
avio_close(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
AVDictionary *options = NULL;
|
|
||||||
AVIOContext *client = NULL, *server = NULL;
|
|
||||||
const char *in_uri, *out_uri;
|
|
||||||
int ret, pid;
|
|
||||||
av_log_set_level(AV_LOG_TRACE);
|
|
||||||
if (argc < 3) {
|
|
||||||
printf("usage: %s input http://hostname[:port]\n"
|
|
||||||
"API example program to serve http to multiple clients.\n"
|
|
||||||
"\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
in_uri = argv[1];
|
|
||||||
out_uri = argv[2];
|
|
||||||
|
|
||||||
av_register_all();
|
|
||||||
avformat_network_init();
|
|
||||||
|
|
||||||
if ((ret = av_dict_set(&options, "listen", "2", 0)) < 0) {
|
|
||||||
fprintf(stderr, "Failed to set listen mode for server: %s\n", av_err2str(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if ((ret = avio_open2(&server, out_uri, AVIO_FLAG_WRITE, NULL, &options)) < 0) {
|
|
||||||
fprintf(stderr, "Failed to open server: %s\n", av_err2str(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "Entering main loop.\n");
|
|
||||||
for(;;) {
|
|
||||||
if ((ret = avio_accept(server, &client)) < 0)
|
|
||||||
goto end;
|
|
||||||
fprintf(stderr, "Accepted client, forking process.\n");
|
|
||||||
// XXX: Since we don't reap our children and don't ignore signals
|
|
||||||
// this produces zombie processes.
|
|
||||||
pid = fork();
|
|
||||||
if (pid < 0) {
|
|
||||||
perror("Fork failed");
|
|
||||||
ret = AVERROR(errno);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
if (pid == 0) {
|
|
||||||
fprintf(stderr, "In child.\n");
|
|
||||||
process_client(client, in_uri);
|
|
||||||
avio_close(server);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
if (pid > 0)
|
|
||||||
avio_close(client);
|
|
||||||
}
|
|
||||||
end:
|
|
||||||
avio_close(server);
|
|
||||||
if (ret < 0 && ret != AVERROR_EOF) {
|
|
||||||
fprintf(stderr, "Some errors occurred: %s\n", av_err2str(ret));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* Shows how the metadata API can be used in application programs.
|
* Shows how the metadata API can be used in application programs.
|
||||||
* @example metadata.c
|
* @example doc/examples/metadata.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|||||||
@@ -24,9 +24,9 @@
|
|||||||
* @file
|
* @file
|
||||||
* libavformat API example.
|
* libavformat API example.
|
||||||
*
|
*
|
||||||
* Output a media file in any supported libavformat format. The default
|
* Output a media file in any supported libavformat format.
|
||||||
* codecs are used.
|
* The default codecs are used.
|
||||||
* @example muxing.c
|
* @example doc/examples/muxing.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -34,68 +34,26 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <libavutil/avassert.h>
|
|
||||||
#include <libavutil/channel_layout.h>
|
|
||||||
#include <libavutil/opt.h>
|
#include <libavutil/opt.h>
|
||||||
#include <libavutil/mathematics.h>
|
#include <libavutil/mathematics.h>
|
||||||
#include <libavutil/timestamp.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>
|
||||||
|
|
||||||
#define STREAM_DURATION 10.0
|
/* 5 seconds stream duration */
|
||||||
|
#define STREAM_DURATION 200.0
|
||||||
#define STREAM_FRAME_RATE 25 /* 25 images/s */
|
#define STREAM_FRAME_RATE 25 /* 25 images/s */
|
||||||
|
#define STREAM_NB_FRAMES ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
|
||||||
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
|
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
|
||||||
|
|
||||||
#define SCALE_FLAGS SWS_BICUBIC
|
static int sws_flags = SWS_BICUBIC;
|
||||||
|
|
||||||
// a wrapper around a single output AVStream
|
|
||||||
typedef struct OutputStream {
|
|
||||||
AVStream *st;
|
|
||||||
AVCodecContext *enc;
|
|
||||||
|
|
||||||
/* pts of the next frame that will be generated */
|
|
||||||
int64_t next_pts;
|
|
||||||
int samples_count;
|
|
||||||
|
|
||||||
AVFrame *frame;
|
|
||||||
AVFrame *tmp_frame;
|
|
||||||
|
|
||||||
float t, tincr, tincr2;
|
|
||||||
|
|
||||||
struct SwsContext *sws_ctx;
|
|
||||||
struct SwrContext *swr_ctx;
|
|
||||||
} OutputStream;
|
|
||||||
|
|
||||||
static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)
|
|
||||||
{
|
|
||||||
AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
|
|
||||||
|
|
||||||
printf("pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
|
|
||||||
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
|
|
||||||
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
|
|
||||||
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
|
|
||||||
pkt->stream_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
|
|
||||||
{
|
|
||||||
/* rescale output packet timestamp values from codec to stream timebase */
|
|
||||||
av_packet_rescale_ts(pkt, *time_base, st->time_base);
|
|
||||||
pkt->stream_index = st->index;
|
|
||||||
|
|
||||||
/* Write the compressed frame to the media file. */
|
|
||||||
log_packet(fmt_ctx, pkt);
|
|
||||||
return av_interleaved_write_frame(fmt_ctx, pkt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add an output stream. */
|
/* Add an output stream. */
|
||||||
static void add_stream(OutputStream *ost, AVFormatContext *oc,
|
static AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,
|
||||||
AVCodec **codec,
|
enum AVCodecID codec_id)
|
||||||
enum AVCodecID codec_id)
|
|
||||||
{
|
{
|
||||||
AVCodecContext *c;
|
AVCodecContext *c;
|
||||||
int i;
|
AVStream *st;
|
||||||
|
|
||||||
/* find the encoder */
|
/* find the encoder */
|
||||||
*codec = avcodec_find_encoder(codec_id);
|
*codec = avcodec_find_encoder(codec_id);
|
||||||
@@ -105,43 +63,20 @@ static void add_stream(OutputStream *ost, AVFormatContext *oc,
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ost->st = avformat_new_stream(oc, NULL);
|
st = avformat_new_stream(oc, *codec);
|
||||||
if (!ost->st) {
|
if (!st) {
|
||||||
fprintf(stderr, "Could not allocate stream\n");
|
fprintf(stderr, "Could not allocate stream\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
ost->st->id = oc->nb_streams-1;
|
st->id = oc->nb_streams-1;
|
||||||
c = avcodec_alloc_context3(*codec);
|
c = st->codec;
|
||||||
if (!c) {
|
|
||||||
fprintf(stderr, "Could not alloc an encoding context\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
ost->enc = c;
|
|
||||||
|
|
||||||
switch ((*codec)->type) {
|
switch ((*codec)->type) {
|
||||||
case AVMEDIA_TYPE_AUDIO:
|
case AVMEDIA_TYPE_AUDIO:
|
||||||
c->sample_fmt = (*codec)->sample_fmts ?
|
c->sample_fmt = AV_SAMPLE_FMT_FLTP;
|
||||||
(*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
|
|
||||||
c->bit_rate = 64000;
|
c->bit_rate = 64000;
|
||||||
c->sample_rate = 44100;
|
c->sample_rate = 44100;
|
||||||
if ((*codec)->supported_samplerates) {
|
c->channels = 2;
|
||||||
c->sample_rate = (*codec)->supported_samplerates[0];
|
|
||||||
for (i = 0; (*codec)->supported_samplerates[i]; i++) {
|
|
||||||
if ((*codec)->supported_samplerates[i] == 44100)
|
|
||||||
c->sample_rate = 44100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
|
|
||||||
c->channel_layout = AV_CH_LAYOUT_STEREO;
|
|
||||||
if ((*codec)->channel_layouts) {
|
|
||||||
c->channel_layout = (*codec)->channel_layouts[0];
|
|
||||||
for (i = 0; (*codec)->channel_layouts[i]; i++) {
|
|
||||||
if ((*codec)->channel_layouts[i] == AV_CH_LAYOUT_STEREO)
|
|
||||||
c->channel_layout = AV_CH_LAYOUT_STEREO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
|
|
||||||
ost->st->time_base = (AVRational){ 1, c->sample_rate };
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AVMEDIA_TYPE_VIDEO:
|
case AVMEDIA_TYPE_VIDEO:
|
||||||
@@ -155,13 +90,12 @@ static void add_stream(OutputStream *ost, AVFormatContext *oc,
|
|||||||
* of which frame timestamps are represented. For fixed-fps content,
|
* of which frame timestamps are represented. For fixed-fps content,
|
||||||
* timebase should be 1/framerate and timestamp increments should be
|
* timebase should be 1/framerate and timestamp increments should be
|
||||||
* identical to 1. */
|
* identical to 1. */
|
||||||
ost->st->time_base = (AVRational){ 1, STREAM_FRAME_RATE };
|
c->time_base.den = STREAM_FRAME_RATE;
|
||||||
c->time_base = ost->st->time_base;
|
c->time_base.num = 1;
|
||||||
|
|
||||||
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
|
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
|
||||||
c->pix_fmt = STREAM_PIX_FMT;
|
c->pix_fmt = STREAM_PIX_FMT;
|
||||||
if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
|
if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
|
||||||
/* just for testing, we also add B-frames */
|
/* just for testing, we also add B frames */
|
||||||
c->max_b_frames = 2;
|
c->max_b_frames = 2;
|
||||||
}
|
}
|
||||||
if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
|
if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
|
||||||
@@ -178,277 +112,238 @@ static void add_stream(OutputStream *ost, AVFormatContext *oc,
|
|||||||
|
|
||||||
/* Some formats want stream headers to be separate. */
|
/* Some formats want stream headers to be separate. */
|
||||||
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
|
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
|
||||||
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||||
|
|
||||||
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
/* audio output */
|
/* audio output */
|
||||||
|
|
||||||
static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
|
static float t, tincr, tincr2;
|
||||||
uint64_t channel_layout,
|
|
||||||
int sample_rate, int nb_samples)
|
|
||||||
{
|
|
||||||
AVFrame *frame = av_frame_alloc();
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!frame) {
|
static uint8_t **src_samples_data;
|
||||||
fprintf(stderr, "Error allocating an audio frame\n");
|
static int src_samples_linesize;
|
||||||
exit(1);
|
static int src_nb_samples;
|
||||||
}
|
|
||||||
|
|
||||||
frame->format = sample_fmt;
|
static int max_dst_nb_samples;
|
||||||
frame->channel_layout = channel_layout;
|
uint8_t **dst_samples_data;
|
||||||
frame->sample_rate = sample_rate;
|
int dst_samples_linesize;
|
||||||
frame->nb_samples = nb_samples;
|
int dst_samples_size;
|
||||||
|
|
||||||
if (nb_samples) {
|
struct SwrContext *swr_ctx = NULL;
|
||||||
ret = av_frame_get_buffer(frame, 0);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error allocating an audio buffer\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return frame;
|
static void open_audio(AVFormatContext *oc, AVCodec *codec, AVStream *st)
|
||||||
}
|
|
||||||
|
|
||||||
static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg)
|
|
||||||
{
|
{
|
||||||
AVCodecContext *c;
|
AVCodecContext *c;
|
||||||
int nb_samples;
|
|
||||||
int ret;
|
int ret;
|
||||||
AVDictionary *opt = NULL;
|
|
||||||
|
|
||||||
c = ost->enc;
|
c = st->codec;
|
||||||
|
|
||||||
/* open it */
|
/* open it */
|
||||||
av_dict_copy(&opt, opt_arg, 0);
|
ret = avcodec_open2(c, codec, NULL);
|
||||||
ret = avcodec_open2(c, codec, &opt);
|
|
||||||
av_dict_free(&opt);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Could not open audio codec: %s\n", av_err2str(ret));
|
fprintf(stderr, "Could not open audio codec: %s\n", av_err2str(ret));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init signal generator */
|
/* init signal generator */
|
||||||
ost->t = 0;
|
t = 0;
|
||||||
ost->tincr = 2 * M_PI * 110.0 / c->sample_rate;
|
tincr = 2 * M_PI * 110.0 / c->sample_rate;
|
||||||
/* increment frequency by 110 Hz per second */
|
/* increment frequency by 110 Hz per second */
|
||||||
ost->tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
|
tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
|
||||||
|
|
||||||
if (c->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
|
src_nb_samples = c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE ?
|
||||||
nb_samples = 10000;
|
10000 : c->frame_size;
|
||||||
else
|
|
||||||
nb_samples = c->frame_size;
|
|
||||||
|
|
||||||
ost->frame = alloc_audio_frame(c->sample_fmt, c->channel_layout,
|
ret = av_samples_alloc_array_and_samples(&src_samples_data, &src_samples_linesize, c->channels,
|
||||||
c->sample_rate, nb_samples);
|
src_nb_samples, c->sample_fmt, 0);
|
||||||
ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, c->channel_layout,
|
|
||||||
c->sample_rate, nb_samples);
|
|
||||||
|
|
||||||
/* copy the stream parameters to the muxer */
|
|
||||||
ret = avcodec_parameters_from_context(ost->st->codecpar, c);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Could not copy the stream parameters\n");
|
fprintf(stderr, "Could not allocate source samples\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create resampler context */
|
/* create resampler context */
|
||||||
ost->swr_ctx = swr_alloc();
|
if (c->sample_fmt != AV_SAMPLE_FMT_S16) {
|
||||||
if (!ost->swr_ctx) {
|
swr_ctx = swr_alloc();
|
||||||
|
if (!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 (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 (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(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 (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 (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(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(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);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* compute the number of converted samples: buffering is avoided
|
||||||
|
* ensuring that the output buffer will contain at least all the
|
||||||
|
* converted input samples */
|
||||||
|
max_dst_nb_samples = src_nb_samples;
|
||||||
|
ret = av_samples_alloc_array_and_samples(&dst_samples_data, &dst_samples_linesize, c->channels,
|
||||||
|
max_dst_nb_samples, c->sample_fmt, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Could not allocate destination samples\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
dst_samples_size = av_samples_get_buffer_size(NULL, c->channels, max_dst_nb_samples,
|
||||||
|
c->sample_fmt, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
|
/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
|
||||||
* 'nb_channels' channels. */
|
* 'nb_channels' channels. */
|
||||||
static AVFrame *get_audio_frame(OutputStream *ost)
|
static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)
|
||||||
{
|
{
|
||||||
AVFrame *frame = ost->tmp_frame;
|
|
||||||
int j, i, v;
|
int j, i, v;
|
||||||
int16_t *q = (int16_t*)frame->data[0];
|
int16_t *q;
|
||||||
|
|
||||||
/* check if we want to generate more frames */
|
q = samples;
|
||||||
if (av_compare_ts(ost->next_pts, ost->enc->time_base,
|
for (j = 0; j < frame_size; j++) {
|
||||||
STREAM_DURATION, (AVRational){ 1, 1 }) >= 0)
|
v = (int)(sin(t) * 10000);
|
||||||
return NULL;
|
for (i = 0; i < nb_channels; i++)
|
||||||
|
|
||||||
for (j = 0; j <frame->nb_samples; j++) {
|
|
||||||
v = (int)(sin(ost->t) * 10000);
|
|
||||||
for (i = 0; i < ost->enc->channels; i++)
|
|
||||||
*q++ = v;
|
*q++ = v;
|
||||||
ost->t += ost->tincr;
|
t += tincr;
|
||||||
ost->tincr += ost->tincr2;
|
tincr += tincr2;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->pts = ost->next_pts;
|
|
||||||
ost->next_pts += frame->nb_samples;
|
|
||||||
|
|
||||||
return frame;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void write_audio_frame(AVFormatContext *oc, AVStream *st)
|
||||||
* encode one audio frame and send it to the muxer
|
|
||||||
* return 1 when encoding is finished, 0 otherwise
|
|
||||||
*/
|
|
||||||
static int write_audio_frame(AVFormatContext *oc, OutputStream *ost)
|
|
||||||
{
|
{
|
||||||
AVCodecContext *c;
|
AVCodecContext *c;
|
||||||
AVPacket pkt = { 0 }; // data and size must be 0;
|
AVPacket pkt = { 0 }; // data and size must be 0;
|
||||||
AVFrame *frame;
|
AVFrame *frame = avcodec_alloc_frame();
|
||||||
int ret;
|
int got_packet, ret, dst_nb_samples;
|
||||||
int got_packet;
|
|
||||||
int dst_nb_samples;
|
|
||||||
|
|
||||||
av_init_packet(&pkt);
|
av_init_packet(&pkt);
|
||||||
c = ost->enc;
|
c = st->codec;
|
||||||
|
|
||||||
frame = get_audio_frame(ost);
|
get_audio_frame((int16_t *)src_samples_data[0], src_nb_samples, c->channels);
|
||||||
|
|
||||||
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 */
|
if (swr_ctx) {
|
||||||
/* 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(swr_ctx, c->sample_rate) + src_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);
|
if (dst_nb_samples > max_dst_nb_samples) {
|
||||||
|
av_free(dst_samples_data[0]);
|
||||||
/* when we pass a frame to the encoder, it may keep a reference to it
|
ret = av_samples_alloc(dst_samples_data, &dst_samples_linesize, c->channels,
|
||||||
* internally;
|
dst_nb_samples, c->sample_fmt, 0);
|
||||||
* make sure we do not overwrite it here
|
if (ret < 0)
|
||||||
*/
|
|
||||||
ret = av_frame_make_writable(ost->frame);
|
|
||||||
if (ret < 0)
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
/* convert to destination format */
|
|
||||||
ret = swr_convert(ost->swr_ctx,
|
|
||||||
ost->frame->data, dst_nb_samples,
|
|
||||||
(const uint8_t **)frame->data, frame->nb_samples);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error while converting\n");
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
max_dst_nb_samples = dst_nb_samples;
|
||||||
frame = ost->frame;
|
dst_samples_size = av_samples_get_buffer_size(NULL, c->channels, dst_nb_samples,
|
||||||
|
c->sample_fmt, 0);
|
||||||
|
}
|
||||||
|
|
||||||
frame->pts = av_rescale_q(ost->samples_count, (AVRational){1, c->sample_rate}, c->time_base);
|
/* convert to destination format */
|
||||||
ost->samples_count += dst_nb_samples;
|
ret = swr_convert(swr_ctx,
|
||||||
|
dst_samples_data, dst_nb_samples,
|
||||||
|
(const uint8_t **)src_samples_data, src_nb_samples);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Error while converting\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dst_samples_data[0] = src_samples_data[0];
|
||||||
|
dst_nb_samples = src_nb_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frame->nb_samples = dst_nb_samples;
|
||||||
|
avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
|
||||||
|
dst_samples_data[0], dst_samples_size, 0);
|
||||||
|
|
||||||
ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet);
|
ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Error encoding audio frame: %s\n", av_err2str(ret));
|
fprintf(stderr, "Error encoding audio frame: %s\n", av_err2str(ret));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (got_packet) {
|
if (!got_packet)
|
||||||
ret = write_frame(oc, &c->time_base, ost->st, &pkt);
|
return;
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error while writing audio frame: %s\n",
|
|
||||||
av_err2str(ret));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (frame || got_packet) ? 0 : 1;
|
pkt.stream_index = st->index;
|
||||||
|
|
||||||
|
/* Write the compressed frame to the media file. */
|
||||||
|
ret = av_interleaved_write_frame(oc, &pkt);
|
||||||
|
if (ret != 0) {
|
||||||
|
fprintf(stderr, "Error while writing audio frame: %s\n",
|
||||||
|
av_err2str(ret));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
avcodec_free_frame(&frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void close_audio(AVFormatContext *oc, AVStream *st)
|
||||||
|
{
|
||||||
|
avcodec_close(st->codec);
|
||||||
|
av_free(src_samples_data[0]);
|
||||||
|
av_free(dst_samples_data[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
/* video output */
|
/* video output */
|
||||||
|
|
||||||
static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
|
static AVFrame *frame;
|
||||||
{
|
static AVPicture src_picture, dst_picture;
|
||||||
AVFrame *picture;
|
static int frame_count;
|
||||||
int ret;
|
|
||||||
|
|
||||||
picture = av_frame_alloc();
|
static void open_video(AVFormatContext *oc, AVCodec *codec, AVStream *st)
|
||||||
if (!picture)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
picture->format = pix_fmt;
|
|
||||||
picture->width = width;
|
|
||||||
picture->height = height;
|
|
||||||
|
|
||||||
/* allocate the buffers for the frame data */
|
|
||||||
ret = av_frame_get_buffer(picture, 32);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Could not allocate frame data.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return picture;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void open_video(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
AVCodecContext *c = ost->enc;
|
AVCodecContext *c = st->codec;
|
||||||
AVDictionary *opt = NULL;
|
|
||||||
|
|
||||||
av_dict_copy(&opt, opt_arg, 0);
|
|
||||||
|
|
||||||
/* open the codec */
|
/* open the codec */
|
||||||
ret = avcodec_open2(c, codec, &opt);
|
ret = avcodec_open2(c, codec, NULL);
|
||||||
av_dict_free(&opt);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Could not open video codec: %s\n", av_err2str(ret));
|
fprintf(stderr, "Could not open video codec: %s\n", av_err2str(ret));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate and init a re-usable frame */
|
/* allocate and init a re-usable frame */
|
||||||
ost->frame = alloc_picture(c->pix_fmt, c->width, c->height);
|
frame = avcodec_alloc_frame();
|
||||||
if (!ost->frame) {
|
if (!frame) {
|
||||||
fprintf(stderr, "Could not allocate video frame\n");
|
fprintf(stderr, "Could not allocate video frame\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate the encoded raw picture. */
|
||||||
|
ret = avpicture_alloc(&dst_picture, c->pix_fmt, c->width, c->height);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Could not allocate picture: %s\n", av_err2str(ret));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
/* If the output format is not YUV420P, then a temporary YUV420P
|
/* If the output format is not YUV420P, then a temporary YUV420P
|
||||||
* picture is needed too. It is then converted to the required
|
* picture is needed too. It is then converted to the required
|
||||||
* output format. */
|
* output format. */
|
||||||
ost->tmp_frame = NULL;
|
|
||||||
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
|
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
|
||||||
ost->tmp_frame = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);
|
ret = avpicture_alloc(&src_picture, AV_PIX_FMT_YUV420P, c->width, c->height);
|
||||||
if (!ost->tmp_frame) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Could not allocate temporary picture\n");
|
fprintf(stderr, "Could not allocate temporary picture: %s\n",
|
||||||
|
av_err2str(ret));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy the stream parameters to the muxer */
|
/* copy data and linesize picture pointers to frame */
|
||||||
ret = avcodec_parameters_from_context(ost->st->codecpar, c);
|
*((AVPicture *)frame) = dst_picture;
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Could not copy the stream parameters\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare a dummy image. */
|
/* Prepare a dummy image. */
|
||||||
static void fill_yuv_image(AVFrame *pict, int frame_index,
|
static void fill_yuv_image(AVPicture *pict, int frame_index,
|
||||||
int width, int height)
|
int width, int height)
|
||||||
{
|
{
|
||||||
int x, y, i, ret;
|
int x, y, i;
|
||||||
|
|
||||||
/* 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;
|
||||||
|
|
||||||
@@ -466,89 +361,85 @@ static void fill_yuv_image(AVFrame *pict, int frame_index,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static AVFrame *get_video_frame(OutputStream *ost)
|
static void write_video_frame(AVFormatContext *oc, AVStream *st)
|
||||||
{
|
|
||||||
AVCodecContext *c = ost->enc;
|
|
||||||
|
|
||||||
/* check if we want to generate more frames */
|
|
||||||
if (av_compare_ts(ost->next_pts, c->time_base,
|
|
||||||
STREAM_DURATION, (AVRational){ 1, 1 }) >= 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
|
|
||||||
/* as we only generate a YUV420P picture, we must convert it
|
|
||||||
* to the codec pixel format if needed */
|
|
||||||
if (!ost->sws_ctx) {
|
|
||||||
ost->sws_ctx = sws_getContext(c->width, c->height,
|
|
||||||
AV_PIX_FMT_YUV420P,
|
|
||||||
c->width, c->height,
|
|
||||||
c->pix_fmt,
|
|
||||||
SCALE_FLAGS, NULL, NULL, NULL);
|
|
||||||
if (!ost->sws_ctx) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Could not initialize the conversion context\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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, ost->tmp_frame->linesize,
|
|
||||||
0, c->height, ost->frame->data, ost->frame->linesize);
|
|
||||||
} else {
|
|
||||||
fill_yuv_image(ost->frame, ost->next_pts, c->width, c->height);
|
|
||||||
}
|
|
||||||
|
|
||||||
ost->frame->pts = ost->next_pts++;
|
|
||||||
|
|
||||||
return ost->frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* encode one video frame and send it to the muxer
|
|
||||||
* return 1 when encoding is finished, 0 otherwise
|
|
||||||
*/
|
|
||||||
static int write_video_frame(AVFormatContext *oc, OutputStream *ost)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
AVCodecContext *c;
|
static struct SwsContext *sws_ctx;
|
||||||
AVFrame *frame;
|
AVCodecContext *c = st->codec;
|
||||||
int got_packet = 0;
|
|
||||||
AVPacket pkt = { 0 };
|
|
||||||
|
|
||||||
c = ost->enc;
|
if (frame_count >= STREAM_NB_FRAMES) {
|
||||||
|
/* No more frames to compress. The codec has a latency of a few
|
||||||
frame = get_video_frame(ost);
|
* frames if using B-frames, so we get the last frames by
|
||||||
|
* passing the same picture again. */
|
||||||
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 {
|
} else {
|
||||||
ret = 0;
|
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
|
||||||
|
/* as we only generate a YUV420P picture, we must convert it
|
||||||
|
* to the codec pixel format if needed */
|
||||||
|
if (!sws_ctx) {
|
||||||
|
sws_ctx = sws_getContext(c->width, c->height, AV_PIX_FMT_YUV420P,
|
||||||
|
c->width, c->height, c->pix_fmt,
|
||||||
|
sws_flags, NULL, NULL, NULL);
|
||||||
|
if (!sws_ctx) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Could not initialize the conversion context\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fill_yuv_image(&src_picture, frame_count, c->width, c->height);
|
||||||
|
sws_scale(sws_ctx,
|
||||||
|
(const uint8_t * const *)src_picture.data, src_picture.linesize,
|
||||||
|
0, c->height, dst_picture.data, dst_picture.linesize);
|
||||||
|
} else {
|
||||||
|
fill_yuv_image(&dst_picture, frame_count, c->width, c->height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0) {
|
if (oc->oformat->flags & AVFMT_RAWPICTURE) {
|
||||||
|
/* Raw video case - directly store the picture in the packet */
|
||||||
|
AVPacket pkt;
|
||||||
|
av_init_packet(&pkt);
|
||||||
|
|
||||||
|
pkt.flags |= AV_PKT_FLAG_KEY;
|
||||||
|
pkt.stream_index = st->index;
|
||||||
|
pkt.data = dst_picture.data[0];
|
||||||
|
pkt.size = sizeof(AVPicture);
|
||||||
|
|
||||||
|
ret = av_interleaved_write_frame(oc, &pkt);
|
||||||
|
} else {
|
||||||
|
AVPacket pkt = { 0 };
|
||||||
|
int got_packet;
|
||||||
|
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 size is zero, it means the image was buffered. */
|
||||||
|
|
||||||
|
if (!ret && got_packet && pkt.size) {
|
||||||
|
pkt.stream_index = st->index;
|
||||||
|
|
||||||
|
/* Write the compressed frame to the media file. */
|
||||||
|
ret = av_interleaved_write_frame(oc, &pkt);
|
||||||
|
} else {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ret != 0) {
|
||||||
fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
|
fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
frame_count++;
|
||||||
return (frame || got_packet) ? 0 : 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void close_stream(AVFormatContext *oc, OutputStream *ost)
|
static void close_video(AVFormatContext *oc, AVStream *st)
|
||||||
{
|
{
|
||||||
avcodec_free_context(&ost->enc);
|
avcodec_close(st->codec);
|
||||||
av_frame_free(&ost->frame);
|
av_free(src_picture.data[0]);
|
||||||
av_frame_free(&ost->tmp_frame);
|
av_free(dst_picture.data[0]);
|
||||||
sws_freeContext(ost->sws_ctx);
|
av_free(frame);
|
||||||
swr_free(&ost->swr_ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
@@ -556,21 +447,18 @@ 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 };
|
|
||||||
const char *filename;
|
const char *filename;
|
||||||
AVOutputFormat *fmt;
|
AVOutputFormat *fmt;
|
||||||
AVFormatContext *oc;
|
AVFormatContext *oc;
|
||||||
|
AVStream *audio_st, *video_st;
|
||||||
AVCodec *audio_codec, *video_codec;
|
AVCodec *audio_codec, *video_codec;
|
||||||
|
double audio_time, video_time;
|
||||||
int ret;
|
int ret;
|
||||||
int have_video = 0, have_audio = 0;
|
|
||||||
int encode_video = 0, encode_audio = 0;
|
|
||||||
AVDictionary *opt = NULL;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Initialize libavcodec, and register all codecs and formats. */
|
/* Initialize libavcodec, and register all codecs and formats. */
|
||||||
av_register_all();
|
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"
|
||||||
"This program generates a synthetic audio and video stream, encodes and\n"
|
"This program generates a synthetic audio and video stream, encodes and\n"
|
||||||
@@ -582,10 +470,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
filename = argv[1];
|
filename = argv[1];
|
||||||
for (i = 2; i+1 < argc; i+=2) {
|
|
||||||
if (!strcmp(argv[i], "-flags") || !strcmp(argv[i], "-fflags"))
|
|
||||||
av_dict_set(&opt, argv[i]+1, argv[i+1], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate the output media context */
|
/* allocate the output media context */
|
||||||
avformat_alloc_output_context2(&oc, NULL, NULL, filename);
|
avformat_alloc_output_context2(&oc, NULL, NULL, filename);
|
||||||
@@ -593,31 +477,29 @@ int main(int argc, char **argv)
|
|||||||
printf("Could not deduce output format from file extension: using MPEG.\n");
|
printf("Could not deduce output format from file extension: using MPEG.\n");
|
||||||
avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
|
avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
|
||||||
}
|
}
|
||||||
if (!oc)
|
if (!oc) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
fmt = oc->oformat;
|
fmt = oc->oformat;
|
||||||
|
|
||||||
/* Add the audio and video streams using the default format codecs
|
/* Add the audio and video streams using the default format codecs
|
||||||
* and initialize the codecs. */
|
* and initialize the codecs. */
|
||||||
|
video_st = NULL;
|
||||||
|
audio_st = NULL;
|
||||||
|
|
||||||
if (fmt->video_codec != AV_CODEC_ID_NONE) {
|
if (fmt->video_codec != AV_CODEC_ID_NONE) {
|
||||||
add_stream(&video_st, oc, &video_codec, fmt->video_codec);
|
video_st = add_stream(oc, &video_codec, fmt->video_codec);
|
||||||
have_video = 1;
|
|
||||||
encode_video = 1;
|
|
||||||
}
|
}
|
||||||
if (fmt->audio_codec != AV_CODEC_ID_NONE) {
|
if (fmt->audio_codec != AV_CODEC_ID_NONE) {
|
||||||
add_stream(&audio_st, oc, &audio_codec, fmt->audio_codec);
|
audio_st = add_stream(oc, &audio_codec, fmt->audio_codec);
|
||||||
have_audio = 1;
|
|
||||||
encode_audio = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now that all the parameters are set, we can open the audio and
|
/* Now that all the parameters are set, we can open the audio and
|
||||||
* video codecs and allocate the necessary encode buffers. */
|
* video codecs and allocate the necessary encode buffers. */
|
||||||
if (have_video)
|
if (video_st)
|
||||||
open_video(oc, video_codec, &video_st, opt);
|
open_video(oc, video_codec, video_st);
|
||||||
|
if (audio_st)
|
||||||
if (have_audio)
|
open_audio(oc, audio_codec, audio_st);
|
||||||
open_audio(oc, audio_codec, &audio_st, opt);
|
|
||||||
|
|
||||||
av_dump_format(oc, 0, filename, 1);
|
av_dump_format(oc, 0, filename, 1);
|
||||||
|
|
||||||
@@ -632,21 +514,30 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write the stream header, if any. */
|
/* Write the stream header, if any. */
|
||||||
ret = avformat_write_header(oc, &opt);
|
ret = avformat_write_header(oc, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Error occurred when opening output file: %s\n",
|
fprintf(stderr, "Error occurred when opening output file: %s\n",
|
||||||
av_err2str(ret));
|
av_err2str(ret));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (encode_video || encode_audio) {
|
if (frame)
|
||||||
/* select the stream to encode */
|
frame->pts = 0;
|
||||||
if (encode_video &&
|
for (;;) {
|
||||||
(!encode_audio || av_compare_ts(video_st.next_pts, video_st.enc->time_base,
|
/* Compute current audio and video time. */
|
||||||
audio_st.next_pts, audio_st.enc->time_base) <= 0)) {
|
audio_time = audio_st ? audio_st->pts.val * av_q2d(audio_st->time_base) : 0.0;
|
||||||
encode_video = !write_video_frame(oc, &video_st);
|
video_time = video_st ? video_st->pts.val * av_q2d(video_st->time_base) : 0.0;
|
||||||
|
|
||||||
|
if ((!audio_st || audio_time >= STREAM_DURATION) &&
|
||||||
|
(!video_st || video_time >= STREAM_DURATION))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* write interleaved audio and video frames */
|
||||||
|
if (!video_st || (video_st && audio_st && audio_time < video_time)) {
|
||||||
|
write_audio_frame(oc, audio_st);
|
||||||
} else {
|
} else {
|
||||||
encode_audio = !write_audio_frame(oc, &audio_st);
|
write_video_frame(oc, video_st);
|
||||||
|
frame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -657,14 +548,14 @@ int main(int argc, char **argv)
|
|||||||
av_write_trailer(oc);
|
av_write_trailer(oc);
|
||||||
|
|
||||||
/* Close each codec. */
|
/* Close each codec. */
|
||||||
if (have_video)
|
if (video_st)
|
||||||
close_stream(oc, &video_st);
|
close_video(oc, video_st);
|
||||||
if (have_audio)
|
if (audio_st)
|
||||||
close_stream(oc, &audio_st);
|
close_audio(oc, audio_st);
|
||||||
|
|
||||||
if (!(fmt->flags & AVFMT_NOFILE))
|
if (!(fmt->flags & AVFMT_NOFILE))
|
||||||
/* Close the output file. */
|
/* Close the output file. */
|
||||||
avio_closep(&oc->pb);
|
avio_close(oc->pb);
|
||||||
|
|
||||||
/* free the stream */
|
/* free the stream */
|
||||||
avformat_free_context(oc);
|
avformat_free_context(oc);
|
||||||
|
|||||||
@@ -1,487 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015 Anton Khirnov
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* Intel QSV-accelerated H.264 decoding example.
|
|
||||||
*
|
|
||||||
* @example qsvdec.c
|
|
||||||
* This example shows how to do QSV-accelerated H.264 decoding with output
|
|
||||||
* frames in the VA-API video surfaces.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.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/avio.h"
|
|
||||||
|
|
||||||
#include "libavcodec/avcodec.h"
|
|
||||||
#include "libavcodec/qsv.h"
|
|
||||||
|
|
||||||
#include "libavutil/error.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)
|
|
||||||
{
|
|
||||||
while (*pix_fmts != AV_PIX_FMT_NONE) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
pix_fmts++;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "The QSV pixel format not offered in get_format()\n");
|
|
||||||
|
|
||||||
return AV_PIX_FMT_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int decode_packet(DecodeContext *decode, AVCodecContext *decoder_ctx,
|
|
||||||
AVFrame *frame, AVPacket *pkt,
|
|
||||||
AVIOContext *output_ctx)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
int got_frame = 1;
|
|
||||||
|
|
||||||
while (pkt->size > 0 || (!pkt->data && got_frame)) {
|
|
||||||
ret = avcodec_decode_video2(decoder_ctx, frame, &got_frame, pkt);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error during decoding\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
pkt->data += ret;
|
|
||||||
pkt->size -= ret;
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
* useless but pedagogic. */
|
|
||||||
if (got_frame) {
|
|
||||||
mfxFrameSurface1 *surf = (mfxFrameSurface1*)frame->data[3];
|
|
||||||
VASurfaceID surface = *(VASurfaceID*)surf->Data.MemId;
|
|
||||||
|
|
||||||
VAImageFormat img_fmt = {
|
|
||||||
.fourcc = VA_FOURCC_NV12,
|
|
||||||
.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:
|
|
||||||
if (img.buf != VA_INVALID_ID)
|
|
||||||
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)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
AVFormatContext *input_ctx = NULL;
|
|
||||||
AVStream *video_st = NULL;
|
|
||||||
AVCodecContext *decoder_ctx = NULL;
|
|
||||||
const AVCodec *decoder;
|
|
||||||
|
|
||||||
AVPacket pkt = { 0 };
|
|
||||||
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;
|
|
||||||
|
|
||||||
int ret, i, err;
|
|
||||||
|
|
||||||
av_register_all();
|
|
||||||
|
|
||||||
if (argc < 3) {
|
|
||||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* open the input file */
|
|
||||||
ret = avformat_open_input(&input_ctx, argv[1], NULL, NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Cannot open input file '%s': ", argv[1]);
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find the first H.264 video stream */
|
|
||||||
for (i = 0; i < input_ctx->nb_streams; i++) {
|
|
||||||
AVStream *st = input_ctx->streams[i];
|
|
||||||
|
|
||||||
if (st->codecpar->codec_id == AV_CODEC_ID_H264 && !video_st)
|
|
||||||
video_st = st;
|
|
||||||
else
|
|
||||||
st->discard = AVDISCARD_ALL;
|
|
||||||
}
|
|
||||||
if (!video_st) {
|
|
||||||
fprintf(stderr, "No H.264 video stream in the input file\n");
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize VA-API */
|
|
||||||
dpy = XOpenDisplay(NULL);
|
|
||||||
if (!dpy) {
|
|
||||||
fprintf(stderr, "Cannot open the X display\n");
|
|
||||||
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 */
|
|
||||||
decoder = avcodec_find_decoder_by_name("h264_qsv");
|
|
||||||
if (!decoder) {
|
|
||||||
fprintf(stderr, "The QSV decoder is not present in libavcodec\n");
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
decoder_ctx = avcodec_alloc_context3(decoder);
|
|
||||||
if (!decoder_ctx) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
decoder_ctx->codec_id = AV_CODEC_ID_H264;
|
|
||||||
if (video_st->codecpar->extradata_size) {
|
|
||||||
decoder_ctx->extradata = av_mallocz(video_st->codecpar->extradata_size +
|
|
||||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
|
||||||
if (!decoder_ctx->extradata) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
memcpy(decoder_ctx->extradata, video_st->codecpar->extradata,
|
|
||||||
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->get_buffer2 = get_buffer;
|
|
||||||
decoder_ctx->get_format = get_format;
|
|
||||||
|
|
||||||
ret = avcodec_open2(decoder_ctx, NULL, NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error opening the decoder: ");
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* open the output stream */
|
|
||||||
ret = avio_open(&output_ctx, argv[2], AVIO_FLAG_WRITE);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error opening the output context: ");
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
frame = av_frame_alloc();
|
|
||||||
if (!frame) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* actual decoding */
|
|
||||||
while (ret >= 0) {
|
|
||||||
ret = av_read_frame(input_ctx, &pkt);
|
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (pkt.stream_index == video_st->index)
|
|
||||||
ret = decode_packet(&decode, decoder_ctx, frame, &pkt, output_ctx);
|
|
||||||
|
|
||||||
av_packet_unref(&pkt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flush the decoder */
|
|
||||||
pkt.data = NULL;
|
|
||||||
pkt.size = 0;
|
|
||||||
ret = decode_packet(&decode, decoder_ctx, frame, &pkt, output_ctx);
|
|
||||||
|
|
||||||
finish:
|
|
||||||
if (ret < 0) {
|
|
||||||
char buf[1024];
|
|
||||||
av_strerror(ret, buf, sizeof(buf));
|
|
||||||
fprintf(stderr, "%s\n", buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
avformat_close_input(&input_ctx);
|
|
||||||
|
|
||||||
av_frame_free(&frame);
|
|
||||||
|
|
||||||
if (decoder_ctx)
|
|
||||||
av_freep(&decoder_ctx->hwaccel_context);
|
|
||||||
avcodec_free_context(&decoder_ctx);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013 Stefano Sabatini
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* libavformat/libavcodec demuxing and muxing API example.
|
|
||||||
*
|
|
||||||
* Remux streams from one container format to another.
|
|
||||||
* @example remuxing.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <libavutil/timestamp.h>
|
|
||||||
#include <libavformat/avformat.h>
|
|
||||||
|
|
||||||
static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt, const char *tag)
|
|
||||||
{
|
|
||||||
AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
|
|
||||||
|
|
||||||
printf("%s: pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
|
|
||||||
tag,
|
|
||||||
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
|
|
||||||
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
|
|
||||||
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
|
|
||||||
pkt->stream_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
AVOutputFormat *ofmt = NULL;
|
|
||||||
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
|
|
||||||
AVPacket pkt;
|
|
||||||
const char *in_filename, *out_filename;
|
|
||||||
int ret, i;
|
|
||||||
|
|
||||||
if (argc < 3) {
|
|
||||||
printf("usage: %s input output\n"
|
|
||||||
"API example program to remux a media file with libavformat and libavcodec.\n"
|
|
||||||
"The output format is guessed according to the file extension.\n"
|
|
||||||
"\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
in_filename = argv[1];
|
|
||||||
out_filename = argv[2];
|
|
||||||
|
|
||||||
av_register_all();
|
|
||||||
|
|
||||||
if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
|
|
||||||
fprintf(stderr, "Could not open input file '%s'", in_filename);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
|
|
||||||
fprintf(stderr, "Failed to retrieve input stream information");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
av_dump_format(ifmt_ctx, 0, in_filename, 0);
|
|
||||||
|
|
||||||
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
|
|
||||||
if (!ofmt_ctx) {
|
|
||||||
fprintf(stderr, "Could not create output context\n");
|
|
||||||
ret = AVERROR_UNKNOWN;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
ofmt = ofmt_ctx->oformat;
|
|
||||||
|
|
||||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
|
||||||
AVStream *in_stream = ifmt_ctx->streams[i];
|
|
||||||
AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
|
|
||||||
if (!out_stream) {
|
|
||||||
fprintf(stderr, "Failed allocating output stream\n");
|
|
||||||
ret = AVERROR_UNKNOWN;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Failed to copy context from input to output stream codec context\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (!(ofmt->flags & AVFMT_NOFILE)) {
|
|
||||||
ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Could not open output file '%s'", out_filename);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = avformat_write_header(ofmt_ctx, NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error occurred when opening output file\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
AVStream *in_stream, *out_stream;
|
|
||||||
|
|
||||||
ret = av_read_frame(ifmt_ctx, &pkt);
|
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
in_stream = ifmt_ctx->streams[pkt.stream_index];
|
|
||||||
out_stream = ofmt_ctx->streams[pkt.stream_index];
|
|
||||||
|
|
||||||
log_packet(ifmt_ctx, &pkt, "in");
|
|
||||||
|
|
||||||
/* copy packet */
|
|
||||||
pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
|
|
||||||
pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
|
|
||||||
pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
|
|
||||||
pkt.pos = -1;
|
|
||||||
log_packet(ofmt_ctx, &pkt, "out");
|
|
||||||
|
|
||||||
ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error muxing packet\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
av_packet_unref(&pkt);
|
|
||||||
}
|
|
||||||
|
|
||||||
av_write_trailer(ofmt_ctx);
|
|
||||||
end:
|
|
||||||
|
|
||||||
avformat_close_input(&ifmt_ctx);
|
|
||||||
|
|
||||||
/* close output */
|
|
||||||
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
|
|
||||||
avio_closep(&ofmt_ctx->pb);
|
|
||||||
avformat_free_context(ofmt_ctx);
|
|
||||||
|
|
||||||
if (ret < 0 && ret != AVERROR_EOF) {
|
|
||||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @example resampling_audio.c
|
* @example doc/examples/resampling_audio.c
|
||||||
* libswresample API use example.
|
* libswresample API use example.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ static int get_format_from_sample_fmt(const char **fmt,
|
|||||||
/**
|
/**
|
||||||
* Fill dst buffer with nb_samples, generated starting from t.
|
* Fill dst buffer with nb_samples, generated starting from t.
|
||||||
*/
|
*/
|
||||||
static void fill_samples(double *dst, int nb_samples, int nb_channels, int sample_rate, double *t)
|
void fill_samples(double *dst, int nb_samples, int nb_channels, int sample_rate, double *t)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
double tincr = 1.0 / sample_rate, *dstp = dst;
|
double tincr = 1.0 / sample_rate, *dstp = dst;
|
||||||
@@ -168,7 +168,7 @@ int main(int argc, char **argv)
|
|||||||
dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, src_rate) +
|
dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, src_rate) +
|
||||||
src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
|
src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
|
||||||
if (dst_nb_samples > max_dst_nb_samples) {
|
if (dst_nb_samples > max_dst_nb_samples) {
|
||||||
av_freep(&dst_data[0]);
|
av_free(dst_data[0]);
|
||||||
ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels,
|
ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels,
|
||||||
dst_nb_samples, dst_sample_fmt, 1);
|
dst_nb_samples, dst_sample_fmt, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -184,10 +184,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,
|
dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,
|
||||||
ret, dst_sample_fmt, 1);
|
ret, dst_sample_fmt, 1);
|
||||||
if (dst_bufsize < 0) {
|
|
||||||
fprintf(stderr, "Could not get sample buffer size\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
printf("t:%f in:%d out:%d\n", t, src_nb_samples, ret);
|
printf("t:%f in:%d out:%d\n", t, src_nb_samples, ret);
|
||||||
fwrite(dst_data[0], 1, dst_bufsize, dst_file);
|
fwrite(dst_data[0], 1, dst_bufsize, dst_file);
|
||||||
} while (t < 10);
|
} while (t < 10);
|
||||||
@@ -199,7 +195,8 @@ int main(int argc, char **argv)
|
|||||||
fmt, dst_ch_layout, dst_nb_channels, dst_rate, dst_filename);
|
fmt, dst_ch_layout, dst_nb_channels, dst_rate, dst_filename);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
fclose(dst_file);
|
if (dst_file)
|
||||||
|
fclose(dst_file);
|
||||||
|
|
||||||
if (src_data)
|
if (src_data)
|
||||||
av_freep(&src_data[0]);
|
av_freep(&src_data[0]);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* libswscale API use example.
|
* libswscale API use example.
|
||||||
* @example scaling_video.c
|
* @example doc/examples/scaling_video.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libavutil/imgutils.h>
|
#include <libavutil/imgutils.h>
|
||||||
@@ -132,7 +132,8 @@ int main(int argc, char **argv)
|
|||||||
av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h, dst_filename);
|
av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h, dst_filename);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
fclose(dst_file);
|
if (dst_file)
|
||||||
|
fclose(dst_file);
|
||||||
av_freep(&src_data[0]);
|
av_freep(&src_data[0]);
|
||||||
av_freep(&dst_data[0]);
|
av_freep(&dst_data[0]);
|
||||||
sws_freeContext(sws_ctx);
|
sws_freeContext(sws_ctx);
|
||||||
|
|||||||
@@ -1,802 +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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* simple audio converter
|
|
||||||
*
|
|
||||||
* @example transcode_aac.c
|
|
||||||
* Convert an input audio file to AAC in an MP4 container using FFmpeg.
|
|
||||||
* @author Andreas Unterweger (dustsigns@gmail.com)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "libavformat/avformat.h"
|
|
||||||
#include "libavformat/avio.h"
|
|
||||||
|
|
||||||
#include "libavcodec/avcodec.h"
|
|
||||||
|
|
||||||
#include "libavutil/audio_fifo.h"
|
|
||||||
#include "libavutil/avassert.h"
|
|
||||||
#include "libavutil/avstring.h"
|
|
||||||
#include "libavutil/frame.h"
|
|
||||||
#include "libavutil/opt.h"
|
|
||||||
|
|
||||||
#include "libswresample/swresample.h"
|
|
||||||
|
|
||||||
/** The output bit rate in kbit/s */
|
|
||||||
#define OUTPUT_BIT_RATE 96000
|
|
||||||
/** The number of output channels */
|
|
||||||
#define OUTPUT_CHANNELS 2
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert an error code into a text message.
|
|
||||||
* @param error Error code to be converted
|
|
||||||
* @return Corresponding error text (not thread-safe)
|
|
||||||
*/
|
|
||||||
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,
|
|
||||||
AVFormatContext **input_format_context,
|
|
||||||
AVCodecContext **input_codec_context)
|
|
||||||
{
|
|
||||||
AVCodecContext *avctx;
|
|
||||||
AVCodec *input_codec;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
/** Open the input file to read from it. */
|
|
||||||
if ((error = avformat_open_input(input_format_context, filename, NULL,
|
|
||||||
NULL)) < 0) {
|
|
||||||
fprintf(stderr, "Could not open input file '%s' (error '%s')\n",
|
|
||||||
filename, get_error_text(error));
|
|
||||||
*input_format_context = NULL;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get information on the input file (number of streams etc.). */
|
|
||||||
if ((error = avformat_find_stream_info(*input_format_context, NULL)) < 0) {
|
|
||||||
fprintf(stderr, "Could not open find stream info (error '%s')\n",
|
|
||||||
get_error_text(error));
|
|
||||||
avformat_close_input(input_format_context);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Make sure that there is only one stream in the input file. */
|
|
||||||
if ((*input_format_context)->nb_streams != 1) {
|
|
||||||
fprintf(stderr, "Expected one audio input stream, but found %d\n",
|
|
||||||
(*input_format_context)->nb_streams);
|
|
||||||
avformat_close_input(input_format_context);
|
|
||||||
return AVERROR_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Find a decoder for the audio stream. */
|
|
||||||
if (!(input_codec = avcodec_find_decoder((*input_format_context)->streams[0]->codecpar->codec_id))) {
|
|
||||||
fprintf(stderr, "Could not find input codec\n");
|
|
||||||
avformat_close_input(input_format_context);
|
|
||||||
return AVERROR_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** allocate a new decoding context */
|
|
||||||
avctx = avcodec_alloc_context3(input_codec);
|
|
||||||
if (!avctx) {
|
|
||||||
fprintf(stderr, "Could not allocate a decoding context\n");
|
|
||||||
avformat_close_input(input_format_context);
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** initialize the stream parameters with demuxer information */
|
|
||||||
error = avcodec_parameters_to_context(avctx, (*input_format_context)->streams[0]->codecpar);
|
|
||||||
if (error < 0) {
|
|
||||||
avformat_close_input(input_format_context);
|
|
||||||
avcodec_free_context(&avctx);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Open the decoder for the audio stream to use it later. */
|
|
||||||
if ((error = avcodec_open2(avctx, input_codec, NULL)) < 0) {
|
|
||||||
fprintf(stderr, "Could not open input codec (error '%s')\n",
|
|
||||||
get_error_text(error));
|
|
||||||
avcodec_free_context(&avctx);
|
|
||||||
avformat_close_input(input_format_context);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Save the decoder context for easier access later. */
|
|
||||||
*input_codec_context = avctx;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open an output file and the required encoder.
|
|
||||||
* Also set some basic encoder parameters.
|
|
||||||
* Some of these parameters are based on the input file's parameters.
|
|
||||||
*/
|
|
||||||
static int open_output_file(const char *filename,
|
|
||||||
AVCodecContext *input_codec_context,
|
|
||||||
AVFormatContext **output_format_context,
|
|
||||||
AVCodecContext **output_codec_context)
|
|
||||||
{
|
|
||||||
AVCodecContext *avctx = NULL;
|
|
||||||
AVIOContext *output_io_context = NULL;
|
|
||||||
AVStream *stream = NULL;
|
|
||||||
AVCodec *output_codec = NULL;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
/** Open the output file to write to it. */
|
|
||||||
if ((error = avio_open(&output_io_context, filename,
|
|
||||||
AVIO_FLAG_WRITE)) < 0) {
|
|
||||||
fprintf(stderr, "Could not open output file '%s' (error '%s')\n",
|
|
||||||
filename, get_error_text(error));
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a new format context for the output container format. */
|
|
||||||
if (!(*output_format_context = avformat_alloc_context())) {
|
|
||||||
fprintf(stderr, "Could not allocate output format context\n");
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Associate the output file (pointer) with the container format context. */
|
|
||||||
(*output_format_context)->pb = output_io_context;
|
|
||||||
|
|
||||||
/** Guess the desired container format based on the file extension. */
|
|
||||||
if (!((*output_format_context)->oformat = av_guess_format(NULL, filename,
|
|
||||||
NULL))) {
|
|
||||||
fprintf(stderr, "Could not find output file format\n");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
av_strlcpy((*output_format_context)->filename, filename,
|
|
||||||
sizeof((*output_format_context)->filename));
|
|
||||||
|
|
||||||
/** Find the encoder to be used by its name. */
|
|
||||||
if (!(output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC))) {
|
|
||||||
fprintf(stderr, "Could not find an AAC encoder.\n");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a new audio stream in the output file container. */
|
|
||||||
if (!(stream = avformat_new_stream(*output_format_context, NULL))) {
|
|
||||||
fprintf(stderr, "Could not create new stream\n");
|
|
||||||
error = AVERROR(ENOMEM);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
avctx = avcodec_alloc_context3(output_codec);
|
|
||||||
if (!avctx) {
|
|
||||||
fprintf(stderr, "Could not allocate an encoding context\n");
|
|
||||||
error = AVERROR(ENOMEM);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the basic encoder parameters.
|
|
||||||
* The input file's sample rate is used to avoid a sample rate conversion.
|
|
||||||
*/
|
|
||||||
avctx->channels = OUTPUT_CHANNELS;
|
|
||||||
avctx->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS);
|
|
||||||
avctx->sample_rate = input_codec_context->sample_rate;
|
|
||||||
avctx->sample_fmt = output_codec->sample_fmts[0];
|
|
||||||
avctx->bit_rate = OUTPUT_BIT_RATE;
|
|
||||||
|
|
||||||
/** Allow the use of the experimental AAC encoder */
|
|
||||||
avctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
|
|
||||||
|
|
||||||
/** Set the sample rate for the container. */
|
|
||||||
stream->time_base.den = input_codec_context->sample_rate;
|
|
||||||
stream->time_base.num = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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)
|
|
||||||
avctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
|
||||||
|
|
||||||
/** Open the encoder for the audio stream to use it later. */
|
|
||||||
if ((error = avcodec_open2(avctx, output_codec, NULL)) < 0) {
|
|
||||||
fprintf(stderr, "Could not open output codec (error '%s')\n",
|
|
||||||
get_error_text(error));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = avcodec_parameters_from_context(stream->codecpar, avctx);
|
|
||||||
if (error < 0) {
|
|
||||||
fprintf(stderr, "Could not initialize stream parameters\n");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Save the encoder context for easier access later. */
|
|
||||||
*output_codec_context = avctx;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
avcodec_free_context(&avctx);
|
|
||||||
avio_closep(&(*output_format_context)->pb);
|
|
||||||
avformat_free_context(*output_format_context);
|
|
||||||
*output_format_context = NULL;
|
|
||||||
return error < 0 ? error : AVERROR_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Initialize one data packet for reading or writing. */
|
|
||||||
static void init_packet(AVPacket *packet)
|
|
||||||
{
|
|
||||||
av_init_packet(packet);
|
|
||||||
/** Set the packet data and size so that it is recognized as being empty. */
|
|
||||||
packet->data = NULL;
|
|
||||||
packet->size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Initialize one audio frame for reading from the input file */
|
|
||||||
static int init_input_frame(AVFrame **frame)
|
|
||||||
{
|
|
||||||
if (!(*frame = av_frame_alloc())) {
|
|
||||||
fprintf(stderr, "Could not allocate input frame\n");
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the audio resampler based on the input and output codec settings.
|
|
||||||
* If the input and output sample formats differ, a conversion is required
|
|
||||||
* libswresample takes care of this, but requires initialization.
|
|
||||||
*/
|
|
||||||
static int init_resampler(AVCodecContext *input_codec_context,
|
|
||||||
AVCodecContext *output_codec_context,
|
|
||||||
SwrContext **resample_context)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a resampler context for the conversion.
|
|
||||||
* Set the conversion parameters.
|
|
||||||
* Default channel layouts based on the number of channels
|
|
||||||
* are assumed for simplicity (they are sometimes not detected
|
|
||||||
* properly by the demuxer and/or decoder).
|
|
||||||
*/
|
|
||||||
*resample_context = swr_alloc_set_opts(NULL,
|
|
||||||
av_get_default_channel_layout(output_codec_context->channels),
|
|
||||||
output_codec_context->sample_fmt,
|
|
||||||
output_codec_context->sample_rate,
|
|
||||||
av_get_default_channel_layout(input_codec_context->channels),
|
|
||||||
input_codec_context->sample_fmt,
|
|
||||||
input_codec_context->sample_rate,
|
|
||||||
0, NULL);
|
|
||||||
if (!*resample_context) {
|
|
||||||
fprintf(stderr, "Could not allocate resample context\n");
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Perform a sanity check so that the number of converted samples is
|
|
||||||
* not greater than the number of samples to be converted.
|
|
||||||
* If the sample rates differ, this case has to be handled differently
|
|
||||||
*/
|
|
||||||
av_assert0(output_codec_context->sample_rate == input_codec_context->sample_rate);
|
|
||||||
|
|
||||||
/** Open the resampler with the specified parameters. */
|
|
||||||
if ((error = swr_init(*resample_context)) < 0) {
|
|
||||||
fprintf(stderr, "Could not open resample context\n");
|
|
||||||
swr_free(resample_context);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Initialize a FIFO buffer for the audio samples to be encoded. */
|
|
||||||
static int init_fifo(AVAudioFifo **fifo, AVCodecContext *output_codec_context)
|
|
||||||
{
|
|
||||||
/** Create the FIFO buffer based on the specified output sample format. */
|
|
||||||
if (!(*fifo = av_audio_fifo_alloc(output_codec_context->sample_fmt,
|
|
||||||
output_codec_context->channels, 1))) {
|
|
||||||
fprintf(stderr, "Could not allocate FIFO\n");
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Write the header of the output file container. */
|
|
||||||
static int write_output_file_header(AVFormatContext *output_format_context)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
if ((error = avformat_write_header(output_format_context, NULL)) < 0) {
|
|
||||||
fprintf(stderr, "Could not write output file header (error '%s')\n",
|
|
||||||
get_error_text(error));
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Decode one audio frame from the input file. */
|
|
||||||
static int decode_audio_frame(AVFrame *frame,
|
|
||||||
AVFormatContext *input_format_context,
|
|
||||||
AVCodecContext *input_codec_context,
|
|
||||||
int *data_present, int *finished)
|
|
||||||
{
|
|
||||||
/** Packet used for temporary storage. */
|
|
||||||
AVPacket input_packet;
|
|
||||||
int error;
|
|
||||||
init_packet(&input_packet);
|
|
||||||
|
|
||||||
/** 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)
|
|
||||||
*finished = 1;
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "Could not read frame (error '%s')\n",
|
|
||||||
get_error_text(error));
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decode the audio frame stored in the temporary packet.
|
|
||||||
* The input audio stream decoder is used to do this.
|
|
||||||
* If we are at the end of the file, pass an empty packet to the decoder
|
|
||||||
* to flush it.
|
|
||||||
*/
|
|
||||||
if ((error = avcodec_decode_audio4(input_codec_context, frame,
|
|
||||||
data_present, &input_packet)) < 0) {
|
|
||||||
fprintf(stderr, "Could not decode frame (error '%s')\n",
|
|
||||||
get_error_text(error));
|
|
||||||
av_packet_unref(&input_packet);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the decoder has not been flushed completely, we are not finished,
|
|
||||||
* 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.
|
|
||||||
* The conversion requires temporary storage due to the different format.
|
|
||||||
* The number of audio samples to be allocated is specified in frame_size.
|
|
||||||
*/
|
|
||||||
static int init_converted_samples(uint8_t ***converted_input_samples,
|
|
||||||
AVCodecContext *output_codec_context,
|
|
||||||
int frame_size)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate as many pointers as there are audio channels.
|
|
||||||
* Each pointer will later point to the audio samples of the corresponding
|
|
||||||
* channels (although it may be NULL for interleaved formats).
|
|
||||||
*/
|
|
||||||
if (!(*converted_input_samples = calloc(output_codec_context->channels,
|
|
||||||
sizeof(**converted_input_samples)))) {
|
|
||||||
fprintf(stderr, "Could not allocate converted input sample pointers\n");
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate memory for the samples of all channels in one consecutive
|
|
||||||
* block for convenience.
|
|
||||||
*/
|
|
||||||
if ((error = av_samples_alloc(*converted_input_samples, NULL,
|
|
||||||
output_codec_context->channels,
|
|
||||||
frame_size,
|
|
||||||
output_codec_context->sample_fmt, 0)) < 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Could not allocate converted input samples (error '%s')\n",
|
|
||||||
get_error_text(error));
|
|
||||||
av_freep(&(*converted_input_samples)[0]);
|
|
||||||
free(*converted_input_samples);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert the input audio samples into the output sample format.
|
|
||||||
* The conversion happens on a per-frame basis, the size of which is specified
|
|
||||||
* by frame_size.
|
|
||||||
*/
|
|
||||||
static int convert_samples(const uint8_t **input_data,
|
|
||||||
uint8_t **converted_data, const int frame_size,
|
|
||||||
SwrContext *resample_context)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
|
|
||||||
/** Convert the samples using the resampler. */
|
|
||||||
if ((error = swr_convert(resample_context,
|
|
||||||
converted_data, frame_size,
|
|
||||||
input_data , frame_size)) < 0) {
|
|
||||||
fprintf(stderr, "Could not convert input samples (error '%s')\n",
|
|
||||||
get_error_text(error));
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Add converted input audio samples to the FIFO buffer for later processing. */
|
|
||||||
static int add_samples_to_fifo(AVAudioFifo *fifo,
|
|
||||||
uint8_t **converted_input_samples,
|
|
||||||
const int frame_size)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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) {
|
|
||||||
fprintf(stderr, "Could not reallocate FIFO\n");
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Store the new samples in the FIFO buffer. */
|
|
||||||
if (av_audio_fifo_write(fifo, (void **)converted_input_samples,
|
|
||||||
frame_size) < frame_size) {
|
|
||||||
fprintf(stderr, "Could not write data to FIFO\n");
|
|
||||||
return AVERROR_EXIT;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read one audio frame from the input file, decodes, converts and stores
|
|
||||||
* it in the FIFO buffer.
|
|
||||||
*/
|
|
||||||
static int read_decode_convert_and_store(AVAudioFifo *fifo,
|
|
||||||
AVFormatContext *input_format_context,
|
|
||||||
AVCodecContext *input_codec_context,
|
|
||||||
AVCodecContext *output_codec_context,
|
|
||||||
SwrContext *resampler_context,
|
|
||||||
int *finished)
|
|
||||||
{
|
|
||||||
/** Temporary storage of the input samples of the frame read from the file. */
|
|
||||||
AVFrame *input_frame = NULL;
|
|
||||||
/** Temporary storage for the converted input samples. */
|
|
||||||
uint8_t **converted_input_samples = NULL;
|
|
||||||
int data_present;
|
|
||||||
int ret = AVERROR_EXIT;
|
|
||||||
|
|
||||||
/** Initialize temporary storage for one input frame. */
|
|
||||||
if (init_input_frame(&input_frame))
|
|
||||||
goto cleanup;
|
|
||||||
/** Decode one frame worth of audio samples. */
|
|
||||||
if (decode_audio_frame(input_frame, input_format_context,
|
|
||||||
input_codec_context, &data_present, finished))
|
|
||||||
goto cleanup;
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
* This must not be treated as an error.
|
|
||||||
*/
|
|
||||||
if (*finished && !data_present) {
|
|
||||||
ret = 0;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
/** If there is decoded data, convert and store it */
|
|
||||||
if (data_present) {
|
|
||||||
/** Initialize the temporary storage for the converted input samples. */
|
|
||||||
if (init_converted_samples(&converted_input_samples, output_codec_context,
|
|
||||||
input_frame->nb_samples))
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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,
|
|
||||||
input_frame->nb_samples, resampler_context))
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
/** Add the converted input samples to the FIFO buffer for later processing. */
|
|
||||||
if (add_samples_to_fifo(fifo, converted_input_samples,
|
|
||||||
input_frame->nb_samples))
|
|
||||||
goto cleanup;
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (converted_input_samples) {
|
|
||||||
av_freep(&converted_input_samples[0]);
|
|
||||||
free(converted_input_samples);
|
|
||||||
}
|
|
||||||
av_frame_free(&input_frame);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize one input frame for writing to the output file.
|
|
||||||
* The frame will be exactly frame_size samples large.
|
|
||||||
*/
|
|
||||||
static int init_output_frame(AVFrame **frame,
|
|
||||||
AVCodecContext *output_codec_context,
|
|
||||||
int frame_size)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
|
|
||||||
/** Create a new frame to store the audio samples. */
|
|
||||||
if (!(*frame = av_frame_alloc())) {
|
|
||||||
fprintf(stderr, "Could not allocate output frame\n");
|
|
||||||
return AVERROR_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the frame's parameters, especially its size and format.
|
|
||||||
* av_frame_get_buffer needs this to allocate memory for the
|
|
||||||
* audio samples of the frame.
|
|
||||||
* Default channel layouts based on the number of channels
|
|
||||||
* are assumed for simplicity.
|
|
||||||
*/
|
|
||||||
(*frame)->nb_samples = frame_size;
|
|
||||||
(*frame)->channel_layout = output_codec_context->channel_layout;
|
|
||||||
(*frame)->format = output_codec_context->sample_fmt;
|
|
||||||
(*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.
|
|
||||||
*/
|
|
||||||
if ((error = av_frame_get_buffer(*frame, 0)) < 0) {
|
|
||||||
fprintf(stderr, "Could allocate output frame samples (error '%s')\n",
|
|
||||||
get_error_text(error));
|
|
||||||
av_frame_free(frame);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Global timestamp for the audio frames */
|
|
||||||
static int64_t pts = 0;
|
|
||||||
|
|
||||||
/** Encode one frame worth of audio to the output file. */
|
|
||||||
static int encode_audio_frame(AVFrame *frame,
|
|
||||||
AVFormatContext *output_format_context,
|
|
||||||
AVCodecContext *output_codec_context,
|
|
||||||
int *data_present)
|
|
||||||
{
|
|
||||||
/** Packet used for temporary storage. */
|
|
||||||
AVPacket output_packet;
|
|
||||||
int error;
|
|
||||||
init_packet(&output_packet);
|
|
||||||
|
|
||||||
/** Set a timestamp based on the sample rate for the container. */
|
|
||||||
if (frame) {
|
|
||||||
frame->pts = pts;
|
|
||||||
pts += frame->nb_samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encode the audio frame and store it in the temporary packet.
|
|
||||||
* The output audio stream encoder is used to do this.
|
|
||||||
*/
|
|
||||||
if ((error = avcodec_encode_audio2(output_codec_context, &output_packet,
|
|
||||||
frame, data_present)) < 0) {
|
|
||||||
fprintf(stderr, "Could not encode frame (error '%s')\n",
|
|
||||||
get_error_text(error));
|
|
||||||
av_packet_unref(&output_packet);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Write one audio frame from the temporary packet to the output file. */
|
|
||||||
if (*data_present) {
|
|
||||||
if ((error = av_write_frame(output_format_context, &output_packet)) < 0) {
|
|
||||||
fprintf(stderr, "Could not write frame (error '%s')\n",
|
|
||||||
get_error_text(error));
|
|
||||||
av_packet_unref(&output_packet);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
av_packet_unref(&output_packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load one audio frame from the FIFO buffer, encode and write it to the
|
|
||||||
* output file.
|
|
||||||
*/
|
|
||||||
static int load_encode_and_write(AVAudioFifo *fifo,
|
|
||||||
AVFormatContext *output_format_context,
|
|
||||||
AVCodecContext *output_codec_context)
|
|
||||||
{
|
|
||||||
/** Temporary storage of the output samples of the frame written to the file. */
|
|
||||||
AVFrame *output_frame;
|
|
||||||
/**
|
|
||||||
* Use the maximum number of possible samples per frame.
|
|
||||||
* If there is less than the maximum possible frame size in the FIFO
|
|
||||||
* buffer use this number. Otherwise, use the maximum possible frame size
|
|
||||||
*/
|
|
||||||
const int frame_size = FFMIN(av_audio_fifo_size(fifo),
|
|
||||||
output_codec_context->frame_size);
|
|
||||||
int data_written;
|
|
||||||
|
|
||||||
/** Initialize temporary storage for one output frame. */
|
|
||||||
if (init_output_frame(&output_frame, output_codec_context, frame_size))
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
if (av_audio_fifo_read(fifo, (void **)output_frame->data, frame_size) < frame_size) {
|
|
||||||
fprintf(stderr, "Could not read data from FIFO\n");
|
|
||||||
av_frame_free(&output_frame);
|
|
||||||
return AVERROR_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Encode one frame worth of audio samples. */
|
|
||||||
if (encode_audio_frame(output_frame, output_format_context,
|
|
||||||
output_codec_context, &data_written)) {
|
|
||||||
av_frame_free(&output_frame);
|
|
||||||
return AVERROR_EXIT;
|
|
||||||
}
|
|
||||||
av_frame_free(&output_frame);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Write the trailer of the output file container. */
|
|
||||||
static int write_output_file_trailer(AVFormatContext *output_format_context)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
if ((error = av_write_trailer(output_format_context)) < 0) {
|
|
||||||
fprintf(stderr, "Could not write output file trailer (error '%s')\n",
|
|
||||||
get_error_text(error));
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Convert an audio file to an AAC file in an MP4 container. */
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
AVFormatContext *input_format_context = NULL, *output_format_context = NULL;
|
|
||||||
AVCodecContext *input_codec_context = NULL, *output_codec_context = NULL;
|
|
||||||
SwrContext *resample_context = NULL;
|
|
||||||
AVAudioFifo *fifo = NULL;
|
|
||||||
int ret = AVERROR_EXIT;
|
|
||||||
|
|
||||||
if (argc < 3) {
|
|
||||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 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,
|
|
||||||
&input_codec_context))
|
|
||||||
goto cleanup;
|
|
||||||
/** Open the output file for writing. */
|
|
||||||
if (open_output_file(argv[2], input_codec_context,
|
|
||||||
&output_format_context, &output_codec_context))
|
|
||||||
goto cleanup;
|
|
||||||
/** Initialize the resampler to be able to convert audio sample formats. */
|
|
||||||
if (init_resampler(input_codec_context, output_codec_context,
|
|
||||||
&resample_context))
|
|
||||||
goto cleanup;
|
|
||||||
/** Initialize the FIFO buffer to store audio samples to be encoded. */
|
|
||||||
if (init_fifo(&fifo, output_codec_context))
|
|
||||||
goto cleanup;
|
|
||||||
/** Write the header of the output file container. */
|
|
||||||
if (write_output_file_header(output_format_context))
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loop as long as we have input samples to read or output samples
|
|
||||||
* to write; abort as soon as we have neither.
|
|
||||||
*/
|
|
||||||
while (1) {
|
|
||||||
/** Use the encoder's desired frame size for processing. */
|
|
||||||
const int output_frame_size = output_codec_context->frame_size;
|
|
||||||
int finished = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make sure that there is one frame worth of samples in the FIFO
|
|
||||||
* buffer so that the encoder can do its work.
|
|
||||||
* 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
|
|
||||||
* that they make up at least one frame worth of output samples.
|
|
||||||
*/
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
if (read_decode_convert_and_store(fifo, input_format_context,
|
|
||||||
input_codec_context,
|
|
||||||
output_codec_context,
|
|
||||||
resample_context, &finished))
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If we are at the end of the input file, we continue
|
|
||||||
* encoding the remaining audio samples to the output file.
|
|
||||||
*/
|
|
||||||
if (finished)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If we have enough samples for the encoder, we encode them.
|
|
||||||
* At the end of the file, we pass the remaining samples to
|
|
||||||
* the encoder.
|
|
||||||
*/
|
|
||||||
while (av_audio_fifo_size(fifo) >= output_frame_size ||
|
|
||||||
(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.
|
|
||||||
*/
|
|
||||||
if (load_encode_and_write(fifo, output_format_context,
|
|
||||||
output_codec_context))
|
|
||||||
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 (finished) {
|
|
||||||
int data_written;
|
|
||||||
/** Flush the encoder as it may have delayed frames. */
|
|
||||||
do {
|
|
||||||
if (encode_audio_frame(NULL, output_format_context,
|
|
||||||
output_codec_context, &data_written))
|
|
||||||
goto cleanup;
|
|
||||||
} while (data_written);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Write the trailer of the output file container. */
|
|
||||||
if (write_output_file_trailer(output_format_context))
|
|
||||||
goto cleanup;
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (fifo)
|
|
||||||
av_audio_fifo_free(fifo);
|
|
||||||
swr_free(&resample_context);
|
|
||||||
if (output_codec_context)
|
|
||||||
avcodec_free_context(&output_codec_context);
|
|
||||||
if (output_format_context) {
|
|
||||||
avio_closep(&output_format_context->pb);
|
|
||||||
avformat_free_context(output_format_context);
|
|
||||||
}
|
|
||||||
if (input_codec_context)
|
|
||||||
avcodec_free_context(&input_codec_context);
|
|
||||||
if (input_format_context)
|
|
||||||
avformat_close_input(&input_format_context);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1,585 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2010 Nicolas George
|
|
||||||
* Copyright (c) 2011 Stefano Sabatini
|
|
||||||
* Copyright (c) 2014 Andrey Utkin
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* API example for demuxing, decoding, filtering, encoding and muxing
|
|
||||||
* @example transcoding.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
|
||||||
#include <libavformat/avformat.h>
|
|
||||||
#include <libavfilter/avfiltergraph.h>
|
|
||||||
#include <libavfilter/buffersink.h>
|
|
||||||
#include <libavfilter/buffersrc.h>
|
|
||||||
#include <libavutil/opt.h>
|
|
||||||
#include <libavutil/pixdesc.h>
|
|
||||||
|
|
||||||
static AVFormatContext *ifmt_ctx;
|
|
||||||
static AVFormatContext *ofmt_ctx;
|
|
||||||
typedef struct FilteringContext {
|
|
||||||
AVFilterContext *buffersink_ctx;
|
|
||||||
AVFilterContext *buffersrc_ctx;
|
|
||||||
AVFilterGraph *filter_graph;
|
|
||||||
} FilteringContext;
|
|
||||||
static FilteringContext *filter_ctx;
|
|
||||||
|
|
||||||
static int open_input_file(const char *filename)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
ifmt_ctx = NULL;
|
|
||||||
if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
|
||||||
AVStream *stream;
|
|
||||||
AVCodecContext *codec_ctx;
|
|
||||||
stream = ifmt_ctx->streams[i];
|
|
||||||
codec_ctx = stream->codec;
|
|
||||||
/* Reencode video & audio and remux subtitles etc. */
|
|
||||||
if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
|
|
||||||
|| codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
|
||||||
/* Open decoder */
|
|
||||||
ret = avcodec_open2(codec_ctx,
|
|
||||||
avcodec_find_decoder(codec_ctx->codec_id), NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
av_dump_format(ifmt_ctx, 0, filename, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int open_output_file(const char *filename)
|
|
||||||
{
|
|
||||||
AVStream *out_stream;
|
|
||||||
AVStream *in_stream;
|
|
||||||
AVCodecContext *dec_ctx, *enc_ctx;
|
|
||||||
AVCodec *encoder;
|
|
||||||
int ret;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
ofmt_ctx = NULL;
|
|
||||||
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, filename);
|
|
||||||
if (!ofmt_ctx) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Could not create output context\n");
|
|
||||||
return AVERROR_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
|
||||||
out_stream = avformat_new_stream(ofmt_ctx, NULL);
|
|
||||||
if (!out_stream) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Failed allocating output stream\n");
|
|
||||||
return AVERROR_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
in_stream = ifmt_ctx->streams[i];
|
|
||||||
dec_ctx = in_stream->codec;
|
|
||||||
enc_ctx = out_stream->codec;
|
|
||||||
|
|
||||||
if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
|
|
||||||
|| dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
|
||||||
/* in this example, we choose transcoding to same codec */
|
|
||||||
encoder = avcodec_find_encoder(dec_ctx->codec_id);
|
|
||||||
if (!encoder) {
|
|
||||||
av_log(NULL, AV_LOG_FATAL, "Necessary encoder not found\n");
|
|
||||||
return AVERROR_INVALIDDATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In this example, we transcode to same properties (picture size,
|
|
||||||
* sample rate etc.). These properties can be changed for output
|
|
||||||
* streams easily using filters */
|
|
||||||
if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
|
|
||||||
enc_ctx->height = dec_ctx->height;
|
|
||||||
enc_ctx->width = dec_ctx->width;
|
|
||||||
enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;
|
|
||||||
/* take first format from list of supported formats */
|
|
||||||
if (encoder->pix_fmts)
|
|
||||||
enc_ctx->pix_fmt = encoder->pix_fmts[0];
|
|
||||||
else
|
|
||||||
enc_ctx->pix_fmt = dec_ctx->pix_fmt;
|
|
||||||
/* video time_base can be set to whatever is handy and supported by encoder */
|
|
||||||
enc_ctx->time_base = dec_ctx->time_base;
|
|
||||||
} else {
|
|
||||||
enc_ctx->sample_rate = dec_ctx->sample_rate;
|
|
||||||
enc_ctx->channel_layout = dec_ctx->channel_layout;
|
|
||||||
enc_ctx->channels = av_get_channel_layout_nb_channels(enc_ctx->channel_layout);
|
|
||||||
/* take first format from list of supported formats */
|
|
||||||
enc_ctx->sample_fmt = encoder->sample_fmts[0];
|
|
||||||
enc_ctx->time_base = (AVRational){1, enc_ctx->sample_rate};
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Third parameter can be used to pass settings to encoder */
|
|
||||||
ret = avcodec_open2(enc_ctx, encoder, NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
} 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);
|
|
||||||
return AVERROR_INVALIDDATA;
|
|
||||||
} else {
|
|
||||||
/* if this stream must be remuxed */
|
|
||||||
ret = avcodec_copy_context(ofmt_ctx->streams[i]->codec,
|
|
||||||
ifmt_ctx->streams[i]->codec);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Copying stream context failed\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
|
||||||
enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
|
||||||
|
|
||||||
}
|
|
||||||
av_dump_format(ofmt_ctx, 0, filename, 1);
|
|
||||||
|
|
||||||
if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) {
|
|
||||||
ret = avio_open(&ofmt_ctx->pb, filename, AVIO_FLAG_WRITE);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Could not open output file '%s'", filename);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* init muxer, write output file header */
|
|
||||||
ret = avformat_write_header(ofmt_ctx, NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Error occurred when opening output file\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx,
|
|
||||||
AVCodecContext *enc_ctx, const char *filter_spec)
|
|
||||||
{
|
|
||||||
char args[512];
|
|
||||||
int ret = 0;
|
|
||||||
AVFilter *buffersrc = NULL;
|
|
||||||
AVFilter *buffersink = NULL;
|
|
||||||
AVFilterContext *buffersrc_ctx = NULL;
|
|
||||||
AVFilterContext *buffersink_ctx = NULL;
|
|
||||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
|
||||||
AVFilterInOut *inputs = avfilter_inout_alloc();
|
|
||||||
AVFilterGraph *filter_graph = avfilter_graph_alloc();
|
|
||||||
|
|
||||||
if (!outputs || !inputs || !filter_graph) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
|
|
||||||
buffersrc = avfilter_get_by_name("buffer");
|
|
||||||
buffersink = avfilter_get_by_name("buffersink");
|
|
||||||
if (!buffersrc || !buffersink) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n");
|
|
||||||
ret = AVERROR_UNKNOWN;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(args, sizeof(args),
|
|
||||||
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
|
|
||||||
dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
|
|
||||||
dec_ctx->time_base.num, dec_ctx->time_base.den,
|
|
||||||
dec_ctx->sample_aspect_ratio.num,
|
|
||||||
dec_ctx->sample_aspect_ratio.den);
|
|
||||||
|
|
||||||
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
|
|
||||||
args, NULL, filter_graph);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
|
|
||||||
NULL, NULL, filter_graph);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = av_opt_set_bin(buffersink_ctx, "pix_fmts",
|
|
||||||
(uint8_t*)&enc_ctx->pix_fmt, sizeof(enc_ctx->pix_fmt),
|
|
||||||
AV_OPT_SEARCH_CHILDREN);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
} else if (dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
|
||||||
buffersrc = avfilter_get_by_name("abuffer");
|
|
||||||
buffersink = avfilter_get_by_name("abuffersink");
|
|
||||||
if (!buffersrc || !buffersink) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n");
|
|
||||||
ret = AVERROR_UNKNOWN;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dec_ctx->channel_layout)
|
|
||||||
dec_ctx->channel_layout =
|
|
||||||
av_get_default_channel_layout(dec_ctx->channels);
|
|
||||||
snprintf(args, sizeof(args),
|
|
||||||
"time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
|
|
||||||
dec_ctx->time_base.num, dec_ctx->time_base.den, dec_ctx->sample_rate,
|
|
||||||
av_get_sample_fmt_name(dec_ctx->sample_fmt),
|
|
||||||
dec_ctx->channel_layout);
|
|
||||||
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
|
|
||||||
args, NULL, filter_graph);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
|
|
||||||
NULL, NULL, filter_graph);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = av_opt_set_bin(buffersink_ctx, "sample_fmts",
|
|
||||||
(uint8_t*)&enc_ctx->sample_fmt, sizeof(enc_ctx->sample_fmt),
|
|
||||||
AV_OPT_SEARCH_CHILDREN);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = av_opt_set_bin(buffersink_ctx, "channel_layouts",
|
|
||||||
(uint8_t*)&enc_ctx->channel_layout,
|
|
||||||
sizeof(enc_ctx->channel_layout), AV_OPT_SEARCH_CHILDREN);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = av_opt_set_bin(buffersink_ctx, "sample_rates",
|
|
||||||
(uint8_t*)&enc_ctx->sample_rate, sizeof(enc_ctx->sample_rate),
|
|
||||||
AV_OPT_SEARCH_CHILDREN);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ret = AVERROR_UNKNOWN;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Endpoints for the filter graph. */
|
|
||||||
outputs->name = av_strdup("in");
|
|
||||||
outputs->filter_ctx = buffersrc_ctx;
|
|
||||||
outputs->pad_idx = 0;
|
|
||||||
outputs->next = NULL;
|
|
||||||
|
|
||||||
inputs->name = av_strdup("out");
|
|
||||||
inputs->filter_ctx = buffersink_ctx;
|
|
||||||
inputs->pad_idx = 0;
|
|
||||||
inputs->next = NULL;
|
|
||||||
|
|
||||||
if (!outputs->name || !inputs->name) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_spec,
|
|
||||||
&inputs, &outputs, NULL)) < 0)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
/* Fill FilteringContext */
|
|
||||||
fctx->buffersrc_ctx = buffersrc_ctx;
|
|
||||||
fctx->buffersink_ctx = buffersink_ctx;
|
|
||||||
fctx->filter_graph = filter_graph;
|
|
||||||
|
|
||||||
end:
|
|
||||||
avfilter_inout_free(&inputs);
|
|
||||||
avfilter_inout_free(&outputs);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int init_filters(void)
|
|
||||||
{
|
|
||||||
const char *filter_spec;
|
|
||||||
unsigned int i;
|
|
||||||
int ret;
|
|
||||||
filter_ctx = av_malloc_array(ifmt_ctx->nb_streams, sizeof(*filter_ctx));
|
|
||||||
if (!filter_ctx)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
|
|
||||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
|
||||||
filter_ctx[i].buffersrc_ctx = NULL;
|
|
||||||
filter_ctx[i].buffersink_ctx = NULL;
|
|
||||||
filter_ctx[i].filter_graph = NULL;
|
|
||||||
if (!(ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO
|
|
||||||
|| ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
|
||||||
if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
|
||||||
filter_spec = "null"; /* passthrough (dummy) filter for video */
|
|
||||||
else
|
|
||||||
filter_spec = "anull"; /* passthrough (dummy) filter for audio */
|
|
||||||
ret = init_filter(&filter_ctx[i], ifmt_ctx->streams[i]->codec,
|
|
||||||
ofmt_ctx->streams[i]->codec, filter_spec);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame) {
|
|
||||||
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");
|
|
||||||
/* encode filtered frame */
|
|
||||||
enc_pkt.data = NULL;
|
|
||||||
enc_pkt.size = 0;
|
|
||||||
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)
|
|
||||||
return ret;
|
|
||||||
if (!(*got_frame))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* prepare packet for muxing */
|
|
||||||
enc_pkt.stream_index = stream_index;
|
|
||||||
av_packet_rescale_ts(&enc_pkt,
|
|
||||||
ofmt_ctx->streams[stream_index]->codec->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);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
AVFrame *filt_frame;
|
|
||||||
|
|
||||||
av_log(NULL, AV_LOG_INFO, "Pushing decoded frame to filters\n");
|
|
||||||
/* push the decoded frame into the filtergraph */
|
|
||||||
ret = av_buffersrc_add_frame_flags(filter_ctx[stream_index].buffersrc_ctx,
|
|
||||||
frame, 0);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pull filtered frames from the filtergraph */
|
|
||||||
while (1) {
|
|
||||||
filt_frame = av_frame_alloc();
|
|
||||||
if (!filt_frame) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
av_log(NULL, AV_LOG_INFO, "Pulling filtered frame from filters\n");
|
|
||||||
ret = av_buffersink_get_frame(filter_ctx[stream_index].buffersink_ctx,
|
|
||||||
filt_frame);
|
|
||||||
if (ret < 0) {
|
|
||||||
/* if no more frames for output - returns AVERROR(EAGAIN)
|
|
||||||
* if flushed and no more frames for output - returns AVERROR_EOF
|
|
||||||
* rewrite retcode to 0 to show it as normal procedure completion
|
|
||||||
*/
|
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
|
||||||
ret = 0;
|
|
||||||
av_frame_free(&filt_frame);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
filt_frame->pict_type = AV_PICTURE_TYPE_NONE;
|
|
||||||
ret = encode_write_frame(filt_frame, stream_index, NULL);
|
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int flush_encoder(unsigned int stream_index)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int got_frame;
|
|
||||||
|
|
||||||
if (!(ofmt_ctx->streams[stream_index]->codec->codec->capabilities &
|
|
||||||
AV_CODEC_CAP_DELAY))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index);
|
|
||||||
ret = encode_write_frame(NULL, stream_index, &got_frame);
|
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
if (!got_frame)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
AVPacket packet = { .data = NULL, .size = 0 };
|
|
||||||
AVFrame *frame = NULL;
|
|
||||||
enum AVMediaType type;
|
|
||||||
unsigned int stream_index;
|
|
||||||
unsigned int i;
|
|
||||||
int got_frame;
|
|
||||||
int (*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket *);
|
|
||||||
|
|
||||||
if (argc != 3) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Usage: %s <input file> <output file>\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
av_register_all();
|
|
||||||
avfilter_register_all();
|
|
||||||
|
|
||||||
if ((ret = open_input_file(argv[1])) < 0)
|
|
||||||
goto end;
|
|
||||||
if ((ret = open_output_file(argv[2])) < 0)
|
|
||||||
goto end;
|
|
||||||
if ((ret = init_filters()) < 0)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
/* read all packets */
|
|
||||||
while (1) {
|
|
||||||
if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0)
|
|
||||||
break;
|
|
||||||
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",
|
|
||||||
stream_index);
|
|
||||||
|
|
||||||
if (filter_ctx[stream_index].filter_graph) {
|
|
||||||
av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the frame\n");
|
|
||||||
frame = av_frame_alloc();
|
|
||||||
if (!frame) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
av_packet_rescale_ts(&packet,
|
|
||||||
ifmt_ctx->streams[stream_index]->time_base,
|
|
||||||
ifmt_ctx->streams[stream_index]->codec->time_base);
|
|
||||||
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) {
|
|
||||||
av_frame_free(&frame);
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Decoding failed\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (got_frame) {
|
|
||||||
frame->pts = av_frame_get_best_effort_timestamp(frame);
|
|
||||||
ret = filter_encode_write_frame(frame, stream_index);
|
|
||||||
av_frame_free(&frame);
|
|
||||||
if (ret < 0)
|
|
||||||
goto end;
|
|
||||||
} else {
|
|
||||||
av_frame_free(&frame);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* remux this frame without reencoding */
|
|
||||||
av_packet_rescale_ts(&packet,
|
|
||||||
ifmt_ctx->streams[stream_index]->time_base,
|
|
||||||
ofmt_ctx->streams[stream_index]->time_base);
|
|
||||||
|
|
||||||
ret = av_interleaved_write_frame(ofmt_ctx, &packet);
|
|
||||||
if (ret < 0)
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
av_packet_unref(&packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flush filters and encoders */
|
|
||||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
|
||||||
/* flush filter */
|
|
||||||
if (!filter_ctx[i].filter_graph)
|
|
||||||
continue;
|
|
||||||
ret = filter_encode_write_frame(NULL, i);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Flushing filter failed\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flush encoder */
|
|
||||||
ret = flush_encoder(i);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Flushing encoder failed\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
av_write_trailer(ofmt_ctx);
|
|
||||||
end:
|
|
||||||
av_packet_unref(&packet);
|
|
||||||
av_frame_free(&frame);
|
|
||||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
|
||||||
avcodec_close(ifmt_ctx->streams[i]->codec);
|
|
||||||
if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && ofmt_ctx->streams[i]->codec)
|
|
||||||
avcodec_close(ofmt_ctx->streams[i]->codec);
|
|
||||||
if (filter_ctx && filter_ctx[i].filter_graph)
|
|
||||||
avfilter_graph_free(&filter_ctx[i].filter_graph);
|
|
||||||
}
|
|
||||||
av_free(filter_ctx);
|
|
||||||
avformat_close_input(&ifmt_ctx);
|
|
||||||
if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
|
|
||||||
avio_closep(&ofmt_ctx->pb);
|
|
||||||
avformat_free_context(ofmt_ctx);
|
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", av_err2str(ret));
|
|
||||||
|
|
||||||
return ret ? 1 : 0;
|
|
||||||
}
|
|
||||||
125
doc/faq.texi
125
doc/faq.texi
@@ -1,5 +1,4 @@
|
|||||||
\input texinfo @c -*- texinfo -*-
|
\input texinfo @c -*- texinfo -*-
|
||||||
@documentencoding UTF-8
|
|
||||||
|
|
||||||
@settitle FFmpeg FAQ
|
@settitle FFmpeg FAQ
|
||||||
@titlepage
|
@titlepage
|
||||||
@@ -91,63 +90,13 @@ To build FFmpeg, you need to install the development package. It is usually
|
|||||||
called @file{libfoo-dev} or @file{libfoo-devel}. You can remove it after the
|
called @file{libfoo-dev} or @file{libfoo-devel}. You can remove it after the
|
||||||
build is finished, but be sure to keep the main package.
|
build is finished, but be sure to keep the main package.
|
||||||
|
|
||||||
@section How do I make @command{pkg-config} find my libraries?
|
|
||||||
|
|
||||||
Somewhere along with your libraries, there is a @file{.pc} file (or several)
|
|
||||||
in a @file{pkgconfig} directory. You need to set environment variables to
|
|
||||||
point @command{pkg-config} to these files.
|
|
||||||
|
|
||||||
If you need to @emph{add} directories to @command{pkg-config}'s search list
|
|
||||||
(typical use case: library installed separately), add it to
|
|
||||||
@code{$PKG_CONFIG_PATH}:
|
|
||||||
|
|
||||||
@example
|
|
||||||
export PKG_CONFIG_PATH=/opt/x264/lib/pkgconfig:/opt/opus/lib/pkgconfig
|
|
||||||
@end example
|
|
||||||
|
|
||||||
If you need to @emph{replace} @command{pkg-config}'s search list
|
|
||||||
(typical use case: cross-compiling), set it in
|
|
||||||
@code{$PKG_CONFIG_LIBDIR}:
|
|
||||||
|
|
||||||
@example
|
|
||||||
export PKG_CONFIG_LIBDIR=/home/me/cross/usr/lib/pkgconfig:/home/me/cross/usr/local/lib/pkgconfig
|
|
||||||
@end example
|
|
||||||
|
|
||||||
If you need to know the library's internal dependencies (typical use: static
|
|
||||||
linking), add the @code{--static} option to @command{pkg-config}:
|
|
||||||
|
|
||||||
@example
|
|
||||||
./configure --pkg-config-flags=--static
|
|
||||||
@end example
|
|
||||||
|
|
||||||
@section How do I use @command{pkg-config} when cross-compiling?
|
|
||||||
|
|
||||||
The best way is to install @command{pkg-config} in your cross-compilation
|
|
||||||
environment. It will automatically use the cross-compilation libraries.
|
|
||||||
|
|
||||||
You can also use @command{pkg-config} from the host environment by
|
|
||||||
specifying explicitly @code{--pkg-config=pkg-config} to @command{configure}.
|
|
||||||
In that case, you must point @command{pkg-config} to the correct directories
|
|
||||||
using the @code{PKG_CONFIG_LIBDIR}, as explained in the previous entry.
|
|
||||||
|
|
||||||
As an intermediate solution, you can place in your cross-compilation
|
|
||||||
environment a script that calls the host @command{pkg-config} with
|
|
||||||
@code{PKG_CONFIG_LIBDIR} set. That script can look like that:
|
|
||||||
|
|
||||||
@example
|
|
||||||
#!/bin/sh
|
|
||||||
PKG_CONFIG_LIBDIR=/path/to/cross/lib/pkgconfig
|
|
||||||
export PKG_CONFIG_LIBDIR
|
|
||||||
exec /usr/bin/pkg-config "$@@"
|
|
||||||
@end example
|
|
||||||
|
|
||||||
@chapter Usage
|
@chapter Usage
|
||||||
|
|
||||||
@section ffmpeg does not work; what is wrong?
|
@section ffmpeg does not work; what is wrong?
|
||||||
|
|
||||||
Try a @code{make distclean} in the ffmpeg source directory before the build.
|
Try a @code{make distclean} in the ffmpeg source directory before the build.
|
||||||
If this does not help see
|
If this does not help see
|
||||||
(@url{https://ffmpeg.org/bugreports.html}).
|
(@url{http://ffmpeg.org/bugreports.html}).
|
||||||
|
|
||||||
@section How do I encode single pictures into movies?
|
@section How do I encode single pictures into movies?
|
||||||
|
|
||||||
@@ -311,18 +260,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{http://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{http://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{http://ffmpeg.org/ffmpeg-filters.html#overlay, @code{overlay}} video filter.
|
||||||
|
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@@ -333,23 +282,23 @@ 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{http://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{http://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{http://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.
|
||||||
|
|
||||||
A few multimedia containers (MPEG-1, MPEG-2 PS, DV) allow one to concatenate
|
A few multimedia containers (MPEG-1, MPEG-2 PS, DV) allow to concatenate
|
||||||
video by merely concatenating the files containing them.
|
video by merely concatenating the files containing them.
|
||||||
|
|
||||||
Hence you may concatenate your multimedia files by first transcoding them to
|
Hence you may concatenate your multimedia files by first transcoding them to
|
||||||
@@ -419,6 +368,26 @@ ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \
|
|||||||
rm temp[12].[av] all.[av]
|
rm temp[12].[av] all.[av]
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
@section -profile option fails when encoding H.264 video with AAC audio
|
||||||
|
|
||||||
|
@command{ffmpeg} prints an error like
|
||||||
|
|
||||||
|
@example
|
||||||
|
Undefined constant or missing '(' in 'baseline'
|
||||||
|
Unable to parse option value "baseline"
|
||||||
|
Error setting option profile to value baseline.
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Short answer: write @option{-profile:v} instead of @option{-profile}.
|
||||||
|
|
||||||
|
Long answer: this happens because the @option{-profile} option can apply to both
|
||||||
|
video and audio. Specifically the AAC encoder also defines some profiles, none
|
||||||
|
of which are named @var{baseline}.
|
||||||
|
|
||||||
|
The solution is to apply the @option{-profile} option to the video stream only
|
||||||
|
by using @url{http://ffmpeg.org/ffmpeg.html#Stream-specifiers-1, Stream specifiers}.
|
||||||
|
Appending @code{:v} to it will do exactly that.
|
||||||
|
|
||||||
@section Using @option{-f lavfi}, audio becomes mono for no apparent reason.
|
@section Using @option{-f lavfi}, audio becomes mono for no apparent reason.
|
||||||
|
|
||||||
Use @option{-dumpgraph -} to find out exactly where the channel layout is
|
Use @option{-dumpgraph -} to find out exactly where the channel layout is
|
||||||
@@ -443,7 +412,7 @@ VOB and a few other formats do not have a global header that describes
|
|||||||
everything present in the file. Instead, applications are supposed to scan
|
everything present in the file. Instead, applications are supposed to scan
|
||||||
the file to see what it contains. Since VOB files are frequently large, only
|
the file to see what it contains. Since VOB files are frequently large, only
|
||||||
the beginning is scanned. If the subtitles happen only later in the file,
|
the beginning is scanned. If the subtitles happen only later in the file,
|
||||||
they will not be initially detected.
|
they will not be initally detected.
|
||||||
|
|
||||||
Some applications, including the @code{ffmpeg} command-line tool, can only
|
Some applications, including the @code{ffmpeg} command-line tool, can only
|
||||||
work with streams that were detected during the initial scan; streams that
|
work with streams that were detected during the initial scan; streams that
|
||||||
@@ -467,40 +436,6 @@ point acceptable for your tastes. The most common options to do that are
|
|||||||
@option{-qscale} and @option{-qmax}, but you should peruse the documentation
|
@option{-qscale} and @option{-qmax}, but you should peruse the documentation
|
||||||
of the encoder you chose.
|
of the encoder you chose.
|
||||||
|
|
||||||
@section I have a stretched video, why does scaling does not fix it?
|
|
||||||
|
|
||||||
A lot of video codecs and formats can store the @emph{aspect ratio} of the
|
|
||||||
video: this is the ratio between the width and the height of either the full
|
|
||||||
image (DAR, display aspect ratio) or individual pixels (SAR, sample aspect
|
|
||||||
ratio). For example, EGA screens at resolution 640×350 had 4:3 DAR and 35:48
|
|
||||||
SAR.
|
|
||||||
|
|
||||||
Most still image processing work with square pixels, i.e. 1:1 SAR, but a lot
|
|
||||||
of video standards, especially from the analogic-numeric transition era, use
|
|
||||||
non-square pixels.
|
|
||||||
|
|
||||||
Most processing filters in FFmpeg handle the aspect ratio to avoid
|
|
||||||
stretching the image: cropping adjusts the DAR to keep the SAR constant,
|
|
||||||
scaling adjusts the SAR to keep the DAR constant.
|
|
||||||
|
|
||||||
If you want to stretch, or “unstretch”, the image, you need to override the
|
|
||||||
information with the
|
|
||||||
@url{ffmpeg-filters.html#setdar_002c-setsar, @code{setdar or setsar filters}}.
|
|
||||||
|
|
||||||
Do not forget to examine carefully the original video to check whether the
|
|
||||||
stretching comes from the image or from the aspect ratio information.
|
|
||||||
|
|
||||||
For example, to fix a badly encoded EGA capture, use the following commands,
|
|
||||||
either the first one to upscale to square pixels or the second one to set
|
|
||||||
the correct aspect ratio or the third one to avoid transcoding (may not work
|
|
||||||
depending on the format / codec / player / phase of the moon):
|
|
||||||
|
|
||||||
@example
|
|
||||||
ffmpeg -i ega_screen.nut -vf scale=640:480,setsar=1 ega_screen_scaled.nut
|
|
||||||
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
|
|
||||||
@end example
|
|
||||||
|
|
||||||
@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?
|
||||||
@@ -589,7 +524,7 @@ see @file{libavformat/aviobuf.c} in FFmpeg and @file{libmpdemux/demux_lavf.c} in
|
|||||||
|
|
||||||
@section Where is the documentation about ffv1, msmpeg4, asv1, 4xm?
|
@section Where is the documentation about ffv1, msmpeg4, asv1, 4xm?
|
||||||
|
|
||||||
see @url{https://www.ffmpeg.org/~michael/}
|
see @url{http://www.ffmpeg.org/~michael/}
|
||||||
|
|
||||||
@section How do I feed H.263-RTP (and other codecs in RTP) to libavcodec?
|
@section How do I feed H.263-RTP (and other codecs in RTP) to libavcodec?
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
\input texinfo @c -*- texinfo -*-
|
\input texinfo @c -*- texinfo -*-
|
||||||
@documentencoding UTF-8
|
|
||||||
|
|
||||||
@settitle FFmpeg Automated Testing Environment
|
@settitle FFmpeg Automated Testing Environment
|
||||||
@titlepage
|
@titlepage
|
||||||
@@ -13,36 +12,36 @@
|
|||||||
|
|
||||||
@chapter Introduction
|
@chapter Introduction
|
||||||
|
|
||||||
FATE is an extended regression suite on the client-side and a means
|
FATE is an extended regression suite on the client-side and a means
|
||||||
for results aggregation and presentation on the server-side.
|
for results aggregation and presentation on the server-side.
|
||||||
|
|
||||||
The first part of this document explains how you can use FATE from
|
The first part of this document explains how you can use FATE from
|
||||||
your FFmpeg source directory to test your ffmpeg binary. The second
|
your FFmpeg source directory to test your ffmpeg binary. The second
|
||||||
part describes how you can run FATE to submit the results to FFmpeg's
|
part describes how you can run FATE to submit the results to FFmpeg's
|
||||||
FATE server.
|
FATE server.
|
||||||
|
|
||||||
In any way you can have a look at the publicly viewable FATE results
|
In any way you can have a look at the publicly viewable FATE results
|
||||||
by visiting this website:
|
by visiting this website:
|
||||||
|
|
||||||
@url{http://fate.ffmpeg.org/}
|
@url{http://fate.ffmpeg.org/}
|
||||||
|
|
||||||
This is especially recommended for all people contributing source
|
This is especially recommended for all people contributing source
|
||||||
code to FFmpeg, as it can be seen if some test on some platform broke
|
code to FFmpeg, as it can be seen if some test on some platform broke
|
||||||
with their recent contribution. This usually happens on the platforms
|
with their recent contribution. This usually happens on the platforms
|
||||||
the developers could not test on.
|
the developers could not test on.
|
||||||
|
|
||||||
The second part of this document describes how you can run FATE to
|
The second part of this document describes how you can run FATE to
|
||||||
submit your results to FFmpeg's FATE server. If you want to submit your
|
submit your results to FFmpeg's FATE server. If you want to submit your
|
||||||
results be sure to check that your combination of CPU, OS and compiler
|
results be sure to check that your combination of CPU, OS and compiler
|
||||||
is not already listed on the above mentioned website.
|
is not already listed on the above mentioned website.
|
||||||
|
|
||||||
In the third part you can find a comprehensive listing of FATE makefile
|
In the third part you can find a comprehensive listing of FATE makefile
|
||||||
targets and variables.
|
targets and variables.
|
||||||
|
|
||||||
|
|
||||||
@chapter Using FATE from your FFmpeg source directory
|
@chapter Using FATE from your FFmpeg source directory
|
||||||
|
|
||||||
If you want to run FATE on your machine you need to have the samples
|
If you want to run FATE on your machine you need to have the samples
|
||||||
in place. You can get the samples via the build target fate-rsync.
|
in place. You can get the samples via the build target fate-rsync.
|
||||||
Use this command from the top-level source directory:
|
Use this command from the top-level source directory:
|
||||||
|
|
||||||
@@ -51,11 +50,11 @@ make fate-rsync SAMPLES=fate-suite/
|
|||||||
make fate SAMPLES=fate-suite/
|
make fate SAMPLES=fate-suite/
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
The above commands set the samples location by passing a makefile
|
The above commands set the samples location by passing a makefile
|
||||||
variable via command line. It is also possible to set the samples
|
variable via command line. It is also possible to set the samples
|
||||||
location at source configuration time by invoking configure with
|
location at source configuration time by invoking configure with
|
||||||
@option{--samples=<path to the samples directory>}. Afterwards you can
|
`--samples=<path to the samples directory>'. Afterwards you can
|
||||||
invoke the makefile targets without setting the @var{SAMPLES} makefile
|
invoke the makefile targets without setting the SAMPLES makefile
|
||||||
variable. This is illustrated by the following commands:
|
variable. This is illustrated by the following commands:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
@@ -64,7 +63,7 @@ make fate-rsync
|
|||||||
make fate
|
make fate
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Yet another way to tell FATE about the location of the sample
|
Yet another way to tell FATE about the location of the sample
|
||||||
directory is by making sure the environment variable FATE_SAMPLES
|
directory is by making sure the environment variable FATE_SAMPLES
|
||||||
contains the path to your samples directory. This can be achieved
|
contains the path to your samples directory. This can be achieved
|
||||||
by e.g. putting that variable in your shell profile or by setting
|
by e.g. putting that variable in your shell profile or by setting
|
||||||
@@ -85,7 +84,7 @@ To use a custom wrapper to run the test, pass @option{--target-exec} to
|
|||||||
|
|
||||||
@chapter Submitting the results to the FFmpeg result aggregation server
|
@chapter Submitting the results to the FFmpeg result aggregation server
|
||||||
|
|
||||||
To submit your results to the server you should run fate through the
|
To submit your results to the server you should run fate through the
|
||||||
shell script @file{tests/fate.sh} from the FFmpeg sources. This script needs
|
shell script @file{tests/fate.sh} from the FFmpeg sources. This script needs
|
||||||
to be invoked with a configuration file as its first argument.
|
to be invoked with a configuration file as its first argument.
|
||||||
|
|
||||||
@@ -93,23 +92,23 @@ to be invoked with a configuration file as its first argument.
|
|||||||
tests/fate.sh /path/to/fate_config
|
tests/fate.sh /path/to/fate_config
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
A configuration file template with comments describing the individual
|
A configuration file template with comments describing the individual
|
||||||
configuration variables can be found at @file{doc/fate_config.sh.template}.
|
configuration variables can be found at @file{doc/fate_config.sh.template}.
|
||||||
|
|
||||||
@ifhtml
|
@ifhtml
|
||||||
The mentioned configuration template is also available here:
|
The mentioned configuration template is also available here:
|
||||||
@verbatiminclude fate_config.sh.template
|
@verbatiminclude fate_config.sh.template
|
||||||
@end ifhtml
|
@end ifhtml
|
||||||
|
|
||||||
Create a configuration that suits your needs, based on the configuration
|
Create a configuration that suits your needs, based on the configuration
|
||||||
template. The @env{slot} configuration variable can be any string that is not
|
template. The `slot' configuration variable can be any string that is not
|
||||||
yet used, but it is suggested that you name it adhering to the following
|
yet used, but it is suggested that you name it adhering to the following
|
||||||
pattern @samp{@var{arch}-@var{os}-@var{compiler}-@var{compiler version}}. The
|
pattern <arch>-<os>-<compiler>-<compiler version>. The configuration file
|
||||||
configuration file itself will be sourced in a shell script, therefore all
|
itself will be sourced in a shell script, therefore all shell features may
|
||||||
shell features may be used. This enables you to setup the environment as you
|
be used. This enables you to setup the environment as you need it for your
|
||||||
need it for your build.
|
build.
|
||||||
|
|
||||||
For your first test runs the @env{fate_recv} variable should be empty or
|
For your first test runs the `fate_recv' variable should be empty or
|
||||||
commented out. This will run everything as normal except that it will omit
|
commented out. This will run everything as normal except that it will omit
|
||||||
the submission of the results to the server. The following files should be
|
the submission of the results to the server. The following files should be
|
||||||
present in $workdir as specified in the configuration file:
|
present in $workdir as specified in the configuration file:
|
||||||
@@ -122,29 +121,29 @@ present in $workdir as specified in the configuration file:
|
|||||||
@item version
|
@item version
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
When you have everything working properly you can create an SSH key pair
|
When you have everything working properly you can create an SSH key pair
|
||||||
and send the public key to the FATE server administrator who can be contacted
|
and send the public key to the FATE server administrator who can be contacted
|
||||||
at the email address @email{fate-admin@@ffmpeg.org}.
|
at the email address @email{fate-admin@@ffmpeg.org}.
|
||||||
|
|
||||||
Configure your SSH client to use public key authentication with that key
|
Configure your SSH client to use public key authentication with that key
|
||||||
when connecting to the FATE server. Also do not forget to check the identity
|
when connecting to the FATE server. Also do not forget to check the identity
|
||||||
of the server and to accept its host key. This can usually be achieved by
|
of the server and to accept its host key. This can usually be achieved by
|
||||||
running your SSH client manually and killing it after you accepted the key.
|
running your SSH client manually and killing it after you accepted the key.
|
||||||
The FATE server's fingerprint is:
|
The FATE server's fingerprint is:
|
||||||
|
|
||||||
@table @samp
|
@table @option
|
||||||
@item RSA
|
@item RSA
|
||||||
d3:f1:83:97:a4:75:2b:a6:fb:d6:e8:aa:81:93:97:51
|
d3:f1:83:97:a4:75:2b:a6:fb:d6:e8:aa:81:93:97:51
|
||||||
@item ECDSA
|
@item ECDSA
|
||||||
76:9f:68:32:04:1e:d5:d4:ec:47:3f:dc:fc:18:17:86
|
76:9f:68:32:04:1e:d5:d4:ec:47:3f:dc:fc:18:17:86
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
If you have problems connecting to the FATE server, it may help to try out
|
If you have problems connecting to the FATE server, it may help to try out
|
||||||
the @command{ssh} command with one or more @option{-v} options. You should
|
the @command{ssh} command with one or more @option{-v} options. You should
|
||||||
get detailed output concerning your SSH configuration and the authentication
|
get detailed output concerning your SSH configuration and the authentication
|
||||||
process.
|
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.
|
||||||
|
|
||||||
|
|
||||||
@@ -165,7 +164,7 @@ Run the FATE test suite (requires the fate-suite dataset).
|
|||||||
|
|
||||||
@section Makefile variables
|
@section Makefile variables
|
||||||
|
|
||||||
@table @env
|
@table @option
|
||||||
@item V
|
@item V
|
||||||
Verbosity level, can be set to 0, 1 or 2.
|
Verbosity level, can be set to 0, 1 or 2.
|
||||||
@itemize
|
@itemize
|
||||||
@@ -183,20 +182,20 @@ Specify how many threads to use while running regression tests, it is
|
|||||||
quite useful to detect thread-related regressions.
|
quite useful to detect thread-related regressions.
|
||||||
|
|
||||||
@item THREAD_TYPE
|
@item THREAD_TYPE
|
||||||
Specify which threading strategy test, either @samp{slice} or @samp{frame},
|
Specify which threading strategy test, either @var{slice} or @var{frame},
|
||||||
by default @samp{slice+frame}
|
by default @var{slice+frame}
|
||||||
|
|
||||||
@item CPUFLAGS
|
@item CPUFLAGS
|
||||||
Specify CPU flags.
|
Specify CPU flags.
|
||||||
|
|
||||||
@item TARGET_EXEC
|
@item TARGET_EXEC
|
||||||
Specify or override the wrapper used to run the tests.
|
Specify or override the wrapper used to run the tests.
|
||||||
The @env{TARGET_EXEC} option provides a way to run FATE wrapped in
|
The @var{TARGET_EXEC} option provides a way to run FATE wrapped in
|
||||||
@command{valgrind}, @command{qemu-user} or @command{wine} or on remote targets
|
@command{valgrind}, @command{qemu-user} or @command{wine} or on remote targets
|
||||||
through @command{ssh}.
|
through @command{ssh}.
|
||||||
|
|
||||||
@item GEN
|
@item GEN
|
||||||
Set to @samp{1} to generate the missing or mismatched references.
|
Set to @var{1} to generate the missing or mismatched references.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@section Examples
|
@section Examples
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
slot= # some unique identifier
|
slot= # some unique identifier
|
||||||
repo=git://source.ffmpeg.org/ffmpeg.git # the source repository
|
repo=git://source.ffmpeg.org/ffmpeg.git # the source repository
|
||||||
#branch=release/2.6 # the branch to test
|
|
||||||
samples= # path to samples directory
|
samples= # path to samples directory
|
||||||
workdir= # directory in which to do all the work
|
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
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
\input texinfo @c -*- texinfo -*-
|
\input texinfo @c -*- texinfo -*-
|
||||||
@documentencoding UTF-8
|
|
||||||
|
|
||||||
@settitle FFmpeg Bitstream Filters Documentation
|
@settitle FFmpeg Bitstream Filters Documentation
|
||||||
@titlepage
|
@titlepage
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
\input texinfo @c -*- texinfo -*-
|
\input texinfo @c -*- texinfo -*-
|
||||||
@documentencoding UTF-8
|
|
||||||
|
|
||||||
@settitle FFmpeg Codecs Documentation
|
@settitle FFmpeg Codecs Documentation
|
||||||
@titlepage
|
@titlepage
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
\input texinfo @c -*- texinfo -*-
|
\input texinfo @c -*- texinfo -*-
|
||||||
@documentencoding UTF-8
|
|
||||||
|
|
||||||
@settitle FFmpeg Devices Documentation
|
@settitle FFmpeg Devices Documentation
|
||||||
@titlepage
|
@titlepage
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
\input texinfo @c -*- texinfo -*-
|
\input texinfo @c -*- texinfo -*-
|
||||||
@documentencoding UTF-8
|
|
||||||
|
|
||||||
@settitle FFmpeg Filters Documentation
|
@settitle FFmpeg Filters Documentation
|
||||||
@titlepage
|
@titlepage
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
\input texinfo @c -*- texinfo -*-
|
\input texinfo @c -*- texinfo -*-
|
||||||
@documentencoding UTF-8
|
|
||||||
|
|
||||||
@settitle FFmpeg Formats Documentation
|
@settitle FFmpeg Formats Documentation
|
||||||
@titlepage
|
@titlepage
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
\input texinfo @c -*- texinfo -*-
|
\input texinfo @c -*- texinfo -*-
|
||||||
@documentencoding UTF-8
|
|
||||||
|
|
||||||
@settitle FFmpeg Protocols Documentation
|
@settitle FFmpeg Protocols Documentation
|
||||||
@titlepage
|
@titlepage
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
\input texinfo @c -*- texinfo -*-
|
\input texinfo @c -*- texinfo -*-
|
||||||
@documentencoding UTF-8
|
|
||||||
|
|
||||||
@settitle FFmpeg Resampler Documentation
|
@settitle FFmpeg Resampler Documentation
|
||||||
@titlepage
|
@titlepage
|
||||||
@@ -15,7 +14,7 @@
|
|||||||
|
|
||||||
The FFmpeg resampler provides a high-level interface to the
|
The FFmpeg resampler provides a high-level interface to the
|
||||||
libswresample library audio resampling utilities. In particular it
|
libswresample library audio resampling utilities. In particular it
|
||||||
allows one to perform audio resampling, audio channel layout rematrixing,
|
allows to perform audio resampling, audio channel layout rematrixing,
|
||||||
and convert audio format and packing layout.
|
and convert audio format and packing layout.
|
||||||
|
|
||||||
@c man end DESCRIPTION
|
@c man end DESCRIPTION
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
\input texinfo @c -*- texinfo -*-
|
\input texinfo @c -*- texinfo -*-
|
||||||
@documentencoding UTF-8
|
|
||||||
|
|
||||||
@settitle FFmpeg Scaler Documentation
|
@settitle FFmpeg Scaler Documentation
|
||||||
@titlepage
|
@titlepage
|
||||||
@@ -14,7 +13,7 @@
|
|||||||
@c man begin DESCRIPTION
|
@c man begin DESCRIPTION
|
||||||
|
|
||||||
The FFmpeg rescaler provides a high-level interface to the libswscale
|
The FFmpeg rescaler provides a high-level interface to the libswscale
|
||||||
library image conversion utilities. In particular it allows one to perform
|
library image conversion utilities. In particular it allows to perform
|
||||||
image rescaling and pixel format conversion.
|
image rescaling and pixel format conversion.
|
||||||
|
|
||||||
@c man end DESCRIPTION
|
@c man end DESCRIPTION
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
\input texinfo @c -*- texinfo -*-
|
\input texinfo @c -*- texinfo -*-
|
||||||
@documentencoding UTF-8
|
|
||||||
|
|
||||||
@settitle FFmpeg Utilities Documentation
|
@settitle FFmpeg Utilities Documentation
|
||||||
@titlepage
|
@titlepage
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user