Compare commits

..

203 Commits

Author SHA1 Message Date
Michael Niedermayer
af5917698b avformat/avidec: add mp2 to the list of exceptions instead of generally treating dshow_block_align==1 special
Fixes Ticket4552

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 488383afd1)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-17 02:16:39 +02:00
Michael Niedermayer
b58cbb07bc avformat/mov: Fix parsing short loci
Fixes Ticket4557

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 50393bce31)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-16 21:36:48 +02:00
Michael Niedermayer
dd9789ab6d avformat/mov: Print reason of loci parsing failure
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 9e4f0cfc8f)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-16 21:36:36 +02:00
Michael Niedermayer
aded27a30b Update for 2.6.3
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-16 00:41:10 +02:00
Michael Niedermayer
a1f68d9518 avcodec/hevc: Fix typo in num_entry_point_offsets check
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 3051e7fa71)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 23:56:52 +02:00
Michael Niedermayer
2612b69d3f avcodec/libtheoraenc: Check for av_malloc failure
Fixes CID1257799

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit c64b2d480b)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 23:55:29 +02:00
Michael Niedermayer
88217c40b6 avcodec/dcadec: Check active_bands
Fixes CID1297594 part2

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit fc624ec9ba)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 20:40:26 +02:00
Michael Niedermayer
001cc6d27a avcodec/dcadec: Check scale table index
Fixes CID1297594 part 1

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 0f3e6959bf)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 20:33:04 +02:00
Michael Niedermayer
ea6bd45885 avcodec/sonic: More completely check sample_rate_index and channels
Fixes CID1271783

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit ade8a46154)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 17:52:47 +02:00
Michael Niedermayer
51850d9a2c avcodec/sonic: check memory allocations
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit c131a9fead)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 17:52:26 +02:00
Michael Niedermayer
211ec9196d avcodec/smvjpegdec: check avcodec_decode_video2() return code
Fixes CID1271810

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit cdd25f9a3d)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 17:52:07 +02:00
Michael Niedermayer
e4318f6875 avcodec/shorten: More complete pred_order check
Fixes CID1239055

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 294469416d)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 17:45:06 +02:00
Michael Niedermayer
008c1debb9 avcodec/shorten: Check skip_bytes()
Fixes CID1210526

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit d201becfc0)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 17:44:31 +02:00
Michael Niedermayer
f33bd39d27 avcodec/shorten: Fix code depending on signed overflow behavior
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 2d15588124)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 17:41:47 +02:00
Michael Niedermayer
0337770352 avcodec/proresdec2: Reset slice_count on deallocation
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit c4c6aea397)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 16:30:11 +02:00
Michael Niedermayer
ab8f686bbc avcodec/dvbsubdec: Clear w/h/size on region buffer allocation failure
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 9f0b898e82)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:52 +02:00
Carl Eugen Hoyos
b5a942685f lavf/matroskaenc: List subtitle codecs with fake codec_tags to allow remuxing.
Fixes remuxing of DVBSUB to mkv.
2015-05-15 10:04:52 +02:00
Michael Niedermayer
7e2ea1cb70 ffmpeg_opt: Fix -timestamp parsing
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 107e4da476)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:52 +02:00
Michael Niedermayer
10e1108732 avcodec/dcadec: Check subsubframes
Fixes: CID1239152

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit a9bf628bfd)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:52 +02:00
Michael Niedermayer
3da0395b34 avcodec/dcadec: Check nchans
Fixes CID1239110

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit a6a45774d0)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
wm4
25d50ad814 hevc: make avcodec_decode_video2() fail if get_format() fails
Personally, I need the decoder to back out if get_format() returns no
usable pixel format. This didn't work because the error code was not
propagated down the call chain. This in turn happened because the
variable declaration removed in this patch shadowed the variable, whose
value is returned at the end of the function. Consequently, failures of
decode_nal_unit() were ignored in this place.

Reviewed-by:  Andreas Cadhalpun <andreas.cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit cc5e4bb484)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
fb564cd21d avcodec/cavsdec: Use ff_set_dimensions()
Fixes CID1239111 part2

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit f6b8b96607)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
10609d8864 avcodec/cavsdec: Check esc_code
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 139e1c8009)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
dbc48ba1cd avcodec/on2avc: Check run more carefully
Fixes CID1239106

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 22f15f5735)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
19ffa15d2d avcodec/mpeg4audio: add some padding/alignment to MAX_PCE_SIZE
This avoids potential accesses over the end

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 93cfa7d169)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Rainer Hochecker
531ea97b89 swr: fix alignment issue caused by 8ch sse functions
Fix crash when doing 8 ch conversion from apps compiled with MSVS
Thanks to Ronald for giving this hint:
https://ffmpeg.org/pipermail/ffmpeg-devel/2015-May/173049.html

Reviewed-by: "Ronald S. Bultje" <rsbultje@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit adb7372f74)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
0a5b242422 avcodec/mjpegdec: fix len computation in ff_mjpeg_decode_dqt()
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 81cf910856)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
f43fb74ad4 avcodec/jpeg2000dec: fix boolean operator
Fixes CID1271791 #7-6

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit f8f155a18a)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
0463e9d6da avcodec/hevc_ps: Explicitly check num_tile_* for negative values
This fixes nothing but maybe helps coverity which does not see that this is failing later

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 65e5032955)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
e8784ec5f5 avcodec/hevc_ps: Check vps_num_hrd_parameters
Fix CID1239052 part2

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit b195aa5d52)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
0a93dc83d2 avcodec/hevc_ps: More completely check vps_num_layer_sets
Fixes CID1239052  part1

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 16c95b1073)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
bced2ad1bd avcodec/hevc: Check num_entry_point_offsets
Fixes CID1239099 part 2

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 1c6ae98d4a)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
fe22d0d7c6 avcodec/hevc: Check offset_len
Fixes CID1239099 part 1

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 3e9d5e16ad)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Nick Lewycky
a5167b4d66 libswscale/x86/hscale_fast_bilinear_simd.c: Include BX in the clobber list on x86_64, because it isn't implicitly included when PIC is on.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 48e9f68384)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
3123cb5d0b avcodec/hevc_sei: Check num_sps_ids_minus1 value
Fixes CID1271794

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 93b0ee21a2)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
375a97bb70 avcodec/vqavideo: Check chunk size
Fixes CID1239154

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 8a62b80ce6)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
0fc6a95116 avformat/hevc: Check num_negative_pics and num_positive_pics
Fixes CID1238994

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit b62b3292d8)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
f93412406f avformat/hevc: Check cpb_cnt_minus1
Fixes CID1239014

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 2cddc0b19a)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
05eddbbc05 avformat/matroskadec: Cleanup error handling for bz2 & zlib
Fixes CID703652

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 171af59d58)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
75b21eb8f8 avformat/nutdec: Fix use of uinitialized value
Fixes CID1041175

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 56abf35151)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
1933fa5daa avformat/rtpenc_jpeg: Check remaining buffer size for SOS
Fixes CID1238818

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 81198a6837)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
bd05ac1df8 avformat/rtpdec_xiph: Check upper bound on len in xiph_handle_packet()
Larger packets are not supported and would cause problems later

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit aa5169935e)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
8d0f079c45 tools/graph2dot: use larger data types than int for array/string sizes
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit acf4925f44)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
889a4779eb avformat/matroskaenc: Check ff_vorbiscomment_length in put_flac_codecpriv()
Its currently guaranteed to be smaller but its safer to check anyway

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 66f26b3e8e)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
a9d3baff03 avformat/oggenc: Check ff_vorbiscomment_length in ogg_write_vorbiscomment()
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 0db5b2b9f8)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
f4ce752f22 avformat/flacenc: Check length in flac_write_block_comment()
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 40a7700b82)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
02532e1162 avformat/subtitles: Use size_t for len
string length could theoretically be larger than int

Reviewed-by: Clément Bœsch <u@pkh.me>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit a633928d47)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
b1652fbb9e avformat/url: Use size_t for len from strlen()
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 95efc65129)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
39236d5618 avutil/avstring: Use size_t in av_strlcatf()
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit ae4eea8be4)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
38e628fd6d avformat/vorbiscomment: Check entry length in ff_vorbiscomment_write()
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit eca38864a6)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:51 +02:00
Michael Niedermayer
cf6cbcca7e avutil/dict: Use size_t for appending strings
the string length is not constrained to INT_MAX

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 4c128ea162)

Conflicts:

	libavutil/dict.c
2015-05-15 10:04:51 +02:00
Michael Niedermayer
df9eca44f8 libavutil/mem: use size_t for the length in av_strdup()
the string length is not constrained to INT_MAX

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 4950bd4ebe)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Giorgio Vazzana
a563a1468f lavd/v4l2: fix typo
This was introduced in cde6e328de

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 23e6cf832f)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Michael Niedermayer
fd17e34217 avcodec/mpeg12dec: use the correct dimensions for checking SAR
Fixes Ticket4533

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 7f45f7fc7f)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Michael Niedermayer
ec17706e5c avcodec/ffv1dec: Check chroma shift parameters
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit d43cd6b08e)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Michael Niedermayer
e0f85f10c8 avcodec/wavpack: Check L/R values before use to avoid harmless integer overflow and undefined behavior in fate
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 042260cde4)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Luca Barbato
9ccaeff67a xcbgrab: Validate the capture area
And notify why the capture is impossible.

Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
(cherry picked from commit e8c4db0d4d)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Luca Barbato
4a46a29b07 xcbgrab: Do not assume the non shm image data is always available
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
(cherry picked from commit 82a10225f8)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Michael Niedermayer
22ef88ee30 avfilter/lavfutils: disable frame threads when decoding a single image
The image decoding code does expect the image to be decoded immedeatly

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit d2184bf3b6)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Michael Niedermayer
48e53620e0 avformat/mov: Do not read ACLR into extradata for H.264
Fixes regression decoding AVCI
Fixes Ticket4493

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 2025e803cd)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Michael Niedermayer
8a7748e1de ffmpeg: remove incorrect network deinit
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit e2877bdf38)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Maneesh Gupta
86a360e349 OpenCL: Avoid potential buffer overflow in cmdutils_opencl.c
The opt_opencl_bench function copied the device name using strcpy without checking if the source string was larger.
This patch fixes this by replacing the strcpy with av_strlcpy, with the string copy size capped to the destination buffer size.

Signed-off-by: Maneesh Gupta <maneesh.gupta@amd.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit cf234552b8)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
James Zern
07ad029d1b libvpxenc: only set noise reduction w/vp8
this quiets a warning:
Failed to set VP8E_SET_NOISE_SENSITIVITY codec control: Unspecified
internal error

Reviewed-by: Michael Niedermayer <michaelni@gmx.at>
Signed-off-by: James Zern <jzern@google.com>
(cherry picked from commit 238ec505e2)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Ronald S. Bultje
b53b6a25e2 vp9: remove another optimization branch in iadst16 which causes overflows.
See sample vp90-2-14-resize-fp-tiles-16-8.webm from the vp9 test vector
set to reproduce the issue.
(cherry picked from commit 3de13d5212)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Michael Niedermayer
83ee63e7f8 avcodec/dvbsubdec: Do not return a value from a function returning void
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit e06dde52d7)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Vittorio Giovara
536093824d lavf: Reset global flag on deinit
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 32da94fa7f)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Vittorio Giovara
485f53548b network: Do not leave context locked on error
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 45340f9fc7)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Ronald S. Bultje
2ac7a0d999 vp9: remove one optimization branch in iadst16 which causes overflows.
See sample vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm from the vp9 test
vector set which reproduces the issue. This probably costs a few cycles,
but I don't think there's an easy way to workaround that.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit d02d04a18f)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Timothy Gu
b35d67fa51 fate: Include branch information in the payload header
The server is properly equiped not to choke on that now.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 7ad27f1221)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Michael Niedermayer
b942813a41 avformat/utils: Ensure that AVFMT_FLAG_CUSTOM_IO is set before use
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit ba631b7914)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Michael Niedermayer
a75f293264 avformat/img2dec: do not rewind custom io buffers
Fixes double free with some applications

Fixes vlc ticket14121
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit e6e8cc8ce9)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Michael Niedermayer
33862c1f6d avcodec/alsdec: Use av_mallocz_array() for chan_data to ensure the arrays never contain random data
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 7e104647a3)

Conflicts:

	libavcodec/alsdec.c
2015-05-15 10:04:50 +02:00
Michael Niedermayer
89fbae7686 avcodec/atrac3plusdsp: fix on stack alignment
Fixes fate failure on ARM
(cherry picked from commit 38f6726068)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Michael Niedermayer
3f9ecaf886 swresample/swresample-test: Randomly wipe out channel counts
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit ff50b1b13b)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Michael Niedermayer
50dc37f281 swresample: Check channel layouts and channels against each other and print human readable error messages
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 3c77bb5f23)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Michael Niedermayer
6c39528a3a swresample: Allow reinitialization without ever setting channel layouts
(cherry picked from commit 80a28c7509)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
Michael Niedermayer
9b0c9261cc swresample: Allow reinitialization without ever setting channel counts
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit d7b9cb2f7a)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-05-15 10:04:50 +02:00
James Almer
9fc45b313c dashenc: replace attribute id with contentType for the AdaptationSet element
id should be an integer, not a string. It is also optional, so use
contentType instead which is the proper attribute for these values.

This addresses ticket #4545, fixing an MPD validation error.

Signed-off-by: James Almer <jamrial@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 32a4177a62)
2015-05-14 20:57:24 -03:00
Michael Niedermayer
d9390b9d64 avformat/matroskaenc: Use avoid_negative_ts_use_pts if no stream writes dts
This reduces the number of cases where timestamps need to be shifted

Fixes Ticket4487

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 9d4fdfe24c)
2015-05-14 19:52:02 -03:00
Michael Niedermayer
5a8b43285b avformat/mux: Add avoid_negative_ts_use_pts
This allows using pts instead of dts for negative TS avoidance

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 7ac5c38ec5)
2015-05-14 19:51:55 -03:00
Michael Niedermayer
8e94e5d339 tests/fate-run: do not attempt to parse tiny_psnrs output if it failed
This avoids confusing syntax errors with awk later

Likely fixes awk errors at:
http://buildd.debian-ports.org/status/fetch.php?pkg=ffmpeg&arch=sparc64&ver=7%3A2.6.2-1&stamp=1428928967

Reviewed-by: Timothy Gu <timothygu99@gmail.com>
Thanks-to: Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> for the link
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit c0d847e457)
2015-05-14 19:51:39 -03:00
Andreas Cadhalpun
73cf5d9a28 cafdec: free extradata before allocating it
This fixes a memleak if read_kuki_chunk is executed more than once.

Reviewed-by: Carl Eugen Hoyos <cehoyos@ag.or.at>
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
(cherry picked from commit cb7c4f73e5)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:14:32 +02:00
Andreas Cadhalpun
ac83399281 cafdec: check avio_read return value
If avio_read fails, the buffer can contain uninitialized values.

Reviewed-by: Carl Eugen Hoyos <cehoyos@ag.or.at>
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
(cherry picked from commit a3ede6b742)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:14:19 +02:00
Andreas Cadhalpun
9bcaf90378 imgutils: initialize palette padding bytes in av_image_alloc
av_image_fill_pointers always aligns the palette, but the padding
bytes don't (and can't) get initialized in av_image_copy.

Thus initialize them in av_image_alloc.

This fixes 'Syscall param write(buf) points to uninitialised byte(s)'
valgrind warnings.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 51f6455285)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:14:10 +02:00
Andreas Cadhalpun
d9249b5582 aacdec: don't return frames without data
Since commit 676a395a aac->frame->data is not necessarily allocated at
the end of aac_decode_frame_int if avctx->channels is 0.

In this case a bogus frame without any data, but non-zero nb_samples is
returned.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit ec38a1ba40)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:13:58 +02:00
Andreas Cadhalpun
66b95ee4df id3v2: catch avio_read errors in check_tag
Since len is an unsigned int, the comparison is currently treated as
unsigned and thus ignores all errors from avio_read.

Thus cast len to int, which is unproblematic, because at that point len
is between 0 and 4.

This fixes 'Conditional jump or move depends on uninitialised value'
valgrind warnings in is_tag.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 0382c94f13)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:13:49 +02:00
Andreas Cadhalpun
0f7e67be3a avi: Validate sample_size
And either error out or set it to 0 if it is negative.

CC: libav-stable@libav.org
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
(cherry picked from commit 4d0ee4962b)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>

Conflicts:
	libavformat/avidec.c
2015-05-14 19:13:13 +02:00
Andreas Cadhalpun
0856eea770 aacsbr: break infinite loop in sbr_hf_calc_npatches
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 584cc1ade1)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:10:49 +02:00
Andreas Cadhalpun
04f80ed3f8 diracdec: check that block length is valid
In init_planes p->xblen and p->yblen are set to:
            p->xblen = s->plane[0].xblen >> s->chroma_x_shift;
            p->yblen = s->plane[0].yblen >> s->chroma_y_shift;

These are later used as block_w and block_h arguments of
s->vdsp.emulated_edge_mc. If one of them is 0 it triggers an av_assert2
in emulated_edge_mc:
    av_assert2(start_x < end_x && block_w > 0);
    av_assert2(start_y < end_y && block_h > 0);

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 75fc81c831)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:10:32 +02:00
Andreas Cadhalpun
c6f6be93ac diracdec: check if reference could not be allocated
s->ref_pics[i] is later used as ref argument of interpolate_refplane,
where it is dereferenced.

If it is NULL, it causes a segmentation fault.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit d93181ef3e)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:10:23 +02:00
Andreas Cadhalpun
c6418be043 diracdec: avoid overflow of bytes*8 in decode_lowdelay
If bytes is large enough, bytes*8 can overflow and become negative.

In that case 'bufsize -= bytes*8' causes bufsize to increase instead of
decrease.

This leads to a segmentation fault.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 9e66b39aa8)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:10:16 +02:00
Andreas Cadhalpun
f78d7e6a03 diracdec: prevent overflow in data_unit_size check
buf_idx + data_unit_size can overflow, causing the '> buf_size' check to
wrongly fail.

This causes a segmentation fault.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 984f50deb2)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:10:06 +02:00
Andreas Cadhalpun
0cb8d786f2 avidec: check for valid bit_rate range
If bit_rate is negative, it can trigger an av_assert2 in av_rescale_rnd.

Since av_rescale returns int64_t, but st->codec_bit_rate is int, it can
also overflow into a negative value.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 0eec40b713)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:09:47 +02:00
Michael Niedermayer
c74846388b avformat/matroskadec: Use tracks[k]->stream instead of s->streams[k]
The later is not correct

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 5d309d3091)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:09:37 +02:00
Andreas Cadhalpun
35013fa23a matroskadec: check s->streams[k] before using it
This fixes a segmentation fault.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit e54540655f)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:09:32 +02:00
Andreas Cadhalpun
33d77bc384 matroskadec: use uint64_t instead of int for index_scale
index_scale is set to matroska->time_scale of type uint64_t.

When index_scale is int, the assignment can overflow and e.g. result
in index_scale = 0. This causes a floating point exception due to the
division by index_scale.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit eb9fb508b0)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:09:19 +02:00
Andreas Cadhalpun
e6a5023d1f pngdec: don't use AV_PIX_FMT_MONOBLACK for apng
AV_PIX_FMT_MONOBLACK has the AV_PIX_FMT_FLAG_BITSTREAM flag, i.e.
linesize can be smaller than width.

Since x_offset is only check against the width, this can lead to
x_offset * bpp >= image_linesize.

In this case ptr could be set to a position outside the image_buf in
png_handle_row, leading to memory corruption and thus crashes.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 372aa0777a)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:09:10 +02:00
Andreas Cadhalpun
99e737a7c7 pngdec: return correct error code from decode_frame_common
During the loop ret can get changed. Since it is not set on all failure
paths, decode_frame_common can return 0 even though an error occurred.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 8f760be4d3)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:09:00 +02:00
Andreas Cadhalpun
835037506b pngdec: check s->last_picture.f->data[0] before using it
This check was removed in commit 08aec6f6, but
s->last_picture.f->data[0] is still used in handle_p_frame_apng
unconditionally.

This fixes a segmentation fault.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 287dbb0771)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:08:54 +02:00
Andreas Cadhalpun
2f290cf881 nutdec: fix illegal count check in decode_main_header
The existing check has two problems:
 1) i + count can overflow, so that the check '< 256' returns true.
 2) In the (i == 'N') case occurs a j-- so that the loop runs once more.

This can trigger the assertion 'nut->header_len[0] == 0' or cause
segmentation faults or infinite hangs.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 7c24ca1bda)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:08:38 +02:00
Andreas Cadhalpun
2523bdcd67 nutdec: fix memleaks on error in nut_read_header
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 361702660d)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:08:26 +02:00
Andreas Cadhalpun
9b87d15ca8 nutdec: check chapter creation in decode_info_header
This fixes a segmentation fault when accessing the metadata.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 3ff1af2b0d)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:08:02 +02:00
Andreas Cadhalpun
a13a288ec8 nutdec: check for negative frame rate in decode_info_header
A negative frame rate triggers an av_assert2 in av_rescale_rnd.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 6621105877)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:07:55 +02:00
Andreas Cadhalpun
9f2c8734b9 apedec: prevent out of array writes in decode_array_0000
s->decoded_buffer is allocated with a min_size of:
    2 * FFALIGN(blockstodecode, 8) * sizeof(*s->decoded_buffer)

Then it is assigned to s->decoded[0] (and s->decoded_buffer + FFALIGN(blockstodecode, 8)
to s->decoded[1]) and passed as out buffer to decode_array_0000.

In this function 64 elements of the out buffer are written
unconditionally and outside the array if blockstodecode is too small.

This causes memory corruption, leading to segmentation faults or other
crashes.

Thus change decode_array_0000 to write at most blockstodecode elements
of the out buffer.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 699341d647)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:07:47 +02:00
Andreas Cadhalpun
d35086d715 apedec: set s->samples only when init_frame_decoder succeeded
Otherwise range_start_decoding is not necessarily run and thus
ctx->rc.range still 0 in range_dec_normalize leading to an infinite
loop.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 464c49155c)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:07:42 +02:00
Rong Yan
be1b665dec swscale/ppc/swscale_altivec.c: POWER LE support in yuv2planeX_8() delete macro GET_VF() it was wrong
GCC tool had a bug of PPC intrinsic interpret, which has been fixed in GCC 4.9.1. This bug lead to
errors in two of our previous patches. We found this when we update our GCC tools to 4.9.1 and by
reading the related info on GCC website. We fix our previous error in two separate commits

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 603c839398)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:07:33 +02:00
Andreas Cadhalpun
47f5f6b230 alac: reject rice_limit 0 if compression is used
If rice_limit is 0, k can be 0 in decode_scalar, which calls show_bits(gb, k).

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 4b657a1b1e)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:07:21 +02:00
Andreas Cadhalpun
01291b4e2f alsdec: only adapt order for positive max_order
For max_order = 0 the clipping range is invalid. (amin = 2, amax = 1)

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 58d605ee9b)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:07:13 +02:00
Andreas Cadhalpun
787e094ed0 bink: check vst->index_entries before using it
This fixes a NULL pointer dereference if vst->duration is 0.

The problem was introduced in commit 0588acaf.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 86d00ede4f)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:07:01 +02:00
Andreas Cadhalpun
2f8f4351b8 mpeg4videodec: only allow a positive length
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit b3408ae4c6)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:06:54 +02:00
Andreas Cadhalpun
f77cb3d4a6 alsdec: check sample pointer range in revert_channel_correlation
Also change the type of begin, end and smp to ptrdiff_t to make the
comparison well-defined.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Reviewed-by: Thilo Borgmann <thilo.borgmann@mail.de>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit afc7748d1f)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:06:42 +02:00
Andreas Cadhalpun
3258e12d8c aacpsy: correct calculation of minath in psy_3gpp_init
The minimum of the ath(x, ATH_ADD) function depends on ATH_ADD.
This patch uses the first order approximation to determine it.

For ATH_ADD = 4 this results in the value at 3407.06812 (-5.24241638)
not the one at 3410 (-5.24237967).

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Approved-by: Claudio Freire <klaussfreire@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit ca9849eecd)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:06:36 +02:00
Andreas Cadhalpun
84cd276d0e alsdec: validate time diff index
If begin is smaller than t, the subtraction 'begin -= t' wraps around,
because begin is unsigned. The same applies for end < t.

This causes segmentation faults.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit faf9fe2c22)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:06:24 +02:00
Andreas Cadhalpun
a298e13c2c alsdec: limit avctx->bits_per_raw_sample to 32
avctx->bits_per_raw_sample is used in get_sbits_long, which only
supports up to 32 bits.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 4c2b88678b)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:06:16 +02:00
Andreas Cadhalpun
50fb69c737 alsdec: ensure channel reordering is reversible
If the same idx is used for more than one i, at least one entry in
sconf->chan_pos remains uninitialized.

This can cause segmentation faults.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit ef16501aeb)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:06:01 +02:00
Andreas Cadhalpun
9c826d8d51 ac3: validate end in ff_ac3_bit_alloc_calc_mask
This fixes an invalid read if end is 0:
     band_end   = ff_ac3_bin_to_band_tab[end-1] + 1;

Depending on what is before the array, this can cause stack smashing,
when band_end becomes too large.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit bc4fee7f2a)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:05:54 +02:00
Andreas Cadhalpun
4aa4c78dae aacpsy: avoid psy_band->threshold becoming NaN
If band->thr is 0.0f, the division is undefined, making norm_fac not a
number or infinity, which causes psy_band->threshold to become NaN.

This is passed on to other variables until it finally reaches
sce->sf_idx and is converted to an integer (-2147483648).

This causes a segmentation fault when it is used as array index.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Reviewed-by: Claudio Freire <klaussfreire@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit e224aa4191)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:05:48 +02:00
Andreas Cadhalpun
7b13aef5d2 aasc: return correct buffer size from aasc_decode_frame
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 0be54ad280)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:05:41 +02:00
Andreas Cadhalpun
aebafed24f aacdec: consistently use avctx for logging in decode_eld_specific_config
ac may be NULL and then accessing ac->avctx results in a segmentation fault.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 5b75689b98)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:05:32 +02:00
Andreas Cadhalpun
4ea7ff4354 msrledec: use signed pixel_ptr in msrle_decode_pal4
This fixes segmentation faults, when pic->linesize[0] is negative.
In that case 'line * pic->linesize[0] + pixel_ptr' is treated as
unsigned and wraps around.

This reverts commit 7d78a964.
The problem was introduced in commit f7e1367f, which should obsolete
that commit.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit ae6fd7300b)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:05:11 +02:00
wm4
262c678357 matroskadec: export cover art correctly
Generally, libavformat exports cover art pictures as video streams with
1 packet and AV_DISPOSITION_ATTACHED_PIC set. Only matroskadec exported
it as attachment with codec_id set to AV_CODEC_ID_MJPEG.

Obviously, this should be consistent, so change the Matroska demuxer to
export a AV_DISPOSITION_ATTACHED_PIC pseudo video stream.

Matroska muxing is probably incorrect too. I know that it can create
broken files with an audio track and just 1 video frame when e.g.
remuxing mp3 with APIC to mkv. But for now this commit does not change
anything about muxing, and also continues to write attachments with
AV_CODEC_ID_MJPEG should the muxer application have special knowledge
that the Matroska is broken in this way.

Fixes trac #4423.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 511585ce7f)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:04:55 +02:00
Andreas Cadhalpun
763ab41f77 mxfenc: don't try to write footer without header
This fixes a crash, when trying to mux h264 into mxf_opatom.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Previous version reviewed-by: tomas.hardin@codemill.se
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

(cherry picked from commit b61cb61ab8)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:04:33 +02:00
Andreas Cadhalpun
76ee9fdb61 mxfenc: fix memleaks in mxf_write_footer
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Reviewed-by: tomas.hardin@codemill.se
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 39ddda12f1)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:04:17 +02:00
Martin Storsjö
692fd5635f rtpenc_mpegts: Set chain->rtp_ctx only after avformat_write_header succeeded
By making sure we at each time only have one pointer set, either a
local variable or one in the context, we avoid potential double frees
in the cleanup routines. If chain->rtp_ctx is set, it is closed by
calling avformat_write_trailer, but that shouldn't be called unless
avformat_write_header succeeded.

This issue was pointed out by Andreas Cadhalpun.

Signed-off-by: Martin Storsjö <martin@martin.st>
(cherry picked from commit cf402d6fa8)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:04:05 +02:00
Martin Storsjö
c3b1261afa rtpenc_mpegts: Free the right ->pb in the error path in the init function
This fixes a typo from 8e32b1f096.

Signed-off-by: Martin Storsjö <martin@martin.st>
(cherry picked from commit c83dd2d2a4)
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
2015-05-14 19:03:26 +02:00
James Almer
04fd0250e1 doc: add aarch64 cpuflags to fftools documentation
Signed-off-by: James Almer <jamrial@gmail.com>
(cherry picked from commit 9fc45681e0)
2015-04-11 16:21:31 -03:00
James Almer
6f236d3774 doc: add missing arm cpuflags to fftools documentation
Signed-off-by: James Almer <jamrial@gmail.com>
(cherry picked from commit 666ec9bd09)
2015-04-11 16:21:24 -03:00
James Almer
c1c245e1a3 doc: add missing x86 cpuflags to fftools documentation
Signed-off-by: James Almer <jamrial@gmail.com>
(cherry picked from commit 410c93cfd5)
2015-04-11 16:21:02 -03:00
Michael Niedermayer
369f46aae3 Update for 2.6.2
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-04-11 22:31:01 +02:00
Michael Niedermayer
05b448082a avcodec/h264: Do not fail with randomly truncated VUIs
Fixes Ticket4445

Tested-by: Vittorio Giovara <vittorio.giovara@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit bc48c88918)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-04-11 22:01:46 +02:00
Michael Niedermayer
b4bfbbfb95 avcodec/h264_ps: Move truncation check from VUI to SPS
This more completely checks for truncation

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 32e06c485b)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-04-11 22:01:46 +02:00
Michael Niedermayer
e6d9094fd3 avcodec/h264: Be more tolerant to changing pps id between slices
Fixes Ticket4446

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 98d0c4236c)

Conflicts:

	libavcodec/h264.c
2015-04-11 22:01:46 +02:00
Michael Niedermayer
bcc4c360aa avcodec/aacdec: Fix storing state before PCE decode
Fixes Ticket4460

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit e88b3852ae)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-04-11 22:01:46 +02:00
Michael Niedermayer
8be177e048 avcodec/h264: reset the counts in the correct context
Fixes null pointer dereference

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-04-11 22:01:46 +02:00
Michael Niedermayer
7d5908d5c8 avcodec/h264_slice: Dont reset mb_aff_frame per slice
Fixes null pointer dereference
Fixes Ticket4440

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 386601286f)

Conflicts:

	libavcodec/h264_slice.c
2015-04-11 22:01:46 +02:00
Michael Niedermayer
3550d239a6 avcodec/h264: finish previous slices before switching to single thread mode
Fixes null pointer dereference
Fixes Ticket4438

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit c4b2017ba6)

Conflicts:

	libavcodec/h264.c
2015-04-11 22:01:46 +02:00
Michael Niedermayer
d3f96c1e3c avcodec/h264: Fix race between slices where one overwrites data from the next
Fixes non deterministic crash in ticket4408/fuzz2.264
Likely fixes other samples as well

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 43b434210e)

Conflicts:

	libavcodec/h264.h
	libavcodec/h264_slice.c
2015-04-11 22:01:46 +02:00
Michael Niedermayer
ac07ab7db7 avformat/utils: avoid discarded streams in av_find_default_stream_index()
Fixes Ticket2010

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit ff6841c6bb)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-04-11 22:01:46 +02:00
Michael Niedermayer
9bff35abde ffmpeg: Fix extradata allocation
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 4d02dfbde4)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-04-11 22:01:46 +02:00
Michael Niedermayer
9ee7fcdcd0 avcodec/h264_refs: Do not set reference to things which dont exist
Fixes deadlock
Fixes Ticket4428
Fixes Ticket4429

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 429de04320)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-04-11 22:01:46 +02:00
Michael Niedermayer
f1b4a71ddf avcodec/h264: Fail for invalid mixed IDR / non IDR frames in slice threading mode
Fixes Ticket4408

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit fc58d5c43b)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-04-11 22:01:46 +02:00
Michael Niedermayer
fa538f1a8c Revert "avcodec/exr: fix memset first arg in reverse_lut()"
This reverts commit 586ba24ff2.

Fixes Ticket 4386

Found-by: Martin Vignali <martin.vignali@gmail.com>
(cherry picked from commit 5dd5b7d531)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-04-11 22:01:46 +02:00
Rainer Hochecker
7689fe5cfd h264: avoid unnecessary calls to get_format
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-04-11 22:01:46 +02:00
Michael Niedermayer
f597b9f04e avutil/pca: Check for av_malloc* failures
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit dadc43eee4)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-04-11 22:01:46 +02:00
James Almer
037d6cf580 avutil/cpu: add missing check for mmxext to av_force_cpu_flags
Reviewed-by: Michael Niedermayer <michaelni@gmx.at>
Signed-off-by: James Almer <jamrial@gmail.com>
(cherry picked from commit 1f5d1eed78)
2015-03-28 22:10:34 -03:00
Carl Eugen Hoyos
8bd7bf1a3c lavc/dnxhd: Fix pix_fmt change.
Fixes ticket #4400.
(cherry picked from commit dcac15a84c)
2015-03-28 20:01:22 +01:00
Micah Galizia
f90c9bbbca avformat/http: replace cookies with updated values instead of appending forever
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit c59654d67d)
Signed-off-by: Micah Galizia <micahgalizia@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-28 11:59:35 +01:00
Micah Galizia
f2abcdedfe avformat/hls: refactor repeated HLS option updates
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit fca0851879)
Signed-off-by: Micah Galizia <micahgalizia@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-28 11:59:24 +01:00
Micah Galizia
eebd161e76 avformat/hls: store cookies returned in HLS key response
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 7859618aff)
Signed-off-by: Micah Galizia <micahgalizia@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-28 11:59:09 +01:00
Michael Niedermayer
6a4d1325e2 avformat/rmdec: fix support for 0 sized mdpr
Fixes Ticket4393

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit df43d03731)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-28 11:59:05 +01:00
Michael Niedermayer
dfce316c12 avcodec/msrledec: restructure msrle_decode_pal4() based on the line number instead of the pixel pointer
Fixes out of array access
Fixes: da14e86d8462be6493eab16bc2d40f88/asan_heap-oob_204cfd2_528_cov_340150052_COMPRESS.BMP

Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit f7e1367f58)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-28 11:59:05 +01:00
Michael Niedermayer
87e2a689a8 avcodec/hevc_ps: Check cropping parameters more correctly
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 06c70d4537)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-28 11:59:04 +01:00
Anton Khirnov
e9eb9839bd hevc: make the crop sizes unsigned
(cherry picked from commit c929659bdd)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-28 11:59:04 +01:00
Michael Niedermayer
c3be71001c avcodec/dnxhddec: Reset is_444 if format is not 444
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit d3bd943108)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-28 11:59:04 +01:00
Michael Niedermayer
f3deed98ec avcodec/dnxhddec: Check that the frame is interlaced before using cur_field
Fixes Ticket4227

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 2c660e34cf)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-28 11:59:04 +01:00
James Cowgill
7439ed2f39 mips/float_dsp: fix vector_fmul_window_mips on mips64
Commit dfa9208074 ("mips/float_dsp: fix a bug in vector_fmul_window_mips")
fixed vector_fmul_window_mips by unrolling the loop only 4 times, but also
removed the outer C loop and replaced it with assembly branches and pointer
arithmetic. When submitting my 64-bit porting patch I missed this new
assembly which also needed porting.

This patch fixes a bus error in the fate-float-dsp test when run on 64-bit
mips.

Signed-off-by: James Cowgill <james410@cowgill.org.uk>
Reviewed-by: Nedeljko Babic <nedeljko.babic@imgtec.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit f8323744a0)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-28 11:59:04 +01:00
Carl Eugen Hoyos
40607290c9 doc: Remove non-existing decklink options.
Reported-by: Bostjan Hamler
(cherry picked from commit c5d0148c7e)
2015-03-24 09:58:11 +01:00
Carl Eugen Hoyos
a9e683bb7a doc: Fix alphabetic ordering for decklink input device.
(cherry picked from commit a47c2a1d5f)
2015-03-24 09:58:08 +01:00
Ronald S. Bultje
0edf9c6907 vp9: make above buffer pointer 32-byte aligned.
Fixes ticket #4383

Signed-off-by: James Almer <jamrial@gmail.com>
(cherry picked from commit 1fd1f58bd6)
2015-03-21 14:28:01 -03:00
Michael Niedermayer
b2c9cd36d3 Changelog: update for 2.6.1
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-16 20:09:11 +01:00
Michael Niedermayer
b3e6d3ee78 update for 2.6.1
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-16 19:45:24 +01:00
Michael Niedermayer
f6327e5fa6 avformat/mov: Disallow ".." in dref unless use_absolute_path is set
as this kind of allows to circumvent it to some extend.
We also could add a separate parameter or value to choose this

Found-by: ramiro
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 1e4d0498df)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-16 04:01:58 +01:00
Clément Bœsch
b80c486fb3 avfilter/palettegen: make sure at least one frame was sent to the filter
Fix FPE.

(cherry picked from commit 84da9339c2)
2015-03-15 19:10:20 +01:00
Michael Niedermayer
37469af294 avformat/mov: Check for string truncation in mov_open_dref()
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 8003816e16)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-14 21:59:47 +01:00
Michael Niedermayer
350054e8e2 avformat/mov: Use sizeof(filename) instead of a literal number
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 21a53dd08d)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-14 21:58:26 +01:00
Christophe Gisquet
7ff46a20d5 eac3dec: fix scaling
This is the remaining error, the output on the SPX samples,
respectively csi_miami_stereo_128_spx.eac3 and
csi_miami_5.1_256_spx.eac3, goes from:
stddev:    8.71 PSNR: 77.52 MAXDIFF:  235
stddev:24270.51 PSNR: 22.17 MAXDIFF:47166
to:
stddev:    0.12 PSNR:114.12 MAXDIFF:    1
stddev:    0.12 PSNR:114.73 MAXDIFF:    1

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 0c3339f4bd)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-14 14:26:28 +01:00
Christophe Gisquet
7edd380668 ac3_fixed: fix computation of spx_noise_blend
It was set to 1 instead of sqrt(3)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit c4bf3833f4)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-14 14:26:10 +01:00
Christophe Gisquet
26bed98d64 ac3_fixed: fix out-of-bound read
Should also improve decoding, but actually doesn't...

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit b083440060)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-14 14:21:27 +01:00
Andreas Cadhalpun
480e18e6ff ac3dec_fixed: always use the USE_FIXED=1 variant of the AC3DecodeContext
The AC3DecodeContext has a float (USE_FIXED=0) and an integer
(USE_FIXED=1) variant, both of which can be present in the same binary.
This is not only very confusing, but it also breaks horribly, when one
variant is used by code expecting the other.

This currently happens, because eac3dec.c is only compiled for the float
variant, but also used from ac3dec_fixed.c, which uses the integer
variant.

The result is memory corruption, leading to crashes.

So compile eac3dec.c once for each variant and adapt it, so that it
works with the integer variant.

A loss of precission and scaling bug has been fixed by the committer
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 7b05b5093e)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-14 04:42:15 +01:00
James Almer
742bc7eea8 hevcdsp: fix compilation for arm and aarch64
Also add av_cold to ff_hevcdsp_init_arm.

Signed-off-by: James Almer <jamrial@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit d5addf1555)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:32 +01:00
James Cowgill
c58edf52f9 mips/asmdefs: use _ABI64 as defined by gcc
Unfortunately android < api 21 (lollipop) doesn't have the sgidefs.h header,
the easiest way around this is to just use the preprocessor definitions from
gcc / clang.

Signed-off-by: James Cowgill <james410@cowgill.org.uk>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit a251aa1a35)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:32 +01:00
Rainer Hochecker
ea52c0614c hevc: delay ff_thread_finish_setup for hwaccel
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 31816eae32)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:32 +01:00
Michael Niedermayer
5e84ab838c avcodec/012v: redesign main loop
Fixes out of array accesses
Fixes: ffmpeg_012v_crash.ts

Found-by: Thomas Lindroth <thomas.lindroth@gmail.com>
Reviewed-by: Thomas Lindroth <thomas.lindroth@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 48df30d36c)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Michael Niedermayer
3f7b89937d avcodec/012v: Check dimensions more completely
Fixes division by 0

Found-by: Thomas Lindroth <thomas.lindroth@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit d3b25383da)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Andreas Cadhalpun
39c9b47bb6 asfenc: fix leaking asf->index_ptr on error
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 2c8cff2be4)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Andreas Cadhalpun
016bf7cb81 roqvideoenc: set enc->avctx in roq_encode_init
So far it is only set in roq_encode_frame, but it is used in
roq_encode_end to free the coded_frame. This currently segfaults if
roq_encode_frame is not called between roq_encode_init and
roq_encode_end.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit cf82c426fa)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Michael Niedermayer
bb00821f62 avcodec/options_table: remove extradata_size from the AVOptions table
allowing access to the size but not the extradata itself is not useful
and could lead to potential problems if writing happens through this field

Reviewed-by: Andreas Cadhalpun <andreas.cadhalpun@googlemail.com>
Reviewed-by: Lukasz Marek <lukasz.m.luki2@gmail.com>
Reviewed-by: Nicolas George <george@nsup.org>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 1f4088b285)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Andreas Cadhalpun
d9dbd2362d ffmdec: limit the backward seek to the last resync position
If resyncing leads to the same position as previously, it will again
lead to a resync attempt, resulting in an infinite loop.

Thus don't seek back beyond the last syncpoint.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 6b8263b03a)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Arwa Arif
ec684aa58a Add dependencies to configure file for vf_fftfilt
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit b4ec6afd3d)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Andreas Cadhalpun
a613dd627c ffmdec: make sure the time base is valid
A negative time base can trigger assertions.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 4c91d81be2)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Andreas Cadhalpun
1903d6d2b0 ffmdec: fix infinite loop at EOF
If EOF is reached, while skipping bytes, avio_tell(pb) won't change
anymore, resulting in an infinite loop.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 6fa98822eb)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Andreas Cadhalpun
2319fddfd3 ffmdec: initialize f_cprv, f_stvi and f_stau
They are used in a switch statement, but it is not guaranteed that the
COMM case (where they are set to 0) is reached before the other cases.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 66879ee125)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Martin Storsjö
5a6ef7d7cb configure: Move the .object_arch check to the right place
Signed-off-by: Martin Storsjö <martin@martin.st>
(cherry picked from commit b77e335e44)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Martin Storsjö
47e8d17132 arm: Suppress tags about used cpu arch and extensions
When all the codepaths using manually set .arch/.fpu code is
behind runtime detection, the elf attributes should be suppressed.

This allows tools to know that the final built binary doesn't
strictly require these extensions.

Signed-off-by: Martin Storsjö <martin@martin.st>
(cherry picked from commit dcae2e32f7)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Michael Niedermayer
a156f86e91 avcodec/tiff: move bpp check to after "end:"
This ensures that all current and future code-pathes get bpp checked

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit d5e9fc7821)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Andreas Cadhalpun
3586314147 doc: avoid the incorrect phrase 'allow to'
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 10fd7ff814)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Martin Storsjö
28e17ba220 mxfdec: Fix the error handling for when strftime fails
The str variable is a char ** here.

Signed-off-by: Martin Storsjö <martin@martin.st>
(cherry picked from commit 6448f15af0)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Michael Niedermayer
998173ed94 avcodec/opusdec: Fix delayed sample value
Fixes out of array access
Fixes: ffmpeg_opus_crash1.ogg

This solution is likely not optimal in terms of error concealment but
its simple and fixes the out of array access.

Found-by: Thomas Lindroth <thomas.lindroth@gmail.com>
Tested-by: Thomas Lindroth <thomas.lindroth@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 6c583e9048)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Michael Niedermayer
bffed1d9d0 avcodec/opusdec: Clear out pointers per packet
This is safer than to assume that all error pathes cleared them and
nothing will use uncleared pointers.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 1ae092587f)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Michael Niedermayer
52bf144ad9 avcodec/utils: Align YUV411 by as much as the other YUV variants
Fixes out of array accesses
Fixes: ffmpeg_mjpeg_crash2.avi

Found-by: Thomas Lindroth <thomas.lindroth@gmail.com>
Tested-by: Thomas Lindroth <thomas.lindroth@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit e3201c38d5)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Xiangyu Liu
6fc8c72c7d ChangeLog: Remove the redundant VP9 RTP entry
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit b1e9634c10)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-13 13:04:31 +01:00
Carl Eugen Hoyos
77621ca311 lavfi/boxblur: Fix colourspace list.
Fixes ticket #4363.
(cherry picked from commit 0637b59c2c)
2015-03-13 09:46:10 +01:00
Carl Eugen Hoyos
1a89aab3c0 lavf: Do not list mov-only codecs in riff.c.
Instead check for all mov code-points when demuxing avi
and print a warning if a video codec is found like this.
Fixes a regression similar to the one described in ticket #4307.
(cherry picked from commit 2e0b5f5c90)
2015-03-13 09:14:26 +01:00
Carl Eugen Hoyos
c43e5faf03 lavc/hevcdsp: Fix compilation for arm with --disable-neon.
(cherry picked from commit 1d523ea89a)
2015-03-10 15:00:08 +01:00
James Cowgill
876d2d8db8 mips/asmdefs: change include guard to read AVUTIL_ instead of AVCODEC_
Signed-off-by: James Cowgill <james410@cowgill.org.uk>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 3499a1c0a9)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-07 11:34:35 +01:00
Ronald S. Bultje
1caad74533 vp9: fix segmentation map retention with threading enabled.
Fixes ticket 4359.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit efff3854f0)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-07 10:38:07 +01:00
Michael Niedermayer
28950d1f8c Revert "avutil/opencl: is_compiled flag not being cleared in av_opencl_uninit"
Fixed build with opencl enabled
Found-by:  WJ Liu

This reverts commit 0f2359b869.
(cherry picked from commit ebd59d271c)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-07 10:38:07 +01:00
Reynaldo H. Verdejo Pinochet
791e085634 RELEASE_NOTES: small grammar fixes and improvements
Signed-off-by: Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
2015-03-06 22:15:47 -03:00
Clément Bœsch
3dc88e1fd6 Add release notes 2015-03-06 22:32:18 +01:00
Andreas Cadhalpun
4e2cab5a79 fix spelling errors
opttimizations -> optimizations
 grabing        -> grabbing
 many resource  -> many resources
 isnt           -> isn't
 silcense       -> silence

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 482c86f231)
2015-03-06 22:26:53 +01:00
Clément Bœsch
1dab67b647 avcodec/samidec: make sure to properly restore parsing context after a tag
(cherry picked from commit 70082a1e53)
2015-03-06 20:42:43 +01:00
Michael Niedermayer
0d4549c2d6 Add 2.6 to maintained releases
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 0bcb6ac150)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-06 17:49:22 +01:00
Michael Niedermayer
c741eb7d88 Update for 2.6
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
2015-03-06 17:32:52 +01:00
8518 changed files with 375018 additions and 1348256 deletions

79
.gitignore vendored
View File

@@ -1,6 +1,5 @@
*.a
*.o
*.o.*
*.d
*.def
*.dll
@@ -18,26 +17,74 @@
*.so.*
*.swp
*.ver
*.version
*.metal.air
*.metallib
*.metallib.c
*.ptx
*.ptx.c
*.ptx.gz
*-example
*-test
*_g
\#*
.\#*
/.config
/.version
/ffmpeg
/ffplay
/ffprobe
/config.asm
/config.h
/config_components.h
/ffserver
/config.*
/coverage.info
/doc/*.1
/doc/*.3
/doc/*.html
/doc/*.pod
/doc/config.texi
/doc/avoptions_codec.texi
/doc/avoptions_format.texi
/doc/doxy/html/
/doc/examples/avio_reading
/doc/examples/decoding_encoding
/doc/examples/demuxing_decoding
/doc/examples/extract_mvs
/doc/examples/filter_audio
/doc/examples/filtering_audio
/doc/examples/filtering_video
/doc/examples/metadata
/doc/examples/muxing
/doc/examples/pc-uninstalled
/doc/examples/remuxing
/doc/examples/resampling_audio
/doc/examples/scaling_video
/doc/examples/transcode_aac
/doc/examples/transcoding
/doc/fate.txt
/doc/print_options
/lcov/
/src
/mapfile
/tools/python/__pycache__/
/libavcodec/*_tablegen
/libavcodec/*_tables.c
/libavcodec/*_tables.h
/libavutil/avconfig.h
/libavutil/ffversion.h
/tests/audiogen
/tests/base64
/tests/data/
/tests/pixfmts.mak
/tests/rotozoom
/tests/test_copy.ffmeta
/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/sidxindex
/tools/trasher
/tools/seek_print
/tools/uncoded_frame
/tools/zmqsend

View File

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

View File

@@ -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.

View File

@@ -1,6 +1,6 @@
See the Git history of the project (https://git.ffmpeg.org/ffmpeg) to
See the Git history of the project (git://source.ffmpeg.org/ffmpeg) to
get the names of people who have contributed to FFmpeg.
To check the log, you can type the command "git log" in the FFmpeg
source directory, or browse the online repository at
https://git.ffmpeg.org/ffmpeg
http://source.ffmpeg.org.

1352
Changelog

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
## Installing FFmpeg
#Installing FFmpeg:
1. Type `./configure` to create the configuration. A list of configure
options is printed by running `configure --help`.
@@ -15,11 +15,3 @@ NOTICE
------
- Non system dependencies (e.g. libx264, libvpx) are disabled by default.
NOTICE for Package Maintainers
------------------------------
- It is recommended to build FFmpeg twice, first with minimal external dependencies so
that 3rd party packages, which depend on FFmpegs libavutil/libavfilter/libavcodec/libavformat
can then be built. And last build FFmpeg with full dependancies (which may in turn depend on
some of these 3rd party packages). This avoids circular dependencies during build.

View File

@@ -1,4 +1,4 @@
# License
#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
@@ -13,51 +13,45 @@ 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 following building and testing tools
- `compat/solaris/make_sunver.pl`
- `doc/t2h.pm`
- `doc/texi2pod.pl`
- `libswresample/tests/swresample.c`
- `tests/checkasm/*`
- `tests/tiny_ssim.c`
- optional x86 optimizations in the files
- `libavcodec/x86/flac_dsp_gpl.asm`
- `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:
- `signature_lookup.c`
- `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_lensfun.c` (GPL version 3 or later)
- `vf_mcdeint.c`
- `vf_mpdecimate.c`
- `vf_nnedi.c`
- `vf_owdenoise.c`
- `vf_perspective.c`
- `vf_phase.c`
- `vf_pp.c`
- `vf_pp7.c`
- `vf_pullup.c`
- `vf_repeatfields.c`
- `vf_sab.c`
- `vf_signature.c`
- `vf_smartblur.c`
- `vf_repeatfields.c`
- `vf_spp.c`
- `vf_stereo3d.c`
- `vf_super2xsai.c`
- `vf_tinterlace.c`
- `vf_uspp.c`
- `vf_vaguedenoiser.c`
- `vsrc_mptestsrc.c`
Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then
@@ -76,54 +70,41 @@ There are a handful of files under other licensing terms, namely:
* `tests/reference.pnm` is under the expat license.
## External libraries
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
compatible libraries
--------------------
The following libraries are under GPL version 2:
- avisynth
The following libraries are under GPL:
- frei0r
- libcdio
- libdavs2
- librubberband
- libutvideo
- libvidstab
- libx264
- libx265
- libxavs
- libxavs2
- libxvid
When combining them with FFmpeg, FFmpeg needs to be licensed as GPL as well by
passing `--enable-gpl` to configure.
The following libraries are under LGPL version 3:
- gmp
- libaribb24
- liblensfun
When combining them with FFmpeg, use the configure option `--enable-version3` to
upgrade FFmpeg to the LGPL v3.
The VMAF, mbedTLS, RK MPI, OpenCORE and VisualOn libraries are under the Apache License
2.0. That license is incompatible with the LGPL v2.1 and the GPL v2, but not with
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.
The smbclient library is under the GPL v3, to combine it with FFmpeg,
the options `--enable-gpl` and `--enable-version3` have to be passed to
configure to upgrade FFmpeg to the GPL v3.
incompatible libraries
----------------------
### Incompatible libraries
There are certain libraries you can combine with FFmpeg whose licenses are not
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. This will 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 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.

View File

@@ -6,38 +6,32 @@ FFmpeg code.
Please try to keep entries where you are the maintainer up to date!
*Status*, one of the following:
[X] Old code. Something tagged obsolete generally means it has been replaced by a better system and you should be using that.
[0] No current maintainer [but maybe you could take the role as you write your new code].
[1] It has a maintainer but they don't have time to do much other than throw the odd patch in.
[2] Someone actually looks after it.
Names in () mean that the maintainer currently has no time to maintain the code.
A (CC <address>) after the name means that the maintainer prefers to be CC-ed on
patches and related discussions.
(L <address>) *Mailing list* that is relevant to this area
(W <address>) *Web-page* with status/info
(B <address>) URI for where to file *bugs*. A web-page with detailed bug
filing info, a direct bug tracker link, or a mailto: URI.
(P <address>) *Subsystem Profile* document for more details submitting
patches to the given subsystem. This is either an in-tree file,
or a URI. See Documentation/maintainer/maintainer-entry-profile.rst
for details.
(T <address>) *SCM* tree type and location.
Type is one of: git, hg, quilt, stgit, topgit
Project Leader
==============
Michael Niedermayer
final design decisions
Applications
============
ffmpeg:
ffmpeg.c Michael Niedermayer, Anton Khirnov
ffmpeg.c Michael Niedermayer
ffplay:
ffplay.c [2] Marton Balint
ffplay.c Marton Balint
ffprobe:
ffprobe.c [2] Stefano Sabatini
ffprobe.c Stefano Sabatini
ffserver:
ffserver.c Reynaldo H. Verdejo Pinochet
Commandline utility code:
cmdutils.c, cmdutils.h Michael Niedermayer
@@ -49,26 +43,24 @@ QuickTime faststart:
Miscellaneous Areas
===================
documentation Stefano Sabatini, Mike Melanson, Timothy Gu, Gyan Doshi
project server day to day operations (L: root@ffmpeg.org) Árpád Gereöffy, Michael Niedermayer, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov, Timo Rothenpieler
project server emergencies (L: root@ffmpeg.org) Árpád Gereöffy, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov, Timo Rothenpieler
presets [0]
documentation Stefano Sabatini, Mike Melanson, Timothy Gu
build system (configure, makefiles) Diego Biurrun, Mans Rullgard
project server Árpád Gereöffy, Michael Niedermayer, Reimar Doeffinger, Alexander Strasser
presets Robert Swain
metadata subsystem Aurelien Jacobs
release management Michael Niedermayer
API tests [0]
samples-request [2] Thilo Borgmann, James Almer, Ben Littler
Communication
=============
website (T: https://git.ffmpeg.org/ffmpeg-web) Deby Barbara Lepage
fate.ffmpeg.org (L: fate-admin@ffmpeg.org) (W: https://fate.ffmpeg.org) (P: https://ffmpeg.org/fate.html) (S: https://git.ffmpeg.org/fateserver) Timo Rothenpieler
Trac bug tracker (W: https://trac.ffmpeg.org) Alexander Strasser, Michael Niedermayer, Carl Eugen Hoyos
Patchwork [2] (W: https://patchwork.ffmpeg.org) Andriy Gelman
mailing lists (W: https://ffmpeg.org/contact.html#MailingLists) Baptiste Coudurier
Twitter Reynaldo H. Verdejo Pinochet
website Deby Barbara Lepage
fate.ffmpeg.org Timothy Gu
Trac bug tracker Alexander Strasser, Michael Niedermayer, Carl Eugen Hoyos, Lou Logan
mailing lists Michael Niedermayer, Baptiste Coudurier, Lou Logan
Google+ Paul B Mahol, Michael Niedermayer, Alexander Strasser
Twitter Lou Logan
Launchpad Timothy Gu
ffmpeg-security [2] (L: ffmpeg-security@ffmpeg.org) (W: https://ffmpeg.org/security.html) Michael Niedermayer, Reimar Doeffinger
libavutil
@@ -80,27 +72,24 @@ Internal Interfaces:
libavutil/common.h Michael Niedermayer
Other:
aes_ctr.c, aes_ctr.h Eran Kornblau
bprint Nicolas George
bswap.h
des Reimar Doeffinger
dynarray.h Nicolas George
eval.c, eval.h [2] Michael Niedermayer
eval.c, eval.h Michael Niedermayer
float_dsp Loren Merritt
hash Reimar Doeffinger
hwcontext_cuda* Timo Rothenpieler
hwcontext_vulkan* [2] Lynne
intfloat* Michael Niedermayer
integer.c, integer.h Michael Niedermayer
lzo Reimar Doeffinger
mathematics.c, mathematics.h [2] Michael Niedermayer
mem.c, mem.h [2] Michael Niedermayer
mathematics.c, mathematics.h Michael Niedermayer
mem.c, mem.h Michael Niedermayer
opencl.c, opencl.h Wei Gao
opt.c, opt.h Michael Niedermayer
rational.c, rational.h [2] Michael Niedermayer
rational.c, rational.h Michael Niedermayer
rc4 Reimar Doeffinger
ripemd.c, ripemd.h James Almer
tx* [2] Lynne
timecode Clément Bœsch
libavcodec
@@ -122,20 +111,23 @@ Generic Parts:
DSP utilities:
dsputils.c, dsputils.h Michael Niedermayer
entropy coding:
rangecoder.c, rangecoder.h [2] Michael Niedermayer
rangecoder.c, rangecoder.h Michael Niedermayer
lzw.* Michael Niedermayer
floating point AAN DCT:
faandct.c, faandct.h [2] Michael Niedermayer
faandct.c, faandct.h Michael Niedermayer
Golomb coding:
golomb.c, golomb.h [2] Michael Niedermayer
golomb.c, golomb.h Michael Niedermayer
LPC:
lpc.c, lpc.h Justin Ruggles
motion estimation:
motion* Michael Niedermayer
rate control:
ratecontrol.c [2] Michael Niedermayer
ratecontrol.c Michael Niedermayer
libxvid_rc.c Michael Niedermayer
simple IDCT:
simple_idct.c, simple_idct.h [2] Michael Niedermayer
simple_idct.c, simple_idct.h Michael Niedermayer
postprocessing:
libpostproc/* [2] Michael Niedermayer
libpostproc/* Michael Niedermayer
table generation:
tableprint.c, tableprint.h Reimar Doeffinger
fixed point FFT:
@@ -143,45 +135,48 @@ Generic Parts:
Text Subtitles Clément Bœsch
Codecs:
4xm.c [2] Michael Niedermayer
4xm.c Michael Niedermayer
8bps.c Roberto Togni
8svx.c Jaikrishnan Menon
aacenc*, aaccoder.c Rostislav Pehlivanov
adpcm.c Zane van Iperen
aasc.c Kostya Shishkov
ac3* Justin Ruggles
alacenc.c Jaikrishnan Menon
alsdec.c Thilo Borgmann, Umair Khan
amfenc* Dmitrii Ovchinnikov
aptx.c Aurelien Jacobs
alsdec.c Thilo Borgmann
apedec.c Kostya Shishkov
ass* Aurelien Jacobs
asv* Michael Niedermayer
atrac3* Benjamin Larsson
atrac3plus* Maxim Poliakovski
audiotoolbox* rcombs
avs2* Huiwen Ren
bgmc.c, bgmc.h Thilo Borgmann
bink.c Kostya Shishkov
binkaudio.c Peter Ross
bmp.c Mans Rullgard, Kostya Shishkov
cavs* Stefan Gehrer
cdxl.c Paul B Mahol
celp_filters.* Vitor Sessak
cinepak.c Roberto Togni
cinepakenc.c Rl / Aetey G.T. AB
ccaption_dec.c Anshul Maheshwari, Aman Gupta
ccaption_dec.c Anshul Maheshwari
cljr Alex Beregszaszi
cllc.c Derek Buitenhuis
cook.c, cookdata.h Benjamin Larsson
cpia.c Stephan Hilb
crystalhd.c Philip Langdale
cscd.c Reimar Doeffinger
cuviddec.c Timo Rothenpieler
dca* foo86
dfpwm* Jack Bruienne
dirac* Rostislav Pehlivanov
dca.c Kostya Shishkov, Benjamin Larsson
dnxhd* Baptiste Coudurier
dolby_e* foo86
dpcm.c Mike Melanson
dss_sp.c Oleksij Rempel
dss_sp.c Oleksij Rempel, Michael Niedermayer
dv.c Roman Shaposhnik
dvbsubdec.c Anshul Maheshwari
dxa.c Kostya Shishkov
eacmv*, eaidct*, eat* Peter Ross
exif.c, exif.h Thilo Borgmann
ffv1* [2] Michael Niedermayer
ffv1* Michael Niedermayer
ffwavesynth.c Nicolas George
fifo.c Jan Sebechlebsky
fic.c Derek Buitenhuis
flac* Justin Ruggles
flashsv* Benjamin Larsson
flicvideo.c Mike Melanson
g722.c Martin Storsjo
g726.c Roman Shaposhnik
@@ -189,55 +184,59 @@ Codecs:
h261* Michael Niedermayer
h263* Michael Niedermayer
h264* Loren Merritt, Michael Niedermayer
hap* Tom Butterworth
hevc/* Anton Khirnov
huffyuv* Michael Niedermayer
huffyuv* Michael Niedermayer, Christophe Gisquet
idcinvideo.c Mike Melanson
imc* Benjamin Larsson
indeo2* Kostya Shishkov
indeo5* Kostya Shishkov
interplayvideo.c Mike Melanson
jni*, ffjni* Matthieu Bouron
ivi* Kostya Shishkov
jacosub* Clément Bœsch
jpeg2000* Nicolas Bertrand
jpegxl* Leo Izen
jpeg_ls.c Kostya Shishkov
jvdec.c Peter Ross
kmvc.c Kostya Shishkov
lcl*.c Roberto Togni, Reimar Doeffinger
libcelt_dec.c Nicolas George
libcodec2.c Tomas Härdin
libdirac* David Conrad
libdavs2.c Huiwen Ren
libjxl*.c, libjxl.h Leo Izen
libgsm.c Michel Bardiaux
libkvazaar.c Arttu Ylä-Outinen
libopenh264enc.c Martin Storsjo, Linjie Fu
libopenjpeg.c Jaikrishnan Menon
libopenjpegenc.c Michael Bradshaw
libschroedinger* David Conrad
libspeexdec.c Justin Ruggles
libtheoraenc.c David Conrad
libutvideo* Derek Buitenhuis
libvorbis.c David Conrad
libvpx* James Zern
libx264.c Mans Rullgard, Jason Garrett-Glaser
libx265.c Derek Buitenhuis
libxavs.c Stefan Gehrer
libxavs2.c Huiwen Ren
libzvbi-teletextdec.c Marton Balint
loco.c Kostya Shishkov
lzo.h, lzo.c Reimar Doeffinger
mdec.c Michael Niedermayer
mimic.c Ramiro Polla
mjpeg*.c Michael Niedermayer
mlp* Ramiro Polla, Jai Luthra
mlp* Ramiro Polla
mmvideo.c Peter Ross
mpc* Kostya Shishkov
mpeg12.c, mpeg12data.h Michael Niedermayer
mpegvideo.c, mpegvideo.h Michael Niedermayer
mqc* Nicolas Bertrand
msmpeg4.c, msmpeg4data.h Michael Niedermayer
msrle.c Mike Melanson
msrleenc.c Tomas Härdin
msvideo1.c Mike Melanson
nellymoserdec.c Benjamin Larsson
nuv.c Reimar Doeffinger
nvdec*, nvenc* Timo Rothenpieler
omx.c Martin Storsjo, Aman Gupta
opus* Rostislav Pehlivanov
nvenc.c Timo Rothenpieler
paf.* Paul B Mahol
pcx.c Ivo van Poorten
pgssubdec.c Reimar Doeffinger
ptx.c Ivo van Poorten
qcelp* Reynaldo H. Verdejo Pinochet
qdm2.c, qdm2data.h Roberto Togni
qsv* Mark Thompson, Zhong Li, Haihao Xiang
qdm2.c, qdm2data.h Roberto Togni, Benjamin Larsson
qdrw.c Kostya Shishkov
qpeg.c Kostya Shishkov
qtrle.c Mike Melanson
ra144.c, ra144.h, ra288.c, ra288.h Roberto Togni
resample2.c Michael Niedermayer
@@ -245,44 +244,65 @@ Codecs:
rpza.c Roberto Togni
rtjpeg.c, rtjpeg.h Reimar Doeffinger
rv10.c Michael Niedermayer
rv3* Kostya Shishkov
rv4* Kostya Shishkov, Christophe Gisquet
s3tc* Ivo van Poorten
smacker.c Kostya Shishkov
smc.c Mike Melanson
smvjpegdec.c Ash Hughes
snow* Michael Niedermayer, Loren Merritt
sonic.c Alex Beregszaszi
speedhq.c Steinar H. Gunderson
srt* Aurelien Jacobs
sunrast.c Ivo van Poorten
svq3.c Michael Niedermayer
tak* Paul B Mahol
targa.c Kostya Shishkov
tiff.c Kostya Shishkov
truemotion1* Mike Melanson
truemotion2* Kostya Shishkov
truespeech.c Kostya Shishkov
tscc.c Kostya Shishkov
tta.c Alex Beregszaszi, Jaikrishnan Menon
ttaenc.c Paul B Mahol
txd.c Ivo van Poorten
v4l2_* Jorge Ramirez-Ortiz
vc2* Rostislav Pehlivanov
ulti* Kostya Shishkov
v410*.c Derek Buitenhuis
vb.c Kostya Shishkov
vble.c Derek Buitenhuis
vc1* Kostya Shishkov, Christophe Gisquet
vcr1.c Michael Niedermayer
videotoolboxenc.c Rick Kern, Aman Gupta
vda_h264_dec.c Xidorn Quan
vima.c Paul B Mahol
vmnc.c Kostya Shishkov
vorbisdec.c Denes Balatoni, David Conrad
vorbisenc.c Oded Shimon
vp3* Mike Melanson
vp5 Aurelien Jacobs
vp6 Aurelien Jacobs
vp8 David Conrad, Ronald Bultje
vp9 Ronald Bultje
vp8 David Conrad, Jason Garrett-Glaser, Ronald Bultje
vp9 Ronald Bultje, Clément Bœsch
vqavideo.c Mike Melanson
vvc [2] Nuo Mi
wavpack.c Kostya Shishkov
wmaprodec.c Sascha Sommer
wmavoice.c Ronald S. Bultje
wmv2.c Michael Niedermayer
wnv1.c Kostya Shishkov
xan.c Mike Melanson
xbm* Paul B Mahol
xface Stefano Sabatini
xl.c Kostya Shishkov
xvmc.c Ivan Kalvachev
xwd* Paul B Mahol
zerocodec.c Derek Buitenhuis
zmbv* Kostya Shishkov
Hardware acceleration:
dxva2* Hendrik Leppkes, Laurent Aimar, Steve Lhomme
d3d11va* Steve Lhomme
d3d12va_encode* Tong Wu
mediacodec* Matthieu Bouron, Aman Gupta, Zhao Zhili
vaapi* Haihao Xiang
vaapi_encode* Mark Thompson, Haihao Xiang
vdpau* Philip Langdale, Carl Eugen Hoyos
videotoolbox* Rick Kern, Aman Gupta, Zhao Zhili
crystalhd.c Philip Langdale
dxva2* Laurent Aimar
libstagefright.cpp Mohamed Naufal
vaapi* Gwenole Beauchesne
vda* Sebastien Zwickert
vdpau* Carl Eugen Hoyos
libavdevice
@@ -292,8 +312,7 @@ libavdevice
avfoundation.m Thilo Borgmann
android_camera.c Felix Matouschek
decklink* Marton Balint
decklink* Deti Fliegl
dshow.c Roger Pack (CC rogerdpack@gmail.com)
fbdev_enc.c Lukasz Marek
gdigrab.c Roger Pack (CC rogerdpack@gmail.com)
@@ -302,8 +321,8 @@ libavdevice
libdc1394.c Roman Shaposhnik
opengl_enc.c Lukasz Marek
pulse_audio_enc.c Lukasz Marek
qtkit.m Thilo Borgmann
sdl Stefano Sabatini
sdl2.c Josh de Kock
v4l2.c Giorgio Vazzana
vfwcap.c Ramiro Polla
xv.c Lukasz Marek
@@ -314,43 +333,44 @@ libavfilter
Generic parts:
graphdump.c Nicolas George
motion_estimation.c Davinder Singh
Filters:
af_adelay.c Paul B Mahol
af_aecho.c Paul B Mahol
af_afade.c Paul B Mahol
af_amerge.c Nicolas George
af_aphaser.c Paul B Mahol
af_aresample.c Michael Niedermayer
af_astats.c Paul B Mahol
af_astreamsync.c Nicolas George
af_atempo.c Pavel Koshevoy
af_firequalizer.c Muhammad Faiz
af_hdcd.c Burt P.
af_loudnorm.c Kyle Swanson
af_biquads.c Paul B Mahol
af_compand.c Paul B Mahol
af_ladspa.c Paul B Mahol
af_pan.c Nicolas George
af_silenceremove.c Paul B Mahol
avf_avectorscope.c Paul B Mahol
avf_showcqt.c Muhammad Faiz
vf_bwdif Thomas Mundt (CC <thomas.mundt@hr.de>)
vf_chromakey.c Timo Rothenpieler
vf_colorconstancy.c Mina Sami (CC <minas.gorgy@gmail.com>)
vf_colorkey.c Timo Rothenpieler
vf_coreimage.m Thilo Borgmann
vf_blend.c Paul B Mahol
vf_colorbalance.c Paul B Mahol
vf_dejudder.c Nicholas Robbins
vf_delogo.c Jean Delvare (CC <jdelvare@suse.com>)
vf_delogo.c Jean Delvare (CC <khali@linux-fr.org>)
vf_drawbox.c/drawgrid Andrey Utkin
vf_fsync.c Thilo Borgmann
vf_extractplanes.c Paul B Mahol
vf_histogram.c Paul B Mahol
vf_hqx.c Clément Bœsch
vf_idet.c Pascal Massimino
vf_(t)interlace Thomas Mundt (CC <thomas.mundt@hr.de>)
vf_il.c Paul B Mahol
vf_lenscorrection.c Daniel Oberhoff
vf_libplacebo.c Niklas Haas
vf_mestimate.c Davinder Singh
vf_minterpolate.c Davinder Singh
vf_readvitc.c Tobias Rapp (CC t.rapp at noa-archive dot com)
vf_scale.c [2] Michael Niedermayer
vf_tonemap_opencl.c Ruiling Song
vf_yadif.c [2] Michael Niedermayer
vf_xfade_vulkan.c [2] Marvin Scholz (CC <epirat07@gmail.com>)
vf_mergeplanes.c Paul B Mahol
vf_psnr.c Paul B Mahol
vf_scale.c Michael Niedermayer
vf_separatefields.c Paul B Mahol
vf_stereo3d.c Paul B Mahol
vf_telecine.c Paul B Mahol
vf_yadif.c Michael Niedermayer
Sources:
vsrc_mandelbrot.c [2] Michael Niedermayer
dnn Yejun Guo
vsrc_mandelbrot.c Michael Niedermayer
libavformat
===========
@@ -360,80 +380,75 @@ Generic parts:
libavformat/avformat.h Michael Niedermayer
Utility Code:
libavformat/utils.c Michael Niedermayer
Text Subtitles Clément Bœsch
Muxers/Demuxers:
4xm.c Mike Melanson
aadec.c Vesselin Bontchev (vesselin.bontchev at yandex dot com)
adtsenc.c [0]
adtsenc.c Robert Swain
afc.c Paul B Mahol
aiffdec.c Baptiste Coudurier, Matthieu Bouron
aiffenc.c Baptiste Coudurier, Matthieu Bouron
alp.c Zane van Iperen
amvenc.c Zane van Iperen
apm.c Zane van Iperen
ape.c Kostya Shishkov
apngdec.c Benoit Fouet
argo_asf.c Zane van Iperen
argo_brp.c Zane van Iperen
argo_cvg.c Zane van Iperen
ass* Aurelien Jacobs
astdec.c Paul B Mahol
astenc.c James Almer
avi* Michael Niedermayer
avisynth.c Stephen Hutchinson
avisynth.c AvxSynth Team (avxsynth.testing at gmail dot com)
avr.c Paul B Mahol
bink.c Peter Ross
boadec.c Michael Niedermayer
brstm.c Paul B Mahol
caf* Peter Ross
codec2.c Tomas Härdin
cdxl.c Paul B Mahol
crc.c Michael Niedermayer
dashdec.c Steven Liu
dashenc.c Karthick Jeyapal
daud.c Reimar Doeffinger
dfpwmdec.c Jack Bruienne
dss.c Oleksij Rempel
dtsdec.c foo86
dss.c Oleksij Rempel, Michael Niedermayer
dtshddec.c Paul B Mahol
dv.c Roman Shaposhnik
dvdvideodec.c Marth64
dxa.c Kostya Shishkov
electronicarts.c Peter Ross
evc* Samsung (Dawid Kozinski)
epafdec.c Paul B Mahol
ffm* Baptiste Coudurier
flac* Justin Ruggles
flic.c Mike Melanson
flvdec.c Michael Niedermayer
flvenc.c Michael Niedermayer, Steven Liu
flvdec.c, flvenc.c Michael Niedermayer
gxf.c Reimar Doeffinger
gxfenc.c Baptiste Coudurier
hlsenc.c Christian Suloway, Steven Liu
iamf* [2] James Almer
hls.c Anssi Hannula
idcin.c Mike Melanson
idroqdec.c Mike Melanson
iff.c Jaikrishnan Menon
imf* Pierre-Anthony Lemieux
img2*.c Michael Niedermayer
ipmovie.c Mike Melanson
ircam* Paul B Mahol
iss.c Stefan Gehrer
jpegxl* Leo Izen
jacosub* Clément Bœsch
jvdec.c Peter Ross
kvag.c Zane van Iperen
libmodplug.c Clément Bœsch
libopenmpt.c Josh de Kock
libnut.c Oded Shimon
lmlm4.c Ivo van Poorten
lvfdec.c Paul B Mahol
lxfdec.c Tomas Härdin
matroska.c Andreas Rheinhardt
matroskadec.c Andreas Rheinhardt
matroskaenc.c Andreas Rheinhardt
matroska.c Aurelien Jacobs
matroskadec.c Aurelien Jacobs
matroskaenc.c David Conrad
matroska subtitles (matroskaenc.c) John Peebles
metadata* Aurelien Jacobs
mgsts.c Paul B Mahol
microdvd* Aurelien Jacobs
mm.c Peter Ross
mov.c Baptiste Coudurier
mov.c Michael Niedermayer, Baptiste Coudurier
movenc.c Baptiste Coudurier, Matthieu Bouron
movenccenc.c Eran Kornblau
mpc.c Kostya Shishkov
mpeg.c Michael Niedermayer
mpegenc.c Michael Niedermayer
mpegts.c Marton Balint
mpegtsenc.c Baptiste Coudurier
msnwc_tcp.c Ramiro Polla
mtv.c Reynaldo H. Verdejo Pinochet
mxf* Baptiste Coudurier, Tomas Härdin
mxf* Baptiste Coudurier
mxfdec.c Tomas Härdin
nistspheredec.c Paul B Mahol
nsvdec.c Francois Revol
nut* Michael Niedermayer
nuv.c Reimar Doeffinger
@@ -441,15 +456,16 @@ Muxers/Demuxers:
oggenc.c Baptiste Coudurier
oggparse*.c David Conrad
oma.c Maxim Poliakovski
pp_bnk.c Zane van Iperen
paf.c Paul B Mahol
psxstr.c Mike Melanson
pva.c Ivo van Poorten
pvfdec.c Paul B Mahol
r3d.c Baptiste Coudurier
raw.c Michael Niedermayer
rcwtenc.c Marth64
rdt.c Ronald S. Bultje
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
rtpdec_ac3.* Gilles Chanteperdrix
rtpdec_dv.* Thomas Volkert
@@ -457,17 +473,20 @@ Muxers/Demuxers:
rtpdec_hevc.*, rtpenc_hevc.* Thomas Volkert
rtpdec_mpa_robust.* Gilles Chanteperdrix
rtpdec_asf.* Ronald S. Bultje
rtpdec_vc2hq.*, rtpenc_vc2hq.* Thomas Volkert
rtpdec_vp9.c Thomas Volkert
rtpenc_mpv.*, rtpenc_aac.* Martin Storsjo
s337m.c foo86
rtsp.c Luca Barbato
sbgdec.c Nicolas George
sdp.c Martin Storsjo
segafilm.c Mike Melanson
segment.c Stefano Sabatini
siff.c Kostya Shishkov
smacker.c Kostya Shishkov
smjpeg* Paul B Mahol
spdif* Anssi Hannula
srtdec.c Aurelien Jacobs
swf.c Baptiste Coudurier
takdec.c Paul B Mahol
tta.c Alex Beregszaszi
txd.c Ivo van Poorten
voc.c Aurelien Jacobs
@@ -477,104 +496,69 @@ Muxers/Demuxers:
webvtt* Matthew J Heaney
westwood.c Mike Melanson
wtv.c Peter Ross
wv.c Kostya Shishkov
wvenc.c Paul B Mahol
Protocols:
async.c Zhang Rui
bluray.c Petri Hintukainen
ftp.c Lukasz Marek
http.c Ronald S. Bultje
libsrt.c Zhao Zhili
libssh.c Lukasz Marek
libzmq.c Andriy Gelman
mms*.c Ronald S. Bultje
udp.c Luca Abeni
icecast.c [2] Marvin Scholz (CC <epirat07@gmail.com>)
icecast.c Marvin Scholz
libswresample
=============
Generic parts:
audioconvert.c [2] Michael Niedermayer
dither.c [2] Michael Niedermayer
rematrix*.c [2] Michael Niedermayer
swresample*.c [2] Michael Niedermayer
audioconvert.c Michael Niedermayer
dither.c Michael Niedermayer
rematrix*.c Michael Niedermayer
swresample*.c Michael Niedermayer
Resamplers:
resample*.c [2] Michael Niedermayer
resample*.c Michael Niedermayer
soxr_resample.c Rob Sykes
Operating systems / CPU architectures
=====================================
*BSD [2] Brad Smith
Alpha [0]
MIPS Manojkumar Bhosale, Shiyou Yin
LoongArch [2] Shiyou Yin
Mac OS X / PowerPC [0]
Alpha Mans Rullgard, Falk Hueffner
ARM Mans Rullgard
AVR32 Mans Rullgard
MIPS Mans Rullgard, Nedeljko Babic
Mac OS X / PowerPC Romain Dolbeau, Guillaume Poirier
Amiga / PowerPC Colin Ward
Linux / PowerPC [1] Lauri Kasanen
RISC-V [2] Rémi Denis-Courmont
Linux / PowerPC Luca Barbato
Windows MinGW Alex Beregszaszi, Ramiro Polla
Windows Cygwin Victor Paesa
Windows MSVC Hendrik Leppkes
Windows MSVC Matthew Oliver
Windows ICL Matthew Oliver
ADI/Blackfin DSP Marc Hoffman
Sparc Roman Shaposhnik
OS/2 KO Myung-Hun
Developers with git write access who are currently not maintaining any specific part
====================================================================================
Alex Converse
Andreas Cadhalpun
Anuradha Suraparaju
Ben Littler
Benjamin Larsson
Bobby Bingham
Daniel Verkamp
Derek Buitenhuis
Fei Wang
Ganesh Ajjanagadde
Henrik Gramner
Ivan Uskov
James Darnley
Jan Ekström
Joakim Plate
Jun Zhao
Kieran Kunhya
Kirill Gavrilov
Limin Wang
Martin Storsjö
Panagiotis Issaris
Pedro Arthur
Sebastien Zwickert
Vittorio Giovara
wm4
(this list is incomplete)
x86 Michael Niedermayer
Releases
========
7.0 Michael Niedermayer
6.1 Michael Niedermayer
5.1 Michael Niedermayer
4.4 Michael Niedermayer
3.4 Michael Niedermayer
2.8 Michael Niedermayer
2.6 Michael Niedermayer
2.5 Michael Niedermayer
2.4 Michael Niedermayer
2.2 Michael Niedermayer
If you want to maintain an older release, please contact us
GnuPG Fingerprints and IRC nicknames of maintainers and contributors
====================================================================
IRC nicknames are in parentheses. These apply
to the IRC channels listed on the website.
GnuPG Fingerprints of maintainers and contributors
==================================================
Alexander Strasser 1C96 78B7 83CB 8AA7 9AF5 D1EB A7D8 A57B A876 E58F
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
Attila Kinali 11F0 F9A6 A1D2 11F6 C745 D10C 6520 BCDD F2DF E765
Baptiste Coudurier 8D77 134D 20CC 9220 201F C5DB 0AC9 325C 5C1A BAAA
@@ -582,38 +566,27 @@ Ben Littler 3EE3 3723 E560 3214 A8CD 4DEB 2CDB FCE7 768C 8D2C
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
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
Ganesh Ajjanagadde C96A 848E 97C3 CEA2 AB72 5CE4 45F9 6A2D 3C36 FB1B
Gwenole Beauchesne 2E63 B3A6 3E44 37E2 017D 2704 53C7 6266 B153 99C4
Haihao Xiang (haihao) 1F0C 31E8 B4FE F7A4 4DC1 DC99 E0F5 76D4 76FC 437F
Jaikrishnan Menon 61A1 F09F 01C9 2D45 78E1 C862 25DC 8831 AF70 D368
James Almer 7751 2E8C FD94 A169 57E6 9A7A 1463 01AD 7376 59E0
Jean Delvare 7CA6 9F44 60F1 BDC4 1FD2 C858 A552 6B9B B3CD 4E6A
Leo Izen (Traneptora) B6FD 3CFC 7ACF 83FC 9137 6945 5A71 C331 FD2F A19A
Leo Izen (Traneptora) 1D83 0A0B CE46 709E 203B 26FC 764E 48EA 4822 1833
Justin Ruggles 3136 ECC0 C10D 6C04 5F43 CA29 FCBE CD2A 3787 1EBF
Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE
Lynne FE50 139C 6805 72CA FD52 1F8D A2FE A5F0 3F03 4464
Lou Logan 7D68 DC73 CBEF EABB 671A B6CF 621C 2E28 82F8 DC3A
Luca Barbato 6677 4209 213C 8843 5B67 29E7 E84C 78C2 84E9 0E34
Michael Niedermayer 9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB
DD1E C9E8 DE08 5C62 9B3E 1846 B18E 8928 B394 8D64
Nicolas George 24CE 01CE 9ACC 5CEB 74D8 8D9D B063 D997 36E5 4C93
Niklas Haas (haasn) 1DDB 8076 B14D 5B48 32FC 99D9 EB52 DA9C 02BA 6FB4
Nikolay Aleksandrov 8978 1D8C FB71 588E 4B27 EAA8 C4F0 B5FC E011 13B1
Panagiotis Issaris 6571 13A3 33D9 3726 F728 AA98 F643 B12E ECF3 E029
Peter Ross A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B
Philip Langdale 5DC5 8D66 5FBA 3A43 18EC 045E F8D6 B194 6A75 682E
Pierre-Anthony Lemieux (pal) F4B3 9492 E6F2 E4AF AEC8 46CB 698F A1F0 F8D4 EED4
Ramiro Polla 7859 C65B 751B 1179 792E DAE8 8E95 8B2F 9B6C 5700
Reimar Doeffinger C61D 16E5 9E2C D10C 8958 38A4 0899 A2B9 06D4 D9C7
Reinhard Tartler 9300 5DC2 7E87 6C37 ED7B CA9A 9808 3544 9453 48A4
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
Sascha Sommer 38A0 F88B 868E 9D3A 97D4 D6A0 E823 706F 1E07 0D3C
Stefano Sabatini 0D0B AD6B 5330 BBAD D3D6 6A0C 719C 2839 FC43 2D5F
Steinar H. Gunderson C2E9 004F F028 C18E 4EAD DB83 7F61 7561 7797 8F76
Stephan Hilb 4F38 0B3A 5F39 B99B F505 E562 8D5C 5554 4E17 8863
Thilo Borgmann (thilo) CE1D B7F4 4D20 FC3A DD9F FE5A 257C 5B8F 1D20 B92F
Tiancheng "Timothy" Gu 9456 AFC0 814A 8139 E994 8351 7FE6 B095 B582 B0D4
Tim Nicholson 38CF DB09 3ED0 F607 8B67 6CED 0C0B FC44 8B0B FC83
Tomas Härdin (thardin) A79D 4E3D F38F 763F 91F5 8B33 A01E 8AE0 41BB 2551
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
Zane van Iperen (zane) 61AE D40F 368B 6F26 9DAE 3892 6861 6B2D 8AC4 DCC5

196
Makefile
View File

@@ -1,31 +1,50 @@
MAIN_MAKEFILE=1
include ffbuild/config.mak
include config.mak
vpath %.c $(SRC_PATH)
vpath %.cpp $(SRC_PATH)
vpath %.h $(SRC_PATH)
vpath %.inc $(SRC_PATH)
vpath %.m $(SRC_PATH)
vpath %.S $(SRC_PATH)
vpath %.asm $(SRC_PATH)
vpath %.rc $(SRC_PATH)
vpath %.v $(SRC_PATH)
vpath %.texi $(SRC_PATH)
vpath %.cu $(SRC_PATH)
vpath %.ptx $(SRC_PATH)
vpath %.metal $(SRC_PATH)
vpath %/fate_config.sh.template $(SRC_PATH)
TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64 audiomatch
HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options
AVPROGS-$(CONFIG_FFMPEG) += ffmpeg
AVPROGS-$(CONFIG_FFPLAY) += ffplay
AVPROGS-$(CONFIG_FFPROBE) += ffprobe
AVPROGS-$(CONFIG_FFSERVER) += ffserver
ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale swresample
AVPROGS := $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
INSTPROGS = $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
PROGS += $(AVPROGS)
AVBASENAMES = ffmpeg ffplay ffprobe ffserver
ALLAVPROGS = $(AVBASENAMES:%=%$(PROGSSUF)$(EXESUF))
ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
$(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog) += cmdutils.o))
$(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog)-$(CONFIG_OPENCL) += cmdutils_opencl.o))
OBJS-ffmpeg += ffmpeg_opt.o ffmpeg_filter.o
OBJS-ffmpeg-$(HAVE_VDPAU_X11) += ffmpeg_vdpau.o
OBJS-ffmpeg-$(HAVE_DXVA2_LIB) += ffmpeg_dxva2.o
OBJS-ffmpeg-$(CONFIG_VDA) += ffmpeg_vda.o
OBJS-ffserver += ffserver_config.o
TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64
HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options
TOOLS = qt-faststart trasher uncoded_frame
TOOLS-$(CONFIG_ZLIB) += cws2fws
# $(FFLIBS-yes) needs to be in linking order
FFLIBS-$(CONFIG_AVDEVICE) += avdevice
FFLIBS-$(CONFIG_AVFILTER) += avfilter
FFLIBS-$(CONFIG_AVFORMAT) += avformat
FFLIBS-$(CONFIG_AVCODEC) += avcodec
FFLIBS-$(CONFIG_AVRESAMPLE) += avresample
FFLIBS-$(CONFIG_POSTPROC) += postproc
FFLIBS-$(CONFIG_SWRESAMPLE) += swresample
FFLIBS-$(CONFIG_SWSCALE) += swscale
@@ -33,78 +52,36 @@ FFLIBS-$(CONFIG_SWSCALE) += swscale
FFLIBS := avutil
DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.ffpreset) $(SRC_PATH)/doc/ffprobe.xsd
EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/Makefile $(SRC_PATH)/doc/examples/README
SKIPHEADERS = compat/w32pthreads.h
SKIPHEADERS = cmdutils_common_opts.h compat/w32pthreads.h
# first so "all" becomes default target
all: all-yes
include $(SRC_PATH)/tools/Makefile
include $(SRC_PATH)/ffbuild/common.mak
include $(SRC_PATH)/common.mak
FF_EXTRALIBS := $(FFEXTRALIBS)
FF_DEP_LIBS := $(DEP_LIBS)
FF_STATIC_DEP_LIBS := $(STATIC_DEP_LIBS)
$(TOOLS): %$(EXESUF): %.o
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(filter-out $(FF_DEP_LIBS), $^) $(EXTRALIBS-$(*F)) $(EXTRALIBS) $(ELIBS)
all: $(AVPROGS)
target_dec_%_fuzzer$(EXESUF): target_dec_%_fuzzer.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
$(TOOLS): %$(EXESUF): %.o $(EXEOBJS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS)
target_enc_%_fuzzer$(EXESUF): target_enc_%_fuzzer.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
tools/target_bsf_%_fuzzer$(EXESUF): tools/target_bsf_%_fuzzer.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
target_dem_%_fuzzer$(EXESUF): target_dem_%_fuzzer.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
tools/target_dem_fuzzer$(EXESUF): tools/target_dem_fuzzer.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
tools/target_io_dem_fuzzer$(EXESUF): tools/target_io_dem_fuzzer.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
tools/target_sws_fuzzer$(EXESUF): tools/target_sws_fuzzer.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
tools/target_swr_fuzzer$(EXESUF): tools/target_swr_fuzzer.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
tools/enum_options$(EXESUF): ELIBS = $(FF_EXTRALIBS)
tools/enum_options$(EXESUF): $(FF_DEP_LIBS)
tools/enc_recon_frame_test$(EXESUF): $(FF_DEP_LIBS)
tools/enc_recon_frame_test$(EXESUF): ELIBS = $(FF_EXTRALIBS)
tools/scale_slice_test$(EXESUF): $(FF_DEP_LIBS)
tools/scale_slice_test$(EXESUF): ELIBS = $(FF_EXTRALIBS)
tools/sofa2wavs$(EXESUF): ELIBS = $(FF_EXTRALIBS)
tools/cws2fws$(EXESUF): ELIBS = $(ZLIB)
tools/uncoded_frame$(EXESUF): $(FF_DEP_LIBS)
tools/uncoded_frame$(EXESUF): ELIBS = $(FF_EXTRALIBS)
tools/target_dec_%_fuzzer$(EXESUF): $(FF_DEP_LIBS)
tools/target_dem_%_fuzzer$(EXESUF): $(FF_DEP_LIBS)
CONFIGURABLE_COMPONENTS = \
$(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c)) \
$(SRC_PATH)/libavcodec/bitstream_filters.c \
$(SRC_PATH)/libavcodec/hwaccels.h \
$(SRC_PATH)/libavcodec/parsers.c \
$(SRC_PATH)/libavformat/protocols.c \
config_components.h: ffbuild/.config
ffbuild/.config: $(CONFIGURABLE_COMPONENTS)
config.h: .config
.config: $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c))
@-tput bold 2>/dev/null
@-printf '\nWARNING: $(?) newer than config_components.h, rerun configure\n\n'
@-printf '\nWARNING: $(?F) newer than config.h, rerun configure\n\n'
@-tput sgr0 2>/dev/null
SUBDIR_VARS := CLEANFILES FFLIBS HOSTPROGS TESTPROGS TOOLS \
SUBDIR_VARS := CLEANFILES EXAMPLES FFLIBS HOSTPROGS TESTPROGS TOOLS \
HEADERS ARCH_HEADERS BUILT_HEADERS SKIPHEADERS \
ARMV5TE-OBJS ARMV6-OBJS ARMV8-OBJS VFP-OBJS NEON-OBJS \
ALTIVEC-OBJS VSX-OBJS MMX-OBJS X86ASM-OBJS \
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSP-OBJS MSA-OBJS \
MMI-OBJS LSX-OBJS LASX-OBJS RV-OBJS RVV-OBJS RVVB-OBJS \
OBJS SLIBOBJS SHLIBOBJS STLIBOBJS HOSTOBJS TESTOBJS
ALTIVEC-OBJS MMX-OBJS YASM-OBJS \
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSPR1-OBJS \
OBJS SLIBOBJS HOSTOBJS TESTOBJS
define RESET
$(1) :=
@@ -117,88 +94,97 @@ SUBDIR := $(1)/
include $(SRC_PATH)/$(1)/Makefile
-include $(SRC_PATH)/$(1)/$(ARCH)/Makefile
-include $(SRC_PATH)/$(1)/$(INTRINSICS)/Makefile
include $(SRC_PATH)/ffbuild/library.mak
include $(SRC_PATH)/library.mak
endef
$(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D))))
include $(SRC_PATH)/fftools/Makefile
include $(SRC_PATH)/doc/Makefile
include $(SRC_PATH)/doc/examples/Makefile
$(ALLFFLIBS:%=lib%/version.o): libavutil/ffversion.h
define DOPROG
OBJS-$(1) += $(1).o $(EXEOBJS) $(OBJS-$(1)-yes)
$(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1))
$$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1))
$(1)$(PROGSSUF)_g$(EXESUF): LDFLAGS += $(LDFLAGS-$(1))
$(1)$(PROGSSUF)_g$(EXESUF): FF_EXTRALIBS += $(LIBS-$(1))
-include $$(OBJS-$(1):.o=.d)
endef
$(foreach P,$(PROGS),$(eval $(call DOPROG,$(P:$(PROGSSUF)$(EXESUF)=))))
ffprobe.o cmdutils.o libavcodec/utils.o libavformat/utils.o libavdevice/avdevice.o libavfilter/avfilter.o libavutil/utils.o libpostproc/postprocess.o libswresample/swresample.o libswscale/utils.o : libavutil/ffversion.h
$(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF)
ifeq ($(STRIPTYPE),direct)
$(STRIP) -o $@ $<
else
$(RM) $@
$(CP) $< $@
$(STRIP) $@
endif
%$(PROGSSUF)_g$(EXESUF): $(FF_DEP_LIBS)
%$(PROGSSUF)_g$(EXESUF): %.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS)
VERSION_SH = $(SRC_PATH)/ffbuild/version.sh
ifeq ($(VERSION_TRACKING),yes)
GIT_LOG = $(SRC_PATH)/.git/logs/HEAD
endif
OBJDIRS += tools
.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) ffbuild/config.mak
-include $(wildcard tools/*.d)
VERSION_SH = $(SRC_PATH)/version.sh
GIT_LOG = $(SRC_PATH)/.git/logs/HEAD
.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) config.mak
.version: M=@
ifneq ($(VERSION_TRACKING),yes)
libavutil/ffversion.h .version: REVISION=unknown
endif
libavutil/ffversion.h .version:
$(M)revision=$(REVISION) $(VERSION_SH) $(SRC_PATH) libavutil/ffversion.h $(EXTRA_VERSION)
$(M)$(VERSION_SH) $(SRC_PATH) libavutil/ffversion.h $(EXTRA_VERSION)
$(Q)touch .version
# force version.sh to run whenever version might have changed
-include .version
ifdef AVPROGS
install: install-progs install-data
endif
install: install-libs install-headers
install-libs: install-libs-yes
install-data: $(DATA_FILES)
$(Q)mkdir -p "$(DATADIR)"
$(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)"
install-progs-yes:
install-progs-$(CONFIG_SHARED): install-libs
uninstall: uninstall-data uninstall-headers uninstall-libs uninstall-pkgconfig
install-progs: install-progs-yes $(AVPROGS)
$(Q)mkdir -p "$(BINDIR)"
$(INSTALL) -c -m 755 $(INSTPROGS) "$(BINDIR)"
install-data: $(DATA_FILES) $(EXAMPLES_FILES)
$(Q)mkdir -p "$(DATADIR)/examples"
$(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)"
$(INSTALL) -m 644 $(EXAMPLES_FILES) "$(DATADIR)/examples"
uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data
uninstall-progs:
$(RM) $(addprefix "$(BINDIR)/", $(ALLAVPROGS))
uninstall-data:
$(RM) -r "$(DATADIR)"
clean::
$(RM) $(ALLAVPROGS) $(ALLAVPROGS_G)
$(RM) $(CLEANSUFFIXES)
$(RM) $(addprefix compat/,$(CLEANSUFFIXES)) $(addprefix compat/*/,$(CLEANSUFFIXES)) $(addprefix compat/*/*/,$(CLEANSUFFIXES))
$(RM) $(CLEANSUFFIXES:%=tools/%)
$(RM) -r coverage-html
$(RM) -rf coverage.info coverage.info.in lcov
$(RM) -rf coverage.info lcov
distclean:: clean
$(RM) .version config.asm config.h config_components.h mapfile \
ffbuild/.config ffbuild/config.* libavutil/avconfig.h \
version.h libavutil/ffversion.h libavcodec/codec_names.h \
libavcodec/bsf_list.c libavformat/protocol_list.c \
libavcodec/codec_list.c libavcodec/parser_list.c \
libavfilter/filter_list.c libavdevice/indev_list.c libavdevice/outdev_list.c \
libavformat/muxer_list.c libavformat/demuxer_list.c
ifeq ($(SRC_LINK),src)
$(RM) src
endif
$(RM) -rf doc/examples/pc-uninstalled
distclean::
$(RM) $(DISTCLEANSUFFIXES)
$(RM) config.* .config libavutil/avconfig.h .version version.h libavutil/ffversion.h libavcodec/codec_names.h
config:
$(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION)
build: all alltools examples testprogs
check: all alltools examples testprogs fate
include $(SRC_PATH)/tests/Makefile
$(sort $(OUTDIRS)):
$(sort $(OBJDIRS)):
$(Q)mkdir -p $@
# Dummy rule to stop make trying to rebuild removed or renamed headers
@@ -209,5 +195,5 @@ $(sort $(OUTDIRS)):
# so this saves some time on slow systems.
.SUFFIXES:
.PHONY: all all-yes alltools build check config testprogs
.PHONY: *clean install* uninstall*
.PHONY: all all-yes alltools check *clean config install*
.PHONY: testprogs uninstall*

View File

@@ -9,26 +9,28 @@ such as audio, video, subtitles and related metadata.
* `libavcodec` provides implementation of a wider range of codecs.
* `libavformat` implements streaming protocols, container formats and basic I/O access.
* `libavutil` includes hashers, decompressors and miscellaneous utility functions.
* `libavfilter` provides means to alter decoded audio and video through a directed graph of connected filters.
* `libavfilter` provides a mean to alter decoded Audio and Video through chain of filters.
* `libavdevice` provides an abstraction to access capture and playback devices.
* `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
* [ffmpeg](http://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
* [ffplay](http://ffmpeg.org/ffplay.html) is a minimalistic multimedia player.
* [ffprobe](http://ffmpeg.org/ffprobe.html) is a simple analysis tool to inspect
multimedia content.
* [ffserver](http://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).
The online documentation is available in the main [website](http://ffmpeg.org)
and in the [wiki](http://trac.ffmpeg.org).
### Examples
@@ -38,9 +40,3 @@ Coding examples are available in the **doc/examples** directory.
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.

View File

@@ -1 +1 @@
7.1.2
2.6.3

View File

@@ -1,15 +1,65 @@
──────────────────────────────────────┐
│ RELEASE NOTES for FFmpeg 7.1 "Péter" │
──────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ RELEASE NOTES for FFmpeg 2.6 "Grothendieck" │
└─────────────────────────────────────────────┘
The FFmpeg Project proudly presents FFmpeg 7.1 "Péter", about 6
months after the release of FFmpeg 7.0.
The FFmpeg Project proudly presents FFmpeg 2.6 "Grothendieck", about 3
months after the release of FFmpeg 2.5.
A complete Changelog is available at the root of the project, and the
complete Git history on https://git.ffmpeg.org/gitweb/ffmpeg.git
A lot of important work got in this time, so let's start talking about what
we like to brag the most about: features.
A lot of people will probably be happy to hear that we now have support for
NVENC — the Nvidia Video Encoder interface for H.264 encoding — thanks to
Timo Rothenpieler, with some little help from NVIDIA and Philip Langdale.
People in the broadcasting industry might also be interested in the first
steps of closed captions support with the introduction of a decoder by
Anshul Maheswhwari.
Regarding filters love, we improved and added many. We could talk about the
10-bit support in spp, but maybe it's more important to mention the addition
of colorlevels (yet another color handling filter), tblend (allowing you
to for example run a diff between successive frames of a video stream), or
the dcshift audio filter.
There are also two other important filters landing in libavfilter: palettegen
and paletteuse. Both submitted by the Stupeflix company. These filters will
be very useful in case you are looking for creating high quality GIFs, a
format that still bravely fights annihilation in 2015.
There are many other new features, but let's follow-up on one big cleanup
achievement: the libmpcodecs (MPlayer filters) wrapper is finally dead. The
last remaining filters (softpulldown/repeatfields, eq*, and various
postprocessing filters) were ported by Arwa Arif (OPW student) and Paul B
Mahol.
Concerning API changes, there are not many things to mention. Though, the
introduction of device inputs and outputs listing by Lukasz Marek is a
notable addition (try ffmpeg -sources or ffmpeg -sinks for an example of
the usage). As usual, see doc/APIchanges for more information.
Now let's talk about optimizations. Ronald S. Bultje made the VP9 decoder
usable on x86 32-bit systems and pre-ssse3 CPUs like Phenom (even dual core
Athlons can play 1080p 30fps VP9 content now), so we now secretly hope for
Google and Mozilla to use ffvp9 instead of libvpx. But VP9 is not the
center of attention anymore, and HEVC/H.265 is also getting many
improvements, which include C and x86 ASM optimizations, mainly from James
Almer, Christophe Gisquet and Pierre-Edouard Lepere.
Even though we had many x86 contributions, it is not the only architecture
getting some love, with Seppo Tomperi adding ARM NEON optimizations to the
HEVC stack, and James Cowgill adding MIPS64 assembly for all kind of audio
processing code in libavcodec.
And finally, Michael Niedermayer is still fixing many bugs, dealing with
most of the boring work such as making releases, applying tons of
contributors patches, and daily merging the changes from the Libav project.
A more 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.libera.chat) or ask
feel free to join us on the #ffmpeg IRC channel (on irc.freenode.net) or ask
on the mailing-lists.

14
arch.mak Normal file
View File

@@ -0,0 +1,14 @@
OBJS-$(HAVE_ARMV5TE) += $(ARMV5TE-OBJS) $(ARMV5TE-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_NEON) += $(NEON-OBJS) $(NEON-OBJS-yes)
OBJS-$(HAVE_MIPSFPU) += $(MIPSFPU-OBJS) $(MIPSFPU-OBJS-yes)
OBJS-$(HAVE_MIPSDSPR1) += $(MIPSDSPR1-OBJS) $(MIPSDSPR1-OBJS-yes)
OBJS-$(HAVE_MIPSDSPR2) += $(MIPSDSPR2-OBJS) $(MIPSDSPR2-OBJS-yes)
OBJS-$(HAVE_ALTIVEC) += $(ALTIVEC-OBJS) $(ALTIVEC-OBJS-yes)
OBJS-$(HAVE_MMX) += $(MMX-OBJS) $(MMX-OBJS-yes)
OBJS-$(HAVE_YASM) += $(YASM-OBJS) $(YASM-OBJS-yes)

2231
cmdutils.c Normal file

File diff suppressed because it is too large Load Diff

600
cmdutils.h Normal file
View File

@@ -0,0 +1,600 @@
/*
* Various utilities for command line tools
* copyright (c) 2003 Fabrice Bellard
*
* 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 FFMPEG_CMDUTILS_H
#define FFMPEG_CMDUTILS_H
#include <stdint.h>
#include "config.h"
#include "libavcodec/avcodec.h"
#include "libavfilter/avfilter.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#ifdef _WIN32
#undef main /* We don't want SDL to override our main() */
#endif
/**
* program name, defined by the program for show_version().
*/
extern const char program_name[];
/**
* program birth year, defined by the program for show_banner()
*/
extern const int program_birth_year;
extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
extern AVFormatContext *avformat_opts;
extern struct SwsContext *sws_opts;
extern AVDictionary *swr_opts;
extern AVDictionary *format_opts, *codec_opts, *resample_opts;
extern int hide_banner;
/**
* Register a program-specific cleanup routine.
*/
void register_exit(void (*cb)(int ret));
/**
* Wraps exit with a program-specific cleanup routine.
*/
void exit_program(int ret) av_noreturn;
/**
* Initialize the cmdutils option system, in particular
* allocate the *_opts contexts.
*/
void init_opts(void);
/**
* Uninitialize the cmdutils option system, in particular
* free the *_opts contexts and their contents.
*/
void uninit_opts(void);
/**
* Trivial log callback.
* Only suitable for opt_help and similar since it lacks prefix handling.
*/
void log_callback_help(void* ptr, int level, const char* fmt, va_list vl);
/**
* Override the cpuflags.
*/
int opt_cpuflags(void *optctx, const char *opt, const char *arg);
/**
* Fallback for options that are not explicitly handled, these will be
* parsed through AVOptions.
*/
int opt_default(void *optctx, const char *opt, const char *arg);
/**
* Set the libav* libraries log level.
*/
int opt_loglevel(void *optctx, const char *opt, const char *arg);
int opt_report(const char *opt);
int opt_max_alloc(void *optctx, const char *opt, const char *arg);
int opt_codec_debug(void *optctx, const char *opt, const char *arg);
#if CONFIG_OPENCL
int opt_opencl(void *optctx, const char *opt, const char *arg);
int opt_opencl_bench(void *optctx, const char *opt, const char *arg);
#endif
/**
* Limit the execution time.
*/
int opt_timelimit(void *optctx, const char *opt, const char *arg);
/**
* Parse a string and return its corresponding value as a double.
* Exit from the application if the string cannot be correctly
* parsed or the corresponding value is invalid.
*
* @param context the context of the value to be set (e.g. the
* corresponding command line option name)
* @param numstr the string to be parsed
* @param type the type (OPT_INT64 or OPT_FLOAT) as which the
* string should be parsed
* @param min the minimum valid accepted value
* @param max the maximum valid accepted value
*/
double parse_number_or_die(const char *context, const char *numstr, int type,
double min, double max);
/**
* Parse a string specifying a time and return its corresponding
* value as a number of microseconds. Exit from the application if
* the string cannot be correctly parsed.
*
* @param context the context of the value to be set (e.g. the
* corresponding command line option name)
* @param timestr the string to be parsed
* @param is_duration a flag which tells how to interpret timestr, if
* not zero timestr is interpreted as a duration, otherwise as a
* date
*
* @see av_parse_time()
*/
int64_t parse_time_or_die(const char *context, const char *timestr,
int is_duration);
typedef struct SpecifierOpt {
char *specifier; /**< stream/chapter/program/... specifier */
union {
uint8_t *str;
int i;
int64_t i64;
float f;
double dbl;
} u;
} SpecifierOpt;
typedef struct OptionDef {
const char *name;
int flags;
#define HAS_ARG 0x0001
#define OPT_BOOL 0x0002
#define OPT_EXPERT 0x0004
#define OPT_STRING 0x0008
#define OPT_VIDEO 0x0010
#define OPT_AUDIO 0x0020
#define OPT_INT 0x0080
#define OPT_FLOAT 0x0100
#define OPT_SUBTITLE 0x0200
#define OPT_INT64 0x0400
#define OPT_EXIT 0x0800
#define OPT_DATA 0x1000
#define OPT_PERFILE 0x2000 /* the option is per-file (currently ffmpeg-only).
implied by OPT_OFFSET or OPT_SPEC */
#define OPT_OFFSET 0x4000 /* option is specified as an offset in a passed optctx */
#define OPT_SPEC 0x8000 /* option is to be stored in an array of SpecifierOpt.
Implies OPT_OFFSET. Next element after the offset is
an int containing element count in the array. */
#define OPT_TIME 0x10000
#define OPT_DOUBLE 0x20000
#define OPT_INPUT 0x40000
#define OPT_OUTPUT 0x80000
union {
void *dst_ptr;
int (*func_arg)(void *, const char *, const char *);
size_t off;
} u;
const char *help;
const char *argname;
} OptionDef;
/**
* Print help for all options matching specified flags.
*
* @param options a list of options
* @param msg title of this group. Only printed if at least one option matches.
* @param req_flags print only options which have all those flags set.
* @param rej_flags don't print options which have any of those flags set.
* @param alt_flags print only options that have at least one of those flags set
*/
void show_help_options(const OptionDef *options, const char *msg, int req_flags,
int rej_flags, int alt_flags);
/**
* Show help for all options with given flags in class and all its
* children.
*/
void show_help_children(const AVClass *class, int flags);
/**
* Per-fftool specific help handler. Implemented in each
* fftool, called by show_help().
*/
void show_help_default(const char *opt, const char *arg);
/**
* Generic -h handler common to all fftools.
*/
int show_help(void *optctx, const char *opt, const char *arg);
/**
* Parse the command line arguments.
*
* @param optctx an opaque options context
* @param argc number of command line arguments
* @param argv values of command line arguments
* @param options Array with the definitions required to interpret every
* option of the form: -option_name [argument]
* @param parse_arg_function Name of the function called to process every
* argument without a leading option name flag. NULL if such arguments do
* not have to be processed.
*/
void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
void (* parse_arg_function)(void *optctx, const char*));
/**
* Parse one given option.
*
* @return on success 1 if arg was consumed, 0 otherwise; negative number on error
*/
int parse_option(void *optctx, const char *opt, const char *arg,
const OptionDef *options);
/**
* An option extracted from the commandline.
* Cannot use AVDictionary because of options like -map which can be
* used multiple times.
*/
typedef struct Option {
const OptionDef *opt;
const char *key;
const char *val;
} Option;
typedef struct OptionGroupDef {
/**< group name */
const char *name;
/**
* Option to be used as group separator. Can be NULL for groups which
* are terminated by a non-option argument (e.g. ffmpeg output files)
*/
const char *sep;
/**
* Option flags that must be set on each option that is
* applied to this group
*/
int flags;
} OptionGroupDef;
typedef struct OptionGroup {
const OptionGroupDef *group_def;
const char *arg;
Option *opts;
int nb_opts;
AVDictionary *codec_opts;
AVDictionary *format_opts;
AVDictionary *resample_opts;
struct SwsContext *sws_opts;
AVDictionary *swr_opts;
} OptionGroup;
/**
* A list of option groups that all have the same group type
* (e.g. input files or output files)
*/
typedef struct OptionGroupList {
const OptionGroupDef *group_def;
OptionGroup *groups;
int nb_groups;
} OptionGroupList;
typedef struct OptionParseContext {
OptionGroup global_opts;
OptionGroupList *groups;
int nb_groups;
/* parsing state */
OptionGroup cur_group;
} OptionParseContext;
/**
* Parse an options group and write results into optctx.
*
* @param optctx an app-specific options context. NULL for global options group
*/
int parse_optgroup(void *optctx, OptionGroup *g);
/**
* Split the commandline into an intermediate form convenient for further
* processing.
*
* The commandline is assumed to be composed of options which either belong to a
* group (those with OPT_SPEC, OPT_OFFSET or OPT_PERFILE) or are global
* (everything else).
*
* A group (defined by an OptionGroupDef struct) is a sequence of options
* terminated by either a group separator option (e.g. -i) or a parameter that
* is not an option (doesn't start with -). A group without a separator option
* must always be first in the supplied groups list.
*
* All options within the same group are stored in one OptionGroup struct in an
* OptionGroupList, all groups with the same group definition are stored in one
* OptionGroupList in OptionParseContext.groups. The order of group lists is the
* same as the order of group definitions.
*/
int split_commandline(OptionParseContext *octx, int argc, char *argv[],
const OptionDef *options,
const OptionGroupDef *groups, int nb_groups);
/**
* Free all allocated memory in an OptionParseContext.
*/
void uninit_parse_context(OptionParseContext *octx);
/**
* Find the '-loglevel' option in the command line args and apply it.
*/
void parse_loglevel(int argc, char **argv, const OptionDef *options);
/**
* Return index of option opt in argv or 0 if not found.
*/
int locate_option(int argc, char **argv, const OptionDef *options,
const char *optname);
/**
* Check if the given stream matches a stream specifier.
*
* @param s Corresponding format context.
* @param st Stream from s to be checked.
* @param spec A stream specifier of the [v|a|s|d]:[\<stream index\>] form.
*
* @return 1 if the stream matches, 0 if it doesn't, <0 on error
*/
int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec);
/**
* Filter out options for given codec.
*
* Create a new options dictionary containing only the options from
* opts which apply to the codec with ID codec_id.
*
* @param opts dictionary to place options in
* @param codec_id ID of the codec that should be filtered for
* @param s Corresponding format context.
* @param st A stream from s for which the options should be filtered.
* @param codec The particular codec for which the options should be filtered.
* If null, the default one is looked up according to the codec id.
* @return a pointer to the created dictionary
*/
AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
AVFormatContext *s, AVStream *st, AVCodec *codec);
/**
* Setup AVCodecContext options for avformat_find_stream_info().
*
* Create an array of dictionaries, one dictionary for each stream
* contained in s.
* Each dictionary will contain the options from codec_opts which can
* be applied to the corresponding stream codec context.
*
* @return pointer to the created array of dictionaries, NULL if it
* cannot be created
*/
AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
AVDictionary *codec_opts);
/**
* Print an error message to stderr, indicating filename and a human
* readable description of the error code err.
*
* If strerror_r() is not available the use of this function in a
* multithreaded application may be unsafe.
*
* @see av_strerror()
*/
void print_error(const char *filename, int err);
/**
* Print the program banner to stderr. The banner contents depend on the
* current version of the repository and of the libav* libraries used by
* the program.
*/
void show_banner(int argc, char **argv, const OptionDef *options);
/**
* Print the version of the program to stdout. The version message
* depends on the current versions of the repository and of the libav*
* libraries.
* This option processing function does not utilize the arguments.
*/
int show_version(void *optctx, const char *opt, const char *arg);
/**
* Print the build configuration of the program to stdout. The contents
* depend on the definition of FFMPEG_CONFIGURATION.
* This option processing function does not utilize the arguments.
*/
int show_buildconf(void *optctx, const char *opt, const char *arg);
/**
* Print the license of the program to stdout. The license depends on
* the license of the libraries compiled into the program.
* This option processing function does not utilize the arguments.
*/
int show_license(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the formats supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_formats(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the devices supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_devices(void *optctx, const char *opt, const char *arg);
#if CONFIG_AVDEVICE
/**
* Print a listing containing audodetected 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 audodetected sources of the input device.
* Device name with options may be passed as an argument to limit results.
*/
int show_sources(void *optctx, const char *opt, const char *arg);
#endif
/**
* Print a listing containing all the codecs supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_codecs(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the decoders supported by the
* program.
*/
int show_decoders(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the encoders supported by the
* program.
*/
int show_encoders(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the filters supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_filters(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the bit stream filters supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_bsfs(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the protocols supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_protocols(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the pixel formats supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_pix_fmts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the standard channel layouts supported by
* the program.
* This option processing function does not utilize the arguments.
*/
int show_layouts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the sample formats supported by the
* program.
*/
int show_sample_fmts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the color names and values recognized
* by the program.
*/
int show_colors(void *optctx, const char *opt, const char *arg);
/**
* Return a positive value if a line read from standard input
* starts with [yY], otherwise return 0.
*/
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.
*
* If is_path is non-zero, look for the file in the path preset_name.
* Otherwise search for a file named arg.ffpreset in the directories
* $FFMPEG_DATADIR (if set), $HOME/.ffmpeg, and in the datadir defined
* at configuration time or in a "ffpresets" folder along the executable
* on win32, in that order. If no such file is found and
* codec_name is defined, then search for a file named
* codec_name-preset_name.avpreset in the above-mentioned directories.
*
* @param filename buffer where the name of the found filename is written
* @param filename_size size in bytes of the filename buffer
* @param preset_name name of the preset to search
* @param is_path tell if preset_name is a filename path
* @param codec_name name of the codec for which to look for the
* preset, may be NULL
*/
FILE *get_preset_file(char *filename, size_t filename_size,
const char *preset_name, int is_path, const char *codec_name);
/**
* Realloc array to hold new_size elements of elem_size.
* Calls exit() on failure.
*
* @param array array to reallocate
* @param elem_size size in bytes of each element
* @param size new element count will be written here
* @param new_size number of elements to place in reallocated array
* @return reallocated array
*/
void *grow_array(void *array, int elem_size, int *size, int new_size);
#define media_type_string av_get_media_type_string
#define GROW_ARRAY(array, nb_elems)\
array = grow_array(array, sizeof(*array), &nb_elems, nb_elems + 1)
#define GET_PIX_FMT_NAME(pix_fmt)\
const char *name = av_get_pix_fmt_name(pix_fmt);
#define GET_SAMPLE_FMT_NAME(sample_fmt)\
const char *name = av_get_sample_fmt_name(sample_fmt)
#define GET_SAMPLE_RATE_NAME(rate)\
char name[16];\
snprintf(name, sizeof(name), "%d", rate);
#define GET_CH_LAYOUT_NAME(ch_layout)\
char name[16];\
snprintf(name, sizeof(name), "0x%"PRIx64, ch_layout);
#define GET_CH_LAYOUT_DESC(ch_layout)\
char name[128];\
av_get_channel_layout_string(name, sizeof(name), 0, ch_layout);
#endif /* CMDUTILS_H */

35
cmdutils_common_opts.h Normal file
View File

@@ -0,0 +1,35 @@
{ "L" , OPT_EXIT, {.func_arg = show_license}, "show license" },
{ "h" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" },
{ "?" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" },
{ "help" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" },
{ "-help" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" },
{ "version" , OPT_EXIT, {.func_arg = show_version}, "show version" },
{ "buildconf" , OPT_EXIT, {.func_arg = show_buildconf}, "show build configuration" },
{ "formats" , OPT_EXIT, {.func_arg = show_formats }, "show available formats" },
{ "devices" , OPT_EXIT, {.func_arg = show_devices }, "show available devices" },
{ "codecs" , OPT_EXIT, {.func_arg = show_codecs }, "show available codecs" },
{ "decoders" , OPT_EXIT, {.func_arg = show_decoders }, "show available decoders" },
{ "encoders" , OPT_EXIT, {.func_arg = show_encoders }, "show available encoders" },
{ "bsfs" , OPT_EXIT, {.func_arg = show_bsfs }, "show available bit stream filters" },
{ "protocols" , OPT_EXIT, {.func_arg = show_protocols}, "show available protocols" },
{ "filters" , OPT_EXIT, {.func_arg = show_filters }, "show available filters" },
{ "pix_fmts" , OPT_EXIT, {.func_arg = show_pix_fmts }, "show available pixel formats" },
{ "layouts" , OPT_EXIT, {.func_arg = show_layouts }, "show standard channel layouts" },
{ "sample_fmts", OPT_EXIT, {.func_arg = show_sample_fmts }, "show available audio sample formats" },
{ "colors" , OPT_EXIT, {.func_arg = show_colors }, "show available color names" },
{ "loglevel" , HAS_ARG, {.func_arg = opt_loglevel}, "set logging level", "loglevel" },
{ "v", HAS_ARG, {.func_arg = opt_loglevel}, "set logging level", "loglevel" },
{ "report" , 0, {(void*)opt_report}, "generate a report" },
{ "max_alloc" , HAS_ARG, {.func_arg = opt_max_alloc}, "set maximum size of a single allocated block", "bytes" },
{ "cpuflags" , HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpuflags }, "force specific cpu flags", "flags" },
{ "hide_banner", OPT_BOOL | OPT_EXPERT, {&hide_banner}, "do not show program banner", "hide_banner" },
#if CONFIG_OPENCL
{ "opencl_bench", OPT_EXIT, {.func_arg = opt_opencl_bench}, "run benchmark on all OpenCL devices and show results" },
{ "opencl_options", HAS_ARG, {.func_arg = opt_opencl}, "set OpenCL environment options" },
#endif
#if CONFIG_AVDEVICE
{ "sources" , OPT_EXIT | HAS_ARG, { .func_arg = show_sources },
"list sources of the input device", "device" },
{ "sinks" , OPT_EXIT | HAS_ARG, { .func_arg = show_sinks },
"list sinks of the output device", "device" },
#endif

276
cmdutils_opencl.c Normal file
View File

@@ -0,0 +1,276 @@
/*
* 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)
{
return ((OpenCLDeviceBenchmark*)a)->runtime - ((OpenCLDeviceBenchmark*)b)->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;
}

162
common.mak Normal file
View File

@@ -0,0 +1,162 @@
#
# common bits used by all libraries
#
# first so "all" becomes default target
all: all-yes
DEFAULT_YASMD=.dbg
ifeq (1, DBG)
YASMD=$(DEFAULT_YASMD)
else
YASMD=
endif
ifndef SUBDIR
ifndef V
Q = @
ECHO = printf "$(1)\t%s\n" $(2)
BRIEF = CC CXX HOSTCC HOSTLD AS YASM AR LD STRIP CP WINDRES
SILENT = DEPCC DEPHOSTCC DEPAS DEPYASM RANLIB RM
MSG = $@
M = @$(call ECHO,$(TAG),$@);
$(foreach VAR,$(BRIEF), \
$(eval override $(VAR) = @$$(call ECHO,$(VAR),$$(MSG)); $($(VAR))))
$(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR))))
$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL))
endif
ALLFFLIBS = avcodec avdevice avfilter avformat avresample avutil postproc swscale swresample
# NASM requires -I path terminated with /
IFLAGS := -I. -I$(SRC_PATH)/
CPPFLAGS := $(IFLAGS) $(CPPFLAGS)
CFLAGS += $(ECFLAGS)
CCFLAGS = $(CPPFLAGS) $(CFLAGS)
ASFLAGS := $(CPPFLAGS) $(ASFLAGS)
CXXFLAGS += $(CPPFLAGS) $(CFLAGS)
YASMFLAGS += $(IFLAGS:%=%/) -Pconfig.asm
HOSTCCFLAGS = $(IFLAGS) $(HOSTCPPFLAGS) $(HOSTCFLAGS)
LDFLAGS := $(ALLFFLIBS:%=$(LD_PATH)lib%) $(LDFLAGS)
define COMPILE
$(call $(1)DEP,$(1))
$($(1)) $($(1)FLAGS) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $<
endef
COMPILE_C = $(call COMPILE,CC)
COMPILE_CXX = $(call COMPILE,CXX)
COMPILE_S = $(call COMPILE,AS)
COMPILE_HOSTC = $(call COMPILE,HOSTCC)
%.o: %.c
$(COMPILE_C)
%.o: %.cpp
$(COMPILE_CXX)
%.o: %.m
$(COMPILE_C)
%.s: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -S -o $@ $<
%.o: %.S
$(COMPILE_S)
%_host.o: %.c
$(COMPILE_HOSTC)
%.o: %.rc
$(WINDRES) $(IFLAGS) --preprocessor "$(DEPWINDRES) -E -xc-header -DRC_INVOKED $(CC_DEPFLAGS)" -o $@ $<
%.i: %.c
$(CC) $(CCFLAGS) $(CC_E) $<
%.h.c:
$(Q)echo '#include "$*.h"' >$@
%.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
%.h:
@:
# Disable suffix rules. Most of the builtin rules are suffix rules,
# so this saves some time on slow systems.
.SUFFIXES:
# Do not delete intermediate files from chains of implicit rules
$(OBJS):
endif
include $(SRC_PATH)/arch.mak
OBJS += $(OBJS-yes)
SLIBOBJS += $(SLIBOBJS-yes)
FFLIBS := $($(NAME)_FFLIBS) $(FFLIBS-yes) $(FFLIBS)
TESTPROGS += $(TESTPROGS-yes)
LDLIBS = $(FFLIBS:%=%$(BUILDSUF))
FFEXTRALIBS := $(LDLIBS:%=$(LD_LIB)) $(EXTRALIBS)
OBJS := $(sort $(OBJS:%=$(SUBDIR)%))
SLIBOBJS := $(sort $(SLIBOBJS:%=$(SUBDIR)%))
TESTOBJS := $(TESTOBJS:%=$(SUBDIR)%) $(TESTPROGS:%=$(SUBDIR)%-test.o)
TESTPROGS := $(TESTPROGS:%=$(SUBDIR)%-test$(EXESUF))
HOSTOBJS := $(HOSTPROGS:%=$(SUBDIR)%.o)
HOSTPROGS := $(HOSTPROGS:%=$(SUBDIR)%$(HOSTEXESUF))
TOOLS += $(TOOLS-yes)
TOOLOBJS := $(TOOLS:%=tools/%.o)
TOOLS := $(TOOLS:%=tools/%$(EXESUF))
HEADERS += $(HEADERS-yes)
PATH_LIBNAME = $(foreach NAME,$(1),lib$(NAME)/$($(CONFIG_SHARED:yes=S)LIBNAME))
DEP_LIBS := $(foreach lib,$(FFLIBS),$(call PATH_LIBNAME,$(lib)))
SRC_DIR := $(SRC_PATH)/lib$(NAME)
ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)/$(ARCH)/*.h))
SKIPHEADERS += $(ARCH_HEADERS:%=$(ARCH)/%) $(SKIPHEADERS-)
SKIPHEADERS := $(SKIPHEADERS:%=$(SUBDIR)%)
HOBJS = $(filter-out $(SKIPHEADERS:.h=.h.o),$(ALLHEADERS:.h=.h.o))
checkheaders: $(HOBJS)
.SECONDARY: $(HOBJS:.o=.c)
alltools: $(TOOLS)
$(HOSTOBJS): %.o: %.c
$(COMPILE_HOSTC)
$(HOSTPROGS): %$(HOSTEXESUF): %.o
$(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTLIBS)
$(OBJS): | $(sort $(dir $(OBJS)))
$(HOBJS): | $(sort $(dir $(HOBJS)))
$(HOSTOBJS): | $(sort $(dir $(HOSTOBJS)))
$(SLIBOBJS): | $(sort $(dir $(SLIBOBJS)))
$(TESTOBJS): | $(sort $(dir $(TESTOBJS)))
$(TOOLOBJS): | tools
OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(SLIBOBJS) $(TESTOBJS))
CLEANSUFFIXES = *.d *.o *~ *.h.c *.map *.ver *.ho *.gcno *.gcda *$(DEFAULT_YASMD).asm
DISTCLEANSUFFIXES = *.pc
LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a
define RULES
clean::
$(RM) $(OBJS) $(OBJS:.o=.d) $(OBJS:.o=$(DEFAULT_YASMD).d)
$(RM) $(HOSTPROGS)
$(RM) $(TOOLS)
endef
$(eval $(RULES))
-include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d) $(SLIBOBJS:.o=.d)) $(OBJS:.o=$(DEFAULT_YASMD).d)

View File

@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef COMPAT_AIX_MATH_H
#define COMPAT_AIX_MATH_H
#ifndef FFMPEG_COMPAT_AIX_MATH_H
#define FFMPEG_COMPAT_AIX_MATH_H
#define class class_in_math_h_causes_problems
@@ -28,4 +28,4 @@
#undef class
#endif /* COMPAT_AIX_MATH_H */
#endif /* FFMPEG_COMPAT_AIX_MATH_H */

View File

@@ -1,176 +0,0 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* based on vlc_atomic.h from VLC
* Copyright (C) 2010 Rémi Denis-Courmont
*/
#ifndef COMPAT_ATOMICS_DUMMY_STDATOMIC_H
#define COMPAT_ATOMICS_DUMMY_STDATOMIC_H
#include <stdint.h>
#define ATOMIC_FLAG_INIT 0
#define ATOMIC_VAR_INIT(value) (value)
#define atomic_init(obj, value) \
do { \
*(obj) = (value); \
} while(0)
#define kill_dependency(y) ((void)0)
#define atomic_thread_fence(order) \
((void)0)
#define atomic_signal_fence(order) \
((void)0)
#define atomic_is_lock_free(obj) 0
typedef intptr_t atomic_flag;
typedef intptr_t atomic_bool;
typedef intptr_t atomic_char;
typedef intptr_t atomic_schar;
typedef intptr_t atomic_uchar;
typedef intptr_t atomic_short;
typedef intptr_t atomic_ushort;
typedef intptr_t atomic_int;
typedef intptr_t atomic_uint;
typedef intptr_t atomic_long;
typedef intptr_t atomic_ulong;
typedef intptr_t atomic_llong;
typedef intptr_t atomic_ullong;
typedef intptr_t atomic_wchar_t;
typedef intptr_t atomic_int_least8_t;
typedef intptr_t atomic_uint_least8_t;
typedef intptr_t atomic_int_least16_t;
typedef intptr_t atomic_uint_least16_t;
typedef intptr_t atomic_int_least32_t;
typedef intptr_t atomic_uint_least32_t;
typedef intptr_t atomic_int_least64_t;
typedef intptr_t atomic_uint_least64_t;
typedef intptr_t atomic_int_fast8_t;
typedef intptr_t atomic_uint_fast8_t;
typedef intptr_t atomic_int_fast16_t;
typedef intptr_t atomic_uint_fast16_t;
typedef intptr_t atomic_int_fast32_t;
typedef intptr_t atomic_uint_fast32_t;
typedef intptr_t atomic_int_fast64_t;
typedef intptr_t atomic_uint_fast64_t;
typedef intptr_t atomic_intptr_t;
typedef intptr_t atomic_uintptr_t;
typedef intptr_t atomic_size_t;
typedef intptr_t atomic_ptrdiff_t;
typedef intptr_t atomic_intmax_t;
typedef intptr_t atomic_uintmax_t;
#define atomic_store(object, desired) \
do { \
*(object) = (desired); \
} while (0)
#define atomic_store_explicit(object, desired, order) \
atomic_store(object, desired)
#define atomic_load(object) \
(*(object))
#define atomic_load_explicit(object, order) \
atomic_load(object)
static inline intptr_t atomic_exchange(intptr_t *object, intptr_t desired)
{
intptr_t ret = *object;
*object = desired;
return ret;
}
#define atomic_exchange_explicit(object, desired, order) \
atomic_exchange(object, desired)
static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected,
intptr_t desired)
{
int ret;
if (*object == *expected) {
*object = desired;
ret = 1;
} else {
*expected = *object;
ret = 0;
}
return ret;
}
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
atomic_compare_exchange_strong(object, expected, desired)
#define atomic_compare_exchange_weak(object, expected, desired) \
atomic_compare_exchange_strong(object, expected, desired)
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
atomic_compare_exchange_weak(object, expected, desired)
#define FETCH_MODIFY(opname, op) \
static inline intptr_t atomic_fetch_ ## opname(intptr_t *object, intptr_t operand) \
{ \
intptr_t ret; \
ret = *object; \
*object = *object op operand; \
return ret; \
}
FETCH_MODIFY(add, +)
FETCH_MODIFY(sub, -)
FETCH_MODIFY(or, |)
FETCH_MODIFY(xor, ^)
FETCH_MODIFY(and, &)
#undef FETCH_MODIFY
#define atomic_fetch_add_explicit(object, operand, order) \
atomic_fetch_add(object, operand)
#define atomic_fetch_sub_explicit(object, operand, order) \
atomic_fetch_sub(object, operand)
#define atomic_fetch_or_explicit(object, operand, order) \
atomic_fetch_or(object, operand)
#define atomic_fetch_xor_explicit(object, operand, order) \
atomic_fetch_xor(object, operand)
#define atomic_fetch_and_explicit(object, operand, order) \
atomic_fetch_and(object, operand)
#define atomic_flag_test_and_set(object) \
atomic_exchange(object, 1)
#define atomic_flag_test_and_set_explicit(object, order) \
atomic_flag_test_and_set(object)
#define atomic_flag_clear(object) \
atomic_store(object, 0)
#define atomic_flag_clear_explicit(object, order) \
atomic_flag_clear(object)
#endif /* COMPAT_ATOMICS_DUMMY_STDATOMIC_H */

View File

@@ -1,180 +0,0 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef COMPAT_ATOMICS_WIN32_STDATOMIC_H
#define COMPAT_ATOMICS_WIN32_STDATOMIC_H
#include <stddef.h>
#include <stdint.h>
#include <windows.h>
#define ATOMIC_FLAG_INIT 0
#define ATOMIC_VAR_INIT(value) (value)
#define atomic_init(obj, value) \
do { \
*(obj) = (value); \
} while(0)
#define kill_dependency(y) ((void)0)
#define atomic_thread_fence(order) \
MemoryBarrier();
#define atomic_signal_fence(order) \
((void)0)
#define atomic_is_lock_free(obj) 0
typedef intptr_t atomic_flag;
typedef intptr_t atomic_bool;
typedef intptr_t atomic_char;
typedef intptr_t atomic_schar;
typedef intptr_t atomic_uchar;
typedef intptr_t atomic_short;
typedef intptr_t atomic_ushort;
typedef intptr_t atomic_int;
typedef intptr_t atomic_uint;
typedef intptr_t atomic_long;
typedef intptr_t atomic_ulong;
typedef intptr_t atomic_llong;
typedef intptr_t atomic_ullong;
typedef intptr_t atomic_wchar_t;
typedef intptr_t atomic_int_least8_t;
typedef intptr_t atomic_uint_least8_t;
typedef intptr_t atomic_int_least16_t;
typedef intptr_t atomic_uint_least16_t;
typedef intptr_t atomic_int_least32_t;
typedef intptr_t atomic_uint_least32_t;
typedef intptr_t atomic_int_least64_t;
typedef intptr_t atomic_uint_least64_t;
typedef intptr_t atomic_int_fast8_t;
typedef intptr_t atomic_uint_fast8_t;
typedef intptr_t atomic_int_fast16_t;
typedef intptr_t atomic_uint_fast16_t;
typedef intptr_t atomic_int_fast32_t;
typedef intptr_t atomic_uint_fast32_t;
typedef intptr_t atomic_int_fast64_t;
typedef intptr_t atomic_uint_fast64_t;
typedef intptr_t atomic_intptr_t;
typedef intptr_t atomic_uintptr_t;
typedef intptr_t atomic_size_t;
typedef intptr_t atomic_ptrdiff_t;
typedef intptr_t atomic_intmax_t;
typedef intptr_t atomic_uintmax_t;
#define atomic_store(object, desired) \
do { \
*(object) = (desired); \
MemoryBarrier(); \
} while (0)
#define atomic_store_explicit(object, desired, order) \
atomic_store(object, desired)
#define atomic_load(object) \
(MemoryBarrier(), *(object))
#define atomic_load_explicit(object, order) \
atomic_load(object)
#define atomic_exchange(object, desired) \
InterlockedExchangePointer((PVOID volatile *)object, (PVOID)desired)
#define atomic_exchange_explicit(object, desired, order) \
atomic_exchange(object, desired)
static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected,
intptr_t desired)
{
intptr_t old = *expected;
*expected = (intptr_t)InterlockedCompareExchangePointer(
(PVOID *)object, (PVOID)desired, (PVOID)old);
return *expected == old;
}
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
atomic_compare_exchange_strong(object, expected, desired)
#define atomic_compare_exchange_weak(object, expected, desired) \
atomic_compare_exchange_strong(object, expected, desired)
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
atomic_compare_exchange_weak(object, expected, desired)
#ifdef _WIN64
#define atomic_fetch_add(object, operand) \
InterlockedExchangeAdd64(object, operand)
#define atomic_fetch_sub(object, operand) \
InterlockedExchangeAdd64(object, -(operand))
#define atomic_fetch_or(object, operand) \
InterlockedOr64(object, operand)
#define atomic_fetch_xor(object, operand) \
InterlockedXor64(object, operand)
#define atomic_fetch_and(object, operand) \
InterlockedAnd64(object, operand)
#else
#define atomic_fetch_add(object, operand) \
InterlockedExchangeAdd(object, operand)
#define atomic_fetch_sub(object, operand) \
InterlockedExchangeAdd(object, -(operand))
#define atomic_fetch_or(object, operand) \
InterlockedOr(object, operand)
#define atomic_fetch_xor(object, operand) \
InterlockedXor(object, operand)
#define atomic_fetch_and(object, operand) \
InterlockedAnd(object, operand)
#endif /* _WIN64 */
#define atomic_fetch_add_explicit(object, operand, order) \
atomic_fetch_add(object, operand)
#define atomic_fetch_sub_explicit(object, operand, order) \
atomic_fetch_sub(object, operand)
#define atomic_fetch_or_explicit(object, operand, order) \
atomic_fetch_or(object, operand)
#define atomic_fetch_xor_explicit(object, operand, order) \
atomic_fetch_xor(object, operand)
#define atomic_fetch_and_explicit(object, operand, order) \
atomic_fetch_and(object, operand)
#define atomic_flag_test_and_set(object) \
atomic_exchange(object, 1)
#define atomic_flag_test_and_set_explicit(object, order) \
atomic_flag_test_and_set(object)
#define atomic_flag_clear(object) \
atomic_store(object, 0)
#define atomic_flag_clear_explicit(object, order) \
atomic_flag_clear(object)
#endif /* COMPAT_ATOMICS_WIN32_STDATOMIC_H */

View File

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

View 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); }

View File

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

View File

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

View File

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

View File

@@ -1,192 +0,0 @@
/*
* Minimum CUDA compatibility definitions header
*
* Copyright (c) 2019 rcombs
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef COMPAT_CUDA_CUDA_RUNTIME_H
#define COMPAT_CUDA_CUDA_RUNTIME_H
// Common macros
#define __global__ __attribute__((global))
#define __device__ __attribute__((device))
#define __device_builtin__ __attribute__((device_builtin))
#define __align__(N) __attribute__((aligned(N)))
#define __inline__ __inline__ __attribute__((always_inline))
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define abs(x) ((x) < 0 ? -(x) : (x))
#define atomicAdd(a, b) (__atomic_fetch_add(a, b, __ATOMIC_SEQ_CST))
// Basic typedefs
typedef __device_builtin__ unsigned long long cudaTextureObject_t;
typedef struct __device_builtin__ __align__(2) uchar2
{
unsigned char x, y;
} uchar2;
typedef struct __device_builtin__ __align__(4) ushort2
{
unsigned short x, y;
} ushort2;
typedef struct __device_builtin__ __align__(8) float2
{
float x, y;
} float2;
typedef struct __device_builtin__ __align__(8) int2
{
int x, y;
} int2;
typedef struct __device_builtin__ uint3
{
unsigned int x, y, z;
} uint3;
typedef struct uint3 dim3;
typedef struct __device_builtin__ __align__(4) uchar4
{
unsigned char x, y, z, w;
} uchar4;
typedef struct __device_builtin__ __align__(8) ushort4
{
unsigned short x, y, z, w;
} ushort4;
typedef struct __device_builtin__ __align__(16) int4
{
int x, y, z, w;
} int4;
typedef struct __device_builtin__ __align__(16) float4
{
float x, y, z, w;
} float4;
// Accessors for special registers
#define GETCOMP(reg, comp) \
asm("mov.u32 %0, %%" #reg "." #comp ";" : "=r"(tmp)); \
ret.comp = tmp;
#define GET(name, reg) static inline __device__ uint3 name() {\
uint3 ret; \
unsigned tmp; \
GETCOMP(reg, x) \
GETCOMP(reg, y) \
GETCOMP(reg, z) \
return ret; \
}
GET(getBlockIdx, ctaid)
GET(getBlockDim, ntid)
GET(getThreadIdx, tid)
// Instead of externs for these registers, we turn access to them into calls into trivial ASM
#define blockIdx (getBlockIdx())
#define blockDim (getBlockDim())
#define threadIdx (getThreadIdx())
// Basic initializers (simple macros rather than inline functions)
#define make_int2(a, b) ((int2){.x = a, .y = b})
#define make_uchar2(a, b) ((uchar2){.x = a, .y = b})
#define make_ushort2(a, b) ((ushort2){.x = a, .y = b})
#define make_float2(a, b) ((float2){.x = a, .y = b})
#define make_int4(a, b, c, d) ((int4){.x = a, .y = b, .z = c, .w = d})
#define make_uchar4(a, b, c, d) ((uchar4){.x = a, .y = b, .z = c, .w = d})
#define make_ushort4(a, b, c, d) ((ushort4){.x = a, .y = b, .z = c, .w = d})
#define make_float4(a, b, c, d) ((float4){.x = a, .y = b, .z = c, .w = d})
// Conversions from the tex instruction's 4-register output to various types
#define TEX2D(type, ret) static inline __device__ void conv(type* out, unsigned a, unsigned b, unsigned c, unsigned d) {*out = (ret);}
TEX2D(unsigned char, a & 0xFF)
TEX2D(unsigned short, a & 0xFFFF)
TEX2D(float, a)
TEX2D(uchar2, make_uchar2(a & 0xFF, b & 0xFF))
TEX2D(ushort2, make_ushort2(a & 0xFFFF, b & 0xFFFF))
TEX2D(float2, make_float2(a, b))
TEX2D(uchar4, make_uchar4(a & 0xFF, b & 0xFF, c & 0xFF, d & 0xFF))
TEX2D(ushort4, make_ushort4(a & 0xFFFF, b & 0xFFFF, c & 0xFFFF, d & 0xFFFF))
TEX2D(float4, make_float4(a, b, c, d))
// Template calling tex instruction and converting the output to the selected type
template<typename T>
inline __device__ T tex2D(cudaTextureObject_t texObject, float x, float y)
{
T ret;
unsigned ret1, ret2, ret3, ret4;
asm("tex.2d.v4.u32.f32 {%0, %1, %2, %3}, [%4, {%5, %6}];" :
"=r"(ret1), "=r"(ret2), "=r"(ret3), "=r"(ret4) :
"l"(texObject), "f"(x), "f"(y));
conv(&ret, ret1, ret2, ret3, ret4);
return ret;
}
template<>
inline __device__ float4 tex2D<float4>(cudaTextureObject_t texObject, float x, float y)
{
float4 ret;
asm("tex.2d.v4.f32.f32 {%0, %1, %2, %3}, [%4, {%5, %6}];" :
"=r"(ret.x), "=r"(ret.y), "=r"(ret.z), "=r"(ret.w) :
"l"(texObject), "f"(x), "f"(y));
return ret;
}
template<>
inline __device__ float tex2D<float>(cudaTextureObject_t texObject, float x, float y)
{
return tex2D<float4>(texObject, x, y).x;
}
template<>
inline __device__ float2 tex2D<float2>(cudaTextureObject_t texObject, float x, float y)
{
float4 ret = tex2D<float4>(texObject, x, y);
return make_float2(ret.x, ret.y);
}
// Math helper functions
static inline __device__ float floorf(float a) { return __builtin_floorf(a); }
static inline __device__ float floor(float a) { return __builtin_floorf(a); }
static inline __device__ double floor(double a) { return __builtin_floor(a); }
static inline __device__ float ceilf(float a) { return __builtin_ceilf(a); }
static inline __device__ float ceil(float a) { return __builtin_ceilf(a); }
static inline __device__ double ceil(double a) { return __builtin_ceil(a); }
static inline __device__ float truncf(float a) { return __builtin_truncf(a); }
static inline __device__ float trunc(float a) { return __builtin_truncf(a); }
static inline __device__ double trunc(double a) { return __builtin_trunc(a); }
static inline __device__ float fabsf(float a) { return __builtin_fabsf(a); }
static inline __device__ float fabs(float a) { return __builtin_fabsf(a); }
static inline __device__ double fabs(double a) { return __builtin_fabs(a); }
static inline __device__ float sqrtf(float a) { return __builtin_sqrtf(a); }
static inline __device__ float __saturatef(float a) { return __nvvm_saturate_f(a); }
static inline __device__ float __sinf(float a) { return __nvvm_sin_approx_f(a); }
static inline __device__ float __cosf(float a) { return __nvvm_cos_approx_f(a); }
static inline __device__ float __expf(float a) { return __nvvm_ex2_approx_f(a * (float)__builtin_log2(__builtin_exp(1))); }
static inline __device__ float __powf(float a, float b) { return __nvvm_ex2_approx_f(__nvvm_lg2_approx_f(a) * b); }
#endif /* COMPAT_CUDA_CUDA_RUNTIME_H */

View File

@@ -1,33 +0,0 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef COMPAT_CUDA_DYNLINK_LOADER_H
#define COMPAT_CUDA_DYNLINK_LOADER_H
#include "libavutil/log.h"
#include "compat/w32dlfcn.h"
#define FFNV_LOAD_FUNC(path) dlopen((path), RTLD_LAZY)
#define FFNV_SYM_FUNC(lib, sym) dlsym((lib), (sym))
#define FFNV_FREE_FUNC(lib) dlclose(lib)
#define FFNV_LOG_FUNC(logctx, msg, ...) av_log(logctx, AV_LOG_ERROR, msg, __VA_ARGS__)
#define FFNV_DEBUG_LOG_FUNC(logctx, msg, ...) av_log(logctx, AV_LOG_DEBUG, msg, __VA_ARGS__)
#include <ffnvcodec/dynlink_loader.h>
#endif /* COMPAT_CUDA_DYNLINK_LOADER_H */

View File

@@ -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 */

View File

@@ -1,47 +0,0 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <math.h>
#define FUN(name, type, op) \
type name(type x, type y) \
{ \
if (fpclassify(x) == FP_NAN) return y; \
if (fpclassify(y) == FP_NAN) return x; \
return x op y ? x : y; \
}
FUN(fmin, double, <)
FUN(fmax, double, >)
FUN(fminf, float, <)
FUN(fmaxf, float, >)
long double fmodl(long double x, long double y)
{
return fmod(x, y);
}
long double scalbnl(long double x, int exp)
{
return scalbn(x, exp);
}
long double copysignl(long double x, long double y)
{
return copysign(x, y);
}

View File

@@ -1,25 +0,0 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
double fmin(double, double);
double fmax(double, double);
float fminf(float, float);
float fmaxf(float, float);
long double fmodl(long double, long double);
long double scalbnl(long double, int);
long double copysignl(long double, long double);

View File

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

View File

@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef COMPAT_MSVCRT_SNPRINTF_H
#define COMPAT_MSVCRT_SNPRINTF_H
#ifndef COMPAT_SNPRINTF_H
#define COMPAT_SNPRINTF_H
#include <stdarg.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 vsnprintf avpriv_vsnprintf
#endif /* COMPAT_MSVCRT_SNPRINTF_H */
#endif /* COMPAT_SNPRINTF_H */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2017 KO Myung-Hun <komh@chollian.net>
* Copyright (c) 2011 KO Myung-Hun <komh@chollian.net>
*
* This file is part of FFmpeg.
*
@@ -23,118 +23,96 @@
* os2threads to pthreads wrapper
*/
#ifndef COMPAT_OS2THREADS_H
#define COMPAT_OS2THREADS_H
#ifndef AVCODEC_OS2PTHREADS_H
#define AVCODEC_OS2PTHREADS_H
#define INCL_DOS
#define INCL_DOSERRORS
#include <os2.h>
#undef __STRICT_ANSI__ /* for _beginthread() */
#include <stdlib.h>
#include <time.h>
#include <sys/builtin.h>
#include <sys/fmutex.h>
#include "libavutil/attributes.h"
#include "libavutil/common.h"
#include "libavutil/time.h"
typedef struct {
TID tid;
void *(*start_routine)(void *);
void *arg;
void *result;
} pthread_t;
#include "libavutil/mem.h"
typedef TID pthread_t;
typedef void pthread_attr_t;
typedef _fmutex pthread_mutex_t;
typedef HMTX pthread_mutex_t;
typedef void pthread_mutexattr_t;
#define PTHREAD_MUTEX_INITIALIZER _FMUTEX_INITIALIZER
typedef struct {
HEV event_sem;
HEV ack_sem;
volatile unsigned wait_count;
HEV event_sem;
int wait_count;
} pthread_cond_t;
typedef void pthread_condattr_t;
typedef struct {
volatile int done;
_fmutex mtx;
} pthread_once_t;
#define PTHREAD_ONCE_INIT {0, _FMUTEX_INITIALIZER}
struct thread_arg {
void *(*start_routine)(void *);
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,
const pthread_attr_t *attr,
void *(*start_routine)(void*),
void *arg)
static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg)
{
thread->start_routine = start_routine;
thread->arg = arg;
thread->result = NULL;
struct thread_arg *thread_arg;
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;
}
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
{
DosWaitThread(&thread.tid, DCWW_WAIT);
if (value_ptr)
*value_ptr = thread.result;
DosWaitThread((PTID)&thread, DCWW_WAIT);
return 0;
}
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex,
const pthread_mutexattr_t *attr)
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
{
_fmutex_create(mutex, 0);
DosCreateMutexSem(NULL, (PHMTX)mutex, 0, FALSE);
return 0;
}
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
{
_fmutex_close(mutex);
DosCloseMutexSem(*(PHMTX)mutex);
return 0;
}
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
{
_fmutex_request(mutex, 0);
DosRequestMutexSem(*(PHMTX)mutex, SEM_INDEFINITE_WAIT);
return 0;
}
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
{
_fmutex_release(mutex);
DosReleaseMutexSem(*(PHMTX)mutex);
return 0;
}
static av_always_inline int pthread_cond_init(pthread_cond_t *cond,
const pthread_condattr_t *attr)
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
{
DosCreateEventSem(NULL, &cond->event_sem, DCE_POSTONE, FALSE);
DosCreateEventSem(NULL, &cond->ack_sem, DCE_POSTONE, FALSE);
cond->wait_count = 0;
@@ -144,16 +122,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)
{
DosCloseEventSem(cond->event_sem);
DosCloseEventSem(cond->ack_sem);
return 0;
}
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);
DosWaitEventSem(cond->ack_sem, SEM_INDEFINITE_WAIT);
cond->wait_count--;
}
return 0;
@@ -161,69 +139,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)
{
while (!__atomic_cmpxchg32(&cond->wait_count, 0, 0))
pthread_cond_signal(cond);
while (cond->wait_count > 0) {
DosPostEventSem(cond->event_sem);
cond->wait_count--;
}
return 0;
}
static av_always_inline int pthread_cond_timedwait(pthread_cond_t *cond,
pthread_mutex_t *mutex,
const struct timespec *abstime)
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
int64_t abs_milli = abstime->tv_sec * 1000LL + abstime->tv_nsec / 1000000;
ULONG t = av_clip64(abs_milli - av_gettime() / 1000, 0, ULONG_MAX);
__atomic_increment(&cond->wait_count);
pthread_mutex_unlock(mutex);
APIRET ret = DosWaitEventSem(cond->event_sem, t);
__atomic_decrement(&cond->wait_count);
DosPostEventSem(cond->ack_sem);
pthread_mutex_lock(mutex);
return (ret == ERROR_TIMEOUT) ? ETIMEDOUT : 0;
}
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond,
pthread_mutex_t *mutex)
{
__atomic_increment(&cond->wait_count);
cond->wait_count++;
pthread_mutex_unlock(mutex);
DosWaitEventSem(cond->event_sem, SEM_INDEFINITE_WAIT);
__atomic_decrement(&cond->wait_count);
DosPostEventSem(cond->ack_sem);
pthread_mutex_lock(mutex);
return 0;
}
static av_always_inline int pthread_once(pthread_once_t *once_control,
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 */
#endif /* AVCODEC_OS2PTHREADS_H */

10
compat/plan9/head Executable file
View File

@@ -0,0 +1,10 @@
#!/bin/sh
n=10
case "$1" in
-n) n=$2; shift 2 ;;
-n*) n=${1#-n}; shift ;;
esac
exec sed ${n}q "$@"

34
compat/plan9/main.c Normal file
View File

@@ -0,0 +1,34 @@
/*
* 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
*/
int plan9_main(int argc, char **argv);
#undef main
int main(int argc, char **argv)
{
/* The setfcr() function in lib9 is broken, must use asm. */
#ifdef __i386
short fcr;
__asm__ volatile ("fstcw %0 \n"
"or $63, %0 \n"
"fldcw %0 \n"
: "=m"(fcr));
#endif
return plan9_main(argc, argv);
}

2
compat/plan9/printf Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
exec awk "BEGIN { for (i = 2; i < ARGC; i++) printf \"$1\", ARGV[i] }" "$@"

View File

@@ -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;

View File

@@ -1,599 +0,0 @@
/*
* Copyright (C) 2023 Rémi Denis-Courmont
*
* This program 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.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*/
#ifndef __STDC_VERSION_STDBIT_H__
#define __STDC_VERSION_STDBIT_H__ 202311L
#include <stdbool.h>
#include <limits.h> /* CHAR_BIT */
#define __STDC_ENDIAN_LITTLE__ 1234
#define __STDC_ENDIAN_BIG__ 4321
#ifdef __BYTE_ORDER__
# if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
# define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_LITTLE__
# elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
# define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_BIG__
# else
# define __STDC_ENDIAN_NATIVE__ 3412
# endif
#elif defined(_MSC_VER)
# define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_LITTLE__
#else
# error Not implemented.
#endif
#define __stdbit_generic_type_func(func, value) \
_Generic (value, \
unsigned long long: stdc_##func##_ull((unsigned long long)(value)), \
unsigned long: stdc_##func##_ul((unsigned long)(value)), \
unsigned int: stdc_##func##_ui((unsigned int)(value)), \
unsigned short: stdc_##func##_us((unsigned short)(value)), \
unsigned char: stdc_##func##_uc((unsigned char)(value)))
#if defined (__GNUC__) || defined (__clang__)
static inline unsigned int stdc_leading_zeros_ull(unsigned long long value)
{
return value ? __builtin_clzll(value) : (CHAR_BIT * sizeof (value));
}
static inline unsigned int stdc_leading_zeros_ul(unsigned long value)
{
return value ? __builtin_clzl(value) : (CHAR_BIT * sizeof (value));
}
static inline unsigned int stdc_leading_zeros_ui(unsigned int value)
{
return value ? __builtin_clz(value) : (CHAR_BIT * sizeof (value));
}
static inline unsigned int stdc_leading_zeros_us(unsigned short value)
{
return stdc_leading_zeros_ui(value)
- CHAR_BIT * (sizeof (int) - sizeof (value));
}
static inline unsigned int stdc_leading_zeros_uc(unsigned char value)
{
return stdc_leading_zeros_ui(value) - (CHAR_BIT * (sizeof (int) - 1));
}
#else
static inline unsigned int __stdc_leading_zeros(unsigned long long value,
unsigned int size)
{
unsigned int zeros = size * CHAR_BIT;
while (value != 0) {
value >>= 1;
zeros--;
}
return zeros;
}
static inline unsigned int stdc_leading_zeros_ull(unsigned long long value)
{
return __stdc_leading_zeros(value, sizeof (value));
}
static inline unsigned int stdc_leading_zeros_ul(unsigned long value)
{
return __stdc_leading_zeros(value, sizeof (value));
}
static inline unsigned int stdc_leading_zeros_ui(unsigned int value)
{
return __stdc_leading_zeros(value, sizeof (value));
}
static inline unsigned int stdc_leading_zeros_us(unsigned short value)
{
return __stdc_leading_zeros(value, sizeof (value));
}
static inline unsigned int stdc_leading_zeros_uc(unsigned char value)
{
return __stdc_leading_zeros(value, sizeof (value));
}
#endif
#define stdc_leading_zeros(value) \
__stdbit_generic_type_func(leading_zeros, value)
static inline unsigned int stdc_leading_ones_ull(unsigned long long value)
{
return stdc_leading_zeros_ull(~value);
}
static inline unsigned int stdc_leading_ones_ul(unsigned long value)
{
return stdc_leading_zeros_ul(~value);
}
static inline unsigned int stdc_leading_ones_ui(unsigned int value)
{
return stdc_leading_zeros_ui(~value);
}
static inline unsigned int stdc_leading_ones_us(unsigned short value)
{
return stdc_leading_zeros_us(~value);
}
static inline unsigned int stdc_leading_ones_uc(unsigned char value)
{
return stdc_leading_zeros_uc(~value);
}
#define stdc_leading_ones(value) \
__stdbit_generic_type_func(leading_ones, value)
#if defined (__GNUC__) || defined (__clang__)
static inline unsigned int stdc_trailing_zeros_ull(unsigned long long value)
{
return value ? (unsigned int)__builtin_ctzll(value)
: (CHAR_BIT * sizeof (value));
}
static inline unsigned int stdc_trailing_zeros_ul(unsigned long value)
{
return value ? (unsigned int)__builtin_ctzl(value)
: (CHAR_BIT * sizeof (value));
}
static inline unsigned int stdc_trailing_zeros_ui(unsigned int value)
{
return value ? (unsigned int)__builtin_ctz(value)
: (CHAR_BIT * sizeof (value));
}
static inline unsigned int stdc_trailing_zeros_us(unsigned short value)
{
return value ? (unsigned int)__builtin_ctz(value)
: (CHAR_BIT * sizeof (value));
}
static inline unsigned int stdc_trailing_zeros_uc(unsigned char value)
{
return value ? (unsigned int)__builtin_ctz(value)
: (CHAR_BIT * sizeof (value));
}
#else
static inline unsigned int __stdc_trailing_zeros(unsigned long long value,
unsigned int size)
{
unsigned int zeros = 0;
if (!value)
return size * CHAR_BIT;
while ((value & 1) == 0) {
value >>= 1;
zeros++;
}
return zeros;
}
static inline unsigned int stdc_trailing_zeros_ull(unsigned long long value)
{
return __stdc_trailing_zeros(value, sizeof (value));
}
static inline unsigned int stdc_trailing_zeros_ul(unsigned long value)
{
return __stdc_trailing_zeros(value, sizeof (value));
}
static inline unsigned int stdc_trailing_zeros_ui(unsigned int value)
{
return __stdc_trailing_zeros(value, sizeof (value));
}
static inline unsigned int stdc_trailing_zeros_us(unsigned short value)
{
return __stdc_trailing_zeros(value, sizeof (value));
}
static inline unsigned int stdc_trailing_zeros_uc(unsigned char value)
{
return __stdc_trailing_zeros(value, sizeof (value));
}
#endif
#define stdc_trailing_zeros(value) \
__stdbit_generic_type_func(trailing_zeros, value)
static inline unsigned int stdc_trailing_ones_ull(unsigned long long value)
{
return stdc_trailing_zeros_ull(~value);
}
static inline unsigned int stdc_trailing_ones_ul(unsigned long value)
{
return stdc_trailing_zeros_ul(~value);
}
static inline unsigned int stdc_trailing_ones_ui(unsigned int value)
{
return stdc_trailing_zeros_ui(~value);
}
static inline unsigned int stdc_trailing_ones_us(unsigned short value)
{
return stdc_trailing_zeros_us(~value);
}
static inline unsigned int stdc_trailing_ones_uc(unsigned char value)
{
return stdc_trailing_zeros_uc(~value);
}
#define stdc_trailing_ones(value) \
__stdbit_generic_type_func(trailing_ones, value)
static inline unsigned int stdc_first_leading_one_ull(unsigned long long value)
{
return value ? (stdc_leading_zeros_ull(value) + 1) : 0;
}
static inline unsigned int stdc_first_leading_one_ul(unsigned long value)
{
return value ? (stdc_leading_zeros_ul(value) + 1) : 0;
}
static inline unsigned int stdc_first_leading_one_ui(unsigned int value)
{
return value ? (stdc_leading_zeros_ui(value) + 1) : 0;
}
static inline unsigned int stdc_first_leading_one_us(unsigned short value)
{
return value ? (stdc_leading_zeros_us(value) + 1) : 0;
}
static inline unsigned int stdc_first_leading_one_uc(unsigned char value)
{
return value ? (stdc_leading_zeros_uc(value) + 1) : 0;
}
#define stdc_first_leading_one(value) \
__stdbit_generic_type_func(first_leading_one, value)
static inline unsigned int stdc_first_leading_zero_ull(unsigned long long value)
{
return stdc_leading_ones_ull(~value);
}
static inline unsigned int stdc_first_leading_zero_ul(unsigned long value)
{
return stdc_leading_ones_ul(~value);
}
static inline unsigned int stdc_first_leading_zero_ui(unsigned int value)
{
return stdc_leading_ones_ui(~value);
}
static inline unsigned int stdc_first_leading_zero_us(unsigned short value)
{
return stdc_leading_ones_us(~value);
}
static inline unsigned int stdc_first_leading_zero_uc(unsigned char value)
{
return stdc_leading_ones_uc(~value);
}
#define stdc_first_leading_zero(value) \
__stdbit_generic_type_func(first_leading_zero, value)
#if defined (__GNUC__) || defined (__clang__)
static inline unsigned int stdc_first_trailing_one_ull(unsigned long long value)
{
return __builtin_ffsll(value);
}
static inline unsigned int stdc_first_trailing_one_ul(unsigned long value)
{
return __builtin_ffsl(value);
}
static inline unsigned int stdc_first_trailing_one_ui(unsigned int value)
{
return __builtin_ffs(value);
}
static inline unsigned int stdc_first_trailing_one_us(unsigned short value)
{
return __builtin_ffs(value);
}
static inline unsigned int stdc_first_trailing_one_uc(unsigned char value)
{
return __builtin_ffs(value);
}
#else
static inline unsigned int stdc_first_trailing_one_ull(unsigned long long value)
{
return value ? (1 + stdc_trailing_zeros_ull(value)) : 0;
}
static inline unsigned int stdc_first_trailing_one_ul(unsigned long value)
{
return value ? (1 + stdc_trailing_zeros_ul(value)) : 0;
}
static inline unsigned int stdc_first_trailing_one_ui(unsigned int value)
{
return value ? (1 + stdc_trailing_zeros_ui(value)) : 0;
}
static inline unsigned int stdc_first_trailing_one_us(unsigned short value)
{
return value ? (1 + stdc_trailing_zeros_us(value)) : 0;
}
static inline unsigned int stdc_first_trailing_one_uc(unsigned char value)
{
return value ? (1 + stdc_trailing_zeros_uc(value)) : 0;
}
#endif
#define stdc_first_trailing_one(value) \
__stdbit_generic_type_func(first_trailing_one, value)
static inline unsigned int stdc_first_trailing_zero_ull(unsigned long long value)
{
return stdc_first_trailing_one_ull(~value);
}
static inline unsigned int stdc_first_trailing_zero_ul(unsigned long value)
{
return stdc_first_trailing_one_ul(~value);
}
static inline unsigned int stdc_first_trailing_zero_ui(unsigned int value)
{
return stdc_first_trailing_one_ui(~value);
}
static inline unsigned int stdc_first_trailing_zero_us(unsigned short value)
{
return stdc_first_trailing_one_us(~value);
}
static inline unsigned int stdc_first_trailing_zero_uc(unsigned char value)
{
return stdc_first_trailing_one_uc(~value);
}
#define stdc_first_trailing_zero(value) \
__stdbit_generic_type_func(first_trailing_zero, value)
#if defined (__GNUC__) || defined (__clang__)
static inline unsigned int stdc_count_ones_ull(unsigned long long value)
{
return __builtin_popcountll(value);
}
static inline unsigned int stdc_count_ones_ul(unsigned long value)
{
return __builtin_popcountl(value);
}
static inline unsigned int stdc_count_ones_ui(unsigned int value)
{
return __builtin_popcount(value);
}
static inline unsigned int stdc_count_ones_us(unsigned short value)
{
return __builtin_popcount(value);
}
static inline unsigned int stdc_count_ones_uc(unsigned char value)
{
return __builtin_popcount(value);
}
#else
static inline unsigned int __stdc_count_ones(unsigned long long value,
unsigned int size)
{
unsigned int ones = 0;
for (unsigned int c = 0; c < (size * CHAR_BIT); c++) {
ones += value & 1;
value >>= 1;
}
return ones;
}
static inline unsigned int stdc_count_ones_ull(unsigned long long value)
{
return __stdc_count_ones(value, sizeof (value));
}
static inline unsigned int stdc_count_ones_ul(unsigned long value)
{
return __stdc_count_ones(value, sizeof (value));
}
static inline unsigned int stdc_count_ones_ui(unsigned int value)
{
return __stdc_count_ones(value, sizeof (value));
}
static inline unsigned int stdc_count_ones_us(unsigned short value)
{
return __stdc_count_ones(value, sizeof (value));
}
static inline unsigned int stdc_count_ones_uc(unsigned char value)
{
return __stdc_count_ones(value, sizeof (value));
}
#endif
#define stdc_count_ones(value) \
__stdbit_generic_type_func(count_ones, value)
static inline unsigned int stdc_count_zeros_ull(unsigned long long value)
{
return stdc_count_ones_ull(~value);
}
static inline unsigned int stdc_count_zeros_ul(unsigned long value)
{
return stdc_count_ones_ul(~value);
}
static inline unsigned int stdc_count_zeros_ui(unsigned int value)
{
return stdc_count_ones_ui(~value);
}
static inline unsigned int stdc_count_zeros_us(unsigned short value)
{
return stdc_count_ones_us(~value);
}
static inline unsigned int stdc_count_zeros_uc(unsigned char value)
{
return stdc_count_ones_uc(~value);
}
#define stdc_count_zeros(value) \
__stdbit_generic_type_func(count_zeros, value)
static inline bool stdc_has_single_bit_ull(unsigned long long value)
{
return value && (value & (value - 1)) == 0;
}
static inline bool stdc_has_single_bit_ul(unsigned long value)
{
return value && (value & (value - 1)) == 0;
}
static inline bool stdc_has_single_bit_ui(unsigned int value)
{
return value && (value & (value - 1)) == 0;
}
static inline bool stdc_has_single_bit_us(unsigned short value)
{
return value && (value & (value - 1)) == 0;
}
static inline bool stdc_has_single_bit_uc(unsigned char value)
{
return value && (value & (value - 1)) == 0;
}
#define stdc_has_single_bit(value) \
__stdbit_generic_type_func(has_single_bit, value)
static inline unsigned int stdc_bit_width_ull(unsigned long long value)
{
return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_ull(value);
}
static inline unsigned int stdc_bit_width_ul(unsigned long value)
{
return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_ul(value);
}
static inline unsigned int stdc_bit_width_ui(unsigned int value)
{
return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_ui(value);
}
static inline unsigned int stdc_bit_width_us(unsigned short value)
{
return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_us(value);
}
static inline unsigned int stdc_bit_width_uc(unsigned char value)
{
return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_uc(value);
}
#define stdc_bit_width(value) \
__stdbit_generic_type_func(bit_width, value)
static inline unsigned long long stdc_bit_floor_ull(unsigned long long value)
{
return value ? (1ULL << (stdc_bit_width_ull(value) - 1)) : 0ULL;
}
static inline unsigned long stdc_bit_floor_ul(unsigned long value)
{
return value ? (1UL << (stdc_bit_width_ul(value) - 1)) : 0UL;
}
static inline unsigned int stdc_bit_floor_ui(unsigned int value)
{
return value ? (1U << (stdc_bit_width_ui(value) - 1)) : 0U;
}
static inline unsigned short stdc_bit_floor_us(unsigned short value)
{
return value ? (1U << (stdc_bit_width_us(value) - 1)) : 0U;
}
static inline unsigned int stdc_bit_floor_uc(unsigned char value)
{
return value ? (1U << (stdc_bit_width_uc(value) - 1)) : 0U;
}
#define stdc_bit_floor(value) \
__stdbit_generic_type_func(bit_floor, value)
/* NOTE: Bit ceiling undefines overflow. */
static inline unsigned long long stdc_bit_ceil_ull(unsigned long long value)
{
return 1ULL << (value ? stdc_bit_width_ull(value - 1) : 0);
}
static inline unsigned long stdc_bit_ceil_ul(unsigned long value)
{
return 1UL << (value ? stdc_bit_width_ul(value - 1) : 0);
}
static inline unsigned int stdc_bit_ceil_ui(unsigned int value)
{
return 1U << (value ? stdc_bit_width_ui(value - 1) : 0);
}
static inline unsigned short stdc_bit_ceil_us(unsigned short value)
{
return 1U << (value ? stdc_bit_width_us(value - 1) : 0);
}
static inline unsigned int stdc_bit_ceil_uc(unsigned char value)
{
return 1U << (value ? stdc_bit_width_uc(value - 1) : 0);
}
#define stdc_bit_ceil(value) \
__stdbit_generic_type_func(bit_ceil, value)
#endif /* __STDC_VERSION_STDBIT_H__ */

View File

@@ -25,9 +25,9 @@
#include "libavutil/avstring.h"
#include "libavutil/mathematics.h"
static const char *check_nan_suffix(const char *s)
static char *check_nan_suffix(char *s)
{
const char *start = s;
char *start = s;
if (*s++ != '(')
return start;
@@ -44,7 +44,7 @@ double strtod(const char *, char **);
double avpriv_strtod(const char *nptr, char **endptr)
{
const char *end;
char *end;
double res;
/* Skip leading spaces */
@@ -81,13 +81,13 @@ double avpriv_strtod(const char *nptr, char **endptr)
!av_strncasecmp(nptr, "+0x", 3)) {
/* FIXME this doesn't handle exponents, non-integers (float/double)
* and numbers too large for long long */
res = strtoll(nptr, (char **)&end, 16);
res = strtoll(nptr, &end, 16);
} else {
res = strtod(nptr, (char **)&end);
res = strtod(nptr, &end);
}
if (endptr)
*endptr = (char *)end;
*endptr = end;
return res;
}

30
compat/tms470/math.h Normal file
View File

@@ -0,0 +1,30 @@
/*
* 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 FFMPEG_COMPAT_TMS470_MATH_H
#define FFMPEG_COMPAT_TMS470_MATH_H
#include_next <math.h>
#undef INFINITY
#undef NAN
#define INFINITY (*(const float*)((const unsigned []){ 0x7f800000 }))
#define NAN (*(const float*)((const unsigned []){ 0x7fc00000 }))
#endif /* FFMPEG_COMPAT_TMS470_MATH_H */

View File

@@ -19,9 +19,6 @@
* 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>
#if !defined(va_copy) && defined(_MSC_VER)
@@ -30,5 +27,3 @@
#if !defined(va_copy) && defined(__GNUC__) && __GNUC__ < 3
#define va_copy(dst, src) __va_copy(dst, src)
#endif
#endif /* COMPAT_VA_COPY_H */

View File

@@ -1,151 +0,0 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef COMPAT_W32DLFCN_H
#define COMPAT_W32DLFCN_H
#ifdef _WIN32
#include <stdint.h>
#include <windows.h>
#include "config.h"
#include "libavutil/macros.h"
#include "libavutil/mem.h"
#include "libavutil/wchar_filename.h"
static inline wchar_t *get_module_filename(HMODULE module)
{
wchar_t *path = NULL, *new_path;
DWORD path_size = 0, path_len;
do {
path_size = path_size ? FFMIN(2 * path_size, INT16_MAX + 1) : MAX_PATH;
new_path = av_realloc_array(path, path_size, sizeof *path);
if (!new_path) {
av_free(path);
return NULL;
}
path = new_path;
// Returns path_size in case of insufficient buffer.
// Whether the error is set or not and whether the output
// is null-terminated or not depends on the version of Windows.
path_len = GetModuleFileNameW(module, path, path_size);
} while (path_len && path_size <= INT16_MAX && path_size <= path_len);
if (!path_len) {
av_free(path);
return NULL;
}
return path;
}
/**
* Safe function used to open dynamic libs. This attempts to improve program security
* by removing the current directory from the dll search path. Only dll's found in the
* executable or system directory are allowed to be loaded.
* @param name The dynamic lib name.
* @return A handle to the opened lib.
*/
static inline HMODULE win32_dlopen(const char *name)
{
wchar_t *name_w;
HMODULE module = NULL;
if (utf8towchar(name, &name_w))
name_w = NULL;
#if _WIN32_WINNT < 0x0602
// On Win7 and earlier we check if KB2533623 is available
if (!GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetDefaultDllDirectories")) {
wchar_t *path = NULL, *new_path;
DWORD pathlen, pathsize, namelen;
if (!name_w)
goto exit;
namelen = wcslen(name_w);
// Try local directory first
path = get_module_filename(NULL);
if (!path)
goto exit;
new_path = wcsrchr(path, '\\');
if (!new_path)
goto exit;
pathlen = new_path - path;
pathsize = pathlen + namelen + 2;
new_path = av_realloc_array(path, pathsize, sizeof *path);
if (!new_path)
goto exit;
path = new_path;
wcscpy(path + pathlen + 1, name_w);
module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (module == NULL) {
// Next try System32 directory
pathlen = GetSystemDirectoryW(path, pathsize);
if (!pathlen)
goto exit;
// Buffer is not enough in two cases:
// 1. system directory + \ + module name
// 2. system directory even without the module name.
if (pathlen + namelen + 2 > pathsize) {
pathsize = pathlen + namelen + 2;
new_path = av_realloc_array(path, pathsize, sizeof *path);
if (!new_path)
goto exit;
path = new_path;
// Query again to handle the case #2.
pathlen = GetSystemDirectoryW(path, pathsize);
if (!pathlen)
goto exit;
}
path[pathlen] = L'\\';
wcscpy(path + pathlen + 1, name_w);
module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
}
exit:
av_free(path);
av_free(name_w);
return module;
}
#endif
#ifndef LOAD_LIBRARY_SEARCH_APPLICATION_DIR
# define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x00000200
#endif
#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32
# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
#endif
#if HAVE_WINRT
if (!name_w)
return NULL;
module = LoadPackagedLibrary(name_w, 0);
#else
#define LOAD_FLAGS (LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32)
/* filename may be be in CP_ACP */
if (!name_w)
return LoadLibraryExA(name, NULL, LOAD_FLAGS);
module = LoadLibraryExW(name_w, NULL, LOAD_FLAGS);
#undef LOAD_FLAGS
#endif
av_free(name_w);
return module;
}
#define dlopen(name, flags) win32_dlopen(name)
#define dlclose FreeLibrary
#define dlsym GetProcAddress
#else
#include <dlfcn.h>
#endif
#endif /* COMPAT_W32DLFCN_H */

View File

@@ -26,8 +26,8 @@
* w32threads to pthreads wrapper
*/
#ifndef COMPAT_W32PTHREADS_H
#define COMPAT_W32PTHREADS_H
#ifndef FFMPEG_COMPAT_W32PTHREADS_H
#define FFMPEG_COMPAT_W32PTHREADS_H
/* 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
@@ -35,15 +35,14 @@
* As most functions here are used without checking return values,
* only implement return values as necessary. */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <process.h>
#include <time.h>
#include "libavutil/attributes.h"
#include "libavutil/common.h"
#include "libavutil/internal.h"
#include "libavutil/mem.h"
#include "libavutil/time.h"
typedef struct pthread_t {
void *handle;
@@ -52,29 +51,28 @@ typedef struct pthread_t {
void *ret;
} pthread_t;
/* use light weight mutex/condition variable API for Windows Vista and later */
typedef SRWLOCK pthread_mutex_t;
/* the conditional variable api for windows 6.0+ uses critical sections and
* not mutexes */
typedef CRITICAL_SECTION pthread_mutex_t;
/* This is the CONDITION_VARIABLE typedef for using Windows' native
* conditional variables on kernels 6.0+. */
#if HAVE_CONDITION_VARIABLE_PTR
typedef CONDITION_VARIABLE pthread_cond_t;
#define PTHREAD_MUTEX_INITIALIZER SRWLOCK_INIT
#define PTHREAD_COND_INITIALIZER CONDITION_VARIABLE_INIT
#define InitializeCriticalSection(x) InitializeCriticalSectionEx(x, 0, 0)
#define WaitForSingleObject(a, b) WaitForSingleObjectEx(a, b, FALSE)
#define PTHREAD_CANCEL_ENABLE 1
#define PTHREAD_CANCEL_DISABLE 0
#if HAVE_WINRT
#define THREADFUNC_RETTYPE DWORD
#else
#define THREADFUNC_RETTYPE unsigned
typedef struct pthread_cond_t {
void *Ptr;
} pthread_cond_t;
#endif
static av_unused THREADFUNC_RETTYPE
__stdcall attribute_align_arg win32thread_worker(void *arg)
#if _WIN32_WINNT >= 0x0600
#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 = (pthread_t*)arg;
pthread_t *h = arg;
h->ret = h->func(h->arg);
return 0;
}
@@ -84,65 +82,43 @@ static av_unused int pthread_create(pthread_t *thread, const void *unused_attr,
{
thread->func = start_routine;
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,
0, NULL);
#endif
return !thread->handle;
}
static av_unused int pthread_join(pthread_t thread, void **value_ptr)
static av_unused void pthread_join(pthread_t thread, void **value_ptr)
{
DWORD ret = WaitForSingleObject(thread.handle, INFINITE);
if (ret != WAIT_OBJECT_0) {
if (ret == WAIT_ABANDONED)
return EINVAL;
else
return EDEADLK;
}
if (ret != WAIT_OBJECT_0)
return;
if (value_ptr)
*value_ptr = thread.ret;
CloseHandle(thread.handle);
return 0;
}
static inline int pthread_mutex_init(pthread_mutex_t *m, void* attr)
{
InitializeSRWLock(m);
InitializeCriticalSection(m);
return 0;
}
static inline int pthread_mutex_destroy(pthread_mutex_t *m)
{
/* Unlocked SWR locks use no resources */
DeleteCriticalSection(m);
return 0;
}
static inline int pthread_mutex_lock(pthread_mutex_t *m)
{
AcquireSRWLockExclusive(m);
EnterCriticalSection(m);
return 0;
}
static inline int pthread_mutex_unlock(pthread_mutex_t *m)
{
ReleaseSRWLockExclusive(m);
return 0;
}
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);
LeaveCriticalSection(m);
return 0;
}
#if _WIN32_WINNT >= 0x0600
static inline int pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
{
InitializeConditionVariable(cond);
@@ -150,48 +126,191 @@ static inline int pthread_cond_init(pthread_cond_t *cond, const void *unused_att
}
/* native condition variables do not destroy */
static inline int pthread_cond_destroy(pthread_cond_t *cond)
static inline void pthread_cond_destroy(pthread_cond_t *cond)
{
return 0;
return;
}
static inline int pthread_cond_broadcast(pthread_cond_t *cond)
static inline void 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)
{
SleepConditionVariableSRW(cond, mutex, INFINITE, 0);
SleepConditionVariableCS(cond, mutex, INFINITE);
return 0;
}
static inline int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime)
{
int64_t abs_milli = abstime->tv_sec * 1000LL + abstime->tv_nsec / 1000000;
DWORD t = av_clip64(abs_milli - av_gettime() / 1000, 0, UINT32_MAX);
if (!SleepConditionVariableSRW(cond, mutex, t, 0)) {
DWORD err = GetLastError();
if (err == ERROR_TIMEOUT)
return ETIMEDOUT;
else
return EINVAL;
}
return 0;
}
static inline int pthread_cond_signal(pthread_cond_t *cond)
static inline void pthread_cond_signal(pthread_cond_t *cond)
{
WakeConditionVariable(cond);
return 0;
}
static inline int pthread_setcancelstate(int state, int *oldstate)
#else // _WIN32_WINNT < 0x0600
/* for pre-Windows 6.0 platforms we need to define and use our own condition
* variable and api */
typedef struct win32_cond_t {
pthread_mutex_t mtx_broadcast;
pthread_mutex_t mtx_waiter_count;
volatile int waiter_count;
HANDLE semaphore;
HANDLE waiters_done;
volatile int is_broadcast;
} win32_cond_t;
/* function pointers to conditional variable API on windows 6.0+ kernels */
static void (WINAPI *cond_broadcast)(pthread_cond_t *cond);
static void (WINAPI *cond_init)(pthread_cond_t *cond);
static void (WINAPI *cond_signal)(pthread_cond_t *cond);
static BOOL (WINAPI *cond_wait)(pthread_cond_t *cond, pthread_mutex_t *mutex,
DWORD milliseconds);
static av_unused int pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
{
win32_cond_t *win32_cond = NULL;
if (cond_init) {
cond_init(cond);
return 0;
}
/* non native condition variables */
win32_cond = av_mallocz(sizeof(win32_cond_t));
if (!win32_cond)
return ENOMEM;
cond->Ptr = win32_cond;
win32_cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
if (!win32_cond->semaphore)
return ENOMEM;
win32_cond->waiters_done = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!win32_cond->waiters_done)
return ENOMEM;
pthread_mutex_init(&win32_cond->mtx_waiter_count, NULL);
pthread_mutex_init(&win32_cond->mtx_broadcast, NULL);
return 0;
}
#endif /* COMPAT_W32PTHREADS_H */
static av_unused void pthread_cond_destroy(pthread_cond_t *cond)
{
win32_cond_t *win32_cond = cond->Ptr;
/* native condition variables do not destroy */
if (cond_init)
return;
/* non native condition variables */
CloseHandle(win32_cond->semaphore);
CloseHandle(win32_cond->waiters_done);
pthread_mutex_destroy(&win32_cond->mtx_waiter_count);
pthread_mutex_destroy(&win32_cond->mtx_broadcast);
av_freep(&win32_cond);
cond->Ptr = NULL;
}
static av_unused void pthread_cond_broadcast(pthread_cond_t *cond)
{
win32_cond_t *win32_cond = cond->Ptr;
int have_waiter;
if (cond_broadcast) {
cond_broadcast(cond);
return;
}
/* non native condition variables */
pthread_mutex_lock(&win32_cond->mtx_broadcast);
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
have_waiter = 0;
if (win32_cond->waiter_count) {
win32_cond->is_broadcast = 1;
have_waiter = 1;
}
if (have_waiter) {
ReleaseSemaphore(win32_cond->semaphore, win32_cond->waiter_count, NULL);
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
WaitForSingleObject(win32_cond->waiters_done, INFINITE);
ResetEvent(win32_cond->waiters_done);
win32_cond->is_broadcast = 0;
} else
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
}
static av_unused int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
win32_cond_t *win32_cond = cond->Ptr;
int last_waiter;
if (cond_wait) {
cond_wait(cond, mutex, INFINITE);
return 0;
}
/* non native condition variables */
pthread_mutex_lock(&win32_cond->mtx_broadcast);
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
win32_cond->waiter_count++;
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
// unlock the external mutex
pthread_mutex_unlock(mutex);
WaitForSingleObject(win32_cond->semaphore, INFINITE);
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
win32_cond->waiter_count--;
last_waiter = !win32_cond->waiter_count || !win32_cond->is_broadcast;
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
if (last_waiter)
SetEvent(win32_cond->waiters_done);
// lock the external mutex
return pthread_mutex_lock(mutex);
}
static av_unused void pthread_cond_signal(pthread_cond_t *cond)
{
win32_cond_t *win32_cond = cond->Ptr;
int have_waiter;
if (cond_signal) {
cond_signal(cond);
return;
}
pthread_mutex_lock(&win32_cond->mtx_broadcast);
/* non-native condition variables */
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
have_waiter = win32_cond->waiter_count;
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
if (have_waiter) {
ReleaseSemaphore(win32_cond->semaphore, 1, NULL);
WaitForSingleObject(win32_cond->waiters_done, INFINITE);
ResetEvent(win32_cond->waiters_done);
}
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
}
#endif
static av_unused void w32thread_init(void)
{
#if _WIN32_WINNT < 0x0600
HANDLE kernel_dll = GetModuleHandle(TEXT("kernel32.dll"));
/* if one is available, then they should all be available */
cond_init =
(void*)GetProcAddress(kernel_dll, "InitializeConditionVariable");
cond_broadcast =
(void*)GetProcAddress(kernel_dll, "WakeAllConditionVariable");
cond_signal =
(void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
cond_wait =
(void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
#endif
}
#endif /* FFMPEG_COMPAT_W32PTHREADS_H */

View File

@@ -45,11 +45,7 @@ libname=$(mktemp -u "library").lib
trap 'rm -f -- $libname' EXIT
if [ -n "$AR" ]; then
$AR rcs ${libname} $@ >/dev/null
else
lib.exe -out:${libname} $@ >/dev/null
fi
lib -out:${libname} $@ >/dev/null
if [ $? != 0 ]; then
echo "Could not create temporary library." >&2
exit 1
@@ -58,7 +54,23 @@ fi
IFS='
'
prefix="$EXTERN_PREFIX"
# Determine if we're building for x86 or x86_64 and
# set the symbol prefix accordingly.
prefix=""
arch=$(dumpbin -headers ${libname} |
tr '\t' ' ' |
grep '^ \+.\+machine \+(.\+)' |
head -1 |
sed -e 's/^ \{1,\}.\{1,\} \{1,\}machine \{1,\}(\(...\)).*/\1/')
if [ "${arch}" = "x86" ]; then
prefix="_"
else
if [ "${arch}" != "ARM" ] && [ "${arch}" != "x64" ]; then
echo "Unknown machine type." >&2
exit 1
fi
fi
started=0
regex="none"
@@ -100,19 +112,7 @@ for line in $(cat ${vscript} | tr '\t' ' '); do
'
done
if [ -n "$NM" ]; then
# Use eval, since NM="nm -g"
dump=$(eval "$NM --defined-only -g ${libname}" |
grep -v : |
grep -v ^$ |
cut -d' ' -f3 |
sed -e "s/^${prefix}//")
else
dump=$(dumpbin.exe -linkermember:1 ${libname} |
sed -e '/public symbols/,$!d' -e '/^ \{1,\}Summary/,$d' -e "s/ \{1,\}${prefix}/ /" -e 's/ \{1,\}/ /g' |
tail -n +2 |
cut -d' ' -f3)
fi
dump=$(dumpbin -linkermember:1 ${libname})
rm ${libname}
@@ -121,6 +121,9 @@ 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

View File

@@ -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.exe $@
fi
exit $?

View File

@@ -1,32 +0,0 @@
#!/bin/sh
if [ "$1" = "--version" ]; then
rc.exe -?
exit $?
fi
if [ $# -lt 2 ]; then
echo "Usage: mswindres [-I/include/path ...] [-DSOME_DEFINE ...] [-o output.o] input.rc [output.o]" >&2
exit 0
fi
EXTRA_OPTS="-nologo"
while [ $# -gt 2 ]; do
case $1 in
-D*) EXTRA_OPTS="$EXTRA_OPTS -d$(echo $1 | sed -e "s/^..//" -e "s/ /\\\\ /g")" ;;
-I*) EXTRA_OPTS="$EXTRA_OPTS -i$(echo $1 | sed -e "s/^..//" -e "s/ /\\\\ /g")" ;;
-o) OPT_OUT="$2"; shift ;;
esac
shift
done
IN="$1"
if [ -z "$OPT_OUT" ]; then
OUT="$2"
else
OUT="$OPT_OUT"
fi
eval set -- $EXTRA_OPTS
rc.exe "$@" -fo "$OUT" "$IN"

6323
configure vendored

File diff suppressed because it is too large Load Diff

9
doc/.gitignore vendored
View File

@@ -1,9 +0,0 @@
/*.1
/*.3
/*.html
/*.pod
/config.texi
/avoptions_codec.texi
/avoptions_format.texi
/fate.txt
/print_options

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -19,18 +19,13 @@ MANPAGES3 = $(LIBRARIES-yes:%=doc/%.3)
MANPAGES = $(MANPAGES1) $(MANPAGES3)
PODPAGES = $(AVPROGS-yes:%=doc/%.pod) $(AVPROGS-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) \
doc/community.html \
doc/developer.html \
doc/faq.html \
doc/fate.html \
doc/general.html \
doc/git-howto.html \
doc/mailing-list-faq.html \
doc/nut.html \
doc/platform.html \
$(SRC_PATH)/doc/bootstrap.min.css \
$(SRC_PATH)/doc/style.min.css \
$(SRC_PATH)/doc/default.css \
TXTPAGES = doc/fate.txt \
@@ -41,6 +36,29 @@ DOCS-$(CONFIG_MANPAGES) += $(MANPAGES)
DOCS-$(CONFIG_TXTPAGES) += $(TXTPAGES)
DOCS = $(DOCS-yes)
DOC_EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading
DOC_EXAMPLES-$(CONFIG_AVCODEC_EXAMPLE) += avcodec
DOC_EXAMPLES-$(CONFIG_DECODING_ENCODING_EXAMPLE) += decoding_encoding
DOC_EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
DOC_EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE) += extract_mvs
DOC_EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio
DOC_EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE) += filtering_audio
DOC_EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE) += filtering_video
DOC_EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata
DOC_EXAMPLES-$(CONFIG_MUXING_EXAMPLE) += muxing
DOC_EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec
DOC_EXAMPLES-$(CONFIG_REMUXING_EXAMPLE) += remuxing
DOC_EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio
DOC_EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
DOC_EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
DOC_EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE) += transcoding
ALL_DOC_EXAMPLES_LIST = $(DOC_EXAMPLES-) $(DOC_EXAMPLES-yes)
DOC_EXAMPLES := $(DOC_EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
ALL_DOC_EXAMPLES := $(ALL_DOC_EXAMPLES_LIST:%=doc/examples/%$(PROGSSUF)$(EXESUF))
ALL_DOC_EXAMPLES_G := $(ALL_DOC_EXAMPLES_LIST:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
PROGS += $(DOC_EXAMPLES)
all-$(CONFIG_DOC): doc
doc: documentation
@@ -48,6 +66,8 @@ doc: documentation
apidoc: doc/doxy/html
documentation: $(DOCS)
examples: $(DOC_EXAMPLES)
TEXIDEP = perl $(SRC_PATH)/doc/texidep.pl $(SRC_PATH) $< $@ >$(@:%=%.d)
doc/%.txt: TAG = TXT
@@ -60,7 +80,7 @@ GENTEXI := $(GENTEXI:%=doc/avoptions_%.texi)
$(GENTEXI): TAG = GENTEXI
$(GENTEXI): doc/avoptions_%.texi: doc/print_options$(HOSTEXESUF)
$(M)doc/print_options$(HOSTEXESUF) $* > $@
$(M)doc/print_options $* > $@
doc/%.html: TAG = HTML
doc/%-all.html: TAG = HTML
@@ -100,13 +120,14 @@ doc/%.3: doc/%.pod $(GENTEXI)
$(M)pod2man --section=3 --center=" " --release=" " --date=" " $< > $@
$(DOCS) doc/doxy/html: | doc/
$(DOC_EXAMPLES:%$(EXESUF)=%.o): | doc/examples
OBJDIRS += doc/examples
DOXY_INPUT = $(INSTHEADERS)
DOXY_INPUT_DEPS = $(addprefix $(SRC_PATH)/, $(DOXY_INPUT)) ffbuild/config.mak
DOXY_INPUT = $(addprefix $(SRC_PATH)/, $(INSTHEADERS) $(DOC_EXAMPLES:%$(EXESUF)=%.c) $(LIB_EXAMPLES:%$(EXESUF)=%.c))
doc/doxy/html: TAG = DOXY
doc/doxy/html: $(SRC_PATH)/doc/Doxyfile $(SRC_PATH)/doc/doxy-wrapper.sh $(DOXY_INPUT_DEPS)
$(M)$(SRC_PATH)/doc/doxy-wrapper.sh $$PWD/doc/doxy $(SRC_PATH) doc/Doxyfile $(DOXYGEN) $(DOXY_INPUT);
doc/doxy/html: $(SRC_PATH)/doc/Doxyfile $(SRC_PATH)/doc/doxy-wrapper.sh $(DOXY_INPUT)
$(M)$(SRC_PATH)/doc/doxy-wrapper.sh $(SRC_PATH) $< $(DOXYGEN) $(DOXY_INPUT)
install-doc: install-html install-man
@@ -148,7 +169,11 @@ clean:: docclean
distclean:: docclean
$(RM) doc/config.texi
docclean::
examplesclean:
$(RM) $(ALL_DOC_EXAMPLES) $(ALL_DOC_EXAMPLES_G)
$(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

View File

@@ -3,9 +3,9 @@
The FFmpeg developers.
For details about the authorship, see the Git history of the project
(https://git.ffmpeg.org/ffmpeg), e.g. by typing the command
(git://source.ffmpeg.org/ffmpeg), e.g. by typing the command
@command{git log} in the FFmpeg source directory, or browsing the
online repository at @url{https://git.ffmpeg.org/ffmpeg}.
online repository at @url{http://source.ffmpeg.org}.
Maintainers for the specific components are listed in the file
@file{MAINTAINERS} in the source code tree.

View File

@@ -18,7 +18,7 @@ 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
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,
@@ -26,124 +26,36 @@ with their parameters, if any.
@section aac_adtstoasc
Convert MPEG-2/4 AAC ADTS to an MPEG-4 Audio Specific Configuration
bitstream.
Convert MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration
bitstream filter.
This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4
ADTS header and removes the ADTS header.
This filter is required for example when copying an AAC stream from a
raw ADTS AAC or an MPEG-TS container to MP4A-LATM, to an FLV file, or
to MOV/MP4 files and related formats such as 3GP or M4A. Please note
that it is auto-inserted for MP4A-LATM and MOV/MP4 and related formats.
@section av1_metadata
Modify metadata embedded in an AV1 stream.
@table @option
@item td
Insert or remove temporal delimiter OBUs in all temporal units of the
stream.
@table @samp
@item insert
Insert a TD at the beginning of every TU which does not already have one.
@item remove
Remove the TD from the beginning of every TU which has one.
@end table
@item color_primaries
@item transfer_characteristics
@item matrix_coefficients
Set the color description fields in the stream (see AV1 section 6.4.2).
@item color_range
Set the color range in the stream (see AV1 section 6.4.2; note that
this cannot be set for streams using BT.709 primaries, sRGB transfer
characteristic and identity (RGB) matrix coefficients).
@table @samp
@item tv
Limited range.
@item pc
Full range.
@end table
@item chroma_sample_position
Set the chroma sample location in the stream (see AV1 section 6.4.2).
This can only be set for 4:2:0 streams.
@table @samp
@item vertical
Left position (matching the default in MPEG-2 and H.264).
@item colocated
Top-left position.
@end table
@item tick_rate
Set the tick rate (@emph{time_scale / num_units_in_display_tick}) in
the timing info in the sequence header.
@item num_ticks_per_picture
Set the number of ticks in each picture, to indicate that the stream
has a fixed framerate. Ignored if @option{tick_rate} is not also set.
@item delete_padding
Deletes Padding OBUs.
@end table
This is required for example when copying an AAC stream from a raw
ADTS AAC container to a FLV or a MOV/MP4 file.
@section chomp
Remove zero padding at the end of a packet.
@section dca_core
Extract the core from a DCA/DTS stream, dropping extensions such as
DTS-HD.
@section dovi_rpu
Manipulate Dolby Vision metadata in a HEVC/AV1 bitstream, optionally enabling
metadata compression.
@table @option
@item strip
If enabled, strip all Dolby Vision metadata (configuration record + RPU data
blocks) from the stream.
@item compression
Which compression level to enable.
@table @samp
@item none
No metadata compression.
@item limited
Limited metadata compression scheme. Should be compatible with most devices.
This is the default.
@item extended
Extended metadata compression. Devices are not required to support this. Note
that this level currently behaves the same as @samp{limited} in libavcodec.
@end table
@end table
@section dump_extra
Add extradata to the beginning of the filtered packets except when
said packets already exactly begin with the extradata that is intended
to be added.
Add extradata to the beginning of the filtered packets.
@table @option
@item freq
The additional argument specifies which packets should be filtered.
It accepts the values:
@table @samp
@item a
add extradata to all key packets, but only if @var{local_header} is
set in the @option{flags2} codec context field
@item k
@item keyframe
add extradata to all key packets
@item e
@item all
add extradata to all packets
@end table
@end table
If not specified it is assumed @samp{k}.
@@ -155,253 +67,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
@end example
@section dv_error_marker
Blocks in DV which are marked as damaged are replaced by blocks of the specified color.
@table @option
@item color
The color to replace damaged blocks by
@item sta
A 16 bit mask which specifies which of the 16 possible error status values are
to be replaced by colored blocks. 0xFFFE is the default which replaces all non 0
error status values.
@table @samp
@item ok
No error, no concealment
@item err
Error, No concealment
@item res
Reserved
@item notok
Error or concealment
@item notres
Not reserved
@item Aa, Ba, Ca, Ab, Bb, Cb, A, B, C, a, b, erri, erru
The specific error status code
@end table
see page 44-46 or section 5.5 of
@url{http://web.archive.org/web/20060927044735/http://www.smpte.org/smpte_store/standards/pdf/s314m.pdf}
@end table
@section eac3_core
Extract the core from a E-AC-3 stream, dropping extra channels.
@section extract_extradata
Extract the in-band extradata.
Certain codecs allow the long-term headers (e.g. MPEG-2 sequence headers,
or H.264/HEVC (VPS/)SPS/PPS) to be transmitted either "in-band" (i.e. as a part
of the bitstream containing the coded frames) or "out of band" (e.g. on the
container level). This latter form is called "extradata" in FFmpeg terminology.
This bitstream filter detects the in-band headers and makes them available as
extradata.
@table @option
@item remove
When this option is enabled, the long-term headers are removed from the
bitstream after extraction.
@end table
@section filter_units
Remove units with types in or not in a given set from the stream.
@table @option
@item pass_types
List of unit types or ranges of unit types to pass through while removing
all others. This is specified as a '|'-separated list of unit type values
or ranges of values with '-'.
@item remove_types
Identical to @option{pass_types}, except the units in the given set
removed and all others passed through.
@end table
The types used by pass_types and remove_types correspond to NAL unit types
(nal_unit_type) in H.264, HEVC and H.266 (see Table 7-1 in the H.264
and HEVC specifications or Table 5 in the H.266 specification), to
marker values for JPEG (without 0xFF prefix) and to start codes without
start code prefix (i.e. the byte following the 0x000001) for MPEG-2.
For VP8 and VP9, every unit has type zero.
Extradata is unchanged by this transformation, but note that if the stream
contains inline parameter sets then the output may be unusable if they are
removed.
For example, to remove all non-VCL NAL units from an H.264 stream:
@example
ffmpeg -i INPUT -c:v copy -bsf:v 'filter_units=pass_types=1-5' OUTPUT
@end example
To remove all AUDs, SEI and filler from an H.265 stream:
@example
ffmpeg -i INPUT -c:v copy -bsf:v 'filter_units=remove_types=35|38-40' OUTPUT
@end example
To remove all user data from a MPEG-2 stream, including Closed Captions:
@example
ffmpeg -i INPUT -c:v copy -bsf:v 'filter_units=remove_types=178' OUTPUT
@end example
To remove all SEI from a H264 stream, including Closed Captions:
@example
ffmpeg -i INPUT -c:v copy -bsf:v 'filter_units=remove_types=6' OUTPUT
@end example
To remove all prefix and suffix SEI from a HEVC stream, including Closed Captions and dynamic HDR:
@example
ffmpeg -i INPUT -c:v copy -bsf:v 'filter_units=remove_types=39|40' OUTPUT
@end example
@section hapqa_extract
Extract Rgb or Alpha part of an HAPQA file, without recompression, in order to create an HAPQ or an HAPAlphaOnly file.
@table @option
@item texture
Specifies the texture to keep.
@table @option
@item color
@item alpha
@end table
@end table
Convert HAPQA to HAPQ
@example
ffmpeg -i hapqa_inputfile.mov -c copy -bsf:v hapqa_extract=texture=color -tag:v HapY -metadata:s:v:0 encoder="HAPQ" hapq_file.mov
@end example
Convert HAPQA to HAPAlphaOnly
@example
ffmpeg -i hapqa_inputfile.mov -c copy -bsf:v hapqa_extract=texture=alpha -tag:v HapA -metadata:s:v:0 encoder="HAPAlpha Only" hapalphaonly_file.mov
@end example
@section h264_metadata
Modify metadata embedded in an H.264 stream.
@table @option
@item aud
Insert or remove AUD NAL units in all access units of the stream.
@table @samp
@item pass
@item insert
@item remove
@end table
Default is pass.
@item sample_aspect_ratio
Set the sample aspect ratio of the stream in the VUI parameters.
See H.264 table E-1.
@item overscan_appropriate_flag
Set whether the stream is suitable for display using overscan
or not (see H.264 section E.2.1).
@item video_format
@item video_full_range_flag
Set the video format in the stream (see H.264 section E.2.1 and
table E-2).
@item colour_primaries
@item transfer_characteristics
@item matrix_coefficients
Set the colour description in the stream (see H.264 section E.2.1
and tables E-3, E-4 and E-5).
@item chroma_sample_loc_type
Set the chroma sample location in the stream (see H.264 section
E.2.1 and figure E-1).
@item tick_rate
Set the tick rate (time_scale / num_units_in_tick) in the VUI
parameters. This is the smallest time unit representable in the
stream, and in many cases represents the field rate of the stream
(double the frame rate).
@item fixed_frame_rate_flag
Set whether the stream has fixed framerate - typically this indicates
that the framerate is exactly half the tick rate, but the exact
meaning is dependent on interlacing and the picture structure (see
H.264 section E.2.1 and table E-6).
@item zero_new_constraint_set_flags
Zero constraint_set4_flag and constraint_set5_flag in the SPS. These
bits were reserved in a previous version of the H.264 spec, and thus
some hardware decoders require these to be zero. The result of zeroing
this is still a valid bitstream.
@item crop_left
@item crop_right
@item crop_top
@item crop_bottom
Set the frame cropping offsets in the SPS. These values will replace
the current ones if the stream is already cropped.
These fields are set in pixels. Note that some sizes may not be
representable if the chroma is subsampled or the stream is interlaced
(see H.264 section 7.4.2.1.1).
@item sei_user_data
Insert a string as SEI unregistered user data. The argument must
be of the form @emph{UUID+string}, where the UUID is as hex digits
possibly separated by hyphens, and the string can be anything.
For example, @samp{086f3693-b7b3-4f2c-9653-21492feee5b8+hello} will
insert the string ``hello'' associated with the given UUID.
@item delete_filler
Deletes both filler NAL units and filler SEI messages.
@item display_orientation
Insert, extract or remove Display orientation SEI messages.
See H.264 section D.1.27 and D.2.27 for syntax and semantics.
@table @samp
@item pass
@item insert
@item remove
@item extract
@end table
Default is pass.
Insert mode works in conjunction with @code{rotate} and @code{flip} options.
Any pre-existing Display orientation messages will be removed in insert or remove mode.
Extract mode attaches the display matrix to the packet as side data.
@item rotate
Set rotation in display orientation SEI (anticlockwise angle in degrees).
Range is -360 to +360. Default is NaN.
@item flip
Set flip in display orientation SEI.
@table @samp
@item horizontal
@item vertical
@end table
Default is unset.
@item level
Set the level in the SPS. Refer to H.264 section A.3 and tables A-1
to A-5.
The argument must be the name of a level (for example, @samp{4.2}), a
level_idc value (for example, @samp{42}), or the special name @samp{auto}
indicating that the filter should attempt to guess the level from the
input stream properties.
@end table
@section h264_mp4toannexb
Convert an H.264 bitstream from length prefixed mode to start code
@@ -409,7 +74,7 @@ prefixed mode (as defined in the Annex B of the ITU-T H.264
specification).
This is required by some streaming formats, typically the MPEG-2
transport stream format (muxer @code{mpegts}).
transport stream format ("mpegts").
For example to remux an MP4 file containing an H.264 stream to mpegts
format with @command{ffmpeg}, you can use the command:
@@ -418,102 +83,6 @@ format with @command{ffmpeg}, you can use the command:
ffmpeg -i INPUT.mp4 -codec copy -bsf:v h264_mp4toannexb OUTPUT.ts
@end example
Please note that this filter is auto-inserted for MPEG-TS (muxer
@code{mpegts}) and raw H.264 (muxer @code{h264}) output formats.
@section h264_redundant_pps
This applies a specific fixup to some Blu-ray streams which contain
redundant PPSs modifying irrelevant parameters of the stream which
confuse other transformations which require correct extradata.
@section hevc_metadata
Modify metadata embedded in an HEVC stream.
@table @option
@item aud
Insert or remove AUD NAL units in all access units of the stream.
@table @samp
@item insert
@item remove
@end table
@item sample_aspect_ratio
Set the sample aspect ratio in the stream in the VUI parameters.
@item video_format
@item video_full_range_flag
Set the video format in the stream (see H.265 section E.3.1 and
table E.2).
@item colour_primaries
@item transfer_characteristics
@item matrix_coefficients
Set the colour description in the stream (see H.265 section E.3.1
and tables E.3, E.4 and E.5).
@item chroma_sample_loc_type
Set the chroma sample location in the stream (see H.265 section
E.3.1 and figure E.1).
@item tick_rate
Set the tick rate in the VPS and VUI parameters (time_scale /
num_units_in_tick). Combined with @option{num_ticks_poc_diff_one}, this can
set a constant framerate in the stream. Note that it is likely to be
overridden by container parameters when the stream is in a container.
@item num_ticks_poc_diff_one
Set poc_proportional_to_timing_flag in VPS and VUI and use this value
to set num_ticks_poc_diff_one_minus1 (see H.265 sections 7.4.3.1 and
E.3.1). Ignored if @option{tick_rate} is not also set.
@item crop_left
@item crop_right
@item crop_top
@item crop_bottom
Set the conformance window cropping offsets in the SPS. These values
will replace the current ones if the stream is already cropped.
These fields are set in pixels. Note that some sizes may not be
representable if the chroma is subsampled (H.265 section 7.4.3.2.1).
@item width
@item height
Set width and height after crop.
@item level
Set the level in the VPS and SPS. See H.265 section A.4 and tables
A.6 and A.7.
The argument must be the name of a level (for example, @samp{5.1}), a
@emph{general_level_idc} value (for example, @samp{153} for level 5.1),
or the special name @samp{auto} indicating that the filter should
attempt to guess the level from the input stream properties.
@end table
@section hevc_mp4toannexb
Convert an HEVC/H.265 bitstream from length prefixed mode to start code
prefixed mode (as defined in the Annex B of the ITU-T H.265
specification).
This is required by some streaming formats, typically the MPEG-2
transport stream format (muxer @code{mpegts}).
For example to remux an MP4 file containing an HEVC stream to mpegts
format with @command{ffmpeg}, you can use the command:
@example
ffmpeg -i INPUT.mp4 -codec copy -bsf:v hevc_mp4toannexb OUTPUT.ts
@end example
Please note that this filter is auto-inserted for MPEG-TS (muxer
@code{mpegts}) and raw HEVC/H.265 (muxer @code{h265} or
@code{hevc}) output formats.
@section imxdump
Modifies the bitstream to fit in MOV and to be usable by the Final Cut
@@ -564,440 +133,28 @@ exiftran -i -9 frame*.jpg
ffmpeg -i frame_%d.jpg -c:v copy rotated.avi
@end example
@section mjpegadump
@section mjpega_dump_header
Add an MJPEG A header to the bitstream, to enable decoding by
Quicktime.
@section movsub
@anchor{mov2textsub}
@section mov2textsub
Extract a representable text file from MOV subtitles, stripping the
metadata header from each subtitle packet.
See also the @ref{text2movsub} filter.
@section mpeg2_metadata
Modify metadata embedded in an MPEG-2 stream.
@table @option
@item display_aspect_ratio
Set the display aspect ratio in the stream.
The following fixed values are supported:
@table @option
@item 4/3
@item 16/9
@item 221/100
@end table
Any other value will result in square pixels being signalled instead
(see H.262 section 6.3.3 and table 6-3).
@item frame_rate
Set the frame rate in the stream. This is constructed from a table
of known values combined with a small multiplier and divisor - if
the supplied value is not exactly representable, the nearest
representable value will be used instead (see H.262 section 6.3.3
and table 6-4).
@item video_format
Set the video format in the stream (see H.262 section 6.3.6 and
table 6-6).
@item colour_primaries
@item transfer_characteristics
@item matrix_coefficients
Set the colour description in the stream (see H.262 section 6.3.6
and tables 6-7, 6-8 and 6-9).
@end table
@section mpeg4_unpack_bframes
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 mp3_header_decompress
@section noise
Damages the contents of packets or simply drops them without damaging the
container. Can be used for fuzzing or testing error resilience/concealment.
Damages the contents of packets without damaging the container. Can be
used for fuzzing or testing error resilience/concealment.
Parameters:
@table @option
@item amount
Accepts an expression whose evaluation per-packet determines how often bytes in that
packet will be modified. A value below 0 will result in a variable frequency.
Default is 0 which results in no modification. However, if neither amount nor drop is specified,
amount will be set to @var{-1}. See below for accepted variables.
@item drop
Accepts an expression evaluated per-packet whose value determines whether that packet is dropped.
Evaluation to a positive value results in the packet being dropped. Evaluation to a negative
value results in a variable chance of it being dropped, roughly inverse in proportion to the magnitude
of the value. Default is 0 which results in no drops. See below for accepted variables.
@item dropamount
Accepts a non-negative integer, which assigns a variable chance of it being dropped, roughly inverse
in proportion to the value. Default is 0 which results in no drops. This option is kept for backwards
compatibility and is equivalent to setting drop to a negative value with the same magnitude
i.e. @code{dropamount=4} is the same as @code{drop=-4}. Ignored if drop is also specified.
@end table
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.
Both @code{amount} and @code{drop} accept expressions containing the following variables:
@table @samp
@item n
The index of the packet, starting from zero.
@item tb
The timebase for packet timestamps.
@item pts
Packet presentation timestamp.
@item dts
Packet decoding timestamp.
@item nopts
Constant representing AV_NOPTS_VALUE.
@item startpts
First non-AV_NOPTS_VALUE PTS seen in the stream.
@item startdts
First non-AV_NOPTS_VALUE DTS seen in the stream.
@item duration
@itemx d
Packet duration, in timebase units.
@item pos
Packet position in input; may be -1 when unknown or not set.
@item size
Packet size, in bytes.
@item key
Whether packet is marked as a keyframe.
@item state
A pseudo random integer, primarily derived from the content of packet payload.
@end table
@subsection Examples
Apply modification to every byte but don't drop any packets.
@example
ffmpeg -i INPUT -c copy -bsf noise=1 output.mkv
@end example
Drop every video packet not marked as a keyframe after timestamp 30s but do not
modify any of the remaining packets.
@example
ffmpeg -i INPUT -c copy -bsf:v noise=drop='gt(t\,30)*not(key)' output.mkv
@end example
Drop one second of audio every 10 seconds and add some random noise to the rest.
@example
ffmpeg -i INPUT -c copy -bsf:a noise=amount=-1:drop='between(mod(t\,10)\,9\,10)' output.mkv
@end example
@section null
This bitstream filter passes the packets through unchanged.
@section pcm_rechunk
Repacketize PCM audio to a fixed number of samples per packet or a fixed packet
rate per second. This is similar to the @ref{asetnsamples,,asetnsamples audio
filter,ffmpeg-filters} but works on audio packets instead of audio frames.
@table @option
@item nb_out_samples, n
Set the number of samples per each output audio packet. The number is intended
as the number of samples @emph{per each channel}. Default value is 1024.
@item pad, p
If set to 1, the filter will pad the last audio packet with silence, so that it
will contain the same number of samples (or roughly the same number of samples,
see @option{frame_rate}) as the previous ones. Default value is 1.
@item frame_rate, r
This option makes the filter output a fixed number of packets per second instead
of a fixed number of samples per packet. If the audio sample rate is not
divisible by the frame rate then the number of samples will not be constant but
will vary slightly so that each packet will start as close to the frame
boundary as possible. Using this option has precedence over @option{nb_out_samples}.
@end table
You can generate the well known 1602-1601-1602-1601-1602 pattern of 48kHz audio
for NTSC frame rate using the @option{frame_rate} option.
@example
ffmpeg -f lavfi -i sine=r=48000:d=1 -c pcm_s16le -bsf pcm_rechunk=r=30000/1001 -f framecrc -
@end example
@section pgs_frame_merge
Merge a sequence of PGS Subtitle segments ending with an "end of display set"
segment into a single packet.
This is required by some containers that support PGS subtitles
(muxer @code{matroska}).
@section prores_metadata
Modify color property metadata embedded in prores stream.
@table @option
@item color_primaries
Set the color primaries.
Available values are:
@table @samp
@item auto
Keep the same color primaries property (default).
@item unknown
@item bt709
@item bt470bg
BT601 625
@item smpte170m
BT601 525
@item bt2020
@item smpte431
DCI P3
@item smpte432
P3 D65
@end table
@item transfer_characteristics
Set the color transfer.
Available values are:
@table @samp
@item auto
Keep the same transfer characteristics property (default).
@item unknown
@item bt709
BT 601, BT 709, BT 2020
@item smpte2084
SMPTE ST 2084
@item arib-std-b67
ARIB STD-B67
@end table
@item matrix_coefficients
Set the matrix coefficient.
Available values are:
@table @samp
@item auto
Keep the same colorspace property (default).
@item unknown
@item bt709
@item smpte170m
BT 601
@item bt2020nc
@end table
@end table
Set Rec709 colorspace for each frame of the file
@example
ffmpeg -i INPUT -c copy -bsf:v prores_metadata=color_primaries=bt709:color_trc=bt709:colorspace=bt709 output.mov
@end example
Set Hybrid Log-Gamma parameters for each frame of the file
@example
ffmpeg -i INPUT -c copy -bsf:v prores_metadata=color_primaries=bt2020:color_trc=arib-std-b67:colorspace=bt2020nc output.mov
ffmpeg -i INPUT -c copy -bsf noise[=1] output.mkv
@end example
applies the modification to every byte.
@section remove_extra
Remove extradata from packets.
It accepts the following parameter:
@table @option
@item freq
Set which frame types to remove extradata from.
@table @samp
@item k
Remove extradata from non-keyframes only.
@item keyframe
Remove extradata from keyframes only.
@item e, all
Remove extradata from all frames.
@end table
@end table
@section setts
Set PTS and DTS in packets.
It accepts the following parameters:
@table @option
@item ts
@item pts
@item dts
Set expressions for PTS, DTS or both.
@item duration
Set expression for duration.
@item time_base
Set output time base.
@end table
The expressions are evaluated through the eval API and can contain the following
constants:
@table @option
@item N
The count of the input packet. Starting from 0.
@item TS
The demux timestamp in input in case of @code{ts} or @code{dts} option or presentation
timestamp in case of @code{pts} option.
@item POS
The original position in the file of the packet, or undefined if undefined
for the current packet
@item DTS
The demux timestamp in input.
@item PTS
The presentation timestamp in input.
@item DURATION
The duration in input.
@item STARTDTS
The DTS of the first packet.
@item STARTPTS
The PTS of the first packet.
@item PREV_INDTS
The previous input DTS.
@item PREV_INPTS
The previous input PTS.
@item PREV_INDURATION
The previous input duration.
@item PREV_OUTDTS
The previous output DTS.
@item PREV_OUTPTS
The previous output PTS.
@item PREV_OUTDURATION
The previous output duration.
@item NEXT_DTS
The next input DTS.
@item NEXT_PTS
The next input PTS.
@item NEXT_DURATION
The next input duration.
@item TB
The timebase of stream packet belongs.
@item TB_OUT
The output timebase.
@item SR
The sample rate of stream packet belongs.
@item NOPTS
The AV_NOPTS_VALUE constant.
@end table
For example, to set PTS equal to DTS (not recommended if B-frames are involved):
@example
ffmpeg -i INPUT -c:a copy -bsf:a setts=pts=DTS out.mkv
@end example
@section showinfo
Log basic packet information. Mainly useful for testing, debugging,
and development.
@anchor{text2movsub}
@section text2movsub
Convert text subtitles to MOV subtitles (as used by the @code{mov_text}
codec) with metadata headers.
See also the @ref{mov2textsub} filter.
@section trace_headers
Log trace output containing all syntax elements in the coded stream
headers (everything above the level of individual coded blocks).
This can be useful for debugging low-level stream issues.
Supports AV1, H.264, H.265, (M)JPEG, MPEG-2 and VP9, but depending
on the build only a subset of these may be available.
@section truehd_core
Extract the core from a TrueHD stream, dropping ATMOS data.
@section vp9_metadata
Modify metadata embedded in a VP9 stream.
@table @option
@item color_space
Set the color space value in the frame header. Note that any frame
set to RGB will be implicitly set to PC range and that RGB is
incompatible with profiles 0 and 2.
@table @samp
@item unknown
@item bt601
@item bt709
@item smpte170
@item smpte240
@item bt2020
@item rgb
@end table
@item color_range
Set the color range value in the frame header. Note that any value
imposed by the color space will take precedence over this value.
@table @samp
@item tv
@item pc
@end table
@end table
@section vp9_superframe
Merge VP9 invisible (alt-ref) frames back into VP9 superframes. This
fixes merging of split/segmented VP9 streams where the alt-ref frame
was split from its visible counterpart.
@section vp9_superframe_split
Split VP9 superframes into single frames.
@section vp9_raw_reorder
Given a VP9 stream with correct timestamps but possibly out of order,
insert additional show-existing-frame packets to correct the ordering.
@c man end BITSTREAM FILTERS

File diff suppressed because one or more lines are too long

View File

@@ -9,26 +9,23 @@ V
DBG
Preprocess x86 external assembler files to a .dbg.asm file in the object
directory, which then gets compiled. Helps in developing those assembler
directory, which then gets compiled. Helps developping those assembler
files.
DESTDIR
Destination directory for the install targets, useful to prepare packages
or install FFmpeg in cross-environments.
GEN
Set to 1 to generate the missing or mismatched references.
Makefile targets:
all
Default target, builds all the libraries and the executables.
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
List all fate/regression test targets.
Will list all fate/regression test targets
install
Install headers, libraries and programs.
@@ -36,31 +33,29 @@ install
examples
Build all examples located in doc/examples.
checkheaders
Check headers dependencies.
libavformat/output-example
Build the libavformat basic example.
alltools
Build all tools in tools directory.
libavcodec/api-example
Build the libavcodec basic example.
libswscale/swscale-test
Build the swscale self-test (useful also as example).
config
Reconfigure the project with the current configuration.
Reconfigure the project with current configuration.
tools/target_dec_<decoder>_fuzzer
Build fuzzer to fuzz the specified decoder.
tools/target_bsf_<filter>_fuzzer
Build fuzzer to fuzz the specified bitstream filter.
Useful standard make commands:
make -t <target>
Touch all files that otherwise would be built, this is useful to reduce
unneeded rebuilding when changing headers, but note that you must force rebuilds
Touch all files that otherwise would be build, this is useful to reduce
unneeded rebuilding when changing headers, but note you must force rebuilds
of files that actually need it by hand then.
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
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.
continue build in case of errors, this is useful for the regression tests
sometimes but note it will still not run all reg tests.

View File

@@ -3,7 +3,7 @@
@c man begin CODEC OPTIONS
libavcodec provides some generic global options, which can be set on
all the encoders and decoders. In addition, each codec may support
all the encoders and decoders. In addition each codec may support
so-called private options, which are specific for a given codec.
Sometimes, a global option may only affect a specific kind of codec,
@@ -44,20 +44,26 @@ Use 1/4 pel motion compensation.
Use loop filter.
@item qscale
Use fixed qscale.
@item gmc
Use gmc.
@item mv0
Always try a mb with mv=<0,0>.
@item input_preserved
@item pass1
Use internal 2pass ratecontrol in first pass mode.
@item pass2
Use internal 2pass ratecontrol in second pass mode.
@item gray
Only decode/encode grayscale.
@item emu_edge
Do not draw edges.
@item psnr
Set error[?] variables during encoding.
@item truncated
Input bitstream might be randomly truncated.
@item drop_changed
Don't output frames whose parameters differ from first decoded frame in stream.
Error AVERROR_INPUT_CHANGED is returned when a frame is dropped.
@item naq
Normalize adaptive quantization.
@item ildct
Use interlaced DCT.
@item low_delay
@@ -70,14 +76,50 @@ This ensures that file and data checksums are reproducible and match between
platforms. Its primary use is for regression testing.
@item aic
Apply H263 advanced intra coding / mpeg4 ac prediction.
@item cbp
Deprecated, use mpegvideo private options instead.
@item qprd
Deprecated, use mpegvideo private options instead.
@item ilme
Apply interlaced motion estimation.
@item cgop
Use closed gop.
@item output_corrupt
Output even potentially corrupted frames.
@end table
@item me_method @var{integer} (@emph{encoding,video})
Set motion estimation method.
Possible values:
@table @samp
@item zero
zero motion estimation (fastest)
@item full
full motion estimation (slowest)
@item epzs
EPZS motion estimation (default)
@item esa
esa motion estimation (alias for full)
@item tesa
tesa motion estimation
@item dia
dia motion estimation (alias for epzs)
@item log
log motion estimation
@item phods
phods motion estimation
@item x1
X1 motion estimation
@item hex
hex motion estimation
@item umh
umh motion estimation
@item iter
iter motion estimation
@end table
@item extradata_size @var{integer}
Set extradata size.
@item time_base @var{rational number}
Set codec time base.
@@ -87,7 +129,7 @@ should be @code{1 / frame_rate} and timestamp increments should be
identically 1.
@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})
Set audio sampling rate (in Hz).
@@ -96,8 +138,7 @@ Set audio sampling rate (in Hz).
Set number of audio channels.
@item cutoff @var{integer} (@emph{encoding,audio})
Set cutoff bandwidth. (Supported only by selected encoders, see
their respective documentation sections.)
Set cutoff bandwidth.
@item frame_size @var{integer} (@emph{encoding,audio})
Set audio frame size.
@@ -144,6 +185,24 @@ Default value is 0.
@item b_qfactor @var{float} (@emph{encoding,video})
Set qp factor between P and B frames.
@item rc_strategy @var{integer} (@emph{encoding,video})
Set ratecontrol method.
@item b_strategy @var{integer} (@emph{encoding,video})
Set strategy to choose between I/P/B-frames.
@item ps @var{integer} (@emph{encoding,video})
Set RTP payload size in bytes.
@item mv_bits @var{integer}
@item header_bits @var{integer}
@item i_tex_bits @var{integer}
@item p_tex_bits @var{integer}
@item i_count @var{integer}
@item p_count @var{integer}
@item skip_count @var{integer}
@item misc_bits @var{integer}
@item frame_bits @var{integer}
@item codec_tag @var{integer}
@item bug @var{flags} (@emph{decoding,video})
Workaround not auto detected encoder bugs.
@@ -152,6 +211,8 @@ Possible values:
@table @samp
@item autodetect
@item old_msmpeg4
some old lavc generated msmpeg4v3 files (no autodetection)
@item xvid_ilace
Xvid interlacing bug (autodetected if fourcc==XVIX)
@item ump4
@@ -160,6 +221,8 @@ Xvid interlacing bug (autodetected if fourcc==XVIX)
padding bug (autodetected)
@item amv
@item ac_vlc
illegal vlc bug (autodetected per fourcc)
@item qpel_chroma
@item std_qpel
@@ -180,13 +243,21 @@ Workaround various bugs in microsoft broken decoders.
trancated frames
@end table
@item lelim @var{integer} (@emph{encoding,video})
Set single coefficient elimination threshold for luminance (negative
values also consider DC coefficient).
@item celim @var{integer} (@emph{encoding,video})
Set single coefficient elimination threshold for chrominance (negative
values also consider dc coefficient)
@item strict @var{integer} (@emph{decoding/encoding,audio,video})
Specify how strictly to follow the standards.
Possible values:
@table @samp
@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
strictly conform to all the things in the spec no matter what consequences
@item normal
@@ -233,8 +304,29 @@ consider things that a sane encoder should not do as an error
@item block_align @var{integer}
@item mpeg_quant @var{integer} (@emph{encoding,video})
Use MPEG quantizers instead of H.263.
@item qsquish @var{float} (@emph{encoding,video})
How to keep quantizer between qmin and qmax (0 = clip, 1 = use
differentiable function).
@item rc_qmod_amp @var{float} (@emph{encoding,video})
Set experimental quantizer modulation.
@item rc_qmod_freq @var{integer} (@emph{encoding,video})
Set experimental quantizer modulation.
@item rc_override_count @var{integer}
@item rc_eq @var{string} (@emph{encoding,video})
Set rate control equation. When computing the expression, besides the
standard functions defined in the section 'Expression Evaluation', the
following functions are available: bits2qp(bits), qp2bits(qp). Also
the following constants are available: iTex pTex tex mv fCode iCount
mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex
avgTex.
@item maxrate @var{integer} (@emph{encoding,audio,video})
Set max bitrate tolerance (in bits/s). Requires bufsize to be set.
@@ -245,12 +337,18 @@ encode. It is of little use elsewise.
@item bufsize @var{integer} (@emph{encoding,audio,video})
Set ratecontrol buffer size (in bits).
@item rc_buf_aggressivity @var{float} (@emph{encoding,video})
Currently useless.
@item i_qfactor @var{float} (@emph{encoding,video})
Set QP factor between P and I frames.
@item i_qoffset @var{float} (@emph{encoding,video})
Set QP offset between P and I frames.
@item rc_init_cplx @var{float} (@emph{encoding,video})
Set initial complexity for 1-pass encoding.
@item dct @var{integer} (@emph{encoding,video})
Set DCT algorithm.
@@ -315,7 +413,11 @@ Automatically pick a IDCT compatible with the simple one
@item simpleneon
@item xvid
@item simplealpha
@item ipp
@item xvidmmx
@item faani
floating point AAN IDCT
@@ -338,12 +440,22 @@ favor predicting from the previous frame instead of the current
@item bits_per_coded_sample @var{integer}
@item pred @var{integer} (@emph{encoding,video})
Set prediction method.
Possible values:
@table @samp
@item left
@item plane
@item median
@end table
@item aspect @var{rational number} (@emph{encoding,video})
Set sample aspect ratio.
@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})
Print specific debug info.
@@ -359,21 +471,26 @@ rate control
macroblock (MB) type
@item qp
per-block quantization parameter (QP)
@item mv
motion vector
@item dct_coeff
@item green_metadata
display complexity metadata for the upcoming frame, GoP or for a given duration.
@item skip
@item startcode
@item pts
@item er
error recognition
@item mmco
memory management control operations (H.264)
@item bugs
@item vis_qp
visualize quantization parameter (QP), lower QP are tinted greener
@item vis_mb_type
visualize block types
@item buffers
picture buffer allocations
@item thread_ops
@@ -382,6 +499,21 @@ threading operations
skip motion compensation
@end table
@item vismv @var{integer} (@emph{decoding,video})
Visualize motion vectors (MVs).
This option is deprecated, see the codecview filter instead.
Possible values:
@table @samp
@item pf
forward predicted MVs of P-frames
@item bf
forward predicted MVs of B-frames
@item bb
backward predicted MVs of B-frames
@end table
@item cmp @var{integer} (@emph{encoding,video})
Set full pel me compare function.
@@ -532,28 +664,13 @@ noise preserving sum of squared differences
@item dia_size @var{integer} (@emph{encoding,video})
Set diamond type & size for motion estimation.
@table @samp
@item (1024, INT_MAX)
full motion estimation(slowest)
@item (768, 1024]
umh motion estimation
@item (512, 768]
hex motion estimation
@item (256, 512]
l2s diamond motion estimation
@item [2,256]
var diamond motion estimation
@item (-1, 2)
small diamond motion estimation
@item -1
funny diamond motion estimation
@item (INT_MIN, -1)
sab diamond motion estimation
@end table
@item last_pred @var{integer} (@emph{encoding,video})
Set amount of motion predictors from the previous frame.
@item preme @var{integer} (@emph{encoding,video})
Set pre motion estimation.
@item precmp @var{integer} (@emph{encoding,video})
Set pre motion estimation compare function.
@@ -597,13 +714,44 @@ Set diamond type & size for motion estimation pre-pass.
@item subq @var{integer} (@emph{encoding,video})
Set sub pel motion estimation quality.
@item dtg_active_format @var{integer}
@item me_range @var{integer} (@emph{encoding,video})
Set limit motion vectors range (1023 for DivX player).
@item ibias @var{integer} (@emph{encoding,video})
Set intra quant bias.
@item pbias @var{integer} (@emph{encoding,video})
Set inter quant bias.
@item color_table_id @var{integer}
@item global_quality @var{integer} (@emph{encoding,audio,video})
@item coder @var{integer} (@emph{encoding,video})
Possible values:
@table @samp
@item vlc
variable length coder / huffman coder
@item ac
arithmetic coder
@item raw
raw (no encoding)
@item rle
run-length coder
@item deflate
deflate-based coder
@end table
@item context @var{integer} (@emph{encoding,video})
Set context model.
@item slice_flags @var{integer}
@item xvmc_acceleration @var{integer}
@item mbd @var{integer} (@emph{encoding,video})
Set macroblock decision algorithm (high quality mode).
@@ -617,16 +765,32 @@ use fewest bits
use best rate distortion
@end table
@item stream_codec_tag @var{integer}
@item sc_threshold @var{integer} (@emph{encoding,video})
Set scene change threshold.
@item lmin @var{integer} (@emph{encoding,video})
Set min lagrange factor (VBR).
@item lmax @var{integer} (@emph{encoding,video})
Set max lagrange factor (VBR).
@item nr @var{integer} (@emph{encoding,video})
Set noise reduction.
@item rc_init_occupancy @var{integer} (@emph{encoding,video})
Set number of bits which should be loaded into the rc buffer before
decoding starts.
@item flags2 @var{flags} (@emph{decoding/encoding,audio,video,subtitles})
@item flags2 @var{flags} (@emph{decoding/encoding,audio,video})
Possible values:
@table @samp
@item fast
Allow non spec compliant speedup tricks.
@item sgop
Deprecated, use mpegvideo private options instead.
@item noout
Skip bitstream encoding.
@item ignorecrop
@@ -637,46 +801,31 @@ Place global headers at every keyframe instead of in extradata.
Frame data might be split into multiple chunks.
@item showall
Show all frames before the first keyframe.
@item skiprd
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}.
@item skip_manual
Do not skip samples and export skip information as frame side data.
@item ass_ro_flush_noop
Do not reset ASS ReadOrder field on flush.
@item icc_profiles
Generate/parse embedded ICC profiles from/to colorimetry tags.
@end table
@item export_side_data @var{flags} (@emph{decoding/encoding,audio,video,subtitles})
@item error @var{integer} (@emph{encoding,video})
Possible values:
@table @samp
@item mvs
Export motion vectors into frame side-data (see @code{AV_FRAME_DATA_MOTION_VECTORS})
for codecs that support it. See also @file{doc/examples/export_mvs.c}.
@item prft
Export encoder Producer Reference Time into packet side-data (see @code{AV_PKT_DATA_PRFT})
for codecs that support it.
@item venc_params
Export video encoding parameters through frame side data (see @code{AV_FRAME_DATA_VIDEO_ENC_PARAMS})
for codecs that support it. At present, those are H.264 and VP9.
@item film_grain
Export film grain parameters through frame side data (see @code{AV_FRAME_DATA_FILM_GRAIN_PARAMS}).
Supported at present by AV1 decoders.
@end table
@item qns @var{integer} (@emph{encoding,video})
Deprecated, use mpegvideo private options instead.
@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:
@table @samp
@item auto, 0
automatically select the number of threads to set
@item auto
detect a good number of threads
@end table
Default value is @samp{auto}.
@item me_threshold @var{integer} (@emph{encoding,video})
Set motion estimation threshold.
@item mb_threshold @var{integer} (@emph{encoding,video})
Set macroblock threshold.
@item dc @var{integer} (@emph{encoding,video})
Set intra_dc_precision.
@@ -692,29 +841,122 @@ Set number of macroblock rows at the bottom which are skipped.
@item profile @var{integer} (@emph{encoding,audio,video})
Set encoder codec profile. Default value is @samp{unknown}. Encoder specific
profiles are documented in the relevant encoder documentation.
Possible values:
@table @samp
@item unknown
@item aac_main
@item aac_low
@item aac_ssr
@item aac_ltp
@item aac_he
@item aac_he_v2
@item aac_ld
@item aac_eld
@item mpeg2_aac_low
@item mpeg2_aac_he
@item mpeg4_sp
@item mpeg4_core
@item mpeg4_main
@item mpeg4_asp
@item dts
@item dts_es
@item dts_96_24
@item dts_hd_hra
@item dts_hd_ma
@end table
@item level @var{integer} (@emph{encoding,audio,video})
Set the encoder level. This level depends on the specific codec, and
might correspond to the profile level. It is set by default to
@samp{unknown}.
Possible values:
@table @samp
@item unknown
@end table
@item lowres @var{integer} (@emph{decoding,audio,video})
Decode at 1= 1/2, 2=1/4, 3=1/8 resolutions.
@item skip_threshold @var{integer} (@emph{encoding,video})
Set frame skip threshold.
@item skip_factor @var{integer} (@emph{encoding,video})
Set frame skip factor.
@item skip_exp @var{integer} (@emph{encoding,video})
Set frame skip exponent.
Negative values behave identical to the corresponding positive ones, except
that the score is normalized.
Positive values exist primarily for compatibility reasons and are not so useful.
@item skipcmp @var{integer} (@emph{encoding,video})
Set frame skip compare function.
Possible values:
@table @samp
@item sad
sum of absolute differences, fast (default)
@item sse
sum of squared errors
@item satd
sum of absolute Hadamard transformed differences
@item dct
sum of absolute DCT transformed differences
@item psnr
sum of squared quantization errors (avoid, low quality)
@item bit
number of bits needed for the block
@item rd
rate distortion optimal, slow
@item zero
0
@item vsad
sum of absolute vertical differences
@item vsse
sum of squared vertical differences
@item nsse
noise preserving sum of squared differences
@item w53
5/3 wavelet, only used in snow
@item w97
9/7 wavelet, only used in snow
@item dctmax
@item chroma
@end table
@item border_mask @var{float} (@emph{encoding,video})
Increase the quantizer for macroblocks close to borders.
@item mblmin @var{integer} (@emph{encoding,video})
Set min macroblock lagrange factor (VBR).
@item mblmax @var{integer} (@emph{encoding,video})
Set max macroblock lagrange factor (VBR).
@item mepc @var{integer} (@emph{encoding,video})
Set motion estimation bitrate penalty compensation (1.0 = 256).
@item skip_loop_filter @var{integer} (@emph{decoding,video})
@item skip_idct @var{integer} (@emph{decoding,video})
@item skip_frame @var{integer} (@emph{decoding,video})
@@ -742,9 +984,6 @@ Discard all bidirectional frames.
@item nokey
Discard all frames excepts keyframes.
@item nointra
Discard all frames except I frames.
@item all
Discard all frames.
@end table
@@ -754,162 +993,57 @@ Default value is @samp{default}.
@item bidir_refine @var{integer} (@emph{encoding,video})
Refine the two motion vectors used in bidirectional macroblocks.
@item brd_scale @var{integer} (@emph{encoding,video})
Downscale frames for dynamic B-frame decision.
@item keyint_min @var{integer} (@emph{encoding,video})
Set minimum interval between IDR-frames.
@item refs @var{integer} (@emph{encoding,video})
Set reference frames to consider for motion compensation.
@item chromaoffset @var{integer} (@emph{encoding,video})
Set chroma qp offset from luma.
@item trellis @var{integer} (@emph{encoding,audio,video})
Set rate-distortion optimal quantization.
@item sc_factor @var{integer} (@emph{encoding,video})
Set value multiplied by qscale for each frame and added to
scene_change_score.
@item mv0_threshold @var{integer} (@emph{encoding,video})
@item b_sensitivity @var{integer} (@emph{encoding,video})
Adjust sensitivity of b_frame_strategy 1.
@item compression_level @var{integer} (@emph{encoding,audio,video})
@item min_prediction_order @var{integer} (@emph{encoding,audio})
@item max_prediction_order @var{integer} (@emph{encoding,audio})
@item timecode_frame_start @var{integer} (@emph{encoding,video})
Set GOP timecode frame start number, in non drop frame format.
@item request_channels @var{integer} (@emph{decoding,audio})
Set desired number of audio channels.
@item bits_per_raw_sample @var{integer}
@item channel_layout @var{integer} (@emph{decoding/encoding,audio})
See @ref{channel layout syntax,,the Channel Layout section in the ffmpeg-utils(1) manual,ffmpeg-utils}
for the required syntax.
Possible values:
@table @samp
@end table
@item request_channel_layout @var{integer} (@emph{decoding,audio})
Possible values:
@table @samp
@end table
@item rc_max_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 color_primaries @var{integer} (@emph{decoding/encoding,video})
Possible values:
@table @samp
@item bt709
BT.709
@item bt470m
BT.470 M
@item bt470bg
BT.470 BG
@item smpte170m
SMPTE 170 M
@item smpte240m
SMPTE 240 M
@item film
Film
@item bt2020
BT.2020
@item smpte428
@item smpte428_1
SMPTE ST 428-1
@item smpte431
SMPTE 431-2
@item smpte432
SMPTE 432-1
@item jedec-p22
JEDEC P22
@end table
@item color_trc @var{integer} (@emph{decoding/encoding,video})
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
@item log100
Log
@item log_sqrt
@item log316
Log square root
@item iec61966_2_4
@item iec61966-2-4
IEC 61966-2-4
@item bt1361
@item bt1361e
BT.1361
@item iec61966_2_1
@item iec61966-2-1
IEC 61966-2-1
@item bt2020_10
@item bt2020_10bit
BT.2020 - 10 bit
@item bt2020_12
@item bt2020_12bit
BT.2020 - 12 bit
@item smpte2084
SMPTE ST 2084
@item smpte428
@item smpte428_1
SMPTE ST 428-1
@item arib-std-b67
ARIB STD-B67
@end table
@item colorspace @var{integer} (@emph{decoding/encoding,video})
Possible values:
@table @samp
@item rgb
RGB
@item bt709
BT.709
@item fcc
FCC
@item bt470bg
BT.470 BG
@item smpte170m
SMPTE 170 M
@item smpte240m
SMPTE 240 M
@item ycocg
YCOCG
@item bt2020nc
@item bt2020_ncl
BT.2020 NCL
@item bt2020c
@item bt2020_cl
BT.2020 CL
@item smpte2085
SMPTE 2085
@item chroma-derived-nc
Chroma-derived NCL
@item chroma-derived-c
Chroma-derived CL
@item ictcp
ICtCp
@end table
@item color_range @var{integer} (@emph{decoding/encoding,video})
If used as input parameter, it serves as a hint to the decoder, which
color_range the input has.
Possible values:
@table @samp
@item tv
@item mpeg
@item limited
MPEG (219*2^(n-8))
@item pc
@item jpeg
@item full
JPEG (2^n-1)
@end table
@item chroma_sample_location @var{integer} (@emph{decoding/encoding,video})
Possible values:
@table @samp
@item left
@item center
@item topleft
@item top
@item bottomleft
@item bottom
@end table
@item log_level_offset @var{integer}
Set the log level offset.
@@ -988,37 +1122,23 @@ Interlaced video, top coded first, bottom displayed first
Interlaced video, bottom coded first, top displayed first
@end table
@item skip_alpha @var{bool} (@emph{decoding,video})
@item skip_alpha @var{integer} (@emph{decoding,video})
Set to 1 to disable processing alpha (transparency). This works like the
@samp{gray} flag in the @option{flags} option which skips chroma information
instead of alpha. Default is 0.
@item codec_whitelist @var{list} (@emph{input})
"," separated list of allowed decoders. By default all are allowed.
"," separated List of allowed decoders. By default all are allowed.
@item dump_separator @var{string} (@emph{input})
Separator used to separate the fields printed on the command line about the
Stream parameters.
For example, to separate the fields with newlines and indentation:
For example to separate the fields with newlines and indention:
@example
ffprobe -dump_separator "
" -i ~/videos/matrixbench_mpeg2.mpg
@end example
@item max_pixels @var{integer} (@emph{decoding/encoding,video})
Maximum number of pixels per image. This value can be used to avoid out of
memory failures due to large images.
@item apply_cropping @var{bool} (@emph{decoding,video})
Enable cropping if cropping parameters are multiples of the required
alignment for the left and top parameters. If the alignment is not met the
cropping will be partially applied to maintain alignment.
Default is 1 (enabled).
Note: The required alignment depends on if @code{AV_CODEC_FLAG_UNALIGNED} is set and the
CPU. @code{AV_CODEC_FLAG_UNALIGNED} cannot be changed from the command line. Also hardware
decoders will not apply left/top Cropping.
@end table
@c man end CODEC OPTIONS

View File

@@ -1,182 +0,0 @@
\input texinfo @c -*- texinfo -*-
@documentencoding UTF-8
@settitle Community
@titlepage
@center @titlefont{Community}
@end titlepage
@top
@contents
@anchor{Organisation}
@chapter Organisation
The FFmpeg project is organized through a community working on global consensus.
Decisions are taken by the ensemble of active members, through voting and are aided by two committees.
@anchor{General Assembly}
@chapter General Assembly
The ensemble of active members is called the General Assembly (GA).
The General Assembly is sovereign and legitimate for all its decisions regarding the FFmpeg project.
The General Assembly is made up of active contributors.
Contributors are considered "active contributors" if they have authored more than 20 patches in the last 36 months in the main FFmpeg repository, or if they have been voted in by the GA.
The list of active contributors is updated twice each year, on 1st January and 1st July, 0:00 UTC.
Additional members are added to the General Assembly through a vote after proposal by a member of the General Assembly. They are part of the GA for two years, after which they need a confirmation by the GA.
A script to generate the current members of the general assembly (minus members voted in) can be found in `tools/general_assembly.pl`.
@anchor{Voting}
@chapter Voting
Voting is done using a ranked voting system, currently running on https://vote.ffmpeg.org/ .
Majority vote means more than 50% of the expressed ballots.
@anchor{Technical Committee}
@chapter Technical Committee
The Technical Committee (TC) is here to arbitrate and make decisions when technical conflicts occur in the project. They will consider the merits of all the positions, judge them and make a decision.
The TC resolves technical conflicts but is not a technical steering committee.
Decisions by the TC are binding for all the contributors.
Decisions made by the TC can be re-opened after 1 year or by a majority vote of the General Assembly, requested by one of the member of the GA.
The TC is elected by the General Assembly for a duration of 1 year, and is composed of 5 members. Members can be re-elected if they wish. A majority vote in the General Assembly can trigger a new election of the TC.
The members of the TC can be elected from outside of the GA. Candidates for election can either be suggested or self-nominated.
The conflict resolution process is detailed in the resolution process document.
The TC can be contacted at <tc@@ffmpeg>.
@anchor{Resolution Process}
@section Resolution Process
The Technical Committee (TC) is here to arbitrate and make decisions when technical conflicts occur in the project.
The TC main role is to resolve technical conflicts. It is therefore not a technical steering committee, but it is understood that some decisions might impact the future of the project.
@subsection Seizing
The TC can take possession of any technical matter that it sees fit.
To involve the TC in a matter, email tc@ or CC them on an ongoing discussion.
As members of TC are developers, they also can email tc@ to raise an issue.
@subsection Announcement
The TC, once seized, must announce itself on the main mailing list, with a [TC] tag.
The TC has 2 modes of operation: a RFC one and an internal one.
If the TC thinks it needs the input from the larger community, the TC can call for a RFC. Else, it can decide by itself.
The decision to use a RFC process or an internal discussion is a discretionary decision of the TC.
The TC can also reject a seizure for a few reasons such as: the matter was not discussed enough previously; it lacks expertise to reach a beneficial decision on the matter; or the matter is too trivial.
@subsection RFC call
In the RFC mode, one person from the TC posts on the mailing list the technical question and will request input from the community.
The mail will have the following specification:
a precise title
a specific tag [TC RFC]
a top-level email
contain a precise question that does not exceed 100 words and that is answerable by developers
may have an extra description, or a link to a previous discussion, if deemed necessary,
contain a precise end date for the answers.
The answers from the community must be on the main mailing list and must have the following specification:
keep the tag and the title unchanged
limited to 400 words
a first-level, answering directly to the main email
answering to the question.
Further replies to answers are permitted, as long as they conform to the community standards of politeness, they are limited to 100 words, and are not nested more than once. (max-depth=2)
After the end-date, mails on the thread will be ignored.
Violations of those rules will be escalated through the Community Committee.
After all the emails are in, the TC has 96 hours to give its final decision. Exceptionally, the TC can request an extra delay, that will be notified on the mailing list.
@subsection Within TC
In the internal case, the TC has 96 hours to give its final decision. Exceptionally, the TC can request an extra delay.
@subsection Decisions
The decisions from the TC will be sent on the mailing list, with the [TC] tag.
Internally, the TC should take decisions with a majority, or using ranked-choice voting.
Each TC member must vote on such decision according to what is, in their view, best for the project.
If a TC member feels they are affected by a conflict of interest with regards to the case, they should announce it and recuse themselves from the TC
discussion and vote.
A conflict of interest is presumed to occur when a TC member has a personal interest (e.g. financial) in a specific outcome of the case.
The decision from the TC should be published with a summary of the reasons that lead to this decision.
The decisions from the TC are final, until the matters are reopened after no less than one year.
@anchor{Community Committee}
@chapter Community Committee
The Community Committee (CC) is here to arbitrage and make decisions when inter-personal conflicts occur in the project. It will decide quickly and take actions, for the sake of the project.
The CC can remove privileges of offending members, including removal of commit access and temporary ban from the community.
Decisions made by the CC can be re-opened after 1 year or by a majority vote of the General Assembly. Indefinite bans from the community must be confirmed by the General Assembly, in a majority vote.
The CC is elected by the General Assembly for a duration of 1 year, and is composed of 5 members. Members can be re-elected if they wish. A majority vote in the General Assembly can trigger a new election of the CC.
The members of the CC can be elected from outside of the GA. Candidates for election can either be suggested or self-nominated.
The CC is governed by and responsible for enforcing the Code of Conduct.
The CC can be contacted at <cc@@ffmpeg>.
@anchor{Code of Conduct}
@chapter 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."
@bye

View File

@@ -25,64 +25,6 @@ enabled decoders.
A description of some of the currently available video decoders
follows.
@section av1
AOMedia Video 1 (AV1) decoder.
@subsection Options
@table @option
@item operating_point
Select an operating point of a scalable AV1 bitstream (0 - 31). Default is 0.
@end table
@section hevc
HEVC (AKA ITU-T H.265 or ISO/IEC 23008-2) decoder.
The decoder supports MV-HEVC multiview streams with at most two views. Views to
be output are selected by supplying a list of view IDs to the decoder (the
@option{view_ids} option). This option may be set either statically before
decoder init, or from the @code{get_format()} callback - useful for the case
when the view count or IDs change dynamically during decoding.
Only the base layer is decoded by default.
Note that if you are using the @code{ffmpeg} CLI tool, you should be using view
specifiers as documented in its manual, rather than the options documented here.
@subsection Options
@table @option
@item view_ids (MV-HEVC)
Specify a list of view IDs that should be output. This option can also be set to
a single '-1', which will cause all views defined in the VPS to be decoded and
output.
@item view_ids_available (MV-HEVC)
This option may be read by the caller to retrieve an array of view IDs available
in the active VPS. The array is empty for single-layer video.
The value of this option is guaranteed to be accurate when read from the
@code{get_format()} callback. It may also be set at other times (e.g. after
opening the decoder), but the value is informational only and may be incorrect
(e.g. when the stream contains multiple distinct VPS NALUs).
@item view_pos_available (MV-HEVC)
This option may be read by the caller to retrieve an array of view positions
(left, right, or unspecified) available in the active VPS, as
@code{AVStereo3DView} values. When the array is available, its elements apply to
the corresponding elements of @option{view_ids_available}, i.e.
@code{view_pos_available[i]} contains the position of view with ID
@code{view_ids_available[i]}.
Same validity restrictions as for @option{view_ids_available} apply to
this option.
@end table
@section rawvideo
Raw video decoder.
@@ -105,157 +47,6 @@ top-field-first is assumed
@end table
@section libdav1d
dav1d AV1 decoder.
libdav1d allows libavcodec to decode the AOMedia Video 1 (AV1) codec.
Requires the presence of the libdav1d headers and library during configuration.
You need to explicitly configure the build with @code{--enable-libdav1d}.
@subsection Options
The following options are supported by the libdav1d wrapper.
@table @option
@item framethreads
Set amount of frame threads to use during decoding. The default value is 0 (autodetect).
This option is deprecated for libdav1d >= 1.0 and will be removed in the future. Use the
option @code{max_frame_delay} and the global option @code{threads} instead.
@item tilethreads
Set amount of tile threads to use during decoding. The default value is 0 (autodetect).
This option is deprecated for libdav1d >= 1.0 and will be removed in the future. Use the
global option @code{threads} instead.
@item max_frame_delay
Set max amount of frames the decoder may buffer internally. The default value is 0
(autodetect).
@item filmgrain
Apply film grain to the decoded video if present in the bitstream. Defaults to the
internal default of the library.
This option is deprecated and will be removed in the future. See the global option
@code{export_side_data} to export Film Grain parameters instead of applying it.
@item oppoint
Select an operating point of a scalable AV1 bitstream (0 - 31). Defaults to the
internal default of the library.
@item alllayers
Output all spatial layers of a scalable AV1 bitstream. The default value is false.
@end table
@section libdavs2
AVS2-P2/IEEE1857.4 video decoder wrapper.
This decoder allows libavcodec to decode AVS2 streams with davs2 library.
@c man end VIDEO DECODERS
@section libuavs3d
AVS3-P2/IEEE1857.10 video decoder.
libuavs3d allows libavcodec to decode AVS3 streams.
Requires the presence of the libuavs3d headers and library during configuration.
You need to explicitly configure the build with @code{--enable-libuavs3d}.
@subsection Options
The following option is supported by the libuavs3d wrapper.
@table @option
@item frame_threads
Set amount of frame threads to use during decoding. The default value is 0 (autodetect).
@end table
@section libxevd
eXtra-fast Essential Video Decoder (XEVD) MPEG-5 EVC decoder wrapper.
This decoder requires the presence of the libxevd headers and library
during configuration. You need to explicitly configure the build with
@option{--enable-libxevd}.
The xevd project website is at @url{https://github.com/mpeg5/xevd}.
@subsection Options
The following options are supported by the libxevd wrapper.
The xevd-equivalent options or values are listed in parentheses for easy migration.
To get a more accurate and extensive documentation of the libxevd options,
invoke the command @code{xevd_app --help} or consult the libxevd documentation.
@table @option
@item threads (@emph{threads})
Force to use a specific number of threads
@end table
@section QSV Decoders
The family of Intel QuickSync Video decoders (VC1, MPEG-2, H.264, HEVC,
JPEG/MJPEG, VP8, VP9, AV1, VVC).
@subsection Common Options
The following options are supported by all qsv decoders.
@table @option
@item @var{async_depth}
Internal parallelization depth, the higher the value the higher the latency.
@item @var{gpu_copy}
A GPU-accelerated copy between video and system memory
@table @samp
@item default
@item on
@item off
@end table
@end table
@subsection HEVC Options
Extra options for hevc_qsv.
@table @option
@item @var{load_plugin}
A user plugin to load in an internal session
@table @samp
@item none
@item hevc_sw
@item hevc_hw
@end table
@item @var{load_plugins}
A :-separate list of hexadecimal plugin UIDs to load in an internal session
@end table
@section v210
Uncompressed 4:2:2 10-bit decoder.
@subsection Options
@table @option
@item custom_stride
Set the line size of the v210 data in bytes. The default value is 0
(autodetect). You can use the special -1 value for a strideless v210 as seen in
BOXX files.
@end table
@c man end VIDEO DECODERS
@chapter Audio Decoders
@@ -277,7 +68,7 @@ the undocumented RealAudio 3 (a.k.a. dnet).
@item -drc_scale @var{value}
Dynamic Range Scale Factor. The factor to apply to dynamic range values
from the AC-3 stream. This factor is applied exponentially. The default value is 1.
from the AC-3 stream. This factor is applied exponentially.
There are 3 notable scale factor ranges:
@table @option
@item drc_scale == 0
@@ -292,26 +83,9 @@ Loud sounds are fully compressed. Soft sounds are enhanced.
@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
Internal wave synthesizer.
Internal wave synthetizer.
This decoder generates wave patterns according to predefined sequences. Its
use is purely internal and the format of the data it accepts is not publicly
@@ -397,215 +171,6 @@ without this library.
@chapter Subtitles Decoders
@c man begin SUBTILES DECODERS
@section libaribb24
ARIB STD-B24 caption decoder.
Implements profiles A and C of the ARIB STD-B24 standard.
@subsection libaribb24 Decoder Options
@table @option
@item -aribb24-base-path @var{path}
Sets the base path for the libaribb24 library. This is utilized for reading of
configuration files (for custom unicode conversions), and for dumping of
non-text symbols as images under that location.
Unset by default.
@item -aribb24-skip-ruby-text @var{boolean}
Tells the decoder wrapper to skip text blocks that contain half-height ruby
text.
Enabled by default.
@end table
@section libaribcaption
Yet another ARIB STD-B24 caption decoder using external @dfn{libaribcaption}
library.
Implements profiles A and C of the Japanse ARIB STD-B24 standard,
Brazilian ABNT NBR 15606-1, and Philippines version of ISDB-T.
Requires the presence of the libaribcaption headers and library
(@url{https://github.com/xqq/libaribcaption}) during configuration.
You need to explicitly configure the build with @code{--enable-libaribcaption}.
If both @dfn{libaribb24} and @dfn{libaribcaption} are enabled, @dfn{libaribcaption}
decoder precedes.
@subsection libaribcaption Decoder Options
@table @option
@item -sub_type @var{subtitle_type}
Specifies the format of the decoded subtitles.
@table @samp
@item bitmap
Graphical image.
@item ass
ASS formatted text.
@item text
Simple text based output without formatting.
@end table
The default is @dfn{ass} as same as @dfn{libaribb24} decoder.
Some present players (e.g., @dfn{mpv}) expect ASS format for ARIB caption.
@item -caption_encoding @var{encoding_scheme}
Specifies the encoding scheme of input subtitle text.
@table @samp
@item auto
Automatically detect text encoding (default).
@item jis
8bit-char JIS encoding defined in ARIB STD B24.
This encoding used in Japan for ISDB captions.
@item utf8
UTF-8 encoding defined in ARIB STD B24.
This encoding is used in Philippines for ISDB-T captions.
@item latin
Latin character encoding defined in ABNT NBR 15606-1.
This encoding is used in South America for SBTVD / ISDB-Tb captions.
@end table
@item -font @var{font_name[,font_name2,...]}
Specify comma-separated list of font family names to be used for @dfn{bitmap}
or @dfn{ass} type subtitle rendering.
Only first font name is used for @dfn{ass} type subtitle.
If not specified, use internaly defined default font family.
@item -ass_single_rect @var{boolean}
ARIB STD-B24 specifies that some captions may be displayed at different
positions at a time (multi-rectangle subtitle).
Since some players (e.g., old @dfn{mpv}) can't handle multiple ASS rectangles
in a single AVSubtitle, or multiple ASS rectangles of indeterminate duration
with the same start timestamp, this option can change the behavior so that
all the texts are displayed in a single ASS rectangle.
The default is @var{false}.
If your player cannot handle AVSubtitles with multiple ASS rectangles properly,
set this option to @var{true} or define @env{ASS_SINGLE_RECT=1} to change
default behavior at compilation.
@item -force_outline_text @var{boolean}
Specify whether always render outline text for all characters regardless of
the indication by charactor style.
The default is @var{false}.
@item -outline_width @var{number} (0.0 - 3.0)
Specify width for outline text, in dots (relative).
The default is @var{1.5}.
@item -ignore_background @var{boolean}
Specify whether to ignore background color rendering.
The default is @var{false}.
@item -ignore_ruby @var{boolean}
Specify whether to ignore rendering for ruby-like (furigana) characters.
The default is @var{false}.
@item -replace_drcs @var{boolean}
Specify whether to render replaced DRCS characters as Unicode characters.
The default is @var{true}.
@item -replace_msz_ascii @var{boolean}
Specify whether to replace MSZ (Middle Size; half width) fullwidth
alphanumerics with halfwidth alphanumerics.
The default is @var{true}.
@item -replace_msz_japanese @var{boolean}
Specify whether to replace some MSZ (Middle Size; half width) fullwidth
japanese special characters with halfwidth ones.
The default is @var{true}.
@item -replace_msz_glyph @var{boolean}
Specify whether to replace MSZ (Middle Size; half width) characters
with halfwidth glyphs if the fonts supports it.
This option works under FreeType or DirectWrite renderer
with Adobe-Japan1 compliant fonts.
e.g., IBM Plex Sans JP, Morisawa BIZ UDGothic, Morisawa BIZ UDMincho,
Yu Gothic, Yu Mincho, and Meiryo.
The default is @var{true}.
@item -canvas_size @var{image_size}
Specify the resolution of the canvas to render subtitles to; usually, this
should be frame size of input video.
This only applies when @code{-subtitle_type} is set to @var{bitmap}.
The libaribcaption decoder assumes input frame size for bitmap rendering as below:
@enumerate
@item
PROFILE_A : 1440 x 1080 with SAR (PAR) 4:3
@item
PROFILE_C : 320 x 180 with SAR (PAR) 1:1
@end enumerate
If actual frame size of input video does not match above assumption,
the rendered captions may be distorted.
To make the captions undistorted, add @code{-canvas_size} option to specify
actual input video size.
Note that the @code{-canvas_size} option is not required for video with
different size but same aspect ratio.
In such cases, the caption will be stretched or shrunk to actual video size
if @code{-canvas_size} option is not specified.
If @code{-canvas_size} option is specified with different size,
the caption will be stretched or shrunk as specified size with calculated SAR.
@end table
@subsection libaribcaption decoder usage examples
Display MPEG-TS file with ARIB subtitle by @code{ffplay} tool:
@example
ffplay -sub_type bitmap MPEG.TS
@end example
Display MPEG-TS file with input frame size 1920x1080 by @code{ffplay} tool:
@example
ffplay -sub_type bitmap -canvas_size 1920x1080 MPEG.TS
@end example
Embed ARIB subtitle in transcoded video:
@example
ffmpeg -sub_type bitmap -i src.m2t -filter_complex "[0:v][0:s]overlay" -vcodec h264 dest.mp4
@end example
@section dvbsub
@subsection Options
@table @option
@item compute_clut
@table @option
@item -2
Compute clut once if no matching CLUT is in the stream.
@item -1
Compute clut if no matching CLUT is in the stream.
@item 0
Never compute CLUT
@item 1
Always compute CLUT and override the one provided in the stream.
@end table
@item dvb_substream
Selects the dvb substream, or all substreams if -1 which is default.
@end table
@section dvdsub
This codec decodes the bitmap subtitles used in DVDs; the same subtitles can
@@ -622,7 +187,7 @@ palette is stored in the IFO file, and therefore not available when reading
from dumped VOB files.
The format for this option is a string containing 16 24-bits hexadecimal
numbers (without 0x prefix) separated by commas, for example @code{0d00ee,
numbers (without 0x prefix) separated by comas, for example @code{0d00ee,
ee450d, 101010, eaeaea, 0ce60b, ec14ed, ebff0b, 0d617a, 7b7b7b, d1d1d1,
7b2a0e, 0d950c, 0f007b, cf0dec, cfa80c, 7c127b}.
@@ -647,30 +212,18 @@ configuration. You need to explicitly configure the build with
@table @option
@item txt_page
List of teletext page numbers to decode. Pages that do not match the specified
list are dropped. You may use the special @code{*} string to match all pages,
or @code{subtitle} to match all subtitle pages.
List of teletext page numbers to decode. You may use the special * string to
match all pages. Pages that do not match the specified list are dropped.
Default value is *.
@item txt_default_region
Set default character set used for decoding, a value between 0 and 87 (see
ETS 300 706, Section 15, Table 32). Default value is -1, which does not
override the libzvbi default. This option is needed for some legacy level 1.0
transmissions which cannot signal the proper charset.
@item txt_chop_top
Discards the top teletext line. Default value is 1.
@item txt_format
Specifies the format of the decoded subtitles.
@table @option
@item bitmap
The default format, you should use this for teletext pages, because certain
graphics and colors cannot be expressed in simple text or even ASS.
@item text
Simple text based output without formatting.
@item ass
Formatted ASS output, subtitle pages and teletext pages are returned in
different styles, subtitle pages are stripped down to text, but an effort is
made to keep the text alignment and the formatting.
@end table
Specifies the format of the decoded subtitles. The teletext decoder is capable
of decoding the teletext pages to bitmaps or to simple text, you should use
"bitmap" for teletext pages, because certain graphics and colors cannot be
expressed in simple text. You might use "text" for teletext based subtitles if
your application can handle simple text based subtitles. Default value is
bitmap.
@item txt_left
X offset of generated bitmaps, default is 0.
@item txt_top
@@ -679,21 +232,14 @@ Y offset of generated bitmaps, default is 0.
Chops leading and trailing spaces and removes empty lines from the generated
text. This option is useful for teletext based subtitles where empty spaces may
be present at the start or at the end of the lines or empty lines may be
present between the subtitle lines because of double-sized teletext characters.
present between the subtitle lines because of double-sized teletext charactes.
Default value is 1.
@item txt_duration
Sets the display duration of the decoded teletext pages or subtitles in
milliseconds. Default value is -1 which means infinity or until the next
subtitle event comes.
miliseconds. Default value is 30000 which is 30 seconds.
@item txt_transparent
Force transparent background of the generated teletext bitmaps. Default value
is 0 which means an opaque 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.
is 0 which means an opaque (black) background.
@end table
@c man end SUBTILES DECODERS

View File

@@ -13,24 +13,21 @@ You can disable all the demuxers using the configure option
the option @code{--enable-demuxer=@var{DEMUXER}}, or disable it
with the option @code{--disable-demuxer=@var{DEMUXER}}.
The option @code{-demuxers} of the ff* tools will display the list of
enabled demuxers. Use @code{-formats} to view a combined list of
enabled demuxers and muxers.
The option @code{-formats} of the ff* tools will display the list of
enabled demuxers.
The description of some of the currently available demuxers follows.
@section aa
@section applehttp
Audible Format 2, 3, and 4 demuxer.
Apple HTTP Live Streaming demuxer.
This demuxer is used to demux Audible Format 2, 3, and 4 (.aa) files.
@section aac
Raw Audio Data Transport Stream AAC demuxer.
This demuxer is used to demux an ADTS input containing a single AAC stream
alongwith any ID3v1/2 or APE tags in it.
This demuxer presents all AVStreams from all variant streams.
The id field is set to the bitrate variant index number. By setting
the discard flags on AVStreams (by pressing 'a' or 'v' in ffplay),
the caller can decide which variant streams to actually receive.
The total bitrate of the variant that the stream belongs to is
available in a metadata key named "variant_bitrate".
@section apng
@@ -44,15 +41,12 @@ between the last fcTL and IEND chunks.
@table @option
@item -ignore_loop @var{bool}
Ignore the loop variable in the file if set. Default is enabled.
Ignore the loop variable in the file if set.
@item -max_fps @var{int}
Maximum framerate in frames per second. Default of 0 imposes no limit.
Maximum framerate in frames per second (0 for no limit).
@item -default_fps @var{int}
Default framerate in frames per second when none is specified in the file
(0 meaning as fast as possible). Default is 15.
(0 meaning as fast as possible).
@end table
@section asf
@@ -72,7 +66,7 @@ Do not try to resynchronize by looking for a certain optional start code.
Virtual concatenation script demuxer.
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.
The timestamps in the files are adjusted so that the first file starts at 0
@@ -103,10 +97,11 @@ backslash or single quotes.
All subsequent file-related directives apply to that file.
@item @code{ffconcat version 1.0}
Identify the script type and version.
Identify the script type and version. It also sets the @option{safe} option
to 1 if it was to its default -1.
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.
@item @code{duration @var{dur}}
@@ -117,57 +112,6 @@ file is not available or accurate.
If the duration is set for all files, then it is possible to seek in the
whole concatenated video.
@item @code{inpoint @var{timestamp}}
In point of the file. When the demuxer opens the file it instantly seeks to the
specified timestamp. Seeking is done so that all streams can be presented
successfully at In point.
This directive works best with intra frame codecs, because for non-intra frame
ones you will usually get extra packets before the actual In point and the
decoded content will most likely contain frames before In point too.
For each file, packets before the file In point will have timestamps less than
the calculated start timestamp of the file (negative in case of the first
file), and the duration of the files (if not specified by the @code{duration}
directive) will be reduced based on their specified In point.
Because of potential packets before the specified In point, packet timestamps
may overlap between two concatenated files.
@item @code{outpoint @var{timestamp}}
Out point of the file. When the demuxer reaches the specified decoding
timestamp in any of the streams, it handles it as an end of file condition and
skips the current and all the remaining packets from all streams.
Out point is exclusive, which means that the demuxer will not output packets
with a decoding timestamp greater or equal to Out point.
This directive works best with intra frame codecs and formats where all streams
are tightly interleaved. For non-intra frame codecs you will usually get
additional packets with presentation timestamp after Out point therefore the
decoded content will most likely contain frames after Out point too. If your
streams are not tightly interleaved you may not get all the packets from all
streams before Out point and you may only will be able to decode the earliest
stream until Out point.
The duration of the files (if not specified by the @code{duration}
directive) will be reduced based on their specified Out point.
@item @code{file_packet_metadata @var{key=value}}
Metadata of the packets of the file. The specified metadata will be set for
each file packet. You can specify this directive multiple times to add multiple
metadata entries.
This directive is deprecated, use @code{file_packet_meta} instead.
@item @code{file_packet_meta @var{key} @var{value}}
Metadata of the packets of the file. The specified metadata will be set for
each file packet. You can specify this directive multiple times to add multiple
metadata entries.
@item @code{option @var{key} @var{value}}
Option to access, open and probe the file.
Can be present multiple times.
@item @code{stream}
Introduce a stream in the virtual file.
All subsequent stream-related directives apply to the last introduced
@@ -184,20 +128,6 @@ subfiles will be used.
This is especially useful for MPEG-PS (VOB) files, where the order of the
streams is not reliable.
@item @code{stream_meta @var{key} @var{value}}
Metadata for the stream.
Can be present multiple times.
@item @code{stream_codec @var{value}}
Codec for the stream.
@item @code{stream_extradata @var{hex_string}}
Extradata for the string, encoded in hexadecimal.
@item @code{chapter @var{id} @var{start} @var{end}}
Add a chapter. @var{id} is an unique identifier, possibly small and
consecutive.
@end table
@subsection Options
@@ -207,8 +137,7 @@ This demuxer accepts the following option:
@table @option
@item safe
If set to 1, reject unsafe file paths and directives.
A file path is considered safe if it
If set to 1, reject unsafe file paths. A file path is considered safe if it
does not contain a protocol specification and is relative and all components
only contain characters from the portable character set (letters, digits,
period, underscore and hyphen) and have no period at the beginning of a
@@ -216,290 +145,55 @@ component.
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
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
@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 dash
Dynamic Adaptive Streaming over HTTP demuxer.
This demuxer presents all AVStreams found in the manifest.
By setting the discard flags on AVStreams the caller can decide
which streams to actually receive.
Each stream mirrors the @code{id} and @code{bandwidth} properties from the
@code{<Representation>} as metadata keys named "id" and "variant_bitrate" respectively.
@subsection Options
This demuxer accepts the following option:
@table @option
@item cenc_decryption_key
16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
@end table
@section dvdvideo
DVD-Video demuxer, powered by libdvdnav and libdvdread.
Can directly ingest DVD titles, specifically sequential PGCs, into
a conversion pipeline. Menu assets, such as background video or audio,
can also be demuxed given the menu's coordinates (at best effort).
Block devices (DVD drives), ISO files, and directory structures are accepted.
Activate with @code{-f dvdvideo} in front of one of these inputs.
This demuxer does NOT have decryption code of any kind. You are on your own
working with encrypted DVDs, and should not expect support on the matter.
Underlying playback is handled by libdvdnav, and structure parsing by libdvdread.
FFmpeg must be built with GPL library support available as well as the
configure switches @code{--enable-libdvdnav} and @code{--enable-libdvdread}.
You will need to provide either the desired "title number" or exact PGC/PG coordinates.
Many open-source DVD players and tools can aid in providing this information.
If not specified, the demuxer will default to title 1 which works for many discs.
However, due to the flexibility of the format, it is recommended to check manually.
There are many discs that are authored strangely or with invalid headers.
If the input is a real DVD drive, please note that there are some drives which may
silently fail on reading bad sectors from the disc, returning random bits instead
which is effectively corrupt data. This is especially prominent on aging or rotting discs.
A second pass and integrity checks would be needed to detect the corruption.
This is not an FFmpeg issue.
@subsection Background
DVD-Video is not a directly accessible, linear container format in the
traditional sense. Instead, it allows for complex and programmatic playback of
carefully muxed MPEG-PS streams that are stored in headerless VOB files.
To the end-user, these streams are known simply as "titles", but the actual
logical playback sequence is defined by one or more "PGCs", or Program Group Chains,
within the title. The PGC is in turn comprised of multiple "PGs", or Programs",
which are the actual video segments (and for a typical video feature, sequentially
ordered). The PGC structure, along with stream layout and metadata, are stored in
IFO files that need to be parsed. PGCs can be thought of as playlists in easier terms.
An actual DVD player relies on user GUI interaction via menus and an internal VM
to drive the direction of demuxing. Generally, the user would either navigate (via menus)
or automatically be redirected to the PGC of their choice. During this process and
the subsequent playback, the DVD player's internal VM also maintains a state and
executes instructions that can create jumps to different sectors during playback.
This is why libdvdnav is involved, as a linear read of the MPEG-PS blobs on the
disc (VOBs) is not enough to produce the right sequence in many cases.
There are many other DVD structures (a long subject) that will not be discussed here.
NAV packets, in particular, are handled by this demuxer to build accurate timing
but not emitted as a stream. For a good high-level understanding, refer to:
@url{https://code.videolan.org/videolan/libdvdnav/-/blob/master/doc/dvd_structures}
@subsection Options
This demuxer accepts the following options:
@table @option
@item title @var{int}
The title number to play. Must be set if @option{pgc} and @option{pg} are not set.
Not applicable to menus.
Default is 0 (auto), which currently only selects the first available title (title 1)
and notifies the user about the implications.
@item chapter_start @var{int}
The chapter, or PTT (part-of-title), number to start at. Not applicable to menus.
Default is 1.
@item chapter_end @var{int}
The chapter, or PTT (part-of-title), number to end at. Not applicable to menus.
Default is 0, which is a special value to signal end at the last possible chapter.
@item angle @var{int}
The video angle number, referring to what is essentially an additional
video stream that is composed from alternate frames interleaved in the VOBs.
Not applicable to menus.
Default is 1.
@item region @var{int}
The region code to use for playback. Some discs may use this to default playback
at a particular angle in different regions. This option will not affect the region code
of a real DVD drive, if used as an input. Not applicable to menus.
Default is 0, "world".
@item menu @var{bool}
Demux menu assets instead of navigating a title. Requires exact coordinates
of the menu (@option{menu_lu}, @option{menu_vts}, @option{pgc}, @option{pg}).
Default is false.
@item menu_lu @var{int}
The menu language to demux. In DVD, menus are grouped by language.
Default is 1, the first language unit.
@item menu_vts @var{int}
The VTS where the menu lives, or 0 if it is a VMG menu (root-level).
Default is 1, menu of the first VTS.
@item pgc @var{int}
The entry PGC to start playback, in conjunction with @option{pg}.
Alternative to setting @option{title}.
Chapter markers are not supported at this time.
Must be explicitly set for menus.
Default is 0, automatically resolve from value of @option{title}.
@item pg @var{int}
The entry PG to start playback, in conjunction with @option{pgc}.
Alternative to setting @option{title}.
Chapter markers are not supported at this time.
Default is 1, the first PG of the PGC.
@item preindex @var{bool}
Enable this to have accurate chapter (PTT) markers and duration measurement,
which requires a slow second pass read in order to index the chapter marker
timestamps from NAV packets. This is non-ideal extra work for real optical drives.
It is recommended and faster to use this option with a backup of the DVD structure
stored on a hard drive. Not compatible with @option{pgc} and @option{pg}.
Default is 0, false.
@item trim @var{bool}
Skip padding cells (i.e. cells shorter than 1 second) from the beginning.
There exist many discs with filler segments at the beginning of the PGC,
often with junk data intended for controlling a real DVD player's
buffering speed and with no other material data value.
Not applicable to menus.
Default is 1, true.
@end table
@subsection Examples
@itemize
@item
Open title 3 from a given DVD structure:
@example
ffmpeg -f dvdvideo -title 3 -i <path to DVD> ...
@end example
@item
Open chapters 3-6 from title 1 from a given DVD structure:
@example
ffmpeg -f dvdvideo -chapter_start 3 -chapter_end 6 -title 1 -i <path to DVD> ...
@end example
@item
Open only chapter 5 from title 1 from a given DVD structure:
@example
ffmpeg -f dvdvideo -chapter_start 5 -chapter_end 5 -title 1 -i <path to DVD> ...
@end example
@item
Demux menu with language 1 from VTS 1, PGC 1, starting at PG 1:
@example
ffmpeg -f dvdvideo -menu 1 -menu_lu 1 -menu_vts 1 -pgc 1 -pg 1 -i <path to DVD> ...
@end example
@end itemize
@section ea
Electronic Arts Multimedia format demuxer.
This format is used by various Electronic Arts games.
@subsection Options
@table @option
@item merge_alpha @var{bool}
Normally the VP6 alpha channel (if exists) is returned as a secondary video
stream, by setting this option you can make the demuxer return a single video
stream which contains the alpha channel in addition to the ordinary video.
@end table
@section imf
Interoperable Master Format demuxer.
This demuxer presents audio and video streams found in an IMF Composition, as
specified in @url{https://doi.org/10.5594/SMPTE.ST2067-2.2020, SMPTE ST 2067-2}.
@example
ffmpeg [-assetmaps <path of ASSETMAP1>,<path of ASSETMAP2>,...] -i <path of CPL> ...
@end example
If @code{-assetmaps} is not specified, the demuxer looks for a file called
@file{ASSETMAP.xml} in the same directory as the CPL.
@section flv, live_flv, kux
@section flv
Adobe Flash Video Format demuxer.
This demuxer is used to demux FLV files and RTMP network streams. In case of live network streams, if you force format, you may use live_flv option instead of flv to survive timestamp discontinuities.
KUX is a flv variant used on the Youku platform.
@example
ffmpeg -f flv -i myfile.flv ...
ffmpeg -f live_flv -i rtmp://<any.server>/anything/key ....
@end example
This demuxer is used to demux FLV files and RTMP network streams.
@table @option
@item -flv_metadata @var{bool}
Allocate the streams according to the onMetaData array content.
@item -flv_ignore_prevtag @var{bool}
Ignore the size of previous tag value.
@item -flv_full_metadata @var{bool}
Output all context of the onMetadata.
@end table
@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 libquvi
Play media from Internet services using the quvi project.
The demuxer accepts a @option{format} option to request a specific quality. It
is by default set to @var{best}.
See @url{http://quvi.sourceforge.net/} for more information.
FFmpeg needs to be built with @code{--enable-libquvi} for this demuxer to be
enabled.
@section gif
Animated GIF demuxer.
@@ -511,11 +205,6 @@ It accepts the following options:
Set the minimum valid delay between frames in hundredths of seconds.
Range is 0 to 6000. Default value is 2.
@item max_gif_delay
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
Set the default delay between frames in hundredths of seconds.
Range is 0 to 6000. Default value is 10.
@@ -539,66 +228,6 @@ used to end the output video at the length of the shortest input file,
which in this case is @file{input.mp4} as the GIF in this example loops
infinitely.
@section hls
HLS demuxer
Apple HTTP Live Streaming demuxer.
This demuxer presents all AVStreams from all variant streams.
The id field is set to the bitrate variant index number. By setting
the discard flags on AVStreams (by pressing 'a' or 'v' in ffplay),
the caller can decide which variant streams to actually receive.
The total bitrate of the variant that the stream belongs to is
available in a metadata key named "variant_bitrate".
It accepts the following options:
@table @option
@item live_start_index
segment index to start live streams at (negative values are from the end).
@item prefer_x_start
prefer to use #EXT-X-START if it's in playlist instead of live_start_index.
@item allowed_extensions
',' separated list of file extensions that hls is allowed to access.
@item extension_picky
This blocks disallowed extensions from probing
It also requires all available segments to have matching extensions to the format
except mpegts, which is always allowed.
It is recommended to set the whitelists correctly instead of depending on extensions
Enabled by default.
@item max_reload
Maximum number of times a insufficient list is attempted to be reloaded.
Default value is 1000.
@item m3u8_hold_counters
The maximum number of times to load m3u8 when it refreshes without new segments.
Default value is 1000.
@item http_persistent
Use persistent HTTP connections. Applicable only for HTTP streams.
Enabled by default.
@item http_multiple
Use multiple HTTP connections for downloading HTTP segments.
Enabled by default for HTTP/1.1 servers.
@item http_seekable
Use HTTP partial requests for downloading HTTP segments.
0 = disable, 1 = enable, -1 = auto, Default is auto.
@item seg_format_options
Set options for the demuxer of media segments using a list of key=value pairs separated by @code{:}.
@item seg_max_retry
Maximum number of times to reload a segment on error, useful when segment skip on network error is not desired.
Default value is 0.
@end table
@section image2
Image file demuxer.
@@ -624,10 +253,6 @@ Select the pattern type used to interpret the provided filename.
@var{pattern_type} accepts one of the following values.
@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
Select a sequence pattern type, used to specify a sequence of files
indexed by sequential numbers.
@@ -707,17 +332,6 @@ nanosecond precision.
@item video_size
Set the video size of the images to read. If not specified the video
size is guessed from the first image file in the sequence.
@item export_path_metadata
If set to 1, will add two extra fields to the metadata found in input, making them
also available for other filters (see @var{drawtext} filter for examples). Default
value is 0. The extra fields are described below:
@table @option
@item lavf.image2dec.source_path
Corresponds to the full path to the input file being read.
@item lavf.image2dec.source_basename
Corresponds to the name of the file being read.
@end table
@end table
@subsection Examples
@@ -745,272 +359,17 @@ ffmpeg -framerate 10 -pattern_type glob -i "*.png" out.mkv
@end example
@end itemize
@section libgme
The Game Music Emu library is a collection of video game music file emulators.
See @url{https://bitbucket.org/mpyne/game-music-emu/overview} for more information.
It accepts the following options:
@table @option
@item track_index
Set the index of which track to demux. The demuxer can only export one track.
Track indexes start at 0. Default is to pick the first track. Number of tracks
is exported as @var{tracks} metadata entry.
@item sample_rate
Set the sampling rate of the exported track. Range is 1000 to 999999. Default is 44100.
@item max_size @emph{(bytes)}
The demuxer buffers the entire file into memory. Adjust this value to set the maximum buffer size,
which in turn, acts as a ceiling for the size of files that can be read.
Default is 50 MiB.
@end table
@section libmodplug
ModPlug based module demuxer
See @url{https://github.com/Konstanty/libmodplug}
It will export one 2-channel 16-bit 44.1 kHz audio stream.
Optionally, a @code{pal8} 16-color video stream can be exported with or without printed metadata.
It accepts the following options:
@table @option
@item noise_reduction
Apply a simple low-pass filter. Can be 1 (on) or 0 (off). Default is 0.
@item reverb_depth
Set amount of reverb. Range 0-100. Default is 0.
@item reverb_delay
Set delay in ms, clamped to 40-250 ms. Default is 0.
@item bass_amount
Apply bass expansion a.k.a. XBass or megabass. Range is 0 (quiet) to 100 (loud). Default is 0.
@item bass_range
Set cutoff i.e. upper-bound for bass frequencies. Range is 10-100 Hz. Default is 0.
@item surround_depth
Apply a Dolby Pro-Logic surround effect. Range is 0 (quiet) to 100 (heavy). Default is 0.
@item surround_delay
Set surround delay in ms, clamped to 5-40 ms. Default is 0.
@item max_size
The demuxer buffers the entire file into memory. Adjust this value to set the maximum buffer size,
which in turn, acts as a ceiling for the size of files that can be read. Range is 0 to 100 MiB.
0 removes buffer size limit (not recommended). Default is 5 MiB.
@item video_stream_expr
String which is evaluated using the eval API to assign colors to the generated video stream.
Variables which can be used are @code{x}, @code{y}, @code{w}, @code{h}, @code{t}, @code{speed},
@code{tempo}, @code{order}, @code{pattern} and @code{row}.
@item video_stream
Generate video stream. Can be 1 (on) or 0 (off). Default is 0.
@item video_stream_w
Set video frame width in 'chars' where one char indicates 8 pixels. Range is 20-512. Default is 30.
@item video_stream_h
Set video frame height in 'chars' where one char indicates 8 pixels. Range is 20-512. Default is 30.
@item video_stream_ptxt
Print metadata on video stream. Includes @code{speed}, @code{tempo}, @code{order}, @code{pattern},
@code{row} and @code{ts} (time in ms). Can be 1 (on) or 0 (off). Default is 1.
@end table
@section libopenmpt
libopenmpt based module demuxer
See @url{https://lib.openmpt.org/libopenmpt/} for more information.
Some files have multiple subsongs (tracks) this can be set with the @option{subsong}
option.
It accepts the following options:
@table @option
@item subsong
Set the subsong index. This can be either 'all', 'auto', or the index of the
subsong. Subsong indexes start at 0. The default is 'auto'.
The default value is to let libopenmpt choose.
@item layout
Set the channel layout. Valid values are 1, 2, and 4 channel layouts.
The default value is STEREO.
@item sample_rate
Set the sample rate for libopenmpt to output.
Range is from 1000 to INT_MAX. The value default is 48000.
@end table
@section mov/mp4/3gp
Demuxer for Quicktime File Format & ISO/IEC Base Media File Format (ISO/IEC 14496-12 or MPEG-4 Part 12, ISO/IEC 15444-12 or JPEG 2000 Part 12).
Registered extensions: mov, mp4, m4a, 3gp, 3g2, mj2, psp, m4b, ism, ismv, isma, f4v
@subsection Options
This demuxer accepts the following options:
@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.
@item seek_streams_individually
When seeking, identify the closest point in each stream individually and demux packets in
that stream from identified point. This can lead to a different sequence of packets compared
to demuxing linearly from the beginning. Default is true.
@item ignore_editlist
Ignore any edit list atoms. The demuxer, by default, modifies the stream index to reflect the
timeline described by the edit list. Default is false.
@item advanced_editlist
Modify the stream index to reflect the timeline described by the edit list. @code{ignore_editlist}
must be set to false for this option to be effective.
If both @code{ignore_editlist} and this option are set to false, then only the
start of the stream index is modified to reflect initial dwell time or starting timestamp
described by the edit list. Default is true.
@item ignore_chapters
Don't parse chapters. This includes GoPro 'HiLight' tags/moments. Note that chapters are
only parsed when input is seekable. Default is false.
@item use_mfra_for
For seekable fragmented input, set fragment's starting timestamp from media fragment random access box, if present.
Following options are available:
@table @samp
@item auto
Auto-detect whether to set mfra timestamps as PTS or DTS @emph{(default)}
@item dts
Set mfra timestamps as DTS
@item pts
Set mfra timestamps as PTS
@item 0
Don't use mfra box to set timestamps
@end table
@item use_tfdt
For fragmented input, set fragment's starting timestamp to @code{baseMediaDecodeTime} from the @code{tfdt} box.
Default is enabled, which will prefer to use the @code{tfdt} box to set DTS. Disable to use the @code{earliest_presentation_time} from the @code{sidx} box.
In either case, the timestamp from the @code{mfra} box will be used if it's available and @code{use_mfra_for} is
set to pts or dts.
@item export_all
Export unrecognized boxes within the @var{udta} box as metadata entries. The first four
characters of the box type are set as the key. Default is false.
@item export_xmp
Export entire contents of @var{XMP_} box and @var{uuid} box as a string with key @code{xmp}. Note that
if @code{export_all} is set and this option isn't, the contents of @var{XMP_} box are still exported
but with key @code{XMP_}. Default is false.
@item activation_bytes
4-byte key required to decrypt Audible AAX and AAX+ files. See Audible AAX subsection below.
@item audible_fixed_key
Fixed key used for handling Audible AAX/AAX+ files. It has been pre-set so should not be necessary to
specify.
@item decryption_key
16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
@item max_stts_delta
Very high sample deltas written in a trak's stts box may occasionally be intended but usually they are written in
error or used to store a negative value for dts correction when treated as signed 32-bit integers. This option lets
the user set an upper limit, beyond which the delta is clamped to 1. Values greater than the limit if negative when
cast to int32 are used to adjust onward dts.
Unit is the track time scale. Range is 0 to UINT_MAX. Default is @code{UINT_MAX - 48000*10} which allows up to
a 10 second dts correction for 48 kHz audio streams while accommodating 99.9% of @code{uint32} range.
@item interleaved_read
Interleave packets from multiple tracks at demuxer level. For badly interleaved files, this prevents playback issues
caused by large gaps between packets in different tracks, as MOV/MP4 do not have packet placement requirements.
However, this can cause excessive seeking on very badly interleaved files, due to seeking between tracks, so disabling
it may prevent I/O issues, at the expense of playback.
@end table
@subsection Audible AAX
Audible AAX files are encrypted M4B files, and they can be decrypted by specifying a 4 byte activation secret.
@example
ffmpeg -activation_bytes 1CEB00DA -i test.aax -vn -c:a copy output.mp4
@end example
@section mpegts
MPEG-2 transport stream demuxer.
This demuxer accepts the following options:
@table @option
@item resync_size
Set size limit for looking up a new synchronization. Default value is
65536.
@item skip_unknown_pmt
Skip PMTs for programs not defined in the PAT. Default value is 0.
@item fix_teletext_pts
Override teletext packet PTS and DTS values with the timestamps calculated
Overrides teletext packet PTS and DTS values with the timestamps calculated
from the PCR of the first program which the teletext stream is part of and is
not discarded. Default value is 1, set this option to 0 if you want your
teletext packet PTS and DTS values untouched.
@item ts_packetsize
Output option carrying the raw packet size in bytes.
Show the detected raw packet size, cannot be set by the user.
@item scan_all_pmts
Scan and combine all PMTs. The value is an integer with value from -1
to 1 (-1 means automatic setting, 1 means enabled, 0 means
disabled). Default value is -1.
@item merge_pmt_versions
Re-use existing streams when a PMT's version is updated and elementary
streams move to different PIDs. Default value is 0.
@item max_packet_size
Set maximum size, in bytes, of packet emitted by the demuxer. Payloads above this size
are split across multiple packets. Range is 1 to INT_MAX/2. Default is 204800 bytes.
@end table
@section mpjpeg
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
@section rawvideo
@@ -1042,36 +401,6 @@ the command:
ffplay -f rawvideo -pixel_format rgb24 -video_size 320x240 -framerate 10 input.raw
@end example
@anchor{rcwtdec}
@section rcwt
RCWT (Raw Captions With Time) is a format native to ccextractor, a commonly
used open source tool for processing 608/708 Closed Captions (CC) sources.
For more information on the format, see @ref{rcwtenc,,,ffmpeg-formats}.
This demuxer implements the specification as of March 2024, which has
been stable and unchanged since April 2014.
@subsection Examples
@itemize
@item
Render CC to ASS using the built-in decoder:
@example
ffmpeg -i CC.rcwt.bin CC.ass
@end example
Note that if your output appears to be empty, you may have to manually
set the decoder's @option{data_field} option to pick the desired CC substream.
@item
Convert an RCWT backup to Scenarist (SCC) format:
@example
ffmpeg -i CC.rcwt.bin -c:s copy CC.scc
@end example
Note that the SCC format does not support all of the possible CC extensions
that can be stored in RCWT (such as EIA-708).
@end itemize
@section sbg
SBaGen script demuxer.
@@ -1123,43 +452,4 @@ Example: convert the captions to a format most players understand:
ffmpeg -i http://www.ted.com/talks/subtitles/id/1/lang/en talk1-en.srt
@end example
@section vapoursynth
Vapoursynth wrapper.
Due to security concerns, Vapoursynth scripts will not
be autodetected so the input format has to be forced. For ff* CLI tools,
add @code{-f vapoursynth} before the input @code{-i yourscript.vpy}.
This demuxer accepts the following option:
@table @option
@item max_script_size
The demuxer buffers the entire script into memory. Adjust this value to set the maximum buffer size,
which in turn, acts as a ceiling for the size of scripts that can be read.
Default is 1 MiB.
@end table
@section w64
Sony Wave64 Audio demuxer.
This demuxer accepts the following options:
@table @option
@item max_size
See the same option for the @ref{wav} demuxer.
@end table
@anchor{wav}
@section wav
RIFF Wave Audio demuxer.
This demuxer accepts the following options:
@table @option
@item max_size
Specify the maximum packet size in bytes for the demuxed packets. By default
this is set to 0, which means that a sensible value is chosen based on the
input format.
@end table
@c man end DEMUXERS

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +1,21 @@
#!/bin/sh
OUT_DIR="${1}"
SRC_DIR="${2}"
DOXYFILE="${3}"
DOXYGEN="${4}"
SRC_PATH="${1}"
DOXYFILE="${2}"
DOXYGEN="${3}"
shift 4
shift 3
cd ${SRC_DIR}
if [ -e "VERSION" ]; then
VERSION=`cat "VERSION"`
if [ -e "$SRC_PATH/VERSION" ]; then
VERSION=`cat "$SRC_PATH/VERSION"`
else
VERSION=`git describe`
VERSION=`cd "$SRC_PATH"; git describe`
fi
$DOXYGEN - <<EOF
@INCLUDE = ${DOXYFILE}
INPUT = $@
EXAMPLE_PATH = ${SRC_PATH}/doc/examples
HTML_TIMESTAMP = NO
PROJECT_NUMBER = $VERSION
OUTPUT_DIRECTORY = $OUT_DIR
EOF

1
doc/doxy/.gitignore vendored
View File

@@ -1 +0,0 @@
/html/

File diff suppressed because it is too large Load Diff

View File

@@ -76,7 +76,7 @@ EMFILE POSIX ++++++ Too many open files
EMLINK POSIX ++++++ Too many links
EMSGSIZE POSIX +++..+ Message too long
EMULTIHOP POSIX ++4... Multihop attempted
ENAMETOOLONG POSIX - ++++++ File name too long
ENAMETOOLONG POSIX - ++++++ Filen ame too long
ENAVAIL +..... No XENIX semaphores available
ENEEDAUTH .++... Need authenticator
ENETDOWN POSIX +++..+ Network is down

View File

@@ -1,25 +0,0 @@
/avio_list_dir
/avio_reading
/decode_audio
/decode_video
/demuxing_decoding
/encode_audio
/encode_video
/extract_mvs
/filter_audio
/filtering_audio
/filtering_video
/http_multiclient
/hw_decode
/metadata
/muxing
/pc-uninstalled
/qsvdec
/remuxing
/resampling_audio
/scaling_video
/transcode_aac
/transcoding
/vaapi_encode
/vaapi_transcode
/qsv_transcode

View File

@@ -1,65 +1,44 @@
EXAMPLES-$(CONFIG_AVIO_HTTP_SERVE_FILES) += avio_http_serve_files
EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir
EXAMPLES-$(CONFIG_AVIO_READ_CALLBACK_EXAMPLE) += avio_read_callback
EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio
EXAMPLES-$(CONFIG_DECODE_FILTER_AUDIO_EXAMPLE) += decode_filter_audio
EXAMPLES-$(CONFIG_DECODE_FILTER_VIDEO_EXAMPLE) += decode_filter_video
EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video
EXAMPLES-$(CONFIG_DEMUX_DECODE_EXAMPLE) += demux_decode
EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio
EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video
EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE) += extract_mvs
EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio
EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode
EXAMPLES-$(CONFIG_MUX_EXAMPLE) += mux
EXAMPLES-$(CONFIG_QSV_DECODE_EXAMPLE) += qsv_decode
EXAMPLES-$(CONFIG_REMUX_EXAMPLE) += remux
EXAMPLES-$(CONFIG_RESAMPLE_AUDIO_EXAMPLE) += resample_audio
EXAMPLES-$(CONFIG_SCALE_VIDEO_EXAMPLE) += scale_video
EXAMPLES-$(CONFIG_SHOW_METADATA_EXAMPLE) += show_metadata
EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
EXAMPLES-$(CONFIG_TRANSCODE_EXAMPLE) += transcode
EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE) += vaapi_encode
EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE) += vaapi_transcode
EXAMPLES-$(CONFIG_QSV_TRANSCODE_EXAMPLE) += qsv_transcode
# use pkg-config for getting CFLAGS and LDLIBS
FFMPEG_LIBS= libavdevice \
libavformat \
libavfilter \
libavcodec \
libswresample \
libswscale \
libavutil \
EXAMPLES := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
EXAMPLES_G := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
ALL_EXAMPLES := $(EXAMPLES) $(EXAMPLES-:%=doc/examples/%$(PROGSSUF)$(EXESUF))
ALL_EXAMPLES_G := $(EXAMPLES_G) $(EXAMPLES-:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
PROGS += $(EXAMPLES)
CFLAGS += -Wall -g
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
EXAMPLE_MAKEFILE := $(SRC_PATH)/doc/examples/Makefile
EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/README $(EXAMPLE_MAKEFILE)
EXAMPLES= avio_reading \
decoding_encoding \
demuxing_decoding \
extract_mvs \
filtering_video \
filtering_audio \
metadata \
muxing \
remuxing \
resampling_audio \
scaling_video \
transcode_aac \
transcoding \
$(foreach P,$(EXAMPLES),$(eval OBJS-$(P:%$(PROGSSUF)$(EXESUF)=%) = $(P:%$(PROGSSUF)$(EXESUF)=%).o))
$(EXAMPLES_G): %$(PROGSSUF)_g$(EXESUF): %.o
OBJS=$(addsuffix .o,$(EXAMPLES))
examples: $(EXAMPLES)
# the following examples make explicit use of the math library
avcodec: LDLIBS += -lm
decoding_encoding: LDLIBS += -lm
muxing: LDLIBS += -lm
resampling_audio: LDLIBS += -lm
$(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.o): | doc/examples
OUTDIRS += doc/examples
.phony: all clean-test clean
DOXY_INPUT += $(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.c)
all: $(OBJS) $(EXAMPLES)
install: install-examples
clean-test:
$(RM) test*.pgm test.h264 test.mp2 test.sw test.mpg
install-examples: $(EXAMPLES_FILES)
$(Q)mkdir -p "$(DATADIR)/examples"
$(INSTALL) -m 644 $(EXAMPLES_FILES) "$(DATADIR)/examples"
$(INSTALL) -m 644 $(EXAMPLE_MAKEFILE:%=%.example) "$(DATADIR)/examples/Makefile"
uninstall: uninstall-examples
uninstall-examples:
$(RM) -r "$(DATADIR)/examples"
examplesclean:
$(RM) $(ALL_EXAMPLES) $(ALL_EXAMPLES_G)
$(RM) $(CLEANSUFFIXES:%=doc/examples/%)
docclean:: examplesclean
-include $(wildcard $(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.d))
.PHONY: examples
clean: clean-test
$(RM) $(EXAMPLES) $(OBJS)

View File

@@ -1,57 +0,0 @@
# use pkg-config for getting CFLAGS and LDLIBS
FFMPEG_LIBS= libavdevice \
libavformat \
libavfilter \
libavcodec \
libswresample \
libswscale \
libavutil \
CFLAGS += -Wall -g
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
# missing the following targets, since they need special options in the FFmpeg build:
# qsv_decode
# qsv_transcode
# vaapi_encode
# vaapi_transcode
EXAMPLES=\
avio_http_serve_files \
avio_list_dir \
avio_read_callback \
decode_audio \
decode_filter_audio \
decode_filter_video \
decode_video \
demux_decode \
encode_audio \
encode_video \
extract_mvs \
hw_decode \
mux \
remux \
resample_audio \
scale_video \
show_metadata \
transcode_aac \
transcode
OBJS=$(addsuffix .o,$(EXAMPLES))
# the following examples make explicit use of the math library
avcodec: LDLIBS += -lm
encode_audio: LDLIBS += -lm
mux: LDLIBS += -lm
resample_audio: LDLIBS += -lm
.phony: all clean-test clean
all: $(OBJS) $(EXAMPLES)
clean-test:
$(RM) test*.pgm test.h264 test.mp2 test.sw test.mpg
clean: clean-test
$(RM) $(EXAMPLES) $(OBJS)

View File

@@ -7,10 +7,8 @@ that you have them installed and working on your system.
Method 1: build the installed examples in a generic read/write user directory
Copy to a read/write user directory and run:
make -f Makefile.example
It will link to the libraries on your system, assuming the PKG_CONFIG_PATH is
Copy to a read/write user directory and just use "make", it will link
to the libraries on your system, assuming the PKG_CONFIG_PATH is
correctly configured.
Method 2: build the examples in-tree
@@ -22,4 +20,4 @@ examples using "make examplesclean"
If you want to try the dedicated Makefile examples (to emulate the first
method), go into doc/examples and run a command such as
PKG_CONFIG_PATH=pc-uninstalled make -f Makefile.example
PKG_CONFIG_PATH=pc-uninstalled make.

View File

@@ -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 avio_http_serve_files.c
*
* Serve a file without decoding or demuxing it over the HTTP protocol. 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;
av_freep(&resource);
}
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);
av_freep(&resource);
}
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];
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;
}

View File

@@ -1,137 +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.
*/
/**
* @file libavformat AVIOContext list directory API usage example
* @example avio_list_dir.c
*
* Show how to list directories through the libavformat AVIOContext API.
*/
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
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 void usage(const char *program_name)
{
fprintf(stderr, "usage: %s input_dir\n"
"API example program to show how to list files in directory "
"accessed through AVIOContext.\n", program_name);
}
int main(int argc, char *argv[])
{
int ret;
av_log_set_level(AV_LOG_DEBUG);
if (argc < 2) {
usage(argv[0]);
return 1;
}
avformat_network_init();
ret = list_op(argv[1]);
avformat_network_deinit();
return ret < 0 ? 1 : 0;
}

View File

@@ -1,135 +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 read callback API usage example
* @example avio_read_callback.c
*
* Make libavformat demuxer access media content through a custom
* AVIOContext read callback.
*/
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
#include <libavutil/file.h>
#include <libavutil/mem.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);
if (!buf_size)
return AVERROR_EOF;
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];
/* 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) {
av_freep(&avio_ctx_buffer);
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);
avio_context_free(&avio_ctx);
av_file_unmap(buffer, buffer_size);
if (ret < 0) {
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
return 1;
}
return 0;
}

134
doc/examples/avio_reading.c Normal file
View File

@@ -0,0 +1,134 @@
/*
* 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;
}

View File

@@ -1,241 +0,0 @@
/*
* Copyright (c) 2001 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @file libavcodec audio decoding API usage example
* @example decode_audio.c
*
* Decode data from an MP2 input file and generate a raw audio file to
* be played with ffplay.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libavutil/frame.h>
#include <libavutil/mem.h>
#include <libavcodec/avcodec.h>
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
static int get_format_from_sample_fmt(const char **fmt,
enum AVSampleFormat sample_fmt)
{
int i;
struct sample_fmt_entry {
enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
} sample_fmt_entries[] = {
{ AV_SAMPLE_FMT_U8, "u8", "u8" },
{ AV_SAMPLE_FMT_S16, "s16be", "s16le" },
{ AV_SAMPLE_FMT_S32, "s32be", "s32le" },
{ AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
{ AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
};
*fmt = NULL;
for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
struct sample_fmt_entry *entry = &sample_fmt_entries[i];
if (sample_fmt == entry->sample_fmt) {
*fmt = AV_NE(entry->fmt_be, entry->fmt_le);
return 0;
}
}
fprintf(stderr,
"sample format %s is not supported as output format\n",
av_get_sample_fmt_name(sample_fmt));
return -1;
}
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame,
FILE *outfile)
{
int i, ch;
int ret, data_size;
/* send the packet with the compressed data to the decoder */
ret = avcodec_send_packet(dec_ctx, pkt);
if (ret < 0) {
fprintf(stderr, "Error submitting the packet to the decoder\n");
exit(1);
}
/* read all the output frames (in general there may be any number of them */
while (ret >= 0) {
ret = avcodec_receive_frame(dec_ctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return;
else if (ret < 0) {
fprintf(stderr, "Error during decoding\n");
exit(1);
}
data_size = av_get_bytes_per_sample(dec_ctx->sample_fmt);
if (data_size < 0) {
/* This should not occur, checking just for paranoia */
fprintf(stderr, "Failed to calculate data size\n");
exit(1);
}
for (i = 0; i < frame->nb_samples; i++)
for (ch = 0; ch < dec_ctx->ch_layout.nb_channels; ch++)
fwrite(frame->data[ch] + data_size*i, 1, data_size, outfile);
}
}
int main(int argc, char **argv)
{
const char *outfilename, *filename;
const AVCodec *codec;
AVCodecContext *c= NULL;
AVCodecParserContext *parser = NULL;
int len, ret;
FILE *f, *outfile;
uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
uint8_t *data;
size_t data_size;
AVPacket *pkt;
AVFrame *decoded_frame = NULL;
enum AVSampleFormat sfmt;
int n_channels = 0;
const char *fmt;
if (argc <= 2) {
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
exit(0);
}
filename = argv[1];
outfilename = argv[2];
pkt = av_packet_alloc();
if (!pkt) {
fprintf(stderr, "Could not allocate AVPacket\n");
exit(1); /* or proper cleanup and returning */
}
/* find the MPEG audio decoder */
codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
if (!codec) {
fprintf(stderr, "Codec not found\n");
exit(1);
}
parser = av_parser_init(codec->id);
if (!parser) {
fprintf(stderr, "Parser not found\n");
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate audio codec context\n");
exit(1);
}
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
exit(1);
}
f = fopen(filename, "rb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename);
exit(1);
}
outfile = fopen(outfilename, "wb");
if (!outfile) {
fprintf(stderr, "Could not open %s\n", outfilename);
exit(1);
}
/* decode until eof */
data = inbuf;
data_size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
while (data_size > 0) {
if (!decoded_frame) {
if (!(decoded_frame = av_frame_alloc())) {
fprintf(stderr, "Could not allocate audio frame\n");
exit(1);
}
}
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
data, data_size,
AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
if (ret < 0) {
fprintf(stderr, "Error while parsing\n");
exit(1);
}
data += ret;
data_size -= ret;
if (pkt->size)
decode(c, pkt, decoded_frame, outfile);
if (data_size < AUDIO_REFILL_THRESH) {
memmove(inbuf, data, data_size);
data = inbuf;
len = fread(data + data_size, 1,
AUDIO_INBUF_SIZE - data_size, f);
if (len > 0)
data_size += len;
}
}
/* flush the decoder */
pkt->data = NULL;
pkt->size = 0;
decode(c, pkt, decoded_frame, outfile);
/* print output pcm infomations, because there have no metadata of pcm */
sfmt = c->sample_fmt;
if (av_sample_fmt_is_planar(sfmt)) {
const char *packed = av_get_sample_fmt_name(sfmt);
printf("Warning: the sample format the decoder produced is planar "
"(%s). This example will output the first channel only.\n",
packed ? packed : "?");
sfmt = av_get_packed_sample_fmt(sfmt);
}
n_channels = c->ch_layout.nb_channels;
if ((ret = get_format_from_sample_fmt(&fmt, sfmt)) < 0)
goto end;
printf("Play the output audio file with the command:\n"
"ffplay -f %s -ac %d -ar %d %s\n",
fmt, n_channels, c->sample_rate,
outfilename);
end:
fclose(outfile);
fclose(f);
avcodec_free_context(&c);
av_parser_close(parser);
av_frame_free(&decoded_frame);
av_packet_free(&pkt);
return 0;
}

View File

@@ -1,316 +0,0 @@
/*
* Copyright (c) 2010 Nicolas George
* Copyright (c) 2011 Stefano Sabatini
* Copyright (c) 2012 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.
*/
/**
* @file audio decoding and filtering usage example
* @example decode_filter_audio.c
*
* Demux, decode and filter audio input file, generate a raw audio
* file to be played with ffplay.
*/
#include <unistd.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/channel_layout.h>
#include <libavutil/mem.h>
#include <libavutil/opt.h>
static const char *filter_descr = "aresample=8000,aformat=sample_fmts=s16:channel_layouts=mono";
static const char *player = "ffplay -f s16le -ar 8000 -ac 1 -";
static AVFormatContext *fmt_ctx;
static AVCodecContext *dec_ctx;
AVFilterContext *buffersink_ctx;
AVFilterContext *buffersrc_ctx;
AVFilterGraph *filter_graph;
static int audio_stream_index = -1;
static int open_input_file(const char *filename)
{
const AVCodec *dec;
int ret;
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
return ret;
}
if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
return ret;
}
/* select the audio stream */
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot find an audio stream in the input file\n");
return ret;
}
audio_stream_index = ret;
/* create decoding context */
dec_ctx = avcodec_alloc_context3(dec);
if (!dec_ctx)
return AVERROR(ENOMEM);
avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[audio_stream_index]->codecpar);
/* init the audio decoder */
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open audio decoder\n");
return ret;
}
return 0;
}
static int init_filters(const char *filters_descr)
{
char args[512];
int ret = 0;
const AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
const AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs = avfilter_inout_alloc();
static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 };
static const int out_sample_rates[] = { 8000, -1 };
const AVFilterLink *outlink;
AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base;
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. */
if (dec_ctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
av_channel_layout_default(&dec_ctx->ch_layout, dec_ctx->ch_layout.nb_channels);
ret = snprintf(args, sizeof(args),
"time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=",
time_base.num, time_base.den, dec_ctx->sample_rate,
av_get_sample_fmt_name(dec_ctx->sample_fmt));
av_channel_layout_describe(&dec_ctx->ch_layout, args + ret, sizeof(args) - ret);
ret = avfilter_graph_create_filter(&buffersrc_ctx, abuffersrc, "in",
args, NULL, filter_graph);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
goto end;
}
/* buffer audio sink: to terminate the filter chain. */
ret = avfilter_graph_create_filter(&buffersink_ctx, abuffersink, "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_int_list(buffersink_ctx, "sample_fmts", out_sample_fmts, -1,
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(buffersink_ctx, "ch_layouts", "mono",
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_int_list(buffersink_ctx, "sample_rates", out_sample_rates, -1,
AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\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->filter_ctx = buffersrc_ctx;
outputs->pad_idx = 0;
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->filter_ctx = buffersink_ctx;
inputs->pad_idx = 0;
inputs->next = NULL;
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
&inputs, &outputs, NULL)) < 0)
goto end;
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
goto end;
/* Print summary of the sink buffer
* Note: args buffer is reused to store channel layout string */
outlink = buffersink_ctx->inputs[0];
av_channel_layout_describe(&outlink->ch_layout, args, sizeof(args));
av_log(NULL, AV_LOG_INFO, "Output: srate:%dHz fmt:%s chlayout:%s\n",
(int)outlink->sample_rate,
(char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"),
args);
end:
avfilter_inout_free(&inputs);
avfilter_inout_free(&outputs);
return ret;
}
static void print_frame(const AVFrame *frame)
{
const int n = frame->nb_samples * frame->ch_layout.nb_channels;
const uint16_t *p = (uint16_t*)frame->data[0];
const uint16_t *p_end = p + n;
while (p < p_end) {
fputc(*p & 0xff, stdout);
fputc(*p>>8 & 0xff, stdout);
p++;
}
fflush(stdout);
}
int main(int argc, char **argv)
{
int ret;
AVPacket *packet = av_packet_alloc();
AVFrame *frame = av_frame_alloc();
AVFrame *filt_frame = av_frame_alloc();
if (!packet || !frame || !filt_frame) {
fprintf(stderr, "Could not allocate frame or packet\n");
exit(1);
}
if (argc != 2) {
fprintf(stderr, "Usage: %s file | %s\n", argv[0], player);
exit(1);
}
if ((ret = open_input_file(argv[1])) < 0)
goto end;
if ((ret = init_filters(filter_descr)) < 0)
goto end;
/* read all packets */
while (1) {
if ((ret = av_read_frame(fmt_ctx, packet)) < 0)
break;
if (packet->stream_index == audio_stream_index) {
ret = avcodec_send_packet(dec_ctx, packet);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");
break;
}
while (ret >= 0) {
ret = avcodec_receive_frame(dec_ctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
} else if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n");
goto end;
}
if (ret >= 0) {
/* push the audio data from decoded frame into the filtergraph */
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n");
break;
}
/* pull filtered audio from the filtergraph */
while (1) {
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
if (ret < 0)
goto end;
print_frame(filt_frame);
av_frame_unref(filt_frame);
}
av_frame_unref(frame);
}
}
}
av_packet_unref(packet);
}
if (ret == AVERROR_EOF) {
/* signal EOF to the filtergraph */
if (av_buffersrc_add_frame_flags(buffersrc_ctx, NULL, 0) < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while closing the filtergraph\n");
goto end;
}
/* pull remaining frames from the filtergraph */
while (1) {
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
if (ret < 0)
goto end;
print_frame(filt_frame);
av_frame_unref(filt_frame);
}
}
end:
avfilter_graph_free(&filter_graph);
avcodec_free_context(&dec_ctx);
avformat_close_input(&fmt_ctx);
av_packet_free(&packet);
av_frame_free(&frame);
av_frame_free(&filt_frame);
if (ret < 0 && ret != AVERROR_EOF) {
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
exit(1);
}
exit(0);
}

View File

@@ -1,313 +0,0 @@
/*
* Copyright (c) 2010 Nicolas George
* Copyright (c) 2011 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
* API example for decoding and filtering
* @example decode_filter_video.c
*/
#define _XOPEN_SOURCE 600 /* for usleep */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/mem.h>
#include <libavutil/opt.h>
const char *filter_descr = "scale=78:24,transpose=cclock";
/* other way:
scale=78:24 [scl]; [scl] transpose=cclock // assumes "[in]" and "[out]" to be input output pads respectively
*/
static AVFormatContext *fmt_ctx;
static AVCodecContext *dec_ctx;
AVFilterContext *buffersink_ctx;
AVFilterContext *buffersrc_ctx;
AVFilterGraph *filter_graph;
static int video_stream_index = -1;
static int64_t last_pts = AV_NOPTS_VALUE;
static int open_input_file(const char *filename)
{
const AVCodec *dec;
int ret;
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
return ret;
}
if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
return ret;
}
/* select the video stream */
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot find a video stream in the input file\n");
return ret;
}
video_stream_index = ret;
/* create decoding context */
dec_ctx = avcodec_alloc_context3(dec);
if (!dec_ctx)
return AVERROR(ENOMEM);
avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[video_stream_index]->codecpar);
/* init the video decoder */
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open video decoder\n");
return ret;
}
return 0;
}
static int init_filters(const char *filters_descr)
{
char args[512];
int ret = 0;
const AVFilter *buffersrc = avfilter_get_by_name("buffer");
const AVFilter *buffersink = avfilter_get_by_name("buffersink");
AVFilterInOut *outputs = 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 };
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. */
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,
time_base.num, 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;
}
/* buffer video sink: to terminate the filter chain. */
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_int_list(buffersink_ctx, "pix_fmts", pix_fmts,
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->filter_ctx = buffersrc_ctx;
outputs->pad_idx = 0;
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->filter_ctx = buffersink_ctx;
inputs->pad_idx = 0;
inputs->next = NULL;
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
&inputs, &outputs, NULL)) < 0)
goto end;
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
goto end;
end:
avfilter_inout_free(&inputs);
avfilter_inout_free(&outputs);
return ret;
}
static void display_frame(const AVFrame *frame, AVRational time_base)
{
int x, y;
uint8_t *p0, *p;
int64_t delay;
if (frame->pts != AV_NOPTS_VALUE) {
if (last_pts != AV_NOPTS_VALUE) {
/* sleep roughly the right amount of time;
* usleep is in microseconds, just like AV_TIME_BASE. */
delay = av_rescale_q(frame->pts - last_pts,
time_base, AV_TIME_BASE_Q);
if (delay > 0 && delay < 1000000)
usleep(delay);
}
last_pts = frame->pts;
}
/* Trivial ASCII grayscale display. */
p0 = frame->data[0];
puts("\033c");
for (y = 0; y < frame->height; y++) {
p = p0;
for (x = 0; x < frame->width; x++)
putchar(" .-+#"[*(p++) / 52]);
putchar('\n');
p0 += frame->linesize[0];
}
fflush(stdout);
}
int main(int argc, char **argv)
{
int ret;
AVPacket *packet;
AVFrame *frame;
AVFrame *filt_frame;
if (argc != 2) {
fprintf(stderr, "Usage: %s file\n", argv[0]);
exit(1);
}
frame = av_frame_alloc();
filt_frame = av_frame_alloc();
packet = av_packet_alloc();
if (!frame || !filt_frame || !packet) {
fprintf(stderr, "Could not allocate frame or packet\n");
exit(1);
}
if ((ret = open_input_file(argv[1])) < 0)
goto end;
if ((ret = init_filters(filter_descr)) < 0)
goto end;
/* read all packets */
while (1) {
if ((ret = av_read_frame(fmt_ctx, packet)) < 0)
break;
if (packet->stream_index == video_stream_index) {
ret = avcodec_send_packet(dec_ctx, packet);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");
break;
}
while (ret >= 0) {
ret = avcodec_receive_frame(dec_ctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
} else if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n");
goto end;
}
frame->pts = frame->best_effort_timestamp;
/* push the decoded frame into the filtergraph */
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
break;
}
/* pull filtered frames from the filtergraph */
while (1) {
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
if (ret < 0)
goto end;
display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
av_frame_unref(filt_frame);
}
av_frame_unref(frame);
}
}
av_packet_unref(packet);
}
if (ret == AVERROR_EOF) {
/* signal EOF to the filtergraph */
if (av_buffersrc_add_frame_flags(buffersrc_ctx, NULL, 0) < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while closing the filtergraph\n");
goto end;
}
/* pull remaining frames from the filtergraph */
while (1) {
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
if (ret < 0)
goto end;
display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
av_frame_unref(filt_frame);
}
}
end:
avfilter_graph_free(&filter_graph);
avcodec_free_context(&dec_ctx);
avformat_close_input(&fmt_ctx);
av_frame_free(&frame);
av_frame_free(&filt_frame);
av_packet_free(&packet);
if (ret < 0 && ret != AVERROR_EOF) {
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
exit(1);
}
exit(0);
}

View File

@@ -1,192 +0,0 @@
/*
* Copyright (c) 2001 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @file libavcodec video decoding API usage example
* @example decode_video.c *
*
* Read from an MPEG1 video file, decode frames, and generate PGM images as
* output.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libavcodec/avcodec.h>
#define INBUF_SIZE 4096
static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
char *filename)
{
FILE *f;
int i;
f = fopen(filename,"wb");
fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
for (i = 0; i < ysize; i++)
fwrite(buf + i * wrap, 1, xsize, f);
fclose(f);
}
static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
const char *filename)
{
char buf[1024];
int ret;
ret = avcodec_send_packet(dec_ctx, pkt);
if (ret < 0) {
fprintf(stderr, "Error sending a packet for decoding\n");
exit(1);
}
while (ret >= 0) {
ret = avcodec_receive_frame(dec_ctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return;
else if (ret < 0) {
fprintf(stderr, "Error during decoding\n");
exit(1);
}
printf("saving frame %3"PRId64"\n", dec_ctx->frame_num);
fflush(stdout);
/* the picture is allocated by the decoder. no need to
free it */
snprintf(buf, sizeof(buf), "%s-%"PRId64, filename, dec_ctx->frame_num);
pgm_save(frame->data[0], frame->linesize[0],
frame->width, frame->height, buf);
}
}
int main(int argc, char **argv)
{
const char *filename, *outfilename;
const AVCodec *codec;
AVCodecParserContext *parser;
AVCodecContext *c= NULL;
FILE *f;
AVFrame *frame;
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
uint8_t *data;
size_t data_size;
int ret;
int eof;
AVPacket *pkt;
if (argc <= 2) {
fprintf(stderr, "Usage: %s <input file> <output file>\n"
"And check your input file is encoded by mpeg1video please.\n", argv[0]);
exit(0);
}
filename = argv[1];
outfilename = argv[2];
pkt = av_packet_alloc();
if (!pkt)
exit(1);
/* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
/* find the MPEG-1 video decoder */
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
if (!codec) {
fprintf(stderr, "Codec not found\n");
exit(1);
}
parser = av_parser_init(codec->id);
if (!parser) {
fprintf(stderr, "parser not found\n");
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate video codec context\n");
exit(1);
}
/* For some codecs, such as msmpeg4 and mpeg4, width and height
MUST be initialized there because this information is not
available in the bitstream. */
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
exit(1);
}
f = fopen(filename, "rb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename);
exit(1);
}
frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(1);
}
do {
/* read raw data from the input file */
data_size = fread(inbuf, 1, INBUF_SIZE, f);
if (ferror(f))
break;
eof = !data_size;
/* use the parser to split the data into frames */
data = inbuf;
while (data_size > 0 || eof) {
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
if (ret < 0) {
fprintf(stderr, "Error while parsing\n");
exit(1);
}
data += ret;
data_size -= ret;
if (pkt->size)
decode(c, frame, pkt, outfilename);
else if (eof)
break;
}
} while (!eof);
/* flush the decoder */
decode(c, frame, NULL, outfilename);
fclose(f);
av_parser_close(parser);
avcodec_free_context(&c);
av_frame_free(&frame);
av_packet_free(&pkt);
return 0;
}

View File

@@ -0,0 +1,665 @@
/*
* Copyright (c) 2001 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @file
* libavcodec API use example.
*
* @example decoding_encoding.c
* Note that libavcodec only handles codecs (mpeg, mpeg4, etc...),
* not file formats (avi, vob, mp4, mov, mkv, mxf, flv, mpegts, mpegps, etc...). See library 'libavformat' for the
* format handling
*/
#include <math.h>
#include <libavutil/opt.h>
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/common.h>
#include <libavutil/imgutils.h>
#include <libavutil/mathematics.h>
#include <libavutil/samplefmt.h>
#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
/* check that a given sample format is supported by the encoder */
static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
{
const enum AVSampleFormat *p = codec->sample_fmts;
while (*p != AV_SAMPLE_FMT_NONE) {
if (*p == sample_fmt)
return 1;
p++;
}
return 0;
}
/* just pick the highest supported samplerate */
static int select_sample_rate(AVCodec *codec)
{
const int *p;
int best_samplerate = 0;
if (!codec->supported_samplerates)
return 44100;
p = codec->supported_samplerates;
while (*p) {
best_samplerate = FFMAX(*p, best_samplerate);
p++;
}
return best_samplerate;
}
/* select layout with the highest channel count */
static int select_channel_layout(AVCodec *codec)
{
const uint64_t *p;
uint64_t best_ch_layout = 0;
int best_nb_channels = 0;
if (!codec->channel_layouts)
return AV_CH_LAYOUT_STEREO;
p = codec->channel_layouts;
while (*p) {
int nb_channels = av_get_channel_layout_nb_channels(*p);
if (nb_channels > best_nb_channels) {
best_ch_layout = *p;
best_nb_channels = nb_channels;
}
p++;
}
return best_ch_layout;
}
/*
* Audio encoding example
*/
static void audio_encode_example(const char *filename)
{
AVCodec *codec;
AVCodecContext *c= NULL;
AVFrame *frame;
AVPacket pkt;
int i, j, k, ret, got_output;
int buffer_size;
FILE *f;
uint16_t *samples;
float t, tincr;
printf("Encode audio file %s\n", filename);
/* find the MP2 encoder */
codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
if (!codec) {
fprintf(stderr, "Codec not found\n");
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate audio codec context\n");
exit(1);
}
/* put sample parameters */
c->bit_rate = 64000;
/* check that the encoder supports s16 pcm input */
c->sample_fmt = AV_SAMPLE_FMT_S16;
if (!check_sample_fmt(codec, c->sample_fmt)) {
fprintf(stderr, "Encoder does not support sample format %s",
av_get_sample_fmt_name(c->sample_fmt));
exit(1);
}
/* select other audio parameters supported by the encoder */
c->sample_rate = select_sample_rate(codec);
c->channel_layout = select_channel_layout(codec);
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
exit(1);
}
f = fopen(filename, "wb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename);
exit(1);
}
/* frame containing input raw audio */
frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate audio frame\n");
exit(1);
}
frame->nb_samples = c->frame_size;
frame->format = c->sample_fmt;
frame->channel_layout = c->channel_layout;
/* the codec gives us the frame size, in samples,
* we calculate the size of the samples buffer in bytes */
buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
c->sample_fmt, 0);
if (buffer_size < 0) {
fprintf(stderr, "Could not get sample buffer size\n");
exit(1);
}
samples = av_malloc(buffer_size);
if (!samples) {
fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
buffer_size);
exit(1);
}
/* setup the data pointers in the AVFrame */
ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
(const uint8_t*)samples, buffer_size, 0);
if (ret < 0) {
fprintf(stderr, "Could not setup audio frame\n");
exit(1);
}
/* encode a single tone sound */
t = 0;
tincr = 2 * M_PI * 440.0 / c->sample_rate;
for (i = 0; i < 200; i++) {
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by the encoder
pkt.size = 0;
for (j = 0; j < c->frame_size; j++) {
samples[2*j] = (int)(sin(t) * 10000);
for (k = 1; k < c->channels; k++)
samples[2*j + k] = samples[2*j];
t += tincr;
}
/* encode the samples */
ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding audio frame\n");
exit(1);
}
if (got_output) {
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}
/* get the delayed frames */
for (got_output = 1; got_output; i++) {
ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding frame\n");
exit(1);
}
if (got_output) {
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}
fclose(f);
av_freep(&samples);
av_frame_free(&frame);
avcodec_close(c);
av_free(c);
}
/*
* Audio decoding.
*/
static void audio_decode_example(const char *outfilename, const char *filename)
{
AVCodec *codec;
AVCodecContext *c= NULL;
int len;
FILE *f, *outfile;
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
AVPacket avpkt;
AVFrame *decoded_frame = NULL;
av_init_packet(&avpkt);
printf("Decode audio file %s to %s\n", filename, outfilename);
/* find the mpeg audio decoder */
codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
if (!codec) {
fprintf(stderr, "Codec not found\n");
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate audio codec context\n");
exit(1);
}
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
exit(1);
}
f = fopen(filename, "rb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename);
exit(1);
}
outfile = fopen(outfilename, "wb");
if (!outfile) {
av_free(c);
exit(1);
}
/* decode until eof */
avpkt.data = inbuf;
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
while (avpkt.size > 0) {
int i, ch;
int got_frame = 0;
if (!decoded_frame) {
if (!(decoded_frame = av_frame_alloc())) {
fprintf(stderr, "Could not allocate audio frame\n");
exit(1);
}
}
len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
if (len < 0) {
fprintf(stderr, "Error while decoding\n");
exit(1);
}
if (got_frame) {
/* if a frame has been decoded, output it */
int data_size = av_get_bytes_per_sample(c->sample_fmt);
if (data_size < 0) {
/* This should not occur, checking just for paranoia */
fprintf(stderr, "Failed to calculate data size\n");
exit(1);
}
for (i=0; i<decoded_frame->nb_samples; i++)
for (ch=0; ch<c->channels; ch++)
fwrite(decoded_frame->data[ch] + data_size*i, 1, data_size, outfile);
}
avpkt.size -= len;
avpkt.data += len;
avpkt.dts =
avpkt.pts = AV_NOPTS_VALUE;
if (avpkt.size < AUDIO_REFILL_THRESH) {
/* Refill the input buffer, to avoid trying to decode
* incomplete frames. Instead of this, one could also use
* a parser, or use a proper container format through
* libavformat. */
memmove(inbuf, avpkt.data, avpkt.size);
avpkt.data = inbuf;
len = fread(avpkt.data + avpkt.size, 1,
AUDIO_INBUF_SIZE - avpkt.size, f);
if (len > 0)
avpkt.size += len;
}
}
fclose(outfile);
fclose(f);
avcodec_close(c);
av_free(c);
av_frame_free(&decoded_frame);
}
/*
* Video encoding example
*/
static void video_encode_example(const char *filename, int codec_id)
{
AVCodec *codec;
AVCodecContext *c= NULL;
int i, ret, x, y, got_output;
FILE *f;
AVFrame *frame;
AVPacket pkt;
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
printf("Encode video file %s\n", filename);
/* find the mpeg1 video encoder */
codec = avcodec_find_encoder(codec_id);
if (!codec) {
fprintf(stderr, "Codec not found\n");
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate video codec context\n");
exit(1);
}
/* put sample parameters */
c->bit_rate = 400000;
/* resolution must be a multiple of two */
c->width = 352;
c->height = 288;
/* frames per second */
c->time_base = (AVRational){1,25};
/* emit one intra frame every ten frames
* check frame pict_type before passing frame
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
* then gop_size is ignored and the output of encoder
* will always be I frame irrespective to gop_size
*/
c->gop_size = 10;
c->max_b_frames = 1;
c->pix_fmt = AV_PIX_FMT_YUV420P;
if (codec_id == AV_CODEC_ID_H264)
av_opt_set(c->priv_data, "preset", "slow", 0);
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
exit(1);
}
f = fopen(filename, "wb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename);
exit(1);
}
frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(1);
}
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;
/* the image can be allocated by any means and av_image_alloc() is
* just the most convenient way if av_malloc() is to be used */
ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
c->pix_fmt, 32);
if (ret < 0) {
fprintf(stderr, "Could not allocate raw picture buffer\n");
exit(1);
}
/* encode 1 second of video */
for (i = 0; i < 25; i++) {
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by the encoder
pkt.size = 0;
fflush(stdout);
/* prepare a dummy image */
/* Y */
for (y = 0; y < c->height; y++) {
for (x = 0; x < c->width; x++) {
frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
}
}
/* Cb and Cr */
for (y = 0; y < c->height/2; y++) {
for (x = 0; x < c->width/2; x++) {
frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
}
}
frame->pts = i;
/* encode the image */
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding frame\n");
exit(1);
}
if (got_output) {
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}
/* get the delayed frames */
for (got_output = 1; got_output; i++) {
fflush(stdout);
ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding frame\n");
exit(1);
}
if (got_output) {
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}
/* add sequence end code to have a real mpeg file */
fwrite(endcode, 1, sizeof(endcode), f);
fclose(f);
avcodec_close(c);
av_free(c);
av_freep(&frame->data[0]);
av_frame_free(&frame);
printf("\n");
}
/*
* Video decoding example
*/
static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
char *filename)
{
FILE *f;
int i;
f = fopen(filename,"w");
fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
for (i = 0; i < ysize; i++)
fwrite(buf + i * wrap, 1, xsize, f);
fclose(f);
}
static int decode_write_frame(const char *outfilename, AVCodecContext *avctx,
AVFrame *frame, int *frame_count, AVPacket *pkt, int last)
{
int len, got_frame;
char buf[1024];
len = avcodec_decode_video2(avctx, frame, &got_frame, pkt);
if (len < 0) {
fprintf(stderr, "Error while decoding frame %d\n", *frame_count);
return len;
}
if (got_frame) {
printf("Saving %sframe %3d\n", last ? "last " : "", *frame_count);
fflush(stdout);
/* the picture is allocated by the decoder, no need to free it */
snprintf(buf, sizeof(buf), outfilename, *frame_count);
pgm_save(frame->data[0], frame->linesize[0],
avctx->width, avctx->height, buf);
(*frame_count)++;
}
if (pkt->data) {
pkt->size -= len;
pkt->data += len;
}
return 0;
}
static void video_decode_example(const char *outfilename, const char *filename)
{
AVCodec *codec;
AVCodecContext *c= NULL;
int frame_count;
FILE *f;
AVFrame *frame;
uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
AVPacket avpkt;
av_init_packet(&avpkt);
/* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
printf("Decode video file %s to %s\n", filename, outfilename);
/* find the mpeg1 video decoder */
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
if (!codec) {
fprintf(stderr, "Codec not found\n");
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate video codec context\n");
exit(1);
}
if(codec->capabilities&CODEC_CAP_TRUNCATED)
c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
/* For some codecs, such as msmpeg4 and mpeg4, width and height
MUST be initialized there because this information is not
available in the bitstream. */
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
exit(1);
}
f = fopen(filename, "rb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename);
exit(1);
}
frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(1);
}
frame_count = 0;
for (;;) {
avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
if (avpkt.size == 0)
break;
/* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
and this is the only method to use them because you cannot
know the compressed data size before analysing it.
BUT some other codecs (msmpeg4, mpeg4) are inherently frame
based, so you must call them with all the data for one
frame exactly. You must also initialize 'width' and
'height' before initializing them. */
/* NOTE2: some codecs allow the raw parameters (frame size,
sample rate) to be changed at any frame. We handle this, so
you should also take care of it */
/* here, we use a stream based decoder (mpeg1video), so we
feed decoder and see if it could decode a frame */
avpkt.data = inbuf;
while (avpkt.size > 0)
if (decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 0) < 0)
exit(1);
}
/* some codecs, such as MPEG, transmit the I and P frame with a
latency of one frame. You must do the following to have a
chance to get the last frame of the video */
avpkt.data = NULL;
avpkt.size = 0;
decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 1);
fclose(f);
avcodec_close(c);
av_free(c);
av_frame_free(&frame);
printf("\n");
}
int main(int argc, char **argv)
{
const char *output_type;
/* register all the codecs */
avcodec_register_all();
if (argc < 2) {
printf("usage: %s output_type\n"
"API example program to decode/encode a media stream with libavcodec.\n"
"This program generates a synthetic stream and encodes it to a file\n"
"named test.h264, test.mp2 or test.mpg depending on output_type.\n"
"The encoded stream is then decoded and written to a raw data output.\n"
"output_type must be chosen between 'h264', 'mp2', 'mpg'.\n",
argv[0]);
return 1;
}
output_type = argv[1];
if (!strcmp(output_type, "h264")) {
video_encode_example("test.h264", AV_CODEC_ID_H264);
} else if (!strcmp(output_type, "mp2")) {
audio_encode_example("test.mp2");
audio_decode_example("test.pcm", "test.mp2");
} else if (!strcmp(output_type, "mpg")) {
video_encode_example("test.mpg", AV_CODEC_ID_MPEG1VIDEO);
video_decode_example("test%02d.pgm", "test.mpg");
} else {
fprintf(stderr, "Invalid output type '%s', choose between 'h264', 'mp2', or 'mpg'\n",
output_type);
return 1;
}
return 0;
}

View File

@@ -1,380 +0,0 @@
/*
* Copyright (c) 2012 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 and libavcodec demuxing and decoding API usage example
* @example demux_decode.c
*
* Show how to use the libavformat and libavcodec API to demux and decode audio
* and video data. Write the output as raw audio and input files to be played by
* ffplay.
*/
#include <libavutil/imgutils.h>
#include <libavutil/samplefmt.h>
#include <libavutil/timestamp.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
static AVFormatContext *fmt_ctx = NULL;
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 const char *src_filename = NULL;
static const char *video_dst_filename = NULL;
static const char *audio_dst_filename = NULL;
static FILE *video_dst_file = NULL;
static FILE *audio_dst_file = NULL;
static uint8_t *video_dst_data[4] = {NULL};
static int video_dst_linesize[4];
static int video_dst_bufsize;
static int video_stream_idx = -1, audio_stream_idx = -1;
static AVFrame *frame = NULL;
static AVPacket *pkt = NULL;
static int video_frame_count = 0;
static int audio_frame_count = 0;
static int output_video_frame(AVFrame *frame)
{
if (frame->width != width || frame->height != height ||
frame->format != pix_fmt) {
/* To handle this change, one could call av_image_alloc again and
* decode the following frames into another rawvideo file. */
fprintf(stderr, "Error: Width, height and pixel format have to be "
"constant in a rawvideo file, but the width, height or "
"pixel format of the input video changed:\n"
"old: width = %d, height = %d, format = %s\n"
"new: width = %d, height = %d, format = %s\n",
width, height, av_get_pix_fmt_name(pix_fmt),
frame->width, frame->height,
av_get_pix_fmt_name(frame->format));
return -1;
}
printf("video_frame n:%d\n",
video_frame_count++);
/* copy decoded frame to destination buffer:
* this is required since rawvideo expects non aligned data */
av_image_copy2(video_dst_data, video_dst_linesize,
frame->data, frame->linesize,
pix_fmt, width, height);
/* write to rawvideo file */
fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);
return 0;
}
static int output_audio_frame(AVFrame *frame)
{
size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(frame->format);
printf("audio_frame n:%d nb_samples:%d pts:%s\n",
audio_frame_count++, frame->nb_samples,
av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));
/* Write the raw audio data samples of the first plane. This works
* fine for packed formats (e.g. AV_SAMPLE_FMT_S16). However,
* most audio decoders output planar audio, which uses a separate
* plane of audio samples for each channel (e.g. AV_SAMPLE_FMT_S16P).
* In other words, this code will write only the first audio channel
* in these cases.
* You should use libswresample or libavfilter to convert the frame
* to packed data. */
fwrite(frame->extended_data[0], 1, unpadded_linesize, audio_dst_file);
return 0;
}
static int decode_packet(AVCodecContext *dec, const AVPacket *pkt)
{
int ret = 0;
// submit the packet to the decoder
ret = avcodec_send_packet(dec, pkt);
if (ret < 0) {
fprintf(stderr, "Error submitting a packet for decoding (%s)\n", av_err2str(ret));
return ret;
}
// get all the available frames from the decoder
while (ret >= 0) {
ret = avcodec_receive_frame(dec, frame);
if (ret < 0) {
// those two return values are special and mean there is no output
// frame available, but there were no errors during decoding
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
return 0;
fprintf(stderr, "Error during decoding (%s)\n", av_err2str(ret));
return ret;
}
// write the frame data to output file
if (dec->codec->type == AVMEDIA_TYPE_VIDEO)
ret = output_video_frame(frame);
else
ret = output_audio_frame(frame);
av_frame_unref(frame);
}
return ret;
}
static int open_codec_context(int *stream_idx,
AVCodecContext **dec_ctx, AVFormatContext *fmt_ctx, enum AVMediaType type)
{
int ret, stream_index;
AVStream *st;
const AVCodec *dec = 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_index = ret;
st = fmt_ctx->streams[stream_index];
/* find decoder for the stream */
dec = avcodec_find_decoder(st->codecpar->codec_id);
if (!dec) {
fprintf(stderr, "Failed to find %s codec\n",
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;
}
/* Init the decoders */
if ((ret = avcodec_open2(*dec_ctx, dec, NULL)) < 0) {
fprintf(stderr, "Failed to open %s codec\n",
av_get_media_type_string(type));
return ret;
}
*stream_idx = stream_index;
}
return 0;
}
static int get_format_from_sample_fmt(const char **fmt,
enum AVSampleFormat sample_fmt)
{
int i;
struct sample_fmt_entry {
enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
} sample_fmt_entries[] = {
{ AV_SAMPLE_FMT_U8, "u8", "u8" },
{ AV_SAMPLE_FMT_S16, "s16be", "s16le" },
{ AV_SAMPLE_FMT_S32, "s32be", "s32le" },
{ AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
{ AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
};
*fmt = NULL;
for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
struct sample_fmt_entry *entry = &sample_fmt_entries[i];
if (sample_fmt == entry->sample_fmt) {
*fmt = AV_NE(entry->fmt_be, entry->fmt_le);
return 0;
}
}
fprintf(stderr,
"sample format %s is not supported as output format\n",
av_get_sample_fmt_name(sample_fmt));
return -1;
}
int main (int argc, char **argv)
{
int ret = 0;
if (argc != 4) {
fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"
"API example program to show how to read frames from an input file.\n"
"This program reads frames from a file, decodes them, and writes decoded\n"
"video frames to a rawvideo file named video_output_file, and decoded\n"
"audio frames to a rawaudio file named audio_output_file.\n",
argv[0]);
exit(1);
}
src_filename = argv[1];
video_dst_filename = argv[2];
audio_dst_filename = argv[3];
/* open input file, and allocate format context */
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
fprintf(stderr, "Could not open source file %s\n", src_filename);
exit(1);
}
/* retrieve stream information */
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, &video_dec_ctx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {
video_stream = fmt_ctx->streams[video_stream_idx];
video_dst_file = fopen(video_dst_filename, "wb");
if (!video_dst_file) {
fprintf(stderr, "Could not open destination file %s\n", video_dst_filename);
ret = 1;
goto end;
}
/* 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,
width, height, pix_fmt, 1);
if (ret < 0) {
fprintf(stderr, "Could not allocate raw video buffer\n");
goto end;
}
video_dst_bufsize = ret;
}
if (open_codec_context(&audio_stream_idx, &audio_dec_ctx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {
audio_stream = fmt_ctx->streams[audio_stream_idx];
audio_dst_file = fopen(audio_dst_filename, "wb");
if (!audio_dst_file) {
fprintf(stderr, "Could not open destination file %s\n", audio_dst_filename);
ret = 1;
goto end;
}
}
/* dump input information to stderr */
av_dump_format(fmt_ctx, 0, src_filename, 0);
if (!audio_stream && !video_stream) {
fprintf(stderr, "Could not find audio or 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;
}
pkt = av_packet_alloc();
if (!pkt) {
fprintf(stderr, "Could not allocate packet\n");
ret = AVERROR(ENOMEM);
goto end;
}
if (video_stream)
printf("Demuxing video from file '%s' into '%s'\n", src_filename, video_dst_filename);
if (audio_stream)
printf("Demuxing audio from file '%s' into '%s'\n", src_filename, audio_dst_filename);
/* read frames from the file */
while (av_read_frame(fmt_ctx, pkt) >= 0) {
// check if the packet belongs to a stream we are interested in, otherwise
// skip it
if (pkt->stream_index == video_stream_idx)
ret = decode_packet(video_dec_ctx, pkt);
else if (pkt->stream_index == audio_stream_idx)
ret = decode_packet(audio_dec_ctx, pkt);
av_packet_unref(pkt);
if (ret < 0)
break;
}
/* flush the decoders */
if (video_dec_ctx)
decode_packet(video_dec_ctx, NULL);
if (audio_dec_ctx)
decode_packet(audio_dec_ctx, NULL);
printf("Demuxing succeeded.\n");
if (video_stream) {
printf("Play the output video file with the command:\n"
"ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
av_get_pix_fmt_name(pix_fmt), width, height,
video_dst_filename);
}
if (audio_stream) {
enum AVSampleFormat sfmt = audio_dec_ctx->sample_fmt;
int n_channels = audio_dec_ctx->ch_layout.nb_channels;
const char *fmt;
if (av_sample_fmt_is_planar(sfmt)) {
const char *packed = av_get_sample_fmt_name(sfmt);
printf("Warning: the sample format the decoder produced is planar "
"(%s). This example will output the first channel only.\n",
packed ? packed : "?");
sfmt = av_get_packed_sample_fmt(sfmt);
n_channels = 1;
}
if ((ret = get_format_from_sample_fmt(&fmt, sfmt)) < 0)
goto end;
printf("Play the output audio file with the command:\n"
"ffplay -f %s -ac %d -ar %d %s\n",
fmt, n_channels, audio_dec_ctx->sample_rate,
audio_dst_filename);
}
end:
avcodec_free_context(&video_dec_ctx);
avcodec_free_context(&audio_dec_ctx);
avformat_close_input(&fmt_ctx);
if (video_dst_file)
fclose(video_dst_file);
if (audio_dst_file)
fclose(audio_dst_file);
av_packet_free(&pkt);
av_frame_free(&frame);
av_free(video_dst_data[0]);
return ret < 0;
}

View File

@@ -0,0 +1,405 @@
/*
* Copyright (c) 2012 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
* Demuxing and decoding example.
*
* Show how to use the libavformat and libavcodec API to demux and
* decode audio and video data.
* @example demuxing_decoding.c
*/
#include <libavutil/imgutils.h>
#include <libavutil/samplefmt.h>
#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>
static AVFormatContext *fmt_ctx = NULL;
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 const char *src_filename = NULL;
static const char *video_dst_filename = NULL;
static const char *audio_dst_filename = NULL;
static FILE *video_dst_file = NULL;
static FILE *audio_dst_file = NULL;
static uint8_t *video_dst_data[4] = {NULL};
static int video_dst_linesize[4];
static int video_dst_bufsize;
static int video_stream_idx = -1, audio_stream_idx = -1;
static AVFrame *frame = NULL;
static AVPacket pkt;
static int video_frame_count = 0;
static int audio_frame_count = 0;
/* The different ways of decoding and managing data memory. You are not
* supposed to support all the modes in your application but pick the one most
* appropriate to your needs. Look for the use of api_mode in this example to
* see what are the differences of API usage between them */
enum {
API_MODE_OLD = 0, /* old method, deprecated */
API_MODE_NEW_API_REF_COUNT = 1, /* new method, using the frame reference counting */
API_MODE_NEW_API_NO_REF_COUNT = 2, /* new method, without reference counting */
};
static int api_mode = API_MODE_OLD;
static int decode_packet(int *got_frame, int cached)
{
int ret = 0;
int decoded = pkt.size;
*got_frame = 0;
if (pkt.stream_index == video_stream_idx) {
/* decode video frame */
ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
if (ret < 0) {
fprintf(stderr, "Error decoding video frame (%s)\n", av_err2str(ret));
return ret;
}
if (video_dec_ctx->width != width || video_dec_ctx->height != height ||
video_dec_ctx->pix_fmt != 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),
video_dec_ctx->width, video_dec_ctx->height,
av_get_pix_fmt_name(video_dec_ctx->pix_fmt));
return -1;
}
if (*got_frame) {
printf("video_frame%s n:%d coded_n:%d pts:%s\n",
cached ? "(cached)" : "",
video_frame_count++, frame->coded_picture_number,
av_ts2timestr(frame->pts, &video_dec_ctx->time_base));
/* copy decoded frame to destination buffer:
* this is required since rawvideo expects non aligned data */
av_image_copy(video_dst_data, video_dst_linesize,
(const uint8_t **)(frame->data), frame->linesize,
pix_fmt, width, height);
/* write to rawvideo file */
fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);
}
} else if (pkt.stream_index == audio_stream_idx) {
/* decode audio frame */
ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
if (ret < 0) {
fprintf(stderr, "Error decoding audio frame (%s)\n", av_err2str(ret));
return ret;
}
/* Some audio decoders decode only part of the packet, and have to be
* called again with the remainder of the packet data.
* Sample: fate-suite/lossless-audio/luckynight-partial.shn
* Also, some decoders might over-read the packet. */
decoded = FFMIN(ret, pkt.size);
if (*got_frame) {
size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(frame->format);
printf("audio_frame%s n:%d nb_samples:%d pts:%s\n",
cached ? "(cached)" : "",
audio_frame_count++, frame->nb_samples,
av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));
/* Write the raw audio data samples of the first plane. This works
* fine for packed formats (e.g. AV_SAMPLE_FMT_S16). However,
* most audio decoders output planar audio, which uses a separate
* plane of audio samples for each channel (e.g. AV_SAMPLE_FMT_S16P).
* In other words, this code will write only the first audio channel
* in these cases.
* You should use libswresample or libavfilter to convert the frame
* to packed data. */
fwrite(frame->extended_data[0], 1, unpadded_linesize, audio_dst_file);
}
}
/* If we use the new API with reference counting, we own the data and need
* to de-reference it when we don't use it anymore */
if (*got_frame && api_mode == API_MODE_NEW_API_REF_COUNT)
av_frame_unref(frame);
return decoded;
}
static int open_codec_context(int *stream_idx,
AVFormatContext *fmt_ctx, enum AVMediaType type)
{
int ret, stream_index;
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_index = ret;
st = fmt_ctx->streams[stream_index];
/* 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 decoders, with or without reference counting */
if (api_mode == API_MODE_NEW_API_REF_COUNT)
av_dict_set(&opts, "refcounted_frames", "1", 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;
}
*stream_idx = stream_index;
}
return 0;
}
static int get_format_from_sample_fmt(const char **fmt,
enum AVSampleFormat sample_fmt)
{
int i;
struct sample_fmt_entry {
enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
} sample_fmt_entries[] = {
{ AV_SAMPLE_FMT_U8, "u8", "u8" },
{ AV_SAMPLE_FMT_S16, "s16be", "s16le" },
{ AV_SAMPLE_FMT_S32, "s32be", "s32le" },
{ AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
{ AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
};
*fmt = NULL;
for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
struct sample_fmt_entry *entry = &sample_fmt_entries[i];
if (sample_fmt == entry->sample_fmt) {
*fmt = AV_NE(entry->fmt_be, entry->fmt_le);
return 0;
}
}
fprintf(stderr,
"sample format %s is not supported as output format\n",
av_get_sample_fmt_name(sample_fmt));
return -1;
}
int main (int argc, char **argv)
{
int ret = 0, got_frame;
if (argc != 4 && argc != 5) {
fprintf(stderr, "usage: %s [-refcount=<old|new_norefcount|new_refcount>] "
"input_file video_output_file audio_output_file\n"
"API example program to show how to read frames from an input file.\n"
"This program reads frames from a file, decodes them, and writes decoded\n"
"video frames to a rawvideo file named video_output_file, and decoded\n"
"audio frames to a rawaudio file named audio_output_file.\n\n"
"If the -refcount option is specified, the program use the\n"
"reference counting frame system which allows keeping a copy of\n"
"the data for longer than one decode call. If unset, it's using\n"
"the classic old method.\n"
"\n", argv[0]);
exit(1);
}
if (argc == 5) {
const char *mode = argv[1] + strlen("-refcount=");
if (!strcmp(mode, "old")) api_mode = API_MODE_OLD;
else if (!strcmp(mode, "new_norefcount")) api_mode = API_MODE_NEW_API_NO_REF_COUNT;
else if (!strcmp(mode, "new_refcount")) api_mode = API_MODE_NEW_API_REF_COUNT;
else {
fprintf(stderr, "unknow mode '%s'\n", mode);
exit(1);
}
argv++;
}
src_filename = argv[1];
video_dst_filename = argv[2];
audio_dst_filename = argv[3];
/* register all formats and codecs */
av_register_all();
/* open input file, and allocate format context */
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
fprintf(stderr, "Could not open source file %s\n", src_filename);
exit(1);
}
/* retrieve stream information */
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;
video_dst_file = fopen(video_dst_filename, "wb");
if (!video_dst_file) {
fprintf(stderr, "Could not open destination file %s\n", video_dst_filename);
ret = 1;
goto end;
}
/* 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,
width, height, pix_fmt, 1);
if (ret < 0) {
fprintf(stderr, "Could not allocate raw video buffer\n");
goto end;
}
video_dst_bufsize = ret;
}
if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {
audio_stream = fmt_ctx->streams[audio_stream_idx];
audio_dec_ctx = audio_stream->codec;
audio_dst_file = fopen(audio_dst_filename, "wb");
if (!audio_dst_file) {
fprintf(stderr, "Could not open destination file %s\n", audio_dst_filename);
ret = 1;
goto end;
}
}
/* dump input information to stderr */
av_dump_format(fmt_ctx, 0, src_filename, 0);
if (!audio_stream && !video_stream) {
fprintf(stderr, "Could not find audio or video stream in the input, aborting\n");
ret = 1;
goto end;
}
/* When using the new API, you need to use the libavutil/frame.h API, while
* the classic frame management is available in libavcodec */
if (api_mode == API_MODE_OLD)
frame = avcodec_alloc_frame();
else
frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate frame\n");
ret = AVERROR(ENOMEM);
goto end;
}
/* initialize packet, set data to NULL, let the demuxer fill it */
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
if (video_stream)
printf("Demuxing video from file '%s' into '%s'\n", src_filename, video_dst_filename);
if (audio_stream)
printf("Demuxing audio from file '%s' into '%s'\n", src_filename, audio_dst_filename);
/* read frames from the file */
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
AVPacket orig_pkt = pkt;
do {
ret = decode_packet(&got_frame, 0);
if (ret < 0)
break;
pkt.data += ret;
pkt.size -= ret;
} while (pkt.size > 0);
av_free_packet(&orig_pkt);
}
/* flush cached frames */
pkt.data = NULL;
pkt.size = 0;
do {
decode_packet(&got_frame, 1);
} while (got_frame);
printf("Demuxing succeeded.\n");
if (video_stream) {
printf("Play the output video file with the command:\n"
"ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
av_get_pix_fmt_name(pix_fmt), width, height,
video_dst_filename);
}
if (audio_stream) {
enum AVSampleFormat sfmt = audio_dec_ctx->sample_fmt;
int n_channels = audio_dec_ctx->channels;
const char *fmt;
if (av_sample_fmt_is_planar(sfmt)) {
const char *packed = av_get_sample_fmt_name(sfmt);
printf("Warning: the sample format the decoder produced is planar "
"(%s). This example will output the first channel only.\n",
packed ? packed : "?");
sfmt = av_get_packed_sample_fmt(sfmt);
n_channels = 1;
}
if ((ret = get_format_from_sample_fmt(&fmt, sfmt)) < 0)
goto end;
printf("Play the output audio file with the command:\n"
"ffplay -f %s -ac %d -ar %d %s\n",
fmt, n_channels, audio_dec_ctx->sample_rate,
audio_dst_filename);
}
end:
avcodec_close(video_dec_ctx);
avcodec_close(audio_dec_ctx);
avformat_close_input(&fmt_ctx);
if (video_dst_file)
fclose(video_dst_file);
if (audio_dst_file)
fclose(audio_dst_file);
if (api_mode == API_MODE_OLD)
avcodec_free_frame(&frame);
else
av_frame_free(&frame);
av_free(video_dst_data[0]);
return ret < 0;
}

View File

@@ -1,240 +0,0 @@
/*
* Copyright (c) 2001 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @file libavcodec encoding audio API usage examples
* @example encode_audio.c
*
* Generate a synthetic audio signal and encode it to an output MP2 file.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/common.h>
#include <libavutil/frame.h>
#include <libavutil/samplefmt.h>
/* check that a given sample format is supported by the encoder */
static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt)
{
const enum AVSampleFormat *p = codec->sample_fmts;
while (*p != AV_SAMPLE_FMT_NONE) {
if (*p == sample_fmt)
return 1;
p++;
}
return 0;
}
/* just pick the highest supported samplerate */
static int select_sample_rate(const AVCodec *codec)
{
const int *p;
int best_samplerate = 0;
if (!codec->supported_samplerates)
return 44100;
p = codec->supported_samplerates;
while (*p) {
if (!best_samplerate || abs(44100 - *p) < abs(44100 - best_samplerate))
best_samplerate = *p;
p++;
}
return best_samplerate;
}
/* select layout with the highest channel count */
static int select_channel_layout(const AVCodec *codec, AVChannelLayout *dst)
{
const AVChannelLayout *p, *best_ch_layout;
int best_nb_channels = 0;
if (!codec->ch_layouts)
return av_channel_layout_copy(dst, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO);
p = codec->ch_layouts;
while (p->nb_channels) {
int nb_channels = p->nb_channels;
if (nb_channels > best_nb_channels) {
best_ch_layout = p;
best_nb_channels = nb_channels;
}
p++;
}
return av_channel_layout_copy(dst, best_ch_layout);
}
static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt,
FILE *output)
{
int ret;
/* send the frame for encoding */
ret = avcodec_send_frame(ctx, frame);
if (ret < 0) {
fprintf(stderr, "Error sending the frame to the encoder\n");
exit(1);
}
/* read all the available output packets (in general there may be any
* number of them */
while (ret >= 0) {
ret = avcodec_receive_packet(ctx, pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return;
else if (ret < 0) {
fprintf(stderr, "Error encoding audio frame\n");
exit(1);
}
fwrite(pkt->data, 1, pkt->size, output);
av_packet_unref(pkt);
}
}
int main(int argc, char **argv)
{
const char *filename;
const AVCodec *codec;
AVCodecContext *c= NULL;
AVFrame *frame;
AVPacket *pkt;
int i, j, k, ret;
FILE *f;
uint16_t *samples;
float t, tincr;
if (argc <= 1) {
fprintf(stderr, "Usage: %s <output file>\n", argv[0]);
return 0;
}
filename = argv[1];
/* find the MP2 encoder */
codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
if (!codec) {
fprintf(stderr, "Codec not found\n");
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate audio codec context\n");
exit(1);
}
/* put sample parameters */
c->bit_rate = 64000;
/* check that the encoder supports s16 pcm input */
c->sample_fmt = AV_SAMPLE_FMT_S16;
if (!check_sample_fmt(codec, c->sample_fmt)) {
fprintf(stderr, "Encoder does not support sample format %s",
av_get_sample_fmt_name(c->sample_fmt));
exit(1);
}
/* select other audio parameters supported by the encoder */
c->sample_rate = select_sample_rate(codec);
ret = select_channel_layout(codec, &c->ch_layout);
if (ret < 0)
exit(1);
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
exit(1);
}
f = fopen(filename, "wb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename);
exit(1);
}
/* packet for holding encoded output */
pkt = av_packet_alloc();
if (!pkt) {
fprintf(stderr, "could not allocate the packet\n");
exit(1);
}
/* frame containing input raw audio */
frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate audio frame\n");
exit(1);
}
frame->nb_samples = c->frame_size;
frame->format = c->sample_fmt;
ret = av_channel_layout_copy(&frame->ch_layout, &c->ch_layout);
if (ret < 0)
exit(1);
/* allocate the data buffers */
ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {
fprintf(stderr, "Could not allocate audio data buffers\n");
exit(1);
}
/* encode a single tone sound */
t = 0;
tincr = 2 * M_PI * 440.0 / c->sample_rate;
for (i = 0; i < 200; i++) {
/* make sure the frame is writable -- makes a copy if the encoder
* kept a reference internally */
ret = av_frame_make_writable(frame);
if (ret < 0)
exit(1);
samples = (uint16_t*)frame->data[0];
for (j = 0; j < c->frame_size; j++) {
samples[2*j] = (int)(sin(t) * 10000);
for (k = 1; k < c->ch_layout.nb_channels; k++)
samples[2*j + k] = samples[2*j];
t += tincr;
}
encode(c, frame, pkt, f);
}
/* flush the encoder */
encode(c, NULL, pkt, f);
fclose(f);
av_frame_free(&frame);
av_packet_free(&pkt);
avcodec_free_context(&c);
return 0;
}

View File

@@ -1,216 +0,0 @@
/*
* Copyright (c) 2001 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @file libavcodec encoding video API usage example
* @example encode_video.c
*
* Generate synthetic video data and encode it to an output file.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>
static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,
FILE *outfile)
{
int ret;
/* send the frame to the encoder */
if (frame)
printf("Send frame %3"PRId64"\n", frame->pts);
ret = avcodec_send_frame(enc_ctx, frame);
if (ret < 0) {
fprintf(stderr, "Error sending a frame for encoding\n");
exit(1);
}
while (ret >= 0) {
ret = avcodec_receive_packet(enc_ctx, pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return;
else if (ret < 0) {
fprintf(stderr, "Error during encoding\n");
exit(1);
}
printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size);
fwrite(pkt->data, 1, pkt->size, outfile);
av_packet_unref(pkt);
}
}
int main(int argc, char **argv)
{
const char *filename, *codec_name;
const AVCodec *codec;
AVCodecContext *c= NULL;
int i, ret, x, y;
FILE *f;
AVFrame *frame;
AVPacket *pkt;
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
if (argc <= 2) {
fprintf(stderr, "Usage: %s <output file> <codec name>\n", argv[0]);
exit(0);
}
filename = argv[1];
codec_name = argv[2];
/* find the mpeg1video encoder */
codec = avcodec_find_encoder_by_name(codec_name);
if (!codec) {
fprintf(stderr, "Codec '%s' not found\n", codec_name);
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate video codec context\n");
exit(1);
}
pkt = av_packet_alloc();
if (!pkt)
exit(1);
/* put sample parameters */
c->bit_rate = 400000;
/* resolution must be a multiple of two */
c->width = 352;
c->height = 288;
/* frames per second */
c->time_base = (AVRational){1, 25};
c->framerate = (AVRational){25, 1};
/* emit one intra frame every ten frames
* check frame pict_type before passing frame
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
* then gop_size is ignored and the output of encoder
* will always be I frame irrespective to gop_size
*/
c->gop_size = 10;
c->max_b_frames = 1;
c->pix_fmt = AV_PIX_FMT_YUV420P;
if (codec->id == AV_CODEC_ID_H264)
av_opt_set(c->priv_data, "preset", "slow", 0);
/* open it */
ret = avcodec_open2(c, codec, NULL);
if (ret < 0) {
fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
exit(1);
}
f = fopen(filename, "wb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename);
exit(1);
}
frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(1);
}
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;
ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {
fprintf(stderr, "Could not allocate the video frame data\n");
exit(1);
}
/* encode 1 second of video */
for (i = 0; i < 25; i++) {
fflush(stdout);
/* Make sure the frame data is writable.
On the first round, the frame is fresh from av_frame_get_buffer()
and therefore we know it is writable.
But on the next rounds, encode() will have called
avcodec_send_frame(), and the codec may have kept a reference to
the frame in its internal structures, that makes the frame
unwritable.
av_frame_make_writable() checks that and allocates a new buffer
for the frame only if necessary.
*/
ret = av_frame_make_writable(frame);
if (ret < 0)
exit(1);
/* Prepare a dummy image.
In real code, this is where you would have your own logic for
filling the frame. FFmpeg does not care what you put in the
frame.
*/
/* Y */
for (y = 0; y < c->height; y++) {
for (x = 0; x < c->width; x++) {
frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
}
}
/* Cb and Cr */
for (y = 0; y < c->height/2; y++) {
for (x = 0; x < c->width/2; x++) {
frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
}
}
frame->pts = i;
/* encode the image */
encode(c, frame, pkt, f);
}
/* flush the encoder */
encode(c, NULL, pkt, f);
/* Add sequence end code to have a real MPEG file.
It makes only sense because this tiny examples writes packets
directly. This is called "elementary stream" and only works for some
codecs. To create a valid file, you usually need to write packets
into a proper file format or protocol; see mux.c.
*/
if (codec->id == AV_CODEC_ID_MPEG1VIDEO || codec->id == AV_CODEC_ID_MPEG2VIDEO)
fwrite(endcode, 1, sizeof(endcode), f);
fclose(f);
avcodec_free_context(&c);
av_frame_free(&frame);
av_packet_free(&pkt);
return 0;
}

View File

@@ -21,16 +21,7 @@
* THE SOFTWARE.
*/
/**
* @file libavcodec motion vectors extraction API usage example
* @example extract_mvs.c
*
* Read from input file, decode video stream and print a motion vectors
* representation to stdout.
*/
#include <libavutil/motion_vector.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
static AVFormatContext *fmt_ctx = NULL;
@@ -40,26 +31,23 @@ 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(const AVPacket *pkt)
static int decode_packet(int *got_frame, int cached)
{
int ret = avcodec_send_packet(video_dec_ctx, pkt);
if (ret < 0) {
fprintf(stderr, "Error while sending a packet to the decoder: %s\n", av_err2str(ret));
return ret;
}
int decoded = pkt.size;
while (ret >= 0) {
ret = avcodec_receive_frame(video_dec_ctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
} else if (ret < 0) {
fprintf(stderr, "Error while receiving a frame from the decoder: %s\n", av_err2str(ret));
*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 (ret >= 0) {
if (*got_frame) {
int i;
AVFrameSideData *sd;
@@ -69,62 +57,52 @@ static int decode_packet(const AVPacket *pkt)
const AVMotionVector *mvs = (const AVMotionVector *)sd->data;
for (i = 0; i < sd->size / sizeof(*mvs); i++) {
const AVMotionVector *mv = &mvs[i];
printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64",%4d,%4d,%4d\n",
video_frame_count, mv->source,
mv->w, mv->h, mv->src_x, mv->src_y,
mv->dst_x, mv->dst_y, mv->flags,
mv->motion_x, mv->motion_y, mv->motion_scale);
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);
}
}
av_frame_unref(frame);
}
}
return 0;
return decoded;
}
static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
static int open_codec_context(int *stream_idx,
AVFormatContext *fmt_ctx, enum AVMediaType type)
{
int ret;
AVStream *st;
AVCodecContext *dec_ctx = NULL;
const AVCodec *dec = NULL;
AVCodec *dec = NULL;
AVDictionary *opts = NULL;
ret = av_find_best_stream(fmt_ctx, type, -1, -1, &dec, 0);
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
if (ret < 0) {
fprintf(stderr, "Could not find %s stream in input file '%s'\n",
av_get_media_type_string(type), src_filename);
return ret;
} else {
int stream_idx = ret;
st = fmt_ctx->streams[stream_idx];
*stream_idx = ret;
st = fmt_ctx->streams[*stream_idx];
dec_ctx = avcodec_alloc_context3(dec);
if (!dec_ctx) {
fprintf(stderr, "Failed to allocate codec\n");
/* 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);
}
ret = avcodec_parameters_to_context(dec_ctx, st->codecpar);
if (ret < 0) {
fprintf(stderr, "Failed to copy codec parameters to codec context\n");
return ret;
}
/* Init the video decoder */
av_dict_set(&opts, "flags2", "+export_mvs", 0);
ret = avcodec_open2(dec_ctx, dec, &opts);
av_dict_free(&opts);
if (ret < 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;
}
video_stream_idx = stream_idx;
video_stream = fmt_ctx->streams[video_stream_idx];
video_dec_ctx = dec_ctx;
}
return 0;
@@ -132,8 +110,7 @@ static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
int main(int argc, char **argv)
{
int ret = 0;
AVPacket *pkt = NULL;
int ret = 0, got_frame;
if (argc != 2) {
fprintf(stderr, "Usage: %s <video>\n", argv[0]);
@@ -141,6 +118,8 @@ int main(int argc, char **argv)
}
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);
@@ -151,7 +130,10 @@ int main(int argc, char **argv)
exit(1);
}
open_codec_context(fmt_ctx, AVMEDIA_TYPE_VIDEO);
if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {
video_stream = fmt_ctx->streams[video_stream_idx];
video_dec_ctx = video_stream->codec;
}
av_dump_format(fmt_ctx, 0, src_filename, 0);
@@ -168,31 +150,36 @@ int main(int argc, char **argv)
goto end;
}
pkt = av_packet_alloc();
if (!pkt) {
fprintf(stderr, "Could not allocate AVPacket\n");
ret = AVERROR(ENOMEM);
goto end;
}
printf("framenum,source,blockw,blockh,srcx,srcy,dstx,dsty,flags\n");
printf("framenum,source,blockw,blockh,srcx,srcy,dstx,dsty,flags,motion_x,motion_y,motion_scale\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) {
if (pkt->stream_index == video_stream_idx)
ret = decode_packet(pkt);
av_packet_unref(pkt);
if (ret < 0)
break;
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_free_packet(&orig_pkt);
}
/* flush cached frames */
decode_packet(NULL);
pkt.data = NULL;
pkt.size = 0;
do {
decode_packet(&got_frame, 1);
} while (got_frame);
end:
avcodec_free_context(&video_dec_ctx);
avcodec_close(video_dec_ctx);
avformat_close_input(&fmt_ctx);
av_frame_free(&frame);
av_packet_free(&pkt);
return ret < 0;
}

View File

@@ -19,11 +19,13 @@
*/
/**
* @file libavfilter audio filtering API usage example
* @example filter_audio.c
* @file
* libavfilter API usage example.
*
* This example will generate a sine wave audio, pass it through a simple filter
* chain, and then compute the MD5 checksum of the output data.
* @example filter_audio.c
* This example will generate a sine wave audio,
* pass it through a simple filter chain, and then compute the MD5 checksum of
* the output data.
*
* The filter chain it uses is:
* (input) -> abuffer -> volume -> aformat -> abuffersink -> (output)
@@ -41,19 +43,19 @@
#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 "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>
#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 (AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0
#define INPUT_CHANNEL_LAYOUT AV_CH_LAYOUT_5POINT0
#define VOLUME_VAL 0.90
@@ -62,13 +64,13 @@ static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src,
{
AVFilterGraph *filter_graph;
AVFilterContext *abuffer_ctx;
const AVFilter *abuffer;
AVFilter *abuffer;
AVFilterContext *volume_ctx;
const AVFilter *volume;
AVFilter *volume;
AVFilterContext *aformat_ctx;
const AVFilter *aformat;
AVFilter *aformat;
AVFilterContext *abuffersink_ctx;
const AVFilter *abuffersink;
AVFilter *abuffersink;
AVDictionary *options_dict = NULL;
uint8_t options_str[1024];
@@ -98,7 +100,7 @@ static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src,
}
/* Set the filter options through the AVOptions API. */
av_channel_layout_describe(&INPUT_CHANNEL_LAYOUT, ch_layout, sizeof(ch_layout));
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);
@@ -152,8 +154,9 @@ static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src,
/* A third way of passing the options is in a string of the form
* key1=value1:key2=value2.... */
snprintf(options_str, sizeof(options_str),
"sample_fmts=%s:sample_rates=%d:channel_layouts=stereo",
av_get_sample_fmt_name(AV_SAMPLE_FMT_S16), 44100);
"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");
@@ -212,7 +215,7 @@ static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src,
static int process_output(struct AVMD5 *md5, AVFrame *frame)
{
int planar = av_sample_fmt_is_planar(frame->format);
int channels = frame->ch_layout.nb_channels;
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);
@@ -245,7 +248,7 @@ static int get_input(AVFrame *frame, int frame_num)
/* Set up the frame properties and allocate the buffer for the data. */
frame->sample_rate = INPUT_SAMPLERATE;
frame->format = INPUT_FORMAT;
av_channel_layout_copy(&frame->ch_layout, &INPUT_CHANNEL_LAYOUT);
frame->channel_layout = INPUT_CHANNEL_LAYOUT;
frame->nb_samples = FRAME_SIZE;
frame->pts = frame_num * FRAME_SIZE;
@@ -286,6 +289,8 @@ int main(int argc, char *argv[])
return 1;
}
avfilter_register_all();
/* Allocate the frame we will be using to store the data. */
frame = av_frame_alloc();
if (!frame) {

View File

@@ -0,0 +1,296 @@
/*
* Copyright (c) 2010 Nicolas George
* Copyright (c) 2011 Stefano Sabatini
* Copyright (c) 2012 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.
*/
/**
* @file
* API example for audio decoding and filtering
* @example filtering_audio.c
*/
#include <unistd.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/avfiltergraph.h>
#include <libavfilter/avcodec.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/opt.h>
static const char *filter_descr = "aresample=8000,aformat=sample_fmts=s16:channel_layouts=mono";
static const char *player = "ffplay -f s16le -ar 8000 -ac 1 -";
static AVFormatContext *fmt_ctx;
static AVCodecContext *dec_ctx;
AVFilterContext *buffersink_ctx;
AVFilterContext *buffersrc_ctx;
AVFilterGraph *filter_graph;
static int audio_stream_index = -1;
static int open_input_file(const char *filename)
{
int ret;
AVCodec *dec;
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
return ret;
}
if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
return ret;
}
/* select the audio stream */
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot find a audio stream in the input file\n");
return ret;
}
audio_stream_index = ret;
dec_ctx = fmt_ctx->streams[audio_stream_index]->codec;
av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);
/* init the audio decoder */
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open audio decoder\n");
return ret;
}
return 0;
}
static int init_filters(const char *filters_descr)
{
char args[512];
int ret = 0;
AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs = avfilter_inout_alloc();
static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 };
static const int64_t out_channel_layouts[] = { AV_CH_LAYOUT_MONO, -1 };
static const int out_sample_rates[] = { 8000, -1 };
const AVFilterLink *outlink;
AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base;
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. */
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,
time_base.num, 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, abuffersrc, "in",
args, NULL, filter_graph);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
goto end;
}
/* buffer audio sink: to terminate the filter chain. */
ret = avfilter_graph_create_filter(&buffersink_ctx, abuffersink, "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_int_list(buffersink_ctx, "sample_fmts", out_sample_fmts, -1,
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_int_list(buffersink_ctx, "channel_layouts", out_channel_layouts, -1,
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_int_list(buffersink_ctx, "sample_rates", out_sample_rates, -1,
AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\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->filter_ctx = buffersrc_ctx;
outputs->pad_idx = 0;
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->filter_ctx = buffersink_ctx;
inputs->pad_idx = 0;
inputs->next = NULL;
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
&inputs, &outputs, NULL)) < 0)
goto end;
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
goto end;
/* Print summary of the sink buffer
* Note: args buffer is reused to store channel layout string */
outlink = buffersink_ctx->inputs[0];
av_get_channel_layout_string(args, sizeof(args), -1, outlink->channel_layout);
av_log(NULL, AV_LOG_INFO, "Output: srate:%dHz fmt:%s chlayout:%s\n",
(int)outlink->sample_rate,
(char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"),
args);
end:
avfilter_inout_free(&inputs);
avfilter_inout_free(&outputs);
return ret;
}
static void print_frame(const AVFrame *frame)
{
const int n = frame->nb_samples * av_get_channel_layout_nb_channels(av_frame_get_channel_layout(frame));
const uint16_t *p = (uint16_t*)frame->data[0];
const uint16_t *p_end = p + n;
while (p < p_end) {
fputc(*p & 0xff, stdout);
fputc(*p>>8 & 0xff, stdout);
p++;
}
fflush(stdout);
}
int main(int argc, char **argv)
{
int ret;
AVPacket packet0, packet;
AVFrame *frame = av_frame_alloc();
AVFrame *filt_frame = av_frame_alloc();
int got_frame;
if (!frame || !filt_frame) {
perror("Could not allocate frame");
exit(1);
}
if (argc != 2) {
fprintf(stderr, "Usage: %s file | %s\n", argv[0], player);
exit(1);
}
av_register_all();
avfilter_register_all();
if ((ret = open_input_file(argv[1])) < 0)
goto end;
if ((ret = init_filters(filter_descr)) < 0)
goto end;
/* read all packets */
packet0.data = NULL;
packet.data = NULL;
while (1) {
if (!packet0.data) {
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
break;
packet0 = packet;
}
if (packet.stream_index == audio_stream_index) {
got_frame = 0;
ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, &packet);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error decoding audio\n");
continue;
}
packet.size -= ret;
packet.data += ret;
if (got_frame) {
/* push the audio data from decoded frame into the filtergraph */
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, 0) < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n");
break;
}
/* pull filtered audio from the filtergraph */
while (1) {
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
if (ret < 0)
goto end;
print_frame(filt_frame);
av_frame_unref(filt_frame);
}
}
if (packet.size <= 0)
av_free_packet(&packet0);
} else {
/* discard non-wanted packets */
av_free_packet(&packet0);
}
}
end:
avfilter_graph_free(&filter_graph);
avcodec_close(dec_ctx);
avformat_close_input(&fmt_ctx);
av_frame_free(&frame);
av_frame_free(&filt_frame);
if (ret < 0 && ret != AVERROR_EOF) {
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
exit(1);
}
exit(0);
}

View File

@@ -0,0 +1,278 @@
/*
* Copyright (c) 2010 Nicolas George
* Copyright (c) 2011 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
* API example for decoding and filtering
* @example filtering_video.c
*/
#define _XOPEN_SOURCE 600 /* for usleep */
#include <unistd.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/avfiltergraph.h>
#include <libavfilter/avcodec.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/opt.h>
const char *filter_descr = "scale=78:24";
static AVFormatContext *fmt_ctx;
static AVCodecContext *dec_ctx;
AVFilterContext *buffersink_ctx;
AVFilterContext *buffersrc_ctx;
AVFilterGraph *filter_graph;
static int video_stream_index = -1;
static int64_t last_pts = AV_NOPTS_VALUE;
static int open_input_file(const char *filename)
{
int ret;
AVCodec *dec;
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
return ret;
}
if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
return ret;
}
/* select the video stream */
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot find a video stream in the input file\n");
return ret;
}
video_stream_index = ret;
dec_ctx = fmt_ctx->streams[video_stream_index]->codec;
av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);
/* init the video decoder */
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open video decoder\n");
return ret;
}
return 0;
}
static int init_filters(const char *filters_descr)
{
char args[512];
int ret = 0;
AVFilter *buffersrc = avfilter_get_by_name("buffer");
AVFilter *buffersink = avfilter_get_by_name("buffersink");
AVFilterInOut *outputs = 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 };
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. */
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,
time_base.num, 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;
}
/* buffer video sink: to terminate the filter chain. */
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_int_list(buffersink_ctx, "pix_fmts", pix_fmts,
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->filter_ctx = buffersrc_ctx;
outputs->pad_idx = 0;
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->filter_ctx = buffersink_ctx;
inputs->pad_idx = 0;
inputs->next = NULL;
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
&inputs, &outputs, NULL)) < 0)
goto end;
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
goto end;
end:
avfilter_inout_free(&inputs);
avfilter_inout_free(&outputs);
return ret;
}
static void display_frame(const AVFrame *frame, AVRational time_base)
{
int x, y;
uint8_t *p0, *p;
int64_t delay;
if (frame->pts != AV_NOPTS_VALUE) {
if (last_pts != AV_NOPTS_VALUE) {
/* sleep roughly the right amount of time;
* usleep is in microseconds, just like AV_TIME_BASE. */
delay = av_rescale_q(frame->pts - last_pts,
time_base, AV_TIME_BASE_Q);
if (delay > 0 && delay < 1000000)
usleep(delay);
}
last_pts = frame->pts;
}
/* Trivial ASCII grayscale display. */
p0 = frame->data[0];
puts("\033c");
for (y = 0; y < frame->height; y++) {
p = p0;
for (x = 0; x < frame->width; x++)
putchar(" .-+#"[*(p++) / 52]);
putchar('\n');
p0 += frame->linesize[0];
}
fflush(stdout);
}
int main(int argc, char **argv)
{
int ret;
AVPacket packet;
AVFrame *frame = av_frame_alloc();
AVFrame *filt_frame = av_frame_alloc();
int got_frame;
if (!frame || !filt_frame) {
perror("Could not allocate frame");
exit(1);
}
if (argc != 2) {
fprintf(stderr, "Usage: %s file\n", argv[0]);
exit(1);
}
av_register_all();
avfilter_register_all();
if ((ret = open_input_file(argv[1])) < 0)
goto end;
if ((ret = init_filters(filter_descr)) < 0)
goto end;
/* read all packets */
while (1) {
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
break;
if (packet.stream_index == video_stream_index) {
got_frame = 0;
ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, &packet);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error decoding video\n");
break;
}
if (got_frame) {
frame->pts = av_frame_get_best_effort_timestamp(frame);
/* push the decoded frame into the filtergraph */
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
break;
}
/* pull filtered frames from the filtergraph */
while (1) {
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
if (ret < 0)
goto end;
display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
av_frame_unref(filt_frame);
}
av_frame_unref(frame);
}
}
av_free_packet(&packet);
}
end:
avfilter_graph_free(&filter_graph);
avcodec_close(dec_ctx);
avformat_close_input(&fmt_ctx);
av_frame_free(&frame);
av_frame_free(&filt_frame);
if (ret < 0 && ret != AVERROR_EOF) {
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
exit(1);
}
exit(0);
}

View File

@@ -1,256 +0,0 @@
/*
* Copyright (c) 2017 Jun Zhao
* Copyright (c) 2017 Kaixuan Liu
*
* HW Acceleration API (video decoding) decode sample
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @file HW-accelerated decoding API usage.example
* @example hw_decode.c
*
* Perform HW-accelerated decoding with output frames from HW video
* surfaces.
*/
#include <stdio.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/mem.h>
#include <libavutil/pixdesc.h>
#include <libavutil/hwcontext.h>
#include <libavutil/opt.h>
#include <libavutil/avassert.h>
#include <libavutil/imgutils.h>
static AVBufferRef *hw_device_ctx = NULL;
static enum AVPixelFormat hw_pix_fmt;
static FILE *output_file = NULL;
static int hw_decoder_init(AVCodecContext *ctx, const enum AVHWDeviceType type)
{
int err = 0;
if ((err = av_hwdevice_ctx_create(&hw_device_ctx, type,
NULL, NULL, 0)) < 0) {
fprintf(stderr, "Failed to create specified HW device.\n");
return err;
}
ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
return err;
}
static enum AVPixelFormat get_hw_format(AVCodecContext *ctx,
const enum AVPixelFormat *pix_fmts)
{
const enum AVPixelFormat *p;
for (p = pix_fmts; *p != -1; p++) {
if (*p == hw_pix_fmt)
return *p;
}
fprintf(stderr, "Failed to get HW surface format.\n");
return AV_PIX_FMT_NONE;
}
static int decode_write(AVCodecContext *avctx, AVPacket *packet)
{
AVFrame *frame = NULL, *sw_frame = NULL;
AVFrame *tmp_frame = NULL;
uint8_t *buffer = NULL;
int size;
int ret = 0;
ret = avcodec_send_packet(avctx, packet);
if (ret < 0) {
fprintf(stderr, "Error during decoding\n");
return ret;
}
while (1) {
if (!(frame = av_frame_alloc()) || !(sw_frame = av_frame_alloc())) {
fprintf(stderr, "Can not alloc frame\n");
ret = AVERROR(ENOMEM);
goto fail;
}
ret = avcodec_receive_frame(avctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
av_frame_free(&frame);
av_frame_free(&sw_frame);
return 0;
} else if (ret < 0) {
fprintf(stderr, "Error while decoding\n");
goto fail;
}
if (frame->format == hw_pix_fmt) {
/* retrieve data from GPU to CPU */
if ((ret = av_hwframe_transfer_data(sw_frame, frame, 0)) < 0) {
fprintf(stderr, "Error transferring the data to system memory\n");
goto fail;
}
tmp_frame = sw_frame;
} else
tmp_frame = frame;
size = av_image_get_buffer_size(tmp_frame->format, tmp_frame->width,
tmp_frame->height, 1);
buffer = av_malloc(size);
if (!buffer) {
fprintf(stderr, "Can not alloc buffer\n");
ret = AVERROR(ENOMEM);
goto fail;
}
ret = av_image_copy_to_buffer(buffer, size,
(const uint8_t * const *)tmp_frame->data,
(const int *)tmp_frame->linesize, tmp_frame->format,
tmp_frame->width, tmp_frame->height, 1);
if (ret < 0) {
fprintf(stderr, "Can not copy image to buffer\n");
goto fail;
}
if ((ret = fwrite(buffer, 1, size, output_file)) < 0) {
fprintf(stderr, "Failed to dump raw data.\n");
goto fail;
}
fail:
av_frame_free(&frame);
av_frame_free(&sw_frame);
av_freep(&buffer);
if (ret < 0)
return ret;
}
}
int main(int argc, char *argv[])
{
AVFormatContext *input_ctx = NULL;
int video_stream, ret;
AVStream *video = NULL;
AVCodecContext *decoder_ctx = NULL;
const AVCodec *decoder = NULL;
AVPacket *packet = NULL;
enum AVHWDeviceType type;
int i;
if (argc < 4) {
fprintf(stderr, "Usage: %s <device type> <input file> <output file>\n", argv[0]);
return -1;
}
type = av_hwdevice_find_type_by_name(argv[1]);
if (type == AV_HWDEVICE_TYPE_NONE) {
fprintf(stderr, "Device type %s is not supported.\n", argv[1]);
fprintf(stderr, "Available device types:");
while((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE)
fprintf(stderr, " %s", av_hwdevice_get_type_name(type));
fprintf(stderr, "\n");
return -1;
}
packet = av_packet_alloc();
if (!packet) {
fprintf(stderr, "Failed to allocate AVPacket\n");
return -1;
}
/* open the input file */
if (avformat_open_input(&input_ctx, argv[2], NULL, NULL) != 0) {
fprintf(stderr, "Cannot open input file '%s'\n", argv[2]);
return -1;
}
if (avformat_find_stream_info(input_ctx, NULL) < 0) {
fprintf(stderr, "Cannot find input stream information.\n");
return -1;
}
/* find the video stream information */
ret = av_find_best_stream(input_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
if (ret < 0) {
fprintf(stderr, "Cannot find a video stream in the input file\n");
return -1;
}
video_stream = ret;
for (i = 0;; i++) {
const AVCodecHWConfig *config = avcodec_get_hw_config(decoder, i);
if (!config) {
fprintf(stderr, "Decoder %s does not support device type %s.\n",
decoder->name, av_hwdevice_get_type_name(type));
return -1;
}
if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
config->device_type == type) {
hw_pix_fmt = config->pix_fmt;
break;
}
}
if (!(decoder_ctx = avcodec_alloc_context3(decoder)))
return AVERROR(ENOMEM);
video = input_ctx->streams[video_stream];
if (avcodec_parameters_to_context(decoder_ctx, video->codecpar) < 0)
return -1;
decoder_ctx->get_format = get_hw_format;
if (hw_decoder_init(decoder_ctx, type) < 0)
return -1;
if ((ret = avcodec_open2(decoder_ctx, decoder, NULL)) < 0) {
fprintf(stderr, "Failed to open codec for stream #%u\n", video_stream);
return -1;
}
/* open the file to dump raw data */
output_file = fopen(argv[3], "w+b");
/* actual decoding and dump the raw data */
while (ret >= 0) {
if ((ret = av_read_frame(input_ctx, packet)) < 0)
break;
if (video_stream == packet->stream_index)
ret = decode_write(decoder_ctx, packet);
av_packet_unref(packet);
}
/* flush the decoder */
ret = decode_write(decoder_ctx, NULL);
if (output_file)
fclose(output_file);
av_packet_free(&packet);
avcodec_free_context(&decoder_ctx);
avformat_close_input(&input_ctx);
av_buffer_unref(&hw_device_ctx);
return 0;
}

56
doc/examples/metadata.c Normal file
View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2011 Reinhard Tartler
*
* 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
* Shows how the metadata API can be used in application programs.
* @example metadata.c
*/
#include <stdio.h>
#include <libavformat/avformat.h>
#include <libavutil/dict.h>
int main (int argc, char **argv)
{
AVFormatContext *fmt_ctx = NULL;
AVDictionaryEntry *tag = NULL;
int ret;
if (argc != 2) {
printf("usage: %s <input_file>\n"
"example program to demonstrate the use of the libavformat metadata API.\n"
"\n", argv[0]);
return 1;
}
av_register_all();
if ((ret = avformat_open_input(&fmt_ctx, argv[1], NULL, NULL)))
return ret;
while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
printf("%s=%s\n", tag->key, tag->value);
avformat_close_input(&fmt_ctx);
return 0;
}

View File

@@ -1,643 +0,0 @@
/*
* Copyright (c) 2003 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @file libavformat muxing API usage example
* @example mux.c
*
* Generate a synthetic audio and video signal and mux them to a media file in
* any supported libavformat format. The default codecs are used.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <libavutil/avassert.h>
#include <libavutil/channel_layout.h>
#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
#include <libavutil/timestamp.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libswresample/swresample.h>
#define STREAM_DURATION 10.0
#define STREAM_FRAME_RATE 25 /* 25 images/s */
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
#define SCALE_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;
AVPacket *tmp_pkt;
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, AVCodecContext *c,
AVStream *st, AVFrame *frame, AVPacket *pkt)
{
int ret;
// send the frame to the encoder
ret = avcodec_send_frame(c, frame);
if (ret < 0) {
fprintf(stderr, "Error sending a frame to the encoder: %s\n",
av_err2str(ret));
exit(1);
}
while (ret >= 0) {
ret = avcodec_receive_packet(c, pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
else if (ret < 0) {
fprintf(stderr, "Error encoding a frame: %s\n", av_err2str(ret));
exit(1);
}
/* rescale output packet timestamp values from codec to stream timebase */
av_packet_rescale_ts(pkt, c->time_base, st->time_base);
pkt->stream_index = st->index;
/* Write the compressed frame to the media file. */
log_packet(fmt_ctx, pkt);
ret = av_interleaved_write_frame(fmt_ctx, pkt);
/* pkt is now blank (av_interleaved_write_frame() takes ownership of
* its contents and resets pkt), so that no unreferencing is necessary.
* This would be different if one used av_write_frame(). */
if (ret < 0) {
fprintf(stderr, "Error while writing output packet: %s\n", av_err2str(ret));
exit(1);
}
}
return ret == AVERROR_EOF ? 1 : 0;
}
/* Add an output stream. */
static void add_stream(OutputStream *ost, AVFormatContext *oc,
const AVCodec **codec,
enum AVCodecID codec_id)
{
AVCodecContext *c;
int i;
/* find the encoder */
*codec = avcodec_find_encoder(codec_id);
if (!(*codec)) {
fprintf(stderr, "Could not find encoder for '%s'\n",
avcodec_get_name(codec_id));
exit(1);
}
ost->tmp_pkt = av_packet_alloc();
if (!ost->tmp_pkt) {
fprintf(stderr, "Could not allocate AVPacket\n");
exit(1);
}
ost->st = avformat_new_stream(oc, NULL);
if (!ost->st) {
fprintf(stderr, "Could not allocate stream\n");
exit(1);
}
ost->st->id = oc->nb_streams-1;
c = avcodec_alloc_context3(*codec);
if (!c) {
fprintf(stderr, "Could not alloc an encoding context\n");
exit(1);
}
ost->enc = c;
switch ((*codec)->type) {
case AVMEDIA_TYPE_AUDIO:
c->sample_fmt = (*codec)->sample_fmts ?
(*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
c->bit_rate = 64000;
c->sample_rate = 44100;
if ((*codec)->supported_samplerates) {
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;
}
}
av_channel_layout_copy(&c->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO);
ost->st->time_base = (AVRational){ 1, c->sample_rate };
break;
case AVMEDIA_TYPE_VIDEO:
c->codec_id = codec_id;
c->bit_rate = 400000;
/* Resolution must be a multiple of two. */
c->width = 352;
c->height = 288;
/* timebase: This is the fundamental unit of time (in seconds) in terms
* of which frame timestamps are represented. For fixed-fps content,
* timebase should be 1/framerate and timestamp increments should be
* identical to 1. */
ost->st->time_base = (AVRational){ 1, STREAM_FRAME_RATE };
c->time_base = ost->st->time_base;
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
c->pix_fmt = STREAM_PIX_FMT;
if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
/* just for testing, we also add B-frames */
c->max_b_frames = 2;
}
if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
/* Needed to avoid using macroblocks in which some coeffs overflow.
* This does not happen with normal video, it just happens here as
* the motion of the chroma plane does not match the luma plane. */
c->mb_decision = 2;
}
break;
default:
break;
}
/* Some formats want stream headers to be separate. */
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
/**************************************************************/
/* audio output */
static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
const AVChannelLayout *channel_layout,
int sample_rate, int nb_samples)
{
AVFrame *frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Error allocating an audio frame\n");
exit(1);
}
frame->format = sample_fmt;
av_channel_layout_copy(&frame->ch_layout, channel_layout);
frame->sample_rate = sample_rate;
frame->nb_samples = nb_samples;
if (nb_samples) {
if (av_frame_get_buffer(frame, 0) < 0) {
fprintf(stderr, "Error allocating an audio buffer\n");
exit(1);
}
}
return frame;
}
static void open_audio(AVFormatContext *oc, const AVCodec *codec,
OutputStream *ost, AVDictionary *opt_arg)
{
AVCodecContext *c;
int nb_samples;
int ret;
AVDictionary *opt = NULL;
c = ost->enc;
/* open it */
av_dict_copy(&opt, opt_arg, 0);
ret = avcodec_open2(c, codec, &opt);
av_dict_free(&opt);
if (ret < 0) {
fprintf(stderr, "Could not open audio codec: %s\n", av_err2str(ret));
exit(1);
}
/* init signal generator */
ost->t = 0;
ost->tincr = 2 * M_PI * 110.0 / c->sample_rate;
/* increment frequency by 110 Hz per second */
ost->tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
if (c->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
nb_samples = 10000;
else
nb_samples = c->frame_size;
ost->frame = alloc_audio_frame(c->sample_fmt, &c->ch_layout,
c->sample_rate, nb_samples);
ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, &c->ch_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) {
fprintf(stderr, "Could not copy the stream parameters\n");
exit(1);
}
/* create resampler context */
ost->swr_ctx = swr_alloc();
if (!ost->swr_ctx) {
fprintf(stderr, "Could not allocate resampler context\n");
exit(1);
}
/* set options */
av_opt_set_chlayout (ost->swr_ctx, "in_chlayout", &c->ch_layout, 0);
av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
av_opt_set_chlayout (ost->swr_ctx, "out_chlayout", &c->ch_layout, 0);
av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
/* initialize the resampling context */
if ((ret = swr_init(ost->swr_ctx)) < 0) {
fprintf(stderr, "Failed to initialize the resampling context\n");
exit(1);
}
}
/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
* 'nb_channels' channels. */
static AVFrame *get_audio_frame(OutputStream *ost)
{
AVFrame *frame = ost->tmp_frame;
int j, i, v;
int16_t *q = (int16_t*)frame->data[0];
/* check if we want to generate more frames */
if (av_compare_ts(ost->next_pts, ost->enc->time_base,
STREAM_DURATION, (AVRational){ 1, 1 }) > 0)
return NULL;
for (j = 0; j <frame->nb_samples; j++) {
v = (int)(sin(ost->t) * 10000);
for (i = 0; i < ost->enc->ch_layout.nb_channels; i++)
*q++ = v;
ost->t += ost->tincr;
ost->tincr += ost->tincr2;
}
frame->pts = ost->next_pts;
ost->next_pts += frame->nb_samples;
return frame;
}
/*
* 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;
AVFrame *frame;
int ret;
int dst_nb_samples;
c = ost->enc;
frame = get_audio_frame(ost);
if (frame) {
/* convert samples from native format to destination codec format, using the resampler */
/* compute destination number of samples */
dst_nb_samples = swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples;
av_assert0(dst_nb_samples == frame->nb_samples);
/* when we pass a frame to the encoder, it may keep a reference to it
* internally;
* make sure we do not overwrite it here
*/
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);
}
frame = ost->frame;
frame->pts = av_rescale_q(ost->samples_count, (AVRational){1, c->sample_rate}, c->time_base);
ost->samples_count += dst_nb_samples;
}
return write_frame(oc, c, ost->st, frame, ost->tmp_pkt);
}
/**************************************************************/
/* video output */
static AVFrame *alloc_frame(enum AVPixelFormat pix_fmt, int width, int height)
{
AVFrame *frame;
int ret;
frame = av_frame_alloc();
if (!frame)
return NULL;
frame->format = pix_fmt;
frame->width = width;
frame->height = height;
/* allocate the buffers for the frame data */
ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {
fprintf(stderr, "Could not allocate frame data.\n");
exit(1);
}
return frame;
}
static void open_video(AVFormatContext *oc, const AVCodec *codec,
OutputStream *ost, AVDictionary *opt_arg)
{
int ret;
AVCodecContext *c = ost->enc;
AVDictionary *opt = NULL;
av_dict_copy(&opt, opt_arg, 0);
/* open the codec */
ret = avcodec_open2(c, codec, &opt);
av_dict_free(&opt);
if (ret < 0) {
fprintf(stderr, "Could not open video codec: %s\n", av_err2str(ret));
exit(1);
}
/* allocate and init a re-usable frame */
ost->frame = alloc_frame(c->pix_fmt, c->width, c->height);
if (!ost->frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(1);
}
/* If the output format is not YUV420P, then a temporary YUV420P
* picture is needed too. It is then converted to the required
* output format. */
ost->tmp_frame = NULL;
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
ost->tmp_frame = alloc_frame(AV_PIX_FMT_YUV420P, c->width, c->height);
if (!ost->tmp_frame) {
fprintf(stderr, "Could not allocate temporary video frame\n");
exit(1);
}
}
/* copy the stream parameters to the muxer */
ret = avcodec_parameters_from_context(ost->st->codecpar, c);
if (ret < 0) {
fprintf(stderr, "Could not copy the stream parameters\n");
exit(1);
}
}
/* Prepare a dummy image. */
static void fill_yuv_image(AVFrame *pict, int frame_index,
int width, int height)
{
int x, y, i;
i = frame_index;
/* Y */
for (y = 0; y < height; y++)
for (x = 0; x < width; x++)
pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;
/* Cb and Cr */
for (y = 0; y < height / 2; y++) {
for (x = 0; x < width / 2; x++) {
pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5;
}
}
}
static AVFrame *get_video_frame(OutputStream *ost)
{
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;
/* when we pass a frame to the encoder, it may keep a reference to it
* internally; make sure we do not overwrite it here */
if (av_frame_make_writable(ost->frame) < 0)
exit(1);
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
/* 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)
{
return write_frame(oc, ost->enc, ost->st, get_video_frame(ost), ost->tmp_pkt);
}
static void close_stream(AVFormatContext *oc, OutputStream *ost)
{
avcodec_free_context(&ost->enc);
av_frame_free(&ost->frame);
av_frame_free(&ost->tmp_frame);
av_packet_free(&ost->tmp_pkt);
sws_freeContext(ost->sws_ctx);
swr_free(&ost->swr_ctx);
}
/**************************************************************/
/* media file output */
int main(int argc, char **argv)
{
OutputStream video_st = { 0 }, audio_st = { 0 };
const AVOutputFormat *fmt;
const char *filename;
AVFormatContext *oc;
const AVCodec *audio_codec, *video_codec;
int ret;
int have_video = 0, have_audio = 0;
int encode_video = 0, encode_audio = 0;
AVDictionary *opt = NULL;
int i;
if (argc < 2) {
printf("usage: %s output_file\n"
"API example program to output a media file with libavformat.\n"
"This program generates a synthetic audio and video stream, encodes and\n"
"muxes them into a file named output_file.\n"
"The output format is automatically guessed according to the file extension.\n"
"Raw images can also be output by using '%%d' in the filename.\n"
"\n", argv[0]);
return 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 */
avformat_alloc_output_context2(&oc, NULL, NULL, filename);
if (!oc) {
printf("Could not deduce output format from file extension: using MPEG.\n");
avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
}
if (!oc)
return 1;
fmt = oc->oformat;
/* Add the audio and video streams using the default format codecs
* and initialize the codecs. */
if (fmt->video_codec != AV_CODEC_ID_NONE) {
add_stream(&video_st, oc, &video_codec, fmt->video_codec);
have_video = 1;
encode_video = 1;
}
if (fmt->audio_codec != AV_CODEC_ID_NONE) {
add_stream(&audio_st, 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
* video codecs and allocate the necessary encode buffers. */
if (have_video)
open_video(oc, video_codec, &video_st, opt);
if (have_audio)
open_audio(oc, audio_codec, &audio_st, opt);
av_dump_format(oc, 0, filename, 1);
/* open the output file, if needed */
if (!(fmt->flags & AVFMT_NOFILE)) {
ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);
if (ret < 0) {
fprintf(stderr, "Could not open '%s': %s\n", filename,
av_err2str(ret));
return 1;
}
}
/* Write the stream header, if any. */
ret = avformat_write_header(oc, &opt);
if (ret < 0) {
fprintf(stderr, "Error occurred when opening output file: %s\n",
av_err2str(ret));
return 1;
}
while (encode_video || encode_audio) {
/* select the stream to encode */
if (encode_video &&
(!encode_audio || av_compare_ts(video_st.next_pts, video_st.enc->time_base,
audio_st.next_pts, audio_st.enc->time_base) <= 0)) {
encode_video = !write_video_frame(oc, &video_st);
} else {
encode_audio = !write_audio_frame(oc, &audio_st);
}
}
av_write_trailer(oc);
/* Close each codec. */
if (have_video)
close_stream(oc, &video_st);
if (have_audio)
close_stream(oc, &audio_st);
if (!(fmt->flags & AVFMT_NOFILE))
/* Close the output file. */
avio_closep(&oc->pb);
/* free the stream */
avformat_free_context(oc);
return 0;
}

670
doc/examples/muxing.c Normal file
View File

@@ -0,0 +1,670 @@
/*
* Copyright (c) 2003 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @file
* libavformat API example.
*
* Output a media file in any supported libavformat format. The default
* codecs are used.
* @example muxing.c
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <libavutil/avassert.h>
#include <libavutil/channel_layout.h>
#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libswresample/swresample.h>
#define STREAM_DURATION 10.0
#define STREAM_FRAME_RATE 25 /* 25 images/s */
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
#define SCALE_FLAGS SWS_BICUBIC
// a wrapper around a single output AVStream
typedef struct OutputStream {
AVStream *st;
/* 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. */
static void add_stream(OutputStream *ost, AVFormatContext *oc,
AVCodec **codec,
enum AVCodecID codec_id)
{
AVCodecContext *c;
int i;
/* find the encoder */
*codec = avcodec_find_encoder(codec_id);
if (!(*codec)) {
fprintf(stderr, "Could not find encoder for '%s'\n",
avcodec_get_name(codec_id));
exit(1);
}
ost->st = avformat_new_stream(oc, *codec);
if (!ost->st) {
fprintf(stderr, "Could not allocate stream\n");
exit(1);
}
ost->st->id = oc->nb_streams-1;
c = ost->st->codec;
switch ((*codec)->type) {
case AVMEDIA_TYPE_AUDIO:
c->sample_fmt = (*codec)->sample_fmts ?
(*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
c->bit_rate = 64000;
c->sample_rate = 44100;
if ((*codec)->supported_samplerates) {
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;
case AVMEDIA_TYPE_VIDEO:
c->codec_id = codec_id;
c->bit_rate = 400000;
/* Resolution must be a multiple of two. */
c->width = 352;
c->height = 288;
/* timebase: This is the fundamental unit of time (in seconds) in terms
* of which frame timestamps are represented. For fixed-fps content,
* timebase should be 1/framerate and timestamp increments should be
* identical to 1. */
ost->st->time_base = (AVRational){ 1, STREAM_FRAME_RATE };
c->time_base = ost->st->time_base;
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
c->pix_fmt = STREAM_PIX_FMT;
if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
/* just for testing, we also add B frames */
c->max_b_frames = 2;
}
if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
/* Needed to avoid using macroblocks in which some coeffs overflow.
* This does not happen with normal video, it just happens here as
* the motion of the chroma plane does not match the luma plane. */
c->mb_decision = 2;
}
break;
default:
break;
}
/* Some formats want stream headers to be separate. */
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
/**************************************************************/
/* audio output */
static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
uint64_t channel_layout,
int sample_rate, int nb_samples)
{
AVFrame *frame = av_frame_alloc();
int ret;
if (!frame) {
fprintf(stderr, "Error allocating an audio frame\n");
exit(1);
}
frame->format = sample_fmt;
frame->channel_layout = channel_layout;
frame->sample_rate = sample_rate;
frame->nb_samples = nb_samples;
if (nb_samples) {
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, OutputStream *ost, AVDictionary *opt_arg)
{
AVCodecContext *c;
int nb_samples;
int ret;
AVDictionary *opt = NULL;
c = ost->st->codec;
/* open it */
av_dict_copy(&opt, opt_arg, 0);
ret = avcodec_open2(c, codec, &opt);
av_dict_free(&opt);
if (ret < 0) {
fprintf(stderr, "Could not open audio codec: %s\n", av_err2str(ret));
exit(1);
}
/* init signal generator */
ost->t = 0;
ost->tincr = 2 * M_PI * 110.0 / c->sample_rate;
/* increment frequency by 110 Hz per second */
ost->tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
if (c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
nb_samples = 10000;
else
nb_samples = c->frame_size;
ost->frame = alloc_audio_frame(c->sample_fmt, c->channel_layout,
c->sample_rate, nb_samples);
ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, c->channel_layout,
c->sample_rate, nb_samples);
/* create resampler context */
ost->swr_ctx = swr_alloc();
if (!ost->swr_ctx) {
fprintf(stderr, "Could not allocate resampler context\n");
exit(1);
}
/* set options */
av_opt_set_int (ost->swr_ctx, "in_channel_count", c->channels, 0);
av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
av_opt_set_int (ost->swr_ctx, "out_channel_count", c->channels, 0);
av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
/* initialize the resampling context */
if ((ret = swr_init(ost->swr_ctx)) < 0) {
fprintf(stderr, "Failed to initialize the resampling context\n");
exit(1);
}
}
/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
* 'nb_channels' channels. */
static AVFrame *get_audio_frame(OutputStream *ost)
{
AVFrame *frame = ost->tmp_frame;
int j, i, v;
int16_t *q = (int16_t*)frame->data[0];
/* check if we want to generate more frames */
if (av_compare_ts(ost->next_pts, ost->st->codec->time_base,
STREAM_DURATION, (AVRational){ 1, 1 }) >= 0)
return NULL;
for (j = 0; j <frame->nb_samples; j++) {
v = (int)(sin(ost->t) * 10000);
for (i = 0; i < ost->st->codec->channels; i++)
*q++ = v;
ost->t += ost->tincr;
ost->tincr += ost->tincr2;
}
frame->pts = ost->next_pts;
ost->next_pts += frame->nb_samples;
return frame;
}
/*
* 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;
AVPacket pkt = { 0 }; // data and size must be 0;
AVFrame *frame;
int ret;
int got_packet;
int dst_nb_samples;
av_init_packet(&pkt);
c = ost->st->codec;
frame = get_audio_frame(ost);
if (frame) {
/* convert samples from native format to destination codec format, using the resampler */
/* compute destination number of samples */
dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples,
c->sample_rate, c->sample_rate, AV_ROUND_UP);
av_assert0(dst_nb_samples == frame->nb_samples);
/* 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(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);
}
frame = ost->frame;
frame->pts = av_rescale_q(ost->samples_count, (AVRational){1, c->sample_rate}, c->time_base);
ost->samples_count += dst_nb_samples;
}
ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet);
if (ret < 0) {
fprintf(stderr, "Error encoding audio frame: %s\n", av_err2str(ret));
exit(1);
}
if (got_packet) {
ret = write_frame(oc, &c->time_base, ost->st, &pkt);
if (ret < 0) {
fprintf(stderr, "Error while writing audio frame: %s\n",
av_err2str(ret));
exit(1);
}
}
return (frame || got_packet) ? 0 : 1;
}
/**************************************************************/
/* video output */
static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
{
AVFrame *picture;
int ret;
picture = av_frame_alloc();
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;
AVCodecContext *c = ost->st->codec;
AVDictionary *opt = NULL;
av_dict_copy(&opt, opt_arg, 0);
/* open the codec */
ret = avcodec_open2(c, codec, &opt);
av_dict_free(&opt);
if (ret < 0) {
fprintf(stderr, "Could not open video codec: %s\n", av_err2str(ret));
exit(1);
}
/* allocate and init a re-usable frame */
ost->frame = alloc_picture(c->pix_fmt, c->width, c->height);
if (!ost->frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(1);
}
/* If the output format is not YUV420P, then a temporary YUV420P
* picture is needed too. It is then converted to the required
* output format. */
ost->tmp_frame = NULL;
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
ost->tmp_frame = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);
if (!ost->tmp_frame) {
fprintf(stderr, "Could not allocate temporary picture\n");
exit(1);
}
}
}
/* Prepare a dummy image. */
static void fill_yuv_image(AVFrame *pict, int frame_index,
int width, int height)
{
int x, y, i, ret;
/* when we pass a frame to the encoder, it may keep a reference to it
* internally;
* make sure we do not overwrite it here
*/
ret = av_frame_make_writable(pict);
if (ret < 0)
exit(1);
i = frame_index;
/* Y */
for (y = 0; y < height; y++)
for (x = 0; x < width; x++)
pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;
/* Cb and Cr */
for (y = 0; y < height / 2; y++) {
for (x = 0; x < width / 2; x++) {
pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5;
}
}
}
static AVFrame *get_video_frame(OutputStream *ost)
{
AVCodecContext *c = ost->st->codec;
/* check if we want to generate more frames */
if (av_compare_ts(ost->next_pts, ost->st->codec->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;
AVCodecContext *c;
AVFrame *frame;
int got_packet = 0;
c = ost->st->codec;
frame = get_video_frame(ost);
if (oc->oformat->flags & AVFMT_RAWPICTURE) {
/* a hack to avoid data copy with some raw video muxers */
AVPacket pkt;
av_init_packet(&pkt);
if (!frame)
return 1;
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.stream_index = ost->st->index;
pkt.data = (uint8_t *)frame;
pkt.size = sizeof(AVPicture);
pkt.pts = pkt.dts = frame->pts;
av_packet_rescale_ts(&pkt, c->time_base, ost->st->time_base);
ret = av_interleaved_write_frame(oc, &pkt);
} else {
AVPacket pkt = { 0 };
av_init_packet(&pkt);
/* encode the image */
ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
if (ret < 0) {
fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));
exit(1);
}
if (got_packet) {
ret = write_frame(oc, &c->time_base, ost->st, &pkt);
} else {
ret = 0;
}
}
if (ret < 0) {
fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
exit(1);
}
return (frame || got_packet) ? 0 : 1;
}
static void close_stream(AVFormatContext *oc, OutputStream *ost)
{
avcodec_close(ost->st->codec);
av_frame_free(&ost->frame);
av_frame_free(&ost->tmp_frame);
sws_freeContext(ost->sws_ctx);
swr_free(&ost->swr_ctx);
}
/**************************************************************/
/* media file output */
int main(int argc, char **argv)
{
OutputStream video_st = { 0 }, audio_st = { 0 };
const char *filename;
AVOutputFormat *fmt;
AVFormatContext *oc;
AVCodec *audio_codec, *video_codec;
int ret;
int have_video = 0, have_audio = 0;
int encode_video = 0, encode_audio = 0;
AVDictionary *opt = NULL;
/* Initialize libavcodec, and register all codecs and formats. */
av_register_all();
if (argc < 2) {
printf("usage: %s output_file\n"
"API example program to output a media file with libavformat.\n"
"This program generates a synthetic audio and video stream, encodes and\n"
"muxes them into a file named output_file.\n"
"The output format is automatically guessed according to the file extension.\n"
"Raw images can also be output by using '%%d' in the filename.\n"
"\n", argv[0]);
return 1;
}
filename = argv[1];
if (argc > 3 && !strcmp(argv[2], "-flags")) {
av_dict_set(&opt, argv[2]+1, argv[3], 0);
}
/* allocate the output media context */
avformat_alloc_output_context2(&oc, NULL, NULL, filename);
if (!oc) {
printf("Could not deduce output format from file extension: using MPEG.\n");
avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
}
if (!oc)
return 1;
fmt = oc->oformat;
/* Add the audio and video streams using the default format codecs
* and initialize the codecs. */
if (fmt->video_codec != AV_CODEC_ID_NONE) {
add_stream(&video_st, oc, &video_codec, fmt->video_codec);
have_video = 1;
encode_video = 1;
}
if (fmt->audio_codec != AV_CODEC_ID_NONE) {
add_stream(&audio_st, 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
* video codecs and allocate the necessary encode buffers. */
if (have_video)
open_video(oc, video_codec, &video_st, opt);
if (have_audio)
open_audio(oc, audio_codec, &audio_st, opt);
av_dump_format(oc, 0, filename, 1);
/* open the output file, if needed */
if (!(fmt->flags & AVFMT_NOFILE)) {
ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);
if (ret < 0) {
fprintf(stderr, "Could not open '%s': %s\n", filename,
av_err2str(ret));
return 1;
}
}
/* Write the stream header, if any. */
ret = avformat_write_header(oc, &opt);
if (ret < 0) {
fprintf(stderr, "Error occurred when opening output file: %s\n",
av_err2str(ret));
return 1;
}
while (encode_video || encode_audio) {
/* select the stream to encode */
if (encode_video &&
(!encode_audio || av_compare_ts(video_st.next_pts, video_st.st->codec->time_base,
audio_st.next_pts, audio_st.st->codec->time_base) <= 0)) {
encode_video = !write_video_frame(oc, &video_st);
} else {
encode_audio = !write_audio_frame(oc, &audio_st);
}
}
/* Write the trailer, if any. The trailer must be written before you
* close the CodecContexts open when you wrote the header; otherwise
* av_write_trailer() may try to use memory that was freed on
* av_codec_close(). */
av_write_trailer(oc);
/* Close each codec. */
if (have_video)
close_stream(oc, &video_st);
if (have_audio)
close_stream(oc, &audio_st);
if (!(fmt->flags & AVFMT_NOFILE))
/* Close the output file. */
avio_closep(&oc->pb);
/* free the stream */
avformat_free_context(oc);
return 0;
}

View File

@@ -1,241 +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 API usage example
* @example qsv_decode.c
*
* Perform QSV-accelerated H.264 decoding with output frames in the
* GPU video surfaces, write the decoded frames to an output file.
*/
#include <stdio.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
#include <libavcodec/avcodec.h>
#include <libavutil/buffer.h>
#include <libavutil/error.h>
#include <libavutil/hwcontext.h>
#include <libavutil/hwcontext_qsv.h>
#include <libavutil/mem.h>
static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
{
while (*pix_fmts != AV_PIX_FMT_NONE) {
if (*pix_fmts == AV_PIX_FMT_QSV) {
return AV_PIX_FMT_QSV;
}
pix_fmts++;
}
fprintf(stderr, "The QSV pixel format not offered in get_format()\n");
return AV_PIX_FMT_NONE;
}
static int decode_packet(AVCodecContext *decoder_ctx,
AVFrame *frame, AVFrame *sw_frame,
AVPacket *pkt, AVIOContext *output_ctx)
{
int ret = 0;
ret = avcodec_send_packet(decoder_ctx, pkt);
if (ret < 0) {
fprintf(stderr, "Error during decoding\n");
return ret;
}
while (ret >= 0) {
int i, j;
ret = avcodec_receive_frame(decoder_ctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
else if (ret < 0) {
fprintf(stderr, "Error during decoding\n");
return 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. */
ret = av_hwframe_transfer_data(sw_frame, frame, 0);
if (ret < 0) {
fprintf(stderr, "Error transferring the data to system memory\n");
goto fail;
}
for (i = 0; i < FF_ARRAY_ELEMS(sw_frame->data) && sw_frame->data[i]; i++)
for (j = 0; j < (sw_frame->height >> (i > 0)); j++)
avio_write(output_ctx, sw_frame->data[i] + j * sw_frame->linesize[i], sw_frame->width);
fail:
av_frame_unref(sw_frame);
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 = NULL;
AVFrame *frame = NULL, *sw_frame = NULL;
AVIOContext *output_ctx = NULL;
int ret, i;
AVBufferRef *device_ref = NULL;
if (argc < 3) {
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
return 1;
}
/* 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;
}
/* open the hardware device */
ret = av_hwdevice_ctx_create(&device_ref, AV_HWDEVICE_TYPE_QSV,
"auto", NULL, 0);
if (ret < 0) {
fprintf(stderr, "Cannot open the hardware device\n");
goto finish;
}
/* 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->hw_device_ctx = av_buffer_ref(device_ref);
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();
sw_frame = av_frame_alloc();
pkt = av_packet_alloc();
if (!frame || !sw_frame || !pkt) {
ret = AVERROR(ENOMEM);
goto finish;
}
/* actual decoding */
while (ret >= 0) {
ret = av_read_frame(input_ctx, pkt);
if (ret < 0)
break;
if (pkt->stream_index == video_st->index)
ret = decode_packet(decoder_ctx, frame, sw_frame, pkt, output_ctx);
av_packet_unref(pkt);
}
/* flush the decoder */
ret = decode_packet(decoder_ctx, frame, sw_frame, NULL, 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);
av_frame_free(&sw_frame);
av_packet_free(&pkt);
avcodec_free_context(&decoder_ctx);
av_buffer_unref(&device_ref);
avio_close(output_ctx);
return ret;
}

View File

@@ -1,436 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @file Intel QSV-accelerated video transcoding API usage example
* @example qsv_transcode.c
*
* Perform QSV-accelerated transcoding and show to dynamically change
* encoder's options.
*
* Usage: qsv_transcode input_stream codec output_stream initial option
* { frame_number new_option }
* e.g: - qsv_transcode input.mp4 h264_qsv output_h264.mp4 "g 60"
* - qsv_transcode input.mp4 hevc_qsv output_hevc.mp4 "g 60 async_depth 1"
* 100 "g 120"
* (initialize codec with gop_size 60 and change it to 120 after 100
* frames)
*/
#include <stdio.h>
#include <errno.h>
#include <libavutil/hwcontext.h>
#include <libavutil/mem.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
static AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
static AVBufferRef *hw_device_ctx = NULL;
static AVCodecContext *decoder_ctx = NULL, *encoder_ctx = NULL;
static int video_stream = -1;
typedef struct DynamicSetting {
int frame_number;
char* optstr;
} DynamicSetting;
static DynamicSetting *dynamic_setting;
static int setting_number;
static int current_setting_number;
static int str_to_dict(char* optstr, AVDictionary **opt)
{
char *key, *value;
if (strlen(optstr) == 0)
return 0;
key = strtok(optstr, " ");
if (key == NULL)
return AVERROR(EINVAL);
value = strtok(NULL, " ");
if (value == NULL)
return AVERROR(EINVAL);
av_dict_set(opt, key, value, 0);
do {
key = strtok(NULL, " ");
if (key == NULL)
return 0;
value = strtok(NULL, " ");
if (value == NULL)
return AVERROR(EINVAL);
av_dict_set(opt, key, value, 0);
} while(1);
}
static int dynamic_set_parameter(AVCodecContext *avctx)
{
AVDictionary *opts = NULL;
int ret = 0;
static int frame_number = 0;
frame_number++;
if (current_setting_number < setting_number &&
frame_number == dynamic_setting[current_setting_number].frame_number) {
AVDictionaryEntry *e = NULL;
ret = str_to_dict(dynamic_setting[current_setting_number++].optstr, &opts);
if (ret < 0) {
fprintf(stderr, "The dynamic parameter is wrong\n");
goto fail;
}
/* Set common option. The dictionary will be freed and replaced
* by a new one containing all options not found in common option list.
* Then this new dictionary is used to set private option. */
if ((ret = av_opt_set_dict(avctx, &opts)) < 0)
goto fail;
/* Set codec specific option */
if ((ret = av_opt_set_dict(avctx->priv_data, &opts)) < 0)
goto fail;
/* There is no "framerate" option in commom option list. Use "-r" to set
* framerate, which is compatible with ffmpeg commandline. The video is
* assumed to be average frame rate, so set time_base to 1/framerate. */
e = av_dict_get(opts, "r", NULL, 0);
if (e) {
avctx->framerate = av_d2q(atof(e->value), INT_MAX);
encoder_ctx->time_base = av_inv_q(encoder_ctx->framerate);
}
}
fail:
av_dict_free(&opts);
return ret;
}
static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
{
while (*pix_fmts != AV_PIX_FMT_NONE) {
if (*pix_fmts == AV_PIX_FMT_QSV) {
return AV_PIX_FMT_QSV;
}
pix_fmts++;
}
fprintf(stderr, "The QSV pixel format not offered in get_format()\n");
return AV_PIX_FMT_NONE;
}
static int open_input_file(char *filename)
{
int ret;
const AVCodec *decoder = NULL;
AVStream *video = NULL;
if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {
fprintf(stderr, "Cannot open input file '%s', Error code: %s\n",
filename, av_err2str(ret));
return ret;
}
if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
fprintf(stderr, "Cannot find input stream information. Error code: %s\n",
av_err2str(ret));
return ret;
}
ret = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
if (ret < 0) {
fprintf(stderr, "Cannot find a video stream in the input file. "
"Error code: %s\n", av_err2str(ret));
return ret;
}
video_stream = ret;
video = ifmt_ctx->streams[video_stream];
switch(video->codecpar->codec_id) {
case AV_CODEC_ID_H264:
decoder = avcodec_find_decoder_by_name("h264_qsv");
break;
case AV_CODEC_ID_HEVC:
decoder = avcodec_find_decoder_by_name("hevc_qsv");
break;
case AV_CODEC_ID_VP9:
decoder = avcodec_find_decoder_by_name("vp9_qsv");
break;
case AV_CODEC_ID_VP8:
decoder = avcodec_find_decoder_by_name("vp8_qsv");
break;
case AV_CODEC_ID_AV1:
decoder = avcodec_find_decoder_by_name("av1_qsv");
break;
case AV_CODEC_ID_MPEG2VIDEO:
decoder = avcodec_find_decoder_by_name("mpeg2_qsv");
break;
case AV_CODEC_ID_MJPEG:
decoder = avcodec_find_decoder_by_name("mjpeg_qsv");
break;
default:
fprintf(stderr, "Codec is not supportted by qsv\n");
return AVERROR(EINVAL);
}
if (!(decoder_ctx = avcodec_alloc_context3(decoder)))
return AVERROR(ENOMEM);
if ((ret = avcodec_parameters_to_context(decoder_ctx, video->codecpar)) < 0) {
fprintf(stderr, "avcodec_parameters_to_context error. Error code: %s\n",
av_err2str(ret));
return ret;
}
decoder_ctx->framerate = av_guess_frame_rate(ifmt_ctx, video, NULL);
decoder_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
if (!decoder_ctx->hw_device_ctx) {
fprintf(stderr, "A hardware device reference create failed.\n");
return AVERROR(ENOMEM);
}
decoder_ctx->get_format = get_format;
decoder_ctx->pkt_timebase = video->time_base;
if ((ret = avcodec_open2(decoder_ctx, decoder, NULL)) < 0)
fprintf(stderr, "Failed to open codec for decoding. Error code: %s\n",
av_err2str(ret));
return ret;
}
static int encode_write(AVPacket *enc_pkt, AVFrame *frame)
{
int ret = 0;
av_packet_unref(enc_pkt);
if((ret = dynamic_set_parameter(encoder_ctx)) < 0) {
fprintf(stderr, "Failed to set dynamic parameter. Error code: %s\n",
av_err2str(ret));
goto end;
}
if ((ret = avcodec_send_frame(encoder_ctx, frame)) < 0) {
fprintf(stderr, "Error during encoding. Error code: %s\n", av_err2str(ret));
goto end;
}
while (1) {
if (ret = avcodec_receive_packet(encoder_ctx, enc_pkt))
break;
enc_pkt->stream_index = 0;
av_packet_rescale_ts(enc_pkt, encoder_ctx->time_base,
ofmt_ctx->streams[0]->time_base);
if ((ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt)) < 0) {
fprintf(stderr, "Error during writing data to output file. "
"Error code: %s\n", av_err2str(ret));
return ret;
}
}
end:
if (ret == AVERROR_EOF)
return 0;
ret = ((ret == AVERROR(EAGAIN)) ? 0:-1);
return ret;
}
static int dec_enc(AVPacket *pkt, const AVCodec *enc_codec, char *optstr)
{
AVFrame *frame;
int ret = 0;
ret = avcodec_send_packet(decoder_ctx, pkt);
if (ret < 0) {
fprintf(stderr, "Error during decoding. Error code: %s\n", av_err2str(ret));
return ret;
}
while (ret >= 0) {
if (!(frame = av_frame_alloc()))
return AVERROR(ENOMEM);
ret = avcodec_receive_frame(decoder_ctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
av_frame_free(&frame);
return 0;
} else if (ret < 0) {
fprintf(stderr, "Error while decoding. Error code: %s\n", av_err2str(ret));
goto fail;
}
if (!encoder_ctx->hw_frames_ctx) {
AVDictionaryEntry *e = NULL;
AVDictionary *opts = NULL;
AVStream *ost;
/* we need to ref hw_frames_ctx of decoder to initialize encoder's codec.
Only after we get a decoded frame, can we obtain its hw_frames_ctx */
encoder_ctx->hw_frames_ctx = av_buffer_ref(decoder_ctx->hw_frames_ctx);
if (!encoder_ctx->hw_frames_ctx) {
ret = AVERROR(ENOMEM);
goto fail;
}
/* set AVCodecContext Parameters for encoder, here we keep them stay
* the same as decoder.
*/
encoder_ctx->time_base = av_inv_q(decoder_ctx->framerate);
encoder_ctx->pix_fmt = AV_PIX_FMT_QSV;
encoder_ctx->width = decoder_ctx->width;
encoder_ctx->height = decoder_ctx->height;
if ((ret = str_to_dict(optstr, &opts)) < 0) {
fprintf(stderr, "Failed to set encoding parameter.\n");
goto fail;
}
/* There is no "framerate" option in commom option list. Use "-r" to
* set framerate, which is compatible with ffmpeg commandline. The
* video is assumed to be average frame rate, so set time_base to
* 1/framerate. */
e = av_dict_get(opts, "r", NULL, 0);
if (e) {
encoder_ctx->framerate = av_d2q(atof(e->value), INT_MAX);
encoder_ctx->time_base = av_inv_q(encoder_ctx->framerate);
}
if ((ret = avcodec_open2(encoder_ctx, enc_codec, &opts)) < 0) {
fprintf(stderr, "Failed to open encode codec. Error code: %s\n",
av_err2str(ret));
av_dict_free(&opts);
goto fail;
}
av_dict_free(&opts);
if (!(ost = avformat_new_stream(ofmt_ctx, enc_codec))) {
fprintf(stderr, "Failed to allocate stream for output format.\n");
ret = AVERROR(ENOMEM);
goto fail;
}
ost->time_base = encoder_ctx->time_base;
ret = avcodec_parameters_from_context(ost->codecpar, encoder_ctx);
if (ret < 0) {
fprintf(stderr, "Failed to copy the stream parameters. "
"Error code: %s\n", av_err2str(ret));
goto fail;
}
/* write the stream header */
if ((ret = avformat_write_header(ofmt_ctx, NULL)) < 0) {
fprintf(stderr, "Error while writing stream header. "
"Error code: %s\n", av_err2str(ret));
goto fail;
}
}
frame->pts = av_rescale_q(frame->pts, decoder_ctx->pkt_timebase,
encoder_ctx->time_base);
if ((ret = encode_write(pkt, frame)) < 0)
fprintf(stderr, "Error during encoding and writing.\n");
fail:
av_frame_free(&frame);
}
return ret;
}
int main(int argc, char **argv)
{
const AVCodec *enc_codec;
int ret = 0;
AVPacket *dec_pkt = NULL;
if (argc < 5 || (argc - 5) % 2) {
av_log(NULL, AV_LOG_ERROR, "Usage: %s <input file> <encoder> <output file>"
" <\"encoding option set 0\"> [<frame_number> <\"encoding options set 1\">]...\n", argv[0]);
return 1;
}
setting_number = (argc - 5) / 2;
dynamic_setting = av_malloc(setting_number * sizeof(*dynamic_setting));
current_setting_number = 0;
for (int i = 0; i < setting_number; i++) {
dynamic_setting[i].frame_number = atoi(argv[i*2 + 5]);
dynamic_setting[i].optstr = argv[i*2 + 6];
}
ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_QSV, NULL, NULL, 0);
if (ret < 0) {
fprintf(stderr, "Failed to create a QSV device. Error code: %s\n", av_err2str(ret));
goto end;
}
dec_pkt = av_packet_alloc();
if (!dec_pkt) {
fprintf(stderr, "Failed to allocate decode packet\n");
goto end;
}
if ((ret = open_input_file(argv[1])) < 0)
goto end;
if (!(enc_codec = avcodec_find_encoder_by_name(argv[2]))) {
fprintf(stderr, "Could not find encoder '%s'\n", argv[2]);
ret = -1;
goto end;
}
if ((ret = (avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, argv[3]))) < 0) {
fprintf(stderr, "Failed to deduce output format from file extension. Error code: "
"%s\n", av_err2str(ret));
goto end;
}
if (!(encoder_ctx = avcodec_alloc_context3(enc_codec))) {
ret = AVERROR(ENOMEM);
goto end;
}
ret = avio_open(&ofmt_ctx->pb, argv[3], AVIO_FLAG_WRITE);
if (ret < 0) {
fprintf(stderr, "Cannot open output file. "
"Error code: %s\n", av_err2str(ret));
goto end;
}
/* read all packets and only transcoding video */
while (ret >= 0) {
if ((ret = av_read_frame(ifmt_ctx, dec_pkt)) < 0)
break;
if (video_stream == dec_pkt->stream_index)
ret = dec_enc(dec_pkt, enc_codec, argv[4]);
av_packet_unref(dec_pkt);
}
/* flush decoder */
av_packet_unref(dec_pkt);
if ((ret = dec_enc(dec_pkt, enc_codec, argv[4])) < 0) {
fprintf(stderr, "Failed to flush decoder %s\n", av_err2str(ret));
goto end;
}
/* flush encoder */
if ((ret = encode_write(dec_pkt, NULL)) < 0) {
fprintf(stderr, "Failed to flush encoder %s\n", av_err2str(ret));
goto end;
}
/* write the trailer for output stream */
if ((ret = av_write_trailer(ofmt_ctx)) < 0)
fprintf(stderr, "Failed to write trailer %s\n", av_err2str(ret));
end:
avformat_close_input(&ifmt_ctx);
avformat_close_input(&ofmt_ctx);
avcodec_free_context(&decoder_ctx);
avcodec_free_context(&encoder_ctx);
av_buffer_unref(&hw_device_ctx);
av_packet_free(&dec_pkt);
av_freep(&dynamic_setting);
return ret;
}

484
doc/examples/qsvdec.c Normal file
View File

@@ -0,0 +1,484 @@
/*
* 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)
{
DecodeContext *decode = pthis;
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;
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_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->codec->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->codec->extradata_size) {
decoder_ctx->extradata = av_mallocz(video_st->codec->extradata_size +
FF_INPUT_BUFFER_PADDING_SIZE);
if (!decoder_ctx->extradata) {
ret = AVERROR(ENOMEM);
goto finish;
}
memcpy(decoder_ctx->extradata, video_st->codec->extradata,
video_st->codec->extradata_size);
decoder_ctx->extradata_size = video_st->codec->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 (decode.mfx_session)
MFXClose(decode.mfx_session);
if (decode.va_dpy)
vaTerminate(decode.va_dpy);
if (dpy)
XCloseDisplay(dpy);
if (decoder_ctx)
av_freep(&decoder_ctx->hwaccel_context);
avcodec_free_context(&decoder_ctx);
avio_close(output_ctx);
return ret;
}

View File

@@ -1,199 +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 usage example
* @example remux.c
*
* Remux streams from one container format to another. Data is copied from the
* input to the output without transcoding.
*/
#include <libavutil/mem.h>
#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)
{
const AVOutputFormat *ofmt = NULL;
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
AVPacket *pkt = NULL;
const char *in_filename, *out_filename;
int ret, i;
int stream_index = 0;
int *stream_mapping = NULL;
int stream_mapping_size = 0;
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];
pkt = av_packet_alloc();
if (!pkt) {
fprintf(stderr, "Could not allocate AVPacket\n");
return 1;
}
if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
fprintf(stderr, "Could not open input file '%s'", in_filename);
goto end;
}
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;
}
stream_mapping_size = ifmt_ctx->nb_streams;
stream_mapping = av_calloc(stream_mapping_size, sizeof(*stream_mapping));
if (!stream_mapping) {
ret = AVERROR(ENOMEM);
goto end;
}
ofmt = ofmt_ctx->oformat;
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
AVStream *out_stream;
AVStream *in_stream = ifmt_ctx->streams[i];
AVCodecParameters *in_codecpar = in_stream->codecpar;
if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
stream_mapping[i] = -1;
continue;
}
stream_mapping[i] = stream_index++;
out_stream = avformat_new_stream(ofmt_ctx, NULL);
if (!out_stream) {
fprintf(stderr, "Failed allocating output stream\n");
ret = AVERROR_UNKNOWN;
goto end;
}
ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar);
if (ret < 0) {
fprintf(stderr, "Failed to copy codec parameters\n");
goto end;
}
out_stream->codecpar->codec_tag = 0;
}
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];
if (pkt->stream_index >= stream_mapping_size ||
stream_mapping[pkt->stream_index] < 0) {
av_packet_unref(pkt);
continue;
}
pkt->stream_index = stream_mapping[pkt->stream_index];
out_stream = ofmt_ctx->streams[pkt->stream_index];
log_packet(ifmt_ctx, pkt, "in");
/* copy packet */
av_packet_rescale_ts(pkt, in_stream->time_base, out_stream->time_base);
pkt->pos = -1;
log_packet(ofmt_ctx, pkt, "out");
ret = av_interleaved_write_frame(ofmt_ctx, pkt);
/* pkt is now blank (av_interleaved_write_frame() takes ownership of
* its contents and resets pkt), so that no unreferencing is necessary.
* This would be different if one used av_write_frame(). */
if (ret < 0) {
fprintf(stderr, "Error muxing packet\n");
break;
}
}
av_write_trailer(ofmt_ctx);
end:
av_packet_free(&pkt);
avformat_close_input(&ifmt_ctx);
/* close output */
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
avio_closep(&ofmt_ctx->pb);
avformat_free_context(ofmt_ctx);
av_freep(&stream_mapping);
if (ret < 0 && ret != AVERROR_EOF) {
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
return 1;
}
return 0;
}

165
doc/examples/remuxing.c Normal file
View File

@@ -0,0 +1,165 @@
/*
* 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 |= 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_free_packet(&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;
}

View File

@@ -1,220 +0,0 @@
/*
* Copyright (c) 2012 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 audio resampling API usage example
* @example resample_audio.c
*
* Generate a synthetic audio signal, and Use libswresample API to perform audio
* resampling. The output is written to a raw audio file to be played with
* ffplay.
*/
#include <libavutil/opt.h>
#include <libavutil/channel_layout.h>
#include <libavutil/samplefmt.h>
#include <libswresample/swresample.h>
static int get_format_from_sample_fmt(const char **fmt,
enum AVSampleFormat sample_fmt)
{
int i;
struct sample_fmt_entry {
enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
} sample_fmt_entries[] = {
{ AV_SAMPLE_FMT_U8, "u8", "u8" },
{ AV_SAMPLE_FMT_S16, "s16be", "s16le" },
{ AV_SAMPLE_FMT_S32, "s32be", "s32le" },
{ AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
{ AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
};
*fmt = NULL;
for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
struct sample_fmt_entry *entry = &sample_fmt_entries[i];
if (sample_fmt == entry->sample_fmt) {
*fmt = AV_NE(entry->fmt_be, entry->fmt_le);
return 0;
}
}
fprintf(stderr,
"Sample format %s not supported as output format\n",
av_get_sample_fmt_name(sample_fmt));
return AVERROR(EINVAL);
}
/**
* 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)
{
int i, j;
double tincr = 1.0 / sample_rate, *dstp = dst;
const double c = 2 * M_PI * 440.0;
/* generate sin tone with 440Hz frequency and duplicated channels */
for (i = 0; i < nb_samples; i++) {
*dstp = sin(c * *t);
for (j = 1; j < nb_channels; j++)
dstp[j] = dstp[0];
dstp += nb_channels;
*t += tincr;
}
}
int main(int argc, char **argv)
{
AVChannelLayout src_ch_layout = AV_CHANNEL_LAYOUT_STEREO, dst_ch_layout = AV_CHANNEL_LAYOUT_SURROUND;
int src_rate = 48000, dst_rate = 44100;
uint8_t **src_data = NULL, **dst_data = NULL;
int src_nb_channels = 0, dst_nb_channels = 0;
int src_linesize, dst_linesize;
int src_nb_samples = 1024, dst_nb_samples, max_dst_nb_samples;
enum AVSampleFormat src_sample_fmt = AV_SAMPLE_FMT_DBL, dst_sample_fmt = AV_SAMPLE_FMT_S16;
const char *dst_filename = NULL;
FILE *dst_file;
int dst_bufsize;
const char *fmt;
struct SwrContext *swr_ctx;
char buf[64];
double t;
int ret;
if (argc != 2) {
fprintf(stderr, "Usage: %s output_file\n"
"API example program to show how to resample an audio stream with libswresample.\n"
"This program generates a series of audio frames, resamples them to a specified "
"output format and rate and saves them to an output file named output_file.\n",
argv[0]);
exit(1);
}
dst_filename = argv[1];
dst_file = fopen(dst_filename, "wb");
if (!dst_file) {
fprintf(stderr, "Could not open destination file %s\n", dst_filename);
exit(1);
}
/* create resampler context */
swr_ctx = swr_alloc();
if (!swr_ctx) {
fprintf(stderr, "Could not allocate resampler context\n");
ret = AVERROR(ENOMEM);
goto end;
}
/* set options */
av_opt_set_chlayout(swr_ctx, "in_chlayout", &src_ch_layout, 0);
av_opt_set_int(swr_ctx, "in_sample_rate", src_rate, 0);
av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", src_sample_fmt, 0);
av_opt_set_chlayout(swr_ctx, "out_chlayout", &dst_ch_layout, 0);
av_opt_set_int(swr_ctx, "out_sample_rate", dst_rate, 0);
av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", dst_sample_fmt, 0);
/* initialize the resampling context */
if ((ret = swr_init(swr_ctx)) < 0) {
fprintf(stderr, "Failed to initialize the resampling context\n");
goto end;
}
/* allocate source and destination samples buffers */
src_nb_channels = src_ch_layout.nb_channels;
ret = av_samples_alloc_array_and_samples(&src_data, &src_linesize, src_nb_channels,
src_nb_samples, src_sample_fmt, 0);
if (ret < 0) {
fprintf(stderr, "Could not allocate source samples\n");
goto end;
}
/* 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 = dst_nb_samples =
av_rescale_rnd(src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
/* buffer is going to be directly written to a rawaudio file, no alignment */
dst_nb_channels = dst_ch_layout.nb_channels;
ret = av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, dst_nb_channels,
dst_nb_samples, dst_sample_fmt, 0);
if (ret < 0) {
fprintf(stderr, "Could not allocate destination samples\n");
goto end;
}
t = 0;
do {
/* generate synthetic audio */
fill_samples((double *)src_data[0], src_nb_samples, src_nb_channels, src_rate, &t);
/* compute destination number of samples */
dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, src_rate) +
src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
if (dst_nb_samples > max_dst_nb_samples) {
av_freep(&dst_data[0]);
ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels,
dst_nb_samples, dst_sample_fmt, 1);
if (ret < 0)
break;
max_dst_nb_samples = dst_nb_samples;
}
/* convert to destination format */
ret = swr_convert(swr_ctx, dst_data, dst_nb_samples, (const uint8_t **)src_data, src_nb_samples);
if (ret < 0) {
fprintf(stderr, "Error while converting\n");
goto end;
}
dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,
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);
fwrite(dst_data[0], 1, dst_bufsize, dst_file);
} while (t < 10);
if ((ret = get_format_from_sample_fmt(&fmt, dst_sample_fmt)) < 0)
goto end;
av_channel_layout_describe(&dst_ch_layout, buf, sizeof(buf));
fprintf(stderr, "Resampling succeeded. Play the output file with the command:\n"
"ffplay -f %s -channel_layout %s -channels %d -ar %d %s\n",
fmt, buf, dst_nb_channels, dst_rate, dst_filename);
end:
fclose(dst_file);
if (src_data)
av_freep(&src_data[0]);
av_freep(&src_data);
if (dst_data)
av_freep(&dst_data[0]);
av_freep(&dst_data);
swr_free(&swr_ctx);
return ret < 0;
}

View File

@@ -0,0 +1,214 @@
/*
* Copyright (c) 2012 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.
*/
/**
* @example resampling_audio.c
* libswresample API use example.
*/
#include <libavutil/opt.h>
#include <libavutil/channel_layout.h>
#include <libavutil/samplefmt.h>
#include <libswresample/swresample.h>
static int get_format_from_sample_fmt(const char **fmt,
enum AVSampleFormat sample_fmt)
{
int i;
struct sample_fmt_entry {
enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
} sample_fmt_entries[] = {
{ AV_SAMPLE_FMT_U8, "u8", "u8" },
{ AV_SAMPLE_FMT_S16, "s16be", "s16le" },
{ AV_SAMPLE_FMT_S32, "s32be", "s32le" },
{ AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
{ AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
};
*fmt = NULL;
for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
struct sample_fmt_entry *entry = &sample_fmt_entries[i];
if (sample_fmt == entry->sample_fmt) {
*fmt = AV_NE(entry->fmt_be, entry->fmt_le);
return 0;
}
}
fprintf(stderr,
"Sample format %s not supported as output format\n",
av_get_sample_fmt_name(sample_fmt));
return AVERROR(EINVAL);
}
/**
* 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)
{
int i, j;
double tincr = 1.0 / sample_rate, *dstp = dst;
const double c = 2 * M_PI * 440.0;
/* generate sin tone with 440Hz frequency and duplicated channels */
for (i = 0; i < nb_samples; i++) {
*dstp = sin(c * *t);
for (j = 1; j < nb_channels; j++)
dstp[j] = dstp[0];
dstp += nb_channels;
*t += tincr;
}
}
int main(int argc, char **argv)
{
int64_t src_ch_layout = AV_CH_LAYOUT_STEREO, dst_ch_layout = AV_CH_LAYOUT_SURROUND;
int src_rate = 48000, dst_rate = 44100;
uint8_t **src_data = NULL, **dst_data = NULL;
int src_nb_channels = 0, dst_nb_channels = 0;
int src_linesize, dst_linesize;
int src_nb_samples = 1024, dst_nb_samples, max_dst_nb_samples;
enum AVSampleFormat src_sample_fmt = AV_SAMPLE_FMT_DBL, dst_sample_fmt = AV_SAMPLE_FMT_S16;
const char *dst_filename = NULL;
FILE *dst_file;
int dst_bufsize;
const char *fmt;
struct SwrContext *swr_ctx;
double t;
int ret;
if (argc != 2) {
fprintf(stderr, "Usage: %s output_file\n"
"API example program to show how to resample an audio stream with libswresample.\n"
"This program generates a series of audio frames, resamples them to a specified "
"output format and rate and saves them to an output file named output_file.\n",
argv[0]);
exit(1);
}
dst_filename = argv[1];
dst_file = fopen(dst_filename, "wb");
if (!dst_file) {
fprintf(stderr, "Could not open destination file %s\n", dst_filename);
exit(1);
}
/* create resampler context */
swr_ctx = swr_alloc();
if (!swr_ctx) {
fprintf(stderr, "Could not allocate resampler context\n");
ret = AVERROR(ENOMEM);
goto end;
}
/* set options */
av_opt_set_int(swr_ctx, "in_channel_layout", src_ch_layout, 0);
av_opt_set_int(swr_ctx, "in_sample_rate", src_rate, 0);
av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", src_sample_fmt, 0);
av_opt_set_int(swr_ctx, "out_channel_layout", dst_ch_layout, 0);
av_opt_set_int(swr_ctx, "out_sample_rate", dst_rate, 0);
av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", dst_sample_fmt, 0);
/* initialize the resampling context */
if ((ret = swr_init(swr_ctx)) < 0) {
fprintf(stderr, "Failed to initialize the resampling context\n");
goto end;
}
/* allocate source and destination samples buffers */
src_nb_channels = av_get_channel_layout_nb_channels(src_ch_layout);
ret = av_samples_alloc_array_and_samples(&src_data, &src_linesize, src_nb_channels,
src_nb_samples, src_sample_fmt, 0);
if (ret < 0) {
fprintf(stderr, "Could not allocate source samples\n");
goto end;
}
/* 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 = dst_nb_samples =
av_rescale_rnd(src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
/* buffer is going to be directly written to a rawaudio file, no alignment */
dst_nb_channels = av_get_channel_layout_nb_channels(dst_ch_layout);
ret = av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, dst_nb_channels,
dst_nb_samples, dst_sample_fmt, 0);
if (ret < 0) {
fprintf(stderr, "Could not allocate destination samples\n");
goto end;
}
t = 0;
do {
/* generate synthetic audio */
fill_samples((double *)src_data[0], src_nb_samples, src_nb_channels, src_rate, &t);
/* compute destination number of samples */
dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, src_rate) +
src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
if (dst_nb_samples > max_dst_nb_samples) {
av_freep(&dst_data[0]);
ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels,
dst_nb_samples, dst_sample_fmt, 1);
if (ret < 0)
break;
max_dst_nb_samples = dst_nb_samples;
}
/* convert to destination format */
ret = swr_convert(swr_ctx, dst_data, dst_nb_samples, (const uint8_t **)src_data, src_nb_samples);
if (ret < 0) {
fprintf(stderr, "Error while converting\n");
goto end;
}
dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,
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);
fwrite(dst_data[0], 1, dst_bufsize, dst_file);
} while (t < 10);
if ((ret = get_format_from_sample_fmt(&fmt, dst_sample_fmt)) < 0)
goto end;
fprintf(stderr, "Resampling succeeded. Play the output file with the command:\n"
"ffplay -f %s -channel_layout %"PRId64" -channels %d -ar %d %s\n",
fmt, dst_ch_layout, dst_nb_channels, dst_rate, dst_filename);
end:
fclose(dst_file);
if (src_data)
av_freep(&src_data[0]);
av_freep(&src_data);
if (dst_data)
av_freep(&dst_data[0]);
av_freep(&dst_data);
swr_free(&swr_ctx);
return ret < 0;
}

View File

@@ -1,141 +0,0 @@
/*
* Copyright (c) 2012 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 libswscale API usage example
* @example scale_video.c
*
* Generate a synthetic video signal and use libswscale to perform rescaling.
*/
#include <libavutil/imgutils.h>
#include <libavutil/parseutils.h>
#include <libswscale/swscale.h>
static void fill_yuv_image(uint8_t *data[4], int linesize[4],
int width, int height, int frame_index)
{
int x, y;
/* Y */
for (y = 0; y < height; y++)
for (x = 0; x < width; x++)
data[0][y * linesize[0] + x] = x + y + frame_index * 3;
/* Cb and Cr */
for (y = 0; y < height / 2; y++) {
for (x = 0; x < width / 2; x++) {
data[1][y * linesize[1] + x] = 128 + y + frame_index * 2;
data[2][y * linesize[2] + x] = 64 + x + frame_index * 5;
}
}
}
int main(int argc, char **argv)
{
uint8_t *src_data[4], *dst_data[4];
int src_linesize[4], dst_linesize[4];
int src_w = 320, src_h = 240, dst_w, dst_h;
enum AVPixelFormat src_pix_fmt = AV_PIX_FMT_YUV420P, dst_pix_fmt = AV_PIX_FMT_RGB24;
const char *dst_size = NULL;
const char *dst_filename = NULL;
FILE *dst_file;
int dst_bufsize;
struct SwsContext *sws_ctx;
int i, ret;
if (argc != 3) {
fprintf(stderr, "Usage: %s output_file output_size\n"
"API example program to show how to scale an image with libswscale.\n"
"This program generates a series of pictures, rescales them to the given "
"output_size and saves them to an output file named output_file\n."
"\n", argv[0]);
exit(1);
}
dst_filename = argv[1];
dst_size = argv[2];
if (av_parse_video_size(&dst_w, &dst_h, dst_size) < 0) {
fprintf(stderr,
"Invalid size '%s', must be in the form WxH or a valid size abbreviation\n",
dst_size);
exit(1);
}
dst_file = fopen(dst_filename, "wb");
if (!dst_file) {
fprintf(stderr, "Could not open destination file %s\n", dst_filename);
exit(1);
}
/* create scaling context */
sws_ctx = sws_getContext(src_w, src_h, src_pix_fmt,
dst_w, dst_h, dst_pix_fmt,
SWS_BILINEAR, NULL, NULL, NULL);
if (!sws_ctx) {
fprintf(stderr,
"Impossible to create scale context for the conversion "
"fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
av_get_pix_fmt_name(src_pix_fmt), src_w, src_h,
av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h);
ret = AVERROR(EINVAL);
goto end;
}
/* allocate source and destination image buffers */
if ((ret = av_image_alloc(src_data, src_linesize,
src_w, src_h, src_pix_fmt, 16)) < 0) {
fprintf(stderr, "Could not allocate source image\n");
goto end;
}
/* buffer is going to be written to rawvideo file, no alignment */
if ((ret = av_image_alloc(dst_data, dst_linesize,
dst_w, dst_h, dst_pix_fmt, 1)) < 0) {
fprintf(stderr, "Could not allocate destination image\n");
goto end;
}
dst_bufsize = ret;
for (i = 0; i < 100; i++) {
/* generate synthetic video */
fill_yuv_image(src_data, src_linesize, src_w, src_h, i);
/* convert to destination format */
sws_scale(sws_ctx, (const uint8_t * const*)src_data,
src_linesize, 0, src_h, dst_data, dst_linesize);
/* write scaled image to file */
fwrite(dst_data[0], 1, dst_bufsize, dst_file);
}
fprintf(stderr, "Scaling succeeded. Play the output file with the command:\n"
"ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h, dst_filename);
end:
fclose(dst_file);
av_freep(&src_data[0]);
av_freep(&dst_data[0]);
sws_freeContext(sws_ctx);
return ret < 0;
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (c) 2012 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
* libswscale API use example.
* @example scaling_video.c
*/
#include <libavutil/imgutils.h>
#include <libavutil/parseutils.h>
#include <libswscale/swscale.h>
static void fill_yuv_image(uint8_t *data[4], int linesize[4],
int width, int height, int frame_index)
{
int x, y;
/* Y */
for (y = 0; y < height; y++)
for (x = 0; x < width; x++)
data[0][y * linesize[0] + x] = x + y + frame_index * 3;
/* Cb and Cr */
for (y = 0; y < height / 2; y++) {
for (x = 0; x < width / 2; x++) {
data[1][y * linesize[1] + x] = 128 + y + frame_index * 2;
data[2][y * linesize[2] + x] = 64 + x + frame_index * 5;
}
}
}
int main(int argc, char **argv)
{
uint8_t *src_data[4], *dst_data[4];
int src_linesize[4], dst_linesize[4];
int src_w = 320, src_h = 240, dst_w, dst_h;
enum AVPixelFormat src_pix_fmt = AV_PIX_FMT_YUV420P, dst_pix_fmt = AV_PIX_FMT_RGB24;
const char *dst_size = NULL;
const char *dst_filename = NULL;
FILE *dst_file;
int dst_bufsize;
struct SwsContext *sws_ctx;
int i, ret;
if (argc != 3) {
fprintf(stderr, "Usage: %s output_file output_size\n"
"API example program to show how to scale an image with libswscale.\n"
"This program generates a series of pictures, rescales them to the given "
"output_size and saves them to an output file named output_file\n."
"\n", argv[0]);
exit(1);
}
dst_filename = argv[1];
dst_size = argv[2];
if (av_parse_video_size(&dst_w, &dst_h, dst_size) < 0) {
fprintf(stderr,
"Invalid size '%s', must be in the form WxH or a valid size abbreviation\n",
dst_size);
exit(1);
}
dst_file = fopen(dst_filename, "wb");
if (!dst_file) {
fprintf(stderr, "Could not open destination file %s\n", dst_filename);
exit(1);
}
/* create scaling context */
sws_ctx = sws_getContext(src_w, src_h, src_pix_fmt,
dst_w, dst_h, dst_pix_fmt,
SWS_BILINEAR, NULL, NULL, NULL);
if (!sws_ctx) {
fprintf(stderr,
"Impossible to create scale context for the conversion "
"fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
av_get_pix_fmt_name(src_pix_fmt), src_w, src_h,
av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h);
ret = AVERROR(EINVAL);
goto end;
}
/* allocate source and destination image buffers */
if ((ret = av_image_alloc(src_data, src_linesize,
src_w, src_h, src_pix_fmt, 16)) < 0) {
fprintf(stderr, "Could not allocate source image\n");
goto end;
}
/* buffer is going to be written to rawvideo file, no alignment */
if ((ret = av_image_alloc(dst_data, dst_linesize,
dst_w, dst_h, dst_pix_fmt, 1)) < 0) {
fprintf(stderr, "Could not allocate destination image\n");
goto end;
}
dst_bufsize = ret;
for (i = 0; i < 100; i++) {
/* generate synthetic video */
fill_yuv_image(src_data, src_linesize, src_w, src_h, i);
/* convert to destination format */
sws_scale(sws_ctx, (const uint8_t * const*)src_data,
src_linesize, 0, src_h, dst_data, dst_linesize);
/* write scaled image to file */
fwrite(dst_data[0], 1, dst_bufsize, dst_file);
}
fprintf(stderr, "Scaling succeeded. Play the output file with the command:\n"
"ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h, dst_filename);
end:
fclose(dst_file);
av_freep(&src_data[0]);
av_freep(&dst_data[0]);
sws_freeContext(sws_ctx);
return ret < 0;
}

View File

@@ -1,61 +0,0 @@
/*
* Copyright (c) 2011 Reinhard Tartler
*
* 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 metadata extraction API usage example
* @example show_metadata.c
*
* Show metadata from an input file.
*/
#include <stdio.h>
#include <libavformat/avformat.h>
#include <libavutil/dict.h>
int main (int argc, char **argv)
{
AVFormatContext *fmt_ctx = NULL;
const AVDictionaryEntry *tag = NULL;
int ret;
if (argc != 2) {
printf("usage: %s <input_file>\n"
"example program to demonstrate the use of the libavformat metadata API.\n"
"\n", argv[0]);
return 1;
}
if ((ret = avformat_open_input(&fmt_ctx, argv[1], NULL, NULL)))
return ret;
if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
return ret;
}
while ((tag = av_dict_iterate(fmt_ctx->metadata, tag)))
printf("%s=%s\n", tag->key, tag->value);
avformat_close_input(&fmt_ctx);
return 0;
}

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