Compare commits

..

246 Commits
n6.1 ... master

Author SHA1 Message Date
Rémi Denis-Courmont
07c303b708 lavc/flacdsp: R-V V decorrelate_indep 16-bit packed
flac_decorrelate_indep2_16_c:        981.7
flac_decorrelate_indep2_16_rvv_i32:  199.2
flac_decorrelate_indep4_16_c:       1749.7
flac_decorrelate_indep4_16_rvv_i32:  401.2
flac_decorrelate_indep6_16_c:       2517.7
flac_decorrelate_indep6_16_rvv_i32:  858.0
flac_decorrelate_indep8_16_c:       3285.7
flac_decorrelate_indep8_16_rvv_i32: 1123.5
2023-11-17 23:59:56 +02:00
Rémi Denis-Courmont
fb0295e5fd lavc/flacdsp: R-V V decorrelate_indep 32-bit packed
flac_decorrelate_indep2_32_c:       981.7
flac_decorrelate_indep2_32_rvv_i32: 183.7
flac_decorrelate_indep4_32_c:      1749.7
flac_decorrelate_indep4_32_rvv_i32: 362.5
flac_decorrelate_indep6_32_c:      2517.7
flac_decorrelate_indep6_32_rvv_i32: 715.2
flac_decorrelate_indep8_32_c:      3285.7
flac_decorrelate_indep8_32_rvv_i32: 909.0
2023-11-17 23:59:56 +02:00
Rémi Denis-Courmont
6183a69c0b lavc/flacdsp: R-V V decorrelate_ms packed
flac_decorrelate_ms_16_c:       585.5
flac_decorrelate_ms_16_rvv_i32: 263.0
flac_decorrelate_ms_32_c:       584.7
flac_decorrelate_ms_32_rvv_i32: 250.0
2023-11-17 23:59:23 +02:00
Rémi Denis-Courmont
636ae0e0bc lavc/flacdsp: R-V V packed decorrelate_{l,r}s
flac_decorrelate_ms_16_c:       457.2
flac_decorrelate_ms_16_rvv_i32: 203.0
flac_decorrelate_ms_32_c:       457.2
flac_decorrelate_ms_32_rvv_i32: 203.5
flac_decorrelate_rs_16_c:       456.2
flac_decorrelate_rs_16_rvv_i32: 207.0
flac_decorrelate_rs_32_c:       456.2
flac_decorrelate_rs_32_rvv_i32: 210.5
2023-11-17 23:59:22 +02:00
Rémi Denis-Courmont
be1675035f checkasm/flacdsp: fix ls/rs/ms tests
decorrelate_ls, _rs and _ms are decorrelate[1], [2] and [3] respectively.
The code ended up testing indep ([0]) as twice, ms never, and misnaming
the other two.
2023-11-17 23:59:22 +02:00
Paul B Mahol
08e97dae20 avfilter/af_adynamicequalizer: add adaptive detection mode 2023-11-17 00:17:54 +01:00
Paul B Mahol
82be1e5c0d avfilter/af_adynamicequalizer: do gain calculations in log domain 2023-11-17 00:17:54 +01:00
sunyuechi
afb967b81e af_afir: RISC-V V fcmul_add
Segmented loads are slow, so here we use unit-strided load and narrowing shifts.

c910:
fcmul_add_c: 2179
fcmul_add_rvv_f64: 1652

c908:
fcmul_add_c: 4891.2
fcmul_add_rvv_f64: 2399.5

Signed-off-by: Rémi Denis-Courmont <remi@remlab.net>
2023-11-16 20:53:18 +02:00
Rémi Denis-Courmont
d076517056 lavc/llauddsp: R-V V scalarproduct_and_madd_int32
scalarproduct_and_madd_int32_c:      10899.7
scalarproduct_and_madd_int32_rvv_i32: 1749.0
2023-11-16 16:53:44 +02:00
Rémi Denis-Courmont
45d0eb3f70 lavc/llauddsp: R-V V scalarproduct_and_madd_int16
scalarproduct_and_madd_int16_c:      10355.7
scalarproduct_and_madd_int16_rvv_i32: 1480.0
2023-11-16 16:53:44 +02:00
Rémi Denis-Courmont
6720a509a7 checkasm: add lossless audio DSP 2023-11-16 16:53:44 +02:00
James Almer
78f55457c9 x86/flacds: clear the high bits from pred_order in lpc_32 functions
Reviewed-by: Ronald S. Bultje <rsbultje@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
2023-11-15 16:10:15 -03:00
Dai, Jianhui J
c9fe9fb863 avcodec/cbs_vp8: Add support for VP8 codec bitstream
This commit adds support for VP8 bitstream read methods to the cbs
codec. This enables the trace_headers bitstream filter to support VP8,
in addition to AV1, H.264, H.265, and VP9. This can be useful for
debugging VP8 stream issues.

The CBS VP8 implements a simple VP8 boolean decoder using GetBitContext
to read the bitstream.

Only the read methods `read_unit` and `split_fragment` are implemented.
The write methods `write_unit` and `assemble_fragment` return the error
code AVERROR_PATCHWELCOME. This is because CBS VP8 write is unlikely to
be used by any applications at the moment. The write methods can be
added later if there is a real need for them.

TESTS: ffmpeg -i fate-suite/vp8/frame_size_change.webm -vcodec copy
-bsf:v trace_headers -f null -

Signed-off-by: Jianhui Dai <jianhui.j.dai@intel.com>
Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com>
2023-11-15 10:29:03 -05:00
Dai, Jianhui J
5cb8accd09 avcodec/vp8: Export vp8_token_update_probs variable
This commit exports the `vp8_token_update_probs` variable to internal
library scope to facilitate its reuse within the library.

Signed-off-by: Jianhui Dai <jianhui.j.dai@intel.com>
Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com>
2023-11-15 10:29:03 -05:00
Rémi Denis-Courmont
90a779bed6 lavc/huffyuvdsp: basic R-V V add_hfyu_left_pred_bgr32
Better performance can probably be achieved with a more intricate
unrolled loop, but this is a start:

add_hfyu_left_pred_bgr32_c: 15084.0
add_hfyu_left_pred_bgr32_rvv_i32: 10280.2

This would actually be cleaner with the RISC-V P extension, but that is
not ratified yet (I think?) and usually not supported if V is supported.
2023-11-15 16:51:07 +02:00
Rémi Denis-Courmont
6b708cd783 checkasm/huffyuvdsp: test for add_hfyu_left_pred_bgr32 2023-11-15 16:51:07 +02:00
Cosmin Stejerean via ffmpeg-devel
575efc0406 tools/general_assembly.pl - add options to print names, emails or both
Signed-off-by: Cosmin Stejerean <cosmin@cosmin.at>
Signed-off-by: Anton Khirnov <anton@khirnov.net>
2023-11-14 18:33:07 +01:00
James Almer
b360c91752 avcodec/codecpar: mention how to allocate coded_side_data
Signed-off-by: James Almer <jamrial@gmail.com>
2023-11-14 14:26:42 -03:00
Zhao Zhili
a1a6a328f0 fftools/ffplay: add hwaccel decoding support
Add vulkan renderer via libplacebo.

Simple usage:
$ ffplay -hwaccel vulkan foo.mp4

Use cuda to vulkan map:
$ ffplay -hwaccel cuda foo.mp4

Create vulkan instance by libplacebo, and enable debug:
$ ffplay -hwaccel vulkan \
	-vulkan_params create_by_placebo=1:debug=1 foo.mp4

Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2023-11-15 01:20:11 +08:00
Anton Khirnov
889a022cce fftools/ffmpeg: rework keeping track of file duration for -stream_loop
Current code tracks min/max pts for each stream separately; then when
the file ends it combines them with last frame's duration to compute the
total duration of each stream; finally it selects the longest of those
durations as the file duration.

This is incorrect - the total file duration is the largest timestamp
difference between any frames, regardless of the stream.

Also change the way the last frame information is reported from decoders
to the muxer - previously it would be just the last frame's duration,
now the end timestamp is sent, which is simpler.

Changes the result of the fate-ffmpeg-streamloop-transcode-av test,
where the timestamps are shifted slightly forward. Note that the
matroska demuxer does not return the first audio packet after seeking
(due to buggy interaction betwen the generic code and the demuxer), so
there is a gap in audio.
2023-11-14 18:18:26 +01:00
Anton Khirnov
87016e031f fftools/thread_queue: count receive-finished streams as finished
This ensures that tq_receive() will always return EOF after all streams
were receive-finished, even though the sending side might not have
closed them yet. This may allow the receiver to avoid manually tracking
which streams it has already closed.
2023-11-14 18:18:26 +01:00
Anton Khirnov
4f7b91a698 fftools/thread_queue: do not return elements for receive-finished streams
It does not cause any issues in current callers, but still should not
happen.
2023-11-14 18:18:26 +01:00
Anton Khirnov
7c97a0c63f fftools/ffmpeg: move a few inline function into a new header
Will allow to use them in future commits without including the whole
ffmpeg.h.
2023-11-14 18:18:26 +01:00
Anton Khirnov
6dbde68cb5 lavc/8bps: fix exporting palette after 63767b79a5
It would be left empty on each frame whose packet does not come with
palette attached.
2023-11-14 18:18:26 +01:00
Paul B Mahol
7282137f48 lavfi/af_amix: make sure the output does not depend on input ordering
Signed-off-by: Anton Khirnov <anton@khirnov.net>
2023-11-14 18:18:26 +01:00
Anton Khirnov
de85815bfa lavf/mux: do not apply max_interleave_delta to subtitles
It is common for subtitle streams to have large gaps between packets.
When the caller is interleaving packets from multiple files, it can
easily happen that two successive subtitle packets trigger this limit,
even though no excessive buffering is happening.

Should fix #7064
2023-11-14 18:18:26 +01:00
Anton Khirnov
436b972fc8 doc/ffmpeg: expand -bsf documentation
Explain how to pass options to filters.
2023-11-14 18:18:26 +01:00
Anton Khirnov
a8d9d6b08d tests/fate: replace deprecated -vsync with -fps_mode 2023-11-14 18:18:26 +01:00
Anton Khirnov
23de85d1ec tests/fate/ffmpeg: replace deprecated -vbsf with -bsf:v 2023-11-14 18:18:26 +01:00
Rémi Denis-Courmont
ce467421dc lavc/exrdsp: unroll predictor
With explicit unrolling, we can skip half of the sign bit flips, and
the compiler is then better able to optimise the scalar loop:

predictor_c: 31376.0 (before)
predictor_c: 23703.0 (after)
2023-11-14 19:15:51 +02:00
Rémi Denis-Courmont
c536e92207 lavc/sbrdsp: R-V V hf_apply_noise functions
This is restricted to 128-bit vectors as larger vector sizes could read
past the end of the noise array. Support for future hardware with larger
vector sizes is left for some other time.

hf_apply_noise_0_c:       2319.7
hf_apply_noise_0_rvv_f32: 1229.0
hf_apply_noise_1_c:       2539.0
hf_apply_noise_1_rvv_f32: 1244.7
hf_apply_noise_2_c:       2319.7
hf_apply_noise_2_rvv_f32: 1232.7
hf_apply_noise_3_c:       2541.2
hf_apply_noise_3_rvv_f32: 1244.2
2023-11-13 18:34:29 +02:00
Rémi Denis-Courmont
20e6195c54 checkasm: test the noise case of sbrdsp.hf_apply_noise
The tested functions treat s_m[i] == 0 as a special case. Other than
that, the functions are slightly complicated vector additions.

This actually makes the zero case happen pseudorandomly.
2023-11-13 18:34:29 +02:00
Rémi Denis-Courmont
6d60cc7baf sws/rgb2rgb: fix unaligned accesses in R-V V YUYV to I422p
In my personal opinion, we should not need to support unaligned YUY2
pixel maps. They should always be aligned to at least 32 bits, and the
current code assumes just 16 bits. However checkasm does test for
unaligned input bitmaps. QEMU accepts it, but real hardware dose not.

In this particular case, we can at the same time improve performance and
handle unaligned inputs, so do just that.

uyvytoyuv422_c:      104379.0
uyvytoyuv422_c:      104060.0
uyvytoyuv422_rvv_i32: 25284.0 (before)
uyvytoyuv422_rvv_i32: 19303.2 (after)
2023-11-13 18:34:29 +02:00
Rémi Denis-Courmont
5b8b5ec9c5 sws/rgb2rgb: rework R-V V YUY2 to 4:2:2 planar
This saves three scratch registers and three instructions per line. The
performance gains are mostly negligible. The main point is to free up
registers for further rework.
2023-11-13 18:34:29 +02:00
Rémi Denis-Courmont
5b33104fca lavc/sbrdsp: R-V V hf_gen
hf_gen_c:      2922.7
hf_gen_rvv_f32: 731.5
2023-11-13 18:33:02 +02:00
Gyan Doshi
67a2571a55 avcodec/libsvtav1: add version guard for external param
Setting of external param 'force_key_frames' was added in 7bcc1b4eb8.
It is available since v1.1.0 but ffmpeg allows linking against v0.9.0.
2023-11-13 13:14:43 +05:30
Paul B Mahol
84e400ae37 avfilter/buffersrc: switch to activate
Fixes OOM when caller keeps adding frames into filtergraph
that reached EOF by other means, for example EOF is signalled
by other filter in filtergraph or by buffersink.
2023-11-12 23:48:10 +01:00
Evgeny Pavlov
da3ce21f68 libavcodec/amfenc: Fix issue with missing headers in AV1 encoder
This commit fixes issue with missing SPS/PPS headers in video
encoded by AMF AV1 encoder.
Missing headers leads to broken seek in MPV video player.
Default value for property AV1_HEADER_INSERTION_MODE shouldn't be setup
to NONE (no headers insertion). We need to skip definition of this property,
because default value depends on USAGE property.

Signed-off-by: Dmitrii Ovchinnikov <ovchinnikov.dmitrii@gmail.com>
2023-11-12 22:57:17 +01:00
Rémi Denis-Courmont
427347309b checkasm: test with random bw value
With a value of zero, the function is a glorified memory copy.
2023-11-12 22:33:11 +02:00
Sebastian Ramacher
250471ea17 avcoded/fft: Fix memory leak if ctx2 is used
Signed-off-by: James Almer <jamrial@gmail.com>
2023-11-12 14:47:56 -03:00
Sebastian Ramacher
a562cfee2e avcodec/fft: Use av_mallocz to avoid invalid free/uninit
Signed-off-by: James Almer <jamrial@gmail.com>
2023-11-12 14:47:56 -03:00
Rémi Denis-Courmont
cd7b352c53 lavc/sbrdsp: R-V V autocorrelate
With 5 accumulator vectors and 6 inputs, this can only use LMUL=2.
Also the number of vector loop iterations is small, just 5 on 128-bit
vector hardware.

The vector loop is somewhat unusual in that it processes data in
descending memory order, in order to save on vector slides:
in descending order, we can extract elements to carry over to the next
iteration from the bottom of the vectors directly. With ascending order
(see in the Opus postfilter function), there are no ways to get the top
elements directly. On the downside, this requires the use of separate
shift and sub (the would-be SH3SUB instruction does not exist), with
a small pipeline stall on the vector load address.

The edge cases in scalar are done in scalar as this saves on loads
and remains significantly faster than C.

autocorrelate_c: 669.2
autocorrelate_rvv_f32: 421.0
2023-11-12 14:03:09 +02:00
Rémi Denis-Courmont
f576a0835b lavc/aacpsdsp: rework R-V V hybrid_synthesis_deint
Given the size of the data set, strided memory accesses cannot be avoided.
We can still do better than the current code.

ps_hybrid_synthesis_deint_c:       12065.5
ps_hybrid_synthesis_deint_rvv_i32: 13650.2 (before)
ps_hybrid_synthesis_deint_rvv_i64:  8181.0 (after)
2023-11-12 14:03:09 +02:00
Rémi Denis-Courmont
eb508702a8 lavc/aacpsdsp: rework R-V V add_squares
Segmented loads may be slower than not. So this advantageously uses a
unit-strided load and narrowing shifts instead.

Before:
ps_add_squares_c: 60757.7
ps_add_squares_rvv_f32: 22242.5

After:
ps_add_squares_c: 60516.0
ps_add_squares_rvv_i64: 17067.7
2023-11-12 14:03:09 +02:00
Dave Johansen
ab78d22553 avformat/hlsenc: Fix name of flag in error message
Reviewed-by: Steven Liu <lq@chinaffmpeg.org>
2023-11-12 16:47:40 +08:00
Dave Johansen
39878fc504 avformat/hlsenc: Add CHANNELS to EXT-X-MEDIA for Audio
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
2023-11-12 16:44:47 +08:00
Léon Spaans
9bcbe04aa0 avformat/hlsenc: set HTTP options before writing WebVTT HLS playlists
Fixes: Erroneous HTTP POST instead of HTTP PUT for WebVTT HLS variant playlists.

Signed-off-by: Léon Spaans <leons@gridpoint.nl>
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
2023-11-12 11:19:31 +08:00
Paul B Mahol
3ff811a41f avfilter/vf_colortemperature: add gbr(a)pf support 2023-11-12 02:39:44 +01:00
Paul B Mahol
10440a489a avcodec/gif_parser: split correctly also bitstreams that do not have extension blocks 2023-11-12 02:19:53 +01:00
Paul B Mahol
553b31da68 avfilter/avf_showcwt: fix invalid write for full bargraph 2023-11-11 23:29:45 +01:00
Paul B Mahol
fa4c2884dd avfilter/avf_showcwt: do not return initial black frames with negative timestamps 2023-11-11 17:53:26 +01:00
Nuo Mi
09f783692e avcodec/cbs_h266: H266RawSliceHeader, expose curr_subpic_idx
Signed-off-by: James Almer <jamrial@gmail.com>
2023-11-11 11:53:21 -03:00
Wenbin Chen
fa81de4af0 libavfilter/dnn/openvino: Reduce redundant memory allocation
We can directly get data ptr from tensor, so that extral memory
allocation can be removed.

Signed-off-by: Wenbin Chen <wenbin.chen@intel.com>
2023-11-11 09:32:31 +08:00
Paul B Mahol
49719d3cb5 avfilter/avf_showcwt: add fm frequency scaler 2023-11-11 01:19:44 +01:00
Michael Niedermayer
409b29d3f9 doc/APIchanges: Fill in missing values
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-10 02:04:25 +01:00
Michael Niedermayer
ac4e3e188a avcodec/evc_parse: Check num_remaining_tiles_in_slice_minus1
Fixes: out of array access
Fixes: 62467/clusterfuzz-testcase-minimized-ffmpeg_BSF_EVC_FRAME_MERGE_fuzzer-6092990982258688

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Reviewed-by: "Dawid Kozinski/Multimedia (PLT) /SRPOL/Staff Engineer/Samsung Electronics" <d.kozinski@samsung.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-10 00:15:28 +01:00
Michael Niedermayer
bb0a684d93 avcodec/4xm: Check for cfrm exhaustion
Fixes: index -1 out of bounds for type 'CFrameBuffer [100]'
Fixes: 63877/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_FOURXM_fuzzer-5854263397711872

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-10 00:14:02 +01:00
Michael Niedermayer
19fcf43131 avformat/mov: Disallow FTYP after streams
Fixes: Assertion !c->fc->nb_streams failed at libavformat/mov.c:7799
Fixes: 63875/clusterfuzz-testcase-minimized-ffmpeg_dem_MOV_fuzzer-5479178702815232

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-10 00:14:02 +01:00
Niklas Haas
96d2a40b9e avcodec/pnm: explicitly tag color range
PGMYUV seems to be always limited range. This was a format originally
invented by FFmpeg at a time when YUVJ distinguished limited from full
range YUV, and this codec never appeared to output YUVJ in any
circumstance, so hard-coding limited range preserves the status quo.

The other formats are explicitly documented to be full range RGB/gray
formats. That said, don't tag them yet, due to outstanding bugs w.r.t
grayscale formats and color range handling.

This change in behavior updates a bunch of FATE tests in trivial ways
(added tagging being the only difference).
2023-11-09 12:53:35 +01:00
Niklas Haas
cf60046cdc avfilter/vf_scale: tag output color space
When using vf_scale to force a specific output color space, also tag
this on the AVFrame. (Mirroring existing logic for output range)

Move the sanity fix for RGB after the new assignment, to avoid leaking
bogus YUV colorspace metadata for RGB spaces.
2023-11-09 12:53:35 +01:00
Niklas Haas
5d5bb77af1 avfilter/vf_scale: simplify color matrix parsing logic
No need to write a custom string parser when we can just use an integer
option with preset values. The various bits of fallback logic are wholly
redundant with equivalent logic already inside sws_getCoefficients.

Note: I disallowed setting 'out_color_matrix=auto', because this does
not do anything meaningful in the current code (just hard-codes
AVCOL_SPC_BT470BG fallback).
2023-11-09 12:53:35 +01:00
Niklas Haas
ea9557043e avfilter/vf_alphamerge: warn if input not full range
Alpha planes must always be full range, so complain loudly if fed
limited range grayscale input.
2023-11-09 12:53:35 +01:00
Niklas Haas
b7284f2410 avfilter/vf_extractplanes: tag alpha plane as full range
Alpha planes are explicitly full range, even for limited range YUVA
formats. Mark them as such.
2023-11-09 12:53:35 +01:00
Niklas Haas
736284e7b9 swscale/yuv2rgb: fix sws_getCoefficients for colorspace=0
The documentation states that invalid entries default to SWS_CS_DEFAULT.
A value of 0 is not a valid SWS_CS_*, yet the code incorrectly
hard-codes it to BT.709 coefficients instead of SWS_CS_DEFAULT.
2023-11-09 12:53:35 +01:00
Niklas Haas
d043e5c54c swscale: don't omit ff_sws_init_range_convert for high-bit
This was a complete hack seemingly designed to work around a different
bug, which was fixed in the previous commit. As such, there is no more
reason not to do this, as it simply breaks changing color range in
sws_setColorspaceDetails for no reason.
2023-11-09 12:53:35 +01:00
Niklas Haas
cedf589c09 swscale: fix sws_setColorspaceDetails after sws_init_context
More commonly, this fixes the case of sws_setColorspaceDetails after
sws_getContext, since the latter implies sws_init_context.

The problem here is that sws_init_context sets up the range conversion
and fast path tables based on the values of srcRange/dstRange at init
time. This may result in locking in a "wrong" path (either using
unscaled fast path when range conversion later required, or using
scaled slow path when range conversion becomes no longer required).

There are two way outs:

1. Always initialize range conversion and unscaled converters, even if
   they will be unused, and extend the runtime check.
2. Re-do initialization if the values change after
   sws_setColorspaceDetails.

I opted for approach 1 because it was simpler and easier to reason
about.

Reword the av_log message to make it clear that this special converter
is not necessarily used, depending on whether or not there is range
conversion or YUV matrix conversion going on.
2023-11-09 12:53:35 +01:00
Anton Khirnov
acf63d5350 lavu/log: do not assume AVClass.item_name is always set 2023-11-09 11:25:17 +01:00
Anton Khirnov
26ebd96371 fftools/ffmpeg_filter: return an error on ofilter_alloc() failure 2023-11-09 11:25:17 +01:00
Anton Khirnov
5db07311a0 fftools/ffmpeg_filter: fail on ifilter_alloc() failure 2023-11-09 11:25:17 +01:00
Anton Khirnov
ed0a50923a fftools/cmdutils: only set array size after allocation succeeded 2023-11-09 11:25:17 +01:00
Marvin Scholz
e900a559c2 fate: enhance tpad filter test
Adds another test that uses the start_duration and stop_duration
options instead of start and stop.

Signed-off-by: Anton Khirnov <anton@khirnov.net>
2023-11-09 11:11:00 +01:00
Marvin Scholz
6667741029 avfilter/vf_tpad: fix check for drawing initialization
The check if drawing needs to be initialized and supported formats
should be drawable ones was flawed, as pad_stop/pad_start is only
populated from stop_duration/start_duration after these checks.

To fix that, check the _duration variants as well and for better
readability and maintainability break the check out into its own
helper.

Fixes a regression from 86b252ea9d
Fix #10621

Signed-off-by: Anton Khirnov <anton@khirnov.net>
2023-11-09 11:11:00 +01:00
Lynne
99fcdee5e8 nlmeans_vulkan: fix offsets calculation and various stride issues
We calculated offsets as pairs, but addressed them in the shader
as single float values, while reading them as ivec2s.

Also removes unused code (was provisionally added if cooperative matrices
could be used, but that turned out to be impossible).
2023-11-09 09:14:18 +01:00
Víctor Manuel Jáquez Leal
854012ec59 avutil/hwcontext_vulkan: get VkFormatFeatureFlagBits2
Rather than the VkFormatFeatureFlagBits enum

Signed-off-by: Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
2023-11-09 09:13:47 +01:00
Zhao Zhili
6f39dee974 avutil/hwcontext_vulkan: fix run on macOS
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME is required on macOS,
and VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR flag should
be set.

Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2023-11-09 19:23:01 +08:00
Frank Plowman
f16900bda2 doc/html: fix styling issue with Texinfo 7.0
Texinfo 7.0 produces quite different HTML to Texinfo 6.8. Without
this change, enumerated option flags (i.e. Possible values of x
are...) render as white text on a white background with Texinfo 7.0
and are unreadable. This change removes a style for the selector
`.table .table` which causes the background to turn white for these
elements. As far as I can tell, it is not actually used anywhere in
files generated by Texinfo 6.8.

Signed-off-by: Frank Plowman <post@frankplowman.com>
2023-11-08 23:54:23 +01:00
Frank Plowman
f01fdedb69 doc/html: support texinfo 7.0
Resolves trac ticket #10636 (http://trac.ffmpeg.org/ticket/10636).

Texinfo 7.0, released in November 2022, changed the names of various
functions. Compiling docs with Texinfo 7.0 resulted in warnings and
improperly formatted documentation. More old names appear to have
been removed in Texinfo 7.1, released October 2023, which causes docs
compilation to fail.

This commit addresses the issue by adding logic to switch between the old
and new function names depending on the Texinfo version. Texinfo 6.8
produces identical documentation before and after the patch.

CC
https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1938238.html
https://bugs.gentoo.org/916104

Signed-off-by: Frank Plowman <post@frankplowman.com>
2023-11-08 23:53:19 +01:00
Anton Khirnov
2b4035d1dc doc/community: improve wording
By intent, and in practice, the "active contributor" criterion applies
to the person authoring the commits, not the one pushing them into the
repository.
2023-11-08 17:01:50 +01:00
Anton Khirnov
88f9164f97 doc/community: update the rules according to voting results
Cf.:
* http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2023-October/316054.html
* http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2023-November/316618.html
2023-11-08 17:01:50 +01:00
James Almer
b82957a66a avutil: bump minor version after recent commits
Signed-off-by: James Almer <jamrial@gmail.com>
2023-11-08 10:13:50 -03:00
James Almer
04e53927ad avutil/channel_layout: add a 9.1.4 channel layout
Mapping to ITU-R BS.2051-3 "Sound System G" and ITU-R BS.1196-8 "Channel
Configuration 20".

Signed-off-by: James Almer <jamrial@gmail.com>
2023-11-08 10:09:46 -03:00
James Almer
b4169760b0 avutil/channel_layout: add a 7.2.3 channel layout
Mapping to ITU-R BS.2051-3 "Sound System F" and ITU-R BS.1196-8 "Channel
Configuration 15".

Signed-off-by: James Almer <jamrial@gmail.com>
2023-11-08 10:09:46 -03:00
Henrik Gramner
ed8ddf0bd3 x86inc: Add REPX macro to repeat instructions/operations
When operating on large blocks of data it's common to repeatedly use
an instruction on multiple registers. Using the REPX macro makes it
easy to quickly write dense code to achieve this without having to
explicitly duplicate the same instruction over and over.

For example,

    REPX {paddw x, m4}, m0, m1, m2, m3
    REPX {mova [r0+16*x], m5}, 0, 1, 2, 3

will expand to

    paddw       m0, m4
    paddw       m1, m4
    paddw       m2, m4
    paddw       m3, m4
    mova [r0+16*0], m5
    mova [r0+16*1], m5
    mova [r0+16*2], m5
    mova [r0+16*3], m5

Commit taken from x264:
6d10612ab0

Signed-off-by: Frank Plowman <post@frankplowman.com>
Signed-off-by: Anton Khirnov <anton@khirnov.net>
2023-11-08 13:49:08 +01:00
Zhao Zhili
5a2ca4bf7a MAINTAINERS: add myself as a mediacodec and videotoolbox maintainer
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2023-11-08 16:15:04 +08:00
Peter Ross
10869cd849 avcodec: LEAD MCMP decoder
Partially fixes ticket #798

Reviewed-by: James Almer <jamrial@gmail.com>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Reviewed-by: Paul B Mahol <onemda@gmail.com>
Signed-off-by: Peter Ross <pross@xvid.org>
2023-11-08 17:37:58 +11:00
Zhao Zhili
f084e9b0be avdevice/android_camera: fix build failure due to typo
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2023-11-07 11:10:07 +08:00
Rémi Denis-Courmont
adc87a5f7c lavc/opusdsp: rewrite R-V V postfilter
This uses a more traditional approach allowing up processing of up to
period minus two elements per iteration. This also allows the algorithm
to work for all and any vector length.

As the T-Head C908 device under test can load 16 elements loop, there is
unsurprisingly a little performance drop when the period is minimal and
the parallelism is capped at 13 elements:

Before:
postfilter_15_c:         21222.2
postfilter_15_rvv_f32:   22007.7
postfilter_512_c:        20189.7
postfilter_512_rvv_f32:  22004.2
postfilter_1022_c:       20189.7
postfilter_1022_rvv_f32: 22004.2

After:
postfilter_15_c:         20189.5
postfilter_15_rvv_f32:    7057.2
postfilter_512_c:        20189.5
postfilter_512_rvv_f32:   5667.2
postfilter_1022_c:       20192.7
postfilter_1022_rvv_f32:  5667.2
2023-11-06 22:09:30 +02:00
Rémi Denis-Courmont
02594c8c01 lavc/pixblockdsp: rework R-V V get_pixels_unaligned
As in the aligned case, we can use VLSE64.V, though the way of doing so
gets more convoluted, so the performance gains are more modest:

get_pixels_unaligned_c:       126.7
get_pixels_unaligned_rvv_i32: 145.5 (before)
get_pixels_unaligned_rvv_i64:  62.2 (after)

For the reference, those are the aligned benchmarks (unchanged) on the
same T-Head C908 hardware:

get_pixels_c:                 126.7
get_pixels_rvi:                85.7
get_pixels_rvv_i64:            33.2
2023-11-06 19:42:49 +02:00
Rémi Denis-Courmont
f68ad5d2de lavc/sbrdsp: R-V V sbr_hf_g_filt
hf_g_filt_c:      1552.5
hf_g_filt_rvv_f32: 679.5
2023-11-06 19:42:49 +02:00
Paul B Mahol
44a0148fad avfilter/af_adynamicequalizer: do detection of threshold first
Makes better results in final output if multiple filters are cascaded at once.
2023-11-05 16:00:29 +01:00
Paul B Mahol
799fad1828 avfilter/af_adynamicequalizer: always start filtering from unit gain 2023-11-05 16:00:28 +01:00
Anton Khirnov
f9fdaa2ca9 configure: warn when threading is disabled
Explicitly state what the implications of this are.
2023-11-05 11:30:13 +01:00
Anton Khirnov
ad3df6bf35 lavf/smacker: export sample_aspect_ratio
Partially fixes #10617
2023-11-05 11:30:13 +01:00
Rob Hall
1a7a85137e ffbuild: Add gzip -n flag to fix reproducible builds
Without this flag, timestamps were embedded into the final
binary if CUDA was enabled.

Signed-off-by: Rob Hall <robxnanocode@outlook.com>
Signed-off-by: Anton Khirnov <anton@khirnov.net>
2023-11-05 11:30:13 +01:00
Paul B Mahol
fd1712b6fb avfilter/af_adynamicequalizer: merge direction option with mode option
More user-friendly and self-explanatory what certain mode does.
2023-11-04 15:39:24 +01:00
Paul B Mahol
43226efc21 avfilter/af_adynamicequalizer: add new structure to hold filtering state 2023-11-04 15:39:23 +01:00
Andreas Rheinhardt
3f890fbfd9 avcodec/cbs_h2645: Fix leak of SPS VUI extension data
Fixes: VUI extension leak
Fixes: 63004/clusterfuzz-testcase-minimized-ffmpeg_BSF_VVC_METADATA_fuzzer-4928832253329408

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:27:41 +01:00
Andreas Rheinhardt
de4846dd18 avfilter/deshake: Merge header into its only user
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:26:25 +01:00
Andreas Rheinhardt
2fdaeec41b avfilter/vf_deshake: Remove unnecessary emms_c
Redundant since ea043cc53e
(which made 16x16 no longer use MMX).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:26:25 +01:00
Andreas Rheinhardt
392ab35db1 avfilter/vf_mpdecimate: Remove emms_c
Unnecessary now that the pixelutils API abides by the ABI.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:26:25 +01:00
Andreas Rheinhardt
5b85ca5317 avutil/x86/pixelutils: Empty MMX state in ff_pixelutils_sad_8x8_mmxext
We currently mostly do not empty the MMX state in our MMX
DSP functions; instead we only do so before code that might
be using x87 code. This is a violation of the System V i386 ABI
(and maybe of other ABIs, too):
"The CPU shall be in x87 mode upon entry to a function. Therefore,
every function that uses the MMX registers is required to issue an
emms or femms instruction after using MMX registers, before returning
or calling another function." (See 2.2.1 in [1])
This patch does not intend to change all these functions to abide
by the ABI; it only does so for ff_pixelutils_sad_8x8_mmxext, as this
function can by called by external users, because it is exported
via the pixelutils API. Without this, the following fragment will
assert (on x86/x64):
    uint8_t src1[8 * 8], src2[8 * 8];
    av_pixelutils_sad_fn fn = av_pixelutils_get_sad_fn(3, 3, 0, NULL);
    fn(src1, 8, src2, 8);
    av_assert0_fpu();

[1]: https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/intel386-psABI-1.1.pdf

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:26:03 +01:00
Andreas Rheinhardt
8661b5e8f9 avfilter/vf_format: Deduplicate inputs
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:24:09 +01:00
Andreas Rheinhardt
c32c1a18b9 avfilter/vsrc_testsrc: Deduplicate outputs
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:24:09 +01:00
Andreas Rheinhardt
748c168f8e avfilter/vf_xmedian: Deduplicate outputs
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:24:09 +01:00
Andreas Rheinhardt
93abb9b560 avfilter/vf_hsvkey: Deduplicate inputs and outputs
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:24:09 +01:00
Andreas Rheinhardt
50d3c5bd8c avfilter/vf_convolve: Deduplicate outputs
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:24:09 +01:00
Andreas Rheinhardt
e557d89ac1 avfilter/vf_chromakey: Deduplicate inputs and outputs
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:24:09 +01:00
Andreas Rheinhardt
2e2c28119f avfilter/vf_blend: Deduplicate outputs
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:24:09 +01:00
Andreas Rheinhardt
1d33a310df avfilter/vf_aspect: Deduplicate inputs
Also avoid using the avfilter-prefix for static objects.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:24:09 +01:00
Andreas Rheinhardt
a40f833bac avfilter/f_graphmonitor: Deduplicate outputs
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:24:09 +01:00
Andreas Rheinhardt
a02670ded7 avfilter/f_drawgraph: Deduplicate outputs
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:24:09 +01:00
Andreas Rheinhardt
5935423e1e avcodec/aactab: Deduplicate swb_offset_960 tabs
swb_offset_960_48 and swb_offset_960_32 coincide.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-04 01:24:09 +01:00
Michael Niedermayer
4fb9d94688 avformat/lafdec: Check for 0 parameters
Fixes: Timeout
Fixes: 63661/clusterfuzz-testcase-minimized-ffmpeg_dem_LAF_fuzzer-6615365234589696

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Reviewed-by: Sean McGovern <gseanmcg@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-03 22:16:33 +01:00
Michael Niedermayer
03a4aa9699 avcodec/flicvideo: consider width in copy loops
Fixes: out of array write
Fixes: 63520/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_FLIC_fuzzer-4876198087622656
Regression since: c7f8d42c12 (was not posted to ffmpeg-devel)

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Reviewed-by: Sean McGovern <gseanmcg@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-03 22:16:33 +01:00
Michael Niedermayer
c0a18e884c avfilter/buffersink: fix order of operation with = and <0
Reviewed-by: Sean McGovern <gseanmcg@gmail.com>
Reviewed-by: Nicolas George <george@nsup.org>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-03 22:17:18 +01:00
Michael Niedermayer
9450a4a7fe avfilter/framesync: fix order of operation with = and <0
Reviewed-by: Sean McGovern <gseanmcg@gmail.com>
Reviewed-by: Nicolas George <george@nsup.org>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-03 22:16:33 +01:00
Andreas Rheinhardt
155f0c8ef7 avformat/webpenc: Check seeks
Addresses the issue reported in ticket #4609.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-03 14:47:57 +01:00
Zhao Zhili
e920a84801 mailmap: remap my email accounts
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2023-11-03 20:57:49 +08:00
Reimar Döffinger
9dd49c8b52 libavutil/log.c: only include valgrind header when used.
This is cleaner, but it is also a workaround for when
the header exists, but cannot be compiled.
This will happen when the compiler has no inline asm
support.
Possibly the configure check should be improved as well.
2023-11-02 21:03:43 +01:00
Reimar Döffinger
0ea184fc39 libavutil/aarch64/cpu.c: HWCAPS requires inline asm support.
Fixes compilation with tcc, which does not have aarch64
inline asm support.
2023-11-02 21:03:43 +01:00
Reimar Döffinger
a31992634f configure: fix _Pragma check.
The test can currently pass when _Pragma is not supported, since
_Pragma might be treated as a implicitly declared function.
This happens e.g. with tinycc.
Extending the check to 2 pragmas both matches the actual use
better and avoids this misdetection.
2023-11-02 21:03:43 +01:00
Andreas Rheinhardt
02064ba3a3 fftools/ffmpeg_mux_init: Restrict disabling automatic copying of metadata
Fixes ticket #10638 (and should also fix ticket #10482)
by restoring the behaviour from before
3c7dd5ed37.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-02 13:24:21 +01:00
zheng qian
4dbfb52230 doc/decoders: correctly note an option's default in libaribcaption
The `-caption_encoding` option was reported as having a default value of
'ass', whereas it's actually 'auto'.

Signed-off-by: zheng qian <xqq@xqq.im>
Signed-off-by: Gyan Doshi <ffmpeg@gyani.pro>
2023-11-02 14:07:00 +05:30
Rémi Denis-Courmont
d06fd18f8f lavc/sbrdsp: R-V V neg_odd_64
With 128-bit vectors, this is mostly pointless but also harmless.
Performance gains should be more noticeable with larger vector sizes.

neg_odd_64_c:       76.2
neg_odd_64_rvv_i64: 74.7
2023-11-01 22:53:26 +02:00
Rémi Denis-Courmont
b0aba7dd0c lavc/sbrdsp: R-V V sum_square
sum_square_c:       803.5
sum_square_rvv_f32: 283.2
2023-11-01 22:53:26 +02:00
Rémi Denis-Courmont
86bee42473 lavc/sbrdsp: R-V V sum64x5
sum64x5_c:       385.0
sum64x5_rvv_f32: 116.0
2023-11-01 22:53:26 +02:00
Andreas Rheinhardt
eba73142ad avcodec/vp9: Join extradata buffer pools
Up until now each thread had its own buffer pool for extradata
buffers when using frame-threading. Each thread can have at most
three references to extradata and in the long run, each thread's
bufferpool seems to fill up with three entries. But given
that at any given time there can be at most 2 + number of threads
entries used (the oldest thread can have two references to preceding
frames that are not currently decoded and each thread has its own
current frame, but there can be no references to any other frames),
this is wasteful. This commit therefore uses a single buffer pool
that is synced across threads.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-01 20:16:02 +01:00
Andreas Rheinhardt
0c44f63b02 avcodec/refstruct: Allow to share pools
To do this, make FFRefStructPool itself refcounted according
to the RefStruct API.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-01 20:15:54 +01:00
Andreas Rheinhardt
92abc7266b avcodec/vaapi_encode: Use RefStruct pool API, stop abusing AVBuffer API
Up until now, the VAAPI encoder uses fake data with the
AVBuffer-API: The data pointer does not point to real memory,
but is instead just a VABufferID converted to a pointer.
This has probably been copied from the VAAPI-hwcontext-API
(which presumably does it to avoid allocations).

This commit changes this without causing additional allocations
by switching to the RefStruct-pool API. This also fixes an
unchecked av_buffer_ref().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-01 20:14:22 +01:00
Andreas Rheinhardt
8c0350f57e avcodec/vp9: Use RefStruct-pool API for extradata
It avoids allocations and corresponding error checks.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-01 20:14:06 +01:00
Andreas Rheinhardt
090d9956fd avcodec/refstruct: Allow to always return zeroed pool entries
This is in preparation for the following commit.

Reviewed-by: Anton Khirnov <anton@khirnov.net>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-01 20:13:40 +01:00
Andreas Rheinhardt
e01e30ede1 avcodec/nvdec: Use RefStruct-pool API for decoder pool
It involves less allocations, in particular no allocations
after the entry has been created. Therefore creating a new
reference from an existing one can't fail and therefore
need not be checked. It also avoids indirections and casts.

Also note that nvdec_decoder_frame_init() (the callback
to initialize new entries from the pool) does not use
atomics to read and replace the number of entries
currently used by the pool. This relies on nvdec (like
most other hwaccels) not being run in a truely frame-threaded
way.

Tested-by: Timo Rothenpieler <timo@rothenpieler.org>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-01 20:13:01 +01:00
Andreas Rheinhardt
fd2e65871c avcodec/hevcdec: Use RefStruct-pool API instead of AVBufferPool API
It involves less allocations and therefore has the nice property
that deriving a reference from a reference can't fail,
simplifying hevc_ref_frame().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-01 20:10:20 +01:00
Andreas Rheinhardt
736b510fcc avcodec/h264dec: Use RefStruct-pool API instead of AVBufferPool API
It involves less allocations and therefore has the nice property
that deriving a reference from a reference can't fail.
This allows for considerable simplifications in
ff_h264_(ref|replace)_picture().
Switching to the RefStruct API also allows to make H264Picture
smaller, because some AVBufferRef* pointers could be removed
without replacement.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-01 20:07:56 +01:00
Andreas Rheinhardt
26c0a7321f avcodec/refstruct: Add RefStruct pool API
Very similar to the AVBufferPool API, but with some differences:
1. Reusing an already existing entry does not incur an allocation
at all any more (the AVBufferPool API needs to allocate an AVBufferRef).
2. The tasks done while holding the lock are smaller; e.g.
allocating new entries is now performed without holding the lock.
The same goes for freeing.
3. The entries are freed as soon as possible (the AVBufferPool API
frees them in two batches: The first in av_buffer_pool_uninit() and
the second immediately before the pool is freed when the last
outstanding entry is returned to the pool).
4. The API is designed for objects and not naked buffers and
therefore has a reset callback. This is called whenever an object
is returned to the pool.
5. Just like with the RefStruct API, custom allocators are not
supported.

(If desired, the FFRefStructPool struct itself could be made
reference counted via the RefStruct API; an FFRefStructPool
would then be freed via ff_refstruct_unref().)

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-11-01 20:07:23 +01:00
Rémi Denis-Courmont
92bcc6703a lavc/pixblockdsp: remove R-V V get_pixels_16
In the aligned case, the existing RVI assembler is actually much
faster. In the unaligned case, there is nothing much to gain over C.
2023-11-01 19:27:22 +02:00
Rémi Denis-Courmont
28840cf499 lavc/jpeg2000dsp: R-V V rct_int
jpeg2000_rct_int_c:       2592.2
jpeg2000_rct_int_rvv_i32: 1154.2
2023-11-01 18:52:55 +02:00
Rémi Denis-Courmont
73dea2bb91 lavc/jpeg2000dsp: R-V V ict_float
jpeg2000_ict_float_c:       3112.2
jpeg2000_ict_float_rvv_f32: 1225.0
2023-11-01 18:52:55 +02:00
Rémi Denis-Courmont
b2a441a3be lavc/jpeg2000dsp: make coefficients extern
This is so that they can be loaded from assembler, rather than
duplicated.
2023-11-01 18:52:55 +02:00
Michael Niedermayer
a5259f326b avcodec/vlc: Pass VLC_MULTI_ELEM directly not by pointer
This makes the code more testable as uninitialized fields are 0
and not random values from the last call

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-01 16:40:22 +01:00
Michael Niedermayer
8516609edd avcodec/vlc: Replace mysterious max computation code in multi vlc
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-01 16:40:21 +01:00
Michael Niedermayer
356b1ba765 avcodec/vlc: Skip subtable entries in multi VLC
These entries do not correspond to VLC symbols that can be used
they do corrupt various variables like min/max bits

This also no longer assumes that there is a single non subtable
entry
Probably fixes some infinite loops too

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-01 16:40:21 +01:00
Michael Niedermayer
c2f2bf82c1 tools/target_dec_fuzzer: Adjust threshold for CSCD
Fixes: Timeout
Fixes: 63362/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_CSCD_fuzzer-4694620065628160

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-01 16:40:21 +01:00
Michael Niedermayer
2817efbba3 avcodec/dovi_rpu: Use 64 bit in get_us/se_coeff()
Fixes: shift exponent 32 is too large for 32-bit type 'int'
Fixes: 63151/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_HEVC_fuzzer-5067531154751488

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-01 16:40:20 +01:00
Michael Niedermayer
2def617787 avcodec/apedec: Fix integer overflow in predictor_decode_stereo_3950()
Fixes: signed integer overflow: 1900031961 + 553590817 cannot be represented in type 'int'
Fixes: 63061/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_APE_fuzzer-5166188298371072

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-01 16:40:20 +01:00
Michael Niedermayer
98c2711b58 avformat/mov: Check that is_still_picture_avif has no trak based streams
Fixes: Assertion failure in mov_read_iloc( in mov_read_iloc())
Fixes: 62866/clusterfuzz-testcase-minimized-ffmpeg_dem_MOV_fuzzer-5282997370486784

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-01 16:40:20 +01:00
Michael Niedermayer
68cc1744db avcodec/evc_parse: Check tid
The check is based on not infinite looping. It is likely
a more strict check can be done

Fixes: Infinite loop
Fixes: 62473/clusterfuzz-testcase-minimized-ffmpeg_BSF_EVC_FRAME_MERGE_fuzzer-5719883750703104
Fixes: 62765/clusterfuzz-testcase-minimized-ffmpeg_dem_EVC_fuzzer-6448531252314112
Fixes: 63378/clusterfuzz-testcase-minimized-ffmpeg_dem_MPEGPS_fuzzer-6504993844494336

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Reviewed-by: "Dawid Kozinski/Multimedia (PLT) /SRPOL/Staff Engineer/Samsung Electronics" <d.kozinski@samsung.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-01 16:40:19 +01:00
Michael Niedermayer
d35eecd24f avcodec/evc_parse: remove pow() and log2()
The use of float based functions is both unneeded and wrong due to unpredictable rounding

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-11-01 16:40:03 +01:00
Andreas Rheinhardt
f2687a3b69 avcodec/wmavoice: Avoid unnecessary VLC structure
Everything besides VLC.table is basically write-only
and even VLC.table can be removed by accessing the
underlying table directly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Andreas Rheinhardt
5615f9dab4 avcodec/wmaprodec: Avoid superfluous VLC structures
For all VLCs here, the number of bits of the VLC is write-only,
because it is hardcoded at the call site. Therefore one can replace
these VLC structures with the only thing that is actually used:
The pointer to the VLCElem table. And in most cases one can even
avoid this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Andreas Rheinhardt
7e2120c4d9 avcodec/mpeg12: Avoid unnecessary VLC structures
Everything besides VLC.table is basically write-only
and even VLC.table can be removed by accessing the
underlying tables directly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Andreas Rheinhardt
c9aa80c313 avcodec/mpegaudiodec_common: Avoid superfluous VLC structures
For some VLCs here, the number of bits of the VLC is
write-only, because it is hardcoded at the call site.
Therefore one can replace these VLC structures with
the only thing that is actually used: The pointer
to the VLCElem table.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Andreas Rheinhardt
5dc31bc67b avcodec/aacps_common: Apply offset for VLCs during init
This avoids having to apply it later after every get_vlc2().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Andreas Rheinhardt
40a8cb9e6c avcodec/aacps_common: Combine huffman tabels
This allows to avoid the relocations inherent in an array
to individual tables; it also reduces padding.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Andreas Rheinhardt
774611a349 avcodec/aacps_common: Switch to ff_vlc_init_tables_from_lengths()
It allows to replace codes of type uint16_t or uint32_t
by symbols of type uint8_t.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Andreas Rheinhardt
eb422c606a avcodec/aacps_common: Avoid superfluous VLC structures
For all VLCs here, the number of bits of the VLC is
write-only, because it is hardcoded at the call site.
Therefore one can replace these VLC structures with
the only thing that is actually used: The pointer
to the VLCElem table.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Andreas Rheinhardt
4fe91e3676 avcodec/aacps: Move initializing common stuff to aacdec_common.c
ff_ps_init() initializes some tables for AAC parametric stereo
and some of them are only valid for the fixed- or floating-point
decoder, whereas others (namely VLCs) are valid for both.
The latter are therefore initialized by ff_ps_init_common()
and because the two versions of ff_ps_init() can be run
concurrently, it is guarded by an AVOnce.

Yet now that there is ff_aacdec_common_init_once() there is
a better way to do this: Call ff_ps_init_common()
from ff_aacdec_common_init_once(). That way there is no need
to guard ff_ps_init_common() by an AVOnce any more.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Andreas Rheinhardt
7f66d9d6c5 avcodec/aacdec_common: Apply offset for SBR VLCs during init
This avoids having to apply it later after every get_vlc2().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Andreas Rheinhardt
1aca4e7fc5 avcodec/aacdec_common: Combine huffman tabs
This allows to avoid the relocations inherent in a table
to individual tables; it also reduces padding.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Andreas Rheinhardt
2c131f126d avcodec/aacdec_common: Switch to ff_vlc_init_tables_from_lengths()
It allows to replace code tables of type uint32_t or uint16_t
by symbols of type uint8_t. It is also faster.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Andreas Rheinhardt
0b4e69cc87 avcodec/aacdec_common: Avoid superfluous VLC structures for SBR VLCs
For all VLCs here, the number of bits of the VLC is
write-only, because it is hardcoded at the call site.
Therefore one can replace these VLC structures with
the only thing that is actually used: The pointer
to the VLCElem table.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Andreas Rheinhardt
22d60524d8 avcodec/aacsbr_template: Deduplicate VLCs
The VLCs, their init code and the tables used for initialization
are currently duplicated for the floating- and fixed-point decoders.
This commit stops doing so and moves this stuff to aacdec_common.c.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Andreas Rheinhardt
4d6042e9d7 avcodec/aacdec_common: Avoid superfluous VLC structures
For all VLCs here, the number of bits of the VLC is
write-only, because it is hardcoded at the call site.
Therefore one can replace these VLC structures with
the only thing that is actually used: The pointer
to the VLCElem table. And in some cases one can even
avoid this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 21:44:48 +01:00
Lynne
0e8abf2698 bwdif_vulkan: fix artifacts on vulkan decode images
Due to making the decode frames context use the coded size, the
filter started to display those artifacts as it reused the input frame's size.

Change it to instead output the real image size for images, not the input.
2023-10-31 21:35:28 +01:00
Benjamin Cheng
4536de3769 vulkan_h264: fix long-term ref handling
h->long_ref isn't guaranteed to be contiguously filled. Use the approach
from both vaapi_h264 and vdpau_h264 which goes through the 16 frames in
h->long_ref to find the LTR entries.

Fixes MR2_MW_A.264 from JVT-AVC_V1.
2023-10-31 21:35:23 +01:00
Andreas Rheinhardt
1e63e24c76 avcodec/aactab: Improve included headers
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
30deaba97b avcodec/aacdec_template: Don't init unused table for fixed-point decoder
The fixed-point decoder actually does not use the floating-point
tables initialized by ff_aac_tableinit() at all. So don't
initialize them for it; instead merge initializing these tables
into ff_aac_float_common_init() which is already the function
for the common static initializations of the floating-point
AAC decoder and the (also floating-point) AAC encoder.
Doing so saves also one AVOnce.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
3b080fe7af avcodec/aacdec_template: Deduplicate VLCs
They (as well as their init code) are currently duplicated
for the floating- and fixed-point decoders.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
1f15a7e9a8 avcodec/aacdectab: Deduplicate common decoder tables
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
8c1e71a811 avcodec/aacps: Pass logctx as void* instead of AVCodecContext*
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
70b5d9c569 avcodec/aacps: Remove unused AVCodecContext* parameter from ff_ps_apply
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
36b5f71b1f avcodec/msmpeg4dec: Avoid superfluous VLC structures
For all VLCs here, the number of bits of the VLC is write-only,
because it is hardcoded at the call site. Therefore one can replace
these VLC structures with the only thing that is actually used:
The pointer to the VLCElem table. And in some cases one can even
avoid this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
5a694d62c5 avcodec/mpeg4videodec: Avoid superfluous VLC structures
For all VLCs here, the number of bits of the VLC is
write-only, because it is hardcoded at the call site.
Therefore one can replace these VLC structures with
the only thing that is actually used: The pointer
to the VLCElem table. And in some cases one can even
avoid this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
8c39b2bca7 avcodec/mss4: Partially inline max_depth and nb_bits of VLC
It is known at compile-time for the vec_entry_vlcs.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
05577d2c76 avcodec/indeo2: Avoid unnecessary VLC structure
Everything besides VLC.table is basically write-only
and even VLC.table can be removed by accessing the
underlying table directly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
25b9ff2780 avcodec/4xm: Avoid unnecessary VLC structures
Everything besides VLC.table is basically write-only
and even VLC.table can be removed by accessing the
underlying table directly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
e5dcde620d avcodec/vc1: Avoid superfluous VLC structures
For all VLCs here, the number of bits of the VLC is
write-only, because it is hardcoded at the call site.
Therefore one can replace these VLC structures with
the only thing that is actually used: The pointer
to the VLCElem table. And in some cases one can even
avoid this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
fd4cb6ebee avcodec/speedhqdec: Avoid unnecessary VLC structure
Everything besides VLC.table is basically write-only
and even VLC.table can be removed by accessing the
underlying table directly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
0a610e22c1 avcodec/lagarith: Avoid unnecessary VLC structure
Everything besides VLC.table is basically write-only
and even VLC.table can be removed by accessing the
underlying table directly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
e3ad5b9784 avcodec/imm4: Avoid unnecessary VLC structure
Everything besides VLC.table is basically write-only
and even VLC.table can be removed by accessing the
underlying table directly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
f6c5d04b6d avcodec/mimic: Avoid unnecessary VLC structure
Everything besides VLC.table is basically write-only
and even VLC.table can be removed by accessing the
underlying table directly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
827d0325a9 avcodec/mobiclip: Avoid unnecessary VLC structure
Everything besides VLC.table is basically write-only
and only VLC.table needs to be retained.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
36e7f9b339 avcodec/vqcdec: Avoid unnecessary VLC structure
Everything besides VLC.table is basically write-only
and even VLC.table can be removed by accessing the
underlying table directly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
99ed510d4b avcodec/mv30: Avoid unnecessary VLC structure
Everything besides VLC.table is basically write-only
and even VLC.table can be removed by accessing the
underlying table directly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
b60a3f70be avcodec/wnv1: Avoid unnecessary VLC structure
Everything besides VLC.table is basically write-only
and even VLC.table can be removed by accessing the
underlying table directly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
1ae750a16e avcodec/rv34: Constify pointer to static object
Said object is only allowed to be modified during its
initialization and is immutable afterwards.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
716ddc8c62 avcodec/rv34: Avoid superfluous VLC structures
For most VLCs here, the number of bits of the VLC is
write-only, because it is hardcoded at the call site.
Therefore one can replace these VLC structures with
the only thing that is actually used: The pointer
to the VLCElem table.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
73fa6d486d avcodec/vp3: Reindent after the previous commits
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
75c6a253a4 avcodec/vp3: Avoid complete VLC struct, only use VLCElem*
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
6c7a344b65 avcodec/vp3: Share coefficient VLCs between threads
These VLCs are very big: The VP3 one have 164382 elements
but due to the overallocation enough memory for 313344 elements
are allocated (1.195 MiB with sizeof(VLCElem) == 4);
for VP4 the numbers are very similar, namely 311296 and 164392
elements. Since 1f4cf92cfb, each
frame thread has its own copy of these VLCs.

This commit fixes this by sharing these VLCs across threads.
The approach used here will also make it easier to support
stream reconfigurations in case of frame-multithreading
in the future.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
7fee90efac avcodec/imc: Avoid superfluous VLC structures
Of all these VLCs here, only VLC.table was really used
after init, so use the ff_vlc_init_tables API
to get rid of them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
6fb96ef755 avcodec/atrac9dec: Avoid superfluous VLC structures
Of all these VLCs here, only VLC.table was really used
after init, so use the ff_vlc_init_tables API
to get rid of them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
4c7e8b969e avcodec/clearvideo: Avoid superfluous VLC structures
Of all these VLCs here, only VLC.table was really used
after init, so use the ff_vlc_init_tables API
to get rid of them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
c95e123e8c avcodec/intrax8: Avoid superfluous VLC structures
Of all these VLCs here, only VLC.table was really used
after init, so use the ff_vlc_init_tables API
to get rid of them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
886fbec82f avcodec/mpc7: Avoid superfluous VLC structures
Of all these VLCs here, only VLC.table was really used
after init, so use the ff_vlc_init_tables API
to get rid of them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
e5e05fd3c8 avcodec/rv40: Avoid superfluous VLC structures
Of all these VLCs here, only VLC.table was really used
after init, so use the ff_vlc_init_tables API
to get rid of them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
460c6ae597 avcodec/svq1dec: Increase size of VLC
It allows to reduce the number of maximum reloads by one.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
7d542e26a9 avcodec/svq1dec: Avoid superfluous VLC structures
Of all these VLCs here, only VLC.table was really used
after init, so use the ff_vlc_init_tables API
to get rid of them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:47:00 +01:00
Andreas Rheinhardt
7902c0df4c avcodec/msmpeg4_vc1_data: Avoid superfluous VLC structures
Of all these VLCs here, only VLC.table was really used
after init, so use the ff_vlc_init_tables API
to get rid of them.
Also combine the ff_msmp4_dc_(luma|chroma)_vlcs as well
as the tables used to generate them to simplify the code.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:46:59 +01:00
Andreas Rheinhardt
ff886fc282 avcodec/ituh263dec: Avoid superfluous VLC structures
Of all these VLCs here, only VLC.table was really used
after init, so use the ff_vlc_init_tables API
to get rid of them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:46:59 +01:00
Andreas Rheinhardt
5a9e185dfc avcodec/h261dec: Avoid superfluous VLC structures
Of all these VLCs here, only VLC.table was really used
after init, so use the ff_vlc_init_tables API
to get rid of them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:46:59 +01:00
Andreas Rheinhardt
363837de0e avcodec/faxcompr: Avoid superfluous VLC structures
Of all these VLCs here, only VLC.table was really used
after init, so use the ff_vlc_init_tables API
to get rid of them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:46:59 +01:00
Andreas Rheinhardt
a99285aedf avcodec/asvdec: Avoid superfluous VLC structures
Of all these VLCs here, only VLC.table was really used
after init, so use the ff_vlc_init_tables API
to get rid of them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:46:59 +01:00
Andreas Rheinhardt
ab8a8246c8 avcodec/h264_cavlc: Remove code duplication
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:46:59 +01:00
Andreas Rheinhardt
bd4c778e19 avcodec/h264_cavlc: Avoid indirection for coefficient table VLCs
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:46:59 +01:00
Andreas Rheinhardt
fe748ddf62 avcodec/h264_cavlc: Avoid superfluous VLC structures
Of all these VLCs here, only VLC.table was really used
after init, so use the ff_vlc_init_tables API
to get rid of them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:46:59 +01:00
Andreas Rheinhardt
c630d76b27 avcodec/vp3: Increase some VLC tables
These are quite small and therefore force reloads
that can be avoided by modest increases in the number of bits used.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:46:59 +01:00
Andreas Rheinhardt
1fee3a3dce avcodec/vp3: Make VLC tables static where possible
This is especially important for frame-threaded decoders like
this one, because up until now each thread had an identical
copy of all these VLC tables.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:46:59 +01:00
Andreas Rheinhardt
edc50658d9 avcodec/vlc: Add functions to init static VLCElem[] without VLC
For lots of static VLCs, the number of bits is not read from
VLC.bits, but rather a compile-constant that is hardcoded
at the callsite of get_vlc2(). Only VLC.table is ever used
and not using it directly is just an unnecessary indirection.

This commit adds helper functions and macros to avoid the VLC
structure when initializing VLC tables; there are 2x2 functions:
Two choices for init_sparse or from_lengths and two choices
for "overlong" initialization (as used when multiple VLCs are
initialized that share the same underlying table).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2023-10-31 20:46:59 +01:00
Rémi Denis-Courmont
424c8ceb08 lavc/huffyuvdsp: R-V V add_int16
add_int16_128_c:      2390.5
add_int16_128_rvv_i32: 832.0
add_int16_rnd_width_c:      2390.2
add_int16_rnd_width_rvv_i32: 832.5
2023-10-31 21:33:25 +02:00
Rémi Denis-Courmont
7e1cdc69fb lavc/utvideodsp: R-V V restore_rgb_planes10
restore_rgb_planes10_c:      185852.2
restore_rgb_planes10_rvv_i32: 90130.5
2023-10-31 21:33:25 +02:00
Rémi Denis-Courmont
4aea0da230 lavc/utvideodsp: R-V V restore_rgb_planes
restore_rgb_planes_c:      133065.7
restore_rgb_planes_rvv_i32: 33317.2
2023-10-31 21:33:25 +02:00
Niklas Haas
6aff17a451 avformat/vf_vapoursynth: simplify xyz format check 2023-10-31 15:46:38 +01:00
Niklas Haas
93f07d98d9 avutil/pixdesc: simplify xyz pixfmt check 2023-10-31 15:46:38 +01:00
Niklas Haas
d312a33ed2 avfilter/drawutils: remove redundant xyz format check
The code above this does a whitelist on desc->flags, which now includes
the (disallowed) AV_PIX_FMT_FLAG_XYZ for XYZ formats. So there is no
more need for a separate check, here.
2023-10-31 15:46:38 +01:00
Niklas Haas
57c16323f2 avutil/pixdesc: add AV_PIX_FMT_FLAG_XYZ
There are already several places in the codebase that match desc->name
against "xyz", and many downstream clients replicate this behavior.
I have no idea why this is not just a flag.

Motivated by my desire to add yet another check for XYZ to the codebase,
and I'd rather not keep copy/pasting a string comparison hack.
2023-10-31 15:46:07 +01:00
Niklas Haas
96dfc4481b avfilter/drawutils: ban XYZ formats
These are not supported by the drawing functions at all, and were
incorrectly advertised as supported in the past.

Note: This check is added only to separate the logic change from the API
change in the following commit, and will be removed again after it
becomes redundant.
2023-10-31 15:43:30 +01:00
Logan Lyu
55f28eb627 lavc/aarch64: new optimization for 8-bit hevc_qpel_hv
checkasm bench:
put_hevc_qpel_hv4_8_c: 422.1
put_hevc_qpel_hv4_8_i8mm: 101.6
put_hevc_qpel_hv6_8_c: 756.4
put_hevc_qpel_hv6_8_i8mm: 225.9
put_hevc_qpel_hv8_8_c: 1189.9
put_hevc_qpel_hv8_8_i8mm: 296.6
put_hevc_qpel_hv12_8_c: 2407.4
put_hevc_qpel_hv12_8_i8mm: 552.4
put_hevc_qpel_hv16_8_c: 4021.4
put_hevc_qpel_hv16_8_i8mm: 886.6
put_hevc_qpel_hv24_8_c: 8992.1
put_hevc_qpel_hv24_8_i8mm: 1968.9
put_hevc_qpel_hv32_8_c: 15197.9
put_hevc_qpel_hv32_8_i8mm: 3209.4
put_hevc_qpel_hv48_8_c: 32811.1
put_hevc_qpel_hv48_8_i8mm: 7442.1
put_hevc_qpel_hv64_8_c: 58106.1
put_hevc_qpel_hv64_8_i8mm: 12423.9

Co-Authored-By: J. Dekker <jdek@itanimul.li>
Signed-off-by: Martin Storsjö <martin@martin.st>
2023-10-31 14:14:21 +02:00
Logan Lyu
97a9d12657 lavc/aarch64: new optimization for 8-bit hevc_qpel_v
checkasm bench:

put_hevc_qpel_v4_8_c: 138.1
put_hevc_qpel_v4_8_neon: 41.1
put_hevc_qpel_v6_8_c: 276.6
put_hevc_qpel_v6_8_neon: 60.9
put_hevc_qpel_v8_8_c: 478.9
put_hevc_qpel_v8_8_neon: 72.9
put_hevc_qpel_v12_8_c: 1072.6
put_hevc_qpel_v12_8_neon: 203.9
put_hevc_qpel_v16_8_c: 1852.1
put_hevc_qpel_v16_8_neon: 264.1
put_hevc_qpel_v24_8_c: 4137.6
put_hevc_qpel_v24_8_neon: 586.9
put_hevc_qpel_v32_8_c: 7579.1
put_hevc_qpel_v32_8_neon: 1036.6
put_hevc_qpel_v48_8_c: 16355.6
put_hevc_qpel_v48_8_neon: 2326.4
put_hevc_qpel_v64_8_c: 33545.1
put_hevc_qpel_v64_8_neon: 4126.4

Co-Authored-By: J. Dekker <jdek@itanimul.li>
Signed-off-by: Martin Storsjö <martin@martin.st>
2023-10-31 14:14:21 +02:00
Logan Lyu
265450b89e lavc/aarch64: new optimization for 8-bit hevc_epel_hv
checkasm bench:
put_hevc_epel_hv4_8_c: 213.7
put_hevc_epel_hv4_8_i8mm: 59.4
put_hevc_epel_hv6_8_c: 350.9
put_hevc_epel_hv6_8_i8mm: 130.2
put_hevc_epel_hv8_8_c: 548.7
put_hevc_epel_hv8_8_i8mm: 136.9
put_hevc_epel_hv12_8_c: 1126.7
put_hevc_epel_hv12_8_i8mm: 302.2
put_hevc_epel_hv16_8_c: 1925.2
put_hevc_epel_hv16_8_i8mm: 459.9
put_hevc_epel_hv24_8_c: 4301.9
put_hevc_epel_hv24_8_i8mm: 1024.9
put_hevc_epel_hv32_8_c: 7509.2
put_hevc_epel_hv32_8_i8mm: 1680.4
put_hevc_epel_hv48_8_c: 16566.9
put_hevc_epel_hv48_8_i8mm: 3945.4
put_hevc_epel_hv64_8_c: 29134.2
put_hevc_epel_hv64_8_i8mm: 6567.7

Co-Authored-By: J. Dekker <jdek@itanimul.li>
Signed-off-by: Martin Storsjö <martin@martin.st>
2023-10-31 14:02:53 +02:00
Logan Lyu
22c7291506 lavc/aarch64: new optimization for 8-bit hevc_epel_v
checkasm bench:
put_hevc_epel_v4_8_c: 79.9
put_hevc_epel_v4_8_neon: 25.7
put_hevc_epel_v6_8_c: 151.4
put_hevc_epel_v6_8_neon: 46.4
put_hevc_epel_v8_8_c: 250.9
put_hevc_epel_v8_8_neon: 41.7
put_hevc_epel_v12_8_c: 542.7
put_hevc_epel_v12_8_neon: 108.7
put_hevc_epel_v16_8_c: 939.4
put_hevc_epel_v16_8_neon: 169.2
put_hevc_epel_v24_8_c: 2104.9
put_hevc_epel_v24_8_neon: 307.9
put_hevc_epel_v32_8_c: 3713.9
put_hevc_epel_v32_8_neon: 524.2
put_hevc_epel_v48_8_c: 8175.2
put_hevc_epel_v48_8_neon: 1197.2
put_hevc_epel_v64_8_c: 16049.4
put_hevc_epel_v64_8_neon: 2094.9

Co-Authored-By: J. Dekker <jdek@itanimul.li>
Signed-off-by: Martin Storsjö <martin@martin.st>
2023-10-31 14:02:53 +02:00
Logan Lyu
772865717b lavc/aarch64: new optimization for 8-bit hevc_epel_pixels and and hevc_qpel_pixels
checkasm bench:
put_hevc_pel_pixels4_8_c: 33.7
put_hevc_pel_pixels4_8_neon: 20.2
put_hevc_pel_pixels6_8_c: 61.4
put_hevc_pel_pixels6_8_neon: 25.4
put_hevc_pel_pixels8_8_c: 121.4
put_hevc_pel_pixels8_8_neon: 16.9
put_hevc_pel_pixels12_8_c: 199.9
put_hevc_pel_pixels12_8_neon: 40.2
put_hevc_pel_pixels16_8_c: 355.9
put_hevc_pel_pixels16_8_neon: 43.4
put_hevc_pel_pixels24_8_c: 774.7
put_hevc_pel_pixels24_8_neon: 78.9
put_hevc_pel_pixels32_8_c: 1345.2
put_hevc_pel_pixels32_8_neon: 152.2
put_hevc_pel_pixels48_8_c: 2963.7
put_hevc_pel_pixels48_8_neon: 309.4
put_hevc_pel_pixels64_8_c: 5236.2
put_hevc_pel_pixels64_8_neon: 514.2

Co-Authored-By: J. Dekker <jdek@itanimul.li>
Signed-off-by: Martin Storsjö <martin@martin.st>
2023-10-31 14:02:53 +02:00
Martin Storsjö
2c3d2a0245 configure: Improve aarch64 feature detection on older, broken Clang versions
Clang versions before 17 (Xcode versions up to and including 15.0)
had a very annoying bug in its behaviour of the ".arch" directive
in assembly. If the directive only contained a level, such as
".arch armv8.2-a", it did validate the name of the level, but it
didn't apply the level to what instructions are allowed. The level
was applied if the directive contained an extra feature enabled,
such as ".arch armv8.2-a+crc" though. It was also applied on the
next ".arch_extension" directive.

This bug, combined with the fact that the same versions of Clang
didn't support the dotprod/i8mm extension names in either
".arch <level>+<feature>" or in ".arch_extension", could lead to
unexepcted build failures.

As the dotprod/i8mm extensions couldn't be enabled dynamically
via the ".arch_extension" directive, someone building ffmpeg could
try to enable them by configuring their build with
--extra-cflags="-march=armv8.6-a".

During configure, we test for support for the i8mm instructions
like this:

    # Built with -march=armv8.6-a
    .arch armv8.2-a             # Has no visible effect here
    #.arch_extension i8mm       # Omitted as the extension name isn't known
    usdot v0.4s, v0.16b, v0.16b
    # Successfully assembled as armv8.6-a is the effective level,
    # and i8mm is enabled implicitly in armv8.6-a.

Thus, we would enable assembling those instructions. However if
we later check for another extension, such as sve (which those
versions of Clang actually do support), we can later run into the
following situation when building actual code:

    # Built with -march=armv8.6-a
    .arch armv8.2-a             # Has no visible effect here
    #.arch_extension i8mm       # Omitted as the extension name isn't known
    .arch_extension sve         # Included as "sve" is as supported extension name
    # .arch_extension effectively activates the previous .arch directive,
    # so the effective level is armv8.2-a+sve now.
    usdot v0.4s, v0.16b, v0.16b
    # Fails to build the instructions that require i8mm. Despite the
    # configure check, the unrelated ".arch_extension sve" directive
    # breaks the functionality of the i8mm feature.

This patch avoids this situation:
- By adding a dummy feature such as "+crc" on the .arch directive
  (if supported), we make sure that it does get applied immediately,
  avoiding it taking effect spuriously at a later unrelated
  ".arch_extension" directive.
- By checking for higher arch levels such as armv8.4-a and armv8.6-a,
  we can assemble the dotprod and i8mm extensions without the user
  needing to pass -march=armv8.6-a. This allows using the dotprod/i8mm
  codepaths via runtime detection while keeping the binary runnable
  on older versions. I.e. this enables the i8mm codepaths on Apple M2
  machines while built with Xcode's Clang.

TL;DR: Enable the I8MM extensions for Apple M2 without the user needing
to do a custom configuration; avoid potential build breakage if a user
does such a custom configuration.

Once Xcode versions that have these issues fixed are prevalent, we
can consider reverting this change.

Signed-off-by: Martin Storsjö <martin@martin.st>
2023-10-31 12:23:31 +02:00
Martin Storsjö
f05948ada4 aarch64: Simplify the linux runtime cpu detection code
Skip doing the whole getauxval(AT_HWCAP) if HWCAP_CPUID isn't
defined.

Signed-off-by: Martin Storsjö <martin@martin.st>
2023-10-31 12:23:27 +02:00
Rémi Denis-Courmont
ae72412aa8 lavc/idctdsp: improve R-V V put_pixels_clamped 2023-10-30 18:14:16 +02:00
Rémi Denis-Courmont
d48810f3a5 lavc/idctdsp: improve R-V V add_pixels_clamped 2023-10-30 18:14:16 +02:00
Rémi Denis-Courmont
600c6f1b55 lavc/idctdsp: improve R-V V put_signed_pixels_clamped
This follows the same idea as with pixblockdsp, but applied at the
other end, whilst writing data at the end of the function.
2023-10-30 18:14:16 +02:00
Rémi Denis-Courmont
3ea2310e89 lavc/idctdsp: require Zve64x for R-V V functions
This will be required for the following changesets.
2023-10-30 18:14:16 +02:00
Rémi Denis-Courmont
300ee8b02d lavc/pixblockdsp: aligned R-V V 8-bit functions
If the scan lines are aligned, we can load each row as a 64-bit value,
thus avoiding segmentation. And then we can factor the conversion or
subtraction.

In principle, the same optimisation should be possible for high depth,
but would require 128-bit elements, for which no FFmpeg CPU flag
exists.
2023-10-30 18:14:16 +02:00
Rémi Denis-Courmont
722765687b lavc/pixblockdsp: rename unaligned R-V V functions 2023-10-30 18:14:16 +02:00
Paul B Mahol
6323ca5902 avfilter/vf_feedback: add timeline support 2023-10-30 16:06:46 +01:00
Paul B Mahol
2f268505b9 doc/filters: add one more example for feedback filter 2023-10-30 15:12:12 +01:00
James Almer
4cba3e0f07 avutil/video_enc_params: fix doxy for av_video_enc_params_block()
Reviewed-by: Anton Khirnov <anton@khirnov.net>
Signed-off-by: James Almer <jamrial@gmail.com>
2023-10-30 10:30:05 -03:00
Kieran Kunhya
2532e832d2 libavcodec/mpeg12: Reindent 2023-10-29 22:12:05 +00:00
Kieran Kunhya
7d497a1119 libavcodec/mpeg12: Remove "fast" mode 2023-10-29 22:12:02 +00:00
Rémi Denis-Courmont
04b49fb3c5 lavu/riscv: fix typo 2023-10-29 22:15:15 +02:00
TADANO Tokumei
a824c6f2f6 lavc/libaribcaption: rename replace_fullwidth_ascii to replace_msz_ascii
This should hopefully clarify that the option only affects MSZ
full-width characters, and not all full-width ASCII. Additionally,
this matches the prefix with the upstream option.

Signed-off-by: TADANO Tokumei <aimingoff@pc.nifty.jp>
2023-10-29 18:21:05 +02:00
TADANO Tokumei
21bfadd9b4 lavc/libaribcaption: add MSZ character related options
This patch adds two MSZ (Middle Size; half width) character
related options, mapping against newly added upstream
functionality:

* `replace_msz_japanese`, which was introduced in version 1.0.1
  of libaribcaption.
* `replace_msz_glyph`, which was introduced in version 1.1.0
  of libaribcaption.

The latter option improves bitmap type rendering if specified
fonts contain half-width glyphs (e.g., BIZ UDGothic), even
if both ASCII and Japanese MSZ replacement options are set
to false.

As these options require newer versions of libaribcaption, the
configure requirement has been bumped accordingly.

Signed-off-by: TADANO Tokumei <aimingoff@pc.nifty.jp>
2023-10-29 18:20:43 +02:00
TADANO Tokumei
82faba8a6c lavc/libaribcaption: switch all bool context variables to int
On some environments, a `bool` variable is of smaller size than `int`.
As AV_OPT_TYPE_BOOL is internally handled as sizeof(int), if a `bool`
option was set on such an environment, the memory of following
variables would be filled. Additionally, set values may be destroyed
by av_opt_copy().

Signed-off-by: TADANO Tokumei <aimingoff@pc.nifty.jp>
2023-10-29 18:19:58 +02:00
James Almer
ff3429991e Changelog: mark 6.1
Signed-off-by: James Almer <jamrial@gmail.com>
2023-10-29 12:55:37 -03:00
Michael Niedermayer
47e784f881 Bump versions after 6.1
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-10-29 16:19:14 +01:00
Michael Niedermayer
0e15b2b828 doc/APIchanges: Add 6.1 cut point
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-10-29 16:19:14 +01:00
Michael Niedermayer
9d3a7d30c4 Bump versions prior to 6.1
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2023-10-29 15:34:05 +01:00
Zhao Zhili
105657540b avutil/hwcontext_vaapi: return ENOSYS for unsupported operation
av_hwframe_transfer_data try with src_ctx first. If the operation
failed with AVERROR(ENOSYS), it will try again with dst_ctx. Return
AVERROR(EINVAL) makes the second step being skipped.

Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2023-10-29 13:58:52 +08:00
Zhao Zhili
63078b4599 avutil/hwcontext_vulkan: cuda doesn't belong to valid_sw_formats
Move it to transfer_get_formats.

Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2023-10-29 13:58:30 +08:00
Zhao Zhili
891f70c6d5 avutil/hwcontext_vulkan: fix memleak when device_create is skipped
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2023-10-29 13:57:43 +08:00
266 changed files with 9041 additions and 3795 deletions

View File

@@ -1,8 +1,8 @@
<jeebjp@gmail.com> <jan.ekstrom@aminocom.com>
<sw@jkqxz.net> <mrt@jkqxz.net>
<u@pkh.me> <cboesch@gopro.com>
<zhilizhao@tencent.com> <quinkblack@foxmail.com>
<zhilizhao@tencent.com> <wantlamy@gmail.com>
<quinkblack@foxmail.com> <wantlamy@gmail.com>
<quinkblack@foxmail.com> <zhilizhao@tencent.com>
<modmaker@google.com> <modmaker-at-google.com@ffmpeg.org>
<stebbins@jetheaddev.com> <jstebbins@jetheaddev.com>
<barryjzhao@tencent.com> <mypopydev@gmail.com>

View File

@@ -1,6 +1,9 @@
Entries are sorted chronologically from oldest to youngest within each release,
releases are sorted from youngest to oldest.
version <next>:
- LEAD MCMP decoder
version 6.1:
- libaribcaption decoder
- Playdate video decoder and demuxer

View File

@@ -268,11 +268,11 @@ Codecs:
Hardware acceleration:
dxva2* Hendrik Leppkes, Laurent Aimar, Steve Lhomme
d3d11va* Steve Lhomme
mediacodec* Matthieu Bouron, Aman Gupta
mediacodec* Matthieu Bouron, Aman Gupta, Zhao Zhili
vaapi* Haihao Xiang
vaapi_encode* Mark Thompson, Haihao Xiang
vdpau* Philip Langdale, Carl Eugen Hoyos
videotoolbox* Rick Kern, Aman Gupta
videotoolbox* Rick Kern, Aman Gupta, Zhao Zhili
libavdevice

View File

@@ -1 +1 @@
6.1
5.1.git

View File

@@ -1,15 +0,0 @@
┌──────────────────────────────────────────┐
│ RELEASE NOTES for FFmpeg 6.1 "Heaviside" │
└──────────────────────────────────────────┘
The FFmpeg Project proudly presents FFmpeg 6.1 "Heaviside", about 8
months after the release of FFmpeg 6.0.
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.libera.chat) or ask
on the mailing-lists.

36
configure vendored
View File

@@ -2471,6 +2471,7 @@ CONFIG_EXTRA="
cbs_h266
cbs_jpeg
cbs_mpeg2
cbs_vp8
cbs_vp9
deflate_wrapper
dirac_parse
@@ -2756,6 +2757,7 @@ cbs_h265_select="cbs"
cbs_h266_select="cbs"
cbs_jpeg_select="cbs"
cbs_mpeg2_select="cbs"
cbs_vp8_select="cbs"
cbs_vp9_select="cbs"
deflate_wrapper_deps="zlib"
dirac_parse_select="golomb"
@@ -2887,6 +2889,7 @@ ipu_decoder_select="mpegvideodec"
jpegls_decoder_select="mjpeg_decoder"
jv_decoder_select="blockdsp"
lagarith_decoder_select="llviddsp"
lead_decoder_select="idctdsp jpegtables"
ljpeg_encoder_select="jpegtables"
lscr_decoder_select="inflate_wrapper"
magicyuv_decoder_select="llviddsp"
@@ -3339,7 +3342,7 @@ h264_redundant_pps_bsf_select="cbs_h264"
hevc_metadata_bsf_select="cbs_h265"
mjpeg2jpeg_bsf_select="jpegtables"
mpeg2_metadata_bsf_select="cbs_mpeg2"
trace_headers_bsf_select="cbs"
trace_headers_bsf_select="cbs cbs_vp8"
vp9_metadata_bsf_select="cbs_vp9"
vvc_metadata_bsf_select="cbs_h266"
@@ -3903,7 +3906,7 @@ ffmpeg_select="aformat_filter anull_filter atrim_filter format_filter
ffmpeg_suggest="ole32 psapi shell32"
ffplay_deps="avcodec avformat avfilter swscale swresample sdl2"
ffplay_select="crop_filter transpose_filter hflip_filter vflip_filter rotate_filter"
ffplay_suggest="shell32"
ffplay_suggest="shell32 libplacebo vulkan"
ffprobe_deps="avcodec avformat"
ffprobe_suggest="shell32"
@@ -5984,7 +5987,7 @@ for restrict_keyword in restrict __restrict__ __restrict ""; do
test_code cc "" "char * $restrict_keyword p" && break
done
check_cc pragma_deprecated "" '_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")'
check_cc pragma_deprecated "" '_Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")'
# The global variable ensures the bits appear unchanged in the object file.
test_cc <<EOF || die "endian test failed"
@@ -6045,7 +6048,26 @@ check_inline_asm inline_asm_nonlocal_labels '"Label:\n"'
if enabled aarch64; then
as_arch_level="armv8-a"
check_as as_arch_directive ".arch $as_arch_level"
enabled as_arch_directive && check_arch_level armv8.2-a
if enabled as_arch_directive; then
# Check for higher .arch levels. We only need armv8.2-a in order to
# enable the extensions we want below - we primarily want to control
# them via .arch_extension. However:
#
# Clang before version 17 (Xcode versions up to and including 15.0)
# didn't support controlling the dotprod/i8mm extensions via
# .arch_extension; thus try to enable them via the .arch level as well.
for level in armv8.2-a armv8.4-a armv8.6-a; do
check_arch_level $level
done
# Clang before version 17 (Xcode versions up to and including 15.0)
# also had a bug (https://github.com/llvm/llvm-project/issues/32220)
# causing a plain ".arch <level>" to not have any effect unless it
# had an extra "+<feature>" included - but it was activate on the next
# ".arch_extension" directive. Check if we can include "+crc" as dummy
# feature to make the .arch directive behave as expected and take
# effect right away.
check_arch_level "${as_arch_level}+crc"
fi
enabled armv8 && check_insn armv8 'prfm pldl1strm, [x0]'
# internal assembler in clang 3.3 does not support this instruction
@@ -7504,6 +7526,12 @@ check_deps $CONFIG_LIST \
enabled threads && ! enabled pthreads && ! enabled atomics_native && die "non pthread threading without atomics not supported, try adding --enable-pthreads or --cpu=i486 or higher if you are on x86"
enabled threads || warn \
"Threading support was disabled or is not available on the target platform." \
"This means that not only is this build not multi-threaded, but also" \
"that the libraries from this build MUST NOT be used in a multi-threaded"\
"environment."
case $target_os in
haiku)
disable memalign

View File

@@ -2,6 +2,13 @@ The last version increases of all libraries were on 2023-02-09
API changes, most recent first:
2023-11-08 - b82957a66a7 - lavu 58.32.100 - channel_layout.h
Add AV_CH_LAYOUT_7POINT2POINT3 and AV_CHANNEL_LAYOUT_7POINT2POINT3.
Add AV_CH_LAYOUT_9POINT1POINT4_BACK and AV_CHANNEL_LAYOUT_9POINT1POINT4_BACK.
2023-10-31 - 57c16323f26 - lavu 58.31.100 - pixdesc.h
Add AV_PIX_FMT_FLAG_XYZ.
-------- 8< --------- FFmpeg 6.1 was cut here -------- 8< ---------
2023-10-27 - 52a97642604 - lavu 58.28.100 - channel_layout.h

View File

@@ -38,7 +38,7 @@ PROJECT_NAME = FFmpeg
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 6.1
PROJECT_NUMBER =
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

View File

@@ -26,7 +26,9 @@ The General Assembly is sovereign and legitimate for all its decisions regarding
The General Assembly is made up of active contributors.
Contributors are considered "active contributors" if they have pushed more than 20 patches in the last 36 months in the main FFmpeg repository, or if they have been voted in by the GA.
Contributors are considered "active contributors" if they have authored more than 20 patches in the last 36 months in the main FFmpeg repository, or if they have been voted in by the GA.
The list of active contributors is updated twice each year, on 1st January and 1st July, 0:00 UTC.
Additional members are added to the General Assembly through a vote after proposal by a member of the General Assembly. They are part of the GA for two years, after which they need a confirmation by the GA.

View File

@@ -1888,9 +1888,19 @@ ffmpeg -i inurl -streamid 0:33 -streamid 1:36 out.ts
@end example
@item -bsf[:@var{stream_specifier}] @var{bitstream_filters} (@emph{output,per-stream})
Set bitstream filters for matching streams. @var{bitstream_filters} is
a comma-separated list of bitstream filters. Use the @code{-bsfs} option
to get the list of bitstream filters.
Apply bitstream filters to matching streams.
@var{bitstream_filters} is a comma-separated list of bitstream filter
specifications. The specified bitstream filters are applied to coded packets in
the order they are written in. Each bitstream filter specification is of the
form
@example
@var{filter}[=@var{optname0}=@var{optval0}:@var{optname1}=@var{optval1}:...]
@end example
Any of the ',=:' characters that are to be a part of an option value need to be
escaped with a backslash.
Use the @code{-bsfs} option to get the list of bitstream filters.
@example
ffmpeg -i h264.mp4 -c:v copy -bsf:v h264_mp4toannexb -an out.h264
@end example

View File

@@ -196,6 +196,18 @@ will produce a thread pool with this many threads available for parallel
processing. The default is 0 which means that the thread count will be
determined by the number of available CPUs.
@item -enable_vulkan
Use vulkan renderer rather than SDL builtin renderer. Depends on libplacebo.
@item -vulkan_params
Vulkan configuration using a list of @var{key}=@var{value} pairs separated by
":".
@item -hwaccel
Use HW accelerated decoding. Enable this option will enable vulkan renderer
automatically.
@end table
@section While playing

View File

@@ -1054,12 +1054,16 @@ Set the mode of filter operation, can be one of the following:
@table @samp
@item listen
Output only isolated detection signal.
@item cut
@item cutbelow
Cut frequencies below detection threshold.
@item cutabove
Cut frequencies above detection threshold.
@item boost
Boost frequencies bellow detection threshold.
@item boostbelow
Boost frequencies below detection threshold.
@item boostabove
Boost frequencies above detection threshold.
@end table
Default mode is @samp{cut}.
Default mode is @samp{cutbelow}.
@item dftype
Set the type of detection filter, can be one of the following:
@@ -1082,16 +1086,6 @@ Set the type of target filter, can be one of the following:
@end table
Default type is @samp{bell}.
@item direction
Set processing direction relative to threshold.
@table @samp
@item downward
Boost/Cut if threshold is higher/lower than detected volume.
@item upward
Boost/Cut if threshold is lower/higher than detected volume.
@end table
Default direction is @samp{downward}.
@item auto
Automatically gather threshold from detection filter. By default
is @samp{disabled}.
@@ -1106,6 +1100,8 @@ Disable using automatically gathered threshold value.
Stop picking threshold value.
@item on
Start picking threshold value.
@item adaptive
Adaptively pick threshold value, by calculating sliding window entropy.
@end table
@item precision
@@ -13498,6 +13494,12 @@ Draw black box on top left part of video frame of size 100x100 with drawbox filt
@example
[in][blurin]feedback=x=0:y=0:w=100:h=100[out][blurout];[blurout]drawbox=x=0:y=0:w=100:h=100:t=100[blurin]
@end example
@item
Pixelize rectangular part of video frame of size 100x100 with pixelize filter.
@example
[in][blurin]feedback=x=320:y=240:w=100:h=100[out][blurout];[blurout]pixelize[blurin]
@end example
@end itemize
@section fftdnoiz
@@ -30842,6 +30844,7 @@ Set the frequency scale used. Allowed values are:
@item sqrt
@item cbrt
@item qdrt
@item fm
@end table
Default value is @code{linear}.

View File

@@ -997,6 +997,7 @@ following image formats are supported:
@item Lagarith @tab @tab X
@item LCL (LossLess Codec Library) MSZH @tab @tab X
@item LCL (LossLess Codec Library) ZLIB @tab E @tab E
@item LEAD MCMP @tab @tab X
@item LOCO @tab @tab X
@item LucasArts SANM/Smush @tab @tab X
@tab Used in LucasArts games / SMUSH animations.

View File

@@ -727,6 +727,10 @@ FL+FR+FC+LFE+BL+BR+TFL+TFR+TBL+TBR
FL+FR+FC+LFE+BL+BR+SL+SR+TFL+TFR
@item 7.1.4
FL+FR+FC+LFE+BL+BR+SL+SR+TFL+TFR+TBL+TBR
@item 7.2.3
FL+FR+FC+LFE+BL+BR+SL+SR+TFL+TFR+TBC+LFE2
@item 9.1.4
FL+FR+FC+LFE+BL+BR+FLC+FRC+SL+SR+TFL+TFR+TBL+TBR
@item hexadecagonal
FL+FR+FC+BL+BR+BC+SL+SR+WL+WR+TBL+TBR+TBC+TFC+TFL+TFR
@item downmix

View File

@@ -130,7 +130,7 @@ $(BIN2CEXE): ffbuild/bin2c_host.o
ifdef CONFIG_PTX_COMPRESSION
%.ptx.gz: TAG = GZIP
%.ptx.gz: %.ptx
$(M)gzip -c9 $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) >$@
$(M)gzip -nc9 $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) >$@
%.ptx.c: %.ptx.gz $(BIN2CEXE)
$(BIN2C) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) $@ $(subst .,_,$(basename $(notdir $@)))

View File

@@ -22,6 +22,8 @@ OBJS-ffmpeg += \
fftools/sync_queue.o \
fftools/thread_queue.o \
OBJS-ffplay += fftools/ffplay_renderer.o
define DOFFTOOL
OBJS-$(1) += fftools/cmdutils.o fftools/opt_common.o fftools/$(1).o $(OBJS-$(1)-yes)
ifdef HAVE_GNU_WINDRES

View File

@@ -665,10 +665,10 @@ static int init_parse_context(OptionParseContext *octx,
memset(octx, 0, sizeof(*octx));
octx->nb_groups = nb_groups;
octx->groups = av_calloc(octx->nb_groups, sizeof(*octx->groups));
octx->groups = av_calloc(nb_groups, sizeof(*octx->groups));
if (!octx->groups)
return AVERROR(ENOMEM);
octx->nb_groups = nb_groups;
for (i = 0; i < octx->nb_groups; i++)
octx->groups[i].group_def = &groups[i];

View File

@@ -99,6 +99,7 @@
#include "cmdutils.h"
#include "ffmpeg.h"
#include "ffmpeg_utils.h"
#include "sync_queue.h"
const char program_name[] = "ffmpeg";

View File

@@ -347,8 +347,6 @@ typedef struct InputStream {
AVRational framerate_guessed;
int64_t nb_samples; /* number of samples in the last decoded audio frame before looping */
AVDictionary *decoder_opts;
AVRational framerate; /* framerate forced with -r */
#if FFMPEG_OPT_TOP
@@ -391,11 +389,6 @@ typedef struct InputStream {
uint64_t decode_errors;
} InputStream;
typedef struct LastFrameDuration {
int stream_idx;
int64_t duration;
} LastFrameDuration;
typedef struct InputFile {
const AVClass *class;
@@ -427,9 +420,9 @@ typedef struct InputFile {
int accurate_seek;
/* when looping the input file, this queue is used by decoders to report
* the last frame duration back to the demuxer thread */
AVThreadMessageQueue *audio_duration_queue;
int audio_duration_queue_size;
* the last frame timestamp back to the demuxer thread */
AVThreadMessageQueue *audio_ts_queue;
int audio_ts_queue_size;
} InputFile;
enum forced_keyframes_const {
@@ -880,17 +873,6 @@ int trigger_fix_sub_duration_heartbeat(OutputStream *ost, const AVPacket *pkt);
int fix_sub_duration_heartbeat(InputStream *ist, int64_t signal_pts);
void update_benchmark(const char *fmt, ...);
/**
* Merge two return codes - return one of the error codes if at least one of
* them was negative, 0 otherwise.
* Currently just picks the first one, eventually we might want to do something
* more sophisticated, like sorting them by priority.
*/
static inline int err_merge(int err0, int err1)
{
return (err0 < 0) ? err0 : FFMIN(err1, 0);
}
#define SPECIFIER_OPT_FMT_str "%s"
#define SPECIFIER_OPT_FMT_i "%i"
#define SPECIFIER_OPT_FMT_i64 "%"PRId64
@@ -942,14 +924,4 @@ extern const char * const opt_name_frame_rates[];
extern const char * const opt_name_top_field_first[];
#endif
static inline void pkt_move(void *dst, void *src)
{
av_packet_move_ref(dst, src);
}
static inline void frame_move(void *dst, void *src)
{
av_frame_move_ref(dst, src);
}
#endif /* FFTOOLS_FFMPEG_H */

View File

@@ -30,6 +30,7 @@
#include "libavfilter/buffersrc.h"
#include "ffmpeg.h"
#include "ffmpeg_utils.h"
#include "thread_queue.h"
struct Decoder {
@@ -631,7 +632,6 @@ static int packet_decode(InputStream *ist, AVPacket *pkt, AVFrame *frame)
if (dec->codec_type == AVMEDIA_TYPE_AUDIO) {
ist->samples_decoded += frame->nb_samples;
ist->nb_samples = frame->nb_samples;
audio_ts_process(ist, ist->decoder, frame);
} else {
@@ -723,14 +723,9 @@ static void *decoder_thread(void *arg)
/* report last frame duration to the demuxer thread */
if (ist->dec->type == AVMEDIA_TYPE_AUDIO) {
LastFrameDuration dur;
dur.stream_idx = ist->index;
dur.duration = av_rescale_q(ist->nb_samples,
(AVRational){ 1, ist->dec_ctx->sample_rate},
ist->st->time_base);
av_thread_message_queue_send(ifile->audio_duration_queue, &dur, 0);
Timestamp ts = { .ts = d->last_frame_pts + d->last_frame_duration_est,
.tb = d->last_frame_tb };
av_thread_message_queue_send(ifile->audio_ts_queue, &ts, 0);
}
avcodec_flush_buffers(ist->dec_ctx);
@@ -759,8 +754,8 @@ finish:
// make sure the demuxer does not get stuck waiting for audio durations
// that will never arrive
if (ifile->audio_duration_queue && ist->dec->type == AVMEDIA_TYPE_AUDIO)
av_thread_message_queue_set_err_recv(ifile->audio_duration_queue, AVERROR_EOF);
if (ifile->audio_ts_queue && ist->dec->type == AVMEDIA_TYPE_AUDIO)
av_thread_message_queue_set_err_recv(ifile->audio_ts_queue, AVERROR_EOF);
dec_thread_uninit(&dt);

View File

@@ -20,6 +20,7 @@
#include <stdint.h>
#include "ffmpeg.h"
#include "ffmpeg_utils.h"
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
@@ -73,9 +74,6 @@ typedef struct DemuxStream {
///< dts of the last packet read for this stream (in AV_TIME_BASE units)
int64_t dts;
int64_t min_pts; /* pts with the smallest value in a current stream */
int64_t max_pts; /* pts with the higher value in a current stream */
/* number of packets successfully read for this stream */
uint64_t nb_packets;
// combined size of all the packets read
@@ -98,11 +96,11 @@ typedef struct Demuxer {
/* number of times input stream should be looped */
int loop;
/* actual duration of the longest stream in a file at the moment when
* looping happens */
int64_t duration;
/* time base of the duration */
AVRational time_base;
/* duration of the looped segment of the input file */
Timestamp duration;
/* pts with the smallest/largest values ever seen */
Timestamp min_pts;
Timestamp max_pts;
/* number of streams that the user was warned of */
int nb_streams_warn;
@@ -155,23 +153,6 @@ static void report_new_stream(Demuxer *d, const AVPacket *pkt)
d->nb_streams_warn = pkt->stream_index + 1;
}
static void ifile_duration_update(Demuxer *d, DemuxStream *ds,
int64_t last_duration)
{
/* the total duration of the stream, max_pts - min_pts is
* the duration of the stream without the last frame */
if (ds->max_pts > ds->min_pts &&
ds->max_pts - (uint64_t)ds->min_pts < INT64_MAX - last_duration)
last_duration += ds->max_pts - ds->min_pts;
if (!d->duration ||
av_compare_ts(d->duration, d->time_base,
last_duration, ds->ist.st->time_base) < 0) {
d->duration = last_duration;
d->time_base = ds->ist.st->time_base;
}
}
static int seek_to_start(Demuxer *d)
{
InputFile *ifile = &d->f;
@@ -182,41 +163,28 @@ static int seek_to_start(Demuxer *d)
if (ret < 0)
return ret;
if (ifile->audio_duration_queue_size) {
/* duration is the length of the last frame in a stream
* when audio stream is present we don't care about
* last video frame length because it's not defined exactly */
int got_durations = 0;
if (ifile->audio_ts_queue_size) {
int got_ts = 0;
while (got_durations < ifile->audio_duration_queue_size) {
DemuxStream *ds;
LastFrameDuration dur;
ret = av_thread_message_queue_recv(ifile->audio_duration_queue, &dur, 0);
while (got_ts < ifile->audio_ts_queue_size) {
Timestamp ts;
ret = av_thread_message_queue_recv(ifile->audio_ts_queue, &ts, 0);
if (ret < 0)
return ret;
got_durations++;
got_ts++;
ds = ds_from_ist(ifile->streams[dur.stream_idx]);
ifile_duration_update(d, ds, dur.duration);
}
} else {
for (int i = 0; i < ifile->nb_streams; i++) {
int64_t duration = 0;
InputStream *ist = ifile->streams[i];
DemuxStream *ds = ds_from_ist(ist);
if (ist->framerate.num) {
duration = av_rescale_q(1, av_inv_q(ist->framerate), ist->st->time_base);
} else if (ist->st->avg_frame_rate.num) {
duration = av_rescale_q(1, av_inv_q(ist->st->avg_frame_rate), ist->st->time_base);
} else {
duration = 1;
}
ifile_duration_update(d, ds, duration);
if (d->max_pts.ts == AV_NOPTS_VALUE ||
av_compare_ts(d->max_pts.ts, d->max_pts.tb, ts.ts, ts.tb) < 0)
d->max_pts = ts;
}
}
if (d->max_pts.ts != AV_NOPTS_VALUE) {
int64_t min_pts = d->min_pts.ts == AV_NOPTS_VALUE ? 0 : d->min_pts.ts;
d->duration.ts = d->max_pts.ts - av_rescale_q(min_pts, d->min_pts.tb, d->max_pts.tb);
}
d->duration.tb = d->max_pts.tb;
if (d->loop > 0)
d->loop--;
@@ -433,11 +401,27 @@ static int ts_fixup(Demuxer *d, AVPacket *pkt)
if (pkt->dts != AV_NOPTS_VALUE)
pkt->dts *= ds->ts_scale;
duration = av_rescale_q(d->duration, d->time_base, pkt->time_base);
duration = av_rescale_q(d->duration.ts, d->duration.tb, pkt->time_base);
if (pkt->pts != AV_NOPTS_VALUE) {
// audio decoders take precedence for estimating total file duration
int64_t pkt_duration = ifile->audio_ts_queue_size ? 0 : pkt->duration;
pkt->pts += duration;
ds->max_pts = FFMAX(pkt->pts, ds->max_pts);
ds->min_pts = FFMIN(pkt->pts, ds->min_pts);
// update max/min pts that will be used to compute total file duration
// when using -stream_loop
if (d->max_pts.ts == AV_NOPTS_VALUE ||
av_compare_ts(d->max_pts.ts, d->max_pts.tb,
pkt->pts + pkt_duration, pkt->time_base) < 0) {
d->max_pts = (Timestamp){ .ts = pkt->pts + pkt_duration,
.tb = pkt->time_base };
}
if (d->min_pts.ts == AV_NOPTS_VALUE ||
av_compare_ts(d->min_pts.ts, d->min_pts.tb,
pkt->pts, pkt->time_base) > 0) {
d->min_pts = (Timestamp){ .ts = pkt->pts,
.tb = pkt->time_base };
}
}
if (pkt->dts != AV_NOPTS_VALUE)
@@ -668,7 +652,7 @@ static void thread_stop(Demuxer *d)
pthread_join(d->thread, NULL);
av_thread_message_queue_free(&d->in_thread_queue);
av_thread_message_queue_free(&f->audio_duration_queue);
av_thread_message_queue_free(&f->audio_ts_queue);
}
static int thread_start(Demuxer *d)
@@ -698,11 +682,11 @@ static int thread_start(Demuxer *d)
}
if (nb_audio_dec) {
ret = av_thread_message_queue_alloc(&f->audio_duration_queue,
nb_audio_dec, sizeof(LastFrameDuration));
ret = av_thread_message_queue_alloc(&f->audio_ts_queue,
nb_audio_dec, sizeof(Timestamp));
if (ret < 0)
goto fail;
f->audio_duration_queue_size = nb_audio_dec;
f->audio_ts_queue_size = nb_audio_dec;
}
}
@@ -1052,13 +1036,9 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st)
ist->discard = 1;
st->discard = AVDISCARD_ALL;
ist->nb_samples = 0;
ds->first_dts = AV_NOPTS_VALUE;
ds->next_dts = AV_NOPTS_VALUE;
ds->min_pts = INT64_MAX;
ds->max_pts = INT64_MIN;
ds->ts_scale = 1.0;
MATCH_PER_STREAM_OPT(ts_scale, dbl, ds->ts_scale, ic, st);
@@ -1590,10 +1570,12 @@ int ifile_open(const OptionsContext *o, const char *filename)
f->ts_offset = o->input_ts_offset - (copy_ts ? (start_at_zero && ic->start_time != AV_NOPTS_VALUE ? ic->start_time : 0) : timestamp);
f->accurate_seek = o->accurate_seek;
d->loop = o->loop;
d->duration = 0;
d->time_base = (AVRational){ 1, 1 };
d->nb_streams_warn = ic->nb_streams;
d->duration = (Timestamp){ .ts = 0, .tb = (AVRational){ 1, 1 } };
d->min_pts = (Timestamp){ .ts = AV_NOPTS_VALUE, .tb = (AVRational){ 1, 1 } };
d->max_pts = (Timestamp){ .ts = AV_NOPTS_VALUE, .tb = (AVRational){ 1, 1 } };
f->format_nots = !!(ic->iformat->flags & AVFMT_NOTIMESTAMPS);
f->readrate = o->readrate ? o->readrate : 0.0;

View File

@@ -905,8 +905,14 @@ int fg_create(FilterGraph **pfg, char *graph_desc)
for (AVFilterInOut *cur = inputs; cur; cur = cur->next) {
InputFilter *const ifilter = ifilter_alloc(fg);
InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
InputFilterPriv *ifp;
if (!ifilter) {
ret = AVERROR(ENOMEM);
goto fail;
}
ifp = ifp_from_ifilter(ifilter);
ifp->linklabel = cur->name;
cur->name = NULL;
@@ -922,8 +928,10 @@ int fg_create(FilterGraph **pfg, char *graph_desc)
for (AVFilterInOut *cur = outputs; cur; cur = cur->next) {
OutputFilter *const ofilter = ofilter_alloc(fg);
if (!ofilter)
if (!ofilter) {
ret = AVERROR(ENOMEM);
goto fail;
}
ofilter->linklabel = cur->name;
cur->name = NULL;

View File

@@ -22,6 +22,7 @@
#include "ffmpeg.h"
#include "ffmpeg_mux.h"
#include "ffmpeg_utils.h"
#include "objpool.h"
#include "sync_queue.h"
#include "thread_queue.h"

56
fftools/ffmpeg_utils.h Normal file
View File

@@ -0,0 +1,56 @@
/*
* 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 FFTOOLS_FFMPEG_UTILS_H
#define FFTOOLS_FFMPEG_UTILS_H
#include <stdint.h>
#include "libavutil/common.h"
#include "libavutil/frame.h"
#include "libavutil/rational.h"
#include "libavcodec/packet.h"
typedef struct Timestamp {
int64_t ts;
AVRational tb;
} Timestamp;
/**
* Merge two return codes - return one of the error codes if at least one of
* them was negative, 0 otherwise.
* Currently just picks the first one, eventually we might want to do something
* more sophisticated, like sorting them by priority.
*/
static inline int err_merge(int err0, int err1)
{
return (err0 < 0) ? err0 : FFMIN(err1, 0);
}
static inline void pkt_move(void *dst, void *src)
{
av_packet_move_ref(dst, src);
}
static inline void frame_move(void *dst, void *src)
{
av_frame_move_ref(dst, src);
}
#endif // FFTOOLS_FFMPEG_UTILS_H

View File

@@ -58,6 +58,7 @@
#include <SDL_thread.h>
#include "cmdutils.h"
#include "ffplay_renderer.h"
#include "opt_common.h"
const char program_name[] = "ffplay";
@@ -350,6 +351,9 @@ static char *afilters = NULL;
static int autorotate = 1;
static int find_stream_info = 1;
static int filter_nbthreads = 0;
static int enable_vulkan = 0;
static char *vulkan_params = NULL;
static const char *hwaccel = NULL;
/* current context */
static int is_full_screen;
@@ -362,6 +366,8 @@ static SDL_Renderer *renderer;
static SDL_RendererInfo renderer_info = {0};
static SDL_AudioDeviceID audio_dev;
static VkRenderer *vk_renderer;
static const struct TextureFormatEntry {
enum AVPixelFormat format;
int texture_fmt;
@@ -954,6 +960,11 @@ static void video_image_display(VideoState *is)
SDL_Rect rect;
vp = frame_queue_peek_last(&is->pictq);
if (vk_renderer) {
vk_renderer_display(vk_renderer, vp->frame);
return;
}
if (is->subtitle_st) {
if (frame_queue_nb_remaining(&is->subpq) > 0) {
sp = frame_queue_peek(&is->subpq);
@@ -1289,6 +1300,8 @@ static void do_exit(VideoState *is)
}
if (renderer)
SDL_DestroyRenderer(renderer);
if (vk_renderer)
vk_renderer_destroy(vk_renderer);
if (window)
SDL_DestroyWindow(window);
uninit_opts();
@@ -2546,6 +2559,37 @@ static int audio_open(void *opaque, AVChannelLayout *wanted_channel_layout, int
return spec.size;
}
static int create_hwaccel(AVBufferRef **device_ctx)
{
enum AVHWDeviceType type;
int ret;
AVBufferRef *vk_dev;
*device_ctx = NULL;
if (!hwaccel)
return 0;
type = av_hwdevice_find_type_by_name(hwaccel);
if (type == AV_HWDEVICE_TYPE_NONE)
return AVERROR(ENOTSUP);
ret = vk_renderer_get_hw_dev(vk_renderer, &vk_dev);
if (ret < 0)
return ret;
ret = av_hwdevice_ctx_create_derived(device_ctx, type, vk_dev, 0);
if (!ret)
return 0;
if (ret != AVERROR(ENOSYS))
return ret;
av_log(NULL, AV_LOG_WARNING, "Derive %s from vulkan not supported.\n", hwaccel);
ret = av_hwdevice_ctx_create(device_ctx, type, NULL, NULL, 0);
return ret;
}
/* open a given stream. Return 0 if OK */
static int stream_component_open(VideoState *is, int stream_index)
{
@@ -2613,6 +2657,12 @@ static int stream_component_open(VideoState *is, int stream_index)
av_dict_set(&opts, "flags", "+copy_opaque", AV_DICT_MULTIKEY);
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
ret = create_hwaccel(&avctx->hw_device_ctx);
if (ret < 0)
goto fail;
}
if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
goto fail;
}
@@ -3447,6 +3497,8 @@ static void event_loop(VideoState *cur_stream)
SDL_DestroyTexture(cur_stream->vis_texture);
cur_stream->vis_texture = NULL;
}
if (vk_renderer)
vk_renderer_resize(vk_renderer, screen_width, screen_height);
case SDL_WINDOWEVENT_EXPOSED:
cur_stream->force_refresh = 1;
}
@@ -3611,6 +3663,9 @@ static const OptionDef options[] = {
{ "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
"read and decode the streams to fill missing information with heuristics" },
{ "filter_threads", HAS_ARG | OPT_INT | OPT_EXPERT, { &filter_nbthreads }, "number of filter threads per graph" },
{ "enable_vulkan", OPT_BOOL, { &enable_vulkan }, "enable vulkan renderer" },
{ "vulkan_params", HAS_ARG | OPT_STRING | OPT_EXPERT, { &vulkan_params }, "vulkan configuration using a list of key=value pairs separated by ':'" },
{ "hwaccel", HAS_ARG | OPT_STRING | OPT_EXPERT, { &hwaccel }, "use HW accelerated decoding" },
{ NULL, },
};
@@ -3725,9 +3780,40 @@ int main(int argc, char **argv)
#ifdef SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
#endif
if (hwaccel && !enable_vulkan) {
av_log(NULL, AV_LOG_INFO, "Enable vulkan renderer to support hwaccel %s\n", hwaccel);
enable_vulkan = 1;
}
if (enable_vulkan) {
vk_renderer = vk_get_renderer();
if (vk_renderer) {
#if SDL_VERSION_ATLEAST(2, 0, 6)
flags |= SDL_WINDOW_VULKAN;
#endif
} else {
av_log(NULL, AV_LOG_WARNING, "Doesn't support vulkan renderer, fallback to SDL renderer\n");
enable_vulkan = 0;
}
}
window = SDL_CreateWindow(program_name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, default_width, default_height, flags);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
if (window) {
if (!window) {
av_log(NULL, AV_LOG_FATAL, "Failed to create window: %s", SDL_GetError());
do_exit(NULL);
}
if (vk_renderer) {
AVDictionary *dict = NULL;
if (vulkan_params)
av_dict_parse_string(&dict, vulkan_params, "=", ":", 0);
ret = vk_renderer_create(vk_renderer, window, dict);
av_dict_free(&dict);
if (ret < 0) {
av_log(NULL, AV_LOG_FATAL, "Failed to create vulkan renderer, %s\n", av_err2str(ret));
do_exit(NULL);
}
} else {
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (!renderer) {
av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
@@ -3737,10 +3823,10 @@ int main(int argc, char **argv)
if (!SDL_GetRendererInfo(renderer, &renderer_info))
av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", renderer_info.name);
}
}
if (!window || !renderer || !renderer_info.num_texture_formats) {
av_log(NULL, AV_LOG_FATAL, "Failed to create window or renderer: %s", SDL_GetError());
do_exit(NULL);
if (!renderer || !renderer_info.num_texture_formats) {
av_log(NULL, AV_LOG_FATAL, "Failed to create window or renderer: %s", SDL_GetError());
do_exit(NULL);
}
}
}

824
fftools/ffplay_renderer.c Normal file
View File

@@ -0,0 +1,824 @@
/*
* 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
*/
#define VK_NO_PROTOTYPES
#define VK_ENABLE_BETA_EXTENSIONS
#include "config.h"
#include "ffplay_renderer.h"
#if (SDL_VERSION_ATLEAST(2, 0, 6) && CONFIG_LIBPLACEBO)
/* Get PL_API_VER */
#include <libplacebo/config.h>
#define HAVE_VULKAN_RENDERER (PL_API_VER >= 278)
#else
#define HAVE_VULKAN_RENDERER 0
#endif
#if HAVE_VULKAN_RENDERER
#if defined(_WIN32) && !defined(VK_USE_PLATFORM_WIN32_KHR)
#define VK_USE_PLATFORM_WIN32_KHR
#endif
#include <libplacebo/vulkan.h>
#include <libplacebo/utils/frame_queue.h>
#include <libplacebo/utils/libav.h>
#include <SDL_vulkan.h>
#include "libavutil/bprint.h"
#endif
struct VkRenderer {
const AVClass *class;
int (*create)(VkRenderer *renderer, SDL_Window *window, AVDictionary *dict);
int (*get_hw_dev)(VkRenderer *renderer, AVBufferRef **dev);
int (*display)(VkRenderer *renderer, AVFrame *frame);
int (*resize)(VkRenderer *renderer, int width, int height);
void (*destroy)(VkRenderer *renderer);
};
#if HAVE_VULKAN_RENDERER
typedef struct RendererContext {
VkRenderer api;
// Can be NULL when vulkan instance is created by avutil
pl_vk_inst placebo_instance;
pl_vulkan placebo_vulkan;
pl_swapchain swapchain;
VkSurfaceKHR vk_surface;
pl_renderer renderer;
pl_tex tex[4];
pl_log vk_log;
AVBufferRef *hw_device_ref;
AVBufferRef *hw_frame_ref;
enum AVPixelFormat *transfer_formats;
AVHWFramesConstraints *constraints;
PFN_vkGetInstanceProcAddr get_proc_addr;
// This field is a copy from pl_vk_inst->instance or hw_device_ref instance.
VkInstance inst;
AVFrame *vk_frame;
} RendererContext;
static void vk_log_cb(void *log_priv, enum pl_log_level level,
const char *msg)
{
static const int level_map[] = {
AV_LOG_QUIET,
AV_LOG_FATAL,
AV_LOG_ERROR,
AV_LOG_WARNING,
AV_LOG_INFO,
AV_LOG_DEBUG,
AV_LOG_TRACE,
};
if (level > 0 && level < FF_ARRAY_ELEMS(level_map))
av_log(log_priv, level_map[level], "%s\n", msg);
}
// Should keep sync with optional_device_exts inside hwcontext_vulkan.c
static const char *optional_device_exts[] = {
/* Misc or required by other extensions */
VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME,
VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME,
VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME,
VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME,
VK_EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME,
VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME,
VK_KHR_COOPERATIVE_MATRIX_EXTENSION_NAME,
/* Imports/exports */
VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME,
VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME,
#ifdef _WIN32
VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME,
#endif
/* Video encoding/decoding */
VK_KHR_VIDEO_QUEUE_EXTENSION_NAME,
VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME,
VK_KHR_VIDEO_DECODE_H264_EXTENSION_NAME,
VK_KHR_VIDEO_DECODE_H265_EXTENSION_NAME,
"VK_MESA_video_decode_av1",
};
static inline int enable_debug(AVDictionary *opt)
{
AVDictionaryEntry *entry = av_dict_get(opt, "debug", NULL, 0);
int debug = entry && strtol(entry->value, NULL, 10);
return debug;
}
static void hwctx_lock_queue(void *priv, uint32_t qf, uint32_t qidx)
{
AVHWDeviceContext *avhwctx = priv;
const AVVulkanDeviceContext *hwctx = avhwctx->hwctx;
hwctx->lock_queue(avhwctx, qf, qidx);
}
static void hwctx_unlock_queue(void *priv, uint32_t qf, uint32_t qidx)
{
AVHWDeviceContext *avhwctx = priv;
const AVVulkanDeviceContext *hwctx = avhwctx->hwctx;
hwctx->unlock_queue(avhwctx, qf, qidx);
}
static int add_instance_extension(const char **ext, unsigned num_ext,
const AVDictionary *opt,
AVDictionary **dict)
{
const char *inst_ext_key = "instance_extensions";
AVDictionaryEntry *entry;
AVBPrint buf;
char *ext_list = NULL;
int ret;
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
for (int i = 0; i < num_ext; i++) {
if (i)
av_bprintf(&buf, "+%s", ext[i]);
else
av_bprintf(&buf, "%s", ext[i]);
}
entry = av_dict_get(opt, inst_ext_key, NULL, 0);
if (entry && entry->value && entry->value[0]) {
if (num_ext)
av_bprintf(&buf, "+");
av_bprintf(&buf, "%s", entry->value);
}
ret = av_bprint_finalize(&buf, &ext_list);
if (ret < 0)
return ret;
return av_dict_set(dict, inst_ext_key, ext_list, AV_DICT_DONT_STRDUP_VAL);
}
static int add_device_extension(const AVDictionary *opt,
AVDictionary **dict)
{
const char *dev_ext_key = "device_extensions";
AVDictionaryEntry *entry;
AVBPrint buf;
char *ext_list = NULL;
int ret;
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
av_bprintf(&buf, "%s", VK_KHR_SWAPCHAIN_EXTENSION_NAME);
for (int i = 0; i < pl_vulkan_num_recommended_extensions; i++)
av_bprintf(&buf, "+%s", pl_vulkan_recommended_extensions[i]);
entry = av_dict_get(opt, dev_ext_key, NULL, 0);
if (entry && entry->value && entry->value[0])
av_bprintf(&buf, "+%s", entry->value);
ret = av_bprint_finalize(&buf, &ext_list);
if (ret < 0)
return ret;
return av_dict_set(dict, dev_ext_key, ext_list, AV_DICT_DONT_STRDUP_VAL);
}
static int create_vk_by_hwcontext(VkRenderer *renderer,
const char **ext, unsigned num_ext,
const AVDictionary *opt)
{
RendererContext *ctx = (RendererContext *) renderer;
AVHWDeviceContext *dev;
AVVulkanDeviceContext *hwctx;
AVDictionary *dict = NULL;
int ret;
ret = add_instance_extension(ext, num_ext, opt, &dict);
if (ret < 0)
return ret;
ret = add_device_extension(opt, &dict);
if (ret) {
av_dict_free(&dict);
return ret;
}
ret = av_hwdevice_ctx_create(&ctx->hw_device_ref, AV_HWDEVICE_TYPE_VULKAN,
NULL, dict, 0);
av_dict_free(&dict);
if (ret < 0)
return ret;
dev = (AVHWDeviceContext *) ctx->hw_device_ref->data;
hwctx = dev->hwctx;
// There is no way to pass SDL GetInstanceProcAddr to hwdevice.
// Check the result and return error if they don't match.
if (hwctx->get_proc_addr != SDL_Vulkan_GetVkGetInstanceProcAddr()) {
av_log(renderer, AV_LOG_ERROR,
"hwdevice and SDL use different get_proc_addr. "
"Try -vulkan_params create_by_placebo=1\n");
return AVERROR_PATCHWELCOME;
}
ctx->get_proc_addr = hwctx->get_proc_addr;
ctx->inst = hwctx->inst;
ctx->placebo_vulkan = pl_vulkan_import(ctx->vk_log,
pl_vulkan_import_params(
.instance = hwctx->inst,
.get_proc_addr = hwctx->get_proc_addr,
.phys_device = hwctx->phys_dev,
.device = hwctx->act_dev,
.extensions = hwctx->enabled_dev_extensions,
.num_extensions = hwctx->nb_enabled_dev_extensions,
.features = &hwctx->device_features,
.lock_queue = hwctx_lock_queue,
.unlock_queue = hwctx_unlock_queue,
.queue_ctx = dev,
.queue_graphics = {
.index = hwctx->queue_family_index,
.count = hwctx->nb_graphics_queues,
},
.queue_compute = {
.index = hwctx->queue_family_comp_index,
.count = hwctx->nb_comp_queues,
},
.queue_transfer = {
.index = hwctx->queue_family_tx_index,
.count = hwctx->nb_tx_queues,
},
));
if (!ctx->placebo_vulkan)
return AVERROR_EXTERNAL;
return 0;
}
static void placebo_lock_queue(struct AVHWDeviceContext *dev_ctx,
uint32_t queue_family, uint32_t index)
{
RendererContext *ctx = dev_ctx->user_opaque;
pl_vulkan vk = ctx->placebo_vulkan;
vk->lock_queue(vk, queue_family, index);
}
static void placebo_unlock_queue(struct AVHWDeviceContext *dev_ctx,
uint32_t queue_family,
uint32_t index)
{
RendererContext *ctx = dev_ctx->user_opaque;
pl_vulkan vk = ctx->placebo_vulkan;
vk->unlock_queue(vk, queue_family, index);
}
static int get_decode_queue(VkRenderer *renderer, int *index, int *count)
{
RendererContext *ctx = (RendererContext *) renderer;
VkQueueFamilyProperties *queue_family_prop = NULL;
uint32_t num_queue_family_prop = 0;
PFN_vkGetPhysicalDeviceQueueFamilyProperties get_queue_family_prop;
PFN_vkGetInstanceProcAddr get_proc_addr = ctx->get_proc_addr;
*index = -1;
*count = 0;
get_queue_family_prop = (PFN_vkGetPhysicalDeviceQueueFamilyProperties)
get_proc_addr(ctx->placebo_instance->instance,
"vkGetPhysicalDeviceQueueFamilyProperties");
get_queue_family_prop(ctx->placebo_vulkan->phys_device,
&num_queue_family_prop, NULL);
if (!num_queue_family_prop)
return AVERROR_EXTERNAL;
queue_family_prop = av_calloc(num_queue_family_prop,
sizeof(*queue_family_prop));
if (!queue_family_prop)
return AVERROR(ENOMEM);
get_queue_family_prop(ctx->placebo_vulkan->phys_device,
&num_queue_family_prop,
queue_family_prop);
for (int i = 0; i < num_queue_family_prop; i++) {
if (queue_family_prop[i].queueFlags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) {
*index = i;
*count = queue_family_prop[i].queueCount;
break;
}
}
av_free(queue_family_prop);
return 0;
}
static int create_vk_by_placebo(VkRenderer *renderer,
const char **ext, unsigned num_ext,
const AVDictionary *opt)
{
RendererContext *ctx = (RendererContext *) renderer;
AVHWDeviceContext *device_ctx;
AVVulkanDeviceContext *vk_dev_ctx;
int decode_index;
int decode_count;
int ret;
ctx->get_proc_addr = SDL_Vulkan_GetVkGetInstanceProcAddr();
ctx->placebo_instance = pl_vk_inst_create(ctx->vk_log, pl_vk_inst_params(
.get_proc_addr = ctx->get_proc_addr,
.debug = enable_debug(opt),
.extensions = ext,
.num_extensions = num_ext
));
if (!ctx->placebo_instance) {
return AVERROR_EXTERNAL;
}
ctx->inst = ctx->placebo_instance->instance;
ctx->placebo_vulkan = pl_vulkan_create(ctx->vk_log, pl_vulkan_params(
.instance = ctx->placebo_instance->instance,
.get_proc_addr = ctx->placebo_instance->get_proc_addr,
.surface = ctx->vk_surface,
.allow_software = false,
.opt_extensions = optional_device_exts,
.num_opt_extensions = FF_ARRAY_ELEMS(optional_device_exts),
.extra_queues = VK_QUEUE_VIDEO_DECODE_BIT_KHR,
));
if (!ctx->placebo_vulkan)
return AVERROR_EXTERNAL;
ctx->hw_device_ref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VULKAN);
if (!ctx->hw_device_ref) {
return AVERROR(ENOMEM);
}
device_ctx = (AVHWDeviceContext *) ctx->hw_device_ref->data;
device_ctx->user_opaque = ctx;
vk_dev_ctx = device_ctx->hwctx;
vk_dev_ctx->lock_queue = placebo_lock_queue,
vk_dev_ctx->unlock_queue = placebo_unlock_queue;
vk_dev_ctx->get_proc_addr = ctx->placebo_instance->get_proc_addr;
vk_dev_ctx->inst = ctx->placebo_instance->instance;
vk_dev_ctx->phys_dev = ctx->placebo_vulkan->phys_device;
vk_dev_ctx->act_dev = ctx->placebo_vulkan->device;
vk_dev_ctx->device_features = *ctx->placebo_vulkan->features;
vk_dev_ctx->enabled_inst_extensions = ctx->placebo_instance->extensions;
vk_dev_ctx->nb_enabled_inst_extensions = ctx->placebo_instance->num_extensions;
vk_dev_ctx->enabled_dev_extensions = ctx->placebo_vulkan->extensions;
vk_dev_ctx->nb_enabled_dev_extensions = ctx->placebo_vulkan->num_extensions;
vk_dev_ctx->queue_family_index = ctx->placebo_vulkan->queue_graphics.index;
vk_dev_ctx->nb_graphics_queues = ctx->placebo_vulkan->queue_graphics.count;
vk_dev_ctx->queue_family_tx_index = ctx->placebo_vulkan->queue_transfer.index;
vk_dev_ctx->nb_tx_queues = ctx->placebo_vulkan->queue_transfer.count;
vk_dev_ctx->queue_family_comp_index = ctx->placebo_vulkan->queue_compute.index;
vk_dev_ctx->nb_comp_queues = ctx->placebo_vulkan->queue_compute.count;
ret = get_decode_queue(renderer, &decode_index, &decode_count);
if (ret < 0)
return ret;
vk_dev_ctx->queue_family_decode_index = decode_index;
vk_dev_ctx->nb_decode_queues = decode_count;
ret = av_hwdevice_ctx_init(ctx->hw_device_ref);
if (ret < 0)
return ret;
return 0;
}
static int create(VkRenderer *renderer, SDL_Window *window, AVDictionary *opt)
{
int ret = 0;
unsigned num_ext = 0;
const char **ext = NULL;
int w, h;
struct pl_log_params vk_log_params = {
.log_cb = vk_log_cb,
.log_level = PL_LOG_DEBUG,
.log_priv = renderer,
};
RendererContext *ctx = (RendererContext *) renderer;
AVDictionaryEntry *entry;
ctx->vk_log = pl_log_create(PL_API_VER, &vk_log_params);
if (!SDL_Vulkan_GetInstanceExtensions(window, &num_ext, NULL)) {
av_log(NULL, AV_LOG_FATAL, "Failed to get vulkan extensions: %s\n",
SDL_GetError());
return AVERROR_EXTERNAL;
}
ext = av_calloc(num_ext, sizeof(*ext));
if (!ext) {
ret = AVERROR(ENOMEM);
goto out;
}
SDL_Vulkan_GetInstanceExtensions(window, &num_ext, ext);
entry = av_dict_get(opt, "create_by_placebo", NULL, 0);
if (entry && strtol(entry->value, NULL, 10))
ret = create_vk_by_placebo(renderer, ext, num_ext, opt);
else
ret = create_vk_by_hwcontext(renderer, ext, num_ext, opt);
if (ret < 0)
goto out;
if (!SDL_Vulkan_CreateSurface(window, ctx->inst, &ctx->vk_surface)) {
ret = AVERROR_EXTERNAL;
goto out;
}
ctx->swapchain = pl_vulkan_create_swapchain(
ctx->placebo_vulkan,
pl_vulkan_swapchain_params(
.surface = ctx->vk_surface,
.present_mode = VK_PRESENT_MODE_FIFO_KHR));
if (!ctx->swapchain) {
ret = AVERROR_EXTERNAL;
goto out;
}
SDL_Vulkan_GetDrawableSize(window, &w, &h);
pl_swapchain_resize(ctx->swapchain, &w, &h);
ctx->renderer = pl_renderer_create(ctx->vk_log, ctx->placebo_vulkan->gpu);
if (!ctx->renderer) {
ret = AVERROR_EXTERNAL;
goto out;
}
ctx->vk_frame = av_frame_alloc();
if (!ctx->vk_frame) {
ret = AVERROR(ENOMEM);
goto out;
}
ret = 0;
out:
av_free(ext);
return ret;
}
static int get_hw_dev(VkRenderer *renderer, AVBufferRef **dev)
{
RendererContext *ctx = (RendererContext *) renderer;
*dev = ctx->hw_device_ref;
return 0;
}
static int create_hw_frame(VkRenderer *renderer, AVFrame *frame)
{
RendererContext *ctx = (RendererContext *) renderer;
AVHWFramesContext *src_hw_frame = (AVHWFramesContext *)
frame->hw_frames_ctx->data;
AVHWFramesContext *hw_frame;
AVVulkanFramesContext *vk_frame_ctx;
int ret;
if (ctx->hw_frame_ref) {
hw_frame = (AVHWFramesContext *) ctx->hw_frame_ref->data;
if (hw_frame->width == frame->width &&
hw_frame->height == frame->height &&
hw_frame->sw_format == src_hw_frame->sw_format)
return 0;
av_buffer_unref(&ctx->hw_frame_ref);
}
if (!ctx->constraints) {
ctx->constraints = av_hwdevice_get_hwframe_constraints(
ctx->hw_device_ref, NULL);
if (!ctx->constraints)
return AVERROR(ENOMEM);
}
// Check constraints and skip create hwframe. Don't take it as error since
// we can fallback to memory copy from GPU to CPU.
if ((ctx->constraints->max_width &&
ctx->constraints->max_width < frame->width) ||
(ctx->constraints->max_height &&
ctx->constraints->max_height < frame->height) ||
(ctx->constraints->min_width &&
ctx->constraints->min_width > frame->width) ||
(ctx->constraints->min_height &&
ctx->constraints->min_height > frame->height))
return 0;
if (ctx->constraints->valid_sw_formats) {
enum AVPixelFormat *sw_formats = ctx->constraints->valid_sw_formats;
while (*sw_formats != AV_PIX_FMT_NONE) {
if (*sw_formats == src_hw_frame->sw_format)
break;
sw_formats++;
}
if (*sw_formats == AV_PIX_FMT_NONE)
return 0;
}
ctx->hw_frame_ref = av_hwframe_ctx_alloc(ctx->hw_device_ref);
if (!ctx->hw_frame_ref)
return AVERROR(ENOMEM);
hw_frame = (AVHWFramesContext *) ctx->hw_frame_ref->data;
hw_frame->format = AV_PIX_FMT_VULKAN;
hw_frame->sw_format = src_hw_frame->sw_format;
hw_frame->width = frame->width;
hw_frame->height = frame->height;
if (frame->format == AV_PIX_FMT_CUDA) {
vk_frame_ctx = hw_frame->hwctx;
vk_frame_ctx->flags = AV_VK_FRAME_FLAG_DISABLE_MULTIPLANE;
}
ret = av_hwframe_ctx_init(ctx->hw_frame_ref);
if (ret < 0) {
av_log(renderer, AV_LOG_ERROR, "Create hwframe context failed, %s\n",
av_err2str(ret));
return ret;
}
av_hwframe_transfer_get_formats(ctx->hw_frame_ref,
AV_HWFRAME_TRANSFER_DIRECTION_TO,
&ctx->transfer_formats, 0);
return 0;
}
static inline int check_hw_transfer(RendererContext *ctx, AVFrame *frame)
{
if (!ctx->hw_frame_ref || !ctx->transfer_formats)
return 0;
for (int i = 0; ctx->transfer_formats[i] != AV_PIX_FMT_NONE; i++)
if (ctx->transfer_formats[i] == frame->format)
return 1;
return 0;
}
static inline int move_to_output_frame(RendererContext *ctx, AVFrame *frame)
{
int ret = av_frame_copy_props(ctx->vk_frame, frame);
if (ret < 0)
return ret;
av_frame_unref(frame);
av_frame_move_ref(frame, ctx->vk_frame);
return 0;
}
static int map_frame(VkRenderer *renderer, AVFrame *frame, int use_hw_frame)
{
RendererContext *ctx = (RendererContext *) renderer;
int ret;
if (use_hw_frame && !ctx->hw_frame_ref)
return AVERROR(ENOSYS);
// Try map data first
av_frame_unref(ctx->vk_frame);
if (use_hw_frame) {
ctx->vk_frame->hw_frames_ctx = av_buffer_ref(ctx->hw_frame_ref);
ctx->vk_frame->format = AV_PIX_FMT_VULKAN;
}
ret = av_hwframe_map(ctx->vk_frame, frame, 0);
if (!ret)
return move_to_output_frame(ctx, frame);
if (ret != AVERROR(ENOSYS))
av_log(NULL, AV_LOG_FATAL, "Map frame failed: %s\n", av_err2str(ret));
return ret;
}
static int transfer_frame(VkRenderer *renderer, AVFrame *frame, int use_hw_frame)
{
RendererContext *ctx = (RendererContext *) renderer;
int ret;
if (use_hw_frame && !check_hw_transfer(ctx, frame))
return AVERROR(ENOSYS);
av_frame_unref(ctx->vk_frame);
if (use_hw_frame)
av_hwframe_get_buffer(ctx->hw_frame_ref, ctx->vk_frame, 0);
ret = av_hwframe_transfer_data(ctx->vk_frame, frame, 1);
if (!ret)
return move_to_output_frame(ctx, frame);
if (ret != AVERROR(ENOSYS))
av_log(NULL, AV_LOG_FATAL, "Transfer frame failed: %s\n",
av_err2str(ret));
return ret;
}
static int convert_frame(VkRenderer *renderer, AVFrame *frame)
{
int ret;
if (!frame->hw_frames_ctx)
return 0;
if (frame->format == AV_PIX_FMT_VULKAN)
return 0;
ret = create_hw_frame(renderer, frame);
if (ret < 0)
return ret;
for (int use_hw = 1; use_hw >=0; use_hw--) {
ret = map_frame(renderer, frame, use_hw);
if (!ret)
return 0;
if (ret != AVERROR(ENOSYS))
return ret;
ret = transfer_frame(renderer, frame, use_hw);
if (!ret)
return 0;
if (ret != AVERROR(ENOSYS))
return ret;
}
return ret;
}
static int display(VkRenderer *renderer, AVFrame *frame)
{
struct pl_swapchain_frame swap_frame = {0};
struct pl_frame pl_frame = {0};
struct pl_frame target = {0};
RendererContext *ctx = (RendererContext *) renderer;
int ret = 0;
ret = convert_frame(renderer, frame);
if (ret < 0)
return ret;
if (!pl_map_avframe_ex(ctx->placebo_vulkan->gpu, &pl_frame, pl_avframe_params(
.frame = frame,
.tex = ctx->tex))) {
av_log(NULL, AV_LOG_ERROR, "pl_map_avframe_ex failed\n");
return AVERROR_EXTERNAL;
}
if (!pl_swapchain_start_frame(ctx->swapchain, &swap_frame)) {
av_log(NULL, AV_LOG_ERROR, "start frame failed\n");
ret = AVERROR_EXTERNAL;
goto out;
}
pl_frame_from_swapchain(&target, &swap_frame);
if (!pl_render_image(ctx->renderer, &pl_frame, &target,
&pl_render_default_params)) {
av_log(NULL, AV_LOG_ERROR, "pl_render_image failed\n");
ret = AVERROR_EXTERNAL;
goto out;
}
if (!pl_swapchain_submit_frame(ctx->swapchain)) {
av_log(NULL, AV_LOG_ERROR, "pl_swapchain_submit_frame failed\n");
ret = AVERROR_EXTERNAL;
goto out;
}
pl_swapchain_swap_buffers(ctx->swapchain);
out:
pl_unmap_avframe(ctx->placebo_vulkan->gpu, &pl_frame);
return ret;
}
static int resize(VkRenderer *renderer, int width, int height)
{
RendererContext *ctx = (RendererContext *) renderer;
if (!pl_swapchain_resize(ctx->swapchain, &width, &height))
return AVERROR_EXTERNAL;
return 0;
}
static void destroy(VkRenderer *renderer)
{
RendererContext *ctx = (RendererContext *) renderer;
PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
av_frame_free(&ctx->vk_frame);
av_freep(&ctx->transfer_formats);
av_hwframe_constraints_free(&ctx->constraints);
av_buffer_unref(&ctx->hw_frame_ref);
if (ctx->placebo_vulkan) {
for (int i = 0; i < FF_ARRAY_ELEMS(ctx->tex); i++)
pl_tex_destroy(ctx->placebo_vulkan->gpu, &ctx->tex[i]);
pl_renderer_destroy(&ctx->renderer);
pl_swapchain_destroy(&ctx->swapchain);
pl_vulkan_destroy(&ctx->placebo_vulkan);
}
if (ctx->vk_surface) {
vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)
ctx->get_proc_addr(ctx->inst, "vkDestroySurfaceKHR");
vkDestroySurfaceKHR(ctx->inst, ctx->vk_surface, NULL);
ctx->vk_surface = NULL;
}
av_buffer_unref(&ctx->hw_device_ref);
pl_vk_inst_destroy(&ctx->placebo_instance);
pl_log_destroy(&ctx->vk_log);
}
static const AVClass vulkan_renderer_class = {
.class_name = "Vulkan Renderer",
.item_name = av_default_item_name,
.version = LIBAVUTIL_VERSION_INT,
};
VkRenderer *vk_get_renderer(void)
{
RendererContext *ctx = av_mallocz(sizeof(*ctx));
VkRenderer *renderer;
if (!ctx)
return NULL;
renderer = &ctx->api;
renderer->class = &vulkan_renderer_class;
renderer->get_hw_dev = get_hw_dev;
renderer->create = create;
renderer->display = display;
renderer->resize = resize;
renderer->destroy = destroy;
return renderer;
}
#else
VkRenderer *vk_get_renderer(void)
{
return NULL;
}
#endif
int vk_renderer_create(VkRenderer *renderer, SDL_Window *window,
AVDictionary *opt)
{
return renderer->create(renderer, window, opt);
}
int vk_renderer_get_hw_dev(VkRenderer *renderer, AVBufferRef **dev)
{
return renderer->get_hw_dev(renderer, dev);
}
int vk_renderer_display(VkRenderer *renderer, AVFrame *frame)
{
return renderer->display(renderer, frame);
}
int vk_renderer_resize(VkRenderer *renderer, int width, int height)
{
return renderer->resize(renderer, width, height);
}
void vk_renderer_destroy(VkRenderer *renderer)
{
renderer->destroy(renderer);
}

41
fftools/ffplay_renderer.h Normal file
View File

@@ -0,0 +1,41 @@
/*
* 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 FFTOOLS_FFPLAY_RENDERER_H
#define FFTOOLS_FFPLAY_RENDERER_H
#include <SDL.h>
#include "libavutil/frame.h"
typedef struct VkRenderer VkRenderer;
VkRenderer *vk_get_renderer(void);
int vk_renderer_create(VkRenderer *renderer, SDL_Window *window,
AVDictionary *opt);
int vk_renderer_get_hw_dev(VkRenderer *renderer, AVBufferRef **dev);
int vk_renderer_display(VkRenderer *renderer, AVFrame *frame);
int vk_renderer_resize(VkRenderer *renderer, int width, int height);
void vk_renderer_destroy(VkRenderer *renderer);
#endif /* FFTOOLS_FFPLAY_RENDERER_H */

View File

@@ -164,7 +164,12 @@ static int receive_locked(ThreadQueue *tq, int *stream_idx,
FifoElem elem;
unsigned int nb_finished = 0;
if (av_fifo_read(tq->fifo, &elem, 1) >= 0) {
while (av_fifo_read(tq->fifo, &elem, 1) >= 0) {
if (tq->finished[elem.stream_idx] & FINISHED_RECV) {
objpool_release(tq->obj_pool, &elem.obj);
continue;
}
tq->obj_move(data, elem.obj);
objpool_release(tq->obj_pool, &elem.obj);
*stream_idx = elem.stream_idx;
@@ -172,7 +177,7 @@ static int receive_locked(ThreadQueue *tq, int *stream_idx,
}
for (unsigned int i = 0; i < tq->nb_streams; i++) {
if (!(tq->finished[i] & FINISHED_SEND))
if (!tq->finished[i])
continue;
/* return EOF to the consumer at most once for each stream */
@@ -197,7 +202,14 @@ int tq_receive(ThreadQueue *tq, int *stream_idx, void *data)
pthread_mutex_lock(&tq->lock);
while (1) {
size_t can_read = av_fifo_can_read(tq->fifo);
ret = receive_locked(tq, stream_idx, data);
// signal other threads if the fifo state changed
if (can_read != av_fifo_can_read(tq->fifo))
pthread_cond_broadcast(&tq->cond);
if (ret == AVERROR(EAGAIN)) {
pthread_cond_wait(&tq->cond, &tq->lock);
continue;
@@ -206,9 +218,6 @@ int tq_receive(ThreadQueue *tq, int *stream_idx, void *data)
break;
}
if (ret == 0)
pthread_cond_broadcast(&tq->cond);
pthread_mutex_unlock(&tq->lock);
return ret;

View File

@@ -125,7 +125,7 @@ static const uint8_t dequant_table[64] = {
20, 35, 34, 32, 31, 22, 15, 8,
};
static VLC block_type_vlc[2][4];
static VLCElem block_type_vlc[2][4][32];
typedef struct CFrameBuffer {
@@ -250,17 +250,15 @@ static void idct(int16_t block[64])
static av_cold void init_vlcs(void)
{
static VLCElem table[2][4][32];
int i, j;
for (i = 0; i < 2; i++) {
for (j = 0; j < 4; j++) {
block_type_vlc[i][j].table = table[i][j];
block_type_vlc[i][j].table_allocated = 32;
vlc_init(&block_type_vlc[i][j], BLOCK_TYPE_VLC_BITS, 7,
&block_type_tab[i][j][0][1], 2, 1,
&block_type_tab[i][j][0][0], 2, 1,
VLC_INIT_USE_STATIC);
ff_vlc_init_table_sparse(block_type_vlc[i][j], FF_ARRAY_ELEMS(block_type_vlc[i][j]),
BLOCK_TYPE_VLC_BITS, 7,
&block_type_tab[i][j][0][1], 2, 1,
&block_type_tab[i][j][0][0], 2, 1,
NULL, 0, 0, 0);
}
}
}
@@ -357,7 +355,7 @@ static int decode_p_block(FourXContext *f, uint16_t *dst, const uint16_t *src,
if (get_bits_left(&f->gb) < 1)
return AVERROR_INVALIDDATA;
h = 1 << log2h;
code = get_vlc2(&f->gb, block_type_vlc[1 - (f->version > 1)][index].table,
code = get_vlc2(&f->gb, block_type_vlc[1 - (f->version > 1)][index],
BLOCK_TYPE_VLC_BITS, 1);
av_assert0(code >= 0 && code <= 6);

View File

@@ -43,6 +43,8 @@ typedef struct EightBpsContext {
uint8_t planes;
uint8_t planemap[4];
uint32_t pal[256];
} EightBpsContext;
static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
@@ -116,10 +118,12 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
FF_DISABLE_DEPRECATION_WARNINGS
frame->palette_has_changed =
#endif
ff_copy_palette(frame->data[1], avpkt, avctx);
ff_copy_palette(c->pal, avpkt, avctx);
#if FF_API_PALETTE_HAS_CHANGED
FF_ENABLE_DEPRECATION_WARNINGS
#endif
memcpy(frame->data[1], c->pal, AVPALETTE_SIZE);
}
*got_frame = 1;

View File

@@ -81,6 +81,7 @@ OBJS-$(CONFIG_CBS_H265) += cbs_h2645.o cbs_sei.o h2645_parse.o
OBJS-$(CONFIG_CBS_H266) += cbs_h2645.o cbs_sei.o h2645_parse.o
OBJS-$(CONFIG_CBS_JPEG) += cbs_jpeg.o
OBJS-$(CONFIG_CBS_MPEG2) += cbs_mpeg2.o
OBJS-$(CONFIG_CBS_VP8) += cbs_vp8.o vp8data.o
OBJS-$(CONFIG_CBS_VP9) += cbs_vp9.o
OBJS-$(CONFIG_CRYSTALHD) += crystalhd.o
OBJS-$(CONFIG_DEFLATE_WRAPPER) += zlib_wrapper.o
@@ -176,10 +177,12 @@ OBJS-$(CONFIG_WMV2DSP) += wmv2dsp.o
OBJS-$(CONFIG_ZERO12V_DECODER) += 012v.o
OBJS-$(CONFIG_A64MULTI_ENCODER) += a64multienc.o elbg.o
OBJS-$(CONFIG_A64MULTI5_ENCODER) += a64multienc.o elbg.o
OBJS-$(CONFIG_AAC_DECODER) += aacdec.o aactab.o aacsbr.o aacps_common.o aacps_float.o \
OBJS-$(CONFIG_AAC_DECODER) += aacdec.o aacdec_common.o aactab.o \
aacsbr.o aacps_common.o aacps_float.o \
kbdwin.o \
sbrdsp.o aacpsdsp_float.o cbrt_data.o
OBJS-$(CONFIG_AAC_FIXED_DECODER) += aacdec_fixed.o aactab.o aacsbr_fixed.o aacps_common.o aacps_fixed.o \
OBJS-$(CONFIG_AAC_FIXED_DECODER) += aacdec_fixed.o aacdec_common.o aactab.o \
aacsbr_fixed.o aacps_common.o aacps_fixed.o \
kbdwin.o \
sbrdsp_fixed.o aacpsdsp_fixed.o cbrt_data_fixed.o
OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacenctab.o \
@@ -477,6 +480,7 @@ OBJS-$(CONFIG_JV_DECODER) += jvdec.o
OBJS-$(CONFIG_KGV1_DECODER) += kgv1dec.o
OBJS-$(CONFIG_KMVC_DECODER) += kmvc.o
OBJS-$(CONFIG_LAGARITH_DECODER) += lagarith.o lagarithrac.o
OBJS-$(CONFIG_LEAD_DECODER) += leaddec.o jpegquanttables.o
OBJS-$(CONFIG_LJPEG_ENCODER) += ljpegenc.o mjpegenc_common.o
OBJS-$(CONFIG_LOCO_DECODER) += loco.o
OBJS-$(CONFIG_LSCR_DECODER) += lscrdec.o png.o pngdec.o pngdsp.o

View File

@@ -564,8 +564,8 @@ const FFCodec ff_aac_decoder = {
},
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(aac_channel_layout)
.p.ch_layouts = aac_ch_layout,
CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(ff_aac_channel_layout)
.p.ch_layouts = ff_aac_ch_layout,
.flush = flush,
.p.priv_class = &aac_decoder_class,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
@@ -590,8 +590,8 @@ const FFCodec ff_aac_latm_decoder = {
},
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(aac_channel_layout)
.p.ch_layouts = aac_ch_layout,
CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(ff_aac_channel_layout)
.p.ch_layouts = ff_aac_ch_layout,
.flush = flush,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
};

324
libavcodec/aacdec_common.c Normal file
View File

@@ -0,0 +1,324 @@
/*
* Common code and tables of the AAC fixed- and floating-point decoders
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov 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
*/
/**
* @file
* Common code and tables of the AAC fixed- and floating-point decoders
*/
#include "aac.h"
#include "aacdectab.h"
#include "aacps.h"
#include "aactab.h"
#include "vlc.h"
#include "libavutil/attributes.h"
#include "libavutil/thread.h"
const int8_t ff_tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 5, 5, 16, 5, 0 };
const uint8_t ff_aac_channel_layout_map[16][16][3] = {
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, },
{ { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
{ { 0, } },
{ { 0, } },
{ { 0, } },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
{
{ TYPE_SCE, 0, AAC_CHANNEL_FRONT }, // SCE1 = FC,
{ TYPE_CPE, 0, AAC_CHANNEL_FRONT }, // CPE1 = FLc and FRc,
{ TYPE_CPE, 1, AAC_CHANNEL_FRONT }, // CPE2 = FL and FR,
{ TYPE_CPE, 2, AAC_CHANNEL_BACK }, // CPE3 = SiL and SiR,
{ TYPE_CPE, 3, AAC_CHANNEL_BACK }, // CPE4 = BL and BR,
{ TYPE_SCE, 1, AAC_CHANNEL_BACK }, // SCE2 = BC,
{ TYPE_LFE, 0, AAC_CHANNEL_LFE }, // LFE1 = LFE1,
{ TYPE_LFE, 1, AAC_CHANNEL_LFE }, // LFE2 = LFE2,
{ TYPE_SCE, 2, AAC_CHANNEL_FRONT }, // SCE3 = TpFC,
{ TYPE_CPE, 4, AAC_CHANNEL_FRONT }, // CPE5 = TpFL and TpFR,
{ TYPE_CPE, 5, AAC_CHANNEL_SIDE }, // CPE6 = TpSiL and TpSiR,
{ TYPE_SCE, 3, AAC_CHANNEL_SIDE }, // SCE4 = TpC,
{ TYPE_CPE, 6, AAC_CHANNEL_BACK }, // CPE7 = TpBL and TpBR,
{ TYPE_SCE, 4, AAC_CHANNEL_BACK }, // SCE5 = TpBC,
{ TYPE_SCE, 5, AAC_CHANNEL_FRONT }, // SCE6 = BtFC,
{ TYPE_CPE, 7, AAC_CHANNEL_FRONT }, // CPE8 = BtFL and BtFR
},
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, { TYPE_CPE, 2, AAC_CHANNEL_FRONT }, },
{ { 0, } },
};
const int16_t ff_aac_channel_map[3][4][6] = {
{
{ AV_CHAN_FRONT_CENTER, AV_CHAN_FRONT_LEFT_OF_CENTER, AV_CHAN_FRONT_RIGHT_OF_CENTER, AV_CHAN_FRONT_LEFT, AV_CHAN_FRONT_RIGHT, AV_CHAN_NONE },
{ AV_CHAN_UNUSED, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
{ AV_CHAN_UNUSED, AV_CHAN_SIDE_LEFT, AV_CHAN_SIDE_RIGHT, AV_CHAN_BACK_LEFT, AV_CHAN_BACK_RIGHT, AV_CHAN_BACK_CENTER },
{ AV_CHAN_LOW_FREQUENCY, AV_CHAN_LOW_FREQUENCY_2, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
},
{
{ AV_CHAN_TOP_FRONT_CENTER, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_TOP_FRONT_LEFT, AV_CHAN_TOP_FRONT_RIGHT, AV_CHAN_NONE },
{ AV_CHAN_UNUSED, AV_CHAN_TOP_SIDE_LEFT, AV_CHAN_TOP_SIDE_RIGHT, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_TOP_CENTER},
{ AV_CHAN_UNUSED, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_TOP_BACK_LEFT, AV_CHAN_TOP_BACK_RIGHT, AV_CHAN_TOP_BACK_CENTER},
{ AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE},
},
{
{ AV_CHAN_BOTTOM_FRONT_CENTER, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_BOTTOM_FRONT_LEFT, AV_CHAN_BOTTOM_FRONT_RIGHT, AV_CHAN_NONE },
{ AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
{ AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
{ AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
},
};
#if FF_API_OLD_CHANNEL_LAYOUT
const uint64_t ff_aac_channel_layout[] = {
AV_CH_LAYOUT_MONO,
AV_CH_LAYOUT_STEREO,
AV_CH_LAYOUT_SURROUND,
AV_CH_LAYOUT_4POINT0,
AV_CH_LAYOUT_5POINT0_BACK,
AV_CH_LAYOUT_5POINT1_BACK,
AV_CH_LAYOUT_7POINT1_WIDE_BACK,
AV_CH_LAYOUT_6POINT1_BACK,
AV_CH_LAYOUT_7POINT1,
AV_CH_LAYOUT_22POINT2,
AV_CH_LAYOUT_7POINT1_TOP_BACK,
0,
};
#endif
const AVChannelLayout ff_aac_ch_layout[] = {
AV_CHANNEL_LAYOUT_MONO,
AV_CHANNEL_LAYOUT_STEREO,
AV_CHANNEL_LAYOUT_SURROUND,
AV_CHANNEL_LAYOUT_4POINT0,
AV_CHANNEL_LAYOUT_5POINT0_BACK,
AV_CHANNEL_LAYOUT_5POINT1_BACK,
AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK,
AV_CHANNEL_LAYOUT_6POINT1_BACK,
AV_CHANNEL_LAYOUT_7POINT1,
AV_CHANNEL_LAYOUT_22POINT2,
AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK,
{ 0 },
};
VLCElem ff_vlc_scalefactors[352];
const VLCElem *ff_vlc_spectral[11];
/// Huffman tables for SBR
static const uint8_t sbr_huffman_tab[][2] = {
/* t_huffman_env_1_5dB - 121 entries */
{ 60, 2 }, { 59, 2 }, { 61, 3 }, { 58, 3 }, { 62, 4 },
{ 57, 4 }, { 63, 5 }, { 56, 5 }, { 64, 6 }, { 55, 6 },
{ 65, 7 }, { 54, 7 }, { 66, 8 }, { 53, 8 }, { 67, 9 },
{ 52, 9 }, { 51, 10 }, { 68, 10 }, { 50, 11 }, { 69, 12 },
{ 49, 12 }, { 70, 13 }, { 48, 13 }, { 47, 13 }, { 71, 14 },
{ 46, 14 }, { 72, 14 }, { 45, 14 }, { 44, 15 }, { 73, 15 },
{ 41, 16 }, { 42, 16 }, { 43, 16 }, { 74, 16 }, { 36, 16 },
{ 40, 16 }, { 76, 16 }, { 34, 17 }, { 39, 17 }, { 75, 17 },
{ 37, 17 }, { 35, 18 }, { 38, 18 }, { 0, 18 }, { 1, 18 },
{ 2, 18 }, { 3, 18 }, { 4, 18 }, { 5, 18 }, { 6, 19 },
{ 7, 19 }, { 8, 19 }, { 9, 19 }, { 10, 19 }, { 11, 19 },
{ 12, 19 }, { 13, 19 }, { 14, 19 }, { 15, 19 }, { 16, 19 },
{ 17, 19 }, { 18, 19 }, { 19, 19 }, { 20, 19 }, { 21, 19 },
{ 22, 19 }, { 23, 19 }, { 24, 19 }, { 25, 19 }, { 26, 19 },
{ 27, 19 }, { 28, 19 }, { 29, 19 }, { 30, 19 }, { 31, 19 },
{ 32, 19 }, { 33, 19 }, { 77, 19 }, { 78, 19 }, { 79, 19 },
{ 80, 19 }, { 81, 19 }, { 82, 19 }, { 83, 19 }, { 84, 19 },
{ 85, 19 }, { 86, 19 }, { 87, 19 }, { 88, 19 }, { 89, 19 },
{ 90, 19 }, { 91, 19 }, { 92, 19 }, { 93, 19 }, { 94, 19 },
{ 95, 19 }, { 96, 19 }, { 97, 19 }, { 98, 19 }, { 99, 19 },
{ 100, 19 }, { 101, 19 }, { 102, 19 }, { 103, 19 }, { 104, 19 },
{ 105, 19 }, { 106, 19 }, { 107, 19 }, { 108, 19 }, { 109, 19 },
{ 110, 19 }, { 111, 19 }, { 112, 19 }, { 113, 19 }, { 114, 19 },
{ 115, 19 }, { 116, 19 }, { 117, 19 }, { 118, 19 }, { 119, 19 },
{ 120, 19 },
/* f_huffman_env_1_5dB - 121 entries */
{ 60, 2 }, { 59, 2 }, { 61, 3 }, { 58, 3 }, { 57, 4 },
{ 62, 4 }, { 56, 5 }, { 63, 5 }, { 55, 6 }, { 64, 6 },
{ 54, 7 }, { 65, 8 }, { 53, 8 }, { 66, 8 }, { 52, 9 },
{ 67, 9 }, { 51, 9 }, { 68, 10 }, { 50, 10 }, { 69, 11 },
{ 49, 11 }, { 70, 11 }, { 71, 11 }, { 48, 12 }, { 72, 12 },
{ 47, 12 }, { 73, 12 }, { 74, 13 }, { 46, 13 }, { 45, 13 },
{ 75, 13 }, { 76, 14 }, { 77, 14 }, { 44, 14 }, { 43, 15 },
{ 42, 15 }, { 41, 16 }, { 78, 16 }, { 79, 16 }, { 40, 16 },
{ 39, 16 }, { 80, 17 }, { 81, 17 }, { 36, 17 }, { 37, 17 },
{ 38, 17 }, { 34, 17 }, { 32, 18 }, { 82, 18 }, { 83, 18 },
{ 85, 18 }, { 19, 18 }, { 35, 18 }, { 86, 18 }, { 87, 18 },
{ 30, 18 }, { 33, 18 }, { 84, 18 }, { 88, 18 }, { 104, 18 },
{ 9, 19 }, { 14, 19 }, { 16, 19 }, { 17, 19 }, { 23, 19 },
{ 27, 19 }, { 29, 19 }, { 31, 19 }, { 90, 19 }, { 97, 19 },
{ 102, 19 }, { 107, 19 }, { 108, 19 }, { 0, 19 }, { 1, 19 },
{ 2, 20 }, { 3, 20 }, { 4, 20 }, { 5, 20 }, { 6, 20 },
{ 7, 20 }, { 8, 20 }, { 10, 20 }, { 11, 20 }, { 12, 20 },
{ 13, 20 }, { 15, 20 }, { 18, 20 }, { 20, 20 }, { 21, 20 },
{ 22, 20 }, { 24, 20 }, { 25, 20 }, { 26, 20 }, { 28, 20 },
{ 89, 20 }, { 91, 20 }, { 92, 20 }, { 93, 20 }, { 94, 20 },
{ 95, 20 }, { 96, 20 }, { 98, 20 }, { 99, 20 }, { 100, 20 },
{ 101, 20 }, { 103, 20 }, { 105, 20 }, { 106, 20 }, { 109, 20 },
{ 110, 20 }, { 111, 20 }, { 112, 20 }, { 113, 20 }, { 114, 20 },
{ 115, 20 }, { 116, 20 }, { 117, 20 }, { 118, 20 }, { 119, 20 },
{ 120, 20 },
/* t_huffman_env_bal_1_5dB - 49 entries */
{ 24, 1 }, { 25, 2 }, { 23, 3 }, { 26, 4 }, { 22, 5 },
{ 27, 6 }, { 21, 7 }, { 28, 8 }, { 20, 9 }, { 19, 11 },
{ 29, 11 }, { 18, 12 }, { 30, 12 }, { 31, 15 }, { 17, 16 },
{ 32, 16 }, { 0, 16 }, { 1, 16 }, { 2, 16 }, { 3, 16 },
{ 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 }, { 8, 16 },
{ 9, 16 }, { 10, 16 }, { 11, 16 }, { 12, 16 }, { 13, 16 },
{ 14, 16 }, { 15, 16 }, { 16, 16 }, { 33, 16 }, { 34, 16 },
{ 35, 16 }, { 36, 16 }, { 37, 16 }, { 38, 16 }, { 39, 17 },
{ 40, 17 }, { 41, 17 }, { 42, 17 }, { 43, 17 }, { 44, 17 },
{ 45, 17 }, { 46, 17 }, { 47, 17 }, { 48, 17 },
/* f_huffman_env_bal_1_5dB - 49 entries */
{ 24, 1 }, { 23, 2 }, { 25, 3 }, { 22, 4 }, { 26, 5 },
{ 27, 6 }, { 21, 7 }, { 20, 8 }, { 28, 9 }, { 19, 11 },
{ 29, 11 }, { 18, 11 }, { 30, 12 }, { 17, 14 }, { 31, 15 },
{ 32, 16 }, { 15, 16 }, { 16, 17 }, { 0, 18 }, { 1, 18 },
{ 2, 18 }, { 3, 18 }, { 4, 18 }, { 5, 18 }, { 6, 18 },
{ 7, 18 }, { 8, 18 }, { 9, 18 }, { 10, 18 }, { 11, 18 },
{ 12, 18 }, { 13, 18 }, { 14, 18 }, { 33, 18 }, { 34, 18 },
{ 35, 18 }, { 36, 18 }, { 37, 18 }, { 38, 18 }, { 39, 18 },
{ 40, 18 }, { 41, 18 }, { 42, 18 }, { 43, 18 }, { 44, 18 },
{ 45, 18 }, { 46, 18 }, { 47, 19 }, { 48, 19 },
/* t_huffman_env_3_0dB - 63 entries */
{ 31, 1 }, { 30, 2 }, { 32, 3 }, { 29, 4 }, { 33, 5 },
{ 28, 6 }, { 34, 7 }, { 27, 8 }, { 35, 9 }, { 26, 11 },
{ 36, 11 }, { 25, 12 }, { 24, 13 }, { 37, 13 }, { 23, 14 },
{ 38, 14 }, { 22, 14 }, { 21, 14 }, { 39, 14 }, { 40, 15 },
{ 41, 16 }, { 18, 16 }, { 20, 16 }, { 19, 16 }, { 17, 17 },
{ 42, 17 }, { 43, 18 }, { 0, 18 }, { 1, 18 }, { 2, 19 },
{ 3, 19 }, { 4, 19 }, { 5, 19 }, { 6, 19 }, { 7, 19 },
{ 8, 19 }, { 9, 19 }, { 10, 19 }, { 11, 19 }, { 12, 19 },
{ 13, 19 }, { 14, 19 }, { 15, 19 }, { 16, 19 }, { 44, 19 },
{ 45, 19 }, { 46, 19 }, { 47, 19 }, { 48, 19 }, { 49, 19 },
{ 50, 19 }, { 51, 19 }, { 52, 19 }, { 53, 19 }, { 54, 19 },
{ 55, 19 }, { 56, 19 }, { 57, 19 }, { 58, 19 }, { 59, 19 },
{ 60, 19 }, { 61, 19 }, { 62, 19 },
/* f_huffman_env_3_0dB - 63 entries */
{ 31, 1 }, { 30, 2 }, { 32, 3 }, { 29, 4 }, { 33, 5 },
{ 28, 6 }, { 34, 8 }, { 27, 8 }, { 35, 9 }, { 26, 9 },
{ 36, 10 }, { 25, 10 }, { 37, 11 }, { 24, 11 }, { 38, 12 },
{ 23, 12 }, { 39, 13 }, { 40, 14 }, { 22, 14 }, { 21, 15 },
{ 41, 15 }, { 42, 15 }, { 20, 16 }, { 19, 16 }, { 43, 16 },
{ 44, 16 }, { 18, 17 }, { 16, 17 }, { 45, 17 }, { 46, 17 },
{ 17, 18 }, { 49, 18 }, { 13, 18 }, { 7, 18 }, { 12, 18 },
{ 47, 18 }, { 48, 18 }, { 9, 19 }, { 10, 19 }, { 15, 19 },
{ 51, 19 }, { 52, 19 }, { 53, 19 }, { 56, 19 }, { 8, 19 },
{ 11, 19 }, { 55, 19 }, { 0, 20 }, { 1, 20 }, { 2, 20 },
{ 3, 20 }, { 4, 20 }, { 5, 20 }, { 6, 20 }, { 14, 20 },
{ 50, 20 }, { 54, 20 }, { 57, 20 }, { 58, 20 }, { 59, 20 },
{ 60, 20 }, { 61, 20 }, { 62, 20 },
/* t_huffman_env_bal_3_0dB - 25 entries */
{ 12, 1 }, { 13, 2 }, { 11, 3 }, { 10, 4 }, { 14, 5 },
{ 15, 6 }, { 9, 7 }, { 8, 8 }, { 16, 9 }, { 7, 12 },
{ 0, 13 }, { 1, 13 }, { 2, 13 }, { 3, 13 }, { 4, 13 },
{ 5, 13 }, { 6, 13 }, { 17, 13 }, { 18, 13 }, { 19, 13 },
{ 20, 13 }, { 21, 13 }, { 22, 13 }, { 23, 14 }, { 24, 14 },
/* f_huffman_env_bal_3_0dB - 25 entries */
{ 12, 1 }, { 11, 2 }, { 13, 3 }, { 10, 4 }, { 14, 5 },
{ 15, 6 }, { 9, 7 }, { 8, 8 }, { 16, 9 }, { 7, 11 },
{ 17, 12 }, { 18, 13 }, { 0, 13 }, { 1, 13 }, { 2, 13 },
{ 3, 13 }, { 4, 13 }, { 5, 14 }, { 6, 14 }, { 19, 14 },
{ 20, 14 }, { 21, 14 }, { 22, 14 }, { 23, 14 }, { 24, 14 },
/* t_huffman_noise_3_0dB - 63 entries */
{ 31, 1 }, { 32, 2 }, { 30, 3 }, { 29, 4 }, { 33, 5 },
{ 28, 6 }, { 34, 8 }, { 27, 8 }, { 35, 10 }, { 26, 11 },
{ 36, 13 }, { 42, 13 }, { 0, 13 }, { 1, 13 }, { 2, 13 },
{ 3, 13 }, { 4, 13 }, { 5, 13 }, { 6, 13 }, { 7, 13 },
{ 8, 13 }, { 9, 13 }, { 10, 13 }, { 11, 13 }, { 12, 13 },
{ 13, 13 }, { 14, 13 }, { 15, 13 }, { 16, 13 }, { 17, 13 },
{ 18, 13 }, { 19, 13 }, { 20, 13 }, { 21, 13 }, { 22, 13 },
{ 23, 13 }, { 24, 13 }, { 25, 13 }, { 37, 13 }, { 38, 13 },
{ 39, 13 }, { 40, 13 }, { 41, 13 }, { 43, 13 }, { 44, 13 },
{ 45, 13 }, { 46, 13 }, { 47, 13 }, { 48, 13 }, { 49, 13 },
{ 50, 13 }, { 51, 13 }, { 52, 13 }, { 53, 13 }, { 54, 13 },
{ 55, 13 }, { 56, 13 }, { 57, 13 }, { 58, 13 }, { 59, 13 },
{ 60, 13 }, { 61, 14 }, { 62, 14 },
/* t_huffman_noise_bal_3_0dB - 25 entries */
{ 12, 1 }, { 11, 2 }, { 13, 3 }, { 10, 5 }, { 14, 6 },
{ 0, 8 }, { 1, 8 }, { 2, 8 }, { 3, 8 }, { 4, 8 },
{ 5, 8 }, { 6, 8 }, { 7, 8 }, { 8, 8 }, { 9, 8 },
{ 15, 8 }, { 16, 8 }, { 17, 8 }, { 18, 8 }, { 19, 8 },
{ 20, 8 }, { 21, 8 }, { 22, 8 }, { 23, 8 }, { 24, 8 },
};
static const uint8_t sbr_huffman_nb_codes[] = {
121, 121, 49, 49, 63, 63, 25, 25, 63, 25
};
static const int8_t sbr_vlc_offsets[10] = {
-60, -60, -24, -24, -31, -31, -12, -12, -31, -12
};
const VLCElem *ff_aac_sbr_vlc[10];
static av_cold void aacdec_common_init(void)
{
static VLCElem vlc_buf[(304 + 270 + 550 + 300 + 328 +
294 + 306 + 268 + 510 + 366 + 462) +
(1098 + 1092 + 768 + 1026 + 1058 +
1052 + 544 + 544 + 592 + 512)];
VLCInitState state = VLC_INIT_STATE(vlc_buf);
const uint8_t (*tab)[2] = sbr_huffman_tab;
for (unsigned i = 0; i < 11; i++) {
#define TAB_WRAP_SIZE(name) name[i], sizeof(name[i][0]), sizeof(name[i][0])
ff_vlc_spectral[i] =
ff_vlc_init_tables_sparse(&state, 8, ff_aac_spectral_sizes[i],
TAB_WRAP_SIZE(ff_aac_spectral_bits),
TAB_WRAP_SIZE(ff_aac_spectral_codes),
TAB_WRAP_SIZE(ff_aac_codebook_vector_idx),
0);
}
VLC_INIT_STATIC_TABLE(ff_vlc_scalefactors, 7,
FF_ARRAY_ELEMS(ff_aac_scalefactor_code),
ff_aac_scalefactor_bits,
sizeof(ff_aac_scalefactor_bits[0]),
sizeof(ff_aac_scalefactor_bits[0]),
ff_aac_scalefactor_code,
sizeof(ff_aac_scalefactor_code[0]),
sizeof(ff_aac_scalefactor_code[0]), 0);
// SBR VLC table initialization
for (int i = 0; i < FF_ARRAY_ELEMS(ff_aac_sbr_vlc); i++) {
ff_aac_sbr_vlc[i] =
ff_vlc_init_tables_from_lengths(&state, 9, sbr_huffman_nb_codes[i],
&tab[0][1], 2,
&tab[0][0], 2, 1,
sbr_vlc_offsets[i], 0);
tab += sbr_huffman_nb_codes[i];
}
ff_ps_init_common();
}
av_cold void ff_aacdec_common_init_once(void)
{
static AVOnce init_static_once = AV_ONCE_INIT;
ff_thread_once(&init_static_once, aacdec_common_init);
}

View File

@@ -465,8 +465,8 @@ const FFCodec ff_aac_fixed_decoder = {
},
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(aac_channel_layout)
.p.ch_layouts = aac_ch_layout,
CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(ff_aac_channel_layout)
.p.ch_layouts = ff_aac_ch_layout,
.p.priv_class = &aac_decoder_class,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
.flush = flush,

View File

@@ -94,9 +94,6 @@
#include "decode.h"
#include "internal.h"
static VLC vlc_scalefactors;
static VLC vlc_spectral[11];
static int output_configure(AACContext *ac,
uint8_t layout_map[MAX_ELEM_ID*4][3], int tags,
enum OCStatus oc_type, int get_new_frame);
@@ -283,10 +280,10 @@ static int assign_channels(struct elem_to_channel e2c_vec[MAX_ELEM_ID], uint8_t
if (pos == AAC_CHANNEL_LFE) {
while (nb_channels) {
if (aac_channel_map[layer][pos - 1][j] == AV_CHAN_NONE)
if (ff_aac_channel_map[layer][pos - 1][j] == AV_CHAN_NONE)
return -1;
e2c_vec[i] = (struct elem_to_channel) {
.av_position = 1ULL << aac_channel_map[layer][pos - 1][j],
.av_position = 1ULL << ff_aac_channel_map[layer][pos - 1][j],
.syn_ele = layout_map[i][0],
.elem_id = layout_map[i][1],
.aac_position = pos
@@ -302,12 +299,12 @@ static int assign_channels(struct elem_to_channel e2c_vec[MAX_ELEM_ID], uint8_t
}
while (nb_channels & 1) {
if (aac_channel_map[layer][pos - 1][0] == AV_CHAN_NONE)
if (ff_aac_channel_map[layer][pos - 1][0] == AV_CHAN_NONE)
return -1;
if (aac_channel_map[layer][pos - 1][0] == AV_CHAN_UNUSED)
if (ff_aac_channel_map[layer][pos - 1][0] == AV_CHAN_UNUSED)
break;
e2c_vec[i] = (struct elem_to_channel) {
.av_position = 1ULL << aac_channel_map[layer][pos - 1][0],
.av_position = 1ULL << ff_aac_channel_map[layer][pos - 1][0],
.syn_ele = layout_map[i][0],
.elem_id = layout_map[i][1],
.aac_position = pos
@@ -319,21 +316,21 @@ static int assign_channels(struct elem_to_channel e2c_vec[MAX_ELEM_ID], uint8_t
j = (pos != AAC_CHANNEL_SIDE) && nb_channels <= 3 ? 3 : 1;
while (nb_channels >= 2) {
if (aac_channel_map[layer][pos - 1][j] == AV_CHAN_NONE ||
aac_channel_map[layer][pos - 1][j+1] == AV_CHAN_NONE)
if (ff_aac_channel_map[layer][pos - 1][j] == AV_CHAN_NONE ||
ff_aac_channel_map[layer][pos - 1][j+1] == AV_CHAN_NONE)
return -1;
i += assign_pair(e2c_vec, layout_map, i,
1ULL << aac_channel_map[layer][pos - 1][j],
1ULL << aac_channel_map[layer][pos - 1][j+1],
1ULL << ff_aac_channel_map[layer][pos - 1][j],
1ULL << ff_aac_channel_map[layer][pos - 1][j+1],
pos, layout);
j += 2;
nb_channels -= 2;
}
while (nb_channels & 1) {
if (aac_channel_map[layer][pos - 1][5] == AV_CHAN_NONE)
if (ff_aac_channel_map[layer][pos - 1][5] == AV_CHAN_NONE)
return -1;
e2c_vec[i] = (struct elem_to_channel) {
.av_position = 1ULL << aac_channel_map[layer][pos - 1][5],
.av_position = 1ULL << ff_aac_channel_map[layer][pos - 1][5],
.syn_ele = layout_map[i][0],
.elem_id = layout_map[i][1],
.aac_position = pos
@@ -552,8 +549,8 @@ static int set_default_channel_config(AACContext *ac, AVCodecContext *avctx,
channel_config);
return AVERROR_INVALIDDATA;
}
*tags = tags_per_config[channel_config];
memcpy(layout_map, aac_channel_layout_map[channel_config - 1],
*tags = ff_tags_per_config[channel_config];
memcpy(layout_map, ff_aac_channel_layout_map[channel_config - 1],
*tags * sizeof(*layout_map));
/*
@@ -661,7 +658,7 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
* SCE[0] CPE[0] CPE[1] LFE[0].
* If we seem to have encountered such a stream, transfer
* the LFE[0] element to the SCE[1]'s mapping */
if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) {
if (ac->tags_mapped == ff_tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) {
if (!ac->warned_remapping_once && (type != TYPE_LFE || elem_id != 0)) {
av_log(ac->avctx, AV_LOG_WARNING,
"This stream seems to incorrectly report its last channel as %s[%d], mapping to LFE[0]\n",
@@ -683,7 +680,7 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
* SCE[0] CPE[0] SCE[1].
* If we seem to have encountered such a stream, transfer
* the SCE[1] element to the LFE[0]'s mapping */
if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) {
if (ac->tags_mapped == ff_tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) {
if (!ac->warned_remapping_once && (type != TYPE_SCE || elem_id != 1)) {
av_log(ac->avctx, AV_LOG_WARNING,
"This stream seems to incorrectly report its last channel as %s[%d], mapping to SCE[1]\n",
@@ -1128,35 +1125,9 @@ static void aacdec_init(AACContext *ac);
static av_cold void aac_static_table_init(void)
{
static VLCElem vlc_buf[304 + 270 + 550 + 300 + 328 +
294 + 306 + 268 + 510 + 366 + 462];
for (unsigned i = 0, offset = 0; i < 11; i++) {
vlc_spectral[i].table = &vlc_buf[offset];
vlc_spectral[i].table_allocated = FF_ARRAY_ELEMS(vlc_buf) - offset;
ff_vlc_init_sparse(&vlc_spectral[i], 8, ff_aac_spectral_sizes[i],
ff_aac_spectral_bits[i], sizeof(ff_aac_spectral_bits[i][0]),
sizeof(ff_aac_spectral_bits[i][0]),
ff_aac_spectral_codes[i], sizeof(ff_aac_spectral_codes[i][0]),
sizeof(ff_aac_spectral_codes[i][0]),
ff_aac_codebook_vector_idx[i], sizeof(ff_aac_codebook_vector_idx[i][0]),
sizeof(ff_aac_codebook_vector_idx[i][0]),
VLC_INIT_STATIC_OVERLONG);
offset += vlc_spectral[i].table_size;
}
AAC_RENAME(ff_aac_sbr_init)();
ff_aac_tableinit();
VLC_INIT_STATIC(&vlc_scalefactors, 7,
FF_ARRAY_ELEMS(ff_aac_scalefactor_code),
ff_aac_scalefactor_bits,
sizeof(ff_aac_scalefactor_bits[0]),
sizeof(ff_aac_scalefactor_bits[0]),
ff_aac_scalefactor_code,
sizeof(ff_aac_scalefactor_code[0]),
sizeof(ff_aac_scalefactor_code[0]),
352);
ff_aacdec_common_init_once();
// window initialization
AAC_RENAME(avpriv_kbd_window_init)(AAC_RENAME(aac_kbd_long_960), 4.0, 960);
@@ -1526,7 +1497,7 @@ static int decode_scalefactors(AACContext *ac, INTFLOAT sf[120], GetBitContext *
} else if ((band_type[idx] == INTENSITY_BT) ||
(band_type[idx] == INTENSITY_BT2)) {
for (; i < run_end; i++, idx++) {
offset[2] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - SCALE_DIFF_ZERO;
offset[2] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO;
clipped_offset = av_clip(offset[2], -155, 100);
if (offset[2] != clipped_offset) {
avpriv_request_sample(ac->avctx,
@@ -1545,7 +1516,7 @@ static int decode_scalefactors(AACContext *ac, INTFLOAT sf[120], GetBitContext *
if (noise_flag-- > 0)
offset[1] += get_bits(gb, NOISE_PRE_BITS) - NOISE_PRE;
else
offset[1] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - SCALE_DIFF_ZERO;
offset[1] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO;
clipped_offset = av_clip(offset[1], -100, 155);
if (offset[1] != clipped_offset) {
avpriv_request_sample(ac->avctx,
@@ -1561,7 +1532,7 @@ static int decode_scalefactors(AACContext *ac, INTFLOAT sf[120], GetBitContext *
}
} else {
for (; i < run_end; i++, idx++) {
offset[0] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - SCALE_DIFF_ZERO;
offset[0] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO;
if (offset[0] > 255U) {
av_log(ac->avctx, AV_LOG_ERROR,
"Scalefactor (%d) out of range.\n", offset[0]);
@@ -1734,7 +1705,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, INTFLOAT coef[1024],
#if !USE_FIXED
const float *vq = ff_aac_codebook_vector_vals[cbt_m1];
#endif /* !USE_FIXED */
const VLCElem *vlc_tab = vlc_spectral[cbt_m1].table;
const VLCElem *vlc_tab = ff_vlc_spectral[cbt_m1];
OPEN_READER(re, gb);
switch (cbt_m1 >> 1) {
@@ -2308,7 +2279,7 @@ static int decode_cce(AACContext *ac, GetBitContext *gb, ChannelElement *che)
INTFLOAT gain_cache = FIXR10(1.);
if (c) {
cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb);
gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0;
gain = cge ? get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - 60: 0;
gain_cache = GET_GAIN(scale, gain);
#if USE_FIXED
if ((abs(gain_cache)-1024) >> 3 > 30)
@@ -2322,7 +2293,7 @@ static int decode_cce(AACContext *ac, GetBitContext *gb, ChannelElement *che)
for (sfb = 0; sfb < sce->ics.max_sfb; sfb++, idx++) {
if (sce->band_type[idx] != ZERO_BT) {
if (!cge) {
int t = get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60;
int t = get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - 60;
if (t) {
int s = 1;
t = gain += t;
@@ -3091,9 +3062,9 @@ static int aac_decode_er_frame(AVCodecContext *avctx, void *data,
chan_config);
return AVERROR_INVALIDDATA;
}
for (i = 0; i < tags_per_config[chan_config]; i++) {
const int elem_type = aac_channel_layout_map[chan_config-1][i][0];
const int elem_id = aac_channel_layout_map[chan_config-1][i][1];
for (i = 0; i < ff_tags_per_config[chan_config]; i++) {
const int elem_type = ff_aac_channel_layout_map[chan_config-1][i][0];
const int elem_id = ff_aac_channel_layout_map[chan_config-1][i][1];
if (!(che=get_che(ac, elem_type, elem_id))) {
av_log(ac->avctx, AV_LOG_ERROR,
"channel element %d.%d is not allocated\n",

View File

@@ -1,7 +1,5 @@
/*
* AAC decoder data
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
*
* This file is part of FFmpeg.
*
@@ -30,99 +28,32 @@
#ifndef AVCODEC_AACDECTAB_H
#define AVCODEC_AACDECTAB_H
#include "libavutil/channel_layout.h"
#include "aac.h"
#include <stdint.h>
static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 5, 5, 16, 5, 0 };
#include "vlc.h"
static const uint8_t aac_channel_layout_map[16][16][3] = {
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, },
{ { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
{ { 0, } },
{ { 0, } },
{ { 0, } },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
{
{ TYPE_SCE, 0, AAC_CHANNEL_FRONT }, // SCE1 = FC,
{ TYPE_CPE, 0, AAC_CHANNEL_FRONT }, // CPE1 = FLc and FRc,
{ TYPE_CPE, 1, AAC_CHANNEL_FRONT }, // CPE2 = FL and FR,
{ TYPE_CPE, 2, AAC_CHANNEL_BACK }, // CPE3 = SiL and SiR,
{ TYPE_CPE, 3, AAC_CHANNEL_BACK }, // CPE4 = BL and BR,
{ TYPE_SCE, 1, AAC_CHANNEL_BACK }, // SCE2 = BC,
{ TYPE_LFE, 0, AAC_CHANNEL_LFE }, // LFE1 = LFE1,
{ TYPE_LFE, 1, AAC_CHANNEL_LFE }, // LFE2 = LFE2,
{ TYPE_SCE, 2, AAC_CHANNEL_FRONT }, // SCE3 = TpFC,
{ TYPE_CPE, 4, AAC_CHANNEL_FRONT }, // CPE5 = TpFL and TpFR,
{ TYPE_CPE, 5, AAC_CHANNEL_SIDE }, // CPE6 = TpSiL and TpSiR,
{ TYPE_SCE, 3, AAC_CHANNEL_SIDE }, // SCE4 = TpC,
{ TYPE_CPE, 6, AAC_CHANNEL_BACK }, // CPE7 = TpBL and TpBR,
{ TYPE_SCE, 4, AAC_CHANNEL_BACK }, // SCE5 = TpBC,
{ TYPE_SCE, 5, AAC_CHANNEL_FRONT }, // SCE6 = BtFC,
{ TYPE_CPE, 7, AAC_CHANNEL_FRONT }, // CPE8 = BtFL and BtFR
},
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, { TYPE_CPE, 2, AAC_CHANNEL_FRONT }, },
{ { 0, } },
};
#include "libavutil/attributes_internal.h"
#include "libavutil/channel_layout.h"
static const int16_t aac_channel_map[3][4][6] = {
{
{ AV_CHAN_FRONT_CENTER, AV_CHAN_FRONT_LEFT_OF_CENTER, AV_CHAN_FRONT_RIGHT_OF_CENTER, AV_CHAN_FRONT_LEFT, AV_CHAN_FRONT_RIGHT, AV_CHAN_NONE },
{ AV_CHAN_UNUSED, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
{ AV_CHAN_UNUSED, AV_CHAN_SIDE_LEFT, AV_CHAN_SIDE_RIGHT, AV_CHAN_BACK_LEFT, AV_CHAN_BACK_RIGHT, AV_CHAN_BACK_CENTER },
{ AV_CHAN_LOW_FREQUENCY, AV_CHAN_LOW_FREQUENCY_2, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
},
{
{ AV_CHAN_TOP_FRONT_CENTER, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_TOP_FRONT_LEFT, AV_CHAN_TOP_FRONT_RIGHT, AV_CHAN_NONE },
{ AV_CHAN_UNUSED, AV_CHAN_TOP_SIDE_LEFT, AV_CHAN_TOP_SIDE_RIGHT, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_TOP_CENTER},
{ AV_CHAN_UNUSED, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_TOP_BACK_LEFT, AV_CHAN_TOP_BACK_RIGHT, AV_CHAN_TOP_BACK_CENTER},
{ AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE},
},
{
{ AV_CHAN_BOTTOM_FRONT_CENTER, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_BOTTOM_FRONT_LEFT, AV_CHAN_BOTTOM_FRONT_RIGHT, AV_CHAN_NONE },
{ AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
{ AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
{ AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
},
};
FF_VISIBILITY_PUSH_HIDDEN
void ff_aacdec_common_init_once(void);
extern const VLCElem *ff_aac_sbr_vlc[10];
extern VLCElem ff_vlc_scalefactors[];
extern const VLCElem *ff_vlc_spectral[11];
extern const int8_t ff_tags_per_config[16];
extern const uint8_t ff_aac_channel_layout_map[16][16][3];
extern const int16_t ff_aac_channel_map[3][4][6];
#if FF_API_OLD_CHANNEL_LAYOUT
static const uint64_t aac_channel_layout[] = {
AV_CH_LAYOUT_MONO,
AV_CH_LAYOUT_STEREO,
AV_CH_LAYOUT_SURROUND,
AV_CH_LAYOUT_4POINT0,
AV_CH_LAYOUT_5POINT0_BACK,
AV_CH_LAYOUT_5POINT1_BACK,
AV_CH_LAYOUT_7POINT1_WIDE_BACK,
AV_CH_LAYOUT_6POINT1_BACK,
AV_CH_LAYOUT_7POINT1,
AV_CH_LAYOUT_22POINT2,
AV_CH_LAYOUT_7POINT1_TOP_BACK,
0,
};
extern const uint64_t ff_aac_channel_layout[];
#endif
static const AVChannelLayout aac_ch_layout[] = {
AV_CHANNEL_LAYOUT_MONO,
AV_CHANNEL_LAYOUT_STEREO,
AV_CHANNEL_LAYOUT_SURROUND,
AV_CHANNEL_LAYOUT_4POINT0,
AV_CHANNEL_LAYOUT_5POINT0_BACK,
AV_CHANNEL_LAYOUT_5POINT1_BACK,
AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK,
AV_CHANNEL_LAYOUT_6POINT1_BACK,
AV_CHANNEL_LAYOUT_7POINT1,
AV_CHANNEL_LAYOUT_22POINT2,
AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK,
{ 0 },
};
extern const AVChannelLayout ff_aac_ch_layout[];
FF_VISIBILITY_POP_HIDDEN
#endif /* AVCODEC_AACDECTAB_H */

View File

@@ -1210,9 +1210,6 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s)
if (!s->fdsp)
return AVERROR(ENOMEM);
// window init
ff_aac_float_common_init();
if ((ret = av_tx_init(&s->mdct1024, &s->mdct1024_fn, AV_TX_FLOAT_MDCT, 0,
1024, &scale, 0)) < 0)
return ret;
@@ -1359,6 +1356,9 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
if (s->channels > 3)
s->options.mid_side = 0;
// Initialize static tables
ff_aac_float_common_init();
if ((ret = dsp_init(avctx, s)) < 0)
return ret;
@@ -1393,7 +1393,6 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
#endif
ff_af_queue_init(avctx, &s->afq);
ff_aac_tableinit();
return 0;
}

View File

@@ -26,7 +26,6 @@
#include "libavutil/common.h"
#include "libavutil/mathematics.h"
#include "libavutil/mem_internal.h"
#include "avcodec.h"
#include "aacps.h"
#if USE_FIXED
#include "aacps_fixed_tablegen.h"
@@ -717,7 +716,7 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)
}
}
int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top)
int AAC_RENAME(ff_ps_apply)(PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top)
{
INTFLOAT (*Lbuf)[32][2] = ps->Lbuf;
INTFLOAT (*Rbuf)[32][2] = ps->Rbuf;
@@ -740,7 +739,6 @@ int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][
av_cold void AAC_RENAME(ff_ps_init)(void) {
ps_tableinit();
ff_ps_init_common();
}
av_cold void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps)

View File

@@ -27,7 +27,6 @@
#include "libavutil/mem_internal.h"
#include "aacpsdsp.h"
#include "avcodec.h"
#include "get_bits.h"
#define PS_MAX_NUM_ENV 5
@@ -95,8 +94,8 @@ extern const int8_t ff_k_to_i_34[];
void ff_ps_init_common(void);
void AAC_RENAME(ff_ps_init)(void);
void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps);
int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb,
int ff_ps_read_data(void *logctx, GetBitContext *gb,
PSCommonContext *ps, int bits_left);
int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top);
int AAC_RENAME(ff_ps_apply)(PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top);
#endif /* AVCODEC_AACPS_H */

View File

@@ -21,7 +21,6 @@
#include <stdint.h>
#include "libavutil/common.h"
#include "libavutil/thread.h"
#include "aacps.h"
#include "get_bits.h"
#include "aacpsdata.c"
@@ -59,31 +58,31 @@ static const int huff_iid[] = {
huff_iid_dt1,
};
static VLC vlc_ps[10];
static const VLCElem *vlc_ps[10];
#define READ_PAR_DATA(PAR, OFFSET, MASK, ERR_CONDITION, NB_BITS, MAX_DEPTH) \
#define READ_PAR_DATA(PAR, MASK, ERR_CONDITION, NB_BITS, MAX_DEPTH) \
/** \
* Read Inter-channel Intensity Difference/Inter-Channel Coherence/ \
* Inter-channel Phase Difference/Overall Phase Difference parameters from the \
* bitstream. \
* \
* @param avctx contains the current codec context \
* @param logctx a context for logging \
* @param gb pointer to the input bitstream \
* @param ps pointer to the Parametric Stereo context \
* @param PAR pointer to the parameter to be read \
* @param e envelope to decode \
* @param dt 1: time delta-coded, 0: frequency delta-coded \
*/ \
static int read_ ## PAR ## _data(AVCodecContext *avctx, GetBitContext *gb, PSCommonContext *ps, \
static int read_ ## PAR ## _data(void *logctx, GetBitContext *gb, PSCommonContext *ps, \
int8_t (*PAR)[PS_MAX_NR_IIDICC], int table_idx, int e, int dt) \
{ \
int b, num = ps->nr_ ## PAR ## _par; \
const VLCElem *vlc_table = vlc_ps[table_idx].table; \
const VLCElem *vlc_table = vlc_ps[table_idx]; \
if (dt) { \
int e_prev = e ? e - 1 : ps->num_env_old - 1; \
e_prev = FFMAX(e_prev, 0); \
for (b = 0; b < num; b++) { \
int val = PAR[e_prev][b] + get_vlc2(gb, vlc_table, NB_BITS, MAX_DEPTH) - OFFSET; \
int val = PAR[e_prev][b] + get_vlc2(gb, vlc_table, NB_BITS, MAX_DEPTH); \
if (MASK) val &= MASK; \
PAR[e][b] = val; \
if (ERR_CONDITION) \
@@ -92,7 +91,7 @@ static int read_ ## PAR ## _data(AVCodecContext *avctx, GetBitContext *gb, PSCom
} else { \
int val = 0; \
for (b = 0; b < num; b++) { \
val += get_vlc2(gb, vlc_table, NB_BITS, MAX_DEPTH) - OFFSET; \
val += get_vlc2(gb, vlc_table, NB_BITS, MAX_DEPTH); \
if (MASK) val &= MASK; \
PAR[e][b] = val; \
if (ERR_CONDITION) \
@@ -101,13 +100,13 @@ static int read_ ## PAR ## _data(AVCodecContext *avctx, GetBitContext *gb, PSCom
} \
return 0; \
err: \
av_log(avctx, AV_LOG_ERROR, "illegal "#PAR"\n"); \
av_log(logctx, AV_LOG_ERROR, "illegal "#PAR"\n"); \
return AVERROR_INVALIDDATA; \
}
READ_PAR_DATA(iid, huff_offset[table_idx], 0, FFABS(ps->iid_par[e][b]) > 7 + 8 * ps->iid_quant, 9, 3)
READ_PAR_DATA(icc, huff_offset[table_idx], 0, ps->icc_par[e][b] > 7U, 9, 2)
READ_PAR_DATA(ipdopd, 0, 0x07, 0, 5, 1)
READ_PAR_DATA(iid, 0, FFABS(ps->iid_par[e][b]) > 7 + 8 * ps->iid_quant, 9, 3)
READ_PAR_DATA(icc, 0, ps->icc_par[e][b] > 7U, 9, 2)
READ_PAR_DATA(ipdopd, 0x07, 0, 5, 1)
static int ps_read_extension_data(GetBitContext *gb, PSCommonContext *ps,
int ps_extension_id)
@@ -131,7 +130,7 @@ static int ps_read_extension_data(GetBitContext *gb, PSCommonContext *ps,
return get_bits_count(gb) - count;
}
int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
int ff_ps_read_data(void *logctx, GetBitContext *gb_host,
PSCommonContext *ps, int bits_left)
{
int e;
@@ -146,7 +145,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
if (ps->enable_iid) {
int iid_mode = get_bits(gb, 3);
if (iid_mode > 5) {
av_log(avctx, AV_LOG_ERROR, "iid_mode %d is reserved.\n",
av_log(logctx, AV_LOG_ERROR, "iid_mode %d is reserved.\n",
iid_mode);
goto err;
}
@@ -158,7 +157,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
if (ps->enable_icc) {
ps->icc_mode = get_bits(gb, 3);
if (ps->icc_mode > 5) {
av_log(avctx, AV_LOG_ERROR, "icc_mode %d is reserved.\n",
av_log(logctx, AV_LOG_ERROR, "icc_mode %d is reserved.\n",
ps->icc_mode);
goto err;
}
@@ -176,7 +175,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
for (e = 1; e <= ps->num_env; e++) {
ps->border_position[e] = get_bits(gb, 5);
if (ps->border_position[e] < ps->border_position[e-1]) {
av_log(avctx, AV_LOG_ERROR, "border_position non monotone.\n");
av_log(logctx, AV_LOG_ERROR, "border_position non monotone.\n");
goto err;
}
}
@@ -187,7 +186,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
if (ps->enable_iid) {
for (e = 0; e < ps->num_env; e++) {
int dt = get_bits1(gb);
if (read_iid_data(avctx, gb, ps, ps->iid_par, huff_iid[2*dt+ps->iid_quant], e, dt))
if (read_iid_data(logctx, gb, ps, ps->iid_par, huff_iid[2*dt+ps->iid_quant], e, dt))
goto err;
}
} else
@@ -196,7 +195,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
if (ps->enable_icc)
for (e = 0; e < ps->num_env; e++) {
int dt = get_bits1(gb);
if (read_icc_data(avctx, gb, ps, ps->icc_par, dt ? huff_icc_dt : huff_icc_df, e, dt))
if (read_icc_data(logctx, gb, ps, ps->icc_par, dt ? huff_icc_dt : huff_icc_df, e, dt))
goto err;
}
else
@@ -213,7 +212,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
cnt -= 2 + ps_read_extension_data(gb, ps, ps_extension_id);
}
if (cnt < 0) {
av_log(avctx, AV_LOG_ERROR, "ps extension overflow %d\n", cnt);
av_log(logctx, AV_LOG_ERROR, "ps extension overflow %d\n", cnt);
goto err;
}
skip_bits(gb, cnt);
@@ -241,7 +240,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
if (ps->enable_iid){
for (b = 0; b < ps->nr_iid_par; b++) {
if (FFABS(ps->iid_par[ps->num_env][b]) > 7 + 8 * ps->iid_quant) {
av_log(avctx, AV_LOG_ERROR, "iid_par invalid\n");
av_log(logctx, AV_LOG_ERROR, "iid_par invalid\n");
goto err;
}
}
@@ -249,7 +248,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
if (ps->enable_icc){
for (b = 0; b < ps->nr_iid_par; b++) {
if (ps->icc_par[ps->num_env][b] > 7U) {
av_log(avctx, AV_LOG_ERROR, "icc_par invalid\n");
av_log(logctx, AV_LOG_ERROR, "icc_par invalid\n");
goto err;
}
}
@@ -278,7 +277,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
skip_bits_long(gb_host, bits_consumed);
return bits_consumed;
}
av_log(avctx, AV_LOG_ERROR, "Expected to read %d PS bits actually read %d.\n", bits_left, bits_consumed);
av_log(logctx, AV_LOG_ERROR, "Expected to read %d PS bits actually read %d.\n", bits_left, bits_consumed);
err:
ps->start = 0;
skip_bits_long(gb_host, bits_left);
@@ -289,48 +288,19 @@ err:
return bits_left;
}
#define PS_INIT_VLC_STATIC(num, nb_bits, size) \
VLC_INIT_STATIC(&vlc_ps[num], nb_bits, ps_tmp[num].table_size / ps_tmp[num].elem_size, \
ps_tmp[num].ps_bits, 1, 1, \
ps_tmp[num].ps_codes, ps_tmp[num].elem_size, ps_tmp[num].elem_size, \
size);
#define PS_VLC_ROW(name) \
{ name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) }
static av_cold void ps_init_common(void)
{
// Syntax initialization
static const struct {
const void *ps_codes, *ps_bits;
const unsigned int table_size, elem_size;
} ps_tmp[] = {
PS_VLC_ROW(huff_iid_df1),
PS_VLC_ROW(huff_iid_dt1),
PS_VLC_ROW(huff_iid_df0),
PS_VLC_ROW(huff_iid_dt0),
PS_VLC_ROW(huff_icc_df),
PS_VLC_ROW(huff_icc_dt),
PS_VLC_ROW(huff_ipd_df),
PS_VLC_ROW(huff_ipd_dt),
PS_VLC_ROW(huff_opd_df),
PS_VLC_ROW(huff_opd_dt),
};
PS_INIT_VLC_STATIC(0, 9, 1544);
PS_INIT_VLC_STATIC(1, 9, 832);
PS_INIT_VLC_STATIC(2, 9, 1024);
PS_INIT_VLC_STATIC(3, 9, 1036);
PS_INIT_VLC_STATIC(4, 9, 544);
PS_INIT_VLC_STATIC(5, 9, 544);
PS_INIT_VLC_STATIC(6, 5, 32);
PS_INIT_VLC_STATIC(7, 5, 32);
PS_INIT_VLC_STATIC(8, 5, 32);
PS_INIT_VLC_STATIC(9, 5, 32);
}
av_cold void ff_ps_init_common(void)
{
static AVOnce init_static_once = AV_ONCE_INIT;
ff_thread_once(&init_static_once, ps_init_common);
static VLCElem vlc_buf[(1544 + 832 + 1024 + 1036) +
(544 + 544) + (32 + 32 + 32 + 32)];
VLCInitState state = VLC_INIT_STATE(vlc_buf);
const uint8_t (*tab)[2] = aacps_huff_tabs;
for (int i = 0; i < FF_ARRAY_ELEMS(vlc_ps); i++) {
vlc_ps[i] =
ff_vlc_init_tables_from_lengths(&state, i <= 5 ? 9 : 5, huff_sizes[i],
&tab[0][1], 2,
&tab[0][0], 2, 1,
huff_offset[i], 0);
tab += huff_sizes[i];
}
}

View File

@@ -19,124 +19,79 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
static const uint8_t huff_iid_df1_bits[] = {
18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 18, 17, 17, 16, 16, 15, 14, 14,
13, 12, 12, 11, 10, 10, 8, 7, 6, 5, 4, 3, 1, 3, 4, 5, 6, 7,
8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 16, 16, 17, 17, 18, 17, 18, 18,
18, 18, 18, 18, 18, 18, 18,
};
#include <stdint.h>
static const uint32_t huff_iid_df1_codes[] = {
0x01FEB4, 0x01FEB5, 0x01FD76, 0x01FD77, 0x01FD74, 0x01FD75, 0x01FE8A,
0x01FE8B, 0x01FE88, 0x00FE80, 0x01FEB6, 0x00FE82, 0x00FEB8, 0x007F42,
0x007FAE, 0x003FAF, 0x001FD1, 0x001FE9, 0x000FE9, 0x0007EA, 0x0007FB,
0x0003FB, 0x0001FB, 0x0001FF, 0x00007C, 0x00003C, 0x00001C, 0x00000C,
0x000000, 0x000001, 0x000001, 0x000002, 0x000001, 0x00000D, 0x00001D,
0x00003D, 0x00007D, 0x0000FC, 0x0001FC, 0x0003FC, 0x0003F4, 0x0007EB,
0x000FEA, 0x001FEA, 0x001FD6, 0x003FD0, 0x007FAF, 0x007F43, 0x00FEB9,
0x00FE83, 0x01FEB7, 0x00FE81, 0x01FE89, 0x01FE8E, 0x01FE8F, 0x01FE8C,
0x01FE8D, 0x01FEB2, 0x01FEB3, 0x01FEB0, 0x01FEB1,
};
static const uint8_t huff_sizes[] = { 61, 61, 29, 29, 15, 15, 8, 8, 8, 8 };
static const uint8_t huff_iid_dt1_bits[] = {
16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 13,
13, 13, 12, 12, 11, 10, 9, 9, 7, 6, 5, 3, 1, 2, 5, 6, 7, 8,
9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16,
};
static const uint16_t huff_iid_dt1_codes[] = {
0x004ED4, 0x004ED5, 0x004ECE, 0x004ECF, 0x004ECC, 0x004ED6, 0x004ED8,
0x004F46, 0x004F60, 0x002718, 0x002719, 0x002764, 0x002765, 0x00276D,
0x0027B1, 0x0013B7, 0x0013D6, 0x0009C7, 0x0009E9, 0x0009ED, 0x0004EE,
0x0004F7, 0x000278, 0x000139, 0x00009A, 0x00009F, 0x000020, 0x000011,
0x00000A, 0x000003, 0x000001, 0x000000, 0x00000B, 0x000012, 0x000021,
0x00004C, 0x00009B, 0x00013A, 0x000279, 0x000270, 0x0004EF, 0x0004E2,
0x0009EA, 0x0009D8, 0x0013D7, 0x0013D0, 0x0027B2, 0x0027A2, 0x00271A,
0x00271B, 0x004F66, 0x004F67, 0x004F61, 0x004F47, 0x004ED9, 0x004ED7,
0x004ECD, 0x004ED2, 0x004ED3, 0x004ED0, 0x004ED1,
};
static const uint8_t huff_iid_df0_bits[] = {
17, 17, 17, 17, 16, 15, 13, 10, 9, 7, 6, 5, 4, 3, 1, 3, 4, 5,
6, 6, 8, 11, 13, 14, 14, 15, 17, 18, 18,
};
static const uint32_t huff_iid_df0_codes[] = {
0x01FFFB, 0x01FFFC, 0x01FFFD, 0x01FFFA, 0x00FFFC, 0x007FFC, 0x001FFD,
0x0003FE, 0x0001FE, 0x00007E, 0x00003C, 0x00001D, 0x00000D, 0x000005,
0x000000, 0x000004, 0x00000C, 0x00001C, 0x00003D, 0x00003E, 0x0000FE,
0x0007FE, 0x001FFC, 0x003FFC, 0x003FFD, 0x007FFD, 0x01FFFE, 0x03FFFE,
0x03FFFF,
};
static const uint8_t huff_iid_dt0_bits[] = {
19, 19, 19, 20, 20, 20, 17, 15, 12, 10, 8, 6, 4, 2, 1, 3, 5, 7,
9, 11, 13, 14, 17, 19, 20, 20, 20, 20, 20,
};
static const uint32_t huff_iid_dt0_codes[] = {
0x07FFF9, 0x07FFFA, 0x07FFFB, 0x0FFFF8, 0x0FFFF9, 0x0FFFFA, 0x01FFFD,
0x007FFE, 0x000FFE, 0x0003FE, 0x0000FE, 0x00003E, 0x00000E, 0x000002,
0x000000, 0x000006, 0x00001E, 0x00007E, 0x0001FE, 0x0007FE, 0x001FFE,
0x003FFE, 0x01FFFC, 0x07FFF8, 0x0FFFFB, 0x0FFFFC, 0x0FFFFD, 0x0FFFFE,
0x0FFFFF,
};
static const uint8_t huff_icc_df_bits[] = {
14, 14, 12, 10, 7, 5, 3, 1, 2, 4, 6, 8, 9, 11, 13,
};
static const uint16_t huff_icc_df_codes[] = {
0x3FFF, 0x3FFE, 0x0FFE, 0x03FE, 0x007E, 0x001E, 0x0006, 0x0000,
0x0002, 0x000E, 0x003E, 0x00FE, 0x01FE, 0x07FE, 0x1FFE,
};
static const uint8_t huff_icc_dt_bits[] = {
14, 13, 11, 9, 7, 5, 3, 1, 2, 4, 6, 8, 10, 12, 14,
};
static const uint16_t huff_icc_dt_codes[] = {
0x3FFE, 0x1FFE, 0x07FE, 0x01FE, 0x007E, 0x001E, 0x0006, 0x0000,
0x0002, 0x000E, 0x003E, 0x00FE, 0x03FE, 0x0FFE, 0x3FFF,
};
static const uint8_t huff_ipd_df_bits[] = {
1, 3, 4, 4, 4, 4, 4, 4,
};
static const uint8_t huff_ipd_df_codes[] = {
0x01, 0x00, 0x06, 0x04, 0x02, 0x03, 0x05, 0x07,
};
static const uint8_t huff_ipd_dt_bits[] = {
1, 3, 4, 5, 5, 4, 4, 3,
};
static const uint8_t huff_ipd_dt_codes[] = {
0x01, 0x02, 0x02, 0x03, 0x02, 0x00, 0x03, 0x03,
};
static const uint8_t huff_opd_df_bits[] = {
1, 3, 4, 4, 5, 5, 4, 3,
};
static const uint8_t huff_opd_df_codes[] = {
0x01, 0x01, 0x06, 0x04, 0x0F, 0x0E, 0x05, 0x00,
};
static const uint8_t huff_opd_dt_bits[] = {
1, 3, 4, 5, 5, 4, 4, 3,
};
static const uint8_t huff_opd_dt_codes[] = {
0x01, 0x02, 0x01, 0x07, 0x06, 0x00, 0x02, 0x03,
static const uint8_t aacps_huff_tabs[][2] = {
/* huff_iid_df1 - 61 entries */
{ 28, 4 }, { 32, 4 }, { 29, 3 }, { 31, 3 }, { 27, 5 },
{ 33, 5 }, { 26, 6 }, { 34, 6 }, { 25, 7 }, { 35, 7 },
{ 24, 8 }, { 36, 8 }, { 37, 9 }, { 40, 11 }, { 19, 12 },
{ 41, 12 }, { 22, 10 }, { 38, 10 }, { 9, 17 }, { 51, 17 },
{ 11, 17 }, { 49, 17 }, { 13, 16 }, { 47, 16 }, { 16, 14 },
{ 18, 13 }, { 42, 13 }, { 44, 14 }, { 12, 17 }, { 48, 17 },
{ 4, 18 }, { 5, 18 }, { 2, 18 }, { 3, 18 }, { 15, 15 },
{ 21, 11 }, { 39, 11 }, { 45, 15 }, { 8, 18 }, { 52, 18 },
{ 6, 18 }, { 7, 18 }, { 55, 18 }, { 56, 18 }, { 53, 18 },
{ 54, 18 }, { 17, 14 }, { 43, 14 }, { 59, 18 }, { 60, 18 },
{ 57, 18 }, { 58, 18 }, { 0, 18 }, { 1, 18 }, { 10, 18 },
{ 50, 18 }, { 14, 16 }, { 46, 16 }, { 20, 12 }, { 23, 10 },
{ 30, 1 },
/* huff_iid_dt1 - 61 entries */
{ 31, 2 }, { 26, 7 }, { 34, 7 }, { 27, 6 }, { 33, 6 },
{ 35, 8 }, { 24, 9 }, { 36, 9 }, { 39, 11 }, { 41, 12 },
{ 9, 15 }, { 10, 15 }, { 48, 15 }, { 49, 15 }, { 17, 13 },
{ 23, 10 }, { 37, 10 }, { 43, 13 }, { 11, 15 }, { 12, 15 },
{ 4, 16 }, { 56, 16 }, { 2, 16 }, { 3, 16 }, { 59, 16 },
{ 60, 16 }, { 57, 16 }, { 58, 16 }, { 0, 16 }, { 1, 16 },
{ 5, 16 }, { 55, 16 }, { 6, 16 }, { 54, 16 }, { 13, 15 },
{ 15, 14 }, { 20, 12 }, { 40, 12 }, { 22, 11 }, { 38, 11 },
{ 45, 14 }, { 47, 15 }, { 7, 16 }, { 53, 16 }, { 18, 13 },
{ 42, 13 }, { 16, 14 }, { 44, 14 }, { 8, 16 }, { 52, 16 },
{ 14, 15 }, { 46, 15 }, { 50, 16 }, { 51, 16 }, { 19, 13 },
{ 21, 12 }, { 25, 9 }, { 28, 5 }, { 32, 5 }, { 29, 3 },
{ 30, 1 },
/* huff_iid_df0 - 29 entries */
{ 14, 1 }, { 15, 3 }, { 13, 3 }, { 16, 4 }, { 12, 4 },
{ 17, 5 }, { 11, 5 }, { 10, 6 }, { 18, 6 }, { 19, 6 },
{ 9, 7 }, { 20, 8 }, { 8, 9 }, { 7, 10 }, { 21, 11 },
{ 22, 13 }, { 6, 13 }, { 23, 14 }, { 24, 14 }, { 5, 15 },
{ 25, 15 }, { 4, 16 }, { 3, 17 }, { 0, 17 }, { 1, 17 },
{ 2, 17 }, { 26, 17 }, { 27, 18 }, { 28, 18 },
/* huff_iid_dt0 - 29 entries */
{ 14, 1 }, { 13, 2 }, { 15, 3 }, { 12, 4 }, { 16, 5 },
{ 11, 6 }, { 17, 7 }, { 10, 8 }, { 18, 9 }, { 9, 10 },
{ 19, 11 }, { 8, 12 }, { 20, 13 }, { 21, 14 }, { 7, 15 },
{ 22, 17 }, { 6, 17 }, { 23, 19 }, { 0, 19 }, { 1, 19 },
{ 2, 19 }, { 3, 20 }, { 4, 20 }, { 5, 20 }, { 24, 20 },
{ 25, 20 }, { 26, 20 }, { 27, 20 }, { 28, 20 },
/* huff_icc_df - 15 entries */
{ 7, 1 }, { 8, 2 }, { 6, 3 }, { 9, 4 }, { 5, 5 },
{ 10, 6 }, { 4, 7 }, { 11, 8 }, { 12, 9 }, { 3, 10 },
{ 13, 11 }, { 2, 12 }, { 14, 13 }, { 1, 14 }, { 0, 14 },
/* huff_icc_dt - 15 entries */
{ 7, 1 }, { 8, 2 }, { 6, 3 }, { 9, 4 }, { 5, 5 },
{ 10, 6 }, { 4, 7 }, { 11, 8 }, { 3, 9 }, { 12, 10 },
{ 2, 11 }, { 13, 12 }, { 1, 13 }, { 0, 14 }, { 14, 14 },
/* huff_ipd_df - 8 entries */
{ 1, 3 }, { 4, 4 }, { 5, 4 }, { 3, 4 }, { 6, 4 },
{ 2, 4 }, { 7, 4 }, { 0, 1 },
/* huff_ipd_dt - 8 entries */
{ 5, 4 }, { 4, 5 }, { 3, 5 }, { 2, 4 }, { 6, 4 },
{ 1, 3 }, { 7, 3 }, { 0, 1 },
/* huff_opd_df - 8 entries */
{ 7, 3 }, { 1, 3 }, { 3, 4 }, { 6, 4 }, { 2, 4 },
{ 5, 5 }, { 4, 5 }, { 0, 1 },
/* huff_opd_dt - 8 entries */
{ 5, 4 }, { 2, 4 }, { 6, 4 }, { 4, 5 }, { 3, 5 },
{ 1, 3 }, { 7, 3 }, { 0, 1 },
};
static const int8_t huff_offset[] = {
30, 30,
14, 14,
7, 7,
-30, -30,
-14, -14,
-7, -7,
0, 0,
0, 0,
};

View File

@@ -28,7 +28,7 @@
#include "libavutil/ffmath.h"
#include "avcodec.h"
#include "aactab.h"
#include "aac.h"
#include "psymodel.h"
/***********************************

View File

@@ -47,7 +47,6 @@
#include "mips/aacsbr_mips.h"
#endif /* ARCH_MIPS */
static VLC vlc_sbr[10];
static void aacsbr_func_ptr_init(AACSBRContext *c);
static void make_bands(int16_t* bands, int start, int stop, int num_bands)

View File

@@ -30,7 +30,7 @@
#define AVCODEC_AACSBR_H
#include "get_bits.h"
#include "aac.h"
#include "aac_defines.h"
#include "sbr.h"
#define ENVELOPE_ADJUSTMENT_OFFSET 2
@@ -66,18 +66,6 @@ enum {
EXTENSION_ID_PS = 2,
};
static const int8_t vlc_sbr_lav[10] =
{ 60, 60, 24, 24, 31, 31, 12, 12, 31, 12 };
#define SBR_INIT_VLC_STATIC(num, size) \
VLC_INIT_STATIC(&vlc_sbr[num], 9, sbr_tmp[num].table_size / sbr_tmp[num].elem_size, \
sbr_tmp[num].sbr_bits , 1, 1, \
sbr_tmp[num].sbr_codes, sbr_tmp[num].elem_size, sbr_tmp[num].elem_size, \
size)
#define SBR_VLC_ROW(name) \
{ name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) }
/** Initialize SBR. */
void AAC_RENAME(ff_aac_sbr_init)(void);
/** Initialize one SBR context. */

View File

@@ -70,7 +70,6 @@
#include <float.h>
#include <math.h>
static VLC vlc_sbr[10];
static void aacsbr_func_ptr_init(AACSBRContext *c);
static const int CONST_LN2 = Q31(0.6931471806/256); // ln(2)/256
static const int CONST_RECIP_LN2 = Q31(0.7213475204); // 0.5/ln(2)

View File

@@ -32,6 +32,7 @@
* @author Zoran Basaric ( zoran.basaric@imgtec.com )
*/
#include "aacdectab.h"
#include "libavutil/qsort.h"
static av_cold void aacsbr_tableinit(void)
@@ -44,34 +45,6 @@ static av_cold void aacsbr_tableinit(void)
av_cold void AAC_RENAME(ff_aac_sbr_init)(void)
{
static const struct {
const void *sbr_codes, *sbr_bits;
const unsigned int table_size, elem_size;
} sbr_tmp[] = {
SBR_VLC_ROW(t_huffman_env_1_5dB),
SBR_VLC_ROW(f_huffman_env_1_5dB),
SBR_VLC_ROW(t_huffman_env_bal_1_5dB),
SBR_VLC_ROW(f_huffman_env_bal_1_5dB),
SBR_VLC_ROW(t_huffman_env_3_0dB),
SBR_VLC_ROW(f_huffman_env_3_0dB),
SBR_VLC_ROW(t_huffman_env_bal_3_0dB),
SBR_VLC_ROW(f_huffman_env_bal_3_0dB),
SBR_VLC_ROW(t_huffman_noise_3_0dB),
SBR_VLC_ROW(t_huffman_noise_bal_3_0dB),
};
// SBR VLC table initialization
SBR_INIT_VLC_STATIC(0, 1098);
SBR_INIT_VLC_STATIC(1, 1092);
SBR_INIT_VLC_STATIC(2, 768);
SBR_INIT_VLC_STATIC(3, 1026);
SBR_INIT_VLC_STATIC(4, 1058);
SBR_INIT_VLC_STATIC(5, 1052);
SBR_INIT_VLC_STATIC(6, 544);
SBR_INIT_VLC_STATIC(7, 544);
SBR_INIT_VLC_STATIC(8, 592);
SBR_INIT_VLC_STATIC(9, 512);
aacsbr_tableinit();
AAC_RENAME(ff_ps_init)();
@@ -831,37 +804,28 @@ static int read_sbr_envelope(AACContext *ac, SpectralBandReplication *sbr, GetBi
int bits;
int i, j, k;
const VLCElem *t_huff, *f_huff;
int t_lav, f_lav;
const int delta = (ch == 1 && sbr->bs_coupling == 1) + 1;
const int odd = sbr->n[1] & 1;
if (sbr->bs_coupling && ch) {
if (ch_data->bs_amp_res) {
bits = 5;
t_huff = vlc_sbr[T_HUFFMAN_ENV_BAL_3_0DB].table;
t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_BAL_3_0DB];
f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_3_0DB].table;
f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_3_0DB];
t_huff = ff_aac_sbr_vlc[T_HUFFMAN_ENV_BAL_3_0DB];
f_huff = ff_aac_sbr_vlc[F_HUFFMAN_ENV_BAL_3_0DB];
} else {
bits = 6;
t_huff = vlc_sbr[T_HUFFMAN_ENV_BAL_1_5DB].table;
t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_BAL_1_5DB];
f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_1_5DB].table;
f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_1_5DB];
t_huff = ff_aac_sbr_vlc[T_HUFFMAN_ENV_BAL_1_5DB];
f_huff = ff_aac_sbr_vlc[F_HUFFMAN_ENV_BAL_1_5DB];
}
} else {
if (ch_data->bs_amp_res) {
bits = 6;
t_huff = vlc_sbr[T_HUFFMAN_ENV_3_0DB].table;
t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_3_0DB];
f_huff = vlc_sbr[F_HUFFMAN_ENV_3_0DB].table;
f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_3_0DB];
t_huff = ff_aac_sbr_vlc[T_HUFFMAN_ENV_3_0DB];
f_huff = ff_aac_sbr_vlc[F_HUFFMAN_ENV_3_0DB];
} else {
bits = 7;
t_huff = vlc_sbr[T_HUFFMAN_ENV_1_5DB].table;
t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_1_5DB];
f_huff = vlc_sbr[F_HUFFMAN_ENV_1_5DB].table;
f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_1_5DB];
t_huff = ff_aac_sbr_vlc[T_HUFFMAN_ENV_1_5DB];
f_huff = ff_aac_sbr_vlc[F_HUFFMAN_ENV_1_5DB];
}
}
@@ -870,7 +834,7 @@ static int read_sbr_envelope(AACContext *ac, SpectralBandReplication *sbr, GetBi
// bs_freq_res[0] == bs_freq_res[bs_num_env] from prev frame
if (ch_data->bs_freq_res[i + 1] == ch_data->bs_freq_res[i]) {
for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) {
ch_data->env_facs_q[i + 1][j] = ch_data->env_facs_q[i][j] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
ch_data->env_facs_q[i + 1][j] = ch_data->env_facs_q[i][j] + delta * get_vlc2(gb, t_huff, 9, 3);
if (ch_data->env_facs_q[i + 1][j] > 127U) {
av_log(ac->avctx, AV_LOG_ERROR, "env_facs_q %d is invalid\n", ch_data->env_facs_q[i + 1][j]);
return AVERROR_INVALIDDATA;
@@ -879,7 +843,7 @@ static int read_sbr_envelope(AACContext *ac, SpectralBandReplication *sbr, GetBi
} else if (ch_data->bs_freq_res[i + 1]) {
for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) {
k = (j + odd) >> 1; // find k such that f_tablelow[k] <= f_tablehigh[j] < f_tablelow[k + 1]
ch_data->env_facs_q[i + 1][j] = ch_data->env_facs_q[i][k] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
ch_data->env_facs_q[i + 1][j] = ch_data->env_facs_q[i][k] + delta * get_vlc2(gb, t_huff, 9, 3);
if (ch_data->env_facs_q[i + 1][j] > 127U) {
av_log(ac->avctx, AV_LOG_ERROR, "env_facs_q %d is invalid\n", ch_data->env_facs_q[i + 1][j]);
return AVERROR_INVALIDDATA;
@@ -888,7 +852,7 @@ static int read_sbr_envelope(AACContext *ac, SpectralBandReplication *sbr, GetBi
} else {
for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) {
k = j ? 2*j - odd : 0; // find k such that f_tablehigh[k] == f_tablelow[j]
ch_data->env_facs_q[i + 1][j] = ch_data->env_facs_q[i][k] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
ch_data->env_facs_q[i + 1][j] = ch_data->env_facs_q[i][k] + delta * get_vlc2(gb, t_huff, 9, 3);
if (ch_data->env_facs_q[i + 1][j] > 127U) {
av_log(ac->avctx, AV_LOG_ERROR, "env_facs_q %d is invalid\n", ch_data->env_facs_q[i + 1][j]);
return AVERROR_INVALIDDATA;
@@ -898,7 +862,7 @@ static int read_sbr_envelope(AACContext *ac, SpectralBandReplication *sbr, GetBi
} else {
ch_data->env_facs_q[i + 1][0] = delta * get_bits(gb, bits); // bs_env_start_value_balance
for (j = 1; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) {
ch_data->env_facs_q[i + 1][j] = ch_data->env_facs_q[i + 1][j - 1] + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav);
ch_data->env_facs_q[i + 1][j] = ch_data->env_facs_q[i + 1][j - 1] + delta * get_vlc2(gb, f_huff, 9, 3);
if (ch_data->env_facs_q[i + 1][j] > 127U) {
av_log(ac->avctx, AV_LOG_ERROR, "env_facs_q %d is invalid\n", ch_data->env_facs_q[i + 1][j]);
return AVERROR_INVALIDDATA;
@@ -919,25 +883,20 @@ static int read_sbr_noise(AACContext *ac, SpectralBandReplication *sbr, GetBitCo
{
int i, j;
const VLCElem *t_huff, *f_huff;
int t_lav, f_lav;
int delta = (ch == 1 && sbr->bs_coupling == 1) + 1;
if (sbr->bs_coupling && ch) {
t_huff = vlc_sbr[T_HUFFMAN_NOISE_BAL_3_0DB].table;
t_lav = vlc_sbr_lav[T_HUFFMAN_NOISE_BAL_3_0DB];
f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_3_0DB].table;
f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_3_0DB];
t_huff = ff_aac_sbr_vlc[T_HUFFMAN_NOISE_BAL_3_0DB];
f_huff = ff_aac_sbr_vlc[F_HUFFMAN_ENV_BAL_3_0DB];
} else {
t_huff = vlc_sbr[T_HUFFMAN_NOISE_3_0DB].table;
t_lav = vlc_sbr_lav[T_HUFFMAN_NOISE_3_0DB];
f_huff = vlc_sbr[F_HUFFMAN_ENV_3_0DB].table;
f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_3_0DB];
t_huff = ff_aac_sbr_vlc[T_HUFFMAN_NOISE_3_0DB];
f_huff = ff_aac_sbr_vlc[F_HUFFMAN_ENV_3_0DB];
}
for (i = 0; i < ch_data->bs_num_noise; i++) {
if (ch_data->bs_df_noise[i]) {
for (j = 0; j < sbr->n_q; j++) {
ch_data->noise_facs_q[i + 1][j] = ch_data->noise_facs_q[i][j] + delta * (get_vlc2(gb, t_huff, 9, 2) - t_lav);
ch_data->noise_facs_q[i + 1][j] = ch_data->noise_facs_q[i][j] + delta * get_vlc2(gb, t_huff, 9, 2);
if (ch_data->noise_facs_q[i + 1][j] > 30U) {
av_log(ac->avctx, AV_LOG_ERROR, "noise_facs_q %d is invalid\n", ch_data->noise_facs_q[i + 1][j]);
return AVERROR_INVALIDDATA;
@@ -946,7 +905,7 @@ static int read_sbr_noise(AACContext *ac, SpectralBandReplication *sbr, GetBitCo
} else {
ch_data->noise_facs_q[i + 1][0] = delta * get_bits(gb, 5); // bs_noise_start_value_balance or bs_noise_start_value_level
for (j = 1; j < sbr->n_q; j++) {
ch_data->noise_facs_q[i + 1][j] = ch_data->noise_facs_q[i + 1][j - 1] + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav);
ch_data->noise_facs_q[i + 1][j] = ch_data->noise_facs_q[i + 1][j - 1] + delta * get_vlc2(gb, f_huff, 9, 3);
if (ch_data->noise_facs_q[i + 1][j] > 30U) {
av_log(ac->avctx, AV_LOG_ERROR, "noise_facs_q %d is invalid\n", ch_data->noise_facs_q[i + 1][j]);
return AVERROR_INVALIDDATA;
@@ -1569,7 +1528,7 @@ void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication *sbr, int
if (ac->oc[1].m4ac.ps == 1) {
if (sbr->ps.common.start) {
AAC_RENAME(ff_ps_apply)(ac->avctx, &sbr->ps, sbr->X[0], sbr->X[1], sbr->kx[1] + sbr->m[1]);
AAC_RENAME(ff_ps_apply)(&sbr->ps, sbr->X[0], sbr->X[1], sbr->kx[1] + sbr->m[1]);
} else {
memcpy(sbr->X[1], sbr->X[0], sizeof(sbr->X[0]));
}

View File

@@ -32,232 +32,6 @@
#include "libavutil/mem_internal.h"
#include "aac_defines.h"
///< Huffman tables for SBR
static const uint8_t t_huffman_env_1_5dB_bits[121] = {
18, 18, 18, 18, 18, 18, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 17, 18, 16, 17, 18, 17,
16, 16, 16, 16, 15, 14, 14, 13,
13, 12, 11, 10, 9, 8, 7, 6,
5, 4, 3, 2, 2, 3, 4, 5,
6, 7, 8, 9, 10, 12, 13, 14,
14, 15, 16, 17, 16, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19,
};
static const uint32_t t_huffman_env_1_5dB_codes[121] = {
0x3ffd6, 0x3ffd7, 0x3ffd8, 0x3ffd9, 0x3ffda, 0x3ffdb, 0x7ffb8, 0x7ffb9,
0x7ffba, 0x7ffbb, 0x7ffbc, 0x7ffbd, 0x7ffbe, 0x7ffbf, 0x7ffc0, 0x7ffc1,
0x7ffc2, 0x7ffc3, 0x7ffc4, 0x7ffc5, 0x7ffc6, 0x7ffc7, 0x7ffc8, 0x7ffc9,
0x7ffca, 0x7ffcb, 0x7ffcc, 0x7ffcd, 0x7ffce, 0x7ffcf, 0x7ffd0, 0x7ffd1,
0x7ffd2, 0x7ffd3, 0x1ffe6, 0x3ffd4, 0x0fff0, 0x1ffe9, 0x3ffd5, 0x1ffe7,
0x0fff1, 0x0ffec, 0x0ffed, 0x0ffee, 0x07ff4, 0x03ff9, 0x03ff7, 0x01ffa,
0x01ff9, 0x00ffb, 0x007fc, 0x003fc, 0x001fd, 0x000fd, 0x0007d, 0x0003d,
0x0001d, 0x0000d, 0x00005, 0x00001, 0x00000, 0x00004, 0x0000c, 0x0001c,
0x0003c, 0x0007c, 0x000fc, 0x001fc, 0x003fd, 0x00ffa, 0x01ff8, 0x03ff6,
0x03ff8, 0x07ff5, 0x0ffef, 0x1ffe8, 0x0fff2, 0x7ffd4, 0x7ffd5, 0x7ffd6,
0x7ffd7, 0x7ffd8, 0x7ffd9, 0x7ffda, 0x7ffdb, 0x7ffdc, 0x7ffdd, 0x7ffde,
0x7ffdf, 0x7ffe0, 0x7ffe1, 0x7ffe2, 0x7ffe3, 0x7ffe4, 0x7ffe5, 0x7ffe6,
0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb, 0x7ffec, 0x7ffed, 0x7ffee,
0x7ffef, 0x7fff0, 0x7fff1, 0x7fff2, 0x7fff3, 0x7fff4, 0x7fff5, 0x7fff6,
0x7fff7, 0x7fff8, 0x7fff9, 0x7fffa, 0x7fffb, 0x7fffc, 0x7fffd, 0x7fffe,
0x7ffff,
};
static const uint8_t f_huffman_env_1_5dB_bits[121] = {
19, 19, 20, 20, 20, 20, 20, 20,
20, 19, 20, 20, 20, 20, 19, 20,
19, 19, 20, 18, 20, 20, 20, 19,
20, 20, 20, 19, 20, 19, 18, 19,
18, 18, 17, 18, 17, 17, 17, 16,
16, 16, 15, 15, 14, 13, 13, 12,
12, 11, 10, 9, 9, 8, 7, 6,
5, 4, 3, 2, 2, 3, 4, 5,
6, 8, 8, 9, 10, 11, 11, 11,
12, 12, 13, 13, 14, 14, 16, 16,
17, 17, 18, 18, 18, 18, 18, 18,
18, 20, 19, 20, 20, 20, 20, 20,
20, 19, 20, 20, 20, 20, 19, 20,
18, 20, 20, 19, 19, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20,
};
static const uint32_t f_huffman_env_1_5dB_codes[121] = {
0x7ffe7, 0x7ffe8, 0xfffd2, 0xfffd3, 0xfffd4, 0xfffd5, 0xfffd6, 0xfffd7,
0xfffd8, 0x7ffda, 0xfffd9, 0xfffda, 0xfffdb, 0xfffdc, 0x7ffdb, 0xfffdd,
0x7ffdc, 0x7ffdd, 0xfffde, 0x3ffe4, 0xfffdf, 0xfffe0, 0xfffe1, 0x7ffde,
0xfffe2, 0xfffe3, 0xfffe4, 0x7ffdf, 0xfffe5, 0x7ffe0, 0x3ffe8, 0x7ffe1,
0x3ffe0, 0x3ffe9, 0x1ffef, 0x3ffe5, 0x1ffec, 0x1ffed, 0x1ffee, 0x0fff4,
0x0fff3, 0x0fff0, 0x07ff7, 0x07ff6, 0x03ffa, 0x01ffa, 0x01ff9, 0x00ffa,
0x00ff8, 0x007f9, 0x003fb, 0x001fc, 0x001fa, 0x000fb, 0x0007c, 0x0003c,
0x0001c, 0x0000c, 0x00005, 0x00001, 0x00000, 0x00004, 0x0000d, 0x0001d,
0x0003d, 0x000fa, 0x000fc, 0x001fb, 0x003fa, 0x007f8, 0x007fa, 0x007fb,
0x00ff9, 0x00ffb, 0x01ff8, 0x01ffb, 0x03ff8, 0x03ff9, 0x0fff1, 0x0fff2,
0x1ffea, 0x1ffeb, 0x3ffe1, 0x3ffe2, 0x3ffea, 0x3ffe3, 0x3ffe6, 0x3ffe7,
0x3ffeb, 0xfffe6, 0x7ffe2, 0xfffe7, 0xfffe8, 0xfffe9, 0xfffea, 0xfffeb,
0xfffec, 0x7ffe3, 0xfffed, 0xfffee, 0xfffef, 0xffff0, 0x7ffe4, 0xffff1,
0x3ffec, 0xffff2, 0xffff3, 0x7ffe5, 0x7ffe6, 0xffff4, 0xffff5, 0xffff6,
0xffff7, 0xffff8, 0xffff9, 0xffffa, 0xffffb, 0xffffc, 0xffffd, 0xffffe,
0xfffff,
};
static const uint8_t t_huffman_env_bal_1_5dB_bits[49] = {
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 12, 11, 9, 7, 5, 3,
1, 2, 4, 6, 8, 11, 12, 15,
16, 16, 16, 16, 16, 16, 16, 17,
17, 17, 17, 17, 17, 17, 17, 17,
17,
};
static const uint32_t t_huffman_env_bal_1_5dB_codes[49] = {
0x0ffe4, 0x0ffe5, 0x0ffe6, 0x0ffe7, 0x0ffe8, 0x0ffe9, 0x0ffea, 0x0ffeb,
0x0ffec, 0x0ffed, 0x0ffee, 0x0ffef, 0x0fff0, 0x0fff1, 0x0fff2, 0x0fff3,
0x0fff4, 0x0ffe2, 0x00ffc, 0x007fc, 0x001fe, 0x0007e, 0x0001e, 0x00006,
0x00000, 0x00002, 0x0000e, 0x0003e, 0x000fe, 0x007fd, 0x00ffd, 0x07ff0,
0x0ffe3, 0x0fff5, 0x0fff6, 0x0fff7, 0x0fff8, 0x0fff9, 0x0fffa, 0x1fff6,
0x1fff7, 0x1fff8, 0x1fff9, 0x1fffa, 0x1fffb, 0x1fffc, 0x1fffd, 0x1fffe,
0x1ffff,
};
static const uint8_t f_huffman_env_bal_1_5dB_bits[49] = {
18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 16,
17, 14, 11, 11, 8, 7, 4, 2,
1, 3, 5, 6, 9, 11, 12, 15,
16, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 19,
19,
};
static const uint32_t f_huffman_env_bal_1_5dB_codes[49] = {
0x3ffe2, 0x3ffe3, 0x3ffe4, 0x3ffe5, 0x3ffe6, 0x3ffe7, 0x3ffe8, 0x3ffe9,
0x3ffea, 0x3ffeb, 0x3ffec, 0x3ffed, 0x3ffee, 0x3ffef, 0x3fff0, 0x0fff7,
0x1fff0, 0x03ffc, 0x007fe, 0x007fc, 0x000fe, 0x0007e, 0x0000e, 0x00002,
0x00000, 0x00006, 0x0001e, 0x0003e, 0x001fe, 0x007fd, 0x00ffe, 0x07ffa,
0x0fff6, 0x3fff1, 0x3fff2, 0x3fff3, 0x3fff4, 0x3fff5, 0x3fff6, 0x3fff7,
0x3fff8, 0x3fff9, 0x3fffa, 0x3fffb, 0x3fffc, 0x3fffd, 0x3fffe, 0x7fffe,
0x7ffff,
};
static const uint8_t t_huffman_env_3_0dB_bits[63] = {
18, 18, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 17, 16, 16, 16, 14, 14, 14,
13, 12, 11, 8, 6, 4, 2, 1,
3, 5, 7, 9, 11, 13, 14, 14,
15, 16, 17, 18, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19,
};
static const uint32_t t_huffman_env_3_0dB_codes[63] = {
0x3ffed, 0x3ffee, 0x7ffde, 0x7ffdf, 0x7ffe0, 0x7ffe1, 0x7ffe2, 0x7ffe3,
0x7ffe4, 0x7ffe5, 0x7ffe6, 0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb,
0x7ffec, 0x1fff4, 0x0fff7, 0x0fff9, 0x0fff8, 0x03ffb, 0x03ffa, 0x03ff8,
0x01ffa, 0x00ffc, 0x007fc, 0x000fe, 0x0003e, 0x0000e, 0x00002, 0x00000,
0x00006, 0x0001e, 0x0007e, 0x001fe, 0x007fd, 0x01ffb, 0x03ff9, 0x03ffc,
0x07ffa, 0x0fff6, 0x1fff5, 0x3ffec, 0x7ffed, 0x7ffee, 0x7ffef, 0x7fff0,
0x7fff1, 0x7fff2, 0x7fff3, 0x7fff4, 0x7fff5, 0x7fff6, 0x7fff7, 0x7fff8,
0x7fff9, 0x7fffa, 0x7fffb, 0x7fffc, 0x7fffd, 0x7fffe, 0x7ffff,
};
static const uint8_t f_huffman_env_3_0dB_bits[63] = {
20, 20, 20, 20, 20, 20, 20, 18,
19, 19, 19, 19, 18, 18, 20, 19,
17, 18, 17, 16, 16, 15, 14, 12,
11, 10, 9, 8, 6, 4, 2, 1,
3, 5, 8, 9, 10, 11, 12, 13,
14, 15, 15, 16, 16, 17, 17, 18,
18, 18, 20, 19, 19, 19, 20, 19,
19, 20, 20, 20, 20, 20, 20,
};
static const uint32_t f_huffman_env_3_0dB_codes[63] = {
0xffff0, 0xffff1, 0xffff2, 0xffff3, 0xffff4, 0xffff5, 0xffff6, 0x3fff3,
0x7fff5, 0x7ffee, 0x7ffef, 0x7fff6, 0x3fff4, 0x3fff2, 0xffff7, 0x7fff0,
0x1fff5, 0x3fff0, 0x1fff4, 0x0fff7, 0x0fff6, 0x07ff8, 0x03ffb, 0x00ffd,
0x007fd, 0x003fd, 0x001fd, 0x000fd, 0x0003e, 0x0000e, 0x00002, 0x00000,
0x00006, 0x0001e, 0x000fc, 0x001fc, 0x003fc, 0x007fc, 0x00ffc, 0x01ffc,
0x03ffa, 0x07ff9, 0x07ffa, 0x0fff8, 0x0fff9, 0x1fff6, 0x1fff7, 0x3fff5,
0x3fff6, 0x3fff1, 0xffff8, 0x7fff1, 0x7fff2, 0x7fff3, 0xffff9, 0x7fff7,
0x7fff4, 0xffffa, 0xffffb, 0xffffc, 0xffffd, 0xffffe, 0xfffff,
};
static const uint8_t t_huffman_env_bal_3_0dB_bits[25] = {
13, 13, 13, 13, 13, 13, 13, 12,
8, 7, 4, 3, 1, 2, 5, 6,
9, 13, 13, 13, 13, 13, 13, 14,
14,
};
static const uint16_t t_huffman_env_bal_3_0dB_codes[25] = {
0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 0x1ff8, 0x0ff8,
0x00fe, 0x007e, 0x000e, 0x0006, 0x0000, 0x0002, 0x001e, 0x003e,
0x01fe, 0x1ff9, 0x1ffa, 0x1ffb, 0x1ffc, 0x1ffd, 0x1ffe, 0x3ffe,
0x3fff,
};
static const uint8_t f_huffman_env_bal_3_0dB_bits[25] = {
13, 13, 13, 13, 13, 14, 14, 11,
8, 7, 4, 2, 1, 3, 5, 6,
9, 12, 13, 14, 14, 14, 14, 14,
14,
};
static const uint16_t f_huffman_env_bal_3_0dB_codes[25] = {
0x1ff7, 0x1ff8, 0x1ff9, 0x1ffa, 0x1ffb, 0x3ff8, 0x3ff9, 0x07fc,
0x00fe, 0x007e, 0x000e, 0x0002, 0x0000, 0x0006, 0x001e, 0x003e,
0x01fe, 0x0ffa, 0x1ff6, 0x3ffa, 0x3ffb, 0x3ffc, 0x3ffd, 0x3ffe,
0x3fff,
};
static const uint8_t t_huffman_noise_3_0dB_bits[63] = {
13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 11, 8, 6, 4, 3, 1,
2, 5, 8, 10, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 14, 14,
};
static const uint16_t t_huffman_noise_3_0dB_codes[63] = {
0x1fce, 0x1fcf, 0x1fd0, 0x1fd1, 0x1fd2, 0x1fd3, 0x1fd4, 0x1fd5,
0x1fd6, 0x1fd7, 0x1fd8, 0x1fd9, 0x1fda, 0x1fdb, 0x1fdc, 0x1fdd,
0x1fde, 0x1fdf, 0x1fe0, 0x1fe1, 0x1fe2, 0x1fe3, 0x1fe4, 0x1fe5,
0x1fe6, 0x1fe7, 0x07f2, 0x00fd, 0x003e, 0x000e, 0x0006, 0x0000,
0x0002, 0x001e, 0x00fc, 0x03f8, 0x1fcc, 0x1fe8, 0x1fe9, 0x1fea,
0x1feb, 0x1fec, 0x1fcd, 0x1fed, 0x1fee, 0x1fef, 0x1ff0, 0x1ff1,
0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 0x1ff8, 0x1ff9,
0x1ffa, 0x1ffb, 0x1ffc, 0x1ffd, 0x1ffe, 0x3ffe, 0x3fff,
};
static const uint8_t t_huffman_noise_bal_3_0dB_bits[25] = {
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 5, 2, 1, 3, 6, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8,
};
static const uint8_t t_huffman_noise_bal_3_0dB_codes[25] = {
0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3,
0xf4, 0xf5, 0x1c, 0x02, 0x00, 0x06, 0x3a, 0xf6,
0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe,
0xff,
};
static const int8_t sbr_offset[6][16] = {
{-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}, // fs_sbr = 16000 Hz
{-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13}, // fs_sbr = 22050 Hz

View File

@@ -27,27 +27,73 @@
* @author Maxim Gavrilov ( maxim.gavrilov gmail com )
*/
#include "config.h"
#include "config_components.h"
#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"
#include "aac.h"
#include "aactab.h"
#include <stddef.h>
#include <stdint.h>
float ff_aac_pow2sf_tab[428];
float ff_aac_pow34sf_tab[428];
#include "config_components.h"
#include "libavutil/attributes.h"
#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"
#include "aactab.h"
#if CONFIG_AAC_ENCODER || CONFIG_AAC_DECODER
#include "kbdwin.h"
#include "sinewin.h"
float ff_aac_pow2sf_tab[428];
float ff_aac_pow34sf_tab[428];
DECLARE_ALIGNED(32, float, ff_aac_kbd_long_1024)[1024];
DECLARE_ALIGNED(32, float, ff_aac_kbd_short_128)[128];
static av_cold void aac_tableinit(void)
{
/* 2^(i/16) for 0 <= i <= 15 */
static const float exp2_lut[] = {
1.00000000000000000000,
1.04427378242741384032,
1.09050773266525765921,
1.13878863475669165370,
1.18920711500272106672,
1.24185781207348404859,
1.29683955465100966593,
1.35425554693689272830,
1.41421356237309504880,
1.47682614593949931139,
1.54221082540794082361,
1.61049033194925430818,
1.68179283050742908606,
1.75625216037329948311,
1.83400808640934246349,
1.91520656139714729387,
};
float t1 = 8.8817841970012523233890533447265625e-16; // 2^(-50)
float t2 = 3.63797880709171295166015625e-12; // 2^(-38)
int t1_inc_cur, t2_inc_cur;
int t1_inc_prev = 0;
int t2_inc_prev = 8;
for (int i = 0; i < 428; i++) {
t1_inc_cur = 4 * (i % 4);
t2_inc_cur = (8 + 3*i) % 16;
if (t1_inc_cur < t1_inc_prev)
t1 *= 2;
if (t2_inc_cur < t2_inc_prev)
t2 *= 2;
// A much more efficient and accurate way of doing:
// ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.0);
// ff_aac_pow34sf_tab[i] = pow(ff_aac_pow2sf_tab[i], 3.0/4.0);
ff_aac_pow2sf_tab[i] = t1 * exp2_lut[t1_inc_cur];
ff_aac_pow34sf_tab[i] = t2 * exp2_lut[t2_inc_cur];
t1_inc_prev = t1_inc_cur;
t2_inc_prev = t2_inc_cur;
}
}
static av_cold void aac_float_common_init(void)
{
aac_tableinit();
avpriv_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
avpriv_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);
ff_init_ff_sine_windows(10);
@@ -1285,14 +1331,7 @@ static const uint16_t swb_offset_960_48[] =
672, 704, 736, 768, 800, 832, 864, 896, 928, 960
};
static const uint16_t swb_offset_960_32[] =
{
0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
40, 48, 56, 64, 72, 80, 88, 96, 108, 120,
132, 144, 160, 176, 196, 216, 240, 264, 292, 320,
352, 384, 416, 448, 480, 512, 544, 576, 608, 640,
672, 704, 736, 768, 800, 832, 864, 896, 928, 960
};
#define swb_offset_960_32 swb_offset_960_48
static const uint16_t swb_offset_960_24[] =
{
@@ -3299,53 +3338,3 @@ const DECLARE_ALIGNED(32, int, ff_aac_eld_window_480_fixed)[1800] = {
0xffecff1c, 0xffed391e, 0xffed740c, 0xffedafb1,
0xffedebe1, 0xffee287d, 0xffee654e, 0xffeea23f,
};
static void aac_tableinit(void)
{
/* 2^(i/16) for 0 <= i <= 15 */
static const float exp2_lut[] = {
1.00000000000000000000,
1.04427378242741384032,
1.09050773266525765921,
1.13878863475669165370,
1.18920711500272106672,
1.24185781207348404859,
1.29683955465100966593,
1.35425554693689272830,
1.41421356237309504880,
1.47682614593949931139,
1.54221082540794082361,
1.61049033194925430818,
1.68179283050742908606,
1.75625216037329948311,
1.83400808640934246349,
1.91520656139714729387,
};
float t1 = 8.8817841970012523233890533447265625e-16; // 2^(-50)
float t2 = 3.63797880709171295166015625e-12; // 2^(-38)
int t1_inc_cur, t2_inc_cur;
int t1_inc_prev = 0;
int t2_inc_prev = 8;
for (int i = 0; i < 428; i++) {
t1_inc_cur = 4 * (i % 4);
t2_inc_cur = (8 + 3*i) % 16;
if (t1_inc_cur < t1_inc_prev)
t1 *= 2;
if (t2_inc_cur < t2_inc_prev)
t2 *= 2;
// A much more efficient and accurate way of doing:
// ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.0);
// ff_aac_pow34sf_tab[i] = pow(ff_aac_pow2sf_tab[i], 3.0/4.0);
ff_aac_pow2sf_tab[i] = t1 * exp2_lut[t1_inc_cur];
ff_aac_pow34sf_tab[i] = t2 * exp2_lut[t2_inc_cur];
t1_inc_prev = t1_inc_cur;
t2_inc_prev = t2_inc_cur;
}
}
void ff_aac_tableinit(void)
{
static AVOnce init_static_once = AV_ONCE_INIT;
ff_thread_once(&init_static_once, aac_tableinit);
}

View File

@@ -31,7 +31,7 @@
#define AVCODEC_AACTAB_H
#include "libavutil/mem_internal.h"
#include "aac.h"
#include "aac_defines.h"
#include <stdint.h>
@@ -42,8 +42,6 @@
extern float ff_aac_pow2sf_tab[428];
extern float ff_aac_pow34sf_tab[428];
void ff_aac_tableinit(void);
/* @name ltp_coef
* Table of the LTP coefficients
*/

View File

@@ -131,6 +131,341 @@ endconst
b.ne 1b
.endm
function ff_hevc_put_hevc_pel_pixels4_8_neon, export=1
mov x7, #(MAX_PB_SIZE * 2)
1: ld1 {v0.s}[0], [x1], x2
ushll v4.8h, v0.8b, #6
subs w3, w3, #1
st1 {v4.d}[0], [x0], x7
b.ne 1b
ret
endfunc
function ff_hevc_put_hevc_pel_pixels6_8_neon, export=1
mov x7, #(MAX_PB_SIZE * 2 - 8)
1: ld1 {v0.8b}, [x1], x2
ushll v4.8h, v0.8b, #6
st1 {v4.d}[0], [x0], #8
subs w3, w3, #1
st1 {v4.s}[2], [x0], x7
b.ne 1b
ret
endfunc
function ff_hevc_put_hevc_pel_pixels8_8_neon, export=1
mov x7, #(MAX_PB_SIZE * 2)
1: ld1 {v0.8b}, [x1], x2
ushll v4.8h, v0.8b, #6
subs w3, w3, #1
st1 {v4.8h}, [x0], x7
b.ne 1b
ret
endfunc
function ff_hevc_put_hevc_pel_pixels12_8_neon, export=1
mov x7, #(MAX_PB_SIZE * 2 - 16)
1: ld1 {v0.8b, v1.8b}, [x1], x2
ushll v4.8h, v0.8b, #6
st1 {v4.8h}, [x0], #16
ushll v5.8h, v1.8b, #6
subs w3, w3, #1
st1 {v5.d}[0], [x0], x7
b.ne 1b
ret
endfunc
function ff_hevc_put_hevc_pel_pixels16_8_neon, export=1
mov x7, #(MAX_PB_SIZE * 2)
1: ld1 {v0.8b, v1.8b}, [x1], x2
ushll v4.8h, v0.8b, #6
ushll v5.8h, v1.8b, #6
subs w3, w3, #1
st1 {v4.8h, v5.8h}, [x0], x7
b.ne 1b
ret
endfunc
function ff_hevc_put_hevc_pel_pixels24_8_neon, export=1
mov x7, #(MAX_PB_SIZE * 2)
1: ld1 {v0.8b-v2.8b}, [x1], x2
ushll v4.8h, v0.8b, #6
ushll v5.8h, v1.8b, #6
ushll v6.8h, v2.8b, #6
subs w3, w3, #1
st1 {v4.8h-v6.8h}, [x0], x7
b.ne 1b
ret
endfunc
function ff_hevc_put_hevc_pel_pixels32_8_neon, export=1
mov x7, #(MAX_PB_SIZE * 2)
1: ld1 {v0.8b-v3.8b}, [x1], x2
ushll v4.8h, v0.8b, #6
ushll v5.8h, v1.8b, #6
ushll v6.8h, v2.8b, #6
ushll v7.8h, v3.8b, #6
subs w3, w3, #1
st1 {v4.8h-v7.8h}, [x0], x7
b.ne 1b
ret
endfunc
function ff_hevc_put_hevc_pel_pixels48_8_neon, export=1
mov x7, #(MAX_PB_SIZE)
1: ld1 {v0.16b-v2.16b}, [x1], x2
ushll v4.8h, v0.8b, #6
ushll2 v5.8h, v0.16b, #6
ushll v6.8h, v1.8b, #6
ushll2 v7.8h, v1.16b, #6
st1 {v4.8h-v7.8h}, [x0], #64
ushll v16.8h, v2.8b, #6
ushll2 v17.8h, v2.16b, #6
subs w3, w3, #1
st1 {v16.8h-v17.8h}, [x0], x7
b.ne 1b
ret
endfunc
function ff_hevc_put_hevc_pel_pixels64_8_neon, export=1
1: ld1 {v0.16b-v3.16b}, [x1], x2
ushll v4.8h, v0.8b, #6
ushll2 v5.8h, v0.16b, #6
ushll v6.8h, v1.8b, #6
ushll2 v7.8h, v1.16b, #6
st1 {v4.8h-v7.8h}, [x0], #(MAX_PB_SIZE)
ushll v16.8h, v2.8b, #6
ushll2 v17.8h, v2.16b, #6
ushll v18.8h, v3.8b, #6
ushll2 v19.8h, v3.16b, #6
subs w3, w3, #1
st1 {v16.8h-v19.8h}, [x0], #(MAX_PB_SIZE)
b.ne 1b
ret
endfunc
function ff_hevc_put_hevc_epel_v4_8_neon, export=1
load_epel_filterb x5, x4
sub x1, x1, x2
mov x10, #(MAX_PB_SIZE * 2)
ldr s16, [x1]
ldr s17, [x1, x2]
add x1, x1, x2, lsl #1
ld1 {v18.s}[0], [x1], x2
.macro calc src0, src1, src2, src3
ld1 {\src3\().s}[0], [x1], x2
movi v4.8h, #0
calc_epelb v4, \src0, \src1, \src2, \src3
subs w3, w3, #1
st1 {v4.4h}, [x0], x10
.endm
1: calc_all4
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_epel_v6_8_neon, export=1
load_epel_filterb x5, x4
sub x1, x1, x2
mov x10, #(MAX_PB_SIZE * 2 - 8)
ldr d16, [x1]
ldr d17, [x1, x2]
add x1, x1, x2, lsl #1
ld1 {v18.8b}, [x1], x2
.macro calc src0, src1, src2, src3
ld1 {\src3\().8b}, [x1], x2
movi v4.8h, #0
calc_epelb v4, \src0, \src1, \src2, \src3
st1 {v4.d}[0], [x0], #8
subs w3, w3, #1
st1 {v4.s}[2], [x0], x10
.endm
1: calc_all4
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_epel_v8_8_neon, export=1
load_epel_filterb x5, x4
sub x1, x1, x2
mov x10, #(MAX_PB_SIZE * 2)
ldr d16, [x1]
ldr d17, [x1, x2]
add x1, x1, x2, lsl #1
ld1 {v18.8b}, [x1], x2
.macro calc src0, src1, src2, src3
ld1 {\src3\().8b}, [x1], x2
movi v4.8h, #0
calc_epelb v4, \src0, \src1, \src2, \src3
subs w3, w3, #1
st1 {v4.8h}, [x0], x10
.endm
1: calc_all4
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_epel_v12_8_neon, export=1
load_epel_filterb x5, x4
sub x1, x1, x2
mov x10, #(MAX_PB_SIZE * 2)
ldr q16, [x1]
ldr q17, [x1, x2]
add x1, x1, x2, lsl #1
ld1 {v18.16b}, [x1], x2
.macro calc src0, src1, src2, src3
ld1 {\src3\().16b}, [x1], x2
movi v4.8h, #0
movi v5.8h, #0
calc_epelb v4, \src0, \src1, \src2, \src3
calc_epelb2 v5, \src0, \src1, \src2, \src3
str q4, [x0]
subs w3, w3, #1
str d5, [x0, #16]
add x0, x0, x10
.endm
1: calc_all4
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_epel_v16_8_neon, export=1
load_epel_filterb x5, x4
sub x1, x1, x2
mov x10, #(MAX_PB_SIZE * 2)
ldr q16, [x1]
ldr q17, [x1, x2]
add x1, x1, x2, lsl #1
ld1 {v18.16b}, [x1], x2
.macro calc src0, src1, src2, src3
ld1 {\src3\().16b}, [x1], x2
movi v4.8h, #0
movi v5.8h, #0
calc_epelb v4, \src0, \src1, \src2, \src3
calc_epelb2 v5, \src0, \src1, \src2, \src3
subs w3, w3, #1
st1 {v4.8h, v5.8h}, [x0], x10
.endm
1: calc_all4
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_epel_v24_8_neon, export=1
load_epel_filterb x5, x4
sub x1, x1, x2
mov x10, #(MAX_PB_SIZE * 2)
ld1 {v16.8b, v17.8b, v18.8b}, [x1], x2
ld1 {v19.8b, v20.8b, v21.8b}, [x1], x2
ld1 {v22.8b, v23.8b, v24.8b}, [x1], x2
.macro calc src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11
ld1 {\src9\().8b, \src10\().8b, \src11\().8b}, [x1], x2
movi v4.8h, #0
movi v5.8h, #0
movi v6.8h, #0
calc_epelb v4, \src0, \src3, \src6, \src9
calc_epelb v5, \src1, \src4, \src7, \src10
calc_epelb v6, \src2, \src5, \src8, \src11
subs w3, w3, #1
st1 {v4.8h-v6.8h}, [x0], x10
.endm
1: calc_all12
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_epel_v32_8_neon, export=1
load_epel_filterb x5, x4
sub x1, x1, x2
mov x10, #(MAX_PB_SIZE * 2)
ld1 {v16.16b, v17.16b}, [x1], x2
ld1 {v18.16b, v19.16b}, [x1], x2
ld1 {v20.16b, v21.16b}, [x1], x2
.macro calc src0, src1, src2, src3, src4, src5, src6, src7
ld1 {\src6\().16b, \src7\().16b}, [x1], x2
movi v4.8h, #0
movi v5.8h, #0
movi v6.8h, #0
movi v7.8h, #0
calc_epelb v4, \src0, \src2, \src4, \src6
calc_epelb2 v5, \src0, \src2, \src4, \src6
calc_epelb v6, \src1, \src3, \src5, \src7
calc_epelb2 v7, \src1, \src3, \src5, \src7
subs w3, w3, #1
st1 {v4.8h-v7.8h}, [x0], x10
.endm
1: calc_all8
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_epel_v48_8_neon, export=1
load_epel_filterb x5, x4
sub x1, x1, x2
mov x10, #64
ld1 {v16.16b, v17.16b, v18.16b}, [x1], x2
ld1 {v19.16b, v20.16b, v21.16b}, [x1], x2
ld1 {v22.16b, v23.16b, v24.16b}, [x1], x2
.macro calc src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11
ld1 {\src9\().16b, \src10\().16b, \src11\().16b}, [x1], x2
movi v4.8h, #0
movi v5.8h, #0
movi v6.8h, #0
movi v7.8h, #0
movi v28.8h, #0
movi v29.8h, #0
calc_epelb v4, \src0, \src3, \src6, \src9
calc_epelb2 v5, \src0, \src3, \src6, \src9
calc_epelb v6, \src1, \src4, \src7, \src10
calc_epelb2 v7, \src1, \src4, \src7, \src10
calc_epelb v28, \src2, \src5, \src8, \src11
calc_epelb2 v29, \src2, \src5, \src8, \src11
st1 {v4.8h-v7.8h}, [x0], #64
subs w3, w3, #1
st1 {v28.8h-v29.8h}, [x0], x10
.endm
1: calc_all12
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_epel_v64_8_neon, export=1
load_epel_filterb x5, x4
sub sp, sp, #32
st1 {v8.8b-v11.8b}, [sp]
sub x1, x1, x2
ld1 {v16.16b, v17.16b, v18.16b, v19.16b}, [x1], x2
ld1 {v20.16b, v21.16b, v22.16b, v23.16b}, [x1], x2
ld1 {v24.16b, v25.16b, v26.16b, v27.16b}, [x1], x2
.macro calc src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11, src12, src13, src14, src15
ld1 {\src12\().16b-\src15\().16b}, [x1], x2
movi v4.8h, #0
movi v5.8h, #0
movi v6.8h, #0
movi v7.8h, #0
movi v8.8h, #0
movi v9.8h, #0
movi v10.8h, #0
movi v11.8h, #0
calc_epelb v4, \src0, \src4, \src8, \src12
calc_epelb2 v5, \src0, \src4, \src8, \src12
calc_epelb v6, \src1, \src5, \src9, \src13
calc_epelb2 v7, \src1, \src5, \src9, \src13
calc_epelb v8, \src2, \src6, \src10, \src14
calc_epelb2 v9, \src2, \src6, \src10, \src14
calc_epelb v10, \src3, \src7, \src11, \src15
calc_epelb2 v11, \src3, \src7, \src11, \src15
st1 {v4.8h-v7.8h}, [x0], #64
subs w3, w3, #1
st1 {v8.8h-v11.8h}, [x0], #64
.endm
1: calc_all16
.purgem calc
2: ld1 {v8.8b-v11.8b}, [sp]
add sp, sp, #32
ret
endfunc
function ff_hevc_put_hevc_epel_uni_v4_8_neon, export=1
load_epel_filterb x6, x5
sub x2, x2, x3
@@ -683,6 +1018,262 @@ function ff_hevc_put_hevc_epel_h64_8_neon_i8mm, export=1
ret
endfunc
function ff_hevc_put_hevc_epel_hv4_8_neon_i8mm, export=1
add w10, w3, #3
lsl x10, x10, #7
sub sp, sp, x10 // tmp_array
stp x5, x30, [sp, #-32]!
stp x0, x3, [sp, #16]
add x0, sp, #32
sub x1, x1, x2
add w3, w3, #3
bl X(ff_hevc_put_hevc_epel_h4_8_neon_i8mm)
ldp x0, x3, [sp, #16]
ldp x5, x30, [sp], #32
load_epel_filterh x5, x4
mov x10, #(MAX_PB_SIZE * 2)
ldr d16, [sp]
ldr d17, [sp, x10]
add sp, sp, x10, lsl #1
ld1 {v18.4h}, [sp], x10
.macro calc src0, src1, src2, src3
ld1 {\src3\().4h}, [sp], x10
calc_epelh v4, \src0, \src1, \src2, \src3
subs w3, w3, #1
st1 {v4.4h}, [x0], x10
.endm
1: calc_all4
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_epel_hv6_8_neon_i8mm, export=1
add w10, w3, #3
lsl x10, x10, #7
sub sp, sp, x10 // tmp_array
stp x5, x30, [sp, #-32]!
stp x0, x3, [sp, #16]
add x0, sp, #32
sub x1, x1, x2
add w3, w3, #3
bl X(ff_hevc_put_hevc_epel_h6_8_neon_i8mm)
ldp x0, x3, [sp, #16]
ldp x5, x30, [sp], #32
load_epel_filterh x5, x4
mov x5, #120
mov x10, #(MAX_PB_SIZE * 2)
ldr q16, [sp]
ldr q17, [sp, x10]
add sp, sp, x10, lsl #1
ld1 {v18.8h}, [sp], x10
.macro calc src0, src1, src2, src3
ld1 {\src3\().8h}, [sp], x10
calc_epelh v4, \src0, \src1, \src2, \src3
calc_epelh2 v4, v5, \src0, \src1, \src2, \src3
st1 {v4.d}[0], [x0], #8
subs w3, w3, #1
st1 {v4.s}[2], [x0], x5
.endm
1: calc_all4
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_epel_hv8_8_neon_i8mm, export=1
add w10, w3, #3
lsl x10, x10, #7
sub sp, sp, x10 // tmp_array
stp x5, x30, [sp, #-32]!
stp x0, x3, [sp, #16]
add x0, sp, #32
sub x1, x1, x2
add w3, w3, #3
bl X(ff_hevc_put_hevc_epel_h8_8_neon_i8mm)
ldp x0, x3, [sp, #16]
ldp x5, x30, [sp], #32
load_epel_filterh x5, x4
mov x10, #(MAX_PB_SIZE * 2)
ldr q16, [sp]
ldr q17, [sp, x10]
add sp, sp, x10, lsl #1
ld1 {v18.8h}, [sp], x10
.macro calc src0, src1, src2, src3
ld1 {\src3\().8h}, [sp], x10
calc_epelh v4, \src0, \src1, \src2, \src3
calc_epelh2 v4, v5, \src0, \src1, \src2, \src3
subs w3, w3, #1
st1 {v4.8h}, [x0], x10
.endm
1: calc_all4
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_epel_hv12_8_neon_i8mm, export=1
add w10, w3, #3
lsl x10, x10, #7
sub sp, sp, x10 // tmp_array
stp x5, x30, [sp, #-32]!
stp x0, x3, [sp, #16]
add x0, sp, #32
sub x1, x1, x2
add w3, w3, #3
bl X(ff_hevc_put_hevc_epel_h12_8_neon_i8mm)
ldp x0, x3, [sp, #16]
ldp x5, x30, [sp], #32
load_epel_filterh x5, x4
mov x5, #112
mov x10, #(MAX_PB_SIZE * 2)
ld1 {v16.8h, v17.8h}, [sp], x10
ld1 {v18.8h, v19.8h}, [sp], x10
ld1 {v20.8h, v21.8h}, [sp], x10
.macro calc src0, src1, src2, src3, src4, src5, src6, src7
ld1 {\src6\().8h, \src7\().8h}, [sp], x10
calc_epelh v4, \src0, \src2, \src4, \src6
calc_epelh2 v4, v5, \src0, \src2, \src4, \src6
calc_epelh v5, \src1, \src3, \src5, \src7
st1 {v4.8h}, [x0], #16
subs w3, w3, #1
st1 {v5.4h}, [x0], x5
.endm
1: calc_all8
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_epel_hv16_8_neon_i8mm, export=1
add w10, w3, #3
lsl x10, x10, #7
sub sp, sp, x10 // tmp_array
stp x5, x30, [sp, #-32]!
stp x0, x3, [sp, #16]
add x0, sp, #32
sub x1, x1, x2
add w3, w3, #3
bl X(ff_hevc_put_hevc_epel_h16_8_neon_i8mm)
ldp x0, x3, [sp, #16]
ldp x5, x30, [sp], #32
load_epel_filterh x5, x4
mov x10, #(MAX_PB_SIZE * 2)
ld1 {v16.8h, v17.8h}, [sp], x10
ld1 {v18.8h, v19.8h}, [sp], x10
ld1 {v20.8h, v21.8h}, [sp], x10
.macro calc src0, src1, src2, src3, src4, src5, src6, src7
ld1 {\src6\().8h, \src7\().8h}, [sp], x10
calc_epelh v4, \src0, \src2, \src4, \src6
calc_epelh2 v4, v5, \src0, \src2, \src4, \src6
calc_epelh v5, \src1, \src3, \src5, \src7
calc_epelh2 v5, v6, \src1, \src3, \src5, \src7
subs w3, w3, #1
st1 {v4.8h, v5.8h}, [x0], x10
.endm
1: calc_all8
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_epel_hv24_8_neon_i8mm, export=1
add w10, w3, #3
lsl x10, x10, #7
sub sp, sp, x10 // tmp_array
stp x5, x30, [sp, #-32]!
stp x0, x3, [sp, #16]
add x0, sp, #32
sub x1, x1, x2
add w3, w3, #3
bl X(ff_hevc_put_hevc_epel_h24_8_neon_i8mm)
ldp x0, x3, [sp, #16]
ldp x5, x30, [sp], #32
load_epel_filterh x5, x4
mov x10, #(MAX_PB_SIZE * 2)
ld1 {v16.8h, v17.8h, v18.8h}, [sp], x10
ld1 {v19.8h, v20.8h, v21.8h}, [sp], x10
ld1 {v22.8h, v23.8h, v24.8h}, [sp], x10
.macro calc src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11
ld1 {\src9\().8h-\src11\().8h}, [sp], x10
calc_epelh v4, \src0, \src3, \src6, \src9
calc_epelh2 v4, v5, \src0, \src3, \src6, \src9
calc_epelh v5, \src1, \src4, \src7, \src10
calc_epelh2 v5, v6, \src1, \src4, \src7, \src10
calc_epelh v6, \src2, \src5, \src8, \src11
calc_epelh2 v6, v7, \src2, \src5, \src8, \src11
subs w3, w3, #1
st1 {v4.8h-v6.8h}, [x0], x10
.endm
1: calc_all12
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_epel_hv32_8_neon_i8mm, export=1
stp x4, x5, [sp, #-64]!
stp x2, x3, [sp, #16]
stp x0, x1, [sp, #32]
str x30, [sp, #48]
mov x6, #16
bl X(ff_hevc_put_hevc_epel_hv16_8_neon_i8mm)
ldp x0, x1, [sp, #32]
ldp x2, x3, [sp, #16]
ldp x4, x5, [sp], #48
add x0, x0, #32
add x1, x1, #16
mov x6, #16
bl X(ff_hevc_put_hevc_epel_hv16_8_neon_i8mm)
ldr x30, [sp], #16
ret
endfunc
function ff_hevc_put_hevc_epel_hv48_8_neon_i8mm, export=1
stp x4, x5, [sp, #-64]!
stp x2, x3, [sp, #16]
stp x0, x1, [sp, #32]
str x30, [sp, #48]
mov x6, #24
bl X(ff_hevc_put_hevc_epel_hv24_8_neon_i8mm)
ldp x0, x1, [sp, #32]
ldp x2, x3, [sp, #16]
ldp x4, x5, [sp], #48
add x0, x0, #48
add x1, x1, #24
mov x6, #24
bl X(ff_hevc_put_hevc_epel_hv24_8_neon_i8mm)
ldr x30, [sp], #16
ret
endfunc
function ff_hevc_put_hevc_epel_hv64_8_neon_i8mm, export=1
stp x4, x5, [sp, #-64]!
stp x2, x3, [sp, #16]
stp x0, x1, [sp, #32]
str x30, [sp, #48]
mov x6, #16
bl X(ff_hevc_put_hevc_epel_hv16_8_neon_i8mm)
ldp x4, x5, [sp]
ldp x2, x3, [sp, #16]
ldp x0, x1, [sp, #32]
add x0, x0, #32
add x1, x1, #16
mov x6, #16
bl X(ff_hevc_put_hevc_epel_hv16_8_neon_i8mm)
ldp x4, x5, [sp]
ldp x2, x3, [sp, #16]
ldp x0, x1, [sp, #32]
add x0, x0, #64
add x1, x1, #32
mov x6, #16
bl X(ff_hevc_put_hevc_epel_hv16_8_neon_i8mm)
ldp x0, x1, [sp, #32]
ldp x2, x3, [sp, #16]
ldp x4, x5, [sp], #48
add x0, x0, #96
add x1, x1, #48
mov x6, #16
bl X(ff_hevc_put_hevc_epel_hv16_8_neon_i8mm)
ldr x30, [sp], #16
ret
endfunc
function ff_hevc_put_hevc_epel_uni_hv4_8_neon_i8mm, export=1
add w10, w4, #3
lsl x10, x10, #7

View File

@@ -152,6 +152,14 @@ void ff_hevc_put_hevc_qpel_bi_h16_8_neon(uint8_t *_dst, ptrdiff_t _dststride, co
void ff_hevc_put_hevc_##fn##32_8_neon##ext args; \
void ff_hevc_put_hevc_##fn##64_8_neon##ext args
NEON8_FNPROTO(pel_pixels, (int16_t *dst,
const uint8_t *src, ptrdiff_t srcstride,
int height, intptr_t mx, intptr_t my, int width),);
NEON8_FNPROTO(epel_v, (int16_t *dst,
const uint8_t *src, ptrdiff_t srcstride,
int height, intptr_t mx, intptr_t my, int width),);
NEON8_FNPROTO(pel_uni_pixels, (uint8_t *_dst, ptrdiff_t _dststride,
const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width),);
@@ -183,6 +191,10 @@ NEON8_FNPROTO(epel_h, (int16_t *dst,
const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width), _i8mm);
NEON8_FNPROTO(epel_hv, (int16_t *dst,
const uint8_t *src, ptrdiff_t srcstride,
int height, intptr_t mx, intptr_t my, int width), _i8mm);
NEON8_FNPROTO(epel_uni_w_h, (uint8_t *_dst, ptrdiff_t _dststride,
const uint8_t *_src, ptrdiff_t _srcstride,
int height, int denom, int wx, int ox,
@@ -192,6 +204,14 @@ NEON8_FNPROTO(qpel_h, (int16_t *dst,
const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width), _i8mm);
NEON8_FNPROTO(qpel_v, (int16_t *dst,
const uint8_t *src, ptrdiff_t srcstride,
int height, intptr_t mx, intptr_t my, int width),);
NEON8_FNPROTO(qpel_hv, (int16_t *dst,
const uint8_t *src, ptrdiff_t srcstride,
int height, intptr_t mx, intptr_t my, int width), _i8mm);
NEON8_FNPROTO(qpel_uni_v, (uint8_t *dst, ptrdiff_t dststride,
const uint8_t *src, ptrdiff_t srcstride,
int height, intptr_t mx, intptr_t my, int width),);
@@ -300,6 +320,10 @@ av_cold void ff_hevc_dsp_init_aarch64(HEVCDSPContext *c, const int bit_depth)
c->put_hevc_qpel_bi[8][0][1] =
c->put_hevc_qpel_bi[9][0][1] = ff_hevc_put_hevc_qpel_bi_h16_8_neon;
NEON8_FNASSIGN(c->put_hevc_epel, 0, 0, pel_pixels,);
NEON8_FNASSIGN(c->put_hevc_epel, 1, 0, epel_v,);
NEON8_FNASSIGN(c->put_hevc_qpel, 0, 0, pel_pixels,);
NEON8_FNASSIGN(c->put_hevc_qpel, 1, 0, qpel_v,);
NEON8_FNASSIGN(c->put_hevc_epel_uni, 0, 0, pel_uni_pixels,);
NEON8_FNASSIGN(c->put_hevc_epel_uni, 1, 0, epel_uni_v,);
NEON8_FNASSIGN(c->put_hevc_qpel_uni, 0, 0, pel_uni_pixels,);
@@ -311,9 +335,11 @@ av_cold void ff_hevc_dsp_init_aarch64(HEVCDSPContext *c, const int bit_depth)
if (have_i8mm(cpu_flags)) {
NEON8_FNASSIGN(c->put_hevc_epel, 0, 1, epel_h, _i8mm);
NEON8_FNASSIGN(c->put_hevc_epel, 1, 1, epel_hv, _i8mm);
NEON8_FNASSIGN(c->put_hevc_epel_uni, 1, 1, epel_uni_hv, _i8mm);
NEON8_FNASSIGN(c->put_hevc_epel_uni_w, 0, 1, epel_uni_w_h ,_i8mm);
NEON8_FNASSIGN(c->put_hevc_qpel, 0, 1, qpel_h, _i8mm);
NEON8_FNASSIGN(c->put_hevc_qpel, 1, 1, qpel_hv, _i8mm);
NEON8_FNASSIGN(c->put_hevc_qpel_uni, 1, 1, qpel_uni_hv, _i8mm);
NEON8_FNASSIGN(c->put_hevc_qpel_uni_w, 0, 1, qpel_uni_w_h, _i8mm);
NEON8_FNASSIGN(c->put_hevc_epel_uni_w, 1, 1, epel_uni_w_hv, _i8mm);

View File

@@ -112,6 +112,44 @@ endconst
.endif
.endm
.macro calc_all
calc v23, v16, v17, v18, v19, v20, v21, v22, v23
b.eq 2f
calc v16, v17, v18, v19, v20, v21, v22, v23, v16
b.eq 2f
calc v17, v18, v19, v20, v21, v22, v23, v16, v17
b.eq 2f
calc v18, v19, v20, v21, v22, v23, v16, v17, v18
b.eq 2f
calc v19, v20, v21, v22, v23, v16, v17, v18, v19
b.eq 2f
calc v20, v21, v22, v23, v16, v17, v18, v19, v20
b.eq 2f
calc v21, v22, v23, v16, v17, v18, v19, v20, v21
b.eq 2f
calc v22, v23, v16, v17, v18, v19, v20, v21, v22
b.hi 1b
.endm
.macro calc_all2
calc v30, v31, v16, v18, v20, v22, v24, v26, v28, v30, v17, v19, v21, v23, v25, v27, v29, v31
b.eq 2f
calc v16, v17, v18, v20, v22, v24, v26, v28, v30, v16, v19, v21, v23, v25, v27, v29, v31, v17
b.eq 2f
calc v18, v19, v20, v22, v24, v26, v28, v30, v16, v18, v21, v23, v25, v27, v29, v31, v17, v19
b.eq 2f
calc v20, v21, v22, v24, v26, v28, v30, v16, v18, v20, v23, v25, v27, v29, v31, v17, v19, v21
b.eq 2f
calc v22, v23, v24, v26, v28, v30, v16, v18, v20, v22, v25, v27, v29, v31, v17, v19, v21, v23
b.eq 2f
calc v24, v25, v26, v28, v30, v16, v18, v20, v22, v24, v27, v29, v31, v17, v19, v21, v23, v25
b.eq 2f
calc v26, v27, v28, v30, v16, v18, v20, v22, v24, v26, v29, v31, v17, v19, v21, v23, v25, v27
b.eq 2f
calc v28, v29, v30, v16, v18, v20, v22, v24, v26, v28, v31, v17, v19, v21, v23, v25, v27, v29
b.hi 1b
.endm
.macro put_hevc type
.ifc \type, qpel
// void put_hevc_qpel_h(int16_t *dst,
@@ -558,6 +596,276 @@ put_hevc qpel
put_hevc qpel_uni
put_hevc qpel_bi
function ff_hevc_put_hevc_qpel_v4_8_neon, export=1
load_qpel_filterb x5, x4
sub x1, x1, x2, lsl #1
mov x9, #(MAX_PB_SIZE * 2)
sub x1, x1, x2
ldr s16, [x1]
ldr s17, [x1, x2]
add x1, x1, x2, lsl #1
ldr s18, [x1]
ldr s19, [x1, x2]
add x1, x1, x2, lsl #1
ldr s20, [x1]
ldr s21, [x1, x2]
add x1, x1, x2, lsl #1
ldr s22, [x1]
add x1, x1, x2
.macro calc tmp, src0, src1, src2, src3, src4, src5, src6, src7
ld1 {\tmp\().s}[0], [x1], x2
movi v24.8h, #0
calc_qpelb v24, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7
st1 {v24.4h}, [x0], x9
subs w3, w3, #1
b.eq 2f
.endm
1: calc_all
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_qpel_v6_8_neon, export=1
load_qpel_filterb x5, x4
sub x1, x1, x2, lsl #1
mov x9, #(MAX_PB_SIZE * 2 - 8)
sub x1, x1, x2
ldr d16, [x1]
ldr d17, [x1, x2]
add x1, x1, x2, lsl #1
ldr d18, [x1]
ldr d19, [x1, x2]
add x1, x1, x2, lsl #1
ldr d20, [x1]
ldr d21, [x1, x2]
add x1, x1, x2, lsl #1
ldr d22, [x1]
add x1, x1, x2
.macro calc tmp, src0, src1, src2, src3, src4, src5, src6, src7
ld1 {\tmp\().8b}, [x1], x2
movi v24.8h, #0
calc_qpelb v24, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7
st1 {v24.4h}, [x0], #8
st1 {v24.s}[2], [x0], x9
subs w3, w3, #1
.endm
1: calc_all
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_qpel_v8_8_neon, export=1
load_qpel_filterb x5, x4
sub x1, x1, x2, lsl #1
mov x9, #(MAX_PB_SIZE * 2)
sub x1, x1, x2
ldr d16, [x1]
ldr d17, [x1, x2]
add x1, x1, x2, lsl #1
ldr d18, [x1]
ldr d19, [x1, x2]
add x1, x1, x2, lsl #1
ldr d20, [x1]
ldr d21, [x1, x2]
add x1, x1, x2, lsl #1
ldr d22, [x1]
add x1, x1, x2
.macro calc tmp, src0, src1, src2, src3, src4, src5, src6, src7
ld1 {\tmp\().8b}, [x1], x2
movi v24.8h, #0
calc_qpelb v24, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7
st1 {v24.8h}, [x0], x9
subs w3, w3, #1
.endm
1: calc_all
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_qpel_v12_8_neon, export=1
load_qpel_filterb x5, x4
sub x1, x1, x2, lsl #1
mov x9, #(MAX_PB_SIZE * 2 - 16)
sub x1, x1, x2
ldr q16, [x1]
ldr q17, [x1, x2]
add x1, x1, x2, lsl #1
ldr q18, [x1]
ldr q19, [x1, x2]
add x1, x1, x2, lsl #1
ldr q20, [x1]
ldr q21, [x1, x2]
add x1, x1, x2, lsl #1
ldr q22, [x1]
add x1, x1, x2
.macro calc tmp, src0, src1, src2, src3, src4, src5, src6, src7
ld1 {\tmp\().16b}, [x1], x2
movi v24.8h, #0
movi v25.8h, #0
calc_qpelb v24, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7
calc_qpelb2 v25, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7
st1 {v24.8h}, [x0], #16
subs w3, w3, #1
st1 {v25.4h}, [x0], x9
.endm
1: calc_all
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_qpel_v16_8_neon, export=1
load_qpel_filterb x5, x4
sub x1, x1, x2, lsl #1
mov x9, #(MAX_PB_SIZE * 2)
sub x1, x1, x2
ldr q16, [x1]
ldr q17, [x1, x2]
add x1, x1, x2, lsl #1
ldr q18, [x1]
ldr q19, [x1, x2]
add x1, x1, x2, lsl #1
ldr q20, [x1]
ldr q21, [x1, x2]
add x1, x1, x2, lsl #1
ldr q22, [x1]
add x1, x1, x2
.macro calc tmp, src0, src1, src2, src3, src4, src5, src6, src7
ld1 {\tmp\().16b}, [x1], x2
movi v24.8h, #0
movi v25.8h, #0
calc_qpelb v24, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7
calc_qpelb2 v25, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7
subs w3, w3, #1
st1 {v24.8h, v25.8h}, [x0], x9
.endm
1: calc_all
.purgem calc
2: ret
endfunc
// todo: reads #32 bytes
function ff_hevc_put_hevc_qpel_v24_8_neon, export=1
sub sp, sp, #32
st1 {v8.8b, v9.8b, v10.8b}, [sp]
load_qpel_filterb x5, x4
sub x1, x1, x2, lsl #1
sub x1, x1, x2
mov x9, #(MAX_PB_SIZE * 2)
ld1 {v16.16b, v17.16b}, [x1], x2
ld1 {v18.16b, v19.16b}, [x1], x2
ld1 {v20.16b, v21.16b}, [x1], x2
ld1 {v22.16b, v23.16b}, [x1], x2
ld1 {v24.16b, v25.16b}, [x1], x2
ld1 {v26.16b, v27.16b}, [x1], x2
ld1 {v28.16b, v29.16b}, [x1], x2
.macro calc tmp0, tmp1, src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11, src12, src13, src14, src15
ld1 {\tmp0\().16b, \tmp1\().16b}, [x1], x2
movi v8.8h, #0
movi v9.8h, #0
movi v10.8h, #0
calc_qpelb v8, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7
calc_qpelb2 v9, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7
calc_qpelb v10, \src8, \src9, \src10, \src11, \src12, \src13, \src14, \src15
subs w3, w3, #1
st1 {v8.8h, v9.8h, v10.8h}, [x0], x9
.endm
1: calc_all2
.purgem calc
2: ld1 {v8.8b, v9.8b, v10.8b}, [sp]
add sp, sp, #32
ret
endfunc
function ff_hevc_put_hevc_qpel_v32_8_neon, export=1
sub sp, sp, #32
st1 {v8.8b-v11.8b}, [sp]
load_qpel_filterb x5, x4
sub x1, x1, x2, lsl #1
mov x9, #(MAX_PB_SIZE * 2)
sub x1, x1, x2
ld1 {v16.16b, v17.16b}, [x1], x2
ld1 {v18.16b, v19.16b}, [x1], x2
ld1 {v20.16b, v21.16b}, [x1], x2
ld1 {v22.16b, v23.16b}, [x1], x2
ld1 {v24.16b, v25.16b}, [x1], x2
ld1 {v26.16b, v27.16b}, [x1], x2
ld1 {v28.16b, v29.16b}, [x1], x2
.macro calc tmp0, tmp1, src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11, src12, src13, src14, src15
ld1 {\tmp0\().16b, \tmp1\().16b}, [x1], x2
movi v8.8h, #0
movi v9.8h, #0
movi v10.8h, #0
movi v11.8h, #0
calc_qpelb v8, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7
calc_qpelb2 v9, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7
calc_qpelb v10, \src8, \src9, \src10, \src11, \src12, \src13, \src14, \src15
calc_qpelb2 v11, \src8, \src9, \src10, \src11, \src12, \src13, \src14, \src15
subs w3, w3, #1
st1 {v8.8h-v11.8h}, [x0], x9
.endm
1: calc_all2
.purgem calc
2: ld1 {v8.8b-v11.8b}, [sp], #32
ret
endfunc
function ff_hevc_put_hevc_qpel_v48_8_neon, export=1
stp x2, x3, [sp, #-48]!
stp x0, x1, [sp, #16]
stp x5, x30, [sp, #32]
bl X(ff_hevc_put_hevc_qpel_v24_8_neon)
ldr x5, [sp, #32]
ldp x0, x1, [sp, #16]
ldp x2, x3, [sp], #32
add x0, x0, #48
add x1, x1, #24
bl X(ff_hevc_put_hevc_qpel_v24_8_neon)
ldr x30, [sp, #8]
add sp, sp, #16
ret
endfunc
function ff_hevc_put_hevc_qpel_v64_8_neon, export=1
sub sp, sp, #32
st1 {v8.8b-v11.8b}, [sp]
load_qpel_filterb x5, x4
sub x1, x1, x2, lsl #1
sub x1, x1, x2
mov x9, #(MAX_PB_SIZE * 2)
0: mov x8, x1 // src
ld1 {v16.16b, v17.16b}, [x8], x2
mov w11, w3 // height
ld1 {v18.16b, v19.16b}, [x8], x2
mov x10, x0 // dst
ld1 {v20.16b, v21.16b}, [x8], x2
ld1 {v22.16b, v23.16b}, [x8], x2
ld1 {v24.16b, v25.16b}, [x8], x2
ld1 {v26.16b, v27.16b}, [x8], x2
ld1 {v28.16b, v29.16b}, [x8], x2
.macro calc tmp0, tmp1, src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11, src12, src13, src14, src15
ld1 {\tmp0\().16b, \tmp1\().16b}, [x8], x2
movi v8.8h, #0
movi v9.8h, #0
movi v10.8h, #0
movi v11.8h, #0
calc_qpelb v8, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7
calc_qpelb2 v9, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7
calc_qpelb v10, \src8, \src9, \src10, \src11, \src12, \src13, \src14, \src15
calc_qpelb2 v11, \src8, \src9, \src10, \src11, \src12, \src13, \src14, \src15
subs x11, x11, #1
st1 {v8.8h-v11.8h}, [x10], x9
.endm
1: calc_all2
.purgem calc
2: add x0, x0, #64
add x1, x1, #32
subs w6, w6, #32
b.hi 0b
ld1 {v8.8b-v11.8b}, [sp], #32
ret
endfunc
function ff_hevc_put_hevc_pel_uni_pixels4_8_neon, export=1
1:
ldr s0, [x2]
@@ -663,25 +971,6 @@ function ff_hevc_put_hevc_pel_uni_pixels64_8_neon, export=1
ret
endfunc
.macro calc_all
calc v23, v16, v17, v18, v19, v20, v21, v22, v23
b.eq 2f
calc v16, v17, v18, v19, v20, v21, v22, v23, v16
b.eq 2f
calc v17, v18, v19, v20, v21, v22, v23, v16, v17
b.eq 2f
calc v18, v19, v20, v21, v22, v23, v16, v17, v18
b.eq 2f
calc v19, v20, v21, v22, v23, v16, v17, v18, v19
b.eq 2f
calc v20, v21, v22, v23, v16, v17, v18, v19, v20
b.eq 2f
calc v21, v22, v23, v16, v17, v18, v19, v20, v21
b.eq 2f
calc v22, v23, v16, v17, v18, v19, v20, v21, v22
b.hi 1b
.endm
function ff_hevc_put_hevc_qpel_uni_v4_8_neon, export=1
load_qpel_filterb x6, x5
sub x2, x2, x3, lsl #1
@@ -1560,25 +1849,6 @@ endfunc
#if HAVE_I8MM
ENABLE_I8MM
.macro calc_all2
calc v30, v31, v16, v18, v20, v22, v24, v26, v28, v30, v17, v19, v21, v23, v25, v27, v29, v31
b.eq 2f
calc v16, v17, v18, v20, v22, v24, v26, v28, v30, v16, v19, v21, v23, v25, v27, v29, v31, v17
b.eq 2f
calc v18, v19, v20, v22, v24, v26, v28, v30, v16, v18, v21, v23, v25, v27, v29, v31, v17, v19
b.eq 2f
calc v20, v21, v22, v24, v26, v28, v30, v16, v18, v20, v23, v25, v27, v29, v31, v17, v19, v21
b.eq 2f
calc v22, v23, v24, v26, v28, v30, v16, v18, v20, v22, v25, v27, v29, v31, v17, v19, v21, v23
b.eq 2f
calc v24, v25, v26, v28, v30, v16, v18, v20, v22, v24, v27, v29, v31, v17, v19, v21, v23, v25
b.eq 2f
calc v26, v27, v28, v30, v16, v18, v20, v22, v24, v26, v29, v31, v17, v19, v21, v23, v25, v27
b.eq 2f
calc v28, v29, v30, v16, v18, v20, v22, v24, v26, v28, v31, v17, v19, v21, v23, v25, v27, v29
b.hi 1b
.endm
function ff_hevc_put_hevc_qpel_uni_hv4_8_neon_i8mm, export=1
add w10, w4, #7
lsl x10, x10, #7
@@ -2791,6 +3061,292 @@ function ff_hevc_put_hevc_qpel_h64_8_neon_i8mm, export=1
ret
endfunc
function ff_hevc_put_hevc_qpel_hv4_8_neon_i8mm, export=1
add w10, w3, #7
mov x7, #128
lsl x10, x10, #7
sub sp, sp, x10 // tmp_array
stp x5, x30, [sp, #-32]!
stp x0, x3, [sp, #16]
add x0, sp, #32
sub x1, x1, x2, lsl #1
add x3, x3, #7
sub x1, x1, x2
bl X(ff_hevc_put_hevc_qpel_h4_8_neon_i8mm)
ldp x0, x3, [sp, #16]
ldp x5, x30, [sp], #32
load_qpel_filterh x5, x4
ldr d16, [sp]
ldr d17, [sp, x7]
add sp, sp, x7, lsl #1
ldr d18, [sp]
ldr d19, [sp, x7]
add sp, sp, x7, lsl #1
ldr d20, [sp]
ldr d21, [sp, x7]
add sp, sp, x7, lsl #1
ldr d22, [sp]
add sp, sp, x7
.macro calc tmp, src0, src1, src2, src3, src4, src5, src6, src7
ld1 {\tmp\().4h}, [sp], x7
calc_qpelh v1, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7, sqshrn
subs w3, w3, #1
st1 {v1.4h}, [x0], x7
.endm
1: calc_all
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_qpel_hv6_8_neon_i8mm, export=1
add w10, w3, #7
mov x7, #128
lsl x10, x10, #7
sub sp, sp, x10 // tmp_array
stp x5, x30, [sp, #-32]!
stp x0, x3, [sp, #16]
add x0, sp, #32
sub x1, x1, x2, lsl #1
add x3, x3, #7
sub x1, x1, x2
bl X(ff_hevc_put_hevc_qpel_h6_8_neon_i8mm)
ldp x0, x3, [sp, #16]
ldp x5, x30, [sp], #32
mov x8, #120
load_qpel_filterh x5, x4
ldr q16, [sp]
ldr q17, [sp, x7]
add sp, sp, x7, lsl #1
ldr q18, [sp]
ldr q19, [sp, x7]
add sp, sp, x7, lsl #1
ldr q20, [sp]
ldr q21, [sp, x7]
add sp, sp, x7, lsl #1
ldr q22, [sp]
add sp, sp, x7
.macro calc tmp, src0, src1, src2, src3, src4, src5, src6, src7
ld1 {\tmp\().8h}, [sp], x7
calc_qpelh v1, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7, sqshrn
calc_qpelh2 v1, v2, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7, sqshrn2
st1 {v1.4h}, [x0], #8
subs w3, w3, #1
st1 {v1.s}[2], [x0], x8
.endm
1: calc_all
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_qpel_hv8_8_neon_i8mm, export=1
add w10, w3, #7
lsl x10, x10, #7
sub x1, x1, x2, lsl #1
sub sp, sp, x10 // tmp_array
stp x5, x30, [sp, #-32]!
stp x0, x3, [sp, #16]
add x0, sp, #32
add x3, x3, #7
sub x1, x1, x2
bl X(ff_hevc_put_hevc_qpel_h8_8_neon_i8mm)
ldp x0, x3, [sp, #16]
ldp x5, x30, [sp], #32
mov x7, #128
load_qpel_filterh x5, x4
ldr q16, [sp]
ldr q17, [sp, x7]
add sp, sp, x7, lsl #1
ldr q18, [sp]
ldr q19, [sp, x7]
add sp, sp, x7, lsl #1
ldr q20, [sp]
ldr q21, [sp, x7]
add sp, sp, x7, lsl #1
ldr q22, [sp]
add sp, sp, x7
.macro calc tmp, src0, src1, src2, src3, src4, src5, src6, src7
ld1 {\tmp\().8h}, [sp], x7
calc_qpelh v1, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7, sqshrn
calc_qpelh2 v1, v2, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7, sqshrn2
subs w3, w3, #1
st1 {v1.8h}, [x0], x7
.endm
1: calc_all
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_qpel_hv12_8_neon_i8mm, export=1
add w10, w3, #7
lsl x10, x10, #7
sub x1, x1, x2, lsl #1
sub sp, sp, x10 // tmp_array
stp x5, x30, [sp, #-32]!
stp x0, x3, [sp, #16]
add x0, sp, #32
add x3, x3, #7
sub x1, x1, x2
bl X(ff_hevc_put_hevc_qpel_h12_8_neon_i8mm)
ldp x0, x3, [sp, #16]
ldp x5, x30, [sp], #32
mov x7, #128
load_qpel_filterh x5, x4
mov x8, #112
ld1 {v16.8h, v17.8h}, [sp], x7
ld1 {v18.8h, v19.8h}, [sp], x7
ld1 {v20.8h, v21.8h}, [sp], x7
ld1 {v22.8h, v23.8h}, [sp], x7
ld1 {v24.8h, v25.8h}, [sp], x7
ld1 {v26.8h, v27.8h}, [sp], x7
ld1 {v28.8h, v29.8h}, [sp], x7
.macro calc tmp0, tmp1, src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11, src12, src13, src14, src15
ld1 {\tmp0\().8h, \tmp1\().8h}, [sp], x7
calc_qpelh v1, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7, sqshrn
calc_qpelh2 v1, v2, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7, sqshrn2
calc_qpelh v2, \src8, \src9, \src10, \src11, \src12, \src13, \src14, \src15, sqshrn
st1 {v1.8h}, [x0], #16
subs w3, w3, #1
st1 {v2.4h}, [x0], x8
.endm
1: calc_all2
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_qpel_hv16_8_neon_i8mm, export=1
add w10, w3, #7
lsl x10, x10, #7
sub x1, x1, x2, lsl #1
sub sp, sp, x10 // tmp_array
stp x5, x30, [sp, #-32]!
stp x0, x3, [sp, #16]
add x3, x3, #7
add x0, sp, #32
sub x1, x1, x2
bl X(ff_hevc_put_hevc_qpel_h16_8_neon_i8mm)
ldp x0, x3, [sp, #16]
ldp x5, x30, [sp], #32
mov x7, #128
load_qpel_filterh x5, x4
ld1 {v16.8h, v17.8h}, [sp], x7
ld1 {v18.8h, v19.8h}, [sp], x7
ld1 {v20.8h, v21.8h}, [sp], x7
ld1 {v22.8h, v23.8h}, [sp], x7
ld1 {v24.8h, v25.8h}, [sp], x7
ld1 {v26.8h, v27.8h}, [sp], x7
ld1 {v28.8h, v29.8h}, [sp], x7
.macro calc tmp0, tmp1, src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11, src12, src13, src14, src15
ld1 {\tmp0\().8h, \tmp1\().8h}, [sp], x7
calc_qpelh v1, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7, sqshrn
calc_qpelh2 v1, v2, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7, sqshrn2
calc_qpelh v2, \src8, \src9, \src10, \src11, \src12, \src13, \src14, \src15, sqshrn
calc_qpelh2 v2, v3, \src8, \src9, \src10, \src11, \src12, \src13, \src14, \src15, sqshrn2
subs w3, w3, #1
st1 {v1.8h, v2.8h}, [x0], x7
.endm
1: calc_all2
.purgem calc
2: ret
endfunc
function ff_hevc_put_hevc_qpel_hv24_8_neon_i8mm, export=1
stp x4, x5, [sp, #-64]!
stp x2, x3, [sp, #16]
stp x0, x1, [sp, #32]
str x30, [sp, #48]
bl X(ff_hevc_put_hevc_qpel_hv12_8_neon_i8mm)
ldp x0, x1, [sp, #32]
ldp x2, x3, [sp, #16]
ldp x4, x5, [sp], #48
add x1, x1, #12
add x0, x0, #24
bl X(ff_hevc_put_hevc_qpel_hv12_8_neon_i8mm)
ldr x30, [sp], #16
ret
endfunc
function ff_hevc_put_hevc_qpel_hv32_8_neon_i8mm, export=1
add w10, w3, #7
sub x1, x1, x2, lsl #1
lsl x10, x10, #7
sub x1, x1, x2
sub sp, sp, x10 // tmp_array
stp x5, x30, [sp, #-32]!
stp x0, x3, [sp, #16]
add x3, x3, #7
add x0, sp, #32
bl X(ff_hevc_put_hevc_qpel_h32_8_neon_i8mm)
ldp x0, x3, [sp, #16]
ldp x5, x30, [sp], #32
mov x7, #128
load_qpel_filterh x5, x4
0: mov x8, sp // src
ld1 {v16.8h, v17.8h}, [x8], x7
mov w9, w3 // height
ld1 {v18.8h, v19.8h}, [x8], x7
mov x5, x0 // dst
ld1 {v20.8h, v21.8h}, [x8], x7
ld1 {v22.8h, v23.8h}, [x8], x7
ld1 {v24.8h, v25.8h}, [x8], x7
ld1 {v26.8h, v27.8h}, [x8], x7
ld1 {v28.8h, v29.8h}, [x8], x7
.macro calc tmp0, tmp1, src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11, src12, src13, src14, src15
ld1 {\tmp0\().8h, \tmp1\().8h}, [x8], x7
calc_qpelh v1, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7, sqshrn
calc_qpelh2 v1, v2, \src0, \src1, \src2, \src3, \src4, \src5, \src6, \src7, sqshrn2
calc_qpelh v2, \src8, \src9, \src10, \src11, \src12, \src13, \src14, \src15, sqshrn
calc_qpelh2 v2, v3, \src8, \src9, \src10, \src11, \src12, \src13, \src14, \src15, sqshrn2
subs x9, x9, #1
st1 {v1.8h, v2.8h}, [x5], x7
.endm
1: calc_all2
.purgem calc
2: add x0, x0, #32
add sp, sp, #32
subs w6, w6, #16
b.hi 0b
add w10, w3, #6
add sp, sp, #64 // discard rest of first line
lsl x10, x10, #7
add sp, sp, x10 // tmp_array without first line
ret
endfunc
function ff_hevc_put_hevc_qpel_hv48_8_neon_i8mm, export=1
stp x4, x5, [sp, #-64]!
stp x2, x3, [sp, #16]
stp x0, x1, [sp, #32]
str x30, [sp, #48]
bl X(ff_hevc_put_hevc_qpel_hv24_8_neon_i8mm)
ldp x0, x1, [sp, #32]
ldp x2, x3, [sp, #16]
ldp x4, x5, [sp], #48
add x1, x1, #24
add x0, x0, #48
bl X(ff_hevc_put_hevc_qpel_hv24_8_neon_i8mm)
ldr x30, [sp], #16
ret
endfunc
function ff_hevc_put_hevc_qpel_hv64_8_neon_i8mm, export=1
stp x4, x5, [sp, #-64]!
stp x2, x3, [sp, #16]
stp x0, x1, [sp, #32]
str x30, [sp, #48]
mov x6, #32
bl X(ff_hevc_put_hevc_qpel_hv32_8_neon_i8mm)
ldp x0, x1, [sp, #32]
ldp x2, x3, [sp, #16]
ldp x4, x5, [sp], #48
add x1, x1, #32
add x0, x0, #64
mov x6, #32
bl X(ff_hevc_put_hevc_qpel_hv32_8_neon_i8mm)
ldr x30, [sp], #16
ret
endfunc
.macro QPEL_UNI_W_HV_HEADER width
ldp x14, x15, [sp] // mx, my
ldr w13, [sp, #16] // width

View File

@@ -188,6 +188,7 @@ extern const FFCodec ff_jv_decoder;
extern const FFCodec ff_kgv1_decoder;
extern const FFCodec ff_kmvc_decoder;
extern const FFCodec ff_lagarith_decoder;
extern const FFCodec ff_lead_decoder;
extern const FFCodec ff_ljpeg_encoder;
extern const FFCodec ff_loco_decoder;
extern const FFCodec ff_lscr_decoder;

View File

@@ -77,7 +77,7 @@ static const AVOption options[] = {
{ "qvbr_quality_level", "Sets the QVBR quality level", OFFSET(qvbr_quality_level), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 51, VE },
{ "header_insertion_mode", "Set header insertion mode", OFFSET(header_insertion_mode), AV_OPT_TYPE_INT,{.i64 = AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_NONE }, AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_NONE, AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_KEY_FRAME_ALIGNED, VE, "hdrmode" },
{ "header_insertion_mode", "Set header insertion mode", OFFSET(header_insertion_mode), AV_OPT_TYPE_INT,{.i64 = -1 }, -1, AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_KEY_FRAME_ALIGNED, VE, "hdrmode" },
{ "none", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_NONE }, 0, 0, VE, "hdrmode" },
{ "gop", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_GOP_ALIGNED }, 0, 0, VE, "hdrmode" },
{ "frame", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_KEY_FRAME_ALIGNED }, 0, 0, VE, "hdrmode" },
@@ -220,7 +220,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
// Picture control properties
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_GOP_SIZE, avctx->gop_size);
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE, ctx->header_insertion_mode);
// Setup header insertion mode only if this option was defined explicitly
if (ctx->header_insertion_mode != -1)
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE, ctx->header_insertion_mode);
// Rate control
// autodetect rate control method

View File

@@ -45,11 +45,11 @@
#define ASV1_LEVEL_VLC_BITS 4
#define ASV2_LEVEL_VLC_BITS 10
static VLC ccp_vlc;
static VLC level_vlc;
static VLC dc_ccp_vlc;
static VLC ac_ccp_vlc;
static VLC asv2_level_vlc;
static VLCElem ccp_vlc[32];
static VLCElem level_vlc[16];
static VLCElem dc_ccp_vlc[16];
static VLCElem ac_ccp_vlc[64];
static VLCElem asv2_level_vlc[1024];
typedef struct ASVDecContext {
ASVCommonContext c;
@@ -67,26 +67,26 @@ typedef struct ASVDecContext {
static av_cold void init_vlcs(void)
{
VLC_INIT_STATIC(&ccp_vlc, CCP_VLC_BITS, 17,
&ff_asv_ccp_tab[0][1], 2, 1,
&ff_asv_ccp_tab[0][0], 2, 1, 32);
VLC_INIT_LE_STATIC(&dc_ccp_vlc, DC_CCP_VLC_BITS, 8,
&ff_asv_dc_ccp_tab[0][1], 2, 1,
&ff_asv_dc_ccp_tab[0][0], 2, 1, 16);
VLC_INIT_LE_STATIC(&ac_ccp_vlc, AC_CCP_VLC_BITS, 16,
&ff_asv_ac_ccp_tab[0][1], 2, 1,
&ff_asv_ac_ccp_tab[0][0], 2, 1, 64);
VLC_INIT_STATIC(&level_vlc, ASV1_LEVEL_VLC_BITS, 7,
&ff_asv_level_tab[0][1], 2, 1,
&ff_asv_level_tab[0][0], 2, 1, 16);
VLC_INIT_LE_STATIC(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63,
&ff_asv2_level_tab[0][1], 4, 2,
&ff_asv2_level_tab[0][0], 4, 2, 1024);
VLC_INIT_STATIC_TABLE(ccp_vlc, CCP_VLC_BITS, 17,
&ff_asv_ccp_tab[0][1], 2, 1,
&ff_asv_ccp_tab[0][0], 2, 1, 0);
VLC_INIT_STATIC_TABLE(dc_ccp_vlc, DC_CCP_VLC_BITS, 8,
&ff_asv_dc_ccp_tab[0][1], 2, 1,
&ff_asv_dc_ccp_tab[0][0], 2, 1, VLC_INIT_LE);
VLC_INIT_STATIC_TABLE(ac_ccp_vlc, AC_CCP_VLC_BITS, 16,
&ff_asv_ac_ccp_tab[0][1], 2, 1,
&ff_asv_ac_ccp_tab[0][0], 2, 1, VLC_INIT_LE);
VLC_INIT_STATIC_TABLE(level_vlc, ASV1_LEVEL_VLC_BITS, 7,
&ff_asv_level_tab[0][1], 2, 1,
&ff_asv_level_tab[0][0], 2, 1, 0);
VLC_INIT_STATIC_TABLE(asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63,
&ff_asv2_level_tab[0][1], 4, 2,
&ff_asv2_level_tab[0][0], 4, 2, VLC_INIT_LE);
}
static inline int asv1_get_level(GetBitContext *gb)
{
int code = get_vlc2(gb, level_vlc.table, ASV1_LEVEL_VLC_BITS, 1);
int code = get_vlc2(gb, level_vlc, ASV1_LEVEL_VLC_BITS, 1);
if (code == 3)
return get_sbits(gb, 8);
@@ -115,7 +115,7 @@ static inline int asv2_get_vlc2(GetBitContext *gb, const VLCElem *table, int bit
static inline int asv2_get_level(GetBitContext *gb)
{
int code = asv2_get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS);
int code = asv2_get_vlc2(gb, asv2_level_vlc, ASV2_LEVEL_VLC_BITS);
if (code == 31)
return (int8_t) get_bits_le(gb, 8);
@@ -130,7 +130,7 @@ static inline int asv1_decode_block(ASVDecContext *a, int16_t block[64])
block[0] = 8 * get_bits(&a->gb, 8);
for (i = 0; i < 11; i++) {
const int ccp = get_vlc2(&a->gb, ccp_vlc.table, CCP_VLC_BITS, 1);
const int ccp = get_vlc2(&a->gb, ccp_vlc, CCP_VLC_BITS, 1);
if (ccp) {
if (ccp == 16)
@@ -162,7 +162,7 @@ static inline int asv2_decode_block(ASVDecContext *a, int16_t block[64])
block[0] = 8 * get_bits_le(&a->gb, 8);
ccp = asv2_get_vlc2(&a->gb, dc_ccp_vlc.table, DC_CCP_VLC_BITS);
ccp = asv2_get_vlc2(&a->gb, dc_ccp_vlc, DC_CCP_VLC_BITS);
if (ccp) {
if (ccp & 4)
block[a->permutated_scantable[1]] = (asv2_get_level(&a->gb) * a->intra_matrix[1]) >> 4;
@@ -173,7 +173,7 @@ static inline int asv2_decode_block(ASVDecContext *a, int16_t block[64])
}
for (i = 1; i < count + 1; i++) {
const int ccp = asv2_get_vlc2(&a->gb, ac_ccp_vlc.table, AC_CCP_VLC_BITS);
const int ccp = asv2_get_vlc2(&a->gb, ac_ccp_vlc, AC_CCP_VLC_BITS);
if (ccp) {
if (ccp & 8)

View File

@@ -105,8 +105,8 @@ typedef struct ATRAC9Context {
DECLARE_ALIGNED(32, float, temp)[2048];
} ATRAC9Context;
static VLC sf_vlc[2][8]; /* Signed/unsigned, length */
static VLC coeff_vlc[2][8][4]; /* Cookbook, precision, cookbook index */
static const VLCElem *sf_vlc[2][8]; /* Signed/unsigned, length */
static const VLCElem *coeff_vlc[2][8][4]; /* Cookbook, precision, cookbook index */
static inline int parse_gradient(ATRAC9Context *s, ATRAC9BlockData *b,
GetBitContext *gb)
@@ -277,12 +277,12 @@ static inline int read_scalefactors(ATRAC9Context *s, ATRAC9BlockData *b,
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 = &sf_vlc[0][len];
const VLCElem *tab = 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,
int val = c->scalefactors[i - 1] + get_vlc2(gb, tab,
ATRAC9_SF_VLC_BITS, 1);
c->scalefactors[i] = val & ((1 << len) - 1);
}
@@ -310,10 +310,10 @@ static inline int read_scalefactors(ATRAC9Context *s, ATRAC9BlockData *b,
const int len = get_bits(gb, 2) + 2;
const int unit_cnt = FFMIN(b->band_ext_q_unit, baseline_len);
const VLC *tab = &sf_vlc[1][len];
const VLCElem *tab = sf_vlc[1][len];
for (int i = 0; i < unit_cnt; i++) {
int dist = get_vlc2(gb, tab->table, ATRAC9_SF_VLC_BITS, 1);
int dist = get_vlc2(gb, tab, ATRAC9_SF_VLC_BITS, 1);
c->scalefactors[i] = baseline[i] + dist;
}
@@ -331,12 +331,12 @@ static inline int read_scalefactors(ATRAC9Context *s, ATRAC9BlockData *b,
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 = &sf_vlc[0][len];
const VLCElem *tab = 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,
int val = c->scalefactors[i - 1] + get_vlc2(gb, tab,
ATRAC9_SF_VLC_BITS, 1);
c->scalefactors[i] = val & ((1 << len) - 1);
}
@@ -418,12 +418,12 @@ static inline void read_coeffs_coarse(ATRAC9Context *s, ATRAC9BlockData *b,
if (prec <= max_prec) {
const int cb = c->codebookset[i];
const int cbi = at9_q_unit_to_codebookidx[i];
const VLC *tab = &coeff_vlc[cb][prec][cbi];
const VLCElem *tab = 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, ATRAC9_COEFF_VLC_BITS, 2);
uint16_t val = get_vlc2(gb, tab, ATRAC9_COEFF_VLC_BITS, 2);
for (int k = 0; k < huff->value_cnt; k++) {
coeffs[k] = sign_extend(val, huff->value_bits);
@@ -841,33 +841,31 @@ static av_cold int atrac9_decode_close(AVCodecContext *avctx)
return 0;
}
static av_cold void atrac9_init_vlc(VLC *vlc, int nb_bits, int nb_codes,
const uint8_t (**tab)[2],
unsigned *buf_offset, int offset)
static av_cold const VLCElem *atrac9_init_vlc(VLCInitState *state,
int nb_bits, int nb_codes,
const uint8_t (**tab)[2], int offset)
{
static VLCElem vlc_buf[24812];
const uint8_t (*table)[2] = *tab;
vlc->table = &vlc_buf[*buf_offset];
vlc->table_allocated = FF_ARRAY_ELEMS(vlc_buf) - *buf_offset;
ff_vlc_init_from_lengths(vlc, nb_bits, nb_codes,
&(*tab)[0][1], 2, &(*tab)[0][0], 2, 1,
offset, VLC_INIT_STATIC_OVERLONG, NULL);
*buf_offset += vlc->table_size;
*tab += nb_codes;
return ff_vlc_init_tables_from_lengths(state, nb_bits, nb_codes,
&table[0][1], 2, &table[0][0], 2, 1,
offset, 0);
}
static av_cold void atrac9_init_static(void)
{
static VLCElem vlc_buf[24812];
VLCInitState state = VLC_INIT_STATE(vlc_buf);
const uint8_t (*tab)[2];
unsigned offset = 0;
/* Unsigned scalefactor VLCs */
tab = at9_sfb_a_tab;
for (int i = 1; i < 7; i++) {
const HuffmanCodebook *hf = &at9_huffman_sf_unsigned[i];
atrac9_init_vlc(&sf_vlc[0][i], ATRAC9_SF_VLC_BITS,
hf->size, &tab, &offset, 0);
sf_vlc[0][i] = atrac9_init_vlc(&state, ATRAC9_SF_VLC_BITS,
hf->size, &tab, 0);
}
/* Signed scalefactor VLCs */
@@ -878,8 +876,8 @@ static av_cold void atrac9_init_static(void)
/* The symbols are signed integers in the range -16..15;
* the values in the source table are offset by 16 to make
* them fit into an uint8_t; the -16 reverses this shift. */
atrac9_init_vlc(&sf_vlc[1][i], ATRAC9_SF_VLC_BITS,
hf->size, &tab, &offset, -16);
sf_vlc[1][i] = atrac9_init_vlc(&state, ATRAC9_SF_VLC_BITS,
hf->size, &tab, -16);
}
/* Coefficient VLCs */
@@ -888,8 +886,8 @@ static av_cold void atrac9_init_static(void)
for (int j = 2; j < 8; j++) {
for (int k = i; k < 4; k++) {
const HuffmanCodebook *hf = &at9_huffman_coeffs[i][j][k];
atrac9_init_vlc(&coeff_vlc[i][j][k], ATRAC9_COEFF_VLC_BITS,
hf->size, &tab, &offset, 0);
coeff_vlc[i][j][k] = atrac9_init_vlc(&state, ATRAC9_COEFF_VLC_BITS,
hf->size, &tab, 0);
}
}
}

View File

@@ -46,7 +46,7 @@ FFTContext *av_fft_init(int nbits, int inverse)
{
int ret;
float scale = 1.0f;
AVTXWrapper *s = av_malloc(sizeof(*s));
AVTXWrapper *s = av_mallocz(sizeof(*s));
if (!s)
return NULL;
@@ -85,7 +85,7 @@ FFTContext *av_mdct_init(int nbits, int inverse, double scale)
{
int ret;
float scale_f = scale;
AVTXWrapper *s = av_malloc(sizeof(*s));
AVTXWrapper *s = av_mallocz(sizeof(*s));
if (!s)
return NULL;
@@ -130,6 +130,7 @@ av_cold void av_mdct_end(FFTContext *s)
{
if (s) {
AVTXWrapper *w = (AVTXWrapper *)s;
av_tx_uninit(&w->ctx2);
av_tx_uninit(&w->ctx);
av_free(w);
}
@@ -146,7 +147,7 @@ RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans)
if (trans != IDFT_C2R && trans != DFT_R2C)
return NULL;
s = av_malloc(sizeof(*s));
s = av_mallocz(sizeof(*s));
if (!s)
return NULL;
@@ -199,7 +200,7 @@ DCTContext *av_dct_init(int nbits, enum DCTTransformType inverse)
[DST_I] = AV_TX_FLOAT_DST_I,
};
AVTXWrapper *s = av_malloc(sizeof(*s));
AVTXWrapper *s = av_mallocz(sizeof(*s));
if (!s)
return NULL;

View File

@@ -50,6 +50,9 @@ static const CodedBitstreamType *const cbs_type_table[] = {
#if CONFIG_CBS_MPEG2
&ff_cbs_type_mpeg2,
#endif
#if CONFIG_CBS_VP8
&ff_cbs_type_vp8,
#endif
#if CONFIG_CBS_VP9
&ff_cbs_type_vp9,
#endif
@@ -74,6 +77,9 @@ const enum AVCodecID ff_cbs_all_codec_ids[] = {
#if CONFIG_CBS_MPEG2
AV_CODEC_ID_MPEG2VIDEO,
#endif
#if CONFIG_CBS_VP8
AV_CODEC_ID_VP8,
#endif
#if CONFIG_CBS_VP9
AV_CODEC_ID_VP9,
#endif

View File

@@ -832,6 +832,7 @@ typedef struct H266RawSliceHeader {
uint32_t sh_entry_point_offset_minus1[VVC_MAX_ENTRY_POINTS];
// derived values
uint16_t curr_subpic_idx; ///< CurrSubpicIdx
uint32_t num_entry_points; ///< NumEntryPoints
uint8_t num_ref_idx_active[2]; ///< NumRefIdxActive[]

View File

@@ -3008,7 +3008,6 @@ static int FUNC(slice_header) (CodedBitstreamContext *ctx, RWContext *rw,
const H266RefPicLists *ref_pic_lists;
int err, i;
uint8_t nal_unit_type, qp_bd_offset;
uint16_t curr_subpic_idx;
uint16_t num_slices_in_subpic;
HEADER("Slice Header");
@@ -3046,7 +3045,7 @@ static int FUNC(slice_header) (CodedBitstreamContext *ctx, RWContext *rw,
ub(sps->sps_subpic_id_len_minus1 + 1, sh_subpic_id);
for (i = 0; i <= sps->sps_num_subpics_minus1; i++) {
if (pps->sub_pic_id_val[i] == current->sh_subpic_id) {
curr_subpic_idx = i;
current->curr_subpic_idx = i;
break;
}
}
@@ -3055,10 +3054,10 @@ static int FUNC(slice_header) (CodedBitstreamContext *ctx, RWContext *rw,
return AVERROR_INVALIDDATA;
}
} else {
curr_subpic_idx = 0;
current->curr_subpic_idx = 0;
}
num_slices_in_subpic = pps->num_slices_in_subpic[curr_subpic_idx];
num_slices_in_subpic = pps->num_slices_in_subpic[current->curr_subpic_idx];
if ((pps->pps_rect_slice_flag && num_slices_in_subpic > 1) ||
(!pps->pps_rect_slice_flag && pps->num_tiles_in_pic > 1)) {
@@ -3375,7 +3374,7 @@ static int FUNC(slice_header) (CodedBitstreamContext *ctx, RWContext *rw,
if (pps->pps_rect_slice_flag) {
int width_in_tiles;
int slice_idx = current->sh_slice_address;
for (i = 0; i < curr_subpic_idx; i++) {
for (i = 0; i < current->curr_subpic_idx; i++) {
slice_idx += pps->num_slices_in_subpic[i];
}
width_in_tiles =

View File

@@ -341,6 +341,7 @@ extern const CodedBitstreamType ff_cbs_type_h265;
extern const CodedBitstreamType ff_cbs_type_h266;
extern const CodedBitstreamType ff_cbs_type_jpeg;
extern const CodedBitstreamType ff_cbs_type_mpeg2;
extern const CodedBitstreamType ff_cbs_type_vp8;
extern const CodedBitstreamType ff_cbs_type_vp9;

380
libavcodec/cbs_vp8.c Normal file
View File

@@ -0,0 +1,380 @@
/*
* 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_vp8.h"
#include <stdbool.h>
#define DEFAULT_PROB 0x80
// The probability table is defined in 'vp8data.c'.
extern const uint8_t ff_vp8_token_update_probs[4][8][3][11];
// Implements VP8 boolean decoder using GetBitContext to read the bitstream.
typedef struct CBSVP8BoolDecoder {
GetBitContext *gbc;
uint8_t value;
uint8_t range;
uint8_t count; // Store the number of bits in the `value` buffer.
} CBSVP8BoolDecoder;
static int cbs_vp8_bool_decoder_init(CBSVP8BoolDecoder *decoder, GetBitContext *gbc)
{
av_assert0(decoder);
av_assert0(gbc);
decoder->gbc = gbc;
decoder->value = 0;
decoder->range = 255;
decoder->count = 0;
return 0;
}
static bool cbs_vp8_bool_decoder_fill_value(CBSVP8BoolDecoder *decoder)
{
int bits = 8 - decoder->count;
av_assert0(decoder->count <= 8);
if (decoder->count == 8) {
return true;
}
if (get_bits_left(decoder->gbc) >= bits) {
decoder->value |= get_bits(decoder->gbc, bits);
decoder->count += bits;
}
return (decoder->count == 8);
}
static int cbs_vp8_bool_decoder_read_bool(CBSVP8BoolDecoder *decoder,
const uint8_t prob, uint8_t *output)
{
uint8_t split = 1 + (((decoder->range - 1) * prob) >> 8);
if (!cbs_vp8_bool_decoder_fill_value(decoder)) {
return AVERROR_INVALIDDATA;
}
av_assert0(decoder->count == 8);
if (decoder->value >= split) {
*output = 1;
decoder->range -= split;
decoder->value -= split;
} else {
*output = 0;
decoder->range = split;
}
while (decoder->range < 128) {
decoder->value <<= 1;
decoder->range <<= 1;
--decoder->count;
}
return 0;
}
static int cbs_vp8_bool_decoder_read_literal(CBSVP8BoolDecoder *decoder,
const uint8_t prob,
uint32_t num_bits,
uint32_t *output)
{
int ret = 0;
av_assert0(num_bits <= 32);
*output = 0;
for (; num_bits > 0; --num_bits) {
uint8_t bit_output = 0;
if ((ret = cbs_vp8_bool_decoder_read_bool(decoder, prob,
&bit_output)) != 0) {
return ret;
}
*output = (*output << 1) | bit_output;
}
return 0;
}
static int cbs_vp8_bool_decoder_read_unsigned(
CodedBitstreamContext *ctx, CBSVP8BoolDecoder *bool_decoder, int width,
uint8_t prob, const char *name, const int *subscripts, uint32_t *write_to,
bool trace_enable)
{
int ret = 0;
GetBitContext *gbc = bool_decoder->gbc;
uint32_t value;
CBS_TRACE_READ_START();
av_assert0(width >= 0 && width <= 8);
ret = cbs_vp8_bool_decoder_read_literal(bool_decoder, prob, width, &value);
if (ret != 0) {
return ret;
}
if (trace_enable) {
CBS_TRACE_READ_END();
}
*write_to = value;
return 0;
}
static int cbs_vp8_bool_decoder_read_signed(
CodedBitstreamContext *ctx, CBSVP8BoolDecoder *bool_decoder, int width,
uint8_t prob, const char *name, const int *subscripts, int32_t *write_to)
{
int ret = 0;
GetBitContext *gbc = bool_decoder->gbc;
int32_t value;
uint8_t sign = 0;
CBS_TRACE_READ_START();
av_assert0(width >= 0 && width <= 8);
ret = cbs_vp8_bool_decoder_read_literal(bool_decoder, prob, width, &value);
if (ret != 0) {
return ret;
}
ret = cbs_vp8_bool_decoder_read_bool(bool_decoder, prob, &sign);
if (ret != 0) {
return ret;
}
if (sign) {
value = -value;
}
CBS_TRACE_READ_END();
*write_to = value;
return 0;
}
static int cbs_vp8_read_unsigned_le(CodedBitstreamContext *ctx, GetBitContext *gbc,
int width, const char *name,
const int *subscripts, uint32_t *write_to)
{
int32_t value;
CBS_TRACE_READ_START();
av_assert0(width > 0 && width <= 24);
if (get_bits_left(gbc) < width) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value: bitstream ended.\n");
return AVERROR_INVALIDDATA;
}
value = get_bits_le(gbc, width);
CBS_TRACE_READ_END();
*write_to = value;
return 0;
}
#define HEADER(name) \
do { \
ff_cbs_trace_header(ctx, name); \
} while (0)
#define CHECK(call) \
do { \
int err = (call); \
if (err < 0) \
return err; \
} while (0)
#define FUNC_NAME(rw, codec, name) cbs_##codec##_##rw##_##name
#define FUNC_VP8(rw, name) FUNC_NAME(rw, vp8, name)
#define FUNC(name) FUNC_VP8(READWRITE, name)
#define SUBSCRIPTS(subs, ...) \
(subs > 0 ? ((int[subs + 1]){subs, __VA_ARGS__}) : NULL)
#define f(width, name) xf(width, name, 0)
// bool [de|en]coder methods.
#define bc_f(width, name) bc_unsigned_subs(width, DEFAULT_PROB, true, name, 0)
#define bc_s(width, name) bc_signed_subs(width, DEFAULT_PROB, name, 0)
#define bc_fs(width, name, subs, ...) \
bc_unsigned_subs(width, DEFAULT_PROB, true, name, subs, __VA_ARGS__)
#define bc_ss(width, name, subs, ...) \
bc_signed_subs(width, DEFAULT_PROB, name, subs, __VA_ARGS__)
// bool [de|en]coder methods for boolean value and disable tracing.
#define bc_b(name) bc_unsigned_subs(1, DEFAULT_PROB, false, name, 0)
#define bc_b_prob(prob, name) bc_unsigned_subs(1, prob, false, name, 0)
#define READ
#define READWRITE read
#define RWContext GetBitContext
#define CBSVP8BoolCodingRW CBSVP8BoolDecoder
#define xf(width, name, subs, ...) \
do { \
uint32_t value; \
CHECK(cbs_vp8_read_unsigned_le(ctx, rw, width, #name, \
SUBSCRIPTS(subs, __VA_ARGS__), &value)); \
current->name = value; \
} while (0)
#define fixed(width, name, value) \
do { \
uint32_t fixed_value; \
CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, 0, &fixed_value, \
value, value)); \
} while (0)
#define bc_unsigned_subs(width, prob, enable_trace, name, subs, ...) \
do { \
uint32_t value; \
CHECK(cbs_vp8_bool_decoder_read_unsigned( \
ctx, bool_coding_rw, width, prob, #name, \
SUBSCRIPTS(subs, __VA_ARGS__), &value, enable_trace)); \
current->name = value; \
} while (0)
#define bc_signed_subs(width, prob, name, subs, ...) \
do { \
int32_t value; \
CHECK(cbs_vp8_bool_decoder_read_signed( \
ctx, bool_coding_rw, width, prob, #name, \
SUBSCRIPTS(subs, __VA_ARGS__), &value)); \
current->name = value; \
} while (0)
#include "cbs_vp8_syntax_template.c"
static int cbs_vp8_split_fragment(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag, int header)
{
int err;
if (frag->data_size == 0)
return AVERROR_INVALIDDATA;
err = ff_cbs_append_unit_data(frag, 0, frag->data, frag->data_size,
frag->data_ref);
if (err < 0)
return err;
return 0;
}
static int cbs_vp8_read_unit(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit)
{
VP8RawFrame *frame;
GetBitContext gbc;
CBSVP8BoolDecoder bool_decoder;
int err, pos;
err = ff_cbs_alloc_unit_content(ctx, unit);
if (err < 0)
return err;
frame = unit->content;
// Create GetBitContext for uncompressed header.
err = init_get_bits8_le(&gbc, unit->data, 8 * unit->data_size);
if (err < 0)
return err;
err = cbs_vp8_read_uncompressed_header(ctx, &gbc, frame);
if (err < 0)
return err;
pos = get_bits_count(&gbc);
av_assert0(pos % 8 == 0);
// Create boolean decoder for compressed header.
err = cbs_vp8_bool_decoder_init(&bool_decoder, &gbc);
if (err < 0)
return err;
err = cbs_vp8_read_compressed_header(ctx, &bool_decoder, frame);
if (err < 0)
return err;
pos = get_bits_count(&gbc);
pos /= 8;
av_assert0(pos <= unit->data_size);
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_vp8_write_unit(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit, PutBitContext *pbc)
{
return AVERROR_PATCHWELCOME;
}
static int cbs_vp8_assemble_fragment(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag)
{
return AVERROR_PATCHWELCOME;
}
static void cbs_vp8_flush(CodedBitstreamContext *ctx)
{
// Do nothing.
}
static const CodedBitstreamUnitTypeDescriptor cbs_vp8_unit_types[] = {
CBS_UNIT_TYPE_INTERNAL_REF(0, VP8RawFrame, data),
CBS_UNIT_TYPE_END_OF_LIST,
};
const CodedBitstreamType ff_cbs_type_vp8 = {
.codec_id = AV_CODEC_ID_VP8,
.priv_data_size = 0,
.unit_types = cbs_vp8_unit_types,
.split_fragment = &cbs_vp8_split_fragment,
.read_unit = &cbs_vp8_read_unit,
.write_unit = &cbs_vp8_write_unit,
.flush = &cbs_vp8_flush,
.assemble_fragment = &cbs_vp8_assemble_fragment,
};

133
libavcodec/cbs_vp8.h Normal file
View File

@@ -0,0 +1,133 @@
/*
* 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_VP8_H
#define AVCODEC_CBS_VP8_H
#include <stddef.h>
#include <stdint.h>
#include "cbs.h"
enum {
VP8_START_CODE_0 = 0x9D,
VP8_START_CODE_1 = 0x01,
VP8_START_CODE_2 = 0x2A,
};
enum {
VP8_KEY_FRAME = 0,
VP8_NON_KEY_FRAME = 1,
};
typedef struct VP8RawFrameHeader {
// frame tag
uint8_t frame_type;
uint8_t profile;
uint8_t show_frame;
uint32_t first_partition_length_in_bytes;
uint16_t width;
uint8_t horizontal_scale;
uint16_t height;
uint8_t vertical_scale;
// frame header
uint8_t color_space;
uint8_t clamping_type;
// segmentation
uint8_t segmentation_enable;
uint8_t update_segment_map;
uint8_t update_segment_feature_data;
uint8_t segment_feature_mode;
uint8_t segment_qp_update[4];
int8_t segment_qp[4];
uint8_t segment_loop_filter_level_update[4];
int8_t segment_loop_filter_level[4];
uint8_t segment_probs_update[3];
uint8_t segment_probs[3];
// loop filter
uint8_t loop_filter_type;
uint8_t loop_filter_level;
uint8_t loop_filter_sharpness;
uint8_t mode_ref_lf_delta_enable;
uint8_t mode_ref_lf_delta_update;
uint8_t ref_lf_deltas_update[4];
int8_t ref_lf_deltas[4];
uint8_t mode_lf_deltas_update[4];
int8_t mode_lf_deltas[4];
uint8_t log2_token_partitions;
// qp
uint8_t base_qindex;
uint8_t y1dc_delta_q_present;
int8_t y1dc_delta_q;
uint8_t y2dc_delta_q_present;
int8_t y2dc_delta_q;
uint8_t y2ac_delta_q_present;
int8_t y2ac_delta_q;
uint8_t uvdc_delta_q_present;
int8_t uvdc_delta_q;
uint8_t uvac_delta_q_present;
int8_t uvac_delta_q;
// ref
uint8_t refresh_golden_frame;
uint8_t refresh_alternate_frame;
uint8_t copy_buffer_to_golden;
uint8_t copy_buffer_to_alternate;
uint8_t ref_frame_sign_bias_golden;
uint8_t ref_frame_sign_bias_alternate;
uint8_t refresh_last_frame;
uint8_t refresh_entropy_probs;
// token probs
uint8_t coeff_prob_update[4][8][3][11];
uint8_t coeff_prob[4][8][3][11];
uint8_t mb_no_skip_coeff;
uint8_t prob_skip_false;
uint8_t prob_intra;
uint8_t prob_last;
uint8_t prob_golden;
uint8_t intra_16x16_prob_update;
uint8_t intra_16x16_prob[4];
uint8_t intra_chrome_prob_update;
uint8_t intra_chrome_prob[3];
// mv probs
uint8_t mv_prob_update[2][19];
uint8_t mv_prob[2][19];
} VP8RawFrameHeader;
typedef struct VP8RawFrame {
VP8RawFrameHeader header;
uint8_t *data;
AVBufferRef *data_ref;
size_t data_size;
} VP8RawFrame;
#endif /* AVCODEC_CBS_VP8_H */

View File

@@ -0,0 +1,248 @@
/*
* 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(update_segmentation)(CodedBitstreamContext *ctx,
CBSVP8BoolCodingRW *bool_coding_rw,
VP8RawFrameHeader *current)
{
bc_f(1, update_segment_map);
bc_f(1, update_segment_feature_data);
if (current->update_segment_feature_data) {
bc_f(1, segment_feature_mode);
// quantizer
for (int i = 0; i < 4; i++) {
bc_b(segment_qp_update[i]);
if (current->segment_qp_update[i])
bc_ss(7, segment_qp[i], 1, i);
}
// loop filter
for (int i = 0; i < 4; i++) {
bc_b(segment_loop_filter_level_update[i]);
if (current->segment_loop_filter_level_update[i])
bc_ss(6, segment_loop_filter_level[i], 1, i);
}
}
if (current->update_segment_map) {
for (int i = 0; i < 3; i++) {
bc_b(segment_probs_update[i]);
if (current->segment_probs_update[i])
bc_fs(8, segment_probs[i], 1, i);
}
}
return 0;
}
static int FUNC(mode_ref_lf_deltas)(CodedBitstreamContext *ctx,
CBSVP8BoolCodingRW *bool_coding_rw,
VP8RawFrameHeader *current)
{
bc_f(1, mode_ref_lf_delta_enable);
if (current->mode_ref_lf_delta_enable) {
bc_b(mode_ref_lf_delta_update);
if (current->mode_ref_lf_delta_update) {
// ref_lf_deltas
for (int i = 0; i < 4; i++) {
bc_b(ref_lf_deltas_update[i]);
if (current->ref_lf_deltas_update[i])
bc_ss(6, ref_lf_deltas[i], 1, i);
}
// mode_lf_deltas
for (int i = 0; i < 4; i++) {
bc_b(mode_lf_deltas_update[i]);
if (current->mode_lf_deltas_update[i])
bc_ss(6, mode_lf_deltas[i], 1, i);
}
}
}
return 0;
}
static int FUNC(quantization_params)(CodedBitstreamContext *ctx,
CBSVP8BoolCodingRW *bool_coding_rw,
VP8RawFrameHeader *current)
{
bc_f(7, base_qindex);
bc_b(y1dc_delta_q_present);
if (current->y1dc_delta_q_present)
bc_s(4, y1dc_delta_q);
bc_b(y2dc_delta_q_present);
if (current->y2dc_delta_q_present)
bc_s(4, y2dc_delta_q);
bc_b(y2ac_delta_q_present);
if (current->y2ac_delta_q_present)
bc_s(4, y2ac_delta_q);
bc_b(uvdc_delta_q_present);
if (current->uvdc_delta_q_present)
bc_s(4, uvdc_delta_q);
bc_b(uvac_delta_q_present);
if (current->uvac_delta_q_present)
bc_s(4, uvac_delta_q);
return 0;
}
static int FUNC(update_token_probs)(CodedBitstreamContext *ctx,
CBSVP8BoolCodingRW *bool_coding_rw,
VP8RawFrameHeader *current)
{
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 8; ++j) {
for (int k = 0; k < 3; ++k) {
for (int l = 0; l < 11; ++l) {
bc_b_prob(ff_vp8_token_update_probs[i][j][k][l],
coeff_prob_update[i][j][k][l]);
if (current->coeff_prob_update[i][j][k][l])
bc_fs(8, coeff_prob[i][j][k][l], 4, i, j, k, l);
}
}
}
}
return 0;
}
static int FUNC(update_mv_probs)(CodedBitstreamContext *ctx,
CBSVP8BoolCodingRW *bool_coding_rw,
VP8RawFrameHeader *current)
{
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 19; ++j) {
bc_b(mv_prob_update[i][j]);
if (current->mv_prob_update[i][j])
bc_fs(7, mv_prob[i][j], 2, i, j);
}
}
return 0;
}
static int FUNC(frame_tag)(CodedBitstreamContext *ctx, RWContext *rw,
VP8RawFrameHeader *current)
{
f(1, frame_type);
f(3, profile);
f(1, show_frame);
f(19, first_partition_length_in_bytes);
if (current->frame_type == VP8_KEY_FRAME) {
fixed(8, start_code_0, VP8_START_CODE_0);
fixed(8, start_code_1, VP8_START_CODE_1);
fixed(8, start_code_2, VP8_START_CODE_2);
f(14, width);
f(2, horizontal_scale);
f(14, height);
f(2, vertical_scale);
}
return 0;
}
static int FUNC(frame_header)(CodedBitstreamContext *ctx,
CBSVP8BoolCodingRW *bool_coding_rw,
VP8RawFrameHeader *current)
{
if (current->frame_type == VP8_KEY_FRAME) {
bc_f(1, color_space);
bc_f(1, clamping_type);
}
bc_f(1, segmentation_enable);
if (current->segmentation_enable)
CHECK(FUNC(update_segmentation)(ctx, bool_coding_rw, current));
bc_f(1, loop_filter_type);
bc_f(6, loop_filter_level);
bc_f(3, loop_filter_sharpness);
CHECK(FUNC(mode_ref_lf_deltas)(ctx, bool_coding_rw, current));
bc_f(2, log2_token_partitions);
CHECK(FUNC(quantization_params)(ctx, bool_coding_rw, current));
if (current->frame_type != VP8_KEY_FRAME) {
bc_f(1, refresh_golden_frame);
bc_f(1, refresh_alternate_frame);
if (!current->refresh_golden_frame)
bc_f(2, copy_buffer_to_golden);
if (!current->refresh_alternate_frame)
bc_f(2, copy_buffer_to_alternate);
bc_f(1, ref_frame_sign_bias_golden);
bc_f(1, ref_frame_sign_bias_alternate);
}
bc_f(1, refresh_entropy_probs);
if (current->frame_type != VP8_KEY_FRAME)
bc_f(1, refresh_last_frame);
CHECK(FUNC(update_token_probs)(ctx, bool_coding_rw, current));
bc_f(1, mb_no_skip_coeff);
if (current->mb_no_skip_coeff)
bc_f(8, prob_skip_false);
if (current->frame_type != VP8_KEY_FRAME) {
bc_f(8, prob_intra);
bc_f(8, prob_last);
bc_f(8, prob_golden);
// intra_16x16_prob
bc_b(intra_16x16_prob_update);
if (current->intra_16x16_prob_update)
for (int i = 0; i < 4; i++)
bc_fs(8, intra_16x16_prob[i], 1, i);
// intra_chroma_prob
bc_b(intra_chrome_prob_update);
if (current->intra_chrome_prob_update)
for (int i = 0; i < 3; i++)
bc_fs(8, intra_chrome_prob[i], 1, i);
CHECK(FUNC(update_mv_probs)(ctx, bool_coding_rw, current));
}
return 0;
}
static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw,
VP8RawFrame *current)
{
HEADER("Frame");
CHECK(FUNC(frame_tag)(ctx, rw, &current->header));
return 0;
}
static int FUNC(compressed_header)(CodedBitstreamContext *ctx,
CBSVP8BoolCodingRW *bool_coding_rw,
VP8RawFrame *current)
{
CHECK(FUNC(frame_header)(ctx, bool_coding_rw, &current->header));
return 0;
}

View File

@@ -39,9 +39,9 @@
#define CLV_VLC_BITS 9
typedef struct LevelCodes {
VLC flags_cb;
VLC mv_cb;
VLC bias_cb;
const VLCElem *flags_cb;
const VLCElem *mv_cb;
const VLCElem *bias_cb;
} LevelCodes;
typedef struct MV {
@@ -75,9 +75,8 @@ typedef struct CLVContext {
int top_dc[3], left_dc[4];
} CLVContext;
static VLC dc_vlc, ac_vlc;
static VLCElem dc_vlc[1104], ac_vlc[554];
static LevelCodes lev[4 + 3 + 3]; // 0..3: Y, 4..6: U, 7..9: V
static VLCElem vlc_buf[16716];
static inline int decode_block(CLVContext *ctx, int16_t *blk, int has_ac,
int ac_quant)
@@ -86,13 +85,13 @@ static inline int decode_block(CLVContext *ctx, int16_t *blk, int has_ac,
int idx = 1, last = 0, val, skip;
memset(blk, 0, sizeof(*blk) * 64);
blk[0] = get_vlc2(gb, dc_vlc.table, CLV_VLC_BITS, 3);
blk[0] = get_vlc2(gb, dc_vlc, CLV_VLC_BITS, 3);
if (!has_ac)
return 0;
while (idx < 64 && !last) {
val = get_vlc2(gb, ac_vlc.table, CLV_VLC_BITS, 2);
val = get_vlc2(gb, ac_vlc, CLV_VLC_BITS, 2);
if (val < 0)
return AVERROR_INVALIDDATA;
if (val != 0x1BFF) {
@@ -387,11 +386,11 @@ static int decode_tile(AVCodecContext *avctx, GetBitContext *gb,
MV mv = { 0 };
int err;
if (lc->flags_cb.table)
flags = get_vlc2(gb, lc->flags_cb.table, CLV_VLC_BITS, 2);
if (lc->flags_cb)
flags = get_vlc2(gb, lc->flags_cb, CLV_VLC_BITS, 2);
if (lc->mv_cb.table) {
uint16_t mv_code = get_vlc2(gb, lc->mv_cb.table, CLV_VLC_BITS, 2);
if (lc->mv_cb) {
uint16_t mv_code = get_vlc2(gb, lc->mv_cb, CLV_VLC_BITS, 2);
if (mv_code != MV_ESC) {
mv.x = (int8_t)(mv_code & 0xff);
@@ -406,8 +405,8 @@ static int decode_tile(AVCodecContext *avctx, GetBitContext *gb,
mv.x += root_mv.x;
mv.y += root_mv.y;
if (lc->bias_cb.table) {
uint16_t bias_val = get_vlc2(gb, lc->bias_cb.table, CLV_VLC_BITS, 2);
if (lc->bias_cb) {
uint16_t bias_val = get_vlc2(gb, lc->bias_cb, CLV_VLC_BITS, 2);
if (bias_val != BIAS_ESC) {
bias = (int16_t)(bias_val);
@@ -622,10 +621,12 @@ static int clv_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
return mb_ret < 0 ? mb_ret : buf_size;
}
static av_cold void build_vlc(VLC *vlc, const uint8_t counts[16],
const uint16_t **syms, unsigned *offset)
static av_cold const VLCElem *build_vlc(VLCInitState *state,
const uint8_t counts[16],
const uint16_t **syms)
{
uint8_t lens[MAX_VLC_ENTRIES];
const uint16_t *symbols = *syms;
unsigned num = 0;
for (int i = 0; i < 16; i++) {
@@ -635,42 +636,39 @@ static av_cold void build_vlc(VLC *vlc, const uint8_t counts[16],
for (count += num; num < count; num++)
lens[num] = i + 1;
}
vlc->table = &vlc_buf[*offset];
vlc->table_allocated = FF_ARRAY_ELEMS(vlc_buf) - *offset;
ff_vlc_init_from_lengths(vlc, CLV_VLC_BITS, num, lens, 1,
*syms, 2, 2, 0, VLC_INIT_STATIC_OVERLONG, NULL);
*syms += num;
*offset += vlc->table_size;
return ff_vlc_init_tables_from_lengths(state, CLV_VLC_BITS, num, lens, 1,
symbols, 2, 2, 0, 0);
}
static av_cold void clv_init_static(void)
{
static VLCElem vlc_buf[16716];
VLCInitState state = VLC_INIT_STATE(vlc_buf);
const uint16_t *mv_syms = clv_mv_syms, *bias_syms = clv_bias_syms;
VLC_INIT_STATIC_FROM_LENGTHS(&dc_vlc, CLV_VLC_BITS, NUM_DC_CODES,
clv_dc_lens, 1,
clv_dc_syms, 1, 1, -63, 0, 1104);
VLC_INIT_STATIC_FROM_LENGTHS(&ac_vlc, CLV_VLC_BITS, NUM_AC_CODES,
clv_ac_bits, 1,
clv_ac_syms, 2, 2, 0, 0, 554);
for (unsigned i = 0, j = 0, k = 0, offset = 0;; i++) {
VLC_INIT_STATIC_TABLE_FROM_LENGTHS(dc_vlc, CLV_VLC_BITS, NUM_DC_CODES,
clv_dc_lens, 1,
clv_dc_syms, 1, 1, -63, 0);
VLC_INIT_STATIC_TABLE_FROM_LENGTHS(ac_vlc, CLV_VLC_BITS, NUM_AC_CODES,
clv_ac_bits, 1,
clv_ac_syms, 2, 2, 0, 0);
for (unsigned i = 0, j = 0, k = 0;; i++) {
if (0x36F & (1 << i)) {
build_vlc(&lev[i].mv_cb, clv_mv_len_counts[k], &mv_syms, &offset);
lev[i].mv_cb = build_vlc(&state, clv_mv_len_counts[k], &mv_syms);
k++;
}
if (i == FF_ARRAY_ELEMS(lev) - 1)
break;
if (0x1B7 & (1 << i)) {
lev[i].flags_cb.table = &vlc_buf[offset];
lev[i].flags_cb.table_allocated = FF_ARRAY_ELEMS(vlc_buf) - offset;
ff_vlc_init_from_lengths(&lev[i].flags_cb, CLV_VLC_BITS, 16,
clv_flags_bits[j], 1,
clv_flags_syms[j], 1, 1,
0, VLC_INIT_STATIC_OVERLONG, NULL);
offset += lev[i].flags_cb.table_size;
lev[i].flags_cb =
ff_vlc_init_tables_from_lengths(&state, CLV_VLC_BITS, 16,
clv_flags_bits[j], 1,
clv_flags_syms[j], 1, 1,
0, 0);
build_vlc(&lev[i + 1].bias_cb, clv_bias_len_counts[j],
&bias_syms, &offset);
lev[i + 1].bias_cb = build_vlc(&state, clv_bias_len_counts[j],
&bias_syms);
j++;
}
}

View File

@@ -1960,6 +1960,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("vMix Video"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
},
{
.id = AV_CODEC_ID_LEAD,
.type = AVMEDIA_TYPE_VIDEO,
.name = "lead",
.long_name = NULL_IF_CONFIG_SMALL("LEAD MCMP"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
},
/* various PCM "codecs" */
{

View File

@@ -324,6 +324,7 @@ enum AVCodecID {
AV_CODEC_ID_EVC,
AV_CODEC_ID_RTV1,
AV_CODEC_ID_VMIX,
AV_CODEC_ID_LEAD,
/* various PCM "codecs" */
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs

View File

@@ -219,6 +219,9 @@ typedef struct AVCodecParameters {
/**
* Additional data associated with the entire stream.
*
* Should be allocated with av_packet_side_data_new() or
* av_packet_side_data_add(), and will be freed by avcodec_parameters_free().
*/
AVPacketSideData *coded_side_data;

View File

@@ -40,10 +40,20 @@ static void reorder_pixels_scalar(uint8_t *dst, const uint8_t *src, ptrdiff_t si
static void predictor_scalar(uint8_t *src, ptrdiff_t size)
{
ptrdiff_t i;
/* Unrolled: `src[i + 1] += src[i] - 128;` */
if ((size & 1) == 0) {
src[1] += src[0] ^ 0x80;
src++;
size--;
}
for (i = 1; i < size; i++)
src[i] += src[i-1] - 128;
for (ptrdiff_t i = 1; i < size; i += 2) {
uint8_t a = src[i] + src[i - 1];
src[i] = a;
src[i + 1] += a;
src[i] ^= 0x80;
}
}
av_cold void ff_exrdsp_init(ExrDSPContext *c)

View File

@@ -95,28 +95,24 @@ static const uint8_t ccitt_group3_2d_lens[11] = {
4, 3, 7, 6, 3, 1, 3, 6, 7, 7, 9
};
static VLC ccitt_vlc[2], ccitt_group3_2d_vlc;
// Also contains the other VLC tables pointed to by ccitt_vlc
static VLCElem ccitt_group3_2d_vlc[512 + 528 + 648];
static const VLCElem *ccitt_vlc[2];
static av_cold void ccitt_unpack_init(void)
{
static VLCElem code_table1[528];
static VLCElem code_table2[648];
VLCInitState state = VLC_INIT_STATE(ccitt_group3_2d_vlc);
int i;
ccitt_vlc[0].table = code_table1;
ccitt_vlc[0].table_allocated = 528;
ccitt_vlc[1].table = code_table2;
ccitt_vlc[1].table_allocated = 648;
ff_vlc_init_tables(&state, 9, 11,
ccitt_group3_2d_lens, 1, 1,
ccitt_group3_2d_bits, 1, 1, 0);
for (i = 0; i < 2; i++) {
ff_vlc_init_sparse(&ccitt_vlc[i], 9, CCITT_SYMS,
ccitt_codes_lens[i], 1, 1,
ccitt_codes_bits[i], 1, 1,
ccitt_syms, 2, 2,
VLC_INIT_USE_STATIC);
ccitt_vlc[i] = ff_vlc_init_tables_sparse(&state, 9, CCITT_SYMS,
ccitt_codes_lens[i], 1, 1,
ccitt_codes_bits[i], 1, 1,
ccitt_syms, 2, 2, 0);
}
VLC_INIT_STATIC(&ccitt_group3_2d_vlc, 9, 11,
ccitt_group3_2d_lens, 1, 1,
ccitt_group3_2d_bits, 1, 1, 512);
}
av_cold void ff_ccitt_unpack_init(void)
@@ -213,7 +209,7 @@ static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb,
for (;;) {
if (get_bits_left(gb) <= 0)
return AVERROR_INVALIDDATA;
t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2);
t = get_vlc2(gb, ccitt_vlc[mode], 9, 2);
run += t;
if (t < 64) {
*runs++ = run;
@@ -261,7 +257,7 @@ static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb,
int cmode;
if (get_bits_left(gb) <= 0)
return AVERROR_INVALIDDATA;
cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1);
cmode = get_vlc2(gb, ccitt_group3_2d_vlc, 9, 1);
if (cmode == -1) {
av_log(avctx, AV_LOG_ERROR, "Incorrect mode VLC\n");
return AVERROR_INVALIDDATA;
@@ -285,7 +281,7 @@ static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb,
for (;;) {
if (get_bits_left(gb) <= 0)
return AVERROR_INVALIDDATA;
t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2);
t = get_vlc2(gb, ccitt_vlc[mode], 9, 2);
if (t == -1) {
av_log(avctx, AV_LOG_ERROR, "Incorrect code\n");
return AVERROR_INVALIDDATA;

View File

@@ -121,6 +121,8 @@ av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int cha
#if ARCH_ARM
ff_flacdsp_init_arm(c, fmt, channels);
#elif ARCH_RISCV
ff_flacdsp_init_riscv(c, fmt, channels);
#elif ARCH_X86
ff_flacdsp_init_x86(c, fmt, channels);
#endif

View File

@@ -38,6 +38,7 @@ typedef struct FLACDSPContext {
void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int channels);
void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt, int channels);
void ff_flacdsp_init_riscv(FLACDSPContext *c, enum AVSampleFormat fmt, int channels);
void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int channels);
#endif /* AVCODEC_FLACDSP_H */

View File

@@ -67,6 +67,17 @@ static int gif_find_frame_end(GIFParseContext *g, const uint8_t *buf,
g->state = GIF_EXTENSION;
g->found_start = pc->frame_start_found = 1;
} else if (buf[index] == GIF_IMAGE_SEPARATOR) {
if (g->state != GIF_EXTENSION_BLOCK && g->found_start &&
g->found_end && g->found_sig) {
next = index;
g->found_start = pc->frame_start_found = 1;
g->found_end = 0;
g->index = 0;
g->gct_flag = 0;
g->gct_size = 0;
g->state = GIF_IMAGE;
break;
}
g->state = GIF_IMAGE;
} else if (buf[index] == GIF_TRAILER) {
g->state = 0;

View File

@@ -44,10 +44,10 @@
#define MBA_STUFFING 33
#define MBA_STARTCODE 34
static VLC h261_mba_vlc;
static VLC h261_mtype_vlc;
static VLC h261_mv_vlc;
static VLC h261_cbp_vlc;
static VLCElem h261_mba_vlc[540];
static VLCElem h261_mtype_vlc[80];
static VLCElem h261_mv_vlc[144];
static VLCElem h261_cbp_vlc[512];
typedef struct H261DecContext {
MpegEncContext s;
@@ -64,18 +64,18 @@ typedef struct H261DecContext {
static av_cold void h261_decode_init_static(void)
{
VLC_INIT_STATIC(&h261_mba_vlc, H261_MBA_VLC_BITS, 35,
ff_h261_mba_bits, 1, 1,
ff_h261_mba_code, 1, 1, 540);
VLC_INIT_STATIC(&h261_mtype_vlc, H261_MTYPE_VLC_BITS, 10,
ff_h261_mtype_bits, 1, 1,
ff_h261_mtype_code, 1, 1, 80);
VLC_INIT_STATIC(&h261_mv_vlc, H261_MV_VLC_BITS, 17,
&ff_h261_mv_tab[0][1], 2, 1,
&ff_h261_mv_tab[0][0], 2, 1, 144);
VLC_INIT_STATIC(&h261_cbp_vlc, H261_CBP_VLC_BITS, 63,
&ff_h261_cbp_tab[0][1], 2, 1,
&ff_h261_cbp_tab[0][0], 2, 1, 512);
VLC_INIT_STATIC_TABLE(h261_mba_vlc, H261_MBA_VLC_BITS, 35,
ff_h261_mba_bits, 1, 1,
ff_h261_mba_code, 1, 1, 0);
VLC_INIT_STATIC_TABLE(h261_mtype_vlc, H261_MTYPE_VLC_BITS, 10,
ff_h261_mtype_bits, 1, 1,
ff_h261_mtype_code, 1, 1, 0);
VLC_INIT_STATIC_TABLE(h261_mv_vlc, H261_MV_VLC_BITS, 17,
&ff_h261_mv_tab[0][1], 2, 1,
&ff_h261_mv_tab[0][0], 2, 1, 0);
VLC_INIT_STATIC_TABLE(h261_cbp_vlc, H261_CBP_VLC_BITS, 63,
&ff_h261_cbp_tab[0][1], 2, 1,
&ff_h261_cbp_tab[0][0], 2, 1, 0);
INIT_FIRST_VLC_RL(ff_h261_rl_tcoeff, 552);
}
@@ -253,7 +253,7 @@ static const int mvmap[17] = {
static int decode_mv_component(GetBitContext *gb, int v)
{
int mv_diff = get_vlc2(gb, h261_mv_vlc.table, H261_MV_VLC_BITS, 2);
int mv_diff = get_vlc2(gb, h261_mv_vlc, H261_MV_VLC_BITS, 2);
/* check if mv_diff is valid */
if (mv_diff < 0)
@@ -378,7 +378,7 @@ static int h261_decode_mb(H261DecContext *h)
cbp = 63;
// Read mba
do {
h->mba_diff = get_vlc2(&s->gb, h261_mba_vlc.table,
h->mba_diff = get_vlc2(&s->gb, h261_mba_vlc,
H261_MBA_VLC_BITS, 2);
/* Check for slice end */
@@ -409,7 +409,7 @@ static int h261_decode_mb(H261DecContext *h)
h261_init_dest(s);
// Read mtype
com->mtype = get_vlc2(&s->gb, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2);
com->mtype = get_vlc2(&s->gb, h261_mtype_vlc, H261_MTYPE_VLC_BITS, 2);
if (com->mtype < 0) {
av_log(s->avctx, AV_LOG_ERROR, "Invalid mtype index %d\n",
com->mtype);
@@ -449,7 +449,7 @@ static int h261_decode_mb(H261DecContext *h)
// Read cbp
if (HAS_CBP(com->mtype))
cbp = get_vlc2(&s->gb, h261_cbp_vlc.table, H261_CBP_VLC_BITS, 1) + 1;
cbp = get_vlc2(&s->gb, h261_cbp_vlc, H261_CBP_VLC_BITS, 1) + 1;
if (s->mb_intra) {
s->current_picture.mb_type[xy] = MB_TYPE_INTRA;

View File

@@ -33,10 +33,10 @@
#define CBPY_VLC_BITS 6
#define TEX_VLC_BITS 9
extern VLC ff_h263_intra_MCBPC_vlc;
extern VLC ff_h263_inter_MCBPC_vlc;
extern VLC ff_h263_cbpy_vlc;
extern VLC ff_h263_mv_vlc;
extern VLCElem ff_h263_intra_MCBPC_vlc[];
extern VLCElem ff_h263_inter_MCBPC_vlc[];
extern VLCElem ff_h263_cbpy_vlc[];
extern VLCElem ff_h263_mv_vlc[];
extern const enum AVPixelFormat ff_h263_hwaccel_pixfmt_list_420[];

View File

@@ -234,38 +234,6 @@ static const uint8_t run_bits[7][16]={
{7,6,5,4,3,2,1,1,1,1,1,1,1,1,1},
};
static VLC coeff_token_vlc[4];
static VLCElem coeff_token_vlc_tables[520+332+280+256];
static const int coeff_token_vlc_tables_size[4]={520,332,280,256};
static VLC chroma_dc_coeff_token_vlc;
static VLCElem chroma_dc_coeff_token_vlc_table[256];
static const int chroma_dc_coeff_token_vlc_table_size = 256;
static VLC chroma422_dc_coeff_token_vlc;
static VLCElem chroma422_dc_coeff_token_vlc_table[8192];
static const int chroma422_dc_coeff_token_vlc_table_size = 8192;
static VLC total_zeros_vlc[15+1];
static VLCElem total_zeros_vlc_tables[15][512];
static const int total_zeros_vlc_tables_size = 512;
static VLC chroma_dc_total_zeros_vlc[3+1];
static VLCElem chroma_dc_total_zeros_vlc_tables[3][8];
static const int chroma_dc_total_zeros_vlc_tables_size = 8;
static VLC chroma422_dc_total_zeros_vlc[7+1];
static VLCElem chroma422_dc_total_zeros_vlc_tables[7][32];
static const int chroma422_dc_total_zeros_vlc_tables_size = 32;
static VLC run_vlc[6+1];
static VLCElem run_vlc_tables[6][8];
static const int run_vlc_tables_size = 8;
static VLC run7_vlc;
static VLCElem run7_vlc_table[96];
static const int run7_vlc_table_size = 96;
#define LEVEL_TAB_BITS 8
static int8_t cavlc_level_tab[7][1<<LEVEL_TAB_BITS][2];
@@ -278,6 +246,28 @@ static int8_t cavlc_level_tab[7][1<<LEVEL_TAB_BITS][2];
#define RUN_VLC_BITS 3
#define RUN7_VLC_BITS 6
/// 17 pointers to only four different VLCs
static const VLCElem *coeff_token_vlc[17];
static VLCElem chroma_dc_coeff_token_vlc_table[256];
static VLCElem chroma422_dc_coeff_token_vlc_table[1 << CHROMA422_DC_COEFF_TOKEN_VLC_BITS];
static const VLCElem *total_zeros_vlc[15+1];
static const VLCElem *chroma_dc_total_zeros_vlc[3+1];
static const VLCElem *chroma422_dc_total_zeros_vlc[7+1];
static const VLCElem *run_vlc[6+1];
// The other pointers to VLCElem point into this array.
static VLCElem run7_vlc_table[96 + (6 << RUN_VLC_BITS)
+ (15 << TOTAL_ZEROS_VLC_BITS)
+ (3 << CHROMA_DC_TOTAL_ZEROS_VLC_BITS)
+ (7 << CHROMA422_DC_TOTAL_ZEROS_VLC_BITS)
+ (520 + 332 + 280 + 256) /* coeff token */];
/**
* Get the predicted number of non-zero coefficients.
* @param n block index
@@ -324,84 +314,67 @@ static av_cold void init_cavlc_level_tab(void){
av_cold void ff_h264_decode_init_vlc(void)
{
int offset;
const VLCElem *coeff_token_vlc_original[4];
VLCInitState state = VLC_INIT_STATE(run7_vlc_table);
chroma_dc_coeff_token_vlc.table = chroma_dc_coeff_token_vlc_table;
chroma_dc_coeff_token_vlc.table_allocated = chroma_dc_coeff_token_vlc_table_size;
vlc_init(&chroma_dc_coeff_token_vlc, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 4*5,
&chroma_dc_coeff_token_len [0], 1, 1,
&chroma_dc_coeff_token_bits[0], 1, 1,
VLC_INIT_USE_STATIC);
VLC_INIT_STATIC_TABLE(chroma_dc_coeff_token_vlc_table,
CHROMA_DC_COEFF_TOKEN_VLC_BITS, 4 * 5,
&chroma_dc_coeff_token_len [0], 1, 1,
&chroma_dc_coeff_token_bits[0], 1, 1, 0);
chroma422_dc_coeff_token_vlc.table = chroma422_dc_coeff_token_vlc_table;
chroma422_dc_coeff_token_vlc.table_allocated = chroma422_dc_coeff_token_vlc_table_size;
vlc_init(&chroma422_dc_coeff_token_vlc, CHROMA422_DC_COEFF_TOKEN_VLC_BITS, 4*9,
&chroma422_dc_coeff_token_len [0], 1, 1,
&chroma422_dc_coeff_token_bits[0], 1, 1,
VLC_INIT_USE_STATIC);
VLC_INIT_STATIC_TABLE(chroma422_dc_coeff_token_vlc_table,
CHROMA422_DC_COEFF_TOKEN_VLC_BITS, 4 * 9,
&chroma422_dc_coeff_token_len [0], 1, 1,
&chroma422_dc_coeff_token_bits[0], 1, 1, 0);
offset = 0;
for (int i = 0; i < 4; i++) {
coeff_token_vlc[i].table = coeff_token_vlc_tables + offset;
coeff_token_vlc[i].table_allocated = coeff_token_vlc_tables_size[i];
vlc_init(&coeff_token_vlc[i], COEFF_TOKEN_VLC_BITS, 4*17,
&coeff_token_len [i][0], 1, 1,
&coeff_token_bits[i][0], 1, 1,
VLC_INIT_USE_STATIC);
offset += coeff_token_vlc_tables_size[i];
ff_vlc_init_tables(&state, RUN7_VLC_BITS, 16,
&run_len [6][0], 1, 1,
&run_bits[6][0], 1, 1, 0);
for (int i = 0; i < 6; i++) {
run_vlc[i + 1] = ff_vlc_init_tables(&state, RUN_VLC_BITS, 7,
&run_len [i][0], 1, 1,
&run_bits[i][0], 1, 1, 0);
}
for (int i = 0; i < 4; i++) {
coeff_token_vlc_original[i] =
ff_vlc_init_tables(&state, COEFF_TOKEN_VLC_BITS, 4*17,
&coeff_token_len [i][0], 1, 1,
&coeff_token_bits[i][0], 1, 1, 0);
}
for (int i = 0; i < FF_ARRAY_ELEMS(coeff_token_vlc); i++) {
static const uint8_t coeff_token_table_index[17] = {
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3
};
coeff_token_vlc[i] = coeff_token_vlc_original[coeff_token_table_index[i]];
}
/*
* This is a one time safety check to make sure that
* the packed static coeff_token_vlc table sizes
* were initialized correctly.
*/
av_assert0(offset == FF_ARRAY_ELEMS(coeff_token_vlc_tables));
for (int i = 0; i < 3; i++) {
chroma_dc_total_zeros_vlc[i + 1].table = chroma_dc_total_zeros_vlc_tables[i];
chroma_dc_total_zeros_vlc[i + 1].table_allocated = chroma_dc_total_zeros_vlc_tables_size;
vlc_init(&chroma_dc_total_zeros_vlc[i + 1],
CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 4,
&chroma_dc_total_zeros_len [i][0], 1, 1,
&chroma_dc_total_zeros_bits[i][0], 1, 1,
VLC_INIT_USE_STATIC);
chroma_dc_total_zeros_vlc[i + 1] =
ff_vlc_init_tables(&state, CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 4,
&chroma_dc_total_zeros_len [i][0], 1, 1,
&chroma_dc_total_zeros_bits[i][0], 1, 1, 0);
}
for (int i = 0; i < 7; i++) {
chroma422_dc_total_zeros_vlc[i + 1].table = chroma422_dc_total_zeros_vlc_tables[i];
chroma422_dc_total_zeros_vlc[i + 1].table_allocated = chroma422_dc_total_zeros_vlc_tables_size;
vlc_init(&chroma422_dc_total_zeros_vlc[i + 1],
CHROMA422_DC_TOTAL_ZEROS_VLC_BITS, 8,
&chroma422_dc_total_zeros_len [i][0], 1, 1,
&chroma422_dc_total_zeros_bits[i][0], 1, 1,
VLC_INIT_USE_STATIC);
chroma422_dc_total_zeros_vlc[i + 1] =
ff_vlc_init_tables(&state, CHROMA422_DC_TOTAL_ZEROS_VLC_BITS, 8,
&chroma422_dc_total_zeros_len [i][0], 1, 1,
&chroma422_dc_total_zeros_bits[i][0], 1, 1, 0);
}
for (int i = 0; i < 15; i++) {
total_zeros_vlc[i + 1].table = total_zeros_vlc_tables[i];
total_zeros_vlc[i + 1].table_allocated = total_zeros_vlc_tables_size;
vlc_init(&total_zeros_vlc[i + 1],
TOTAL_ZEROS_VLC_BITS, 16,
&total_zeros_len [i][0], 1, 1,
&total_zeros_bits[i][0], 1, 1,
VLC_INIT_USE_STATIC);
total_zeros_vlc[i + 1] =
ff_vlc_init_tables(&state, TOTAL_ZEROS_VLC_BITS, 16,
&total_zeros_len [i][0], 1, 1,
&total_zeros_bits[i][0], 1, 1, 0);
}
for (int i = 0; i < 6; i++) {
run_vlc[i + 1].table = run_vlc_tables[i];
run_vlc[i + 1].table_allocated = run_vlc_tables_size;
vlc_init(&run_vlc[i + 1],
RUN_VLC_BITS, 7,
&run_len [i][0], 1, 1,
&run_bits[i][0], 1, 1,
VLC_INIT_USE_STATIC);
}
run7_vlc.table = run7_vlc_table;
run7_vlc.table_allocated = run7_vlc_table_size;
vlc_init(&run7_vlc, RUN7_VLC_BITS, 16,
&run_len [6][0], 1, 1,
&run_bits[6][0], 1, 1,
VLC_INIT_USE_STATIC);
/*
* This is a one time safety check to make sure that
* the vlc table sizes were initialized correctly.
*/
av_assert1(state.size == 0);
init_cavlc_level_tab();
}
@@ -434,7 +407,6 @@ static int decode_residual(const H264Context *h, H264SliceContext *sl,
const uint8_t *scantable, const uint32_t *qmul,
int max_coeff)
{
static const int coeff_token_table_index[17]= {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3};
int level[16];
int zeros_left, coeff_token, total_coeff, i, trailing_ones, run_before;
@@ -442,21 +414,18 @@ static int decode_residual(const H264Context *h, H264SliceContext *sl,
if(max_coeff <= 8){
if (max_coeff == 4)
coeff_token = get_vlc2(gb, chroma_dc_coeff_token_vlc.table, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1);
coeff_token = get_vlc2(gb, chroma_dc_coeff_token_vlc_table,
CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1);
else
coeff_token = get_vlc2(gb, chroma422_dc_coeff_token_vlc.table, CHROMA422_DC_COEFF_TOKEN_VLC_BITS, 1);
total_coeff= coeff_token>>2;
coeff_token = get_vlc2(gb, chroma422_dc_coeff_token_vlc_table,
CHROMA422_DC_COEFF_TOKEN_VLC_BITS, 1);
}else{
if(n >= LUMA_DC_BLOCK_INDEX){
total_coeff= pred_non_zero_count(h, sl, (n - LUMA_DC_BLOCK_INDEX)*16);
coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2);
total_coeff= coeff_token>>2;
}else{
total_coeff= pred_non_zero_count(h, sl, n);
coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2);
total_coeff= coeff_token>>2;
}
total_coeff = pred_non_zero_count(h, sl, n >= LUMA_DC_BLOCK_INDEX ?
(n - LUMA_DC_BLOCK_INDEX) * 16 : n);
coeff_token = get_vlc2(gb, coeff_token_vlc[total_coeff],
COEFF_TOKEN_VLC_BITS, 2);
}
total_coeff = coeff_token >> 2;
sl->non_zero_count_cache[scan8[n]] = total_coeff;
//FIXME set last_non_zero?
@@ -563,13 +532,14 @@ static int decode_residual(const H264Context *h, H264SliceContext *sl,
else{
if (max_coeff <= 8) {
if (max_coeff == 4)
zeros_left = get_vlc2(gb, chroma_dc_total_zeros_vlc[total_coeff].table,
zeros_left = get_vlc2(gb, chroma_dc_total_zeros_vlc[total_coeff],
CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1);
else
zeros_left = get_vlc2(gb, chroma422_dc_total_zeros_vlc[total_coeff].table,
zeros_left = get_vlc2(gb, chroma422_dc_total_zeros_vlc[total_coeff],
CHROMA422_DC_TOTAL_ZEROS_VLC_BITS, 1);
} else {
zeros_left= get_vlc2(gb, total_zeros_vlc[ total_coeff ].table, TOTAL_ZEROS_VLC_BITS, 1);
zeros_left = get_vlc2(gb, total_zeros_vlc[total_coeff],
TOTAL_ZEROS_VLC_BITS, 1);
}
}
@@ -579,9 +549,9 @@ static int decode_residual(const H264Context *h, H264SliceContext *sl,
((type*)block)[*scantable] = level[0]; \
for(i=1;i<total_coeff && zeros_left > 0;i++) { \
if(zeros_left < 7) \
run_before= get_vlc2(gb, run_vlc[zeros_left].table, RUN_VLC_BITS, 1); \
run_before = get_vlc2(gb, run_vlc[zeros_left], RUN_VLC_BITS, 1); \
else \
run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2); \
run_before = get_vlc2(gb, run7_vlc_table, RUN7_VLC_BITS, 2); \
zeros_left -= run_before; \
scantable -= 1 + run_before; \
((type*)block)[*scantable]= level[i]; \
@@ -594,9 +564,9 @@ static int decode_residual(const H264Context *h, H264SliceContext *sl,
((type*)block)[*scantable] = ((int)(level[0] * qmul[*scantable] + 32))>>6; \
for(i=1;i<total_coeff && zeros_left > 0;i++) { \
if(zeros_left < 7) \
run_before= get_vlc2(gb, run_vlc[zeros_left].table, RUN_VLC_BITS, 1); \
run_before = get_vlc2(gb, run_vlc[zeros_left], RUN_VLC_BITS, 1); \
else \
run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2); \
run_before = get_vlc2(gb, run7_vlc_table, RUN7_VLC_BITS, 2); \
zeros_left -= run_before; \
scantable -= 1 + run_before; \
((type*)block)[*scantable]= ((int)(level[i] * qmul[*scantable] + 32))>>6; \

View File

@@ -48,29 +48,39 @@ void ff_h264_unref_picture(H264Picture *pic)
av_frame_unref(pic->f_grain);
ff_refstruct_unref(&pic->hwaccel_picture_private);
av_buffer_unref(&pic->qscale_table_buf);
av_buffer_unref(&pic->mb_type_buf);
ff_refstruct_unref(&pic->qscale_table_base);
ff_refstruct_unref(&pic->mb_type_base);
ff_refstruct_unref(&pic->pps);
for (i = 0; i < 2; i++) {
av_buffer_unref(&pic->motion_val_buf[i]);
av_buffer_unref(&pic->ref_index_buf[i]);
ff_refstruct_unref(&pic->motion_val_base[i]);
ff_refstruct_unref(&pic->ref_index[i]);
}
av_buffer_unref(&pic->decode_error_flags);
ff_refstruct_unref(&pic->decode_error_flags);
memset((uint8_t*)pic + off, 0, sizeof(*pic) - off);
}
static void h264_copy_picture_params(H264Picture *dst, const H264Picture *src)
{
ff_refstruct_replace(&dst->qscale_table_base, src->qscale_table_base);
ff_refstruct_replace(&dst->mb_type_base, src->mb_type_base);
ff_refstruct_replace(&dst->pps, src->pps);
for (int i = 0; i < 2; i++) {
ff_refstruct_replace(&dst->motion_val_base[i], src->motion_val_base[i]);
ff_refstruct_replace(&dst->ref_index[i], src->ref_index[i]);
}
ff_refstruct_replace(&dst->hwaccel_picture_private,
src->hwaccel_picture_private);
ff_refstruct_replace(&dst->decode_error_flags, src->decode_error_flags);
dst->qscale_table = src->qscale_table;
dst->mb_type = src->mb_type;
for (int i = 0; i < 2; i++) {
for (int i = 0; i < 2; i++)
dst->motion_val[i] = src->motion_val[i];
dst->ref_index[i] = src->ref_index[i];
}
for (int i = 0; i < 2; i++)
dst->field_poc[i] = src->field_poc[i];
@@ -96,7 +106,7 @@ static void h264_copy_picture_params(H264Picture *dst, const H264Picture *src)
int ff_h264_ref_picture(H264Picture *dst, const H264Picture *src)
{
int ret, i;
int ret;
av_assert0(!dst->f->buf[0]);
av_assert0(src->f->buf[0]);
@@ -113,29 +123,6 @@ int ff_h264_ref_picture(H264Picture *dst, const H264Picture *src)
goto fail;
}
dst->qscale_table_buf = av_buffer_ref(src->qscale_table_buf);
dst->mb_type_buf = av_buffer_ref(src->mb_type_buf);
if (!dst->qscale_table_buf || !dst->mb_type_buf) {
ret = AVERROR(ENOMEM);
goto fail;
}
for (i = 0; i < 2; i++) {
dst->motion_val_buf[i] = av_buffer_ref(src->motion_val_buf[i]);
dst->ref_index_buf[i] = av_buffer_ref(src->ref_index_buf[i]);
if (!dst->motion_val_buf[i] || !dst->ref_index_buf[i]) {
ret = AVERROR(ENOMEM);
goto fail;
}
}
ff_refstruct_replace(&dst->hwaccel_picture_private,
src->hwaccel_picture_private);
ret = av_buffer_replace(&dst->decode_error_flags, src->decode_error_flags);
if (ret < 0)
goto fail;
h264_copy_picture_params(dst, src);
return 0;
@@ -146,7 +133,7 @@ fail:
int ff_h264_replace_picture(H264Picture *dst, const H264Picture *src)
{
int ret, i;
int ret;
if (!src->f || !src->f->buf[0]) {
ff_h264_unref_picture(dst);
@@ -167,25 +154,6 @@ int ff_h264_replace_picture(H264Picture *dst, const H264Picture *src)
goto fail;
}
ret = av_buffer_replace(&dst->qscale_table_buf, src->qscale_table_buf);
ret |= av_buffer_replace(&dst->mb_type_buf, src->mb_type_buf);
if (ret < 0)
goto fail;
for (i = 0; i < 2; i++) {
ret = av_buffer_replace(&dst->motion_val_buf[i], src->motion_val_buf[i]);
ret |= av_buffer_replace(&dst->ref_index_buf[i], src->ref_index_buf[i]);
if (ret < 0)
goto fail;
}
ff_refstruct_replace(&dst->hwaccel_picture_private,
src->hwaccel_picture_private);
ret = av_buffer_replace(&dst->decode_error_flags, src->decode_error_flags);
if (ret < 0)
goto fail;
h264_copy_picture_params(dst, src);
return 0;

View File

@@ -165,20 +165,19 @@ static int init_table_pools(H264Context *h)
const int b4_stride = h->mb_width * 4 + 1;
const int b4_array_size = b4_stride * h->mb_height * 4;
h->qscale_table_pool = av_buffer_pool_init(big_mb_num + h->mb_stride,
av_buffer_allocz);
h->mb_type_pool = av_buffer_pool_init((big_mb_num + h->mb_stride) *
sizeof(uint32_t), av_buffer_allocz);
h->motion_val_pool = av_buffer_pool_init(2 * (b4_array_size + 4) *
sizeof(int16_t), av_buffer_allocz);
h->ref_index_pool = av_buffer_pool_init(4 * mb_array_size, av_buffer_allocz);
h->qscale_table_pool = ff_refstruct_pool_alloc(big_mb_num + h->mb_stride, 0);
h->mb_type_pool = ff_refstruct_pool_alloc((big_mb_num + h->mb_stride) *
sizeof(uint32_t), 0);
h->motion_val_pool = ff_refstruct_pool_alloc(2 * (b4_array_size + 4) *
sizeof(int16_t), 0);
h->ref_index_pool = ff_refstruct_pool_alloc(4 * mb_array_size, 0);
if (!h->qscale_table_pool || !h->mb_type_pool || !h->motion_val_pool ||
!h->ref_index_pool) {
av_buffer_pool_uninit(&h->qscale_table_pool);
av_buffer_pool_uninit(&h->mb_type_pool);
av_buffer_pool_uninit(&h->motion_val_pool);
av_buffer_pool_uninit(&h->ref_index_pool);
ff_refstruct_pool_uninit(&h->qscale_table_pool);
ff_refstruct_pool_uninit(&h->mb_type_pool);
ff_refstruct_pool_uninit(&h->motion_val_pool);
ff_refstruct_pool_uninit(&h->ref_index_pool);
return AVERROR(ENOMEM);
}
@@ -211,10 +210,10 @@ static int alloc_picture(H264Context *h, H264Picture *pic)
goto fail;
if (h->decode_error_flags_pool) {
pic->decode_error_flags = av_buffer_pool_get(h->decode_error_flags_pool);
pic->decode_error_flags = ff_refstruct_pool_get(h->decode_error_flags_pool);
if (!pic->decode_error_flags)
goto fail;
atomic_init((atomic_int*)pic->decode_error_flags->data, 0);
atomic_init(pic->decode_error_flags, 0);
}
if (CONFIG_GRAY && !h->avctx->hwaccel && h->flags & AV_CODEC_FLAG_GRAY && pic->f->data[2]) {
@@ -236,22 +235,21 @@ static int alloc_picture(H264Context *h, H264Picture *pic)
goto fail;
}
pic->qscale_table_buf = av_buffer_pool_get(h->qscale_table_pool);
pic->mb_type_buf = av_buffer_pool_get(h->mb_type_pool);
if (!pic->qscale_table_buf || !pic->mb_type_buf)
pic->qscale_table_base = ff_refstruct_pool_get(h->qscale_table_pool);
pic->mb_type_base = ff_refstruct_pool_get(h->mb_type_pool);
if (!pic->qscale_table_base || !pic->mb_type_base)
goto fail;
pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * h->mb_stride + 1;
pic->qscale_table = pic->qscale_table_buf->data + 2 * h->mb_stride + 1;
pic->mb_type = pic->mb_type_base + 2 * h->mb_stride + 1;
pic->qscale_table = pic->qscale_table_base + 2 * h->mb_stride + 1;
for (i = 0; i < 2; i++) {
pic->motion_val_buf[i] = av_buffer_pool_get(h->motion_val_pool);
pic->ref_index_buf[i] = av_buffer_pool_get(h->ref_index_pool);
if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i])
pic->motion_val_base[i] = ff_refstruct_pool_get(h->motion_val_pool);
pic->ref_index[i] = ff_refstruct_pool_get(h->ref_index_pool);
if (!pic->motion_val_base[i] || !pic->ref_index[i])
goto fail;
pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4;
pic->ref_index[i] = pic->ref_index_buf[i]->data;
pic->motion_val[i] = pic->motion_val_base[i] + 4;
}
pic->pps = ff_refstruct_ref_c(h->ps.pps);

View File

@@ -51,6 +51,7 @@
#include "mpegutils.h"
#include "profiles.h"
#include "rectangle.h"
#include "refstruct.h"
#include "thread.h"
#include "threadframe.h"
@@ -151,10 +152,10 @@ void ff_h264_free_tables(H264Context *h)
av_freep(&h->mb2b_xy);
av_freep(&h->mb2br_xy);
av_buffer_pool_uninit(&h->qscale_table_pool);
av_buffer_pool_uninit(&h->mb_type_pool);
av_buffer_pool_uninit(&h->motion_val_pool);
av_buffer_pool_uninit(&h->ref_index_pool);
ff_refstruct_pool_uninit(&h->qscale_table_pool);
ff_refstruct_pool_uninit(&h->mb_type_pool);
ff_refstruct_pool_uninit(&h->motion_val_pool);
ff_refstruct_pool_uninit(&h->ref_index_pool);
#if CONFIG_ERROR_RESILIENCE
av_freep(&h->er.mb_index2xy);
@@ -308,7 +309,7 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h)
ff_h264_sei_uninit(&h->sei);
if (avctx->active_thread_type & FF_THREAD_FRAME) {
h->decode_error_flags_pool = av_buffer_pool_init(sizeof(atomic_int), NULL);
h->decode_error_flags_pool = ff_refstruct_pool_alloc(sizeof(atomic_int), 0);
if (!h->decode_error_flags_pool)
return AVERROR(ENOMEM);
}
@@ -359,7 +360,7 @@ static av_cold int h264_decode_end(AVCodecContext *avctx)
h->cur_pic_ptr = NULL;
av_buffer_pool_uninit(&h->decode_error_flags_pool);
ff_refstruct_pool_uninit(&h->decode_error_flags_pool);
av_freep(&h->slice_ctx);
h->nb_slice_ctx = 0;
@@ -749,7 +750,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
if ((ret < 0 || h->er.error_occurred) && h->cur_pic_ptr) {
if (h->cur_pic_ptr->decode_error_flags) {
/* Frame-threading in use */
atomic_int *decode_error = (atomic_int*)h->cur_pic_ptr->decode_error_flags->data;
atomic_int *decode_error = h->cur_pic_ptr->decode_error_flags;
/* Using atomics here is not supposed to provide syncronisation;
* they are merely used to allow to set decode_error from both
* decoding threads in case of coded slices. */
@@ -800,7 +801,7 @@ end:
ff_er_frame_end(&h->er, &decode_error_flags);
if (decode_error_flags) {
if (h->cur_pic_ptr->decode_error_flags) {
atomic_int *decode_error = (atomic_int*)h->cur_pic_ptr->decode_error_flags->data;
atomic_int *decode_error = h->cur_pic_ptr->decode_error_flags;
atomic_fetch_or_explicit(decode_error, decode_error_flags,
memory_order_relaxed);
} else
@@ -878,7 +879,7 @@ static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
return ret;
if (srcp->decode_error_flags) {
atomic_int *decode_error = (atomic_int*)srcp->decode_error_flags->data;
atomic_int *decode_error = srcp->decode_error_flags;
/* The following is not supposed to provide synchronisation at all:
* given that srcp has already finished decoding, decode_error
* has already been set to its final value. */

View File

@@ -109,20 +109,19 @@ typedef struct H264Picture {
AVFrame *f_grain;
AVBufferRef *qscale_table_buf;
int8_t *qscale_table_base; ///< RefStruct reference
int8_t *qscale_table;
AVBufferRef *motion_val_buf[2];
int16_t (*motion_val_base[2])[2]; ///< RefStruct reference
int16_t (*motion_val[2])[2];
AVBufferRef *mb_type_buf;
uint32_t *mb_type_base; ///< RefStruct reference
uint32_t *mb_type;
/// RefStruct reference for hardware accelerator private data
void *hwaccel_picture_private;
AVBufferRef *ref_index_buf[2];
int8_t *ref_index[2];
int8_t *ref_index[2]; ///< RefStruct reference
int field_poc[2]; ///< top/bottom POC
int poc; ///< frame POC
@@ -153,8 +152,8 @@ typedef struct H264Picture {
int mb_width, mb_height;
int mb_stride;
/* data points to an atomic_int */
AVBufferRef *decode_error_flags;
/// RefStruct reference; its pointee is shared between decoding threads.
atomic_int *decode_error_flags;
} H264Picture;
typedef struct H264Ref {
@@ -548,11 +547,11 @@ typedef struct H264Context {
H264SEIContext sei;
AVBufferPool *qscale_table_pool;
AVBufferPool *mb_type_pool;
AVBufferPool *motion_val_pool;
AVBufferPool *ref_index_pool;
AVBufferPool *decode_error_flags_pool;
struct FFRefStructPool *qscale_table_pool;
struct FFRefStructPool *mb_type_pool;
struct FFRefStructPool *motion_val_pool;
struct FFRefStructPool *ref_index_pool;
struct FFRefStructPool *decode_error_flags_pool;
int ref2frm[MAX_SLICES][2][64]; ///< reference to frame number lists, used in the loop filter, the first 2 are for -2,-1
} H264Context;

View File

@@ -42,13 +42,11 @@ void ff_hevc_unref_frame(HEVCFrame *frame, int flags)
av_frame_unref(frame->frame_grain);
frame->needs_fg = 0;
av_buffer_unref(&frame->tab_mvf_buf);
frame->tab_mvf = NULL;
ff_refstruct_unref(&frame->tab_mvf);
ff_refstruct_unref(&frame->rpl);
frame->nb_rpl_elems = 0;
av_buffer_unref(&frame->rpl_tab_buf);
frame->rpl_tab = NULL;
ff_refstruct_unref(&frame->rpl_tab);
frame->refPicList = NULL;
ff_refstruct_unref(&frame->hwaccel_picture_private);
@@ -99,15 +97,13 @@ static HEVCFrame *alloc_frame(HEVCContext *s)
goto fail;
frame->nb_rpl_elems = s->pkt.nb_nals;
frame->tab_mvf_buf = av_buffer_pool_get(s->tab_mvf_pool);
if (!frame->tab_mvf_buf)
frame->tab_mvf = ff_refstruct_pool_get(s->tab_mvf_pool);
if (!frame->tab_mvf)
goto fail;
frame->tab_mvf = (MvField *)frame->tab_mvf_buf->data;
frame->rpl_tab_buf = av_buffer_pool_get(s->rpl_tab_pool);
if (!frame->rpl_tab_buf)
frame->rpl_tab = ff_refstruct_pool_get(s->rpl_tab_pool);
if (!frame->rpl_tab)
goto fail;
frame->rpl_tab = (RefPicListTab **)frame->rpl_tab_buf->data;
frame->ctb_count = s->ps.sps->ctb_width * s->ps.sps->ctb_height;
for (j = 0; j < frame->ctb_count; j++)
frame->rpl_tab[j] = frame->rpl;

View File

@@ -86,8 +86,8 @@ static void pic_arrays_free(HEVCContext *s)
av_freep(&s->sh.size);
av_freep(&s->sh.offset);
av_buffer_pool_uninit(&s->tab_mvf_pool);
av_buffer_pool_uninit(&s->rpl_tab_pool);
ff_refstruct_pool_uninit(&s->tab_mvf_pool);
ff_refstruct_pool_uninit(&s->rpl_tab_pool);
}
/* allocate arrays that depend on frame dimensions */
@@ -133,10 +133,8 @@ static int pic_arrays_init(HEVCContext *s, const HEVCSPS *sps)
if (!s->horizontal_bs || !s->vertical_bs)
goto fail;
s->tab_mvf_pool = av_buffer_pool_init(min_pu_size * sizeof(MvField),
av_buffer_allocz);
s->rpl_tab_pool = av_buffer_pool_init(ctb_count * sizeof(RefPicListTab),
av_buffer_allocz);
s->tab_mvf_pool = ff_refstruct_pool_alloc(min_pu_size * sizeof(MvField), 0);
s->rpl_tab_pool = ff_refstruct_pool_alloc(ctb_count * sizeof(RefPicListTab), 0);
if (!s->tab_mvf_pool || !s->rpl_tab_pool)
goto fail;
@@ -3404,16 +3402,8 @@ static int hevc_ref_frame(HEVCFrame *dst, HEVCFrame *src)
dst->needs_fg = 1;
}
dst->tab_mvf_buf = av_buffer_ref(src->tab_mvf_buf);
if (!dst->tab_mvf_buf)
goto fail;
dst->tab_mvf = src->tab_mvf;
dst->rpl_tab_buf = av_buffer_ref(src->rpl_tab_buf);
if (!dst->rpl_tab_buf)
goto fail;
dst->rpl_tab = src->rpl_tab;
dst->tab_mvf = ff_refstruct_ref(src->tab_mvf);
dst->rpl_tab = ff_refstruct_ref(src->rpl_tab);
dst->rpl = ff_refstruct_ref(src->rpl);
dst->nb_rpl_elems = src->nb_rpl_elems;
@@ -3426,9 +3416,6 @@ static int hevc_ref_frame(HEVCFrame *dst, HEVCFrame *src)
src->hwaccel_picture_private);
return 0;
fail:
ff_hevc_unref_frame(dst, ~0);
return AVERROR(ENOMEM);
}
static av_cold int hevc_decode_free(AVCodecContext *avctx)

View File

@@ -408,14 +408,12 @@ typedef struct HEVCFrame {
AVFrame *frame_grain;
ThreadFrame tf;
int needs_fg; /* 1 if grain needs to be applied by the decoder */
MvField *tab_mvf;
MvField *tab_mvf; ///< RefStruct reference
RefPicList *refPicList;
RefPicListTab **rpl_tab;
RefPicListTab **rpl_tab; ///< RefStruct reference
int ctb_count;
int poc;
AVBufferRef *tab_mvf_buf;
AVBufferRef *rpl_tab_buf;
RefPicListTab *rpl; ///< RefStruct reference
int nb_rpl_elems;
@@ -516,8 +514,8 @@ typedef struct HEVCContext {
HEVCSEI sei;
struct AVMD5 *md5_ctx;
AVBufferPool *tab_mvf_pool;
AVBufferPool *rpl_tab_pool;
struct FFRefStructPool *tab_mvf_pool;
struct FFRefStructPool *rpl_tab_pool;
///< candidate references for the current frame
RefPicList rps[5];

View File

@@ -87,7 +87,9 @@ av_cold void ff_huffyuvdsp_init(HuffYUVDSPContext *c, enum AVPixelFormat pix_fmt
c->add_hfyu_median_pred_int16 = add_hfyu_median_pred_int16_c;
c->add_hfyu_left_pred_bgr32 = add_hfyu_left_pred_bgr32_c;
#if ARCH_X86
#if ARCH_RISCV
ff_huffyuvdsp_init_riscv(c, pix_fmt);
#elif ARCH_X86
ff_huffyuvdsp_init_x86(c, pix_fmt);
#endif
}

View File

@@ -34,6 +34,8 @@ typedef struct HuffYUVDSPContext {
} HuffYUVDSPContext;
void ff_huffyuvdsp_init(HuffYUVDSPContext *c, enum AVPixelFormat pix_fmt);
void ff_huffyuvdsp_init_riscv(HuffYUVDSPContext *c,
enum AVPixelFormat pix_fmt);
void ff_huffyuvdsp_init_x86(HuffYUVDSPContext *c, enum AVPixelFormat pix_fmt);
#endif /* AVCODEC_HUFFYUVDSP_H */

View File

@@ -106,7 +106,7 @@ typedef struct IMCContext {
AVCodecContext *avctx;
} IMCContext;
static VLC huffman_vlc[4][4];
static const VLCElem *huffman_vlc[4][4];
#define IMC_VLC_BITS 9
#define VLC_TABLES_SIZE 9512
@@ -171,16 +171,15 @@ static av_cold void iac_generate_tabs(IMCContext *q, int sampling_rate)
static av_cold void imc_init_static(void)
{
VLCInitState state = VLC_INIT_STATE(vlc_tables);
/* initialize the VLC tables */
for (int i = 0, offset = 0; i < 4 ; i++) {
for (int i = 0; i < 4 ; i++) {
for (int j = 0; j < 4; j++) {
huffman_vlc[i][j].table = &vlc_tables[offset];
huffman_vlc[i][j].table_allocated = VLC_TABLES_SIZE - offset;
ff_vlc_init_from_lengths(&huffman_vlc[i][j], IMC_VLC_BITS, imc_huffman_sizes[i],
imc_huffman_lens[i][j], 1,
imc_huffman_syms[i][j], 1, 1,
0, VLC_INIT_STATIC_OVERLONG, NULL);
offset += huffman_vlc[i][j].table_size;
huffman_vlc[i][j] =
ff_vlc_init_tables_from_lengths(&state, IMC_VLC_BITS, imc_huffman_sizes[i],
imc_huffman_lens[i][j], 1,
imc_huffman_syms[i][j], 1, 1,
0, 0);
}
}
}
@@ -311,16 +310,11 @@ static void imc_read_level_coeffs(IMCContext *q, int stream_format_code,
int *levlCoeffs)
{
int i;
VLC *hufftab[4];
int start = 0;
const uint8_t *cb_sel;
int s;
int s = stream_format_code >> 1;
const VLCElem * const *const hufftab = huffman_vlc[s];
s = stream_format_code >> 1;
hufftab[0] = &huffman_vlc[s][0];
hufftab[1] = &huffman_vlc[s][1];
hufftab[2] = &huffman_vlc[s][2];
hufftab[3] = &huffman_vlc[s][3];
cb_sel = imc_cb_select[s];
if (stream_format_code & 4)
@@ -328,7 +322,7 @@ static void imc_read_level_coeffs(IMCContext *q, int stream_format_code,
if (start)
levlCoeffs[0] = get_bits(&q->gb, 7);
for (i = start; i < BANDS; i++) {
levlCoeffs[i] = get_vlc2(&q->gb, hufftab[cb_sel[i]]->table,
levlCoeffs[i] = get_vlc2(&q->gb, hufftab[cb_sel[i]],
IMC_VLC_BITS, 2);
if (levlCoeffs[i] == 17)
levlCoeffs[i] += get_bits(&q->gb, 4);

View File

@@ -108,16 +108,16 @@ static const uint8_t block_bits[] = {
6, 5, 5, 5, 4, 2, 3, 4, 4,
};
static VLC cbplo_tab;
static VLC cbphi_tab;
static VLC blktype_tab;
static VLC block_tab;
static VLCElem cbplo_tab[1 << CBPLO_VLC_BITS];
static VLCElem cbphi_tab[1 << CBPHI_VLC_BITS];
static VLCElem blktype_tab[1 << BLKTYPE_VLC_BITS];
static VLCElem block_tab[1 << BLOCK_VLC_BITS];
static int get_cbphi(GetBitContext *gb, int x)
{
int value;
value = get_vlc2(gb, cbphi_tab.table, CBPHI_VLC_BITS, 1);
value = get_vlc2(gb, cbphi_tab, CBPHI_VLC_BITS, 1);
if (value < 0)
return AVERROR_INVALIDDATA;
@@ -134,7 +134,7 @@ static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
for (i = !flag; i < 64; i++) {
int value;
value = get_vlc2(gb, block_tab.table, BLOCK_VLC_BITS, 1);
value = get_vlc2(gb, block_tab, BLOCK_VLC_BITS, 1);
if (value < 0)
return AVERROR_INVALIDDATA;
if (value == 0) {
@@ -221,7 +221,7 @@ static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame
for (x = 0; x < avctx->width; x += 16) {
unsigned flag, cbphi, cbplo;
cbplo = get_vlc2(gb, cbplo_tab.table, CBPLO_VLC_BITS, 1);
cbplo = get_vlc2(gb, cbplo_tab, CBPLO_VLC_BITS, 1);
flag = get_bits1(gb);
cbphi = get_cbphi(gb, 1);
@@ -287,7 +287,7 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
continue;
}
value = get_vlc2(gb, blktype_tab.table, BLKTYPE_VLC_BITS, 1);
value = get_vlc2(gb, blktype_tab, BLKTYPE_VLC_BITS, 1);
if (value < 0)
return AVERROR_INVALIDDATA;
@@ -473,20 +473,20 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
static av_cold void imm4_init_static_data(void)
{
VLC_INIT_STATIC_FROM_LENGTHS(&cbplo_tab, CBPLO_VLC_BITS, FF_ARRAY_ELEMS(cbplo),
&cbplo[0][1], 2, &cbplo[0][0], 2, 1,
0, 0, 1 << CBPLO_VLC_BITS);
VLC_INIT_STATIC_TABLE_FROM_LENGTHS(cbplo_tab, CBPLO_VLC_BITS, FF_ARRAY_ELEMS(cbplo),
&cbplo[0][1], 2, &cbplo[0][0], 2, 1,
0, 0);
VLC_INIT_SPARSE_STATIC(&cbphi_tab, CBPHI_VLC_BITS, FF_ARRAY_ELEMS(cbphi_bits),
cbphi_bits, 1, 1, cbphi_codes, 1, 1, NULL, 0, 0, 64);
VLC_INIT_STATIC_TABLE(cbphi_tab, CBPHI_VLC_BITS, FF_ARRAY_ELEMS(cbphi_bits),
cbphi_bits, 1, 1, cbphi_codes, 1, 1, 0);
VLC_INIT_STATIC_FROM_LENGTHS(&blktype_tab, BLKTYPE_VLC_BITS, FF_ARRAY_ELEMS(blktype),
&blktype[0][1], 2, &blktype[0][0], 2, 1,
0, 0, 1 << BLKTYPE_VLC_BITS);
VLC_INIT_STATIC_TABLE_FROM_LENGTHS(blktype_tab, BLKTYPE_VLC_BITS, FF_ARRAY_ELEMS(blktype),
&blktype[0][1], 2, &blktype[0][0], 2, 1,
0, 0);
VLC_INIT_STATIC_FROM_LENGTHS(&block_tab, BLOCK_VLC_BITS, FF_ARRAY_ELEMS(block_bits),
block_bits, 1, block_symbols, 2, 2,
0, 0, 1 << BLOCK_VLC_BITS);
VLC_INIT_STATIC_TABLE_FROM_LENGTHS(block_tab, BLOCK_VLC_BITS, FF_ARRAY_ELEMS(block_bits),
block_bits, 1, block_symbols, 2, 2,
0, 0);
}
static av_cold int decode_init(AVCodecContext *avctx)

View File

@@ -42,12 +42,12 @@ typedef struct Ir2Context{
} Ir2Context;
#define CODE_VLC_BITS 14
static VLC ir2_vlc;
static VLCElem ir2_vlc[1 << CODE_VLC_BITS];
/* Indeo 2 codes are in range 0x01..0x7F and 0x81..0x90 */
static inline int ir2_get_code(GetBitContext *gb)
{
return get_vlc2(gb, ir2_vlc.table, CODE_VLC_BITS, 1);
return get_vlc2(gb, ir2_vlc, CODE_VLC_BITS, 1);
}
static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst,
@@ -226,9 +226,9 @@ static int ir2_decode_frame(AVCodecContext *avctx, AVFrame *picture,
static av_cold void ir2_init_static(void)
{
VLC_INIT_STATIC_FROM_LENGTHS(&ir2_vlc, CODE_VLC_BITS, IR2_CODES,
&ir2_tab[0][1], 2, &ir2_tab[0][0], 2, 1,
0, VLC_INIT_OUTPUT_LE, 1 << CODE_VLC_BITS);
VLC_INIT_STATIC_TABLE_FROM_LENGTHS(ir2_vlc, CODE_VLC_BITS, IR2_CODES,
&ir2_tab[0][1], 2, &ir2_tab[0][0], 2, 1,
0, VLC_INIT_OUTPUT_LE);
}
static av_cold int ir2_decode_init(AVCodecContext *avctx)

View File

@@ -45,49 +45,43 @@
#define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
#define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS)
static VLC j_ac_vlc[2][2][8]; // [quant < 13], [intra / inter], [select]
static VLC j_dc_vlc[2][8]; // [quant], [select]
static VLC j_orient_vlc[2][4]; // [quant], [select]
static const VLCElem *j_ac_vlc[2][2][8]; // [quant < 13], [intra / inter], [select]
static const VLCElem *j_dc_vlc[2][8]; // [quant], [select]
static const VLCElem *j_orient_vlc[2][4]; // [quant], [select]
static av_cold void x8_init_vlc(VLC *vlc, int nb_bits, int nb_codes,
int *offset, const uint8_t table[][2])
static av_cold const VLCElem *x8_init_vlc(VLCInitState *state, int nb_bits,
int nb_codes, const uint8_t table[][2])
{
static VLCElem vlc_buf[VLC_BUFFER_SIZE];
vlc->table = &vlc_buf[*offset];
vlc->table_allocated = VLC_BUFFER_SIZE - *offset;
ff_vlc_init_from_lengths(vlc, nb_bits, nb_codes, &table[0][1], 2,
&table[0][0], 2, 1, 0, VLC_INIT_STATIC_OVERLONG, NULL);
*offset += vlc->table_size;
return ff_vlc_init_tables_from_lengths(state, nb_bits, nb_codes, &table[0][1], 2,
&table[0][0], 2, 1, 0, 0);
}
static av_cold void x8_vlc_init(void)
{
static VLCElem vlc_buf[VLC_BUFFER_SIZE];
VLCInitState state = VLC_INIT_STATE(vlc_buf);
int i;
int offset = 0;
// set ac tables
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
for (int k = 0; k < 8; k++)
x8_init_vlc(&j_ac_vlc[i][j][k], AC_VLC_BITS, 77,
&offset, x8_ac_quant_table[i][j][k]);
j_ac_vlc[i][j][k] = x8_init_vlc(&state, AC_VLC_BITS, 77,
x8_ac_quant_table[i][j][k]);
// set dc tables
for (int i = 0; i < 2; i++)
for (int j = 0; j < 8; j++)
x8_init_vlc(&j_dc_vlc[i][j], DC_VLC_BITS, 34, &offset,
x8_dc_quant_table[i][j]);
j_dc_vlc[i][j] = x8_init_vlc(&state, DC_VLC_BITS, 34,
x8_dc_quant_table[i][j]);
// set orient tables
for (i = 0; i < 2; i++)
x8_init_vlc(&j_orient_vlc[0][i], OR_VLC_BITS, 12,
&offset, x8_orient_highquant_table[i]);
j_orient_vlc[0][i] = x8_init_vlc(&state, OR_VLC_BITS, 12,
x8_orient_highquant_table[i]);
for (i = 0; i < 4; i++)
x8_init_vlc(&j_orient_vlc[1][i], OR_VLC_BITS, 12,
&offset, x8_orient_lowquant_table[i]);
av_assert2(offset == VLC_BUFFER_SIZE);
j_orient_vlc[1][i] = x8_init_vlc(&state, OR_VLC_BITS, 12,
x8_orient_lowquant_table[i]);
}
static void x8_reset_vlc_tables(IntraX8Context *w)
@@ -108,7 +102,7 @@ static inline void x8_select_ac_table(IntraX8Context *const w, int mode)
table_index = get_bits(w->gb, 3);
// 2 modes use same tables
w->j_ac_vlc_table[mode] = j_ac_vlc[w->quant < 13][mode >> 1][table_index].table;
w->j_ac_vlc_table[mode] = j_ac_vlc[w->quant < 13][mode >> 1][table_index];
av_assert2(j_ac_vlc[mode]);
}
@@ -116,7 +110,7 @@ static inline int x8_get_orient_vlc(IntraX8Context *w)
{
if (!w->j_orient_vlc_table) {
int table_index = get_bits(w->gb, 1 + (w->quant < 13));
w->j_orient_vlc_table = j_orient_vlc[w->quant < 13][table_index].table;
w->j_orient_vlc_table = j_orient_vlc[w->quant < 13][table_index];
}
return get_vlc2(w->gb, w->j_orient_vlc_table, OR_VLC_BITS, OR_VLC_MTD);
@@ -258,7 +252,7 @@ static int x8_get_dc_rlf(IntraX8Context *const w, const int mode,
if (!w->j_dc_vlc_table[mode]) {
int table_index = get_bits(w->gb, 3);
// 4 modes, same table
w->j_dc_vlc_table[mode] = j_dc_vlc[w->quant < 13][table_index].table;
w->j_dc_vlc_table[mode] = j_dc_vlc[w->quant < 13][table_index];
}
i = get_vlc2(w->gb, w->j_dc_vlc_table[mode], DC_VLC_BITS, DC_VLC_MTD);

View File

@@ -99,38 +99,38 @@ void ff_h263_show_pict_info(MpegEncContext *s){
/***********************************************/
/* decoding */
VLC ff_h263_intra_MCBPC_vlc;
VLC ff_h263_inter_MCBPC_vlc;
VLC ff_h263_cbpy_vlc;
VLC ff_h263_mv_vlc;
static VLC h263_mbtype_b_vlc;
static VLC cbpc_b_vlc;
VLCElem ff_h263_intra_MCBPC_vlc[72];
VLCElem ff_h263_inter_MCBPC_vlc[198];
VLCElem ff_h263_cbpy_vlc[64];
VLCElem ff_h263_mv_vlc[538];
static VLCElem h263_mbtype_b_vlc[80];
static VLCElem cbpc_b_vlc[8];
/* init vlcs */
static av_cold void h263_decode_init_vlc(void)
{
VLC_INIT_STATIC(&ff_h263_intra_MCBPC_vlc, INTRA_MCBPC_VLC_BITS, 9,
ff_h263_intra_MCBPC_bits, 1, 1,
ff_h263_intra_MCBPC_code, 1, 1, 72);
VLC_INIT_STATIC(&ff_h263_inter_MCBPC_vlc, INTER_MCBPC_VLC_BITS, 28,
ff_h263_inter_MCBPC_bits, 1, 1,
ff_h263_inter_MCBPC_code, 1, 1, 198);
VLC_INIT_STATIC(&ff_h263_cbpy_vlc, CBPY_VLC_BITS, 16,
&ff_h263_cbpy_tab[0][1], 2, 1,
&ff_h263_cbpy_tab[0][0], 2, 1, 64);
VLC_INIT_STATIC(&ff_h263_mv_vlc, H263_MV_VLC_BITS, 33,
&ff_mvtab[0][1], 2, 1,
&ff_mvtab[0][0], 2, 1, 538);
VLC_INIT_STATIC_TABLE(ff_h263_intra_MCBPC_vlc, INTRA_MCBPC_VLC_BITS, 9,
ff_h263_intra_MCBPC_bits, 1, 1,
ff_h263_intra_MCBPC_code, 1, 1, 0);
VLC_INIT_STATIC_TABLE(ff_h263_inter_MCBPC_vlc, INTER_MCBPC_VLC_BITS, 28,
ff_h263_inter_MCBPC_bits, 1, 1,
ff_h263_inter_MCBPC_code, 1, 1, 0);
VLC_INIT_STATIC_TABLE(ff_h263_cbpy_vlc, CBPY_VLC_BITS, 16,
&ff_h263_cbpy_tab[0][1], 2, 1,
&ff_h263_cbpy_tab[0][0], 2, 1, 0);
VLC_INIT_STATIC_TABLE(ff_h263_mv_vlc, H263_MV_VLC_BITS, 33,
&ff_mvtab[0][1], 2, 1,
&ff_mvtab[0][0], 2, 1, 0);
ff_h263_init_rl_inter();
VLC_INIT_RL(ff_h263_rl_inter, 554);
INIT_FIRST_VLC_RL(ff_rl_intra_aic, 554);
VLC_INIT_STATIC(&h263_mbtype_b_vlc, H263_MBTYPE_B_VLC_BITS, 15,
&ff_h263_mbtype_b_tab[0][1], 2, 1,
&ff_h263_mbtype_b_tab[0][0], 2, 1, 80);
VLC_INIT_STATIC(&cbpc_b_vlc, CBPC_B_VLC_BITS, 4,
&ff_cbpc_b_tab[0][1], 2, 1,
&ff_cbpc_b_tab[0][0], 2, 1, 8);
VLC_INIT_STATIC_TABLE(h263_mbtype_b_vlc, H263_MBTYPE_B_VLC_BITS, 15,
&ff_h263_mbtype_b_tab[0][1], 2, 1,
&ff_h263_mbtype_b_tab[0][0], 2, 1, 0);
VLC_INIT_STATIC_TABLE(cbpc_b_vlc, CBPC_B_VLC_BITS, 4,
&ff_cbpc_b_tab[0][1], 2, 1,
&ff_cbpc_b_tab[0][0], 2, 1, 0);
}
av_cold void ff_h263_decode_init_vlc(void)
@@ -273,7 +273,7 @@ int ff_h263_resync(MpegEncContext *s){
int ff_h263_decode_motion(MpegEncContext * s, int pred, int f_code)
{
int code, val, sign, shift;
code = get_vlc2(&s->gb, ff_h263_mv_vlc.table, H263_MV_VLC_BITS, 2);
code = get_vlc2(&s->gb, ff_h263_mv_vlc, H263_MV_VLC_BITS, 2);
if (code == 0)
return pred;
@@ -366,13 +366,13 @@ static void preview_obmc(MpegEncContext *s){
s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
goto end;
}
cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc, INTER_MCBPC_VLC_BITS, 2);
}while(cbpc == 20);
if(cbpc & 4){
s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
}else{
get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
get_vlc2(&s->gb, ff_h263_cbpy_vlc, CBPY_VLC_BITS, 1);
if (cbpc & 8) {
if(s->modified_quant){
if(get_bits1(&s->gb)) skip_bits(&s->gb, 1);
@@ -809,7 +809,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
s->mb_skipped = !(s->obmc | s->loop_filter);
goto end;
}
cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc, INTER_MCBPC_VLC_BITS, 2);
if (cbpc < 0){
av_log(s->avctx, AV_LOG_ERROR, "cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
return SLICE_ERROR;
@@ -824,7 +824,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
if(s->pb_frame && get_bits1(&s->gb))
pb_mv_count = h263_get_modb(&s->gb, s->pb_frame, &cbpb);
cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc, CBPY_VLC_BITS, 1);
if (cbpy < 0) {
av_log(s->avctx, AV_LOG_ERROR, "cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
@@ -905,7 +905,8 @@ int ff_h263_decode_mb(MpegEncContext *s,
mot_val1[1 ]= mot_val1[3 ]= mot_val1[1+2*stride]= mot_val1[3+2*stride]= 0;
do{
mb_type= get_vlc2(&s->gb, h263_mbtype_b_vlc.table, H263_MBTYPE_B_VLC_BITS, 2);
mb_type = get_vlc2(&s->gb, h263_mbtype_b_vlc,
H263_MBTYPE_B_VLC_BITS, 2);
if (mb_type < 0){
av_log(s->avctx, AV_LOG_ERROR, "b mb_type damaged at %d %d\n", s->mb_x, s->mb_y);
return SLICE_ERROR;
@@ -917,13 +918,13 @@ int ff_h263_decode_mb(MpegEncContext *s,
s->mb_intra = IS_INTRA(mb_type);
if(HAS_CBP(mb_type)){
s->bdsp.clear_blocks(s->block[0]);
cbpc = get_vlc2(&s->gb, cbpc_b_vlc.table, CBPC_B_VLC_BITS, 1);
cbpc = get_vlc2(&s->gb, cbpc_b_vlc, CBPC_B_VLC_BITS, 1);
if(s->mb_intra){
dquant = IS_QUANT(mb_type);
goto intra;
}
cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc, CBPY_VLC_BITS, 1);
if (cbpy < 0){
av_log(s->avctx, AV_LOG_ERROR, "b cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
@@ -1009,7 +1010,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
s->current_picture.mb_type[xy] = mb_type;
} else { /* I-Frame */
do{
cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc, INTRA_MCBPC_VLC_BITS, 2);
if (cbpc < 0){
av_log(s->avctx, AV_LOG_ERROR, "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
return SLICE_ERROR;
@@ -1034,7 +1035,7 @@ intra:
if(s->pb_frame && get_bits1(&s->gb))
pb_mv_count = h263_get_modb(&s->gb, s->pb_frame, &cbpb);
cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc, CBPY_VLC_BITS, 1);
if(cbpy<0){
av_log(s->avctx, AV_LOG_ERROR, "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
return SLICE_ERROR;

View File

@@ -26,7 +26,7 @@
/* Inverse ICT parameters in float and integer.
* int value = (float value) * (1<<16) */
static const float f_ict_params[4] = {
const float ff_jpeg2000_f_ict_params[4] = {
1.402f,
0.34413f,
0.71414f,
@@ -42,6 +42,7 @@ static const int i_ict_params[4] = {
static void ict_float(void *_src0, void *_src1, void *_src2, int csize)
{
const float *const f_ict_params = ff_jpeg2000_f_ict_params;
float *src0 = _src0, *src1 = _src1, *src2 = _src2;
float i0f, i1f, i2f;
int i;
@@ -95,7 +96,9 @@ av_cold void ff_jpeg2000dsp_init(Jpeg2000DSPContext *c)
c->mct_decode[FF_DWT53] = rct_int;
c->mct_decode[FF_DWT97_INT] = ict_int;
#if ARCH_X86
#if ARCH_RISCV
ff_jpeg2000dsp_init_riscv(c);
#elif ARCH_X86
ff_jpeg2000dsp_init_x86(c);
#endif
}

View File

@@ -30,7 +30,10 @@ typedef struct Jpeg2000DSPContext {
void (*mct_decode[FF_DWT_NB])(void *src0, void *src1, void *src2, int csize);
} Jpeg2000DSPContext;
extern const float ff_jpeg2000_f_ict_params[4];
void ff_jpeg2000dsp_init(Jpeg2000DSPContext *c);
void ff_jpeg2000dsp_init_riscv(Jpeg2000DSPContext *c);
void ff_jpeg2000dsp_init_x86(Jpeg2000DSPContext *c);
#endif /* AVCODEC_JPEG2000DSP_H */

View File

@@ -60,7 +60,7 @@ typedef struct LagarithContext {
int zeros_rem; /**< number of zero bytes remaining to output */
} LagarithContext;
static VLC lag_tab;
static VLCElem lag_tab[1 << VLC_BITS];
static const uint8_t lag_bits[] = {
7, 7, 2, 7, 3, 4, 5, 6, 7, 7, 7, 7, 7, 6, 7, 4, 5, 7, 7, 7, 7,
@@ -85,8 +85,8 @@ static const uint8_t lag_symbols[] = {
static av_cold void lag_init_static_data(void)
{
VLC_INIT_SPARSE_STATIC(&lag_tab, VLC_BITS, FF_ARRAY_ELEMS(lag_bits),
lag_bits, 1, 1, lag_codes, 1, 1, lag_symbols, 1, 1, 128);
VLC_INIT_STATIC_SPARSE_TABLE(lag_tab, VLC_BITS, FF_ARRAY_ELEMS(lag_bits),
lag_bits, 1, 1, lag_codes, 1, 1, lag_symbols, 1, 1, 0);
}
/**
@@ -136,7 +136,7 @@ static int lag_decode_prob(GetBitContext *gb, uint32_t *value)
{
unsigned val, bits;
bits = get_vlc2(gb, lag_tab.table, VLC_BITS, 1);
bits = get_vlc2(gb, lag_tab, VLC_BITS, 1);
if (bits > 31) {
*value = 0;
return AVERROR_INVALIDDATA;

62
libavcodec/leaddata.h Normal file
View File

@@ -0,0 +1,62 @@
/*
* LEAD MCMP decoder tables
*
* 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_LEADDATA_H
#define AVCODEC_LEADDATA_H
#include <stdint.h>
static const uint8_t luma_dc_len[]={
2, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 9
};
static const uint8_t chroma_dc_len[]={
2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
};
static const uint8_t luma_ac_len[]={
2, 2, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 7, 8,
8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11,
12, 12, 12, 12, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16
};
static const uint8_t chroma_ac_len[]={
2, 2, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10,
11, 11, 11, 11, 12, 12, 12, 12, 14, 15, 15, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16
};
#endif /* AVCODEC_LEADDATA_H */

270
libavcodec/leaddec.c Normal file
View File

@@ -0,0 +1,270 @@
/*
* LEAD MCMP decoder
*
* Copyright (c) 2023 Peter Ross
*
* 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 "avcodec.h"
#include "blockdsp.h"
#include "codec_internal.h"
#include "copy_block.h"
#include "decode.h"
#include "get_bits.h"
#include "idctdsp.h"
#include "jpegquanttables.h"
#include "jpegtables.h"
#include "leaddata.h"
#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"
#define LUMA_DC_BITS 9
#define CHROMA_DC_BITS 11
#define LUMA_AC_BITS 10
#define CHROMA_AC_BITS 10
static VLC luma_dc_vlc;
static VLC chroma_dc_vlc;
static VLC luma_ac_vlc;
static VLC chroma_ac_vlc;
static av_cold void lead_init_static_data(void)
{
VLC_INIT_STATIC_FROM_LENGTHS(&luma_dc_vlc, LUMA_DC_BITS, FF_ARRAY_ELEMS(luma_dc_len),
luma_dc_len, 1,
0, 0, 0,
0, 0, 1 << LUMA_DC_BITS);
VLC_INIT_STATIC_FROM_LENGTHS(&chroma_dc_vlc, CHROMA_DC_BITS, FF_ARRAY_ELEMS(chroma_dc_len),
chroma_dc_len, 1,
0, 0, 0,
0, 0, 1 << CHROMA_DC_BITS);
VLC_INIT_STATIC_FROM_LENGTHS(&luma_ac_vlc, LUMA_AC_BITS, FF_ARRAY_ELEMS(luma_ac_len),
luma_ac_len, 1,
ff_mjpeg_val_ac_luminance, 1, 1,
0, 0, 1160);
VLC_INIT_STATIC_FROM_LENGTHS(&chroma_ac_vlc, CHROMA_AC_BITS, FF_ARRAY_ELEMS(chroma_ac_len),
chroma_ac_len, 1,
ff_mjpeg_val_ac_chrominance, 1, 1,
0, 0, 1160);
}
typedef struct LeadContext {
uint8_t *bitstream_buf;
unsigned int bitstream_buf_size;
BlockDSPContext bdsp;
IDCTDSPContext idsp;
uint8_t permutated_scantable[64];
} LeadContext;
static av_cold int lead_decode_init(AVCodecContext * avctx)
{
static AVOnce init_static_once = AV_ONCE_INIT;
LeadContext *s = avctx->priv_data;
if (avctx->extradata_size < 20)
return AVERROR_INVALIDDATA;
ff_blockdsp_init(&s->bdsp);
ff_idctdsp_init(&s->idsp, avctx);
ff_permute_scantable(s->permutated_scantable, ff_zigzag_direct, s->idsp.idct_permutation);
ff_thread_once(&init_static_once, lead_init_static_data);
return 0;
}
static void calc_dequant(uint16_t * dequant, const uint8_t * quant_tbl, int q)
{
for (int i = 0; i < 64; i++)
dequant[i] = av_clip(q * quant_tbl[ff_zigzag_direct[i]] / 50, 2, 32767);
}
static int decode_block(LeadContext * s, GetBitContext * gb,
const VLCElem * dc_table, int dc_bits, const VLCElem * ac_table, int ac_bits,
int16_t * dc_pred, const uint16_t * dequant,
uint8_t * dst, int stride)
{
DECLARE_ALIGNED(32, int16_t, block)[64];
int size;
s->bdsp.clear_block(block);
size = get_vlc2(gb, dc_table, dc_bits, 1);
if (size < 0)
return AVERROR_INVALIDDATA;
if (size)
*dc_pred += get_xbits(gb, size);
block[0] = (1 << 10) + *dc_pred * dequant[0];
for (int i = 1; i < 64; i++) {
int symbol = get_vlc2(gb, ac_table, ac_bits, 2);
if (symbol < 0)
return AVERROR_INVALIDDATA;
if (!symbol)
break;
i += symbol >> 4;
if (i >= 64)
return AVERROR_INVALIDDATA;
size = symbol & 0xF;
if (size)
block[s->permutated_scantable[i]] = get_xbits(gb, size) * dequant[i];
}
s->idsp.idct_put(dst, stride, block);
return 0;
}
static int lead_decode_frame(AVCodecContext *avctx, AVFrame * frame,
int * got_frame, AVPacket * avpkt)
{
LeadContext *s = avctx->priv_data;
const uint8_t * buf = avpkt->data;
int ret, format, yuv20p_half = 0, fields = 1, q, size;
GetBitContext gb;
int16_t dc_pred[3] = {0, 0, 0};
uint16_t dequant[2][64];
if (avpkt->size < 8)
return AVERROR_INVALIDDATA;
format = AV_RL16(buf + 4);
switch(format) {
case 0x8000:
yuv20p_half = 1;
// fall-through
case 0x1000:
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
break;
case 0x2000:
avctx->pix_fmt = AV_PIX_FMT_YUV444P;
break;
case 0x2006:
avctx->pix_fmt = AV_PIX_FMT_YUV444P;
fields = 2;
break;
default:
avpriv_request_sample(avctx, "unsupported format 0x%x", format);
return AVERROR_PATCHWELCOME;
}
q = AV_RL16(buf + 6);
calc_dequant(dequant[0], ff_mjpeg_std_luminance_quant_tbl, q);
calc_dequant(dequant[1], ff_mjpeg_std_chrominance_quant_tbl, q);
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret;
frame->flags |= AV_FRAME_FLAG_KEY;
frame->pict_type = AV_PICTURE_TYPE_I;
av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size, avpkt->size - 8);
if (!s->bitstream_buf)
return AVERROR(ENOMEM);
size = 0;
for (int i = 8; i < avpkt->size; i++) {
int src = buf[i] ^ 0x80;
s->bitstream_buf[size++] = src;
if (src == 0xFF && i + 1 < avpkt->size && (buf[i + 1] ^ 0x80) == 0x00)
i++;
}
init_get_bits8(&gb, s->bitstream_buf, size);
if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
for (int mb_y = 0; mb_y < avctx->height / 16; mb_y++)
for (int mb_x = 0; mb_x < avctx->width / 16; mb_x++)
for (int b = 0; b < (yuv20p_half ? 4 : 6); b++) {
int luma_block = yuv20p_half ? 2 : 4;
const VLCElem * dc_vlc = b < luma_block ? luma_dc_vlc.table : chroma_dc_vlc.table;
int dc_bits = b < luma_block ? LUMA_DC_BITS : CHROMA_DC_BITS;
const VLCElem * ac_vlc = b < luma_block ? luma_ac_vlc.table : chroma_ac_vlc.table;
int ac_bits = b < luma_block ? LUMA_AC_BITS : CHROMA_AC_BITS;
int plane = b < luma_block ? 0 : b - (yuv20p_half ? 1 : 3);
int x, y;
if (b < luma_block) {
y = 16*mb_y + 8*(b >> 1);
x = 16*mb_x + 8*(b & 1);
} else {
y = 8*mb_y;
x = 8*mb_x;
}
ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits,
dc_pred + plane, dequant[!(b < 4)],
frame->data[plane] + y*frame->linesize[plane] + x,
(yuv20p_half && b < 2 ? 2 : 1) * frame->linesize[plane]);
if (ret < 0)
return ret;
if (yuv20p_half && b < 2)
copy_block8(frame->data[plane] + (y + 1)*frame->linesize[plane] + x,
frame->data[plane] + y*frame->linesize[plane] + x,
2*frame->linesize[plane], 2*frame->linesize[plane], 8);
}
} else {
for (int f = 0; f < fields; f++)
for (int j = 0; j < avctx->height / fields / 8; j++)
for (int i = 0; i < avctx->width / 8; i++)
for (int plane = 0; plane < 3; plane++) {
const VLCElem * dc_vlc = !plane ? luma_dc_vlc.table : chroma_dc_vlc.table;
int dc_bits = !plane ? LUMA_DC_BITS : CHROMA_DC_BITS;
const VLCElem * ac_vlc = !plane ? luma_ac_vlc.table : chroma_ac_vlc.table;
int ac_bits = !plane ? LUMA_AC_BITS : CHROMA_AC_BITS;
ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits,
dc_pred + plane, dequant[!!plane],
frame->data[plane] + (f + 8*j*fields)*frame->linesize[plane] + 8*i,
fields * frame->linesize[plane]);
if (ret < 0)
return ret;
}
}
*got_frame = 1;
return avpkt->size;
}
static av_cold int lead_decode_end(AVCodecContext * avctx)
{
LeadContext *s = avctx->priv_data;
av_freep(&s->bitstream_buf);
return 0;
}
const FFCodec ff_lead_decoder = {
.p.name = "lead",
CODEC_LONG_NAME("LEAD MCMP"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_LEAD,
.priv_data_size = sizeof(LeadContext),
.init = lead_decode_init,
.close = lead_decode_end,
FF_CODEC_DECODE_CB(lead_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};

View File

@@ -250,6 +250,7 @@ static int config_enc_params(EbSvtAv1EncConfiguration *param,
if (avctx->gop_size > 1)
param->intra_period_length = avctx->gop_size - 1;
#if SVT_AV1_CHECK_VERSION(1, 1, 0)
// In order for SVT-AV1 to force keyframes by setting pic_type to
// EB_AV1_KEY_PICTURE on any frame, force_key_frames has to be set. Note
// that this does not force all frames to be keyframes (it only forces a
@@ -260,6 +261,7 @@ static int config_enc_params(EbSvtAv1EncConfiguration *param,
// to be updated to set force_key_frames accordingly.
if (avctx->gop_size == 1)
param->force_key_frames = 1;
#endif
if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
param->frame_rate_numerator = avctx->framerate.num;

View File

@@ -63,6 +63,8 @@ av_cold void ff_llauddsp_init(LLAudDSPContext *c)
ff_llauddsp_init_arm(c);
#elif ARCH_PPC
ff_llauddsp_init_ppc(c);
#elif ARCH_RISCV
ff_llauddsp_init_riscv(c);
#elif ARCH_X86
ff_llauddsp_init_x86(c);
#endif

View File

@@ -46,6 +46,7 @@ typedef struct LLAudDSPContext {
void ff_llauddsp_init(LLAudDSPContext *c);
void ff_llauddsp_init_arm(LLAudDSPContext *c);
void ff_llauddsp_init_ppc(LLAudDSPContext *c);
void ff_llauddsp_init_riscv(LLAudDSPContext *c);
void ff_llauddsp_init_x86(LLAudDSPContext *c);
#endif /* AVCODEC_LOSSLESS_AUDIODSP_H */

View File

@@ -67,7 +67,7 @@ typedef struct MimicContext {
int next_prev_index;
} MimicContext;
static VLC block_vlc;
static VLCElem block_vlc[4368];
static const uint8_t huffsyms[] = {
0x10, 0x20, 0x30, 0x00, 0x11, 0x40, 0x50, 0x12, 0x13, 0x21, 0x31, 0x60,
@@ -120,8 +120,9 @@ static av_cold int mimic_decode_end(AVCodecContext *avctx)
static av_cold void mimic_init_static(void)
{
VLC_INIT_STATIC_FROM_LENGTHS(&block_vlc, MIMIC_VLC_BITS, FF_ARRAY_ELEMS(huffbits),
huffbits, 1, huffsyms, 1, 1, 0, 0, 4368);
VLC_INIT_STATIC_TABLE_FROM_LENGTHS(block_vlc, MIMIC_VLC_BITS,
FF_ARRAY_ELEMS(huffbits),
huffbits, 1, huffsyms, 1, 1, 0, 0);
}
static av_cold int mimic_decode_init(AVCodecContext *avctx)
@@ -226,7 +227,7 @@ static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
int value;
int coeff;
vlc = get_vlc2(&ctx->gb, block_vlc.table, MIMIC_VLC_BITS, 3);
vlc = get_vlc2(&ctx->gb, block_vlc, MIMIC_VLC_BITS, 3);
if (!vlc) /* end-of-block code */
return 0;
if (vlc == -1)

View File

@@ -274,28 +274,26 @@ typedef struct MobiClipContext {
BswapDSPContext bdsp;
} MobiClipContext;
static VLC rl_vlc[2];
static VLC mv_vlc[2][16];
static const VLCElem *rl_vlc[2];
static const VLCElem *mv_vlc[2][16];
static av_cold void mobiclip_init_static(void)
{
VLC_INIT_STATIC_FROM_LENGTHS(&rl_vlc[0], MOBI_RL_VLC_BITS, 104,
bits0, sizeof(*bits0),
syms0, sizeof(*syms0), sizeof(*syms0),
0, 0, 1 << MOBI_RL_VLC_BITS);
VLC_INIT_STATIC_FROM_LENGTHS(&rl_vlc[1], MOBI_RL_VLC_BITS, 104,
bits0, sizeof(*bits0),
syms1, sizeof(*syms1), sizeof(*syms1),
0, 0, 1 << MOBI_RL_VLC_BITS);
static VLCElem vlc_buf[(2 << MOBI_RL_VLC_BITS) + (2 * 16 << MOBI_MV_VLC_BITS)];
VLCInitState state =VLC_INIT_STATE(vlc_buf);
for (int i = 0; i < 2; i++) {
static VLCElem vlc_buf[2 * 16 << MOBI_MV_VLC_BITS];
rl_vlc[i] =
ff_vlc_init_tables_from_lengths(&state, MOBI_RL_VLC_BITS, 104,
bits0, sizeof(*bits0),
i ? syms1 : syms0, sizeof(*syms0), sizeof(*syms0),
0, 0);
for (int j = 0; j < 16; j++) {
mv_vlc[i][j].table = &vlc_buf[(16 * i + j) << MOBI_MV_VLC_BITS];
mv_vlc[i][j].table_allocated = 1 << MOBI_MV_VLC_BITS;
ff_vlc_init_from_lengths(&mv_vlc[i][j], MOBI_MV_VLC_BITS, mv_len[j],
mv_bits[i][j], sizeof(*mv_bits[i][j]),
mv_syms[i][j], sizeof(*mv_syms[i][j]), sizeof(*mv_syms[i][j]),
0, VLC_INIT_USE_STATIC, NULL);
mv_vlc[i][j] =
ff_vlc_init_tables_from_lengths(&state, MOBI_MV_VLC_BITS, mv_len[j],
mv_bits[i][j], sizeof(*mv_bits[i][j]),
mv_syms[i][j], sizeof(*mv_syms[i][j]), sizeof(*mv_syms[i][j]),
0, 0);
}
}
}
@@ -410,8 +408,7 @@ static void read_run_encoding(AVCodecContext *avctx,
{
MobiClipContext *s = avctx->priv_data;
GetBitContext *gb = &s->gb;
int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx].table,
MOBI_RL_VLC_BITS, 1);
int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx], MOBI_RL_VLC_BITS, 1);
*last = (n >> 11) == 1;
*run = (n >> 5) & 0x3F;
@@ -1195,8 +1192,7 @@ static int predict_motion(AVCodecContext *avctx,
for (int i = 0; i < 2; i++) {
int ret, idx2;
idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx].table,
MOBI_MV_VLC_BITS, 1);
idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx], MOBI_MV_VLC_BITS, 1);
ret = predict_motion(avctx, width, height, idx2,
offsetm, offsetx + i * adjx, offsety + i * adjy);
@@ -1272,8 +1268,7 @@ static int mobiclip_decode(AVCodecContext *avctx, AVFrame *rframe,
motion[x / 16 + 2].x = 0;
motion[x / 16 + 2].y = 0;
idx = get_vlc2(gb, mv_vlc[s->moflex][0].table,
MOBI_MV_VLC_BITS, 1);
idx = get_vlc2(gb, mv_vlc[s->moflex][0], MOBI_MV_VLC_BITS, 1);
if (idx == 6 || idx == 7) {
ret = decode_macroblock(avctx, frame, x, y, idx == 7);

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