Compare commits
340 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee66e04bc9 | ||
|
|
494ce3da24 | ||
|
|
c877b32905 | ||
|
|
1d44fab8c3 | ||
|
|
530286c96b | ||
|
|
d34202f4f0 | ||
|
|
162b44e110 | ||
|
|
2a2bc79187 | ||
|
|
599cfce022 | ||
|
|
86af0e2a87 | ||
|
|
09b6cce9ba | ||
|
|
1d77b60e35 | ||
|
|
33651c0940 | ||
|
|
01209d220b | ||
|
|
aadce82c58 | ||
|
|
63383dea3b | ||
|
|
8f6d7a454a | ||
|
|
36a1939b59 | ||
|
|
ccf6ca1701 | ||
|
|
87eecb7d85 | ||
|
|
24e4039c6f | ||
|
|
4ee463b69f | ||
|
|
63957591e9 | ||
|
|
80c8815444 | ||
|
|
f32ce15f7c | ||
|
|
ffaa3c3071 | ||
|
|
5f52e2c420 | ||
|
|
f1263f5c7d | ||
|
|
4a9f111296 | ||
|
|
02518ba07f | ||
|
|
7dc5c93035 | ||
|
|
381fa4a29d | ||
|
|
c50ba3cb6c | ||
|
|
8183623ca3 | ||
|
|
5f799f0cee | ||
|
|
d5a946615f | ||
|
|
32017af5ef | ||
|
|
12a09ce975 | ||
|
|
b9269c960c | ||
|
|
a066fc25ca | ||
|
|
636e66f350 | ||
|
|
c600c06af9 | ||
|
|
fcfa104b0e | ||
|
|
f5c6d42124 | ||
|
|
63de02051d | ||
|
|
48ca78728a | ||
|
|
1e09bf4d10 | ||
|
|
bf83eadbcc | ||
|
|
5a9170345a | ||
|
|
11e8ea4d0a | ||
|
|
6c2b4c716b | ||
|
|
96ef96f6ba | ||
|
|
ab0a8e4772 | ||
|
|
472498ed47 | ||
|
|
541b627962 | ||
|
|
cdf1dc136c | ||
|
|
4dbfbcef16 | ||
|
|
67bc75d5b1 | ||
|
|
3355596325 | ||
|
|
3006a5675c | ||
|
|
90d73a207c | ||
|
|
5161e1e610 | ||
|
|
b29b6afdfb | ||
|
|
d0e900187c | ||
|
|
965eddc7ed | ||
|
|
bd9525b4bf | ||
|
|
e02f55a3c5 | ||
|
|
b80d504412 | ||
|
|
5d9daae62b | ||
|
|
50ee16431c | ||
|
|
ff8ba749b4 | ||
|
|
7070de99c0 | ||
|
|
c3e263b862 | ||
|
|
f3095068d8 | ||
|
|
ee20d64bec | ||
|
|
773f58229f | ||
|
|
040aa14074 | ||
|
|
0e11b29834 | ||
|
|
dab6409d84 | ||
|
|
4b0d040e18 | ||
|
|
5bdc1e51fd | ||
|
|
92382748e4 | ||
|
|
86ba4473fa | ||
|
|
9664c3a4d4 | ||
|
|
d53202f92d | ||
|
|
7c000b9cea | ||
|
|
e44498984d | ||
|
|
263b3ad407 | ||
|
|
dee8f4b01b | ||
|
|
fcbd117df3 | ||
|
|
b8aa7b9a6d | ||
|
|
d2ce6472a7 | ||
|
|
ebc01c8f6d | ||
|
|
00e7e4b188 | ||
|
|
938bc919ea | ||
|
|
afebdc3ed7 | ||
|
|
6e14fc4aa1 | ||
|
|
1061a2e2ef | ||
|
|
65b0caf47d | ||
|
|
bccddd7fcc | ||
|
|
b2e9d3da81 | ||
|
|
380bc8585c | ||
|
|
8791a1e7de | ||
|
|
70d0d83d4d | ||
|
|
aec3daa8b4 | ||
|
|
7b23dd0f41 | ||
|
|
967604fecf | ||
|
|
3fb09dba40 | ||
|
|
a634da282b | ||
|
|
df6e929e89 | ||
|
|
42355d12db | ||
|
|
eb495b20e5 | ||
|
|
7f521fae2b | ||
|
|
531ebb7506 | ||
|
|
d7973cf03d | ||
|
|
45fb50b4bc | ||
|
|
f645fd64c3 | ||
|
|
1a05e6ced3 | ||
|
|
5a4234de5e | ||
|
|
47f608a7e1 | ||
|
|
5af88171e7 | ||
|
|
6d2b2ee3a5 | ||
|
|
9afcf994f6 | ||
|
|
7da37aa980 | ||
|
|
318b13a5ad | ||
|
|
17a5df4ab8 | ||
|
|
968ffb93af | ||
|
|
84ab680624 | ||
|
|
8327559fe8 | ||
|
|
229025799f | ||
|
|
a04ff0c054 | ||
|
|
ce828a247d | ||
|
|
6e60a38322 | ||
|
|
f2b51fd54c | ||
|
|
0f36c5f5c7 | ||
|
|
3f095c5b56 | ||
|
|
b95c209a61 | ||
|
|
cd42c19f53 | ||
|
|
32353f8bcb | ||
|
|
2c3ea34082 | ||
|
|
c0a6febf32 | ||
|
|
cc0817af0d | ||
|
|
386975d7a4 | ||
|
|
8591d16ce5 | ||
|
|
07255282d0 | ||
|
|
f9235773d6 | ||
|
|
4f51a21c30 | ||
|
|
6cf72a56e7 | ||
|
|
88093d2c1f | ||
|
|
8147da2bad | ||
|
|
f291acafbb | ||
|
|
cec6df48ba | ||
|
|
1a4a6d94cc | ||
|
|
2be51cbeea | ||
|
|
49a90d5d31 | ||
|
|
fab3418cb9 | ||
|
|
9cc5337247 | ||
|
|
d6d7853b4b | ||
|
|
db923b3fbd | ||
|
|
0a155c57bd | ||
|
|
3ef38c414e | ||
|
|
40ed40902a | ||
|
|
0561cde128 | ||
|
|
670b565ba2 | ||
|
|
6b65f46673 | ||
|
|
052edeec55 | ||
|
|
48479937c3 | ||
|
|
fd53179f4a | ||
|
|
5db47b3983 | ||
|
|
0981dfee7d | ||
|
|
d8c4b2ae57 | ||
|
|
fc92ca5b8e | ||
|
|
6d992a51c7 | ||
|
|
6f4b82cc3a | ||
|
|
37f505cc85 | ||
|
|
a21703ca5d | ||
|
|
a28ab09e2a | ||
|
|
4439d6aa69 | ||
|
|
3bf80c7b22 | ||
|
|
1361e4abb8 | ||
|
|
5fd1dce39a | ||
|
|
de0a1d01ba | ||
|
|
c4b23793d4 | ||
|
|
e21e5c95c1 | ||
|
|
2b13c136c4 | ||
|
|
d3536ce839 | ||
|
|
679d749eab | ||
|
|
7610538224 | ||
|
|
0003ace83b | ||
|
|
20c5fb9721 | ||
|
|
841e1399e6 | ||
|
|
9f76f0fab8 | ||
|
|
bf3e331b76 | ||
|
|
21732c1adc | ||
|
|
d00548f2c1 | ||
|
|
10e5302db4 | ||
|
|
84280dc7cf | ||
|
|
2c404cc11a | ||
|
|
acb7907319 | ||
|
|
2c138c2d8c | ||
|
|
b5106c5aa2 | ||
|
|
789bac72ed | ||
|
|
33fcbb4372 | ||
|
|
a56eb4d56c | ||
|
|
70799fae35 | ||
|
|
e049f7c24f | ||
|
|
83a737aa70 | ||
|
|
2deeb2eaef | ||
|
|
9eaf908897 | ||
|
|
1ca157b026 | ||
|
|
f36128518b | ||
|
|
897524954b | ||
|
|
f0e4bc61e3 | ||
|
|
36628bd215 | ||
|
|
e42ab0115e | ||
|
|
10f68641ae | ||
|
|
f0a10f6376 | ||
|
|
0b4d76d891 | ||
|
|
4fa2078217 | ||
|
|
081874a050 | ||
|
|
028a0c9148 | ||
|
|
9a53e8572a | ||
|
|
3aa3b05d64 | ||
|
|
7a5ddf731b | ||
|
|
4b12afccb2 | ||
|
|
b55c824ee7 | ||
|
|
a90497c183 | ||
|
|
65b2b0d98a | ||
|
|
0097cc0ea3 | ||
|
|
07767c704b | ||
|
|
2e7830e5ff | ||
|
|
4f644b2632 | ||
|
|
1d01a3b34c | ||
|
|
2742cb10c7 | ||
|
|
8229afc3a9 | ||
|
|
76f8c8cd05 | ||
|
|
786834a693 | ||
|
|
f2c253f083 | ||
|
|
e26be20a27 | ||
|
|
7b7c582c15 | ||
|
|
06b84f7271 | ||
|
|
f974cc9830 | ||
|
|
af0ba288e7 | ||
|
|
c98d84e229 | ||
|
|
b3d740263c | ||
|
|
6edf0ecab0 | ||
|
|
b2aaf5de42 | ||
|
|
217367b5eb | ||
|
|
c97f9ed53f | ||
|
|
05ac7fdeeb | ||
|
|
c071618ba6 | ||
|
|
b367c23da1 | ||
|
|
58a03420be | ||
|
|
cbe442048f | ||
|
|
87e9f5e118 | ||
|
|
2cffce26a7 | ||
|
|
c26e101654 | ||
|
|
60e408f252 | ||
|
|
e61dcd2c86 | ||
|
|
dd3914c5b5 | ||
|
|
90c4c076c7 | ||
|
|
d976855c00 | ||
|
|
7bc5d49c60 | ||
|
|
36c4995428 | ||
|
|
57bb78d980 | ||
|
|
b2cb42f1c3 | ||
|
|
fe7f2a77c7 | ||
|
|
9dfe36616f | ||
|
|
4ace1597a2 | ||
|
|
6d2c5bb5d2 | ||
|
|
a6d85a97d0 | ||
|
|
72a34d2332 | ||
|
|
c8b57d4333 | ||
|
|
da399903c7 | ||
|
|
8336a66270 | ||
|
|
d1845e7f1a | ||
|
|
852f78443a | ||
|
|
c343eabfb7 | ||
|
|
7ad163c258 | ||
|
|
ef28571efe | ||
|
|
97aea63340 | ||
|
|
bb6a34f237 | ||
|
|
db5631e408 | ||
|
|
df2c811b7c | ||
|
|
6f55a36be9 | ||
|
|
33042d632d | ||
|
|
3054e53ddc | ||
|
|
84bf631018 | ||
|
|
2884575d97 | ||
|
|
76716518a8 | ||
|
|
e8caf67f56 | ||
|
|
e40922c16c | ||
|
|
ef9478d264 | ||
|
|
13d83899df | ||
|
|
61fed89ad4 | ||
|
|
7931e01540 | ||
|
|
93cee87b13 | ||
|
|
2a44f706aa | ||
|
|
61b673b1f1 | ||
|
|
8fde71acd9 | ||
|
|
b32f865969 | ||
|
|
d89eea3455 | ||
|
|
0a22e31fbb | ||
|
|
70a01aa490 | ||
|
|
da6c519f6e | ||
|
|
29328d96b9 | ||
|
|
44cb647477 | ||
|
|
a768c0a3e1 | ||
|
|
58569162c2 | ||
|
|
6b2fee19a7 | ||
|
|
8cd79c2e73 | ||
|
|
0502602d37 | ||
|
|
ace829cb45 | ||
|
|
b9b3ef4f5a | ||
|
|
b2b7cb0f60 | ||
|
|
5cc6370a15 | ||
|
|
8b019be79b | ||
|
|
e36830c695 | ||
|
|
bc2ceeb3ac | ||
|
|
66bdf8f145 | ||
|
|
bfe61bbd00 | ||
|
|
5888679ae3 | ||
|
|
ecb375684d | ||
|
|
df56bc18ef | ||
|
|
ef99025603 | ||
|
|
860293a9a2 | ||
|
|
9b71114247 | ||
|
|
0b6de235b9 | ||
|
|
a73b464118 | ||
|
|
d9e9e97e5f | ||
|
|
d52676da38 | ||
|
|
ca85c3cd7d | ||
|
|
de253343c1 | ||
|
|
9c787a21ce | ||
|
|
7e11a86175 | ||
|
|
9ef90ff0a2 | ||
|
|
6c95a26c1a | ||
|
|
b6ec181240 | ||
|
|
b42e135614 | ||
|
|
0564e8ee49 |
356
Changelog
356
Changelog
@@ -1,47 +1,320 @@
|
||||
Entries are sorted chronologically from oldest to youngest within each release,
|
||||
releases are sorted from youngest to oldest.
|
||||
|
||||
version 4.1:
|
||||
- deblock filter
|
||||
- tmix filter
|
||||
- amplify filter
|
||||
- fftdnoiz filter
|
||||
- aderivative and aintegral audio filters
|
||||
- pal75bars and pal100bars video filter sources
|
||||
- support mbedTLS based TLS
|
||||
- adeclick filter
|
||||
- adeclip filter
|
||||
- libtensorflow backend for DNN based filters like srcnn
|
||||
- vc1 decoder is now bit-exact
|
||||
- ATRAC9 decoder
|
||||
- lensfun wrapper filter
|
||||
- colorconstancy filter
|
||||
- AVS2 video decoder via libdavs2
|
||||
- IMM4 video decoder
|
||||
- Brooktree ProSumer video decoder
|
||||
- MatchWare Screen Capture Codec decoder
|
||||
- WinCam Motion Video decoder
|
||||
- 1D LUT filter (lut1d)
|
||||
- RemotelyAnywhere Screen Capture decoder
|
||||
- cue and acue filters
|
||||
- support for AV1 in MP4
|
||||
- transpose_npp filter
|
||||
- AVS2 video encoder via libxavs2
|
||||
- amultiply filter
|
||||
- Block-Matching 3d (bm3d) denoising filter
|
||||
- acrossover filter
|
||||
- ilbc decoder
|
||||
- audio denoiser as afftdn filter
|
||||
- AV1 parser
|
||||
- SER demuxer
|
||||
- sinc audio filter source
|
||||
- chromahold filter
|
||||
- setparams filter
|
||||
- vibrance filter
|
||||
- decoding S12M timecode in h264
|
||||
- xstack filter
|
||||
- pcm vidc decoder and encoder
|
||||
- (a)graphmonitor filter
|
||||
version 4.0.4:
|
||||
- avcodec/hevcdec: Avoid only partly skiping duplicate first slices
|
||||
- lavc/bmp: Avoid a heap buffer overwrite for 1bpp input.
|
||||
- avcodec/mpegpicture: Check size of edge_emu_buffer
|
||||
- avformat/mov: Fix potential integer overflow in entry check in mov_read_trun()
|
||||
- avcodec/truemotion2: Fix integer overflow in tm2_null_res_block()
|
||||
- avcodec/dfa: Check the chunk header is not truncated
|
||||
- avcodec/clearvideo: Check remaining data in P frames
|
||||
- avcodec/dvbsubdec: Check object position
|
||||
- avcodec/cdgraphics: Use ff_set_dimensions()
|
||||
- avformat/gdv: Check fps
|
||||
- configure: use vpx_codec_vp8_dx/cx for libvpx-vp8 checking
|
||||
- configure: add missing pthreads extralibs dependency for libvpx-vp9
|
||||
- avcodec/mpeg4videodec: Check idx in mpeg4_decode_studio_block()
|
||||
- avcodec/dxv: Correct integer overflow in get_opcodes()
|
||||
- avcodec/scpr: Fix use of uninitialized variable
|
||||
- avcodec/qpeg: Limit copy in qpeg_decode_intra() to the available bytes
|
||||
- avcodec/aic: Check remaining bits in aic_decode_coeffs()
|
||||
- avcodec/gdv: Check for truncated tags in decompress_5()
|
||||
- avcodec/bethsoftvideo: Check block_type
|
||||
- avcodec/jpeg2000dwt: Fix integer overflow in dwt_decode97_int()
|
||||
- avcodec/error_resilience: Use a symmetric check for skipping MV estimation
|
||||
- avcodec/mlpdec: Insuffient typo
|
||||
- avcodec/zmbv: obtain frame later
|
||||
- avcodec/jvdec: Check available input space before decode8x8()
|
||||
- avcodec/h264_direct: Fix overflow in POC comparission
|
||||
- avformat/webmdashenc: Check id in adaption_sets
|
||||
- avformat/http: Fix Out-of-Bounds access in process_line()
|
||||
- avformat/ftp: Fix Out-of-Bounds Access and Information Leak in ftp.c:393
|
||||
- avcodec/htmlsubtitles: Fixes denial of service due to use of sscanf in inner loop for handling braces
|
||||
- avcodec/htmlsubtitles: Fixes denial of service due to use of sscanf in inner loop for tag scaning
|
||||
- avformat/matroskadec: Do not leak queued packets on sync errors
|
||||
- avcodec/mpeg4videodec: Clear interlaced_dct for studio profile
|
||||
- avformat/mov: Do not use reference stream in mov_read_sidx() if there is no reference stream
|
||||
- avcodec/sbrdsp_fixed.c: remove input value limit for sbr_sum_square_c()
|
||||
- avformat/mov: validate chunk_count vs stsc_data
|
||||
- avformat/mov.c: require tfhd to begin parsing trun
|
||||
- avcodec/pgssubdec: Check for duplicate display segments
|
||||
- avformat/rtsp: Check number of streams in sdp_parse_line()
|
||||
- avformat/rtsp: Clear reply in every iteration in ff_rtsp_connect()
|
||||
- avcodec/fic: Check that there is input left in fic_decode_block()
|
||||
- avcodec/tiff: Check for 12bit gray fax
|
||||
- avutil/imgutils: Optimize memset_bytes() by using av_memcpy_backptr()
|
||||
- avutil/mem: Optimize fill32() by unrolling and using 64bit
|
||||
- configure: bump year
|
||||
- avcodec/diracdec: Check component quant
|
||||
- avcodec/tests/rangecoder: initialize array to avoid valgrind warning
|
||||
- avcodec/h264_slice: Fix integer overflow in implicit_weight_table()
|
||||
- avcodec/exr: set layer_match in all branches
|
||||
- avcodec/exr: Check for duplicate channel index
|
||||
- avcodec/4xm: Fix returned error codes
|
||||
- avformat/libopenmpt: Fix successfull typo
|
||||
- avcodec/v4l2_m2m: fix cant typo
|
||||
- avcodec/mjpegbdec: Fix some misplaced {} and spaces
|
||||
- avformat/wvdec: detect and error out on WavPack DSD files
|
||||
- avcodec/mips: Fix failed case: hevc-conformance-AMP_A_Samsung_* when enable msa
|
||||
- avcodec/fic: Fail on invalid slice size/off
|
||||
- postproc/postprocess_template: remove FF_REG_sp from clobber list
|
||||
- postproc/postprocess_template: Avoid using %4 for the threshold compare
|
||||
- avcodec/rpza: Check that there is enough data for all the blocks
|
||||
- avcodec/rpza: Move frame allocation to a later point
|
||||
- avcodec/avcodec: Document the data type for AV_PKT_DATA_MPEGTS_STREAM_ID
|
||||
- avformat/mpegts: Fix side data type for stream id
|
||||
- tests/fate/filter-video: increase fuzz for fate-filter-refcmp-psnr-rgb
|
||||
- avcodec/mjpegdec: Fix indention of ljpeg_decode_yuv_scan()
|
||||
- lavf/id3v2: fail read_apic on EOF reading mimetype
|
||||
- avformat/nutenc: Document trailer index assert better
|
||||
- lavf/mov: ensure only one tkhd per trak
|
||||
- avcodec/clearvideo: Check remaining input bits in P macro block loop
|
||||
- avcodec/dxv: Check that there is enough data to decompress
|
||||
- avcodec/ppc/hevcdsp: Fix build failures with powerpc-linux-gnu-gcc-4.8 with --disable-optimizations
|
||||
- avcodec/msvideo1: Check for too small dimensions
|
||||
- avcodec/wmv2dec: Skip I frame if its smaller than 1/8 of the minimal size
|
||||
- avcodec/msmpeg4dec: Skip frame if its smaller than 1/8 of the minimal size
|
||||
- avcodec/truemotion2rt: Fix rounding in input size check
|
||||
- avcodec/truemotion2: fix integer overflows in tm2_low_chroma()
|
||||
- avcodec/pngdec: Check compression method
|
||||
- fftools/ffmpeg: Repair reinit_filter feature
|
||||
- avcodec/shorten: Fix integer overflow with offset
|
||||
- h264_redundant_pps: Fix logging context
|
||||
- avcodec/cavsdec: Propagate error codes inside decode_mb_i()
|
||||
- avcodec/mpeg4videodec: Clear partitioned frame in decode_studio_vop_header()
|
||||
- avcodec/mpegaudio_parser: Consume more than 0 bytes in case of the unsupported mp3adu case
|
||||
- avcodec/hevcdec: decode at most one slice reporting being the first in the picture
|
||||
- avformat/dsfdec: fix calculation of size of data chunk
|
||||
- avformat/dsfdec: properly handle padded last packet
|
||||
- avcodec/hevcdec: fix non-ref frame judgement
|
||||
- avcodec/libaomenc: remove AVOption related to frame partitions
|
||||
|
||||
version 4.0.3:
|
||||
- avutil/integer: Fix integer overflow in av_mul_i()
|
||||
- avcodec/msrle: Check that the input is large enough to contain a end of picture code
|
||||
- avformat/ftp: return AVERROR_EOF for EOF
|
||||
- avcodec/libx264: remove FF_CODEC_CAP_INIT_THREADSAFE flag
|
||||
- avcodec/jpeg2000dec: Fix off by 1 error in JPEG2000_PGOD_CPRL handling
|
||||
- avcodec/mpeg4videodec: Fix typo in sprite delta check
|
||||
- avcodec/h264_cavlc: Check mb_skip_run
|
||||
- avcodec/ra144: Fix integer overflow in add_wav()
|
||||
- avformat/utils: Never store negative values in last_IP_duration
|
||||
- avformat/utils: Fix integer overflow in discontinuity check
|
||||
- Revert "avcodec/cbs_h264: silence errors about end_of_seq nalus"
|
||||
- avcodec/cbs: ensure user_data is padded for GBC parsing
|
||||
- avcodec/cbs: fix crash in sei_pic_timestamp
|
||||
- avcodec/cbs_h264: silence errors about end_of_seq nalus
|
||||
- avcodec/cuviddec: properly take deinterlacing and display delay into account for buffer_full check
|
||||
- avcodec/h2645_parse: skip NALUs with no content after stripping all the trailing zeros
|
||||
- configure: <fflib>_deps: validate, reduce sensitivity
|
||||
- configure: speed up check_deps()
|
||||
- configure: speed up print_enabled_components()
|
||||
- configure: speed up flatten_extralibs_wrapper()
|
||||
- avformat/utils: Fix potential integer overflow in extract_extradata()
|
||||
- avcodec/unary: Improve get_unary() docs
|
||||
- avcodec/gdv: Replace divisions by shifts in rescale()
|
||||
- avcodec/ac3dec: Fix shift signedness in mask creation
|
||||
- avcodec/eac3dec: Check that channel_map does not contain more than EAC3_MAX_CHANNELS
|
||||
- doc/examples/vaapi_transcode: Fix the typo
|
||||
- avcodec/dvdsubdec: Sanity check len in decode_rle()
|
||||
- avcodec/mpeg4videodec: Fix undefined shift in get_amv()
|
||||
- avcodec/zmbv: Check that the decompressed data size is correct
|
||||
- avcodec/zmbv: Update decomp_len in raw frames
|
||||
- avcodec/shorten: Fix bitstream end check in read_header()
|
||||
- avcodec/dvdsubdec: Avoid branch in decode_run_8bit()
|
||||
- avcodec/h264_refs: Document last if() in ff_h264_execute_ref_pic_marking()
|
||||
- avcodec/ra144: Fix undefined integer overflow in add_wav()
|
||||
- avcodec/indeo4: Check dimensions in decode_pic_hdr()
|
||||
- avformat/mov: Error on too large stsd entry counts.
|
||||
- examples: Fix use of AV_CODEC_FLAG_GLOBAL_HEADER
|
||||
- avcodec/hq_hqa: Check remaining input bits in hqa_decode_mb()
|
||||
- avcodec/vb: Check for end of bytestream before reading blocktype
|
||||
- avcodec/snowdec: Fix integer overflow with motion vector residual
|
||||
- avcodec/mpeg4videodec: Fix slice end detection in mpeg4_decode_studio_mb()
|
||||
- avformat/nsvdec: Do not parse multiple NSVf
|
||||
- avformat/dashdec: Fix strlen(rep_id_val) with it being NULL
|
||||
- avformat/mlvdec: read_string() received unsigned size, make the argument unsigned
|
||||
- avformat/rmdec: Fix EOF check in the stream loop in ivr_read_header()
|
||||
- avcodec/scpr: Check for min > max in decompress_p()
|
||||
- avcodec/shorten: Fix signed 32bit overflow in shift in shorten_decode_frame()
|
||||
- avcodec/shorten: Fix integer overflow in residual/LPC combination
|
||||
- avcodec/shorten: Check verbatim length
|
||||
- avcodec/mpegaudio_parser: Initialize poutbuf*
|
||||
- avcodec/aacpsdsp_template: Fix integer overflow in ps_stereo_interpolate_c()
|
||||
- avformat/flvenc: Check audio packet size
|
||||
- lavc/svq3: Fix regression decoding some files.
|
||||
- avcodec/mlp_parser: Check if synccode is within buffer
|
||||
- avcodec/qtrle: Check remaining bytestream in qtrle_decode_XYbpp()
|
||||
- avcodec/diracdec: Check bytes count in else branch in decode_lowdelay() too
|
||||
- avcodec/diracdec: Check slice numbers for overflows in relation to picture dimensions
|
||||
- avcodec/diracdec: Change frame_number to 64bit as its a 32bit from the bitstream and we also have a -1 special case
|
||||
- avcodec/dirac_dwt_template: Fix several integer overflows in horizontal_compose_daub97i()
|
||||
- avcodec/diracdec: Prevent integer overflow in intermediate in global_mv()
|
||||
- swresample/swresample: Fix input channel count in resample_first computation
|
||||
- avutil/pixfmt: Document chroma plane size for odd resolutions
|
||||
- lavf/libsmbclient: return AVERROR_EOF for EOF.
|
||||
- lavc/videotoolboxenc: Fix compilation on osx 10.10.5 Yosemite
|
||||
- avcodec/mediacodecdec: fix SEGV on modern nvidia decoders
|
||||
- avcodec/bitstream_filters: check the input argument of av_bsf_get_by_name() for NULL
|
||||
- avformat/librtmp: fix returning EOF from Read/Write
|
||||
- avcodec/videotoolboxenc: fix undefined behavior with rc_max_rate=0
|
||||
|
||||
|
||||
version 4.0.2:
|
||||
- avcodec/dvdsub_parser: Allocate input padding
|
||||
- avcodec/dvdsub_parser: Init output buf/size
|
||||
- avcodec/dirac_dwt_template: Fix signedness regression in interleave()
|
||||
- avformat/mov: Simplify last element computation in mov_estimate_video_delay()
|
||||
- avformat/mov: Break out of inner loop early in mov_estimate_video_delay()
|
||||
- avformat/mov: Eliminate variable buf_size from mov_estimate_video_delay()
|
||||
- avformat/mov: remove modulo operations from mov_estimate_video_delay()
|
||||
- avformat/movenc: Write version 2 of audio atom if channels is not known
|
||||
- swresample/arm: rename labels to fix xcode build error
|
||||
- avformat/movenc: Check input sample count
|
||||
- avcodec/mjpegdec: Check for odd progressive RGB
|
||||
- avcodec/vp8_parser: Do not leave data/size uninitialized
|
||||
- avformat/mms: Add missing chunksize check
|
||||
- avformat/pva: Check for EOF before retrying in read_part_of_packet()
|
||||
- avformat/rmdec: Do not pass mime type in rm_read_multi() to ff_rm_read_mdpr_codecdata()
|
||||
- avformat/asfdec_o: Check size_bmp more fully
|
||||
- avformat/mxfdec: Fix av_log context
|
||||
- avcodec/mpeg4videodec: Check for bitstream end in read_quant_matrix_ext()
|
||||
- avcodec/indeo4: Check for end of bitstream in decode_mb_info()
|
||||
- avcodec/ac3dec: Check channel_map index
|
||||
- avcodec/mpeg4videodec: Remove use of FF_PROFILE_MPEG4_SIMPLE_STUDIO as indicator of studio profile
|
||||
- avcodec/shorten: Fix undefined addition in shorten_decode_frame()
|
||||
- avcodec/shorten: Fix undefined integer overflow
|
||||
- avcodec/jpeg2000dec: Fixes invalid shifts in jpeg2000_decode_packets_po_iteration()
|
||||
- avcodec/jpeg2000dec: Check that there are enough bytes for all tiles
|
||||
- avformat/movenc: Use mov->fc consistently for av_log()
|
||||
- avcodec/mpeg4videodec: Check read profile before setting it
|
||||
- avformat/movenc: Do not pass AVCodecParameters in avpriv_request_sample
|
||||
- avcodec/ac3_parser: Check init_get_bits8() for failure
|
||||
- avformat/movenc: Check that frame_types other than EAC3_FRAME_TYPE_INDEPENDENT have a supported substream id
|
||||
- avcodec/dpx: Check elements in 12bps planar path
|
||||
- avcodec/escape124: Fix spelling errors in comment
|
||||
- avcodec/ra144: Fix integer overflow in ff_eval_refl()
|
||||
- avcodec/cscd: Check output buffer size for lzo.
|
||||
- avcodec/escape124: Check buf_size against num_superblocks
|
||||
- avcodec/h264_parser: Reduce needed history for parsing mb index
|
||||
- avcodec/magicyuv: Check bits left in flags&1 branch
|
||||
- avcodec/mjpegdec: Check for end of bitstream in ljpeg_decode_rgb_scan()
|
||||
- ffmpeg: fix -stream_loop with multiple inputs
|
||||
- ffmpeg: factorize input thread creation and destruction
|
||||
- avformat/mpegts: parse large PMTs with multiple tables
|
||||
- Revert "avcodec/mediacodecdec: wait on first frame after input buffers are full"
|
||||
- avcodec/videotoolboxenc: fix invalid session on iOS
|
||||
- avcodec/videotoolboxenc: split initialization
|
||||
- avcodec/videotoolboxenc: fix mutex/cond leak in error path
|
||||
|
||||
version 4.0.1:
|
||||
- avcodec/aacdec_fixed: Fix undefined integer overflow in apply_independent_coupling_fixed()
|
||||
- avcodec/dirac_dwt_template: Fix undefined behavior in interleave()
|
||||
- avutil/common: Fix undefined behavior in av_clip_uintp2_c()
|
||||
- fftools/ffmpeg: Fallback to duration if sample rate is unavailable
|
||||
- avformat/mov: Only set pkt->duration to non negative values
|
||||
- avcodec/mpeg4videodec: Clear bits_per_raw_sample if it has originated from a previous instance
|
||||
- avformat/movenc: fix recognization of cover image streams
|
||||
- avformat/movenc: properly handle cover image codecs
|
||||
- avcodec/h264_slice: Fix overflow in recovery_frame computation
|
||||
- avcodec/h264_ps: Move MAX_LOG2_MAX_FRAME_NUM to header so it can be used in h264_sei
|
||||
- avcodec/h264_mc_template: Only prefetch motion if the list is used.
|
||||
- avcodec/xwddec: Use ff_set_dimensions()
|
||||
- avcodec/wavpack: Fix overflow in adding tail
|
||||
- avcodec/shorten: Fix multiple integer overflows
|
||||
- avcodec/shorten: Fix undefined shift in fix_bitshift()
|
||||
- avcodec/shorten: Fix a negative left shift in shorten_decode_frame()
|
||||
- avcodec/shorten: Sanity check nmeans
|
||||
- avcodec/shorten: Check non COMM chunk len before skip in decode_aiff_header()
|
||||
- avcodec/mjpegdec: Fix integer overflow in ljpeg_decode_rgb_scan()
|
||||
- avcodec/truemotion2: Fix overflow in tm2_apply_deltas()
|
||||
- avcodec/opus_silk: Change silk_lsf2lpc() slightly toward silk/NLSF2A.c
|
||||
- avcodec/amrwbdec: Fix division by 0 in find_hb_gain()
|
||||
- avcodec/h263dec: Reinitialize idct context if it has not been setup for the active profile
|
||||
- avcodec/idctdsp: Clear idct/idct_add for studio profile
|
||||
- avformat/mov: replace a value error by clipping into valid range in mov_read_stsc()
|
||||
- avformat/bintext: Reduce detection for random .bin files as it more likely is not a multimedia related file
|
||||
- avformat/mov: Break out early if chunk_count is 0 in mov_build_index()
|
||||
- avcodec/fic: Avoid some magic numbers related to cursors
|
||||
- avcodec/mpeg4video: Detect reference studio streams as studio streams
|
||||
- avcodec/mpeg4videodec: Do not corrupt bits_per_raw_sample
|
||||
- avcodec/mpeg4videode: Eliminate out of loop VOP startcode reading for studio profile
|
||||
- avcodec/g2meet: ask for sample with overflowing RGB
|
||||
- avcodec/idctdsp: Transmit studio_profile to init instead of using AVCodecContext profile
|
||||
- avcodec/ac3dec: Check that the number of channels with dependant streams is valid
|
||||
- avcodec/ac3dec: Fix null pointer dereference in ac3_decode_frame()
|
||||
- avcodec/aacdec_fixed: use 64bit to avoid overflow in rounding in apply_dependent_coupling_fixed()
|
||||
- oavcodec/aacpsdsp_template: Use unsigned for hs0X to prevent undefined behavior
|
||||
- avcodec/g723_1dec: Clip bits2 in both directions
|
||||
- avcodec/mpeg4videoenc: Use 64 bit for times in mpeg4_encode_gop_header()
|
||||
- avcodec/mlpdec: Only change noise_type if the related fields are valid
|
||||
- indeo4: Decode all or nothing of a band header.
|
||||
- avcodec/ac3dec: Use frame_size if superframe_size is 0
|
||||
- avformat/mov: Only fail for STCO/STSC contradictions if both exist
|
||||
- avcodec/dirac_dwt: Fix integer overflow in COMPOSE_DD97iH0 / COMPOSE_DD137iL0
|
||||
- avcodec/fic: Check available input space for cursor
|
||||
- avcodec/mpeg4videodec: Check bps (VOL header) before VOP for studio profile
|
||||
- avcodec/g2meet: Check RGB upper limit
|
||||
- avcodec/jpeg2000dec: Fix undefined shift in the jpeg2000_decode_packets_po_iteration() CPRL case
|
||||
- avcodec/jpeg2000dec: Skip init for component in CPRL if nothing is to be done
|
||||
- avcodec/g2meet: Change order of operations to avoid undefined behavior
|
||||
- avcodec/flac_parser: Fix infinite loop
|
||||
- avcodec/mpeg4videodec: Split decode_studio_vol_header() out of decode_studiovisualobject()
|
||||
- avcodec/mpeg4videodec: Move decode_studiovisualobject() parsing in the branch for visual object parsing
|
||||
- avcodec/mpeg4video_parser: Avoid litteral 0x1B6, use named constant instead
|
||||
- avcodec/mpeg4video_parser: Fix incorrect spliting of MPEG-4 studio frames
|
||||
- avformat/m4vdec: Use the same constant names as libavcodec
|
||||
- avformat/m4vdec: Fix detection of raw MPEG-4 ES Studio
|
||||
- avcodec/wavpack: Fix integer overflow in DEC_MED() / INC_MED()
|
||||
- avcodec/wavpack: Fix integer overflow in wv_unpack_stereo()
|
||||
- avcodec/error_resilience: Fix integer overflow in filter181()
|
||||
- avcodec/h263dec: Check slice_ret in mspeg4 slice loop
|
||||
- avcodec/elsdec: Fix memleaks
|
||||
- avcodec/vc1_block: simplify ac_val computation
|
||||
- avcodec/ffv1enc: Check that the crc + version combination is supported
|
||||
- configure: The eac3_core bitstream filter needs the ac3 parser.
|
||||
- configure: fix arm inline asm checks
|
||||
- lavf/libssh: translate a read of 0 to EOF
|
||||
- ffprobe: fix SEGV when new streams are added
|
||||
- avformat/mpegts: fix incorrect indentation
|
||||
- avformat/mpegts: initialize section_buf to fix valgrind test failure
|
||||
- avformat/mpegts: reindent after last change
|
||||
- avformat/mpegts: parse sections with multiple tables
|
||||
- avformat/mpegts: clean up whitespace
|
||||
- avformat/mpegts: use MAX_SECTION_SIZE instead of hardcoded value
|
||||
- avformat/mpegts: skip non-PMT tids earlier
|
||||
- avcodec/mediacodecdec: add workaround for buggy amlogic mpeg2 decoder
|
||||
- avcodec/mediacodecdec: wait on first frame after input buffers are full
|
||||
- avcodec/mediacodecdec: restructure mediacodec_receive_frame
|
||||
- avcodec/mediacodec_wrapper: add helper to fetch SDK_INT
|
||||
- avcodec/mediacodecdec: refactor pts handling
|
||||
- avcodec/mediacodecdec: use AV_TIME_BASE_Q
|
||||
- avcodec/mediacodecdec: clarify delay_flush specific code
|
||||
- avcodec/videotoolbox: fix decoding of some HEVC videos
|
||||
- avcodec/hevc: remove videotoolbox hack
|
||||
- avcodec/videotoolbox: split h264/hevc callbacks
|
||||
- avcodec/videotoolbox: cleanups
|
||||
- avcodec/videotoolbox: fix kVTCouldNotFindVideoDecoderErr trying to decode HEVC on iOS
|
||||
- avcodec/videotoolbox: improve logging of decoder errors
|
||||
- avcodec/xwddec: fix palette alpha
|
||||
- avformat/webm_chunk: always use a static buffer for get_chunk_filename
|
||||
- configure: fix configure check for lilv-0
|
||||
- avcodec/nvdec_hevc: fix scaling lists
|
||||
- avcodec/hevcdec: make ff_hevc_frame_nb_refs take a const pointer
|
||||
- lavf/bluray: translate a read of 0 to EOF
|
||||
- lavf/dashenc: don't call flush_init_segment before avformat_write_header
|
||||
- avdevice/decklink_dec: unref packets on avpacket_queue_put error
|
||||
- avcodec/hnm4video: fix palette alpha
|
||||
- avcodec/anm: fix palette alpha
|
||||
- avformat/qtpalette: parse color table according to the QuickTime file format specs
|
||||
- ffplay: Fix realloc_texture when input texture is NULL.
|
||||
- hwcontext_vaapi: Fix compilation with libva versions < 1.4.0
|
||||
- lavf/qsv: clone the frame which may be managed by framework
|
||||
- lavf: make overlay_qsv work based on framesync
|
||||
- avformat/segafilm - revert keyframe detection
|
||||
- avformat/utils: refactor upstream_stream_timings
|
||||
- avformat/utils: ignore outlier durations on subtitle/data streams as well
|
||||
|
||||
|
||||
version 4.0:
|
||||
@@ -97,7 +370,6 @@ version 4.0:
|
||||
- Haivision SRT protocol via libsrt
|
||||
- segafilm muxer
|
||||
- vfrdet filter
|
||||
- SRCNN filter
|
||||
|
||||
|
||||
version 3.4:
|
||||
|
||||
18
MAINTAINERS
18
MAINTAINERS
@@ -121,6 +121,7 @@ Generic Parts:
|
||||
motion* Michael Niedermayer
|
||||
rate control:
|
||||
ratecontrol.c Michael Niedermayer
|
||||
libxvid_rc.c Michael Niedermayer
|
||||
simple IDCT:
|
||||
simple_idct.c, simple_idct.h Michael Niedermayer
|
||||
postprocessing:
|
||||
@@ -219,7 +220,7 @@ Codecs:
|
||||
ptx.c Ivo van Poorten
|
||||
qcelp* Reynaldo H. Verdejo Pinochet
|
||||
qdm2.c, qdm2data.h Roberto Togni
|
||||
qsv* Mark Thompson, Zhong Li
|
||||
qsv* Mark Thompson
|
||||
qtrle.c Mike Melanson
|
||||
ra144.c, ra144.h, ra288.c, ra288.h Roberto Togni
|
||||
resample2.c Michael Niedermayer
|
||||
@@ -332,7 +333,6 @@ Filters:
|
||||
vf_bwdif Thomas Mundt (CC <thomas.mundt@hr.de>)
|
||||
vf_chromakey.c Timo Rothenpieler
|
||||
vf_colorchannelmixer.c Paul B Mahol
|
||||
vf_colorconstancy.c Mina Sami (CC <minas.gorgy@gmail.com>)
|
||||
vf_colorbalance.c Paul B Mahol
|
||||
vf_colorkey.c Timo Rothenpieler
|
||||
vf_colorlevels.c Paul B Mahol
|
||||
@@ -413,6 +413,7 @@ Muxers/Demuxers:
|
||||
flvenc.c Michael Niedermayer, Steven Liu
|
||||
gxf.c Reimar Doeffinger
|
||||
gxfenc.c Baptiste Coudurier
|
||||
hls.c Anssi Hannula
|
||||
hlsenc.c Christian Suloway, Steven Liu
|
||||
idcin.c Mike Melanson
|
||||
idroqdec.c Mike Melanson
|
||||
@@ -523,7 +524,7 @@ Operating systems / CPU architectures
|
||||
=====================================
|
||||
|
||||
Alpha Falk Hueffner
|
||||
MIPS Manojkumar Bhosale, Shiyou Yin
|
||||
MIPS Manojkumar Bhosale
|
||||
Mac OS X / PowerPC Romain Dolbeau, Guillaume Poirier
|
||||
Amiga / PowerPC Colin Ward
|
||||
Windows MinGW Alex Beregszaszi, Ramiro Polla
|
||||
@@ -574,11 +575,8 @@ Releases
|
||||
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
|
||||
@@ -596,7 +594,7 @@ 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
|
||||
Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE
|
||||
Lou Logan (llogan) 7D68 DC73 CBEF EABB 671A B6CF 621C 2E28 82F8 DC3A
|
||||
Lou Logan 7D68 DC73 CBEF EABB 671A B6CF 621C 2E28 82F8 DC3A
|
||||
Michael Niedermayer 9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB
|
||||
Nicolas George 24CE 01CE 9ACC 5CEB 74D8 8D9D B063 D997 36E5 4C93
|
||||
Nikolay Aleksandrov 8978 1D8C FB71 588E 4B27 EAA8 C4F0 B5FC E011 13B1
|
||||
@@ -613,5 +611,5 @@ 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
|
||||
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
|
||||
|
||||
1
Makefile
1
Makefile
@@ -58,7 +58,6 @@ tools/target_dec_%_fuzzer$(EXESUF): $(FF_DEP_LIBS)
|
||||
CONFIGURABLE_COMPONENTS = \
|
||||
$(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c)) \
|
||||
$(SRC_PATH)/libavcodec/bitstream_filters.c \
|
||||
$(SRC_PATH)/libavcodec/parsers.c \
|
||||
$(SRC_PATH)/libavformat/protocols.c \
|
||||
|
||||
config.h: ffbuild/.config
|
||||
|
||||
15
RELEASE_NOTES
Normal file
15
RELEASE_NOTES
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
┌───────────────────────────────────┐
|
||||
│ RELEASE NOTES for FFmpeg 4.0 "Wu" │
|
||||
└───────────────────────────────────┘
|
||||
|
||||
The FFmpeg Project proudly presents FFmpeg 4.0 "Wu", about 6
|
||||
months after the release of FFmpeg 3.4.
|
||||
|
||||
A complete Changelog is available at the root of the project, and the
|
||||
complete Git history on https://git.ffmpeg.org/gitweb/ffmpeg.git
|
||||
|
||||
We hope you will like this release as much as we enjoyed working on it, and
|
||||
as usual, if you have any questions about it, or any FFmpeg related topic,
|
||||
feel free to join us on the #ffmpeg IRC channel (on irc.freenode.net) or ask
|
||||
on the mailing-lists.
|
||||
@@ -15,41 +15,6 @@ libavutil: 2017-10-21
|
||||
|
||||
API changes, most recent first:
|
||||
|
||||
-------- 8< --------- FFmpeg 4.1 was cut here -------- 8< ---------
|
||||
|
||||
2018-10-27 - 718044dc19 - lavu 56.21.100 - pixdesc.h
|
||||
Add av_read_image_line2(), av_write_image_line2()
|
||||
|
||||
2018-10-24 - f9d4126f28 - lavu 56.20.100 - frame.h
|
||||
Add AV_FRAME_DATA_S12M_TIMECODE
|
||||
|
||||
2018-10-11 - f6d48b618a - lavc 58.33.100 - mediacodec.h
|
||||
Add av_mediacodec_render_buffer_at_time().
|
||||
|
||||
2018-09-09 - 35498c124a - lavc 58.29.100 - avcodec.h
|
||||
Add AV_PKT_DATA_AFD
|
||||
|
||||
2018-08-16 - b33f5299a5 - lavc 58.23.100 - avcodec.h
|
||||
Add av_bsf_flush().
|
||||
|
||||
2018-05-18 - 2b2f2f65f3 - lavf 58.15.100 - avformat.h
|
||||
Add pmt_version field to AVProgram
|
||||
|
||||
2018-05-17 - 5dfeb7f081 - lavf 58.14.100 - avformat.h
|
||||
Add AV_DISPOSITION_STILL_IMAGE
|
||||
|
||||
2018-05-10 - c855683427 - lavu 56.18.101 - hwcontext_cuda.h
|
||||
Add AVCUDADeviceContext.stream.
|
||||
|
||||
2018-04-30 - 56b081da57 - lavu 56.18.100 - pixdesc.h
|
||||
Add AV_PIX_FMT_FLAG_ALPHA to AV_PIX_FMT_PAL8.
|
||||
|
||||
2018-04-26 - 5be0410cb3 - lavu 56.17.100 - opt.h
|
||||
Add AV_OPT_FLAG_DEPRECATED.
|
||||
|
||||
2018-04-26 - 71fa82bed6 - lavu 56.16.100 - threadmessage.h
|
||||
Add av_thread_message_queue_nb_elems().
|
||||
|
||||
-------- 8< --------- FFmpeg 4.0 was cut here -------- 8< ---------
|
||||
|
||||
2018-04-03 - d6fc031caf - lavu 56.13.100 - pixdesc.h
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = FFmpeg
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER =
|
||||
PROJECT_NUMBER = 4.0.4
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
@@ -37,58 +37,6 @@ 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{num_units_in_display_tick / time_scale}) 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.
|
||||
|
||||
@end table
|
||||
|
||||
@section chomp
|
||||
|
||||
Remove zero padding at the end of a packet.
|
||||
@@ -267,15 +215,6 @@ insert the string ``hello'' associated with the given UUID.
|
||||
@item delete_filler
|
||||
Deletes both filler NAL units and filler SEI messages.
|
||||
|
||||
@item level
|
||||
Set the level in the SPS. Refer to H.264 section A.3 and tables A-1
|
||||
to A-5.
|
||||
|
||||
The argument must be the name of a level (for example, @samp{4.2}), a
|
||||
level_idc value (for example, @samp{42}), or the special name @samp{auto}
|
||||
indicating that the filter should attempt to guess the level from the
|
||||
input stream properties.
|
||||
|
||||
@end table
|
||||
|
||||
@section h264_mp4toannexb
|
||||
@@ -566,33 +505,7 @@ 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 H.264, H.265, MPEG-2 and VP9.
|
||||
|
||||
@section vp9_metadata
|
||||
|
||||
Modify metadata embedded in a VP9 stream.
|
||||
|
||||
@table @option
|
||||
@item color_space
|
||||
Set the color space value in the frame header.
|
||||
@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 this cannot
|
||||
be set in RGB streams.
|
||||
@table @samp
|
||||
@item tv
|
||||
@item pc
|
||||
@end table
|
||||
@end table
|
||||
Supports H.264, H.265 and MPEG-2.
|
||||
|
||||
@section vp9_superframe
|
||||
|
||||
|
||||
@@ -986,6 +986,10 @@ 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.
|
||||
|
||||
@@ -47,12 +47,6 @@ top-field-first is assumed
|
||||
|
||||
@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
|
||||
|
||||
@chapter Audio Decoders
|
||||
@@ -254,25 +248,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_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
|
||||
@@ -285,8 +272,7 @@ present between the subtitle lines because of double-sized teletext characters.
|
||||
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.
|
||||
milliseconds. 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.
|
||||
|
||||
@@ -269,12 +269,6 @@ ffmpeg -f live_flv -i rtmp://<any.server>/anything/key ....
|
||||
@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 gif
|
||||
@@ -544,9 +538,6 @@ This demuxer accepts the following options:
|
||||
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
|
||||
from the PCR of the first program which the teletext stream is part of and is
|
||||
@@ -561,10 +552,6 @@ Show the detected raw packet size, cannot be set by the user.
|
||||
Scan and combine all PMTs. The value is an integer with value from -1
|
||||
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.
|
||||
@end table
|
||||
|
||||
@section mpjpeg
|
||||
|
||||
@@ -128,9 +128,6 @@ designated struct initializers (@samp{struct s x = @{ .i = 17 @};});
|
||||
@item
|
||||
compound literals (@samp{x = (struct s) @{ 17, 23 @};}).
|
||||
|
||||
@item
|
||||
for loops with variable definition (@samp{for (int i = 0; i < 8; i++)});
|
||||
|
||||
@item
|
||||
Implementation defined behavior for signed integers is assumed to match the
|
||||
expected behavior for two's complement. Non representable values in integer
|
||||
|
||||
@@ -2565,9 +2565,6 @@ The following standard libavcodec options are used:
|
||||
@option{bf} / @option{max_b_frames}
|
||||
@item
|
||||
@option{profile}
|
||||
|
||||
If not set, this will be determined automatically from the format of the input
|
||||
frames and the profiles supported by the driver.
|
||||
@item
|
||||
@option{level}
|
||||
@item
|
||||
@@ -2588,8 +2585,7 @@ Speed / quality tradeoff: higher values are faster / worse quality.
|
||||
Size / quality tradeoff: higher values are smaller / worse quality.
|
||||
@item
|
||||
@option{qmin}
|
||||
@item
|
||||
@option{qmax}
|
||||
(only: @option{qmax} is not supported)
|
||||
@item
|
||||
@option{i_qfactor} / @option{i_quant_factor}
|
||||
@item
|
||||
@@ -2598,22 +2594,8 @@ Size / quality tradeoff: higher values are smaller / worse quality.
|
||||
@option{b_qfactor} / @option{b_quant_factor}
|
||||
@item
|
||||
@option{b_qoffset} / @option{b_quant_offset}
|
||||
@item
|
||||
@option{slices}
|
||||
@end itemize
|
||||
|
||||
All encoders support the following options:
|
||||
@itemize
|
||||
@item
|
||||
@option{low_power}
|
||||
|
||||
Some drivers/platforms offer a second encoder for some codecs intended to use
|
||||
less power than the default encoder; setting this option will attempt to use
|
||||
that encoder. Note that it may support a reduced feature set, so some other
|
||||
options may not be available in this mode.
|
||||
@end itemize
|
||||
|
||||
Each encoder also has its own specific options:
|
||||
@table @option
|
||||
|
||||
@item h264_vaapi
|
||||
@@ -2621,6 +2603,8 @@ Each encoder also has its own specific options:
|
||||
@option{level} sets the value of @emph{level_idc}.
|
||||
|
||||
@table @option
|
||||
@item low_power
|
||||
Use low-power encoding mode.
|
||||
@item coder
|
||||
Set entropy encoder (default is @emph{cabac}). Possible values:
|
||||
|
||||
@@ -2633,70 +2617,21 @@ Use CABAC.
|
||||
@item cavlc
|
||||
Use CAVLC.
|
||||
@end table
|
||||
|
||||
@item aud
|
||||
Include access unit delimiters in the stream (not included by default).
|
||||
|
||||
@item sei
|
||||
Set SEI message types to include.
|
||||
Some combination of the following values:
|
||||
@table @samp
|
||||
@item identifier
|
||||
Include a @emph{user_data_unregistered} message containing information about
|
||||
the encoder.
|
||||
@item timing
|
||||
Include picture timing parameters (@emph{buffering_period} and
|
||||
@emph{pic_timing} messages).
|
||||
@item recovery_point
|
||||
Include recovery points where appropriate (@emph{recovery_point} messages).
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@item hevc_vaapi
|
||||
@option{profile} and @option{level} set the values of
|
||||
@emph{general_profile_idc} and @emph{general_level_idc} respectively.
|
||||
|
||||
@table @option
|
||||
@item aud
|
||||
Include access unit delimiters in the stream (not included by default).
|
||||
|
||||
@item tier
|
||||
Set @emph{general_tier_flag}. This may affect the level chosen for the stream
|
||||
if it is not explicitly specified.
|
||||
|
||||
@item sei
|
||||
Set SEI message types to include.
|
||||
Some combination of the following values:
|
||||
@table @samp
|
||||
@item hdr
|
||||
Include HDR metadata if the input frames have it
|
||||
(@emph{mastering_display_colour_volume} and @emph{content_light_level}
|
||||
messages).
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@item mjpeg_vaapi
|
||||
Only baseline DCT encoding is supported. The encoder always uses the standard
|
||||
quantisation and huffman tables - @option{global_quality} scales the standard
|
||||
quantisation table (range 1-100).
|
||||
|
||||
For YUV, 4:2:0, 4:2:2 and 4:4:4 subsampling modes are supported. RGB is also
|
||||
supported, and will create an RGB JPEG.
|
||||
|
||||
@table @option
|
||||
@item jfif
|
||||
Include JFIF header in each frame (not included by default).
|
||||
@item huffman
|
||||
Include standard huffman tables (on by default). Turning this off will save
|
||||
a few hundred bytes in each output frame, but may lose compatibility with some
|
||||
JPEG decoders which don't fully handle MJPEG.
|
||||
@end table
|
||||
Always encodes using the standard quantisation and huffman tables -
|
||||
@option{global_quality} scales the standard quantisation table (range 1-100).
|
||||
|
||||
@item mpeg2_vaapi
|
||||
@option{profile} and @option{level} set the value of @emph{profile_and_level_indication}.
|
||||
|
||||
No rate control is supported.
|
||||
|
||||
@item vp8_vaapi
|
||||
B-frames are not supported.
|
||||
|
||||
@@ -2791,52 +2726,6 @@ Reduces detail but attempts to preserve color at extremely low bitrates.
|
||||
|
||||
@end table
|
||||
|
||||
@section libxavs2
|
||||
|
||||
xavs2 AVS2-P2/IEEE1857.4 encoder wrapper.
|
||||
|
||||
This encoder requires the presence of the libxavs2 headers and library
|
||||
during configuration. You need to explicitly configure the build with
|
||||
@option{--enable-libxavs2}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item lcu_row_threads
|
||||
Set the number of parallel threads for rows from 1 to 8 (default 5).
|
||||
|
||||
@item initial_qp
|
||||
Set the xavs2 quantization parameter from 1 to 63 (default 34). This is
|
||||
used to set the initial qp for the first frame.
|
||||
|
||||
@item qp
|
||||
Set the xavs2 quantization parameter from 1 to 63 (default 34). This is
|
||||
used to set the qp value under constant-QP mode.
|
||||
|
||||
@item max_qp
|
||||
Set the max qp for rate control from 1 to 63 (default 55).
|
||||
|
||||
@item min_qp
|
||||
Set the min qp for rate control from 1 to 63 (default 20).
|
||||
|
||||
@item speed_level
|
||||
Set the Speed level from 0 to 9 (default 0). Higher is better but slower.
|
||||
|
||||
@item log_level
|
||||
Set the log level from -1 to 3 (default 0). -1: none, 0: error,
|
||||
1: warning, 2: info, 3: debug.
|
||||
|
||||
@item xavs2-params
|
||||
Set xavs2 options using a list of @var{key}=@var{value} couples separated
|
||||
by ":".
|
||||
|
||||
For example to specify libxavs2 encoding options with @option{-xavs2-params}:
|
||||
|
||||
@example
|
||||
ffmpeg -i input -c:v libxavs2 -xavs2-params preset_level=5 output.avs2
|
||||
@end example
|
||||
@end table
|
||||
|
||||
@c man end VIDEO ENCODERS
|
||||
|
||||
@chapter Subtitles Encoders
|
||||
|
||||
2
doc/examples/.gitignore
vendored
2
doc/examples/.gitignore
vendored
@@ -20,5 +20,3 @@
|
||||
/scaling_video
|
||||
/transcode_aac
|
||||
/transcoding
|
||||
/vaapi_encode
|
||||
/vaapi_transcode
|
||||
|
||||
@@ -74,6 +74,7 @@ static int open_input_file(const char *filename)
|
||||
if (!dec_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[audio_stream_index]->codecpar);
|
||||
av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);
|
||||
|
||||
/* init the audio decoder */
|
||||
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
|
||||
#define _XOPEN_SOURCE 600 /* for usleep */
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
@@ -79,6 +77,7 @@ static int open_input_file(const char *filename)
|
||||
if (!dec_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[video_stream_index]->codecpar);
|
||||
av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);
|
||||
|
||||
/* init the video decoder */
|
||||
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
||||
@@ -211,20 +210,17 @@ int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
AVPacket packet;
|
||||
AVFrame *frame;
|
||||
AVFrame *filt_frame;
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
AVFrame *filt_frame = av_frame_alloc();
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s file\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
filt_frame = av_frame_alloc();
|
||||
if (!frame || !filt_frame) {
|
||||
perror("Could not allocate frame");
|
||||
exit(1);
|
||||
}
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s file\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((ret = open_input_file(argv[1])) < 0)
|
||||
goto end;
|
||||
@@ -252,25 +248,27 @@ int main(int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
frame->pts = frame->best_effort_timestamp;
|
||||
if (ret >= 0) {
|
||||
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)
|
||||
/* 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;
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
|
||||
av_frame_unref(filt_frame);
|
||||
}
|
||||
|
||||
/* 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_frame_unref(frame);
|
||||
}
|
||||
}
|
||||
av_packet_unref(&packet);
|
||||
|
||||
@@ -4,23 +4,21 @@
|
||||
*
|
||||
* 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:
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -213,6 +211,7 @@ int main(int argc, char *argv[])
|
||||
return -1;
|
||||
|
||||
decoder_ctx->get_format = get_hw_format;
|
||||
av_opt_set_int(decoder_ctx, "refcounted_frames", 1, 0);
|
||||
|
||||
if (hw_decoder_init(decoder_ctx, type) < 0)
|
||||
return -1;
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
/*
|
||||
* Video Acceleration API (video encoding) encode sample
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
/*
|
||||
* Video Acceleration API (video transcoding) transcode sample
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -155,8 +155,6 @@ space on each client, network bandwidth and so on benefit from smaller test case
|
||||
Also keep in mind older checkouts use existing sample files, that means in
|
||||
practice generally do not replace, remove or overwrite files as it likely would
|
||||
break older checkouts or releases.
|
||||
Also all needed samples for a commit should be uploaded, ideally 24
|
||||
hours, before the push.
|
||||
|
||||
@example
|
||||
#First update your local samples copy:
|
||||
@@ -224,11 +222,6 @@ Set to @samp{1} to generate the missing or mismatched references.
|
||||
Specify which hardware acceleration to use while running regression tests,
|
||||
by default @samp{none} is used.
|
||||
|
||||
@item KEEP
|
||||
Set to @samp{1} to keep temp files generated by fate test(s) when test is successful.
|
||||
Default is @samp{0}, which removes these files. Files are always kept when a test
|
||||
fails.
|
||||
|
||||
@end table
|
||||
|
||||
@section Examples
|
||||
|
||||
231
doc/ffmpeg.texi
231
doc/ffmpeg.texi
@@ -216,208 +216,16 @@ filters is obviously also impossible, since filters work on uncompressed data.
|
||||
@chapter Stream selection
|
||||
@c man begin STREAM SELECTION
|
||||
|
||||
@command{ffmpeg} provides the @code{-map} option for manual control of stream selection in each
|
||||
output file. Users can skip @code{-map} and let ffmpeg perform automatic stream selection as
|
||||
described below. The @code{-vn / -an / -sn / -dn} options can be used to skip inclusion of
|
||||
video, audio, subtitle and data streams respectively, whether manually mapped or automatically
|
||||
selected, except for those streams which are outputs of complex filtergraphs.
|
||||
By default, @command{ffmpeg} includes only one stream of each type (video, audio, subtitle)
|
||||
present in the input files and adds them to each output file. It picks the
|
||||
"best" of each based upon the following criteria: for video, it is the stream
|
||||
with the highest resolution, for audio, it is the stream with the most channels, for
|
||||
subtitles, it is the first subtitle stream. In the case where several streams of
|
||||
the same type rate equally, the stream with the lowest index is chosen.
|
||||
|
||||
@section Description
|
||||
The sub-sections that follow describe the various rules that are involved in stream selection.
|
||||
The examples that follow next show how these rules are applied in practice.
|
||||
|
||||
While every effort is made to accurately reflect the behavior of the program, FFmpeg is under
|
||||
continuous development and the code may have changed since the time of this writing.
|
||||
|
||||
@subsection Automatic stream selection
|
||||
|
||||
In the absence of any map options for a particular output file, ffmpeg inspects the output
|
||||
format to check which type of streams can be included in it, viz. video, audio and/or
|
||||
subtitles. For each acceptable stream type, ffmpeg will pick one stream, when available,
|
||||
from among all the inputs.
|
||||
|
||||
It will select that stream based upon the following criteria:
|
||||
@itemize
|
||||
@item
|
||||
for video, it is the stream with the highest resolution,
|
||||
@item
|
||||
for audio, it is the stream with the most channels,
|
||||
@item
|
||||
for subtitles, it is the first subtitle stream found but there's a caveat.
|
||||
The output format's default subtitle encoder can be either text-based or image-based,
|
||||
and only a subtitle stream of the same type will be chosen.
|
||||
@end itemize
|
||||
|
||||
In the case where several streams of the same type rate equally, the stream with the lowest
|
||||
index is chosen.
|
||||
|
||||
Data or attachment streams are not automatically selected and can only be included
|
||||
using @code{-map}.
|
||||
@subsection Manual stream selection
|
||||
|
||||
When @code{-map} is used, only user-mapped streams are included in that output file,
|
||||
with one possible exception for filtergraph outputs described below.
|
||||
|
||||
@subsection Complex filtergraphs
|
||||
|
||||
If there are any complex filtergraph output streams with unlabeled pads, they will be added
|
||||
to the first output file. This will lead to a fatal error if the stream type is not supported
|
||||
by the output format. In the absence of the map option, the inclusion of these streams leads
|
||||
to the automatic stream selection of their types being skipped. If map options are present,
|
||||
these filtergraph streams are included in addition to the mapped streams.
|
||||
|
||||
Complex filtergraph output streams with labeled pads must be mapped once and exactly once.
|
||||
|
||||
@subsection Stream handling
|
||||
|
||||
Stream handling is independent of stream selection, with an exception for subtitles described
|
||||
below. Stream handling is set via the @code{-codec} option addressed to streams within a
|
||||
specific @emph{output} file. In particular, codec options are applied by ffmpeg after the
|
||||
stream selection process and thus do not influence the latter. If no @code{-codec} option is
|
||||
specified for a stream type, ffmpeg will select the default encoder registered by the output
|
||||
file muxer.
|
||||
|
||||
An exception exists for subtitles. If a subtitle encoder is specified for an output file, the
|
||||
first subtitle stream found of any type, text or image, will be included. ffmpeg does not validate
|
||||
if the specified encoder can convert the selected stream or if the converted stream is acceptable
|
||||
within the output format. This applies generally as well: when the user sets an encoder manually,
|
||||
the stream selection process cannot check if the encoded stream can be muxed into the output file.
|
||||
If it cannot, ffmpeg will abort and @emph{all} output files will fail to be processed.
|
||||
|
||||
@section Examples
|
||||
|
||||
The following examples illustrate the behavior, quirks and limitations of ffmpeg's stream
|
||||
selection methods.
|
||||
|
||||
They assume the following three input files.
|
||||
|
||||
@verbatim
|
||||
|
||||
input file 'A.avi'
|
||||
stream 0: video 640x360
|
||||
stream 1: audio 2 channels
|
||||
|
||||
input file 'B.mp4'
|
||||
stream 0: video 1920x1080
|
||||
stream 1: audio 2 channels
|
||||
stream 2: subtitles (text)
|
||||
stream 3: audio 5.1 channels
|
||||
stream 4: subtitles (text)
|
||||
|
||||
input file 'C.mkv'
|
||||
stream 0: video 1280x720
|
||||
stream 1: audio 2 channels
|
||||
stream 2: subtitles (image)
|
||||
@end verbatim
|
||||
|
||||
@subsubheading Example: automatic stream selection
|
||||
@example
|
||||
ffmpeg -i A.avi -i B.mp4 out1.mkv out2.wav -map 1:a -c:a copy out3.mov
|
||||
@end example
|
||||
There are three output files specified, and for the first two, no @code{-map} options
|
||||
are set, so ffmpeg will select streams for these two files automatically.
|
||||
|
||||
@file{out1.mkv} is a Matroska container file and accepts video, audio and subtitle streams,
|
||||
so ffmpeg will try to select one of each type.@*
|
||||
For video, it will select @code{stream 0} from @file{B.mp4}, which has the highest
|
||||
resolution among all the input video streams.@*
|
||||
For audio, it will select @code{stream 3} from @file{B.mp4}, since it has the greatest
|
||||
number of channels.@*
|
||||
For subtitles, it will select @code{stream 2} from @file{B.mp4}, which is the first subtitle
|
||||
stream from among @file{A.avi} and @file{B.mp4}.
|
||||
|
||||
@file{out2.wav} accepts only audio streams, so only @code{stream 3} from @file{B.mp4} is
|
||||
selected.
|
||||
|
||||
For @file{out3.mov}, since a @code{-map} option is set, no automatic stream selection will
|
||||
occur. The @code{-map 1:a} option will select all audio streams from the second input
|
||||
@file{B.mp4}. No other streams will be included in this output file.
|
||||
|
||||
For the first two outputs, all included streams will be transcoded. The encoders chosen will
|
||||
be the default ones registered by each output format, which may not match the codec of the
|
||||
selected input streams.
|
||||
|
||||
For the third output, codec option for audio streams has been set
|
||||
to @code{copy}, so no decoding-filtering-encoding operations will occur, or @emph{can} occur.
|
||||
Packets of selected streams shall be conveyed from the input file and muxed within the output
|
||||
file.
|
||||
|
||||
@subsubheading Example: automatic subtitles selection
|
||||
@example
|
||||
ffmpeg -i C.mkv out1.mkv -c:s dvdsub -an out2.mkv
|
||||
@end example
|
||||
Although @file{out1.mkv} is a Matroska container file which accepts subtitle streams, only a
|
||||
video and audio stream shall be selected. The subtitle stream of @file{C.mkv} is image-based
|
||||
and the default subtitle encoder of the Matroska muxer is text-based, so a transcode operation
|
||||
for the subtitles is expected to fail and hence the stream isn't selected. However, in
|
||||
@file{out2.mkv}, a subtitle encoder is specified in the command and so, the subtitle stream is
|
||||
selected, in addition to the video stream. The presence of @code{-an} disables audio stream
|
||||
selection for @file{out2.mkv}.
|
||||
|
||||
@subsubheading Example: unlabeled filtergraph outputs
|
||||
@example
|
||||
ffmpeg -i A.avi -i C.mkv -i B.mp4 -filter_complex "overlay" out1.mp4 out2.srt
|
||||
@end example
|
||||
A filtergraph is setup here using the @code{-filter_complex} option and consists of a single
|
||||
video filter. The @code{overlay} filter requires exactly two video inputs, but none are
|
||||
specified, so the first two available video streams are used, those of @file{A.avi} and
|
||||
@file{C.mkv}. The output pad of the filter has no label and so is sent to the first output file
|
||||
@file{out1.mp4}. Due to this, automatic selection of the video stream is skipped, which would
|
||||
have selected the stream in @file{B.mp4}. The audio stream with most channels viz. @code{stream 3}
|
||||
in @file{B.mp4}, is chosen automatically. No subtitle stream is chosen however, since the MP4
|
||||
format has no default subtitle encoder registered, and the user hasn't specified a subtitle encoder.
|
||||
|
||||
The 2nd output file, @file{out2.srt}, only accepts text-based subtitle streams. So, even though
|
||||
the first subtitle stream available belongs to @file{C.mkv}, it is image-based and hence skipped.
|
||||
The selected stream, @code{stream 2} in @file{B.mp4}, is the first text-based subtitle stream.
|
||||
|
||||
@subsubheading Example: labeled filtergraph outputs
|
||||
@example
|
||||
ffmpeg -i A.avi -i B.mp4 -i C.mkv -filter_complex "[1:v]hue=s=0[outv];overlay;aresample" \
|
||||
-map '[outv]' -an out1.mp4 \
|
||||
out2.mkv \
|
||||
-map '[outv]' -map 1:a:0 out3.mkv
|
||||
@end example
|
||||
|
||||
The above command will fail, as the output pad labelled @code{[outv]} has been mapped twice.
|
||||
None of the output files shall be processed.
|
||||
|
||||
@example
|
||||
ffmpeg -i A.avi -i B.mp4 -i C.mkv -filter_complex "[1:v]hue=s=0[outv];overlay;aresample" \
|
||||
-an out1.mp4 \
|
||||
out2.mkv \
|
||||
-map 1:a:0 out3.mkv
|
||||
@end example
|
||||
|
||||
This command above will also fail as the hue filter output has a label, @code{[outv]},
|
||||
and hasn't been mapped anywhere.
|
||||
|
||||
The command should be modified as follows,
|
||||
@example
|
||||
ffmpeg -i A.avi -i B.mp4 -i C.mkv -filter_complex "[1:v]hue=s=0,split=2[outv1][outv2];overlay;aresample" \
|
||||
-map '[outv1]' -an out1.mp4 \
|
||||
out2.mkv \
|
||||
-map '[outv2]' -map 1:a:0 out3.mkv
|
||||
@end example
|
||||
The video stream from @file{B.mp4} is sent to the hue filter, whose output is cloned once using
|
||||
the split filter, and both outputs labelled. Then a copy each is mapped to the first and third
|
||||
output files.
|
||||
|
||||
The overlay filter, requiring two video inputs, uses the first two unused video streams. Those
|
||||
are the streams from @file{A.avi} and @file{C.mkv}. The overlay output isn't labelled, so it is
|
||||
sent to the first output file @file{out1.mp4}, regardless of the presence of the @code{-map} option.
|
||||
|
||||
The aresample filter is sent the first unused audio stream, that of @file{A.avi}. Since this filter
|
||||
output is also unlabelled, it too is mapped to the first output file. The presence of @code{-an}
|
||||
only suppresses automatic or manual stream selection of audio streams, not outputs sent from
|
||||
filtergraphs. Both these mapped streams shall be ordered before the mapped stream in @file{out1.mp4}.
|
||||
|
||||
The video, audio and subtitle streams mapped to @code{out2.mkv} are entirely determined by
|
||||
automatic stream selection.
|
||||
|
||||
@file{out3.mkv} consists of the cloned video output from the hue filter and the first audio
|
||||
stream from @file{B.mp4}.
|
||||
@*
|
||||
You can disable some of those defaults by using the @code{-vn/-an/-sn/-dn} options. For
|
||||
full manual control, use the @code{-map} option, which disables the defaults just
|
||||
described.
|
||||
|
||||
@c man end STREAM SELECTION
|
||||
|
||||
@@ -508,7 +316,7 @@ input until the timestamps reach @var{position}.
|
||||
@var{position} must be a time duration specification,
|
||||
see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
|
||||
@item -sseof @var{position} (@emph{input})
|
||||
@item -sseof @var{position} (@emph{input/output})
|
||||
|
||||
Like the @code{-ss} option but relative to the "end of file". That is negative
|
||||
values are earlier in the file, 0 is at EOF.
|
||||
@@ -567,31 +375,22 @@ The following dispositions are recognized:
|
||||
@item hearing_impaired
|
||||
@item visual_impaired
|
||||
@item clean_effects
|
||||
@item attached_pic
|
||||
@item captions
|
||||
@item descriptions
|
||||
@item dependent
|
||||
@item metadata
|
||||
@end table
|
||||
|
||||
For example, to make the second audio stream the default stream:
|
||||
@example
|
||||
ffmpeg -i in.mkv -c copy -disposition:a:1 default out.mkv
|
||||
ffmpeg -i in.mkv -disposition:a:1 default out.mkv
|
||||
@end example
|
||||
|
||||
To make the second subtitle stream the default stream and remove the default
|
||||
disposition from the first subtitle stream:
|
||||
@example
|
||||
ffmpeg -i in.mkv -c copy -disposition:s:0 0 -disposition:s:1 default out.mkv
|
||||
ffmpeg -i INPUT -disposition:s:0 0 -disposition:s:1 default OUTPUT
|
||||
@end example
|
||||
|
||||
To add an embedded cover/thumbnail:
|
||||
@example
|
||||
ffmpeg -i in.mp4 -i IMAGE -map 0 -map 1 -c copy -c:v:1 png -disposition:v:1 attached_pic out.mp4
|
||||
@end example
|
||||
|
||||
Not all muxers support embedded thumbnails, and those who do, only support a few formats, like JPEG or PNG.
|
||||
|
||||
@item -program [title=@var{title}:][program_num=@var{program_num}:]st=@var{stream}[:st=@var{stream}...] (@emph{output})
|
||||
|
||||
Creates a program with the specified @var{title}, @var{program_num} and adds the specified
|
||||
@@ -824,6 +623,8 @@ as the input (or graph output) and automatic conversions are disabled.
|
||||
|
||||
@item -sws_flags @var{flags} (@emph{input/output})
|
||||
Set SwScaler flags.
|
||||
@item -vdt @var{n}
|
||||
Discard threshold.
|
||||
|
||||
@item -rc_override[:@var{stream_specifier}] @var{override} (@emph{output,per-stream})
|
||||
Rate control override for specific intervals, formatted as "int,int,int"
|
||||
@@ -1353,12 +1154,12 @@ disable any chapter copying.
|
||||
|
||||
@item -benchmark (@emph{global})
|
||||
Show benchmarking information at the end of an encode.
|
||||
Shows real, system and user time used and maximum memory consumption.
|
||||
Shows CPU time used and maximum memory consumption.
|
||||
Maximum memory consumption is not supported on all systems,
|
||||
it will usually display as 0 if not supported.
|
||||
@item -benchmark_all (@emph{global})
|
||||
Show benchmarking information during the encode.
|
||||
Shows real, system and user time used in various steps (audio/video encode/decode).
|
||||
Shows CPU time used in various steps (audio/video encode/decode).
|
||||
@item -timelimit @var{duration} (@emph{global})
|
||||
Exit after ffmpeg has been running for @var{duration} seconds.
|
||||
@item -dump (@emph{global})
|
||||
|
||||
@@ -60,8 +60,6 @@ Play @var{duration} seconds of audio/video.
|
||||
see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
|
||||
@item -bytes
|
||||
Seek by bytes.
|
||||
@item -seek_interval
|
||||
Set custom interval, in seconds, for seeking using left/right keys. Default is 10 seconds.
|
||||
@item -nodisp
|
||||
Disable graphical display.
|
||||
@item -noborder
|
||||
@@ -74,10 +72,6 @@ as 100.
|
||||
Force format.
|
||||
@item -window_title @var{title}
|
||||
Set window title (default is the input filename).
|
||||
@item -left @var{title}
|
||||
Set the x position for the left of the window (default is a centered window).
|
||||
@item -top @var{title}
|
||||
Set the y position for the top of the window (default is a centered window).
|
||||
@item -loop @var{number}
|
||||
Loops movie playback <number> times. 0 means forever.
|
||||
@item -showmode @var{mode}
|
||||
|
||||
@@ -584,7 +584,7 @@ value is 0.
|
||||
This is required for generating an XML file which can be validated
|
||||
through an XSD file.
|
||||
|
||||
@item xsd_strict, x
|
||||
@item xsd_compliant, x
|
||||
If set to 1 perform more checks for ensuring that the output is XSD
|
||||
compliant. Default value is 0.
|
||||
This option automatically sets @option{fully_qualified} to 1.
|
||||
|
||||
1432
doc/filters.texi
1432
doc/filters.texi
File diff suppressed because it is too large
Load Diff
@@ -30,43 +30,37 @@ latency. Must be an integer not lesser than 32. It is 5000000 by default.
|
||||
@item packetsize @var{integer} (@emph{output})
|
||||
Set packet size.
|
||||
|
||||
@item fflags @var{flags}
|
||||
Set format flags. Some are implemented for a limited number of formats.
|
||||
@item fflags @var{flags} (@emph{input/output})
|
||||
Set format flags.
|
||||
|
||||
Possible values for input files:
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item discardcorrupt
|
||||
Discard corrupted packets.
|
||||
@item ignidx
|
||||
Ignore index.
|
||||
@item fastseek
|
||||
Enable fast, but inaccurate seeks for some formats.
|
||||
@item genpts
|
||||
Generate missing PTS if DTS is present.
|
||||
@item igndts
|
||||
Ignore DTS if PTS is set. Inert when nofillin is set.
|
||||
@item ignidx
|
||||
Ignore index.
|
||||
@item keepside (@emph{deprecated},@emph{inert})
|
||||
@item nobuffer
|
||||
Reduce the latency introduced by buffering during initial input streams analysis.
|
||||
Generate PTS.
|
||||
@item nofillin
|
||||
Do not fill in missing values in packet fields that can be exactly calculated.
|
||||
Do not fill in missing values that can be exactly calculated.
|
||||
@item noparse
|
||||
Disable AVParsers, this needs @code{+nofillin} too.
|
||||
@item igndts
|
||||
Ignore DTS.
|
||||
@item discardcorrupt
|
||||
Discard corrupted frames.
|
||||
@item sortdts
|
||||
Try to interleave output packets by DTS. At present, available only for AVIs with an index.
|
||||
@end table
|
||||
|
||||
Possible values for output files:
|
||||
@table @samp
|
||||
@item autobsf
|
||||
Automatically apply bitstream filters as required by the output format. Enabled by default.
|
||||
Try to interleave output packets by DTS.
|
||||
@item keepside
|
||||
Do not merge side data.
|
||||
@item latm
|
||||
Enable RTP MP4A-LATM payload.
|
||||
@item nobuffer
|
||||
Reduce the latency introduced by optional buffering
|
||||
@item bitexact
|
||||
Only write platform-, build- and time-independent data.
|
||||
This ensures that file and data checksums are reproducible and match between
|
||||
platforms. Its primary use is for regression testing.
|
||||
@item flush_packets
|
||||
Write out packets immediately.
|
||||
@item latm (@emph{deprecated},@emph{inert})
|
||||
@item shortest
|
||||
Stop muxing at the end of the shortest stream.
|
||||
It may be needed to increase max_interleave_delta to avoid flushing the longer
|
||||
@@ -220,10 +214,6 @@ ffprobe -dump_separator "
|
||||
@item max_streams @var{integer} (@emph{input})
|
||||
Specifies the maximum number of streams. This can be used to reject files that
|
||||
would require too many resources due to a large number of streams.
|
||||
|
||||
@item skip_estimate_duration_from_pts @var{bool} (@emph{input})
|
||||
Skip estimation of input duration when calculated using PTS.
|
||||
At present, applicable for MPEG-PS and MPEG-TS.
|
||||
@end table
|
||||
|
||||
@c man end FORMAT OPTIONS
|
||||
|
||||
@@ -17,34 +17,6 @@ for more formats. None of them are used by default, their use has to be
|
||||
explicitly requested by passing the appropriate flags to
|
||||
@command{./configure}.
|
||||
|
||||
@section libxavs2
|
||||
|
||||
FFmpeg can make use of the xavs2 library for AVS2-P2/IEEE1857.4 video encoding.
|
||||
|
||||
Go to @url{https://github.com/pkuvcl/xavs2} and follow the instructions for
|
||||
installing the library. Then pass @code{--enable-libxavs2} to configure to
|
||||
enable it.
|
||||
|
||||
@float NOTE
|
||||
libxavs2 is under the GNU Public License Version 2 or later
|
||||
(see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for
|
||||
details), you must upgrade FFmpeg's license to GPL in order to use it.
|
||||
@end float
|
||||
|
||||
@section libdavs2
|
||||
|
||||
FFmpeg can make use of the davs2 library for AVS2-P2/IEEE1857.4 video decoding.
|
||||
|
||||
Go to @url{https://github.com/pkuvcl/davs2} and follow the instructions for
|
||||
installing the library. Then pass @code{--enable-libdavs2} to configure to
|
||||
enable it.
|
||||
|
||||
@float NOTE
|
||||
libdavs2 is under the GNU Public License Version 2 or later
|
||||
(see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for
|
||||
details), you must upgrade FFmpeg's license to GPL in order to use it.
|
||||
@end float
|
||||
|
||||
@section Alliance for Open Media libaom
|
||||
|
||||
FFmpeg can make use of the libaom library for AV1 decoding.
|
||||
@@ -74,10 +46,9 @@ upgrade FFmpeg's license to LGPL version 3 (or if you have enabled
|
||||
GPL components, GPL version 3) by passing @code{--enable-version3} to configure in
|
||||
order to use it.
|
||||
|
||||
The license of the Fraunhofer AAC library is incompatible with the GPL.
|
||||
Therefore, for GPL builds, you have to pass @code{--enable-nonfree} to
|
||||
configure in order to use it. To the best of our knowledge, it is
|
||||
compatible with the LGPL.
|
||||
The Fraunhofer AAC library is licensed under a license incompatible to the GPL
|
||||
and is not known to be compatible to the LGPL. Therefore, you have to pass
|
||||
@code{--enable-nonfree} to configure to use it.
|
||||
@end float
|
||||
|
||||
@subsection OpenCORE AMR
|
||||
@@ -100,7 +71,7 @@ Then pass @code{--enable-libvo-amrwbenc} to configure to enable it.
|
||||
|
||||
@subsection Fraunhofer AAC library
|
||||
|
||||
FFmpeg can make use of the Fraunhofer AAC library for AAC decoding & encoding.
|
||||
FFmpeg can make use of the Fraunhofer AAC library for AAC encoding.
|
||||
|
||||
Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the
|
||||
instructions for installing the library.
|
||||
@@ -545,7 +516,6 @@ library:
|
||||
@item raw VC-1 @tab X @tab X
|
||||
@item raw PCM A-law @tab X @tab X
|
||||
@item raw PCM mu-law @tab X @tab X
|
||||
@item raw PCM Archimedes VIDC @tab X @tab X
|
||||
@item raw PCM signed 8 bit @tab X @tab X
|
||||
@item raw PCM signed 16 bit big-endian @tab X @tab X
|
||||
@item raw PCM signed 16 bit little-endian @tab X @tab X
|
||||
@@ -589,7 +559,6 @@ library:
|
||||
@item SAP @tab X @tab X
|
||||
@item SBG @tab @tab X
|
||||
@item SDP @tab @tab X
|
||||
@item SER @tab @tab X
|
||||
@item Sega FILM/CPK @tab X @tab X
|
||||
@tab Used in many Sega Saturn console games.
|
||||
@item Silicon Graphics Movie @tab @tab X
|
||||
@@ -833,7 +802,6 @@ following image formats are supported:
|
||||
@tab fourcc: G2M2, G2M3
|
||||
@item Go2Webinar @tab @tab X
|
||||
@tab fourcc: G2M4
|
||||
@item Gremlin Digital Video @tab @tab X
|
||||
@item H.261 @tab X @tab X
|
||||
@item H.263 / H.263-1996 @tab X @tab X
|
||||
@item H.263+ / H.263-1998 / H.263 version 2 @tab X @tab X
|
||||
@@ -854,7 +822,6 @@ following image formats are supported:
|
||||
@tab IFF interleaved bitmap
|
||||
@item IFF ByteRun1 @tab @tab X
|
||||
@tab IFF run length encoded bitmap
|
||||
@item Infinity IMM4 @tab @tab X
|
||||
@item Intel H.263 @tab @tab X
|
||||
@item Intel Indeo 2 @tab @tab X
|
||||
@item Intel Indeo 3 @tab @tab X
|
||||
@@ -1081,7 +1048,6 @@ following image formats are supported:
|
||||
@item ATRAC1 @tab @tab X
|
||||
@item ATRAC3 @tab @tab X
|
||||
@item ATRAC3+ @tab @tab X
|
||||
@item ATRAC9 @tab @tab X
|
||||
@item Bink Audio @tab @tab X
|
||||
@tab Used in Bink and Smacker files in many games.
|
||||
@item CELT @tab @tab E
|
||||
@@ -1148,7 +1114,6 @@ following image formats are supported:
|
||||
@tab encoding supported through external library libopus
|
||||
@item PCM A-law @tab X @tab X
|
||||
@item PCM mu-law @tab X @tab X
|
||||
@item PCM Archimedes VIDC @tab X @tab X
|
||||
@item PCM signed 8-bit planar @tab X @tab X
|
||||
@item PCM signed 16-bit big-endian planar @tab X @tab X
|
||||
@item PCM signed 16-bit little-endian planar @tab X @tab X
|
||||
|
||||
261
doc/indevs.texi
261
doc/indevs.texi
@@ -267,8 +267,7 @@ audio track.
|
||||
|
||||
@item list_devices
|
||||
If set to @option{true}, print a list of devices and exit.
|
||||
Defaults to @option{false}. Alternatively you can use the @code{-sources}
|
||||
option of ffmpeg to list the available input devices.
|
||||
Defaults to @option{false}.
|
||||
|
||||
@item list_formats
|
||||
If set to @option{true}, print a list of supported formats and exit.
|
||||
@@ -327,12 +326,6 @@ Defaults to @samp{2}.
|
||||
Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.
|
||||
Defaults to @samp{unset}.
|
||||
|
||||
@item timecode_format
|
||||
Timecode type to include in the frame and video stream metadata. Must be
|
||||
@samp{none}, @samp{rp188vitc}, @samp{rp188vitc2}, @samp{rp188ltc},
|
||||
@samp{rp188any}, @samp{vitc}, @samp{vitc2}, or @samp{serial}. Defaults to
|
||||
@samp{none} (not included).
|
||||
|
||||
@item video_input
|
||||
Sets the video input source. Must be @samp{unset}, @samp{sdi}, @samp{hdmi},
|
||||
@samp{optical_sdi}, @samp{component}, @samp{composite} or @samp{s_video}.
|
||||
@@ -371,20 +364,6 @@ If set to @option{true}, timestamps are forwarded as they are without removing
|
||||
the initial offset.
|
||||
Defaults to @option{false}.
|
||||
|
||||
@item timestamp_align
|
||||
Capture start time alignment in seconds. If set to nonzero, input frames are
|
||||
dropped till the system timestamp aligns with configured value.
|
||||
Alignment difference of upto one frame duration is tolerated.
|
||||
This is useful for maintaining input synchronization across N different
|
||||
hardware devices deployed for 'N-way' redundancy. The system time of different
|
||||
hardware devices should be synchronized with protocols such as NTP or PTP,
|
||||
before using this option.
|
||||
Note that this method is not foolproof. In some border cases input
|
||||
synchronization may not happen due to thread scheduling jitters in the OS.
|
||||
Either sync could go wrong by 1 frame or in a rarer case
|
||||
@option{timestamp_align} seconds.
|
||||
Defaults to @samp{0}.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
@@ -423,6 +402,116 @@ ffmpeg -channels 16 -format_code Hi50 -f decklink -i 'UltraStudio Mini Recorder'
|
||||
|
||||
@end itemize
|
||||
|
||||
@section kmsgrab
|
||||
|
||||
KMS video input device.
|
||||
|
||||
Captures the KMS scanout framebuffer associated with a specified CRTC or plane as a
|
||||
DRM object that can be passed to other hardware functions.
|
||||
|
||||
Requires either DRM master or CAP_SYS_ADMIN to run.
|
||||
|
||||
If you don't understand what all of that means, you probably don't want this. Look at
|
||||
@option{x11grab} instead.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item device
|
||||
DRM device to capture on. Defaults to @option{/dev/dri/card0}.
|
||||
|
||||
@item format
|
||||
Pixel format of the framebuffer. Defaults to @option{bgr0}.
|
||||
|
||||
@item format_modifier
|
||||
Format modifier to signal on output frames. This is necessary to import correctly into
|
||||
some APIs, but can't be autodetected. See the libdrm documentation for possible values.
|
||||
|
||||
@item crtc_id
|
||||
KMS CRTC ID to define the capture source. The first active plane on the given CRTC
|
||||
will be used.
|
||||
|
||||
@item plane_id
|
||||
KMS plane ID to define the capture source. Defaults to the first active plane found if
|
||||
neither @option{crtc_id} nor @option{plane_id} are specified.
|
||||
|
||||
@item framerate
|
||||
Framerate to capture at. This is not synchronised to any page flipping or framebuffer
|
||||
changes - it just defines the interval at which the framebuffer is sampled. Sampling
|
||||
faster than the framebuffer update rate will generate independent frames with the same
|
||||
content. Defaults to @code{30}.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
|
||||
@item
|
||||
Capture from the first active plane, download the result to normal frames and encode.
|
||||
This will only work if the framebuffer is both linear and mappable - if not, the result
|
||||
may be scrambled or fail to download.
|
||||
@example
|
||||
ffmpeg -f kmsgrab -i - -vf 'hwdownload,format=bgr0' output.mp4
|
||||
@end example
|
||||
|
||||
@item
|
||||
Capture from CRTC ID 42 at 60fps, map the result to VAAPI, convert to NV12 and encode as H.264.
|
||||
@example
|
||||
ffmpeg -crtc_id 42 -framerate 60 -f kmsgrab -i - -vf 'hwmap=derive_device=vaapi,scale_vaapi=w=1920:h=1080:format=nv12' -c:v h264_vaapi output.mp4
|
||||
@end example
|
||||
|
||||
@end itemize
|
||||
|
||||
@section libndi_newtek
|
||||
|
||||
The libndi_newtek input device provides capture capabilities for using NDI (Network
|
||||
Device Interface, standard created by NewTek).
|
||||
|
||||
Input filename is a NDI source name that could be found by sending -find_sources 1
|
||||
to command line - it has no specific syntax but human-readable formatted.
|
||||
|
||||
To enable this input device, you need the NDI SDK and you
|
||||
need to configure with the appropriate @code{--extra-cflags}
|
||||
and @code{--extra-ldflags}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item find_sources
|
||||
If set to @option{true}, print a list of found/available NDI sources and exit.
|
||||
Defaults to @option{false}.
|
||||
|
||||
@item wait_sources
|
||||
Override time to wait until the number of online sources have changed.
|
||||
Defaults to @option{0.5}.
|
||||
|
||||
@item allow_video_fields
|
||||
When this flag is @option{false}, all video that you receive will be progressive.
|
||||
Defaults to @option{true}.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
|
||||
@item
|
||||
List input devices:
|
||||
@example
|
||||
ffmpeg -f libndi_newtek -find_sources 1 -i dummy
|
||||
@end example
|
||||
|
||||
@item
|
||||
Restream to NDI:
|
||||
@example
|
||||
ffmpeg -f libndi_newtek -i "DEV-5.INTERNAL.M1STEREO.TV (NDI_SOURCE_NAME_1)" -f libndi_newtek -y NDI_SOURCE_NAME_2
|
||||
@end example
|
||||
|
||||
@end itemize
|
||||
|
||||
@section dshow
|
||||
|
||||
Windows DirectShow input device.
|
||||
@@ -850,68 +939,6 @@ Set the number of channels. Default is 2.
|
||||
|
||||
@end table
|
||||
|
||||
@section kmsgrab
|
||||
|
||||
KMS video input device.
|
||||
|
||||
Captures the KMS scanout framebuffer associated with a specified CRTC or plane as a
|
||||
DRM object that can be passed to other hardware functions.
|
||||
|
||||
Requires either DRM master or CAP_SYS_ADMIN to run.
|
||||
|
||||
If you don't understand what all of that means, you probably don't want this. Look at
|
||||
@option{x11grab} instead.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item device
|
||||
DRM device to capture on. Defaults to @option{/dev/dri/card0}.
|
||||
|
||||
@item format
|
||||
Pixel format of the framebuffer. Defaults to @option{bgr0}.
|
||||
|
||||
@item format_modifier
|
||||
Format modifier to signal on output frames. This is necessary to import correctly into
|
||||
some APIs, but can't be autodetected. See the libdrm documentation for possible values.
|
||||
|
||||
@item crtc_id
|
||||
KMS CRTC ID to define the capture source. The first active plane on the given CRTC
|
||||
will be used.
|
||||
|
||||
@item plane_id
|
||||
KMS plane ID to define the capture source. Defaults to the first active plane found if
|
||||
neither @option{crtc_id} nor @option{plane_id} are specified.
|
||||
|
||||
@item framerate
|
||||
Framerate to capture at. This is not synchronised to any page flipping or framebuffer
|
||||
changes - it just defines the interval at which the framebuffer is sampled. Sampling
|
||||
faster than the framebuffer update rate will generate independent frames with the same
|
||||
content. Defaults to @code{30}.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
|
||||
@item
|
||||
Capture from the first active plane, download the result to normal frames and encode.
|
||||
This will only work if the framebuffer is both linear and mappable - if not, the result
|
||||
may be scrambled or fail to download.
|
||||
@example
|
||||
ffmpeg -f kmsgrab -i - -vf 'hwdownload,format=bgr0' output.mp4
|
||||
@end example
|
||||
|
||||
@item
|
||||
Capture from CRTC ID 42 at 60fps, map the result to VAAPI, convert to NV12 and encode as H.264.
|
||||
@example
|
||||
ffmpeg -crtc_id 42 -framerate 60 -f kmsgrab -i - -vf 'hwmap=derive_device=vaapi,scale_vaapi=w=1920:h=1080:format=nv12' -c:v h264_vaapi output.mp4
|
||||
@end example
|
||||
|
||||
@end itemize
|
||||
|
||||
@section lavfi
|
||||
|
||||
Libavfilter input virtual device.
|
||||
@@ -1050,71 +1077,6 @@ IIDC1394 input device, based on libdc1394 and libraw1394.
|
||||
|
||||
Requires the configure option @code{--enable-libdc1394}.
|
||||
|
||||
@section libndi_newtek
|
||||
|
||||
The libndi_newtek input device provides capture capabilities for using NDI (Network
|
||||
Device Interface, standard created by NewTek).
|
||||
|
||||
Input filename is a NDI source name that could be found by sending -find_sources 1
|
||||
to command line - it has no specific syntax but human-readable formatted.
|
||||
|
||||
To enable this input device, you need the NDI SDK and you
|
||||
need to configure with the appropriate @code{--extra-cflags}
|
||||
and @code{--extra-ldflags}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item find_sources
|
||||
If set to @option{true}, print a list of found/available NDI sources and exit.
|
||||
Defaults to @option{false}.
|
||||
|
||||
@item wait_sources
|
||||
Override time to wait until the number of online sources have changed.
|
||||
Defaults to @option{0.5}.
|
||||
|
||||
@item allow_video_fields
|
||||
When this flag is @option{false}, all video that you receive will be progressive.
|
||||
Defaults to @option{true}.
|
||||
|
||||
@item extra_ips
|
||||
If is set to list of comma separated ip addresses, scan for sources not only
|
||||
using mDNS but also use unicast ip addresses specified by this list.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
|
||||
@item
|
||||
List input devices:
|
||||
@example
|
||||
ffmpeg -f libndi_newtek -find_sources 1 -i dummy
|
||||
@end example
|
||||
|
||||
@item
|
||||
List local and remote input devices:
|
||||
@example
|
||||
ffmpeg -f libndi_newtek -extra_ips "192.168.10.10" -find_sources 1 -i dummy
|
||||
@end example
|
||||
|
||||
@item
|
||||
Restream to NDI:
|
||||
@example
|
||||
ffmpeg -f libndi_newtek -i "DEV-5.INTERNAL.M1STEREO.TV (NDI_SOURCE_NAME_1)" -f libndi_newtek -y NDI_SOURCE_NAME_2
|
||||
@end example
|
||||
|
||||
@item
|
||||
Restream remote NDI to local NDI:
|
||||
@example
|
||||
ffmpeg -f libndi_newtek -extra_ips "192.168.10.10" -i "DEV-5.REMOTE.M1STEREO.TV (NDI_SOURCE_NAME_1)" -f libndi_newtek -y NDI_SOURCE_NAME_2
|
||||
@end example
|
||||
|
||||
|
||||
@end itemize
|
||||
|
||||
@section openal
|
||||
|
||||
The OpenAL input device provides audio capture on all systems with a
|
||||
@@ -1233,6 +1195,7 @@ Set the number of channels. Default is 2.
|
||||
|
||||
@end table
|
||||
|
||||
|
||||
@section pulse
|
||||
|
||||
PulseAudio input device.
|
||||
|
||||
@@ -95,6 +95,7 @@ Stuff that didn't reach the codebase:
|
||||
- 0cef06df0 checkasm: add HEVC MC tests
|
||||
- e7078e842 hevcdsp: add x86 SIMD for MC
|
||||
- 7993ec19a hevc: Add hevc_get_pixel_4/8/12/16/24/32/48/64
|
||||
- new bitstream reader (see http://ffmpeg.org/pipermail/ffmpeg-devel/2017-April/209609.html)
|
||||
- use av_cpu_max_align() instead of hardcoding alignment requirements (see https://ffmpeg.org/pipermail/ffmpeg-devel/2017-September/215834.html)
|
||||
- f44ec22e0 lavc: use av_cpu_max_align() instead of hardcoding alignment requirements
|
||||
- 4de220d2e frame: allow align=0 (meaning automatic) for av_frame_get_buffer()
|
||||
@@ -104,6 +105,7 @@ Stuff that didn't reach the codebase:
|
||||
Collateral damage that needs work locally:
|
||||
------------------------------------------
|
||||
|
||||
- Merge proresdec2.c and proresdec_lgpl.c
|
||||
- Merge proresenc_anatoliy.c and proresenc_kostya.c
|
||||
- Fix MIPS AC3 downmix
|
||||
|
||||
|
||||
@@ -47,8 +47,7 @@ We cannot provide help for scripts and/or third-party tools.
|
||||
@anchor{How do I ask a question or send a message to a mailing list?}
|
||||
@section How do I ask a question or send a message to a mailing list?
|
||||
|
||||
First you must @ref{How do I subscribe?, subscribe}. Then all you have to do is
|
||||
send an email:
|
||||
All you have to do is send an email:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
@@ -58,18 +57,49 @@ ffmpeg-user mailing list.
|
||||
@item
|
||||
Email @email{libav-user@@ffmpeg.org} to send a message to the
|
||||
libav-user mailing list.
|
||||
|
||||
@item
|
||||
Email @email{ffmpeg-devel@@ffmpeg.org} to send a message to the
|
||||
ffmpeg-devel mailing list.
|
||||
@end itemize
|
||||
|
||||
Note that the ffmpeg-devel mailing list does not require you to subscribe
|
||||
to send a message or patch, but ffmpeg-user and libav-user do require
|
||||
subscription.
|
||||
If you are not subscribed to the mailing list then your question must be
|
||||
manually approved. Approval may take several days, but the wait is
|
||||
usually less. If you want the message to be sent with no delay then you
|
||||
must subscribe first. See @ref{How do I subscribe?}
|
||||
|
||||
Please do not send a message, subscribe, and re-send the message: this
|
||||
results in duplicates, causes more work for the admins, and may lower
|
||||
your chance at getting an answer. However, you may do so if you first
|
||||
@ref{How do I delete my message in the moderation queue?, delete your original message from the moderation queue}.
|
||||
|
||||
@chapter Subscribing / Unsubscribing
|
||||
|
||||
@section What does subscribing do?
|
||||
|
||||
Subscribing allows two things:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Your messages will show up in the mailing list without waiting in the
|
||||
moderation queue and needing to be manually approved by a mailing list
|
||||
admin.
|
||||
|
||||
@item
|
||||
You will receive all messages to the mailing list including replies to
|
||||
your messages. Non-subscribed users do not receive any messages.
|
||||
@end itemize
|
||||
|
||||
@section Do I need to subscribe?
|
||||
|
||||
No. You can still send a message to the mailing list without
|
||||
subscribing. See @ref{How do I ask a question or send a message to a mailing list?}
|
||||
|
||||
However, your message will need to be manually approved by a mailing
|
||||
list admin, and you will not receive any mailing list messages or
|
||||
replies.
|
||||
|
||||
You can ask to be CCd in your message, but replying users will
|
||||
sometimes forget to do so.
|
||||
|
||||
You may also view and reply to messages via the @ref{Where are the archives?, archives}.
|
||||
|
||||
@anchor{How do I subscribe?}
|
||||
@section How do I subscribe?
|
||||
|
||||
@@ -104,6 +134,8 @@ must be manually approved by a mailing list admin:
|
||||
These are:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Messages from users who are @strong{not} subscribed.
|
||||
|
||||
@item
|
||||
Messages that exceed the @ref{What is the message size limit?, message size limit}.
|
||||
@@ -116,12 +148,13 @@ or is abusive towards others).
|
||||
|
||||
@section How long does it take for my message in the moderation queue to be approved?
|
||||
|
||||
The queue is usually checked daily to several times a week.
|
||||
The queue is usually checked once or twice a day, but on occasion
|
||||
several days may pass before someone checks the queue.
|
||||
|
||||
@anchor{How do I delete my message in the moderation queue?}
|
||||
@section How do I delete my message in the moderation queue?
|
||||
|
||||
You should have received an email with the subject @emph{Your message to <mailing list name> awaits moderator approval}.
|
||||
You should have received an email with the subject @emph{Your message to ffmpeg-user awaits moderator approval}.
|
||||
A link is in the message that will allow you to delete your message
|
||||
unless a mailing list admin already approved or rejected it.
|
||||
|
||||
@@ -142,9 +175,6 @@ Click the email link at the top of the message just under the subject
|
||||
title. The link will provide the proper headers to keep the message
|
||||
within the thread.
|
||||
|
||||
Note that you must be subscribed to send a message to the ffmpeg-user or
|
||||
libav-user mailing lists.
|
||||
|
||||
@section How do I search the archives?
|
||||
|
||||
Perform a site search using your favorite search engine. Example:
|
||||
@@ -173,8 +203,9 @@ Instead, use trimmed interleaved/inline replies (@url{https://lists.ffmpeg.org/p
|
||||
@anchor{What is the message size limit?}
|
||||
@section What is the message size limit?
|
||||
|
||||
The message size limit is 1000 kilobytes. Please provide links to larger files
|
||||
instead of attaching them.
|
||||
The message size limit is 500 kilobytes for the user lists and 1000
|
||||
kilobytes for ffmpeg-devel. Please provide links to larger files instead
|
||||
of attaching them.
|
||||
|
||||
@section Where can I upload sample files?
|
||||
|
||||
|
||||
162
doc/muxers.texi
162
doc/muxers.texi
@@ -226,12 +226,7 @@ ffmpeg -re -i <input> -map 0 -map 0 -c:a libfdk_aac -c:v libx264
|
||||
|
||||
@table @option
|
||||
@item -min_seg_duration @var{microseconds}
|
||||
This is a deprecated option to set the segment length in microseconds, use @var{seg_duration} instead.
|
||||
@item -seg_duration @var{duration}
|
||||
Set the segment length in seconds (fractional value can be set). The value is
|
||||
treated as average segment duration when @var{use_template} is enabled and
|
||||
@var{use_timeline} is disabled and as minimum segment duration for all the other
|
||||
use cases.
|
||||
Set the segment length in microseconds.
|
||||
@item -window_size @var{size}
|
||||
Set the maximum number of segments kept in the manifest.
|
||||
@item -extra_window_size @var{size}
|
||||
@@ -252,8 +247,6 @@ DASH-templated name to used for the initialization segment. Default is "init-str
|
||||
DASH-templated name to used for the media segments. Default is "chunk-stream$RepresentationID$-$Number%05d$.m4s"
|
||||
@item -utc_timing_url @var{utc_url}
|
||||
URL of the page that will return the UTC timestamp in ISO format. Example: "https://time.akamai.com/?iso"
|
||||
@item method @var{method}
|
||||
Use the given HTTP method to create output files. Generally set to PUT or POST.
|
||||
@item -http_user_agent @var{user_agent}
|
||||
Override User-Agent field in HTTP header. Applicable only for HTTP output.
|
||||
@item -http_persistent @var{http_persistent}
|
||||
@@ -273,30 +266,6 @@ To map all video (or audio) streams to an AdaptationSet, "v" (or "a") can be use
|
||||
When no assignment is defined, this defaults to an AdaptationSet for each stream.
|
||||
@item -timeout @var{timeout}
|
||||
Set timeout for socket I/O operations. Applicable only for HTTP output.
|
||||
@item -index_correction @var{index_correction}
|
||||
Enable (1) or Disable (0) segment index correction logic. Applicable only when
|
||||
@var{use_template} is enabled and @var{use_timeline} is disabled.
|
||||
|
||||
When enabled, the logic monitors the flow of segment indexes. If a streams's
|
||||
segment index value is not at the expected real time position, then the logic
|
||||
corrects that index value.
|
||||
|
||||
Typically this logic is needed in live streaming use cases. The network bandwidth
|
||||
fluctuations are common during long run streaming. Each fluctuation can cause
|
||||
the segment indexes fall behind the expected real time position.
|
||||
@item -format_options @var{options_list}
|
||||
Set container format (mp4/webm) options using a @code{:} separated list of
|
||||
key=value parameters. Values containing @code{:} special characters must be
|
||||
escaped.
|
||||
|
||||
@item dash_segment_type @var{dash_segment_type}
|
||||
Possible values:
|
||||
@item mp4
|
||||
If this flag is set, the dash segment files will be in in ISOBMFF format. This is the default format.
|
||||
|
||||
@item webm
|
||||
If this flag is set, the dash segment files will be in in WebM format.
|
||||
|
||||
@end table
|
||||
|
||||
@anchor{framecrc}
|
||||
@@ -617,7 +586,7 @@ This example will produce the playlist, @file{out.m3u8}, and segment files:
|
||||
but only the file name part without any path info will be contained in the m3u8 segment list.
|
||||
Should a relative path be specified, the path of the created segment
|
||||
files will be relative to the current working directory.
|
||||
When strftime_mkdir is set, the whole expanded value of @var{filename} will be written into the m3u8 segment list.
|
||||
When use_localtime_mkdir is set, the whole expanded value of @var{filename} will be written into the m3u8 segment list.
|
||||
|
||||
When @code{var_stream_map} is set with two or more variant streams, the
|
||||
@var{filename} pattern must contain the string "%v", this string specifies
|
||||
@@ -646,40 +615,34 @@ This example will produce the playlists segment file sets:
|
||||
@file{vs1/file_000.ts}, @file{vs1/file_001.ts}, @file{vs1/file_002.ts}, etc.
|
||||
|
||||
@item use_localtime
|
||||
Same as strftime option, will be deprecated.
|
||||
|
||||
@item strftime
|
||||
Use strftime() on @var{filename} to expand the segment filename with localtime.
|
||||
The segment number is also available in this mode, but to use it, you need to specify second_level_segment_index
|
||||
hls_flag and %%d will be the specifier.
|
||||
@example
|
||||
ffmpeg -i in.nut -strftime 1 -hls_segment_filename 'file-%Y%m%d-%s.ts' out.m3u8
|
||||
ffmpeg -i in.nut -use_localtime 1 -hls_segment_filename 'file-%Y%m%d-%s.ts' out.m3u8
|
||||
@end example
|
||||
This example will produce the playlist, @file{out.m3u8}, and segment files:
|
||||
@file{file-20160215-1455569023.ts}, @file{file-20160215-1455569024.ts}, etc.
|
||||
Note: On some systems/environments, the @code{%s} specifier is not available. See
|
||||
@code{strftime()} documentation.
|
||||
@example
|
||||
ffmpeg -i in.nut -strftime 1 -hls_flags second_level_segment_index -hls_segment_filename 'file-%Y%m%d-%%04d.ts' out.m3u8
|
||||
ffmpeg -i in.nut -use_localtime 1 -hls_flags second_level_segment_index -hls_segment_filename 'file-%Y%m%d-%%04d.ts' out.m3u8
|
||||
@end example
|
||||
This example will produce the playlist, @file{out.m3u8}, and segment files:
|
||||
@file{file-20160215-0001.ts}, @file{file-20160215-0002.ts}, etc.
|
||||
|
||||
@item use_localtime_mkdir
|
||||
Same as strftime_mkdir option, will be deprecated .
|
||||
|
||||
@item strftime_mkdir
|
||||
Used together with -strftime_mkdir, it will create all subdirectories which
|
||||
Used together with -use_localtime, it will create all subdirectories which
|
||||
is expanded in @var{filename}.
|
||||
@example
|
||||
ffmpeg -i in.nut -strftime 1 -strftime_mkdir 1 -hls_segment_filename '%Y%m%d/file-%Y%m%d-%s.ts' out.m3u8
|
||||
ffmpeg -i in.nut -use_localtime 1 -use_localtime_mkdir 1 -hls_segment_filename '%Y%m%d/file-%Y%m%d-%s.ts' out.m3u8
|
||||
@end example
|
||||
This example will create a directory 201560215 (if it does not exist), and then
|
||||
produce the playlist, @file{out.m3u8}, and segment files:
|
||||
@file{20160215/file-20160215-1455569023.ts}, @file{20160215/file-20160215-1455569024.ts}, etc.
|
||||
|
||||
@example
|
||||
ffmpeg -i in.nut -strftime 1 -strftime_mkdir 1 -hls_segment_filename '%Y/%m/%d/file-%Y%m%d-%s.ts' out.m3u8
|
||||
ffmpeg -i in.nut -use_localtime 1 -use_localtime_mkdir 1 -hls_segment_filename '%Y/%m/%d/file-%Y%m%d-%s.ts' out.m3u8
|
||||
@end example
|
||||
This example will create a directory hierarchy 2016/02/15 (if any of them do not exist), and then
|
||||
produce the playlist, @file{out.m3u8}, and segment files:
|
||||
@@ -764,17 +727,17 @@ Possible values:
|
||||
|
||||
@table @samp
|
||||
@item mpegts
|
||||
Output segment files in MPEG-2 Transport Stream format. This is
|
||||
compatible with all HLS versions.
|
||||
If this flag is set, the hls segment files will format to mpegts.
|
||||
the mpegts files is used in all hls versions.
|
||||
|
||||
@item fmp4
|
||||
Output segment files in fragmented MP4 format, similar to MPEG-DASH.
|
||||
fmp4 files may be used in HLS version 7 and above.
|
||||
If this flag is set, the hls segment files will format to fragment mp4 looks like dash.
|
||||
the fmp4 files is used in hls after version 7.
|
||||
|
||||
@end table
|
||||
|
||||
@item hls_fmp4_init_filename @var{filename}
|
||||
Set filename to the fragment files header file, default filename is @file{init.mp4}.
|
||||
set filename to the fragment files header file, default filename is @file{init.mp4}.
|
||||
|
||||
When @code{var_stream_map} is set with two or more variant streams, the
|
||||
@var{filename} pattern must contain the string "%v", this string specifies
|
||||
@@ -839,24 +802,24 @@ Generate @code{EXT-X-PROGRAM-DATE-TIME} tags.
|
||||
|
||||
@item second_level_segment_index
|
||||
Makes it possible to use segment indexes as %%d in hls_segment_filename expression
|
||||
besides date/time values when strftime is on.
|
||||
besides date/time values when use_localtime is on.
|
||||
To get fixed width numbers with trailing zeroes, %%0xd format is available where x is the required width.
|
||||
|
||||
@item second_level_segment_size
|
||||
Makes it possible to use segment sizes (counted in bytes) as %%s in hls_segment_filename
|
||||
expression besides date/time values when strftime is on.
|
||||
expression besides date/time values when use_localtime is on.
|
||||
To get fixed width numbers with trailing zeroes, %%0xs format is available where x is the required width.
|
||||
|
||||
@item second_level_segment_duration
|
||||
Makes it possible to use segment duration (calculated in microseconds) as %%t in hls_segment_filename
|
||||
expression besides date/time values when strftime is on.
|
||||
expression besides date/time values when use_localtime is on.
|
||||
To get fixed width numbers with trailing zeroes, %%0xt format is available where x is the required width.
|
||||
|
||||
@example
|
||||
ffmpeg -i sample.mpeg \
|
||||
-f hls -hls_time 3 -hls_list_size 5 \
|
||||
-hls_flags second_level_segment_index+second_level_segment_size+second_level_segment_duration \
|
||||
-strftime 1 -strftime_mkdir 1 -hls_segment_filename "segment_%Y%m%d%H%M%S_%%04d_%%08s_%%013t.ts" stream.m3u8
|
||||
-use_localtime 1 -use_localtime_mkdir 1 -hls_segment_filename "segment_%Y%m%d%H%M%S_%%04d_%%08s_%%013t.ts" stream.m3u8
|
||||
@end example
|
||||
This will produce segments like this:
|
||||
@file{segment_20170102194334_0003_00122200_0000003000000.ts}, @file{segment_20170102194334_0004_00120072_0000003000000.ts} etc.
|
||||
@@ -1350,18 +1313,6 @@ be negative. This enables the initial sample to have DTS/CTS of zero, and
|
||||
reduces the need for edit lists for some cases such as video tracks with
|
||||
B-frames. Additionally, eases conformance with the DASH-IF interoperability
|
||||
guidelines.
|
||||
|
||||
This option is implicitly set when writing ismv (Smooth Streaming) files.
|
||||
@item -write_prft
|
||||
Write producer time reference box (PRFT) with a specified time source for the
|
||||
NTP field in the PRFT box. Set value as @samp{wallclock} to specify timesource
|
||||
as wallclock time and @samp{pts} to specify timesource as input packets' PTS
|
||||
values.
|
||||
|
||||
Setting value to @samp{pts} is applicable only for a live encoding use case,
|
||||
where PTS values are set as as wallclock time at the source. For example, an
|
||||
encoding use case with decklink capture source where @option{video_pts} and
|
||||
@option{audio_pts} are set to @samp{abs_wallclock}.
|
||||
@end table
|
||||
|
||||
@subsection Example
|
||||
@@ -2070,35 +2021,20 @@ ffmpeg -re -i ... -c:v libx264 -c:a aac -f fifo -fifo_format flv -map 0:v -map 0
|
||||
@anchor{tee}
|
||||
@section tee
|
||||
|
||||
The tee muxer can be used to write the same data to several outputs, such as files or streams.
|
||||
It can be used, for example, to stream a video over a network and save it to disk at the same time.
|
||||
The tee muxer can be used to write the same data to several files or any
|
||||
other kind of muxer. It can be used, for example, to both stream a video to
|
||||
the network and save it to disk at the same time.
|
||||
|
||||
It is different from specifying several outputs to the @command{ffmpeg}
|
||||
command-line tool. With the tee muxer, the audio and video data will be encoded only once.
|
||||
With conventional multiple outputs, multiple encoding operations in parallel are initiated,
|
||||
which can be a very expensive process. The tee muxer is not useful when using the libavformat API
|
||||
directly because it is then possible to feed the same packets to several muxers directly.
|
||||
|
||||
Since the tee muxer does not represent any particular output format, ffmpeg cannot auto-select
|
||||
output streams. So all streams intended for output must be specified using @code{-map}. See
|
||||
the examples below.
|
||||
|
||||
Some encoders may need different options depending on the output format;
|
||||
the auto-detection of this can not work with the tee muxer, so they need to be explicitly specified.
|
||||
The main example is the @option{global_header} flag.
|
||||
|
||||
The slave outputs are specified in the file name given to the muxer,
|
||||
separated by '|'. If any of the slave name contains the '|' separator,
|
||||
leading or trailing spaces or any special character, those must be
|
||||
escaped (see @ref{quoting_and_escaping,,the "Quoting and escaping"
|
||||
section in the ffmpeg-utils(1) manual,ffmpeg-utils}).
|
||||
|
||||
@subsection Options
|
||||
command-line tool because the audio and video data will be encoded only once
|
||||
with the tee muxer; encoding can be a very expensive process. It is not
|
||||
useful when using the libavformat API directly because it is then possible
|
||||
to feed the same packets to several muxers directly.
|
||||
|
||||
@table @option
|
||||
|
||||
@item use_fifo @var{bool}
|
||||
If set to 1, slave outputs will be processed in separate threads using the @ref{fifo}
|
||||
If set to 1, slave outputs will be processed in separate thread using @ref{fifo}
|
||||
muxer. This allows to compensate for different speed/latency/reliability of
|
||||
outputs and setup transparent recovery. By default this feature is turned off.
|
||||
|
||||
@@ -2107,6 +2043,12 @@ Options to pass to fifo pseudo-muxer instances. See @ref{fifo}.
|
||||
|
||||
@end table
|
||||
|
||||
The slave outputs are specified in the file name given to the muxer,
|
||||
separated by '|'. If any of the slave name contains the '|' separator,
|
||||
leading or trailing spaces or any special character, it must be
|
||||
escaped (see @ref{quoting_and_escaping,,the "Quoting and escaping"
|
||||
section in the ffmpeg-utils(1) manual,ffmpeg-utils}).
|
||||
|
||||
Muxer options can be specified for each slave by prepending them as a list of
|
||||
@var{key}=@var{value} pairs separated by ':', between square brackets. If
|
||||
the options values contain a special character or the ':' separator, they
|
||||
@@ -2115,27 +2057,13 @@ must be escaped; note that this is a second level escaping.
|
||||
The following special options are also recognized:
|
||||
@table @option
|
||||
@item f
|
||||
Specify the format name. Required if it cannot be guessed from the
|
||||
output URL.
|
||||
Specify the format name. Useful if it cannot be guessed from the
|
||||
output name suffix.
|
||||
|
||||
@item bsfs[/@var{spec}]
|
||||
Specify a list of bitstream filters to apply to the specified
|
||||
output.
|
||||
|
||||
It is possible to specify to which streams a given bitstream filter
|
||||
applies, by appending a stream specifier to the option separated by
|
||||
@code{/}. @var{spec} must be a stream specifier (see @ref{Format
|
||||
stream specifiers}).
|
||||
|
||||
If the stream specifier is not specified, the bitstream filters will be
|
||||
applied to all streams in the output. This will cause that output operation
|
||||
to fail if the output contains streams to which the bitstream filter cannot
|
||||
be applied e.g. @code{h264_mp4toannexb} being applied to an output containing an audio stream.
|
||||
|
||||
Options for a bitstream filter must be specified in the form of @code{opt=value}.
|
||||
|
||||
Several bitstream filters can be specified, separated by ",".
|
||||
|
||||
@item use_fifo @var{bool}
|
||||
This allows to override tee muxer use_fifo option for individual slave muxer.
|
||||
|
||||
@@ -2143,13 +2071,19 @@ This allows to override tee muxer use_fifo option for individual slave muxer.
|
||||
This allows to override tee muxer fifo_options for individual slave muxer.
|
||||
See @ref{fifo}.
|
||||
|
||||
It is possible to specify to which streams a given bitstream filter
|
||||
applies, by appending a stream specifier to the option separated by
|
||||
@code{/}. @var{spec} must be a stream specifier (see @ref{Format
|
||||
stream specifiers}). If the stream specifier is not specified, the
|
||||
bitstream filters will be applied to all streams in the output.
|
||||
|
||||
Several bitstream filters can be specified, separated by ",".
|
||||
|
||||
@item select
|
||||
Select the streams that should be mapped to the slave output,
|
||||
specified by a stream specifier. If not specified, this defaults to
|
||||
all the mapped streams. This will cause that output operation to fail
|
||||
if the output format does not accept all mapped streams.
|
||||
|
||||
You may use multiple stream specifiers separated by commas (@code{,}) e.g.: @code{a:0,v}
|
||||
all the input streams. You may use multiple stream specifiers
|
||||
separated by commas (@code{,}) e.g.: @code{a:0,v}
|
||||
|
||||
@item onfail
|
||||
Specify behaviour on output failure. This can be set to either @code{abort} (which is
|
||||
@@ -2163,7 +2097,7 @@ will continue without being affected.
|
||||
@itemize
|
||||
@item
|
||||
Encode something and both archive it in a WebM file and stream it
|
||||
as MPEG-TS over UDP:
|
||||
as MPEG-TS over UDP (the streams need to be explicitly mapped):
|
||||
@example
|
||||
ffmpeg -i ... -c:v libx264 -c:a mp2 -f tee -map 0:v -map 0:a
|
||||
"archive-20121107.mkv|[f=mpegts]udp://10.0.1.255:1234/"
|
||||
@@ -2186,19 +2120,23 @@ option is applied to @file{out.aac} in order to make it contain only
|
||||
audio packets.
|
||||
@example
|
||||
ffmpeg -i ... -map 0 -flags +global_header -c:v libx264 -c:a aac
|
||||
-f tee "[bsfs/v=dump_extra=freq=keyframe]out.ts|[movflags=+faststart]out.mp4|[select=a]out.aac"
|
||||
-f tee "[bsfs/v=dump_extra]out.ts|[movflags=+faststart]out.mp4|[select=a]out.aac"
|
||||
@end example
|
||||
|
||||
@item
|
||||
As above, but select only stream @code{a:1} for the audio output. Note
|
||||
As below, but select only stream @code{a:1} for the audio output. Note
|
||||
that a second level escaping must be performed, as ":" is a special
|
||||
character used to separate options.
|
||||
@example
|
||||
ffmpeg -i ... -map 0 -flags +global_header -c:v libx264 -c:a aac
|
||||
-f tee "[bsfs/v=dump_extra=freq=keyframe]out.ts|[movflags=+faststart]out.mp4|[select=\'a:1\']out.aac"
|
||||
-f tee "[bsfs/v=dump_extra]out.ts|[movflags=+faststart]out.mp4|[select=\'a:1\']out.aac"
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
Note: some codecs may need different options depending on the output format;
|
||||
the auto-detection of this can not work with the tee muxer. The main example
|
||||
is the @option{global_header} flag.
|
||||
|
||||
@section webm_dash_manifest
|
||||
|
||||
WebM DASH Manifest muxer.
|
||||
|
||||
@@ -140,8 +140,7 @@ device with @command{-list_formats 1}. Audio sample rate is always 48 kHz.
|
||||
|
||||
@item list_devices
|
||||
If set to @option{true}, print a list of devices and exit.
|
||||
Defaults to @option{false}. Alternatively you can use the @code{-sinks}
|
||||
option of ffmpeg to list the available output devices.
|
||||
Defaults to @option{false}.
|
||||
|
||||
@item list_formats
|
||||
If set to @option{true}, print a list of supported formats and exit.
|
||||
@@ -151,10 +150,6 @@ Defaults to @option{false}.
|
||||
Amount of time to preroll video in seconds.
|
||||
Defaults to @option{0.5}.
|
||||
|
||||
@item duplex_mode
|
||||
Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.
|
||||
Defaults to @samp{unset}.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
@@ -187,35 +182,6 @@ ffmpeg -i test.avi -f decklink -pix_fmt uyvy422 -s 720x486 -r 24000/1001 'DeckLi
|
||||
|
||||
@end itemize
|
||||
|
||||
@section fbdev
|
||||
|
||||
Linux framebuffer output device.
|
||||
|
||||
The Linux framebuffer is a graphic hardware-independent abstraction
|
||||
layer to show graphics on a computer monitor, typically on the
|
||||
console. It is accessed through a file device node, usually
|
||||
@file{/dev/fb0}.
|
||||
|
||||
For more detailed information read the file
|
||||
@file{Documentation/fb/framebuffer.txt} included in the Linux source tree.
|
||||
|
||||
@subsection Options
|
||||
@table @option
|
||||
|
||||
@item xoffset
|
||||
@item yoffset
|
||||
Set x/y coordinate of top left corner. Default is 0.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
Play a file on framebuffer device @file{/dev/fb0}.
|
||||
Required pixel format depends on current framebuffer settings.
|
||||
@example
|
||||
ffmpeg -re -i INPUT -c:v rawvideo -pix_fmt bgra -f fbdev /dev/fb0
|
||||
@end example
|
||||
|
||||
See also @url{http://linux-fbdev.sourceforge.net/}, and fbset(1).
|
||||
|
||||
@section libndi_newtek
|
||||
|
||||
The libndi_newtek output device provides playback capabilities for using NDI (Network
|
||||
@@ -261,6 +227,35 @@ ffmpeg -i "udp://@@239.1.1.1:10480?fifo_size=1000000&overrun_nonfatal=1" -vf "sc
|
||||
|
||||
@end itemize
|
||||
|
||||
@section fbdev
|
||||
|
||||
Linux framebuffer output device.
|
||||
|
||||
The Linux framebuffer is a graphic hardware-independent abstraction
|
||||
layer to show graphics on a computer monitor, typically on the
|
||||
console. It is accessed through a file device node, usually
|
||||
@file{/dev/fb0}.
|
||||
|
||||
For more detailed information read the file
|
||||
@file{Documentation/fb/framebuffer.txt} included in the Linux source tree.
|
||||
|
||||
@subsection Options
|
||||
@table @option
|
||||
|
||||
@item xoffset
|
||||
@item yoffset
|
||||
Set x/y coordinate of top left corner. Default is 0.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
Play a file on framebuffer device @file{/dev/fb0}.
|
||||
Required pixel format depends on current framebuffer settings.
|
||||
@example
|
||||
ffmpeg -re -i INPUT -c:v rawvideo -pix_fmt bgra -f fbdev /dev/fb0
|
||||
@end example
|
||||
|
||||
See also @url{http://linux-fbdev.sourceforge.net/}, and fbset(1).
|
||||
|
||||
@section opengl
|
||||
OpenGL output device.
|
||||
|
||||
@@ -398,18 +393,9 @@ Set the SDL window size, can be a string of the form
|
||||
If not specified it defaults to the size of the input video,
|
||||
downscaled according to the aspect ratio.
|
||||
|
||||
@item window_x
|
||||
@item window_y
|
||||
Set the position of the window on the screen.
|
||||
|
||||
@item window_fullscreen
|
||||
Set fullscreen mode when non-zero value is provided.
|
||||
Default value is zero.
|
||||
|
||||
@item window_enable_quit
|
||||
Enable quit action (using window button or keyboard key)
|
||||
when non-zero value is provided.
|
||||
Default value is 1 (enable quit action)
|
||||
@end table
|
||||
|
||||
@subsection Interactive commands
|
||||
@@ -434,10 +420,6 @@ ffmpeg -i INPUT -c:v rawvideo -pix_fmt yuv420p -window_size qcif -f sdl "SDL out
|
||||
|
||||
sndio audio output device.
|
||||
|
||||
@section v4l2
|
||||
|
||||
Video4Linux2 output device.
|
||||
|
||||
@section xv
|
||||
|
||||
XV (XVideo) output device.
|
||||
|
||||
@@ -148,11 +148,16 @@ To target 32 bits replace @code{x86_64} with @code{i686} in the command above.
|
||||
|
||||
@section Microsoft Visual C++ or Intel C++ Compiler for Windows
|
||||
|
||||
FFmpeg can be built with MSVC 2013 or later.
|
||||
FFmpeg can be built with MSVC 2012 or earlier using a C99-to-C89 conversion utility
|
||||
and wrapper, or with MSVC 2013 and ICL natively.
|
||||
|
||||
You will need the following prerequisites:
|
||||
|
||||
@itemize
|
||||
@item @uref{https://github.com/libav/c99-to-c89/, C99-to-C89 Converter & Wrapper}
|
||||
(if using MSVC 2012 or earlier)
|
||||
@item @uref{http://code.google.com/p/msinttypes/, msinttypes}
|
||||
(if using MSVC 2012 or earlier)
|
||||
@item @uref{http://msys2.github.io/, MSYS2}
|
||||
@item @uref{http://www.nasm.us/, NASM}
|
||||
(Also available via MSYS2's package manager.)
|
||||
@@ -161,13 +166,16 @@ You will need the following prerequisites:
|
||||
To set up a proper environment in MSYS2, you need to run @code{msys_shell.bat} from
|
||||
the Visual Studio or Intel Compiler command prompt.
|
||||
|
||||
Place @code{yasm.exe} somewhere in your @code{PATH}.
|
||||
Place @code{yasm.exe} somewhere in your @code{PATH}. If using MSVC 2012 or
|
||||
earlier, place @code{c99wrap.exe} and @code{c99conv.exe} somewhere in your
|
||||
@code{PATH} as well.
|
||||
|
||||
Next, make sure any other headers and libs you want to use, such as zlib, are
|
||||
located in a spot that the compiler can see. Do so by modifying the @code{LIB}
|
||||
and @code{INCLUDE} environment variables to include the @strong{Windows-style}
|
||||
paths to these directories. Alternatively, you can try to use the
|
||||
@code{--extra-cflags}/@code{--extra-ldflags} configure options.
|
||||
@code{--extra-cflags}/@code{--extra-ldflags} configure options. If using MSVC
|
||||
2012 or earlier, place @code{inttypes.h} somewhere the compiler can see too.
|
||||
|
||||
Finally, run:
|
||||
|
||||
@@ -209,6 +217,8 @@ can see.
|
||||
|
||||
@item FFmpeg has been tested with the following on i686 and x86_64:
|
||||
@itemize
|
||||
@item Visual Studio 2010 Pro and Express
|
||||
@item Visual Studio 2012 Pro and Express
|
||||
@item Visual Studio 2013 Pro and Express
|
||||
@item Intel Composer XE 2013
|
||||
@item Intel Composer XE 2013 SP1
|
||||
|
||||
@@ -1210,17 +1210,6 @@ IP Type of Service. Applies to sender only. Default value is 0xB8.
|
||||
@item ipttl=@var{ttl}
|
||||
IP Time To Live. Applies to sender only. Default value is 64.
|
||||
|
||||
@item latency
|
||||
Timestamp-based Packet Delivery Delay.
|
||||
Used to absorb bursts of missed packet retransmissions.
|
||||
This flag sets both @option{rcvlatency} and @option{peerlatency}
|
||||
to the same value. Note that prior to version 1.3.0
|
||||
this is the only flag to set the latency, however
|
||||
this is effectively equivalent to setting @option{peerlatency},
|
||||
when side is sender and @option{rcvlatency}
|
||||
when side is receiver, and the bidirectional stream
|
||||
sending is not supported.
|
||||
|
||||
@item listen_timeout
|
||||
Set socket listen timeout.
|
||||
|
||||
@@ -1266,25 +1255,6 @@ only if @option{pbkeylen} is non-zero. It is used on
|
||||
the receiver only if the received data is encrypted.
|
||||
The configured passphrase cannot be recovered (write-only).
|
||||
|
||||
@item payload_size=@var{bytes}
|
||||
Sets the maximum declared size of a packet transferred
|
||||
during the single call to the sending function in Live
|
||||
mode. Use 0 if this value isn't used (which is default in
|
||||
file mode).
|
||||
Default is -1 (automatic), which typically means MPEG-TS;
|
||||
if you are going to use SRT
|
||||
to send any different kind of payload, such as, for example,
|
||||
wrapping a live stream in very small frames, then you can
|
||||
use a bigger maximum frame size, though not greater than
|
||||
1456 bytes.
|
||||
|
||||
@item pkt_size=@var{bytes}
|
||||
Alias for @samp{payload_size}.
|
||||
|
||||
@item peerlatency
|
||||
The latency value (as described in @option{rcvlatency}) that is
|
||||
set by the sender side as a minimum value for the receiver.
|
||||
|
||||
@item pbkeylen=@var{bytes}
|
||||
Sender encryption key length, in bytes.
|
||||
Only can be set to 0, 16, 24 and 32.
|
||||
@@ -1293,23 +1263,11 @@ Not required on receiver (set to 0),
|
||||
key size obtained from sender in HaiCrypt handshake.
|
||||
Default value is 0.
|
||||
|
||||
@item rcvlatency
|
||||
The time that should elapse since the moment when the
|
||||
packet was sent and the moment when it's delivered to
|
||||
the receiver application in the receiving function.
|
||||
This time should be a buffer time large enough to cover
|
||||
the time spent for sending, unexpectedly extended RTT
|
||||
time, and the time needed to retransmit the lost UDP
|
||||
packet. The effective latency value will be the maximum
|
||||
of this options' value and the value of @option{peerlatency}
|
||||
set by the peer side. Before version 1.3.0 this option
|
||||
is only available as @option{latency}.
|
||||
|
||||
@item recv_buffer_size=@var{bytes}
|
||||
Set UDP receive buffer size, expressed in bytes.
|
||||
Set receive buffer size, expressed in bytes.
|
||||
|
||||
@item send_buffer_size=@var{bytes}
|
||||
Set UDP send buffer size, expressed in bytes.
|
||||
Set send buffer size, expressed in bytes.
|
||||
|
||||
@item rw_timeout
|
||||
Set raise error timeout for read/write optations.
|
||||
@@ -1329,86 +1287,9 @@ have no chance of being delivered in time. It was
|
||||
automatically enabled in the sender if the receiver
|
||||
supports it.
|
||||
|
||||
@item sndbuf=@var{bytes}
|
||||
Set send buffer size, expressed in bytes.
|
||||
|
||||
@item rcvbuf=@var{bytes}
|
||||
Set receive buffer size, expressed in bytes.
|
||||
|
||||
Receive buffer must not be greater than @option{ffs}.
|
||||
|
||||
@item lossmaxttl=@var{packets}
|
||||
The value up to which the Reorder Tolerance may grow. When
|
||||
Reorder Tolerance is > 0, then packet loss report is delayed
|
||||
until that number of packets come in. Reorder Tolerance
|
||||
increases every time a "belated" packet has come, but it
|
||||
wasn't due to retransmission (that is, when UDP packets tend
|
||||
to come out of order), with the difference between the latest
|
||||
sequence and this packet's sequence, and not more than the
|
||||
value of this option. By default it's 0, which means that this
|
||||
mechanism is turned off, and the loss report is always sent
|
||||
immediately upon experiencing a "gap" in sequences.
|
||||
|
||||
@item minversion
|
||||
The minimum SRT version that is required from the peer. A connection
|
||||
to a peer that does not satisfy the minimum version requirement
|
||||
will be rejected.
|
||||
|
||||
The version format in hex is 0xXXYYZZ for x.y.z in human readable
|
||||
form.
|
||||
|
||||
@item streamid=@var{string}
|
||||
A string limited to 512 characters that can be set on the socket prior
|
||||
to connecting. This stream ID will be able to be retrieved by the
|
||||
listener side from the socket that is returned from srt_accept and
|
||||
was connected by a socket with that set stream ID. SRT does not enforce
|
||||
any special interpretation of the contents of this string.
|
||||
This option doesn’t make sense in Rendezvous connection; the result
|
||||
might be that simply one side will override the value from the other
|
||||
side and it’s the matter of luck which one would win
|
||||
|
||||
@item smoother=@var{live|file}
|
||||
The type of Smoother used for the transmission for that socket, which
|
||||
is responsible for the transmission and congestion control. The Smoother
|
||||
type must be exactly the same on both connecting parties, otherwise
|
||||
the connection is rejected.
|
||||
|
||||
@item messageapi=@var{1|0}
|
||||
When set, this socket uses the Message API, otherwise it uses Buffer
|
||||
API. Note that in live mode (see @option{transtype}) there’s only
|
||||
message API available. In File mode you can chose to use one of two modes:
|
||||
|
||||
Stream API (default, when this option is false). In this mode you may
|
||||
send as many data as you wish with one sending instruction, or even use
|
||||
dedicated functions that read directly from a file. The internal facility
|
||||
will take care of any speed and congestion control. When receiving, you
|
||||
can also receive as many data as desired, the data not extracted will be
|
||||
waiting for the next call. There is no boundary between data portions in
|
||||
the Stream mode.
|
||||
|
||||
Message API. In this mode your single sending instruction passes exactly
|
||||
one piece of data that has boundaries (a message). Contrary to Live mode,
|
||||
this message may span across multiple UDP packets and the only size
|
||||
limitation is that it shall fit as a whole in the sending buffer. The
|
||||
receiver shall use as large buffer as necessary to receive the message,
|
||||
otherwise the message will not be given up. When the message is not
|
||||
complete (not all packets received or there was a packet loss) it will
|
||||
not be given up.
|
||||
|
||||
@item transtype=@var{live|file}
|
||||
Sets the transmission type for the socket, in particular, setting this
|
||||
option sets multiple other parameters to their default values as required
|
||||
for a particular transmission type.
|
||||
|
||||
live: Set options as for live transmission. In this mode, you should
|
||||
send by one sending instruction only so many data that fit in one UDP packet,
|
||||
and limited to the value defined first in @option{payload_size} (1316 is
|
||||
default in this mode). There is no speed control in this mode, only the
|
||||
bandwidth control, if configured, in order to not exceed the bandwidth with
|
||||
the overhead transmission (retransmitted and control packets).
|
||||
|
||||
file: Set options as for non-live transmission. See @option{messageapi}
|
||||
for further explanations
|
||||
@item tsbpddelay
|
||||
Timestamp-based Packet Delivery Delay.
|
||||
Used to absorb burst of missed packet retransmission.
|
||||
|
||||
@end table
|
||||
|
||||
@@ -1516,9 +1397,6 @@ Set send buffer size, expressed bytes.
|
||||
|
||||
@item tcp_nodelay=@var{1|0}
|
||||
Set TCP_NODELAY to disable Nagle's algorithm. Default value is 0.
|
||||
|
||||
@item tcp_mss=@var{bytes}
|
||||
Set maximum segment size for outgoing TCP packets, expressed in bytes.
|
||||
@end table
|
||||
|
||||
The following example shows how to setup a listening TCP connection
|
||||
@@ -1625,8 +1503,9 @@ packet bursts.
|
||||
Override the local UDP port to bind with.
|
||||
|
||||
@item localaddr=@var{addr}
|
||||
Local IP address of a network interface used for sending packets or joining
|
||||
multicast groups.
|
||||
Choose the local IP address. This is useful e.g. if sending multicast
|
||||
and the host has multiple interfaces, where the user can choose
|
||||
which interface to send on by specifying the IP address of that interface.
|
||||
|
||||
@item pkt_size=@var{size}
|
||||
Set the size in bytes of UDP packets.
|
||||
@@ -1649,12 +1528,12 @@ For receiving, this gives the benefit of only receiving packets from
|
||||
the specified peer address/port.
|
||||
|
||||
@item sources=@var{address}[,@var{address}]
|
||||
Only receive packets sent from the specified addresses. In case of multicast,
|
||||
also subscribe to multicast traffic coming from these addresses only.
|
||||
Only receive packets sent to the multicast group from one of the
|
||||
specified sender IP addresses.
|
||||
|
||||
@item block=@var{address}[,@var{address}]
|
||||
Ignore packets sent from the specified addresses. In case of multicast, also
|
||||
exclude the source addresses in the multicast subscription.
|
||||
Ignore packets sent to the multicast group from the specified
|
||||
sender IP addresses.
|
||||
|
||||
@item fifo_size=@var{units}
|
||||
Set the UDP receiving circular buffer size, expressed as a number of
|
||||
|
||||
@@ -1018,7 +1018,7 @@ static int init_report(const char *env)
|
||||
av_free(key);
|
||||
}
|
||||
|
||||
av_bprint_init(&filename, 0, AV_BPRINT_SIZE_AUTOMATIC);
|
||||
av_bprint_init(&filename, 0, 1);
|
||||
expand_filename_template(&filename,
|
||||
av_x_if_null(filename_template, "%p-%t.log"), tm);
|
||||
av_free(filename_template);
|
||||
@@ -1414,16 +1414,6 @@ static void print_codec(const AVCodec *c)
|
||||
AV_CODEC_CAP_SLICE_THREADS |
|
||||
AV_CODEC_CAP_AUTO_THREADS))
|
||||
printf("threads ");
|
||||
if (c->capabilities & AV_CODEC_CAP_AVOID_PROBING)
|
||||
printf("avoidprobe ");
|
||||
if (c->capabilities & AV_CODEC_CAP_INTRA_ONLY)
|
||||
printf("intraonly ");
|
||||
if (c->capabilities & AV_CODEC_CAP_LOSSLESS)
|
||||
printf("lossless ");
|
||||
if (c->capabilities & AV_CODEC_CAP_HARDWARE)
|
||||
printf("hardware ");
|
||||
if (c->capabilities & AV_CODEC_CAP_HYBRID)
|
||||
printf("hybrid ");
|
||||
if (!c->capabilities)
|
||||
printf("none");
|
||||
printf("\n");
|
||||
@@ -1444,17 +1434,6 @@ static void print_codec(const AVCodec *c)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (avcodec_get_hw_config(c, 0)) {
|
||||
printf(" Supported hardware devices: ");
|
||||
for (int i = 0;; i++) {
|
||||
const AVCodecHWConfig *config = avcodec_get_hw_config(c, i);
|
||||
if (!config)
|
||||
break;
|
||||
printf("%s ", av_hwdevice_get_type_name(config->device_type));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (c->supported_framerates) {
|
||||
const AVRational *fps = c->supported_framerates;
|
||||
|
||||
@@ -1956,10 +1935,7 @@ static void show_help_bsf(const char *name)
|
||||
{
|
||||
const AVBitStreamFilter *bsf = av_bsf_get_by_name(name);
|
||||
|
||||
if (!name) {
|
||||
av_log(NULL, AV_LOG_ERROR, "No bitstream filter name specified.\n");
|
||||
return;
|
||||
} else if (!bsf) {
|
||||
if (!bsf) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Unknown bit stream filter '%s'.\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
127
fftools/ffmpeg.c
127
fftools/ffmpeg.c
@@ -120,14 +120,8 @@ const char *const forced_keyframes_const_names[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
typedef struct BenchmarkTimeStamps {
|
||||
int64_t real_usec;
|
||||
int64_t user_usec;
|
||||
int64_t sys_usec;
|
||||
} BenchmarkTimeStamps;
|
||||
|
||||
static void do_video_stats(OutputStream *ost, int frame_size);
|
||||
static BenchmarkTimeStamps get_benchmark_time_stamps(void);
|
||||
static int64_t getutime(void);
|
||||
static int64_t getmaxrss(void);
|
||||
static int ifilter_has_all_input_formats(FilterGraph *fg);
|
||||
|
||||
@@ -139,7 +133,7 @@ static int64_t decode_error_stat[2];
|
||||
|
||||
static int want_sdp = 1;
|
||||
|
||||
static BenchmarkTimeStamps current_time;
|
||||
static int current_time;
|
||||
AVIOContext *progress_avio = NULL;
|
||||
|
||||
static uint8_t *subtitle_out;
|
||||
@@ -659,7 +653,7 @@ static void abort_codec_experimental(AVCodec *c, int encoder)
|
||||
static void update_benchmark(const char *fmt, ...)
|
||||
{
|
||||
if (do_benchmark_all) {
|
||||
BenchmarkTimeStamps t = get_benchmark_time_stamps();
|
||||
int64_t t = getutime();
|
||||
va_list va;
|
||||
char buf[1024];
|
||||
|
||||
@@ -667,11 +661,7 @@ static void update_benchmark(const char *fmt, ...)
|
||||
va_start(va, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, va);
|
||||
va_end(va);
|
||||
av_log(NULL, AV_LOG_INFO,
|
||||
"bench: %8" PRIu64 " user %8" PRIu64 " sys %8" PRIu64 " real %s \n",
|
||||
t.user_usec - current_time.user_usec,
|
||||
t.sys_usec - current_time.sys_usec,
|
||||
t.real_usec - current_time.real_usec, buf);
|
||||
av_log(NULL, AV_LOG_INFO, "bench: %8"PRIu64" %s \n", t - current_time, buf);
|
||||
}
|
||||
current_time = t;
|
||||
}
|
||||
@@ -724,11 +714,11 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int u
|
||||
if (ret < 0)
|
||||
exit_program(1);
|
||||
}
|
||||
ret = av_packet_make_refcounted(pkt);
|
||||
ret = av_packet_ref(&tmp_pkt, pkt);
|
||||
if (ret < 0)
|
||||
exit_program(1);
|
||||
av_packet_move_ref(&tmp_pkt, pkt);
|
||||
av_fifo_generic_write(ost->muxing_queue, &tmp_pkt, sizeof(tmp_pkt), NULL);
|
||||
av_packet_unref(pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -772,7 +762,7 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int u
|
||||
- FFMIN3(pkt->pts, pkt->dts, ost->last_mux_dts + 1)
|
||||
- FFMAX3(pkt->pts, pkt->dts, ost->last_mux_dts + 1);
|
||||
}
|
||||
if ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) &&
|
||||
if ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) &&
|
||||
pkt->dts != AV_NOPTS_VALUE &&
|
||||
!(st->codecpar->codec_id == AV_CODEC_ID_VP9 && ost->stream_copy) &&
|
||||
ost->last_mux_dts != AV_NOPTS_VALUE) {
|
||||
@@ -1121,7 +1111,7 @@ static void do_video_out(OutputFile *of,
|
||||
format_video_sync != VSYNC_PASSTHROUGH &&
|
||||
format_video_sync != VSYNC_DROP) {
|
||||
if (delta0 < -0.6) {
|
||||
av_log(NULL, AV_LOG_VERBOSE, "Past duration %f too large\n", -delta0);
|
||||
av_log(NULL, AV_LOG_WARNING, "Past duration %f too large\n", -delta0);
|
||||
} else
|
||||
av_log(NULL, AV_LOG_DEBUG, "Clipping frame in rate conversion by %f\n", -delta0);
|
||||
sync_ipts = ost->sync_opts;
|
||||
@@ -1236,12 +1226,8 @@ static void do_video_out(OutputFile *of,
|
||||
in_picture->quality = enc->global_quality;
|
||||
in_picture->pict_type = 0;
|
||||
|
||||
if (ost->forced_kf_ref_pts == AV_NOPTS_VALUE &&
|
||||
in_picture->pts != AV_NOPTS_VALUE)
|
||||
ost->forced_kf_ref_pts = in_picture->pts;
|
||||
|
||||
pts_time = in_picture->pts != AV_NOPTS_VALUE ?
|
||||
(in_picture->pts - ost->forced_kf_ref_pts) * av_q2d(enc->time_base) : NAN;
|
||||
in_picture->pts * av_q2d(enc->time_base) : NAN;
|
||||
if (ost->forced_kf_index < ost->forced_kf_count &&
|
||||
in_picture->pts >= ost->forced_kf_pts[ost->forced_kf_index]) {
|
||||
ost->forced_kf_index++;
|
||||
@@ -1689,7 +1675,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
||||
|
||||
vid = 0;
|
||||
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
|
||||
av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
|
||||
av_bprint_init(&buf_script, 0, 1);
|
||||
for (i = 0; i < nb_output_streams; i++) {
|
||||
float q = -1;
|
||||
ost = output_streams[i];
|
||||
@@ -1710,7 +1696,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
||||
av_bprintf(&buf, "frame=%5d fps=%3.*f q=%3.1f ",
|
||||
frame_number, fps < 9.95, fps, q);
|
||||
av_bprintf(&buf_script, "frame=%d\n", frame_number);
|
||||
av_bprintf(&buf_script, "fps=%.2f\n", fps);
|
||||
av_bprintf(&buf_script, "fps=%.1f\n", fps);
|
||||
av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
|
||||
ost->file_index, ost->index, q);
|
||||
if (is_last_report)
|
||||
@@ -1794,11 +1780,9 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
||||
if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
|
||||
else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
|
||||
if (pts == AV_NOPTS_VALUE) {
|
||||
av_bprintf(&buf_script, "out_time_us=N/A\n");
|
||||
av_bprintf(&buf_script, "out_time_ms=N/A\n");
|
||||
av_bprintf(&buf_script, "out_time=N/A\n");
|
||||
} else {
|
||||
av_bprintf(&buf_script, "out_time_us=%"PRId64"\n", pts);
|
||||
av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
|
||||
av_bprintf(&buf_script, "out_time=%s%02d:%02d:%02d.%06d\n",
|
||||
hours_sign, hours, mins, secs, us);
|
||||
@@ -2110,12 +2094,10 @@ static void check_decode_result(InputStream *ist, int *got_output, int ret)
|
||||
if (ret < 0 && exit_on_error)
|
||||
exit_program(1);
|
||||
|
||||
if (*got_output && ist) {
|
||||
if (exit_on_error && *got_output && ist) {
|
||||
if (ist->decoded_frame->decode_error_flags || (ist->decoded_frame->flags & AV_FRAME_FLAG_CORRUPT)) {
|
||||
av_log(NULL, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING,
|
||||
"%s: corrupt decoded frame in stream %d\n", input_files[ist->file_index]->ctx->url, ist->st->index);
|
||||
if (exit_on_error)
|
||||
exit_program(1);
|
||||
av_log(NULL, AV_LOG_FATAL, "%s: corrupt decoded frame in stream %d\n", input_files[ist->file_index]->ctx->url, ist->st->index);
|
||||
exit_program(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2139,9 +2121,6 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
|
||||
|
||||
/* determine if the parameters for this input changed */
|
||||
need_reinit = ifilter->format != frame->format;
|
||||
if (!!ifilter->hw_frames_ctx != !!frame->hw_frames_ctx ||
|
||||
(ifilter->hw_frames_ctx && ifilter->hw_frames_ctx->data != frame->hw_frames_ctx->data))
|
||||
need_reinit = 1;
|
||||
|
||||
switch (ifilter->ist->st->codecpar->codec_type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
@@ -2155,6 +2134,13 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ifilter->ist->reinit_filters && fg->graph)
|
||||
need_reinit = 0;
|
||||
|
||||
if (!!ifilter->hw_frames_ctx != !!frame->hw_frames_ctx ||
|
||||
(ifilter->hw_frames_ctx && ifilter->hw_frames_ctx->data != frame->hw_frames_ctx->data))
|
||||
need_reinit = 1;
|
||||
|
||||
if (need_reinit) {
|
||||
ret = ifilter_parameters_from_frame(ifilter, frame);
|
||||
if (ret < 0)
|
||||
@@ -2714,7 +2700,6 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
|
||||
ist->dts = ist->next_dts;
|
||||
switch (ist->dec_ctx->codec_type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
av_assert1(pkt->duration >= 0);
|
||||
if (ist->dec_ctx->sample_rate) {
|
||||
ist->next_dts += ((int64_t)AV_TIME_BASE * ist->dec_ctx->frame_size) /
|
||||
ist->dec_ctx->sample_rate;
|
||||
@@ -3074,13 +3059,7 @@ static int init_output_stream_streamcopy(OutputStream *ost)
|
||||
"Error setting up codec context options.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = avcodec_parameters_from_context(par_src, ost->enc_ctx);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL,
|
||||
"Error getting reference codec parameters.\n");
|
||||
return ret;
|
||||
}
|
||||
avcodec_parameters_from_context(par_src, ost->enc_ctx);
|
||||
|
||||
if (!codec_tag) {
|
||||
unsigned int codec_tag_tmp;
|
||||
@@ -3408,12 +3387,6 @@ static int init_output_stream_encode(OutputStream *ost)
|
||||
enc_ctx->bits_per_raw_sample = frame_bits_per_raw_sample;
|
||||
}
|
||||
|
||||
if (ost->top_field_first == 0) {
|
||||
enc_ctx->field_order = AV_FIELD_BB;
|
||||
} else if (ost->top_field_first == 1) {
|
||||
enc_ctx->field_order = AV_FIELD_TT;
|
||||
}
|
||||
|
||||
if (ost->forced_keyframes) {
|
||||
if (!strncmp(ost->forced_keyframes, "expr:", 5)) {
|
||||
ret = av_expr_parse(&ost->forced_keyframes_pexpr, ost->forced_keyframes+5,
|
||||
@@ -3500,23 +3473,6 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (ist && ist->dec->type == AVMEDIA_TYPE_SUBTITLE && ost->enc->type == AVMEDIA_TYPE_SUBTITLE) {
|
||||
int input_props = 0, output_props = 0;
|
||||
AVCodecDescriptor const *input_descriptor =
|
||||
avcodec_descriptor_get(dec->codec_id);
|
||||
AVCodecDescriptor const *output_descriptor =
|
||||
avcodec_descriptor_get(ost->enc_ctx->codec_id);
|
||||
if (input_descriptor)
|
||||
input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
|
||||
if (output_descriptor)
|
||||
output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
|
||||
if (input_props && output_props && input_props != output_props) {
|
||||
snprintf(error, error_len,
|
||||
"Subtitle encoding currently only possible from text to text "
|
||||
"or bitmap to bitmap");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret = avcodec_open2(ost->enc_ctx, codec, &ost->encoder_opts)) < 0) {
|
||||
if (ret == AVERROR_EXPERIMENTAL)
|
||||
@@ -4352,11 +4308,9 @@ static int process_input(int file_index)
|
||||
if (ist->discard)
|
||||
goto discard_packet;
|
||||
|
||||
if (pkt.flags & AV_PKT_FLAG_CORRUPT) {
|
||||
av_log(NULL, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING,
|
||||
"%s: corrupt input packet in stream %d\n", is->url, pkt.stream_index);
|
||||
if (exit_on_error)
|
||||
exit_program(1);
|
||||
if (exit_on_error && (pkt.flags & AV_PKT_FLAG_CORRUPT)) {
|
||||
av_log(NULL, AV_LOG_FATAL, "%s: corrupt input packet in stream %d\n", is->url, pkt.stream_index);
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
if (debug_ts) {
|
||||
@@ -4791,30 +4745,23 @@ static int transcode(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BenchmarkTimeStamps get_benchmark_time_stamps(void)
|
||||
|
||||
static int64_t getutime(void)
|
||||
{
|
||||
BenchmarkTimeStamps time_stamps = { av_gettime_relative() };
|
||||
#if HAVE_GETRUSAGE
|
||||
struct rusage rusage;
|
||||
|
||||
getrusage(RUSAGE_SELF, &rusage);
|
||||
time_stamps.user_usec =
|
||||
(rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
|
||||
time_stamps.sys_usec =
|
||||
(rusage.ru_stime.tv_sec * 1000000LL) + rusage.ru_stime.tv_usec;
|
||||
return (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
|
||||
#elif HAVE_GETPROCESSTIMES
|
||||
HANDLE proc;
|
||||
FILETIME c, e, k, u;
|
||||
proc = GetCurrentProcess();
|
||||
GetProcessTimes(proc, &c, &e, &k, &u);
|
||||
time_stamps.user_usec =
|
||||
((int64_t)u.dwHighDateTime << 32 | u.dwLowDateTime) / 10;
|
||||
time_stamps.sys_usec =
|
||||
((int64_t)k.dwHighDateTime << 32 | k.dwLowDateTime) / 10;
|
||||
return ((int64_t) u.dwHighDateTime << 32 | u.dwLowDateTime) / 10;
|
||||
#else
|
||||
time_stamps.user_usec = time_stamps.sys_usec = 0;
|
||||
return av_gettime_relative();
|
||||
#endif
|
||||
return time_stamps;
|
||||
}
|
||||
|
||||
static int64_t getmaxrss(void)
|
||||
@@ -4842,7 +4789,7 @@ static void log_callback_null(void *ptr, int level, const char *fmt, va_list vl)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, ret;
|
||||
BenchmarkTimeStamps ti;
|
||||
int64_t ti;
|
||||
|
||||
init_dynload();
|
||||
|
||||
@@ -4894,18 +4841,12 @@ int main(int argc, char **argv)
|
||||
want_sdp = 0;
|
||||
}
|
||||
|
||||
current_time = ti = get_benchmark_time_stamps();
|
||||
current_time = ti = getutime();
|
||||
if (transcode() < 0)
|
||||
exit_program(1);
|
||||
ti = getutime() - ti;
|
||||
if (do_benchmark) {
|
||||
int64_t utime, stime, rtime;
|
||||
current_time = get_benchmark_time_stamps();
|
||||
utime = current_time.user_usec - ti.user_usec;
|
||||
stime = current_time.sys_usec - ti.sys_usec;
|
||||
rtime = current_time.real_usec - ti.real_usec;
|
||||
av_log(NULL, AV_LOG_INFO,
|
||||
"bench: utime=%0.3fs stime=%0.3fs rtime=%0.3fs\n",
|
||||
utime / 1000000.0, stime / 1000000.0, rtime / 1000000.0);
|
||||
av_log(NULL, AV_LOG_INFO, "bench: utime=%0.3fs\n", ti / 1000000.0);
|
||||
}
|
||||
av_log(NULL, AV_LOG_DEBUG, "%"PRIu64" frames successfully decoded, %"PRIu64" decoding errors\n",
|
||||
decode_error_stat[0], decode_error_stat[1]);
|
||||
|
||||
@@ -484,7 +484,6 @@ typedef struct OutputStream {
|
||||
AVRational frame_aspect_ratio;
|
||||
|
||||
/* forced key frames */
|
||||
int64_t forced_kf_ref_pts;
|
||||
int64_t *forced_kf_pts;
|
||||
int forced_kf_count;
|
||||
int forced_kf_index;
|
||||
|
||||
@@ -65,7 +65,6 @@ enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCod
|
||||
if (codec && codec->pix_fmts) {
|
||||
const enum AVPixelFormat *p = codec->pix_fmts;
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(target);
|
||||
//FIXME: This should check for AV_PIX_FMT_FLAG_ALPHA after PAL8 pixel format without alpha is implemented
|
||||
int has_alpha = desc ? desc->nb_components % 2 == 0 : 0;
|
||||
enum AVPixelFormat best= AV_PIX_FMT_NONE;
|
||||
|
||||
@@ -775,7 +774,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
sar = ifilter->sample_aspect_ratio;
|
||||
if(!sar.den)
|
||||
sar = (AVRational){0,1};
|
||||
av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
|
||||
av_bprint_init(&args, 0, 1);
|
||||
av_bprintf(&args,
|
||||
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:"
|
||||
"pixel_aspect=%d/%d:sws_param=flags=%d",
|
||||
|
||||
@@ -900,14 +900,13 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
|
||||
|
||||
static void assert_file_overwrite(const char *filename)
|
||||
{
|
||||
const char *proto_name = avio_find_protocol_name(filename);
|
||||
|
||||
if (file_overwrite && no_file_overwrite) {
|
||||
fprintf(stderr, "Error, both -y and -n supplied. Exiting.\n");
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
if (!file_overwrite) {
|
||||
const char *proto_name = avio_find_protocol_name(filename);
|
||||
if (proto_name && !strcmp(proto_name, "file") && avio_check(filename, 0) == 0) {
|
||||
if (stdin_interaction && !no_file_overwrite) {
|
||||
fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
|
||||
@@ -926,19 +925,6 @@ static void assert_file_overwrite(const char *filename)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (proto_name && !strcmp(proto_name, "file")) {
|
||||
for (int i = 0; i < nb_input_files; i++) {
|
||||
InputFile *file = input_files[i];
|
||||
if (file->ctx->iformat->flags & AVFMT_NOFILE)
|
||||
continue;
|
||||
if (!strcmp(filename, file->ctx->url)) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Output %s same as Input #%d - exiting\n", filename, i);
|
||||
av_log(NULL, AV_LOG_WARNING, "FFmpeg cannot edit existing files in-place.\n");
|
||||
exit_program(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_attachment(AVStream *st, const char *filename)
|
||||
@@ -1117,22 +1103,9 @@ static int open_input_file(OptionsContext *o, const char *filename)
|
||||
}
|
||||
}
|
||||
|
||||
if (o->start_time != AV_NOPTS_VALUE && o->start_time_eof != AV_NOPTS_VALUE) {
|
||||
av_log(NULL, AV_LOG_WARNING, "Cannot use -ss and -sseof both, using -ss for %s\n", filename);
|
||||
o->start_time_eof = AV_NOPTS_VALUE;
|
||||
}
|
||||
|
||||
if (o->start_time_eof != AV_NOPTS_VALUE) {
|
||||
if (o->start_time_eof >= 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "-sseof value must be negative; aborting\n");
|
||||
exit_program(1);
|
||||
}
|
||||
if (ic->duration > 0) {
|
||||
if (ic->duration>0) {
|
||||
o->start_time = o->start_time_eof + ic->duration;
|
||||
if (o->start_time < 0) {
|
||||
av_log(NULL, AV_LOG_WARNING, "-sseof value seeks to before start of file %s; ignored\n", filename);
|
||||
o->start_time = AV_NOPTS_VALUE;
|
||||
}
|
||||
} else
|
||||
av_log(NULL, AV_LOG_WARNING, "Cannot use -sseof, duration of %s not known\n", filename);
|
||||
}
|
||||
@@ -1149,10 +1122,8 @@ static int open_input_file(OptionsContext *o, const char *filename)
|
||||
int dts_heuristic = 0;
|
||||
for (i=0; i<ic->nb_streams; i++) {
|
||||
const AVCodecParameters *par = ic->streams[i]->codecpar;
|
||||
if (par->video_delay) {
|
||||
if (par->video_delay)
|
||||
dts_heuristic = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dts_heuristic) {
|
||||
seek_timestamp -= 3*AV_TIME_BASE / 23;
|
||||
@@ -1353,7 +1324,6 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
|
||||
ost->file_index = nb_output_files - 1;
|
||||
ost->index = idx;
|
||||
ost->st = st;
|
||||
ost->forced_kf_ref_pts = AV_NOPTS_VALUE;
|
||||
st->codecpar->codec_type = type;
|
||||
|
||||
ret = choose_encoder(o, oc, ost);
|
||||
@@ -3187,9 +3157,7 @@ void show_help_default(const char *opt, const char *arg)
|
||||
#if CONFIG_SWSCALE
|
||||
show_help_children(sws_get_class(), flags);
|
||||
#endif
|
||||
#if CONFIG_SWRESAMPLE
|
||||
show_help_children(swr_get_class(), AV_OPT_FLAG_AUDIO_PARAM);
|
||||
#endif
|
||||
show_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM);
|
||||
show_help_children(av_bsf_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_BSF_PARAM);
|
||||
}
|
||||
@@ -3369,7 +3337,7 @@ const OptionDef options[] = {
|
||||
OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(start_time) },
|
||||
"set the start time offset", "time_off" },
|
||||
{ "sseof", HAS_ARG | OPT_TIME | OPT_OFFSET |
|
||||
OPT_INPUT, { .off = OFFSET(start_time_eof) },
|
||||
OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(start_time_eof) },
|
||||
"set the start time offset relative to EOF", "time_off" },
|
||||
{ "seek_timestamp", HAS_ARG | OPT_INT | OPT_OFFSET |
|
||||
OPT_INPUT, { .off = OFFSET(seek_timestamp) },
|
||||
|
||||
@@ -93,7 +93,7 @@ int qsv_init(AVCodecContext *s)
|
||||
frames_ctx->height = FFALIGN(s->coded_height, 32);
|
||||
frames_ctx->format = AV_PIX_FMT_QSV;
|
||||
frames_ctx->sw_format = s->sw_pix_fmt;
|
||||
frames_ctx->initial_pool_size = 64 + s->extra_hw_frames;
|
||||
frames_ctx->initial_pool_size = 64;
|
||||
frames_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
|
||||
|
||||
ret = av_hwframe_ctx_init(ist->hw_frames_ctx);
|
||||
|
||||
@@ -314,14 +314,11 @@ static int default_width = 640;
|
||||
static int default_height = 480;
|
||||
static int screen_width = 0;
|
||||
static int screen_height = 0;
|
||||
static int screen_left = SDL_WINDOWPOS_CENTERED;
|
||||
static int screen_top = SDL_WINDOWPOS_CENTERED;
|
||||
static int audio_disable;
|
||||
static int video_disable;
|
||||
static int subtitle_disable;
|
||||
static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
|
||||
static int seek_by_bytes = -1;
|
||||
static float seek_interval = 10;
|
||||
static int display_disable;
|
||||
static int borderless;
|
||||
static int startup_volume = 100;
|
||||
@@ -957,22 +954,6 @@ static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext *
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void set_sdl_yuv_conversion_mode(AVFrame *frame)
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST(2,0,8)
|
||||
SDL_YUV_CONVERSION_MODE mode = SDL_YUV_CONVERSION_AUTOMATIC;
|
||||
if (frame && (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUYV422 || frame->format == AV_PIX_FMT_UYVY422)) {
|
||||
if (frame->color_range == AVCOL_RANGE_JPEG)
|
||||
mode = SDL_YUV_CONVERSION_JPEG;
|
||||
else if (frame->colorspace == AVCOL_SPC_BT709)
|
||||
mode = SDL_YUV_CONVERSION_BT709;
|
||||
else if (frame->colorspace == AVCOL_SPC_BT470BG || frame->colorspace == AVCOL_SPC_SMPTE170M || frame->colorspace == AVCOL_SPC_SMPTE240M)
|
||||
mode = SDL_YUV_CONVERSION_BT601;
|
||||
}
|
||||
SDL_SetYUVConversionMode(mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void video_image_display(VideoState *is)
|
||||
{
|
||||
Frame *vp;
|
||||
@@ -1034,9 +1015,7 @@ static void video_image_display(VideoState *is)
|
||||
vp->flip_v = vp->frame->linesize[0] < 0;
|
||||
}
|
||||
|
||||
set_sdl_yuv_conversion_mode(vp->frame);
|
||||
SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
|
||||
set_sdl_yuv_conversion_mode(NULL);
|
||||
if (sp) {
|
||||
#if USE_ONEPASS_SUBTITLE_RENDER
|
||||
SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
|
||||
@@ -1348,7 +1327,7 @@ static int video_open(VideoState *is)
|
||||
SDL_SetWindowTitle(window, window_title);
|
||||
|
||||
SDL_SetWindowSize(window, w, h);
|
||||
SDL_SetWindowPosition(window, screen_left, screen_top);
|
||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
if (is_full_screen)
|
||||
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
SDL_ShowWindow(window);
|
||||
@@ -2214,8 +2193,6 @@ static int video_thread(void *arg)
|
||||
ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
|
||||
av_frame_unref(frame);
|
||||
#if CONFIG_AVFILTER
|
||||
if (is->videoq.serial != is->viddec.pkt_serial)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2601,7 +2578,7 @@ static int stream_component_open(VideoState *is, int stream_index)
|
||||
if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
|
||||
"No codec could be found with name '%s'\n", forced_codec_name);
|
||||
else av_log(NULL, AV_LOG_WARNING,
|
||||
"No decoder could be found for codec %s\n", avcodec_get_name(avctx->codec_id));
|
||||
"No codec could be found with id %d\n", avctx->codec_id);
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
@@ -3274,14 +3251,15 @@ static void event_loop(VideoState *cur_stream)
|
||||
refresh_loop_wait_event(cur_stream, &event);
|
||||
switch (event.type) {
|
||||
case SDL_KEYDOWN:
|
||||
if (exit_on_keydown || event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q) {
|
||||
if (exit_on_keydown) {
|
||||
do_exit(cur_stream);
|
||||
break;
|
||||
}
|
||||
// If we don't yet have a window, skip all key events, because read_thread might still be initializing...
|
||||
if (!cur_stream->width)
|
||||
continue;
|
||||
switch (event.key.keysym.sym) {
|
||||
case SDLK_ESCAPE:
|
||||
case SDLK_q:
|
||||
do_exit(cur_stream);
|
||||
break;
|
||||
case SDLK_f:
|
||||
toggle_full_screen(cur_stream);
|
||||
cur_stream->force_refresh = 1;
|
||||
@@ -3346,10 +3324,10 @@ static void event_loop(VideoState *cur_stream)
|
||||
seek_chapter(cur_stream, -1);
|
||||
break;
|
||||
case SDLK_LEFT:
|
||||
incr = seek_interval ? -seek_interval : -10.0;
|
||||
incr = -10.0;
|
||||
goto do_seek;
|
||||
case SDLK_RIGHT:
|
||||
incr = seek_interval ? seek_interval : 10.0;
|
||||
incr = 10.0;
|
||||
goto do_seek;
|
||||
case SDLK_UP:
|
||||
incr = 60.0;
|
||||
@@ -3585,7 +3563,6 @@ static const OptionDef options[] = {
|
||||
{ "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
|
||||
{ "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
|
||||
{ "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
|
||||
{ "seek_interval", OPT_FLOAT | HAS_ARG, { &seek_interval }, "set seek interval for left/right keys, in seconds", "seconds" },
|
||||
{ "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
|
||||
{ "noborder", OPT_BOOL, { &borderless }, "borderless window" },
|
||||
{ "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
|
||||
@@ -3604,8 +3581,6 @@ static const OptionDef options[] = {
|
||||
{ "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
|
||||
{ "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
|
||||
{ "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
|
||||
{ "left", OPT_INT | HAS_ARG | OPT_EXPERT, { &screen_left }, "set the x position for the left of the window", "x pos" },
|
||||
{ "top", OPT_INT | HAS_ARG | OPT_EXPERT, { &screen_top }, "set the y position for the top of the window", "y pos" },
|
||||
#if CONFIG_AVFILTER
|
||||
{ "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
|
||||
{ "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
|
||||
@@ -3658,7 +3633,7 @@ void show_help_default(const char *opt, const char *arg)
|
||||
"c cycle program\n"
|
||||
"w cycle video filters or show modes\n"
|
||||
"s activate frame-step mode\n"
|
||||
"left/right seek backward/forward 10 seconds or to custom interval if -seek_interval is set\n"
|
||||
"left/right seek backward/forward 10 seconds\n"
|
||||
"down/up seek backward/forward 1 minute\n"
|
||||
"page down/page up seek backward/forward 10 minutes\n"
|
||||
"right mouse click seek to percentage in file corresponding to fraction of width\n"
|
||||
|
||||
@@ -498,7 +498,7 @@ static int decode_i_block(FourXContext *f, int16_t *block)
|
||||
|
||||
if (get_bits_left(&f->gb) < 2){
|
||||
av_log(f->avctx, AV_LOG_ERROR, "%d bits left before decode_i_block()\n", get_bits_left(&f->gb));
|
||||
return -1;
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
/* DC coef */
|
||||
@@ -732,7 +732,7 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length)
|
||||
for (x = 0; x < width; x += 16) {
|
||||
unsigned int color[4] = { 0 }, bits;
|
||||
if (buf_end - buf < 8)
|
||||
return -1;
|
||||
return AVERROR_INVALIDDATA;
|
||||
// warning following is purely guessed ...
|
||||
color[0] = bytestream2_get_le16u(&g3);
|
||||
color[1] = bytestream2_get_le16u(&g3);
|
||||
|
||||
@@ -44,7 +44,6 @@ OBJS = ac3_parser.o \
|
||||
options.o \
|
||||
mjpegenc_huffman.o \
|
||||
parser.o \
|
||||
parsers.o \
|
||||
profiles.o \
|
||||
qsv_api.o \
|
||||
raw.o \
|
||||
@@ -63,12 +62,9 @@ OBJS-$(CONFIG_BLOCKDSP) += blockdsp.o
|
||||
OBJS-$(CONFIG_BSWAPDSP) += bswapdsp.o
|
||||
OBJS-$(CONFIG_CABAC) += cabac.o
|
||||
OBJS-$(CONFIG_CBS) += cbs.o
|
||||
OBJS-$(CONFIG_CBS_AV1) += cbs_av1.o
|
||||
OBJS-$(CONFIG_CBS_H264) += cbs_h2645.o h2645_parse.o
|
||||
OBJS-$(CONFIG_CBS_H265) += cbs_h2645.o h2645_parse.o
|
||||
OBJS-$(CONFIG_CBS_JPEG) += cbs_jpeg.o
|
||||
OBJS-$(CONFIG_CBS_MPEG2) += cbs_mpeg2.o
|
||||
OBJS-$(CONFIG_CBS_VP9) += cbs_vp9.o
|
||||
OBJS-$(CONFIG_CRYSTALHD) += crystalhd.o
|
||||
OBJS-$(CONFIG_DCT) += dct.o dct32_fixed.o dct32_float.o
|
||||
OBJS-$(CONFIG_ERROR_RESILIENCE) += error_resilience.o
|
||||
@@ -213,7 +209,6 @@ OBJS-$(CONFIG_ATRAC3P_DECODER) += atrac3plusdec.o atrac3plus.o \
|
||||
atrac3plusdsp.o atrac.o
|
||||
OBJS-$(CONFIG_ATRAC3PAL_DECODER) += atrac3plusdec.o atrac3plus.o \
|
||||
atrac3plusdsp.o atrac.o
|
||||
OBJS-$(CONFIG_ATRAC9_DECODER) += atrac9dec.o
|
||||
OBJS-$(CONFIG_AURA_DECODER) += cyuv.o
|
||||
OBJS-$(CONFIG_AURA2_DECODER) += aura.o
|
||||
OBJS-$(CONFIG_AVRN_DECODER) += avrndec.o mjpegdec.o
|
||||
@@ -356,7 +351,7 @@ OBJS-$(CONFIG_H264_OMX_ENCODER) += omx.o
|
||||
OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec_h2645.o
|
||||
OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o
|
||||
OBJS-$(CONFIG_H264_RKMPP_DECODER) += rkmppdec.o
|
||||
OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o h264_levels.o
|
||||
OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o
|
||||
OBJS-$(CONFIG_H264_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
|
||||
OBJS-$(CONFIG_H264_V4L2M2M_DECODER) += v4l2_m2m_dec.o
|
||||
OBJS-$(CONFIG_H264_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
|
||||
@@ -374,7 +369,7 @@ OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec_h2645.o
|
||||
OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \
|
||||
hevc_data.o
|
||||
OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o
|
||||
OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level.o
|
||||
OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o
|
||||
OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o
|
||||
OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
|
||||
OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o
|
||||
@@ -386,9 +381,7 @@ OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o huffyuvenc.o
|
||||
OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o
|
||||
OBJS-$(CONFIG_IDF_DECODER) += bintext.o cga_data.o
|
||||
OBJS-$(CONFIG_IFF_ILBM_DECODER) += iff.o
|
||||
OBJS-$(CONFIG_ILBC_DECODER) += ilbcdec.o
|
||||
OBJS-$(CONFIG_IMC_DECODER) += imc.o
|
||||
OBJS-$(CONFIG_IMM4_DECODER) += imm4.o
|
||||
OBJS-$(CONFIG_INDEO2_DECODER) += indeo2.o
|
||||
OBJS-$(CONFIG_INDEO3_DECODER) += indeo3.o
|
||||
OBJS-$(CONFIG_INDEO4_DECODER) += indeo4.o ivi.o
|
||||
@@ -485,7 +478,6 @@ OBJS-$(CONFIG_MSZH_DECODER) += lcldec.o
|
||||
OBJS-$(CONFIG_MTS2_DECODER) += mss4.o
|
||||
OBJS-$(CONFIG_MVC1_DECODER) += mvcdec.o
|
||||
OBJS-$(CONFIG_MVC2_DECODER) += mvcdec.o
|
||||
OBJS-$(CONFIG_MWSC_DECODER) += mwsc.o
|
||||
OBJS-$(CONFIG_MXPEG_DECODER) += mxpegdec.o
|
||||
OBJS-$(CONFIG_NELLYMOSER_DECODER) += nellymoserdec.o nellymoser.o
|
||||
OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o
|
||||
@@ -516,10 +508,10 @@ OBJS-$(CONFIG_PNG_ENCODER) += png.o pngenc.o
|
||||
OBJS-$(CONFIG_PPM_DECODER) += pnmdec.o pnm.o
|
||||
OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o
|
||||
OBJS-$(CONFIG_PRORES_DECODER) += proresdec2.o proresdsp.o proresdata.o
|
||||
OBJS-$(CONFIG_PRORES_ENCODER) += proresenc_anatoliy.o proresdata.o
|
||||
OBJS-$(CONFIG_PRORES_AW_ENCODER) += proresenc_anatoliy.o proresdata.o
|
||||
OBJS-$(CONFIG_PRORES_LGPL_DECODER) += proresdec_lgpl.o proresdsp.o proresdata.o
|
||||
OBJS-$(CONFIG_PRORES_ENCODER) += proresenc_anatoliy.o
|
||||
OBJS-$(CONFIG_PRORES_AW_ENCODER) += proresenc_anatoliy.o
|
||||
OBJS-$(CONFIG_PRORES_KS_ENCODER) += proresenc_kostya.o proresdata.o
|
||||
OBJS-$(CONFIG_PROSUMER_DECODER) += prosumer.o
|
||||
OBJS-$(CONFIG_PSD_DECODER) += psd.o
|
||||
OBJS-$(CONFIG_PTX_DECODER) += ptx.o
|
||||
OBJS-$(CONFIG_QCELP_DECODER) += qcelpdec.o \
|
||||
@@ -539,7 +531,6 @@ OBJS-$(CONFIG_RA_144_DECODER) += ra144dec.o ra144.o celp_filters.o
|
||||
OBJS-$(CONFIG_RA_144_ENCODER) += ra144enc.o ra144.o celp_filters.o
|
||||
OBJS-$(CONFIG_RA_288_DECODER) += ra288.o celp_filters.o
|
||||
OBJS-$(CONFIG_RALF_DECODER) += ralf.o
|
||||
OBJS-$(CONFIG_RASC_DECODER) += rasc.o
|
||||
OBJS-$(CONFIG_RAWVIDEO_DECODER) += rawdec.o
|
||||
OBJS-$(CONFIG_RAWVIDEO_ENCODER) += rawenc.o
|
||||
OBJS-$(CONFIG_REALTEXT_DECODER) += realtextdec.o ass.o
|
||||
@@ -583,7 +574,7 @@ OBJS-$(CONFIG_SOL_DPCM_DECODER) += dpcm.o
|
||||
OBJS-$(CONFIG_SONIC_DECODER) += sonic.o
|
||||
OBJS-$(CONFIG_SONIC_ENCODER) += sonic.o
|
||||
OBJS-$(CONFIG_SONIC_LS_ENCODER) += sonic.o
|
||||
OBJS-$(CONFIG_SPEEDHQ_DECODER) += speedhq.o mpeg12.o mpeg12data.o simple_idct.o
|
||||
OBJS-$(CONFIG_SPEEDHQ_DECODER) += speedhq.o simple_idct.o
|
||||
OBJS-$(CONFIG_SP5X_DECODER) += sp5xdec.o
|
||||
OBJS-$(CONFIG_SRGC_DECODER) += mscc.o
|
||||
OBJS-$(CONFIG_SRT_DECODER) += srtdec.o ass.o htmlsubtitles.o
|
||||
@@ -681,7 +672,6 @@ OBJS-$(CONFIG_VP9_V4L2M2M_DECODER) += v4l2_m2m_dec.o
|
||||
OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o
|
||||
OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o
|
||||
OBJS-$(CONFIG_WAVPACK_ENCODER) += wavpackenc.o
|
||||
OBJS-$(CONFIG_WCMV_DECODER) += wcmv.o
|
||||
OBJS-$(CONFIG_WEBP_DECODER) += webp.o
|
||||
OBJS-$(CONFIG_WEBVTT_DECODER) += webvttdec.o ass.o
|
||||
OBJS-$(CONFIG_WEBVTT_ENCODER) += webvttenc.o ass_split.o
|
||||
@@ -794,8 +784,6 @@ OBJS-$(CONFIG_PCM_U32BE_DECODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_U32BE_ENCODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_U32LE_DECODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_U32LE_ENCODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_VIDC_DECODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_VIDC_ENCODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_ZORK_DECODER) += pcm.o
|
||||
|
||||
OBJS-$(CONFIG_ADPCM_4XM_DECODER) += adpcm.o adpcm_data.o
|
||||
@@ -956,7 +944,6 @@ OBJS-$(CONFIG_LIBAOM_AV1_ENCODER) += libaomenc.o
|
||||
OBJS-$(CONFIG_LIBCELT_DECODER) += libcelt_dec.o
|
||||
OBJS-$(CONFIG_LIBCODEC2_DECODER) += libcodec2.o codec2utils.o
|
||||
OBJS-$(CONFIG_LIBCODEC2_ENCODER) += libcodec2.o codec2utils.o
|
||||
OBJS-$(CONFIG_LIBDAVS2_DECODER) += libdavs2.o
|
||||
OBJS-$(CONFIG_LIBFDK_AAC_DECODER) += libfdk-aacdec.o
|
||||
OBJS-$(CONFIG_LIBFDK_AAC_ENCODER) += libfdk-aacenc.o
|
||||
OBJS-$(CONFIG_LIBGSM_DECODER) += libgsmdec.o
|
||||
@@ -998,8 +985,7 @@ OBJS-$(CONFIG_LIBX262_ENCODER) += libx264.o
|
||||
OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o
|
||||
OBJS-$(CONFIG_LIBX265_ENCODER) += libx265.o
|
||||
OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o
|
||||
OBJS-$(CONFIG_LIBXAVS2_ENCODER) += libxavs2.o
|
||||
OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvid.o
|
||||
OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvid.o libxvid_rc.o
|
||||
OBJS-$(CONFIG_LIBZVBI_TELETEXT_DECODER) += libzvbi-teletextdec.o ass.o
|
||||
|
||||
# parsers
|
||||
@@ -1008,8 +994,6 @@ OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o \
|
||||
mpeg4audio.o
|
||||
OBJS-$(CONFIG_AC3_PARSER) += ac3tab.o aac_ac3_parser.o
|
||||
OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o
|
||||
OBJS-$(CONFIG_AV1_PARSER) += av1_parser.o av1_parse.o
|
||||
OBJS-$(CONFIG_AVS2_PARSER) += avs2_parser.o
|
||||
OBJS-$(CONFIG_BMP_PARSER) += bmp_parser.o
|
||||
OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o
|
||||
OBJS-$(CONFIG_COOK_PARSER) += cook_parser.o
|
||||
@@ -1056,15 +1040,14 @@ OBJS-$(CONFIG_XMA_PARSER) += xma_parser.o
|
||||
|
||||
# bitstream filters
|
||||
OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o mpeg4audio.o
|
||||
OBJS-$(CONFIG_AV1_METADATA_BSF) += av1_metadata_bsf.o
|
||||
OBJS-$(CONFIG_CHOMP_BSF) += chomp_bsf.o
|
||||
OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o
|
||||
OBJS-$(CONFIG_DCA_CORE_BSF) += dca_core_bsf.o
|
||||
OBJS-$(CONFIG_EAC3_CORE_BSF) += eac3_core_bsf.o
|
||||
OBJS-$(CONFIG_EXTRACT_EXTRADATA_BSF) += extract_extradata_bsf.o \
|
||||
av1_parse.o h2645_parse.o
|
||||
h2645_parse.o
|
||||
OBJS-$(CONFIG_FILTER_UNITS_BSF) += filter_units_bsf.o
|
||||
OBJS-$(CONFIG_H264_METADATA_BSF) += h264_metadata_bsf.o h264_levels.o
|
||||
OBJS-$(CONFIG_H264_METADATA_BSF) += h264_metadata_bsf.o
|
||||
OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += h264_mp4toannexb_bsf.o
|
||||
OBJS-$(CONFIG_H264_REDUNDANT_PPS_BSF) += h264_redundant_pps_bsf.o
|
||||
OBJS-$(CONFIG_HAPQA_EXTRACT_BSF) += hapqa_extract_bsf.o hap.o
|
||||
@@ -1083,7 +1066,6 @@ OBJS-$(CONFIG_NULL_BSF) += null_bsf.o
|
||||
OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o
|
||||
OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o
|
||||
OBJS-$(CONFIG_TRACE_HEADERS_BSF) += trace_headers_bsf.o
|
||||
OBJS-$(CONFIG_VP9_METADATA_BSF) += vp9_metadata_bsf.o
|
||||
OBJS-$(CONFIG_VP9_RAW_REORDER_BSF) += vp9_raw_reorder_bsf.o
|
||||
OBJS-$(CONFIG_VP9_SUPERFRAME_BSF) += vp9_superframe_bsf.o
|
||||
OBJS-$(CONFIG_VP9_SUPERFRAME_SPLIT_BSF) += vp9_superframe_split_bsf.o
|
||||
@@ -1145,7 +1127,6 @@ TESTPROGS-$(CONFIG_IDCTDSP) += dct
|
||||
TESTPROGS-$(CONFIG_IIRFILTER) += iirfilter
|
||||
TESTPROGS-$(HAVE_MMX) += motion
|
||||
TESTPROGS-$(CONFIG_MPEGVIDEO) += mpeg12framerate
|
||||
TESTPROGS-$(CONFIG_H264_METADATA_BSF) += h264_levels
|
||||
TESTPROGS-$(CONFIG_RANGECODER) += rangecoder
|
||||
TESTPROGS-$(CONFIG_SNOW_ENCODER) += snowenc
|
||||
|
||||
|
||||
@@ -3122,7 +3122,6 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
|
||||
int samples = 0, multiplier, audio_found = 0, pce_found = 0;
|
||||
int is_dmono, sce_count = 0;
|
||||
int payload_alignment;
|
||||
uint8_t che_presence[4][MAX_ELEM_ID] = {{0}};
|
||||
|
||||
ac->frame = data;
|
||||
|
||||
@@ -3160,17 +3159,6 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
|
||||
}
|
||||
|
||||
if (elem_type < TYPE_DSE) {
|
||||
if (che_presence[elem_type][elem_id]) {
|
||||
int error = che_presence[elem_type][elem_id] > 1;
|
||||
av_log(ac->avctx, error ? AV_LOG_ERROR : AV_LOG_DEBUG, "channel element %d.%d duplicate\n",
|
||||
elem_type, elem_id);
|
||||
if (error) {
|
||||
err = AVERROR_INVALIDDATA;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
che_presence[elem_type][elem_id]++;
|
||||
|
||||
if (!(che=get_che(ac, elem_type, elem_id))) {
|
||||
av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n",
|
||||
elem_type, elem_id);
|
||||
@@ -3336,14 +3324,20 @@ static int aac_decode_frame(AVCodecContext *avctx, void *data,
|
||||
AV_PKT_DATA_JP_DUALMONO,
|
||||
&jp_dualmono_size);
|
||||
|
||||
if (new_extradata) {
|
||||
/* discard previous configuration */
|
||||
ac->oc[1].status = OC_NONE;
|
||||
err = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
|
||||
new_extradata,
|
||||
new_extradata_size * 8LL, 1);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
if (new_extradata && 0) {
|
||||
av_free(avctx->extradata);
|
||||
avctx->extradata = av_mallocz(new_extradata_size +
|
||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!avctx->extradata)
|
||||
return AVERROR(ENOMEM);
|
||||
avctx->extradata_size = new_extradata_size;
|
||||
memcpy(avctx->extradata, new_extradata, new_extradata_size);
|
||||
push_output_configuration(ac);
|
||||
if (decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
|
||||
avctx->extradata,
|
||||
avctx->extradata_size*8LL, 1) < 0) {
|
||||
pop_output_configuration(ac);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -982,13 +982,11 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
|
||||
}
|
||||
|
||||
if (s->needs_pce) {
|
||||
char buf[64];
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(aac_pce_configs); i++)
|
||||
if (avctx->channel_layout == aac_pce_configs[i].layout)
|
||||
break;
|
||||
av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout);
|
||||
ERROR_IF(i == FF_ARRAY_ELEMS(aac_pce_configs), "Unsupported channel layout \"%s\"\n", buf);
|
||||
av_log(avctx, AV_LOG_INFO, "Using a PCE to encode channel layout \"%s\"\n", buf);
|
||||
ERROR_IF(i == FF_ARRAY_ELEMS(aac_pce_configs), "Unsupported channel layout\n");
|
||||
av_log(avctx, AV_LOG_INFO, "Using a PCE to encode channel layout\n");
|
||||
s->pce = aac_pce_configs[i];
|
||||
s->reorder_map = s->pce.reorder_map;
|
||||
s->chan_map = s->pce.config_map;
|
||||
|
||||
@@ -111,4 +111,16 @@ static DECLARE_ALIGNED(32, INTFLOAT, sbr_qmf_window_us)[640] = {
|
||||
Q31( 0.8537385600f),
|
||||
};
|
||||
|
||||
static av_cold void aacsbr_tableinit(void)
|
||||
{
|
||||
int n;
|
||||
for (n = 1; n < 320; n++)
|
||||
sbr_qmf_window_us[320 + n] = sbr_qmf_window_us[320 - n];
|
||||
sbr_qmf_window_us[384] = -sbr_qmf_window_us[384];
|
||||
sbr_qmf_window_us[512] = -sbr_qmf_window_us[512];
|
||||
|
||||
for (n = 0; n < 320; n++)
|
||||
sbr_qmf_window_ds[n] = sbr_qmf_window_us[2*n];
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_AACSBR_TABLEGEN_COMMON_H */
|
||||
|
||||
@@ -34,18 +34,6 @@
|
||||
|
||||
#include "libavutil/qsort.h"
|
||||
|
||||
static av_cold void aacsbr_tableinit(void)
|
||||
{
|
||||
int n;
|
||||
for (n = 1; n < 320; n++)
|
||||
sbr_qmf_window_us[320 + n] = sbr_qmf_window_us[320 - n];
|
||||
sbr_qmf_window_us[384] = -sbr_qmf_window_us[384];
|
||||
sbr_qmf_window_us[512] = -sbr_qmf_window_us[512];
|
||||
|
||||
for (n = 0; n < 320; n++)
|
||||
sbr_qmf_window_ds[n] = sbr_qmf_window_us[2*n];
|
||||
}
|
||||
|
||||
av_cold void AAC_RENAME(ff_aac_sbr_init)(void)
|
||||
{
|
||||
static const struct {
|
||||
|
||||
@@ -34,20 +34,20 @@ void ff_h264_v_loop_filter_chroma_neon(uint8_t *pix, int stride, int alpha,
|
||||
void ff_h264_h_loop_filter_chroma_neon(uint8_t *pix, int stride, int alpha,
|
||||
int beta, int8_t *tc0);
|
||||
|
||||
void ff_weight_h264_pixels_16_neon(uint8_t *dst, ptrdiff_t stride, int height,
|
||||
void ff_weight_h264_pixels_16_neon(uint8_t *dst, int stride, int height,
|
||||
int log2_den, int weight, int offset);
|
||||
void ff_weight_h264_pixels_8_neon(uint8_t *dst, ptrdiff_t stride, int height,
|
||||
void ff_weight_h264_pixels_8_neon(uint8_t *dst, int stride, int height,
|
||||
int log2_den, int weight, int offset);
|
||||
void ff_weight_h264_pixels_4_neon(uint8_t *dst, ptrdiff_t stride, int height,
|
||||
void ff_weight_h264_pixels_4_neon(uint8_t *dst, int stride, int height,
|
||||
int log2_den, int weight, int offset);
|
||||
|
||||
void ff_biweight_h264_pixels_16_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
|
||||
void ff_biweight_h264_pixels_16_neon(uint8_t *dst, uint8_t *src, int stride,
|
||||
int height, int log2_den, int weightd,
|
||||
int weights, int offset);
|
||||
void ff_biweight_h264_pixels_8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
|
||||
void ff_biweight_h264_pixels_8_neon(uint8_t *dst, uint8_t *src, int stride,
|
||||
int height, int log2_den, int weightd,
|
||||
int weights, int offset);
|
||||
void ff_biweight_h264_pixels_4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
|
||||
void ff_biweight_h264_pixels_4_neon(uint8_t *dst, uint8_t *src, int stride,
|
||||
int height, int log2_den, int weightd,
|
||||
int weights, int offset);
|
||||
|
||||
|
||||
@@ -208,6 +208,9 @@ static int aic_decode_coeffs(GetBitContext *gb, int16_t *dst,
|
||||
int mb, idx;
|
||||
unsigned val;
|
||||
|
||||
if (get_bits_left(gb) < 5)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
has_skips = get_bits1(gb);
|
||||
coeff_type = get_bits1(gb);
|
||||
coeff_bits = get_bits(gb, 3);
|
||||
|
||||
@@ -58,7 +58,6 @@ extern AVCodec ff_ayuv_decoder;
|
||||
extern AVCodec ff_bethsoftvid_decoder;
|
||||
extern AVCodec ff_bfi_decoder;
|
||||
extern AVCodec ff_bink_decoder;
|
||||
extern AVCodec ff_bitpacked_decoder;
|
||||
extern AVCodec ff_bmp_encoder;
|
||||
extern AVCodec ff_bmp_decoder;
|
||||
extern AVCodec ff_bmv_video_decoder;
|
||||
@@ -154,7 +153,6 @@ extern AVCodec ff_huffyuv_encoder;
|
||||
extern AVCodec ff_huffyuv_decoder;
|
||||
extern AVCodec ff_idcin_decoder;
|
||||
extern AVCodec ff_iff_ilbm_decoder;
|
||||
extern AVCodec ff_imm4_decoder;
|
||||
extern AVCodec ff_indeo2_decoder;
|
||||
extern AVCodec ff_indeo3_decoder;
|
||||
extern AVCodec ff_indeo4_decoder;
|
||||
@@ -213,7 +211,6 @@ extern AVCodec ff_mszh_decoder;
|
||||
extern AVCodec ff_mts2_decoder;
|
||||
extern AVCodec ff_mvc1_decoder;
|
||||
extern AVCodec ff_mvc2_decoder;
|
||||
extern AVCodec ff_mwsc_decoder;
|
||||
extern AVCodec ff_mxpeg_decoder;
|
||||
extern AVCodec ff_nuv_decoder;
|
||||
extern AVCodec ff_paf_video_decoder;
|
||||
@@ -237,7 +234,7 @@ extern AVCodec ff_prores_encoder;
|
||||
extern AVCodec ff_prores_decoder;
|
||||
extern AVCodec ff_prores_aw_encoder;
|
||||
extern AVCodec ff_prores_ks_encoder;
|
||||
extern AVCodec ff_prosumer_decoder;
|
||||
extern AVCodec ff_prores_lgpl_decoder;
|
||||
extern AVCodec ff_psd_decoder;
|
||||
extern AVCodec ff_ptx_decoder;
|
||||
extern AVCodec ff_qdraw_decoder;
|
||||
@@ -248,7 +245,6 @@ extern AVCodec ff_r10k_encoder;
|
||||
extern AVCodec ff_r10k_decoder;
|
||||
extern AVCodec ff_r210_encoder;
|
||||
extern AVCodec ff_r210_decoder;
|
||||
extern AVCodec ff_rasc_decoder;
|
||||
extern AVCodec ff_rawvideo_encoder;
|
||||
extern AVCodec ff_rawvideo_decoder;
|
||||
extern AVCodec ff_rl2_decoder;
|
||||
@@ -338,8 +334,8 @@ extern AVCodec ff_vp9_decoder;
|
||||
extern AVCodec ff_vp9_rkmpp_decoder;
|
||||
extern AVCodec ff_vp9_v4l2m2m_decoder;
|
||||
extern AVCodec ff_vqa_decoder;
|
||||
extern AVCodec ff_bitpacked_decoder;
|
||||
extern AVCodec ff_webp_decoder;
|
||||
extern AVCodec ff_wcmv_decoder;
|
||||
extern AVCodec ff_wrapped_avframe_encoder;
|
||||
extern AVCodec ff_wrapped_avframe_decoder;
|
||||
extern AVCodec ff_wmv1_encoder;
|
||||
@@ -397,7 +393,6 @@ extern AVCodec ff_atrac3_decoder;
|
||||
extern AVCodec ff_atrac3al_decoder;
|
||||
extern AVCodec ff_atrac3p_decoder;
|
||||
extern AVCodec ff_atrac3pal_decoder;
|
||||
extern AVCodec ff_atrac9_decoder;
|
||||
extern AVCodec ff_binkaudio_dct_decoder;
|
||||
extern AVCodec ff_binkaudio_rdft_decoder;
|
||||
extern AVCodec ff_bmv_audio_decoder;
|
||||
@@ -424,7 +419,6 @@ extern AVCodec ff_g729_decoder;
|
||||
extern AVCodec ff_gsm_decoder;
|
||||
extern AVCodec ff_gsm_ms_decoder;
|
||||
extern AVCodec ff_iac_decoder;
|
||||
extern AVCodec ff_ilbc_decoder;
|
||||
extern AVCodec ff_imc_decoder;
|
||||
extern AVCodec ff_interplay_acm_decoder;
|
||||
extern AVCodec ff_mace3_decoder;
|
||||
@@ -552,8 +546,6 @@ extern AVCodec ff_pcm_u32be_encoder;
|
||||
extern AVCodec ff_pcm_u32be_decoder;
|
||||
extern AVCodec ff_pcm_u32le_encoder;
|
||||
extern AVCodec ff_pcm_u32le_decoder;
|
||||
extern AVCodec ff_pcm_vidc_encoder;
|
||||
extern AVCodec ff_pcm_vidc_decoder;
|
||||
extern AVCodec ff_pcm_zork_decoder;
|
||||
|
||||
/* DPCM codecs */
|
||||
@@ -676,7 +668,6 @@ extern AVCodec ff_libaom_av1_encoder;
|
||||
extern AVCodec ff_libcelt_decoder;
|
||||
extern AVCodec ff_libcodec2_encoder;
|
||||
extern AVCodec ff_libcodec2_decoder;
|
||||
extern AVCodec ff_libdavs2_decoder;
|
||||
extern AVCodec ff_libfdk_aac_encoder;
|
||||
extern AVCodec ff_libfdk_aac_decoder;
|
||||
extern AVCodec ff_libgsm_encoder;
|
||||
@@ -715,7 +706,6 @@ extern AVCodec ff_libx264_encoder;
|
||||
extern AVCodec ff_libx264rgb_encoder;
|
||||
extern AVCodec ff_libx265_encoder;
|
||||
extern AVCodec ff_libxavs_encoder;
|
||||
extern AVCodec ff_libxavs2_encoder;
|
||||
extern AVCodec ff_libxvid_encoder;
|
||||
extern AVCodec ff_libzvbi_teletext_decoder;
|
||||
|
||||
@@ -771,15 +761,7 @@ extern AVCodec ff_vp9_cuvid_decoder;
|
||||
extern AVCodec ff_vp9_mediacodec_decoder;
|
||||
extern AVCodec ff_vp9_vaapi_encoder;
|
||||
|
||||
// The iterate API is not usable with ossfuzz due to the excessive size of binaries created
|
||||
#if CONFIG_OSSFUZZ
|
||||
AVCodec * codec_list[] = {
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
#else
|
||||
#include "libavcodec/codec_list.c"
|
||||
#endif
|
||||
|
||||
static AVOnce av_codec_static_init = AV_ONCE_INIT;
|
||||
static void av_codec_init_static(void)
|
||||
|
||||
@@ -1,954 +0,0 @@
|
||||
/*
|
||||
* ATRAC9 decoder
|
||||
* Copyright (c) 2018 Rostislav Pehlivanov <atomnuker@gmail.com>
|
||||
*
|
||||
* 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 "internal.h"
|
||||
#include "get_bits.h"
|
||||
#include "fft.h"
|
||||
#include "atrac9tab.h"
|
||||
#include "libavutil/lfg.h"
|
||||
#include "libavutil/float_dsp.h"
|
||||
|
||||
typedef struct ATRAC9ChannelData {
|
||||
int band_ext;
|
||||
int q_unit_cnt;
|
||||
int band_ext_data[4];
|
||||
int32_t scalefactors[31];
|
||||
int32_t scalefactors_prev[31];
|
||||
|
||||
int precision_coarse[30];
|
||||
int precision_fine[30];
|
||||
int precision_mask[30];
|
||||
|
||||
int codebookset[30];
|
||||
|
||||
int32_t q_coeffs_coarse[256];
|
||||
int32_t q_coeffs_fine[256];
|
||||
|
||||
DECLARE_ALIGNED(32, float, coeffs )[256];
|
||||
DECLARE_ALIGNED(32, float, prev_win)[128];
|
||||
} ATRAC9ChannelData;
|
||||
|
||||
typedef struct ATRAC9BlockData {
|
||||
ATRAC9ChannelData channel[2];
|
||||
|
||||
/* Base */
|
||||
int band_count;
|
||||
int q_unit_cnt;
|
||||
int q_unit_cnt_prev;
|
||||
|
||||
/* Stereo block only */
|
||||
int stereo_q_unit;
|
||||
|
||||
/* Band extension only */
|
||||
int has_band_ext;
|
||||
int has_band_ext_data;
|
||||
int band_ext_q_unit;
|
||||
|
||||
/* Gradient */
|
||||
int grad_mode;
|
||||
int grad_boundary;
|
||||
int gradient[31];
|
||||
|
||||
/* Stereo */
|
||||
int cpe_base_channel;
|
||||
int is_signs[30];
|
||||
|
||||
} ATRAC9BlockData;
|
||||
|
||||
typedef struct ATRAC9Context {
|
||||
AVCodecContext *avctx;
|
||||
AVFloatDSPContext *fdsp;
|
||||
FFTContext imdct;
|
||||
ATRAC9BlockData block[5];
|
||||
AVLFG lfg;
|
||||
|
||||
/* Set on init */
|
||||
int frame_log2;
|
||||
int avg_frame_size;
|
||||
int frame_count;
|
||||
int samplerate_idx;
|
||||
const ATRAC9BlockConfig *block_config;
|
||||
|
||||
/* Generated on init */
|
||||
VLC sf_vlc[2][8]; /* Signed/unsigned, length */
|
||||
VLC coeff_vlc[2][8][4]; /* Cookbook, precision, cookbook index */
|
||||
uint8_t alloc_curve[48][48];
|
||||
DECLARE_ALIGNED(32, float, imdct_win)[256];
|
||||
|
||||
DECLARE_ALIGNED(32, float, temp)[256];
|
||||
} ATRAC9Context;
|
||||
|
||||
static inline int parse_gradient(ATRAC9Context *s, ATRAC9BlockData *b,
|
||||
GetBitContext *gb)
|
||||
{
|
||||
int grad_range[2];
|
||||
int grad_value[2];
|
||||
int values, sign, base;
|
||||
uint8_t *curve;
|
||||
float scale;
|
||||
|
||||
b->grad_mode = get_bits(gb, 2);
|
||||
if (b->grad_mode) {
|
||||
grad_range[0] = get_bits(gb, 5);
|
||||
grad_range[1] = 31;
|
||||
grad_value[0] = get_bits(gb, 5);
|
||||
grad_value[1] = 31;
|
||||
} else {
|
||||
grad_range[0] = get_bits(gb, 6);
|
||||
grad_range[1] = get_bits(gb, 6) + 1;
|
||||
grad_value[0] = get_bits(gb, 5);
|
||||
grad_value[1] = get_bits(gb, 5);
|
||||
}
|
||||
b->grad_boundary = get_bits(gb, 4);
|
||||
|
||||
if (grad_range[0] >= grad_range[1] || grad_range[1] > 47)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if (grad_value[0] > 31 || grad_value[1] > 31)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if (b->grad_boundary > b->q_unit_cnt)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
values = grad_value[1] - grad_value[0];
|
||||
sign = 1 - 2*(values < 0);
|
||||
base = grad_value[0] + sign;
|
||||
scale = (FFABS(values) - 1) / 31.0f;
|
||||
curve = s->alloc_curve[grad_range[1] - grad_range[0] - 1];
|
||||
|
||||
for (int i = 0; i <= b->q_unit_cnt; i++)
|
||||
b->gradient[i] = grad_value[i >= grad_range[0]];
|
||||
|
||||
for (int i = grad_range[0]; i < grad_range[1]; i++)
|
||||
b->gradient[i] = base + sign*((int)(scale*curve[i - grad_range[0]]));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void calc_precision(ATRAC9Context *s, ATRAC9BlockData *b,
|
||||
ATRAC9ChannelData *c)
|
||||
{
|
||||
memset(c->precision_mask, 0, sizeof(c->precision_mask));
|
||||
for (int i = 1; i < b->q_unit_cnt; i++) {
|
||||
const int delta = FFABS(c->scalefactors[i] - c->scalefactors[i - 1]) - 1;
|
||||
if (delta > 0) {
|
||||
const int neg = c->scalefactors[i - 1] > c->scalefactors[i];
|
||||
c->precision_mask[i - neg] += FFMIN(delta, 5);
|
||||
}
|
||||
}
|
||||
|
||||
if (b->grad_mode) {
|
||||
for (int i = 0; i < b->q_unit_cnt; i++) {
|
||||
c->precision_coarse[i] = c->scalefactors[i];
|
||||
c->precision_coarse[i] += c->precision_mask[i] - b->gradient[i];
|
||||
if (c->precision_coarse[i] < 0)
|
||||
continue;
|
||||
switch (b->grad_mode) {
|
||||
case 1:
|
||||
c->precision_coarse[i] >>= 1;
|
||||
break;
|
||||
case 2:
|
||||
c->precision_coarse[i] = (3 * c->precision_coarse[i]) >> 3;
|
||||
break;
|
||||
case 3:
|
||||
c->precision_coarse[i] >>= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < b->q_unit_cnt; i++)
|
||||
c->precision_coarse[i] = c->scalefactors[i] - b->gradient[i];
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < b->q_unit_cnt; i++)
|
||||
c->precision_coarse[i] = FFMAX(c->precision_coarse[i], 1);
|
||||
|
||||
for (int i = 0; i < b->grad_boundary; i++)
|
||||
c->precision_coarse[i]++;
|
||||
|
||||
for (int i = 0; i < b->q_unit_cnt; i++) {
|
||||
c->precision_fine[i] = 0;
|
||||
if (c->precision_coarse[i] > 15) {
|
||||
c->precision_fine[i] = c->precision_coarse[i] - 15;
|
||||
c->precision_coarse[i] = 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int parse_band_ext(ATRAC9Context *s, ATRAC9BlockData *b,
|
||||
GetBitContext *gb, int stereo)
|
||||
{
|
||||
int ext_band = 0;
|
||||
|
||||
if (b->has_band_ext) {
|
||||
ext_band = at9_tab_band_ext_group[b->q_unit_cnt - 13][2];
|
||||
if (stereo) {
|
||||
b->channel[1].band_ext = get_bits(gb, 2);
|
||||
b->channel[1].band_ext = ext_band > 2 ? b->channel[1].band_ext : 4;
|
||||
} else {
|
||||
skip_bits1(gb);
|
||||
}
|
||||
}
|
||||
|
||||
b->has_band_ext_data = get_bits1(gb);
|
||||
if (!b->has_band_ext_data)
|
||||
return 0;
|
||||
|
||||
if (!b->has_band_ext) {
|
||||
skip_bits(gb, 2);
|
||||
skip_bits_long(gb, get_bits(gb, 5));
|
||||
return 0;
|
||||
}
|
||||
|
||||
b->channel[0].band_ext = get_bits(gb, 2);
|
||||
b->channel[0].band_ext = ext_band > 2 ? b->channel[0].band_ext : 4;
|
||||
|
||||
if (!get_bits(gb, 5))
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i <= stereo; i++) {
|
||||
ATRAC9ChannelData *c = &b->channel[i];
|
||||
const int count = at9_tab_band_ext_cnt[c->band_ext][ext_band];
|
||||
for (int j = 0; j < count; j++) {
|
||||
int len = at9_tab_band_ext_lengths[c->band_ext][ext_band][j];
|
||||
c->band_ext_data[j] = get_bits(gb, len);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int read_scalefactors(ATRAC9Context *s, ATRAC9BlockData *b,
|
||||
ATRAC9ChannelData *c, GetBitContext *gb,
|
||||
int channel_idx, int first_in_pkt)
|
||||
{
|
||||
static const int mode_map[2][4] = { { 0, 1, 2, 3 }, { 0, 2, 3, 4 } };
|
||||
const int mode = mode_map[channel_idx][get_bits(gb, 2)];
|
||||
|
||||
memset(c->scalefactors, 0, sizeof(c->scalefactors));
|
||||
|
||||
if (first_in_pkt && (mode == 4 || ((mode == 3) && !channel_idx))) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Invalid scalefactor coding mode!\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case 0: { /* VLC delta offset */
|
||||
const uint8_t *sf_weights = at9_tab_sf_weights[get_bits(gb, 3)];
|
||||
const int base = get_bits(gb, 5);
|
||||
const int len = get_bits(gb, 2) + 3;
|
||||
const VLC *tab = &s->sf_vlc[0][len];
|
||||
|
||||
c->scalefactors[0] = get_bits(gb, len);
|
||||
|
||||
for (int i = 1; i < b->band_ext_q_unit; i++) {
|
||||
int val = c->scalefactors[i - 1] + get_vlc2(gb, tab->table, 9, 2);
|
||||
c->scalefactors[i] = val & ((1 << len) - 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < b->band_ext_q_unit; i++)
|
||||
c->scalefactors[i] += base - sf_weights[i];
|
||||
|
||||
break;
|
||||
}
|
||||
case 1: { /* CLC offset */
|
||||
const int len = get_bits(gb, 2) + 2;
|
||||
const int base = len < 5 ? get_bits(gb, 5) : 0;
|
||||
for (int i = 0; i < b->band_ext_q_unit; i++)
|
||||
c->scalefactors[i] = base + get_bits(gb, len);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
case 4: { /* VLC dist to baseline */
|
||||
const int *baseline = mode == 4 ? c->scalefactors_prev :
|
||||
channel_idx ? b->channel[0].scalefactors :
|
||||
c->scalefactors_prev;
|
||||
const int baseline_len = mode == 4 ? b->q_unit_cnt_prev :
|
||||
channel_idx ? b->band_ext_q_unit :
|
||||
b->q_unit_cnt_prev;
|
||||
|
||||
const int len = get_bits(gb, 2) + 2;
|
||||
const int unit_cnt = FFMIN(b->band_ext_q_unit, baseline_len);
|
||||
const VLC *tab = &s->sf_vlc[1][len];
|
||||
|
||||
for (int i = 0; i < unit_cnt; i++) {
|
||||
int dist = get_vlc2(gb, tab->table, 9, 2);
|
||||
c->scalefactors[i] = baseline[i] + dist;
|
||||
}
|
||||
|
||||
for (int i = unit_cnt; i < b->band_ext_q_unit; i++)
|
||||
c->scalefactors[i] = get_bits(gb, 5);
|
||||
|
||||
break;
|
||||
}
|
||||
case 3: { /* VLC offset with baseline */
|
||||
const int *baseline = channel_idx ? b->channel[0].scalefactors :
|
||||
c->scalefactors_prev;
|
||||
const int baseline_len = channel_idx ? b->band_ext_q_unit :
|
||||
b->q_unit_cnt_prev;
|
||||
|
||||
const int base = get_bits(gb, 5) - (1 << (5 - 1));
|
||||
const int len = get_bits(gb, 2) + 1;
|
||||
const int unit_cnt = FFMIN(b->band_ext_q_unit, baseline_len);
|
||||
const VLC *tab = &s->sf_vlc[0][len];
|
||||
|
||||
c->scalefactors[0] = get_bits(gb, len);
|
||||
|
||||
for (int i = 1; i < unit_cnt; i++) {
|
||||
int val = c->scalefactors[i - 1] + get_vlc2(gb, tab->table, 9, 2);
|
||||
c->scalefactors[i] = val & ((1 << len) - 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < unit_cnt; i++)
|
||||
c->scalefactors[i] += base + baseline[i];
|
||||
|
||||
for (int i = unit_cnt; i < b->band_ext_q_unit; i++)
|
||||
c->scalefactors[i] = get_bits(gb, 5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < b->band_ext_q_unit; i++)
|
||||
if (c->scalefactors[i] < 0 || c->scalefactors[i] > 31)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
memcpy(c->scalefactors_prev, c->scalefactors, sizeof(c->scalefactors));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void calc_codebook_idx(ATRAC9Context *s, ATRAC9BlockData *b,
|
||||
ATRAC9ChannelData *c)
|
||||
{
|
||||
int avg = 0;
|
||||
const int last_sf = c->scalefactors[c->q_unit_cnt];
|
||||
|
||||
memset(c->codebookset, 0, sizeof(c->codebookset));
|
||||
|
||||
if (c->q_unit_cnt <= 1)
|
||||
return;
|
||||
if (s->samplerate_idx > 7)
|
||||
return;
|
||||
|
||||
c->scalefactors[c->q_unit_cnt] = c->scalefactors[c->q_unit_cnt - 1];
|
||||
|
||||
if (c->q_unit_cnt > 12) {
|
||||
for (int i = 0; i < 12; i++)
|
||||
avg += c->scalefactors[i];
|
||||
avg = (avg + 6) / 12;
|
||||
}
|
||||
|
||||
for (int i = 8; i < c->q_unit_cnt; i++) {
|
||||
const int prev = c->scalefactors[i - 1];
|
||||
const int cur = c->scalefactors[i ];
|
||||
const int next = c->scalefactors[i + 1];
|
||||
const int min = FFMIN(prev, next);
|
||||
if ((cur - min >= 3 || 2*cur - prev - next >= 3))
|
||||
c->codebookset[i] = 1;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 12; i < c->q_unit_cnt; i++) {
|
||||
const int cur = c->scalefactors[i];
|
||||
const int cnd = at9_q_unit_to_coeff_cnt[i] == 16;
|
||||
const int min = FFMIN(c->scalefactors[i + 1], c->scalefactors[i - 1]);
|
||||
if (c->codebookset[i])
|
||||
continue;
|
||||
|
||||
c->codebookset[i] = (((cur - min) >= 2) && (cur >= (avg - cnd)));
|
||||
}
|
||||
|
||||
c->scalefactors[c->q_unit_cnt] = last_sf;
|
||||
}
|
||||
|
||||
static inline void read_coeffs_coarse(ATRAC9Context *s, ATRAC9BlockData *b,
|
||||
ATRAC9ChannelData *c, GetBitContext *gb)
|
||||
{
|
||||
const int max_prec = s->samplerate_idx > 7 ? 1 : 7;
|
||||
|
||||
memset(c->q_coeffs_coarse, 0, sizeof(c->q_coeffs_coarse));
|
||||
|
||||
for (int i = 0; i < c->q_unit_cnt; i++) {
|
||||
int *coeffs = &c->q_coeffs_coarse[at9_q_unit_to_coeff_idx[i]];
|
||||
const int bands = at9_q_unit_to_coeff_cnt[i];
|
||||
const int prec = c->precision_coarse[i] + 1;
|
||||
|
||||
if (prec <= max_prec) {
|
||||
const int cb = c->codebookset[i];
|
||||
const int cbi = at9_q_unit_to_codebookidx[i];
|
||||
const VLC *tab = &s->coeff_vlc[cb][prec][cbi];
|
||||
const HuffmanCodebook *huff = &at9_huffman_coeffs[cb][prec][cbi];
|
||||
const int groups = bands >> huff->value_cnt_pow;
|
||||
|
||||
for (int j = 0; j < groups; j++) {
|
||||
uint16_t val = get_vlc2(gb, tab->table, 9, huff->max_bit_size);
|
||||
|
||||
for (int k = 0; k < huff->value_cnt; k++) {
|
||||
coeffs[k] = sign_extend(val, huff->value_bits);
|
||||
val >>= huff->value_bits;
|
||||
}
|
||||
|
||||
coeffs += huff->value_cnt;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < bands; j++)
|
||||
coeffs[j] = sign_extend(get_bits(gb, prec), prec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void read_coeffs_fine(ATRAC9Context *s, ATRAC9BlockData *b,
|
||||
ATRAC9ChannelData *c, GetBitContext *gb)
|
||||
{
|
||||
memset(c->q_coeffs_fine, 0, sizeof(c->q_coeffs_fine));
|
||||
|
||||
for (int i = 0; i < c->q_unit_cnt; i++) {
|
||||
const int start = at9_q_unit_to_coeff_idx[i + 0];
|
||||
const int end = at9_q_unit_to_coeff_idx[i + 1];
|
||||
const int len = c->precision_fine[i] + 1;
|
||||
|
||||
if (c->precision_fine[i] <= 0)
|
||||
continue;
|
||||
|
||||
for (int j = start; j < end; j++)
|
||||
c->q_coeffs_fine[j] = sign_extend(get_bits(gb, len), len);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dequantize(ATRAC9Context *s, ATRAC9BlockData *b,
|
||||
ATRAC9ChannelData *c)
|
||||
{
|
||||
memset(c->coeffs, 0, sizeof(c->coeffs));
|
||||
|
||||
for (int i = 0; i < c->q_unit_cnt; i++) {
|
||||
const int start = at9_q_unit_to_coeff_idx[i + 0];
|
||||
const int end = at9_q_unit_to_coeff_idx[i + 1];
|
||||
|
||||
const float coarse_c = at9_quant_step_coarse[c->precision_coarse[i]];
|
||||
const float fine_c = at9_quant_step_fine[c->precision_fine[i]];
|
||||
|
||||
for (int j = start; j < end; j++) {
|
||||
const float vc = c->q_coeffs_coarse[j] * coarse_c;
|
||||
const float vf = c->q_coeffs_fine[j] * fine_c;
|
||||
c->coeffs[j] = vc + vf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void apply_intensity_stereo(ATRAC9Context *s, ATRAC9BlockData *b,
|
||||
const int stereo)
|
||||
{
|
||||
float *src = b->channel[ b->cpe_base_channel].coeffs;
|
||||
float *dst = b->channel[!b->cpe_base_channel].coeffs;
|
||||
|
||||
if (!stereo)
|
||||
return;
|
||||
|
||||
if (b->q_unit_cnt <= b->stereo_q_unit)
|
||||
return;
|
||||
|
||||
for (int i = b->stereo_q_unit; i < b->q_unit_cnt; i++) {
|
||||
const int sign = b->is_signs[i];
|
||||
const int start = at9_q_unit_to_coeff_idx[i + 0];
|
||||
const int end = at9_q_unit_to_coeff_idx[i + 1];
|
||||
for (int j = start; j < end; j++)
|
||||
dst[j] = sign*src[j];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void apply_scalefactors(ATRAC9Context *s, ATRAC9BlockData *b,
|
||||
const int stereo)
|
||||
{
|
||||
for (int i = 0; i <= stereo; i++) {
|
||||
float *coeffs = b->channel[i].coeffs;
|
||||
for (int j = 0; j < b->q_unit_cnt; j++) {
|
||||
const int start = at9_q_unit_to_coeff_idx[j + 0];
|
||||
const int end = at9_q_unit_to_coeff_idx[j + 1];
|
||||
const int scalefactor = b->channel[i].scalefactors[j];
|
||||
const float scale = at9_scalefactor_c[scalefactor];
|
||||
for (int k = start; k < end; k++)
|
||||
coeffs[k] *= scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void fill_with_noise(ATRAC9Context *s, ATRAC9ChannelData *c,
|
||||
int start, int count)
|
||||
{
|
||||
float maxval = 0.0f;
|
||||
for (int i = 0; i < count; i += 2) {
|
||||
double tmp[2];
|
||||
av_bmg_get(&s->lfg, tmp);
|
||||
c->coeffs[start + i + 0] = tmp[0];
|
||||
c->coeffs[start + i + 1] = tmp[1];
|
||||
maxval = FFMAX(FFMAX(FFABS(tmp[0]), FFABS(tmp[1])), maxval);
|
||||
}
|
||||
/* Normalize */
|
||||
for (int i = 0; i < count; i++)
|
||||
c->coeffs[start + i] /= maxval;
|
||||
}
|
||||
|
||||
static inline void scale_band_ext_coeffs(ATRAC9ChannelData *c, float sf[6],
|
||||
const int s_unit, const int e_unit)
|
||||
{
|
||||
for (int i = s_unit; i < e_unit; i++) {
|
||||
const int start = at9_q_unit_to_coeff_idx[i + 0];
|
||||
const int end = at9_q_unit_to_coeff_idx[i + 1];
|
||||
for (int j = start; j < end; j++)
|
||||
c->coeffs[j] *= sf[i - s_unit];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void apply_band_extension(ATRAC9Context *s, ATRAC9BlockData *b,
|
||||
const int stereo)
|
||||
{
|
||||
const int g_units[4] = { /* A, B, C, total units */
|
||||
b->q_unit_cnt,
|
||||
at9_tab_band_ext_group[b->q_unit_cnt - 13][0],
|
||||
at9_tab_band_ext_group[b->q_unit_cnt - 13][1],
|
||||
FFMAX(g_units[2], 22),
|
||||
};
|
||||
|
||||
const int g_bins[4] = { /* A, B, C, total bins */
|
||||
at9_q_unit_to_coeff_idx[g_units[0]],
|
||||
at9_q_unit_to_coeff_idx[g_units[1]],
|
||||
at9_q_unit_to_coeff_idx[g_units[2]],
|
||||
at9_q_unit_to_coeff_idx[g_units[3]],
|
||||
};
|
||||
|
||||
if (!b->has_band_ext || !b->has_band_ext_data)
|
||||
return;
|
||||
|
||||
for (int ch = 0; ch <= stereo; ch++) {
|
||||
ATRAC9ChannelData *c = &b->channel[ch];
|
||||
|
||||
/* Mirror the spectrum */
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 0; j < (g_bins[i + 1] - g_bins[i + 0]); j++)
|
||||
c->coeffs[g_bins[i] + j] = c->coeffs[g_bins[i] - j - 1];
|
||||
|
||||
switch (c->band_ext) {
|
||||
case 0: {
|
||||
float sf[6] = { 0.0f };
|
||||
const int l = g_units[3] - g_units[0] - 1;
|
||||
const int n_start = at9_q_unit_to_coeff_idx[g_units[3] - 1];
|
||||
const int n_cnt = at9_q_unit_to_coeff_cnt[g_units[3] - 1];
|
||||
switch (at9_tab_band_ext_group[b->q_unit_cnt - 13][2]) {
|
||||
case 3:
|
||||
sf[0] = at9_band_ext_scales_m0[0][0][c->band_ext_data[0]];
|
||||
sf[1] = at9_band_ext_scales_m0[0][1][c->band_ext_data[0]];
|
||||
sf[2] = at9_band_ext_scales_m0[0][2][c->band_ext_data[1]];
|
||||
sf[3] = at9_band_ext_scales_m0[0][3][c->band_ext_data[2]];
|
||||
sf[4] = at9_band_ext_scales_m0[0][4][c->band_ext_data[3]];
|
||||
break;
|
||||
case 4:
|
||||
sf[0] = at9_band_ext_scales_m0[1][0][c->band_ext_data[0]];
|
||||
sf[1] = at9_band_ext_scales_m0[1][1][c->band_ext_data[0]];
|
||||
sf[2] = at9_band_ext_scales_m0[1][2][c->band_ext_data[1]];
|
||||
sf[3] = at9_band_ext_scales_m0[1][3][c->band_ext_data[2]];
|
||||
sf[4] = at9_band_ext_scales_m0[1][4][c->band_ext_data[3]];
|
||||
break;
|
||||
case 5:
|
||||
sf[0] = at9_band_ext_scales_m0[2][0][c->band_ext_data[0]];
|
||||
sf[1] = at9_band_ext_scales_m0[2][1][c->band_ext_data[1]];
|
||||
sf[2] = at9_band_ext_scales_m0[2][2][c->band_ext_data[1]];
|
||||
break;
|
||||
}
|
||||
|
||||
sf[l] = at9_scalefactor_c[c->scalefactors[g_units[0]]];
|
||||
|
||||
fill_with_noise(s, c, n_start, n_cnt);
|
||||
scale_band_ext_coeffs(c, sf, g_units[0], g_units[3]);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
float sf[6];
|
||||
for (int i = g_units[0]; i < g_units[3]; i++)
|
||||
sf[i - g_units[0]] = at9_scalefactor_c[c->scalefactors[i]];
|
||||
|
||||
fill_with_noise(s, c, g_bins[0], g_bins[3] - g_bins[0]);
|
||||
scale_band_ext_coeffs(c, sf, g_units[0], g_units[3]);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
const float g_sf[2] = {
|
||||
at9_band_ext_scales_m2[c->band_ext_data[0]],
|
||||
at9_band_ext_scales_m2[c->band_ext_data[1]],
|
||||
};
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
for (int j = g_bins[i + 0]; j < g_bins[i + 1]; j++)
|
||||
c->coeffs[j] *= g_sf[i];
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
float scale = at9_band_ext_scales_m3[c->band_ext_data[0]][0];
|
||||
float rate = at9_band_ext_scales_m3[c->band_ext_data[1]][1];
|
||||
rate = pow(2, rate);
|
||||
for (int i = g_bins[0]; i < g_bins[3]; i++) {
|
||||
scale *= rate;
|
||||
c->coeffs[i] *= scale;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
const float m = at9_band_ext_scales_m4[c->band_ext_data[0]];
|
||||
const float g_sf[3] = { 0.7079468f*m, 0.5011902f*m, 0.3548279f*m };
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = g_bins[i + 0]; j < g_bins[i + 1]; j++)
|
||||
c->coeffs[j] *= g_sf[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int atrac9_decode_block(ATRAC9Context *s, GetBitContext *gb,
|
||||
ATRAC9BlockData *b, AVFrame *frame,
|
||||
int frame_idx, int block_idx)
|
||||
{
|
||||
const int first_in_pkt = !get_bits1(gb);
|
||||
const int reuse_params = get_bits1(gb);
|
||||
const int stereo = s->block_config->type[block_idx] == ATRAC9_BLOCK_TYPE_CPE;
|
||||
|
||||
if (s->block_config->type[block_idx] == ATRAC9_BLOCK_TYPE_LFE) {
|
||||
ATRAC9ChannelData *c = &b->channel[0];
|
||||
const int precision = reuse_params ? 8 : 4;
|
||||
c->q_unit_cnt = b->q_unit_cnt = 2;
|
||||
|
||||
memset(c->scalefactors, 0, sizeof(c->scalefactors));
|
||||
memset(c->q_coeffs_fine, 0, sizeof(c->q_coeffs_fine));
|
||||
memset(c->q_coeffs_coarse, 0, sizeof(c->q_coeffs_coarse));
|
||||
|
||||
for (int i = 0; i < b->q_unit_cnt; i++) {
|
||||
c->scalefactors[i] = get_bits(gb, 5);
|
||||
c->precision_coarse[i] = precision;
|
||||
c->precision_fine[i] = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < c->q_unit_cnt; i++) {
|
||||
const int start = at9_q_unit_to_coeff_idx[i + 0];
|
||||
const int end = at9_q_unit_to_coeff_idx[i + 1];
|
||||
for (int j = start; j < end; j++)
|
||||
c->q_coeffs_coarse[j] = get_bits(gb, c->precision_coarse[i] + 1);
|
||||
}
|
||||
|
||||
dequantize (s, b, c);
|
||||
apply_scalefactors(s, b, 0);
|
||||
|
||||
goto imdct;
|
||||
}
|
||||
|
||||
if (first_in_pkt && reuse_params) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Invalid block flags!\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
/* Band parameters */
|
||||
if (!reuse_params) {
|
||||
int stereo_band, ext_band;
|
||||
const int min_band_count = s->samplerate_idx > 7 ? 1 : 3;
|
||||
b->band_count = get_bits(gb, 4) + min_band_count;
|
||||
b->q_unit_cnt = at9_tab_band_q_unit_map[b->band_count];
|
||||
|
||||
b->band_ext_q_unit = b->stereo_q_unit = b->q_unit_cnt;
|
||||
|
||||
if (b->band_count > at9_tab_sri_max_bands[s->samplerate_idx]) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Invalid band count %i!\n",
|
||||
b->band_count);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if (stereo) {
|
||||
stereo_band = get_bits(gb, 4) + min_band_count;
|
||||
if (stereo_band > b->band_count) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Invalid stereo band %i!\n",
|
||||
stereo_band);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
b->stereo_q_unit = at9_tab_band_q_unit_map[stereo_band];
|
||||
}
|
||||
|
||||
b->has_band_ext = get_bits1(gb);
|
||||
if (b->has_band_ext) {
|
||||
ext_band = get_bits(gb, 4) + min_band_count;
|
||||
if (ext_band < b->band_count) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Invalid extension band %i!\n",
|
||||
ext_band);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
b->band_ext_q_unit = at9_tab_band_q_unit_map[ext_band];
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate bit alloc gradient */
|
||||
if (parse_gradient(s, b, gb))
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
/* IS data */
|
||||
b->cpe_base_channel = 0;
|
||||
if (stereo) {
|
||||
b->cpe_base_channel = get_bits1(gb);
|
||||
if (get_bits1(gb)) {
|
||||
for (int i = b->stereo_q_unit; i < b->q_unit_cnt; i++)
|
||||
b->is_signs[i] = 1 - 2*get_bits1(gb);
|
||||
} else {
|
||||
for (int i = 0; i < FF_ARRAY_ELEMS(b->is_signs); i++)
|
||||
b->is_signs[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Band extension */
|
||||
if (parse_band_ext(s, b, gb, stereo))
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
/* Scalefactors */
|
||||
for (int i = 0; i <= stereo; i++) {
|
||||
ATRAC9ChannelData *c = &b->channel[i];
|
||||
c->q_unit_cnt = i == b->cpe_base_channel ? b->q_unit_cnt :
|
||||
b->stereo_q_unit;
|
||||
if (read_scalefactors(s, b, c, gb, i, first_in_pkt))
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
calc_precision (s, b, c);
|
||||
calc_codebook_idx (s, b, c);
|
||||
read_coeffs_coarse(s, b, c, gb);
|
||||
read_coeffs_fine (s, b, c, gb);
|
||||
dequantize (s, b, c);
|
||||
}
|
||||
|
||||
b->q_unit_cnt_prev = b->has_band_ext ? b->band_ext_q_unit : b->q_unit_cnt;
|
||||
|
||||
apply_intensity_stereo(s, b, stereo);
|
||||
apply_scalefactors (s, b, stereo);
|
||||
apply_band_extension (s, b, stereo);
|
||||
|
||||
imdct:
|
||||
for (int i = 0; i <= stereo; i++) {
|
||||
ATRAC9ChannelData *c = &b->channel[i];
|
||||
const int dst_idx = s->block_config->plane_map[block_idx][i];
|
||||
const int wsize = 1 << s->frame_log2;
|
||||
const ptrdiff_t offset = wsize*frame_idx*sizeof(float);
|
||||
float *dst = (float *)(frame->extended_data[dst_idx] + offset);
|
||||
|
||||
s->imdct.imdct_half(&s->imdct, s->temp, c->coeffs);
|
||||
s->fdsp->vector_fmul_window(dst, c->prev_win, s->temp,
|
||||
s->imdct_win, wsize >> 1);
|
||||
memcpy(c->prev_win, s->temp + (wsize >> 1), sizeof(float)*wsize >> 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atrac9_decode_frame(AVCodecContext *avctx, void *data,
|
||||
int *got_frame_ptr, AVPacket *avpkt)
|
||||
{
|
||||
int ret;
|
||||
GetBitContext gb;
|
||||
AVFrame *frame = data;
|
||||
ATRAC9Context *s = avctx->priv_data;
|
||||
const int frames = FFMIN(avpkt->size / s->avg_frame_size, s->frame_count);
|
||||
|
||||
frame->nb_samples = (1 << s->frame_log2) * frames;
|
||||
ret = ff_get_buffer(avctx, frame, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
init_get_bits8(&gb, avpkt->data, avpkt->size);
|
||||
|
||||
for (int i = 0; i < frames; i++) {
|
||||
for (int j = 0; j < s->block_config->count; j++) {
|
||||
ret = atrac9_decode_block(s, &gb, &s->block[j], frame, i, j);
|
||||
if (ret)
|
||||
return ret;
|
||||
align_get_bits(&gb);
|
||||
}
|
||||
}
|
||||
|
||||
*got_frame_ptr = 1;
|
||||
|
||||
return avctx->block_align;
|
||||
}
|
||||
|
||||
static void atrac9_decode_flush(AVCodecContext *avctx)
|
||||
{
|
||||
ATRAC9Context *s = avctx->priv_data;
|
||||
|
||||
for (int j = 0; j < s->block_config->count; j++) {
|
||||
ATRAC9BlockData *b = &s->block[j];
|
||||
const int stereo = s->block_config->type[j] == ATRAC9_BLOCK_TYPE_CPE;
|
||||
for (int i = 0; i <= stereo; i++) {
|
||||
ATRAC9ChannelData *c = &b->channel[i];
|
||||
memset(c->prev_win, 0, sizeof(c->prev_win));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static av_cold int atrac9_decode_close(AVCodecContext *avctx)
|
||||
{
|
||||
ATRAC9Context *s = avctx->priv_data;
|
||||
|
||||
for (int i = 1; i < 7; i++)
|
||||
ff_free_vlc(&s->sf_vlc[0][i]);
|
||||
for (int i = 2; i < 6; i++)
|
||||
ff_free_vlc(&s->sf_vlc[1][i]);
|
||||
for (int i = 0; i < 2; i++)
|
||||
for (int j = 0; j < 8; j++)
|
||||
for (int k = 0; k < 4; k++)
|
||||
ff_free_vlc(&s->coeff_vlc[i][j][k]);
|
||||
|
||||
ff_mdct_end(&s->imdct);
|
||||
av_free(s->fdsp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_cold int atrac9_decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
GetBitContext gb;
|
||||
ATRAC9Context *s = avctx->priv_data;
|
||||
int version, block_config_idx, superframe_idx, alloc_c_len;
|
||||
|
||||
s->avctx = avctx;
|
||||
|
||||
av_lfg_init(&s->lfg, 0xFBADF00D);
|
||||
|
||||
if (avctx->extradata_size != 12) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Invalid extradata length!\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
version = AV_RL32(avctx->extradata);
|
||||
if (version > 2) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unsupported version (%i)!\n", version);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
init_get_bits8(&gb, avctx->extradata + 4, avctx->extradata_size);
|
||||
|
||||
if (get_bits(&gb, 8) != 0xFE) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Incorrect magic byte!\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
s->samplerate_idx = get_bits(&gb, 4);
|
||||
avctx->sample_rate = at9_tab_samplerates[s->samplerate_idx];
|
||||
|
||||
block_config_idx = get_bits(&gb, 3);
|
||||
if (block_config_idx > 5) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Incorrect block config!\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
s->block_config = &at9_block_layout[block_config_idx];
|
||||
|
||||
avctx->channel_layout = s->block_config->channel_layout;
|
||||
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
|
||||
|
||||
if (get_bits1(&gb)) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Incorrect verification bit!\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
/* Average frame size in bytes */
|
||||
s->avg_frame_size = get_bits(&gb, 11) + 1;
|
||||
|
||||
superframe_idx = get_bits(&gb, 2);
|
||||
if (superframe_idx & 1) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Invalid superframe index!\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
s->frame_count = 1 << superframe_idx;
|
||||
s->frame_log2 = at9_tab_sri_frame_log2[s->samplerate_idx];
|
||||
|
||||
if (ff_mdct_init(&s->imdct, s->frame_log2 + 1, 1, 1.0f / 32768.0f))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
|
||||
if (!s->fdsp)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
/* iMDCT window */
|
||||
for (int i = 0; i < (1 << s->frame_log2); i++) {
|
||||
const int len = 1 << s->frame_log2;
|
||||
const float sidx = ( i + 0.5f) / len;
|
||||
const float eidx = (len - i - 0.5f) / len;
|
||||
const float s_c = sinf(sidx*M_PI - M_PI_2)*0.5f + 0.5f;
|
||||
const float e_c = sinf(eidx*M_PI - M_PI_2)*0.5f + 0.5f;
|
||||
s->imdct_win[i] = s_c / ((s_c * s_c) + (e_c * e_c));
|
||||
}
|
||||
|
||||
/* Allocation curve */
|
||||
alloc_c_len = FF_ARRAY_ELEMS(at9_tab_b_dist);
|
||||
for (int i = 1; i <= alloc_c_len; i++)
|
||||
for (int j = 0; j < i; j++)
|
||||
s->alloc_curve[i - 1][j] = at9_tab_b_dist[(j * alloc_c_len) / i];
|
||||
|
||||
/* Unsigned scalefactor VLCs */
|
||||
for (int i = 1; i < 7; i++) {
|
||||
const HuffmanCodebook *hf = &at9_huffman_sf_unsigned[i];
|
||||
|
||||
init_vlc(&s->sf_vlc[0][i], 9, hf->size, hf->bits, 1, 1, hf->codes,
|
||||
2, 2, 0);
|
||||
}
|
||||
|
||||
/* Signed scalefactor VLCs */
|
||||
for (int i = 2; i < 6; i++) {
|
||||
const HuffmanCodebook *hf = &at9_huffman_sf_signed[i];
|
||||
|
||||
int nums = hf->size;
|
||||
int16_t sym[32];
|
||||
for (int j = 0; j < nums; j++)
|
||||
sym[j] = sign_extend(j, hf->value_bits);
|
||||
|
||||
ff_init_vlc_sparse(&s->sf_vlc[1][i], 9, hf->size, hf->bits, 1, 1,
|
||||
hf->codes, 2, 2, sym, sizeof(*sym), sizeof(*sym), 0);
|
||||
}
|
||||
|
||||
/* Coefficient VLCs */
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
for (int k = 0; k < 4; k++) {
|
||||
const HuffmanCodebook *hf = &at9_huffman_coeffs[i][j][k];
|
||||
init_vlc(&s->coeff_vlc[i][j][k], 9, hf->size, hf->bits, 1, 1,
|
||||
hf->codes, 2, 2, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec ff_atrac9_decoder = {
|
||||
.name = "atrac9",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("ATRAC9 (Adaptive TRansform Acoustic Coding 9)"),
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = AV_CODEC_ID_ATRAC9,
|
||||
.priv_data_size = sizeof(ATRAC9Context),
|
||||
.init = atrac9_decode_init,
|
||||
.close = atrac9_decode_close,
|
||||
.decode = atrac9_decode_frame,
|
||||
.flush = atrac9_decode_flush,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
|
||||
.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
130
libavcodec/av1.h
130
libavcodec/av1.h
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* AV1 common definitions
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AV1_H
|
||||
#define AVCODEC_AV1_H
|
||||
|
||||
// OBU types (section 6.2.2).
|
||||
typedef enum {
|
||||
// 0 reserved.
|
||||
AV1_OBU_SEQUENCE_HEADER = 1,
|
||||
AV1_OBU_TEMPORAL_DELIMITER = 2,
|
||||
AV1_OBU_FRAME_HEADER = 3,
|
||||
AV1_OBU_TILE_GROUP = 4,
|
||||
AV1_OBU_METADATA = 5,
|
||||
AV1_OBU_FRAME = 6,
|
||||
AV1_OBU_REDUNDANT_FRAME_HEADER = 7,
|
||||
AV1_OBU_TILE_LIST = 8,
|
||||
// 9-14 reserved.
|
||||
AV1_OBU_PADDING = 15,
|
||||
} AV1_OBU_Type;
|
||||
|
||||
// Metadata types (section 6.7.1).
|
||||
enum {
|
||||
AV1_METADATA_TYPE_HDR_CLL = 1,
|
||||
AV1_METADATA_TYPE_HDR_MDCV = 2,
|
||||
AV1_METADATA_TYPE_SCALABILITY = 3,
|
||||
AV1_METADATA_TYPE_ITUT_T35 = 4,
|
||||
AV1_METADATA_TYPE_TIMECODE = 5,
|
||||
};
|
||||
|
||||
// Frame types (section 6.8.2).
|
||||
enum {
|
||||
AV1_FRAME_KEY = 0,
|
||||
AV1_FRAME_INTER = 1,
|
||||
AV1_FRAME_INTRA_ONLY = 2,
|
||||
AV1_FRAME_SWITCH = 3,
|
||||
};
|
||||
|
||||
// Reference frames (section 6.10.24).
|
||||
enum {
|
||||
AV1_REF_FRAME_INTRA = 0,
|
||||
AV1_REF_FRAME_LAST = 1,
|
||||
AV1_REF_FRAME_LAST2 = 2,
|
||||
AV1_REF_FRAME_LAST3 = 3,
|
||||
AV1_REF_FRAME_GOLDEN = 4,
|
||||
AV1_REF_FRAME_BWDREF = 5,
|
||||
AV1_REF_FRAME_ALTREF2 = 6,
|
||||
AV1_REF_FRAME_ALTREF = 7,
|
||||
};
|
||||
|
||||
// Constants (section 3).
|
||||
enum {
|
||||
AV1_MAX_OPERATING_POINTS = 32,
|
||||
|
||||
AV1_MAX_SB_SIZE = 128,
|
||||
AV1_MI_SIZE = 4,
|
||||
|
||||
AV1_MAX_TILE_WIDTH = 4096,
|
||||
AV1_MAX_TILE_AREA = 4096 * 2304,
|
||||
AV1_MAX_TILE_ROWS = 64,
|
||||
AV1_MAX_TILE_COLS = 64,
|
||||
|
||||
AV1_NUM_REF_FRAMES = 8,
|
||||
AV1_REFS_PER_FRAME = 7,
|
||||
AV1_TOTAL_REFS_PER_FRAME = 8,
|
||||
AV1_PRIMARY_REF_NONE = 7,
|
||||
|
||||
AV1_MAX_SEGMENTS = 8,
|
||||
AV1_SEG_LVL_MAX = 8,
|
||||
|
||||
AV1_SEG_LVL_ALT_Q = 0,
|
||||
AV1_SEG_LVL_ALT_LF_Y_V = 1,
|
||||
AV1_SEG_LVL_REF_FRAME = 5,
|
||||
AV1_SEG_LVL_SKIP = 6,
|
||||
AV1_SEG_LVL_GLOBAL_MV = 7,
|
||||
|
||||
AV1_SELECT_SCREEN_CONTENT_TOOLS = 2,
|
||||
AV1_SELECT_INTEGER_MV = 2,
|
||||
|
||||
AV1_SUPERRES_NUM = 8,
|
||||
AV1_SUPERRES_DENOM_MIN = 9,
|
||||
|
||||
AV1_INTERPOLATION_FILTER_SWITCHABLE = 4,
|
||||
|
||||
AV1_GM_ABS_ALPHA_BITS = 12,
|
||||
AV1_GM_ALPHA_PREC_BITS = 15,
|
||||
AV1_GM_ABS_TRANS_ONLY_BITS = 9,
|
||||
AV1_GM_TRANS_ONLY_PREC_BITS = 3,
|
||||
AV1_GM_ABS_TRANS_BITS = 12,
|
||||
AV1_GM_TRANS_PREC_BITS = 6,
|
||||
AV1_WARPEDMODEL_PREC_BITS = 16,
|
||||
|
||||
AV1_WARP_MODEL_IDENTITY = 0,
|
||||
AV1_WARP_MODEL_TRANSLATION = 1,
|
||||
AV1_WARP_MODEL_ROTZOOM = 2,
|
||||
AV1_WARP_MODEL_AFFINE = 3,
|
||||
};
|
||||
|
||||
|
||||
// The main colour configuration information uses the same ISO/IEC 23001-8
|
||||
// (H.273) enums as FFmpeg does, so separate definitions are not required.
|
||||
|
||||
// Chroma sample position.
|
||||
enum {
|
||||
AV1_CSP_UNKNOWN = 0,
|
||||
AV1_CSP_VERTICAL = 1, // -> AVCHROMA_LOC_LEFT.
|
||||
AV1_CSP_COLOCATED = 2, // -> AVCHROMA_LOC_TOPLEFT.
|
||||
};
|
||||
|
||||
#endif /* AVCODEC_AV1_H */
|
||||
@@ -1,298 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
#include "bsf.h"
|
||||
#include "cbs.h"
|
||||
#include "cbs_av1.h"
|
||||
|
||||
enum {
|
||||
PASS,
|
||||
INSERT,
|
||||
REMOVE,
|
||||
};
|
||||
|
||||
typedef struct AV1MetadataContext {
|
||||
const AVClass *class;
|
||||
|
||||
CodedBitstreamContext *cbc;
|
||||
CodedBitstreamFragment access_unit;
|
||||
|
||||
int td;
|
||||
|
||||
int color_primaries;
|
||||
int transfer_characteristics;
|
||||
int matrix_coefficients;
|
||||
|
||||
int color_range;
|
||||
int chroma_sample_position;
|
||||
|
||||
AVRational tick_rate;
|
||||
int num_ticks_per_picture;
|
||||
} AV1MetadataContext;
|
||||
|
||||
|
||||
static int av1_metadata_update_sequence_header(AVBSFContext *bsf,
|
||||
AV1RawSequenceHeader *seq)
|
||||
{
|
||||
AV1MetadataContext *ctx = bsf->priv_data;
|
||||
AV1RawColorConfig *clc = &seq->color_config;
|
||||
AV1RawTimingInfo *tim = &seq->timing_info;
|
||||
|
||||
if (ctx->color_primaries >= 0 ||
|
||||
ctx->transfer_characteristics >= 0 ||
|
||||
ctx->matrix_coefficients >= 0) {
|
||||
if (!clc->color_description_present_flag) {
|
||||
clc->color_description_present_flag = 1;
|
||||
clc->color_primaries = AVCOL_PRI_UNSPECIFIED;
|
||||
clc->transfer_characteristics = AVCOL_TRC_UNSPECIFIED;
|
||||
clc->matrix_coefficients = AVCOL_SPC_UNSPECIFIED;
|
||||
}
|
||||
|
||||
if (ctx->color_primaries >= 0)
|
||||
clc->color_primaries = ctx->color_primaries;
|
||||
if (ctx->transfer_characteristics >= 0)
|
||||
clc->transfer_characteristics = ctx->transfer_characteristics;
|
||||
if (ctx->matrix_coefficients >= 0)
|
||||
clc->matrix_coefficients = ctx->matrix_coefficients;
|
||||
}
|
||||
|
||||
if (ctx->color_range >= 0) {
|
||||
if (clc->color_primaries == AVCOL_PRI_BT709 &&
|
||||
clc->transfer_characteristics == AVCOL_TRC_IEC61966_2_1 &&
|
||||
clc->matrix_coefficients == AVCOL_SPC_RGB) {
|
||||
av_log(bsf, AV_LOG_WARNING, "Warning: color_range cannot be set "
|
||||
"on RGB streams encoded in BT.709 sRGB.\n");
|
||||
} else {
|
||||
clc->color_range = ctx->color_range;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->chroma_sample_position >= 0) {
|
||||
if (clc->mono_chrome || !clc->subsampling_x || !clc->subsampling_y) {
|
||||
av_log(bsf, AV_LOG_WARNING, "Warning: chroma_sample_position "
|
||||
"can only be set for 4:2:0 streams.\n");
|
||||
} else {
|
||||
clc->chroma_sample_position = ctx->chroma_sample_position;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->tick_rate.num && ctx->tick_rate.den) {
|
||||
int num, den;
|
||||
|
||||
av_reduce(&num, &den, ctx->tick_rate.num, ctx->tick_rate.den,
|
||||
UINT32_MAX > INT_MAX ? UINT32_MAX : INT_MAX);
|
||||
|
||||
tim->time_scale = num;
|
||||
tim->num_units_in_display_tick = den;
|
||||
seq->timing_info_present_flag = 1;
|
||||
|
||||
if (ctx->num_ticks_per_picture > 0) {
|
||||
tim->equal_picture_interval = 1;
|
||||
tim->num_ticks_per_picture_minus_1 =
|
||||
ctx->num_ticks_per_picture - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *out)
|
||||
{
|
||||
AV1MetadataContext *ctx = bsf->priv_data;
|
||||
AVPacket *in = NULL;
|
||||
CodedBitstreamFragment *frag = &ctx->access_unit;
|
||||
AV1RawOBU td, *obu;
|
||||
int err, i;
|
||||
|
||||
err = ff_bsf_get_packet(bsf, &in);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = ff_cbs_read_packet(ctx->cbc, frag, in);
|
||||
if (err < 0) {
|
||||
av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < frag->nb_units; i++) {
|
||||
if (frag->units[i].type == AV1_OBU_SEQUENCE_HEADER) {
|
||||
obu = frag->units[i].content;
|
||||
err = av1_metadata_update_sequence_header(bsf, &obu->obu.sequence_header);
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
// If a Temporal Delimiter is present, it must be the first OBU.
|
||||
if (frag->units[0].type == AV1_OBU_TEMPORAL_DELIMITER) {
|
||||
if (ctx->td == REMOVE)
|
||||
ff_cbs_delete_unit(ctx->cbc, frag, 0);
|
||||
} else if (ctx->td == INSERT) {
|
||||
td = (AV1RawOBU) {
|
||||
.header.obu_type = AV1_OBU_TEMPORAL_DELIMITER,
|
||||
};
|
||||
|
||||
err = ff_cbs_insert_unit_content(ctx->cbc, frag, 0, AV1_OBU_TEMPORAL_DELIMITER,
|
||||
&td, NULL);
|
||||
if (err < 0) {
|
||||
av_log(bsf, AV_LOG_ERROR, "Failed to insert Temporal Delimiter.\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
err = ff_cbs_write_packet(ctx->cbc, out, frag);
|
||||
if (err < 0) {
|
||||
av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = av_packet_copy_props(out, in);
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
|
||||
err = 0;
|
||||
fail:
|
||||
ff_cbs_fragment_uninit(ctx->cbc, frag);
|
||||
|
||||
if (err < 0)
|
||||
av_packet_unref(out);
|
||||
av_packet_free(&in);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int av1_metadata_init(AVBSFContext *bsf)
|
||||
{
|
||||
AV1MetadataContext *ctx = bsf->priv_data;
|
||||
CodedBitstreamFragment *frag = &ctx->access_unit;
|
||||
AV1RawOBU *obu;
|
||||
int err, i;
|
||||
|
||||
err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_AV1, bsf);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (bsf->par_in->extradata) {
|
||||
err = ff_cbs_read_extradata(ctx->cbc, frag, bsf->par_in);
|
||||
if (err < 0) {
|
||||
av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < frag->nb_units; i++) {
|
||||
if (frag->units[i].type == AV1_OBU_SEQUENCE_HEADER) {
|
||||
obu = frag->units[i].content;
|
||||
err = av1_metadata_update_sequence_header(bsf, &obu->obu.sequence_header);
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, frag);
|
||||
if (err < 0) {
|
||||
av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
err = 0;
|
||||
fail:
|
||||
ff_cbs_fragment_uninit(ctx->cbc, frag);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void av1_metadata_close(AVBSFContext *bsf)
|
||||
{
|
||||
AV1MetadataContext *ctx = bsf->priv_data;
|
||||
ff_cbs_close(&ctx->cbc);
|
||||
}
|
||||
|
||||
#define OFFSET(x) offsetof(AV1MetadataContext, x)
|
||||
#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM)
|
||||
static const AVOption av1_metadata_options[] = {
|
||||
{ "td", "Temporal Delimiter OBU",
|
||||
OFFSET(td), AV_OPT_TYPE_INT,
|
||||
{ .i64 = PASS }, PASS, REMOVE, FLAGS, "td" },
|
||||
{ "pass", NULL, 0, AV_OPT_TYPE_CONST,
|
||||
{ .i64 = PASS }, .flags = FLAGS, .unit = "td" },
|
||||
{ "insert", NULL, 0, AV_OPT_TYPE_CONST,
|
||||
{ .i64 = INSERT }, .flags = FLAGS, .unit = "td" },
|
||||
{ "remove", NULL, 0, AV_OPT_TYPE_CONST,
|
||||
{ .i64 = REMOVE }, .flags = FLAGS, .unit = "td" },
|
||||
|
||||
{ "color_primaries", "Set color primaries (section 6.4.2)",
|
||||
OFFSET(color_primaries), AV_OPT_TYPE_INT,
|
||||
{ .i64 = -1 }, -1, 255, FLAGS },
|
||||
{ "transfer_characteristics", "Set transfer characteristics (section 6.4.2)",
|
||||
OFFSET(transfer_characteristics), AV_OPT_TYPE_INT,
|
||||
{ .i64 = -1 }, -1, 255, FLAGS },
|
||||
{ "matrix_coefficients", "Set matrix coefficients (section 6.4.2)",
|
||||
OFFSET(matrix_coefficients), AV_OPT_TYPE_INT,
|
||||
{ .i64 = -1 }, -1, 255, FLAGS },
|
||||
|
||||
{ "color_range", "Set color range flag (section 6.4.2)",
|
||||
OFFSET(color_range), AV_OPT_TYPE_INT,
|
||||
{ .i64 = -1 }, -1, 1, FLAGS, "cr" },
|
||||
{ "tv", "TV (limited) range", 0, AV_OPT_TYPE_CONST,
|
||||
{ .i64 = 0 }, .flags = FLAGS, .unit = "cr" },
|
||||
{ "pc", "PC (full) range", 0, AV_OPT_TYPE_CONST,
|
||||
{ .i64 = 1 }, .flags = FLAGS, .unit = "cr" },
|
||||
|
||||
{ "chroma_sample_position", "Set chroma sample position (section 6.4.2)",
|
||||
OFFSET(chroma_sample_position), AV_OPT_TYPE_INT,
|
||||
{ .i64 = -1 }, -1, 3, FLAGS, "csp" },
|
||||
{ "unknown", "Unknown chroma sample position", 0, AV_OPT_TYPE_CONST,
|
||||
{ .i64 = AV1_CSP_UNKNOWN }, .flags = FLAGS, .unit = "csp" },
|
||||
{ "vertical", "Left chroma sample position", 0, AV_OPT_TYPE_CONST,
|
||||
{ .i64 = AV1_CSP_VERTICAL }, .flags = FLAGS, .unit = "csp" },
|
||||
{ "colocated", "Top-left chroma sample position", 0, AV_OPT_TYPE_CONST,
|
||||
{ .i64 = AV1_CSP_COLOCATED }, .flags = FLAGS, .unit = "csp" },
|
||||
|
||||
{ "tick_rate", "Set display tick rate (num_units_in_display_tick / time_scale)",
|
||||
OFFSET(tick_rate), AV_OPT_TYPE_RATIONAL,
|
||||
{ .dbl = 0.0 }, 0, UINT_MAX, FLAGS },
|
||||
{ "num_ticks_per_picture", "Set display ticks per picture for CFR streams",
|
||||
OFFSET(num_ticks_per_picture), AV_OPT_TYPE_INT,
|
||||
{ .i64 = -1 }, -1, INT_MAX, FLAGS },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const AVClass av1_metadata_class = {
|
||||
.class_name = "av1_metadata_bsf",
|
||||
.item_name = av_default_item_name,
|
||||
.option = av1_metadata_options,
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
};
|
||||
|
||||
static const enum AVCodecID av1_metadata_codec_ids[] = {
|
||||
AV_CODEC_ID_AV1, AV_CODEC_ID_NONE,
|
||||
};
|
||||
|
||||
const AVBitStreamFilter ff_av1_metadata_bsf = {
|
||||
.name = "av1_metadata",
|
||||
.priv_data_size = sizeof(AV1MetadataContext),
|
||||
.priv_class = &av1_metadata_class,
|
||||
.init = &av1_metadata_init,
|
||||
.close = &av1_metadata_close,
|
||||
.filter = &av1_metadata_filter,
|
||||
.codec_ids = av1_metadata_codec_ids,
|
||||
};
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* AV1 common parsing code
|
||||
*
|
||||
* 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 "config.h"
|
||||
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
#include "av1.h"
|
||||
#include "av1_parse.h"
|
||||
#include "bytestream.h"
|
||||
|
||||
int ff_av1_extract_obu(AV1OBU *obu, const uint8_t *buf, int length, void *logctx)
|
||||
{
|
||||
int64_t obu_size;
|
||||
int start_pos, type, temporal_id, spatial_id;
|
||||
int len;
|
||||
|
||||
len = parse_obu_header(buf, length, &obu_size, &start_pos,
|
||||
&type, &temporal_id, &spatial_id);
|
||||
if (len < 0)
|
||||
return len;
|
||||
|
||||
obu->type = type;
|
||||
obu->temporal_id = temporal_id;
|
||||
obu->spatial_id = spatial_id;
|
||||
|
||||
obu->data = buf + start_pos;
|
||||
obu->size = obu_size;
|
||||
obu->raw_data = buf;
|
||||
obu->raw_size = len;
|
||||
|
||||
av_log(logctx, AV_LOG_DEBUG,
|
||||
"obu_type: %d, temporal_id: %d, spatial_id: %d, payload size: %d\n",
|
||||
obu->type, obu->temporal_id, obu->spatial_id, obu->size);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int ff_av1_packet_split(AV1Packet *pkt, const uint8_t *buf, int length, void *logctx)
|
||||
{
|
||||
GetByteContext bc;
|
||||
int ret, consumed;
|
||||
|
||||
bytestream2_init(&bc, buf, length);
|
||||
pkt->nb_obus = 0;
|
||||
|
||||
while (bytestream2_get_bytes_left(&bc) > 0) {
|
||||
AV1OBU *obu;
|
||||
|
||||
if (pkt->obus_allocated < pkt->nb_obus + 1) {
|
||||
int new_size = pkt->obus_allocated + 1;
|
||||
AV1OBU *tmp = av_realloc_array(pkt->obus, new_size, sizeof(*tmp));
|
||||
if (!tmp)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
pkt->obus = tmp;
|
||||
memset(pkt->obus + pkt->obus_allocated, 0,
|
||||
(new_size - pkt->obus_allocated) * sizeof(*tmp));
|
||||
pkt->obus_allocated = new_size;
|
||||
}
|
||||
obu = &pkt->obus[pkt->nb_obus];
|
||||
|
||||
consumed = ff_av1_extract_obu(obu, bc.buffer, bytestream2_get_bytes_left(&bc), logctx);
|
||||
if (consumed < 0)
|
||||
return consumed;
|
||||
|
||||
bytestream2_skip(&bc, consumed);
|
||||
|
||||
obu->size_bits = get_obu_bit_length(obu->data, obu->size, obu->type);
|
||||
|
||||
if (obu->size_bits < 0 || (!obu->size_bits && obu->type != AV1_OBU_TEMPORAL_DELIMITER)) {
|
||||
av_log(logctx, AV_LOG_ERROR, "Invalid OBU of type %d, skipping.\n", obu->type);
|
||||
continue;
|
||||
}
|
||||
|
||||
pkt->nb_obus++;
|
||||
|
||||
ret = init_get_bits(&obu->gb, obu->data, obu->size_bits);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ff_av1_packet_uninit(AV1Packet *pkt)
|
||||
{
|
||||
av_freep(&pkt->obus);
|
||||
pkt->obus_allocated = 0;
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* AV1 common parsing code
|
||||
*
|
||||
* 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 AVCODEC_AV1_PARSE_H
|
||||
#define AVCODEC_AV1_PARSE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "av1.h"
|
||||
#include "avcodec.h"
|
||||
#include "get_bits.h"
|
||||
|
||||
typedef struct AV1OBU {
|
||||
/** Size of payload */
|
||||
int size;
|
||||
const uint8_t *data;
|
||||
|
||||
/**
|
||||
* Size, in bits, of just the data, excluding the trailing_one_bit and
|
||||
* any trailing padding.
|
||||
*/
|
||||
int size_bits;
|
||||
|
||||
/** Size of entire OBU, including header */
|
||||
int raw_size;
|
||||
const uint8_t *raw_data;
|
||||
|
||||
/** GetBitContext initialized to the start of the payload */
|
||||
GetBitContext gb;
|
||||
|
||||
int type;
|
||||
|
||||
int temporal_id;
|
||||
int spatial_id;
|
||||
} AV1OBU;
|
||||
|
||||
/** An input packet split into OBUs */
|
||||
typedef struct AV1Packet {
|
||||
AV1OBU *obus;
|
||||
int nb_obus;
|
||||
int obus_allocated;
|
||||
} AV1Packet;
|
||||
|
||||
/**
|
||||
* Extract an OBU from a raw bitstream.
|
||||
*
|
||||
* @note This function does not copy or store any bitstream data. All
|
||||
* the pointers in the AV1OBU structure will be valid as long
|
||||
* as the input buffer also is.
|
||||
*/
|
||||
int ff_av1_extract_obu(AV1OBU *obu, const uint8_t *buf, int length,
|
||||
void *logctx);
|
||||
|
||||
/**
|
||||
* Split an input packet into OBUs.
|
||||
*
|
||||
* @note This function does not copy or store any bitstream data. All
|
||||
* the pointers in the AV1Packet structure will be valid as
|
||||
* long as the input buffer also is.
|
||||
*/
|
||||
int ff_av1_packet_split(AV1Packet *pkt, const uint8_t *buf, int length,
|
||||
void *logctx);
|
||||
|
||||
/**
|
||||
* Free all the allocated memory in the packet.
|
||||
*/
|
||||
void ff_av1_packet_uninit(AV1Packet *pkt);
|
||||
|
||||
static inline int64_t leb128(GetBitContext *gb) {
|
||||
int64_t ret = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
int byte = get_bits(gb, 8);
|
||||
ret |= (int64_t)(byte & 0x7f) << (i * 7);
|
||||
if (!(byte & 0x80))
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int parse_obu_header(const uint8_t *buf, int buf_size,
|
||||
int64_t *obu_size, int *start_pos, int *type,
|
||||
int *temporal_id, int *spatial_id)
|
||||
{
|
||||
GetBitContext gb;
|
||||
int ret, extension_flag, has_size_flag;
|
||||
int64_t size;
|
||||
|
||||
ret = init_get_bits8(&gb, buf, FFMIN(buf_size, 2 + 8)); // OBU header fields + max leb128 length
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (get_bits1(&gb) != 0) // obu_forbidden_bit
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
*type = get_bits(&gb, 4);
|
||||
extension_flag = get_bits1(&gb);
|
||||
has_size_flag = get_bits1(&gb);
|
||||
skip_bits1(&gb); // obu_reserved_1bit
|
||||
|
||||
if (extension_flag) {
|
||||
*temporal_id = get_bits(&gb, 3);
|
||||
*spatial_id = get_bits(&gb, 2);
|
||||
skip_bits(&gb, 3); // extension_header_reserved_3bits
|
||||
} else {
|
||||
*temporal_id = *spatial_id = 0;
|
||||
}
|
||||
|
||||
*obu_size = has_size_flag ? leb128(&gb)
|
||||
: buf_size - 1 - extension_flag;
|
||||
|
||||
if (get_bits_left(&gb) < 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
*start_pos = get_bits_count(&gb) / 8;
|
||||
|
||||
size = *obu_size + *start_pos;
|
||||
|
||||
if (size > buf_size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static inline int get_obu_bit_length(const uint8_t *buf, int size, int type)
|
||||
{
|
||||
int v;
|
||||
|
||||
/* There are no trailing bits on these */
|
||||
if (type == AV1_OBU_TILE_GROUP || type == AV1_OBU_FRAME) {
|
||||
if (size > INT_MAX / 8)
|
||||
return AVERROR(ERANGE);
|
||||
else
|
||||
return size * 8;
|
||||
}
|
||||
|
||||
while (size > 0 && buf[size - 1] == 0)
|
||||
size--;
|
||||
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
v = buf[size - 1];
|
||||
|
||||
if (size > INT_MAX / 8)
|
||||
return AVERROR(ERANGE);
|
||||
size *= 8;
|
||||
|
||||
/* Remove the trailing_one_bit and following trailing zeros */
|
||||
if (v)
|
||||
size -= ff_ctz(v) + 1;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_AV1_PARSE_H */
|
||||
@@ -1,228 +0,0 @@
|
||||
/*
|
||||
* AV1 parser
|
||||
*
|
||||
* Copyright (C) 2018 James Almer <jamrial@gmail.com>
|
||||
*
|
||||
* 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 "av1_parse.h"
|
||||
#include "cbs.h"
|
||||
#include "cbs_av1.h"
|
||||
#include "parser.h"
|
||||
|
||||
typedef struct AV1ParseContext {
|
||||
CodedBitstreamContext *cbc;
|
||||
CodedBitstreamFragment temporal_unit;
|
||||
int parsed_extradata;
|
||||
} AV1ParseContext;
|
||||
|
||||
static const enum AVPixelFormat pix_fmts_8bit[2][2] = {
|
||||
{ AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE },
|
||||
{ AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P },
|
||||
};
|
||||
static const enum AVPixelFormat pix_fmts_10bit[2][2] = {
|
||||
{ AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE },
|
||||
{ AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV420P10 },
|
||||
};
|
||||
static const enum AVPixelFormat pix_fmts_12bit[2][2] = {
|
||||
{ AV_PIX_FMT_YUV444P12, AV_PIX_FMT_NONE },
|
||||
{ AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12 },
|
||||
};
|
||||
|
||||
static int av1_parser_parse(AVCodecParserContext *ctx,
|
||||
AVCodecContext *avctx,
|
||||
const uint8_t **out_data, int *out_size,
|
||||
const uint8_t *data, int size)
|
||||
{
|
||||
AV1ParseContext *s = ctx->priv_data;
|
||||
CodedBitstreamFragment *td = &s->temporal_unit;
|
||||
CodedBitstreamAV1Context *av1 = s->cbc->priv_data;
|
||||
int ret;
|
||||
|
||||
*out_data = data;
|
||||
*out_size = size;
|
||||
|
||||
ctx->key_frame = -1;
|
||||
ctx->pict_type = AV_PICTURE_TYPE_NONE;
|
||||
ctx->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
|
||||
|
||||
s->cbc->log_ctx = avctx;
|
||||
|
||||
if (avctx->extradata_size && !s->parsed_extradata) {
|
||||
s->parsed_extradata = 1;
|
||||
|
||||
ret = ff_cbs_read(s->cbc, td, avctx->extradata, avctx->extradata_size);
|
||||
if (ret < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Failed to parse extradata.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ff_cbs_fragment_uninit(s->cbc, td);
|
||||
}
|
||||
|
||||
ret = ff_cbs_read(s->cbc, td, data, size);
|
||||
if (ret < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Failed to parse temporal unit.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!av1->sequence_header) {
|
||||
av_log(avctx, AV_LOG_ERROR, "No sequence header available\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (int i = 0; i < td->nb_units; i++) {
|
||||
CodedBitstreamUnit *unit = &td->units[i];
|
||||
AV1RawOBU *obu = unit->content;
|
||||
AV1RawSequenceHeader *seq = av1->sequence_header;
|
||||
AV1RawColorConfig *color = &seq->color_config;
|
||||
AV1RawFrameHeader *frame;
|
||||
int frame_type;
|
||||
|
||||
if (unit->type == AV1_OBU_FRAME)
|
||||
frame = &obu->obu.frame.header;
|
||||
else if (unit->type == AV1_OBU_FRAME_HEADER)
|
||||
frame = &obu->obu.frame_header;
|
||||
else
|
||||
continue;
|
||||
|
||||
if (frame->show_existing_frame) {
|
||||
AV1ReferenceFrameState *ref = &av1->ref[frame->frame_to_show_map_idx];
|
||||
|
||||
if (!ref->valid) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Invalid reference frame\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ctx->width = ref->frame_width;
|
||||
ctx->height = ref->frame_height;
|
||||
frame_type = ref->frame_type;
|
||||
|
||||
ctx->key_frame = 0;
|
||||
} else if (!frame->show_frame) {
|
||||
continue;
|
||||
} else {
|
||||
ctx->width = av1->frame_width;
|
||||
ctx->height = av1->frame_height;
|
||||
frame_type = frame->frame_type;
|
||||
|
||||
ctx->key_frame = frame_type == AV1_FRAME_KEY;
|
||||
}
|
||||
|
||||
avctx->profile = seq->seq_profile;
|
||||
avctx->level = seq->seq_level_idx[0];
|
||||
|
||||
switch (frame_type) {
|
||||
case AV1_FRAME_KEY:
|
||||
case AV1_FRAME_INTRA_ONLY:
|
||||
ctx->pict_type = AV_PICTURE_TYPE_I;
|
||||
break;
|
||||
case AV1_FRAME_INTER:
|
||||
ctx->pict_type = AV_PICTURE_TYPE_P;
|
||||
break;
|
||||
case AV1_FRAME_SWITCH:
|
||||
ctx->pict_type = AV_PICTURE_TYPE_SP;
|
||||
break;
|
||||
}
|
||||
ctx->picture_structure = AV_PICTURE_STRUCTURE_FRAME;
|
||||
|
||||
switch (av1->bit_depth) {
|
||||
case 8:
|
||||
ctx->format = color->mono_chrome ? AV_PIX_FMT_GRAY8
|
||||
: pix_fmts_8bit [color->subsampling_x][color->subsampling_y];
|
||||
break;
|
||||
case 10:
|
||||
ctx->format = color->mono_chrome ? AV_PIX_FMT_GRAY10
|
||||
: pix_fmts_10bit[color->subsampling_x][color->subsampling_y];
|
||||
break;
|
||||
case 12:
|
||||
ctx->format = color->mono_chrome ? AV_PIX_FMT_GRAY12
|
||||
: pix_fmts_12bit[color->subsampling_x][color->subsampling_y];
|
||||
break;
|
||||
}
|
||||
av_assert2(ctx->format != AV_PIX_FMT_NONE);
|
||||
}
|
||||
|
||||
end:
|
||||
ff_cbs_fragment_uninit(s->cbc, td);
|
||||
|
||||
s->cbc->log_ctx = NULL;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static const CodedBitstreamUnitType decompose_unit_types[] = {
|
||||
AV1_OBU_TEMPORAL_DELIMITER,
|
||||
AV1_OBU_SEQUENCE_HEADER,
|
||||
AV1_OBU_FRAME_HEADER,
|
||||
AV1_OBU_TILE_GROUP,
|
||||
AV1_OBU_FRAME,
|
||||
};
|
||||
|
||||
static av_cold int av1_parser_init(AVCodecParserContext *ctx)
|
||||
{
|
||||
AV1ParseContext *s = ctx->priv_data;
|
||||
int ret;
|
||||
|
||||
ret = ff_cbs_init(&s->cbc, AV_CODEC_ID_AV1, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
s->cbc->decompose_unit_types = (CodedBitstreamUnitType *)decompose_unit_types;
|
||||
s->cbc->nb_decompose_unit_types = FF_ARRAY_ELEMS(decompose_unit_types);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void av1_parser_close(AVCodecParserContext *ctx)
|
||||
{
|
||||
AV1ParseContext *s = ctx->priv_data;
|
||||
|
||||
ff_cbs_close(&s->cbc);
|
||||
}
|
||||
|
||||
static int av1_parser_split(AVCodecContext *avctx,
|
||||
const uint8_t *buf, int buf_size)
|
||||
{
|
||||
AV1OBU obu;
|
||||
const uint8_t *ptr = buf, *end = buf + buf_size;
|
||||
|
||||
while (ptr < end) {
|
||||
int len = ff_av1_extract_obu(&obu, ptr, buf_size, avctx);
|
||||
if (len < 0)
|
||||
break;
|
||||
|
||||
if (obu.type == AV1_OBU_FRAME_HEADER ||
|
||||
obu.type == AV1_OBU_FRAME) {
|
||||
return ptr - buf;
|
||||
}
|
||||
ptr += len;
|
||||
buf_size -= len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodecParser ff_av1_parser = {
|
||||
.codec_ids = { AV_CODEC_ID_AV1 },
|
||||
.priv_data_size = sizeof(AV1ParseContext),
|
||||
.parser_init = av1_parser_init,
|
||||
.parser_close = av1_parser_close,
|
||||
.parser_parse = av1_parser_parse,
|
||||
.split = av1_parser_split,
|
||||
};
|
||||
@@ -409,7 +409,6 @@ enum AVCodecID {
|
||||
AV_CODEC_ID_DXV,
|
||||
AV_CODEC_ID_SCREENPRESSO,
|
||||
AV_CODEC_ID_RSCC,
|
||||
AV_CODEC_ID_AVS2,
|
||||
|
||||
AV_CODEC_ID_Y41P = 0x8000,
|
||||
AV_CODEC_ID_AVRP,
|
||||
@@ -447,11 +446,6 @@ enum AVCodecID {
|
||||
AV_CODEC_ID_SVG,
|
||||
AV_CODEC_ID_GDV,
|
||||
AV_CODEC_ID_FITS,
|
||||
AV_CODEC_ID_IMM4,
|
||||
AV_CODEC_ID_PROSUMER,
|
||||
AV_CODEC_ID_MWSC,
|
||||
AV_CODEC_ID_WCMV,
|
||||
AV_CODEC_ID_RASC,
|
||||
|
||||
/* various PCM "codecs" */
|
||||
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
|
||||
@@ -491,7 +485,6 @@ enum AVCodecID {
|
||||
AV_CODEC_ID_PCM_S64BE,
|
||||
AV_CODEC_ID_PCM_F16LE,
|
||||
AV_CODEC_ID_PCM_F24LE,
|
||||
AV_CODEC_ID_PCM_VIDC,
|
||||
|
||||
/* various ADPCM codecs */
|
||||
AV_CODEC_ID_ADPCM_IMA_QT = 0x11000,
|
||||
@@ -644,7 +637,6 @@ enum AVCodecID {
|
||||
AV_CODEC_ID_APTX,
|
||||
AV_CODEC_ID_APTX_HD,
|
||||
AV_CODEC_ID_SBC,
|
||||
AV_CODEC_ID_ATRAC9,
|
||||
|
||||
/* subtitle codecs */
|
||||
AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs.
|
||||
@@ -673,7 +665,6 @@ enum AVCodecID {
|
||||
AV_CODEC_ID_PJS,
|
||||
AV_CODEC_ID_ASS,
|
||||
AV_CODEC_ID_HDMV_TEXT_SUBTITLE,
|
||||
AV_CODEC_ID_TTML,
|
||||
|
||||
/* other specific kind of codecs (generally used for attachments) */
|
||||
AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs.
|
||||
@@ -1321,7 +1312,7 @@ enum AVPacketSideDataType {
|
||||
AV_PKT_DATA_METADATA_UPDATE,
|
||||
|
||||
/**
|
||||
* MPEGTS stream ID, this is required to pass the stream ID
|
||||
* MPEGTS stream ID as uint8_t, this is required to pass the stream ID
|
||||
* information from the demuxer to the corresponding muxer.
|
||||
*/
|
||||
AV_PKT_DATA_MPEGTS_STREAM_ID,
|
||||
@@ -1366,12 +1357,6 @@ enum AVPacketSideDataType {
|
||||
*/
|
||||
AV_PKT_DATA_ENCRYPTION_INFO,
|
||||
|
||||
/**
|
||||
* Active Format Description data consisting of a single byte as specified
|
||||
* in ETSI TS 101 154 using AVActiveFormatDescription enum.
|
||||
*/
|
||||
AV_PKT_DATA_AFD,
|
||||
|
||||
/**
|
||||
* The number of side data types.
|
||||
* This is not part of the public API/ABI in the sense that it may
|
||||
@@ -1627,7 +1612,6 @@ typedef struct AVCodecContext {
|
||||
* The allocated memory should be AV_INPUT_BUFFER_PADDING_SIZE bytes larger
|
||||
* than extradata_size to avoid problems if it is read with the bitstream reader.
|
||||
* The bytewise contents of extradata must not depend on the architecture or CPU endianness.
|
||||
* Must be allocated with the av_malloc() family of functions.
|
||||
* - encoding: Set/allocated/freed by libavcodec.
|
||||
* - decoding: Set/allocated/freed by user.
|
||||
*/
|
||||
@@ -5782,7 +5766,6 @@ typedef struct AVBitStreamFilter {
|
||||
int (*init)(AVBSFContext *ctx);
|
||||
int (*filter)(AVBSFContext *ctx, AVPacket *pkt);
|
||||
void (*close)(AVBSFContext *ctx);
|
||||
void (*flush)(AVBSFContext *ctx);
|
||||
} AVBitStreamFilter;
|
||||
|
||||
#if FF_API_OLD_BSF
|
||||
@@ -5909,11 +5892,6 @@ int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt);
|
||||
*/
|
||||
int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt);
|
||||
|
||||
/**
|
||||
* Reset the internal bitstream filter state / flush internal buffers.
|
||||
*/
|
||||
void av_bsf_flush(AVBSFContext *ctx);
|
||||
|
||||
/**
|
||||
* Free a bitstream filter context and everything associated with it; write NULL
|
||||
* into the supplied pointer.
|
||||
|
||||
@@ -375,9 +375,6 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type)
|
||||
case AV_PKT_DATA_DISPLAYMATRIX: return "Display Matrix";
|
||||
case AV_PKT_DATA_STEREO3D: return "Stereo 3D";
|
||||
case AV_PKT_DATA_AUDIO_SERVICE_TYPE: return "Audio Service Type";
|
||||
case AV_PKT_DATA_QUALITY_STATS: return "Quality stats";
|
||||
case AV_PKT_DATA_FALLBACK_TRACK: return "Fallback track";
|
||||
case AV_PKT_DATA_CPB_PROPERTIES: return "CPB properties";
|
||||
case AV_PKT_DATA_SKIP_SAMPLES: return "Skip Samples";
|
||||
case AV_PKT_DATA_JP_DUALMONO: return "JP Dual Mono";
|
||||
case AV_PKT_DATA_STRINGS_METADATA: return "Strings Metadata";
|
||||
@@ -391,9 +388,6 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type)
|
||||
case AV_PKT_DATA_CONTENT_LIGHT_LEVEL: return "Content light level metadata";
|
||||
case AV_PKT_DATA_SPHERICAL: return "Spherical Mapping";
|
||||
case AV_PKT_DATA_A53_CC: return "A53 Closed Captions";
|
||||
case AV_PKT_DATA_ENCRYPTION_INIT_INFO: return "Encryption initialization data";
|
||||
case AV_PKT_DATA_ENCRYPTION_INFO: return "Encryption info";
|
||||
case AV_PKT_DATA_AFD: return "Active Format Description data";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -580,10 +574,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||
dst->side_data = NULL;
|
||||
dst->side_data_elems = 0;
|
||||
for (i = 0; i < src->side_data_elems; i++) {
|
||||
enum AVPacketSideDataType type = src->side_data[i].type;
|
||||
int size = src->side_data[i].size;
|
||||
uint8_t *src_data = src->side_data[i].data;
|
||||
uint8_t *dst_data = av_packet_new_side_data(dst, type, size);
|
||||
enum AVPacketSideDataType type = src->side_data[i].type;
|
||||
int size = src->side_data[i].size;
|
||||
uint8_t *src_data = src->side_data[i].data;
|
||||
uint8_t *dst_data = av_packet_new_side_data(dst, type, size);
|
||||
|
||||
if (!dst_data) {
|
||||
av_packet_free_side_data(dst);
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* AVS2-P2/IEEE1857.4 video parser.
|
||||
* Copyright (c) 2018 Huiwen Ren <hwrenx@gmail.com>
|
||||
*
|
||||
* 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 "parser.h"
|
||||
|
||||
#define SLICE_MAX_START_CODE 0x000001af
|
||||
|
||||
#define ISPIC(x) ((x) == 0xB3 || (x) == 0xB6)
|
||||
#define ISUNIT(x) ((x) == 0xB0 || (x) == 0xB1 || (x) == 0xB2 || ISPIC(x))
|
||||
|
||||
static int avs2_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
|
||||
{
|
||||
int pic_found = pc->frame_start_found;
|
||||
uint32_t state = pc->state;
|
||||
int cur = 0;
|
||||
|
||||
if (!pic_found) {
|
||||
for (; cur < buf_size; ++cur) {
|
||||
state = (state<<8) | buf[cur];
|
||||
if (ISUNIT(buf[cur])){
|
||||
++cur;
|
||||
pic_found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pic_found) {
|
||||
if (!buf_size)
|
||||
return END_NOT_FOUND;
|
||||
for (; cur < buf_size; ++cur) {
|
||||
state = (state << 8) | buf[cur];
|
||||
if ((state & 0xFFFFFF00) == 0x100 && state > SLICE_MAX_START_CODE) {
|
||||
pc->frame_start_found = 0;
|
||||
pc->state = -1;
|
||||
return cur - 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pc->frame_start_found = pic_found;
|
||||
pc->state = state;
|
||||
|
||||
return END_NOT_FOUND;
|
||||
}
|
||||
|
||||
static int avs2_parse(AVCodecParserContext *s, AVCodecContext *avctx,
|
||||
const uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *buf, int buf_size)
|
||||
{
|
||||
ParseContext *pc = s->priv_data;
|
||||
int next;
|
||||
|
||||
if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
|
||||
next = buf_size;
|
||||
} else {
|
||||
next = avs2_find_frame_end(pc, buf, buf_size);
|
||||
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
|
||||
*poutbuf = NULL;
|
||||
*poutbuf_size = 0;
|
||||
return buf_size;
|
||||
}
|
||||
}
|
||||
|
||||
*poutbuf = buf;
|
||||
*poutbuf_size = buf_size;
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
AVCodecParser ff_avs2_parser = {
|
||||
.codec_ids = { AV_CODEC_ID_AVS2 },
|
||||
.priv_data_size = sizeof(ParseContext),
|
||||
.parser_parse = avs2_parse,
|
||||
.parser_close = ff_parse_close,
|
||||
.split = ff_mpeg4video_split,
|
||||
};
|
||||
@@ -109,6 +109,11 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx,
|
||||
if(yoffset >= avctx->height)
|
||||
return AVERROR_INVALIDDATA;
|
||||
dst += vid->frame->linesize[0] * yoffset;
|
||||
case VIDEO_P_FRAME:
|
||||
case VIDEO_I_FRAME:
|
||||
break;
|
||||
default:
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
// main code
|
||||
|
||||
@@ -371,19 +371,11 @@ static const uint8_t bink_rlelens[4] = { 4, 8, 12, 32 };
|
||||
|
||||
static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
|
||||
{
|
||||
BinkContext * const c = avctx->priv_data;
|
||||
int t, v;
|
||||
int last = 0;
|
||||
const uint8_t *dec_end;
|
||||
|
||||
CHECK_READ_VAL(gb, b, t);
|
||||
if (c->version == 'k') {
|
||||
t ^= 0xBBu;
|
||||
if (t == 0) {
|
||||
b->cur_dec = NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
dec_end = b->cur_dec + t;
|
||||
if (dec_end > b->data_end) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Too many block type values\n");
|
||||
@@ -1002,17 +994,6 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
|
||||
int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3;
|
||||
int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3;
|
||||
int width = c->avctx->width >> is_chroma;
|
||||
int height = c->avctx->height >> is_chroma;
|
||||
|
||||
if (c->version == 'k' && get_bits1(gb)) {
|
||||
int fill = get_bits(gb, 8);
|
||||
|
||||
dst = frame->data[plane_idx];
|
||||
|
||||
for (i = 0; i < height; i++)
|
||||
memset(dst + i * stride, fill, width);
|
||||
goto end;
|
||||
}
|
||||
|
||||
init_lengths(c, FFMAX(width, 8), bw);
|
||||
for (i = 0; i < BINK_NB_SRC; i++)
|
||||
@@ -1209,8 +1190,6 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary
|
||||
skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F));
|
||||
|
||||
@@ -1343,7 +1322,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||
return ret;
|
||||
|
||||
avctx->pix_fmt = c->has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P;
|
||||
avctx->color_range = c->version == 'k' ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
|
||||
|
||||
ff_blockdsp_init(&c->bdsp, avctx);
|
||||
ff_hpeldsp_init(&c->hdsp, avctx->flags);
|
||||
|
||||
@@ -96,6 +96,11 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||
if (avctx->width < FONT_WIDTH || avctx->height < s->font_height)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
|
||||
s->frame = av_frame_alloc();
|
||||
if (!s->frame)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -141,12 +146,8 @@ static int decode_frame(AVCodecContext *avctx,
|
||||
const uint8_t *buf_end = buf+buf_size;
|
||||
int ret;
|
||||
|
||||
if ((avctx->width / FONT_WIDTH) * (avctx->height / s->font_height) / 256 > buf_size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
s->frame = data;
|
||||
s->x = s->y = 0;
|
||||
if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0)
|
||||
if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
|
||||
return ret;
|
||||
s->frame->pict_type = AV_PICTURE_TYPE_I;
|
||||
s->frame->palette_has_changed = 1;
|
||||
@@ -204,10 +205,21 @@ static int decode_frame(AVCodecContext *avctx,
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret = av_frame_ref(data, s->frame)) < 0)
|
||||
return ret;
|
||||
*got_frame = 1;
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
static av_cold int decode_end(AVCodecContext *avctx)
|
||||
{
|
||||
XbinContext *s = avctx->priv_data;
|
||||
|
||||
av_frame_free(&s->frame);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_BINTEXT_DECODER
|
||||
AVCodec ff_bintext_decoder = {
|
||||
.name = "bintext",
|
||||
@@ -216,6 +228,7 @@ AVCodec ff_bintext_decoder = {
|
||||
.id = AV_CODEC_ID_BINTEXT,
|
||||
.priv_data_size = sizeof(XbinContext),
|
||||
.init = decode_init,
|
||||
.close = decode_end,
|
||||
.decode = decode_frame,
|
||||
.capabilities = AV_CODEC_CAP_DR1,
|
||||
};
|
||||
@@ -228,6 +241,7 @@ AVCodec ff_xbin_decoder = {
|
||||
.id = AV_CODEC_ID_XBIN,
|
||||
.priv_data_size = sizeof(XbinContext),
|
||||
.init = decode_init,
|
||||
.close = decode_end,
|
||||
.decode = decode_frame,
|
||||
.capabilities = AV_CODEC_CAP_DR1,
|
||||
};
|
||||
@@ -240,6 +254,7 @@ AVCodec ff_idf_decoder = {
|
||||
.id = AV_CODEC_ID_IDF,
|
||||
.priv_data_size = sizeof(XbinContext),
|
||||
.init = decode_init,
|
||||
.close = decode_end,
|
||||
.decode = decode_frame,
|
||||
.capabilities = AV_CODEC_CAP_DR1,
|
||||
};
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "bsf.h"
|
||||
|
||||
extern const AVBitStreamFilter ff_aac_adtstoasc_bsf;
|
||||
extern const AVBitStreamFilter ff_av1_metadata_bsf;
|
||||
extern const AVBitStreamFilter ff_chomp_bsf;
|
||||
extern const AVBitStreamFilter ff_dump_extradata_bsf;
|
||||
extern const AVBitStreamFilter ff_dca_core_bsf;
|
||||
@@ -50,7 +49,6 @@ extern const AVBitStreamFilter ff_null_bsf;
|
||||
extern const AVBitStreamFilter ff_remove_extradata_bsf;
|
||||
extern const AVBitStreamFilter ff_text2movsub_bsf;
|
||||
extern const AVBitStreamFilter ff_trace_headers_bsf;
|
||||
extern const AVBitStreamFilter ff_vp9_metadata_bsf;
|
||||
extern const AVBitStreamFilter ff_vp9_raw_reorder_bsf;
|
||||
extern const AVBitStreamFilter ff_vp9_superframe_bsf;
|
||||
extern const AVBitStreamFilter ff_vp9_superframe_split_bsf;
|
||||
|
||||
@@ -291,7 +291,7 @@ static int bmp_decode_frame(AVCodecContext *avctx,
|
||||
case 1:
|
||||
for (i = 0; i < avctx->height; i++) {
|
||||
int j;
|
||||
for (j = 0; j < n; j++) {
|
||||
for (j = 0; j < avctx->width >> 3; j++) {
|
||||
ptr[j*8+0] = buf[j] >> 7;
|
||||
ptr[j*8+1] = (buf[j] >> 6) & 1;
|
||||
ptr[j*8+2] = (buf[j] >> 5) & 1;
|
||||
@@ -301,6 +301,9 @@ static int bmp_decode_frame(AVCodecContext *avctx,
|
||||
ptr[j*8+6] = (buf[j] >> 1) & 1;
|
||||
ptr[j*8+7] = buf[j] & 1;
|
||||
}
|
||||
for (j = 0; j < (avctx->width & 7); j++) {
|
||||
ptr[avctx->width - (avctx->width & 7) + j] = buf[avctx->width >> 3] >> (7 - j) & 1;
|
||||
}
|
||||
buf += n;
|
||||
ptr += linesize;
|
||||
}
|
||||
|
||||
@@ -172,16 +172,6 @@ int av_bsf_init(AVBSFContext *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void av_bsf_flush(AVBSFContext *ctx)
|
||||
{
|
||||
ctx->internal->eof = 0;
|
||||
|
||||
av_packet_unref(ctx->internal->buffer_pkt);
|
||||
|
||||
if (ctx->filter->flush)
|
||||
ctx->filter->flush(ctx);
|
||||
}
|
||||
|
||||
int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -45,9 +45,6 @@
|
||||
#if ARCH_X86
|
||||
# include "x86/cabac.h"
|
||||
#endif
|
||||
#if ARCH_MIPS
|
||||
# include "mips/cabac.h"
|
||||
#endif
|
||||
|
||||
static const uint8_t * const ff_h264_norm_shift = ff_h264_cabac_tables + H264_NORM_SHIFT_OFFSET;
|
||||
static const uint8_t * const ff_h264_lps_range = ff_h264_cabac_tables + H264_LPS_RANGE_OFFSET;
|
||||
|
||||
@@ -591,14 +591,21 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb,
|
||||
}
|
||||
|
||||
|
||||
static inline void decode_residual_chroma(AVSContext *h)
|
||||
static inline int decode_residual_chroma(AVSContext *h)
|
||||
{
|
||||
if (h->cbp & (1 << 4))
|
||||
decode_residual_block(h, &h->gb, chroma_dec, 0,
|
||||
if (h->cbp & (1 << 4)) {
|
||||
int ret = decode_residual_block(h, &h->gb, chroma_dec, 0,
|
||||
ff_cavs_chroma_qp[h->qp], h->cu, h->c_stride);
|
||||
if (h->cbp & (1 << 5))
|
||||
decode_residual_block(h, &h->gb, chroma_dec, 0,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
if (h->cbp & (1 << 5)) {
|
||||
int ret = decode_residual_block(h, &h->gb, chroma_dec, 0,
|
||||
ff_cavs_chroma_qp[h->qp], h->cv, h->c_stride);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int decode_residual_inter(AVSContext *h)
|
||||
@@ -649,6 +656,7 @@ static int decode_mb_i(AVSContext *h, int cbp_code)
|
||||
uint8_t top[18];
|
||||
uint8_t *left = NULL;
|
||||
uint8_t *d;
|
||||
int ret;
|
||||
|
||||
ff_cavs_init_mb(h);
|
||||
|
||||
@@ -692,8 +700,11 @@ static int decode_mb_i(AVSContext *h, int cbp_code)
|
||||
ff_cavs_load_intra_pred_luma(h, top, &left, block);
|
||||
h->intra_pred_l[h->pred_mode_Y[scan3x3[block]]]
|
||||
(d, top, left, h->l_stride);
|
||||
if (h->cbp & (1<<block))
|
||||
decode_residual_block(h, gb, intra_dec, 1, h->qp, d, h->l_stride);
|
||||
if (h->cbp & (1<<block)) {
|
||||
ret = decode_residual_block(h, gb, intra_dec, 1, h->qp, d, h->l_stride);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* chroma intra prediction */
|
||||
@@ -703,7 +714,9 @@ static int decode_mb_i(AVSContext *h, int cbp_code)
|
||||
h->intra_pred_c[pred_mode_uv](h->cv, &h->top_border_v[h->mbx * 10],
|
||||
h->left_border_v, h->c_stride);
|
||||
|
||||
decode_residual_chroma(h);
|
||||
ret = decode_residual_chroma(h);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ff_cavs_filter(h, I_8X8);
|
||||
set_mv_intra(h);
|
||||
return 0;
|
||||
|
||||
122
libavcodec/cbs.c
122
libavcodec/cbs.c
@@ -29,44 +29,26 @@
|
||||
|
||||
|
||||
static const CodedBitstreamType *cbs_type_table[] = {
|
||||
#if CONFIG_CBS_AV1
|
||||
&ff_cbs_type_av1,
|
||||
#endif
|
||||
#if CONFIG_CBS_H264
|
||||
&ff_cbs_type_h264,
|
||||
#endif
|
||||
#if CONFIG_CBS_H265
|
||||
&ff_cbs_type_h265,
|
||||
#endif
|
||||
#if CONFIG_CBS_JPEG
|
||||
&ff_cbs_type_jpeg,
|
||||
#endif
|
||||
#if CONFIG_CBS_MPEG2
|
||||
&ff_cbs_type_mpeg2,
|
||||
#endif
|
||||
#if CONFIG_CBS_VP9
|
||||
&ff_cbs_type_vp9,
|
||||
#endif
|
||||
};
|
||||
|
||||
const enum AVCodecID ff_cbs_all_codec_ids[] = {
|
||||
#if CONFIG_CBS_AV1
|
||||
AV_CODEC_ID_AV1,
|
||||
#endif
|
||||
#if CONFIG_CBS_H264
|
||||
AV_CODEC_ID_H264,
|
||||
#endif
|
||||
#if CONFIG_CBS_H265
|
||||
AV_CODEC_ID_H265,
|
||||
#endif
|
||||
#if CONFIG_CBS_JPEG
|
||||
AV_CODEC_ID_MJPEG,
|
||||
#endif
|
||||
#if CONFIG_CBS_MPEG2
|
||||
AV_CODEC_ID_MPEG2VIDEO,
|
||||
#endif
|
||||
#if CONFIG_CBS_VP9
|
||||
AV_CODEC_ID_VP9,
|
||||
#endif
|
||||
AV_CODEC_ID_NONE
|
||||
};
|
||||
@@ -158,30 +140,26 @@ static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
|
||||
int err, i, j;
|
||||
|
||||
for (i = 0; i < frag->nb_units; i++) {
|
||||
CodedBitstreamUnit *unit = &frag->units[i];
|
||||
|
||||
if (ctx->decompose_unit_types) {
|
||||
for (j = 0; j < ctx->nb_decompose_unit_types; j++) {
|
||||
if (ctx->decompose_unit_types[j] == unit->type)
|
||||
if (ctx->decompose_unit_types[j] == frag->units[i].type)
|
||||
break;
|
||||
}
|
||||
if (j >= ctx->nb_decompose_unit_types)
|
||||
continue;
|
||||
}
|
||||
|
||||
av_buffer_unref(&unit->content_ref);
|
||||
unit->content = NULL;
|
||||
av_buffer_unref(&frag->units[i].content_ref);
|
||||
frag->units[i].content = NULL;
|
||||
|
||||
av_assert0(unit->data && unit->data_ref);
|
||||
|
||||
err = ctx->codec->read_unit(ctx, unit);
|
||||
err = ctx->codec->read_unit(ctx, &frag->units[i]);
|
||||
if (err == AVERROR(ENOSYS)) {
|
||||
av_log(ctx->log_ctx, AV_LOG_VERBOSE,
|
||||
"Decomposition unimplemented for unit %d "
|
||||
"(type %"PRIu32").\n", i, unit->type);
|
||||
"(type %"PRIu32").\n", i, frag->units[i].type);
|
||||
} else if (err < 0) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to read unit %d "
|
||||
"(type %"PRIu32").\n", i, unit->type);
|
||||
"(type %"PRIu32").\n", i, frag->units[i].type);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@@ -189,6 +167,27 @@ static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag,
|
||||
const AVCodecParameters *par)
|
||||
{
|
||||
int err;
|
||||
|
||||
memset(frag, 0, sizeof(*frag));
|
||||
|
||||
frag->data = par->extradata;
|
||||
frag->data_size = par->extradata_size;
|
||||
|
||||
err = ctx->codec->split_fragment(ctx, frag, 1);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
frag->data = NULL;
|
||||
frag->data_size = 0;
|
||||
|
||||
return cbs_read_fragment_content(ctx, frag);
|
||||
}
|
||||
|
||||
static int cbs_fill_fragment_data(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag,
|
||||
const uint8_t *data, size_t size)
|
||||
@@ -210,26 +209,6 @@ static int cbs_fill_fragment_data(CodedBitstreamContext *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag,
|
||||
const AVCodecParameters *par)
|
||||
{
|
||||
int err;
|
||||
|
||||
memset(frag, 0, sizeof(*frag));
|
||||
|
||||
err = cbs_fill_fragment_data(ctx, frag, par->extradata,
|
||||
par->extradata_size);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = ctx->codec->split_fragment(ctx, frag, 1);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return cbs_read_fragment_content(ctx, frag);
|
||||
}
|
||||
|
||||
int ff_cbs_read_packet(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag,
|
||||
const AVPacket *pkt)
|
||||
@@ -299,7 +278,6 @@ int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx,
|
||||
"(type %"PRIu32").\n", i, unit->type);
|
||||
return err;
|
||||
}
|
||||
av_assert0(unit->data && unit->data_ref);
|
||||
}
|
||||
|
||||
av_buffer_unref(&frag->data_ref);
|
||||
@@ -310,7 +288,6 @@ int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx,
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n");
|
||||
return err;
|
||||
}
|
||||
av_assert0(frag->data && frag->data_ref);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -351,6 +328,7 @@ int ff_cbs_write_packet(CodedBitstreamContext *ctx,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
av_assert0(frag->data_ref);
|
||||
buf = av_buffer_ref(frag->data_ref);
|
||||
if (!buf)
|
||||
return AVERROR(ENOMEM);
|
||||
@@ -374,43 +352,17 @@ void ff_cbs_trace_header(CodedBitstreamContext *ctx,
|
||||
}
|
||||
|
||||
void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position,
|
||||
const char *str, const int *subscripts,
|
||||
const char *bits, int64_t value)
|
||||
const char *name, const char *bits,
|
||||
int64_t value)
|
||||
{
|
||||
char name[256];
|
||||
size_t name_len, bits_len;
|
||||
int pad, subs, i, j, k, n;
|
||||
int pad;
|
||||
|
||||
if (!ctx->trace_enable)
|
||||
return;
|
||||
|
||||
av_assert0(value >= INT_MIN && value <= UINT32_MAX);
|
||||
|
||||
subs = subscripts ? subscripts[0] : 0;
|
||||
n = 0;
|
||||
for (i = j = 0; str[i];) {
|
||||
if (str[i] == '[') {
|
||||
if (n < subs) {
|
||||
++n;
|
||||
k = snprintf(name + j, sizeof(name) - j, "[%d", subscripts[n]);
|
||||
av_assert0(k > 0 && j + k < sizeof(name));
|
||||
j += k;
|
||||
for (++i; str[i] && str[i] != ']'; i++);
|
||||
av_assert0(str[i] == ']');
|
||||
} else {
|
||||
while (str[i] && str[i] != ']')
|
||||
name[j++] = str[i++];
|
||||
av_assert0(str[i] == ']');
|
||||
}
|
||||
} else {
|
||||
av_assert0(j + 1 < sizeof(name));
|
||||
name[j++] = str[i++];
|
||||
}
|
||||
}
|
||||
av_assert0(j + 1 < sizeof(name));
|
||||
name[j] = 0;
|
||||
av_assert0(n == subs);
|
||||
|
||||
name_len = strlen(name);
|
||||
bits_len = strlen(bits);
|
||||
|
||||
@@ -424,8 +376,7 @@ void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position,
|
||||
}
|
||||
|
||||
int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc,
|
||||
int width, const char *name,
|
||||
const int *subscripts, uint32_t *write_to,
|
||||
int width, const char *name, uint32_t *write_to,
|
||||
uint32_t range_min, uint32_t range_max)
|
||||
{
|
||||
uint32_t value;
|
||||
@@ -451,8 +402,7 @@ int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc,
|
||||
bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
|
||||
bits[i] = 0;
|
||||
|
||||
ff_cbs_trace_syntax_element(ctx, position, name, subscripts,
|
||||
bits, value);
|
||||
ff_cbs_trace_syntax_element(ctx, position, name, bits, value);
|
||||
}
|
||||
|
||||
if (value < range_min || value > range_max) {
|
||||
@@ -467,8 +417,7 @@ int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc,
|
||||
}
|
||||
|
||||
int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
|
||||
int width, const char *name,
|
||||
const int *subscripts, uint32_t value,
|
||||
int width, const char *name, uint32_t value,
|
||||
uint32_t range_min, uint32_t range_max)
|
||||
{
|
||||
av_assert0(width > 0 && width <= 32);
|
||||
@@ -490,8 +439,7 @@ int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
|
||||
bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
|
||||
bits[i] = 0;
|
||||
|
||||
ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc),
|
||||
name, subscripts, bits, value);
|
||||
ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), name, bits, value);
|
||||
}
|
||||
|
||||
if (width < 32)
|
||||
|
||||
@@ -48,7 +48,6 @@ struct CodedBitstreamType;
|
||||
* H.264 / AVC: nal_unit_type
|
||||
* H.265 / HEVC: nal_unit_type
|
||||
* MPEG-2: start code value (without prefix)
|
||||
* VP9: unused, set to zero (every unit is a frame)
|
||||
*/
|
||||
typedef uint32_t CodedBitstreamUnitType;
|
||||
|
||||
@@ -85,9 +84,8 @@ typedef struct CodedBitstreamUnit {
|
||||
*/
|
||||
size_t data_bit_padding;
|
||||
/**
|
||||
* A reference to the buffer containing data.
|
||||
*
|
||||
* Must be set if data is not NULL.
|
||||
* If data is reference counted, a reference to the buffer containing
|
||||
* data. Null if data is not reference counted.
|
||||
*/
|
||||
AVBufferRef *data_ref;
|
||||
|
||||
@@ -132,9 +130,8 @@ typedef struct CodedBitstreamFragment {
|
||||
*/
|
||||
size_t data_bit_padding;
|
||||
/**
|
||||
* A reference to the buffer containing data.
|
||||
*
|
||||
* Must be set if data is not NULL.
|
||||
* If data is reference counted, a reference to the buffer containing
|
||||
* data. Null if data is not reference counted.
|
||||
*/
|
||||
AVBufferRef *data_ref;
|
||||
|
||||
|
||||
1320
libavcodec/cbs_av1.c
1320
libavcodec/cbs_av1.c
File diff suppressed because it is too large
Load Diff
@@ -1,429 +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 AVCODEC_CBS_AV1_H
|
||||
#define AVCODEC_CBS_AV1_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "av1.h"
|
||||
#include "cbs.h"
|
||||
|
||||
|
||||
typedef struct AV1RawOBUHeader {
|
||||
uint8_t obu_forbidden_bit;
|
||||
uint8_t obu_type;
|
||||
uint8_t obu_extension_flag;
|
||||
uint8_t obu_has_size_field;
|
||||
uint8_t obu_reserved_1bit;
|
||||
|
||||
uint8_t temporal_id;
|
||||
uint8_t spatial_id;
|
||||
uint8_t extension_header_reserved_3bits;
|
||||
} AV1RawOBUHeader;
|
||||
|
||||
typedef struct AV1RawColorConfig {
|
||||
uint8_t high_bitdepth;
|
||||
uint8_t twelve_bit;
|
||||
uint8_t mono_chrome;
|
||||
|
||||
uint8_t color_description_present_flag;
|
||||
uint8_t color_primaries;
|
||||
uint8_t transfer_characteristics;
|
||||
uint8_t matrix_coefficients;
|
||||
|
||||
uint8_t color_range;
|
||||
uint8_t subsampling_x;
|
||||
uint8_t subsampling_y;
|
||||
uint8_t chroma_sample_position;
|
||||
uint8_t separate_uv_delta_q;
|
||||
} AV1RawColorConfig;
|
||||
|
||||
typedef struct AV1RawTimingInfo {
|
||||
uint32_t num_units_in_display_tick;
|
||||
uint32_t time_scale;
|
||||
|
||||
uint8_t equal_picture_interval;
|
||||
uint32_t num_ticks_per_picture_minus_1;
|
||||
} AV1RawTimingInfo;
|
||||
|
||||
typedef struct AV1RawDecoderModelInfo {
|
||||
uint8_t buffer_delay_length_minus_1;
|
||||
uint32_t num_units_in_decoding_tick;
|
||||
uint8_t buffer_removal_time_length_minus_1;
|
||||
uint8_t frame_presentation_time_length_minus_1;
|
||||
} AV1RawDecoderModelInfo;
|
||||
|
||||
typedef struct AV1RawSequenceHeader {
|
||||
uint8_t seq_profile;
|
||||
uint8_t still_picture;
|
||||
uint8_t reduced_still_picture_header;
|
||||
|
||||
uint8_t timing_info_present_flag;
|
||||
uint8_t decoder_model_info_present_flag;
|
||||
uint8_t initial_display_delay_present_flag;
|
||||
uint8_t operating_points_cnt_minus_1;
|
||||
|
||||
AV1RawTimingInfo timing_info;
|
||||
AV1RawDecoderModelInfo decoder_model_info;
|
||||
|
||||
uint16_t operating_point_idc[AV1_MAX_OPERATING_POINTS];
|
||||
uint8_t seq_level_idx[AV1_MAX_OPERATING_POINTS];
|
||||
uint8_t seq_tier[AV1_MAX_OPERATING_POINTS];
|
||||
uint8_t decoder_model_present_for_this_op[AV1_MAX_OPERATING_POINTS];
|
||||
uint8_t decoder_buffer_delay[AV1_MAX_OPERATING_POINTS];
|
||||
uint8_t encoder_buffer_delay[AV1_MAX_OPERATING_POINTS];
|
||||
uint8_t low_delay_mode_flag[AV1_MAX_OPERATING_POINTS];
|
||||
uint8_t initial_display_delay_present_for_this_op[AV1_MAX_OPERATING_POINTS];
|
||||
uint8_t initial_display_delay_minus_1[AV1_MAX_OPERATING_POINTS];
|
||||
|
||||
uint8_t frame_width_bits_minus_1;
|
||||
uint8_t frame_height_bits_minus_1;
|
||||
uint16_t max_frame_width_minus_1;
|
||||
uint16_t max_frame_height_minus_1;
|
||||
|
||||
uint8_t frame_id_numbers_present_flag;
|
||||
uint8_t delta_frame_id_length_minus_2;
|
||||
uint8_t additional_frame_id_length_minus_1;
|
||||
|
||||
uint8_t use_128x128_superblock;
|
||||
uint8_t enable_filter_intra;
|
||||
uint8_t enable_intra_edge_filter;
|
||||
uint8_t enable_intraintra_compound;
|
||||
uint8_t enable_masked_compound;
|
||||
uint8_t enable_warped_motion;
|
||||
uint8_t enable_dual_filter;
|
||||
|
||||
uint8_t enable_order_hint;
|
||||
uint8_t enable_jnt_comp;
|
||||
uint8_t enable_ref_frame_mvs;
|
||||
|
||||
uint8_t seq_choose_screen_content_tools;
|
||||
uint8_t seq_force_screen_content_tools;
|
||||
uint8_t seq_choose_integer_mv;
|
||||
uint8_t seq_force_integer_mv;
|
||||
|
||||
uint8_t order_hint_bits_minus_1;
|
||||
|
||||
uint8_t enable_superres;
|
||||
uint8_t enable_cdef;
|
||||
uint8_t enable_restoration;
|
||||
|
||||
AV1RawColorConfig color_config;
|
||||
|
||||
uint8_t film_grain_params_present;
|
||||
} AV1RawSequenceHeader;
|
||||
|
||||
typedef struct AV1RawFrameHeader {
|
||||
uint8_t show_existing_frame;
|
||||
uint8_t frame_to_show_map_idx;
|
||||
uint32_t frame_presentation_time;
|
||||
uint32_t display_frame_id;
|
||||
|
||||
uint8_t frame_type;
|
||||
uint8_t show_frame;
|
||||
uint8_t showable_frame;
|
||||
|
||||
uint8_t error_resilient_mode;
|
||||
uint8_t disable_cdf_update;
|
||||
uint8_t allow_screen_content_tools;
|
||||
uint8_t force_integer_mv;
|
||||
|
||||
uint32_t current_frame_id;
|
||||
uint8_t frame_size_override_flag;
|
||||
uint8_t order_hint;
|
||||
|
||||
uint8_t buffer_removal_time_present_flag;
|
||||
uint32_t buffer_removal_time[AV1_MAX_OPERATING_POINTS];
|
||||
|
||||
uint8_t primary_ref_frame;
|
||||
uint16_t frame_width_minus_1;
|
||||
uint16_t frame_height_minus_1;
|
||||
uint8_t use_superres;
|
||||
uint8_t coded_denom;
|
||||
uint8_t render_and_frame_size_different;
|
||||
uint8_t render_width_minus_1;
|
||||
uint8_t render_height_minus_1;
|
||||
|
||||
uint8_t found_ref[AV1_REFS_PER_FRAME];
|
||||
|
||||
uint8_t refresh_frame_flags;
|
||||
uint8_t allow_intrabc;
|
||||
uint8_t ref_order_hint[AV1_NUM_REF_FRAMES];
|
||||
uint8_t frame_refs_short_signaling;
|
||||
uint8_t last_frame_idx;
|
||||
uint8_t golden_frame_idx;
|
||||
int8_t ref_frame_idx[AV1_REFS_PER_FRAME];
|
||||
uint8_t delta_frame_id_minus1;
|
||||
|
||||
uint8_t allow_high_precision_mv;
|
||||
uint8_t is_filter_switchable;
|
||||
uint8_t interpolation_filter;
|
||||
uint8_t is_motion_mode_switchable;
|
||||
uint8_t use_ref_frame_mvs;
|
||||
|
||||
uint8_t disable_frame_end_update_cdf;
|
||||
|
||||
uint8_t uniform_tile_spacing_flag;
|
||||
uint8_t tile_cols_log2;
|
||||
uint8_t tile_rows_log2;
|
||||
uint8_t width_in_sbs_minus_1[AV1_MAX_TILE_COLS];
|
||||
uint8_t height_in_sbs_minus_1[AV1_MAX_TILE_ROWS];
|
||||
uint16_t context_update_tile_id;
|
||||
uint8_t tile_size_bytes_minus1;
|
||||
|
||||
// These are derived values, but it's very unhelpful to have to
|
||||
// recalculate them all the time so we store them here.
|
||||
uint16_t tile_cols;
|
||||
uint16_t tile_rows;
|
||||
|
||||
uint8_t base_q_idx;
|
||||
int8_t delta_q_y_dc;
|
||||
uint8_t diff_uv_delta;
|
||||
int8_t delta_q_u_dc;
|
||||
int8_t delta_q_u_ac;
|
||||
int8_t delta_q_v_dc;
|
||||
int8_t delta_q_v_ac;
|
||||
uint8_t using_qmatrix;
|
||||
uint8_t qm_y;
|
||||
uint8_t qm_u;
|
||||
uint8_t qm_v;
|
||||
|
||||
uint8_t segmentation_enabled;
|
||||
uint8_t segmentation_update_map;
|
||||
uint8_t segmentation_temporal_update;
|
||||
uint8_t segmentation_update_data;
|
||||
uint8_t feature_enabled[AV1_MAX_SEGMENTS][AV1_SEG_LVL_MAX];
|
||||
uint8_t feature_value[AV1_MAX_SEGMENTS][AV1_SEG_LVL_MAX];
|
||||
|
||||
uint8_t delta_q_present;
|
||||
uint8_t delta_q_res;
|
||||
uint8_t delta_lf_present;
|
||||
uint8_t delta_lf_res;
|
||||
uint8_t delta_lf_multi;
|
||||
|
||||
uint8_t loop_filter_level[4];
|
||||
uint8_t loop_filter_sharpness;
|
||||
uint8_t loop_filter_delta_enabled;
|
||||
uint8_t loop_filter_delta_update;
|
||||
uint8_t update_ref_delta[AV1_TOTAL_REFS_PER_FRAME];
|
||||
int8_t loop_filter_ref_deltas[AV1_TOTAL_REFS_PER_FRAME];
|
||||
uint8_t update_mode_delta[2];
|
||||
int8_t loop_filter_mode_deltas[2];
|
||||
|
||||
uint8_t cdef_damping_minus_3;
|
||||
uint8_t cdef_bits;
|
||||
uint8_t cdef_y_pri_strength[8];
|
||||
uint8_t cdef_y_sec_strength[8];
|
||||
uint8_t cdef_uv_pri_strength[8];
|
||||
uint8_t cdef_uv_sec_strength[8];
|
||||
|
||||
uint8_t lr_type[3];
|
||||
uint8_t lr_unit_shift;
|
||||
uint8_t lr_uv_shift;
|
||||
|
||||
uint8_t tx_mode;
|
||||
uint8_t reference_select;
|
||||
uint8_t skip_mode_present;
|
||||
|
||||
uint8_t allow_warped_motion;
|
||||
uint8_t reduced_tx_set;
|
||||
|
||||
uint8_t is_global[AV1_TOTAL_REFS_PER_FRAME];
|
||||
uint8_t is_rot_zoom[AV1_TOTAL_REFS_PER_FRAME];
|
||||
uint8_t is_translation[AV1_TOTAL_REFS_PER_FRAME];
|
||||
//AV1RawSubexp gm_params[AV1_TOTAL_REFS_PER_FRAME][6];
|
||||
uint32_t gm_params[AV1_TOTAL_REFS_PER_FRAME][6];
|
||||
|
||||
uint8_t apply_grain;
|
||||
uint16_t grain_seed;
|
||||
uint8_t update_grain;
|
||||
uint8_t film_grain_params_ref_idx;
|
||||
uint8_t num_y_points;
|
||||
uint8_t point_y_value[16];
|
||||
uint8_t point_y_scaling[16];
|
||||
uint8_t chroma_scaling_from_luma;
|
||||
uint8_t num_cb_points;
|
||||
uint8_t point_cb_value[16];
|
||||
uint8_t point_cb_scaling[16];
|
||||
uint8_t num_cr_points;
|
||||
uint8_t point_cr_value[16];
|
||||
uint8_t point_cr_scaling[16];
|
||||
uint8_t grain_scaling_minus_8;
|
||||
uint8_t ar_coeff_lag;
|
||||
uint8_t ar_coeffs_y_plus_128[24];
|
||||
uint8_t ar_coeffs_cb_plus_128[24];
|
||||
uint8_t ar_coeffs_cr_plus_128[24];
|
||||
uint8_t ar_coeff_shift_minus_6;
|
||||
uint8_t grain_scale_shift;
|
||||
uint8_t cb_mult;
|
||||
uint8_t cb_luma_mult;
|
||||
uint16_t cb_offset;
|
||||
uint8_t cr_mult;
|
||||
uint8_t cr_luma_mult;
|
||||
uint16_t cr_offset;
|
||||
uint8_t overlap_flag;
|
||||
uint8_t clip_to_restricted_range;
|
||||
} AV1RawFrameHeader;
|
||||
|
||||
typedef struct AV1RawTileData {
|
||||
uint8_t *data;
|
||||
size_t data_size;
|
||||
AVBufferRef *data_ref;
|
||||
} AV1RawTileData;
|
||||
|
||||
typedef struct AV1RawTileGroup {
|
||||
uint8_t tile_start_and_end_present_flag;
|
||||
uint16_t tg_start;
|
||||
uint16_t tg_end;
|
||||
|
||||
AV1RawTileData tile_data;
|
||||
} AV1RawTileGroup;
|
||||
|
||||
typedef struct AV1RawFrame {
|
||||
AV1RawFrameHeader header;
|
||||
AV1RawTileGroup tile_group;
|
||||
} AV1RawFrame;
|
||||
|
||||
typedef struct AV1RawTileList {
|
||||
uint8_t output_frame_width_in_tiles_minus_1;
|
||||
uint8_t output_frame_height_in_tiles_minus_1;
|
||||
uint16_t tile_count_minus_1;
|
||||
|
||||
AV1RawTileData tile_data;
|
||||
} AV1RawTileList;
|
||||
|
||||
typedef struct AV1RawMetadataHDRCLL {
|
||||
uint16_t max_cll;
|
||||
uint16_t max_fall;
|
||||
} AV1RawMetadataHDRCLL;
|
||||
|
||||
typedef struct AV1RawMetadataHDRMDCV {
|
||||
uint16_t primary_chromaticity_x[3];
|
||||
uint16_t primary_chromaticity_y[3];
|
||||
uint16_t white_point_chromaticity_x;
|
||||
uint16_t white_point_chromaticity_y;
|
||||
uint32_t luminance_max;
|
||||
uint32_t luminance_min;
|
||||
} AV1RawMetadataHDRMDCV;
|
||||
|
||||
typedef struct AV1RawMetadataScalability {
|
||||
uint8_t scalability_mode_idc;
|
||||
// TODO: more stuff.
|
||||
} AV1RawMetadataScalability;
|
||||
|
||||
typedef struct AV1RawMetadataITUTT35 {
|
||||
uint8_t itu_t_t35_country_code;
|
||||
uint8_t itu_t_t35_country_code_extension_byte;
|
||||
|
||||
uint8_t *payload;
|
||||
size_t payload_size;
|
||||
AVBufferRef *payload_ref;
|
||||
} AV1RawMetadataITUTT35;
|
||||
|
||||
typedef struct AV1RawMetadataTimecode {
|
||||
uint8_t counting_type;
|
||||
uint8_t full_timestamp_flag;
|
||||
uint8_t discontinuity_flag;
|
||||
uint8_t cnt_dropped_flag;
|
||||
uint16_t n_frames;
|
||||
uint8_t seconds_value;
|
||||
uint8_t minutes_value;
|
||||
uint8_t hours_value;
|
||||
uint8_t seconds_flag;
|
||||
uint8_t minutes_flag;
|
||||
uint8_t hours_flag;
|
||||
uint8_t time_offset_length;
|
||||
uint32_t time_offset_value;
|
||||
} AV1RawMetadataTimecode;
|
||||
|
||||
typedef struct AV1RawMetadata {
|
||||
uint64_t metadata_type;
|
||||
union {
|
||||
AV1RawMetadataHDRCLL hdr_cll;
|
||||
AV1RawMetadataHDRMDCV hdr_mdcv;
|
||||
AV1RawMetadataScalability scalability;
|
||||
AV1RawMetadataITUTT35 itut_t35;
|
||||
AV1RawMetadataTimecode timecode;
|
||||
} metadata;
|
||||
} AV1RawMetadata;
|
||||
|
||||
|
||||
typedef struct AV1RawOBU {
|
||||
AV1RawOBUHeader header;
|
||||
|
||||
size_t obu_size;
|
||||
|
||||
union {
|
||||
AV1RawSequenceHeader sequence_header;
|
||||
AV1RawFrameHeader frame_header;
|
||||
AV1RawFrame frame;
|
||||
AV1RawTileGroup tile_group;
|
||||
AV1RawTileList tile_list;
|
||||
AV1RawMetadata metadata;
|
||||
} obu;
|
||||
} AV1RawOBU;
|
||||
|
||||
typedef struct AV1ReferenceFrameState {
|
||||
int valid; // RefValid
|
||||
int frame_id; // RefFrameId
|
||||
int upscaled_width; // RefUpscaledWidth
|
||||
int frame_width; // RefFrameWidth
|
||||
int frame_height; // RefFrameHeight
|
||||
int render_width; // RefRenderWidth
|
||||
int render_height; // RefRenderHeight
|
||||
int frame_type; // RefFrameType
|
||||
int subsampling_x; // RefSubsamplingX
|
||||
int subsampling_y; // RefSubsamplingY
|
||||
int bit_depth; // RefBitDepth
|
||||
int order_hint; // RefOrderHint
|
||||
} AV1ReferenceFrameState;
|
||||
|
||||
typedef struct CodedBitstreamAV1Context {
|
||||
AV1RawSequenceHeader *sequence_header;
|
||||
AVBufferRef *sequence_header_ref;
|
||||
|
||||
int seen_frame_header;
|
||||
|
||||
int temporal_id;
|
||||
int spatial_id;
|
||||
int operating_point_idc;
|
||||
|
||||
int bit_depth;
|
||||
int frame_width;
|
||||
int frame_height;
|
||||
int upscaled_width;
|
||||
int render_width;
|
||||
int render_height;
|
||||
|
||||
int num_planes;
|
||||
int coded_lossless;
|
||||
int all_lossless;
|
||||
int tile_cols;
|
||||
int tile_rows;
|
||||
|
||||
AV1ReferenceFrameState ref[AV1_NUM_REF_FRAMES];
|
||||
|
||||
// Write buffer.
|
||||
uint8_t *write_buffer;
|
||||
size_t write_buffer_size;
|
||||
} CodedBitstreamAV1Context;
|
||||
|
||||
|
||||
#endif /* AVCODEC_CBS_AV1_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -264,17 +264,6 @@ typedef struct H264RawSEIPicTiming {
|
||||
H264RawSEIPicTimestamp timestamp[3];
|
||||
} H264RawSEIPicTiming;
|
||||
|
||||
typedef struct H264RawSEIPanScanRect {
|
||||
uint32_t pan_scan_rect_id;
|
||||
uint8_t pan_scan_rect_cancel_flag;
|
||||
uint8_t pan_scan_cnt_minus1;
|
||||
int32_t pan_scan_rect_left_offset[3];
|
||||
int32_t pan_scan_rect_right_offset[3];
|
||||
int32_t pan_scan_rect_top_offset[3];
|
||||
int32_t pan_scan_rect_bottom_offset[3];
|
||||
uint16_t pan_scan_rect_repetition_period;
|
||||
} H264RawSEIPanScanRect;
|
||||
|
||||
typedef struct H264RawSEIUserDataRegistered {
|
||||
uint8_t itu_t_t35_country_code;
|
||||
uint8_t itu_t_t35_country_code_extension_byte;
|
||||
@@ -306,28 +295,17 @@ typedef struct H264RawSEIDisplayOrientation {
|
||||
uint8_t display_orientation_extension_flag;
|
||||
} H264RawSEIDisplayOrientation;
|
||||
|
||||
typedef struct H264RawSEIMasteringDisplayColourVolume {
|
||||
uint16_t display_primaries_x[3];
|
||||
uint16_t display_primaries_y[3];
|
||||
uint16_t white_point_x;
|
||||
uint16_t white_point_y;
|
||||
uint32_t max_display_mastering_luminance;
|
||||
uint32_t min_display_mastering_luminance;
|
||||
} H264RawSEIMasteringDisplayColourVolume;
|
||||
|
||||
typedef struct H264RawSEIPayload {
|
||||
uint32_t payload_type;
|
||||
uint32_t payload_size;
|
||||
union {
|
||||
H264RawSEIBufferingPeriod buffering_period;
|
||||
H264RawSEIPicTiming pic_timing;
|
||||
H264RawSEIPanScanRect pan_scan_rect;
|
||||
// H264RawSEIFiller filler -> no fields.
|
||||
H264RawSEIUserDataRegistered user_data_registered;
|
||||
H264RawSEIUserDataUnregistered user_data_unregistered;
|
||||
H264RawSEIRecoveryPoint recovery_point;
|
||||
H264RawSEIDisplayOrientation display_orientation;
|
||||
H264RawSEIMasteringDisplayColourVolume mastering_display_colour_volume;
|
||||
struct {
|
||||
uint8_t *data;
|
||||
size_t data_length;
|
||||
@@ -443,8 +421,6 @@ typedef struct CodedBitstreamH264Context {
|
||||
|
||||
// All currently available parameter sets. These are updated when
|
||||
// any parameter set NAL unit is read/written with this context.
|
||||
AVBufferRef *sps_ref[H264_MAX_SPS_COUNT];
|
||||
AVBufferRef *pps_ref[H264_MAX_PPS_COUNT];
|
||||
H264RawSPS *sps[H264_MAX_SPS_COUNT];
|
||||
H264RawPPS *pps[H264_MAX_PPS_COUNT];
|
||||
|
||||
|
||||
@@ -29,12 +29,10 @@
|
||||
#include "h264_sei.h"
|
||||
#include "h2645_parse.h"
|
||||
#include "hevc.h"
|
||||
#include "hevc_sei.h"
|
||||
|
||||
|
||||
static int cbs_read_ue_golomb(CodedBitstreamContext *ctx, GetBitContext *gbc,
|
||||
const char *name, const int *subscripts,
|
||||
uint32_t *write_to,
|
||||
const char *name, uint32_t *write_to,
|
||||
uint32_t range_min, uint32_t range_max)
|
||||
{
|
||||
uint32_t value;
|
||||
@@ -70,8 +68,7 @@ static int cbs_read_ue_golomb(CodedBitstreamContext *ctx, GetBitContext *gbc,
|
||||
--value;
|
||||
|
||||
if (ctx->trace_enable)
|
||||
ff_cbs_trace_syntax_element(ctx, position, name, subscripts,
|
||||
bits, value);
|
||||
ff_cbs_trace_syntax_element(ctx, position, name, bits, value);
|
||||
|
||||
if (value < range_min || value > range_max) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
|
||||
@@ -85,8 +82,7 @@ static int cbs_read_ue_golomb(CodedBitstreamContext *ctx, GetBitContext *gbc,
|
||||
}
|
||||
|
||||
static int cbs_read_se_golomb(CodedBitstreamContext *ctx, GetBitContext *gbc,
|
||||
const char *name, const int *subscripts,
|
||||
int32_t *write_to,
|
||||
const char *name, int32_t *write_to,
|
||||
int32_t range_min, int32_t range_max)
|
||||
{
|
||||
int32_t value;
|
||||
@@ -126,8 +122,7 @@ static int cbs_read_se_golomb(CodedBitstreamContext *ctx, GetBitContext *gbc,
|
||||
value = v / 2;
|
||||
|
||||
if (ctx->trace_enable)
|
||||
ff_cbs_trace_syntax_element(ctx, position, name, subscripts,
|
||||
bits, value);
|
||||
ff_cbs_trace_syntax_element(ctx, position, name, bits, value);
|
||||
|
||||
if (value < range_min || value > range_max) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
|
||||
@@ -141,8 +136,7 @@ static int cbs_read_se_golomb(CodedBitstreamContext *ctx, GetBitContext *gbc,
|
||||
}
|
||||
|
||||
static int cbs_write_ue_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc,
|
||||
const char *name, const int *subscripts,
|
||||
uint32_t value,
|
||||
const char *name, uint32_t value,
|
||||
uint32_t range_min, uint32_t range_max)
|
||||
{
|
||||
int len;
|
||||
@@ -170,8 +164,7 @@ static int cbs_write_ue_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc,
|
||||
bits[len + i + 1] = (value + 1) >> (len - i - 1) & 1 ? '1' : '0';
|
||||
bits[len + len + 1] = 0;
|
||||
|
||||
ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc),
|
||||
name, subscripts, bits, value);
|
||||
ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), name, bits, value);
|
||||
}
|
||||
|
||||
put_bits(pbc, len, 0);
|
||||
@@ -184,8 +177,7 @@ static int cbs_write_ue_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc,
|
||||
}
|
||||
|
||||
static int cbs_write_se_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc,
|
||||
const char *name, const int *subscripts,
|
||||
int32_t value,
|
||||
const char *name, int32_t value,
|
||||
int32_t range_min, int32_t range_max)
|
||||
{
|
||||
int len;
|
||||
@@ -221,8 +213,7 @@ static int cbs_write_se_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc,
|
||||
bits[len + i + 1] = (uvalue + 1) >> (len - i - 1) & 1 ? '1' : '0';
|
||||
bits[len + len + 1] = 0;
|
||||
|
||||
ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc),
|
||||
name, subscripts, bits, value);
|
||||
ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), name, bits, value);
|
||||
}
|
||||
|
||||
put_bits(pbc, len, 0);
|
||||
@@ -248,58 +239,39 @@ static int cbs_write_se_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc,
|
||||
#define FUNC_H264(rw, name) FUNC_NAME(rw, h264, name)
|
||||
#define FUNC_H265(rw, name) FUNC_NAME(rw, h265, name)
|
||||
|
||||
#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)
|
||||
|
||||
#define u(width, name, range_min, range_max) \
|
||||
xu(width, name, current->name, range_min, range_max, 0)
|
||||
#define flag(name) u(1, name, 0, 1)
|
||||
#define ue(name, range_min, range_max) \
|
||||
xue(name, current->name, range_min, range_max, 0)
|
||||
#define se(name, range_min, range_max) \
|
||||
xse(name, current->name, range_min, range_max, 0)
|
||||
|
||||
#define us(width, name, range_min, range_max, subs, ...) \
|
||||
xu(width, name, current->name, range_min, range_max, subs, __VA_ARGS__)
|
||||
#define flags(name, subs, ...) \
|
||||
xu(1, name, current->name, 0, 1, subs, __VA_ARGS__)
|
||||
#define ues(name, range_min, range_max, subs, ...) \
|
||||
xue(name, current->name, range_min, range_max, subs, __VA_ARGS__)
|
||||
#define ses(name, range_min, range_max, subs, ...) \
|
||||
xse(name, current->name, range_min, range_max, subs, __VA_ARGS__)
|
||||
|
||||
#define fixed(width, name, value) do { \
|
||||
av_unused uint32_t fixed_value = value; \
|
||||
xu(width, name, fixed_value, value, value, 0); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define READ
|
||||
#define READWRITE read
|
||||
#define RWContext GetBitContext
|
||||
|
||||
#define xu(width, name, var, range_min, range_max, subs, ...) do { \
|
||||
#define xu(width, name, var, range_min, range_max) do { \
|
||||
uint32_t value = range_min; \
|
||||
CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), \
|
||||
&value, range_min, range_max)); \
|
||||
var = value; \
|
||||
} while (0)
|
||||
#define xue(name, var, range_min, range_max, subs, ...) do { \
|
||||
#define xue(name, var, range_min, range_max) do { \
|
||||
uint32_t value = range_min; \
|
||||
CHECK(cbs_read_ue_golomb(ctx, rw, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), \
|
||||
&value, range_min, range_max)); \
|
||||
var = value; \
|
||||
} while (0)
|
||||
#define xse(name, var, range_min, range_max, subs, ...) do { \
|
||||
#define xse(name, var, range_min, range_max) do { \
|
||||
int32_t value = range_min; \
|
||||
CHECK(cbs_read_se_golomb(ctx, rw, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), \
|
||||
&value, range_min, range_max)); \
|
||||
var = value; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define u(width, name, range_min, range_max) \
|
||||
xu(width, name, current->name, range_min, range_max)
|
||||
#define flag(name) u(1, name, 0, 1)
|
||||
#define ue(name, range_min, range_max) \
|
||||
xue(name, current->name, range_min, range_max)
|
||||
#define se(name, range_min, range_max) \
|
||||
xse(name, current->name, range_min, range_max)
|
||||
|
||||
#define infer(name, value) do { \
|
||||
current->name = value; \
|
||||
} while (0)
|
||||
@@ -319,8 +291,7 @@ static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc)
|
||||
#define byte_alignment(rw) (get_bits_count(rw) % 8)
|
||||
|
||||
#define allocate(name, size) do { \
|
||||
name ## _ref = av_buffer_allocz(size + \
|
||||
AV_INPUT_BUFFER_PADDING_SIZE); \
|
||||
name ## _ref = av_buffer_allocz(size); \
|
||||
if (!name ## _ref) \
|
||||
return AVERROR(ENOMEM); \
|
||||
name = name ## _ref->data; \
|
||||
@@ -340,6 +311,10 @@ static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc)
|
||||
#undef xu
|
||||
#undef xue
|
||||
#undef xse
|
||||
#undef u
|
||||
#undef flag
|
||||
#undef ue
|
||||
#undef se
|
||||
#undef infer
|
||||
#undef more_rbsp_data
|
||||
#undef byte_alignment
|
||||
@@ -350,25 +325,30 @@ static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc)
|
||||
#define READWRITE write
|
||||
#define RWContext PutBitContext
|
||||
|
||||
#define xu(width, name, var, range_min, range_max, subs, ...) do { \
|
||||
#define xu(width, name, var, range_min, range_max) do { \
|
||||
uint32_t value = var; \
|
||||
CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), \
|
||||
value, range_min, range_max)); \
|
||||
} while (0)
|
||||
#define xue(name, var, range_min, range_max, subs, ...) do { \
|
||||
#define xue(name, var, range_min, range_max) do { \
|
||||
uint32_t value = var; \
|
||||
CHECK(cbs_write_ue_golomb(ctx, rw, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), \
|
||||
value, range_min, range_max)); \
|
||||
} while (0)
|
||||
#define xse(name, var, range_min, range_max, subs, ...) do { \
|
||||
#define xse(name, var, range_min, range_max) do { \
|
||||
int32_t value = var; \
|
||||
CHECK(cbs_write_se_golomb(ctx, rw, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), \
|
||||
value, range_min, range_max)); \
|
||||
} while (0)
|
||||
|
||||
#define u(width, name, range_min, range_max) \
|
||||
xu(width, name, current->name, range_min, range_max)
|
||||
#define flag(name) u(1, name, 0, 1)
|
||||
#define ue(name, range_min, range_max) \
|
||||
xue(name, current->name, range_min, range_max)
|
||||
#define se(name, range_min, range_max) \
|
||||
xse(name, current->name, range_min, range_max)
|
||||
|
||||
#define infer(name, value) do { \
|
||||
if (current->name != (value)) { \
|
||||
av_log(ctx->log_ctx, AV_LOG_WARNING, "Warning: " \
|
||||
@@ -426,10 +406,8 @@ static void cbs_h264_free_sei_payload(H264RawSEIPayload *payload)
|
||||
switch (payload->payload_type) {
|
||||
case H264_SEI_TYPE_BUFFERING_PERIOD:
|
||||
case H264_SEI_TYPE_PIC_TIMING:
|
||||
case H264_SEI_TYPE_PAN_SCAN_RECT:
|
||||
case H264_SEI_TYPE_RECOVERY_POINT:
|
||||
case H264_SEI_TYPE_DISPLAY_ORIENTATION:
|
||||
case H264_SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME:
|
||||
break;
|
||||
case H264_SEI_TYPE_USER_DATA_REGISTERED:
|
||||
av_buffer_unref(&payload->payload.user_data_registered.data_ref);
|
||||
@@ -487,27 +465,6 @@ static void cbs_h265_free_slice(void *unit, uint8_t *content)
|
||||
av_freep(&content);
|
||||
}
|
||||
|
||||
static void cbs_h265_free_sei_payload(H265RawSEIPayload *payload)
|
||||
{
|
||||
switch (payload->payload_type) {
|
||||
case HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO:
|
||||
case HEVC_SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO:
|
||||
break;
|
||||
default:
|
||||
av_buffer_unref(&payload->payload.other.data_ref);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void cbs_h265_free_sei(void *unit, uint8_t *content)
|
||||
{
|
||||
H265RawSEI *sei = (H265RawSEI*)content;
|
||||
int i;
|
||||
for (i = 0; i < sei->payload_count; i++)
|
||||
cbs_h265_free_sei_payload(&sei->payload[i]);
|
||||
av_freep(&content);
|
||||
}
|
||||
|
||||
static int cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag,
|
||||
const H2645Packet *packet)
|
||||
@@ -702,10 +659,9 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx,
|
||||
|
||||
#define cbs_h2645_replace_ps(h26n, ps_name, ps_var, id_element) \
|
||||
static int cbs_h26 ## h26n ## _replace_ ## ps_var(CodedBitstreamContext *ctx, \
|
||||
CodedBitstreamUnit *unit) \
|
||||
const H26 ## h26n ## Raw ## ps_name *ps_var) \
|
||||
{ \
|
||||
CodedBitstreamH26 ## h26n ## Context *priv = ctx->priv_data; \
|
||||
H26 ## h26n ## Raw ## ps_name *ps_var = unit->content; \
|
||||
unsigned int id = ps_var->id_element; \
|
||||
if (id > FF_ARRAY_ELEMS(priv->ps_var)) { \
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid " #ps_name \
|
||||
@@ -714,16 +670,11 @@ static int cbs_h26 ## h26n ## _replace_ ## ps_var(CodedBitstreamContext *ctx, \
|
||||
} \
|
||||
if (priv->ps_var[id] == priv->active_ ## ps_var) \
|
||||
priv->active_ ## ps_var = NULL ; \
|
||||
av_buffer_unref(&priv->ps_var ## _ref[id]); \
|
||||
if (unit->content_ref) \
|
||||
priv->ps_var ## _ref[id] = av_buffer_ref(unit->content_ref); \
|
||||
else \
|
||||
priv->ps_var ## _ref[id] = av_buffer_alloc(sizeof(*ps_var)); \
|
||||
if (!priv->ps_var ## _ref[id]) \
|
||||
av_freep(&priv->ps_var[id]); \
|
||||
priv->ps_var[id] = av_malloc(sizeof(*ps_var)); \
|
||||
if (!priv->ps_var[id]) \
|
||||
return AVERROR(ENOMEM); \
|
||||
priv->ps_var[id] = (H26 ## h26n ## Raw ## ps_name *)priv->ps_var ## _ref[id]->data; \
|
||||
if (!unit->content_ref) \
|
||||
memcpy(priv->ps_var[id], ps_var, sizeof(*ps_var)); \
|
||||
memcpy(priv->ps_var[id], ps_var, sizeof(*ps_var)); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
@@ -757,7 +708,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = cbs_h264_replace_sps(ctx, unit);
|
||||
err = cbs_h264_replace_sps(ctx, sps);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@@ -791,7 +742,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = cbs_h264_replace_pps(ctx, unit);
|
||||
err = cbs_h264_replace_pps(ctx, pps);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@@ -825,10 +776,15 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
|
||||
}
|
||||
|
||||
slice->data_size = len - pos / 8;
|
||||
slice->data_ref = av_buffer_ref(unit->data_ref);
|
||||
slice->data_ref = av_buffer_alloc(slice->data_size +
|
||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!slice->data_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
slice->data = unit->data + pos / 8;
|
||||
slice->data = slice->data_ref->data;
|
||||
memcpy(slice->data,
|
||||
unit->data + pos / 8, slice->data_size);
|
||||
memset(slice->data + slice->data_size, 0,
|
||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
slice->data_bit_start = pos % 8;
|
||||
}
|
||||
break;
|
||||
@@ -872,23 +828,6 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
|
||||
}
|
||||
break;
|
||||
|
||||
case H264_NAL_END_SEQUENCE:
|
||||
case H264_NAL_END_STREAM:
|
||||
{
|
||||
err = ff_cbs_alloc_unit_content(ctx, unit,
|
||||
sizeof(H264RawNALUnitHeader),
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = (unit->type == H264_NAL_END_SEQUENCE ?
|
||||
cbs_h264_read_end_of_sequence :
|
||||
cbs_h264_read_end_of_stream)(ctx, &gbc, unit->content);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
@@ -921,7 +860,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = cbs_h265_replace_vps(ctx, unit);
|
||||
err = cbs_h265_replace_vps(ctx, vps);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@@ -940,7 +879,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = cbs_h265_replace_sps(ctx, unit);
|
||||
err = cbs_h265_replace_sps(ctx, sps);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@@ -960,7 +899,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = cbs_h265_replace_pps(ctx, unit);
|
||||
err = cbs_h265_replace_pps(ctx, pps);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@@ -1007,10 +946,15 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
|
||||
}
|
||||
|
||||
slice->data_size = len - pos / 8;
|
||||
slice->data_ref = av_buffer_ref(unit->data_ref);
|
||||
slice->data_ref = av_buffer_alloc(slice->data_size +
|
||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!slice->data_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
slice->data = unit->data + pos / 8;
|
||||
slice->data = slice->data_ref->data;
|
||||
memcpy(slice->data,
|
||||
unit->data + pos / 8, slice->data_size);
|
||||
memset(slice->data + slice->data_size, 0,
|
||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
slice->data_bit_start = pos % 8;
|
||||
}
|
||||
break;
|
||||
@@ -1028,21 +972,6 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
|
||||
}
|
||||
break;
|
||||
|
||||
case HEVC_NAL_SEI_PREFIX:
|
||||
{
|
||||
err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(H265RawSEI),
|
||||
&cbs_h265_free_sei);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = cbs_h265_read_sei(ctx, &gbc, unit->content);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
@@ -1065,7 +994,7 @@ static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = cbs_h264_replace_sps(ctx, unit);
|
||||
err = cbs_h264_replace_sps(ctx, sps);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@@ -1089,7 +1018,7 @@ static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = cbs_h264_replace_pps(ctx, unit);
|
||||
err = cbs_h264_replace_pps(ctx, pps);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@@ -1162,22 +1091,6 @@ static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx,
|
||||
}
|
||||
break;
|
||||
|
||||
case H264_NAL_END_SEQUENCE:
|
||||
{
|
||||
err = cbs_h264_write_end_of_sequence(ctx, pbc, unit->content);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
|
||||
case H264_NAL_END_STREAM:
|
||||
{
|
||||
err = cbs_h264_write_end_of_stream(ctx, pbc, unit->content);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Write unimplemented for "
|
||||
"NAL unit type %"PRIu32".\n", unit->type);
|
||||
@@ -1202,7 +1115,7 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = cbs_h265_replace_vps(ctx, unit);
|
||||
err = cbs_h265_replace_vps(ctx, vps);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@@ -1216,7 +1129,7 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = cbs_h265_replace_sps(ctx, unit);
|
||||
err = cbs_h265_replace_sps(ctx, sps);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@@ -1230,7 +1143,7 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = cbs_h265_replace_pps(ctx, unit);
|
||||
err = cbs_h265_replace_pps(ctx, pps);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@@ -1299,15 +1212,6 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx,
|
||||
}
|
||||
break;
|
||||
|
||||
case HEVC_NAL_SEI_PREFIX:
|
||||
{
|
||||
err = cbs_h265_write_sei(ctx, pbc, unit->content);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Write unimplemented for "
|
||||
"NAL unit type %"PRIu32".\n", unit->type);
|
||||
@@ -1473,9 +1377,9 @@ static void cbs_h264_close(CodedBitstreamContext *ctx)
|
||||
av_freep(&h264->common.write_buffer);
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(h264->sps); i++)
|
||||
av_buffer_unref(&h264->sps_ref[i]);
|
||||
av_freep(&h264->sps[i]);
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(h264->pps); i++)
|
||||
av_buffer_unref(&h264->pps_ref[i]);
|
||||
av_freep(&h264->pps[i]);
|
||||
}
|
||||
|
||||
static void cbs_h265_close(CodedBitstreamContext *ctx)
|
||||
@@ -1488,11 +1392,11 @@ static void cbs_h265_close(CodedBitstreamContext *ctx)
|
||||
av_freep(&h265->common.write_buffer);
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(h265->vps); i++)
|
||||
av_buffer_unref(&h265->vps_ref[i]);
|
||||
av_freep(&h265->vps[i]);
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(h265->sps); i++)
|
||||
av_buffer_unref(&h265->sps_ref[i]);
|
||||
av_freep(&h265->sps[i]);
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(h265->pps); i++)
|
||||
av_buffer_unref(&h265->pps_ref[i]);
|
||||
av_freep(&h265->pps[i]);
|
||||
}
|
||||
|
||||
const CodedBitstreamType ff_cbs_type_h264 = {
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
static int FUNC(rbsp_trailing_bits)(CodedBitstreamContext *ctx, RWContext *rw)
|
||||
{
|
||||
int err;
|
||||
|
||||
fixed(1, rbsp_stop_one_bit, 1);
|
||||
av_unused int one = 1, zero = 0;
|
||||
xu(1, rbsp_stop_one_bit, one, 1, 1);
|
||||
while (byte_alignment(rw) != 0)
|
||||
fixed(1, rbsp_alignment_zero_bit, 0);
|
||||
xu(1, rbsp_alignment_zero_bit, zero, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -76,7 +76,7 @@ static int FUNC(scaling_list)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
|
||||
scale = 8;
|
||||
for (i = 0; i < size_of_scaling_list; i++) {
|
||||
ses(delta_scale[i], -128, +127, 1, i);
|
||||
xse(delta_scale, current->delta_scale[i], -128, +127);
|
||||
scale = (scale + current->delta_scale[i] + 256) % 256;
|
||||
if (scale == 0)
|
||||
break;
|
||||
@@ -95,9 +95,9 @@ static int FUNC(hrd_parameters)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
u(4, cpb_size_scale, 0, 15);
|
||||
|
||||
for (i = 0; i <= current->cpb_cnt_minus1; i++) {
|
||||
ues(bit_rate_value_minus1[i], 0, UINT32_MAX - 1, 1, i);
|
||||
ues(cpb_size_value_minus1[i], 0, UINT32_MAX - 1, 1, i);
|
||||
flags(cbr_flag[i], 1, i);
|
||||
ue(bit_rate_value_minus1[i], 0, UINT32_MAX - 1);
|
||||
ue(cpb_size_value_minus1[i], 0, UINT32_MAX - 1);
|
||||
flag(cbr_flag[i]);
|
||||
}
|
||||
|
||||
u(5, initial_cpb_removal_delay_length_minus1, 0, 31);
|
||||
@@ -185,8 +185,6 @@ static int FUNC(vui_parameters)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
flag(motion_vectors_over_pic_boundaries_flag);
|
||||
ue(max_bytes_per_pic_denom, 0, 16);
|
||||
ue(max_bits_per_mb_denom, 0, 16);
|
||||
// The current version of the standard constrains this to be in
|
||||
// [0,15], but older versions allow 16.
|
||||
ue(log2_max_mv_length_horizontal, 0, 16);
|
||||
ue(log2_max_mv_length_vertical, 0, 16);
|
||||
ue(max_num_reorder_frames, 0, H264_MAX_DPB_FRAMES);
|
||||
@@ -195,11 +193,11 @@ static int FUNC(vui_parameters)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
infer(motion_vectors_over_pic_boundaries_flag, 1);
|
||||
infer(max_bytes_per_pic_denom, 2);
|
||||
infer(max_bits_per_mb_denom, 1);
|
||||
infer(log2_max_mv_length_horizontal, 15);
|
||||
infer(log2_max_mv_length_vertical, 15);
|
||||
infer(log2_max_mv_length_horizontal, 16);
|
||||
infer(log2_max_mv_length_vertical, 16);
|
||||
|
||||
if ((sps->profile_idc == 44 || sps->profile_idc == 86 ||
|
||||
sps->profile_idc == 100 || sps->profile_idc == 110 ||
|
||||
sps->profile_idc == 110 || sps->profile_idc == 110 ||
|
||||
sps->profile_idc == 122 || sps->profile_idc == 244) &&
|
||||
sps->constraint_set3_flag) {
|
||||
infer(max_num_reorder_frames, 0);
|
||||
@@ -213,46 +211,6 @@ static int FUNC(vui_parameters)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(vui_parameters_default)(CodedBitstreamContext *ctx,
|
||||
RWContext *rw, H264RawVUI *current,
|
||||
H264RawSPS *sps)
|
||||
{
|
||||
infer(aspect_ratio_idc, 0);
|
||||
|
||||
infer(video_format, 5);
|
||||
infer(video_full_range_flag, 0);
|
||||
infer(colour_primaries, 2);
|
||||
infer(transfer_characteristics, 2);
|
||||
infer(matrix_coefficients, 2);
|
||||
|
||||
infer(chroma_sample_loc_type_top_field, 0);
|
||||
infer(chroma_sample_loc_type_bottom_field, 0);
|
||||
|
||||
infer(fixed_frame_rate_flag, 0);
|
||||
infer(low_delay_hrd_flag, 1);
|
||||
|
||||
infer(pic_struct_present_flag, 0);
|
||||
|
||||
infer(motion_vectors_over_pic_boundaries_flag, 1);
|
||||
infer(max_bytes_per_pic_denom, 2);
|
||||
infer(max_bits_per_mb_denom, 1);
|
||||
infer(log2_max_mv_length_horizontal, 15);
|
||||
infer(log2_max_mv_length_vertical, 15);
|
||||
|
||||
if ((sps->profile_idc == 44 || sps->profile_idc == 86 ||
|
||||
sps->profile_idc == 100 || sps->profile_idc == 110 ||
|
||||
sps->profile_idc == 122 || sps->profile_idc == 244) &&
|
||||
sps->constraint_set3_flag) {
|
||||
infer(max_num_reorder_frames, 0);
|
||||
infer(max_dec_frame_buffering, 0);
|
||||
} else {
|
||||
infer(max_num_reorder_frames, H264_MAX_DPB_FRAMES);
|
||||
infer(max_dec_frame_buffering, H264_MAX_DPB_FRAMES);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
H264RawSPS *current)
|
||||
{
|
||||
@@ -298,7 +256,7 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
flag(seq_scaling_matrix_present_flag);
|
||||
if (current->seq_scaling_matrix_present_flag) {
|
||||
for (i = 0; i < ((current->chroma_format_idc != 3) ? 8 : 12); i++) {
|
||||
flags(seq_scaling_list_present_flag[i], 1, i);
|
||||
flag(seq_scaling_list_present_flag[i]);
|
||||
if (current->seq_scaling_list_present_flag[i]) {
|
||||
if (i < 6)
|
||||
CHECK(FUNC(scaling_list)(ctx, rw,
|
||||
@@ -331,7 +289,7 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
ue(num_ref_frames_in_pic_order_cnt_cycle, 0, 255);
|
||||
|
||||
for (i = 0; i < current->num_ref_frames_in_pic_order_cnt_cycle; i++)
|
||||
ses(offset_for_ref_frame[i], INT32_MIN + 1, INT32_MAX, 1, i);
|
||||
se(offset_for_ref_frame[i], INT32_MIN + 1, INT32_MAX);
|
||||
}
|
||||
|
||||
ue(max_num_ref_frames, 0, H264_MAX_DPB_FRAMES);
|
||||
@@ -357,8 +315,6 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
flag(vui_parameters_present_flag);
|
||||
if (current->vui_parameters_present_flag)
|
||||
CHECK(FUNC(vui_parameters)(ctx, rw, ¤t->vui, current));
|
||||
else
|
||||
CHECK(FUNC(vui_parameters_default)(ctx, rw, ¤t->vui, current));
|
||||
|
||||
CHECK(FUNC(rbsp_trailing_bits)(ctx, rw));
|
||||
|
||||
@@ -434,13 +390,12 @@ static int FUNC(pps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
|
||||
if (current->slice_group_map_type == 0) {
|
||||
for (iGroup = 0; iGroup <= current->num_slice_groups_minus1; iGroup++)
|
||||
ues(run_length_minus1[iGroup], 0, pic_size - 1, 1, iGroup);
|
||||
ue(run_length_minus1[iGroup], 0, pic_size - 1);
|
||||
|
||||
} else if (current->slice_group_map_type == 2) {
|
||||
for (iGroup = 0; iGroup < current->num_slice_groups_minus1; iGroup++) {
|
||||
ues(top_left[iGroup], 0, pic_size - 1, 1, iGroup);
|
||||
ues(bottom_right[iGroup],
|
||||
current->top_left[iGroup], pic_size - 1, 1, iGroup);
|
||||
ue(top_left[iGroup], 0, pic_size - 1);
|
||||
ue(bottom_right[iGroup], current->top_left[iGroup], pic_size - 1);
|
||||
}
|
||||
} else if (current->slice_group_map_type == 3 ||
|
||||
current->slice_group_map_type == 4 ||
|
||||
@@ -453,8 +408,8 @@ static int FUNC(pps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
allocate(current->slice_group_id,
|
||||
current->pic_size_in_map_units_minus1 + 1);
|
||||
for (i = 0; i <= current->pic_size_in_map_units_minus1; i++)
|
||||
us(av_log2(2 * current->num_slice_groups_minus1 + 1),
|
||||
slice_group_id[i], 0, current->num_slice_groups_minus1, 1, i);
|
||||
u(av_log2(2 * current->num_slice_groups_minus1 + 1),
|
||||
slice_group_id[i], 0, current->num_slice_groups_minus1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,7 +435,7 @@ static int FUNC(pps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
if (current->pic_scaling_matrix_present_flag) {
|
||||
for (i = 0; i < 6 + (((sps->chroma_format_idc != 3) ? 2 : 6) *
|
||||
current->transform_8x8_mode_flag); i++) {
|
||||
flags(pic_scaling_list_present_flag[i], 1, i);
|
||||
flag(pic_scaling_list_present_flag[i]);
|
||||
if (current->pic_scaling_list_present_flag[i]) {
|
||||
if (i < 6)
|
||||
CHECK(FUNC(scaling_list)(ctx, rw,
|
||||
@@ -513,8 +468,6 @@ static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
const H264RawSPS *sps;
|
||||
int err, i, length;
|
||||
|
||||
HEADER("Buffering Period");
|
||||
|
||||
ue(seq_parameter_set_id, 0, 31);
|
||||
|
||||
sps = h264->sps[current->seq_parameter_set_id];
|
||||
@@ -530,10 +483,10 @@ static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
length = sps->vui.nal_hrd_parameters.initial_cpb_removal_delay_length_minus1 + 1;
|
||||
xu(length, initial_cpb_removal_delay[SchedSelIdx],
|
||||
current->nal.initial_cpb_removal_delay[i],
|
||||
1, MAX_UINT_BITS(length), 1, i);
|
||||
1, MAX_UINT_BITS(length));
|
||||
xu(length, initial_cpb_removal_delay_offset[SchedSelIdx],
|
||||
current->nal.initial_cpb_removal_delay_offset[i],
|
||||
0, MAX_UINT_BITS(length), 1, i);
|
||||
0, MAX_UINT_BITS(length));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,10 +495,10 @@ static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
length = sps->vui.vcl_hrd_parameters.initial_cpb_removal_delay_length_minus1 + 1;
|
||||
xu(length, initial_cpb_removal_delay[SchedSelIdx],
|
||||
current->vcl.initial_cpb_removal_delay[i],
|
||||
1, MAX_UINT_BITS(length), 1, i);
|
||||
1, MAX_UINT_BITS(length));
|
||||
xu(length, initial_cpb_removal_delay_offset[SchedSelIdx],
|
||||
current->vcl.initial_cpb_removal_delay_offset[i],
|
||||
0, MAX_UINT_BITS(length), 1, i);
|
||||
0, MAX_UINT_BITS(length));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -553,9 +506,10 @@ static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
}
|
||||
|
||||
static int FUNC(sei_pic_timestamp)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
H264RawSEIPicTimestamp *current,
|
||||
const H264RawSPS *sps)
|
||||
H264RawSEIPicTimestamp *current)
|
||||
{
|
||||
CodedBitstreamH264Context *h264 = ctx->priv_data;
|
||||
const H264RawSPS *sps;
|
||||
uint8_t time_offset_length;
|
||||
int err;
|
||||
|
||||
@@ -584,6 +538,13 @@ static int FUNC(sei_pic_timestamp)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
}
|
||||
}
|
||||
|
||||
sps = h264->active_sps;
|
||||
if (!sps) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR,
|
||||
"No active SPS for pic_timestamp.\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if (sps->vui.nal_hrd_parameters_present_flag)
|
||||
time_offset_length = sps->vui.nal_hrd_parameters.time_offset_length;
|
||||
else if (sps->vui.vcl_hrd_parameters_present_flag)
|
||||
@@ -607,8 +568,6 @@ static int FUNC(sei_pic_timing)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
const H264RawSPS *sps;
|
||||
int err;
|
||||
|
||||
HEADER("Picture Timing");
|
||||
|
||||
sps = h264->active_sps;
|
||||
if (!sps) {
|
||||
// If there is exactly one possible SPS but it is not yet active
|
||||
@@ -663,50 +622,21 @@ static int FUNC(sei_pic_timing)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
for (i = 0; i < num_clock_ts[current->pic_struct]; i++) {
|
||||
flags(clock_timestamp_flag[i], 1, i);
|
||||
flag(clock_timestamp_flag[i]);
|
||||
if (current->clock_timestamp_flag[i])
|
||||
CHECK(FUNC(sei_pic_timestamp)(ctx, rw,
|
||||
¤t->timestamp[i], sps));
|
||||
CHECK(FUNC(sei_pic_timestamp)(ctx, rw, ¤t->timestamp[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(sei_pan_scan_rect)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
H264RawSEIPanScanRect *current)
|
||||
{
|
||||
int err, i;
|
||||
|
||||
HEADER("Pan-Scan Rectangle");
|
||||
|
||||
ue(pan_scan_rect_id, 0, UINT32_MAX - 1);
|
||||
flag(pan_scan_rect_cancel_flag);
|
||||
|
||||
if (!current->pan_scan_rect_cancel_flag) {
|
||||
ue(pan_scan_cnt_minus1, 0, 2);
|
||||
|
||||
for (i = 0; i <= current->pan_scan_cnt_minus1; i++) {
|
||||
ses(pan_scan_rect_left_offset[i], INT32_MIN + 1, INT32_MAX, 1, i);
|
||||
ses(pan_scan_rect_right_offset[i], INT32_MIN + 1, INT32_MAX, 1, i);
|
||||
ses(pan_scan_rect_top_offset[i], INT32_MIN + 1, INT32_MAX, 1, i);
|
||||
ses(pan_scan_rect_bottom_offset[i], INT32_MIN + 1, INT32_MAX, 1, i);
|
||||
}
|
||||
|
||||
ue(pan_scan_rect_repetition_period, 0, 16384);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(sei_user_data_registered)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
H264RawSEIUserDataRegistered *current,
|
||||
uint32_t *payload_size)
|
||||
{
|
||||
int err, i, j;
|
||||
|
||||
HEADER("User Data Registered ITU-T T.35");
|
||||
|
||||
u(8, itu_t_t35_country_code, 0x00, 0xff);
|
||||
if (current->itu_t_t35_country_code != 0xff)
|
||||
i = 1;
|
||||
@@ -726,9 +656,9 @@ static int FUNC(sei_user_data_registered)(CodedBitstreamContext *ctx, RWContext
|
||||
*payload_size = i + current->data_length;
|
||||
#endif
|
||||
|
||||
allocate(current->data, current->data_length);
|
||||
allocate(current->data, current->data_length + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
for (j = 0; j < current->data_length; j++)
|
||||
xu(8, itu_t_t35_payload_byte[i], current->data[j], 0x00, 0xff, 1, i + j);
|
||||
xu(8, itu_t_t35_payload_byte, current->data[j], 0x00, 0xff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -739,8 +669,6 @@ static int FUNC(sei_user_data_unregistered)(CodedBitstreamContext *ctx, RWContex
|
||||
{
|
||||
int err, i;
|
||||
|
||||
HEADER("User Data Unregistered");
|
||||
|
||||
#ifdef READ
|
||||
if (*payload_size < 16) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR,
|
||||
@@ -752,13 +680,15 @@ static int FUNC(sei_user_data_unregistered)(CodedBitstreamContext *ctx, RWContex
|
||||
*payload_size = 16 + current->data_length;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
us(8, uuid_iso_iec_11578[i], 0x00, 0xff, 1, i);
|
||||
for (i = 0; i < 16; i++) {
|
||||
xu(8, uuid_iso_iec_11578,
|
||||
current->uuid_iso_iec_11578[i], 0x00, 0xff);
|
||||
}
|
||||
|
||||
allocate(current->data, current->data_length);
|
||||
|
||||
for (i = 0; i < current->data_length; i++)
|
||||
xu(8, user_data_payload_byte[i], current->data[i], 0x00, 0xff, 1, i);
|
||||
xu(8, user_data_payload_byte, current->data[i], 0x00, 0xff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -768,8 +698,6 @@ static int FUNC(sei_recovery_point)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
{
|
||||
int err;
|
||||
|
||||
HEADER("Recovery Point");
|
||||
|
||||
ue(recovery_frame_cnt, 0, 65535);
|
||||
flag(exact_match_flag);
|
||||
flag(broken_link_flag);
|
||||
@@ -783,8 +711,6 @@ static int FUNC(sei_display_orientation)(CodedBitstreamContext *ctx, RWContext *
|
||||
{
|
||||
int err;
|
||||
|
||||
HEADER("Display Orientation");
|
||||
|
||||
flag(display_orientation_cancel_flag);
|
||||
if (!current->display_orientation_cancel_flag) {
|
||||
flag(hor_flip);
|
||||
@@ -797,27 +723,6 @@ static int FUNC(sei_display_orientation)(CodedBitstreamContext *ctx, RWContext *
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(sei_mastering_display_colour_volume)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
H264RawSEIMasteringDisplayColourVolume *current)
|
||||
{
|
||||
int err, c;
|
||||
|
||||
HEADER("Mastering Display Colour Volume");
|
||||
|
||||
for (c = 0; c < 3; c++) {
|
||||
us(16, display_primaries_x[c], 0, 50000, 1, c);
|
||||
us(16, display_primaries_y[c], 0, 50000, 1, c);
|
||||
}
|
||||
|
||||
u(16, white_point_x, 0, 50000);
|
||||
u(16, white_point_y, 0, 50000);
|
||||
|
||||
u(32, max_display_mastering_luminance, 1, MAX_UINT_BITS(32));
|
||||
u(32, min_display_mastering_luminance, 0, current->max_display_mastering_luminance - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
H264RawSEIPayload *current)
|
||||
{
|
||||
@@ -839,14 +744,11 @@ static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
CHECK(FUNC(sei_pic_timing)
|
||||
(ctx, rw, ¤t->payload.pic_timing));
|
||||
break;
|
||||
case H264_SEI_TYPE_PAN_SCAN_RECT:
|
||||
CHECK(FUNC(sei_pan_scan_rect)
|
||||
(ctx, rw, ¤t->payload.pan_scan_rect));
|
||||
break;
|
||||
case H264_SEI_TYPE_FILLER_PAYLOAD:
|
||||
{
|
||||
av_unused int ff_byte = 0xff;
|
||||
for (i = 0; i < current->payload_size; i++)
|
||||
fixed(8, ff_byte, 0xff);
|
||||
xu(8, ff_byte, ff_byte, 0xff, 0xff);
|
||||
}
|
||||
break;
|
||||
case H264_SEI_TYPE_USER_DATA_REGISTERED:
|
||||
@@ -865,25 +767,19 @@ static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
CHECK(FUNC(sei_display_orientation)
|
||||
(ctx, rw, ¤t->payload.display_orientation));
|
||||
break;
|
||||
case H264_SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME:
|
||||
CHECK(FUNC(sei_mastering_display_colour_volume)
|
||||
(ctx, rw, ¤t->payload.mastering_display_colour_volume));
|
||||
break;
|
||||
default:
|
||||
{
|
||||
#ifdef READ
|
||||
current->payload.other.data_length = current->payload_size;
|
||||
#endif
|
||||
allocate(current->payload.other.data, current->payload.other.data_length);
|
||||
for (i = 0; i < current->payload.other.data_length; i++)
|
||||
xu(8, payload_byte[i], current->payload.other.data[i], 0, 255, 1, i);
|
||||
allocate(current->payload.other.data, current->payload_size);
|
||||
for (i = 0; i < current->payload_size; i++)
|
||||
xu(8, payload_byte, current->payload.other.data[i], 0, 255);
|
||||
}
|
||||
}
|
||||
|
||||
if (byte_alignment(rw)) {
|
||||
fixed(1, bit_equal_to_one, 1);
|
||||
av_unused int one = 1, zero = 0;
|
||||
xu(1, bit_equal_to_one, one, 1, 1);
|
||||
while (byte_alignment(rw))
|
||||
fixed(1, bit_equal_to_zero, 0);
|
||||
xu(1, bit_equal_to_zero, zero, 0, 0);
|
||||
}
|
||||
|
||||
#ifdef READ
|
||||
@@ -920,17 +816,17 @@ static int FUNC(sei)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
uint32_t tmp;
|
||||
|
||||
while (show_bits(rw, 8) == 0xff) {
|
||||
fixed(8, ff_byte, 0xff);
|
||||
xu(8, ff_byte, tmp, 0xff, 0xff);
|
||||
payload_type += 255;
|
||||
}
|
||||
xu(8, last_payload_type_byte, tmp, 0, 254, 0);
|
||||
xu(8, last_payload_type_byte, tmp, 0, 254);
|
||||
payload_type += tmp;
|
||||
|
||||
while (show_bits(rw, 8) == 0xff) {
|
||||
fixed(8, ff_byte, 0xff);
|
||||
xu(8, ff_byte, tmp, 0xff, 0xff);
|
||||
payload_size += 255;
|
||||
}
|
||||
xu(8, last_payload_size_byte, tmp, 0, 254, 0);
|
||||
xu(8, last_payload_size_byte, tmp, 0, 254);
|
||||
payload_size += tmp;
|
||||
|
||||
current->payload[k].payload_type = payload_type;
|
||||
@@ -963,17 +859,17 @@ static int FUNC(sei)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
|
||||
tmp = current->payload[k].payload_type;
|
||||
while (tmp >= 255) {
|
||||
fixed(8, ff_byte, 0xff);
|
||||
xu(8, ff_byte, 0xff, 0xff, 0xff);
|
||||
tmp -= 255;
|
||||
}
|
||||
xu(8, last_payload_type_byte, tmp, 0, 254, 0);
|
||||
xu(8, last_payload_type_byte, tmp, 0, 254);
|
||||
|
||||
tmp = current->payload[k].payload_size;
|
||||
while (tmp >= 255) {
|
||||
fixed(8, ff_byte, 0xff);
|
||||
xu(8, ff_byte, 0xff, 0xff, 0xff);
|
||||
tmp -= 255;
|
||||
}
|
||||
xu(8, last_payload_size_byte, tmp, 0, 254, 0);
|
||||
xu(8, last_payload_size_byte, tmp, 0, 254);
|
||||
|
||||
CHECK(FUNC(sei_payload)(ctx, rw, ¤t->payload[k]));
|
||||
}
|
||||
@@ -1015,7 +911,7 @@ static int FUNC(ref_pic_list_modification)(CodedBitstreamContext *ctx, RWContext
|
||||
if (current->ref_pic_list_modification_flag_l0) {
|
||||
for (i = 0; i < H264_MAX_RPLM_COUNT; i++) {
|
||||
xue(modification_of_pic_nums_idc,
|
||||
current->rplm_l0[i].modification_of_pic_nums_idc, 0, 3, 0);
|
||||
current->rplm_l0[i].modification_of_pic_nums_idc, 0, 3);
|
||||
|
||||
mopn = current->rplm_l0[i].modification_of_pic_nums_idc;
|
||||
if (mopn == 3)
|
||||
@@ -1025,11 +921,11 @@ static int FUNC(ref_pic_list_modification)(CodedBitstreamContext *ctx, RWContext
|
||||
xue(abs_diff_pic_num_minus1,
|
||||
current->rplm_l0[i].abs_diff_pic_num_minus1,
|
||||
0, (1 + current->field_pic_flag) *
|
||||
(1 << (sps->log2_max_frame_num_minus4 + 4)), 0);
|
||||
(1 << (sps->log2_max_frame_num_minus4 + 4)));
|
||||
else if (mopn == 2)
|
||||
xue(long_term_pic_num,
|
||||
current->rplm_l0[i].long_term_pic_num,
|
||||
0, sps->max_num_ref_frames - 1, 0);
|
||||
0, sps->max_num_ref_frames - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1039,7 +935,7 @@ static int FUNC(ref_pic_list_modification)(CodedBitstreamContext *ctx, RWContext
|
||||
if (current->ref_pic_list_modification_flag_l1) {
|
||||
for (i = 0; i < H264_MAX_RPLM_COUNT; i++) {
|
||||
xue(modification_of_pic_nums_idc,
|
||||
current->rplm_l1[i].modification_of_pic_nums_idc, 0, 3, 0);
|
||||
current->rplm_l1[i].modification_of_pic_nums_idc, 0, 3);
|
||||
|
||||
mopn = current->rplm_l1[i].modification_of_pic_nums_idc;
|
||||
if (mopn == 3)
|
||||
@@ -1049,11 +945,11 @@ static int FUNC(ref_pic_list_modification)(CodedBitstreamContext *ctx, RWContext
|
||||
xue(abs_diff_pic_num_minus1,
|
||||
current->rplm_l1[i].abs_diff_pic_num_minus1,
|
||||
0, (1 + current->field_pic_flag) *
|
||||
(1 << (sps->log2_max_frame_num_minus4 + 4)), 0);
|
||||
(1 << (sps->log2_max_frame_num_minus4 + 4)));
|
||||
else if (mopn == 2)
|
||||
xue(long_term_pic_num,
|
||||
current->rplm_l1[i].long_term_pic_num,
|
||||
0, sps->max_num_ref_frames - 1, 0);
|
||||
0, sps->max_num_ref_frames - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1076,17 +972,17 @@ static int FUNC(pred_weight_table)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
ue(chroma_log2_weight_denom, 0, 7);
|
||||
|
||||
for (i = 0; i <= current->num_ref_idx_l0_active_minus1; i++) {
|
||||
flags(luma_weight_l0_flag[i], 1, i);
|
||||
flag(luma_weight_l0_flag[i]);
|
||||
if (current->luma_weight_l0_flag[i]) {
|
||||
ses(luma_weight_l0[i], -128, +127, 1, i);
|
||||
ses(luma_offset_l0[i], -128, +127, 1, i);
|
||||
se(luma_weight_l0[i], -128, +127);
|
||||
se(luma_offset_l0[i], -128, +127);
|
||||
}
|
||||
if (chroma) {
|
||||
flags(chroma_weight_l0_flag[i], 1, i);
|
||||
flag(chroma_weight_l0_flag[i]);
|
||||
if (current->chroma_weight_l0_flag[i]) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
ses(chroma_weight_l0[i][j], -128, +127, 2, i, j);
|
||||
ses(chroma_offset_l0[i][j], -128, +127, 2, i, j);
|
||||
se(chroma_weight_l0[i][j], -128, +127);
|
||||
se(chroma_offset_l0[i][j], -128, +127);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1094,17 +990,17 @@ static int FUNC(pred_weight_table)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
|
||||
if (current->slice_type % 5 == 1) {
|
||||
for (i = 0; i <= current->num_ref_idx_l1_active_minus1; i++) {
|
||||
flags(luma_weight_l1_flag[i], 1, i);
|
||||
flag(luma_weight_l1_flag[i]);
|
||||
if (current->luma_weight_l1_flag[i]) {
|
||||
ses(luma_weight_l1[i], -128, +127, 1, i);
|
||||
ses(luma_offset_l1[i], -128, +127, 1, i);
|
||||
se(luma_weight_l1[i], -128, +127);
|
||||
se(luma_offset_l1[i], -128, +127);
|
||||
}
|
||||
if (chroma) {
|
||||
flags(chroma_weight_l1_flag[i], 1, i);
|
||||
flag(chroma_weight_l1_flag[i]);
|
||||
if (current->chroma_weight_l1_flag[i]) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
ses(chroma_weight_l1[i][j], -128, +127, 2, i, j);
|
||||
ses(chroma_offset_l1[i][j], -128, +127, 2, i, j);
|
||||
se(chroma_weight_l1[i][j], -128, +127);
|
||||
se(chroma_offset_l1[i][j], -128, +127);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1131,7 +1027,7 @@ static int FUNC(dec_ref_pic_marking)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
for (i = 0; i < H264_MAX_MMCO_COUNT; i++) {
|
||||
xue(memory_management_control_operation,
|
||||
current->mmco[i].memory_management_control_operation,
|
||||
0, 6, 0);
|
||||
0, 6);
|
||||
|
||||
mmco = current->mmco[i].memory_management_control_operation;
|
||||
if (mmco == 0)
|
||||
@@ -1140,19 +1036,19 @@ static int FUNC(dec_ref_pic_marking)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
if (mmco == 1 || mmco == 3)
|
||||
xue(difference_of_pic_nums_minus1,
|
||||
current->mmco[i].difference_of_pic_nums_minus1,
|
||||
0, INT32_MAX, 0);
|
||||
0, INT32_MAX);
|
||||
if (mmco == 2)
|
||||
xue(long_term_pic_num,
|
||||
current->mmco[i].long_term_pic_num,
|
||||
0, sps->max_num_ref_frames - 1, 0);
|
||||
0, sps->max_num_ref_frames - 1);
|
||||
if (mmco == 3 || mmco == 6)
|
||||
xue(long_term_frame_idx,
|
||||
current->mmco[i].long_term_frame_idx,
|
||||
0, sps->max_num_ref_frames - 1, 0);
|
||||
0, sps->max_num_ref_frames - 1);
|
||||
if (mmco == 4)
|
||||
xue(max_long_term_frame_idx_plus1,
|
||||
current->mmco[i].max_long_term_frame_idx_plus1,
|
||||
0, sps->max_num_ref_frames, 0);
|
||||
0, sps->max_num_ref_frames);
|
||||
}
|
||||
if (i == H264_MAX_MMCO_COUNT) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Too many "
|
||||
@@ -1350,8 +1246,9 @@ static int FUNC(slice_header)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
}
|
||||
|
||||
if (pps->entropy_coding_mode_flag) {
|
||||
av_unused int one = 1;
|
||||
while (byte_alignment(rw))
|
||||
fixed(1, cabac_alignment_one_bit, 1);
|
||||
xu(1, cabac_alignment_one_bit, one, 1, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1360,6 +1257,7 @@ static int FUNC(slice_header)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
static int FUNC(filler)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
H264RawFiller *current)
|
||||
{
|
||||
av_unused int ff_byte = 0xff;
|
||||
int err;
|
||||
|
||||
HEADER("Filler Data");
|
||||
@@ -1369,14 +1267,14 @@ static int FUNC(filler)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
|
||||
#ifdef READ
|
||||
while (show_bits(rw, 8) == 0xff) {
|
||||
fixed(8, ff_byte, 0xff);
|
||||
xu(8, ff_byte, ff_byte, 0xff, 0xff);
|
||||
++current->filler_size;
|
||||
}
|
||||
#else
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < current->filler_size; i++)
|
||||
fixed(8, ff_byte, 0xff);
|
||||
xu(8, ff_byte, ff_byte, 0xff, 0xff);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1384,21 +1282,3 @@ static int FUNC(filler)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(end_of_sequence)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
H264RawNALUnitHeader *current)
|
||||
{
|
||||
HEADER("End of Sequence");
|
||||
|
||||
return FUNC(nal_unit_header)(ctx, rw, current,
|
||||
1 << H264_NAL_END_SEQUENCE);
|
||||
}
|
||||
|
||||
static int FUNC(end_of_stream)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
H264RawNALUnitHeader *current)
|
||||
{
|
||||
HEADER("End of Stream");
|
||||
|
||||
return FUNC(nal_unit_header)(ctx, rw, current,
|
||||
1 << H264_NAL_END_STREAM);
|
||||
}
|
||||
|
||||
@@ -25,14 +25,6 @@
|
||||
#include "cbs_h2645.h"
|
||||
#include "hevc.h"
|
||||
|
||||
enum {
|
||||
// This limit is arbitrary - it is sufficient for one message of each
|
||||
// type plus some repeats, and will therefore easily cover all sane
|
||||
// streams. However, it is possible to make technically-valid streams
|
||||
// for which it will fail (for example, by including a large number of
|
||||
// user-data-unregistered messages).
|
||||
H265_MAX_SEI_PAYLOADS = 64,
|
||||
};
|
||||
|
||||
typedef struct H265RawNALUnitHeader {
|
||||
uint8_t forbidden_zero_bit;
|
||||
@@ -524,40 +516,6 @@ typedef struct H265RawSlice {
|
||||
AVBufferRef *data_ref;
|
||||
} H265RawSlice;
|
||||
|
||||
typedef struct H265RawSEIMasteringDisplayColourVolume {
|
||||
uint16_t display_primaries_x[3];
|
||||
uint16_t display_primaries_y[3];
|
||||
uint16_t white_point_x;
|
||||
uint16_t white_point_y;
|
||||
uint32_t max_display_mastering_luminance;
|
||||
uint32_t min_display_mastering_luminance;
|
||||
} H265RawSEIMasteringDisplayColourVolume;
|
||||
|
||||
typedef struct H265RawSEIContentLightLevelInfo {
|
||||
uint16_t max_content_light_level;
|
||||
uint16_t max_pic_average_light_level;
|
||||
} H265RawSEIContentLightLevelInfo;
|
||||
|
||||
typedef struct H265RawSEIPayload {
|
||||
uint32_t payload_type;
|
||||
uint32_t payload_size;
|
||||
union {
|
||||
H265RawSEIMasteringDisplayColourVolume mastering_display;
|
||||
H265RawSEIContentLightLevelInfo content_light_level;
|
||||
struct {
|
||||
uint8_t *data;
|
||||
size_t data_length;
|
||||
AVBufferRef *data_ref;
|
||||
} other;
|
||||
} payload;
|
||||
} H265RawSEIPayload;
|
||||
|
||||
typedef struct H265RawSEI {
|
||||
H265RawNALUnitHeader nal_unit_header;
|
||||
|
||||
H265RawSEIPayload payload[H265_MAX_SEI_PAYLOADS];
|
||||
uint8_t payload_count;
|
||||
} H265RawSEI;
|
||||
|
||||
typedef struct CodedBitstreamH265Context {
|
||||
// Reader/writer context in common with the H.264 implementation.
|
||||
@@ -565,9 +523,6 @@ typedef struct CodedBitstreamH265Context {
|
||||
|
||||
// All currently available parameter sets. These are updated when
|
||||
// any parameter set NAL unit is read/written with this context.
|
||||
AVBufferRef *vps_ref[HEVC_MAX_VPS_COUNT];
|
||||
AVBufferRef *sps_ref[HEVC_MAX_SPS_COUNT];
|
||||
AVBufferRef *pps_ref[HEVC_MAX_PPS_COUNT];
|
||||
H265RawVPS *vps[HEVC_MAX_VPS_COUNT];
|
||||
H265RawSPS *sps[HEVC_MAX_SPS_COUNT];
|
||||
H265RawPPS *pps[HEVC_MAX_PPS_COUNT];
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
static int FUNC(rbsp_trailing_bits)(CodedBitstreamContext *ctx, RWContext *rw)
|
||||
{
|
||||
int err;
|
||||
|
||||
fixed(1, rbsp_stop_one_bit, 1);
|
||||
av_unused int one = 1, zero = 0;
|
||||
xu(1, rbsp_stop_one_bit, one, 1, 1);
|
||||
while (byte_alignment(rw) != 0)
|
||||
fixed(1, rbsp_alignment_zero_bit, 0);
|
||||
xu(1, rbsp_alignment_zero_bit, zero, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -50,10 +50,10 @@ static int FUNC(nal_unit_header)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
static int FUNC(byte_alignment)(CodedBitstreamContext *ctx, RWContext *rw)
|
||||
{
|
||||
int err;
|
||||
|
||||
fixed(1, alignment_bit_equal_to_one, 1);
|
||||
av_unused int one = 1, zero = 0;
|
||||
xu(1, alignment_bit_equal_to_one, one, 1, 1);
|
||||
while (byte_alignment(rw) != 0)
|
||||
fixed(1, alignment_bit_equal_to_zero, 0);
|
||||
xu(1, alignment_bit_equal_to_zero, zero, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -74,13 +74,13 @@ static int FUNC(extension_data)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
*rw = start;
|
||||
allocate(current->data, (current->bit_length + 7) / 8);
|
||||
for (k = 0; k < current->bit_length; k++) {
|
||||
xu(1, extension_data, bit, 0, 1, 0);
|
||||
xu(1, extension_data, bit, 0, 1);
|
||||
current->data[k / 8] |= bit << (7 - k % 8);
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (k = 0; k < current->bit_length; k++)
|
||||
xu(1, extension_data, current->data[k / 8] >> (7 - k % 8), 0, 1, 0);
|
||||
xu(1, extension_data, current->data[k / 8] >> (7 - k % 8), 0, 1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -90,6 +90,7 @@ static int FUNC(profile_tier_level)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
int profile_present_flag,
|
||||
int max_num_sub_layers_minus1)
|
||||
{
|
||||
av_unused unsigned int zero = 0;
|
||||
int err, i, j;
|
||||
|
||||
if (profile_present_flag) {
|
||||
@@ -98,7 +99,7 @@ static int FUNC(profile_tier_level)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
u(5, general_profile_idc, 0, 31);
|
||||
|
||||
for (j = 0; j < 32; j++)
|
||||
flags(general_profile_compatibility_flag[j], 1, j);
|
||||
flag(general_profile_compatibility_flag[j]);
|
||||
|
||||
flag(general_progressive_source_flag);
|
||||
flag(general_interlaced_source_flag);
|
||||
@@ -124,20 +125,15 @@ static int FUNC(profile_tier_level)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
if (profile_compatible(5) || profile_compatible(9) ||
|
||||
profile_compatible(10)) {
|
||||
flag(general_max_14bit_constraint_flag);
|
||||
fixed(24, general_reserved_zero_33bits, 0);
|
||||
fixed( 9, general_reserved_zero_33bits, 0);
|
||||
xu(24, general_reserved_zero_33bits, zero, 0, 0);
|
||||
xu(9, general_reserved_zero_33bits, zero, 0, 0);
|
||||
} else {
|
||||
fixed(24, general_reserved_zero_34bits, 0);
|
||||
fixed(10, general_reserved_zero_34bits, 0);
|
||||
xu(24, general_reserved_zero_34bits, zero, 0, 0);
|
||||
xu(10, general_reserved_zero_34bits, zero, 0, 0);
|
||||
}
|
||||
} else if (profile_compatible(2)) {
|
||||
fixed(7, general_reserved_zero_7bits, 0);
|
||||
flag(general_one_picture_only_constraint_flag);
|
||||
fixed(24, general_reserved_zero_35bits, 0);
|
||||
fixed(11, general_reserved_zero_35bits, 0);
|
||||
} else {
|
||||
fixed(24, general_reserved_zero_43bits, 0);
|
||||
fixed(19, general_reserved_zero_43bits, 0);
|
||||
xu(24, general_reserved_zero_43bits, zero, 0, 0);
|
||||
xu(19, general_reserved_zero_43bits, zero, 0, 0);
|
||||
}
|
||||
|
||||
if (profile_compatible(1) || profile_compatible(2) ||
|
||||
@@ -145,7 +141,7 @@ static int FUNC(profile_tier_level)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
profile_compatible(5) || profile_compatible(9)) {
|
||||
flag(general_inbld_flag);
|
||||
} else {
|
||||
fixed(1, general_reserved_zero_bit, 0);
|
||||
xu(1, general_reserved_zero_bit, zero, 0, 0);
|
||||
}
|
||||
#undef profile_compatible
|
||||
}
|
||||
@@ -153,13 +149,15 @@ static int FUNC(profile_tier_level)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
u(8, general_level_idc, 0, 255);
|
||||
|
||||
for (i = 0; i < max_num_sub_layers_minus1; i++) {
|
||||
flags(sub_layer_profile_present_flag[i], 1, i);
|
||||
flags(sub_layer_level_present_flag[i], 1, i);
|
||||
flag(sub_layer_profile_present_flag[i]);
|
||||
flag(sub_layer_level_present_flag[i]);
|
||||
}
|
||||
|
||||
if (max_num_sub_layers_minus1 > 0) {
|
||||
for (i = max_num_sub_layers_minus1; i < 8; i++)
|
||||
fixed(2, reserved_zero_2bits, 0);
|
||||
for (i = max_num_sub_layers_minus1; i < 8; i++) {
|
||||
av_unused int zero = 0;
|
||||
xu(2, reserved_zero_2bits, zero, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < max_num_sub_layers_minus1; i++) {
|
||||
@@ -185,13 +183,13 @@ static int FUNC(sub_layer_hrd_parameters)(CodedBitstreamContext *ctx, RWContext
|
||||
current = &hrd->vcl_sub_layer_hrd_parameters[sub_layer_id];
|
||||
|
||||
for (i = 0; i <= hrd->cpb_cnt_minus1[sub_layer_id]; i++) {
|
||||
ues(bit_rate_value_minus1[i], 0, UINT32_MAX - 1, 1, i);
|
||||
ues(cpb_size_value_minus1[i], 0, UINT32_MAX - 1, 1, i);
|
||||
ue(bit_rate_value_minus1[i], 0, UINT32_MAX - 1);
|
||||
ue(cpb_size_value_minus1[i], 0, UINT32_MAX - 1);
|
||||
if (hrd->sub_pic_hrd_params_present_flag) {
|
||||
ues(cpb_size_du_value_minus1[i], 0, UINT32_MAX - 1, 1, i);
|
||||
ues(bit_rate_du_value_minus1[i], 0, UINT32_MAX - 1, 1, i);
|
||||
ue(cpb_size_du_value_minus1[i], 0, UINT32_MAX - 1);
|
||||
ue(bit_rate_du_value_minus1[i], 0, UINT32_MAX - 1);
|
||||
}
|
||||
flags(cbr_flag[i], 1, i);
|
||||
flag(cbr_flag[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -235,21 +233,21 @@ static int FUNC(hrd_parameters)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
}
|
||||
|
||||
for (i = 0; i <= max_num_sub_layers_minus1; i++) {
|
||||
flags(fixed_pic_rate_general_flag[i], 1, i);
|
||||
flag(fixed_pic_rate_general_flag[i]);
|
||||
|
||||
if (!current->fixed_pic_rate_general_flag[i])
|
||||
flags(fixed_pic_rate_within_cvs_flag[i], 1, i);
|
||||
flag(fixed_pic_rate_within_cvs_flag[i]);
|
||||
else
|
||||
infer(fixed_pic_rate_within_cvs_flag[i], 1);
|
||||
|
||||
if (current->fixed_pic_rate_within_cvs_flag[i]) {
|
||||
ues(elemental_duration_in_tc_minus1[i], 0, 2047, 1, i);
|
||||
ue(elemental_duration_in_tc_minus1[i], 0, 2047);
|
||||
infer(low_delay_hrd_flag[i], 0);
|
||||
} else
|
||||
flags(low_delay_hrd_flag[i], 1, i);
|
||||
flag(low_delay_hrd_flag[i]);
|
||||
|
||||
if (!current->low_delay_hrd_flag[i])
|
||||
ues(cpb_cnt_minus1[i], 0, 31, 1, i);
|
||||
ue(cpb_cnt_minus1[i], 0, 31);
|
||||
else
|
||||
infer(cpb_cnt_minus1[i], 0);
|
||||
|
||||
@@ -388,7 +386,10 @@ static int FUNC(vps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
fixed(16, vps_reserved_0xffff_16bits, 0xffff);
|
||||
{
|
||||
av_unused uint16_t ffff = 0xffff;
|
||||
xu(16, vps_reserved_0xffff_16bits, ffff, 0xffff, 0xffff);
|
||||
}
|
||||
|
||||
CHECK(FUNC(profile_tier_level)(ctx, rw, ¤t->profile_tier_level,
|
||||
1, current->vps_max_sub_layers_minus1));
|
||||
@@ -397,12 +398,9 @@ static int FUNC(vps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
for (i = (current->vps_sub_layer_ordering_info_present_flag ?
|
||||
0 : current->vps_max_sub_layers_minus1);
|
||||
i <= current->vps_max_sub_layers_minus1; i++) {
|
||||
ues(vps_max_dec_pic_buffering_minus1[i],
|
||||
0, HEVC_MAX_DPB_SIZE - 1, 1, i);
|
||||
ues(vps_max_num_reorder_pics[i],
|
||||
0, current->vps_max_dec_pic_buffering_minus1[i], 1, i);
|
||||
ues(vps_max_latency_increase_plus1[i],
|
||||
0, UINT32_MAX - 1, 1, i);
|
||||
ue(vps_max_dec_pic_buffering_minus1[i], 0, HEVC_MAX_DPB_SIZE - 1);
|
||||
ue(vps_max_num_reorder_pics[i], 0, current->vps_max_dec_pic_buffering_minus1[i]);
|
||||
ue(vps_max_latency_increase_plus1[i], 0, UINT32_MAX - 1);
|
||||
}
|
||||
if (!current->vps_sub_layer_ordering_info_present_flag) {
|
||||
for (i = 0; i < current->vps_max_sub_layers_minus1; i++) {
|
||||
@@ -419,7 +417,7 @@ static int FUNC(vps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
ue(vps_num_layer_sets_minus1, 0, HEVC_MAX_LAYER_SETS - 1);
|
||||
for (i = 1; i <= current->vps_num_layer_sets_minus1; i++) {
|
||||
for (j = 0; j <= current->vps_max_layer_id; j++)
|
||||
flags(layer_id_included_flag[i][j], 2, i, j);
|
||||
flag(layer_id_included_flag[i][j]);
|
||||
}
|
||||
for (j = 0; j <= current->vps_max_layer_id; j++)
|
||||
infer(layer_id_included_flag[0][j], j == 0);
|
||||
@@ -433,11 +431,11 @@ static int FUNC(vps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
ue(vps_num_ticks_poc_diff_one_minus1, 0, UINT32_MAX - 1);
|
||||
ue(vps_num_hrd_parameters, 0, current->vps_num_layer_sets_minus1 + 1);
|
||||
for (i = 0; i < current->vps_num_hrd_parameters; i++) {
|
||||
ues(hrd_layer_set_idx[i],
|
||||
current->vps_base_layer_internal_flag ? 0 : 1,
|
||||
current->vps_num_layer_sets_minus1, 1, i);
|
||||
ue(hrd_layer_set_idx[i],
|
||||
current->vps_base_layer_internal_flag ? 0 : 1,
|
||||
current->vps_num_layer_sets_minus1);
|
||||
if (i > 0)
|
||||
flags(cprms_present_flag[i], 1, i);
|
||||
flag(cprms_present_flag[i]);
|
||||
else
|
||||
infer(cprms_present_flag[0], 1);
|
||||
|
||||
@@ -491,9 +489,9 @@ static int FUNC(st_ref_pic_set)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
(current->abs_delta_rps_minus1 + 1);
|
||||
|
||||
for (j = 0; j <= num_delta_pocs; j++) {
|
||||
flags(used_by_curr_pic_flag[j], 1, j);
|
||||
flag(used_by_curr_pic_flag[j]);
|
||||
if (!current->used_by_curr_pic_flag[j])
|
||||
flags(use_delta_flag[j], 1, j);
|
||||
flag(use_delta_flag[j]);
|
||||
else
|
||||
infer(use_delta_flag[j], 1);
|
||||
}
|
||||
@@ -588,13 +586,13 @@ static int FUNC(st_ref_pic_set)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
ue(num_positive_pics, 0, 15 - current->num_negative_pics);
|
||||
|
||||
for (i = 0; i < current->num_negative_pics; i++) {
|
||||
ues(delta_poc_s0_minus1[i], 0, INT16_MAX, 1, i);
|
||||
flags(used_by_curr_pic_s0_flag[i], 1, i);
|
||||
ue(delta_poc_s0_minus1[i], 0, INT16_MAX);
|
||||
flag(used_by_curr_pic_s0_flag[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < current->num_positive_pics; i++) {
|
||||
ues(delta_poc_s1_minus1[i], 0, INT16_MAX, 1, i);
|
||||
flags(used_by_curr_pic_s1_flag[i], 1, i);
|
||||
ue(delta_poc_s1_minus1[i], 0, INT16_MAX);
|
||||
flag(used_by_curr_pic_s1_flag[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -609,21 +607,18 @@ static int FUNC(scaling_list_data)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
|
||||
for (sizeId = 0; sizeId < 4; sizeId++) {
|
||||
for (matrixId = 0; matrixId < 6; matrixId += (sizeId == 3 ? 3 : 1)) {
|
||||
flags(scaling_list_pred_mode_flag[sizeId][matrixId],
|
||||
2, sizeId, matrixId);
|
||||
flag(scaling_list_pred_mode_flag[sizeId][matrixId]);
|
||||
if (!current->scaling_list_pred_mode_flag[sizeId][matrixId]) {
|
||||
ues(scaling_list_pred_matrix_id_delta[sizeId][matrixId],
|
||||
0, sizeId == 3 ? matrixId / 3 : matrixId,
|
||||
2, sizeId, matrixId);
|
||||
ue(scaling_list_pred_matrix_id_delta[sizeId][matrixId],
|
||||
0, sizeId == 3 ? matrixId / 3 : matrixId);
|
||||
} else {
|
||||
n = FFMIN(64, 1 << (4 + (sizeId << 1)));
|
||||
if (sizeId > 1) {
|
||||
ses(scaling_list_dc_coef_minus8[sizeId - 2][matrixId], -7, +247,
|
||||
2, sizeId - 2, matrixId);
|
||||
}
|
||||
if (sizeId > 1)
|
||||
se(scaling_list_dc_coef_minus8[sizeId - 2][matrixId], -7, +247);
|
||||
for (i = 0; i < n; i++) {
|
||||
ses(scaling_list_delta_coeff[sizeId][matrixId][i],
|
||||
-128, +127, 3, sizeId, matrixId, i);
|
||||
xse(scaling_list_delta_coeff,
|
||||
current->scaling_list_delta_coeff[sizeId][matrixId][i],
|
||||
-128, +127);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -669,8 +664,8 @@ static int FUNC(sps_scc_extension)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
int bit_depth = comp == 0 ? current->bit_depth_luma_minus8 + 8
|
||||
: current->bit_depth_chroma_minus8 + 8;
|
||||
for (i = 0; i <= current->sps_num_palette_predictor_initializer_minus1; i++)
|
||||
us(bit_depth, sps_palette_predictor_initializers[comp][i],
|
||||
0, MAX_UINT_BITS(bit_depth), 2, comp, i);
|
||||
u(bit_depth, sps_palette_predictor_initializers[comp][i],
|
||||
0, MAX_UINT_BITS(bit_depth));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -753,12 +748,9 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
for (i = (current->sps_sub_layer_ordering_info_present_flag ?
|
||||
0 : current->sps_max_sub_layers_minus1);
|
||||
i <= current->sps_max_sub_layers_minus1; i++) {
|
||||
ues(sps_max_dec_pic_buffering_minus1[i],
|
||||
0, HEVC_MAX_DPB_SIZE - 1, 1, i);
|
||||
ues(sps_max_num_reorder_pics[i],
|
||||
0, current->sps_max_dec_pic_buffering_minus1[i], 1, i);
|
||||
ues(sps_max_latency_increase_plus1[i],
|
||||
0, UINT32_MAX - 1, 1, i);
|
||||
ue(sps_max_dec_pic_buffering_minus1[i], 0, HEVC_MAX_DPB_SIZE - 1);
|
||||
ue(sps_max_num_reorder_pics[i], 0, current->sps_max_dec_pic_buffering_minus1[i]);
|
||||
ue(sps_max_latency_increase_plus1[i], 0, UINT32_MAX - 1);
|
||||
}
|
||||
if (!current->sps_sub_layer_ordering_info_present_flag) {
|
||||
for (i = 0; i < current->sps_max_sub_layers_minus1; i++) {
|
||||
@@ -833,10 +825,10 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
if (current->long_term_ref_pics_present_flag) {
|
||||
ue(num_long_term_ref_pics_sps, 0, HEVC_MAX_LONG_TERM_REF_PICS);
|
||||
for (i = 0; i < current->num_long_term_ref_pics_sps; i++) {
|
||||
us(current->log2_max_pic_order_cnt_lsb_minus4 + 4,
|
||||
lt_ref_pic_poc_lsb_sps[i],
|
||||
0, MAX_UINT_BITS(current->log2_max_pic_order_cnt_lsb_minus4 + 4), 1, i);
|
||||
flags(used_by_curr_pic_lt_sps_flag[i], 1, i);
|
||||
u(current->log2_max_pic_order_cnt_lsb_minus4 + 4,
|
||||
lt_ref_pic_poc_lsb_sps[i],
|
||||
0, MAX_UINT_BITS(current->log2_max_pic_order_cnt_lsb_minus4 + 4));
|
||||
flag(used_by_curr_pic_lt_sps_flag[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -889,8 +881,8 @@ static int FUNC(pps_range_extension)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
0, sps->log2_diff_max_min_luma_coding_block_size);
|
||||
ue(chroma_qp_offset_list_len_minus1, 0, 5);
|
||||
for (i = 0; i <= current->chroma_qp_offset_list_len_minus1; i++) {
|
||||
ses(cb_qp_offset_list[i], -12, +12, 1, i);
|
||||
ses(cr_qp_offset_list[i], -12, +12, 1, i);
|
||||
se(cb_qp_offset_list[i], -12, +12);
|
||||
se(cr_qp_offset_list[i], -12, +12);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -932,8 +924,8 @@ static int FUNC(pps_scc_extension)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
int bit_depth = comp == 0 ? current->luma_bit_depth_entry_minus8 + 8
|
||||
: current->chroma_bit_depth_entry_minus8 + 8;
|
||||
for (i = 0; i < current->pps_num_palette_predictor_initializer; i++)
|
||||
us(bit_depth, pps_palette_predictor_initializers[comp][i],
|
||||
0, MAX_UINT_BITS(bit_depth), 2, comp, i);
|
||||
u(bit_depth, pps_palette_predictor_initializers[comp][i],
|
||||
0, MAX_UINT_BITS(bit_depth));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -999,9 +991,9 @@ static int FUNC(pps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
flag(uniform_spacing_flag);
|
||||
if (!current->uniform_spacing_flag) {
|
||||
for (i = 0; i < current->num_tile_columns_minus1; i++)
|
||||
ues(column_width_minus1[i], 0, sps->pic_width_in_luma_samples, 1, i);
|
||||
ue(column_width_minus1[i], 0, sps->pic_width_in_luma_samples);
|
||||
for (i = 0; i < current->num_tile_rows_minus1; i++)
|
||||
ues(row_height_minus1[i], 0, sps->pic_height_in_luma_samples, 1, i);
|
||||
ue(row_height_minus1[i], 0, sps->pic_height_in_luma_samples);
|
||||
}
|
||||
flag(loop_filter_across_tiles_enabled_flag);
|
||||
} else {
|
||||
@@ -1092,14 +1084,14 @@ static int FUNC(ref_pic_lists_modification)(CodedBitstreamContext *ctx, RWContex
|
||||
flag(ref_pic_list_modification_flag_l0);
|
||||
if (current->ref_pic_list_modification_flag_l0) {
|
||||
for (i = 0; i <= current->num_ref_idx_l0_active_minus1; i++)
|
||||
us(entry_size, list_entry_l0[i], 0, num_pic_total_curr - 1, 1, i);
|
||||
u(entry_size, list_entry_l0[i], 0, num_pic_total_curr - 1);
|
||||
}
|
||||
|
||||
if (current->slice_type == HEVC_SLICE_B) {
|
||||
flag(ref_pic_list_modification_flag_l1);
|
||||
if (current->ref_pic_list_modification_flag_l1) {
|
||||
for (i = 0; i <= current->num_ref_idx_l1_active_minus1; i++)
|
||||
us(entry_size, list_entry_l1[i], 0, num_pic_total_curr - 1, 1, i);
|
||||
u(entry_size, list_entry_l1[i], 0, num_pic_total_curr - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1123,14 +1115,14 @@ static int FUNC(pred_weight_table)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
|
||||
for (i = 0; i <= current->num_ref_idx_l0_active_minus1; i++) {
|
||||
if (1 /* is not same POC and same layer_id */)
|
||||
flags(luma_weight_l0_flag[i], 1, i);
|
||||
flag(luma_weight_l0_flag[i]);
|
||||
else
|
||||
infer(luma_weight_l0_flag[i], 0);
|
||||
}
|
||||
if (chroma) {
|
||||
for (i = 0; i <= current->num_ref_idx_l0_active_minus1; i++) {
|
||||
if (1 /* is not same POC and same layer_id */)
|
||||
flags(chroma_weight_l0_flag[i], 1, i);
|
||||
flag(chroma_weight_l0_flag[i]);
|
||||
else
|
||||
infer(chroma_weight_l0_flag[i], 0);
|
||||
}
|
||||
@@ -1138,20 +1130,20 @@ static int FUNC(pred_weight_table)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
|
||||
for (i = 0; i <= current->num_ref_idx_l0_active_minus1; i++) {
|
||||
if (current->luma_weight_l0_flag[i]) {
|
||||
ses(delta_luma_weight_l0[i], -128, +127, 1, i);
|
||||
ses(luma_offset_l0[i],
|
||||
-(1 << (sps->bit_depth_luma_minus8 + 8 - 1)),
|
||||
((1 << (sps->bit_depth_luma_minus8 + 8 - 1)) - 1), 1, i);
|
||||
se(delta_luma_weight_l0[i], -128, +127);
|
||||
se(luma_offset_l0[i],
|
||||
-(1 << (sps->bit_depth_luma_minus8 + 8 - 1)),
|
||||
((1 << (sps->bit_depth_luma_minus8 + 8 - 1)) - 1));
|
||||
} else {
|
||||
infer(delta_luma_weight_l0[i], 0);
|
||||
infer(luma_offset_l0[i], 0);
|
||||
}
|
||||
if (current->chroma_weight_l0_flag[i]) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
ses(delta_chroma_weight_l0[i][j], -128, +127, 2, i, j);
|
||||
ses(chroma_offset_l0[i][j],
|
||||
-(4 << (sps->bit_depth_chroma_minus8 + 8 - 1)),
|
||||
((4 << (sps->bit_depth_chroma_minus8 + 8 - 1)) - 1), 2, i, j);
|
||||
se(delta_chroma_weight_l0[i][j], -128, +127);
|
||||
se(chroma_offset_l0[i][j],
|
||||
-(4 << (sps->bit_depth_chroma_minus8 + 8 - 1)),
|
||||
((4 << (sps->bit_depth_chroma_minus8 + 8 - 1)) - 1));
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < 2; j++) {
|
||||
@@ -1164,14 +1156,14 @@ static int FUNC(pred_weight_table)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
if (current->slice_type == HEVC_SLICE_B) {
|
||||
for (i = 0; i <= current->num_ref_idx_l1_active_minus1; i++) {
|
||||
if (1 /* RefPicList1[i] is not CurrPic, nor is it in a different layer */)
|
||||
flags(luma_weight_l1_flag[i], 1, i);
|
||||
flag(luma_weight_l1_flag[i]);
|
||||
else
|
||||
infer(luma_weight_l1_flag[i], 0);
|
||||
}
|
||||
if (chroma) {
|
||||
for (i = 0; i <= current->num_ref_idx_l1_active_minus1; i++) {
|
||||
if (1 /* RefPicList1[i] is not CurrPic, nor is it in a different layer */)
|
||||
flags(chroma_weight_l1_flag[i], 1, i);
|
||||
flag(chroma_weight_l1_flag[i]);
|
||||
else
|
||||
infer(chroma_weight_l1_flag[i], 0);
|
||||
}
|
||||
@@ -1179,20 +1171,20 @@ static int FUNC(pred_weight_table)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
|
||||
for (i = 0; i <= current->num_ref_idx_l1_active_minus1; i++) {
|
||||
if (current->luma_weight_l1_flag[i]) {
|
||||
ses(delta_luma_weight_l1[i], -128, +127, 1, i);
|
||||
ses(luma_offset_l1[i],
|
||||
-(1 << (sps->bit_depth_luma_minus8 + 8 - 1)),
|
||||
((1 << (sps->bit_depth_luma_minus8 + 8 - 1)) - 1), 1, i);
|
||||
se(delta_luma_weight_l1[i], -128, +127);
|
||||
se(luma_offset_l1[i],
|
||||
-(1 << (sps->bit_depth_luma_minus8 + 8 - 1)),
|
||||
((1 << (sps->bit_depth_luma_minus8 + 8 - 1)) - 1));
|
||||
} else {
|
||||
infer(delta_luma_weight_l1[i], 0);
|
||||
infer(luma_offset_l1[i], 0);
|
||||
}
|
||||
if (current->chroma_weight_l1_flag[i]) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
ses(delta_chroma_weight_l1[i][j], -128, +127, 2, i, j);
|
||||
ses(chroma_offset_l1[i][j],
|
||||
-(4 << (sps->bit_depth_chroma_minus8 + 8 - 1)),
|
||||
((4 << (sps->bit_depth_chroma_minus8 + 8 - 1)) - 1), 2, i, j);
|
||||
se(delta_chroma_weight_l1[i][j], -128, +127);
|
||||
se(chroma_offset_l1[i][j],
|
||||
-(4 << (sps->bit_depth_chroma_minus8 + 8 - 1)),
|
||||
((4 << (sps->bit_depth_chroma_minus8 + 8 - 1)) - 1));
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < 2; j++) {
|
||||
@@ -1267,7 +1259,7 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
|
||||
if (!current->dependent_slice_segment_flag) {
|
||||
for (i = 0; i < pps->num_extra_slice_header_bits; i++)
|
||||
flags(slice_reserved_flag[i], 1, i);
|
||||
flag(slice_reserved_flag[i]);
|
||||
|
||||
ue(slice_type, 0, 2);
|
||||
|
||||
@@ -1323,20 +1315,20 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
current->num_long_term_pics; i++) {
|
||||
if (i < current->num_long_term_sps) {
|
||||
if (sps->num_long_term_ref_pics_sps > 1)
|
||||
us(idx_size, lt_idx_sps[i],
|
||||
0, sps->num_long_term_ref_pics_sps - 1, 1, i);
|
||||
u(idx_size, lt_idx_sps[i],
|
||||
0, sps->num_long_term_ref_pics_sps - 1);
|
||||
if (sps->used_by_curr_pic_lt_sps_flag[current->lt_idx_sps[i]])
|
||||
++num_pic_total_curr;
|
||||
} else {
|
||||
us(sps->log2_max_pic_order_cnt_lsb_minus4 + 4, poc_lsb_lt[i],
|
||||
0, MAX_UINT_BITS(sps->log2_max_pic_order_cnt_lsb_minus4 + 4), 1, i);
|
||||
flags(used_by_curr_pic_lt_flag[i], 1, i);
|
||||
u(sps->log2_max_pic_order_cnt_lsb_minus4 + 4, poc_lsb_lt[i],
|
||||
0, MAX_UINT_BITS(sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
|
||||
flag(used_by_curr_pic_lt_flag[i]);
|
||||
if (current->used_by_curr_pic_lt_flag[i])
|
||||
++num_pic_total_curr;
|
||||
}
|
||||
flags(delta_poc_msb_present_flag[i], 1, i);
|
||||
flag(delta_poc_msb_present_flag[i]);
|
||||
if (current->delta_poc_msb_present_flag[i])
|
||||
ues(delta_poc_msb_cycle_lt[i], 0, UINT32_MAX - 1, 1, i);
|
||||
ue(delta_poc_msb_cycle_lt[i], 0, UINT32_MAX - 1);
|
||||
else
|
||||
infer(delta_poc_msb_cycle_lt[i], 0);
|
||||
}
|
||||
@@ -1494,193 +1486,18 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
if (current->num_entry_point_offsets > 0) {
|
||||
ue(offset_len_minus1, 0, 31);
|
||||
for (i = 0; i < current->num_entry_point_offsets; i++)
|
||||
us(current->offset_len_minus1 + 1, entry_point_offset_minus1[i],
|
||||
0, MAX_UINT_BITS(current->offset_len_minus1 + 1), 1, i);
|
||||
u(current->offset_len_minus1 + 1, entry_point_offset_minus1[i],
|
||||
0, MAX_UINT_BITS(current->offset_len_minus1 + 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (pps->slice_segment_header_extension_present_flag) {
|
||||
ue(slice_segment_header_extension_length, 0, 256);
|
||||
for (i = 0; i < current->slice_segment_header_extension_length; i++)
|
||||
us(8, slice_segment_header_extension_data_byte[i], 0x00, 0xff, 1, i);
|
||||
u(8, slice_segment_header_extension_data_byte[i], 0x00, 0xff);
|
||||
}
|
||||
|
||||
CHECK(FUNC(byte_alignment)(ctx, rw));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(sei_mastering_display)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
H265RawSEIMasteringDisplayColourVolume *current)
|
||||
{
|
||||
int err, c;
|
||||
|
||||
for (c = 0; c < 3; c++) {
|
||||
us(16, display_primaries_x[c], 0, 50000, 1, c);
|
||||
us(16, display_primaries_y[c], 0, 50000, 1, c);
|
||||
}
|
||||
|
||||
u(16, white_point_x, 0, 50000);
|
||||
u(16, white_point_y, 0, 50000);
|
||||
|
||||
u(32, max_display_mastering_luminance,
|
||||
1, MAX_UINT_BITS(32));
|
||||
u(32, min_display_mastering_luminance,
|
||||
0, current->max_display_mastering_luminance - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(sei_content_light_level)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
H265RawSEIContentLightLevelInfo *current)
|
||||
{
|
||||
int err;
|
||||
|
||||
u(16, max_content_light_level, 0, MAX_UINT_BITS(16));
|
||||
u(16, max_pic_average_light_level, 0, MAX_UINT_BITS(16));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
H265RawSEIPayload *current)
|
||||
{
|
||||
int err, i;
|
||||
int start_position, end_position;
|
||||
|
||||
#ifdef READ
|
||||
start_position = get_bits_count(rw);
|
||||
#else
|
||||
start_position = put_bits_count(rw);
|
||||
#endif
|
||||
|
||||
switch (current->payload_type) {
|
||||
case HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO:
|
||||
CHECK(FUNC(sei_mastering_display)
|
||||
(ctx, rw, ¤t->payload.mastering_display));
|
||||
|
||||
break;
|
||||
|
||||
case HEVC_SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO:
|
||||
CHECK(FUNC(sei_content_light_level)
|
||||
(ctx, rw, ¤t->payload.content_light_level));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
#ifdef READ
|
||||
current->payload.other.data_length = current->payload_size;
|
||||
#endif
|
||||
allocate(current->payload.other.data, current->payload.other.data_length);
|
||||
|
||||
for (i = 0; i < current->payload_size; i++)
|
||||
xu(8, payload_byte[i], current->payload.other.data[i], 0, 255,
|
||||
1, i);
|
||||
}
|
||||
}
|
||||
|
||||
if (byte_alignment(rw)) {
|
||||
fixed(1, bit_equal_to_one, 1);
|
||||
while (byte_alignment(rw))
|
||||
fixed(1, bit_equal_to_zero, 0);
|
||||
}
|
||||
|
||||
#ifdef READ
|
||||
end_position = get_bits_count(rw);
|
||||
if (end_position < start_position + 8 * current->payload_size) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Incorrect SEI payload length: "
|
||||
"header %"PRIu32" bits, actually %d bits.\n",
|
||||
8 * current->payload_size,
|
||||
end_position - start_position);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
#else
|
||||
end_position = put_bits_count(rw);
|
||||
current->payload_size = (end_position - start_position) >> 3;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(sei)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
H265RawSEI *current)
|
||||
{
|
||||
int err, k;
|
||||
|
||||
HEADER("Supplemental Enhancement Information");
|
||||
|
||||
CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header,
|
||||
HEVC_NAL_SEI_PREFIX));
|
||||
|
||||
#ifdef READ
|
||||
for (k = 0; k < H265_MAX_SEI_PAYLOADS; k++) {
|
||||
uint32_t payload_type = 0;
|
||||
uint32_t payload_size = 0;
|
||||
uint32_t tmp;
|
||||
|
||||
while (show_bits(rw, 8) == 0xff) {
|
||||
fixed(8, ff_byte, 0xff);
|
||||
payload_type += 255;
|
||||
}
|
||||
xu(8, last_payload_type_byte, tmp, 0, 254, 0);
|
||||
payload_type += tmp;
|
||||
|
||||
while (show_bits(rw, 8) == 0xff) {
|
||||
fixed(8, ff_byte, 0xff);
|
||||
payload_size += 255;
|
||||
}
|
||||
xu(8, last_payload_size_byte, tmp, 0, 254, 0);
|
||||
payload_size += tmp;
|
||||
|
||||
current->payload[k].payload_type = payload_type;
|
||||
current->payload[k].payload_size = payload_size;
|
||||
|
||||
CHECK(FUNC(sei_payload)(ctx, rw, ¤t->payload[k]));
|
||||
|
||||
if (!cbs_h2645_read_more_rbsp_data(rw))
|
||||
break;
|
||||
}
|
||||
if (k >= H265_MAX_SEI_PAYLOADS) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Too many payloads in "
|
||||
"SEI message: found %d.\n", k);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
current->payload_count = k + 1;
|
||||
#else
|
||||
for (k = 0; k < current->payload_count; k++) {
|
||||
PutBitContext start_state;
|
||||
uint32_t tmp;
|
||||
int need_size, i;
|
||||
|
||||
// Somewhat clumsy: we write the payload twice when
|
||||
// we don't know the size in advance. This will mess
|
||||
// with trace output, but is otherwise harmless.
|
||||
start_state = *rw;
|
||||
need_size = !current->payload[k].payload_size;
|
||||
for (i = 0; i < 1 + need_size; i++) {
|
||||
*rw = start_state;
|
||||
|
||||
tmp = current->payload[k].payload_type;
|
||||
while (tmp >= 255) {
|
||||
fixed(8, ff_byte, 0xff);
|
||||
tmp -= 255;
|
||||
}
|
||||
xu(8, last_payload_type_byte, tmp, 0, 254, 0);
|
||||
|
||||
tmp = current->payload[k].payload_size;
|
||||
while (tmp >= 255) {
|
||||
fixed(8, ff_byte, 0xff);
|
||||
tmp -= 255;
|
||||
}
|
||||
xu(8, last_payload_size_byte, tmp, 0, 254, 0);
|
||||
|
||||
CHECK(FUNC(sei_payload)(ctx, rw, ¤t->payload[k]));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CHECK(FUNC(rbsp_trailing_bits)(ctx, rw));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -63,8 +63,8 @@ typedef struct CodedBitstreamType {
|
||||
void ff_cbs_trace_header(CodedBitstreamContext *ctx,
|
||||
const char *name);
|
||||
|
||||
void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position,
|
||||
const char *name, const int *subscripts,
|
||||
void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx,
|
||||
int position, const char *name,
|
||||
const char *bitstring, int64_t value);
|
||||
|
||||
|
||||
@@ -72,13 +72,11 @@ void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position,
|
||||
// generation of trace output.
|
||||
|
||||
int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc,
|
||||
int width, const char *name,
|
||||
const int *subscripts, uint32_t *write_to,
|
||||
int width, const char *name, uint32_t *write_to,
|
||||
uint32_t range_min, uint32_t range_max);
|
||||
|
||||
int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
|
||||
int width, const char *name,
|
||||
const int *subscripts, uint32_t value,
|
||||
int width, const char *name, uint32_t value,
|
||||
uint32_t range_min, uint32_t range_max);
|
||||
|
||||
// The largest value representable in N bits, suitable for use as
|
||||
@@ -86,12 +84,9 @@ int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
|
||||
#define MAX_UINT_BITS(length) ((UINT64_C(1) << (length)) - 1)
|
||||
|
||||
|
||||
extern const CodedBitstreamType ff_cbs_type_av1;
|
||||
extern const CodedBitstreamType ff_cbs_type_h264;
|
||||
extern const CodedBitstreamType ff_cbs_type_h265;
|
||||
extern const CodedBitstreamType ff_cbs_type_jpeg;
|
||||
extern const CodedBitstreamType ff_cbs_type_mpeg2;
|
||||
extern const CodedBitstreamType ff_cbs_type_vp9;
|
||||
|
||||
|
||||
#endif /* AVCODEC_CBS_INTERNAL_H */
|
||||
|
||||
@@ -1,520 +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 "cbs.h"
|
||||
#include "cbs_internal.h"
|
||||
#include "cbs_jpeg.h"
|
||||
|
||||
|
||||
#define HEADER(name) do { \
|
||||
ff_cbs_trace_header(ctx, name); \
|
||||
} while (0)
|
||||
|
||||
#define CHECK(call) do { \
|
||||
err = (call); \
|
||||
if (err < 0) \
|
||||
return err; \
|
||||
} while (0)
|
||||
|
||||
#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)
|
||||
|
||||
#define u(width, name, range_min, range_max) \
|
||||
xu(width, name, range_min, range_max, 0)
|
||||
#define us(width, name, sub, range_min, range_max) \
|
||||
xu(width, name, range_min, range_max, 1, sub)
|
||||
|
||||
|
||||
#define READ
|
||||
#define READWRITE read
|
||||
#define RWContext GetBitContext
|
||||
#define FUNC(name) cbs_jpeg_read_ ## name
|
||||
|
||||
#define xu(width, name, range_min, range_max, subs, ...) do { \
|
||||
uint32_t value = range_min; \
|
||||
CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), \
|
||||
&value, range_min, range_max)); \
|
||||
current->name = value; \
|
||||
} while (0)
|
||||
|
||||
#include "cbs_jpeg_syntax_template.c"
|
||||
|
||||
#undef READ
|
||||
#undef READWRITE
|
||||
#undef RWContext
|
||||
#undef FUNC
|
||||
#undef xu
|
||||
|
||||
#define WRITE
|
||||
#define READWRITE write
|
||||
#define RWContext PutBitContext
|
||||
#define FUNC(name) cbs_jpeg_write_ ## name
|
||||
|
||||
#define xu(width, name, range_min, range_max, subs, ...) do { \
|
||||
uint32_t value = current->name; \
|
||||
CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), \
|
||||
value, range_min, range_max)); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#include "cbs_jpeg_syntax_template.c"
|
||||
|
||||
#undef READ
|
||||
#undef READWRITE
|
||||
#undef RWContext
|
||||
#undef FUNC
|
||||
#undef xu
|
||||
|
||||
|
||||
static void cbs_jpeg_free_application_data(void *unit, uint8_t *content)
|
||||
{
|
||||
JPEGRawApplicationData *ad = (JPEGRawApplicationData*)content;
|
||||
av_buffer_unref(&ad->Ap_ref);
|
||||
av_freep(&content);
|
||||
}
|
||||
|
||||
static void cbs_jpeg_free_comment(void *unit, uint8_t *content)
|
||||
{
|
||||
JPEGRawComment *comment = (JPEGRawComment*)content;
|
||||
av_buffer_unref(&comment->Cm_ref);
|
||||
av_freep(&content);
|
||||
}
|
||||
|
||||
static void cbs_jpeg_free_scan(void *unit, uint8_t *content)
|
||||
{
|
||||
JPEGRawScan *scan = (JPEGRawScan*)content;
|
||||
av_buffer_unref(&scan->data_ref);
|
||||
av_freep(&content);
|
||||
}
|
||||
|
||||
static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag,
|
||||
int header)
|
||||
{
|
||||
AVBufferRef *data_ref;
|
||||
uint8_t *data;
|
||||
size_t data_size;
|
||||
int unit, start, end, marker, next_start, next_marker;
|
||||
int err, i, j, length;
|
||||
|
||||
if (frag->data_size < 4) {
|
||||
// Definitely too short to be meaningful.
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
for (i = 0; i + 1 < frag->data_size && frag->data[i] != 0xff; i++);
|
||||
if (i > 0) {
|
||||
av_log(ctx->log_ctx, AV_LOG_WARNING, "Discarding %d bytes at "
|
||||
"beginning of image.\n", i);
|
||||
}
|
||||
for (++i; i + 1 < frag->data_size && frag->data[i] == 0xff; i++);
|
||||
if (i + 1 >= frag->data_size && frag->data[i]) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: "
|
||||
"no SOI marker found.\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
marker = frag->data[i];
|
||||
if (marker != JPEG_MARKER_SOI) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: first "
|
||||
"marker is %02x, should be SOI.\n", marker);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
for (++i; i + 1 < frag->data_size && frag->data[i] == 0xff; i++);
|
||||
if (i + 1 >= frag->data_size) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: "
|
||||
"no image content found.\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
marker = frag->data[i];
|
||||
start = i + 1;
|
||||
|
||||
for (unit = 0;; unit++) {
|
||||
if (marker == JPEG_MARKER_EOI) {
|
||||
break;
|
||||
} else if (marker == JPEG_MARKER_SOS) {
|
||||
for (i = start; i + 1 < frag->data_size; i++) {
|
||||
if (frag->data[i] != 0xff)
|
||||
continue;
|
||||
end = i;
|
||||
for (++i; i + 1 < frag->data_size &&
|
||||
frag->data[i] == 0xff; i++);
|
||||
if (i + 1 >= frag->data_size) {
|
||||
next_marker = -1;
|
||||
} else {
|
||||
if (frag->data[i] == 0x00)
|
||||
continue;
|
||||
next_marker = frag->data[i];
|
||||
next_start = i + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
i = start;
|
||||
if (i + 2 > frag->data_size) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: "
|
||||
"truncated at %02x marker.\n", marker);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
length = AV_RB16(frag->data + i);
|
||||
if (i + length > frag->data_size) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: "
|
||||
"truncated at %02x marker segment.\n", marker);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
end = start + length;
|
||||
|
||||
i = end;
|
||||
if (frag->data[i] != 0xff) {
|
||||
next_marker = -1;
|
||||
} else {
|
||||
for (++i; i + 1 < frag->data_size &&
|
||||
frag->data[i] == 0xff; i++);
|
||||
if (i + 1 >= frag->data_size) {
|
||||
next_marker = -1;
|
||||
} else {
|
||||
next_marker = frag->data[i];
|
||||
next_start = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (marker == JPEG_MARKER_SOS) {
|
||||
length = AV_RB16(frag->data + start);
|
||||
|
||||
data_ref = NULL;
|
||||
data = av_malloc(end - start +
|
||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!data)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
memcpy(data, frag->data + start, length);
|
||||
for (i = start + length, j = length; i < end; i++, j++) {
|
||||
if (frag->data[i] == 0xff) {
|
||||
while (frag->data[i] == 0xff)
|
||||
++i;
|
||||
data[j] = 0xff;
|
||||
} else {
|
||||
data[j] = frag->data[i];
|
||||
}
|
||||
}
|
||||
data_size = j;
|
||||
|
||||
memset(data + data_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
} else {
|
||||
data = frag->data + start;
|
||||
data_size = end - start;
|
||||
data_ref = frag->data_ref;
|
||||
}
|
||||
|
||||
err = ff_cbs_insert_unit_data(ctx, frag, unit, marker,
|
||||
data, data_size, data_ref);
|
||||
if (err < 0) {
|
||||
if (!data_ref)
|
||||
av_freep(&data);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (next_marker == -1)
|
||||
break;
|
||||
marker = next_marker;
|
||||
start = next_start;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamUnit *unit)
|
||||
{
|
||||
GetBitContext gbc;
|
||||
int err;
|
||||
|
||||
err = init_get_bits(&gbc, unit->data, 8 * unit->data_size);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (unit->type >= JPEG_MARKER_SOF0 &&
|
||||
unit->type <= JPEG_MARKER_SOF3) {
|
||||
err = ff_cbs_alloc_unit_content(ctx, unit,
|
||||
sizeof(JPEGRawFrameHeader),
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = cbs_jpeg_read_frame_header(ctx, &gbc, unit->content);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
} else if (unit->type >= JPEG_MARKER_APPN &&
|
||||
unit->type <= JPEG_MARKER_APPN + 15) {
|
||||
err = ff_cbs_alloc_unit_content(ctx, unit,
|
||||
sizeof(JPEGRawApplicationData),
|
||||
&cbs_jpeg_free_application_data);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = cbs_jpeg_read_application_data(ctx, &gbc, unit->content);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
} else if (unit->type == JPEG_MARKER_SOS) {
|
||||
JPEGRawScan *scan;
|
||||
int pos;
|
||||
|
||||
err = ff_cbs_alloc_unit_content(ctx, unit,
|
||||
sizeof(JPEGRawScan),
|
||||
&cbs_jpeg_free_scan);
|
||||
if (err < 0)
|
||||
return err;
|
||||
scan = unit->content;
|
||||
|
||||
err = cbs_jpeg_read_scan_header(ctx, &gbc, &scan->header);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
pos = get_bits_count(&gbc);
|
||||
av_assert0(pos % 8 == 0);
|
||||
if (pos > 0) {
|
||||
scan->data_size = unit->data_size - pos / 8;
|
||||
scan->data_ref = av_buffer_ref(unit->data_ref);
|
||||
if (!scan->data_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
scan->data = unit->data + pos / 8;
|
||||
}
|
||||
|
||||
} else {
|
||||
switch (unit->type) {
|
||||
#define SEGMENT(marker, type, func, free) \
|
||||
case JPEG_MARKER_ ## marker: \
|
||||
{ \
|
||||
err = ff_cbs_alloc_unit_content(ctx, unit, \
|
||||
sizeof(type), free); \
|
||||
if (err < 0) \
|
||||
return err; \
|
||||
err = cbs_jpeg_read_ ## func(ctx, &gbc, unit->content); \
|
||||
if (err < 0) \
|
||||
return err; \
|
||||
} \
|
||||
break
|
||||
SEGMENT(DQT, JPEGRawQuantisationTableSpecification, dqt, NULL);
|
||||
SEGMENT(DHT, JPEGRawHuffmanTableSpecification, dht, NULL);
|
||||
SEGMENT(COM, JPEGRawComment, comment, &cbs_jpeg_free_comment);
|
||||
#undef SEGMENT
|
||||
default:
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbs_jpeg_write_scan(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamUnit *unit,
|
||||
PutBitContext *pbc)
|
||||
{
|
||||
JPEGRawScan *scan = unit->content;
|
||||
int i, err;
|
||||
|
||||
err = cbs_jpeg_write_scan_header(ctx, pbc, &scan->header);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (scan->data) {
|
||||
if (scan->data_size * 8 > put_bits_left(pbc))
|
||||
return AVERROR(ENOSPC);
|
||||
|
||||
for (i = 0; i < scan->data_size; i++)
|
||||
put_bits(pbc, 8, scan->data[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbs_jpeg_write_segment(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamUnit *unit,
|
||||
PutBitContext *pbc)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (unit->type >= JPEG_MARKER_SOF0 &&
|
||||
unit->type <= JPEG_MARKER_SOF3) {
|
||||
err = cbs_jpeg_write_frame_header(ctx, pbc, unit->content);
|
||||
} else if (unit->type >= JPEG_MARKER_APPN &&
|
||||
unit->type <= JPEG_MARKER_APPN + 15) {
|
||||
err = cbs_jpeg_write_application_data(ctx, pbc, unit->content);
|
||||
} else {
|
||||
switch (unit->type) {
|
||||
#define SEGMENT(marker, func) \
|
||||
case JPEG_MARKER_ ## marker: \
|
||||
err = cbs_jpeg_write_ ## func(ctx, pbc, unit->content); \
|
||||
break;
|
||||
SEGMENT(DQT, dqt);
|
||||
SEGMENT(DHT, dht);
|
||||
SEGMENT(COM, comment);
|
||||
default:
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cbs_jpeg_write_unit(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamUnit *unit)
|
||||
{
|
||||
CodedBitstreamJPEGContext *priv = ctx->priv_data;
|
||||
PutBitContext pbc;
|
||||
int err;
|
||||
|
||||
if (!priv->write_buffer) {
|
||||
// Initial write buffer size is 1MB.
|
||||
priv->write_buffer_size = 1024 * 1024;
|
||||
|
||||
reallocate_and_try_again:
|
||||
err = av_reallocp(&priv->write_buffer, priv->write_buffer_size);
|
||||
if (err < 0) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Unable to allocate a "
|
||||
"sufficiently large write buffer (last attempt "
|
||||
"%"SIZE_SPECIFIER" bytes).\n", priv->write_buffer_size);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
init_put_bits(&pbc, priv->write_buffer, priv->write_buffer_size);
|
||||
|
||||
if (unit->type == JPEG_MARKER_SOS)
|
||||
err = cbs_jpeg_write_scan(ctx, unit, &pbc);
|
||||
else
|
||||
err = cbs_jpeg_write_segment(ctx, unit, &pbc);
|
||||
|
||||
if (err == AVERROR(ENOSPC)) {
|
||||
// Overflow.
|
||||
priv->write_buffer_size *= 2;
|
||||
goto reallocate_and_try_again;
|
||||
}
|
||||
if (err < 0) {
|
||||
// Write failed for some other reason.
|
||||
return err;
|
||||
}
|
||||
|
||||
if (put_bits_count(&pbc) % 8)
|
||||
unit->data_bit_padding = 8 - put_bits_count(&pbc) % 8;
|
||||
else
|
||||
unit->data_bit_padding = 0;
|
||||
|
||||
unit->data_size = (put_bits_count(&pbc) + 7) / 8;
|
||||
flush_put_bits(&pbc);
|
||||
|
||||
err = ff_cbs_alloc_unit_data(ctx, unit, unit->data_size);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
memcpy(unit->data, priv->write_buffer, unit->data_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbs_jpeg_assemble_fragment(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag)
|
||||
{
|
||||
const CodedBitstreamUnit *unit;
|
||||
uint8_t *data;
|
||||
size_t size, dp, sp;
|
||||
int i;
|
||||
|
||||
size = 4; // SOI + EOI.
|
||||
for (i = 0; i < frag->nb_units; i++) {
|
||||
unit = &frag->units[i];
|
||||
size += 2 + unit->data_size;
|
||||
if (unit->type == JPEG_MARKER_SOS) {
|
||||
for (sp = 0; sp < unit->data_size; sp++) {
|
||||
if (unit->data[sp] == 0xff)
|
||||
++size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frag->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!frag->data_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
data = frag->data_ref->data;
|
||||
|
||||
dp = 0;
|
||||
|
||||
data[dp++] = 0xff;
|
||||
data[dp++] = JPEG_MARKER_SOI;
|
||||
|
||||
for (i = 0; i < frag->nb_units; i++) {
|
||||
unit = &frag->units[i];
|
||||
|
||||
data[dp++] = 0xff;
|
||||
data[dp++] = unit->type;
|
||||
|
||||
if (unit->type != JPEG_MARKER_SOS) {
|
||||
memcpy(data + dp, unit->data, unit->data_size);
|
||||
dp += unit->data_size;
|
||||
} else {
|
||||
sp = AV_RB16(unit->data);
|
||||
av_assert0(sp <= unit->data_size);
|
||||
memcpy(data + dp, unit->data, sp);
|
||||
dp += sp;
|
||||
|
||||
for (; sp < unit->data_size; sp++) {
|
||||
if (unit->data[sp] == 0xff) {
|
||||
data[dp++] = 0xff;
|
||||
data[dp++] = 0x00;
|
||||
} else {
|
||||
data[dp++] = unit->data[sp];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data[dp++] = 0xff;
|
||||
data[dp++] = JPEG_MARKER_EOI;
|
||||
|
||||
av_assert0(dp == size);
|
||||
|
||||
memset(data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
frag->data = data;
|
||||
frag->data_size = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cbs_jpeg_close(CodedBitstreamContext *ctx)
|
||||
{
|
||||
CodedBitstreamJPEGContext *priv = ctx->priv_data;
|
||||
|
||||
av_freep(&priv->write_buffer);
|
||||
}
|
||||
|
||||
const CodedBitstreamType ff_cbs_type_jpeg = {
|
||||
.codec_id = AV_CODEC_ID_MJPEG,
|
||||
|
||||
.priv_data_size = sizeof(CodedBitstreamJPEGContext),
|
||||
|
||||
.split_fragment = &cbs_jpeg_split_fragment,
|
||||
.read_unit = &cbs_jpeg_read_unit,
|
||||
.write_unit = &cbs_jpeg_write_unit,
|
||||
.assemble_fragment = &cbs_jpeg_assemble_fragment,
|
||||
|
||||
.close = &cbs_jpeg_close,
|
||||
};
|
||||
@@ -1,130 +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 AVCODEC_CBS_JPEG_H
|
||||
#define AVCODEC_CBS_JPEG_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "libavutil/buffer.h"
|
||||
|
||||
|
||||
enum {
|
||||
JPEG_MARKER_SOF0 = 0xc0,
|
||||
JPEG_MARKER_SOF1 = 0xc1,
|
||||
JPEG_MARKER_SOF2 = 0xc2,
|
||||
JPEG_MARKER_SOF3 = 0xc3,
|
||||
|
||||
JPEG_MARKER_DHT = 0xc4,
|
||||
JPEG_MARKER_SOI = 0xd8,
|
||||
JPEG_MARKER_EOI = 0xd9,
|
||||
JPEG_MARKER_SOS = 0xda,
|
||||
JPEG_MARKER_DQT = 0xdb,
|
||||
|
||||
JPEG_MARKER_APPN = 0xe0,
|
||||
JPEG_MARKER_JPGN = 0xf0,
|
||||
JPEG_MARKER_COM = 0xfe,
|
||||
};
|
||||
|
||||
enum {
|
||||
JPEG_MAX_COMPONENTS = 255,
|
||||
|
||||
JPEG_MAX_HEIGHT = 65535,
|
||||
JPEG_MAX_WIDTH = 65535,
|
||||
};
|
||||
|
||||
|
||||
typedef struct JPEGRawFrameHeader {
|
||||
uint16_t Lf;
|
||||
uint8_t P;
|
||||
uint16_t Y;
|
||||
uint16_t X;
|
||||
uint16_t Nf;
|
||||
|
||||
uint8_t C [JPEG_MAX_COMPONENTS];
|
||||
uint8_t H [JPEG_MAX_COMPONENTS];
|
||||
uint8_t V [JPEG_MAX_COMPONENTS];
|
||||
uint8_t Tq[JPEG_MAX_COMPONENTS];
|
||||
} JPEGRawFrameHeader;
|
||||
|
||||
typedef struct JPEGRawScanHeader {
|
||||
uint16_t Ls;
|
||||
uint8_t Ns;
|
||||
|
||||
uint8_t Cs[JPEG_MAX_COMPONENTS];
|
||||
uint8_t Td[JPEG_MAX_COMPONENTS];
|
||||
uint8_t Ta[JPEG_MAX_COMPONENTS];
|
||||
|
||||
uint8_t Ss;
|
||||
uint8_t Se;
|
||||
uint8_t Ah;
|
||||
uint8_t Al;
|
||||
} JPEGRawScanHeader;
|
||||
|
||||
typedef struct JPEGRawScan {
|
||||
JPEGRawScanHeader header;
|
||||
uint8_t *data;
|
||||
size_t data_size;
|
||||
AVBufferRef *data_ref;
|
||||
} JPEGRawScan;
|
||||
|
||||
typedef struct JPEGRawQuantisationTable {
|
||||
uint8_t Pq;
|
||||
uint8_t Tq;
|
||||
uint16_t Q[64];
|
||||
} JPEGRawQuantisationTable;
|
||||
|
||||
typedef struct JPEGRawQuantisationTableSpecification {
|
||||
uint16_t Lq;
|
||||
JPEGRawQuantisationTable table[4];
|
||||
} JPEGRawQuantisationTableSpecification;
|
||||
|
||||
typedef struct JPEGRawHuffmanTable {
|
||||
uint8_t Tc;
|
||||
uint8_t Th;
|
||||
uint8_t L[16];
|
||||
uint8_t V[224];
|
||||
} JPEGRawHuffmanTable;
|
||||
|
||||
typedef struct JPEGRawHuffmanTableSpecification {
|
||||
uint16_t Lh;
|
||||
JPEGRawHuffmanTable table[8];
|
||||
} JPEGRawHuffmanTableSpecification;
|
||||
|
||||
typedef struct JPEGRawApplicationData {
|
||||
uint16_t Lp;
|
||||
uint8_t *Ap;
|
||||
AVBufferRef *Ap_ref;
|
||||
} JPEGRawApplicationData;
|
||||
|
||||
typedef struct JPEGRawComment {
|
||||
uint16_t Lc;
|
||||
uint8_t *Cm;
|
||||
AVBufferRef *Cm_ref;
|
||||
} JPEGRawComment;
|
||||
|
||||
|
||||
typedef struct CodedBitstreamJPEGContext {
|
||||
// Write buffer.
|
||||
uint8_t *write_buffer;
|
||||
size_t write_buffer_size;
|
||||
} CodedBitstreamJPEGContext;
|
||||
|
||||
|
||||
#endif /* AVCODEC_CBS_JPEG_H */
|
||||
@@ -1,191 +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
|
||||
*/
|
||||
|
||||
static int FUNC(frame_header)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
JPEGRawFrameHeader *current)
|
||||
{
|
||||
int err, i;
|
||||
|
||||
HEADER("Frame Header");
|
||||
|
||||
u(16, Lf, 8, 8 + 3 * JPEG_MAX_COMPONENTS);
|
||||
|
||||
u(8, P, 2, 16);
|
||||
u(16, Y, 0, JPEG_MAX_HEIGHT);
|
||||
u(16, X, 1, JPEG_MAX_WIDTH);
|
||||
u(8, Nf, 1, JPEG_MAX_COMPONENTS);
|
||||
|
||||
for (i = 0; i < current->Nf; i++) {
|
||||
us(8, C[i], i, 0, JPEG_MAX_COMPONENTS);
|
||||
us(4, H[i], i, 1, 4);
|
||||
us(4, V[i], i, 1, 4);
|
||||
us(8, Tq[i], i, 0, 3);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(quantisation_table)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
JPEGRawQuantisationTable *current)
|
||||
{
|
||||
int err, i;
|
||||
|
||||
u(4, Pq, 0, 1);
|
||||
u(4, Tq, 0, 3);
|
||||
|
||||
if (current->Pq) {
|
||||
for (i = 0; i < 64; i++)
|
||||
us(16, Q[i], i, 1, 255);
|
||||
} else {
|
||||
for (i = 0; i < 64; i++)
|
||||
us(8, Q[i], i, 1, 255);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(dqt)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
JPEGRawQuantisationTableSpecification *current)
|
||||
{
|
||||
int err, i, n;
|
||||
|
||||
HEADER("Quantisation Tables");
|
||||
|
||||
u(16, Lq, 2, 2 + 4 * 65);
|
||||
n = current->Lq / 65;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
CHECK(FUNC(quantisation_table)(ctx, rw, ¤t->table[i]));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(huffman_table)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
JPEGRawHuffmanTable *current)
|
||||
{
|
||||
int err, i, j, ij;
|
||||
|
||||
u(4, Tc, 0, 1);
|
||||
u(4, Th, 0, 3);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
us(8, L[i], i, 0, 224);
|
||||
|
||||
ij = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < current->L[i]; j++) {
|
||||
us(8, V[ij], ij, 0, 255);
|
||||
++ij;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(dht)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
JPEGRawHuffmanTableSpecification *current)
|
||||
{
|
||||
int err, i, j, n;
|
||||
|
||||
HEADER("Huffman Tables");
|
||||
|
||||
u(16, Lh, 2, 2 + 8 * (1 + 16 + 256));
|
||||
|
||||
n = 2;
|
||||
for (i = 0; n < current->Lh; i++) {
|
||||
CHECK(FUNC(huffman_table)(ctx, rw, ¤t->table[i]));
|
||||
|
||||
++n;
|
||||
for (j = 0; j < 16; j++)
|
||||
n += 1 + current->table[i].L[j];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(scan_header)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
JPEGRawScanHeader *current)
|
||||
{
|
||||
int err, j;
|
||||
|
||||
HEADER("Scan");
|
||||
|
||||
u(16, Ls, 6, 6 + 2 * JPEG_MAX_COMPONENTS);
|
||||
|
||||
u(8, Ns, 1, 4);
|
||||
for (j = 0; j < current->Ns; j++) {
|
||||
us(8, Cs[j], j, 0, JPEG_MAX_COMPONENTS);
|
||||
us(4, Td[j], j, 0, 3);
|
||||
us(4, Ta[j], j, 0, 3);
|
||||
}
|
||||
|
||||
u(8, Ss, 0, 63);
|
||||
u(8, Se, 0, 63);
|
||||
u(4, Ah, 0, 13);
|
||||
u(4, Al, 0, 15);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(application_data)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
JPEGRawApplicationData *current)
|
||||
{
|
||||
int err, i;
|
||||
|
||||
HEADER("Application Data");
|
||||
|
||||
u(16, Lp, 2, 65535);
|
||||
|
||||
if (current->Lp > 2) {
|
||||
#ifdef READ
|
||||
current->Ap_ref = av_buffer_alloc(current->Lp - 2);
|
||||
if (!current->Ap_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
current->Ap = current->Ap_ref->data;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < current->Lp - 2; i++)
|
||||
us(8, Ap[i], i, 0, 255);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(comment)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
JPEGRawComment *current)
|
||||
{
|
||||
int err, i;
|
||||
|
||||
HEADER("Comment");
|
||||
|
||||
u(16, Lc, 2, 65535);
|
||||
|
||||
if (current->Lc > 2) {
|
||||
#ifdef READ
|
||||
current->Cm_ref = av_buffer_alloc(current->Lc - 2);
|
||||
if (!current->Cm_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
current->Cm = current->Cm_ref->data;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < current->Lc - 2; i++)
|
||||
us(8, Cm[i], i, 0, 255);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -38,29 +38,24 @@
|
||||
#define FUNC_MPEG2(rw, name) FUNC_NAME(rw, mpeg2, name)
|
||||
#define FUNC(name) FUNC_MPEG2(READWRITE, name)
|
||||
|
||||
#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)
|
||||
|
||||
#define ui(width, name) \
|
||||
xui(width, name, current->name, 0)
|
||||
#define uis(width, name, subs, ...) \
|
||||
xui(width, name, current->name, subs, __VA_ARGS__)
|
||||
|
||||
|
||||
#define READ
|
||||
#define READWRITE read
|
||||
#define RWContext GetBitContext
|
||||
|
||||
#define xui(width, name, var, subs, ...) do { \
|
||||
#define xui(width, name, var) do { \
|
||||
uint32_t value = 0; \
|
||||
CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), \
|
||||
&value, 0, (1 << width) - 1)); \
|
||||
var = value; \
|
||||
} while (0)
|
||||
|
||||
#define ui(width, name) \
|
||||
xui(width, name, current->name)
|
||||
|
||||
#define marker_bit() do { \
|
||||
av_unused uint32_t one; \
|
||||
CHECK(ff_cbs_read_unsigned(ctx, rw, 1, "marker_bit", NULL, &one, 1, 1)); \
|
||||
CHECK(ff_cbs_read_unsigned(ctx, rw, 1, "marker_bit", &one, 1, 1)); \
|
||||
} while (0)
|
||||
|
||||
#define nextbits(width, compare, var) \
|
||||
@@ -73,6 +68,7 @@
|
||||
#undef READWRITE
|
||||
#undef RWContext
|
||||
#undef xui
|
||||
#undef ui
|
||||
#undef marker_bit
|
||||
#undef nextbits
|
||||
|
||||
@@ -81,14 +77,16 @@
|
||||
#define READWRITE write
|
||||
#define RWContext PutBitContext
|
||||
|
||||
#define xui(width, name, var, subs, ...) do { \
|
||||
#define xui(width, name, var) do { \
|
||||
CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), \
|
||||
var, 0, (1 << width) - 1)); \
|
||||
} while (0)
|
||||
|
||||
#define ui(width, name) \
|
||||
xui(width, name, current->name)
|
||||
|
||||
#define marker_bit() do { \
|
||||
CHECK(ff_cbs_write_unsigned(ctx, rw, 1, "marker_bit", NULL, 1, 1, 1)); \
|
||||
CHECK(ff_cbs_write_unsigned(ctx, rw, 1, "marker_bit", 1, 1, 1)); \
|
||||
} while (0)
|
||||
|
||||
#define nextbits(width, compare, var) (var)
|
||||
@@ -99,6 +97,7 @@
|
||||
#undef READWRITE
|
||||
#undef RWContext
|
||||
#undef xui
|
||||
#undef ui
|
||||
#undef marker_bit
|
||||
#undef nextbits
|
||||
|
||||
@@ -147,12 +146,18 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx,
|
||||
unit_size = (end - 4) - (start - 1);
|
||||
}
|
||||
|
||||
unit_data = (uint8_t *)start - 1;
|
||||
unit_data = av_malloc(unit_size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!unit_data)
|
||||
return AVERROR(ENOMEM);
|
||||
memcpy(unit_data, start - 1, unit_size);
|
||||
memset(unit_data + unit_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
err = ff_cbs_insert_unit_data(ctx, frag, i, unit_type,
|
||||
unit_data, unit_size, frag->data_ref);
|
||||
if (err < 0)
|
||||
unit_data, unit_size, NULL);
|
||||
if (err < 0) {
|
||||
av_freep(&unit_data);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (end == frag->data + frag->data_size)
|
||||
break;
|
||||
@@ -192,11 +197,16 @@ static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx,
|
||||
len = unit->data_size;
|
||||
|
||||
slice->data_size = len - pos / 8;
|
||||
slice->data_ref = av_buffer_ref(unit->data_ref);
|
||||
slice->data_ref = av_buffer_alloc(slice->data_size +
|
||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!slice->data_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
slice->data = unit->data + pos / 8;
|
||||
slice->data = slice->data_ref->data;
|
||||
|
||||
memcpy(slice->data,
|
||||
unit->data + pos / 8, slice->data_size);
|
||||
memset(slice->data + slice->data_size, 0,
|
||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
slice->data_bit_start = pos % 8;
|
||||
|
||||
} else {
|
||||
@@ -352,7 +362,7 @@ static int cbs_mpeg2_assemble_fragment(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag)
|
||||
{
|
||||
uint8_t *data;
|
||||
size_t size, dp;
|
||||
size_t size, dp, sp;
|
||||
int i;
|
||||
|
||||
size = 0;
|
||||
@@ -372,8 +382,8 @@ static int cbs_mpeg2_assemble_fragment(CodedBitstreamContext *ctx,
|
||||
data[dp++] = 0;
|
||||
data[dp++] = 1;
|
||||
|
||||
memcpy(data + dp, unit->data, unit->data_size);
|
||||
dp += unit->data_size;
|
||||
for (sp = 0; sp < unit->data_size; sp++)
|
||||
data[dp++] = unit->data[sp];
|
||||
}
|
||||
|
||||
av_assert0(dp == size);
|
||||
|
||||
@@ -44,13 +44,13 @@ static int FUNC(sequence_header)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
ui(1, load_intra_quantiser_matrix);
|
||||
if (current->load_intra_quantiser_matrix) {
|
||||
for (i = 0; i < 64; i++)
|
||||
uis(8, intra_quantiser_matrix[i], 1, i);
|
||||
ui(8, intra_quantiser_matrix[i]);
|
||||
}
|
||||
|
||||
ui(1, load_non_intra_quantiser_matrix);
|
||||
if (current->load_non_intra_quantiser_matrix) {
|
||||
for (i = 0; i < 64; i++)
|
||||
uis(8, non_intra_quantiser_matrix[i], 1, i);
|
||||
ui(8, non_intra_quantiser_matrix[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -79,7 +79,7 @@ static int FUNC(user_data)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
#endif
|
||||
|
||||
for (k = 0; k < current->user_data_length; k++)
|
||||
xui(8, user_data, current->user_data[k], 0);
|
||||
xui(8, user_data, current->user_data[k]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -250,25 +250,25 @@ static int FUNC(quant_matrix_extension)(CodedBitstreamContext *ctx, RWContext *r
|
||||
ui(1, load_intra_quantiser_matrix);
|
||||
if (current->load_intra_quantiser_matrix) {
|
||||
for (i = 0; i < 64; i++)
|
||||
uis(8, intra_quantiser_matrix[i], 1, i);
|
||||
ui(8, intra_quantiser_matrix[i]);
|
||||
}
|
||||
|
||||
ui(1, load_non_intra_quantiser_matrix);
|
||||
if (current->load_non_intra_quantiser_matrix) {
|
||||
for (i = 0; i < 64; i++)
|
||||
uis(8, non_intra_quantiser_matrix[i], 1, i);
|
||||
ui(8, non_intra_quantiser_matrix[i]);
|
||||
}
|
||||
|
||||
ui(1, load_chroma_intra_quantiser_matrix);
|
||||
if (current->load_chroma_intra_quantiser_matrix) {
|
||||
for (i = 0; i < 64; i++)
|
||||
uis(8, intra_quantiser_matrix[i], 1, i);
|
||||
ui(8, intra_quantiser_matrix[i]);
|
||||
}
|
||||
|
||||
ui(1, load_chroma_non_intra_quantiser_matrix);
|
||||
if (current->load_chroma_non_intra_quantiser_matrix) {
|
||||
for (i = 0; i < 64; i++)
|
||||
uis(8, chroma_non_intra_quantiser_matrix[i], 1, i);
|
||||
ui(8, chroma_non_intra_quantiser_matrix[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -366,16 +366,15 @@ static int FUNC(slice_header)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
if (!current->extra_information)
|
||||
return AVERROR(ENOMEM);
|
||||
for (k = 0; k < current->extra_information_length; k++) {
|
||||
xui(1, extra_bit_slice, bit, 0);
|
||||
xui(8, extra_information_slice[k],
|
||||
current->extra_information[k], 1, k);
|
||||
xui(1, extra_bit_slice, bit);
|
||||
xui(8, extra_information_slice,
|
||||
current->extra_information[k]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (k = 0; k < current->extra_information_length; k++) {
|
||||
xui(1, extra_bit_slice, 1, 0);
|
||||
xui(8, extra_information_slice[k],
|
||||
current->extra_information[k], 1, k);
|
||||
xui(1, extra_bit_slice, 1);
|
||||
xui(8, extra_information_slice, current->extra_information[k]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,692 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
|
||||
#include "cbs.h"
|
||||
#include "cbs_internal.h"
|
||||
#include "cbs_vp9.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
static int cbs_vp9_read_s(CodedBitstreamContext *ctx, GetBitContext *gbc,
|
||||
int width, const char *name,
|
||||
const int *subscripts, int32_t *write_to)
|
||||
{
|
||||
uint32_t magnitude;
|
||||
int position, sign;
|
||||
int32_t value;
|
||||
|
||||
if (ctx->trace_enable)
|
||||
position = get_bits_count(gbc);
|
||||
|
||||
if (get_bits_left(gbc) < width + 1) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid signed value at "
|
||||
"%s: bitstream ended.\n", name);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
magnitude = get_bits(gbc, width);
|
||||
sign = get_bits1(gbc);
|
||||
value = sign ? -(int32_t)magnitude : magnitude;
|
||||
|
||||
if (ctx->trace_enable) {
|
||||
char bits[33];
|
||||
int i;
|
||||
for (i = 0; i < width; i++)
|
||||
bits[i] = magnitude >> (width - i - 1) & 1 ? '1' : '0';
|
||||
bits[i] = sign ? '1' : '0';
|
||||
bits[i + 1] = 0;
|
||||
|
||||
ff_cbs_trace_syntax_element(ctx, position, name, subscripts,
|
||||
bits, value);
|
||||
}
|
||||
|
||||
*write_to = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbs_vp9_write_s(CodedBitstreamContext *ctx, PutBitContext *pbc,
|
||||
int width, const char *name,
|
||||
const int *subscripts, int32_t value)
|
||||
{
|
||||
uint32_t magnitude;
|
||||
int sign;
|
||||
|
||||
if (put_bits_left(pbc) < width + 1)
|
||||
return AVERROR(ENOSPC);
|
||||
|
||||
sign = value < 0;
|
||||
magnitude = sign ? -value : value;
|
||||
|
||||
if (ctx->trace_enable) {
|
||||
char bits[33];
|
||||
int i;
|
||||
for (i = 0; i < width; i++)
|
||||
bits[i] = magnitude >> (width - i - 1) & 1 ? '1' : '0';
|
||||
bits[i] = sign ? '1' : '0';
|
||||
bits[i + 1] = 0;
|
||||
|
||||
ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc),
|
||||
name, subscripts, bits, value);
|
||||
}
|
||||
|
||||
put_bits(pbc, width, magnitude);
|
||||
put_bits(pbc, 1, sign);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbs_vp9_read_increment(CodedBitstreamContext *ctx, GetBitContext *gbc,
|
||||
uint32_t range_min, uint32_t range_max,
|
||||
const char *name, uint32_t *write_to)
|
||||
{
|
||||
uint32_t value;
|
||||
int position, i;
|
||||
char bits[8];
|
||||
|
||||
av_assert0(range_min <= range_max && range_max - range_min < sizeof(bits) - 1);
|
||||
if (ctx->trace_enable)
|
||||
position = get_bits_count(gbc);
|
||||
|
||||
for (i = 0, value = range_min; value < range_max;) {
|
||||
if (get_bits_left(gbc) < 1) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid increment value at "
|
||||
"%s: bitstream ended.\n", name);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
if (get_bits1(gbc)) {
|
||||
bits[i++] = '1';
|
||||
++value;
|
||||
} else {
|
||||
bits[i++] = '0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->trace_enable) {
|
||||
bits[i] = 0;
|
||||
ff_cbs_trace_syntax_element(ctx, position, name, NULL, bits, value);
|
||||
}
|
||||
|
||||
*write_to = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbs_vp9_write_increment(CodedBitstreamContext *ctx, PutBitContext *pbc,
|
||||
uint32_t range_min, uint32_t range_max,
|
||||
const char *name, uint32_t value)
|
||||
{
|
||||
int len;
|
||||
|
||||
av_assert0(range_min <= range_max && range_max - range_min < 8);
|
||||
if (value < range_min || value > range_max) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
|
||||
"%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
|
||||
name, value, range_min, range_max);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if (value == range_max)
|
||||
len = range_max - range_min;
|
||||
else
|
||||
len = value - range_min + 1;
|
||||
if (put_bits_left(pbc) < len)
|
||||
return AVERROR(ENOSPC);
|
||||
|
||||
if (ctx->trace_enable) {
|
||||
char bits[8];
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (range_min + i == value)
|
||||
bits[i] = '0';
|
||||
else
|
||||
bits[i] = '1';
|
||||
}
|
||||
bits[i] = 0;
|
||||
ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc),
|
||||
name, NULL, bits, value);
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
put_bits(pbc, len, (1 << len) - 1 - (value != range_max));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbs_vp9_read_le(CodedBitstreamContext *ctx, GetBitContext *gbc,
|
||||
int width, const char *name,
|
||||
const int *subscripts, uint32_t *write_to)
|
||||
{
|
||||
uint32_t value;
|
||||
int position, b;
|
||||
|
||||
av_assert0(width % 8 == 0);
|
||||
|
||||
if (ctx->trace_enable)
|
||||
position = get_bits_count(gbc);
|
||||
|
||||
if (get_bits_left(gbc) < width) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid le value at "
|
||||
"%s: bitstream ended.\n", name);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
value = 0;
|
||||
for (b = 0; b < width; b += 8)
|
||||
value |= get_bits(gbc, 8) << b;
|
||||
|
||||
if (ctx->trace_enable) {
|
||||
char bits[33];
|
||||
int i;
|
||||
for (b = 0; b < width; b += 8)
|
||||
for (i = 0; i < 8; i++)
|
||||
bits[b + i] = value >> (b + i) & 1 ? '1' : '0';
|
||||
bits[b] = 0;
|
||||
|
||||
ff_cbs_trace_syntax_element(ctx, position, name, subscripts,
|
||||
bits, value);
|
||||
}
|
||||
|
||||
*write_to = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbs_vp9_write_le(CodedBitstreamContext *ctx, PutBitContext *pbc,
|
||||
int width, const char *name,
|
||||
const int *subscripts, uint32_t value)
|
||||
{
|
||||
int b;
|
||||
|
||||
av_assert0(width % 8 == 0);
|
||||
|
||||
if (put_bits_left(pbc) < width)
|
||||
return AVERROR(ENOSPC);
|
||||
|
||||
if (ctx->trace_enable) {
|
||||
char bits[33];
|
||||
int i;
|
||||
for (b = 0; b < width; b += 8)
|
||||
for (i = 0; i < 8; i++)
|
||||
bits[b + i] = value >> (b + i) & 1 ? '1' : '0';
|
||||
bits[b] = 0;
|
||||
|
||||
ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc),
|
||||
name, subscripts, bits, value);
|
||||
}
|
||||
|
||||
for (b = 0; b < width; b += 8)
|
||||
put_bits(pbc, 8, value >> b & 0xff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define HEADER(name) do { \
|
||||
ff_cbs_trace_header(ctx, name); \
|
||||
} while (0)
|
||||
|
||||
#define CHECK(call) do { \
|
||||
err = (call); \
|
||||
if (err < 0) \
|
||||
return err; \
|
||||
} while (0)
|
||||
|
||||
#define FUNC_NAME(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name
|
||||
#define FUNC_VP9(rw, name) FUNC_NAME(rw, vp9, name)
|
||||
#define FUNC(name) FUNC_VP9(READWRITE, name)
|
||||
|
||||
#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)
|
||||
|
||||
#define f(width, name) \
|
||||
xf(width, name, current->name, 0)
|
||||
#define s(width, name) \
|
||||
xs(width, name, current->name, 0)
|
||||
#define fs(width, name, subs, ...) \
|
||||
xf(width, name, current->name, subs, __VA_ARGS__)
|
||||
#define ss(width, name, subs, ...) \
|
||||
xs(width, name, current->name, subs, __VA_ARGS__)
|
||||
|
||||
|
||||
#define READ
|
||||
#define READWRITE read
|
||||
#define RWContext GetBitContext
|
||||
|
||||
#define xf(width, name, var, subs, ...) do { \
|
||||
uint32_t value = 0; \
|
||||
CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), \
|
||||
&value, 0, (1 << width) - 1)); \
|
||||
var = value; \
|
||||
} while (0)
|
||||
#define xs(width, name, var, subs, ...) do { \
|
||||
int32_t value = 0; \
|
||||
CHECK(cbs_vp9_read_s(ctx, rw, width, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), &value)); \
|
||||
var = value; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define increment(name, min, max) do { \
|
||||
uint32_t value = 0; \
|
||||
CHECK(cbs_vp9_read_increment(ctx, rw, min, max, #name, &value)); \
|
||||
current->name = value; \
|
||||
} while (0)
|
||||
|
||||
#define fle(width, name, subs, ...) do { \
|
||||
CHECK(cbs_vp9_read_le(ctx, rw, width, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), ¤t->name)); \
|
||||
} while (0)
|
||||
|
||||
#define delta_q(name) do { \
|
||||
uint8_t delta_coded; \
|
||||
int8_t delta_q; \
|
||||
xf(1, name.delta_coded, delta_coded, 0); \
|
||||
if (delta_coded) \
|
||||
xs(4, name.delta_q, delta_q, 0); \
|
||||
else \
|
||||
delta_q = 0; \
|
||||
current->name = delta_q; \
|
||||
} while (0)
|
||||
|
||||
#define prob(name, subs, ...) do { \
|
||||
uint8_t prob_coded; \
|
||||
int8_t prob; \
|
||||
xf(1, name.prob_coded, prob_coded, subs, __VA_ARGS__); \
|
||||
if (prob_coded) \
|
||||
xf(8, name.prob, prob, subs, __VA_ARGS__); \
|
||||
else \
|
||||
prob = 255; \
|
||||
current->name = prob; \
|
||||
} while (0)
|
||||
|
||||
#define fixed(width, name, value) do { \
|
||||
av_unused uint32_t fixed_value = value; \
|
||||
CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
|
||||
0, &fixed_value, value, value)); \
|
||||
} while (0)
|
||||
|
||||
#define infer(name, value) do { \
|
||||
current->name = value; \
|
||||
} while (0)
|
||||
|
||||
#define byte_alignment(rw) (get_bits_count(rw) % 8)
|
||||
|
||||
#include "cbs_vp9_syntax_template.c"
|
||||
|
||||
#undef READ
|
||||
#undef READWRITE
|
||||
#undef RWContext
|
||||
#undef xf
|
||||
#undef xs
|
||||
#undef increment
|
||||
#undef fle
|
||||
#undef delta_q
|
||||
#undef prob
|
||||
#undef fixed
|
||||
#undef infer
|
||||
#undef byte_alignment
|
||||
|
||||
|
||||
#define WRITE
|
||||
#define READWRITE write
|
||||
#define RWContext PutBitContext
|
||||
|
||||
#define xf(width, name, var, subs, ...) do { \
|
||||
CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), \
|
||||
var, 0, (1 << width) - 1)); \
|
||||
} while (0)
|
||||
#define xs(width, name, var, subs, ...) do { \
|
||||
CHECK(cbs_vp9_write_s(ctx, rw, width, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), var)); \
|
||||
} while (0)
|
||||
|
||||
#define increment(name, min, max) do { \
|
||||
CHECK(cbs_vp9_write_increment(ctx, rw, min, max, #name, current->name)); \
|
||||
} while (0)
|
||||
|
||||
#define fle(width, name, subs, ...) do { \
|
||||
CHECK(cbs_vp9_write_le(ctx, rw, width, #name, \
|
||||
SUBSCRIPTS(subs, __VA_ARGS__), current->name)); \
|
||||
} while (0)
|
||||
|
||||
#define delta_q(name) do { \
|
||||
xf(1, name.delta_coded, !!current->name, 0); \
|
||||
if (current->name) \
|
||||
xs(4, name.delta_q, current->name, 0); \
|
||||
} while (0)
|
||||
|
||||
#define prob(name, subs, ...) do { \
|
||||
xf(1, name.prob_coded, current->name != 255, subs, __VA_ARGS__); \
|
||||
if (current->name != 255) \
|
||||
xf(8, name.prob, current->name, subs, __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define fixed(width, name, value) do { \
|
||||
CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
|
||||
0, value, value, value)); \
|
||||
} while (0)
|
||||
|
||||
#define infer(name, value) do { \
|
||||
if (current->name != (value)) { \
|
||||
av_log(ctx->log_ctx, AV_LOG_WARNING, "Warning: " \
|
||||
"%s does not match inferred value: " \
|
||||
"%"PRId64", but should be %"PRId64".\n", \
|
||||
#name, (int64_t)current->name, (int64_t)(value)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define byte_alignment(rw) (put_bits_count(rw) % 8)
|
||||
|
||||
#include "cbs_vp9_syntax_template.c"
|
||||
|
||||
#undef READ
|
||||
#undef READWRITE
|
||||
#undef RWContext
|
||||
#undef xf
|
||||
#undef xs
|
||||
#undef increment
|
||||
#undef fle
|
||||
#undef delta_q
|
||||
#undef prob
|
||||
#undef fixed
|
||||
#undef infer
|
||||
#undef byte_alignment
|
||||
|
||||
|
||||
static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag,
|
||||
int header)
|
||||
{
|
||||
uint8_t superframe_header;
|
||||
int err;
|
||||
|
||||
// Last byte in the packet.
|
||||
superframe_header = frag->data[frag->data_size - 1];
|
||||
|
||||
if ((superframe_header & 0xe0) == 0xc0) {
|
||||
VP9RawSuperframeIndex sfi;
|
||||
GetBitContext gbc;
|
||||
size_t index_size, pos;
|
||||
int i;
|
||||
|
||||
index_size = 2 + (((superframe_header & 0x18) >> 3) + 1) *
|
||||
((superframe_header & 0x07) + 1);
|
||||
|
||||
err = init_get_bits(&gbc, frag->data + frag->data_size - index_size,
|
||||
8 * index_size);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = cbs_vp9_read_superframe_index(ctx, &gbc, &sfi);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
pos = 0;
|
||||
for (i = 0; i <= sfi.frames_in_superframe_minus_1; i++) {
|
||||
if (pos + sfi.frame_sizes[i] + index_size > frag->data_size) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Frame %d too large "
|
||||
"in superframe: %"PRIu32" bytes.\n",
|
||||
i, sfi.frame_sizes[i]);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
err = ff_cbs_insert_unit_data(ctx, frag, -1, 0,
|
||||
frag->data + pos,
|
||||
sfi.frame_sizes[i],
|
||||
frag->data_ref);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
pos += sfi.frame_sizes[i];
|
||||
}
|
||||
if (pos + index_size != frag->data_size) {
|
||||
av_log(ctx->log_ctx, AV_LOG_WARNING, "Extra padding at "
|
||||
"end of superframe: %zu bytes.\n",
|
||||
frag->data_size - (pos + index_size));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
err = ff_cbs_insert_unit_data(ctx, frag, -1, 0,
|
||||
frag->data, frag->data_size,
|
||||
frag->data_ref);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cbs_vp9_free_frame(void *unit, uint8_t *content)
|
||||
{
|
||||
VP9RawFrame *frame = (VP9RawFrame*)content;
|
||||
av_buffer_unref(&frame->data_ref);
|
||||
av_freep(&frame);
|
||||
}
|
||||
|
||||
static int cbs_vp9_read_unit(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamUnit *unit)
|
||||
{
|
||||
VP9RawFrame *frame;
|
||||
GetBitContext gbc;
|
||||
int err, pos;
|
||||
|
||||
err = init_get_bits(&gbc, unit->data, 8 * unit->data_size);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*frame),
|
||||
&cbs_vp9_free_frame);
|
||||
if (err < 0)
|
||||
return err;
|
||||
frame = unit->content;
|
||||
|
||||
err = cbs_vp9_read_frame(ctx, &gbc, frame);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
pos = get_bits_count(&gbc);
|
||||
av_assert0(pos % 8 == 0);
|
||||
pos /= 8;
|
||||
av_assert0(pos <= unit->data_size);
|
||||
|
||||
if (pos == unit->data_size) {
|
||||
// No data (e.g. a show-existing-frame frame).
|
||||
} else {
|
||||
frame->data_ref = av_buffer_ref(unit->data_ref);
|
||||
if (!frame->data_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
frame->data = unit->data + pos;
|
||||
frame->data_size = unit->data_size - pos;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbs_vp9_write_unit(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamUnit *unit)
|
||||
{
|
||||
CodedBitstreamVP9Context *priv = ctx->priv_data;
|
||||
VP9RawFrame *frame = unit->content;
|
||||
PutBitContext pbc;
|
||||
int err;
|
||||
|
||||
if (!priv->write_buffer) {
|
||||
// Initial write buffer size is 1MB.
|
||||
priv->write_buffer_size = 1024 * 1024;
|
||||
|
||||
reallocate_and_try_again:
|
||||
err = av_reallocp(&priv->write_buffer, priv->write_buffer_size);
|
||||
if (err < 0) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Unable to allocate a "
|
||||
"sufficiently large write buffer (last attempt "
|
||||
"%zu bytes).\n", priv->write_buffer_size);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
init_put_bits(&pbc, priv->write_buffer, priv->write_buffer_size);
|
||||
|
||||
err = cbs_vp9_write_frame(ctx, &pbc, frame);
|
||||
if (err == AVERROR(ENOSPC)) {
|
||||
priv->write_buffer_size *= 2;
|
||||
goto reallocate_and_try_again;
|
||||
}
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
// Frame must be byte-aligned.
|
||||
av_assert0(put_bits_count(&pbc) % 8 == 0);
|
||||
|
||||
unit->data_size = put_bits_count(&pbc) / 8;
|
||||
unit->data_bit_padding = 0;
|
||||
flush_put_bits(&pbc);
|
||||
|
||||
if (frame->data) {
|
||||
if (unit->data_size + frame->data_size >
|
||||
priv->write_buffer_size) {
|
||||
priv->write_buffer_size *= 2;
|
||||
goto reallocate_and_try_again;
|
||||
}
|
||||
|
||||
memcpy(priv->write_buffer + unit->data_size,
|
||||
frame->data, frame->data_size);
|
||||
unit->data_size += frame->data_size;
|
||||
}
|
||||
|
||||
err = ff_cbs_alloc_unit_data(ctx, unit, unit->data_size);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
memcpy(unit->data, priv->write_buffer, unit->data_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbs_vp9_assemble_fragment(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (frag->nb_units == 1) {
|
||||
// Output is just the content of the single frame.
|
||||
|
||||
CodedBitstreamUnit *frame = &frag->units[0];
|
||||
|
||||
frag->data_ref = av_buffer_ref(frame->data_ref);
|
||||
if (!frag->data_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
frag->data = frame->data;
|
||||
frag->data_size = frame->data_size;
|
||||
|
||||
} else {
|
||||
// Build superframe out of frames.
|
||||
|
||||
VP9RawSuperframeIndex sfi;
|
||||
PutBitContext pbc;
|
||||
AVBufferRef *ref;
|
||||
uint8_t *data;
|
||||
size_t size, max, pos;
|
||||
int i, size_len;
|
||||
|
||||
if (frag->nb_units > 8) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Too many frames to "
|
||||
"make superframe: %d.\n", frag->nb_units);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
max = 0;
|
||||
for (i = 0; i < frag->nb_units; i++)
|
||||
if (max < frag->units[i].data_size)
|
||||
max = frag->units[i].data_size;
|
||||
|
||||
if (max < 2)
|
||||
size_len = 1;
|
||||
else
|
||||
size_len = av_log2(max) / 8 + 1;
|
||||
av_assert0(size_len <= 4);
|
||||
|
||||
sfi.superframe_marker = VP9_SUPERFRAME_MARKER;
|
||||
sfi.bytes_per_framesize_minus_1 = size_len - 1;
|
||||
sfi.frames_in_superframe_minus_1 = frag->nb_units - 1;
|
||||
|
||||
size = 2;
|
||||
for (i = 0; i < frag->nb_units; i++) {
|
||||
size += size_len + frag->units[i].data_size;
|
||||
sfi.frame_sizes[i] = frag->units[i].data_size;
|
||||
}
|
||||
|
||||
ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!ref)
|
||||
return AVERROR(ENOMEM);
|
||||
data = ref->data;
|
||||
memset(data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
pos = 0;
|
||||
for (i = 0; i < frag->nb_units; i++) {
|
||||
av_assert0(size - pos > frag->units[i].data_size);
|
||||
memcpy(data + pos, frag->units[i].data,
|
||||
frag->units[i].data_size);
|
||||
pos += frag->units[i].data_size;
|
||||
}
|
||||
av_assert0(size - pos == 2 + frag->nb_units * size_len);
|
||||
|
||||
init_put_bits(&pbc, data + pos, size - pos);
|
||||
|
||||
err = cbs_vp9_write_superframe_index(ctx, &pbc, &sfi);
|
||||
if (err < 0) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write "
|
||||
"superframe index.\n");
|
||||
av_buffer_unref(&ref);
|
||||
return err;
|
||||
}
|
||||
|
||||
av_assert0(put_bits_left(&pbc) == 0);
|
||||
flush_put_bits(&pbc);
|
||||
|
||||
frag->data_ref = ref;
|
||||
frag->data = data;
|
||||
frag->data_size = size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cbs_vp9_close(CodedBitstreamContext *ctx)
|
||||
{
|
||||
CodedBitstreamVP9Context *priv = ctx->priv_data;
|
||||
|
||||
av_freep(&priv->write_buffer);
|
||||
}
|
||||
|
||||
const CodedBitstreamType ff_cbs_type_vp9 = {
|
||||
.codec_id = AV_CODEC_ID_VP9,
|
||||
|
||||
.priv_data_size = sizeof(CodedBitstreamVP9Context),
|
||||
|
||||
.split_fragment = &cbs_vp9_split_fragment,
|
||||
.read_unit = &cbs_vp9_read_unit,
|
||||
.write_unit = &cbs_vp9_write_unit,
|
||||
.assemble_fragment = &cbs_vp9_assemble_fragment,
|
||||
|
||||
.close = &cbs_vp9_close,
|
||||
};
|
||||
@@ -1,217 +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 AVCODEC_CBS_VP9_H
|
||||
#define AVCODEC_CBS_VP9_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cbs.h"
|
||||
|
||||
|
||||
// Miscellaneous constants (section 3).
|
||||
enum {
|
||||
VP9_REFS_PER_FRAME = 3,
|
||||
|
||||
VP9_MIN_TILE_WIDTH_B64 = 4,
|
||||
VP9_MAX_TILE_WIDTH_B64 = 64,
|
||||
|
||||
VP9_NUM_REF_FRAMES = 8,
|
||||
VP9_MAX_REF_FRAMES = 4,
|
||||
|
||||
VP9_MAX_SEGMENTS = 8,
|
||||
VP9_SEG_LVL_MAX = 4,
|
||||
};
|
||||
|
||||
// Frame types (section 7.2).
|
||||
enum {
|
||||
VP9_KEY_FRAME = 0,
|
||||
VP9_NON_KEY_FRAME = 1,
|
||||
};
|
||||
|
||||
// Frame sync bytes (section 7.2.1).
|
||||
enum {
|
||||
VP9_FRAME_SYNC_0 = 0x49,
|
||||
VP9_FRAME_SYNC_1 = 0x83,
|
||||
VP9_FRAME_SYNC_2 = 0x42,
|
||||
};
|
||||
|
||||
// Color space values (section 7.2.2).
|
||||
enum {
|
||||
VP9_CS_UNKNOWN = 0,
|
||||
VP9_CS_BT_601 = 1,
|
||||
VP9_CS_BT_709 = 2,
|
||||
VP9_CS_SMPTE_170 = 3,
|
||||
VP9_CS_SMPTE_240 = 4,
|
||||
VP9_CS_BT_2020 = 5,
|
||||
VP9_CS_RESERVED = 6,
|
||||
VP9_CS_RGB = 7,
|
||||
};
|
||||
|
||||
// Reference frame types (section 7.4.12).
|
||||
enum {
|
||||
VP9_INTRA_FRAME = 0,
|
||||
VP9_LAST_FRAME = 1,
|
||||
VP9_GOLDEN_FRAME = 2,
|
||||
VP9_ALTREF_FRAME = 3,
|
||||
};
|
||||
|
||||
// Superframe properties (section B.3).
|
||||
enum {
|
||||
VP9_MAX_FRAMES_IN_SUPERFRAME = 8,
|
||||
|
||||
VP9_SUPERFRAME_MARKER = 6,
|
||||
};
|
||||
|
||||
|
||||
typedef struct VP9RawFrameHeader {
|
||||
uint8_t frame_marker;
|
||||
uint8_t profile_low_bit;
|
||||
uint8_t profile_high_bit;
|
||||
|
||||
uint8_t show_existing_frame;
|
||||
uint8_t frame_to_show_map_idx;
|
||||
|
||||
uint8_t frame_type;
|
||||
uint8_t show_frame;
|
||||
uint8_t error_resilient_mode;
|
||||
|
||||
// Color config.
|
||||
uint8_t ten_or_twelve_bit;
|
||||
uint8_t color_space;
|
||||
uint8_t color_range;
|
||||
uint8_t subsampling_x;
|
||||
uint8_t subsampling_y;
|
||||
|
||||
uint8_t refresh_frame_flags;
|
||||
|
||||
uint8_t intra_only;
|
||||
uint8_t reset_frame_context;
|
||||
|
||||
uint8_t ref_frame_idx[VP9_REFS_PER_FRAME];
|
||||
uint8_t ref_frame_sign_bias[VP9_MAX_REF_FRAMES];
|
||||
|
||||
uint8_t allow_high_precision_mv;
|
||||
|
||||
uint8_t refresh_frame_context;
|
||||
uint8_t frame_parallel_decoding_mode;
|
||||
|
||||
uint8_t frame_context_idx;
|
||||
|
||||
// Frame/render size.
|
||||
uint8_t found_ref[VP9_REFS_PER_FRAME];
|
||||
uint16_t frame_width_minus_1;
|
||||
uint16_t frame_height_minus_1;
|
||||
uint8_t render_and_frame_size_different;
|
||||
uint16_t render_width_minus_1;
|
||||
uint16_t render_height_minus_1;
|
||||
|
||||
// Interpolation filter.
|
||||
uint8_t is_filter_switchable;
|
||||
uint8_t raw_interpolation_filter_type;
|
||||
|
||||
// Loop filter params.
|
||||
uint8_t loop_filter_level;
|
||||
uint8_t loop_filter_sharpness;
|
||||
uint8_t loop_filter_delta_enabled;
|
||||
uint8_t loop_filter_delta_update;
|
||||
uint8_t update_ref_delta[VP9_MAX_REF_FRAMES];
|
||||
int8_t loop_filter_ref_deltas[VP9_MAX_REF_FRAMES];
|
||||
uint8_t update_mode_delta[2];
|
||||
int8_t loop_filter_mode_deltas[2];
|
||||
|
||||
// Quantization params.
|
||||
uint8_t base_q_idx;
|
||||
int8_t delta_q_y_dc;
|
||||
int8_t delta_q_uv_dc;
|
||||
int8_t delta_q_uv_ac;
|
||||
|
||||
// Segmentation params.
|
||||
uint8_t segmentation_enabled;
|
||||
uint8_t segmentation_update_map;
|
||||
uint8_t segmentation_tree_probs[7];
|
||||
uint8_t segmentation_temporal_update;
|
||||
uint8_t segmentation_pred_prob[3];
|
||||
uint8_t segmentation_update_data;
|
||||
uint8_t segmentation_abs_or_delta_update;
|
||||
uint8_t feature_enabled[VP9_MAX_SEGMENTS][VP9_SEG_LVL_MAX];
|
||||
uint8_t feature_value[VP9_MAX_SEGMENTS][VP9_SEG_LVL_MAX];
|
||||
uint8_t feature_sign[VP9_MAX_SEGMENTS][VP9_SEG_LVL_MAX];
|
||||
|
||||
// Tile info.
|
||||
uint8_t tile_cols_log2;
|
||||
uint8_t tile_rows_log2;
|
||||
|
||||
uint16_t header_size_in_bytes;
|
||||
} VP9RawFrameHeader;
|
||||
|
||||
typedef struct VP9RawFrame {
|
||||
VP9RawFrameHeader header;
|
||||
|
||||
uint8_t *data;
|
||||
size_t data_size;
|
||||
AVBufferRef *data_ref;
|
||||
} VP9RawFrame;
|
||||
|
||||
typedef struct VP9RawSuperframeIndex {
|
||||
uint8_t superframe_marker;
|
||||
uint8_t bytes_per_framesize_minus_1;
|
||||
uint8_t frames_in_superframe_minus_1;
|
||||
uint32_t frame_sizes[VP9_MAX_FRAMES_IN_SUPERFRAME];
|
||||
} VP9RawSuperframeIndex;
|
||||
|
||||
typedef struct VP9RawSuperframe {
|
||||
VP9RawFrame frames[VP9_MAX_FRAMES_IN_SUPERFRAME];
|
||||
VP9RawSuperframeIndex index;
|
||||
} VP9RawSuperframe;
|
||||
|
||||
typedef struct VP9ReferenceFrameState {
|
||||
int frame_width; // RefFrameWidth
|
||||
int frame_height; // RefFrameHeight
|
||||
int subsampling_x; // RefSubsamplingX
|
||||
int subsampling_y; // RefSubsamplingY
|
||||
int bit_depth; // RefBitDepth
|
||||
} VP9ReferenceFrameState;
|
||||
|
||||
typedef struct CodedBitstreamVP9Context {
|
||||
int profile;
|
||||
|
||||
// Frame dimensions in 8x8 mode info blocks.
|
||||
uint16_t mi_cols;
|
||||
uint16_t mi_rows;
|
||||
// Frame dimensions in 64x64 superblocks.
|
||||
uint16_t sb64_cols;
|
||||
uint16_t sb64_rows;
|
||||
|
||||
int frame_width;
|
||||
int frame_height;
|
||||
|
||||
uint8_t subsampling_x;
|
||||
uint8_t subsampling_y;
|
||||
int bit_depth;
|
||||
|
||||
VP9ReferenceFrameState ref[VP9_NUM_REF_FRAMES];
|
||||
|
||||
// Write buffer.
|
||||
uint8_t *write_buffer;
|
||||
size_t write_buffer_size;
|
||||
} CodedBitstreamVP9Context;
|
||||
|
||||
|
||||
#endif /* AVCODEC_CBS_VP9_H */
|
||||
@@ -1,442 +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
|
||||
*/
|
||||
|
||||
static int FUNC(frame_sync_code)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
VP9RawFrameHeader *current)
|
||||
{
|
||||
uint8_t frame_sync_byte_0 = VP9_FRAME_SYNC_0;
|
||||
uint8_t frame_sync_byte_1 = VP9_FRAME_SYNC_1;
|
||||
uint8_t frame_sync_byte_2 = VP9_FRAME_SYNC_2;
|
||||
int err;
|
||||
|
||||
xf(8, frame_sync_byte_0, frame_sync_byte_0, 0);
|
||||
xf(8, frame_sync_byte_1, frame_sync_byte_1, 0);
|
||||
xf(8, frame_sync_byte_2, frame_sync_byte_2, 0);
|
||||
|
||||
if (frame_sync_byte_0 != VP9_FRAME_SYNC_0 ||
|
||||
frame_sync_byte_1 != VP9_FRAME_SYNC_1 ||
|
||||
frame_sync_byte_2 != VP9_FRAME_SYNC_2) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid frame sync code: "
|
||||
"%02x %02x %02x.\n", frame_sync_byte_0,
|
||||
frame_sync_byte_1, frame_sync_byte_2);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(color_config)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
VP9RawFrameHeader *current, int profile)
|
||||
{
|
||||
CodedBitstreamVP9Context *vp9 = ctx->priv_data;
|
||||
int err;
|
||||
|
||||
if (profile >= 2) {
|
||||
f(1, ten_or_twelve_bit);
|
||||
vp9->bit_depth = current->ten_or_twelve_bit ? 12 : 10;
|
||||
} else
|
||||
vp9->bit_depth = 8;
|
||||
|
||||
f(3, color_space);
|
||||
|
||||
if (current->color_space != VP9_CS_RGB) {
|
||||
f(1, color_range);
|
||||
if (profile == 1 || profile == 3) {
|
||||
f(1, subsampling_x);
|
||||
f(1, subsampling_y);
|
||||
fixed(1, reserved_zero, 0);
|
||||
} else {
|
||||
infer(subsampling_x, 1);
|
||||
infer(subsampling_y, 1);
|
||||
}
|
||||
} else {
|
||||
infer(color_range, 1);
|
||||
if (profile == 1 || profile == 3) {
|
||||
infer(subsampling_x, 0);
|
||||
infer(subsampling_y, 0);
|
||||
fixed(1, reserved_zero, 0);
|
||||
}
|
||||
}
|
||||
|
||||
vp9->subsampling_x = current->subsampling_x;
|
||||
vp9->subsampling_y = current->subsampling_y;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(frame_size)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
VP9RawFrameHeader *current)
|
||||
{
|
||||
CodedBitstreamVP9Context *vp9 = ctx->priv_data;
|
||||
int err;
|
||||
|
||||
f(16, frame_width_minus_1);
|
||||
f(16, frame_height_minus_1);
|
||||
|
||||
vp9->frame_width = current->frame_width_minus_1 + 1;
|
||||
vp9->frame_height = current->frame_height_minus_1 + 1;
|
||||
|
||||
vp9->mi_cols = (vp9->frame_width + 7) >> 3;
|
||||
vp9->mi_rows = (vp9->frame_height + 7) >> 3;
|
||||
vp9->sb64_cols = (vp9->mi_cols + 7) >> 3;
|
||||
vp9->sb64_rows = (vp9->mi_rows + 7) >> 3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(render_size)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
VP9RawFrameHeader *current)
|
||||
{
|
||||
int err;
|
||||
|
||||
f(1, render_and_frame_size_different);
|
||||
|
||||
if (current->render_and_frame_size_different) {
|
||||
f(16, render_width_minus_1);
|
||||
f(16, render_height_minus_1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(frame_size_with_refs)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
VP9RawFrameHeader *current)
|
||||
{
|
||||
CodedBitstreamVP9Context *vp9 = ctx->priv_data;
|
||||
int err, i;
|
||||
|
||||
for (i = 0; i < VP9_REFS_PER_FRAME; i++) {
|
||||
fs(1, found_ref[i], 1, i);
|
||||
if (current->found_ref[i]) {
|
||||
VP9ReferenceFrameState *ref =
|
||||
&vp9->ref[current->ref_frame_idx[i]];
|
||||
|
||||
vp9->frame_width = ref->frame_width;
|
||||
vp9->frame_height = ref->frame_height;
|
||||
|
||||
vp9->subsampling_x = ref->subsampling_x;
|
||||
vp9->subsampling_y = ref->subsampling_y;
|
||||
vp9->bit_depth = ref->bit_depth;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= VP9_REFS_PER_FRAME)
|
||||
CHECK(FUNC(frame_size)(ctx, rw, current));
|
||||
else {
|
||||
vp9->mi_cols = (vp9->frame_width + 7) >> 3;
|
||||
vp9->mi_rows = (vp9->frame_height + 7) >> 3;
|
||||
vp9->sb64_cols = (vp9->mi_cols + 7) >> 3;
|
||||
vp9->sb64_rows = (vp9->mi_rows + 7) >> 3;
|
||||
}
|
||||
CHECK(FUNC(render_size)(ctx, rw, current));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(interpolation_filter)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
VP9RawFrameHeader *current)
|
||||
{
|
||||
int err;
|
||||
|
||||
f(1, is_filter_switchable);
|
||||
if (!current->is_filter_switchable)
|
||||
f(2, raw_interpolation_filter_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(loop_filter_params)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
VP9RawFrameHeader *current)
|
||||
{
|
||||
int err, i;
|
||||
|
||||
f(6, loop_filter_level);
|
||||
f(3, loop_filter_sharpness);
|
||||
|
||||
f(1, loop_filter_delta_enabled);
|
||||
if (current->loop_filter_delta_enabled) {
|
||||
f(1, loop_filter_delta_update);
|
||||
if (current->loop_filter_delta_update) {
|
||||
for (i = 0; i < VP9_MAX_REF_FRAMES; i++) {
|
||||
fs(1, update_ref_delta[i], 1, i);
|
||||
if (current->update_ref_delta[i])
|
||||
ss(6, loop_filter_ref_deltas[i], 1, i);
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
fs(1, update_mode_delta[i], 1, i);
|
||||
if (current->update_mode_delta[i])
|
||||
ss(6, loop_filter_mode_deltas[i], 1, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(quantization_params)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
VP9RawFrameHeader *current)
|
||||
{
|
||||
int err;
|
||||
|
||||
f(8, base_q_idx);
|
||||
|
||||
delta_q(delta_q_y_dc);
|
||||
delta_q(delta_q_uv_dc);
|
||||
delta_q(delta_q_uv_ac);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
VP9RawFrameHeader *current)
|
||||
{
|
||||
static const int segmentation_feature_bits[VP9_SEG_LVL_MAX] = { 8, 6, 2, 0 };
|
||||
static const int segmentation_feature_signed[VP9_SEG_LVL_MAX] = { 1, 1, 0, 0 };
|
||||
|
||||
int err, i, j;
|
||||
|
||||
f(1, segmentation_enabled);
|
||||
|
||||
if (current->segmentation_enabled) {
|
||||
f(1, segmentation_update_map);
|
||||
if (current->segmentation_update_map) {
|
||||
for (i = 0; i < 7; i++)
|
||||
prob(segmentation_tree_probs[i], 1, i);
|
||||
f(1, segmentation_temporal_update);
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (current->segmentation_temporal_update)
|
||||
prob(segmentation_pred_prob[i], 1, i);
|
||||
else
|
||||
infer(segmentation_pred_prob[i], 255);
|
||||
}
|
||||
}
|
||||
|
||||
f(1, segmentation_update_data);
|
||||
if (current->segmentation_update_data) {
|
||||
f(1, segmentation_abs_or_delta_update);
|
||||
for (i = 0; i < VP9_MAX_SEGMENTS; i++) {
|
||||
for (j = 0; j < VP9_SEG_LVL_MAX; j++) {
|
||||
fs(1, feature_enabled[i][j], 2, i, j);
|
||||
if (current->feature_enabled[i][j] &&
|
||||
segmentation_feature_bits[j]) {
|
||||
fs(segmentation_feature_bits[j],
|
||||
feature_value[i][j], 2, i, j);
|
||||
if (segmentation_feature_signed[j])
|
||||
fs(1, feature_sign[i][j], 2, i, j);
|
||||
else
|
||||
infer(feature_sign[i][j], 0);
|
||||
} else {
|
||||
infer(feature_value[i][j], 0);
|
||||
infer(feature_sign[i][j], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(tile_info)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
VP9RawFrameHeader *current)
|
||||
{
|
||||
CodedBitstreamVP9Context *vp9 = ctx->priv_data;
|
||||
int min_log2_tile_cols, max_log2_tile_cols;
|
||||
int err;
|
||||
|
||||
min_log2_tile_cols = 0;
|
||||
while ((VP9_MAX_TILE_WIDTH_B64 << min_log2_tile_cols) < vp9->sb64_cols)
|
||||
++min_log2_tile_cols;
|
||||
max_log2_tile_cols = 0;
|
||||
while ((vp9->sb64_cols >> (max_log2_tile_cols + 1)) >= VP9_MIN_TILE_WIDTH_B64)
|
||||
++max_log2_tile_cols;
|
||||
|
||||
increment(tile_cols_log2, min_log2_tile_cols, max_log2_tile_cols);
|
||||
|
||||
increment(tile_rows_log2, 0, 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
VP9RawFrameHeader *current)
|
||||
{
|
||||
CodedBitstreamVP9Context *vp9 = ctx->priv_data;
|
||||
int err, i;
|
||||
|
||||
f(2, frame_marker);
|
||||
|
||||
f(1, profile_low_bit);
|
||||
f(1, profile_high_bit);
|
||||
vp9->profile = (current->profile_high_bit << 1) + current->profile_low_bit;
|
||||
if (vp9->profile == 3)
|
||||
fixed(1, reserved_zero, 0);
|
||||
|
||||
f(1, show_existing_frame);
|
||||
if (current->show_existing_frame) {
|
||||
f(3, frame_to_show_map_idx);
|
||||
infer(header_size_in_bytes, 0);
|
||||
infer(refresh_frame_flags, 0x00);
|
||||
infer(loop_filter_level, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
f(1, frame_type);
|
||||
f(1, show_frame);
|
||||
f(1, error_resilient_mode);
|
||||
|
||||
if (current->frame_type == VP9_KEY_FRAME) {
|
||||
CHECK(FUNC(frame_sync_code)(ctx, rw, current));
|
||||
CHECK(FUNC(color_config)(ctx, rw, current, vp9->profile));
|
||||
CHECK(FUNC(frame_size)(ctx, rw, current));
|
||||
CHECK(FUNC(render_size)(ctx, rw, current));
|
||||
|
||||
infer(refresh_frame_flags, 0xff);
|
||||
|
||||
} else {
|
||||
if (current->show_frame == 0)
|
||||
f(1, intra_only);
|
||||
else
|
||||
infer(intra_only, 0);
|
||||
|
||||
if (current->error_resilient_mode == 0)
|
||||
f(2, reset_frame_context);
|
||||
else
|
||||
infer(reset_frame_context, 0);
|
||||
|
||||
if (current->intra_only == 1) {
|
||||
CHECK(FUNC(frame_sync_code)(ctx, rw, current));
|
||||
|
||||
if (vp9->profile > 0) {
|
||||
CHECK(FUNC(color_config)(ctx, rw, current, vp9->profile));
|
||||
} else {
|
||||
infer(color_space, 1);
|
||||
infer(subsampling_x, 1);
|
||||
infer(subsampling_y, 1);
|
||||
vp9->bit_depth = 8;
|
||||
|
||||
vp9->subsampling_x = current->subsampling_x;
|
||||
vp9->subsampling_y = current->subsampling_y;
|
||||
}
|
||||
|
||||
f(8, refresh_frame_flags);
|
||||
|
||||
CHECK(FUNC(frame_size)(ctx, rw, current));
|
||||
CHECK(FUNC(render_size)(ctx, rw, current));
|
||||
} else {
|
||||
f(8, refresh_frame_flags);
|
||||
|
||||
for (i = 0; i < VP9_REFS_PER_FRAME; i++) {
|
||||
fs(3, ref_frame_idx[i], 1, i);
|
||||
fs(1, ref_frame_sign_bias[VP9_LAST_FRAME + i],
|
||||
1, VP9_LAST_FRAME + i);
|
||||
}
|
||||
|
||||
CHECK(FUNC(frame_size_with_refs)(ctx, rw, current));
|
||||
f(1, allow_high_precision_mv);
|
||||
CHECK(FUNC(interpolation_filter)(ctx, rw, current));
|
||||
}
|
||||
}
|
||||
|
||||
if (current->error_resilient_mode == 0) {
|
||||
f(1, refresh_frame_context);
|
||||
f(1, frame_parallel_decoding_mode);
|
||||
} else {
|
||||
infer(refresh_frame_context, 0);
|
||||
infer(frame_parallel_decoding_mode, 1);
|
||||
}
|
||||
|
||||
f(2, frame_context_idx);
|
||||
|
||||
CHECK(FUNC(loop_filter_params)(ctx, rw, current));
|
||||
CHECK(FUNC(quantization_params)(ctx, rw, current));
|
||||
CHECK(FUNC(segmentation_params)(ctx, rw, current));
|
||||
CHECK(FUNC(tile_info)(ctx, rw, current));
|
||||
|
||||
f(16, header_size_in_bytes);
|
||||
|
||||
for (i = 0; i < VP9_NUM_REF_FRAMES; i++) {
|
||||
if (current->refresh_frame_flags & (1 << i)) {
|
||||
vp9->ref[i] = (VP9ReferenceFrameState) {
|
||||
.frame_width = vp9->frame_width,
|
||||
.frame_height = vp9->frame_height,
|
||||
.subsampling_x = vp9->subsampling_x,
|
||||
.subsampling_y = vp9->subsampling_y,
|
||||
.bit_depth = vp9->bit_depth,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
av_log(ctx->log_ctx, AV_LOG_DEBUG, "Frame: size %dx%d "
|
||||
"subsample %dx%d bit_depth %d tiles %dx%d.\n",
|
||||
vp9->frame_width, vp9->frame_height,
|
||||
vp9->subsampling_x, vp9->subsampling_y,
|
||||
vp9->bit_depth, 1 << current->tile_cols_log2,
|
||||
1 << current->tile_rows_log2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(trailing_bits)(CodedBitstreamContext *ctx, RWContext *rw)
|
||||
{
|
||||
int err;
|
||||
av_unused int zero = 0;
|
||||
while (byte_alignment(rw) != 0)
|
||||
xf(1, zero_bit, zero, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(frame)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
VP9RawFrame *current)
|
||||
{
|
||||
int err;
|
||||
|
||||
HEADER("Frame");
|
||||
|
||||
CHECK(FUNC(uncompressed_header)(ctx, rw, ¤t->header));
|
||||
|
||||
CHECK(FUNC(trailing_bits)(ctx, rw));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(superframe_index)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
VP9RawSuperframeIndex *current)
|
||||
{
|
||||
int err, i;
|
||||
|
||||
HEADER("Superframe Index");
|
||||
|
||||
f(3, superframe_marker);
|
||||
f(2, bytes_per_framesize_minus_1);
|
||||
f(3, frames_in_superframe_minus_1);
|
||||
|
||||
for (i = 0; i <= current->frames_in_superframe_minus_1; i++) {
|
||||
// Surprise little-endian!
|
||||
fle(8 * (current->bytes_per_framesize_minus_1 + 1),
|
||||
frame_sizes[i], 1, i);
|
||||
}
|
||||
|
||||
f(3, superframe_marker);
|
||||
f(2, bytes_per_framesize_minus_1);
|
||||
f(3, frames_in_superframe_minus_1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -69,7 +69,6 @@ typedef struct CDGraphicsContext {
|
||||
int hscroll;
|
||||
int vscroll;
|
||||
int transparency;
|
||||
int cleared;
|
||||
} CDGraphicsContext;
|
||||
|
||||
static av_cold int cdg_decode_init(AVCodecContext *avctx)
|
||||
@@ -81,11 +80,8 @@ static av_cold int cdg_decode_init(AVCodecContext *avctx)
|
||||
return AVERROR(ENOMEM);
|
||||
cc->transparency = -1;
|
||||
|
||||
avctx->width = CDG_FULL_WIDTH;
|
||||
avctx->height = CDG_FULL_HEIGHT;
|
||||
avctx->pix_fmt = AV_PIX_FMT_PAL8;
|
||||
|
||||
return 0;
|
||||
return ff_set_dimensions(avctx, CDG_FULL_WIDTH, CDG_FULL_HEIGHT);
|
||||
}
|
||||
|
||||
static void cdg_border_preset(CDGraphicsContext *cc, uint8_t *data)
|
||||
@@ -288,10 +284,9 @@ static int cdg_decode_frame(AVCodecContext *avctx,
|
||||
|
||||
if ((ret = ff_reget_buffer(avctx, cc->frame)) < 0)
|
||||
return ret;
|
||||
if (!cc->cleared) {
|
||||
if (!avctx->frame_number) {
|
||||
memset(cc->frame->data[0], 0, cc->frame->linesize[0] * avctx->height);
|
||||
memset(cc->frame->data[1], 0, AVPALETTE_SIZE);
|
||||
cc->cleared = 1;
|
||||
}
|
||||
|
||||
command = bytestream2_get_byte(&gb);
|
||||
|
||||
@@ -49,15 +49,12 @@ enum CFHDParam {
|
||||
SubbandNumber = 48,
|
||||
Quantization = 53,
|
||||
ChannelNumber = 62,
|
||||
SampleFlags = 68,
|
||||
BitsPerComponent = 101,
|
||||
ChannelWidth = 104,
|
||||
ChannelHeight = 105,
|
||||
PrescaleShift = 109,
|
||||
};
|
||||
|
||||
|
||||
|
||||
static av_cold int cfhd_init(AVCodecContext *avctx)
|
||||
{
|
||||
CFHDContext *s = avctx->priv_data;
|
||||
@@ -75,13 +72,6 @@ static void init_plane_defaults(CFHDContext *s)
|
||||
s->subband_num_actual = 0;
|
||||
}
|
||||
|
||||
static void init_peak_table_defaults(CFHDContext *s)
|
||||
{
|
||||
s->peak.level = 0;
|
||||
s->peak.offset = 0;
|
||||
memset(&s->peak.base, 0, sizeof(s->peak.base));
|
||||
}
|
||||
|
||||
static void init_frame_defaults(CFHDContext *s)
|
||||
{
|
||||
s->coded_width = 0;
|
||||
@@ -96,44 +86,15 @@ static void init_frame_defaults(CFHDContext *s)
|
||||
s->wavelet_depth = 3;
|
||||
s->pshift = 1;
|
||||
s->codebook = 0;
|
||||
s->difference_coding = 0;
|
||||
s->progressive = 0;
|
||||
init_plane_defaults(s);
|
||||
init_peak_table_defaults(s);
|
||||
}
|
||||
|
||||
/* TODO: merge with VLC tables or use LUT */
|
||||
static inline int dequant_and_decompand(int level, int quantisation, int codebook)
|
||||
static inline int dequant_and_decompand(int level, int quantisation)
|
||||
{
|
||||
if (codebook == 0 || codebook == 1) {
|
||||
int64_t abslevel = abs(level);
|
||||
if (level < 264)
|
||||
return (abslevel + ((768 * abslevel * abslevel * abslevel) / (255 * 255 * 255))) *
|
||||
FFSIGN(level) * quantisation;
|
||||
else
|
||||
return level * quantisation;
|
||||
} else
|
||||
return level * quantisation;
|
||||
}
|
||||
|
||||
static inline void difference_coding(int16_t *band, int width, int height)
|
||||
{
|
||||
|
||||
int i,j;
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 1; j < width; j++) {
|
||||
band[j] += band[j-1];
|
||||
}
|
||||
band += width;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void peak_table(int16_t *band, Peak *peak, int length)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < length; i++)
|
||||
if (abs(band[i]) > peak->level)
|
||||
band[i] = bytestream2_get_le16(&peak->base);
|
||||
int64_t abslevel = abs(level);
|
||||
return (abslevel + ((768 * abslevel * abslevel * abslevel) / (255 * 255 * 255))) *
|
||||
FFSIGN(level) * quantisation;
|
||||
}
|
||||
|
||||
static inline void process_alpha(int16_t *alpha, int width)
|
||||
@@ -193,18 +154,6 @@ static inline void filter(int16_t *output, ptrdiff_t out_stride,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void interlaced_vertical_filter(int16_t *output, int16_t *low, int16_t *high,
|
||||
int width, int linesize, int plane)
|
||||
{
|
||||
int i;
|
||||
int16_t even, odd;
|
||||
for (i = 0; i < width; i++) {
|
||||
even = (low[i] - high[i])/2;
|
||||
odd = (low[i] + high[i])/2;
|
||||
output[i] = av_clip_uintp2(even, 10);
|
||||
output[i + linesize] = av_clip_uintp2(odd, 10);
|
||||
}
|
||||
}
|
||||
static void horiz_filter(int16_t *output, int16_t *low, int16_t *high,
|
||||
int width)
|
||||
{
|
||||
@@ -346,9 +295,6 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
|
||||
uint16_t data = bytestream2_get_be16(&gb);
|
||||
if (abs_tag8 >= 0x60 && abs_tag8 <= 0x6f) {
|
||||
av_log(avctx, AV_LOG_DEBUG, "large len %x\n", ((tagu & 0xff) << 16) | data);
|
||||
} else if (tag == SampleFlags) {
|
||||
av_log(avctx, AV_LOG_DEBUG, "Progressive?%"PRIu16"\n", data);
|
||||
s->progressive = data & 0x0001;
|
||||
} else if (tag == ImageWidth) {
|
||||
av_log(avctx, AV_LOG_DEBUG, "Width %"PRIu16"\n", data);
|
||||
s->coded_width = data;
|
||||
@@ -447,8 +393,6 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
|
||||
}
|
||||
av_log(avctx, AV_LOG_DEBUG, "Transform-type? %"PRIu16"\n", data);
|
||||
} else if (abstag >= 0x4000 && abstag <= 0x40ff) {
|
||||
if (abstag == 0x4001)
|
||||
s->peak.level = 0;
|
||||
av_log(avctx, AV_LOG_DEBUG, "Small chunk length %d %s\n", data * 4, tag < 0 ? "optional" : "required");
|
||||
bytestream2_skipu(&gb, data * 4);
|
||||
} else if (tag == 23) {
|
||||
@@ -506,8 +450,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
|
||||
s->codebook = data;
|
||||
av_log(avctx, AV_LOG_DEBUG, "Codebook %i\n", s->codebook);
|
||||
} else if (tag == 72) {
|
||||
s->codebook = data & 0xf;
|
||||
s->difference_coding = (data >> 4) & 1;
|
||||
s->codebook = data;
|
||||
av_log(avctx, AV_LOG_DEBUG, "Other codebook? %i\n", s->codebook);
|
||||
} else if (tag == 70) {
|
||||
av_log(avctx, AV_LOG_DEBUG, "Subsampling or bit-depth flag? %i\n", data);
|
||||
@@ -534,19 +477,6 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
|
||||
} else if (tag == -85) {
|
||||
av_log(avctx, AV_LOG_DEBUG, "Cropped height %"PRIu16"\n", data);
|
||||
s->cropped_height = data;
|
||||
} else if (tag == -75) {
|
||||
s->peak.offset &= ~0xffff;
|
||||
s->peak.offset |= (data & 0xffff);
|
||||
s->peak.base = gb;
|
||||
s->peak.level = 0;
|
||||
} else if (tag == -76) {
|
||||
s->peak.offset &= 0xffff;
|
||||
s->peak.offset |= (data & 0xffffU)<<16;
|
||||
s->peak.base = gb;
|
||||
s->peak.level = 0;
|
||||
} else if (tag == -74 && s->peak.offset) {
|
||||
s->peak.level = data;
|
||||
bytestream2_seek(&s->peak.base, s->peak.offset - 4, SEEK_CUR);
|
||||
} else
|
||||
av_log(avctx, AV_LOG_DEBUG, "Unknown tag %i data %x\n", tag, data);
|
||||
|
||||
@@ -664,7 +594,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
|
||||
if (count > expected)
|
||||
break;
|
||||
|
||||
coeff = dequant_and_decompand(level, s->quantisation, 0);
|
||||
coeff = dequant_and_decompand(level, s->quantisation);
|
||||
for (i = 0; i < run; i++)
|
||||
*coeff_data++ = coeff;
|
||||
}
|
||||
@@ -683,7 +613,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
|
||||
if (count > expected)
|
||||
break;
|
||||
|
||||
coeff = dequant_and_decompand(level, s->quantisation, s->codebook);
|
||||
coeff = dequant_and_decompand(level, s->quantisation);
|
||||
for (i = 0; i < run; i++)
|
||||
*coeff_data++ = coeff;
|
||||
}
|
||||
@@ -696,12 +626,8 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
|
||||
ret = AVERROR(EINVAL);
|
||||
goto end;
|
||||
}
|
||||
if (s->peak.level)
|
||||
peak_table(coeff_data - count, &s->peak, count);
|
||||
if (s->difference_coding)
|
||||
difference_coding(s->plane[s->channel_num].subband[s->subband_num_actual], highpass_width, highpass_height);
|
||||
|
||||
bytes = FFALIGN(AV_CEIL_RSHIFT(get_bits_count(&s->gb), 3), 4);
|
||||
bytes = FFALIGN(FF_CEIL_RSHIFT(get_bits_count(&s->gb), 3), 4);
|
||||
if (bytes > bytestream2_get_bytes_left(&gb)) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Bitstream overread error\n");
|
||||
ret = AVERROR(EINVAL);
|
||||
@@ -858,68 +784,37 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
|
||||
}
|
||||
|
||||
av_log(avctx, AV_LOG_DEBUG, "Level 3 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride);
|
||||
if (s->progressive) {
|
||||
low = s->plane[plane].subband[0];
|
||||
high = s->plane[plane].subband[8];
|
||||
output = s->plane[plane].l_h[6];
|
||||
for (i = 0; i < lowpass_width; i++) {
|
||||
vert_filter(output, lowpass_width, low, lowpass_width, high, highpass_stride, lowpass_height);
|
||||
low++;
|
||||
high++;
|
||||
output++;
|
||||
}
|
||||
|
||||
low = s->plane[plane].subband[7];
|
||||
high = s->plane[plane].subband[9];
|
||||
output = s->plane[plane].l_h[7];
|
||||
for (i = 0; i < lowpass_width; i++) {
|
||||
vert_filter(output, lowpass_width, low, highpass_stride, high, highpass_stride, lowpass_height);
|
||||
low++;
|
||||
high++;
|
||||
output++;
|
||||
}
|
||||
low = s->plane[plane].subband[0];
|
||||
high = s->plane[plane].subband[8];
|
||||
output = s->plane[plane].l_h[6];
|
||||
for (i = 0; i < lowpass_width; i++) {
|
||||
vert_filter(output, lowpass_width, low, lowpass_width, high, highpass_stride, lowpass_height);
|
||||
low++;
|
||||
high++;
|
||||
output++;
|
||||
}
|
||||
|
||||
dst = (int16_t *)pic->data[act_plane];
|
||||
low = s->plane[plane].l_h[6];
|
||||
high = s->plane[plane].l_h[7];
|
||||
for (i = 0; i < lowpass_height * 2; i++) {
|
||||
horiz_filter_clip(dst, low, high, lowpass_width, s->bpc);
|
||||
low += lowpass_width;
|
||||
high += lowpass_width;
|
||||
dst += pic->linesize[act_plane] / 2;
|
||||
}
|
||||
} else {
|
||||
av_log(avctx, AV_LOG_DEBUG, "interlaced frame ? %d", pic->interlaced_frame);
|
||||
pic->interlaced_frame = 1;
|
||||
low = s->plane[plane].subband[0];
|
||||
high = s->plane[plane].subband[7];
|
||||
output = s->plane[plane].l_h[6];
|
||||
for (i = 0; i < lowpass_height; i++) {
|
||||
horiz_filter(output, low, high, lowpass_width);
|
||||
low += lowpass_width;
|
||||
high += lowpass_width;
|
||||
output += lowpass_width * 2;
|
||||
}
|
||||
low = s->plane[plane].subband[7];
|
||||
high = s->plane[plane].subband[9];
|
||||
output = s->plane[plane].l_h[7];
|
||||
for (i = 0; i < lowpass_width; i++) {
|
||||
vert_filter(output, lowpass_width, low, highpass_stride, high, highpass_stride, lowpass_height);
|
||||
low++;
|
||||
high++;
|
||||
output++;
|
||||
}
|
||||
|
||||
low = s->plane[plane].subband[8];
|
||||
high = s->plane[plane].subband[9];
|
||||
output = s->plane[plane].l_h[7];
|
||||
for (i = 0; i < lowpass_height; i++) {
|
||||
horiz_filter(output, low, high, lowpass_width);
|
||||
low += lowpass_width;
|
||||
high += lowpass_width;
|
||||
output += lowpass_width * 2;
|
||||
}
|
||||
|
||||
dst = (int16_t *)pic->data[act_plane];
|
||||
low = s->plane[plane].l_h[6];
|
||||
high = s->plane[plane].l_h[7];
|
||||
for (i = 0; i < lowpass_height; i++) {
|
||||
interlaced_vertical_filter(dst, low, high, lowpass_width * 2, pic->linesize[act_plane]/2, act_plane);
|
||||
low += lowpass_width * 2;
|
||||
high += lowpass_width * 2;
|
||||
dst += pic->linesize[act_plane];
|
||||
}
|
||||
dst = (int16_t *)pic->data[act_plane];
|
||||
low = s->plane[plane].l_h[6];
|
||||
high = s->plane[plane].l_h[7];
|
||||
for (i = 0; i < lowpass_height * 2; i++) {
|
||||
horiz_filter_clip(dst, low, high, lowpass_width, s->bpc);
|
||||
if (act_plane == 3)
|
||||
process_alpha(dst, lowpass_width * 2);
|
||||
low += lowpass_width;
|
||||
high += lowpass_width;
|
||||
dst += pic->linesize[act_plane] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "libavutil/avassert.h"
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "bytestream.h"
|
||||
#include "get_bits.h"
|
||||
#include "vlc.h"
|
||||
|
||||
@@ -69,12 +68,6 @@ typedef struct Plane {
|
||||
SubBand band[DWT_LEVELS][4];
|
||||
} Plane;
|
||||
|
||||
typedef struct Peak {
|
||||
int level;
|
||||
int offset;
|
||||
GetByteContext base;
|
||||
} Peak;
|
||||
|
||||
typedef struct CFHDContext {
|
||||
AVCodecContext *avctx;
|
||||
|
||||
@@ -90,7 +83,6 @@ typedef struct CFHDContext {
|
||||
int coded_height;
|
||||
int cropped_height;
|
||||
enum AVPixelFormat coded_format;
|
||||
int progressive;
|
||||
|
||||
int a_width;
|
||||
int a_height;
|
||||
@@ -106,14 +98,12 @@ typedef struct CFHDContext {
|
||||
int pshift;
|
||||
|
||||
int codebook;
|
||||
int difference_coding;
|
||||
int subband_num;
|
||||
int level;
|
||||
int subband_num_actual;
|
||||
|
||||
uint8_t prescale_shift[3];
|
||||
Plane plane[4];
|
||||
Peak peak;
|
||||
} CFHDContext;
|
||||
|
||||
int ff_cfhd_init_vlcs(CFHDContext *s);
|
||||
|
||||
@@ -516,8 +516,11 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data,
|
||||
frame_type = bytestream2_get_byte(&gb);
|
||||
|
||||
if ((frame_type & 0x7f) == 0x30) {
|
||||
*got_frame = 0;
|
||||
return buf_size;
|
||||
if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)
|
||||
return ret;
|
||||
|
||||
c->pic->key_frame = 0;
|
||||
c->pic->pict_type = AV_PICTURE_TYPE_P;
|
||||
} else if (frame_type & 0x2) {
|
||||
if (buf_size < c->mb_width * c->mb_height) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Packet too small\n");
|
||||
@@ -555,6 +558,9 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data,
|
||||
} else {
|
||||
int plane;
|
||||
|
||||
if (c->pmb_width * c->pmb_height > 8LL*(buf_size - bytestream2_tell(&gb)))
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)
|
||||
return ret;
|
||||
|
||||
@@ -570,6 +576,8 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data,
|
||||
|
||||
for (j = 0; j < c->pmb_height; j++) {
|
||||
for (i = 0; i < c->pmb_width; i++) {
|
||||
if (get_bits_left(&c->gb) <= 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
if (get_bits1(&c->gb)) {
|
||||
MV mv = mvi_predict(&c->mvi, i, j, zero_mv);
|
||||
|
||||
@@ -637,9 +645,6 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data,
|
||||
|
||||
*got_frame = 1;
|
||||
|
||||
if (get_bits_left(&c->gb) < 0)
|
||||
av_log(c->avctx, AV_LOG_WARNING, "overread %d\n", -get_bits_left(&c->gb));
|
||||
|
||||
return mb_ret < 0 ? mb_ret : buf_size;
|
||||
}
|
||||
|
||||
|
||||
@@ -1394,13 +1394,6 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
||||
.long_name = NULL_IF_CONFIG_SMALL("innoHeim/Rsupport Screen Capture Codec"),
|
||||
.props = AV_CODEC_PROP_LOSSLESS,
|
||||
},
|
||||
{
|
||||
.id = AV_CODEC_ID_AVS2,
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.name = "avs2",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("AVS2-P2/IEEE1857.4"),
|
||||
.props = AV_CODEC_PROP_LOSSY,
|
||||
},
|
||||
{
|
||||
.id = AV_CODEC_ID_Y41P,
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
@@ -1523,7 +1516,7 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.name = "truemotion2rt",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0 Real Time"),
|
||||
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
|
||||
.props = AV_CODEC_PROP_LOSSY,
|
||||
},
|
||||
{
|
||||
.id = AV_CODEC_ID_M101,
|
||||
@@ -1654,41 +1647,6 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
||||
.long_name = NULL_IF_CONFIG_SMALL("FITS (Flexible Image Transport System)"),
|
||||
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
|
||||
},
|
||||
{
|
||||
.id = AV_CODEC_ID_IMM4,
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.name = "imm4",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
|
||||
.props = AV_CODEC_PROP_LOSSY,
|
||||
},
|
||||
{
|
||||
.id = AV_CODEC_ID_PROSUMER,
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.name = "prosumer",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Brooktree ProSumer Video"),
|
||||
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
|
||||
},
|
||||
{
|
||||
.id = AV_CODEC_ID_MWSC,
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.name = "mwsc",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("MatchWare Screen Capture Codec"),
|
||||
.props = AV_CODEC_PROP_LOSSLESS,
|
||||
},
|
||||
{
|
||||
.id = AV_CODEC_ID_WCMV,
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.name = "wcmv",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("WinCAM Motion Video"),
|
||||
.props = AV_CODEC_PROP_LOSSLESS,
|
||||
},
|
||||
{
|
||||
.id = AV_CODEC_ID_RASC,
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.name = "rasc",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("RemotelyAnywhere Screen Capture"),
|
||||
.props = AV_CODEC_PROP_LOSSY,
|
||||
},
|
||||
|
||||
/* various PCM "codecs" */
|
||||
{
|
||||
@@ -1936,13 +1894,6 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
||||
.long_name = NULL_IF_CONFIG_SMALL("PCM 24.0 floating point little-endian"),
|
||||
.props = AV_CODEC_PROP_LOSSLESS,
|
||||
},
|
||||
{
|
||||
.id = AV_CODEC_ID_PCM_VIDC,
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.name = "pcm_vidc",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("PCM Archimedes VIDC"),
|
||||
.props = AV_CODEC_PROP_LOSSY,
|
||||
},
|
||||
|
||||
/* various ADPCM codecs */
|
||||
{
|
||||
@@ -2927,13 +2878,6 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
||||
.long_name = NULL_IF_CONFIG_SMALL("SBC (low-complexity subband codec)"),
|
||||
.props = AV_CODEC_PROP_LOSSY,
|
||||
},
|
||||
{
|
||||
.id = AV_CODEC_ID_ATRAC9,
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.name = "atrac9",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("ATRAC9 (Adaptive TRansform Acoustic Coding 9)"),
|
||||
.props = AV_CODEC_PROP_LOSSY,
|
||||
},
|
||||
|
||||
/* subtitle codecs */
|
||||
{
|
||||
@@ -3103,14 +3047,6 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
||||
.long_name = NULL_IF_CONFIG_SMALL("HDMV Text subtitle"),
|
||||
.props = AV_CODEC_PROP_TEXT_SUB,
|
||||
},
|
||||
{
|
||||
.id = AV_CODEC_ID_TTML,
|
||||
.type = AVMEDIA_TYPE_SUBTITLE,
|
||||
.name = "ttml",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Timed Text Markup Language"),
|
||||
.props = AV_CODEC_PROP_TEXT_SUB,
|
||||
},
|
||||
|
||||
|
||||
/* other kind of codecs and pseudo-codecs */
|
||||
{
|
||||
|
||||
@@ -1282,7 +1282,6 @@ AVCodec ff_cook_decoder = {
|
||||
.close = cook_decode_close,
|
||||
.decode = cook_decode_frame,
|
||||
.capabilities = AV_CODEC_CAP_DR1,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
|
||||
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
};
|
||||
|
||||
@@ -38,8 +38,7 @@ typedef struct CamStudioContext {
|
||||
} CamStudioContext;
|
||||
|
||||
static void copy_frame_default(AVFrame *f, const uint8_t *src,
|
||||
int linelen, int height)
|
||||
{
|
||||
int linelen, int height) {
|
||||
int i, src_stride = FFALIGN(linelen, 4);
|
||||
uint8_t *dst = f->data[0];
|
||||
dst += (height - 1) * f->linesize[0];
|
||||
@@ -51,8 +50,7 @@ static void copy_frame_default(AVFrame *f, const uint8_t *src,
|
||||
}
|
||||
|
||||
static void add_frame_default(AVFrame *f, const uint8_t *src,
|
||||
int linelen, int height)
|
||||
{
|
||||
int linelen, int height) {
|
||||
int i, j, src_stride = FFALIGN(linelen, 4);
|
||||
uint8_t *dst = f->data[0];
|
||||
dst += (height - 1) * f->linesize[0];
|
||||
@@ -65,8 +63,7 @@ static void add_frame_default(AVFrame *f, const uint8_t *src,
|
||||
}
|
||||
|
||||
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
||||
AVPacket *avpkt)
|
||||
{
|
||||
AVPacket *avpkt) {
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
CamStudioContext *c = avctx->priv_data;
|
||||
@@ -82,30 +79,30 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
||||
|
||||
// decompress data
|
||||
switch ((buf[0] >> 1) & 7) {
|
||||
case 0: { // lzo compression
|
||||
int outlen = c->decomp_size, inlen = buf_size - 2;
|
||||
if (av_lzo1x_decode(c->decomp_buf, &outlen, &buf[2], &inlen) || outlen) {
|
||||
av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
case 0: { // lzo compression
|
||||
int outlen = c->decomp_size, inlen = buf_size - 2;
|
||||
if (av_lzo1x_decode(c->decomp_buf, &outlen, &buf[2], &inlen) || outlen) {
|
||||
av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: { // zlib compression
|
||||
case 1: { // zlib compression
|
||||
#if CONFIG_ZLIB
|
||||
unsigned long dlen = c->decomp_size;
|
||||
if (uncompress(c->decomp_buf, &dlen, &buf[2], buf_size - 2) != Z_OK) {
|
||||
av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
break;
|
||||
unsigned long dlen = c->decomp_size;
|
||||
if (uncompress(c->decomp_buf, &dlen, &buf[2], buf_size - 2) != Z_OK) {
|
||||
av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
av_log(avctx, AV_LOG_ERROR, "compiled without zlib support\n");
|
||||
return AVERROR(ENOSYS);
|
||||
av_log(avctx, AV_LOG_ERROR, "compiled without zlib support\n");
|
||||
return AVERROR(ENOSYS);
|
||||
#endif
|
||||
}
|
||||
default:
|
||||
av_log(avctx, AV_LOG_ERROR, "unknown compression\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
default:
|
||||
av_log(avctx, AV_LOG_ERROR, "unknown compression\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
// flip upside down, add difference frame
|
||||
@@ -128,19 +125,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
static av_cold int decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
static av_cold int decode_init(AVCodecContext *avctx) {
|
||||
CamStudioContext *c = avctx->priv_data;
|
||||
int stride;
|
||||
switch (avctx->bits_per_coded_sample) {
|
||||
case 16: avctx->pix_fmt = AV_PIX_FMT_RGB555LE; break;
|
||||
case 24: avctx->pix_fmt = AV_PIX_FMT_BGR24; break;
|
||||
case 32: avctx->pix_fmt = AV_PIX_FMT_BGR0; break;
|
||||
default:
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"CamStudio codec error: invalid depth %i bpp\n",
|
||||
avctx->bits_per_coded_sample);
|
||||
return AVERROR_INVALIDDATA;
|
||||
case 16: avctx->pix_fmt = AV_PIX_FMT_RGB555LE; break;
|
||||
case 24: avctx->pix_fmt = AV_PIX_FMT_BGR24; break;
|
||||
case 32: avctx->pix_fmt = AV_PIX_FMT_BGR0; break;
|
||||
default:
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"CamStudio codec error: invalid depth %i bpp\n",
|
||||
avctx->bits_per_coded_sample);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
c->bpp = avctx->bits_per_coded_sample;
|
||||
c->linelen = avctx->width * avctx->bits_per_coded_sample / 8;
|
||||
@@ -158,8 +154,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_cold int decode_end(AVCodecContext *avctx)
|
||||
{
|
||||
static av_cold int decode_end(AVCodecContext *avctx) {
|
||||
CamStudioContext *c = avctx->priv_data;
|
||||
av_freep(&c->decomp_buf);
|
||||
av_frame_free(&c->pic);
|
||||
@@ -175,6 +170,5 @@ AVCodec ff_cscd_decoder = {
|
||||
.init = decode_init,
|
||||
.close = decode_end,
|
||||
.decode = decode_frame,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
|
||||
.capabilities = AV_CODEC_CAP_DR1,
|
||||
};
|
||||
|
||||
@@ -554,16 +554,12 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame)
|
||||
.Height = avctx->height >> (i ? 1 : 0),
|
||||
};
|
||||
|
||||
ret = CHECK_CU(ctx->cudl->cuMemcpy2DAsync(&cpy, device_hwctx->stream));
|
||||
ret = CHECK_CU(ctx->cudl->cuMemcpy2D(&cpy));
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
offset += avctx->height;
|
||||
}
|
||||
|
||||
ret = CHECK_CU(ctx->cudl->cuStreamSynchronize(device_hwctx->stream));
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
} else if (avctx->pix_fmt == AV_PIX_FMT_NV12 ||
|
||||
avctx->pix_fmt == AV_PIX_FMT_P010 ||
|
||||
avctx->pix_fmt == AV_PIX_FMT_P016) {
|
||||
|
||||
@@ -152,11 +152,8 @@ static int subband_bufer_alloc(DCAEncContext *c)
|
||||
|
||||
static void subband_bufer_free(DCAEncContext *c)
|
||||
{
|
||||
if (c->subband[0][0]) {
|
||||
int32_t *bufer = c->subband[0][0] - DCA_ADPCM_COEFFS;
|
||||
av_free(bufer);
|
||||
c->subband[0][0] = NULL;
|
||||
}
|
||||
int32_t *bufer = c->subband[0][0] - DCA_ADPCM_COEFFS;
|
||||
av_freep(&bufer);
|
||||
}
|
||||
|
||||
static int encode_init(AVCodecContext *avctx)
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "libavutil/internal.h"
|
||||
#include "libavutil/intmath.h"
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "bytestream.h"
|
||||
@@ -182,7 +181,7 @@ static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_decode_bsfs_init(AVCodecContext *avctx)
|
||||
static int bsfs_init(AVCodecContext *avctx)
|
||||
{
|
||||
AVCodecInternal *avci = avctx->internal;
|
||||
DecodeFilterContext *s = &avci->filter;
|
||||
@@ -196,33 +195,27 @@ int ff_decode_bsfs_init(AVCodecContext *avctx)
|
||||
while (bsfs_str && *bsfs_str) {
|
||||
AVBSFContext **tmp;
|
||||
const AVBitStreamFilter *filter;
|
||||
char *bsf, *bsf_options_str, *bsf_name;
|
||||
char *bsf;
|
||||
|
||||
bsf = av_get_token(&bsfs_str, ",");
|
||||
if (!bsf) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
bsf_name = av_strtok(bsf, "=", &bsf_options_str);
|
||||
if (!bsf_name) {
|
||||
av_freep(&bsf);
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
filter = av_bsf_get_by_name(bsf_name);
|
||||
filter = av_bsf_get_by_name(bsf);
|
||||
if (!filter) {
|
||||
av_log(avctx, AV_LOG_ERROR, "A non-existing bitstream filter %s "
|
||||
"requested by a decoder. This is a bug, please report it.\n",
|
||||
bsf_name);
|
||||
av_freep(&bsf);
|
||||
bsf);
|
||||
ret = AVERROR_BUG;
|
||||
av_freep(&bsf);
|
||||
goto fail;
|
||||
}
|
||||
av_freep(&bsf);
|
||||
|
||||
tmp = av_realloc_array(s->bsfs, s->nb_bsfs + 1, sizeof(*s->bsfs));
|
||||
if (!tmp) {
|
||||
av_freep(&bsf);
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
@@ -230,10 +223,8 @@ int ff_decode_bsfs_init(AVCodecContext *avctx)
|
||||
s->nb_bsfs++;
|
||||
|
||||
ret = av_bsf_alloc(filter, &s->bsfs[s->nb_bsfs - 1]);
|
||||
if (ret < 0) {
|
||||
av_freep(&bsf);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (s->nb_bsfs == 1) {
|
||||
/* We do not currently have an API for passing the input timebase into decoders,
|
||||
@@ -247,38 +238,12 @@ int ff_decode_bsfs_init(AVCodecContext *avctx)
|
||||
ret = avcodec_parameters_copy(s->bsfs[s->nb_bsfs - 1]->par_in,
|
||||
s->bsfs[s->nb_bsfs - 2]->par_out);
|
||||
}
|
||||
if (ret < 0) {
|
||||
av_freep(&bsf);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (bsf_options_str && filter->priv_class) {
|
||||
const AVOption *opt = av_opt_next(s->bsfs[s->nb_bsfs - 1]->priv_data, NULL);
|
||||
const char * shorthand[2] = {NULL};
|
||||
|
||||
if (opt)
|
||||
shorthand[0] = opt->name;
|
||||
|
||||
ret = av_opt_set_from_string(s->bsfs[s->nb_bsfs - 1]->priv_data, bsf_options_str, shorthand, "=", ":");
|
||||
if (ret < 0) {
|
||||
if (ret != AVERROR(ENOMEM)) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Invalid options for bitstream filter %s "
|
||||
"requested by the decoder. This is a bug, please report it.\n",
|
||||
bsf_name);
|
||||
ret = AVERROR_BUG;
|
||||
}
|
||||
av_freep(&bsf);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
av_freep(&bsf);
|
||||
|
||||
ret = av_bsf_init(s->bsfs[s->nb_bsfs - 1]);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
if (*bsfs_str)
|
||||
bsfs_str++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -688,6 +653,10 @@ int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacke
|
||||
if (avpkt && !avpkt->size && avpkt->data)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
ret = bsfs_init(avctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
av_packet_unref(avci->buffer_pkt);
|
||||
if (avpkt && (avpkt->data || avpkt->side_data_elems)) {
|
||||
ret = av_packet_ref(avci->buffer_pkt, avpkt);
|
||||
@@ -747,6 +716,10 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr
|
||||
if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec))
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
ret = bsfs_init(avctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (avci->buffer_frame->buf[0]) {
|
||||
av_frame_move_ref(frame, avci->buffer_frame);
|
||||
} else {
|
||||
@@ -1496,7 +1469,7 @@ static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame)
|
||||
tmpsize = av_image_fill_pointers(data, avctx->pix_fmt, h,
|
||||
NULL, linesize);
|
||||
if (tmpsize < 0)
|
||||
return tmpsize;
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < 3 && data[i + 1]; i++)
|
||||
size[i] = data[i + 1] - data[i];
|
||||
@@ -1864,7 +1837,7 @@ static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
|
||||
int ret;
|
||||
|
||||
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
if ((ret = av_image_check_size2(FFALIGN(avctx->width, STRIDE_ALIGN), avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) < 0 || avctx->pix_fmt<0) {
|
||||
if ((ret = av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) < 0 || avctx->pix_fmt<0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
@@ -1970,14 +1943,6 @@ int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void bsfs_flush(AVCodecContext *avctx)
|
||||
{
|
||||
DecodeFilterContext *s = &avctx->internal->filter;
|
||||
|
||||
for (int i = 0; i < s->nb_bsfs; i++)
|
||||
av_bsf_flush(s->bsfs[i]);
|
||||
}
|
||||
|
||||
void avcodec_flush_buffers(AVCodecContext *avctx)
|
||||
{
|
||||
avctx->internal->draining = 0;
|
||||
@@ -1998,7 +1963,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
|
||||
avctx->pts_correction_last_pts =
|
||||
avctx->pts_correction_last_dts = INT64_MIN;
|
||||
|
||||
bsfs_flush(avctx);
|
||||
ff_decode_bsfs_uninit(avctx);
|
||||
|
||||
if (!avctx->refcounted_frames)
|
||||
av_frame_unref(avctx->internal->to_free);
|
||||
|
||||
@@ -64,8 +64,6 @@ typedef struct FrameDecodeData {
|
||||
*/
|
||||
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt);
|
||||
|
||||
int ff_decode_bsfs_init(AVCodecContext *avctx);
|
||||
|
||||
void ff_decode_bsfs_uninit(AVCodecContext *avctx);
|
||||
|
||||
/**
|
||||
|
||||
@@ -355,6 +355,8 @@ static int dfa_decode_frame(AVCodecContext *avctx,
|
||||
|
||||
bytestream2_init(&gb, avpkt->data, avpkt->size);
|
||||
while (bytestream2_get_bytes_left(&gb) > 0) {
|
||||
if (bytestream2_get_bytes_left(&gb) < 12)
|
||||
return AVERROR_INVALIDDATA;
|
||||
bytestream2_skip(&gb, 4);
|
||||
chunk_size = bytestream2_get_le32(&gb);
|
||||
chunk_type = bytestream2_get_le32(&gb);
|
||||
|
||||
@@ -488,7 +488,7 @@ UNPACK_ARITH(10, int32_t)
|
||||
* Decode the coeffs in the rectangle defined by left, right, top, bottom
|
||||
* [DIRAC_STD] 13.4.3.2 Codeblock unpacking loop. codeblock()
|
||||
*/
|
||||
static inline int codeblock(DiracContext *s, SubBand *b,
|
||||
static inline void codeblock(DiracContext *s, SubBand *b,
|
||||
GetBitContext *gb, DiracArith *c,
|
||||
int left, int right, int top, int bottom,
|
||||
int blockcnt_one, int is_arith)
|
||||
@@ -505,7 +505,7 @@ static inline int codeblock(DiracContext *s, SubBand *b,
|
||||
zero_block = get_bits1(gb);
|
||||
|
||||
if (zero_block)
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->codeblock_mode && !(s->old_delta_quant && blockcnt_one)) {
|
||||
@@ -516,7 +516,7 @@ static inline int codeblock(DiracContext *s, SubBand *b,
|
||||
quant = dirac_get_se_golomb(gb);
|
||||
if (quant > INT_MAX - b->quant || b->quant + quant < 0) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Invalid quant\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
return;
|
||||
}
|
||||
b->quant += quant;
|
||||
}
|
||||
@@ -524,7 +524,7 @@ static inline int codeblock(DiracContext *s, SubBand *b,
|
||||
if (b->quant > (DIRAC_MAX_QUANT_INDEX - 1)) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Unsupported quant %d\n", b->quant);
|
||||
b->quant = 0;
|
||||
return AVERROR_INVALIDDATA;
|
||||
return;
|
||||
}
|
||||
|
||||
qfactor = ff_dirac_qscale_tab[b->quant];
|
||||
@@ -548,8 +548,6 @@ static inline int codeblock(DiracContext *s, SubBand *b,
|
||||
}
|
||||
} else {
|
||||
for (y = top; y < bottom; y++) {
|
||||
if (get_bits_left(gb) < 1)
|
||||
return AVERROR_INVALIDDATA;
|
||||
for (x = left; x < right; x++) {
|
||||
int val = coeff_unpack_golomb(gb, qfactor, qoffset);
|
||||
if (b->pshift) {
|
||||
@@ -561,7 +559,6 @@ static inline int codeblock(DiracContext *s, SubBand *b,
|
||||
buf += b->stride;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -596,7 +593,7 @@ INTRA_DC_PRED(10, uint32_t)
|
||||
* Dirac Specification ->
|
||||
* 13.4.2 Non-skipped subbands. subband_coeffs()
|
||||
*/
|
||||
static av_always_inline int decode_subband_internal(DiracContext *s, SubBand *b, int is_arith)
|
||||
static av_always_inline void decode_subband_internal(DiracContext *s, SubBand *b, int is_arith)
|
||||
{
|
||||
int cb_x, cb_y, left, right, top, bottom;
|
||||
DiracArith c;
|
||||
@@ -604,10 +601,9 @@ static av_always_inline int decode_subband_internal(DiracContext *s, SubBand *b,
|
||||
int cb_width = s->codeblock[b->level + (b->orientation != subband_ll)].width;
|
||||
int cb_height = s->codeblock[b->level + (b->orientation != subband_ll)].height;
|
||||
int blockcnt_one = (cb_width + cb_height) == 2;
|
||||
int ret;
|
||||
|
||||
if (!b->length)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
init_get_bits8(&gb, b->coeff_data, b->length);
|
||||
|
||||
@@ -620,9 +616,7 @@ static av_always_inline int decode_subband_internal(DiracContext *s, SubBand *b,
|
||||
left = 0;
|
||||
for (cb_x = 0; cb_x < cb_width; cb_x++) {
|
||||
right = (b->width * (cb_x+1LL)) / cb_width;
|
||||
ret = codeblock(s, b, &gb, &c, left, right, top, bottom, blockcnt_one, is_arith);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
codeblock(s, b, &gb, &c, left, right, top, bottom, blockcnt_one, is_arith);
|
||||
left = right;
|
||||
}
|
||||
top = bottom;
|
||||
@@ -635,35 +629,33 @@ static av_always_inline int decode_subband_internal(DiracContext *s, SubBand *b,
|
||||
intra_dc_prediction_8(b);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_subband_arith(AVCodecContext *avctx, void *b)
|
||||
{
|
||||
DiracContext *s = avctx->priv_data;
|
||||
return decode_subband_internal(s, b, 1);
|
||||
decode_subband_internal(s, b, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_subband_golomb(AVCodecContext *avctx, void *arg)
|
||||
{
|
||||
DiracContext *s = avctx->priv_data;
|
||||
SubBand **b = arg;
|
||||
return decode_subband_internal(s, *b, 0);
|
||||
decode_subband_internal(s, *b, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dirac Specification ->
|
||||
* [DIRAC_STD] 13.4.1 core_transform_data()
|
||||
*/
|
||||
static int decode_component(DiracContext *s, int comp)
|
||||
static void decode_component(DiracContext *s, int comp)
|
||||
{
|
||||
AVCodecContext *avctx = s->avctx;
|
||||
SubBand *bands[3*MAX_DWT_LEVELS+1];
|
||||
enum dirac_subband orientation;
|
||||
int level, num_bands = 0;
|
||||
int ret[3*MAX_DWT_LEVELS+1];
|
||||
int i;
|
||||
int damaged_count = 0;
|
||||
|
||||
/* Unpack all subbands at all levels. */
|
||||
for (level = 0; level < s->wavelet_depth; level++) {
|
||||
@@ -676,6 +668,10 @@ static int decode_component(DiracContext *s, int comp)
|
||||
b->length = get_interleaved_ue_golomb(&s->gb);
|
||||
if (b->length) {
|
||||
b->quant = get_interleaved_ue_golomb(&s->gb);
|
||||
if (b->quant > (DIRAC_MAX_QUANT_INDEX - 1)) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Unsupported quant %d\n", b->quant);
|
||||
b->quant = 0;
|
||||
}
|
||||
align_get_bits(&s->gb);
|
||||
b->coeff_data = s->gb.buffer + get_bits_count(&s->gb)/8;
|
||||
b->length = FFMIN(b->length, FFMAX(get_bits_left(&s->gb)/8, 0));
|
||||
@@ -685,20 +681,11 @@ static int decode_component(DiracContext *s, int comp)
|
||||
/* arithmetic coding has inter-level dependencies, so we can only execute one level at a time */
|
||||
if (s->is_arith)
|
||||
avctx->execute(avctx, decode_subband_arith, &s->plane[comp].band[level][!!level],
|
||||
ret + 3*level + !!level, 4-!!level, sizeof(SubBand));
|
||||
NULL, 4-!!level, sizeof(SubBand));
|
||||
}
|
||||
/* golomb coding has no inter-level dependencies, so we can execute all subbands in parallel */
|
||||
if (!s->is_arith)
|
||||
avctx->execute(avctx, decode_subband_golomb, bands, ret, num_bands, sizeof(SubBand*));
|
||||
|
||||
for (i = 0; i < s->wavelet_depth * 3 + 1; i++) {
|
||||
if (ret[i] < 0)
|
||||
damaged_count++;
|
||||
}
|
||||
if (damaged_count > (s->wavelet_depth * 3 + 1) /2)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
return 0;
|
||||
avctx->execute(avctx, decode_subband_golomb, bands, NULL, num_bands, sizeof(SubBand*));
|
||||
}
|
||||
|
||||
#define PARSE_VALUES(type, x, gb, ebits, buf1, buf2) \
|
||||
@@ -1884,9 +1871,7 @@ static int dirac_decode_frame_internal(DiracContext *s)
|
||||
if (!s->zero_res && !s->low_delay)
|
||||
{
|
||||
memset(p->idwt.buf, 0, p->idwt.stride * p->idwt.height);
|
||||
ret = decode_component(s, comp); /* [DIRAC_STD] 13.4.1 core_transform_data() */
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
decode_component(s, comp); /* [DIRAC_STD] 13.4.1 core_transform_data() */
|
||||
}
|
||||
ret = ff_spatial_idwt_init(&d, &p->idwt, s->wavelet_idx+2,
|
||||
s->wavelet_depth, s->bit_depth);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user