Compare commits
246 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07c303b708 | ||
|
|
fb0295e5fd | ||
|
|
6183a69c0b | ||
|
|
636ae0e0bc | ||
|
|
be1675035f | ||
|
|
08e97dae20 | ||
|
|
82be1e5c0d | ||
|
|
afb967b81e | ||
|
|
d076517056 | ||
|
|
45d0eb3f70 | ||
|
|
6720a509a7 | ||
|
|
78f55457c9 | ||
|
|
c9fe9fb863 | ||
|
|
5cb8accd09 | ||
|
|
90a779bed6 | ||
|
|
6b708cd783 | ||
|
|
575efc0406 | ||
|
|
b360c91752 | ||
|
|
a1a6a328f0 | ||
|
|
889a022cce | ||
|
|
87016e031f | ||
|
|
4f7b91a698 | ||
|
|
7c97a0c63f | ||
|
|
6dbde68cb5 | ||
|
|
7282137f48 | ||
|
|
de85815bfa | ||
|
|
436b972fc8 | ||
|
|
a8d9d6b08d | ||
|
|
23de85d1ec | ||
|
|
ce467421dc | ||
|
|
c536e92207 | ||
|
|
20e6195c54 | ||
|
|
6d60cc7baf | ||
|
|
5b8b5ec9c5 | ||
|
|
5b33104fca | ||
|
|
67a2571a55 | ||
|
|
84e400ae37 | ||
|
|
da3ce21f68 | ||
|
|
427347309b | ||
|
|
250471ea17 | ||
|
|
a562cfee2e | ||
|
|
cd7b352c53 | ||
|
|
f576a0835b | ||
|
|
eb508702a8 | ||
|
|
ab78d22553 | ||
|
|
39878fc504 | ||
|
|
9bcbe04aa0 | ||
|
|
3ff811a41f | ||
|
|
10440a489a | ||
|
|
553b31da68 | ||
|
|
fa4c2884dd | ||
|
|
09f783692e | ||
|
|
fa81de4af0 | ||
|
|
49719d3cb5 | ||
|
|
409b29d3f9 | ||
|
|
ac4e3e188a | ||
|
|
bb0a684d93 | ||
|
|
19fcf43131 | ||
|
|
96d2a40b9e | ||
|
|
cf60046cdc | ||
|
|
5d5bb77af1 | ||
|
|
ea9557043e | ||
|
|
b7284f2410 | ||
|
|
736284e7b9 | ||
|
|
d043e5c54c | ||
|
|
cedf589c09 | ||
|
|
acf63d5350 | ||
|
|
26ebd96371 | ||
|
|
5db07311a0 | ||
|
|
ed0a50923a | ||
|
|
e900a559c2 | ||
|
|
6667741029 | ||
|
|
99fcdee5e8 | ||
|
|
854012ec59 | ||
|
|
6f39dee974 | ||
|
|
f16900bda2 | ||
|
|
f01fdedb69 | ||
|
|
2b4035d1dc | ||
|
|
88f9164f97 | ||
|
|
b82957a66a | ||
|
|
04e53927ad | ||
|
|
b4169760b0 | ||
|
|
ed8ddf0bd3 | ||
|
|
5a2ca4bf7a | ||
|
|
10869cd849 | ||
|
|
f084e9b0be | ||
|
|
adc87a5f7c | ||
|
|
02594c8c01 | ||
|
|
f68ad5d2de | ||
|
|
44a0148fad | ||
|
|
799fad1828 | ||
|
|
f9fdaa2ca9 | ||
|
|
ad3df6bf35 | ||
|
|
1a7a85137e | ||
|
|
fd1712b6fb | ||
|
|
43226efc21 | ||
|
|
3f890fbfd9 | ||
|
|
de4846dd18 | ||
|
|
2fdaeec41b | ||
|
|
392ab35db1 | ||
|
|
5b85ca5317 | ||
|
|
8661b5e8f9 | ||
|
|
c32c1a18b9 | ||
|
|
748c168f8e | ||
|
|
93abb9b560 | ||
|
|
50d3c5bd8c | ||
|
|
e557d89ac1 | ||
|
|
2e2c28119f | ||
|
|
1d33a310df | ||
|
|
a40f833bac | ||
|
|
a02670ded7 | ||
|
|
5935423e1e | ||
|
|
4fb9d94688 | ||
|
|
03a4aa9699 | ||
|
|
c0a18e884c | ||
|
|
9450a4a7fe | ||
|
|
155f0c8ef7 | ||
|
|
e920a84801 | ||
|
|
9dd49c8b52 | ||
|
|
0ea184fc39 | ||
|
|
a31992634f | ||
|
|
02064ba3a3 | ||
|
|
4dbfb52230 | ||
|
|
d06fd18f8f | ||
|
|
b0aba7dd0c | ||
|
|
86bee42473 | ||
|
|
eba73142ad | ||
|
|
0c44f63b02 | ||
|
|
92abc7266b | ||
|
|
8c0350f57e | ||
|
|
090d9956fd | ||
|
|
e01e30ede1 | ||
|
|
fd2e65871c | ||
|
|
736b510fcc | ||
|
|
26c0a7321f | ||
|
|
92bcc6703a | ||
|
|
28840cf499 | ||
|
|
73dea2bb91 | ||
|
|
b2a441a3be | ||
|
|
a5259f326b | ||
|
|
8516609edd | ||
|
|
356b1ba765 | ||
|
|
c2f2bf82c1 | ||
|
|
2817efbba3 | ||
|
|
2def617787 | ||
|
|
98c2711b58 | ||
|
|
68cc1744db | ||
|
|
d35eecd24f | ||
|
|
f2687a3b69 | ||
|
|
5615f9dab4 | ||
|
|
7e2120c4d9 | ||
|
|
c9aa80c313 | ||
|
|
5dc31bc67b | ||
|
|
40a8cb9e6c | ||
|
|
774611a349 | ||
|
|
eb422c606a | ||
|
|
4fe91e3676 | ||
|
|
7f66d9d6c5 | ||
|
|
1aca4e7fc5 | ||
|
|
2c131f126d | ||
|
|
0b4e69cc87 | ||
|
|
22d60524d8 | ||
|
|
4d6042e9d7 | ||
|
|
0e8abf2698 | ||
|
|
4536de3769 | ||
|
|
1e63e24c76 | ||
|
|
30deaba97b | ||
|
|
3b080fe7af | ||
|
|
1f15a7e9a8 | ||
|
|
8c1e71a811 | ||
|
|
70b5d9c569 | ||
|
|
36b5f71b1f | ||
|
|
5a694d62c5 | ||
|
|
8c39b2bca7 | ||
|
|
05577d2c76 | ||
|
|
25b9ff2780 | ||
|
|
e5dcde620d | ||
|
|
fd4cb6ebee | ||
|
|
0a610e22c1 | ||
|
|
e3ad5b9784 | ||
|
|
f6c5d04b6d | ||
|
|
827d0325a9 | ||
|
|
36e7f9b339 | ||
|
|
99ed510d4b | ||
|
|
b60a3f70be | ||
|
|
1ae750a16e | ||
|
|
716ddc8c62 | ||
|
|
73fa6d486d | ||
|
|
75c6a253a4 | ||
|
|
6c7a344b65 | ||
|
|
7fee90efac | ||
|
|
6fb96ef755 | ||
|
|
4c7e8b969e | ||
|
|
c95e123e8c | ||
|
|
886fbec82f | ||
|
|
e5e05fd3c8 | ||
|
|
460c6ae597 | ||
|
|
7d542e26a9 | ||
|
|
7902c0df4c | ||
|
|
ff886fc282 | ||
|
|
5a9e185dfc | ||
|
|
363837de0e | ||
|
|
a99285aedf | ||
|
|
ab8a8246c8 | ||
|
|
bd4c778e19 | ||
|
|
fe748ddf62 | ||
|
|
c630d76b27 | ||
|
|
1fee3a3dce | ||
|
|
edc50658d9 | ||
|
|
424c8ceb08 | ||
|
|
7e1cdc69fb | ||
|
|
4aea0da230 | ||
|
|
6aff17a451 | ||
|
|
93f07d98d9 | ||
|
|
d312a33ed2 | ||
|
|
57c16323f2 | ||
|
|
96dfc4481b | ||
|
|
55f28eb627 | ||
|
|
97a9d12657 | ||
|
|
265450b89e | ||
|
|
22c7291506 | ||
|
|
772865717b | ||
|
|
2c3d2a0245 | ||
|
|
f05948ada4 | ||
|
|
ae72412aa8 | ||
|
|
d48810f3a5 | ||
|
|
600c6f1b55 | ||
|
|
3ea2310e89 | ||
|
|
300ee8b02d | ||
|
|
722765687b | ||
|
|
6323ca5902 | ||
|
|
2f268505b9 | ||
|
|
4cba3e0f07 | ||
|
|
2532e832d2 | ||
|
|
7d497a1119 | ||
|
|
04b49fb3c5 | ||
|
|
a824c6f2f6 | ||
|
|
21bfadd9b4 | ||
|
|
82faba8a6c | ||
|
|
ff3429991e | ||
|
|
47e784f881 | ||
|
|
0e15b2b828 | ||
|
|
9d3a7d30c4 | ||
|
|
105657540b | ||
|
|
63078b4599 | ||
|
|
891f70c6d5 |
4
.mailmap
4
.mailmap
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
36
configure
vendored
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 $@)))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
|
||||
#include "cmdutils.h"
|
||||
#include "ffmpeg.h"
|
||||
#include "ffmpeg_utils.h"
|
||||
#include "sync_queue.h"
|
||||
|
||||
const char program_name[] = "ffmpeg";
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
56
fftools/ffmpeg_utils.h
Normal 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
|
||||
@@ -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
824
fftools/ffplay_renderer.c
Normal 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
41
fftools/ffplay_renderer.h
Normal 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 */
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
324
libavcodec/aacdec_common.c
Normal 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);
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "libavutil/ffmath.h"
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "aactab.h"
|
||||
#include "aac.h"
|
||||
#include "psymodel.h"
|
||||
|
||||
/***********************************
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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[]
|
||||
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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
380
libavcodec/cbs_vp8.c
Normal 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
133
libavcodec/cbs_vp8.h
Normal 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 */
|
||||
248
libavcodec/cbs_vp8_syntax_template.c
Normal file
248
libavcodec/cbs_vp8_syntax_template.c
Normal 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, ¤t->header));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FUNC(compressed_header)(CodedBitstreamContext *ctx,
|
||||
CBSVP8BoolCodingRW *bool_coding_rw,
|
||||
VP8RawFrame *current)
|
||||
{
|
||||
CHECK(FUNC(frame_header)(ctx, bool_coding_rw, ¤t->header));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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" */
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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[];
|
||||
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
62
libavcodec/leaddata.h
Normal 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
270
libavcodec/leaddec.c
Normal 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,
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user