diff --git a/Changelog b/Changelog
index 86f547c9b..1d5810ee0 100644
--- a/Changelog
+++ b/Changelog
@@ -1,85 +1,54 @@
Entries are sorted chronologically from oldest to youngest within each release,
releases are sorted from youngest to oldest.
-version 5.1.2:
-- avcodec/dstdec: Check for overflow in build_filter()
-- avformat/spdifdec: Use 64bit to compute bit rate
-- avformat/rpl: Use 64bit for duration computation
-- avformat/xwma: Use av_rescale() for duration computation
-- avformat/sdsdec: Use av_rescale() to avoid intermediate overflow in duration calculation
-- avformat/sbgdec: Check ts_int in genrate_intervals
-- avformat/sbgdec: clamp end_ts
-- avformat/rmdec: check tag_size
-- avformat/nutdec: Check fields
-- avformat/flvdec: Use 64bit for sum_flv_tag_size
-- avformat/jacosubdec: Fix overflow in get_shift()
-- avformat/genh: Check nb_channels for IMA ADPCM
-- avformat/dxa: avoid bpc overflows
-- avformat/dhav: Use 64bit seek_back
-- avformat/cafdec: Check that nb_frasmes fits within 64bit
-- avformat/asfdec_o: Limit packet offset
-- avformat/apm: Use 64bit for bit_rate computation
-- avformat/ape: Check frames size
-- avformat/icodec: Check nb_pal
-- avformat/aiffdec: Use 64bit for block_duration use
-- avformat/aiffdec: Check block_duration
-- avformat/mxfdec: only probe max run in
-- avformat/mxfdec: Check run_in is within 65536
-- avcodec/mjpegdec: Check for unsupported bayer case
-- avcodec/apedec: Fix integer overflow in filter_3800()
-- avcodec/tta: Check 24bit scaling for overflow
-- avcodec/mobiclip: Check quantizer for overflow
-- avcodec/exr: Check preview psize
-- avcodec/tiff: Fix loop detection
-- libavformat/hls: Free keys
-- avcodec/fmvc: Move frame allocation to a later stage
-- avfilter/vf_showinfo: remove backspaces
-- avcodec/speedhq: Check width
-- avcodec/bink: disallow odd positioned scaled blocks
-- avformat/cafenc: derive Opus frame size from the relevant stream parameters
-- avformat/dashdec: Fix crash on invalid input/ENOMEM, fix leak
-- lavc/videotoolbox: do not pass AVCodecContext to decoder output callback
-- lavc/pthread_frame: always transfer stashed hwaccel state
-- avcodec/arm/sbcenc: avoid callee preserved vfp registers
-- avformat/riffdec: don't unconditionally overwrite WAVEFORMATEXTENSIBLE layout
-- avfilter/vf_scale: overwrite the width and height expressions with the original values
-- lavc/pthread_frame: avoid leaving stale hwaccel state in worker threads
-- avutil/tests/.gitignore: Add channel_layout testtool
-
-
-version 5.1.1:
-- avformat/asfdec_o: limit recursion depth in asf_read_unknown()
-- avformat/mov: Check count sums in build_open_gop_key_points()
-- doc/git-howto.texi: Document commit signing
-- libavcodec/8bps: Check that line lengths fit within the buffer
-- avcodec/midivid: Perform lzss_uncompress() before ff_reget_buffer()
-- libavformat/iff: Check for overflow in body_end calculation
-- avformat/avidec: Prevent entity expansion attacks
-- avcodec/h263dec: Sanity check against minimal I/P frame size
-- avcodec/hevcdec: Check s->ref in the md5 path similar to hwaccel
-- avcodec/mpegaudiodec_template: use unsigned shift in handle_crc()
-- avformat/subviewerdec: Make read_ts() more flexible
-- avcodec/mjpegdec: bayer and rct are incompatible
-- MAINTAINERS: Add ED25519 key for signing my commits in the future
-- avcodec/pngdec: Fix APNG_DISPOSE_OP_BACKGROUND
-- avcodec/libvpx: fix assembling vp9 packets with alpha channel
-- fftools/ffmpeg_opt: try to propagate the requested output channel layout
-- avcodec/libsvtav1: properly initialize the flush EbBufferHeaderType struct
-- configure: enable the av1_frame_split bsf for the av1 decoder
-- swresample/swresample: fill the correct buffer to print the output layout string
-- ffprobe: restore reporting error code for failed inputs
-- ipfsgateway: Remove default gateway
-- avcodec/libspeexdec: Fix use of uninitialized value
-- avformat/avisynth: use ch_layout.nb_channels for channel count
-- fate/lavf-image: Disable file checksums for exr tests
-- tests/fate-run: Allow to skip file checksums for lavf_image
-- fate/imf: Rename IMF fate-target
-- avcodec/alac: don't fail if channels aren't set during init() when extradata is valid
-- configure: properly require libx264 if enabled
+version 6.0:
+- Radiance HDR image support
+- ddagrab (Desktop Duplication) video capture filter
+- ffmpeg -shortest_buf_duration option
+- ffmpeg now requires threading to be built
+- ffmpeg now runs every muxer in a separate thread
+- Add new mode to cropdetect filter to detect crop-area based on motion vectors and edges
+- VAAPI decoding and encoding for 10/12bit 422, 10/12bit 444 HEVC and VP9
+- WBMP (Wireless Application Protocol Bitmap) image format
+- a3dscope filter
+- bonk decoder and demuxer
+- Micronas SC-4 audio decoder
+- LAF demuxer
+- APAC decoder and demuxer
+- Media 100i decoders
+- DTS to PTS reorder bsf
+- ViewQuest VQC decoder
+- backgroundkey filter
+- nvenc AV1 encoding support
+- MediaCodec decoder via NDKMediaCodec
+- MediaCodec encoder
+- oneVPL support for QSV
+- QSV AV1 encoder
+- QSV decoding and encoding for 10/12bit 422, 10/12bit 444 HEVC and VP9
+- showcwt multimedia filter
+- corr video filter
+- adrc audio filter
+- afdelaysrc audio filter
+- WADY DPCM decoder and demuxer
+- CBD2 DPCM decoder
+- ssim360 video filter
+- ffmpeg CLI new options: -stats_enc_pre[_fmt], -stats_enc_post[_fmt],
+ -stats_mux_pre[_fmt]
+- hstack_vaapi, vstack_vaapi and xstack_vaapi filters
+- XMD ADPCM decoder and demuxer
+- media100 to mjpegb bsf
+- ffmpeg CLI new option: -fix_sub_duration_heartbeat
+- WavArc decoder and demuxer
+- CrystalHD decoders deprecated
+- SDNS demuxer
+- RKA decoder and demuxer
+- filtergraph syntax in ffmpeg CLI now supports passing file contents
+ as option values, by prefixing option name with '/'
+- hstack_qsv, vstack_qsv and xstack_qsv filters
version 5.1:
-- add ipfs/ipns protocol support
+- add ipfs/ipns gateway support
- dialogue enhance audio filter
- dropped obsolete XvMC hwaccel
- pcm-bluray encoder
@@ -102,6 +71,7 @@ version 5.1:
- PHM image format support
- remap_opencl filter
- added chromakey_cuda filter
+- added bilateral_cuda filter
version 5.0:
diff --git a/MAINTAINERS b/MAINTAINERS
index 499f6ad0d..854ccc3fa 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11,17 +11,11 @@ A (CC
) after the name means that the maintainer prefers to be CC-ed on
patches and related discussions.
-Project Leader
-==============
-
- final design decisions
-
-
Applications
============
ffmpeg:
- ffmpeg.c Michael Niedermayer
+ ffmpeg.c Michael Niedermayer, Anton Khirnov
ffplay:
ffplay.c Marton Balint
@@ -40,7 +34,8 @@ Miscellaneous Areas
===================
documentation Stefano Sabatini, Mike Melanson, Timothy Gu, Gyan Doshi
-project server Árpád Gereöffy, Michael Niedermayer, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov
+project server day to day operations Árpád Gereöffy, Michael Niedermayer, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov
+project server emergencies Árpád Gereöffy, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov
presets Robert Swain
metadata subsystem Aurelien Jacobs
release management Michael Niedermayer
@@ -115,8 +110,6 @@ Generic Parts:
lzw.* Michael Niedermayer
floating point AAN DCT:
faandct.c, faandct.h Michael Niedermayer
- Non-power-of-two MDCT:
- mdct15.c, mdct15.h Rostislav Pehlivanov
Golomb coding:
golomb.c, golomb.h Michael Niedermayer
motion estimation:
@@ -141,6 +134,7 @@ Codecs:
adpcm.c Zane van Iperen
alacenc.c Jaikrishnan Menon
alsdec.c Thilo Borgmann, Umair Khan
+ amfenc* Dmitrii Ovchinnikov
aptx.c Aurelien Jacobs
ass* Aurelien Jacobs
asv* Michael Niedermayer
@@ -157,7 +151,6 @@ Codecs:
ccaption_dec.c Anshul Maheshwari, Aman Gupta
cljr Alex Beregszaszi
cpia.c Stephan Hilb
- crystalhd.c Philip Langdale
cscd.c Reimar Doeffinger
cuviddec.c Timo Rothenpieler
dca* foo86
@@ -271,7 +264,6 @@ Codecs:
xwd* Paul B Mahol
Hardware acceleration:
- crystalhd.c Philip Langdale
dxva2* Hendrik Leppkes, Laurent Aimar, Steve Lhomme
d3d11va* Steve Lhomme
mediacodec* Matthieu Bouron, Aman Gupta
@@ -435,6 +427,7 @@ Muxers/Demuxers:
idcin.c Mike Melanson
idroqdec.c Mike Melanson
iff.c Jaikrishnan Menon
+ imf* Pierre-Anthony Lemieux
img2*.c Michael Niedermayer
ipmovie.c Mike Melanson
ircam* Paul B Mahol
@@ -632,6 +625,7 @@ Nikolay Aleksandrov 8978 1D8C FB71 588E 4B27 EAA8 C4F0 B5FC E011 13B1
Panagiotis Issaris 6571 13A3 33D9 3726 F728 AA98 F643 B12E ECF3 E029
Peter Ross A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B
Philip Langdale 5DC5 8D66 5FBA 3A43 18EC 045E F8D6 B194 6A75 682E
+Pierre-Anthony Lemieux (pal) F4B3 9492 E6F2 E4AF AEC8 46CB 698F A1F0 F8D4 EED4
Ramiro Polla 7859 C65B 751B 1179 792E DAE8 8E95 8B2F 9B6C 5700
Reimar Doeffinger C61D 16E5 9E2C D10C 8958 38A4 0899 A2B9 06D4 D9C7
Reinhard Tartler 9300 5DC2 7E87 6C37 ED7B CA9A 9808 3544 9453 48A4
diff --git a/Makefile b/Makefile
index 61f79e27a..1fb742f39 100644
--- a/Makefile
+++ b/Makefile
@@ -91,7 +91,7 @@ ffbuild/.config: $(CONFIGURABLE_COMPONENTS)
SUBDIR_VARS := CLEANFILES FFLIBS HOSTPROGS TESTPROGS TOOLS \
HEADERS ARCH_HEADERS BUILT_HEADERS SKIPHEADERS \
ARMV5TE-OBJS ARMV6-OBJS ARMV8-OBJS VFP-OBJS NEON-OBJS \
- ALTIVEC-OBJS VSX-OBJS MMX-OBJS X86ASM-OBJS \
+ ALTIVEC-OBJS VSX-OBJS RVV-OBJS MMX-OBJS X86ASM-OBJS \
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSP-OBJS MSA-OBJS \
MMI-OBJS LSX-OBJS LASX-OBJS OBJS SLIBOBJS SHLIBOBJS \
STLIBOBJS HOSTOBJS TESTOBJS
diff --git a/RELEASE b/RELEASE
index 61fcc8735..e0ea36fee 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1 +1 @@
-5.1.2
+6.0
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index afc063161..ad1c6d775 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -1,13 +1,10 @@
┌────────────────────────────────────────────┐
- │ RELEASE NOTES for FFmpeg 5.1 "Riemann" LTS │
+ │ RELEASE NOTES for FFmpeg 6.0 "Von Neumann" │
└────────────────────────────────────────────┘
- The FFmpeg Project proudly presents FFmpeg 5.1 "Riemann" LTS, about 6
- months after the release of FFmpeg 5.0, our first Long Term Support
- release. While several past FFmpeg releases have enjoyed long term
- support, this is the first release where such an intention is made
- clear at release.
+ The FFmpeg Project proudly presents FFmpeg 6.0 "Von Neumann", about 6
+ months after the release of FFmpeg 5.1.
A complete Changelog is available at the root of the project, and the
complete Git history on https://git.ffmpeg.org/gitweb/ffmpeg.git
diff --git a/VERSION b/VERSION
index 61fcc8735..e0ea36fee 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-5.1.2
+6.0
diff --git a/compat/cuda/cuda_runtime.h b/compat/cuda/cuda_runtime.h
index 5837c1ad3..699c4b6c7 100644
--- a/compat/cuda/cuda_runtime.h
+++ b/compat/cuda/cuda_runtime.h
@@ -187,5 +187,6 @@ static inline __device__ float __saturatef(float a) { return __nvvm_saturate_f(a
static inline __device__ float __sinf(float a) { return __nvvm_sin_approx_f(a); }
static inline __device__ float __cosf(float a) { return __nvvm_cos_approx_f(a); }
static inline __device__ float __expf(float a) { return __nvvm_ex2_approx_f(a * (float)__builtin_log2(__builtin_exp(1))); }
+static inline __device__ float __powf(float a, float b) { return __nvvm_ex2_approx_f(__nvvm_lg2_approx_f(a) * b); }
#endif /* COMPAT_CUDA_CUDA_RUNTIME_H */
diff --git a/compat/cuda/ptx2c.sh b/compat/cuda/ptx2c.sh
deleted file mode 100755
index 48452379c..000000000
--- a/compat/cuda/ptx2c.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
-#
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the "Software"),
-# to deal in the Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish, distribute, sublicense,
-# and/or sell copies of the Software, and to permit persons to whom the
-# Software is furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-# DEALINGS IN THE SOFTWARE.
-
-set -e
-
-OUT="$1"
-IN="$2"
-NAME="$(basename "$IN" | sed 's/\..*//')"
-
-printf "const char %s_ptx[] = \\" "$NAME" > "$OUT"
-echo >> "$OUT"
-sed -e "$(printf 's/\r//g')" -e 's/["\\]/\\&/g' -e "$(printf 's/^/\t"/')" -e 's/$/\\n"/' < "$IN" >> "$OUT"
-echo ";" >> "$OUT"
-
-exit 0
diff --git a/compat/windows/mswindres b/compat/windows/mswindres
new file mode 100755
index 000000000..8c14c96ba
--- /dev/null
+++ b/compat/windows/mswindres
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+if [ "$1" = "--version" ]; then
+ rc.exe -?
+ exit $?
+fi
+
+if [ $# -lt 2 ]; then
+ echo "Usage: mswindres [-I/include/path ...] [-DSOME_DEFINE ...] [-o output.o] input.rc [output.o]" >&2
+ exit 0
+fi
+
+EXTRA_OPTS="-nologo"
+
+while [ $# -gt 2 ]; do
+ case $1 in
+ -D*) EXTRA_OPTS="$EXTRA_OPTS -d$(echo $1 | sed -e "s/^..//" -e "s/ /\\\\ /g")" ;;
+ -I*) EXTRA_OPTS="$EXTRA_OPTS -i$(echo $1 | sed -e "s/^..//" -e "s/ /\\\\ /g")" ;;
+ -o) OPT_OUT="$2"; shift ;;
+ esac
+ shift
+done
+
+IN="$1"
+if [ -z "$OPT_OUT" ]; then
+ OUT="$2"
+else
+ OUT="$OPT_OUT"
+fi
+
+eval set -- $EXTRA_OPTS
+rc.exe "$@" -fo "$OUT" "$IN"
diff --git a/configure b/configure
index ba5793b2f..b6616f00b 100755
--- a/configure
+++ b/configure
@@ -341,6 +341,7 @@ External library support:
--disable-ffnvcodec disable dynamically linked Nvidia code [autodetect]
--enable-libdrm enable DRM code (Linux) [no]
--enable-libmfx enable Intel MediaSDK (AKA Quick Sync Video) code via libmfx [no]
+ --enable-libvpl enable Intel oneVPL code via libvpl if libmfx is not used [no]
--enable-libnpp enable Nvidia Performance Primitives-based code [no]
--enable-mmal enable Broadcom Multi-Media Abstraction Layer (Raspberry Pi) via MMAL [no]
--disable-nvdec disable Nvidia video decoding acceleration (via hwaccel) [autodetect]
@@ -461,6 +462,7 @@ Optimization options (experts only):
--disable-mmi disable Loongson MMI optimizations
--disable-lsx disable Loongson LSX optimizations
--disable-lasx disable Loongson LASX optimizations
+ --disable-rvv disable RISC-V Vector optimizations
--disable-fast-unaligned consider unaligned accesses slow
Developer options (useful when working on FFmpeg itself):
@@ -1315,21 +1317,6 @@ int main(void){ $func(); }
EOF
}
-check_complexfunc(){
- log check_complexfunc "$@"
- func=$1
- narg=$2
- shift 2
- test $narg = 2 && args="f, g" || args="f * I"
- disable $func
- test_ld "cc" "$@" <
-#include
-float foo(complex float f, complex float g) { return $func($args); }
-int main(void){ return (int) foo; }
-EOF
-}
-
check_mathfunc(){
log check_mathfunc "$@"
func=$1
@@ -1723,29 +1710,30 @@ COMPONENT_LIST="
"
EXAMPLE_LIST="
+ avio_http_serve_files_example
avio_list_dir_example
- avio_reading_example
+ avio_read_callback_example
decode_audio_example
+ decode_filter_audio_example
+ decode_filter_video_example
decode_video_example
- demuxing_decoding_example
+ demux_decode_example
encode_audio_example
encode_video_example
extract_mvs_example
filter_audio_example
- filtering_audio_example
- filtering_video_example
- http_multiclient_example
hw_decode_example
- metadata_example
- muxing_example
- qsvdec_example
- remuxing_example
- resampling_audio_example
- scaling_video_example
+ mux_example
+ qsv_decode_example
+ remux_example
+ resample_audio_example
+ scale_video_example
+ show_metadata_example
transcode_aac_example
- transcoding_example
+ transcode_example
vaapi_encode_example
vaapi_transcode_example
+ qsv_transcode_example
"
EXTERNAL_AUTODETECT_LIBRARY_LIST="
@@ -1921,6 +1909,7 @@ HWACCEL_LIBRARY_NONFREE_LIST="
HWACCEL_LIBRARY_LIST="
$HWACCEL_LIBRARY_NONFREE_LIST
libmfx
+ libvpl
mmal
omx
opencl
@@ -2124,6 +2113,10 @@ ARCH_EXT_LIST_PPC="
vsx
"
+ARCH_EXT_LIST_RISCV="
+ rvv
+"
+
ARCH_EXT_LIST_X86="
$ARCH_EXT_LIST_X86_SIMD
cpunop
@@ -2133,6 +2126,7 @@ ARCH_EXT_LIST_X86="
ARCH_EXT_LIST="
$ARCH_EXT_LIST_ARM
$ARCH_EXT_LIST_PPC
+ $ARCH_EXT_LIST_RISCV
$ARCH_EXT_LIST_X86
$ARCH_EXT_LIST_MIPS
$ARCH_EXT_LIST_LOONGSON
@@ -2143,6 +2137,7 @@ ARCH_FEATURES="
fast_64bit
fast_clz
fast_cmov
+ fast_float16
local_aligned
simd_align_16
simd_align_32
@@ -2215,11 +2210,6 @@ INTRINSICS_LIST="
intrinsics_neon
"
-COMPLEX_FUNCS="
- cabs
- cexp
-"
-
MATH_FUNCS="
atanf
atan2f
@@ -2301,6 +2291,7 @@ SYSTEM_FUNCS="
nanosleep
PeekNamedPipe
posix_memalign
+ prctl
pthread_cancel
sched_getaffinity
SecItemImport
@@ -2352,6 +2343,8 @@ TOOLCHAIN_FEATURES="
"
TYPES_LIST="
+ DPI_AWARENESS_CONTEXT
+ IDXGIOutput5
kCMVideoCodecType_HEVC
kCMVideoCodecType_HEVCWithAlpha
kCMVideoCodecType_VP9
@@ -2391,7 +2384,6 @@ HAVE_LIST="
$(add_suffix _inline $ARCH_EXT_LIST)
$ARCH_FEATURES
$BUILTIN_LIST
- $COMPLEX_FUNCS
$HAVE_LIST_CMDLINE
$HAVE_LIST_PUB
$HEADERS_LIST
@@ -2447,7 +2439,6 @@ CONFIG_EXTRA="
faandct
faanidct
fdctdsp
- flacdsp
fmtconvert
frame_thread_encoder
g722dsp
@@ -2459,14 +2450,15 @@ CONFIG_EXTRA="
h264parse
h264pred
h264qpel
+ h264_sei
hevcparse
+ hevc_sei
hpeldsp
huffman
huffyuvdsp
huffyuvencdsp
idctdsp
iirfilter
- mdct15
inflate_wrapper
intrax8
iso_media
@@ -2488,6 +2480,8 @@ CONFIG_EXTRA="
mpegvideo
mpegvideodec
mpegvideoenc
+ msmpeg4dec
+ msmpeg4enc
mss34dsp
pixblockdsp
qpeldsp
@@ -2636,6 +2630,8 @@ ppc4xx_deps="ppc"
vsx_deps="altivec"
power8_deps="vsx"
+rvv_deps="riscv"
+
loongson2_deps="mips"
loongson3_deps="mips"
mmi_deps_any="loongson2 loongson3"
@@ -2728,35 +2724,39 @@ faandct_select="fdctdsp"
faanidct_deps="faan"
faanidct_select="idctdsp"
h264dsp_select="startcode"
-hevcparse_select="atsc_a53 golomb"
+h264_sei_select="atsc_a53 golomb"
+hevcparse_select="golomb"
+hevc_sei_select="atsc_a53 golomb"
frame_thread_encoder_deps="encoders threads"
inflate_wrapper_deps="zlib"
-intrax8_select="blockdsp idctdsp"
+intrax8_select="blockdsp wmv2dsp"
iso_media_select="mpeg4audio"
mdct_select="fft"
-mdct15_select="fft"
-me_cmp_select="fdctdsp idctdsp pixblockdsp"
+me_cmp_select="idctdsp"
mpeg_er_select="error_resilience"
mpegaudio_select="mpegaudiodsp mpegaudioheader"
mpegaudiodsp_select="dct"
-mpegvideo_select="blockdsp h264chroma hpeldsp idctdsp videodsp"
-mpegvideodec_select="mpegvideo mpeg_er"
-mpegvideoenc_select="aandcttables me_cmp mpegvideo pixblockdsp qpeldsp"
+mpegvideo_select="blockdsp hpeldsp idctdsp videodsp"
+mpegvideodec_select="h264chroma mpegvideo mpeg_er"
+mpegvideoenc_select="aandcttables fdctdsp me_cmp mpegvideo pixblockdsp"
+msmpeg4dec_select="h263_decoder"
+msmpeg4enc_select="h263_encoder"
vc1dsp_select="h264chroma qpeldsp startcode"
rdft_select="fft"
# decoders / encoders
-aac_decoder_select="adts_header mdct15 mdct mpeg4audio sinewin"
-aac_fixed_decoder_select="adts_header mdct mpeg4audio"
-aac_encoder_select="audio_frame_queue iirfilter lpc mdct sinewin"
+aac_decoder_select="adts_header mpeg4audio sinewin"
+aac_fixed_decoder_select="adts_header mpeg4audio"
+aac_encoder_select="audio_frame_queue iirfilter lpc sinewin"
aac_latm_decoder_select="aac_decoder aac_latm_parser"
-ac3_decoder_select="ac3_parser ac3dsp bswapdsp fmtconvert mdct"
-ac3_fixed_decoder_select="ac3_parser ac3dsp bswapdsp mdct"
-ac3_encoder_select="ac3dsp audiodsp mdct me_cmp"
-ac3_fixed_encoder_select="ac3dsp audiodsp mdct me_cmp"
+ac3_decoder_select="ac3_parser ac3dsp bswapdsp fmtconvert"
+ac3_fixed_decoder_select="ac3_parser ac3dsp bswapdsp"
+ac3_encoder_select="ac3dsp audiodsp me_cmp"
+ac3_fixed_encoder_select="ac3dsp audiodsp me_cmp"
acelp_kelvin_decoder_select="audiodsp"
adpcm_g722_decoder_select="g722dsp"
adpcm_g722_encoder_select="g722dsp"
+agm_decoder_select="idctdsp"
aic_decoder_select="golomb idctdsp"
alac_encoder_select="lpc"
als_decoder_select="bswapdsp mpeg4audio"
@@ -2767,47 +2767,37 @@ amv_encoder_select="jpegtables mpegvideoenc"
ape_decoder_select="bswapdsp llauddsp"
apng_decoder_select="inflate_wrapper"
apng_encoder_select="deflate_wrapper llvidencdsp"
-aptx_decoder_select="audio_frame_queue"
aptx_encoder_select="audio_frame_queue"
-aptx_hd_decoder_select="audio_frame_queue"
aptx_hd_encoder_select="audio_frame_queue"
asv1_decoder_select="blockdsp bswapdsp idctdsp"
asv1_encoder_select="aandcttables bswapdsp fdctdsp pixblockdsp"
asv2_decoder_select="blockdsp bswapdsp idctdsp"
asv2_encoder_select="aandcttables bswapdsp fdctdsp pixblockdsp"
-atrac1_decoder_select="mdct sinewin"
-atrac3_decoder_select="mdct"
-atrac3al_decoder_select="mdct"
-atrac3p_decoder_select="mdct sinewin"
-atrac3pal_decoder_select="mdct sinewin"
-atrac9_decoder_select="mdct"
+atrac1_decoder_select="sinewin"
av1_decoder_select="av1_frame_split_bsf cbs_av1"
bink_decoder_select="blockdsp hpeldsp"
-binkaudio_dct_decoder_select="mdct rdft dct sinewin wma_freqs"
-binkaudio_rdft_decoder_select="mdct rdft sinewin wma_freqs"
+binkaudio_dct_decoder_select="wma_freqs"
+binkaudio_rdft_decoder_select="wma_freqs"
cavs_decoder_select="blockdsp golomb h264chroma idctdsp qpeldsp videodsp"
clearvideo_decoder_select="idctdsp"
cllc_decoder_select="bswapdsp"
comfortnoise_encoder_select="lpc"
-cook_decoder_select="audiodsp mdct sinewin"
+cook_decoder_select="audiodsp sinewin"
cri_decoder_select="mjpeg_decoder"
cscd_decoder_suggest="zlib"
-dca_decoder_select="mdct"
-dca_encoder_select="mdct"
dds_decoder_select="texturedsp"
dirac_decoder_select="dirac_parse dwt golomb videodsp mpegvideoenc"
dnxhd_decoder_select="blockdsp idctdsp"
-dnxhd_encoder_select="blockdsp fdctdsp idctdsp mpegvideoenc pixblockdsp"
-dolby_e_decoder_select="mdct"
+dnxhd_encoder_select="blockdsp fdctdsp idctdsp mpegvideoenc pixblockdsp videodsp"
dvvideo_decoder_select="dvprofile idctdsp"
dvvideo_encoder_select="dvprofile fdctdsp me_cmp pixblockdsp"
dxa_decoder_deps="zlib"
dxv_decoder_select="lzf texturedsp"
eac3_decoder_select="ac3_decoder"
eac3_encoder_select="ac3_encoder"
-eamad_decoder_select="aandcttables blockdsp bswapdsp idctdsp mpegvideo"
+eamad_decoder_select="aandcttables blockdsp bswapdsp"
eatgq_decoder_select="aandcttables"
-eatqi_decoder_select="aandcttables blockdsp bswapdsp idctdsp"
+eatqi_decoder_select="aandcttables blockdsp bswapdsp"
exr_decoder_deps="zlib"
exr_encoder_deps="zlib"
ffv1_decoder_select="rangecoder"
@@ -2815,8 +2805,7 @@ ffv1_encoder_select="rangecoder"
ffvhuff_decoder_select="huffyuv_decoder"
ffvhuff_encoder_select="huffyuv_encoder"
fic_decoder_select="golomb"
-flac_decoder_select="flacdsp"
-flac_encoder_select="bswapdsp flacdsp lpc"
+flac_encoder_select="bswapdsp lpc"
flashsv2_decoder_select="inflate_wrapper"
flashsv2_encoder_select="deflate_wrapper"
flashsv_decoder_select="inflate_wrapper"
@@ -2835,18 +2824,18 @@ h263_encoder_select="h263dsp mpegvideoenc"
h263i_decoder_select="h263_decoder"
h263p_decoder_select="h263_decoder"
h263p_encoder_select="h263_encoder"
-h264_decoder_select="atsc_a53 cabac golomb h264chroma h264dsp h264parse h264pred h264qpel videodsp"
+h264_decoder_select="cabac golomb h264chroma h264dsp h264parse h264pred h264qpel h264_sei videodsp"
h264_decoder_suggest="error_resilience"
hap_decoder_select="snappy texturedsp"
hap_encoder_deps="libsnappy"
hap_encoder_select="texturedspenc"
-hevc_decoder_select="atsc_a53 bswapdsp cabac dovi_rpu golomb hevcparse videodsp"
+hevc_decoder_select="bswapdsp cabac dovi_rpu golomb hevcparse hevc_sei videodsp"
huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp"
huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llvidencdsp"
hymt_decoder_select="huffyuv_decoder"
iac_decoder_select="imc_decoder"
-imc_decoder_select="bswapdsp fft mdct sinewin"
-imm4_decoder_select="bswapdsp"
+imc_decoder_select="bswapdsp sinewin"
+imm4_decoder_select="bswapdsp idctdsp"
imm5_decoder_select="h264_decoder hevc_decoder"
indeo3_decoder_select="hpeldsp"
indeo4_decoder_select="ividsp"
@@ -2856,12 +2845,13 @@ ipu_decoder_select="mpegvideodec"
jpegls_decoder_select="mjpeg_decoder"
jv_decoder_select="blockdsp"
lagarith_decoder_select="llviddsp"
-ljpeg_encoder_select="idctdsp jpegtables"
+ljpeg_encoder_select="jpegtables"
lscr_decoder_select="inflate_wrapper"
magicyuv_decoder_select="llviddsp"
magicyuv_encoder_select="llvidencdsp"
-mdec_decoder_select="blockdsp bswapdsp idctdsp mpegvideo"
-metasound_decoder_select="lsp mdct sinewin"
+mdec_decoder_select="blockdsp bswapdsp idctdsp"
+media100_decoder_select="media100_to_mjpegb_bsf mjpegb_decoder"
+metasound_decoder_select="lsp sinewin"
mimic_decoder_select="blockdsp bswapdsp hpeldsp idctdsp"
mjpeg_decoder_select="blockdsp hpeldsp exif idctdsp jpegtables"
mjpeg_encoder_select="jpegtables mpegvideoenc"
@@ -2884,45 +2874,44 @@ mpc7_decoder_select="bswapdsp mpegaudiodsp"
mpc8_decoder_select="mpegaudiodsp"
mpegvideo_decoder_select="mpegvideodec"
mpeg1video_decoder_select="mpegvideodec"
-mpeg1video_encoder_select="mpegvideoenc h263dsp"
+mpeg1video_encoder_select="mpegvideoenc"
mpeg2video_decoder_select="mpegvideodec"
-mpeg2video_encoder_select="mpegvideoenc h263dsp"
+mpeg2video_encoder_select="mpegvideoenc"
mpeg4_decoder_select="h263_decoder mpeg4video_parser"
-mpeg4_encoder_select="h263_encoder"
+mpeg4_encoder_select="h263_encoder qpeldsp"
msa1_decoder_select="mss34dsp"
mscc_decoder_select="inflate_wrapper"
-msmpeg4v1_decoder_select="h263_decoder"
-msmpeg4v2_decoder_select="h263_decoder"
-msmpeg4v2_encoder_select="h263_encoder"
-msmpeg4v3_decoder_select="h263_decoder"
-msmpeg4v3_encoder_select="h263_encoder"
+msmpeg4v1_decoder_select="msmpeg4dec"
+msmpeg4v2_decoder_select="msmpeg4dec"
+msmpeg4v2_encoder_select="msmpeg4enc"
+msmpeg4v3_decoder_select="msmpeg4dec"
+msmpeg4v3_encoder_select="msmpeg4enc"
mss2_decoder_select="mpegvideodec qpeldsp vc1_decoder"
mts2_decoder_select="jpegtables mss34dsp"
mv30_decoder_select="aandcttables blockdsp"
mvha_decoder_select="inflate_wrapper llviddsp"
mwsc_decoder_select="inflate_wrapper"
mxpeg_decoder_select="mjpeg_decoder"
-nellymoser_decoder_select="mdct sinewin"
-nellymoser_encoder_select="audio_frame_queue mdct sinewin"
+nellymoser_decoder_select="sinewin"
+nellymoser_encoder_select="audio_frame_queue sinewin"
notchlc_decoder_select="lzf"
nuv_decoder_select="idctdsp"
-on2avc_decoder_select="mdct"
opus_decoder_deps="swresample"
-opus_decoder_select="mdct15"
-opus_encoder_select="audio_frame_queue mdct15"
+opus_encoder_select="audio_frame_queue"
png_decoder_select="inflate_wrapper"
png_encoder_select="deflate_wrapper llvidencdsp"
prores_decoder_select="blockdsp idctdsp"
prores_encoder_select="fdctdsp"
+prores_aw_encoder_select="fdctdsp"
+prores_ks_encoder_select="fdctdsp"
qcelp_decoder_select="lsp"
-qdm2_decoder_select="mdct rdft mpegaudiodsp"
+qdm2_decoder_select="mpegaudiodsp"
ra_144_decoder_select="audiodsp"
ra_144_encoder_select="audio_frame_queue lpc audiodsp"
ralf_decoder_select="golomb"
rasc_decoder_select="inflate_wrapper"
rawvideo_decoder_select="bswapdsp"
rscc_decoder_deps="zlib"
-rtjpeg_decoder_select="me_cmp"
rv10_decoder_select="h263_decoder"
rv10_encoder_select="h263_encoder"
rv20_decoder_select="h263_decoder"
@@ -2933,13 +2922,13 @@ screenpresso_decoder_deps="zlib"
shorten_decoder_select="bswapdsp"
sipr_decoder_select="lsp"
smvjpeg_decoder_select="mjpeg_decoder"
-snow_decoder_select="dwt h264qpel hpeldsp me_cmp rangecoder videodsp"
-snow_encoder_select="dwt h264qpel hpeldsp me_cmp mpegvideoenc rangecoder"
+snow_decoder_select="dwt h264qpel hpeldsp rangecoder videodsp"
+snow_encoder_select="dwt h264qpel hpeldsp me_cmp mpegvideoenc rangecoder videodsp"
sonic_decoder_select="golomb rangecoder"
sonic_encoder_select="golomb rangecoder"
sonic_ls_encoder_select="golomb rangecoder"
sp5x_decoder_select="mjpeg_decoder"
-speedhq_decoder_select="mpegvideo"
+speedhq_decoder_select="blockdsp idctdsp"
speedhq_encoder_select="mpegvideoenc"
srgc_decoder_select="inflate_wrapper"
svq1_decoder_select="hpeldsp"
@@ -2959,17 +2948,16 @@ truehd_encoder_select="lpc audio_frame_queue"
truemotion2_decoder_select="bswapdsp"
truespeech_decoder_select="bswapdsp"
tscc_decoder_select="inflate_wrapper"
-twinvq_decoder_select="mdct lsp sinewin"
+twinvq_decoder_select="lsp sinewin"
txd_decoder_select="texturedsp"
utvideo_decoder_select="bswapdsp llviddsp"
utvideo_encoder_select="bswapdsp huffman llvidencdsp"
vble_decoder_select="llviddsp"
vbn_decoder_select="texturedsp"
vbn_encoder_select="texturedspenc"
-vc1_decoder_select="blockdsp h263_decoder h264qpel intrax8 mpegvideodec vc1dsp"
+vc1_decoder_select="blockdsp h264qpel intrax8 mpegvideodec qpeldsp vc1dsp"
vc1image_decoder_select="vc1_decoder"
-vorbis_decoder_select="mdct"
-vorbis_encoder_select="audio_frame_queue mdct"
+vorbis_encoder_select="audio_frame_queue"
vp3_decoder_select="hpeldsp vp3dsp videodsp"
vp4_decoder_select="vp3_decoder"
vp5_decoder_select="h264chroma hpeldsp videodsp vp3dsp vp56dsp"
@@ -2982,16 +2970,16 @@ vp9_decoder_select="videodsp vp9_parser vp9_superframe_split_bsf"
wcmv_decoder_select="inflate_wrapper"
webp_decoder_select="vp8_decoder exif"
wmalossless_decoder_select="llauddsp"
-wmapro_decoder_select="mdct sinewin wma_freqs"
-wmav1_decoder_select="mdct sinewin wma_freqs"
-wmav1_encoder_select="mdct sinewin wma_freqs"
-wmav2_decoder_select="mdct sinewin wma_freqs"
-wmav2_encoder_select="mdct sinewin wma_freqs"
-wmavoice_decoder_select="lsp rdft dct mdct sinewin"
-wmv1_decoder_select="h263_decoder"
-wmv1_encoder_select="h263_encoder"
-wmv2_decoder_select="blockdsp error_resilience h263_decoder idctdsp intrax8 videodsp wmv2dsp"
-wmv2_encoder_select="h263_encoder wmv2dsp"
+wmapro_decoder_select="sinewin wma_freqs"
+wmav1_decoder_select="sinewin wma_freqs"
+wmav1_encoder_select="sinewin wma_freqs"
+wmav2_decoder_select="sinewin wma_freqs"
+wmav2_encoder_select="sinewin wma_freqs"
+wmavoice_decoder_select="lsp rdft dct sinewin"
+wmv1_decoder_select="msmpeg4dec"
+wmv1_encoder_select="msmpeg4enc"
+wmv2_decoder_select="blockdsp error_resilience idctdsp intrax8 msmpeg4dec videodsp wmv2dsp"
+wmv2_encoder_select="msmpeg4enc wmv2dsp"
wmv3_decoder_select="vc1_decoder"
wmv3image_decoder_select="wmv3_decoder"
xma1_decoder_select="wmapro_decoder"
@@ -3142,8 +3130,12 @@ qsvvpp_select="qsv"
vaapi_encode_deps="vaapi"
v4l2_m2m_deps="linux_videodev2_h sem_timedwait"
+bilateral_cuda_filter_deps="ffnvcodec"
+bilateral_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
chromakey_cuda_filter_deps="ffnvcodec"
chromakey_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
+colorspace_cuda_filter_deps="ffnvcodec"
+colorspace_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
hwupload_cuda_filter_deps="ffnvcodec"
scale_npp_filter_deps="ffnvcodec libnpp"
scale2ref_npp_filter_deps="ffnvcodec libnpp"
@@ -3156,6 +3148,8 @@ overlay_cuda_filter_deps="ffnvcodec"
overlay_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
sharpen_npp_filter_deps="ffnvcodec libnpp"
+ddagrab_filter_deps="d3d11va IDXGIOutput1 DXGI_OUTDUPL_FRAME_INFO"
+
amf_deps_any="libdl LoadLibrary"
nvenc_deps="ffnvcodec"
nvenc_deps_any="libdl LoadLibrary"
@@ -3163,6 +3157,10 @@ nvenc_deps_any="libdl LoadLibrary"
aac_mf_encoder_deps="mediafoundation"
ac3_mf_encoder_deps="mediafoundation"
av1_cuvid_decoder_deps="cuvid CUVIDAV1PICPARAMS"
+av1_mediacodec_decoder_deps="mediacodec"
+av1_mediacodec_decoder_extralibs="-landroid"
+av1_nvenc_encoder_deps="nvenc NV_ENC_PIC_PARAMS_AV1"
+av1_nvenc_encoder_select="atsc_a53"
h263_v4l2m2m_decoder_deps="v4l2_m2m h263_v4l2_m2m"
h263_v4l2m2m_encoder_deps="v4l2_m2m h263_v4l2_m2m"
h264_amf_encoder_deps="amf"
@@ -3170,7 +3168,11 @@ h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser"
h264_cuvid_decoder_deps="cuvid"
h264_cuvid_decoder_select="h264_mp4toannexb_bsf"
h264_mediacodec_decoder_deps="mediacodec"
+h264_mediacodec_decoder_extralibs="-landroid"
h264_mediacodec_decoder_select="h264_mp4toannexb_bsf h264_parser"
+h264_mediacodec_encoder_deps="mediacodec"
+h264_mediacodec_encoder_extralibs="-landroid"
+h264_mediacodec_encoder_select="h264_metadata"
h264_mf_encoder_deps="mediafoundation"
h264_mmal_decoder_deps="mmal"
h264_nvenc_encoder_deps="nvenc"
@@ -3180,7 +3182,7 @@ h264_qsv_decoder_select="h264_mp4toannexb_bsf qsvdec"
h264_qsv_encoder_select="atsc_a53 qsvenc"
h264_rkmpp_decoder_deps="rkmpp"
h264_rkmpp_decoder_select="h264_mp4toannexb_bsf"
-h264_vaapi_encoder_select="cbs_h264 vaapi_encode"
+h264_vaapi_encoder_select="atsc_a53 cbs_h264 vaapi_encode"
h264_v4l2m2m_decoder_deps="v4l2_m2m h264_v4l2_m2m"
h264_v4l2m2m_decoder_select="h264_mp4toannexb_bsf"
h264_v4l2m2m_encoder_deps="v4l2_m2m h264_v4l2_m2m"
@@ -3188,7 +3190,11 @@ hevc_amf_encoder_deps="amf"
hevc_cuvid_decoder_deps="cuvid"
hevc_cuvid_decoder_select="hevc_mp4toannexb_bsf"
hevc_mediacodec_decoder_deps="mediacodec"
+hevc_mediacodec_decoder_extralibs="-landroid"
hevc_mediacodec_decoder_select="hevc_mp4toannexb_bsf hevc_parser"
+hevc_mediacodec_encoder_deps="mediacodec"
+hevc_mediacodec_encoder_extralibs="-landroid"
+hevc_mediacodec_encoder_select="hevc_metadata"
hevc_mf_encoder_deps="mediafoundation"
hevc_nvenc_encoder_deps="nvenc"
hevc_nvenc_encoder_select="atsc_a53"
@@ -3197,7 +3203,7 @@ hevc_qsv_encoder_select="hevcparse qsvenc"
hevc_rkmpp_decoder_deps="rkmpp"
hevc_rkmpp_decoder_select="hevc_mp4toannexb_bsf"
hevc_vaapi_encoder_deps="VAEncPictureParameterBufferHEVC"
-hevc_vaapi_encoder_select="cbs_h265 vaapi_encode"
+hevc_vaapi_encoder_select="atsc_a53 cbs_h265 vaapi_encode"
hevc_v4l2m2m_decoder_deps="v4l2_m2m hevc_v4l2_m2m"
hevc_v4l2m2m_decoder_select="hevc_mp4toannexb_bsf"
hevc_v4l2m2m_encoder_deps="v4l2_m2m hevc_v4l2_m2m"
@@ -3250,14 +3256,16 @@ vp9_qsv_encoder_select="qsvenc"
vp9_v4l2m2m_decoder_deps="v4l2_m2m vp9_v4l2_m2m"
wmv3_crystalhd_decoder_select="crystalhd"
av1_qsv_decoder_select="qsvdec"
+av1_qsv_encoder_select="qsvenc"
+av1_qsv_encoder_deps="libvpl"
+av1_amf_encoder_deps="amf"
# parsers
aac_parser_select="adts_header mpeg4audio"
av1_parser_select="cbs_av1"
-h264_parser_select="atsc_a53 golomb h264dsp h264parse"
-hevc_parser_select="hevcparse"
+h264_parser_select="golomb h264dsp h264parse h264_sei"
+hevc_parser_select="hevcparse hevc_sei"
mpegaudio_parser_select="mpegaudioheader"
-mpegvideo_parser_select="mpegvideo"
mpeg4video_parser_select="h263dsp mpegvideodec qpeldsp"
vc1_parser_select="vc1dsp"
@@ -3266,6 +3274,7 @@ aac_adtstoasc_bsf_select="adts_header mpeg4audio"
av1_frame_merge_bsf_select="cbs_av1"
av1_frame_split_bsf_select="cbs_av1"
av1_metadata_bsf_select="cbs_av1"
+dts2pts_bsf_select="cbs_h264 h264parse"
eac3_core_bsf_select="ac3_parser"
filter_units_bsf_select="cbs"
h264_metadata_bsf_deps="const_nan"
@@ -3360,7 +3369,6 @@ libopus_decoder_deps="libopus"
libopus_encoder_deps="libopus"
libopus_encoder_select="audio_frame_queue"
librav1e_encoder_deps="librav1e"
-librav1e_encoder_select="extract_extradata_bsf"
librsvg_decoder_deps="librsvg"
libshine_encoder_deps="libshine"
libshine_encoder_select="audio_frame_queue mpegaudioheader"
@@ -3387,6 +3395,7 @@ libx264_encoder_select="atsc_a53"
libx264rgb_encoder_deps="libx264"
libx264rgb_encoder_select="libx264_encoder"
libx265_encoder_deps="libx265"
+libx265_encoder_select="atsc_a53"
libxavs_encoder_deps="libxavs"
libxavs2_encoder_deps="libxavs2"
libxvid_encoder_deps="libxvid"
@@ -3427,8 +3436,8 @@ flac_demuxer_select="flac_parser"
flv_muxer_select="aac_adtstoasc_bsf"
gxf_muxer_select="pcm_rechunk_bsf"
hds_muxer_select="flv_muxer"
-hls_demuxer_select="adts_header ac3_parser"
-hls_muxer_select="mpegts_muxer"
+hls_demuxer_select="adts_header ac3_parser mov_demuxer mpegts_demuxer"
+hls_muxer_select="mov_muxer mpegts_muxer"
hls_muxer_suggest="gcrypt openssl"
image2_alias_pix_demuxer_select="image2_demuxer"
image2_brender_pix_demuxer_select="image2_demuxer"
@@ -3521,6 +3530,7 @@ gdigrab_indev_deps="CreateDIBSection"
gdigrab_indev_extralibs="-lgdi32"
gdigrab_indev_select="bmp_decoder"
iec61883_indev_deps="libiec61883"
+iec61883_indev_select="dv_demuxer"
jack_indev_deps="libjack"
jack_indev_deps_any="sem_timedwait dispatch_dispatch_h"
kmsgrab_indev_deps="libdrm"
@@ -3593,8 +3603,8 @@ udp_protocol_select="network"
udplite_protocol_select="network"
unix_protocol_deps="sys_un_h"
unix_protocol_select="network"
-ipfs_protocol_select="https_protocol"
-ipns_protocol_select="https_protocol"
+ipfs_gateway_protocol_select="https_protocol"
+ipns_gateway_protocol_select="https_protocol"
# external library protocols
libamqp_protocol_deps="librabbitmq"
@@ -3625,8 +3635,6 @@ avgblur_vulkan_filter_deps="vulkan spirv_compiler"
azmq_filter_deps="libzmq"
blackframe_filter_deps="gpl"
blend_vulkan_filter_deps="vulkan spirv_compiler"
-bm3d_filter_deps="avcodec"
-bm3d_filter_select="dct"
boxblur_filter_deps="gpl"
boxblur_opencl_filter_deps="opencl gpl"
bs2b_filter_deps="libbs2b"
@@ -3641,6 +3649,7 @@ coreimagesrc_filter_extralibs="-framework OpenGL"
cover_rect_filter_deps="avcodec avformat gpl"
cropdetect_filter_deps="gpl"
deinterlace_qsv_filter_deps="libmfx"
+deinterlace_qsv_filter_select="qsvvpp"
deinterlace_vaapi_filter_deps="vaapi"
delogo_filter_deps="gpl"
denoise_vaapi_filter_deps="vaapi"
@@ -3657,10 +3666,8 @@ elbg_filter_deps="avcodec"
eq_filter_deps="gpl"
erosion_opencl_filter_deps="opencl"
find_rect_filter_deps="avcodec avformat gpl"
-firequalizer_filter_deps="avcodec"
-firequalizer_filter_select="rdft"
flip_vulkan_filter_deps="vulkan spirv_compiler"
-flite_filter_deps="libflite"
+flite_filter_deps="libflite threads"
framerate_filter_select="scene_sad"
freezedetect_filter_select="scene_sad"
frei0r_deps_any="libdl LoadLibrary"
@@ -3717,13 +3724,12 @@ sab_filter_deps="gpl swscale"
scale2ref_filter_deps="swscale"
scale_filter_deps="swscale"
scale_qsv_filter_deps="libmfx"
+scale_qsv_filter_select="qsvvpp"
scdet_filter_select="scene_sad"
select_filter_select="scene_sad"
sharpness_vaapi_filter_deps="vaapi"
showcqt_filter_deps="avformat swscale"
showcqt_filter_suggest="libfontconfig libfreetype"
-showspatial_filter_deps="avcodec"
-showspatial_filter_select="fft"
signature_filter_deps="gpl avcodec avformat"
smartblur_filter_deps="gpl swscale"
sobel_opencl_filter_deps="opencl"
@@ -3763,31 +3769,41 @@ xfade_opencl_filter_deps="opencl"
yadif_cuda_filter_deps="ffnvcodec"
yadif_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
yadif_videotoolbox_filter_deps="metal corevideo videotoolbox"
+hstack_vaapi_filter_deps="vaapi_1"
+vstack_vaapi_filter_deps="vaapi_1"
+xstack_vaapi_filter_deps="vaapi_1"
+hstack_qsv_filter_deps="libmfx"
+hstack_qsv_filter_select="qsvvpp"
+vstack_qsv_filter_deps="libmfx"
+vstack_qsv_filter_select="qsvvpp"
+xstack_qsv_filter_deps="libmfx"
+xstack_qsv_filter_select="qsvvpp"
# examples
+avio_http_serve_files_deps="avformat avutil fork"
avio_list_dir_deps="avformat avutil"
-avio_reading_deps="avformat avcodec avutil"
+avio_read_callback_deps="avformat avcodec avutil"
decode_audio_example_deps="avcodec avutil"
+decode_filter_audio_example_deps="avfilter avcodec avformat avutil"
+decode_filter_video_example_deps="avfilter avcodec avformat avutil"
decode_video_example_deps="avcodec avutil"
-demuxing_decoding_example_deps="avcodec avformat avutil"
+demux_decode_example_deps="avcodec avformat avutil"
encode_audio_example_deps="avcodec avutil"
encode_video_example_deps="avcodec avutil"
extract_mvs_example_deps="avcodec avformat avutil"
filter_audio_example_deps="avfilter avutil"
-filtering_audio_example_deps="avfilter avcodec avformat avutil"
-filtering_video_example_deps="avfilter avcodec avformat avutil"
-http_multiclient_example_deps="avformat avutil fork"
hw_decode_example_deps="avcodec avformat avutil"
-metadata_example_deps="avformat avutil"
-muxing_example_deps="avcodec avformat avutil swscale"
-qsvdec_example_deps="avcodec avutil libmfx h264_qsv_decoder"
-remuxing_example_deps="avcodec avformat avutil"
-resampling_audio_example_deps="avutil swresample"
-scaling_video_example_deps="avutil swscale"
+mux_example_deps="avcodec avformat avutil swscale"
+qsv_decode_example_deps="avcodec avutil libmfx h264_qsv_decoder"
+remux_example_deps="avcodec avformat avutil"
+resample_audio_example_deps="avutil swresample"
+scale_video_example_deps="avutil swscale"
+show_metadata_example_deps="avformat avutil"
transcode_aac_example_deps="avcodec avformat swresample"
-transcoding_example_deps="avfilter avcodec avformat avutil"
+transcode_example_deps="avfilter avcodec avformat avutil"
vaapi_encode_example_deps="avcodec avutil h264_vaapi_encoder"
vaapi_transcode_example_deps="avcodec avformat avutil h264_vaapi_encoder"
+qsv_transcode_example_deps="avcodec avformat avutil h264_qsv_encoder"
# EXTRALIBS_LIST
cpu_init_extralibs="pthreads_extralibs"
@@ -3810,12 +3826,12 @@ swresample_suggest="libm libsoxr stdatomic"
swscale_deps="avutil"
swscale_suggest="libm stdatomic"
-avcodec_extralibs="pthreads_extralibs iconv_extralibs dxva2_extralibs"
+avcodec_extralibs="pthreads_extralibs iconv_extralibs dxva2_extralibs lcms2_extralibs"
avfilter_extralibs="pthreads_extralibs"
avutil_extralibs="d3d11va_extralibs nanosleep_extralibs pthreads_extralibs vaapi_drm_extralibs vaapi_x11_extralibs vdpau_x11_extralibs"
# programs
-ffmpeg_deps="avcodec avfilter avformat"
+ffmpeg_deps="avcodec avfilter avformat threads"
ffmpeg_select="aformat_filter anull_filter atrim_filter format_filter
hflip_filter null_filter
transpose_filter trim_filter vflip_filter"
@@ -4000,9 +4016,9 @@ find_filters_extern(){
}
FILTER_LIST=$(find_filters_extern libavfilter/allfilters.c)
-OUTDEV_LIST=$(find_things_extern muxer AVOutputFormat libavdevice/alldevices.c outdev)
+OUTDEV_LIST=$(find_things_extern muxer FFOutputFormat libavdevice/alldevices.c outdev)
INDEV_LIST=$(find_things_extern demuxer AVInputFormat libavdevice/alldevices.c indev)
-MUXER_LIST=$(find_things_extern muxer AVOutputFormat libavformat/allformats.c)
+MUXER_LIST=$(find_things_extern muxer FFOutputFormat libavformat/allformats.c)
DEMUXER_LIST=$(find_things_extern demuxer AVInputFormat libavformat/allformats.c)
ENCODER_LIST=$(find_things_extern encoder FFCodec libavcodec/allcodecs.c)
DECODER_LIST=$(find_things_extern decoder FFCodec libavcodec/allcodecs.c)
@@ -4316,6 +4332,11 @@ case "$toolchain" in
add_cflags -fsanitize=address
add_ldflags -fsanitize=address
;;
+ *-lsan)
+ cc_default="${toolchain%-lsan}"
+ add_cflags -fsanitize=leak
+ add_ldflags -fsanitize=leak
+ ;;
*-msan)
cc_default="${toolchain%-msan}"
add_cflags -fsanitize=memory -fsanitize-memory-track-origins
@@ -4349,12 +4370,6 @@ case "$toolchain" in
esac
;;
msvc)
- # Check whether the current MSVC version needs the C99 converter.
- # From MSVC 2013 (compiler major version 18) onwards, it does actually
- # support enough of C99 to build ffmpeg. Default to the new
- # behaviour if the regexp was unable to match anything, since this
- # successfully parses the version number of existing supported
- # versions that require the converter (MSVC 2010 and 2012).
cl_major_ver=$(cl.exe 2>&1 | sed -n 's/.*Version \([[:digit:]]\{1,\}\)\..*/\1/p')
if [ -z "$cl_major_ver" ] || [ $cl_major_ver -ge 18 ]; then
cc_default="cl.exe"
@@ -4363,6 +4378,7 @@ case "$toolchain" in
die "Unsupported MSVC version (2013 or newer required)"
fi
ld_default="$source_path/compat/windows/mslink"
+ windres_default="$source_path/compat/windows/mswindres"
nm_default="dumpbin.exe -symbols"
ar_default="lib.exe"
case "${arch:-$arch_default}" in
@@ -5118,6 +5134,8 @@ elif enabled arm; then
;;
esac
+ test_cflags -mfp16-format=ieee && add_cflags -mfp16-format=ieee
+
elif enabled avr32; then
case $cpu in
@@ -5319,6 +5337,12 @@ elif enabled ppc; then
;;
esac
+elif enabled riscv; then
+
+ if test_cpp_condition stddef.h "__riscv_zbb"; then
+ enable fast_clz
+ fi
+
elif enabled sparc; then
case $cpu in
@@ -5563,7 +5587,7 @@ case $target_os in
# Cannot build both shared and static libs when using dllimport.
disable static
fi
- enabled shared && ! enabled small && test_cmd $windres --version && enable gnu_windres
+ ! enabled small && test_cmd $windres --version && enable gnu_windres
enabled x86_32 && check_ldflags -Wl,--large-address-aware
shlibdir_default="$bindir_default"
SLIBPREF=""
@@ -5613,6 +5637,7 @@ case $target_os in
# Cannot build both shared and static libs with MSVC or icl.
disable static
fi
+ ! enabled small && test_cmd $windres --version && enable gnu_windres
enabled x86_32 && check_ldflags -LARGEADDRESSAWARE
shlibdir_default="$bindir_default"
SLIBPREF=""
@@ -5642,7 +5667,7 @@ case $target_os in
SHFLAGS='-shared -Wl,--out-implib,$(SUBDIR)lib$(FULLNAME).dll.a'
enabled x86_64 && objformat="win64" || objformat="win32"
enable dos_paths
- enabled shared && ! enabled small && test_cmd $windres --version && enable gnu_windres
+ ! enabled small && test_cmd $windres --version && enable gnu_windres
add_cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600
;;
*-dos|freedos|opendos)
@@ -6088,6 +6113,10 @@ elif enabled ppc; then
check_cpp_condition power8 "altivec.h" "defined(_ARCH_PWR8)"
fi
+elif enabled riscv; then
+
+ enabled rvv && check_inline_asm rvv '".option arch, +v\nvsetivli zero, 0, e8, m1, ta, ma"'
+
elif enabled x86; then
check_builtin rdtsc intrin.h "__rdtsc()"
@@ -6221,6 +6250,15 @@ check_builtin sync_val_compare_and_swap "" "int *ptr; int oldval, newval; __sync
check_builtin gmtime_r time.h "time_t *time; struct tm *tm; gmtime_r(time, tm)"
check_builtin localtime_r time.h "time_t *time; struct tm *tm; localtime_r(time, tm)"
+check_builtin float16 "" "_Float16 f16var"
+if enabled float16; then
+ if enabled x86; then
+ test_cpp_condition stddef.h "defined(__F16C__)" && enable fast_float16
+ elif enabled arm || enabled aarch64; then
+ enable fast_float16
+ fi
+fi
+
case "$custom_allocator" in
jemalloc)
# jemalloc by default does not use a prefix
@@ -6251,6 +6289,7 @@ check_func mmap
check_func mprotect
# Solaris has nanosleep in -lrt, OpenSolaris no longer needs that
check_func_headers time.h nanosleep || check_lib nanosleep time.h nanosleep -lrt
+check_func_headers sys/prctl.h prctl
check_func sched_getaffinity
check_func setrlimit
check_struct "sys/stat.h" "struct stat" st_mtim.tv_nsec -D_BSD_SOURCE
@@ -6391,8 +6430,12 @@ check_struct "sys/time.h sys/resource.h" "struct rusage" ru_maxrss
check_type "windows.h dxva.h" "DXVA_PicParams_AV1" -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_CRT_BUILD_DESKTOP_APP=0
check_type "windows.h dxva.h" "DXVA_PicParams_HEVC" -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_CRT_BUILD_DESKTOP_APP=0
check_type "windows.h dxva.h" "DXVA_PicParams_VP9" -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_CRT_BUILD_DESKTOP_APP=0
+check_type "windows.h dxgi1_2.h" "DXGI_OUTDUPL_FRAME_INFO"
+check_type "windows.h dxgi1_2.h" "IDXGIOutput1"
+check_type "windows.h dxgi1_5.h" "IDXGIOutput5"
check_type "windows.h d3d11.h" "ID3D11VideoDecoder"
check_type "windows.h d3d11.h" "ID3D11VideoContext"
+check_type "windows.h" "DPI_AWARENESS_CONTEXT" -D_WIN32_WINNT=0x0A00
check_type "d3d9.h dxva2api.h" DXVA2_ConfigPictureDecode -D_WIN32_WINNT=0x0602
check_func_headers mfapi.h MFCreateAlignedMemoryBuffer -lmfplat
@@ -6421,10 +6464,10 @@ fi
if ! disabled ffnvcodec; then
ffnv_hdr_list="ffnvcodec/nvEncodeAPI.h ffnvcodec/dynlink_cuda.h ffnvcodec/dynlink_cuviddec.h ffnvcodec/dynlink_nvcuvid.h"
- check_pkg_config ffnvcodec "ffnvcodec >= 9.1.23.1" "$ffnv_hdr_list" "" || \
- check_pkg_config ffnvcodec "ffnvcodec >= 9.0.18.3 ffnvcodec < 9.1" "$ffnv_hdr_list" "" || \
- check_pkg_config ffnvcodec "ffnvcodec >= 8.2.15.10 ffnvcodec < 8.3" "$ffnv_hdr_list" "" || \
- check_pkg_config ffnvcodec "ffnvcodec >= 8.1.24.11 ffnvcodec < 8.2" "$ffnv_hdr_list" ""
+ check_pkg_config ffnvcodec "ffnvcodec >= 12.0.16.0" "$ffnv_hdr_list" "" || \
+ check_pkg_config ffnvcodec "ffnvcodec >= 11.1.5.2 ffnvcodec < 12.0" "$ffnv_hdr_list" "" || \
+ check_pkg_config ffnvcodec "ffnvcodec >= 11.0.10.2 ffnvcodec < 11.1" "$ffnv_hdr_list" "" || \
+ check_pkg_config ffnvcodec "ffnvcodec >= 8.1.24.14 ffnvcodec < 8.2" "$ffnv_hdr_list" ""
fi
if enabled_all libglslang libshaderc; then
@@ -6505,16 +6548,13 @@ for func in $MATH_FUNCS; do
eval check_mathfunc $func \${${func}_args:-1} $libm_extralibs
done
-for func in $COMPLEX_FUNCS; do
- eval check_complexfunc $func \${${func}_args:-1}
-done
-
# these are off by default, so fail if requested and not available
enabled avisynth && { require_headers "avisynth/avisynth_c.h avisynth/avs/version.h" &&
{ test_cpp_condition avisynth/avs/version.h "AVS_MAJOR_VER >= 3 && AVS_MINOR_VER >= 7 && AVS_BUGFIX_VER >= 1 || AVS_MAJOR_VER >= 3 && AVS_MINOR_VER > 7 || AVS_MAJOR_VER > 3" ||
die "ERROR: AviSynth+ header version must be >= 3.7.1"; } }
enabled cuda_nvcc && { check_nvcc cuda_nvcc || die "ERROR: failed checking for nvcc."; }
-enabled chromaprint && require chromaprint chromaprint.h chromaprint_get_version -lchromaprint
+enabled chromaprint && { check_pkg_config chromaprint libchromaprint "chromaprint.h" chromaprint_get_version ||
+ require chromaprint chromaprint.h chromaprint_get_version -lchromaprint; }
enabled decklink && { require_headers DeckLinkAPI.h &&
{ test_cpp_condition DeckLinkAPIVersion.h "BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a0b0000" || die "ERROR: Decklink API version must be >= 10.11"; } }
enabled frei0r && require_headers "frei0r.h"
@@ -6567,19 +6607,37 @@ enabled libjxl && require_pkg_config libjxl "libjxl >= 0.7.0" jxl/dec
enabled libklvanc && require libklvanc libklvanc/vanc.h klvanc_context_create -lklvanc
enabled libkvazaar && require_pkg_config libkvazaar "kvazaar >= 0.8.1" kvazaar.h kvz_api_get
enabled liblensfun && require_pkg_config liblensfun lensfun lensfun.h lf_db_new
+
+if enabled libmfx && enabled libvpl; then
+ die "ERROR: can not use libmfx and libvpl together"
# While it may appear that require is being used as a pkg-config
# fallback for libmfx, it is actually being used to detect a different
# installation route altogether. If libmfx is installed via the Intel
# Media SDK or Intel Media Server Studio, these don't come with
# pkg-config support. Instead, users should make sure that the build
# can find the libraries and headers through other means.
-enabled libmfx && { check_pkg_config libmfx "libmfx >= 1.28" "mfx/mfxvideo.h" MFXInit ||
- { require libmfx "mfx/mfxvideo.h mfx/mfxdefs.h" MFXInit "-llibmfx $advapi32_extralibs" &&
- { test_cpp_condition mfx/mfxdefs.h "MFX_VERSION >= 1028" || die "ERROR: libmfx version must be >= 1.28"; } &&
- warn "using libmfx without pkg-config"; } }
+elif enabled libmfx; then
+ { check_pkg_config libmfx "libmfx >= 1.28 libmfx < 2.0" "mfxvideo.h" MFXInit ||
+# Some old versions of libmfx have the following settings in libmfx.pc:
+# includedir=/usr/include
+# Cflags: -I${includedir}
+# So add -I${includedir}/mfx to CFLAGS
+ { check_pkg_config libmfx "libmfx >= 1.28 libmfx < 2.0" "mfx/mfxvideo.h" MFXInit && add_cflags -I${libmfx_incdir}/mfx; } ||
+ { require libmfx "mfxvideo.h mfxdefs.h" MFXInit "-llibmfx $advapi32_extralibs" &&
+ { test_cpp_condition mfxdefs.h "MFX_VERSION >= 1028 && MFX_VERSION < 2000" || die "ERROR: libmfx version must be >= 1.28 and < 2.0"; } &&
+ warn "using libmfx without pkg-config"; } } &&
+ warn "build FFmpeg against libmfx 1.x, obsolete features of libmfx such as OPAQUE memory,\n"\
+ "multi-frame encode, user plugins and LA_EXT rate control mode are enabled"
+elif enabled libvpl; then
+# Consider pkg-config only. The name of libmfx is still passed to check_pkg_config function for --enable-libvpl option
+# because QSV has dependency on libmfx, we can use the same dependency if using libmfx in this check. The package name
+# is extracted from "vpl >= 2.6"
+ check_pkg_config libmfx "vpl >= 2.6" "mfxvideo.h mfxdispatcher.h" MFXLoad || \
+ die "ERROR: libvpl >= 2.6 not found"
+fi
if enabled libmfx; then
- check_cc MFX_CODEC_VP9 "mfx/mfxvp9.h mfx/mfxstructures.h" "MFX_CODEC_VP9"
+ check_cc MFX_CODEC_VP9 "mfxdefs.h mfxstructures.h" "MFX_CODEC_VP9"
fi
enabled libmodplug && require_pkg_config libmodplug libmodplug libmodplug/modplug.h ModPlug_Load
@@ -6611,7 +6669,7 @@ enabled libopus && {
enabled libplacebo && require_pkg_config libplacebo "libplacebo >= 4.192.0" libplacebo/vulkan.h pl_vulkan_create
enabled libpulse && require_pkg_config libpulse libpulse pulse/pulseaudio.h pa_context_new
enabled librabbitmq && require_pkg_config librabbitmq "librabbitmq >= 0.7.1" amqp.h amqp_new_connection
-enabled librav1e && require_pkg_config librav1e "rav1e >= 0.4.0" rav1e.h rav1e_context_new
+enabled librav1e && require_pkg_config librav1e "rav1e >= 0.5.0" rav1e.h rav1e_context_new
enabled librist && require_pkg_config librist "librist >= 0.2.7" librist/librist.h rist_receiver_create
enabled librsvg && require_pkg_config librsvg librsvg-2.0 librsvg-2.0/librsvg/rsvg.h rsvg_handle_render_cairo
enabled librtmp && require_pkg_config librtmp librtmp librtmp/rtmp.h RTMP_Socket
@@ -6667,12 +6725,12 @@ enabled libwebp && {
enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion
enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; }
enabled libx264 && require_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode &&
- require_cpp_condition libx264 x264.h "X264_BUILD >= 118" && {
+ require_cpp_condition libx264 x264.h "X264_BUILD >= 122" && {
[ "$toolchain" != "msvc" ] ||
require_cpp_condition libx264 x264.h "X264_BUILD >= 158"; } &&
check_cpp_condition libx262 x264.h "X264_MPEG2"
enabled libx265 && require_pkg_config libx265 x265 x265.h x265_api_get &&
- require_cpp_condition libx265 x265.h "X265_BUILD >= 70"
+ require_cpp_condition libx265 x265.h "X265_BUILD >= 89"
enabled libxavs && require libxavs "stdint.h xavs.h" xavs_encoder_encode "-lxavs $pthreads_extralibs $libm_extralibs"
enabled libxavs2 && require_pkg_config libxavs2 "xavs2 >= 1.3.0" "stdint.h xavs2.h" xavs2_api_get
enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore
@@ -6694,7 +6752,8 @@ enabled mmal && { check_lib mmal interface/mmal/mmal.h mmal_port_co
check_lib mmal interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host; } ||
die "ERROR: mmal not found" &&
check_func_headers interface/mmal/mmal.h "MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS"; }
-enabled openal && { { for al_extralibs in "${OPENAL_LIBS}" "-lopenal" "-lOpenAL32"; do
+enabled openal && { check_pkg_config openal "openal >= 1.1" "AL/al.h" alGetError ||
+ { for al_extralibs in "${OPENAL_LIBS}" "-lopenal" "-lOpenAL32"; do
check_lib openal 'AL/al.h' alGetError "${al_extralibs}" && break; done } ||
die "ERROR: openal not found"; } &&
{ test_cpp_condition "AL/al.h" "defined(AL_VERSION_1_1)" ||
@@ -6948,7 +7007,9 @@ enabled vdpau &&
enabled vdpau &&
check_lib vdpau_x11 "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau -lX11
-enabled crystalhd && check_lib crystalhd "stdint.h libcrystalhd/libcrystalhd_if.h" DtsCrystalHDVersion -lcrystalhd
+enabled crystalhd && check_lib crystalhd "stdint.h libcrystalhd/libcrystalhd_if.h" DtsCrystalHDVersion -lcrystalhd && \
+ warn "CrystalHD support is deprecated and will be removed, please contact the developers if you are interested" \
+ "in maintaining it."
if enabled vulkan; then
check_pkg_config_header_only vulkan "vulkan >= 1.2.189" "vulkan/vulkan.h" "defined VK_VERSION_1_2" ||
@@ -6985,13 +7046,17 @@ void f(void) { struct { const GUID guid; } s[] = { { NV_ENC_PRESET_HQ_GUID } };
int main(void) { return 0; }
EOF
+if enabled nvenc; then
+ check_type "ffnvcodec/nvEncodeAPI.h" "NV_ENC_PIC_PARAMS_AV1"
+fi
+
if enabled_any nvdec cuvid; then
check_type "ffnvcodec/dynlink_cuda.h ffnvcodec/dynlink_cuviddec.h" "CUVIDAV1PICPARAMS"
fi
enabled amf &&
check_cpp_condition amf "AMF/core/Version.h" \
- "(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x0001000400090000"
+ "(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x00010004001c0000"
# Funny iconv installations are not unusual, so check it after all flags have been set
if enabled libc_iconv; then
@@ -7401,12 +7466,10 @@ enabled zlib && add_cppflags -DZLIB_CONST
# conditional library dependencies, in any order
enabled amovie_filter && prepend avfilter_deps "avformat avcodec"
enabled aresample_filter && prepend avfilter_deps "swresample"
-enabled bm3d_filter && prepend avfilter_deps "avcodec"
enabled cover_rect_filter && prepend avfilter_deps "avformat avcodec"
enabled ebur128_filter && enabled swresample && prepend avfilter_deps "swresample"
enabled elbg_filter && prepend avfilter_deps "avcodec"
enabled find_rect_filter && prepend avfilter_deps "avformat avcodec"
-enabled firequalizer_filter && prepend avfilter_deps "avcodec"
enabled mcdeint_filter && prepend avfilter_deps "avcodec"
enabled movie_filter && prepend avfilter_deps "avformat avcodec"
enabled pan_filter && prepend avfilter_deps "swresample"
@@ -7543,6 +7606,9 @@ if enabled loongarch; then
echo "LSX enabled ${lsx-no}"
echo "LASX enabled ${lasx-no}"
fi
+if enabled riscv; then
+ echo "RISC-V Vector enabled ${rvv-no}"
+fi
echo "debug symbols ${debug-no}"
echo "strip symbols ${stripping-no}"
echo "optimize for size ${small-no}"
@@ -7783,7 +7849,7 @@ cat > $TMPH <= 1.0 and will be removed in the future. Use the
-global option @code{threads} instead.
+option @code{max_frame_delay} and the global option @code{threads} instead.
@item tilethreads
Set amount of tile threads to use during decoding. The default value is 0 (autodetect).
This option is deprecated for libdav1d >= 1.0 and will be removed in the future. Use the
global option @code{threads} instead.
+@item max_frame_delay
+Set max amount of frames the decoder may buffer internally. The default value is 0
+(autodetect).
+
@item filmgrain
Apply film grain to the decoded video if present in the bitstream. Defaults to the
internal default of the library.
diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index 2b6dd86c2..3c81024f0 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -285,6 +285,24 @@ This demuxer accepts the following option:
@end table
+@section ea
+
+Electronic Arts Multimedia format demuxer.
+
+This format is used by various Electronic Arts games.
+
+@subsection Options
+
+@table @option
+
+@item merge_alpha @var{bool}
+
+Normally the VP6 alpha channel (if exists) is returned as a secondary video
+stream, by setting this option you can make the demuxer return a single video
+stream which contains the alpha channel in addition to the ordinary video.
+
+@end table
+
@section imf
Interoperable Master Format demuxer.
@@ -401,6 +419,10 @@ Use HTTP partial requests for downloading HTTP segments.
@item seg_format_options
Set options for the demuxer of media segments using a list of key=value pairs separated by @code{:}.
+
+@item seg_max_retry
+Maximum number of times to reload a segment on error, useful when segment skip on network error is not desired.
+Default value is 0.
@end table
@section image2
diff --git a/doc/dev_community/community.md b/doc/dev_community/community.md
index 21e08e20e..516ca5c05 100644
--- a/doc/dev_community/community.md
+++ b/doc/dev_community/community.md
@@ -25,6 +25,9 @@ proposal by a member of the General Assembly.
They are part of the GA for two years, after which they need a confirmation by
the GA.
+A script to generate the current members of the general assembly (minus members
+voted in) can be found in `tools/general_assembly.pl`.
+
## Voting
Voting is done using a ranked voting system, currently running on https://vote.ffmpeg.org/ .
diff --git a/doc/developer.texi b/doc/developer.texi
index addee0d82..31b485b0f 100644
--- a/doc/developer.texi
+++ b/doc/developer.texi
@@ -10,41 +10,79 @@
@contents
-@chapter Notes for external developers
+@chapter Introduction
-This document is mostly useful for internal FFmpeg developers.
-External developers who need to use the API in their application should
-refer to the API doxygen documentation in the public headers, and
-check the examples in @file{doc/examples} and in the source code to
-see how the public API is employed.
+This text is concerned with the development @emph{of} FFmpeg itself. Information
+on using the FFmpeg libraries in other programs can be found elsewhere, e.g. in:
+@itemize @bullet
+@item
+the installed header files
+@item
+@url{http://ffmpeg.org/doxygen/trunk/index.html, the Doxygen documentation}
+generated from the headers
+@item
+the examples under @file{doc/examples}
+@end itemize
-You can use the FFmpeg libraries in your commercial program, but you
-are encouraged to @emph{publish any patch you make}. In this case the
-best way to proceed is to send your patches to the ffmpeg-devel
-mailing list following the guidelines illustrated in the remainder of
-this document.
+If you modify FFmpeg code for your own use case, you are highly encouraged to
+@emph{submit your changes back to us}, using this document as a guide. There are
+both pragmatic and ideological reasons to do so:
+@itemize @bullet
+@item
+Maintaining external changes to keep up with upstream development is
+time-consuming and error-prone. With your code in the main tree, it will be
+maintained by FFmpeg developers.
+@item
+FFmpeg developers include leading experts in the field who can find bugs or
+design flaws in your code.
+@item
+By supporting the project you find useful you ensure it continues to be
+maintained and developed.
+@end itemize
For more detailed legal information about the use of FFmpeg in
external programs read the @file{LICENSE} file in the source tree and
consult @url{https://ffmpeg.org/legal.html}.
-@chapter Contributing
+@section Contributing code
-There are 2 ways by which code gets into FFmpeg:
-@itemize @bullet
-@item Submitting patches to the ffmpeg-devel mailing list.
- See @ref{Submitting patches} for details.
-@item Directly committing changes to the main tree.
-@end itemize
-
-Whichever way, changes should be reviewed by the maintainer of the code
-before they are committed. And they should follow the @ref{Coding Rules}.
+All proposed code changes should be submitted for review to
+@url{mailto:ffmpeg-devel@@ffmpeg.org, the development mailing list}, as
+described in more detail in the @ref{Submitting patches} chapter. The code
+should comply with the @ref{Development Policy} and follow the @ref{Coding Rules}.
The developer making the commit and the author are responsible for their changes
and should try to fix issues their commit causes.
@anchor{Coding Rules}
@chapter Coding Rules
+@section C language features
+
+FFmpeg is programmed in the ISO C99 language, extended with:
+@itemize @bullet
+@item
+Atomic operations from C11 @file{stdatomic.h}. They are emulated on
+architectures/compilers that do not support them, so all FFmpeg-internal code
+may use atomics without any extra checks. However, @file{stdatomic.h} must not
+be included in public headers, so they stay C99-compatible.
+@end itemize
+
+Compiler-specific extensions may be used with good reason, but must not be
+depended on, i.e. the code must still compile and work with compilers lacking
+the extension.
+
+The following C99 features must not be used anywhere in the codebase:
+@itemize @bullet
+@item
+variable-length arrays;
+
+@item
+complex numbers;
+
+@item
+mixed statements and declarations.
+@end itemize
+
@section Code formatting conventions
There are the following guidelines regarding the indentation in files:
@@ -67,8 +105,39 @@ K&R coding style is used.
@end itemize
The presentation is one inspired by 'indent -i4 -kr -nut'.
-The main priority in FFmpeg is simplicity and small code size in order to
-minimize the bug count.
+@subsection Vim configuration
+In order to configure Vim to follow FFmpeg formatting conventions, paste
+the following snippet into your @file{.vimrc}:
+@example
+" indentation rules for FFmpeg: 4 spaces, no tabs
+set expandtab
+set shiftwidth=4
+set softtabstop=4
+set cindent
+set cinoptions=(0
+" Allow tabs in Makefiles.
+autocmd FileType make,automake set noexpandtab shiftwidth=8 softtabstop=8
+" Trailing whitespace and tabs are forbidden, so highlight them.
+highlight ForbiddenWhitespace ctermbg=red guibg=red
+match ForbiddenWhitespace /\s\+$\|\t/
+" Do not highlight spaces at the end of line while typing on that line.
+autocmd InsertEnter * match ForbiddenWhitespace /\t\|\s\+\%#\@@/lib.v} files.
+
+@item
+Other public identifiers (struct, union, enum, macro, type names) must use their
+library's public prefix (@code{AV}, @code{Sws}, or @code{Swr}).
@end itemize
Furthermore, name space reserved for the system should not be invaded.
@@ -218,39 +246,7 @@ Casts should be used only when necessary. Unneeded parentheses
should also be avoided if they don't make the code easier to understand.
@end itemize
-@section Editor configuration
-In order to configure Vim to follow FFmpeg formatting conventions, paste
-the following snippet into your @file{.vimrc}:
-@example
-" indentation rules for FFmpeg: 4 spaces, no tabs
-set expandtab
-set shiftwidth=4
-set softtabstop=4
-set cindent
-set cinoptions=(0
-" Allow tabs in Makefiles.
-autocmd FileType make,automake set noexpandtab shiftwidth=8 softtabstop=8
-" Trailing whitespace and tabs are forbidden, so highlight them.
-highlight ForbiddenWhitespace ctermbg=red guibg=red
-match ForbiddenWhitespace /\s\+$\|\t/
-" Do not highlight spaces at the end of line while typing on that line.
-autocmd InsertEnter * match ForbiddenWhitespace /\t\|\s\+\%#\@@= 1.32).
@item scc
@end table
+@item @var{tier}
+Set the encoding tier (only level >= 4 can support high tier).
+This option only takes effect when the level option is specified.
+
+@table @samp
+@item main
+@item high
+@end table
+
@item @var{gpb}
1: GPB (generalized P/B frame)
@@ -3609,8 +3691,10 @@ Specifies intra refresh type. The major goal of intra refresh is improvement of
error resilience without significant impact on encoded bitstream size caused by
I frames. The SDK encoder achieves this by encoding part of each frame in
refresh cycle using intra MBs. @var{none} means no refresh. @var{vertical} means
-vertical refresh, by column of MBs. To enable intra refresh, B frame should be
-set to 0.
+vertical refresh, by column of MBs. @var{horizontal} means horizontal refresh,
+by rows of MBs. @var{slice} means horizontal refresh by slices without
+overlapping. In case of @var{slice}, in_ref_cycle_size is ignored. To enable
+intra refresh, B frame should be set to 0.
@item @var{int_ref_cycle_size}
Specifies number of pictures within refresh cycle starting from 2. 0 and 1 are
@@ -3641,6 +3725,52 @@ Maximum video quantizer scale for B frame.
@item @var{min_qp_b}
Minimum video quantizer scale for B frame.
+
+@item @var{scenario}
+Provides a hint to encoder about the scenario for the encoding session.
+@table @samp
+@item unknown
+@item displayremoting
+@item videoconference
+@item archive
+@item livestreaming
+@item cameracapture
+@item videosurveillance
+@item gamestreaming
+@item remotegaming
+@end table
+
+@item @var{avbr_accuracy}
+Accuracy of the AVBR ratecontrol (unit of tenth of percent).
+
+@item @var{avbr_convergence}
+Convergence of the AVBR ratecontrol (unit of 100 frames)
+
+The parameters @var{avbr_accuracy} and @var{avbr_convergence} are for the
+average variable bitrate control (AVBR) algorithm.
+The algorithm focuses on overall encoding quality while meeting the specified
+bitrate, @var{target_bitrate}, within the accuracy range @var{avbr_accuracy},
+after a @var{avbr_Convergence} period. This method does not follow HRD and the
+instant bitrate is not capped or padded.
+
+@item @var{skip_frame}
+Use per-frame metadata "qsv_skip_frame" to skip frame when encoding. This option
+defines the usage of this metadata.
+@table @samp
+@item no_skip
+Frame skipping is disabled.
+@item insert_dummy
+Encoder inserts into bitstream frame where all macroblocks are encoded as
+skipped.
+@item insert_nothing
+Similar to insert_dummy, but encoder inserts nothing into bitstream. The skipped
+frames are still used in brc. For example, gop still include skipped frames, and
+the frames after skipped frames will be larger in size.
+@item brc_only
+skip_frame metadata indicates the number of missed frames before the current
+frame.
+@end table
+
@end table
@subsection MPEG2 Options
@@ -3674,6 +3804,48 @@ Number of columns for tiled encoding (requires libmfx >= 1.29).
Number of rows for tiled encoding (requires libmfx >= 1.29).
@end table
+@subsection AV1 Options
+These options are used by av1_qsv (requires libvpl).
+@table @option
+@item @var{profile}
+@table @samp
+@item unknown
+@item main
+@end table
+
+@item @var{tile_cols}
+Number of columns for tiled encoding.
+
+@item @var{tile_rows}
+Number of rows for tiled encoding.
+
+@item @var{adaptive_i}
+This flag controls insertion of I frames by the QSV encoder. Turn ON this flag
+to allow changing of frame type from P and B to I.
+
+@item @var{adaptive_b}
+This flag controls changing of frame type from B to P.
+
+@item @var{b_strategy}
+This option controls usage of B frames as reference.
+
+@item @var{extbrc}
+Extended bitrate control.
+
+@item @var{look_ahead_depth}
+Depth of look ahead in number frames, available when extbrc option is enabled.
+
+@item @var{low_delay_brc}
+Setting this flag turns on or off LowDelayBRC feautre in qsv plugin, which provides
+more accurate bitrate control to minimize the variance of bitstream size frame
+by frame. Value: -1-default 0-off 1-on
+
+@item max_frame_size
+Set the allowed max size in bytes for each frame. If the frame size exceeds
+the limitation, encoder will adjust the QP value to control the frame size.
+Invalid in CQP rate control mode.
+@end table
+
@section snow
@subsection Options
diff --git a/doc/examples/.gitignore b/doc/examples/.gitignore
deleted file mode 100644
index 44960e1de..000000000
--- a/doc/examples/.gitignore
+++ /dev/null
@@ -1,24 +0,0 @@
-/avio_list_dir
-/avio_reading
-/decode_audio
-/decode_video
-/demuxing_decoding
-/encode_audio
-/encode_video
-/extract_mvs
-/filter_audio
-/filtering_audio
-/filtering_video
-/http_multiclient
-/hw_decode
-/metadata
-/muxing
-/pc-uninstalled
-/qsvdec
-/remuxing
-/resampling_audio
-/scaling_video
-/transcode_aac
-/transcoding
-/vaapi_encode
-/vaapi_transcode
diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index 81bfd34d5..4efed6b11 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -1,26 +1,27 @@
+EXAMPLES-$(CONFIG_AVIO_HTTP_SERVE_FILES) += avio_http_serve_files
EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir
-EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading
+EXAMPLES-$(CONFIG_AVIO_READ_CALLBACK_EXAMPLE) += avio_read_callback
EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio
+EXAMPLES-$(CONFIG_DECODE_FILTER_AUDIO_EXAMPLE) += decode_filter_audio
+EXAMPLES-$(CONFIG_DECODE_FILTER_VIDEO_EXAMPLE) += decode_filter_video
EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video
-EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
+EXAMPLES-$(CONFIG_DEMUX_DECODE_EXAMPLE) += demux_decode
EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio
EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video
EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE) += extract_mvs
EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio
-EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE) += filtering_audio
-EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE) += filtering_video
-EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE) += http_multiclient
EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode
-EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata
-EXAMPLES-$(CONFIG_MUXING_EXAMPLE) += muxing
-EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec
-EXAMPLES-$(CONFIG_REMUXING_EXAMPLE) += remuxing
-EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio
-EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
+EXAMPLES-$(CONFIG_MUX_EXAMPLE) += mux
+EXAMPLES-$(CONFIG_QSV_DECODE_EXAMPLE) += qsv_decode
+EXAMPLES-$(CONFIG_REMUX_EXAMPLE) += remux
+EXAMPLES-$(CONFIG_RESAMPLE_AUDIO_EXAMPLE) += resample_audio
+EXAMPLES-$(CONFIG_SCALE_VIDEO_EXAMPLE) += scale_video
+EXAMPLES-$(CONFIG_SHOW_METADATA_EXAMPLE) += show_metadata
EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
-EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE) += transcoding
+EXAMPLES-$(CONFIG_TRANSCODE_EXAMPLE) += transcode
EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE) += vaapi_encode
EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE) += vaapi_transcode
+EXAMPLES-$(CONFIG_QSV_TRANSCODE_EXAMPLE) += qsv_transcode
EXAMPLES := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
EXAMPLES_G := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
diff --git a/doc/examples/Makefile.example b/doc/examples/Makefile.example
index a232d97f9..01712f42d 100644
--- a/doc/examples/Makefile.example
+++ b/doc/examples/Makefile.example
@@ -11,25 +11,32 @@ CFLAGS += -Wall -g
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
-EXAMPLES= avio_list_dir \
- avio_reading \
+# missing the following targets, since they need special options in the FFmpeg build:
+# qsv_decode
+# qsv_transcode
+# vaapi_encode
+# vaapi_transcode
+
+EXAMPLES=\
+ avio_http_serve_files \
+ avio_list_dir \
+ avio_read_callback \
decode_audio \
+ decode_filter_audio \
+ decode_filter_video \
decode_video \
- demuxing_decoding \
+ demux_decode \
encode_audio \
encode_video \
extract_mvs \
- filtering_video \
- filtering_audio \
- http_multiclient \
hw_decode \
- metadata \
- muxing \
- remuxing \
- resampling_audio \
- scaling_video \
+ mux \
+ remux \
+ resample_audio \
+ scale_video \
+ show_metadata \
transcode_aac \
- transcoding \
+ transcode
OBJS=$(addsuffix .o,$(EXAMPLES))
diff --git a/doc/examples/README b/doc/examples/README
index c1ce619d3..6cb4b6e17 100644
--- a/doc/examples/README
+++ b/doc/examples/README
@@ -7,8 +7,10 @@ that you have them installed and working on your system.
Method 1: build the installed examples in a generic read/write user directory
-Copy to a read/write user directory and just use "make", it will link
-to the libraries on your system, assuming the PKG_CONFIG_PATH is
+Copy to a read/write user directory and run:
+make -f Makefile.example
+
+It will link to the libraries on your system, assuming the PKG_CONFIG_PATH is
correctly configured.
Method 2: build the examples in-tree
@@ -20,4 +22,4 @@ examples using "make examplesclean"
If you want to try the dedicated Makefile examples (to emulate the first
method), go into doc/examples and run a command such as
-PKG_CONFIG_PATH=pc-uninstalled make.
+PKG_CONFIG_PATH=pc-uninstalled make -f Makefile.example
diff --git a/doc/examples/http_multiclient.c b/doc/examples/avio_http_serve_files.c
similarity index 95%
rename from doc/examples/http_multiclient.c
rename to doc/examples/avio_http_serve_files.c
index 831e89c60..2aae3870c 100644
--- a/doc/examples/http_multiclient.c
+++ b/doc/examples/avio_http_serve_files.c
@@ -21,12 +21,11 @@
*/
/**
- * @file
- * libavformat multi-client network API usage example.
+ * @file libavformat multi-client network API usage example
+ * @example avio_http_serve_files.c
*
- * @example http_multiclient.c
- * This example will serve a file without decoding or demuxing it over http.
- * Multiple clients can connect and will receive the same file.
+ * Serve a file without decoding or demuxing it over the HTTP protocol. Multiple
+ * clients can connect and will receive the same file.
*/
#include
diff --git a/doc/examples/avio_list_dir.c b/doc/examples/avio_list_dir.c
index 3073baaef..bb19debad 100644
--- a/doc/examples/avio_list_dir.c
+++ b/doc/examples/avio_list_dir.c
@@ -20,6 +20,13 @@
* THE SOFTWARE.
*/
+/**
+ * @file libavformat AVIOContext list directory API usage example
+ * @example avio_list_dir.c
+ *
+ * Show how to list directories through the libavformat AVIOContext API.
+ */
+
#include
#include
#include
diff --git a/doc/examples/avio_reading.c b/doc/examples/avio_read_callback.c
similarity index 97%
rename from doc/examples/avio_reading.c
rename to doc/examples/avio_read_callback.c
index 36ee02afa..4cf81ad72 100644
--- a/doc/examples/avio_reading.c
+++ b/doc/examples/avio_read_callback.c
@@ -21,12 +21,11 @@
*/
/**
- * @file
- * libavformat AVIOContext API example.
+ * @file libavformat AVIOContext read callback API usage example
+ * @example avio_read_callback.c
*
* Make libavformat demuxer access media content through a custom
* AVIOContext read callback.
- * @example avio_reading.c
*/
#include
diff --git a/doc/examples/decode_audio.c b/doc/examples/decode_audio.c
index 49ad22cba..bcb3d87a6 100644
--- a/doc/examples/decode_audio.c
+++ b/doc/examples/decode_audio.c
@@ -21,10 +21,11 @@
*/
/**
- * @file
- * audio decoding with libavcodec API example
- *
+ * @file libavcodec audio decoding API usage example
* @example decode_audio.c
+ *
+ * Decode data from an MP2 input file and generate a raw audio file to
+ * be played with ffplay.
*/
#include
diff --git a/doc/examples/filtering_audio.c b/doc/examples/decode_filter_audio.c
similarity index 98%
rename from doc/examples/filtering_audio.c
rename to doc/examples/decode_filter_audio.c
index 51fc47be2..204641981 100644
--- a/doc/examples/filtering_audio.c
+++ b/doc/examples/decode_filter_audio.c
@@ -23,9 +23,11 @@
*/
/**
- * @file
- * API example for audio decoding and filtering
- * @example filtering_audio.c
+ * @file audio decoding and filtering usage example
+ * @example decode_filter_audio.c
+ *
+ * Demux, decode and filter audio input file, generate a raw audio
+ * file to be played with ffplay.
*/
#include
diff --git a/doc/examples/filtering_video.c b/doc/examples/decode_filter_video.c
similarity index 99%
rename from doc/examples/filtering_video.c
rename to doc/examples/decode_filter_video.c
index 7b3e16c40..454c19222 100644
--- a/doc/examples/filtering_video.c
+++ b/doc/examples/decode_filter_video.c
@@ -24,7 +24,7 @@
/**
* @file
* API example for decoding and filtering
- * @example filtering_video.c
+ * @example decode_filter_video.c
*/
#define _XOPEN_SOURCE 600 /* for usleep */
diff --git a/doc/examples/decode_video.c b/doc/examples/decode_video.c
index 7238e3810..b0b3a6ae9 100644
--- a/doc/examples/decode_video.c
+++ b/doc/examples/decode_video.c
@@ -21,10 +21,11 @@
*/
/**
- * @file
- * video decoding with libavcodec API example
+ * @file libavcodec video decoding API usage example
+ * @example decode_video.c *
*
- * @example decode_video.c
+ * Read from an MPEG1 video file, decode frames, and generate PGM images as
+ * output.
*/
#include
@@ -69,12 +70,12 @@ static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
exit(1);
}
- printf("saving frame %3d\n", dec_ctx->frame_number);
+ printf("saving frame %3"PRId64"\n", dec_ctx->frame_num);
fflush(stdout);
/* the picture is allocated by the decoder. no need to
free it */
- snprintf(buf, sizeof(buf), "%s-%d", filename, dec_ctx->frame_number);
+ snprintf(buf, sizeof(buf), "%s-%"PRId64, filename, dec_ctx->frame_num);
pgm_save(frame->data[0], frame->linesize[0],
frame->width, frame->height, buf);
}
diff --git a/doc/examples/demuxing_decoding.c b/doc/examples/demux_decode.c
similarity index 97%
rename from doc/examples/demuxing_decoding.c
rename to doc/examples/demux_decode.c
index 999a78db0..298a369f4 100644
--- a/doc/examples/demuxing_decoding.c
+++ b/doc/examples/demux_decode.c
@@ -21,12 +21,12 @@
*/
/**
- * @file
- * Demuxing and decoding example.
+ * @file libavformat and libavcodec demuxing and decoding API usage example
+ * @example demux_decode.c
*
- * Show how to use the libavformat and libavcodec API to demux and
- * decode audio and video data.
- * @example demuxing_decoding.c
+ * Show how to use the libavformat and libavcodec API to demux and decode audio
+ * and video data. Write the output as raw audio and input files to be played by
+ * ffplay.
*/
#include
@@ -73,8 +73,8 @@ static int output_video_frame(AVFrame *frame)
return -1;
}
- printf("video_frame n:%d coded_n:%d\n",
- video_frame_count++, frame->coded_picture_number);
+ printf("video_frame n:%d\n",
+ video_frame_count++);
/* copy decoded frame to destination buffer:
* this is required since rawvideo expects non aligned data */
diff --git a/doc/examples/encode_audio.c b/doc/examples/encode_audio.c
index 9a1792b72..bb16683d9 100644
--- a/doc/examples/encode_audio.c
+++ b/doc/examples/encode_audio.c
@@ -21,10 +21,10 @@
*/
/**
- * @file
- * audio encoding with libavcodec API example.
- *
+ * @file libavcodec encoding audio API usage examples
* @example encode_audio.c
+ *
+ * Generate a synthetic audio signal and encode it to an output MP2 file.
*/
#include
diff --git a/doc/examples/encode_video.c b/doc/examples/encode_video.c
index 939ed6832..4fae146f2 100644
--- a/doc/examples/encode_video.c
+++ b/doc/examples/encode_video.c
@@ -21,10 +21,10 @@
*/
/**
- * @file
- * video encoding with libavcodec API example
- *
+ * @file libavcodec encoding video API usage example
* @example encode_video.c
+ *
+ * Generate synthetic video data and encode it to an output file.
*/
#include
@@ -202,7 +202,7 @@ int main(int argc, char **argv)
It makes only sense because this tiny examples writes packets
directly. This is called "elementary stream" and only works for some
codecs. To create a valid file, you usually need to write packets
- into a proper file format or protocol; see muxing.c.
+ into a proper file format or protocol; see mux.c.
*/
if (codec->id == AV_CODEC_ID_MPEG1VIDEO || codec->id == AV_CODEC_ID_MPEG2VIDEO)
fwrite(endcode, 1, sizeof(endcode), f);
diff --git a/doc/examples/extract_mvs.c b/doc/examples/extract_mvs.c
index cc1311da9..5603064d7 100644
--- a/doc/examples/extract_mvs.c
+++ b/doc/examples/extract_mvs.c
@@ -21,6 +21,14 @@
* THE SOFTWARE.
*/
+/**
+ * @file libavcodec motion vectors extraction API usage example
+ * @example extract_mvs.c
+ *
+ * Read from input file, decode video stream and print a motion vectors
+ * representation to stdout.
+ */
+
#include
#include
#include
@@ -61,10 +69,11 @@ static int decode_packet(const AVPacket *pkt)
const AVMotionVector *mvs = (const AVMotionVector *)sd->data;
for (i = 0; i < sd->size / sizeof(*mvs); i++) {
const AVMotionVector *mv = &mvs[i];
- printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64"\n",
+ printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64",%4d,%4d,%4d\n",
video_frame_count, mv->source,
mv->w, mv->h, mv->src_x, mv->src_y,
- mv->dst_x, mv->dst_y, mv->flags);
+ mv->dst_x, mv->dst_y, mv->flags,
+ mv->motion_x, mv->motion_y, mv->motion_scale);
}
}
av_frame_unref(frame);
@@ -166,7 +175,7 @@ int main(int argc, char **argv)
goto end;
}
- printf("framenum,source,blockw,blockh,srcx,srcy,dstx,dsty,flags\n");
+ printf("framenum,source,blockw,blockh,srcx,srcy,dstx,dsty,flags,motion_x,motion_y,motion_scale\n");
/* read frames from the file */
while (av_read_frame(fmt_ctx, pkt) >= 0) {
diff --git a/doc/examples/filter_audio.c b/doc/examples/filter_audio.c
index f53e52562..9e4039b90 100644
--- a/doc/examples/filter_audio.c
+++ b/doc/examples/filter_audio.c
@@ -19,13 +19,11 @@
*/
/**
- * @file
- * libavfilter API usage example.
- *
+ * @file libavfilter audio filtering API usage example
* @example filter_audio.c
- * This example will generate a sine wave audio,
- * pass it through a simple filter chain, and then compute the MD5 checksum of
- * the output data.
+ *
+ * This example will generate a sine wave audio, pass it through a simple filter
+ * chain, and then compute the MD5 checksum of the output data.
*
* The filter chain it uses is:
* (input) -> abuffer -> volume -> aformat -> abuffersink -> (output)
diff --git a/doc/examples/hw_decode.c b/doc/examples/hw_decode.c
index 0d23f451e..6a4a4fb83 100644
--- a/doc/examples/hw_decode.c
+++ b/doc/examples/hw_decode.c
@@ -24,12 +24,11 @@
*/
/**
- * @file
- * HW-Accelerated decoding example.
- *
+ * @file HW-accelerated decoding API usage.example
* @example hw_decode.c
- * This example shows how to do HW-accelerated decoding with output
- * frames from the HW video surfaces.
+ *
+ * Perform HW-accelerated decoding with output frames from HW video
+ * surfaces.
*/
#include
diff --git a/doc/examples/muxing.c b/doc/examples/mux.c
similarity index 98%
rename from doc/examples/muxing.c
rename to doc/examples/mux.c
index 3acb77832..d1f682e19 100644
--- a/doc/examples/muxing.c
+++ b/doc/examples/mux.c
@@ -21,12 +21,11 @@
*/
/**
- * @file
- * libavformat API example.
+ * @file libavformat muxing API usage example
+ * @example mux.c
*
- * Output a media file in any supported libavformat format. The default
- * codecs are used.
- * @example muxing.c
+ * Generate a synthetic audio and video signal and mux them to a media file in
+ * any supported libavformat format. The default codecs are used.
*/
#include
@@ -219,8 +218,6 @@ static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
int sample_rate, int nb_samples)
{
AVFrame *frame = av_frame_alloc();
- int ret;
-
if (!frame) {
fprintf(stderr, "Error allocating an audio frame\n");
exit(1);
@@ -232,8 +229,7 @@ static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
frame->nb_samples = nb_samples;
if (nb_samples) {
- ret = av_frame_get_buffer(frame, 0);
- if (ret < 0) {
+ if (av_frame_get_buffer(frame, 0) < 0) {
fprintf(stderr, "Error allocating an audio buffer\n");
exit(1);
}
diff --git a/doc/examples/qsvdec.c b/doc/examples/qsv_decode.c
similarity index 96%
rename from doc/examples/qsvdec.c
rename to doc/examples/qsv_decode.c
index b662ae91c..cc2662d5b 100644
--- a/doc/examples/qsvdec.c
+++ b/doc/examples/qsv_decode.c
@@ -21,12 +21,11 @@
*/
/**
- * @file
- * Intel QSV-accelerated H.264 decoding example.
+ * @file Intel QSV-accelerated H.264 decoding API usage example
+ * @example qsv_decode.c
*
- * @example qsvdec.c
- * This example shows how to do QSV-accelerated H.264 decoding with output
- * frames in the GPU video surfaces.
+ * Perform QSV-accelerated H.264 decoding with output frames in the
+ * GPU video surfaces, write the decoded frames to an output file.
*/
#include "config.h"
diff --git a/doc/examples/qsv_transcode.c b/doc/examples/qsv_transcode.c
new file mode 100644
index 000000000..7ea3ef567
--- /dev/null
+++ b/doc/examples/qsv_transcode.c
@@ -0,0 +1,438 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @file Intel QSV-accelerated video transcoding API usage example
+ * @example qsv_transcode.c
+ *
+ * Perform QSV-accelerated transcoding and show to dynamically change
+ * encoder's options.
+ *
+ * Usage: qsv_transcode input_stream codec output_stream initial option
+ * { frame_number new_option }
+ * e.g: - qsv_transcode input.mp4 h264_qsv output_h264.mp4 "g 60"
+ * - qsv_transcode input.mp4 hevc_qsv output_hevc.mp4 "g 60 async_depth 1"
+ * 100 "g 120"
+ * (initialize codec with gop_size 60 and change it to 120 after 100
+ * frames)
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+static AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
+static AVBufferRef *hw_device_ctx = NULL;
+static AVCodecContext *decoder_ctx = NULL, *encoder_ctx = NULL;
+static int video_stream = -1;
+
+typedef struct DynamicSetting {
+ int frame_number;
+ char* optstr;
+} DynamicSetting;
+static DynamicSetting *dynamic_setting;
+static int setting_number;
+static int current_setting_number;
+
+static int str_to_dict(char* optstr, AVDictionary **opt)
+{
+ char *key, *value;
+ if (strlen(optstr) == 0)
+ return 0;
+ key = strtok(optstr, " ");
+ if (key == NULL)
+ return AVERROR(ENAVAIL);
+ value = strtok(NULL, " ");
+ if (value == NULL)
+ return AVERROR(ENAVAIL);
+ av_dict_set(opt, key, value, 0);
+ do {
+ key = strtok(NULL, " ");
+ if (key == NULL)
+ return 0;
+ value = strtok(NULL, " ");
+ if (value == NULL)
+ return AVERROR(ENAVAIL);
+ av_dict_set(opt, key, value, 0);
+ } while(key != NULL);
+ return 0;
+}
+
+static int dynamic_set_parameter(AVCodecContext *avctx)
+{
+ AVDictionary *opts = NULL;
+ int ret = 0;
+ static int frame_number = 0;
+ frame_number++;
+ if (current_setting_number < setting_number &&
+ frame_number == dynamic_setting[current_setting_number].frame_number) {
+ AVDictionaryEntry *e = NULL;
+ ret = str_to_dict(dynamic_setting[current_setting_number].optstr, &opts);
+ if (ret < 0) {
+ fprintf(stderr, "The dynamic parameter is wrong\n");
+ goto fail;
+ }
+ /* Set common option. The dictionary will be freed and replaced
+ * by a new one containing all options not found in common option list.
+ * Then this new dictionary is used to set private option. */
+ if ((ret = av_opt_set_dict(avctx, &opts)) < 0)
+ goto fail;
+ /* Set codec specific option */
+ if ((ret = av_opt_set_dict(avctx->priv_data, &opts)) < 0)
+ goto fail;
+ /* There is no "framerate" option in commom option list. Use "-r" to set
+ * framerate, which is compatible with ffmpeg commandline. The video is
+ * assumed to be average frame rate, so set time_base to 1/framerate. */
+ e = av_dict_get(opts, "r", NULL, 0);
+ if (e) {
+ avctx->framerate = av_d2q(atof(e->value), INT_MAX);
+ encoder_ctx->time_base = av_inv_q(encoder_ctx->framerate);
+ }
+ }
+fail:
+ av_dict_free(&opts);
+ return ret;
+}
+
+static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
+{
+ while (*pix_fmts != AV_PIX_FMT_NONE) {
+ if (*pix_fmts == AV_PIX_FMT_QSV) {
+ return AV_PIX_FMT_QSV;
+ }
+
+ pix_fmts++;
+ }
+
+ fprintf(stderr, "The QSV pixel format not offered in get_format()\n");
+
+ return AV_PIX_FMT_NONE;
+}
+
+static int open_input_file(char *filename)
+{
+ int ret;
+ const AVCodec *decoder = NULL;
+ AVStream *video = NULL;
+
+ if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {
+ fprintf(stderr, "Cannot open input file '%s', Error code: %s\n",
+ filename, av_err2str(ret));
+ return ret;
+ }
+
+ if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
+ fprintf(stderr, "Cannot find input stream information. Error code: %s\n",
+ av_err2str(ret));
+ return ret;
+ }
+
+ ret = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
+ if (ret < 0) {
+ fprintf(stderr, "Cannot find a video stream in the input file. "
+ "Error code: %s\n", av_err2str(ret));
+ return ret;
+ }
+ video_stream = ret;
+ video = ifmt_ctx->streams[video_stream];
+
+ switch(video->codecpar->codec_id) {
+ case AV_CODEC_ID_H264:
+ decoder = avcodec_find_decoder_by_name("h264_qsv");
+ break;
+ case AV_CODEC_ID_HEVC:
+ decoder = avcodec_find_decoder_by_name("hevc_qsv");
+ break;
+ case AV_CODEC_ID_VP9:
+ decoder = avcodec_find_decoder_by_name("vp9_qsv");
+ break;
+ case AV_CODEC_ID_VP8:
+ decoder = avcodec_find_decoder_by_name("vp8_qsv");
+ break;
+ case AV_CODEC_ID_AV1:
+ decoder = avcodec_find_decoder_by_name("av1_qsv");
+ break;
+ case AV_CODEC_ID_MPEG2VIDEO:
+ decoder = avcodec_find_decoder_by_name("mpeg2_qsv");
+ break;
+ case AV_CODEC_ID_MJPEG:
+ decoder = avcodec_find_decoder_by_name("mjpeg_qsv");
+ break;
+ default:
+ fprintf(stderr, "Codec is not supportted by qsv\n");
+ return AVERROR(ENAVAIL);
+ }
+
+ if (!(decoder_ctx = avcodec_alloc_context3(decoder)))
+ return AVERROR(ENOMEM);
+
+ if ((ret = avcodec_parameters_to_context(decoder_ctx, video->codecpar)) < 0) {
+ fprintf(stderr, "avcodec_parameters_to_context error. Error code: %s\n",
+ av_err2str(ret));
+ return ret;
+ }
+ decoder_ctx->framerate = av_guess_frame_rate(ifmt_ctx, video, NULL);
+
+ decoder_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
+ if (!decoder_ctx->hw_device_ctx) {
+ fprintf(stderr, "A hardware device reference create failed.\n");
+ return AVERROR(ENOMEM);
+ }
+ decoder_ctx->get_format = get_format;
+ decoder_ctx->pkt_timebase = video->time_base;
+ if ((ret = avcodec_open2(decoder_ctx, decoder, NULL)) < 0)
+ fprintf(stderr, "Failed to open codec for decoding. Error code: %s\n",
+ av_err2str(ret));
+
+ return ret;
+}
+
+static int encode_write(AVPacket *enc_pkt, AVFrame *frame)
+{
+ int ret = 0;
+
+ av_packet_unref(enc_pkt);
+
+ if((ret = dynamic_set_parameter(encoder_ctx)) < 0) {
+ fprintf(stderr, "Failed to set dynamic parameter. Error code: %s\n",
+ av_err2str(ret));
+ goto end;
+ }
+
+ if ((ret = avcodec_send_frame(encoder_ctx, frame)) < 0) {
+ fprintf(stderr, "Error during encoding. Error code: %s\n", av_err2str(ret));
+ goto end;
+ }
+ while (1) {
+ if (ret = avcodec_receive_packet(encoder_ctx, enc_pkt))
+ break;
+ enc_pkt->stream_index = 0;
+ av_packet_rescale_ts(enc_pkt, encoder_ctx->time_base,
+ ofmt_ctx->streams[0]->time_base);
+ if ((ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt)) < 0) {
+ fprintf(stderr, "Error during writing data to output file. "
+ "Error code: %s\n", av_err2str(ret));
+ return ret;
+ }
+ }
+
+end:
+ if (ret == AVERROR_EOF)
+ return 0;
+ ret = ((ret == AVERROR(EAGAIN)) ? 0:-1);
+ return ret;
+}
+
+static int dec_enc(AVPacket *pkt, const AVCodec *enc_codec, char *optstr)
+{
+ AVFrame *frame;
+ int ret = 0;
+
+ ret = avcodec_send_packet(decoder_ctx, pkt);
+ if (ret < 0) {
+ fprintf(stderr, "Error during decoding. Error code: %s\n", av_err2str(ret));
+ return ret;
+ }
+
+ while (ret >= 0) {
+ if (!(frame = av_frame_alloc()))
+ return AVERROR(ENOMEM);
+
+ ret = avcodec_receive_frame(decoder_ctx, frame);
+ if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
+ av_frame_free(&frame);
+ return 0;
+ } else if (ret < 0) {
+ fprintf(stderr, "Error while decoding. Error code: %s\n", av_err2str(ret));
+ goto fail;
+ }
+ if (!encoder_ctx->hw_frames_ctx) {
+ AVDictionaryEntry *e = NULL;
+ AVDictionary *opts = NULL;
+ AVStream *ost;
+ /* we need to ref hw_frames_ctx of decoder to initialize encoder's codec.
+ Only after we get a decoded frame, can we obtain its hw_frames_ctx */
+ encoder_ctx->hw_frames_ctx = av_buffer_ref(decoder_ctx->hw_frames_ctx);
+ if (!encoder_ctx->hw_frames_ctx) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ /* set AVCodecContext Parameters for encoder, here we keep them stay
+ * the same as decoder.
+ */
+ encoder_ctx->time_base = av_inv_q(decoder_ctx->framerate);
+ encoder_ctx->pix_fmt = AV_PIX_FMT_QSV;
+ encoder_ctx->width = decoder_ctx->width;
+ encoder_ctx->height = decoder_ctx->height;
+ if ((ret = str_to_dict(optstr, &opts)) < 0) {
+ fprintf(stderr, "Failed to set encoding parameter.\n");
+ goto fail;
+ }
+ /* There is no "framerate" option in commom option list. Use "-r" to
+ * set framerate, which is compatible with ffmpeg commandline. The
+ * video is assumed to be average frame rate, so set time_base to
+ * 1/framerate. */
+ e = av_dict_get(opts, "r", NULL, 0);
+ if (e) {
+ encoder_ctx->framerate = av_d2q(atof(e->value), INT_MAX);
+ encoder_ctx->time_base = av_inv_q(encoder_ctx->framerate);
+ }
+ if ((ret = avcodec_open2(encoder_ctx, enc_codec, &opts)) < 0) {
+ fprintf(stderr, "Failed to open encode codec. Error code: %s\n",
+ av_err2str(ret));
+ av_dict_free(&opts);
+ goto fail;
+ }
+ av_dict_free(&opts);
+
+ if (!(ost = avformat_new_stream(ofmt_ctx, enc_codec))) {
+ fprintf(stderr, "Failed to allocate stream for output format.\n");
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ ost->time_base = encoder_ctx->time_base;
+ ret = avcodec_parameters_from_context(ost->codecpar, encoder_ctx);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to copy the stream parameters. "
+ "Error code: %s\n", av_err2str(ret));
+ goto fail;
+ }
+
+ /* write the stream header */
+ if ((ret = avformat_write_header(ofmt_ctx, NULL)) < 0) {
+ fprintf(stderr, "Error while writing stream header. "
+ "Error code: %s\n", av_err2str(ret));
+ goto fail;
+ }
+ }
+ frame->pts = av_rescale_q(frame->pts, decoder_ctx->pkt_timebase,
+ encoder_ctx->time_base);
+ if ((ret = encode_write(pkt, frame)) < 0)
+ fprintf(stderr, "Error during encoding and writing.\n");
+
+fail:
+ av_frame_free(&frame);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ const AVCodec *enc_codec;
+ int ret = 0;
+ AVPacket *dec_pkt;
+
+ if (argc < 5 || (argc - 5) % 2) {
+ av_log(NULL, AV_LOG_ERROR, "Usage: %s "
+ " <\"encoding option set 0\"> [ <\"encoding options set 1\">]...\n", argv[0]);
+ return 1;
+ }
+ setting_number = (argc - 5) / 2;
+ dynamic_setting = av_malloc(setting_number * sizeof(*dynamic_setting));
+ current_setting_number = 0;
+ for (int i = 0; i < setting_number; i++) {
+ dynamic_setting[i].frame_number = atoi(argv[i*2 + 5]);
+ dynamic_setting[i].optstr = argv[i*2 + 6];
+ }
+
+ ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_QSV, NULL, NULL, 0);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to create a QSV device. Error code: %s\n", av_err2str(ret));
+ goto end;
+ }
+
+ dec_pkt = av_packet_alloc();
+ if (!dec_pkt) {
+ fprintf(stderr, "Failed to allocate decode packet\n");
+ goto end;
+ }
+
+ if ((ret = open_input_file(argv[1])) < 0)
+ goto end;
+
+ if (!(enc_codec = avcodec_find_encoder_by_name(argv[2]))) {
+ fprintf(stderr, "Could not find encoder '%s'\n", argv[2]);
+ ret = -1;
+ goto end;
+ }
+
+ if ((ret = (avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, argv[3]))) < 0) {
+ fprintf(stderr, "Failed to deduce output format from file extension. Error code: "
+ "%s\n", av_err2str(ret));
+ goto end;
+ }
+
+ if (!(encoder_ctx = avcodec_alloc_context3(enc_codec))) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+
+ ret = avio_open(&ofmt_ctx->pb, argv[3], AVIO_FLAG_WRITE);
+ if (ret < 0) {
+ fprintf(stderr, "Cannot open output file. "
+ "Error code: %s\n", av_err2str(ret));
+ goto end;
+ }
+
+ /* read all packets and only transcoding video */
+ while (ret >= 0) {
+ if ((ret = av_read_frame(ifmt_ctx, dec_pkt)) < 0)
+ break;
+
+ if (video_stream == dec_pkt->stream_index)
+ ret = dec_enc(dec_pkt, enc_codec, argv[4]);
+
+ av_packet_unref(dec_pkt);
+ }
+
+ /* flush decoder */
+ av_packet_unref(dec_pkt);
+ if ((ret = dec_enc(dec_pkt, enc_codec, argv[4])) < 0) {
+ fprintf(stderr, "Failed to flush decoder %s\n", av_err2str(ret));
+ goto end;
+ }
+
+ /* flush encoder */
+ if ((ret = encode_write(dec_pkt, NULL)) < 0) {
+ fprintf(stderr, "Failed to flush encoder %s\n", av_err2str(ret));
+ goto end;
+ }
+
+ /* write the trailer for output stream */
+ if ((ret = av_write_trailer(ofmt_ctx)) < 0)
+ fprintf(stderr, "Failed to write trailer %s\n", av_err2str(ret));
+
+end:
+ avformat_close_input(&ifmt_ctx);
+ avformat_close_input(&ofmt_ctx);
+ avcodec_free_context(&decoder_ctx);
+ avcodec_free_context(&encoder_ctx);
+ av_buffer_unref(&hw_device_ctx);
+ av_packet_free(&dec_pkt);
+ av_freep(&dynamic_setting);
+ return ret;
+}
diff --git a/doc/examples/remuxing.c b/doc/examples/remux.c
similarity index 96%
rename from doc/examples/remuxing.c
rename to doc/examples/remux.c
index 2657f9dc6..ecf30489f 100644
--- a/doc/examples/remuxing.c
+++ b/doc/examples/remux.c
@@ -21,11 +21,11 @@
*/
/**
- * @file
- * libavformat/libavcodec demuxing and muxing API example.
+ * @file libavformat/libavcodec demuxing and muxing API usage example
+ * @example remux.c
*
- * Remux streams from one container format to another.
- * @example remuxing.c
+ * Remux streams from one container format to another. Data is copied from the
+ * input to the output without transcoding.
*/
#include
diff --git a/doc/examples/resampling_audio.c b/doc/examples/resample_audio.c
similarity index 97%
rename from doc/examples/resampling_audio.c
rename to doc/examples/resample_audio.c
index 9f1521a5a..db9b4e5e0 100644
--- a/doc/examples/resampling_audio.c
+++ b/doc/examples/resample_audio.c
@@ -21,8 +21,12 @@
*/
/**
- * @example resampling_audio.c
- * libswresample API use example.
+ * @file audio resampling API usage example
+ * @example resample_audio.c
+ *
+ * Generate a synthetic audio signal, and Use libswresample API to perform audio
+ * resampling. The output is written to a raw audio file to be played with
+ * ffplay.
*/
#include
diff --git a/doc/examples/scaling_video.c b/doc/examples/scale_video.c
similarity index 97%
rename from doc/examples/scaling_video.c
rename to doc/examples/scale_video.c
index 587f3abe4..cb4da4a57 100644
--- a/doc/examples/scaling_video.c
+++ b/doc/examples/scale_video.c
@@ -21,9 +21,10 @@
*/
/**
- * @file
- * libswscale API use example.
- * @example scaling_video.c
+ * @file libswscale API usage example
+ * @example scale_video.c
+ *
+ * Generate a synthetic video signal and use libswscale to perform rescaling.
*/
#include
diff --git a/doc/examples/metadata.c b/doc/examples/show_metadata.c
similarity index 91%
rename from doc/examples/metadata.c
rename to doc/examples/show_metadata.c
index 7c44009a2..abe3cc0ca 100644
--- a/doc/examples/metadata.c
+++ b/doc/examples/show_metadata.c
@@ -21,9 +21,10 @@
*/
/**
- * @file
- * Shows how the metadata API can be used in application programs.
- * @example metadata.c
+ * @file libavformat metadata extraction API usage example
+ * @example show_metadata.c
+ *
+ * Show metadata from an input file.
*/
#include
@@ -52,7 +53,7 @@ int main (int argc, char **argv)
return ret;
}
- while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
+ while ((tag = av_dict_iterate(fmt_ctx->metadata, tag)))
printf("%s=%s\n", tag->key, tag->value);
avformat_close_input(&fmt_ctx);
diff --git a/doc/examples/transcoding.c b/doc/examples/transcode.c
similarity index 99%
rename from doc/examples/transcoding.c
rename to doc/examples/transcode.c
index 013f89fc7..805a028ed 100644
--- a/doc/examples/transcoding.c
+++ b/doc/examples/transcode.c
@@ -23,9 +23,11 @@
*/
/**
- * @file
- * API example for demuxing, decoding, filtering, encoding and muxing
- * @example transcoding.c
+ * @file demuxing, decoding, filtering, encoding and muxing API usage example
+ * @example transcode.c
+ *
+ * Convert input to output file, applying some hard-coded filter-graph on both
+ * audio and video streams.
*/
#include
diff --git a/doc/examples/transcode_aac.c b/doc/examples/transcode_aac.c
index 2d4f9a59d..bb5681a7c 100644
--- a/doc/examples/transcode_aac.c
+++ b/doc/examples/transcode_aac.c
@@ -19,12 +19,11 @@
*/
/**
- * @file
- * Simple audio converter
- *
+ * @file audio transcoding to MPEG/AAC API usage example
* @example transcode_aac.c
- * Convert an input audio file to AAC in an MP4 container using FFmpeg.
- * Formats other than MP4 are supported based on the output file extension.
+ *
+ * Convert an input audio file to AAC in an MP4 container. Formats other than
+ * MP4 are supported based on the output file extension.
* @author Andreas Unterweger (dustsigns@gmail.com)
*/
diff --git a/doc/examples/vaapi_encode.c b/doc/examples/vaapi_encode.c
index e232fa579..d5f472f6d 100644
--- a/doc/examples/vaapi_encode.c
+++ b/doc/examples/vaapi_encode.c
@@ -1,6 +1,4 @@
/*
- * Video Acceleration API (video encoding) encode sample
- *
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
@@ -21,13 +19,12 @@
*/
/**
- * @file
- * Intel VAAPI-accelerated encoding example.
- *
+ * @file Intel VAAPI-accelerated encoding API usage example
* @example vaapi_encode.c
- * This example shows how to do VAAPI-accelerated encoding. now only support NV12
- * raw file, usage like: vaapi_encode 1920 1080 input.yuv output.h264
*
+ * Perform VAAPI-accelerated encoding. Read input from an NV12 raw
+ * file, and write the H.264 encoded data to an output raw file.
+ * Usage: vaapi_encode 1920 1080 input.yuv output.h264
*/
#include
diff --git a/doc/examples/vaapi_transcode.c b/doc/examples/vaapi_transcode.c
index a174bb643..8367cb304 100644
--- a/doc/examples/vaapi_transcode.c
+++ b/doc/examples/vaapi_transcode.c
@@ -1,6 +1,4 @@
/*
- * Video Acceleration API (video transcoding) transcode sample
- *
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
@@ -21,11 +19,10 @@
*/
/**
- * @file
- * Intel VAAPI-accelerated transcoding example.
- *
+ * @file Intel VAAPI-accelerated transcoding API usage example
* @example vaapi_transcode.c
- * This example shows how to do VAAPI-accelerated transcoding.
+ *
+ * Perform VAAPI-accelerated transcoding.
* Usage: vaapi_transcode input_stream codec output_stream
* e.g: - vaapi_transcode input.mp4 h264_vaapi output_h264.mp4
* - vaapi_transcode input.mp4 vp9_vaapi output_vp9.ivf
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 767df69b7..d9d4b7556 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -877,9 +877,20 @@ This is not the same as the @option{-framerate} option used for some input forma
like image2 or v4l2 (it used to be the same in older versions of FFmpeg).
If in doubt use @option{-framerate} instead of the input option @option{-r}.
-As an output option, duplicate or drop input frames to achieve constant output
+As an output option:
+@table @option
+@item video encoding
+Duplicate or drop frames right before encoding them to achieve constant output
frame rate @var{fps}.
+@item video streamcopy
+Indicate to the muxer that @var{fps} is the stream frame rate. No data is
+dropped or duplicated in this case. This may produce invalid files if @var{fps}
+does not match the actual stream frame rate as determined by packet timestamps.
+See also the @code{setts} bitstream filter.
+
+@end table
+
@item -fpsmax[:@var{stream_specifier}] @var{fps} (@emph{output,per-stream})
Set maximum frame rate (Hz value, fraction or abbreviation).
@@ -912,6 +923,32 @@ If used together with @option{-vcodec copy}, it will affect the aspect ratio
stored at container level, but not the aspect ratio stored in encoded
frames, if it exists.
+@item -display_rotation[:@var{stream_specifier}] @var{rotation} (@emph{input,per-stream})
+Set video rotation metadata.
+
+@var{rotation} is a decimal number specifying the amount in degree by
+which the video should be rotated counter-clockwise before being
+displayed.
+
+This option overrides the rotation/display transform metadata stored in
+the file, if any. When the video is being transcoded (rather than
+copied) and @code{-autorotate} is enabled, the video will be rotated at
+the filtering stage. Otherwise, the metadata will be written into the
+output file if the muxer supports it.
+
+If the @code{-display_hflip} and/or @code{-display_vflip} options are
+given, they are applied after the rotation specified by this option.
+
+@item -display_hflip[:@var{stream_specifier}] (@emph{input,per-stream})
+Set whether on display the image should be horizontally flipped.
+
+See the @code{-display_rotation} option for more details.
+
+@item -display_vflip[:@var{stream_specifier}] (@emph{input,per-stream})
+Set whether on display the image should be vertically flipped.
+
+See the @code{-display_rotation} option for more details.
+
@item -vn (@emph{input/output})
As an input option, blocks all video streams of a file from being filtered or
being automatically selected or mapped for any output. See @code{-discard}
@@ -985,14 +1022,9 @@ list separated with slashes. Two first values are the beginning and
end frame numbers, last one is quantizer to use if positive, or quality
factor if negative.
-@item -ilme
-Force interlacing support in encoder (MPEG-2 and MPEG-4 only).
-Use this option if your input file is interlaced and you want
-to keep the interlaced format for minimum losses.
-The alternative is to deinterlace the input stream by use of a filter
-such as @code{yadif} or @code{bwdif}, but deinterlacing introduces losses.
@item -psnr
-Calculate PSNR of compressed frames.
+Calculate PSNR of compressed frames. This option is deprecated, pass the
+PSNR flag to the encoder instead, using @code{-flags +psnr}.
@item -vstats
Dump video coding statistics to @file{vstats_HHMMSS.log}.
@item -vstats_file @var{file}
@@ -1009,8 +1041,6 @@ version > 1:
@code{out= %2d st= %2d frame= %5d q= %2.1f PSNR= %6.2f f_size= %6d s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s}
@item -top[:@var{stream_specifier}] @var{n} (@emph{output,per-stream})
top=1/bottom=0/auto=-1 field first
-@item -dc @var{precision}
-Intra_dc_precision.
@item -vtag @var{fourcc/tag} (@emph{output})
Force video tag/fourcc. This is an alias for @code{-tag:v}.
@item -qphist (@emph{global})
@@ -1312,6 +1342,22 @@ List all hardware acceleration components enabled in this build of ffmpeg.
Actual runtime availability depends on the hardware and its suitable driver
being installed.
+@item -fix_sub_duration_heartbeat[:@var{stream_specifier}]
+Set a specific output video stream as the heartbeat stream according to which
+to split and push through currently in-progress subtitle upon receipt of a
+random access packet.
+
+This lowers the latency of subtitles for which the end packet or the following
+subtitle has not yet been received. As a drawback, this will most likely lead
+to duplication of subtitle events in order to cover the full duration, so
+when dealing with use cases where latency of when the subtitle event is passed
+on to output is not relevant this option should not be utilized.
+
+Requires @option{-fix_sub_duration} to be set for the relevant input subtitle
+stream for this to have any effect, as well as for the input subtitle stream
+having to be directly mapped to the same output in which the heartbeat stream
+resides.
+
@end table
@section Audio Options
@@ -1410,18 +1456,18 @@ Set the size of the canvas used to render subtitles.
@section Advanced options
@table @option
-@item -map [-]@var{input_file_id}[:@var{stream_specifier}][?][,@var{sync_file_id}[:@var{stream_specifier}]] | @var{[linklabel]} (@emph{output})
+@item -map [-]@var{input_file_id}[:@var{stream_specifier}][?] | @var{[linklabel]} (@emph{output})
-Designate one or more input streams as a source for the output file. Each input
-stream is identified by the input file index @var{input_file_id} and
-the input stream index @var{input_stream_id} within the input
-file. Both indices start at 0. If specified,
-@var{sync_file_id}:@var{stream_specifier} sets which input stream
-is used as a presentation sync reference.
+Create one or more streams in the output file. This option has two forms for
+specifying the data source(s): the first selects one or more streams from some
+input file (specified with @code{-i}), the second takes an output from some
+complex filtergraph (specified with @code{-filter_complex} or
+@code{-filter_complex_script}).
-The first @code{-map} option on the command line specifies the
-source for output stream 0, the second @code{-map} option specifies
-the source for output stream 1, etc.
+In the first form, an output stream is created for every stream from the input
+file with the index @var{input_file_id}. If @var{stream_specifier} is given,
+only those streams that match the specifier are used (see the
+@ref{Stream specifiers} section for the @var{stream_specifier} syntax).
A @code{-} character before the stream identifier creates a "negative" mapping.
It disables matching streams from already created mappings.
@@ -1435,39 +1481,56 @@ An alternative @var{[linklabel]} form will map outputs from complex filter
graphs (see the @option{-filter_complex} option) to the output file.
@var{linklabel} must correspond to a defined output link label in the graph.
-For example, to map ALL streams from the first input file to output
+This option may be specified multiple times, each adding more streams to the
+output file. Any given input stream may also be mapped any number of times as a
+source for different output streams, e.g. in order to use different encoding
+options and/or filters. The streams are created in the output in the same order
+in which the @code{-map} options are given on the commandline.
+
+Using this option disables the default mappings for this output file.
+
+Examples:
+
+@table @emph
+
+@item map everything
+To map ALL streams from the first input file to output
@example
ffmpeg -i INPUT -map 0 output
@end example
-For example, if you have two audio streams in the first input file,
-these streams are identified by "0:0" and "0:1". You can use
-@code{-map} to select which streams to place in an output file. For
-example:
+@item select specific stream
+If you have two audio streams in the first input file, these streams are
+identified by @var{0:0} and @var{0:1}. You can use @code{-map} to select which
+streams to place in an output file. For example:
@example
ffmpeg -i INPUT -map 0:1 out.wav
@end example
-will map the input stream in @file{INPUT} identified by "0:1" to
-the (single) output stream in @file{out.wav}.
+will map the second input stream in @file{INPUT} to the (single) output stream
+in @file{out.wav}.
-For example, to select the stream with index 2 from input file
-@file{a.mov} (specified by the identifier "0:2"), and stream with
-index 6 from input @file{b.mov} (specified by the identifier "1:6"),
-and copy them to the output file @file{out.mov}:
+@item create multiple streams
+To select the stream with index 2 from input file @file{a.mov} (specified by the
+identifier @var{0:2}), and stream with index 6 from input @file{b.mov}
+(specified by the identifier @var{1:6}), and copy them to the output file
+@file{out.mov}:
@example
ffmpeg -i a.mov -i b.mov -c copy -map 0:2 -map 1:6 out.mov
@end example
+@item create multiple streams 2
To select all video and the third audio stream from an input file:
@example
ffmpeg -i INPUT -map 0:v -map 0:a:2 OUTPUT
@end example
+@item negative map
To map all the streams except the second audio, use negative mappings
@example
ffmpeg -i INPUT -map 0 -map -0:a:1 OUTPUT
@end example
+@item optional map
To map the video and audio streams from the first input, and using the
trailing @code{?}, ignore the audio mapping if no audio streams exist in
the first input:
@@ -1475,12 +1538,13 @@ the first input:
ffmpeg -i INPUT -map 0:v -map 0:a? OUTPUT
@end example
+@item map by language
To pick the English audio stream:
@example
ffmpeg -i INPUT -map 0:m:language:eng OUTPUT
@end example
-Note that using this option disables the default mappings for this output file.
+@end table
@item -ignore_unknown
Ignore input streams with unknown type instead of failing if copying
@@ -1491,6 +1555,10 @@ Allow input streams with unknown type to be copied instead of failing if copying
such streams is attempted.
@item -map_channel [@var{input_file_id}.@var{stream_specifier}.@var{channel_id}|-1][?][:@var{output_file_id}.@var{stream_specifier}]
+This option is deprecated and will be removed. It can be replaced by the
+@var{pan} filter. In some cases it may be easier to use some combination of the
+@var{channelsplit}, @var{channelmap}, or @var{amerge} filters.
+
Map an audio channel from a given input to an output. If
@var{output_file_id}.@var{stream_specifier} is not set, the audio channel will
be mapped on all the audio streams.
@@ -1674,18 +1742,6 @@ The default is -1.1. One possible usecase is to avoid framedrops in case
of noisy timestamps or to increase frame drop precision in case of exact
timestamps.
-@item -async @var{samples_per_second}
-Audio sync method. "Stretches/squeezes" the audio stream to match the timestamps,
-the parameter is the maximum samples per second by which the audio is changed.
--async 1 is a special case where only the start of the audio stream is corrected
-without any later correction.
-
-Note that the timestamps may be further modified by the muxer, after this.
-For example, in the case that the format option @option{avoid_negative_ts}
-is enabled.
-
-This option has been deprecated. Use the @code{aresample} audio filter instead.
-
@item -adrift_threshold @var{time}
Set the minimum difference between timestamps and audio data (in seconds) to trigger
adding/dropping samples to make it match the timestamps. This option effectively is
@@ -1765,6 +1821,22 @@ Default value is 0.
Enable bitexact mode for (de)muxer and (de/en)coder
@item -shortest (@emph{output})
Finish encoding when the shortest output stream ends.
+
+Note that this option may require buffering frames, which introduces extra
+latency. The maximum amount of this latency may be controlled with the
+@code{-shortest_buf_duration} option.
+
+@item -shortest_buf_duration @var{duration} (@emph{output})
+The @code{-shortest} option may require buffering potentially large amounts
+of data when at least one of the streams is "sparse" (i.e. has large gaps
+between frames – this is typically the case for subtitles).
+
+This option controls the maximum duration of buffered frames in seconds.
+Larger values may allow the @code{-shortest} option to produce more accurate
+results, but increase memory use and latency.
+
+The default value is 10 seconds.
+
@item -dts_delta_threshold
Timestamp discontinuity delta threshold.
@item -dts_error_threshold @var{seconds}
@@ -1899,13 +1971,16 @@ to the @option{-ss} option is considered an actual timestamp, and is not
offset by the start time of the file. This matters only for files which do
not start from timestamp 0, such as transport streams.
-@item -thread_queue_size @var{size} (@emph{input})
-This option sets the maximum number of queued packets when reading from the
-file or device. With low latency / high rate live streams, packets may be
-discarded if they are not read in a timely manner; setting this value can
+@item -thread_queue_size @var{size} (@emph{input/output})
+For input, this option sets the maximum number of queued packets when reading
+from the file or device. With low latency / high rate live streams, packets may
+be discarded if they are not read in a timely manner; setting this value can
force ffmpeg to use a separate input thread and read packets as soon as they
arrive. By default ffmpeg only does this if multiple inputs are specified.
+For output, this option specified the maximum number of packets that may be
+queued to each muxing thread.
+
@item -sdp_file @var{file} (@emph{global})
Print sdp information for an output stream to @var{file}.
This allows dumping sdp information when at least one output isn't an
@@ -1986,6 +2061,116 @@ encoder/muxer, it does not change the stream to conform to this value. Setting
values that do not match the stream properties may result in encoding failures
or invalid output files.
+@item -stats_enc_pre[:@var{stream_specifier}] @var{path} (@emph{output,per-stream})
+@item -stats_enc_post[:@var{stream_specifier}] @var{path} (@emph{output,per-stream})
+@item -stats_mux_pre[:@var{stream_specifier}] @var{path} (@emph{output,per-stream})
+Write per-frame encoding information about the matching streams into the file
+given by @var{path}.
+
+@option{-stats_enc_pre} writes information about raw video or audio frames right
+before they are sent for encoding, while @option{-stats_enc_post} writes
+information about encoded packets as they are received from the encoder.
+@option{-stats_mux_pre} writes information about packets just as they are about to
+be sent to the muxer. Every frame or packet produces one line in the specified
+file. The format of this line is controlled by @option{-stats_enc_pre_fmt} /
+@option{-stats_enc_post_fmt} / @option{-stats_mux_pre_fmt}.
+
+When stats for multiple streams are written into a single file, the lines
+corresponding to different streams will be interleaved. The precise order of
+this interleaving is not specified and not guaranteed to remain stable between
+different invocations of the program, even with the same options.
+
+@item -stats_enc_pre_fmt[:@var{stream_specifier}] @var{format_spec} (@emph{output,per-stream})
+@item -stats_enc_post_fmt[:@var{stream_specifier}] @var{format_spec} (@emph{output,per-stream})
+@item -stats_mux_pre_fmt[:@var{stream_specifier}] @var{format_spec} (@emph{output,per-stream})
+Specify the format for the lines written with @option{-stats_enc_pre} /
+@option{-stats_enc_post} / @option{-stats_mux_pre}.
+
+@var{format_spec} is a string that may contain directives of the form
+@var{@{fmt@}}. @var{format_spec} is backslash-escaped --- use \@{, \@}, and \\
+to write a literal @{, @}, or \, respectively, into the output.
+
+The directives given with @var{fmt} may be one of the following:
+@table @option
+@item fidx
+Index of the output file.
+
+@item sidx
+Index of the output stream in the file.
+
+@item n
+Frame number. Pre-encoding: number of frames sent to the encoder so far.
+Post-encoding: number of packets received from the encoder so far.
+Muxing: number of packets submitted to the muxer for this stream so far.
+
+@item ni
+Input frame number. Index of the input frame (i.e. output by a decoder) that
+corresponds to this output frame or packet. -1 if unavailable.
+
+@item tb
+Encoder timebase, as a rational number @var{num/den}. Note that this may be
+different from the timebase used by the muxer.
+
+@item tbi
+Timebase for @var{ptsi}, as a rational number @var{num/den}. Available when
+@var{ptsi} is available, @var{0/1} otherwise.
+
+@item pts
+Presentation timestamp of the frame or packet, as an integer. Should be
+multiplied by the timebase to compute presentation time.
+
+@item ptsi
+Presentation timestamp of the input frame (see @var{ni}), as an integer. Should
+be multiplied by @var{tbi} to compute presentation time. Printed as
+(2^63 - 1 = 9223372036854775807) when not available.
+
+@item t
+Presentation time of the frame or packet, as a decimal number. Equal to
+@var{pts} multiplied by @var{tb}.
+
+@item ti
+Presentation time of the input frame (see @var{ni}), as a decimal number. Equal
+to @var{ptsi} multiplied by @var{tbi}. Printed as inf when not available.
+
+@item dts
+Decoding timestamp of the packet, as an integer. Should be multiplied by the
+timebase to compute presentation time. Post-encoding only.
+
+@item dt
+Decoding time of the frame or packet, as a decimal number. Equal to
+@var{dts} multiplied by @var{tb}.
+
+@item sn
+Number of audio samples sent to the encoder so far. Audio and pre-encoding only.
+
+@item samp
+Number of audio samples in the frame. Audio and pre-encoding only.
+
+@item size
+Size of the encoded packet in bytes. Post-encoding only.
+
+@item br
+Current bitrate in bits per second. Post-encoding only.
+
+@item abr
+Average bitrate for the whole stream so far, in bits per second, -1 if it cannot
+be determined at this point. Post-encoding only.
+@end table
+
+The default format strings are:
+@table @option
+@item pre-encoding
+@{fidx@} @{sidx@} @{n@} @{t@}
+@item post-encoding
+@{fidx@} @{sidx@} @{n@} @{t@}
+@end table
+In the future, new items may be added to the end of the default formatting
+strings. Users who depend on the format staying exactly the same, should
+prescribe it manually.
+
+Note that stats for different streams written into the same file may have
+different formats.
+
@end table
@section Preset files
diff --git a/doc/ffprobe.xsd b/doc/ffprobe.xsd
index 3af621a17..092038010 100644
--- a/doc/ffprobe.xsd
+++ b/doc/ffprobe.xsd
@@ -92,6 +92,8 @@
+
+
@@ -244,6 +246,7 @@
+
diff --git a/doc/filters.texi b/doc/filters.texi
index 40f21fb34..47e92b926 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -171,6 +171,17 @@ within the quoted text; otherwise the argument string is considered
terminated when the next special character (belonging to the set
@samp{[]=;,}) is encountered.
+A special syntax implemented in the @command{ffmpeg} CLI tool allows loading
+option values from files. This is done be prepending a slash '/' to the option
+name, then the supplied value is interpreted as a path from which the actual
+value is loaded. E.g.
+@example
+ffmpeg -i -vf drawtext=/text=/tmp/some_text
+@end example
+will load the text to be drawn from @file{/tmp/some_text}. API users wishing to
+implement a similar feature should use the @code{avfilter_graph_segment_*()}
+functions together with custom IO code.
+
The name and arguments of the filter are optionally preceded and
followed by a list of link labels.
A link label allows one to name a link and associate it to a filter output
@@ -350,6 +361,19 @@ terminates. Default value is 0.
If set to 1, force the filter to extend the last frame of secondary streams
until the end of the primary stream. A value of 0 disables this behavior.
Default value is 1.
+
+@item ts_sync_mode
+How strictly to sync streams based on secondary input timestamps; it accepts
+one of the following values:
+
+@table @option
+@item default
+Frame from secondary input with the nearest lower or equal timestamp to the
+primary input frame.
+@item nearest
+Frame from secondary input with the absolute nearest timestamp to the primary
+input frame.
+@end table
@end table
@c man end OPTIONS FOR FILTERS WITH SEVERAL INPUTS
@@ -859,6 +883,91 @@ Compute derivative/integral of audio stream.
Applying both filters one after another produces original audio.
+@section adrc
+
+Apply spectral dynamic range controller filter to input audio stream.
+
+A description of the accepted options follows.
+
+@table @option
+@item transfer
+Set the transfer expression.
+
+The expression can contain the following constants:
+
+@table @option
+@item ch
+current channel number
+
+@item sn
+current sample number
+
+@item nb_channels
+number of channels
+
+@item t
+timestamp expressed in seconds
+
+@item sr
+sample rate
+
+@item p
+current frequency power value, in dB
+
+@item f
+current frequency in Hz
+@end table
+
+Default value is @code{p}.
+
+@item attack
+Set the attack in milliseconds. Default is @code{50} milliseconds.
+Allowed range is from 1 to 1000 milliseconds.
+@item release
+Set the release in milliseconds. Default is @code{100} milliseconds.
+Allowed range is from 5 to 2000 milliseconds.
+@item channels
+Set which channels to filter, by default @code{all} channels in audio stream are filtered.
+@end table
+
+@subsection Commands
+
+This filter supports the all above options as @ref{commands}.
+
+@subsection Examples
+
+@itemize
+@item
+Apply spectral compression to all frequencies with threshold of -50 dB and 1:6 ratio:
+@example
+adrc=transfer='if(gt(p,-50),-50+(p-(-50))/6,p)':attack=50:release=100
+@end example
+
+@item
+Similar to above but with 1:2 ratio and filtering only front center channel:
+@example
+adrc=transfer='if(gt(p,-50),-50+(p-(-50))/2,p)':attack=50:release=100:channels=FC
+@end example
+
+@item
+Apply spectral noise gate to all frequencies with threshold of -85 dB and with short attack time and short release time:
+@example
+adrc=transfer='if(lte(p,-85),p-800,p)':attack=1:release=5
+@end example
+
+@item
+Apply spectral expansion to all frequencies with threshold of -10 dB and 1:2 ratio:
+@example
+adrc=transfer='if(lt(p,-10),-10+(p-(-10))*2,p)':attack=50:release=100
+@end example
+
+@item
+Apply limiter to max -60 dB to all frequencies, with attack of 2 ms and release of 10 ms:
+@example
+adrc=transfer='min(p,-60)':attack=2:release=10
+@end example
+@end itemize
+
@section adynamicequalizer
Apply dynamic equalization to input audio stream.
@@ -897,25 +1006,17 @@ Set the amount of milliseconds the signal from detection has to fall below the
detection threshold before equalization ends.
Default is 200. Allowed range is between 1 and 2000.
-@item knee
-Curve the sharp knee around the detection threshold to calculate
-equalization gain more softly.
-Default is 1. Allowed range is between 0 and 8.
-
@item ratio
Set the ratio by which the equalization gain is raised.
-Default is 1. Allowed range is between 1 and 20.
+Default is 1. Allowed range is between 0 and 30.
@item makeup
-Set the makeup offset in dB by which the equalization gain is raised.
-Default is 0. Allowed range is between 0 and 30.
+Set the makeup offset by which the equalization gain is raised.
+Default is 0. Allowed range is between 0 and 100.
@item range
-Set the max allowed cut/boost amount in dB. Default is 0.
-Allowed range is from 0 to 200.
-
-@item slew
-Set the slew factor. Default is 1. Allowed range is from 1 to 200.
+Set the max allowed cut/boost amount. Default is 50.
+Allowed range is from 1 to 200.
@item mode
Set the mode of filter operation, can be one of the following:
@@ -939,6 +1040,32 @@ Set the type of target filter, can be one of the following:
@item highshelf
@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}.
+This option is useful to detect threshold in certain time frame of
+input audio stream, in such case option value is changed at runtime.
+
+Available values are:
+@table @samp
+@item disabled
+Disable using automatically gathered threshold value.
+@item off
+Stop picking threshold value.
+@item on
+Start picking threshold value.
+@end table
@end table
@subsection Commands
@@ -1280,6 +1407,14 @@ select inverted sine cardinal function
@item nofade
no fade applied
@end table
+
+@item silence
+Set the initial gain for fade-in or final gain for fade-out.
+Default value is @code{0.0}.
+
+@item unity
+Set the initial gain for fade-out or final gain for fade-in.
+Default value is @code{1.0}.
@end table
@subsection Commands
@@ -1532,6 +1667,7 @@ It accepts the following values:
@item parzen
@item poisson
@item bohman
+@item kaiser
@end table
Default is @code{hann}.
@@ -1560,6 +1696,12 @@ Apply whisper effect:
@example
afftfilt="real='hypot(re,im)*cos((random(0)*2-1)*2*3.14)':imag='hypot(re,im)*sin((random(1)*2-1)*2*3.14)':win_size=128:overlap=0.8"
@end example
+
+@item
+Apply phase shift:
+@example
+afftfilt="real=re*cos(1)-im*sin(1):imag=re*sin(1)+im*cos(1)"
+@end example
@end itemize
@anchor{afir}
@@ -1609,6 +1751,12 @@ select DC gain, limited application.
@item gn
select gain to noise approach, this is most popular one.
+
+@item ac
+select AC gain.
+
+@item rms
+select RMS gain.
@end table
@item irgain
@@ -1639,12 +1787,12 @@ Set video stream frame rate. This option is used only when @var{response} is ena
@item minp
Set minimal partition size used for convolution. Default is @var{8192}.
-Allowed range is from @var{1} to @var{32768}.
+Allowed range is from @var{1} to @var{65536}.
Lower values decreases latency at cost of higher CPU usage.
@item maxp
Set maximal partition size used for convolution. Default is @var{8192}.
-Allowed range is from @var{8} to @var{32768}.
+Allowed range is from @var{8} to @var{65536}.
Lower values may increase CPU usage.
@item nbirs
@@ -1681,6 +1829,13 @@ Apply reverb to stream using mono IR file as second input, complete command usin
@example
ffmpeg -i input.wav -i middle_tunnel_1way_mono.wav -lavfi afir output.wav
@end example
+
+@item
+Apply true stereo processing given input stereo stream, and two stereo impulse responses for left and right channel,
+the impulse response files are files with names l_ir.wav and r_ir.wav:
+@example
+"pan=4C|c0=FL|c1=FL|c2=FR|c3=FR[a];amovie=l_ir.wav[LIR];amovie=r_ir.wav[RIR];[LIR][RIR]amerge[ir];[a][ir]afir=irfmt=input:gtype=gn:irgain=-5dB,pan=stereo|FL0 and <1 values will make less conservative gain adjustments, like
when framelen option is set to smaller value, if framelen option value is
compensated for non-zero overlap then gain adjustments will be smoother across time
compared to zero overlap case.
+
+@item curve, v
+Specify the peak mapping curve expression which is going to be used when calculating
+gain applied to frames. The max output frame gain will still be limited by other
+options mentioned previously for this filter.
+
+The expression can contain the following constants:
+
+@table @option
+@item ch
+current channel number
+
+@item sn
+current sample number
+
+@item nb_channels
+number of channels
+
+@item t
+timestamp expressed in seconds
+
+@item sr
+sample rate
+
+@item p
+current frame peak value
+@end table
@end table
@subsection Commands
@@ -6309,12 +6530,50 @@ option. When enabled any half-cycle of samples with their local peak value below
Link channels when calculating gain applied to each filtered channel sample, by default is disabled.
When disabled each filtered channel gain calculation is independent, otherwise when this option
is enabled the minimum of all possible gains for each filtered channel is used.
+
+@item rms, m
+Set the expansion target RMS value. This specifies the highest allowed RMS level for the normalized
+audio input. Default value is 0.0, thus disabled. Allowed range is from 0.0 to 1.0.
@end table
@subsection Commands
This filter supports the all above options as @ref{commands}.
+@subsection Examples
+
+@itemize
+@item
+Weak and slow amplification:
+@example
+speechnorm=e=3:r=0.00001:l=1
+@end example
+
+@item
+Moderate and slow amplification:
+@example
+speechnorm=e=6.25:r=0.00001:l=1
+@end example
+
+@item
+Strong and fast amplification:
+@example
+speechnorm=e=12.5:r=0.0001:l=1
+@end example
+
+@item
+Very strong and fast amplification:
+@example
+speechnorm=e=25:r=0.0001:l=1
+@end example
+
+@item
+Extreme and fast amplification:
+@example
+speechnorm=e=50:r=0.0001:l=1
+@end example
+@end itemize
+
@section stereotools
This filter has some handy utilities to manage stereo signals, for converting
@@ -6576,10 +6835,20 @@ In @var{add} mode, LFE channel is created from input audio and added to output.
In @var{sub} mode, LFE channel is created from input audio and added to output but
also all non-LFE output channels are subtracted with output LFE channel.
+@item smooth
+Set temporal smoothness strength, used to gradually change factors when transforming
+stereo sound in time. Allowed range is from @var{0.0} to @var{1.0}.
+Useful to improve output quality with @var{focus} option values greater than @var{0.0}.
+Default is @var{0.0}. Only values inside this range and without edges are effective.
+
@item angle
Set angle of stereo surround transform, Allowed range is from @var{0} to @var{360}.
Default is @var{90}.
+@item focus
+Set focus of stereo surround transform, Allowed range is from @var{-1} to @var{1}.
+Default is @var{0}.
+
@item fc_in
Set front center input volume. By default, this is @var{1}.
@@ -6682,6 +6951,7 @@ It accepts the following values:
@item parzen
@item poisson
@item bohman
+@item kaiser
@end table
Default is @code{hann}.
@@ -7295,6 +7565,33 @@ aevalsrc="0.1*sin(2*PI*(360-2.5/2)*t) | 0.1*sin(2*PI*(360+2.5/2)*t)"
@end itemize
+@section afdelaysrc
+
+Generate a fractional delay FIR coefficients.
+
+The resulting stream can be used with @ref{afir} filter for filtering the audio signal.
+
+The filter accepts the following options:
+
+@table @option
+@item delay, d
+Set the fractional delay. Default is 0.
+
+@item sample_rate, r
+Set the sample rate, default is 44100.
+
+@item nb_samples, n
+Set the number of samples per each frame. Default is 1024.
+
+@item taps, t
+Set the number of filter coefficents in output audio stream.
+Default value is 0.
+
+@item channel_layout, c
+Specifies the channel layout, and can be a string representing a channel layout.
+The default value of @var{channel_layout} is "stereo".
+@end table
+
@section afirsrc
Generate a FIR coefficients using frequency sampling method.
@@ -7923,6 +8220,25 @@ The command accepts the same syntax of the corresponding option.
If the specified expression is not valid, it is kept at its current
value.
+@section backgroundkey
+
+Turns a static background into transparency.
+
+The filter accepts the following option:
+
+@table @option
+@item threshold
+Threshold for scene change detection.
+@item similarity
+Similarity percentage with the background.
+@item blend
+Set the blend amount for pixels that are not similar.
+@end table
+
+@subsection Commands
+
+This filter supports the all above options as @ref{commands}.
+
@section bbox
Compute the bounding box for the non-black pixels in the input frame
@@ -7965,6 +8281,45 @@ Set planes to filter. Default is first only.
This filter supports the all above options as @ref{commands}.
+@section bilateral_cuda
+CUDA accelerated bilateral filter, an edge preserving filter.
+This filter is mathematically accurate thanks to the use of GPU acceleration.
+For best output quality, use one to one chroma subsampling, i.e. yuv444p format.
+
+The filter accepts the following options:
+@table @option
+@item sigmaS
+Set sigma of gaussian function to calculate spatial weight, also called sigma space.
+Allowed range is 0.1 to 512. Default is 0.1.
+
+@item sigmaR
+Set sigma of gaussian function to calculate color range weight, also called sigma color.
+Allowed range is 0.1 to 512. Default is 0.1.
+
+@item window_size
+Set window size of the bilateral function to determine the number of neighbours to loop on.
+If the number entered is even, one will be added automatically.
+Allowed range is 1 to 255. Default is 1.
+@end table
+@subsection Examples
+
+@itemize
+@item
+Apply the bilateral filter on a video.
+
+@example
+./ffmpeg -v verbose \
+-hwaccel cuda -hwaccel_output_format cuda -i input.mp4 \
+-init_hw_device cuda \
+-filter_complex \
+" \
+[0:v]scale_cuda=format=yuv444p[scaled_video];
+[scaled_video]bilateral_cuda=window_size=9:sigmaS=3.0:sigmaR=50.0" \
+-an -sn -c:v h264_nvenc -cq 20 out.mp4
+@end example
+
+@end itemize
+
@section bitplanenoise
Show and measure bit plane noise.
@@ -9671,6 +10026,38 @@ For example to convert the input to SMPTE-240M, use the command:
colorspace=smpte240m
@end example
+@section colorspace_cuda
+
+CUDA accelerated implementation of the colorspace filter.
+
+It is by no means feature complete compared to the software colorspace filter,
+and at the current time only supports color range conversion between jpeg/full
+and mpeg/limited range.
+
+The filter accepts the following options:
+
+@table @option
+@item range
+Specify output color range.
+
+The accepted values are:
+@table @samp
+@item tv
+TV (restricted) range
+
+@item mpeg
+MPEG (restricted) range
+
+@item pc
+PC (full) range
+
+@item jpeg
+JPEG (full) range
+
+@end table
+
+@end table
+
@section colortemperature
Adjust color temperature in video to simulate variations in ambient color temperature.
@@ -9902,6 +10289,30 @@ ffmpeg -f lavfi -i nullsrc=s=100x100,coreimage=filter=CIQRCodeGenerator@@inputMe
@end example
@end itemize
+@section corr
+
+Obtain the correlation between two input videos.
+
+This filter takes two input videos.
+
+Both input videos must have the same resolution and pixel format for
+this filter to work correctly. Also it assumes that both inputs
+have the same number of frames, which are compared one by one.
+
+The obtained per component, average, min and max correlation is printed through
+the logging system.
+
+The filter stores the calculated correlation of each frame in frame metadata.
+
+This filter also supports the @ref{framesync} options.
+
+In the below example the input file @file{main.mpg} being processed is compared
+with the reference file @file{ref.mpg}.
+
+@example
+ffmpeg -i main.mpg -i ref.mpg -lavfi corr -f null -
+@end example
+
@section cover_rect
Cover a rectangular object
@@ -10138,12 +10549,23 @@ Auto-detect the crop size.
It calculates the necessary cropping parameters and prints the
recommended parameters via the logging system. The detected dimensions
-correspond to the non-black area of the input video.
+correspond to the non-black or video area of the input video according to @var{mode}.
It accepts the following parameters:
@table @option
+@item mode
+Depending on @var{mode} crop detection is based on either the mere black value of surrounding pixels or a combination of motion vectors and edge pixels.
+
+@table @samp
+@item black
+Detect black pixels surrounding the playing video. For fine control use option @var{limit}.
+
+@item mvedges
+Detect the playing video by the motion vectors inside the video and scanning for edge pixels typically forming the border of a playing video.
+@end table
+
@item limit
Set higher black value threshold, which can be optionally specified
from nothing (0) to everything (255 for 8-bit based formats). An intensity
@@ -10169,6 +10591,56 @@ detect the current optimal crop area. Default value is 0.
This can be useful when channel logos distort the video area. 0
indicates 'never reset', and returns the largest area encountered during
playback.
+
+@item mv_threshold
+Set motion in pixel units as threshold for motion detection. It defaults to 8.
+
+@item low
+@item high
+Set low and high threshold values used by the Canny thresholding
+algorithm.
+
+The high threshold selects the "strong" edge pixels, which are then
+connected through 8-connectivity with the "weak" edge pixels selected
+by the low threshold.
+
+@var{low} and @var{high} threshold values must be chosen in the range
+[0,1], and @var{low} should be lesser or equal to @var{high}.
+
+Default value for @var{low} is @code{5/255}, and default value for @var{high}
+is @code{15/255}.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Find video area surrounded by black borders:
+@example
+ffmpeg -i file.mp4 -vf cropdetect,metadata=mode=print -f null -
+@end example
+
+@item
+Find an embedded video area, generate motion vectors beforehand:
+@example
+ffmpeg -i file.mp4 -vf mestimate,cropdetect=mode=mvedges,metadata=mode=print -f null -
+@end example
+
+@item
+Find an embedded video area, use motion vectors from decoder:
+@example
+ffmpeg -flags2 +export_mvs -i file.mp4 -vf cropdetect=mode=mvedges,metadata=mode=print -f null -
+@end example
+@end itemize
+
+@subsection Commands
+
+This filter supports the following commands:
+
+@table @option
+@item limit
+The command accepts the same syntax of the corresponding option.
+If the specified expression is not valid, it is kept at its current value.
@end table
@anchor{cue}
@@ -10218,11 +10690,15 @@ By default, a component curve is defined by the two points @var{(0;0)} and
"adjusted" to its own value, which means no change to the image.
The filter allows you to redefine these two points and add some more. A new
-curve (using a natural cubic spline interpolation) will be define to pass
-smoothly through all these new coordinates. The new defined points needs to be
-strictly increasing over the x-axis, and their @var{x} and @var{y} values must
-be in the @var{[0;1]} interval. If the computed curves happened to go outside
-the vector spaces, the values will be clipped accordingly.
+curve will be define to pass smoothly through all these new coordinates. The
+new defined points needs to be strictly increasing over the x-axis, and their
+@var{x} and @var{y} values must be in the @var{[0;1]} interval. The curve is
+formed by using a natural or monotonic cubic spline interpolation, depending
+on the @var{interp} option (default: @code{natural}). The @code{natural}
+spline produces a smoother curve in general while the monotonic (@code{pchip})
+spline guarantees the transitions between the specified points to be
+monotonic. If the computed curves happened to go outside the vector spaces,
+the values will be clipped accordingly.
The filter accepts the following options:
@@ -10266,6 +10742,15 @@ options. In this case, the unset component(s) will fallback on this
Specify a Photoshop curves file (@code{.acv}) to import the settings from.
@item plot
Save Gnuplot script of the curves in specified file.
+@item interp
+Specify the kind of interpolation. Available algorithms are:
+@table @samp
+@item natural
+Natural cubic spline using a piece-wise cubic polynomial that is twice continuously differentiable.
+@item pchip
+Monotonic cubic spline using a piecewise cubic Hermite interpolating polynomial (PCHIP).
+@end table
+
@end table
To avoid some filtergraph syntax conflicts, each key points list need to be
@@ -10613,6 +11098,11 @@ stream is the clean source from where the kept frames are chosen. Default is
@item chroma
Set whether or not chroma is considered in the metric calculations. Default is
@code{1}.
+
+@item mixed
+Set whether or not the input only partially contains content to be decimated.
+Default is @code{false}.
+If enabled video output stream will be in variable frame rate.
@end table
@section deconvolve
@@ -11842,7 +12332,7 @@ The current packet's position in the input file or stream
(in bytes, from the start of the input). A value of -1 indicates
this info is not available.
-@item pkt_duration
+@item duration
The current packet's duration, in seconds.
@item pkt_size
@@ -14481,6 +14971,7 @@ Set the scaling dimension: @code{2} for @code{hq2x}, @code{3} for
Default is @code{3}.
@end table
+@anchor{hstack}
@section hstack
Stack input videos horizontally.
@@ -14811,6 +15302,8 @@ the logging system.
The filter stores the calculated identity scores of each frame in frame metadata.
+This filter also supports the @ref{framesync} options.
+
In the below example the input file @file{main.mpg} being processed is compared
with the reference file @file{ref.mpg}.
@@ -15328,9 +15821,10 @@ will be performed.
Work the same as the identical @ref{scale} filter options.
@item normalize_sar
-If enabled (the default), output frames will always have a pixel aspect ratio
-of 1:1. If disabled, any aspect ratio mismatches, including those from e.g.
-anamorphic video sources, are forwarded to the output pixel aspect ratio.
+If enabled, output frames will always have a pixel aspect ratio of 1:1. This
+will introduce padding/cropping as necessary. If disabled (the default), any
+aspect ratio mismatches, including those from e.g. anamorphic video sources,
+are forwarded to the output pixel aspect ratio.
@item pad_crop_ratio
Specifies a ratio (between @code{0.0} and @code{1.0}) between padding and
@@ -15580,6 +16074,18 @@ Automatic selection based on internal heuristics. This is the default.
Performs no tone-mapping, just clips out-of-range colors. Retains perfect color
accuracy for in-range colors but completely destroys out-of-range information.
Does not perform any black point adaptation. Not configurable.
+@item st2094-40
+EETF from SMPTE ST 2094-40 Annex B, which applies the Bezier curves from HDR10+
+dynamic metadata based on Bezier curves to perform tone-mapping. The OOTF used
+is adjusted based on the ratio between the targeted and actual display peak
+luminances.
+@item st2094-10
+EETF from SMPTE ST 2094-10 Annex B.2, which takes into account the input signal
+average luminance in addition to the maximum/minimum. The configurable contrast
+parameter influences the slope of the linear output segment, defaulting to
+@code{1.0} for no increase/decrease in contrast. Note that this does not
+currently include the subjective gain/offset/gamma controls defined in Annex
+B.3.
@item bt.2390
EETF from the ITU-R Report BT.2390, a hermite spline roll-off with linear
segment. The knee point offset is configurable. Note that this parameter
@@ -16437,6 +16943,10 @@ video streams.
Set which planes will be processed as bitmap, unprocessed planes will be
copied from second stream.
By default value 0xf, all planes will be processed.
+
+@item mode
+Set mode of filter operation. Can be @code{abs} or @code{diff}.
+Default is @code{abs}.
@end table
@subsection Commands
@@ -16938,6 +17448,8 @@ the logging system.
The filter stores the calculated MSAD of each frame in frame metadata.
+This filter also supports the @ref{framesync} options.
+
In the below example the input file @file{main.mpg} being processed is compared
with the reference file @file{ref.mpg}.
@@ -18066,9 +18578,6 @@ Compute new histogram for each frame.
@end table
Default value is @var{full}.
-@item use_alpha
-Create a palette of colors with alpha components.
-Setting this, will automatically disable 'reserve_transparent'.
@end table
The filter also exports the frame metadata @code{lavfi.color_quant_ratio}
@@ -18111,6 +18620,12 @@ Floyd and Steingberg dithering (error diffusion)
Frankie Sierra dithering v2 (error diffusion)
@item sierra2_4a
Frankie Sierra dithering v2 "Lite" (error diffusion)
+@item sierra3
+Frankie Sierra dithering v3 (error diffusion)
+@item burkes
+Burkes dithering (error diffusion)
+@item atkinson
+Atkinson dithering by Bill Atkinson at Apple Computer (error diffusion)
@end table
Default is @var{sierra2_4a}.
@@ -18147,11 +18662,6 @@ will be treated as completely opaque, and values below this threshold will be
treated as completely transparent.
The option must be an integer value in the range [0,255]. Default is @var{128}.
-
-@item use_alpha
-Apply the palette by taking alpha values into account. Only useful with
-palettes that are containing multiple colors with alpha components.
-Setting this will automatically disable 'alpha_treshold'.
@end table
@subsection Examples
@@ -18683,6 +19193,7 @@ Available LUTs:
@item nominal
@item preferred
@item total
+@item spectral
@end table
@item opacity
@@ -21928,6 +22439,10 @@ The filter accepts the following options:
Set the frames batch size to analyze; in a set of @var{n} frames, the filter
will pick one of them, and then handle the next batch of @var{n} frames until
the end. Default is @code{100}.
+
+@item log
+Set the log level to display picked frame stats.
+Default is @code{info}.
@end table
Since the filter keeps track of the whole frames sequence, a bigger @var{n}
@@ -23779,6 +24294,8 @@ The obtained average VIF score is printed through the logging system.
The filter stores the calculated VIF score of each frame.
+This filter also supports the @ref{framesync} options.
+
In the below example the input file @file{main.mpg} being processed is compared
with the reference file @file{ref.mpg}.
@@ -23918,6 +24435,7 @@ Example:
ffmpeg -i ref.mpg -vf vmafmotion -f null -
@end example
+@anchor{vstack}
@section vstack
Stack input videos vertically.
@@ -24399,6 +24917,7 @@ minimum values, and @code{1} maximum values.
This filter supports all above options as @ref{commands}, excluding option @code{inputs}.
+@anchor{xstack}
@section xstack
Stack video inputs into custom layout.
@@ -26094,35 +26613,63 @@ To use vaapi filters, you need to setup the vaapi device correctly. For more inf
Overlay one video on the top of another.
It takes two inputs and has one output. The first input is the "main" video on which the second input is overlaid.
-This filter requires same memory layout for all the inputs. So, format conversion may be needed.
The filter accepts the following options:
@table @option
-
@item x
-Set the x coordinate of the overlaid video on the main video.
-Default value is @code{0}.
-
@item y
-Set the y coordinate of the overlaid video on the main video.
-Default value is @code{0}.
+Set expressions for the x and y coordinates of the overlaid video
+on the main video.
+
+Default value is "0" for both expressions.
@item w
-Set the width of the overlaid video on the main video.
-Default value is the width of input overlay video.
-
@item h
-Set the height of the overlaid video on the main video.
-Default value is the height of input overlay video.
+Set expressions for the width and height the overlaid video
+on the main video.
-@item alpha
-Set blocking detection thresholds. Allowed range is 0.0 to 1.0, it
-requires an input video with alpha channel.
-Default value is @code{0.0}.
+Default values are 'overlay_iw' for 'w' and 'overlay_ih*w/overlay_iw' for 'h'.
+
+The expressions can contain the following parameters:
+
+@table @option
+
+@item main_w, W
+@item main_h, H
+The main input width and height.
+
+@item overlay_iw
+@item overlay_ih
+The overlay input width and height.
+
+@item overlay_w, w
+@item overlay_h, h
+The overlay output width and height.
+
+@item overlay_x, x
+@item overlay_y, y
+Position of the overlay layer inside of main
@end table
+@item alpha
+Set transparency of overlaid video. Allowed range is 0.0 to 1.0.
+Higher value means lower transparency.
+Default value is @code{1.0}.
+
+@item eof_action
+See @ref{framesync}.
+
+@item shortest
+See @ref{framesync}.
+
+@item repeatlast
+See @ref{framesync}.
+
+@end table
+
+This filter also supports the @ref{framesync} options.
@subsection Examples
@itemize
@@ -26187,8 +26734,174 @@ tonemap_vaapi=format=p010:t=bt2020-10
@end example
@end itemize
+@section hstack_vaapi
+Stack input videos horizontally.
+
+This is the VA-API variant of the @ref{hstack} filter, each input stream may
+have different height, this filter will scale down/up each input stream while
+keeping the orignal aspect.
+
+It accepts the following options:
+
+@table @option
+@item inputs
+See @ref{hstack}.
+
+@item shortest
+See @ref{hstack}.
+
+@item height
+Set height of output. If set to 0, this filter will set height of output to
+height of the first input stream. Default value is 0.
+@end table
+
+@section vstack_vaapi
+Stack input videos vertically.
+
+This is the VA-API variant of the @ref{vstack} filter, each input stream may
+have different width, this filter will scale down/up each input stream while
+keeping the orignal aspect.
+
+It accepts the following options:
+
+@table @option
+@item inputs
+See @ref{vstack}.
+
+@item shortest
+See @ref{vstack}.
+
+@item width
+Set width of output. If set to 0, this filter will set width of output to
+width of the first input stream. Default value is 0.
+@end table
+
+@section xstack_vaapi
+Stack video inputs into custom layout.
+
+This is the VA-API variant of the @ref{xstack} filter, each input stream may
+have different size, this filter will scale down/up each input stream to the
+given output size, or the size of the first input stream.
+
+It accepts the following options:
+
+@table @option
+@item inputs
+See @ref{xstack}.
+
+@item shortest
+See @ref{xstack}.
+
+@item layout
+See @ref{xstack}.
+Moreover, this permits the user to supply output size for each input stream.
+@example
+xstack_vaapi=inputs=4:layout=0_0_1920x1080|0_h0_1920x1080|w0_0_1920x1080|w0_h0_1920x1080
+@end example
+
+@item grid
+See @ref{xstack}.
+
+@item grid_tile_size
+Set output size for each input stream when @option{grid} is set. If this option
+is not set, this filter will set output size by default to the size of the
+first input stream. For the syntax of this option, check the
+@ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+
+@item fill
+See @ref{xstack}.
+@end table
+
@c man end VAAPI VIDEO FILTERS
+@chapter QSV Video Filters
+@c man begin QSV VIDEO FILTERS
+
+Below is a description of the currently available QSV video filters.
+
+To enable compilation of these filters you need to configure FFmpeg with
+@code{--enable-libmfx} or @code{--enable-libvpl}.
+
+To use QSV filters, you need to setup the QSV device correctly. For more information, please read @url{https://trac.ffmpeg.org/wiki/Hardware/QuickSync}
+
+@section hstack_qsv
+Stack input videos horizontally.
+
+This is the QSV variant of the @ref{hstack} filter, each input stream may
+have different height, this filter will scale down/up each input stream while
+keeping the orignal aspect.
+
+It accepts the following options:
+
+@table @option
+@item inputs
+See @ref{hstack}.
+
+@item shortest
+See @ref{hstack}.
+
+@item height
+Set height of output. If set to 0, this filter will set height of output to
+height of the first input stream. Default value is 0.
+@end table
+
+@section vstack_qsv
+Stack input videos vertically.
+
+This is the QSV variant of the @ref{vstack} filter, each input stream may
+have different width, this filter will scale down/up each input stream while
+keeping the orignal aspect.
+
+It accepts the following options:
+
+@table @option
+@item inputs
+See @ref{vstack}.
+
+@item shortest
+See @ref{vstack}.
+
+@item width
+Set width of output. If set to 0, this filter will set width of output to
+width of the first input stream. Default value is 0.
+@end table
+
+@section xstack_qsv
+Stack video inputs into custom layout.
+
+This is the QSV variant of the @ref{xstack} filter.
+
+It accepts the following options:
+
+@table @option
+@item inputs
+See @ref{xstack}.
+
+@item shortest
+See @ref{xstack}.
+
+@item layout
+See @ref{xstack}.
+Moreover, this permits the user to supply output size for each input stream.
+@example
+xstack_qsv=inputs=4:layout=0_0_1920x1080|0_h0_1920x1080|w0_0_1920x1080|w0_h0_1920x1080
+@end example
+
+@item grid
+See @ref{xstack}.
+
+@item grid_tile_size
+Set output size for each input stream when @option{grid} is set. If this option
+is not set, this filter will set output size by default to the size of the
+first input stream. For the syntax of this option, check the
+@ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+
+@item fill
+See @ref{xstack}.
+@end table
+
+@c man end QSV VIDEO FILTERS
+
@chapter Video Sources
@c man begin VIDEO SOURCES
@@ -26230,11 +26943,6 @@ Specify the frame rate expected for the video stream.
@item pixel_aspect, sar
The sample (pixel) aspect ratio of the input video.
-@item sws_param
-This option is deprecated and ignored. Prepend @code{sws_flags=@var{flags};}
-to the filtergraph description to specify swscale flags for automatically
-inserted scalers. See @ref{Filtergraph syntax}.
-
@item hw_frames_ctx
When using a hardware pixel format, this should be a reference to an
AVHWFramesContext describing input frames.
@@ -26435,6 +27143,90 @@ need for a nullsrc video source.
@end itemize
+@section ddagrab
+
+Captures the Windows Desktop via Desktop Duplication API.
+
+The filter exclusively returns D3D11 Hardware Frames, for on-gpu encoding
+or processing. So an explicit @ref{hwdownload} is needed for any kind of
+software processing.
+
+It accepts the following options:
+
+@table @option
+@item output_idx
+DXGI Output Index to capture.
+
+Usually corresponds to the index Windows has given the screen minus one,
+so it's starting at 0.
+
+Defaults to output 0.
+
+@item draw_mouse
+Whether to draw the mouse cursor.
+
+Defaults to true.
+
+Only affects hardware cursors. If a game or application renders its own cursor,
+it'll always be captured.
+
+@item framerate
+Framerate at which the desktop will be captured.
+
+Defaults to 30 FPS.
+
+@item video_size
+Specify the size of the captured video.
+
+Defaults to the full size of the screen.
+
+Cropped from the bottom/right if smaller than screen size.
+
+@item offset_x
+Horizontal offset of the captured video.
+
+@item offset_y
+Vertical offset of the captured video.
+
+@item output_fmt
+Desired filter output format.
+Defaults to 8 Bit BGRA.
+
+It accepts the following values:
+@table @samp
+@item auto
+Passes all supported output formats to DDA and returns what DDA decides to use.
+@item 8bit
+@item bgra
+8 Bit formats always work, and DDA will convert to them if neccesary.
+@item 10bit
+@item x2bgr10
+Filter initialization will fail if 10 bit format is requested but unavailable.
+@end table
+
+@end table
+
+@subsection Examples
+
+Capture primary screen and encode using nvenc:
+@example
+ffmpeg -f lavfi -i ddagrab -c:v h264_nvenc -cq 18 output.mp4
+@end example
+
+You can also skip the lavfi device and directly use the filter.
+Also demonstrates downloading the frame and encoding with libx264.
+Explicit output format specification is required in this case:
+@example
+ffmpeg -filter_complex ddagrab=output_idx=1:framerate=60,hwdownload,format=bgra -c:v libx264 -crf 18 output.mp4
+@end example
+
+If you want to capture only a subsection of the desktop, this can be achieved
+by specifying a smaller size and its offsets into the screen:
+@example
+ddagrab=video_size=800x600:offset_x=100:offset_y=100
+@end example
+
+
@section gradients
Generate several gradients.
@@ -27082,6 +27874,61 @@ tools.
Below is a description of the currently available multimedia filters.
+@section a3dscope
+
+Convert input audio to 3d scope video output.
+
+The filter accepts the following options:
+
+@table @option
+@item rate, r
+Set frame rate, expressed as number of frames per second. Default
+value is "25".
+
+@item size, s
+Specify the video size for the output. For the syntax of this option, check the
+@ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+Default value is @code{hd720}.
+
+@item fov
+Set the camera field of view. Default is 90 degrees.
+Allowed range is from 40 to 150.
+
+@item roll
+Set the camera roll.
+
+@item pitch
+Set the camera pitch.
+
+@item yaw
+Set the camera yaw.
+
+@item xzoom
+Set the camera zoom on X-axis.
+
+@item yzoom
+Set the camera zoom on Y-axis.
+
+@item zzoom
+Set the camera zoom on Z-axis.
+
+@item xpos
+Set the camera position on X-axis.
+
+@item ypos
+Set the camera position on Y-axis.
+
+@item zpos
+Set the camera position on Z-axis.
+
+@item length
+Set the length of displayed audio waves in number of frames.
+@end table
+
+@subsection Commands
+
+Filter supports the some above options as @ref{commands}.
+
@section abitscope
Convert input audio to a video output, displaying the audio bit scope.
@@ -27345,6 +28192,9 @@ Draw dot for each sample.
@item line
Draw line between previous and current sample.
+
+@item aaline
+Draw anti-aliased line between previous and current sample.
@end table
Default value is @samp{dot}.
@@ -27585,6 +28435,8 @@ Force the frame logging level.
Available values are:
@table @samp
+@item quiet
+logging disabled
@item info
information logging level
@item verbose
@@ -28840,6 +29692,105 @@ axisfile=myaxis.png:basefreq=40:endfreq=10000
@end example
@end itemize
+@section showcwt
+
+Convert input audio to video output representing frequency spectrum
+using Continuous Wavelet Transform and Morlet wavelet.
+
+The filter accepts the following options:
+
+@table @option
+@item size, s
+Specify the video size for the output. For the syntax of this option,
+check the @ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+Default value is @code{640x512}.
+
+@item rate, r
+Set the output frame rate. Default value is @code{25}.
+
+@item scale
+Set the frequency scale used. Allowed values are:
+
+@table @option
+@item linear
+@item log2
+@item bark
+@item mel
+@item erbs
+@end table
+Default value is @code{linear}.
+
+@item min
+Set the minimum frequency that will be used in output.
+Default is @code{20} Hz.
+
+@item max
+Set the maximum frequency that will be used in output.
+Default is @code{20000} Hz. The real frequency upper limit
+depends on input audio's sample rate and such will be enforced
+on this value when it is set to value greater than Nyquist frequency.
+
+@item logb
+Set the logarithmic basis for brightness strength when
+mapping calculated magnitude values to pixel values.
+Allowed range is from @code{0} to @code{1}.
+Default value is @code{0.0001}.
+
+@item deviation
+Set the frequency deviation.
+Lower values than @code{1} are more frequency oriented,
+while higher values than @code{1} are more time oriented.
+Allowed range is from @code{0} to @code{10}.
+Default value is @code{1}.
+
+@item pps
+Set the number of pixel output per each second in one row.
+Allowed range is from @code{1} to @code{1024}.
+Default value is @code{64}.
+
+@item mode
+Set the output visual mode. Allowed values are:
+
+@table @option
+@item magnitude
+Show magnitude.
+@item phase
+Show only phase.
+@item magphase
+Show combination of magnitude and phase.
+Magnitude is mapped to brightness and phase to color.
+@item channel
+Show unique color per channel magnitude.
+@item stereo
+Show unique color per stereo difference.
+@end table
+
+Default value is @code{magnitude}.
+
+@item slide
+Set the output slide method. Allowed values are:
+
+@table @option
+@item replace
+@item scroll
+@item frame
+@end table
+
+@item direction
+Set the direction method for output slide method. Allowed values are:
+
+@table @option
+@item lr
+Direction from left to right.
+@item rl
+Direction from right to left.
+@item ud
+Direction from up to down.
+@item du
+Direction from down to up.
+@end table
+@end table
+
@section showfreqs
Convert input audio to video output representing the audio power spectrum.
@@ -28933,6 +29884,7 @@ It accepts the following values:
@item parzen
@item poisson
@item bohman
+@item kaiser
@end table
Default is @code{hanning}.
@@ -29019,14 +29971,13 @@ It accepts the following values:
@item parzen
@item poisson
@item bohman
+@item kaiser
@end table
Default value is @code{hann}.
-@item overlap
-Set ratio of overlap window. Default value is @code{0.5}.
-When value is @code{1} overlap is set to recommended size for specific
-window function currently used.
+@item rate, r
+Set output framerate.
@end table
@anchor{showspectrum}
@@ -29180,6 +30131,7 @@ It accepts the following values:
@item parzen
@item poisson
@item bohman
+@item kaiser
@end table
Default value is @code{hann}.
@@ -29377,6 +30329,7 @@ It accepts the following values:
@item parzen
@item poisson
@item bohman
+@item kaiser
@end table
Default value is @code{hann}.
diff --git a/doc/general_contents.texi b/doc/general_contents.texi
index b1d3e3aa0..2eeebd847 100644
--- a/doc/general_contents.texi
+++ b/doc/general_contents.texi
@@ -510,6 +510,8 @@ library:
@tab A format used by libvpx
@item Internet Video Recording @tab @tab X
@item IRCAM @tab X @tab X
+@item LAF @tab @tab X
+ @tab Limitless Audio Format
@item LATM @tab X @tab X
@item LMLM4 @tab @tab X
@tab Used by Linux Media Labs MPEG-4 PCI boards
@@ -532,6 +534,8 @@ library:
@item Metal Gear Solid: The Twin Snakes @tab @tab X
@item Megalux Frame @tab @tab X
@tab Used by Megalux Ultimate Paint
+@item MobiClip MODS @tab @tab X
+@item MobiClip MOFLEX @tab @tab X
@item Mobotix .mxg @tab @tab X
@item Monkey's Audio @tab @tab X
@item Motion Pixels MVI @tab @tab X
@@ -575,6 +579,7 @@ library:
@item Ogg @tab X @tab X
@item Playstation Portable PMP @tab @tab X
@item Portable Voice Format @tab @tab X
+@item RK Audio (RKA) @tab @tab X
@item TechnoTrend PVA @tab @tab X
@tab Used by TechnoTrend DVB PCI boards.
@item QCP @tab @tab X
@@ -582,8 +587,10 @@ library:
@item raw AC-3 @tab X @tab X
@item raw AMR-NB @tab @tab X
@item raw AMR-WB @tab @tab X
+@item raw APAC @tab @tab X
@item raw aptX @tab X @tab X
@item raw aptX HD @tab X @tab X
+@item raw Bonk @tab @tab X
@item raw Chinese AVS video @tab X @tab X
@item raw DFPWM @tab X @tab X
@item raw Dirac @tab X @tab X
@@ -659,8 +666,10 @@ library:
@item Sample Dump eXchange @tab @tab X
@item SAP @tab X @tab X
@item SBG @tab @tab X
+@item SDNS @tab @tab X
@item SDP @tab @tab X
@item SER @tab @tab X
+@item Digital Pictures SGA @tab @tab X
@item Sega FILM/CPK @tab X @tab X
@tab Used in many Sega Saturn console games.
@item Silicon Graphics Movie @tab @tab X
@@ -698,7 +707,9 @@ library:
@item Vivo @tab @tab X
@item VPK @tab @tab X
@tab Audio format used in Sony PS games.
+@item Marble WADY @tab @tab X
@item WAV @tab X @tab X
+@item Waveform Archiver @tab @tab X
@item WavPack @tab X @tab X
@item WebM @tab X @tab X
@item Windows Televison (WTV) @tab X @tab X
@@ -710,6 +721,7 @@ library:
@tab Multimedia format used in Westwood Studios games.
@item Wideband Single-bit Data (WSD) @tab @tab X
@item WVE @tab @tab X
+@item Konami XMD @tab @tab X
@item XMV @tab @tab X
@tab Microsoft video container used in Xbox games.
@item XVAG @tab @tab X
@@ -749,6 +761,8 @@ following image formats are supported:
@tab OpenEXR
@item FITS @tab X @tab X
@tab Flexible Image Transport System
+@item HDR @tab X @tab X
+ @tab Radiance HDR RGBE Image format
@item IMG @tab @tab X
@tab GEM Raster image
@item JPEG @tab X @tab X
@@ -757,6 +771,7 @@ following image formats are supported:
@item JPEG-LS @tab X @tab X
@item LJPEG @tab X @tab
@tab Lossless JPEG
+@item Media 100 @tab @tab X
@item MSP @tab @tab X
@tab Microsoft Paint image
@item PAM @tab X @tab X
@@ -799,6 +814,8 @@ following image formats are supported:
@tab Targa (.TGA) image format
@item VBN @tab X @tab X
@tab Vizrt Binary Image format
+@item WBMP @tab X @tab X
+ @tab Wireless Application Protocol Bitmap image format
@item WebP @tab E @tab X
@tab WebP image format, encoding supported through external library libwebp
@item XBM @tab X @tab X
@@ -1151,6 +1168,7 @@ following image formats are supported:
@item ADPCM IMA Electronic Arts SEAD @tab @tab X
@item ADPCM IMA Funcom @tab @tab X
@item ADPCM IMA High Voltage Software ALP @tab X @tab X
+@item ADPCM IMA Mobiclip MOFLEX @tab @tab X
@item ADPCM IMA QuickTime @tab X @tab X
@item ADPCM IMA Simon & Schuster Interactive @tab X @tab X
@item ADPCM IMA Ubisoft APM @tab X @tab X
@@ -1180,6 +1198,7 @@ following image formats are supported:
@item ADPCM Sound Blaster Pro 4-bit @tab @tab X
@item ADPCM VIMA @tab @tab X
@tab Used in LucasArts SMUSH animations.
+@item ADPCM Konami XMD @tab @tab X
@item ADPCM Westwood Studios IMA @tab X @tab X
@tab Used in Westwood Studios games like Command and Conquer.
@item ADPCM Yamaha @tab X @tab X
@@ -1201,6 +1220,7 @@ following image formats are supported:
@item ATRAC9 @tab @tab X
@item Bink Audio @tab @tab X
@tab Used in Bink and Smacker files in many games.
+@item Bonk audio @tab @tab X
@item CELT @tab @tab E
@tab decoding supported through external library libcelt
@item codec2 @tab E @tab E
@@ -1216,9 +1236,12 @@ following image formats are supported:
@item DCA (DTS Coherent Acoustics) @tab X @tab X
@tab supported extensions: XCh, XXCH, X96, XBR, XLL, LBR (partially)
@item Dolby E @tab @tab X
+@item DPCM Cuberoot-Delta-Exact @tab @tab X
+ @tab Used in few games.
@item DPCM Gremlin @tab @tab X
@item DPCM id RoQ @tab X @tab X
@tab Used in Quake III, Jedi Knight 2 and other computer games.
+@item DPCM Marble WADY @tab @tab X
@item DPCM Interplay @tab @tab X
@tab Used in various Interplay computer games.
@item DPCM Squareroot-Delta-Exact @tab @tab X
@@ -1239,6 +1262,7 @@ following image formats are supported:
@item Enhanced AC-3 @tab X @tab X
@item EVRC (Enhanced Variable Rate Codec) @tab @tab X
@item FLAC (Free Lossless Audio Codec) @tab X @tab IX
+@item FTR Voice @tab @tab X
@item G.723.1 @tab X @tab X
@item G.729 @tab @tab X
@item GSM @tab E @tab X
@@ -1252,6 +1276,8 @@ following image formats are supported:
@item Interplay ACM @tab @tab X
@item MACE (Macintosh Audio Compression/Expansion) 3:1 @tab @tab X
@item MACE (Macintosh Audio Compression/Expansion) 6:1 @tab @tab X
+@item Marian's A-pac audio @tab @tab X
+@item MI-SC4 (Micronas SC-4 Audio) @tab @tab X
@item MLP (Meridian Lossless Packing) @tab X @tab X
@tab Used in DVD-Audio discs.
@item Monkey's Audio @tab @tab X
@@ -1261,6 +1287,7 @@ following image formats are supported:
@item MP3 (MPEG audio layer 3) @tab E @tab IX
@tab encoding supported through external library LAME, ADU MP3 and MP3onMP4 also supported
@item MPEG-4 Audio Lossless Coding (ALS) @tab @tab X
+@item MobiClip FastAudio @tab @tab X
@item Musepack SV7 @tab @tab X
@item Musepack SV8 @tab @tab X
@item Nellymoser Asao @tab X @tab X
@@ -1295,6 +1322,7 @@ following image formats are supported:
@item PCM unsigned 24-bit little-endian @tab X @tab X
@item PCM unsigned 32-bit big-endian @tab X @tab X
@item PCM unsigned 32-bit little-endian @tab X @tab X
+@item PCM SGA @tab @tab X
@item QCELP / PureVoice @tab @tab X
@item QDesign Music Codec 1 @tab @tab X
@item QDesign Music Codec 2 @tab @tab X
@@ -1307,6 +1335,7 @@ following image formats are supported:
@tab Real low bitrate AC-3 codec
@item RealAudio Lossless @tab @tab X
@item RealAudio SIPR / ACELP.NET @tab @tab X
+@item RK Audio (RKA) @tab @tab X
@item SBC (low-complexity subband codec) @tab X @tab X
@tab Used in Bluetooth A2DP
@item Shorten @tab @tab X
@@ -1327,9 +1356,11 @@ following image formats are supported:
@item TwinVQ (VQF flavor) @tab @tab X
@item VIMA @tab @tab X
@tab Used in LucasArts SMUSH animations.
+@item ViewQuest VQC @tab @tab X
@item Vorbis @tab E @tab X
@tab A native but very primitive encoder exists.
@item Voxware MetaSound @tab @tab X
+@item Waveform Archiver @tab @tab X
@item WavPack @tab X @tab X
@item Westwood Audio (SND1) @tab @tab X
@item Windows Media Audio 1 @tab X @tab X
diff --git a/doc/muxers.texi b/doc/muxers.texi
index b2f4326aa..79dd86418 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -795,12 +795,6 @@ deletes them. Increase this to allow continue clients to download segments which
were recently referenced in the playlist. Default value is 1, meaning segments older than
@code{hls_list_size+1} will be deleted.
-@item hls_ts_options @var{options_list}
-Set output format options using a :-separated list of key=value
-parameters. Values containing @code{:} special characters must be
-escaped.
-@code{hls_ts_options} is deprecated, use hls_segment_options instead of it..
-
@item hls_start_number_source
Start the playlist sequence number (@code{#EXT-X-MEDIA-SEQUENCE}) according to the specified source.
Unless @code{hls_flags single_file} is set, it also specifies source of starting sequence numbers of
@@ -1915,6 +1909,8 @@ Conform to System B (DVB) instead of System A (ATSC).
Mark the initial packet of each stream as discontinuity.
@item nit
Emit NIT table.
+@item omit_rai
+Disable writing of random access indicator.
@end table
@item mpegts_copyts @var{boolean}
@@ -2367,6 +2363,11 @@ Note that splitting may not be accurate, unless you force the
reference stream key-frames at the given time. See the introductory
notice and the examples below.
+@item min_seg_duration @var{time}
+Set minimum segment duration to @var{time}, the value must be a duration
+specification. This prevents the muxer ending segments at a duration below
+this value. Only effective with @code{segment_time}. Default value is "0".
+
@item segment_atclocktime @var{1|0}
If set to "1" split at regular clock time intervals starting from 00:00
o'clock. The @var{time} value specified in @option{segment_time} is
diff --git a/doc/optimization.txt b/doc/optimization.txt
index 974e2f9af..3ed29fe38 100644
--- a/doc/optimization.txt
+++ b/doc/optimization.txt
@@ -267,6 +267,11 @@ CELL/SPU:
http://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/30B3520C93F437AB87257060006FFE5E/$file/Language_Extensions_for_CBEA_2.4.pdf
http://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/9F820A5FFA3ECE8C8725716A0062585F/$file/CBE_Handbook_v1.1_24APR2007_pub.pdf
+RISC-V-specific:
+----------------
+The RISC-V Instruction Set Manual, Volume 1, Unprivileged ISA:
+https://riscv.org/technical/specifications/
+
GCC asm links:
--------------
official doc but quite ugly
diff --git a/doc/protocols.texi b/doc/protocols.texi
index 0df38d790..21ae6181a 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -275,6 +275,33 @@ For example, to convert a GIF file given inline with @command{ffmpeg}:
ffmpeg -i "data:image/gif;base64,R0lGODdhCAAIAMIEAAAAAAAA//8AAP//AP///////////////ywAAAAACAAIAAADF0gEDLojDgdGiJdJqUX02iB4E8Q9jUMkADs=" smiley.png
@end example
+@section fd
+
+File descriptor access protocol.
+
+The accepted syntax is:
+@example
+fd: -fd @var{file_descriptor}
+@end example
+
+If @option{fd} is not specified, by default the stdout file descriptor will be
+used for writing, stdin for reading. Unlike the pipe protocol, fd protocol has
+seek support if it corresponding to a regular file. fd protocol doesn't support
+pass file descriptor via URL for security.
+
+This protocol accepts the following options:
+
+@table @option
+@item blocksize
+Set I/O operation maximum block size, in bytes. Default value is
+@code{INT_MAX}, which results in not limiting the requested block size.
+Setting this value reasonably low improves user termination request reaction
+time, which is valuable if data transmission is slow.
+
+@item fd
+Set file descriptor.
+@end table
+
@section file
File access protocol.
@@ -622,9 +649,6 @@ This protocol wraps the IPFS native protocols (ipfs:// and ipns://) to be sent
to such a gateway. Users can (and should) host their own node which means this
protocol will use one's local gateway to access files on the IPFS network.
-If a user doesn't have a node of their own then the public gateway @code{https://dweb.link}
-is used by default.
-
This protocol accepts the following options:
@table @option
@@ -632,18 +656,18 @@ This protocol accepts the following options:
@item gateway
Defines the gateway to use. When not set, the protocol will first try
locating the local gateway by looking at @code{$IPFS_GATEWAY}, @code{$IPFS_PATH}
-and @code{$HOME/.ipfs/}, in that order. If that fails @code{https://dweb.link} will be used.
+and @code{$HOME/.ipfs/}, in that order.
@end table
One can use this protocol in 2 ways. Using IPFS:
@example
-ffplay ipfs://QmbGtJg23skhvFmu9mJiePVByhfzu5rwo74MEkVDYAmF5T
+ffplay ipfs://
@end example
Or the IPNS protocol (IPNS is mutable IPFS):
@example
-ffplay ipns://QmbGtJg23skhvFmu9mJiePVByhfzu5rwo74MEkVDYAmF5T
+ffplay ipns://
@end example
@section mmst
@@ -690,7 +714,7 @@ The accepted syntax is:
pipe:[@var{number}]
@end example
-@var{number} is the number corresponding to the file descriptor of the
+If @option{fd} isn't specified, @var{number} is the number corresponding to the file descriptor of the
pipe (e.g. 0 for stdin, 1 for stdout, 2 for stderr). If @var{number}
is not specified, by default the stdout file descriptor will be used
for writing, stdin for reading.
@@ -717,6 +741,8 @@ Set I/O operation maximum block size, in bytes. Default value is
@code{INT_MAX}, which results in not limiting the requested block size.
Setting this value reasonably low improves user termination request reaction
time, which is valuable if data transmission is slow.
+@item fd
+Set file descriptor.
@end table
Note that some formats (typically MOV), require the output protocol to
@@ -1178,6 +1204,59 @@ Options can be set on the @command{ffmpeg}/@command{ffplay} command
line, or set in code via @code{AVOption}s or in
@code{avformat_open_input}.
+@subsection Muxer
+The following options are supported.
+
+@table @option
+@item rtsp_transport
+Set RTSP transport protocols.
+
+It accepts the following values:
+@table @samp
+@item udp
+Use UDP as lower transport protocol.
+
+@item tcp
+Use TCP (interleaving within the RTSP control channel) as lower
+transport protocol.
+@end table
+
+Default value is @samp{0}.
+
+@item rtsp_flags
+Set RTSP flags.
+
+The following values are accepted:
+@table @samp
+@item latm
+Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC.
+@item rfc2190
+Use RFC 2190 packetization instead of RFC 4629 for H.263.
+@item skip_rtcp
+Don't send RTCP sender reports.
+@item h264_mode0
+Use mode 0 for H.264 in RTP.
+@item send_bye
+Send RTCP BYE packets when finishing.
+@end table
+
+Default value is @samp{0}.
+
+
+@item min_port
+Set minimum local UDP port. Default value is 5000.
+
+@item max_port
+Set maximum local UDP port. Default value is 65000.
+
+@item buffer_size
+Set the maximum socket buffer size in bytes.
+
+@item pkt_size
+Set max send packet size (in bytes). Default value is 1472.
+@end table
+
+@subsection Demuxer
The following options are supported.
@table @option
@@ -1203,6 +1282,10 @@ Use UDP multicast as lower transport protocol.
@item http
Use HTTP tunneling as lower transport protocol, which is useful for
passing proxies.
+
+@item https
+Use HTTPs tunneling as lower transport protocol, which is useful for
+passing proxies and widely used for security consideration.
@end table
Multiple lower transport protocols may be specified, in that case they are
@@ -1220,6 +1303,9 @@ Accept packets only from negotiated peer address and port.
Act as a server, listening for an incoming connection.
@item prefer_tcp
Try TCP for RTP transport first, if TCP is available as RTSP RTP transport.
+@item satip_raw
+Export raw MPEG-TS stream instead of demuxing. The flag will simply write out
+the raw stream, with the original PAT/PMT/PIDs intact.
@end table
Default value is @samp{none}.
@@ -1232,6 +1318,7 @@ The following flags are accepted:
@item video
@item audio
@item data
+@item subtitle
@end table
By default it accepts all media types.
@@ -1256,6 +1343,9 @@ Set socket TCP I/O timeout in microseconds.
@item user_agent
Override User-Agent header. If not specified, it defaults to the
libavformat identifier string.
+
+@item buffer_size
+Set the maximum socket buffer size in bytes.
@end table
When receiving data over UDP, the demuxer tries to reorder received packets
diff --git a/doc/resampler.texi b/doc/resampler.texi
index 5ed3f4377..a6224eefb 100644
--- a/doc/resampler.texi
+++ b/doc/resampler.texi
@@ -11,18 +11,8 @@ programmatic use.
@table @option
-@item ich, in_channel_count
-Set the number of input channels. Default value is 0. Setting this
-value is not mandatory if the corresponding channel layout
-@option{in_channel_layout} is set.
-
-@item och, out_channel_count
-Set the number of output channels. Default value is 0. Setting this
-value is not mandatory if the corresponding channel layout
-@option{out_channel_layout} is set.
-
-@item uch, used_channel_count
-Set the number of used input channels. Default value is 0. This option is
+@item uchl, used_chlayout
+Set used input channel layout. Default is unset. This option is
only used for special remapping.
@item isr, in_sample_rate
@@ -41,8 +31,8 @@ Specify the output sample format. It is set by default to @code{none}.
Set the internal sample format. Default value is @code{none}.
This will automatically be chosen when it is not explicitly set.
-@item icl, in_channel_layout
-@item ocl, out_channel_layout
+@item ichl, in_chlayout
+@item ochl, out_chlayout
Set the input/output channel layout.
See @ref{channel layout syntax,,the Channel Layout section in the ffmpeg-utils(1) manual,ffmpeg-utils}
diff --git a/doc/transforms.md b/doc/transforms.md
index 78f3f68d6..04a7c408f 100644
--- a/doc/transforms.md
+++ b/doc/transforms.md
@@ -704,3 +704,326 @@ Also note that this function requires a special iteration way, due to coefficien
beginning to overlap, particularly `[o1]` with `[0]` after the second iteration.
To iterate further, set `z = &z[16]` via `z += 8` for the second iteration. After
the 4th iteration, the layout resets, so repeat the same.
+
+
+# 15-point AVX FFT transform
+The 15-point transform is based on the following unrolling. The input
+must be permuted via the following loop:
+
+``` C
+ for (int k = 0; k < s->sub[0].len; k++) {
+ int cnt = 0;
+ int tmp[15];
+ memcpy(tmp, &s->map[k*15], 15*sizeof(*tmp));
+ for (int i = 1; i < 15; i += 3) {
+ s->map[k*15 + cnt] = tmp[i];
+ cnt++;
+ }
+ for (int i = 2; i < 15; i += 3) {
+ s->map[k*15 + cnt] = tmp[i];
+ cnt++;
+ }
+ for (int i = 0; i < 15; i += 3) {
+ s->map[k*15 + cnt] = tmp[i];
+ cnt++;
+ }
+ memmove(&s->map[k*15 + 7], &s->map[k*15 + 6], 4*sizeof(int));
+ memmove(&s->map[k*15 + 3], &s->map[k*15 + 1], 4*sizeof(int));
+ s->map[k*15 + 1] = tmp[2];
+ s->map[k*15 + 2] = tmp[0];
+ }
+
+```
+
+This separates the ACs from the DCs and flips the SIMD direction to
+performing 5x3pt transforms at once, followed by 3x5pt transforms.
+
+``` C
+static av_always_inline void fft15(TXComplex *out, TXComplex *in,
+ ptrdiff_t stride)
+{
+ const TXSample *tab = TX_TAB(ff_tx_tab_53);
+ TXComplex q[20];
+ TXComplex dc[3], pc[32];
+ TXComplex y[32], k[32];
+ TXComplex t[32];
+ TXComplex r[32];
+ TXComplex z0[32];
+
+ /* DC */
+ pc[0].re = in[ 1].im - in[ 0].im;
+ pc[0].im = in[ 1].re - in[ 0].re;
+ pc[1].re = in[ 1].re + in[ 0].re;
+ pc[1].im = in[ 1].im + in[ 0].im;
+
+ dc[0].re = in[2].re + pc[1].re;
+ dc[0].im = in[2].im + pc[1].im;
+
+ pc[0].re = tab[ 8] * pc[0].re;
+ pc[0].im = tab[ 9] * pc[0].im;
+ pc[1].re = tab[10] * pc[1].re;
+ pc[1].im = tab[11] * pc[1].im;
+
+ dc[1].re = pc[0].re + pc[1].re;
+ dc[1].im = pc[0].im + pc[1].im;
+ dc[2].re = pc[1].re - pc[0].re;
+ dc[2].im = pc[1].im - pc[0].im;
+
+ dc[1].re = in[2].re - dc[1].re;
+ dc[1].im = in[2].im + dc[1].im;
+ dc[2].re = in[2].re - dc[2].re;
+ dc[2].im = in[2].im + dc[2].im;
+
+ /* ACs */
+ q[0].im = in[ 3].re - in[ 7].re; // NOTE THE ORDER
+ q[0].re = in[ 3].im - in[ 7].im;
+ q[1].im = in[ 4].re - in[ 8].re;
+ q[1].re = in[ 4].im - in[ 8].im;
+ q[2].im = in[ 5].re - in[ 9].re;
+ q[2].re = in[ 5].im - in[ 9].im;
+ q[3].re = in[ 6].im - in[10].im;
+ q[3].im = in[ 6].re - in[10].re;
+
+ q[4].re = in[ 3].re + in[ 7].re;
+ q[4].im = in[ 3].im + in[ 7].im;
+ q[5].re = in[ 4].re + in[ 8].re;
+ q[5].im = in[ 4].im + in[ 8].im;
+ q[6].re = in[ 5].re + in[ 9].re;
+ q[6].im = in[ 5].im + in[ 9].im;
+ q[7].re = in[ 6].re + in[10].re;
+ q[7].im = in[ 6].im + in[10].im;
+
+ y[0].re = in[11].re + q[4].re;
+ y[0].im = in[11].im + q[4].im;
+ y[1].re = in[12].re + q[5].re;
+ y[1].im = in[12].im + q[5].im;
+ y[2].re = in[13].re + q[6].re;
+ y[2].im = in[13].im + q[6].im;
+ y[3].re = in[14].re + q[7].re;
+ y[3].im = in[14].im + q[7].im;
+
+ q[0].re = tab[ 8] * q[0].re;
+ q[0].im = tab[ 9] * q[0].im;
+ q[1].re = tab[ 8] * q[1].re;
+ q[1].im = tab[ 9] * q[1].im;
+ q[2].re = tab[ 8] * q[2].re;
+ q[2].im = tab[ 9] * q[2].im;
+ q[3].re = tab[ 8] * q[3].re;
+ q[3].im = tab[ 9] * q[3].im;
+
+ q[4].re = tab[10] * q[4].re;
+ q[4].im = tab[11] * q[4].im;
+ q[5].re = tab[10] * q[5].re;
+ q[5].im = tab[11] * q[5].im;
+ q[6].re = tab[10] * q[6].re;
+ q[6].im = tab[11] * q[6].im;
+ q[7].re = tab[10] * q[7].re;
+ q[7].im = tab[11] * q[7].im;
+
+ k[0].re = q[4].re - q[0].re;
+ k[0].im = q[4].im - q[0].im;
+ k[1].re = q[5].re - q[1].re;
+ k[1].im = q[5].im - q[1].im;
+ k[2].re = q[6].re - q[2].re;
+ k[2].im = q[6].im - q[2].im;
+ k[3].re = q[7].re - q[3].re;
+ k[3].im = q[7].im - q[3].im;
+
+ k[4].re = q[4].re + q[0].re;
+ k[4].im = q[4].im + q[0].im;
+ k[5].re = q[5].re + q[1].re;
+ k[5].im = q[5].im + q[1].im;
+ k[6].re = q[6].re + q[2].re;
+ k[6].im = q[6].im + q[2].im;
+ k[7].re = q[7].re + q[3].re;
+ k[7].im = q[7].im + q[3].im;
+
+ k[0].re = in[11].re - k[0].re;
+ k[0].im = in[11].im + k[0].im;
+ k[1].re = in[12].re - k[1].re;
+ k[1].im = in[12].im + k[1].im;
+ k[2].re = in[13].re - k[2].re;
+ k[2].im = in[13].im + k[2].im;
+ k[3].re = in[14].re - k[3].re;
+ k[3].im = in[14].im + k[3].im;
+
+ k[4].re = in[11].re - k[4].re;
+ k[4].im = in[11].im + k[4].im;
+ k[5].re = in[12].re - k[5].re;
+ k[5].im = in[12].im + k[5].im;
+ k[6].re = in[13].re - k[6].re;
+ k[6].im = in[13].im + k[6].im;
+ k[7].re = in[14].re - k[7].re;
+ k[7].im = in[14].im + k[7].im;
+
+ /* 15pt start here */
+ t[0].re = y[3].re + y[0].re;
+ t[0].im = y[3].im + y[0].im;
+ t[1].re = y[2].re + y[1].re;
+ t[1].im = y[2].im + y[1].im;
+ t[2].re = y[1].re - y[2].re;
+ t[2].im = y[1].im - y[2].im;
+ t[3].re = y[0].re - y[3].re;
+ t[3].im = y[0].im - y[3].im;
+
+ t[4].re = k[3].re + k[0].re;
+ t[4].im = k[3].im + k[0].im;
+ t[5].re = k[2].re + k[1].re;
+ t[5].im = k[2].im + k[1].im;
+ t[6].re = k[1].re - k[2].re;
+ t[6].im = k[1].im - k[2].im;
+ t[7].re = k[0].re - k[3].re;
+ t[7].im = k[0].im - k[3].im;
+
+ t[ 8].re = k[7].re + k[4].re;
+ t[ 8].im = k[7].im + k[4].im;
+ t[ 9].re = k[6].re + k[5].re;
+ t[ 9].im = k[6].im + k[5].im;
+ t[10].re = k[5].re - k[6].re;
+ t[10].im = k[5].im - k[6].im;
+ t[11].re = k[4].re - k[7].re;
+ t[11].im = k[4].im - k[7].im;
+
+ out[ 0*stride].re = dc[0].re + t[0].re + t[ 1].re;
+ out[ 0*stride].im = dc[0].im + t[0].im + t[ 1].im;
+ out[10*stride].re = dc[1].re + t[4].re + t[ 5].re;
+ out[10*stride].im = dc[1].im + t[4].im + t[ 5].im;
+ out[ 5*stride].re = dc[2].re + t[8].re + t[ 9].re;
+ out[ 5*stride].im = dc[2].im + t[8].im + t[ 9].im;
+
+ r[0].re = t[0].re * tab[0];
+ r[0].im = t[0].im * tab[1];
+ r[1].re = t[1].re * tab[0];
+ r[1].im = t[1].im * tab[1];
+ r[2].re = t[2].re * tab[4];
+ r[2].im = t[2].im * tab[5];
+ r[3].re = t[3].re * tab[4];
+ r[3].im = t[3].im * tab[5];
+
+ r[4].re = t[4].re * tab[0];
+ r[4].im = t[4].im * tab[1];
+ r[5].re = t[5].re * tab[0];
+ r[5].im = t[5].im * tab[1];
+ r[6].re = t[6].re * tab[4];
+ r[6].im = t[6].im * tab[5];
+ r[7].re = t[7].re * tab[4];
+ r[7].im = t[7].im * tab[5];
+
+ r[ 8].re = t[ 8].re * tab[0];
+ r[ 8].im = t[ 8].im * tab[1];
+ r[ 9].re = t[ 9].re * tab[0];
+ r[ 9].im = t[ 9].im * tab[1];
+ r[10].re = t[10].re * tab[4];
+ r[10].im = t[10].im * tab[5];
+ r[11].re = t[11].re * tab[4];
+ r[11].im = t[11].im * tab[5];
+
+ t[0].re = t[0].re * tab[2];
+ t[0].im = t[0].im * tab[3];
+ t[1].re = t[1].re * tab[2];
+ t[1].im = t[1].im * tab[3];
+ t[2].re = t[2].re * tab[6];
+ t[2].im = t[2].im * tab[7];
+ t[3].re = t[3].re * tab[6];
+ t[3].im = t[3].im * tab[7];
+
+ t[4].re = t[4].re * tab[2];
+ t[4].im = t[4].im * tab[3];
+ t[5].re = t[5].re * tab[2];
+ t[5].im = t[5].im * tab[3];
+ t[6].re = t[6].re * tab[6];
+ t[6].im = t[6].im * tab[7];
+ t[7].re = t[7].re * tab[6];
+ t[7].im = t[7].im * tab[7];
+
+ t[ 8].re = t[ 8].re * tab[2];
+ t[ 8].im = t[ 8].im * tab[3];
+ t[ 9].re = t[ 9].re * tab[2];
+ t[ 9].im = t[ 9].im * tab[3];
+ t[10].re = t[10].re * tab[6];
+ t[10].im = t[10].im * tab[7];
+ t[11].re = t[11].re * tab[6];
+ t[11].im = t[11].im * tab[7];
+
+ r[0].re = r[0].re - t[1].re;
+ r[0].im = r[0].im - t[1].im;
+ r[1].re = r[1].re - t[0].re;
+ r[1].im = r[1].im - t[0].im;
+ r[2].re = r[2].re - t[3].re;
+ r[2].im = r[2].im - t[3].im;
+ r[3].re = r[3].re + t[2].re;
+ r[3].im = r[3].im + t[2].im;
+
+ r[4].re = r[4].re - t[5].re;
+ r[4].im = r[4].im - t[5].im;
+ r[5].re = r[5].re - t[4].re;
+ r[5].im = r[5].im - t[4].im;
+ r[6].re = r[6].re - t[7].re;
+ r[6].im = r[6].im - t[7].im;
+ r[7].re = r[7].re + t[6].re;
+ r[7].im = r[7].im + t[6].im;
+
+ r[ 8].re = r[ 8].re - t[ 9].re;
+ r[ 8].im = r[ 8].im - t[ 9].im;
+ r[ 9].re = r[ 9].re - t[ 8].re;
+ r[ 9].im = r[ 9].im - t[ 8].im;
+ r[10].re = r[10].re - t[11].re;
+ r[10].im = r[10].im - t[11].im;
+ r[11].re = r[11].re + t[10].re;
+ r[11].im = r[11].im + t[10].im;
+
+ z0[ 0].re = r[ 3].im + r[ 0].re;
+ z0[ 0].im = r[ 3].re + r[ 0].im;
+ z0[ 1].re = r[ 2].im + r[ 1].re;
+ z0[ 1].im = r[ 2].re + r[ 1].im;
+ z0[ 2].re = r[ 1].im - r[ 2].re;
+ z0[ 2].im = r[ 1].re - r[ 2].im;
+ z0[ 3].re = r[ 0].im - r[ 3].re;
+ z0[ 3].im = r[ 0].re - r[ 3].im;
+
+ z0[ 4].re = r[ 7].im + r[ 4].re;
+ z0[ 4].im = r[ 7].re + r[ 4].im;
+ z0[ 5].re = r[ 6].im + r[ 5].re;
+ z0[ 5].im = r[ 6].re + r[ 5].im;
+ z0[ 6].re = r[ 5].im - r[ 6].re;
+ z0[ 6].im = r[ 5].re - r[ 6].im;
+ z0[ 7].re = r[ 4].im - r[ 7].re;
+ z0[ 7].im = r[ 4].re - r[ 7].im;
+
+ z0[ 8].re = r[11].im + r[ 8].re;
+ z0[ 8].im = r[11].re + r[ 8].im;
+ z0[ 9].re = r[10].im + r[ 9].re;
+ z0[ 9].im = r[10].re + r[ 9].im;
+ z0[10].re = r[ 9].im - r[10].re;
+ z0[10].im = r[ 9].re - r[10].im;
+ z0[11].re = r[ 8].im - r[11].re;
+ z0[11].im = r[ 8].re - r[11].im;
+
+ out[ 6*stride].re = dc[0].re + z0[0].re;
+ out[ 6*stride].im = dc[0].im + z0[3].re;
+ out[12*stride].re = dc[0].re + z0[2].im;
+ out[12*stride].im = dc[0].im + z0[1].im;
+ out[ 3*stride].re = dc[0].re + z0[1].re;
+ out[ 3*stride].im = dc[0].im + z0[2].re;
+ out[ 9*stride].re = dc[0].re + z0[3].im;
+ out[ 9*stride].im = dc[0].im + z0[0].im;
+
+ out[ 1*stride].re = dc[1].re + z0[4].re;
+ out[ 1*stride].im = dc[1].im + z0[7].re;
+ out[ 7*stride].re = dc[1].re + z0[6].im;
+ out[ 7*stride].im = dc[1].im + z0[5].im;
+ out[13*stride].re = dc[1].re + z0[5].re;
+ out[13*stride].im = dc[1].im + z0[6].re;
+ out[ 4*stride].re = dc[1].re + z0[7].im;
+ out[ 4*stride].im = dc[1].im + z0[4].im;
+
+ out[11*stride].re = dc[2].re + z0[8].re;
+ out[11*stride].im = dc[2].im + z0[11].re;
+ out[ 2*stride].re = dc[2].re + z0[10].im;
+ out[ 2*stride].im = dc[2].im + z0[9].im;
+ out[ 8*stride].re = dc[2].re + z0[9].re;
+ out[ 8*stride].im = dc[2].im + z0[10].re;
+ out[14*stride].re = dc[2].re + z0[11].im;
+ out[14*stride].im = dc[2].im + z0[8].im;
+}
+```
diff --git a/doc/utils.texi b/doc/utils.texi
index 232a0608b..8e8bfa76d 100644
--- a/doc/utils.texi
+++ b/doc/utils.texi
@@ -713,8 +713,12 @@ FL+FR+FC+LFE+BL+BR+SL+SR
FL+FR+FC+LFE+BL+BR+FLC+FRC
@item 7.1(wide-side)
FL+FR+FC+LFE+FLC+FRC+SL+SR
+@item 7.1(top)
+FL+FR+FC+LFE+BL+BR+TFL+TFR
@item octagonal
FL+FR+FC+BL+BR+BC+SL+SR
+@item cube
+FL+FR+BL+BR+TFL+TFR+TBL+TBR
@item hexadecagonal
FL+FR+FC+BL+BR+BC+SL+SR+WL+WR+TBL+TBR+TBC+TFC+TFL+TFR
@item downmix
@@ -1073,13 +1077,13 @@ indication of the corresponding powers of 10 and of 2.
@item T
10^12 / 2^40
@item P
-10^15 / 2^40
+10^15 / 2^50
@item E
-10^18 / 2^50
+10^18 / 2^60
@item Z
-10^21 / 2^60
+10^21 / 2^70
@item Y
-10^24 / 2^70
+10^24 / 2^80
@end table
@c man end EXPRESSION EVALUATION
diff --git a/ffbuild/.gitignore b/ffbuild/.gitignore
deleted file mode 100644
index 38ed17075..000000000
--- a/ffbuild/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-/.config
-/config.fate
-/config.log
-/config.mak
-/config.sh
diff --git a/ffbuild/arch.mak b/ffbuild/arch.mak
index 997e31e85..39d76ee15 100644
--- a/ffbuild/arch.mak
+++ b/ffbuild/arch.mak
@@ -15,5 +15,7 @@ OBJS-$(HAVE_LASX) += $(LASX-OBJS) $(LASX-OBJS-yes)
OBJS-$(HAVE_ALTIVEC) += $(ALTIVEC-OBJS) $(ALTIVEC-OBJS-yes)
OBJS-$(HAVE_VSX) += $(VSX-OBJS) $(VSX-OBJS-yes)
+OBJS-$(HAVE_RVV) += $(RVV-OBJS) $(RVV-OBJS-yes)
+
OBJS-$(HAVE_MMX) += $(MMX-OBJS) $(MMX-OBJS-yes)
OBJS-$(HAVE_X86ASM) += $(X86ASM-OBJS) $(X86ASM-OBJS-yes)
diff --git a/fftools/Makefile b/fftools/Makefile
index 81ad6c4f4..8ac38e75d 100644
--- a/fftools/Makefile
+++ b/fftools/Makefile
@@ -10,13 +10,21 @@ ALLAVPROGS = $(AVBASENAMES:%=%$(PROGSSUF)$(EXESUF))
ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
OBJS-ffmpeg += \
+ fftools/ffmpeg_demux.o \
fftools/ffmpeg_filter.o \
fftools/ffmpeg_hw.o \
fftools/ffmpeg_mux.o \
+ fftools/ffmpeg_mux_init.o \
fftools/ffmpeg_opt.o \
+ fftools/objpool.o \
+ fftools/sync_queue.o \
+ fftools/thread_queue.o \
define DOFFTOOL
OBJS-$(1) += fftools/cmdutils.o fftools/opt_common.o fftools/$(1).o $(OBJS-$(1)-yes)
+ifdef HAVE_GNU_WINDRES
+OBJS-$(1) += fftools/fftoolsres.o
+endif
$(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1))
$$(OBJS-$(1)): | fftools
$$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1))
diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index 18e768b38..a1de621d1 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -90,6 +90,12 @@ void register_exit(void (*cb)(int ret))
program_exit = cb;
}
+void report_and_exit(int ret)
+{
+ av_log(NULL, AV_LOG_FATAL, "%s\n", av_err2str(ret));
+ exit_program(AVUNERROR(ret));
+}
+
void exit_program(int ret)
{
if (program_exit)
@@ -650,7 +656,7 @@ static void init_parse_context(OptionParseContext *octx,
octx->nb_groups = nb_groups;
octx->groups = av_calloc(octx->nb_groups, sizeof(*octx->groups));
if (!octx->groups)
- exit_program(1);
+ report_and_exit(AVERROR(ENOMEM));
for (i = 0; i < octx->nb_groups; i++)
octx->groups[i].group_def = &groups[i];
@@ -792,12 +798,7 @@ do { \
void print_error(const char *filename, int err)
{
- char errbuf[128];
- const char *errbuf_ptr = errbuf;
-
- if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
- errbuf_ptr = strerror(AVUNERROR(err));
- av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
+ av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, av_err2str(err));
}
int read_yesno(void)
@@ -920,7 +921,7 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
break;
}
- while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
+ while (t = av_dict_iterate(opts, t)) {
const AVClass *priv_class;
char *p = strchr(t->key, ':');
@@ -958,11 +959,8 @@ AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
if (!s->nb_streams)
return NULL;
opts = av_calloc(s->nb_streams, sizeof(*opts));
- if (!opts) {
- av_log(NULL, AV_LOG_ERROR,
- "Could not alloc memory for stream options.\n");
- exit_program(1);
- }
+ if (!opts)
+ report_and_exit(AVERROR(ENOMEM));
for (i = 0; i < s->nb_streams; i++)
opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codecpar->codec_id,
s, s->streams[i], NULL);
@@ -977,10 +975,8 @@ void *grow_array(void *array, int elem_size, int *size, int new_size)
}
if (*size < new_size) {
uint8_t *tmp = av_realloc_array(array, new_size, elem_size);
- if (!tmp) {
- av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
- exit_program(1);
- }
+ if (!tmp)
+ report_and_exit(AVERROR(ENOMEM));
memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
*size = new_size;
return tmp;
@@ -993,10 +989,8 @@ void *allocate_array_elem(void *ptr, size_t elem_size, int *nb_elems)
void *new_elem;
if (!(new_elem = av_mallocz(elem_size)) ||
- av_dynarray_add_nofree(ptr, nb_elems, new_elem) < 0) {
- av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
- exit_program(1);
- }
+ av_dynarray_add_nofree(ptr, nb_elems, new_elem) < 0)
+ report_and_exit(AVERROR(ENOMEM));
return new_elem;
}
diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h
index d87e162cc..449622198 100644
--- a/fftools/cmdutils.h
+++ b/fftools/cmdutils.h
@@ -54,6 +54,17 @@ extern int hide_banner;
*/
void register_exit(void (*cb)(int ret));
+/**
+ * Reports an error corresponding to the provided
+ * AVERROR code and calls exit_program() with the
+ * corresponding POSIX error code.
+ * @note ret must be an AVERROR-value of a POSIX error code
+ * (i.e. AVERROR(EFOO) and not AVERROR_FOO).
+ * library functions can return both, so call this only
+ * with AVERROR(EFOO) of your own.
+ */
+void report_and_exit(int ret) av_noreturn;
+
/**
* Wraps exit with a program-specific cleanup routine.
*/
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index e7384f052..d721a5e72 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -104,6 +104,7 @@
#include "ffmpeg.h"
#include "cmdutils.h"
+#include "sync_queue.h"
#include "libavutil/avassert.h"
@@ -112,14 +113,12 @@ const int program_birth_year = 2000;
static FILE *vstats_file;
-const char *const forced_keyframes_const_names[] = {
- "n",
- "n_forced",
- "prev_forced_n",
- "prev_forced_t",
- "t",
- NULL
-};
+// optionally attached as opaque_ref to decoded AVFrames
+typedef struct FrameData {
+ uint64_t idx;
+ int64_t pts;
+ AVRational tb;
+} FrameData;
typedef struct BenchmarkTimeStamps {
int64_t real_usec;
@@ -127,6 +126,7 @@ typedef struct BenchmarkTimeStamps {
int64_t sys_usec;
} BenchmarkTimeStamps;
+static int trigger_fix_sub_duration_heartbeat(OutputStream *ost, const AVPacket *pkt);
static BenchmarkTimeStamps get_benchmark_time_stamps(void);
static int64_t getmaxrss(void);
static int ifilter_has_all_input_formats(FilterGraph *fg);
@@ -137,20 +137,12 @@ static int64_t nb_frames_drop = 0;
static int64_t decode_error_stat[2];
unsigned nb_output_dumped = 0;
-int want_sdp = 1;
-
static BenchmarkTimeStamps current_time;
AVIOContext *progress_avio = NULL;
-static uint8_t *subtitle_out;
-
-InputStream **input_streams = NULL;
-int nb_input_streams = 0;
InputFile **input_files = NULL;
int nb_input_files = 0;
-OutputStream **output_streams = NULL;
-int nb_output_streams = 0;
OutputFile **output_files = NULL;
int nb_output_files = 0;
@@ -164,10 +156,6 @@ static struct termios oldtty;
static int restore_tty;
#endif
-#if HAVE_THREADS
-static void free_input_threads(void);
-#endif
-
/* sub2video hack:
Convert subtitles to video with alpha to insert them in filter graphs.
This is a temporary solution until libavfilter gets real subtitles support.
@@ -264,7 +252,7 @@ void sub2video_update(InputStream *ist, int64_t heartbeat_pts, AVSubtitle *sub)
num_rects = 0;
}
if (sub2video_get_blank_frame(ist) < 0) {
- av_log(ist->dec_ctx, AV_LOG_ERROR,
+ av_log(NULL, AV_LOG_ERROR,
"Impossible to get a blank canvas.\n");
return;
}
@@ -288,7 +276,7 @@ static void sub2video_heartbeat(InputStream *ist, int64_t pts)
video frames could be accumulating in the filter graph while a filter
(possibly overlay) is desperately waiting for a subtitle frame. */
for (i = 0; i < infile->nb_streams; i++) {
- InputStream *ist2 = input_streams[infile->ist_index + i];
+ InputStream *ist2 = infile->streams[i];
if (!ist2->sub2video.frame)
continue;
/* subtitles seem to be usually muxed ahead of other streams;
@@ -560,72 +548,12 @@ static void ffmpeg_cleanup(int ret)
}
av_freep(&filtergraphs);
- av_freep(&subtitle_out);
-
/* close files */
for (i = 0; i < nb_output_files; i++)
of_close(&output_files[i]);
- for (i = 0; i < nb_output_streams; i++) {
- OutputStream *ost = output_streams[i];
-
- if (!ost)
- continue;
-
- av_bsf_free(&ost->bsf_ctx);
-
- av_frame_free(&ost->filtered_frame);
- av_frame_free(&ost->last_frame);
- av_packet_free(&ost->pkt);
- av_dict_free(&ost->encoder_opts);
-
- av_freep(&ost->forced_keyframes);
- av_expr_free(ost->forced_keyframes_pexpr);
- av_freep(&ost->avfilter);
- av_freep(&ost->logfile_prefix);
-
- av_freep(&ost->audio_channels_map);
- ost->audio_channels_mapped = 0;
-
- av_dict_free(&ost->sws_dict);
- av_dict_free(&ost->swr_opts);
-
- avcodec_free_context(&ost->enc_ctx);
- avcodec_parameters_free(&ost->ref_par);
-
- if (ost->muxing_queue) {
- AVPacket *pkt;
- while (av_fifo_read(ost->muxing_queue, &pkt, 1) >= 0)
- av_packet_free(&pkt);
- av_fifo_freep2(&ost->muxing_queue);
- }
-
- av_freep(&output_streams[i]);
- }
-#if HAVE_THREADS
- free_input_threads();
-#endif
- for (i = 0; i < nb_input_files; i++) {
- avformat_close_input(&input_files[i]->ctx);
- av_packet_free(&input_files[i]->pkt);
- av_freep(&input_files[i]);
- }
- for (i = 0; i < nb_input_streams; i++) {
- InputStream *ist = input_streams[i];
-
- av_frame_free(&ist->decoded_frame);
- av_packet_free(&ist->pkt);
- av_dict_free(&ist->decoder_opts);
- avsubtitle_free(&ist->prev_sub.subtitle);
- av_frame_free(&ist->sub2video.frame);
- av_freep(&ist->filters);
- av_freep(&ist->hwaccel_device);
- av_freep(&ist->dts_buffer);
-
- avcodec_free_context(&ist->dec_ctx);
-
- av_freep(&input_streams[i]);
- }
+ for (i = 0; i < nb_input_files; i++)
+ ifile_close(&input_files[i]);
if (vstats_file) {
if (fclose(vstats_file))
@@ -634,11 +562,11 @@ static void ffmpeg_cleanup(int ret)
av_err2str(AVERROR(errno)));
}
av_freep(&vstats_filename);
+ of_enc_stats_close();
+
av_freep(&filter_nbthreads);
- av_freep(&input_streams);
av_freep(&input_files);
- av_freep(&output_streams);
av_freep(&output_files);
uninit_opts();
@@ -655,11 +583,45 @@ static void ffmpeg_cleanup(int ret)
ffmpeg_exited = 1;
}
+/* iterate over all output streams in all output files;
+ * pass NULL to start iteration */
+static OutputStream *ost_iter(OutputStream *prev)
+{
+ int of_idx = prev ? prev->file_index : 0;
+ int ost_idx = prev ? prev->index + 1 : 0;
+
+ for (; of_idx < nb_output_files; of_idx++) {
+ OutputFile *of = output_files[of_idx];
+ if (ost_idx < of->nb_streams)
+ return of->streams[ost_idx];
+
+ ost_idx = 0;
+ }
+
+ return NULL;
+}
+
+InputStream *ist_iter(InputStream *prev)
+{
+ int if_idx = prev ? prev->file_index : 0;
+ int ist_idx = prev ? prev->st->index + 1 : 0;
+
+ for (; if_idx < nb_input_files; if_idx++) {
+ InputFile *f = input_files[if_idx];
+ if (ist_idx < f->nb_streams)
+ return f->streams[ist_idx];
+
+ ist_idx = 0;
+ }
+
+ return NULL;
+}
+
void remove_avoptions(AVDictionary **a, AVDictionary *b)
{
const AVDictionaryEntry *t = NULL;
- while ((t = av_dict_get(b, "", t, AV_DICT_IGNORE_SUFFIX))) {
+ while ((t = av_dict_iterate(b, t))) {
av_dict_set(a, t->key, NULL, AV_DICT_MATCH_CASE);
}
}
@@ -702,59 +664,18 @@ static void update_benchmark(const char *fmt, ...)
static void close_output_stream(OutputStream *ost)
{
OutputFile *of = output_files[ost->file_index];
- AVRational time_base = ost->stream_copy ? ost->mux_timebase : ost->enc_ctx->time_base;
-
ost->finished |= ENCODER_FINISHED;
- if (of->shortest) {
- int64_t end = av_rescale_q(ost->sync_opts - ost->first_pts, time_base, AV_TIME_BASE_Q);
- of->recording_time = FFMIN(of->recording_time, end);
- }
+
+ if (ost->sq_idx_encode >= 0)
+ sq_send(of->sq_encode, ost->sq_idx_encode, SQFRAME(NULL));
}
-/*
- * Send a single packet to the output, applying any bitstream filters
- * associated with the output stream. This may result in any number
- * of packets actually being written, depending on what bitstream
- * filters are applied. The supplied packet is consumed and will be
- * blank (as if newly-allocated) when this function returns.
- *
- * If eof is set, instead indicate EOF to all bitstream filters and
- * therefore flush any delayed packets to the output. A blank packet
- * must be supplied in this case.
- */
-static void output_packet(OutputFile *of, AVPacket *pkt,
- OutputStream *ost, int eof)
-{
- int ret = 0;
-
- /* apply the output bitstream filters */
- if (ost->bsf_ctx) {
- ret = av_bsf_send_packet(ost->bsf_ctx, eof ? NULL : pkt);
- if (ret < 0)
- goto finish;
- while ((ret = av_bsf_receive_packet(ost->bsf_ctx, pkt)) >= 0)
- of_write_packet(of, pkt, ost, 0);
- if (ret == AVERROR(EAGAIN))
- ret = 0;
- } else if (!eof)
- of_write_packet(of, pkt, ost, 0);
-
-finish:
- if (ret < 0 && ret != AVERROR_EOF) {
- av_log(NULL, AV_LOG_ERROR, "Error applying bitstream filters to an output "
- "packet for stream #%d:%d.\n", ost->file_index, ost->index);
- if(exit_on_error)
- exit_program(1);
- }
-}
-
-static int check_recording_time(OutputStream *ost)
+static int check_recording_time(OutputStream *ost, int64_t ts, AVRational tb)
{
OutputFile *of = output_files[ost->file_index];
if (of->recording_time != INT64_MAX &&
- av_compare_ts(ost->sync_opts - ost->first_pts, ost->enc_ctx->time_base, of->recording_time,
- AV_TIME_BASE_Q) >= 0) {
+ av_compare_ts(ts, tb, of->recording_time, AV_TIME_BASE_Q) >= 0) {
close_output_stream(ost);
return 0;
}
@@ -765,38 +686,36 @@ static double adjust_frame_pts_to_encoder_tb(OutputFile *of, OutputStream *ost,
AVFrame *frame)
{
double float_pts = AV_NOPTS_VALUE; // this is identical to frame.pts but with higher precision
- AVCodecContext *enc = ost->enc_ctx;
- if (!frame || frame->pts == AV_NOPTS_VALUE ||
- !enc || !ost->filter || !ost->filter->graph->graph)
+ const int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ?
+ 0 : of->start_time;
+
+ AVCodecContext *const enc = ost->enc_ctx;
+
+ AVRational tb = enc->time_base;
+ AVRational filter_tb = frame->time_base;
+ const int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16);
+
+ if (frame->pts == AV_NOPTS_VALUE)
goto early_exit;
- {
- AVFilterContext *filter = ost->filter->filter;
+ tb.den <<= extra_bits;
+ float_pts = av_rescale_q(frame->pts, filter_tb, tb) -
+ av_rescale_q(start_time, AV_TIME_BASE_Q, tb);
+ float_pts /= 1 << extra_bits;
+ // avoid exact midoints to reduce the chance of rounding differences, this
+ // can be removed in case the fps code is changed to work with integers
+ float_pts += FFSIGN(float_pts) * 1.0 / (1<<17);
- int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
- AVRational filter_tb = av_buffersink_get_time_base(filter);
- AVRational tb = enc->time_base;
- int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16);
-
- tb.den <<= extra_bits;
- float_pts =
- av_rescale_q(frame->pts, filter_tb, tb) -
- av_rescale_q(start_time, AV_TIME_BASE_Q, tb);
- float_pts /= 1 << extra_bits;
- // avoid exact midoints to reduce the chance of rounding differences, this can be removed in case the fps code is changed to work with integers
- float_pts += FFSIGN(float_pts) * 1.0 / (1<<17);
-
- frame->pts =
- av_rescale_q(frame->pts, filter_tb, enc->time_base) -
- av_rescale_q(start_time, AV_TIME_BASE_Q, enc->time_base);
- }
+ frame->pts = av_rescale_q(frame->pts, filter_tb, enc->time_base) -
+ av_rescale_q(start_time, AV_TIME_BASE_Q, enc->time_base);
+ frame->time_base = enc->time_base;
early_exit:
if (debug_ts) {
av_log(NULL, AV_LOG_INFO, "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n",
frame ? av_ts2str(frame->pts) : "NULL",
- frame ? av_ts2timestr(frame->pts, &enc->time_base) : "NULL",
+ (enc && frame) ? av_ts2timestr(frame->pts, &enc->time_base) : "NULL",
float_pts,
enc ? enc->time_base.num : -1,
enc ? enc->time_base.den : -1);
@@ -819,8 +738,8 @@ static int init_output_stream_wrapper(OutputStream *ost, AVFrame *frame,
ret = init_output_stream(ost, frame, error, sizeof(error));
if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error initializing output stream %d:%d -- %s\n",
- ost->file_index, ost->index, error);
+ av_log(ost, AV_LOG_ERROR, "Error initializing output stream: %s\n",
+ error);
if (fatal)
exit_program(1);
@@ -878,17 +797,83 @@ static void update_video_stats(OutputStream *ost, const AVPacket *pkt, int write
fprintf(vstats_file,"f_size= %6d ", pkt->size);
/* compute pts value */
- ti1 = pkt->dts * av_q2d(ost->mux_timebase);
+ ti1 = pkt->dts * av_q2d(pkt->time_base);
if (ti1 < 0.01)
ti1 = 0.01;
bitrate = (pkt->size * 8) / av_q2d(enc->time_base) / 1000.0;
- avg_bitrate = (double)(ost->data_size * 8) / ti1 / 1000.0;
+ avg_bitrate = (double)(ost->data_size_enc * 8) / ti1 / 1000.0;
fprintf(vstats_file, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ",
- (double)ost->data_size / 1024, ti1, bitrate, avg_bitrate);
+ (double)ost->data_size_enc / 1024, ti1, bitrate, avg_bitrate);
fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(ost->pict_type));
}
+void enc_stats_write(OutputStream *ost, EncStats *es,
+ const AVFrame *frame, const AVPacket *pkt,
+ uint64_t frame_num)
+{
+ AVIOContext *io = es->io;
+ AVRational tb = frame ? frame->time_base : pkt->time_base;
+ int64_t pts = frame ? frame->pts : pkt->pts;
+
+ AVRational tbi = (AVRational){ 0, 1};
+ int64_t ptsi = INT64_MAX;
+
+ const FrameData *fd;
+
+ if ((frame && frame->opaque_ref) || (pkt && pkt->opaque_ref)) {
+ fd = (const FrameData*)(frame ? frame->opaque_ref->data : pkt->opaque_ref->data);
+ tbi = fd->tb;
+ ptsi = fd->pts;
+ }
+
+ for (size_t i = 0; i < es->nb_components; i++) {
+ const EncStatsComponent *c = &es->components[i];
+
+ switch (c->type) {
+ case ENC_STATS_LITERAL: avio_write (io, c->str, c->str_len); continue;
+ case ENC_STATS_FILE_IDX: avio_printf(io, "%d", ost->file_index); continue;
+ case ENC_STATS_STREAM_IDX: avio_printf(io, "%d", ost->index); continue;
+ case ENC_STATS_TIMEBASE: avio_printf(io, "%d/%d", tb.num, tb.den); continue;
+ case ENC_STATS_TIMEBASE_IN: avio_printf(io, "%d/%d", tbi.num, tbi.den); continue;
+ case ENC_STATS_PTS: avio_printf(io, "%"PRId64, pts); continue;
+ case ENC_STATS_PTS_IN: avio_printf(io, "%"PRId64, ptsi); continue;
+ case ENC_STATS_PTS_TIME: avio_printf(io, "%g", pts * av_q2d(tb)); continue;
+ case ENC_STATS_PTS_TIME_IN: avio_printf(io, "%g", ptsi == INT64_MAX ?
+ INFINITY : ptsi * av_q2d(tbi)); continue;
+ case ENC_STATS_FRAME_NUM: avio_printf(io, "%"PRIu64, frame_num); continue;
+ case ENC_STATS_FRAME_NUM_IN: avio_printf(io, "%"PRIu64, fd ? fd->idx : -1); continue;
+ }
+
+ if (frame) {
+ switch (c->type) {
+ case ENC_STATS_SAMPLE_NUM: avio_printf(io, "%"PRIu64, ost->samples_encoded); continue;
+ case ENC_STATS_NB_SAMPLES: avio_printf(io, "%d", frame->nb_samples); continue;
+ default: av_assert0(0);
+ }
+ } else {
+ switch (c->type) {
+ case ENC_STATS_DTS: avio_printf(io, "%"PRId64, pkt->dts); continue;
+ case ENC_STATS_DTS_TIME: avio_printf(io, "%g", pkt->dts * av_q2d(tb)); continue;
+ case ENC_STATS_PKT_SIZE: avio_printf(io, "%d", pkt->size); continue;
+ case ENC_STATS_BITRATE: {
+ double duration = FFMAX(pkt->duration, 1) * av_q2d(tb);
+ avio_printf(io, "%g", 8.0 * pkt->size / duration);
+ continue;
+ }
+ case ENC_STATS_AVG_BITRATE: {
+ double duration = pkt->dts * av_q2d(tb);
+ avio_printf(io, "%g", duration > 0 ? 8.0 * ost->data_size_enc / duration : -1.);
+ continue;
+ }
+ default: av_assert0(0);
+ }
+ }
+ }
+ avio_w8(io, '\n');
+ avio_flush(io);
+}
+
static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame)
{
AVCodecContext *enc = ost->enc_ctx;
@@ -898,10 +883,15 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame)
int ret;
if (frame) {
+ if (ost->enc_stats_pre.io)
+ enc_stats_write(ost, &ost->enc_stats_pre, frame, NULL,
+ ost->frames_encoded);
+
ost->frames_encoded++;
+ ost->samples_encoded += frame->nb_samples;
if (debug_ts) {
- av_log(NULL, AV_LOG_INFO, "encoder <- type:%s "
+ av_log(ost, AV_LOG_INFO, "encoder <- type:%s "
"frame_pts:%s frame_pts_time:%s time_base:%d/%d\n",
type_desc,
av_ts2str(frame->pts), av_ts2timestr(frame->pts, &enc->time_base),
@@ -913,7 +903,7 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame)
ret = avcodec_send_frame(enc, frame);
if (ret < 0 && !(ret == AVERROR_EOF && !frame)) {
- av_log(NULL, AV_LOG_ERROR, "Error submitting %s frame to the encoder\n",
+ av_log(ost, AV_LOG_ERROR, "Error submitting %s frame to the encoder\n",
type_desc);
return ret;
}
@@ -923,6 +913,8 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame)
update_benchmark("%s_%s %d.%d", action, type_desc,
ost->file_index, ost->index);
+ pkt->time_base = enc->time_base;
+
/* if two pass, output log on success and EOF */
if ((ret >= 0 || ret == AVERROR_EOF) && ost->logfile && enc->stats_out)
fprintf(ost->logfile, "%s", enc->stats_out);
@@ -931,63 +923,128 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame)
av_assert0(frame); // should never happen during flushing
return 0;
} else if (ret == AVERROR_EOF) {
- output_packet(of, pkt, ost, 1);
+ of_output_packet(of, pkt, ost, 1);
return ret;
} else if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "%s encoding failed\n", type_desc);
+ av_log(ost, AV_LOG_ERROR, "%s encoding failed\n", type_desc);
return ret;
}
- if (debug_ts) {
- av_log(NULL, AV_LOG_INFO, "encoder -> type:%s "
- "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s "
- "duration:%s duration_time:%s\n",
- type_desc,
- av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base),
- av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base),
- av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &enc->time_base));
- }
-
- av_packet_rescale_ts(pkt, enc->time_base, ost->mux_timebase);
-
- if (debug_ts) {
- av_log(NULL, AV_LOG_INFO, "encoder -> type:%s "
- "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s "
- "duration:%s duration_time:%s\n",
- type_desc,
- av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base),
- av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base),
- av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &enc->time_base));
- }
-
if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
update_video_stats(ost, pkt, !!vstats_filename);
+ if (ost->enc_stats_post.io)
+ enc_stats_write(ost, &ost->enc_stats_post, NULL, pkt,
+ ost->packets_encoded);
+
+ if (debug_ts) {
+ av_log(ost, AV_LOG_INFO, "encoder -> type:%s "
+ "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s "
+ "duration:%s duration_time:%s\n",
+ type_desc,
+ av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base),
+ av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base),
+ av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &enc->time_base));
+ }
+
+ av_packet_rescale_ts(pkt, pkt->time_base, ost->mux_timebase);
+ pkt->time_base = ost->mux_timebase;
+
+ if (debug_ts) {
+ av_log(ost, AV_LOG_INFO, "encoder -> type:%s "
+ "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s "
+ "duration:%s duration_time:%s\n",
+ type_desc,
+ av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base),
+ av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base),
+ av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &enc->time_base));
+ }
+
+ if ((ret = trigger_fix_sub_duration_heartbeat(ost, pkt)) < 0) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Subtitle heartbeat logic failed in %s! (%s)\n",
+ __func__, av_err2str(ret));
+ exit_program(1);
+ }
+
+ ost->data_size_enc += pkt->size;
ost->packets_encoded++;
- output_packet(of, pkt, ost, 0);
+ of_output_packet(of, pkt, ost, 0);
}
av_assert0(0);
}
-static void do_audio_out(OutputFile *of, OutputStream *ost,
- AVFrame *frame)
+static int submit_encode_frame(OutputFile *of, OutputStream *ost,
+ AVFrame *frame)
{
int ret;
- adjust_frame_pts_to_encoder_tb(of, ost, frame);
+ if (ost->sq_idx_encode < 0)
+ return encode_frame(of, ost, frame);
- if (!check_recording_time(ost))
+ if (frame) {
+ ret = av_frame_ref(ost->sq_frame, frame);
+ if (ret < 0)
+ return ret;
+ frame = ost->sq_frame;
+ }
+
+ ret = sq_send(of->sq_encode, ost->sq_idx_encode,
+ SQFRAME(frame));
+ if (ret < 0) {
+ if (frame)
+ av_frame_unref(frame);
+ if (ret != AVERROR_EOF)
+ return ret;
+ }
+
+ while (1) {
+ AVFrame *enc_frame = ost->sq_frame;
+
+ ret = sq_receive(of->sq_encode, ost->sq_idx_encode,
+ SQFRAME(enc_frame));
+ if (ret == AVERROR_EOF) {
+ enc_frame = NULL;
+ } else if (ret < 0) {
+ return (ret == AVERROR(EAGAIN)) ? 0 : ret;
+ }
+
+ ret = encode_frame(of, ost, enc_frame);
+ if (enc_frame)
+ av_frame_unref(enc_frame);
+ if (ret < 0) {
+ if (ret == AVERROR_EOF)
+ close_output_stream(ost);
+ return ret;
+ }
+ }
+}
+
+static void do_audio_out(OutputFile *of, OutputStream *ost,
+ AVFrame *frame)
+{
+ AVCodecContext *enc = ost->enc_ctx;
+ int ret;
+
+ if (frame->pts == AV_NOPTS_VALUE)
+ frame->pts = ost->next_pts;
+ else {
+ int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
+ frame->pts =
+ av_rescale_q(frame->pts, frame->time_base, enc->time_base) -
+ av_rescale_q(start_time, AV_TIME_BASE_Q, enc->time_base);
+ }
+ frame->time_base = enc->time_base;
+
+ if (!check_recording_time(ost, frame->pts, frame->time_base))
return;
- if (frame->pts == AV_NOPTS_VALUE || audio_sync_method < 0)
- frame->pts = ost->sync_opts;
- ost->sync_opts = frame->pts + frame->nb_samples;
- ost->samples_encoded += frame->nb_samples;
+ ost->next_pts = frame->pts + frame->nb_samples;
- ret = encode_frame(of, ost, frame);
- if (ret < 0)
+ ret = submit_encode_frame(of, ost, frame);
+ if (ret < 0 && ret != AVERROR_EOF)
exit_program(1);
}
@@ -996,13 +1053,13 @@ static void do_subtitle_out(OutputFile *of,
AVSubtitle *sub)
{
int subtitle_out_max_size = 1024 * 1024;
- int subtitle_out_size, nb, i;
+ int subtitle_out_size, nb, i, ret;
AVCodecContext *enc;
AVPacket *pkt = ost->pkt;
int64_t pts;
if (sub->pts == AV_NOPTS_VALUE) {
- av_log(NULL, AV_LOG_ERROR, "Subtitle packets must have a pts\n");
+ av_log(ost, AV_LOG_ERROR, "Subtitle packets must have a pts\n");
if (exit_on_error)
exit_program(1);
return;
@@ -1010,14 +1067,6 @@ static void do_subtitle_out(OutputFile *of,
enc = ost->enc_ctx;
- if (!subtitle_out) {
- subtitle_out = av_malloc(subtitle_out_max_size);
- if (!subtitle_out) {
- av_log(NULL, AV_LOG_FATAL, "Failed to allocate subtitle_out\n");
- exit_program(1);
- }
- }
-
/* Note: DVB subtitle need one packet to draw them and one other
packet to clear them */
/* XXX: signal it in the codec context ? */
@@ -1033,10 +1082,13 @@ static void do_subtitle_out(OutputFile *of,
for (i = 0; i < nb; i++) {
unsigned save_num_rects = sub->num_rects;
- ost->sync_opts = av_rescale_q(pts, AV_TIME_BASE_Q, enc->time_base);
- if (!check_recording_time(ost))
+ if (!check_recording_time(ost, pts, AV_TIME_BASE_Q))
return;
+ ret = av_new_packet(pkt, subtitle_out_max_size);
+ if (ret < 0)
+ report_and_exit(AVERROR(ENOMEM));
+
sub->pts = pts;
// start_display_time is required to be 0
sub->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q);
@@ -1047,33 +1099,156 @@ static void do_subtitle_out(OutputFile *of,
ost->frames_encoded++;
- subtitle_out_size = avcodec_encode_subtitle(enc, subtitle_out,
- subtitle_out_max_size, sub);
+ subtitle_out_size = avcodec_encode_subtitle(enc, pkt->data, pkt->size, sub);
if (i == 1)
sub->num_rects = save_num_rects;
if (subtitle_out_size < 0) {
- av_log(NULL, AV_LOG_FATAL, "Subtitle encoding failed\n");
+ av_log(ost, AV_LOG_FATAL, "Subtitle encoding failed\n");
exit_program(1);
}
- av_packet_unref(pkt);
- pkt->data = subtitle_out;
- pkt->size = subtitle_out_size;
- pkt->pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->mux_timebase);
- pkt->duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase);
+ av_shrink_packet(pkt, subtitle_out_size);
+ pkt->time_base = ost->mux_timebase;
+ pkt->pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, pkt->time_base);
+ pkt->duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, pkt->time_base);
if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
/* XXX: the pts correction is handled here. Maybe handling
it in the codec would be better */
if (i == 0)
- pkt->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase);
+ pkt->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, pkt->time_base);
else
- pkt->pts += av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase);
+ pkt->pts += av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, pkt->time_base);
}
pkt->dts = pkt->pts;
- output_packet(of, pkt, ost, 0);
+
+ of_output_packet(of, pkt, ost, 0);
}
}
+/* Convert frame timestamps to the encoder timebase and decide how many times
+ * should this (and possibly previous) frame be repeated in order to conform to
+ * desired target framerate (if any).
+ */
+static void video_sync_process(OutputFile *of, OutputStream *ost,
+ AVFrame *next_picture, double duration,
+ int64_t *nb_frames, int64_t *nb_frames_prev)
+{
+ double delta0, delta;
+
+ double sync_ipts = adjust_frame_pts_to_encoder_tb(of, ost, next_picture);
+ /* delta0 is the "drift" between the input frame (next_picture) and
+ * where it would fall in the output. */
+ delta0 = sync_ipts - ost->next_pts;
+ delta = delta0 + duration;
+
+ // tracks the number of times the PREVIOUS frame should be duplicated,
+ // mostly for variable framerate (VFR)
+ *nb_frames_prev = 0;
+ /* by default, we output a single frame */
+ *nb_frames = 1;
+
+ if (delta0 < 0 &&
+ delta > 0 &&
+ ost->vsync_method != VSYNC_PASSTHROUGH &&
+ ost->vsync_method != VSYNC_DROP) {
+ if (delta0 < -0.6) {
+ av_log(ost, AV_LOG_VERBOSE, "Past duration %f too large\n", -delta0);
+ } else
+ av_log(ost, AV_LOG_DEBUG, "Clipping frame in rate conversion by %f\n", -delta0);
+ sync_ipts = ost->next_pts;
+ duration += delta0;
+ delta0 = 0;
+ }
+
+ switch (ost->vsync_method) {
+ case VSYNC_VSCFR:
+ if (ost->vsync_frame_number == 0 && delta0 >= 0.5) {
+ av_log(ost, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta0));
+ delta = duration;
+ delta0 = 0;
+ ost->next_pts = llrint(sync_ipts);
+ }
+ case VSYNC_CFR:
+ // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
+ if (frame_drop_threshold && delta < frame_drop_threshold && ost->vsync_frame_number) {
+ *nb_frames = 0;
+ } else if (delta < -1.1)
+ *nb_frames = 0;
+ else if (delta > 1.1) {
+ *nb_frames = llrintf(delta);
+ if (delta0 > 1.1)
+ *nb_frames_prev = llrintf(delta0 - 0.6);
+ }
+ next_picture->duration = 1;
+ break;
+ case VSYNC_VFR:
+ if (delta <= -0.6)
+ *nb_frames = 0;
+ else if (delta > 0.6)
+ ost->next_pts = llrint(sync_ipts);
+ next_picture->duration = duration;
+ break;
+ case VSYNC_DROP:
+ case VSYNC_PASSTHROUGH:
+ next_picture->duration = duration;
+ ost->next_pts = llrint(sync_ipts);
+ break;
+ default:
+ av_assert0(0);
+ }
+}
+
+static enum AVPictureType forced_kf_apply(void *logctx, KeyframeForceCtx *kf,
+ AVRational tb, const AVFrame *in_picture,
+ int dup_idx)
+{
+ double pts_time;
+
+ if (kf->ref_pts == AV_NOPTS_VALUE)
+ kf->ref_pts = in_picture->pts;
+
+ pts_time = (in_picture->pts - kf->ref_pts) * av_q2d(tb);
+ if (kf->index < kf->nb_pts &&
+ av_compare_ts(in_picture->pts, tb, kf->pts[kf->index], AV_TIME_BASE_Q) >= 0) {
+ kf->index++;
+ goto force_keyframe;
+ } else if (kf->pexpr) {
+ double res;
+ kf->expr_const_values[FKF_T] = pts_time;
+ res = av_expr_eval(kf->pexpr,
+ kf->expr_const_values, NULL);
+ ff_dlog(NULL, "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n",
+ kf->expr_const_values[FKF_N],
+ kf->expr_const_values[FKF_N_FORCED],
+ kf->expr_const_values[FKF_PREV_FORCED_N],
+ kf->expr_const_values[FKF_T],
+ kf->expr_const_values[FKF_PREV_FORCED_T],
+ res);
+
+ kf->expr_const_values[FKF_N] += 1;
+
+ if (res) {
+ kf->expr_const_values[FKF_PREV_FORCED_N] = kf->expr_const_values[FKF_N] - 1;
+ kf->expr_const_values[FKF_PREV_FORCED_T] = kf->expr_const_values[FKF_T];
+ kf->expr_const_values[FKF_N_FORCED] += 1;
+ goto force_keyframe;
+ }
+ } else if (kf->type == KF_FORCE_SOURCE &&
+ in_picture->key_frame == 1 && !dup_idx) {
+ goto force_keyframe;
+ } else if (kf->type == KF_FORCE_SOURCE_NO_DROP && !dup_idx) {
+ kf->dropped_keyframe = 0;
+ if ((in_picture->key_frame == 1) || kf->dropped_keyframe)
+ goto force_keyframe;
+ }
+
+ return AV_PICTURE_TYPE_NONE;
+
+force_keyframe:
+ av_log(logctx, AV_LOG_DEBUG, "Forced keyframe at time %f\n", pts_time);
+ return AV_PICTURE_TYPE_I;
+}
+
/* May modify/reset next_picture */
static void do_video_out(OutputFile *of,
OutputStream *ost,
@@ -1082,18 +1257,12 @@ static void do_video_out(OutputFile *of,
int ret;
AVCodecContext *enc = ost->enc_ctx;
AVRational frame_rate;
- int64_t nb_frames, nb0_frames, i;
- double delta, delta0;
+ int64_t nb_frames, nb_frames_prev, i;
double duration = 0;
- double sync_ipts = AV_NOPTS_VALUE;
- InputStream *ist = NULL;
+ InputStream *ist = ost->ist;
AVFilterContext *filter = ost->filter->filter;
init_output_stream_wrapper(ost, next_picture, 1);
- sync_ipts = adjust_frame_pts_to_encoder_tb(of, ost, next_picture);
-
- if (ost->source_index >= 0)
- ist = input_streams[ost->source_index];
frame_rate = av_buffersink_get_frame_rate(filter);
if (frame_rate.num > 0 && frame_rate.den > 0)
@@ -1107,113 +1276,52 @@ static void do_video_out(OutputFile *of,
(nb_filtergraphs == 0 || !filtergraphs[0]->graph_desc) &&
next_picture &&
ist &&
- lrintf(next_picture->pkt_duration * av_q2d(ist->st->time_base) / av_q2d(enc->time_base)) > 0) {
- duration = lrintf(next_picture->pkt_duration * av_q2d(ist->st->time_base) / av_q2d(enc->time_base));
+ lrintf(next_picture->duration * av_q2d(ist->st->time_base) / av_q2d(enc->time_base)) > 0) {
+ duration = lrintf(next_picture->duration * av_q2d(ist->st->time_base) / av_q2d(enc->time_base));
}
if (!next_picture) {
//end, flushing
- nb0_frames = nb_frames = mid_pred(ost->last_nb0_frames[0],
- ost->last_nb0_frames[1],
- ost->last_nb0_frames[2]);
+ nb_frames_prev = nb_frames = mid_pred(ost->last_nb0_frames[0],
+ ost->last_nb0_frames[1],
+ ost->last_nb0_frames[2]);
} else {
- delta0 = sync_ipts - ost->sync_opts; // delta0 is the "drift" between the input frame (next_picture) and where it would fall in the output.
- delta = delta0 + duration;
-
- /* by default, we output a single frame */
- nb0_frames = 0; // tracks the number of times the PREVIOUS frame should be duplicated, mostly for variable framerate (VFR)
- nb_frames = 1;
-
- if (delta0 < 0 &&
- delta > 0 &&
- ost->vsync_method != VSYNC_PASSTHROUGH &&
- ost->vsync_method != VSYNC_DROP) {
- if (delta0 < -0.6) {
- av_log(NULL, AV_LOG_VERBOSE, "Past duration %f too large\n", -delta0);
- } else
- av_log(NULL, AV_LOG_DEBUG, "Clipping frame in rate conversion by %f\n", -delta0);
- sync_ipts = ost->sync_opts;
- duration += delta0;
- delta0 = 0;
- }
-
- switch (ost->vsync_method) {
- case VSYNC_VSCFR:
- if (ost->frame_number == 0 && delta0 >= 0.5) {
- av_log(NULL, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta0));
- delta = duration;
- delta0 = 0;
- ost->sync_opts = llrint(sync_ipts);
- }
- case VSYNC_CFR:
- // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
- if (frame_drop_threshold && delta < frame_drop_threshold && ost->frame_number) {
- nb_frames = 0;
- } else if (delta < -1.1)
- nb_frames = 0;
- else if (delta > 1.1) {
- nb_frames = llrintf(delta);
- if (delta0 > 1.1)
- nb0_frames = llrintf(delta0 - 0.6);
- }
- break;
- case VSYNC_VFR:
- if (delta <= -0.6)
- nb_frames = 0;
- else if (delta > 0.6)
- ost->sync_opts = llrint(sync_ipts);
- break;
- case VSYNC_DROP:
- case VSYNC_PASSTHROUGH:
- ost->sync_opts = llrint(sync_ipts);
- break;
- default:
- av_assert0(0);
- }
+ video_sync_process(of, ost, next_picture, duration,
+ &nb_frames, &nb_frames_prev);
}
- /*
- * For video, number of frames in == number of packets out.
- * But there may be reordering, so we can't throw away frames on encoder
- * flush, we need to limit them here, before they go into encoder.
- */
- nb_frames = FFMIN(nb_frames, ost->max_frames - ost->frame_number);
- nb0_frames = FFMIN(nb0_frames, nb_frames);
-
memmove(ost->last_nb0_frames + 1,
ost->last_nb0_frames,
sizeof(ost->last_nb0_frames[0]) * (FF_ARRAY_ELEMS(ost->last_nb0_frames) - 1));
- ost->last_nb0_frames[0] = nb0_frames;
+ ost->last_nb0_frames[0] = nb_frames_prev;
- if (nb0_frames == 0 && ost->last_dropped) {
+ if (nb_frames_prev == 0 && ost->last_dropped) {
nb_frames_drop++;
- av_log(NULL, AV_LOG_VERBOSE,
- "*** dropping frame %"PRId64" from stream %d at ts %"PRId64"\n",
- ost->frame_number, ost->st->index, ost->last_frame->pts);
+ av_log(ost, AV_LOG_VERBOSE,
+ "*** dropping frame %"PRId64" at ts %"PRId64"\n",
+ ost->vsync_frame_number, ost->last_frame->pts);
}
- if (nb_frames > (nb0_frames && ost->last_dropped) + (nb_frames > nb0_frames)) {
+ if (nb_frames > (nb_frames_prev && ost->last_dropped) + (nb_frames > nb_frames_prev)) {
if (nb_frames > dts_error_threshold * 30) {
- av_log(NULL, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", nb_frames - 1);
+ av_log(ost, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", nb_frames - 1);
nb_frames_drop++;
return;
}
- nb_frames_dup += nb_frames - (nb0_frames && ost->last_dropped) - (nb_frames > nb0_frames);
- av_log(NULL, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", nb_frames - 1);
+ nb_frames_dup += nb_frames - (nb_frames_prev && ost->last_dropped) - (nb_frames > nb_frames_prev);
+ av_log(ost, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", nb_frames - 1);
if (nb_frames_dup > dup_warning) {
- av_log(NULL, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", dup_warning);
+ av_log(ost, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", dup_warning);
dup_warning *= 10;
}
}
- ost->last_dropped = nb_frames == nb0_frames && next_picture;
- ost->dropped_keyframe = ost->last_dropped && next_picture && next_picture->key_frame;
+ ost->last_dropped = nb_frames == nb_frames_prev && next_picture;
+ ost->kf.dropped_keyframe = ost->last_dropped && next_picture && next_picture->key_frame;
/* duplicates frame if needed */
for (i = 0; i < nb_frames; i++) {
AVFrame *in_picture;
- int forced_keyframe = 0;
- double pts_time;
- if (i < nb0_frames && ost->last_frame->buf[0]) {
+ if (i < nb_frames_prev && ost->last_frame->buf[0]) {
in_picture = ost->last_frame;
} else
in_picture = next_picture;
@@ -1221,69 +1329,22 @@ static void do_video_out(OutputFile *of,
if (!in_picture)
return;
- in_picture->pts = ost->sync_opts;
+ in_picture->pts = ost->next_pts;
- if (!check_recording_time(ost))
+ if (!check_recording_time(ost, in_picture->pts, ost->enc_ctx->time_base))
return;
in_picture->quality = enc->global_quality;
- in_picture->pict_type = 0;
+ in_picture->pict_type = forced_kf_apply(ost, &ost->kf, enc->time_base, in_picture, i);
- if (ost->forced_kf_ref_pts == AV_NOPTS_VALUE &&
- in_picture->pts != AV_NOPTS_VALUE)
- ost->forced_kf_ref_pts = in_picture->pts;
-
- pts_time = in_picture->pts != AV_NOPTS_VALUE ?
- (in_picture->pts - ost->forced_kf_ref_pts) * av_q2d(enc->time_base) : NAN;
- if (ost->forced_kf_index < ost->forced_kf_count &&
- in_picture->pts >= ost->forced_kf_pts[ost->forced_kf_index]) {
- ost->forced_kf_index++;
- forced_keyframe = 1;
- } else if (ost->forced_keyframes_pexpr) {
- double res;
- ost->forced_keyframes_expr_const_values[FKF_T] = pts_time;
- res = av_expr_eval(ost->forced_keyframes_pexpr,
- ost->forced_keyframes_expr_const_values, NULL);
- ff_dlog(NULL, "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n",
- ost->forced_keyframes_expr_const_values[FKF_N],
- ost->forced_keyframes_expr_const_values[FKF_N_FORCED],
- ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N],
- ost->forced_keyframes_expr_const_values[FKF_T],
- ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T],
- res);
- if (res) {
- forced_keyframe = 1;
- ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N] =
- ost->forced_keyframes_expr_const_values[FKF_N];
- ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T] =
- ost->forced_keyframes_expr_const_values[FKF_T];
- ost->forced_keyframes_expr_const_values[FKF_N_FORCED] += 1;
- }
-
- ost->forced_keyframes_expr_const_values[FKF_N] += 1;
- } else if ( ost->forced_keyframes
- && !strncmp(ost->forced_keyframes, "source", 6)
- && in_picture->key_frame==1
- && !i) {
- forced_keyframe = 1;
- } else if ( ost->forced_keyframes
- && !strncmp(ost->forced_keyframes, "source_no_drop", 14)
- && !i) {
- forced_keyframe = (in_picture->key_frame == 1) || ost->dropped_keyframe;
- ost->dropped_keyframe = 0;
- }
-
- if (forced_keyframe) {
- in_picture->pict_type = AV_PICTURE_TYPE_I;
- av_log(NULL, AV_LOG_DEBUG, "Forced keyframe at time %f\n", pts_time);
- }
-
- ret = encode_frame(of, ost, in_picture);
- if (ret < 0)
+ ret = submit_encode_frame(of, ost, in_picture);
+ if (ret == AVERROR_EOF)
+ break;
+ else if (ret < 0)
exit_program(1);
- ost->sync_opts++;
- ost->frame_number++;
+ ost->next_pts++;
+ ost->vsync_frame_number++;
}
av_frame_unref(ost->last_frame);
@@ -1291,19 +1352,6 @@ static void do_video_out(OutputFile *of,
av_frame_move_ref(ost->last_frame, next_picture);
}
-static void finish_output_stream(OutputStream *ost)
-{
- OutputFile *of = output_files[ost->file_index];
- AVRational time_base = ost->stream_copy ? ost->mux_timebase : ost->enc_ctx->time_base;
-
- ost->finished = ENCODER_FINISHED | MUXER_FINISHED;
-
- if (of->shortest) {
- int64_t end = av_rescale_q(ost->sync_opts - ost->first_pts, time_base, AV_TIME_BASE_Q);
- of->recording_time = FFMIN(of->recording_time, end);
- }
-}
-
/**
* Get and encode new output from any of the filtergraphs, without causing
* activity.
@@ -1313,11 +1361,9 @@ static void finish_output_stream(OutputStream *ost)
static int reap_filters(int flush)
{
AVFrame *filtered_frame = NULL;
- int i;
/* Reap all buffers present in the buffer sinks */
- for (i = 0; i < nb_output_streams; i++) {
- OutputStream *ost = output_streams[i];
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
OutputFile *of = output_files[ost->file_index];
AVFilterContext *filter;
AVCodecContext *enc = ost->enc_ctx;
@@ -1359,6 +1405,19 @@ static int reap_filters(int flush)
continue;
}
+ if (filtered_frame->pts != AV_NOPTS_VALUE) {
+ AVRational tb = av_buffersink_get_time_base(filter);
+ ost->last_filter_pts = av_rescale_q(filtered_frame->pts, tb,
+ AV_TIME_BASE_Q);
+ filtered_frame->time_base = tb;
+
+ if (debug_ts)
+ av_log(NULL, AV_LOG_INFO, "filter_raw -> pts:%s pts_time:%s time_base:%d/%d\n",
+ av_ts2str(filtered_frame->pts),
+ av_ts2timestr(filtered_frame->pts, &tb),
+ tb.num, tb.den);
+ }
+
switch (av_buffersink_get_type(filter)) {
case AVMEDIA_TYPE_VIDEO:
if (!ost->frame_aspect_ratio.num)
@@ -1396,17 +1455,20 @@ static void print_final_stats(int64_t total_size)
int i, j;
int pass1_used = 1;
- for (i = 0; i < nb_output_streams; i++) {
- OutputStream *ost = output_streams[i];
- switch (ost->enc_ctx->codec_type) {
- case AVMEDIA_TYPE_VIDEO: video_size += ost->data_size; break;
- case AVMEDIA_TYPE_AUDIO: audio_size += ost->data_size; break;
- case AVMEDIA_TYPE_SUBTITLE: subtitle_size += ost->data_size; break;
- default: other_size += ost->data_size; break;
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+ AVCodecParameters *par = ost->st->codecpar;
+ const uint64_t s = ost->data_size_mux;
+
+ switch (par->codec_type) {
+ case AVMEDIA_TYPE_VIDEO: video_size += s; break;
+ case AVMEDIA_TYPE_AUDIO: audio_size += s; break;
+ case AVMEDIA_TYPE_SUBTITLE: subtitle_size += s; break;
+ default: other_size += s; break;
}
- extra_size += ost->enc_ctx->extradata_size;
- data_size += ost->data_size;
- if ( (ost->enc_ctx->flags & (AV_CODEC_FLAG_PASS1 | AV_CODEC_FLAG_PASS2))
+ extra_size += par->extradata_size;
+ data_size += s;
+ if (ost->enc_ctx &&
+ (ost->enc_ctx->flags & (AV_CODEC_FLAG_PASS1 | AV_CODEC_FLAG_PASS2))
!= AV_CODEC_FLAG_PASS1)
pass1_used = 0;
}
@@ -1435,8 +1497,8 @@ static void print_final_stats(int64_t total_size)
i, f->ctx->url);
for (j = 0; j < f->nb_streams; j++) {
- InputStream *ist = input_streams[f->ist_index + j];
- enum AVMediaType type = ist->dec_ctx->codec_type;
+ InputStream *ist = f->streams[j];
+ enum AVMediaType type = ist->par->codec_type;
total_size += ist->data_size;
total_packets += ist->nb_packets;
@@ -1466,18 +1528,18 @@ static void print_final_stats(int64_t total_size)
uint64_t total_packets = 0, total_size = 0;
av_log(NULL, AV_LOG_VERBOSE, "Output file #%d (%s):\n",
- i, of->ctx->url);
+ i, of->url);
- for (j = 0; j < of->ctx->nb_streams; j++) {
- OutputStream *ost = output_streams[of->ost_index + j];
- enum AVMediaType type = ost->enc_ctx->codec_type;
+ for (j = 0; j < of->nb_streams; j++) {
+ OutputStream *ost = of->streams[j];
+ enum AVMediaType type = ost->st->codecpar->codec_type;
- total_size += ost->data_size;
- total_packets += ost->packets_written;
+ total_size += ost->data_size_mux;
+ total_packets += atomic_load(&ost->packets_written);
av_log(NULL, AV_LOG_VERBOSE, " Output stream #%d:%d (%s): ",
i, j, av_get_media_type_string(type));
- if (ost->encoding_needed) {
+ if (ost->enc_ctx) {
av_log(NULL, AV_LOG_VERBOSE, "%"PRIu64" frames encoded",
ost->frames_encoded);
if (type == AVMEDIA_TYPE_AUDIO)
@@ -1486,7 +1548,7 @@ static void print_final_stats(int64_t total_size)
}
av_log(NULL, AV_LOG_VERBOSE, "%"PRIu64" packets muxed (%"PRIu64" bytes); ",
- ost->packets_written, ost->data_size);
+ atomic_load(&ost->packets_written), ost->data_size_mux);
av_log(NULL, AV_LOG_VERBOSE, "\n");
}
@@ -1507,11 +1569,8 @@ static void print_final_stats(int64_t total_size)
static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time)
{
AVBPrint buf, buf_script;
- OutputStream *ost;
- AVFormatContext *oc;
- int64_t total_size;
- AVCodecContext *enc;
- int vid, i;
+ int64_t total_size = of_filesize(output_files[0]);
+ int vid;
double bitrate;
double speed;
int64_t pts = INT64_MIN + 1;
@@ -1538,31 +1597,21 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
t = (cur_time-timer_start) / 1000000.0;
-
- oc = output_files[0]->ctx;
-
- total_size = avio_size(oc->pb);
- if (total_size <= 0) // FIXME improve avio_size() so it works with non seekable output too
- total_size = avio_tell(oc->pb);
-
vid = 0;
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
- for (i = 0; i < nb_output_streams; i++) {
- float q = -1;
- ost = output_streams[i];
- enc = ost->enc_ctx;
- if (!ost->stream_copy)
- q = ost->quality / (float) FF_QP2LAMBDA;
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+ const AVCodecContext * const enc = ost->enc_ctx;
+ const float q = enc ? ost->quality / (float) FF_QP2LAMBDA : -1;
- if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (vid && ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
av_bprintf(&buf, "q=%2.1f ", q);
av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
ost->file_index, ost->index, q);
}
- if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (!vid && ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
float fps;
- int64_t frame_number = ost->frame_number;
+ uint64_t frame_number = atomic_load(&ost->packets_written);
fps = t > 1 ? frame_number / t : 0;
av_bprintf(&buf, "frame=%5"PRId64" fps=%3.*f q=%3.1f ",
@@ -1582,7 +1631,8 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
av_bprintf(&buf, "%X", av_log2(qp_histogram[j] + 1));
}
- if ((enc->flags & AV_CODEC_FLAG_PSNR) && (ost->pict_type != AV_PICTURE_TYPE_NONE || is_last_report)) {
+ if (enc && (enc->flags & AV_CODEC_FLAG_PSNR) &&
+ (ost->pict_type != AV_PICTURE_TYPE_NONE || is_last_report)) {
int j;
double error, error_sum = 0;
double scale, scale_sum = 0;
@@ -1614,9 +1664,8 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
vid = 1;
}
/* compute min output value */
- if (av_stream_get_end_pts(ost->st) != AV_NOPTS_VALUE) {
- pts = FFMAX(pts, av_rescale_q(av_stream_get_end_pts(ost->st),
- ost->st->time_base, AV_TIME_BASE_Q));
+ if (ost->last_mux_dts != AV_NOPTS_VALUE) {
+ pts = FFMAX(pts, ost->last_mux_dts);
if (copy_ts) {
if (copy_ts_first_pts == AV_NOPTS_VALUE && pts > 1)
copy_ts_first_pts = pts;
@@ -1734,14 +1783,19 @@ static int ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParamet
static void flush_encoders(void)
{
- int i, ret;
+ int ret;
- for (i = 0; i < nb_output_streams; i++) {
- OutputStream *ost = output_streams[i];
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+ OutputFile *of = output_files[ost->file_index];
+ if (ost->sq_idx_encode >= 0)
+ sq_send(of->sq_encode, ost->sq_idx_encode, SQFRAME(NULL));
+ }
+
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
AVCodecContext *enc = ost->enc_ctx;
OutputFile *of = output_files[ost->file_index];
- if (!ost->encoding_needed)
+ if (!enc)
continue;
// Try to enable encoding with no input frames.
@@ -1749,17 +1803,16 @@ static void flush_encoders(void)
if (!ost->initialized) {
FilterGraph *fg = ost->filter->graph;
- av_log(NULL, AV_LOG_WARNING,
- "Finishing stream %d:%d without any data written to it.\n",
- ost->file_index, ost->st->index);
+ av_log(ost, AV_LOG_WARNING,
+ "Finishing stream without any data written to it.\n");
if (ost->filter && !fg->graph) {
int x;
for (x = 0; x < fg->nb_inputs; x++) {
InputFilter *ifilter = fg->inputs[x];
if (ifilter->format < 0 &&
- ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar) < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error copying paramerets from input stream\n");
+ ifilter_parameters_from_codecpar(ifilter, ifilter->ist->par) < 0) {
+ av_log(ost, AV_LOG_ERROR, "Error copying paramerets from input stream\n");
exit_program(1);
}
}
@@ -1769,11 +1822,11 @@ static void flush_encoders(void)
ret = configure_filtergraph(fg);
if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error configuring filter graph\n");
+ av_log(ost, AV_LOG_ERROR, "Error configuring filter graph\n");
exit_program(1);
}
- finish_output_stream(ost);
+ of_output_packet(of, ost->pkt, ost, 1);
}
init_output_stream_wrapper(ost, NULL, 1);
@@ -1782,7 +1835,7 @@ static void flush_encoders(void)
if (enc->codec_type != AVMEDIA_TYPE_VIDEO && enc->codec_type != AVMEDIA_TYPE_AUDIO)
continue;
- ret = encode_frame(of, ost, NULL);
+ ret = submit_encode_frame(of, ost, NULL);
if (ret != AVERROR_EOF)
exit_program(1);
}
@@ -1794,9 +1847,8 @@ static void flush_encoders(void)
static int check_output_constraints(InputStream *ist, OutputStream *ost)
{
OutputFile *of = output_files[ost->file_index];
- int ist_index = input_files[ist->file_index]->ist_index + ist->st->index;
- if (ost->source_index != ist_index)
+ if (ost->ist != ist)
return 0;
if (ost->finished & MUXER_FINISHED)
@@ -1819,7 +1871,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
av_packet_unref(opkt);
// EOF: flush output bitstream filters.
if (!pkt) {
- output_packet(of, opkt, ost, 1);
+ of_output_packet(of, opkt, ost, 1);
return;
}
@@ -1828,12 +1880,9 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
return;
if (!ost->streamcopy_started && !ost->copy_prior_start) {
- int64_t comp_start = start_time;
- if (copy_ts && f->start_time != AV_NOPTS_VALUE)
- comp_start = FFMAX(start_time, f->start_time + f->ts_offset);
if (pkt->pts == AV_NOPTS_VALUE ?
- ist->pts < comp_start :
- pkt->pts < av_rescale_q(comp_start, AV_TIME_BASE_Q, ist->st->time_base))
+ ist->pts < ost->ts_copy_start :
+ pkt->pts < av_rescale_q(ost->ts_copy_start, AV_TIME_BASE_Q, ist->st->time_base))
return;
}
@@ -1847,7 +1896,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
start_time = 0;
if (copy_ts) {
start_time += f->start_time != AV_NOPTS_VALUE ? f->start_time : 0;
- start_time += start_at_zero ? 0 : f->ctx->start_time;
+ start_time += start_at_zero ? 0 : f->start_time_effective;
}
if (ist->pts >= f->recording_time + start_time) {
close_output_stream(ost);
@@ -1858,52 +1907,43 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
if (av_packet_ref(opkt, pkt) < 0)
exit_program(1);
+ opkt->time_base = ost->mux_timebase;
+
if (pkt->pts != AV_NOPTS_VALUE)
- opkt->pts = av_rescale_q(pkt->pts, ist->st->time_base, ost->mux_timebase) - ost_tb_start_time;
+ opkt->pts = av_rescale_q(pkt->pts, ist->st->time_base, opkt->time_base) - ost_tb_start_time;
if (pkt->dts == AV_NOPTS_VALUE) {
- opkt->dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ost->mux_timebase);
+ opkt->dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, opkt->time_base);
} else if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
- int duration = av_get_audio_frame_duration(ist->dec_ctx, pkt->size);
+ int duration = av_get_audio_frame_duration2(ist->par, pkt->size);
if(!duration)
- duration = ist->dec_ctx->frame_size;
+ duration = ist->par->frame_size;
opkt->dts = av_rescale_delta(ist->st->time_base, pkt->dts,
- (AVRational){1, ist->dec_ctx->sample_rate}, duration,
- &ist->filter_in_rescale_delta_last, ost->mux_timebase);
+ (AVRational){1, ist->par->sample_rate}, duration,
+ &ist->filter_in_rescale_delta_last, opkt->time_base);
/* dts will be set immediately afterwards to what pts is now */
opkt->pts = opkt->dts - ost_tb_start_time;
} else
- opkt->dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->mux_timebase);
+ opkt->dts = av_rescale_q(pkt->dts, ist->st->time_base, opkt->time_base);
opkt->dts -= ost_tb_start_time;
- opkt->duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->mux_timebase);
+ opkt->duration = av_rescale_q(pkt->duration, ist->st->time_base, opkt->time_base);
- ost->sync_opts += opkt->duration;
+ {
+ int ret = trigger_fix_sub_duration_heartbeat(ost, pkt);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Subtitle heartbeat logic failed in %s! (%s)\n",
+ __func__, av_err2str(ret));
+ exit_program(1);
+ }
+ }
- output_packet(of, opkt, ost, 0);
+ of_output_packet(of, opkt, ost, 0);
ost->streamcopy_started = 1;
}
-int guess_input_channel_layout(InputStream *ist)
-{
- AVCodecContext *dec = ist->dec_ctx;
-
- if (dec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
- char layout_name[256];
-
- if (dec->ch_layout.nb_channels > ist->guess_layout_max)
- return 0;
- av_channel_layout_default(&dec->ch_layout, dec->ch_layout.nb_channels);
- if (dec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
- return 0;
- av_channel_layout_describe(&dec->ch_layout, layout_name, sizeof(layout_name));
- av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Input Stream "
- "#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name);
- }
- return 1;
-}
-
static void check_decode_result(InputStream *ist, int *got_output, int ret)
{
if (*got_output || ret<0)
@@ -1947,7 +1987,7 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_ref
/* determine if the parameters for this input changed */
need_reinit = ifilter->format != frame->format;
- switch (ifilter->ist->st->codecpar->codec_type) {
+ switch (ifilter->ist->par->codec_type) {
case AVMEDIA_TYPE_AUDIO:
need_reinit |= ifilter->sample_rate != frame->sample_rate ||
av_channel_layout_compare(&ifilter->ch_layout, &frame->ch_layout);
@@ -2027,7 +2067,7 @@ static int ifilter_send_eof(InputFilter *ifilter, int64_t pts)
} else {
// the filtergraph was never configured
if (ifilter->format < 0) {
- ret = ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar);
+ ret = ifilter_parameters_from_codecpar(ifilter, ifilter->ist->par);
if (ret < 0)
return ret;
}
@@ -2044,7 +2084,8 @@ static int ifilter_send_eof(InputFilter *ifilter, int64_t pts)
// There is the following difference: if you got a frame, you must call
// it again with pkt=NULL. pkt==NULL is treated differently from pkt->size==0
// (pkt==NULL means get more output, pkt->size==0 is a flush/drain packet)
-static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
+static int decode(InputStream *ist, AVCodecContext *avctx,
+ AVFrame *frame, int *got_frame, AVPacket *pkt)
{
int ret;
@@ -2061,8 +2102,24 @@ static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacke
ret = avcodec_receive_frame(avctx, frame);
if (ret < 0 && ret != AVERROR(EAGAIN))
return ret;
- if (ret >= 0)
+ if (ret >= 0) {
+ if (ist->want_frame_data) {
+ FrameData *fd;
+
+ av_assert0(!frame->opaque_ref);
+ frame->opaque_ref = av_buffer_allocz(sizeof(*fd));
+ if (!frame->opaque_ref) {
+ av_frame_unref(frame);
+ return AVERROR(ENOMEM);
+ }
+ fd = (FrameData*)frame->opaque_ref->data;
+ fd->pts = frame->pts;
+ fd->tb = avctx->pkt_timebase;
+ fd->idx = avctx->frame_num - 1;
+ }
+
*got_frame = 1;
+ }
return 0;
}
@@ -2094,16 +2151,11 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output,
AVRational decoded_frame_tb;
update_benchmark(NULL);
- ret = decode(avctx, decoded_frame, got_output, pkt);
+ ret = decode(ist, avctx, decoded_frame, got_output, pkt);
update_benchmark("decode_audio %d.%d", ist->file_index, ist->st->index);
if (ret < 0)
*decode_failed = 1;
- if (ret >= 0 && avctx->sample_rate <= 0) {
- av_log(avctx, AV_LOG_ERROR, "Sample rate %d invalid\n", avctx->sample_rate);
- ret = AVERROR_INVALIDDATA;
- }
-
if (ret != AVERROR_EOF)
check_decode_result(ist, got_output, ret);
@@ -2116,9 +2168,9 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output,
/* increment next_dts to use for the case where the input stream does not
have timestamps or there are multiple frames in the packet */
ist->next_pts += ((int64_t)AV_TIME_BASE * decoded_frame->nb_samples) /
- avctx->sample_rate;
+ decoded_frame->sample_rate;
ist->next_dts += ((int64_t)AV_TIME_BASE * decoded_frame->nb_samples) /
- avctx->sample_rate;
+ decoded_frame->sample_rate;
if (decoded_frame->pts != AV_NOPTS_VALUE) {
decoded_frame_tb = ist->st->time_base;
@@ -2136,8 +2188,10 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output,
ist->prev_pkt_pts = pkt->pts;
if (decoded_frame->pts != AV_NOPTS_VALUE)
decoded_frame->pts = av_rescale_delta(decoded_frame_tb, decoded_frame->pts,
- (AVRational){1, avctx->sample_rate}, decoded_frame->nb_samples, &ist->filter_in_rescale_delta_last,
- (AVRational){1, avctx->sample_rate});
+ (AVRational){1, decoded_frame->sample_rate},
+ decoded_frame->nb_samples,
+ &ist->filter_in_rescale_delta_last,
+ (AVRational){1, decoded_frame->sample_rate});
ist->nb_samples = decoded_frame->nb_samples;
err = send_frame_to_filters(ist, decoded_frame);
@@ -2176,16 +2230,16 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_
}
update_benchmark(NULL);
- ret = decode(ist->dec_ctx, decoded_frame, got_output, pkt);
+ ret = decode(ist, ist->dec_ctx, decoded_frame, got_output, pkt);
update_benchmark("decode_video %d.%d", ist->file_index, ist->st->index);
if (ret < 0)
*decode_failed = 1;
// The following line may be required in some cases where there is no parser
// or the parser does not has_b_frames correctly
- if (ist->st->codecpar->video_delay < ist->dec_ctx->has_b_frames) {
+ if (ist->par->video_delay < ist->dec_ctx->has_b_frames) {
if (ist->dec_ctx->codec_id == AV_CODEC_ID_H264) {
- ist->st->codecpar->video_delay = ist->dec_ctx->has_b_frames;
+ ist->par->video_delay = ist->dec_ctx->has_b_frames;
} else
av_log(ist->dec_ctx, AV_LOG_WARNING,
"video_delay is larger in decoder than demuxer %d > %d.\n"
@@ -2193,7 +2247,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_
"of this file to https://streams.videolan.org/upload/ "
"and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)\n",
ist->dec_ctx->has_b_frames,
- ist->st->codecpar->video_delay);
+ ist->par->video_delay);
}
if (ret != AVERROR_EOF)
@@ -2226,10 +2280,9 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_
if (err < 0)
goto fail;
}
- ist->hwaccel_retrieved_pix_fmt = decoded_frame->format;
best_effort_timestamp= decoded_frame->best_effort_timestamp;
- *duration_pts = decoded_frame->pkt_duration;
+ *duration_pts = decoded_frame->duration;
if (ist->framerate.num)
best_effort_timestamp = ist->cfr_next_pts++;
@@ -2270,13 +2323,201 @@ fail:
return err < 0 ? err : ret;
}
-static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output,
- int *decode_failed)
+static int process_subtitle(InputStream *ist, AVSubtitle *subtitle, int *got_output)
+{
+ int ret = 0;
+ int free_sub = 1;
+
+ if (ist->fix_sub_duration) {
+ int end = 1;
+ if (ist->prev_sub.got_output) {
+ end = av_rescale(subtitle->pts - ist->prev_sub.subtitle.pts,
+ 1000, AV_TIME_BASE);
+ if (end < ist->prev_sub.subtitle.end_display_time) {
+ av_log(NULL, AV_LOG_DEBUG,
+ "Subtitle duration reduced from %"PRId32" to %d%s\n",
+ ist->prev_sub.subtitle.end_display_time, end,
+ end <= 0 ? ", dropping it" : "");
+ ist->prev_sub.subtitle.end_display_time = end;
+ }
+ }
+ FFSWAP(int, *got_output, ist->prev_sub.got_output);
+ FFSWAP(int, ret, ist->prev_sub.ret);
+ FFSWAP(AVSubtitle, *subtitle, ist->prev_sub.subtitle);
+ if (end <= 0)
+ goto out;
+ }
+
+ if (!*got_output)
+ return ret;
+
+ if (ist->sub2video.frame) {
+ sub2video_update(ist, INT64_MIN, subtitle);
+ } else if (ist->nb_filters) {
+ if (!ist->sub2video.sub_queue)
+ ist->sub2video.sub_queue = av_fifo_alloc2(8, sizeof(AVSubtitle), AV_FIFO_FLAG_AUTO_GROW);
+ if (!ist->sub2video.sub_queue)
+ report_and_exit(AVERROR(ENOMEM));
+
+ ret = av_fifo_write(ist->sub2video.sub_queue, subtitle, 1);
+ if (ret < 0)
+ exit_program(1);
+ free_sub = 0;
+ }
+
+ if (!subtitle->num_rects)
+ goto out;
+
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+ if (!check_output_constraints(ist, ost) || !ost->enc_ctx
+ || ost->enc_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE)
+ continue;
+
+ do_subtitle_out(output_files[ost->file_index], ost, subtitle);
+ }
+
+out:
+ if (free_sub)
+ avsubtitle_free(subtitle);
+ return ret;
+}
+
+static int copy_av_subtitle(AVSubtitle *dst, AVSubtitle *src)
+{
+ int ret = AVERROR_BUG;
+ AVSubtitle tmp = {
+ .format = src->format,
+ .start_display_time = src->start_display_time,
+ .end_display_time = src->end_display_time,
+ .num_rects = 0,
+ .rects = NULL,
+ .pts = src->pts
+ };
+
+ if (!src->num_rects)
+ goto success;
+
+ if (!(tmp.rects = av_calloc(src->num_rects, sizeof(*tmp.rects))))
+ return AVERROR(ENOMEM);
+
+ for (int i = 0; i < src->num_rects; i++) {
+ AVSubtitleRect *src_rect = src->rects[i];
+ AVSubtitleRect *dst_rect;
+
+ if (!(dst_rect = tmp.rects[i] = av_mallocz(sizeof(*tmp.rects[0])))) {
+ ret = AVERROR(ENOMEM);
+ goto cleanup;
+ }
+
+ tmp.num_rects++;
+
+ dst_rect->type = src_rect->type;
+ dst_rect->flags = src_rect->flags;
+
+ dst_rect->x = src_rect->x;
+ dst_rect->y = src_rect->y;
+ dst_rect->w = src_rect->w;
+ dst_rect->h = src_rect->h;
+ dst_rect->nb_colors = src_rect->nb_colors;
+
+ if (src_rect->text)
+ if (!(dst_rect->text = av_strdup(src_rect->text))) {
+ ret = AVERROR(ENOMEM);
+ goto cleanup;
+ }
+
+ if (src_rect->ass)
+ if (!(dst_rect->ass = av_strdup(src_rect->ass))) {
+ ret = AVERROR(ENOMEM);
+ goto cleanup;
+ }
+
+ for (int j = 0; j < 4; j++) {
+ // SUBTITLE_BITMAP images are special in the sense that they
+ // are like PAL8 images. first pointer to data, second to
+ // palette. This makes the size calculation match this.
+ size_t buf_size = src_rect->type == SUBTITLE_BITMAP && j == 1 ?
+ AVPALETTE_SIZE :
+ src_rect->h * src_rect->linesize[j];
+
+ if (!src_rect->data[j])
+ continue;
+
+ if (!(dst_rect->data[j] = av_memdup(src_rect->data[j], buf_size))) {
+ ret = AVERROR(ENOMEM);
+ goto cleanup;
+ }
+ dst_rect->linesize[j] = src_rect->linesize[j];
+ }
+ }
+
+success:
+ *dst = tmp;
+
+ return 0;
+
+cleanup:
+ avsubtitle_free(&tmp);
+
+ return ret;
+}
+
+static int fix_sub_duration_heartbeat(InputStream *ist, int64_t signal_pts)
+{
+ int ret = AVERROR_BUG;
+ int got_output = 1;
+ AVSubtitle *prev_subtitle = &ist->prev_sub.subtitle;
+ AVSubtitle subtitle;
+
+ if (!ist->fix_sub_duration || !prev_subtitle->num_rects ||
+ signal_pts <= prev_subtitle->pts)
+ return 0;
+
+ if ((ret = copy_av_subtitle(&subtitle, prev_subtitle)) < 0)
+ return ret;
+
+ subtitle.pts = signal_pts;
+
+ return process_subtitle(ist, &subtitle, &got_output);
+}
+
+static int trigger_fix_sub_duration_heartbeat(OutputStream *ost, const AVPacket *pkt)
+{
+ OutputFile *of = output_files[ost->file_index];
+ int64_t signal_pts = av_rescale_q(pkt->pts, pkt->time_base,
+ AV_TIME_BASE_Q);
+
+ if (!ost->fix_sub_duration_heartbeat || !(pkt->flags & AV_PKT_FLAG_KEY))
+ // we are only interested in heartbeats on streams configured, and
+ // only on random access points.
+ return 0;
+
+ for (int i = 0; i < of->nb_streams; i++) {
+ OutputStream *iter_ost = of->streams[i];
+ InputStream *ist = iter_ost->ist;
+ int ret = AVERROR_BUG;
+
+ if (iter_ost == ost || !ist || !ist->decoding_needed ||
+ ist->dec_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE)
+ // We wish to skip the stream that causes the heartbeat,
+ // output streams without an input stream, streams not decoded
+ // (as fix_sub_duration is only done for decoded subtitles) as
+ // well as non-subtitle streams.
+ continue;
+
+ if ((ret = fix_sub_duration_heartbeat(ist, signal_pts)) < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int transcode_subtitles(InputStream *ist, const AVPacket *pkt,
+ int *got_output, int *decode_failed)
{
AVSubtitle subtitle;
- int free_sub = 1;
- int i, ret = avcodec_decode_subtitle2(ist->dec_ctx,
- &subtitle, got_output, pkt);
+ int ret = avcodec_decode_subtitle2(ist->dec_ctx,
+ &subtitle, got_output, pkt);
check_decode_result(NULL, got_output, ret);
@@ -2287,62 +2528,9 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output,
return ret;
}
- if (ist->fix_sub_duration) {
- int end = 1;
- if (ist->prev_sub.got_output) {
- end = av_rescale(subtitle.pts - ist->prev_sub.subtitle.pts,
- 1000, AV_TIME_BASE);
- if (end < ist->prev_sub.subtitle.end_display_time) {
- av_log(ist->dec_ctx, AV_LOG_DEBUG,
- "Subtitle duration reduced from %"PRId32" to %d%s\n",
- ist->prev_sub.subtitle.end_display_time, end,
- end <= 0 ? ", dropping it" : "");
- ist->prev_sub.subtitle.end_display_time = end;
- }
- }
- FFSWAP(int, *got_output, ist->prev_sub.got_output);
- FFSWAP(int, ret, ist->prev_sub.ret);
- FFSWAP(AVSubtitle, subtitle, ist->prev_sub.subtitle);
- if (end <= 0)
- goto out;
- }
-
- if (!*got_output)
- return ret;
-
- if (ist->sub2video.frame) {
- sub2video_update(ist, INT64_MIN, &subtitle);
- } else if (ist->nb_filters) {
- if (!ist->sub2video.sub_queue)
- ist->sub2video.sub_queue = av_fifo_alloc2(8, sizeof(AVSubtitle), AV_FIFO_FLAG_AUTO_GROW);
- if (!ist->sub2video.sub_queue)
- exit_program(1);
-
- ret = av_fifo_write(ist->sub2video.sub_queue, &subtitle, 1);
- if (ret < 0)
- exit_program(1);
- free_sub = 0;
- }
-
- if (!subtitle.num_rects)
- goto out;
-
ist->frames_decoded++;
- for (i = 0; i < nb_output_streams; i++) {
- OutputStream *ost = output_streams[i];
-
- if (!check_output_constraints(ist, ost) || !ost->encoding_needed
- || ost->enc->type != AVMEDIA_TYPE_SUBTITLE)
- continue;
-
- do_subtitle_out(output_files[ost->file_index], ost, &subtitle);
- }
-
-out:
- if (free_sub)
- avsubtitle_free(&subtitle);
- return ret;
+ return process_subtitle(ist, &subtitle, got_output);
}
static int send_filter_eof(InputStream *ist)
@@ -2363,7 +2551,8 @@ static int send_filter_eof(InputStream *ist)
/* pkt = NULL means EOF (needed to flush decoder buffers) */
static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eof)
{
- int ret = 0, i;
+ const AVCodecParameters *par = ist->par;
+ int ret = 0;
int repeating = 0;
int eof_reached = 0;
@@ -2395,7 +2584,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
if (pkt && pkt->dts != AV_NOPTS_VALUE) {
ist->next_dts = ist->dts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
- if (ist->dec_ctx->codec_type != AVMEDIA_TYPE_VIDEO || !ist->decoding_needed)
+ if (par->codec_type != AVMEDIA_TYPE_VIDEO || !ist->decoding_needed)
ist->next_pts = ist->pts = ist->dts;
}
@@ -2409,7 +2598,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
ist->pts = ist->next_pts;
ist->dts = ist->next_dts;
- switch (ist->dec_ctx->codec_type) {
+ switch (par->codec_type) {
case AVMEDIA_TYPE_AUDIO:
ret = decode_audio (ist, repeating ? NULL : avpkt, &got_output,
&decode_failed);
@@ -2422,7 +2611,9 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
if (pkt && pkt->duration) {
duration_dts = av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);
} else if(ist->dec_ctx->framerate.num != 0 && ist->dec_ctx->framerate.den != 0) {
- int ticks= av_stream_get_parser(ist->st) ? av_stream_get_parser(ist->st)->repeat_pict+1 : ist->dec_ctx->ticks_per_frame;
+ int ticks = ist->last_pkt_repeat_pict >= 0 ?
+ ist->last_pkt_repeat_pict + 1 :
+ ist->dec_ctx->ticks_per_frame;
duration_dts = ((int64_t)AV_TIME_BASE *
ist->dec_ctx->framerate.den * ticks) /
ist->dec_ctx->framerate.num / ist->dec_ctx->ticks_per_frame;
@@ -2506,12 +2697,12 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
/* handle stream copy */
if (!ist->decoding_needed && pkt) {
ist->dts = ist->next_dts;
- switch (ist->dec_ctx->codec_type) {
+ switch (par->codec_type) {
case AVMEDIA_TYPE_AUDIO:
av_assert1(pkt->duration >= 0);
- if (ist->dec_ctx->sample_rate) {
- ist->next_dts += ((int64_t)AV_TIME_BASE * ist->dec_ctx->frame_size) /
- ist->dec_ctx->sample_rate;
+ if (par->sample_rate) {
+ ist->next_dts += ((int64_t)AV_TIME_BASE * par->frame_size) /
+ par->sample_rate;
} else {
ist->next_dts += av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);
}
@@ -2525,7 +2716,9 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
} else if (pkt->duration) {
ist->next_dts += av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);
} else if(ist->dec_ctx->framerate.num != 0) {
- int ticks= av_stream_get_parser(ist->st) ? av_stream_get_parser(ist->st)->repeat_pict + 1 : ist->dec_ctx->ticks_per_frame;
+ int ticks = ist->last_pkt_repeat_pict >= 0 ?
+ ist->last_pkt_repeat_pict + 1 :
+ ist->dec_ctx->ticks_per_frame;
ist->next_dts += ((int64_t)AV_TIME_BASE *
ist->dec_ctx->framerate.den * ticks) /
ist->dec_ctx->framerate.num / ist->dec_ctx->ticks_per_frame;
@@ -2537,10 +2730,9 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
} else if (!ist->decoding_needed)
eof_reached = 1;
- for (i = 0; i < nb_output_streams; i++) {
- OutputStream *ost = output_streams[i];
-
- if (!check_output_constraints(ist, ost) || ost->encoding_needed)
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+ if (!check_output_constraints(ist, ost) || ost->enc_ctx ||
+ (!pkt && no_eof))
continue;
do_streamcopy(ist, ost, pkt);
@@ -2598,10 +2790,9 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat
return *p;
}
-static int init_input_stream(int ist_index, char *error, int error_len)
+static int init_input_stream(InputStream *ist, char *error, int error_len)
{
int ret;
- InputStream *ist = input_streams[ist_index];
if (ist->decoding_needed) {
const AVCodec *codec = ist->dec;
@@ -2613,11 +2804,6 @@ static int init_input_stream(int ist_index, char *error, int error_len)
ist->dec_ctx->opaque = ist;
ist->dec_ctx->get_format = get_format;
-#if LIBAVCODEC_VERSION_MAJOR < 60
- AV_NOWARN_DEPRECATED({
- ist->dec_ctx->thread_safe_callbacks = 1;
- })
-#endif
if (ist->dec_ctx->codec_id == AV_CODEC_ID_DVB_SUBTITLE &&
(ist->decoding_needed & DECODING_FOR_OST)) {
@@ -2663,71 +2849,37 @@ static int init_input_stream(int ist_index, char *error, int error_len)
return 0;
}
-static InputStream *get_input_stream(OutputStream *ost)
-{
- if (ost->source_index >= 0)
- return input_streams[ost->source_index];
- return NULL;
-}
-
-static int compare_int64(const void *a, const void *b)
-{
- return FFDIFFSIGN(*(const int64_t *)a, *(const int64_t *)b);
-}
-
-static int init_output_bsfs(OutputStream *ost)
-{
- AVBSFContext *ctx = ost->bsf_ctx;
- int ret;
-
- if (!ctx)
- return 0;
-
- ret = avcodec_parameters_copy(ctx->par_in, ost->st->codecpar);
- if (ret < 0)
- return ret;
-
- ctx->time_base_in = ost->st->time_base;
-
- ret = av_bsf_init(ctx);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n",
- ctx->filter->name);
- return ret;
- }
-
- ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out);
- if (ret < 0)
- return ret;
- ost->st->time_base = ctx->time_base_out;
-
- return 0;
-}
-
static int init_output_stream_streamcopy(OutputStream *ost)
{
OutputFile *of = output_files[ost->file_index];
- InputStream *ist = get_input_stream(ost);
- AVCodecParameters *par_dst = ost->st->codecpar;
- AVCodecParameters *par_src = ost->ref_par;
+ InputStream *ist = ost->ist;
+ InputFile *ifile = input_files[ist->file_index];
+ AVCodecParameters *par = ost->st->codecpar;
+ AVCodecContext *codec_ctx;
AVRational sar;
int i, ret;
- uint32_t codec_tag = par_dst->codec_tag;
+ uint32_t codec_tag = par->codec_tag;
av_assert0(ist && !ost->filter);
- ret = avcodec_parameters_to_context(ost->enc_ctx, ist->st->codecpar);
+ codec_ctx = avcodec_alloc_context3(NULL);
+ if (!codec_ctx)
+ return AVERROR(ENOMEM);
+
+ ret = avcodec_parameters_to_context(codec_ctx, ist->par);
if (ret >= 0)
- ret = av_opt_set_dict(ost->enc_ctx, &ost->encoder_opts);
+ ret = av_opt_set_dict(codec_ctx, &ost->encoder_opts);
if (ret < 0) {
- av_log(NULL, AV_LOG_FATAL,
+ av_log(ost, AV_LOG_FATAL,
"Error setting up codec context options.\n");
+ avcodec_free_context(&codec_ctx);
return ret;
}
- ret = avcodec_parameters_from_context(par_src, ost->enc_ctx);
+ ret = avcodec_parameters_from_context(par, codec_ctx);
+ avcodec_free_context(&codec_ctx);
if (ret < 0) {
- av_log(NULL, AV_LOG_FATAL,
+ av_log(ost, AV_LOG_FATAL,
"Error getting reference codec parameters.\n");
return ret;
}
@@ -2735,16 +2887,12 @@ static int init_output_stream_streamcopy(OutputStream *ost)
if (!codec_tag) {
unsigned int codec_tag_tmp;
if (!of->format->codec_tag ||
- av_codec_get_id (of->format->codec_tag, par_src->codec_tag) == par_src->codec_id ||
- !av_codec_get_tag2(of->format->codec_tag, par_src->codec_id, &codec_tag_tmp))
- codec_tag = par_src->codec_tag;
+ av_codec_get_id (of->format->codec_tag, par->codec_tag) == par->codec_id ||
+ !av_codec_get_tag2(of->format->codec_tag, par->codec_id, &codec_tag_tmp))
+ codec_tag = par->codec_tag;
}
- ret = avcodec_parameters_copy(par_dst, par_src);
- if (ret < 0)
- return ret;
-
- par_dst->codec_tag = codec_tag;
+ par->codec_tag = codec_tag;
if (!ost->frame_rate.num)
ost->frame_rate = ist->framerate;
@@ -2770,6 +2918,15 @@ static int init_output_stream_streamcopy(OutputStream *ost)
if (ost->st->duration <= 0 && ist->st->duration > 0)
ost->st->duration = av_rescale_q(ist->st->duration, ist->st->time_base, ost->st->time_base);
+ if (!ost->copy_prior_start) {
+ ost->ts_copy_start = (of->start_time == AV_NOPTS_VALUE) ?
+ 0 : of->start_time;
+ if (copy_ts && ifile->start_time != AV_NOPTS_VALUE) {
+ ost->ts_copy_start = FFMAX(ost->ts_copy_start,
+ ifile->start_time + ifile->ts_offset);
+ }
+ }
+
if (ist->st->nb_side_data) {
for (i = 0; i < ist->st->nb_side_data; i++) {
const AVPacketSideData *sd_src = &ist->st->side_data[i];
@@ -2782,37 +2939,36 @@ static int init_output_stream_streamcopy(OutputStream *ost)
}
}
+#if FFMPEG_ROTATION_METADATA
if (ost->rotate_overridden) {
uint8_t *sd = av_stream_new_side_data(ost->st, AV_PKT_DATA_DISPLAYMATRIX,
sizeof(int32_t) * 9);
if (sd)
av_display_rotation_set((int32_t *)sd, -ost->rotate_override_value);
}
+#endif
- switch (par_dst->codec_type) {
+ switch (par->codec_type) {
case AVMEDIA_TYPE_AUDIO:
- if (audio_volume != 256) {
- av_log(NULL, AV_LOG_FATAL, "-acodec copy and -vol are incompatible (frames are not decoded)\n");
- exit_program(1);
- }
- if((par_dst->block_align == 1 || par_dst->block_align == 1152 || par_dst->block_align == 576) && par_dst->codec_id == AV_CODEC_ID_MP3)
- par_dst->block_align= 0;
- if(par_dst->codec_id == AV_CODEC_ID_AC3)
- par_dst->block_align= 0;
+ if ((par->block_align == 1 || par->block_align == 1152 || par->block_align == 576) &&
+ par->codec_id == AV_CODEC_ID_MP3)
+ par->block_align = 0;
+ if (par->codec_id == AV_CODEC_ID_AC3)
+ par->block_align = 0;
break;
case AVMEDIA_TYPE_VIDEO:
if (ost->frame_aspect_ratio.num) { // overridden by the -aspect cli option
sar =
av_mul_q(ost->frame_aspect_ratio,
- (AVRational){ par_dst->height, par_dst->width });
- av_log(NULL, AV_LOG_WARNING, "Overriding aspect ratio "
+ (AVRational){ par->height, par->width });
+ av_log(ost, AV_LOG_WARNING, "Overriding aspect ratio "
"with stream copy may produce invalid files\n");
}
else if (ist->st->sample_aspect_ratio.num)
sar = ist->st->sample_aspect_ratio;
else
- sar = par_src->sample_aspect_ratio;
- ost->st->sample_aspect_ratio = par_dst->sample_aspect_ratio = sar;
+ sar = par->sample_aspect_ratio;
+ ost->st->sample_aspect_ratio = par->sample_aspect_ratio = sar;
ost->st->avg_frame_rate = ist->st->avg_frame_rate;
ost->st->r_frame_rate = ist->st->r_frame_rate;
break;
@@ -2825,113 +2981,31 @@ static int init_output_stream_streamcopy(OutputStream *ost)
static void set_encoder_id(OutputFile *of, OutputStream *ost)
{
- const AVDictionaryEntry *e;
-
+ const char *cname = ost->enc_ctx->codec->name;
uint8_t *encoder_string;
int encoder_string_len;
- int format_flags = 0;
- int codec_flags = ost->enc_ctx->flags;
if (av_dict_get(ost->st->metadata, "encoder", NULL, 0))
return;
- e = av_dict_get(of->opts, "fflags", NULL, 0);
- if (e) {
- const AVOption *o = av_opt_find(of->ctx, "fflags", NULL, 0, 0);
- if (!o)
- return;
- av_opt_eval_flags(of->ctx, o, e->value, &format_flags);
- }
- e = av_dict_get(ost->encoder_opts, "flags", NULL, 0);
- if (e) {
- const AVOption *o = av_opt_find(ost->enc_ctx, "flags", NULL, 0, 0);
- if (!o)
- return;
- av_opt_eval_flags(ost->enc_ctx, o, e->value, &codec_flags);
- }
-
- encoder_string_len = sizeof(LIBAVCODEC_IDENT) + strlen(ost->enc->name) + 2;
+ encoder_string_len = sizeof(LIBAVCODEC_IDENT) + strlen(cname) + 2;
encoder_string = av_mallocz(encoder_string_len);
if (!encoder_string)
- exit_program(1);
+ report_and_exit(AVERROR(ENOMEM));
- if (!(format_flags & AVFMT_FLAG_BITEXACT) && !(codec_flags & AV_CODEC_FLAG_BITEXACT))
+ if (!of->bitexact && !ost->bitexact)
av_strlcpy(encoder_string, LIBAVCODEC_IDENT " ", encoder_string_len);
else
av_strlcpy(encoder_string, "Lavc ", encoder_string_len);
- av_strlcat(encoder_string, ost->enc->name, encoder_string_len);
+ av_strlcat(encoder_string, cname, encoder_string_len);
av_dict_set(&ost->st->metadata, "encoder", encoder_string,
AV_DICT_DONT_STRDUP_VAL | AV_DICT_DONT_OVERWRITE);
}
-static void parse_forced_key_frames(char *kf, OutputStream *ost,
- AVCodecContext *avctx)
-{
- char *p;
- int n = 1, i, size, index = 0;
- int64_t t, *pts;
-
- for (p = kf; *p; p++)
- if (*p == ',')
- n++;
- size = n;
- pts = av_malloc_array(size, sizeof(*pts));
- if (!pts) {
- av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
- exit_program(1);
- }
-
- p = kf;
- for (i = 0; i < n; i++) {
- char *next = strchr(p, ',');
-
- if (next)
- *next++ = 0;
-
- if (!memcmp(p, "chapters", 8)) {
-
- AVFormatContext *avf = output_files[ost->file_index]->ctx;
- int j;
-
- if (avf->nb_chapters > INT_MAX - size ||
- !(pts = av_realloc_f(pts, size += avf->nb_chapters - 1,
- sizeof(*pts)))) {
- av_log(NULL, AV_LOG_FATAL,
- "Could not allocate forced key frames array.\n");
- exit_program(1);
- }
- t = p[8] ? parse_time_or_die("force_key_frames", p + 8, 1) : 0;
- t = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base);
-
- for (j = 0; j < avf->nb_chapters; j++) {
- AVChapter *c = avf->chapters[j];
- av_assert1(index < size);
- pts[index++] = av_rescale_q(c->start, c->time_base,
- avctx->time_base) + t;
- }
-
- } else {
-
- t = parse_time_or_die("force_key_frames", p, 1);
- av_assert1(index < size);
- pts[index++] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base);
-
- }
-
- p = next;
- }
-
- av_assert0(index == size);
- qsort(pts, size, sizeof(*pts), compare_int64);
- ost->forced_kf_count = size;
- ost->forced_kf_pts = pts;
-}
-
static void init_encoder_time_base(OutputStream *ost, AVRational default_time_base)
{
- InputStream *ist = get_input_stream(ost);
+ InputStream *ist = ost->ist;
AVCodecContext *enc_ctx = ost->enc_ctx;
- AVFormatContext *oc;
if (ost->enc_timebase.num > 0) {
enc_ctx->time_base = ost->enc_timebase;
@@ -2944,8 +3018,8 @@ static void init_encoder_time_base(OutputStream *ost, AVRational default_time_ba
return;
}
- oc = output_files[ost->file_index]->ctx;
- av_log(oc, AV_LOG_WARNING, "Input stream data not available, using default time base\n");
+ av_log(ost, AV_LOG_WARNING,
+ "Input stream data not available, using default time base\n");
}
enc_ctx->time_base = default_time_base;
@@ -2953,11 +3027,10 @@ static void init_encoder_time_base(OutputStream *ost, AVRational default_time_ba
static int init_output_stream_encode(OutputStream *ost, AVFrame *frame)
{
- InputStream *ist = get_input_stream(ost);
+ InputStream *ist = ost->ist;
AVCodecContext *enc_ctx = ost->enc_ctx;
AVCodecContext *dec_ctx = NULL;
OutputFile *of = output_files[ost->file_index];
- AVFormatContext *oc = of->ctx;
int ret;
set_encoder_id(output_files[ost->file_index], ost);
@@ -2969,14 +3042,13 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame)
if (enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
if (!ost->frame_rate.num)
ost->frame_rate = av_buffersink_get_frame_rate(ost->filter->filter);
- if (ist && !ost->frame_rate.num && !ost->max_frame_rate.num) {
+ if (!ost->frame_rate.num && !ost->max_frame_rate.num) {
ost->frame_rate = (AVRational){25, 1};
- av_log(NULL, AV_LOG_WARNING,
+ av_log(ost, AV_LOG_WARNING,
"No information "
"about the input framerate is available. Falling "
- "back to a default value of 25fps for output stream #%d:%d. Use the -r option "
- "if you want a different framerate.\n",
- ost->file_index, ost->index);
+ "back to a default value of 25fps. Use the -r option "
+ "if you want a different framerate.\n");
}
if (ost->max_frame_rate.num &&
@@ -2984,9 +3056,9 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame)
!ost->frame_rate.den))
ost->frame_rate = ost->max_frame_rate;
- if (ost->enc->supported_framerates && !ost->force_fps) {
- int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);
- ost->frame_rate = ost->enc->supported_framerates[idx];
+ if (enc_ctx->codec->supported_framerates && !ost->force_fps) {
+ int idx = av_find_nearest_q_idx(ost->frame_rate, enc_ctx->codec->supported_framerates);
+ ost->frame_rate = enc_ctx->codec->supported_framerates[idx];
}
// reduce frame rate for mpeg4 to be within the spec limits
if (enc_ctx->codec_id == AV_CODEC_ID_MPEG4) {
@@ -3020,9 +3092,9 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame)
if ( av_q2d(enc_ctx->time_base) < 0.001 && ost->vsync_method != VSYNC_PASSTHROUGH
&& (ost->vsync_method == VSYNC_CFR || ost->vsync_method == VSYNC_VSCFR ||
(ost->vsync_method == VSYNC_AUTO && !(of->format->flags & AVFMT_VARIABLE_FPS)))){
- av_log(oc, AV_LOG_WARNING, "Frame rate very high for a muxer not efficiently supporting it.\n"
- "Please consider specifying a lower framerate, a different muxer or "
- "setting vsync/fps_mode to vfr\n");
+ av_log(ost, AV_LOG_WARNING, "Frame rate very high for a muxer not efficiently supporting it.\n"
+ "Please consider specifying a lower framerate, a different muxer or "
+ "setting vsync/fps_mode to vfr\n");
}
enc_ctx->width = av_buffersink_get_w(ost->filter->filter);
@@ -3074,33 +3146,41 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame)
enc_ctx->field_order = AV_FIELD_TT;
}
- if (ost->forced_keyframes) {
- if (!strncmp(ost->forced_keyframes, "expr:", 5)) {
- ret = av_expr_parse(&ost->forced_keyframes_pexpr, ost->forced_keyframes+5,
- forced_keyframes_const_names, NULL, NULL, NULL, NULL, 0, NULL);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR,
- "Invalid force_key_frames expression '%s'\n", ost->forced_keyframes+5);
- return ret;
- }
- ost->forced_keyframes_expr_const_values[FKF_N] = 0;
- ost->forced_keyframes_expr_const_values[FKF_N_FORCED] = 0;
- ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N] = NAN;
- ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T] = NAN;
-
- // Don't parse the 'forced_keyframes' in case of 'keep-source-keyframes',
- // parse it only for static kf timings
- } else if(strncmp(ost->forced_keyframes, "source", 6)) {
- parse_forced_key_frames(ost->forced_keyframes, ost, ost->enc_ctx);
- }
- }
break;
case AVMEDIA_TYPE_SUBTITLE:
enc_ctx->time_base = AV_TIME_BASE_Q;
if (!enc_ctx->width) {
- enc_ctx->width = input_streams[ost->source_index]->st->codecpar->width;
- enc_ctx->height = input_streams[ost->source_index]->st->codecpar->height;
+ enc_ctx->width = ost->ist->par->width;
+ enc_ctx->height = ost->ist->par->height;
}
+ if (dec_ctx && dec_ctx->subtitle_header) {
+ /* ASS code assumes this buffer is null terminated so add extra byte. */
+ ost->enc_ctx->subtitle_header = av_mallocz(dec_ctx->subtitle_header_size + 1);
+ if (!ost->enc_ctx->subtitle_header)
+ return AVERROR(ENOMEM);
+ memcpy(ost->enc_ctx->subtitle_header, dec_ctx->subtitle_header,
+ dec_ctx->subtitle_header_size);
+ ost->enc_ctx->subtitle_header_size = dec_ctx->subtitle_header_size;
+ }
+ if (ist && ist->dec->type == AVMEDIA_TYPE_SUBTITLE &&
+ enc_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+ int input_props = 0, output_props = 0;
+ AVCodecDescriptor const *input_descriptor =
+ avcodec_descriptor_get(ist->dec->id);
+ AVCodecDescriptor const *output_descriptor =
+ avcodec_descriptor_get(ost->enc_ctx->codec_id);
+ if (input_descriptor)
+ input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
+ if (output_descriptor)
+ output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
+ if (input_props && output_props && input_props != output_props) {
+ av_log(ost, AV_LOG_ERROR,
+ "Subtitle encoding currently only possible from text to text "
+ "or bitmap to bitmap");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
break;
case AVMEDIA_TYPE_DATA:
break;
@@ -3109,6 +3189,12 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame)
break;
}
+ if (ost->bitexact)
+ enc_ctx->flags |= AV_CODEC_FLAG_BITEXACT;
+
+ if (ost->sq_idx_encode >= 0)
+ sq_set_tb(of->sq_encode, ost->sq_idx_encode, enc_ctx->time_base);
+
ost->mux_timebase = enc_ctx->time_base;
return 0;
@@ -3119,28 +3205,23 @@ static int init_output_stream(OutputStream *ost, AVFrame *frame,
{
int ret = 0;
- if (ost->encoding_needed) {
- const AVCodec *codec = ost->enc;
- AVCodecContext *dec = NULL;
- InputStream *ist;
+ if (ost->enc_ctx) {
+ const AVCodec *codec = ost->enc_ctx->codec;
+ InputStream *ist = ost->ist;
ret = init_output_stream_encode(ost, frame);
if (ret < 0)
return ret;
- if ((ist = get_input_stream(ost)))
- dec = ist->dec_ctx;
- if (dec && dec->subtitle_header) {
- /* ASS code assumes this buffer is null terminated so add extra byte. */
- ost->enc_ctx->subtitle_header = av_mallocz(dec->subtitle_header_size + 1);
- if (!ost->enc_ctx->subtitle_header)
- return AVERROR(ENOMEM);
- memcpy(ost->enc_ctx->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);
- ost->enc_ctx->subtitle_header_size = dec->subtitle_header_size;
- }
if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0))
av_dict_set(&ost->encoder_opts, "threads", "auto", 0);
+ if (codec->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE) {
+ ret = av_dict_set(&ost->encoder_opts, "flags", "+copy_opaque", AV_DICT_MULTIKEY);
+ if (ret < 0)
+ return ret;
+ }
+
ret = hw_device_setup_for_encode(ost);
if (ret < 0) {
snprintf(error, error_len, "Device setup failed for "
@@ -3149,24 +3230,6 @@ static int init_output_stream(OutputStream *ost, AVFrame *frame,
return ret;
}
- if (ist && ist->dec->type == AVMEDIA_TYPE_SUBTITLE && ost->enc->type == AVMEDIA_TYPE_SUBTITLE) {
- int input_props = 0, output_props = 0;
- AVCodecDescriptor const *input_descriptor =
- avcodec_descriptor_get(dec->codec_id);
- AVCodecDescriptor const *output_descriptor =
- avcodec_descriptor_get(ost->enc_ctx->codec_id);
- if (input_descriptor)
- input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
- if (output_descriptor)
- output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
- if (input_props && output_props && input_props != output_props) {
- snprintf(error, error_len,
- "Subtitle encoding currently only possible from text to text "
- "or bitmap to bitmap");
- return AVERROR_INVALIDDATA;
- }
- }
-
if ((ret = avcodec_open2(ost->enc_ctx, codec, &ost->encoder_opts)) < 0) {
if (ret == AVERROR_EXPERIMENTAL)
abort_codec_experimental(codec, 1);
@@ -3176,19 +3239,19 @@ static int init_output_stream(OutputStream *ost, AVFrame *frame,
ost->file_index, ost->index);
return ret;
}
- if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
- !(ost->enc->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE))
+ if (codec->type == AVMEDIA_TYPE_AUDIO &&
+ !(codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE))
av_buffersink_set_frame_size(ost->filter->filter,
ost->enc_ctx->frame_size);
assert_avoptions(ost->encoder_opts);
if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000 &&
ost->enc_ctx->codec_id != AV_CODEC_ID_CODEC2 /* don't complain about 700 bit/s modes */)
- av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
- " It takes bits/s as argument, not kbits/s\n");
+ av_log(ost, AV_LOG_WARNING, "The bitrate parameter is set too low."
+ " It takes bits/s as argument, not kbits/s\n");
ret = avcodec_parameters_from_context(ost->st->codecpar, ost->enc_ctx);
if (ret < 0) {
- av_log(NULL, AV_LOG_FATAL,
+ av_log(ost, AV_LOG_FATAL,
"Error initializing the output stream codec context.\n");
exit_program(1);
}
@@ -3224,7 +3287,7 @@ static int init_output_stream(OutputStream *ost, AVFrame *frame,
return AVERROR(ENOMEM);
memcpy(dst, sd->data, sd->size);
if (ist->autorotate && sd->type == AV_PKT_DATA_DISPLAYMATRIX)
- av_display_rotation_set((uint32_t *)dst, 0);
+ av_display_rotation_set((int32_t *)dst, 0);
}
}
}
@@ -3236,83 +3299,36 @@ static int init_output_stream(OutputStream *ost, AVFrame *frame,
// copy estimated duration as a hint to the muxer
if (ost->st->duration <= 0 && ist && ist->st->duration > 0)
ost->st->duration = av_rescale_q(ist->st->duration, ist->st->time_base, ost->st->time_base);
- } else if (ost->stream_copy) {
+ } else if (ost->ist) {
ret = init_output_stream_streamcopy(ost);
if (ret < 0)
return ret;
}
- /* initialize bitstream filters for the output stream
- * needs to be done here, because the codec id for streamcopy is not
- * known until now */
- ret = init_output_bsfs(ost);
- if (ret < 0)
- return ret;
-
- ost->initialized = 1;
-
- ret = of_check_init(output_files[ost->file_index]);
+ ret = of_stream_init(output_files[ost->file_index], ost);
if (ret < 0)
return ret;
return ret;
}
-static void report_new_stream(int input_index, AVPacket *pkt)
-{
- InputFile *file = input_files[input_index];
- AVStream *st = file->ctx->streams[pkt->stream_index];
-
- if (pkt->stream_index < file->nb_streams_warn)
- return;
- av_log(file->ctx, AV_LOG_WARNING,
- "New %s stream %d:%d at pos:%"PRId64" and DTS:%ss\n",
- av_get_media_type_string(st->codecpar->codec_type),
- input_index, pkt->stream_index,
- pkt->pos, av_ts2timestr(pkt->dts, &st->time_base));
- file->nb_streams_warn = pkt->stream_index + 1;
-}
-
static int transcode_init(void)
{
- int ret = 0, i, j, k;
- AVFormatContext *oc;
- OutputStream *ost;
- InputStream *ist;
+ int ret = 0;
char error[1024] = {0};
- for (i = 0; i < nb_filtergraphs; i++) {
- FilterGraph *fg = filtergraphs[i];
- for (j = 0; j < fg->nb_outputs; j++) {
- OutputFilter *ofilter = fg->outputs[j];
- if (!ofilter->ost || ofilter->ost->source_index >= 0)
- continue;
- if (fg->nb_inputs != 1)
- continue;
- for (k = nb_input_streams-1; k >= 0 ; k--)
- if (fg->inputs[0]->ist == input_streams[k])
- break;
- ofilter->ost->source_index = k;
- }
- }
-
/* init framerate emulation */
- for (i = 0; i < nb_input_files; i++) {
+ for (int i = 0; i < nb_input_files; i++) {
InputFile *ifile = input_files[i];
if (ifile->readrate || ifile->rate_emu)
- for (j = 0; j < ifile->nb_streams; j++)
- input_streams[j + ifile->ist_index]->start = av_gettime_relative();
+ for (int j = 0; j < ifile->nb_streams; j++)
+ ifile->streams[j]->start = av_gettime_relative();
}
/* init input streams */
- for (i = 0; i < nb_input_streams; i++)
- if ((ret = init_input_stream(i, error, sizeof(error))) < 0) {
- for (i = 0; i < nb_output_streams; i++) {
- ost = output_streams[i];
- avcodec_close(ost->enc_ctx);
- }
+ for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist))
+ if ((ret = init_input_stream(ist, error, sizeof(error))) < 0)
goto dump_format;
- }
/*
* initialize stream copy and subtitle/data streams.
@@ -3323,26 +3339,26 @@ static int transcode_init(void)
* to be configured with the correct audio frame size, which is only
* known after the encoder is initialized.
*/
- for (i = 0; i < nb_output_streams; i++) {
- if (!output_streams[i]->stream_copy &&
- (output_streams[i]->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
- output_streams[i]->enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO))
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+ if (ost->enc_ctx &&
+ (ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
+ ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO))
continue;
- ret = init_output_stream_wrapper(output_streams[i], NULL, 0);
+ ret = init_output_stream_wrapper(ost, NULL, 0);
if (ret < 0)
goto dump_format;
}
/* discard unused programs */
- for (i = 0; i < nb_input_files; i++) {
+ for (int i = 0; i < nb_input_files; i++) {
InputFile *ifile = input_files[i];
- for (j = 0; j < ifile->ctx->nb_programs; j++) {
+ for (int j = 0; j < ifile->ctx->nb_programs; j++) {
AVProgram *p = ifile->ctx->programs[j];
int discard = AVDISCARD_ALL;
- for (k = 0; k < p->nb_stream_indexes; k++)
- if (!input_streams[ifile->ist_index + p->stream_index[k]]->discard) {
+ for (int k = 0; k < p->nb_stream_indexes; k++)
+ if (!ifile->streams[p->stream_index[k]]->discard) {
discard = AVDISCARD_DEFAULT;
break;
}
@@ -3350,23 +3366,11 @@ static int transcode_init(void)
}
}
- /* write headers for files with no streams */
- for (i = 0; i < nb_output_files; i++) {
- oc = output_files[i]->ctx;
- if (output_files[i]->format->flags & AVFMT_NOSTREAMS && oc->nb_streams == 0) {
- ret = of_check_init(output_files[i]);
- if (ret < 0)
- goto dump_format;
- }
- }
-
dump_format:
/* dump the stream mapping */
av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
- for (i = 0; i < nb_input_streams; i++) {
- ist = input_streams[i];
-
- for (j = 0; j < ist->nb_filters; j++) {
+ for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
+ for (int j = 0; j < ist->nb_filters; j++) {
if (!filtergraph_is_simple(ist->filters[j]->graph)) {
av_log(NULL, AV_LOG_INFO, " Stream #%d:%d (%s) -> %s",
ist->file_index, ist->st->index, ist->dec ? ist->dec->name : "?",
@@ -3378,9 +3382,7 @@ static int transcode_init(void)
}
}
- for (i = 0; i < nb_output_streams; i++) {
- ost = output_streams[i];
-
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
if (ost->attachment_filename) {
/* an attached file */
av_log(NULL, AV_LOG_INFO, " File %s -> Stream #%d:%d\n",
@@ -3395,24 +3397,18 @@ static int transcode_init(void)
av_log(NULL, AV_LOG_INFO, " (graph %d)", ost->filter->graph->index);
av_log(NULL, AV_LOG_INFO, " -> Stream #%d:%d (%s)\n", ost->file_index,
- ost->index, ost->enc ? ost->enc->name : "?");
+ ost->index, ost->enc_ctx->codec->name);
continue;
}
av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d",
- input_streams[ost->source_index]->file_index,
- input_streams[ost->source_index]->st->index,
+ ost->ist->file_index,
+ ost->ist->st->index,
ost->file_index,
ost->index);
- if (ost->sync_ist != input_streams[ost->source_index])
- av_log(NULL, AV_LOG_INFO, " [sync #%d:%d]",
- ost->sync_ist->file_index,
- ost->sync_ist->st->index);
- if (ost->stream_copy)
- av_log(NULL, AV_LOG_INFO, " (copy)");
- else {
- const AVCodec *in_codec = input_streams[ost->source_index]->dec;
- const AVCodec *out_codec = ost->enc;
+ if (ost->enc_ctx) {
+ const AVCodec *in_codec = ost->ist->dec;
+ const AVCodec *out_codec = ost->enc_ctx->codec;
const char *decoder_name = "?";
const char *in_codec_name = "?";
const char *encoder_name = "?";
@@ -3440,7 +3436,8 @@ static int transcode_init(void)
av_log(NULL, AV_LOG_INFO, " (%s (%s) -> %s (%s))",
in_codec_name, decoder_name,
out_codec_name, encoder_name);
- }
+ } else
+ av_log(NULL, AV_LOG_INFO, " (copy)");
av_log(NULL, AV_LOG_INFO, "\n");
}
@@ -3457,22 +3454,9 @@ static int transcode_init(void)
/* Return 1 if there remain streams where more output is wanted, 0 otherwise. */
static int need_output(void)
{
- int i;
-
- for (i = 0; i < nb_output_streams; i++) {
- OutputStream *ost = output_streams[i];
- OutputFile *of = output_files[ost->file_index];
- AVFormatContext *os = output_files[ost->file_index]->ctx;
-
- if (ost->finished ||
- (os->pb && avio_tell(os->pb) >= of->limit_filesize))
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+ if (ost->finished)
continue;
- if (ost->frame_number >= ost->max_frames) {
- int j;
- for (j = 0; j < of->ctx->nb_streams; j++)
- close_output_stream(output_streams[of->ost_index + j]);
- continue;
- }
return 1;
}
@@ -3487,19 +3471,22 @@ static int need_output(void)
*/
static OutputStream *choose_output(void)
{
- int i;
int64_t opts_min = INT64_MAX;
OutputStream *ost_min = NULL;
- for (i = 0; i < nb_output_streams; i++) {
- OutputStream *ost = output_streams[i];
- int64_t opts = ost->last_mux_dts == AV_NOPTS_VALUE ? INT64_MIN :
- av_rescale_q(ost->last_mux_dts, ost->st->time_base,
- AV_TIME_BASE_Q);
- if (ost->last_mux_dts == AV_NOPTS_VALUE)
- av_log(NULL, AV_LOG_DEBUG,
- "cur_dts is invalid st:%d (%d) [init:%d i_done:%d finish:%d] (this is harmless if it occurs once at the start per stream)\n",
- ost->st->index, ost->st->id, ost->initialized, ost->inputs_done, ost->finished);
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+ int64_t opts;
+
+ if (ost->filter && ost->last_filter_pts != AV_NOPTS_VALUE) {
+ opts = ost->last_filter_pts;
+ } else {
+ opts = ost->last_mux_dts == AV_NOPTS_VALUE ?
+ INT64_MIN : ost->last_mux_dts;
+ if (ost->last_mux_dts == AV_NOPTS_VALUE)
+ av_log(ost, AV_LOG_DEBUG,
+ "cur_dts is invalid [init:%d i_done:%d finish:%d] (this is harmless if it occurs once at the start per stream)\n",
+ ost->initialized, ost->inputs_done, ost->finished);
+ }
if (!ost->initialized && !ost->inputs_done)
return ost->unavailable ? NULL : ost;
@@ -3543,15 +3530,6 @@ static int check_keyboard_interaction(int64_t cur_time)
if (key == '+') av_log_set_level(av_log_get_level()+10);
if (key == '-') av_log_set_level(av_log_get_level()-10);
if (key == 's') qp_hist ^= 1;
- if (key == 'h'){
- if (do_hex_dump){
- do_hex_dump = do_pkt_dump = 0;
- } else if(do_pkt_dump){
- do_hex_dump = 1;
- } else
- do_pkt_dump = 1;
- av_log_set_level(AV_LOG_DEBUG);
- }
if (key == 'c' || key == 'C'){
char buf[4096], target[64], command[256], arg[256] = {0};
double time;
@@ -3595,7 +3573,11 @@ static int check_keyboard_interaction(int64_t cur_time)
if (key == 'd' || key == 'D'){
int debug=0;
if(key == 'D') {
- debug = input_streams[0]->dec_ctx->debug << 1;
+ InputStream *ist = ist_iter(NULL);
+
+ if (ist)
+ debug = ist->dec_ctx->debug << 1;
+
if(!debug) debug = 1;
while (debug & FF_DEBUG_DCT_COEFF) //unsupported, would just crash
debug += debug;
@@ -3613,12 +3595,11 @@ static int check_keyboard_interaction(int64_t cur_time)
if (k <= 0 || sscanf(buf, "%d", &debug)!=1)
fprintf(stderr,"error parsing debug value\n");
}
- for(i=0;idec_ctx->debug = debug;
- }
- for(i=0;ienc_ctx->debug = debug;
+ for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist))
+ ist->dec_ctx->debug = debug;
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+ if (ost->enc_ctx)
+ ost->enc_ctx->debug = debug;
}
if(debug) av_log_set_level(AV_LOG_DEBUG);
fprintf(stderr,"debug=%d\n", debug);
@@ -3639,160 +3620,10 @@ static int check_keyboard_interaction(int64_t cur_time)
return 0;
}
-#if HAVE_THREADS
-static void *input_thread(void *arg)
-{
- InputFile *f = arg;
- AVPacket *pkt = f->pkt, *queue_pkt;
- unsigned flags = f->non_blocking ? AV_THREAD_MESSAGE_NONBLOCK : 0;
- int ret = 0;
-
- while (1) {
- ret = av_read_frame(f->ctx, pkt);
-
- if (ret == AVERROR(EAGAIN)) {
- av_usleep(10000);
- continue;
- }
- if (ret < 0) {
- av_thread_message_queue_set_err_recv(f->in_thread_queue, ret);
- break;
- }
- queue_pkt = av_packet_alloc();
- if (!queue_pkt) {
- av_packet_unref(pkt);
- av_thread_message_queue_set_err_recv(f->in_thread_queue, AVERROR(ENOMEM));
- break;
- }
- av_packet_move_ref(queue_pkt, pkt);
- ret = av_thread_message_queue_send(f->in_thread_queue, &queue_pkt, flags);
- if (flags && ret == AVERROR(EAGAIN)) {
- flags = 0;
- ret = av_thread_message_queue_send(f->in_thread_queue, &queue_pkt, flags);
- av_log(f->ctx, AV_LOG_WARNING,
- "Thread message queue blocking; consider raising the "
- "thread_queue_size option (current value: %d)\n",
- f->thread_queue_size);
- }
- if (ret < 0) {
- if (ret != AVERROR_EOF)
- av_log(f->ctx, AV_LOG_ERROR,
- "Unable to send packet to main thread: %s\n",
- av_err2str(ret));
- av_packet_free(&queue_pkt);
- av_thread_message_queue_set_err_recv(f->in_thread_queue, ret);
- break;
- }
- }
-
- return NULL;
-}
-
-static void free_input_thread(int i)
-{
- InputFile *f = input_files[i];
- AVPacket *pkt;
-
- if (!f || !f->in_thread_queue)
- return;
- av_thread_message_queue_set_err_send(f->in_thread_queue, AVERROR_EOF);
- while (av_thread_message_queue_recv(f->in_thread_queue, &pkt, 0) >= 0)
- av_packet_free(&pkt);
-
- pthread_join(f->thread, NULL);
- f->joined = 1;
- av_thread_message_queue_free(&f->in_thread_queue);
-}
-
-static void free_input_threads(void)
-{
- int i;
-
- for (i = 0; i < nb_input_files; i++)
- free_input_thread(i);
-}
-
-static int init_input_thread(int i)
-{
- int ret;
- InputFile *f = input_files[i];
-
- if (f->thread_queue_size < 0)
- f->thread_queue_size = (nb_input_files > 1 ? 8 : 0);
- if (!f->thread_queue_size)
- return 0;
-
- if (f->ctx->pb ? !f->ctx->pb->seekable :
- strcmp(f->ctx->iformat->name, "lavfi"))
- f->non_blocking = 1;
- ret = av_thread_message_queue_alloc(&f->in_thread_queue,
- f->thread_queue_size, sizeof(f->pkt));
- if (ret < 0)
- return ret;
-
- if ((ret = pthread_create(&f->thread, NULL, input_thread, f))) {
- av_log(NULL, AV_LOG_ERROR, "pthread_create failed: %s. Try to increase `ulimit -v` or decrease `ulimit -s`.\n", strerror(ret));
- av_thread_message_queue_free(&f->in_thread_queue);
- return AVERROR(ret);
- }
-
- return 0;
-}
-
-static int init_input_threads(void)
-{
- int i, ret;
-
- for (i = 0; i < nb_input_files; i++) {
- ret = init_input_thread(i);
- if (ret < 0)
- return ret;
- }
- return 0;
-}
-
-static int get_input_packet_mt(InputFile *f, AVPacket **pkt)
-{
- return av_thread_message_queue_recv(f->in_thread_queue, pkt,
- f->non_blocking ?
- AV_THREAD_MESSAGE_NONBLOCK : 0);
-}
-#endif
-
-static int get_input_packet(InputFile *f, AVPacket **pkt)
-{
- if (f->readrate || f->rate_emu) {
- int i;
- int64_t file_start = copy_ts * (
- (f->ctx->start_time != AV_NOPTS_VALUE ? f->ctx->start_time * !start_at_zero : 0) +
- (f->start_time != AV_NOPTS_VALUE ? f->start_time : 0)
- );
- float scale = f->rate_emu ? 1.0 : f->readrate;
- for (i = 0; i < f->nb_streams; i++) {
- InputStream *ist = input_streams[f->ist_index + i];
- int64_t stream_ts_offset, pts, now;
- if (!ist->nb_packets || (ist->decoding_needed && !ist->got_output)) continue;
- stream_ts_offset = FFMAX(ist->first_dts != AV_NOPTS_VALUE ? ist->first_dts : 0, file_start);
- pts = av_rescale(ist->dts, 1000000, AV_TIME_BASE);
- now = (av_gettime_relative() - ist->start) * scale + stream_ts_offset;
- if (pts > now)
- return AVERROR(EAGAIN);
- }
- }
-
-#if HAVE_THREADS
- if (f->thread_queue_size)
- return get_input_packet_mt(f, pkt);
-#endif
- *pkt = f->pkt;
- return av_read_frame(f->ctx, *pkt);
-}
-
static int got_eagain(void)
{
- int i;
- for (i = 0; i < nb_output_streams; i++)
- if (output_streams[i]->unavailable)
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost))
+ if (ost->unavailable)
return 1;
return 0;
}
@@ -3802,87 +3633,123 @@ static void reset_eagain(void)
int i;
for (i = 0; i < nb_input_files; i++)
input_files[i]->eagain = 0;
- for (i = 0; i < nb_output_streams; i++)
- output_streams[i]->unavailable = 0;
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost))
+ ost->unavailable = 0;
}
-// set duration to max(tmp, duration) in a proper time base and return duration's time_base
-static AVRational duration_max(int64_t tmp, int64_t *duration, AVRational tmp_time_base,
- AVRational time_base)
+static void decode_flush(InputFile *ifile)
{
- int ret;
+ for (int i = 0; i < ifile->nb_streams; i++) {
+ InputStream *ist = ifile->streams[i];
+ int ret;
- if (!*duration) {
- *duration = tmp;
- return tmp_time_base;
+ if (!ist->processing_needed)
+ continue;
+
+ do {
+ ret = process_input_packet(ist, NULL, 1);
+ } while (ret > 0);
+
+ if (ist->decoding_needed) {
+ /* report last frame duration to the demuxer thread */
+ if (ist->par->codec_type == AVMEDIA_TYPE_AUDIO) {
+ LastFrameDuration dur;
+
+ dur.stream_idx = i;
+ 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);
+ }
+
+ avcodec_flush_buffers(ist->dec_ctx);
+ }
}
-
- ret = av_compare_ts(*duration, time_base, tmp, tmp_time_base);
- if (ret < 0) {
- *duration = tmp;
- return tmp_time_base;
- }
-
- return time_base;
}
-static int seek_to_start(InputFile *ifile, AVFormatContext *is)
+static void ts_discontinuity_detect(InputFile *ifile, InputStream *ist,
+ AVPacket *pkt)
{
- InputStream *ist;
- AVCodecContext *avctx;
- int i, ret, has_audio = 0;
- int64_t duration = 0;
+ const int fmt_is_discont = ifile->ctx->iformat->flags & AVFMT_TS_DISCONT;
+ int disable_discontinuity_correction = copy_ts;
+ int64_t pkt_dts = av_rescale_q_rnd(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q,
+ AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
- ret = avformat_seek_file(is, -1, INT64_MIN, is->start_time, is->start_time, 0);
- if (ret < 0)
- return ret;
-
- for (i = 0; i < ifile->nb_streams; i++) {
- ist = input_streams[ifile->ist_index + i];
- avctx = ist->dec_ctx;
-
- /* 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 */
- if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && ist->nb_samples)
- has_audio = 1;
+ if (copy_ts && ist->next_dts != AV_NOPTS_VALUE &&
+ fmt_is_discont && ist->st->pts_wrap_bits < 60) {
+ int64_t wrap_dts = av_rescale_q_rnd(pkt->dts + (1LL<st->pts_wrap_bits),
+ ist->st->time_base, AV_TIME_BASE_Q,
+ AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
+ if (FFABS(wrap_dts - ist->next_dts) < FFABS(pkt_dts - ist->next_dts)/10)
+ disable_discontinuity_correction = 0;
}
- for (i = 0; i < ifile->nb_streams; i++) {
- ist = input_streams[ifile->ist_index + i];
- avctx = ist->dec_ctx;
-
- if (has_audio) {
- if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && ist->nb_samples) {
- AVRational sample_rate = {1, avctx->sample_rate};
-
- duration = av_rescale_q(ist->nb_samples, sample_rate, ist->st->time_base);
- } else {
- continue;
+ if (ist->next_dts != AV_NOPTS_VALUE && !disable_discontinuity_correction) {
+ int64_t delta = pkt_dts - ist->next_dts;
+ if (fmt_is_discont) {
+ if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE ||
+ pkt_dts + AV_TIME_BASE/10 < FFMAX(ist->pts, ist->dts)) {
+ ifile->ts_offset_discont -= delta;
+ av_log(NULL, AV_LOG_DEBUG,
+ "timestamp discontinuity for stream #%d:%d "
+ "(id=%d, type=%s): %"PRId64", new offset= %"PRId64"\n",
+ ist->file_index, ist->st->index, ist->st->id,
+ av_get_media_type_string(ist->par->codec_type),
+ delta, ifile->ts_offset_discont);
+ pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
+ if (pkt->pts != AV_NOPTS_VALUE)
+ pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
}
} else {
- 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;
+ if (FFABS(delta) > 1LL * dts_error_threshold * AV_TIME_BASE) {
+ av_log(NULL, AV_LOG_WARNING, "DTS %"PRId64", next:%"PRId64" st:%d invalid dropping\n", pkt->dts, ist->next_dts, pkt->stream_index);
+ pkt->dts = AV_NOPTS_VALUE;
+ }
+ if (pkt->pts != AV_NOPTS_VALUE){
+ int64_t pkt_pts = av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q);
+ delta = pkt_pts - ist->next_dts;
+ if (FFABS(delta) > 1LL * dts_error_threshold * AV_TIME_BASE) {
+ av_log(NULL, AV_LOG_WARNING, "PTS %"PRId64", next:%"PRId64" invalid dropping st:%d\n", pkt->pts, ist->next_dts, pkt->stream_index);
+ pkt->pts = AV_NOPTS_VALUE;
+ }
}
}
- if (!ifile->duration)
- ifile->time_base = ist->st->time_base;
- /* the total duration of the stream, max_pts - min_pts is
- * the duration of the stream without the last frame */
- if (ist->max_pts > ist->min_pts && ist->max_pts - (uint64_t)ist->min_pts < INT64_MAX - duration)
- duration += ist->max_pts - ist->min_pts;
- ifile->time_base = duration_max(duration, &ifile->duration, ist->st->time_base,
- ifile->time_base);
+ } else if (ist->next_dts == AV_NOPTS_VALUE && !copy_ts &&
+ fmt_is_discont && ifile->last_ts != AV_NOPTS_VALUE) {
+ int64_t delta = pkt_dts - ifile->last_ts;
+ if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE) {
+ ifile->ts_offset_discont -= delta;
+ av_log(NULL, AV_LOG_DEBUG,
+ "Inter stream timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",
+ delta, ifile->ts_offset_discont);
+ pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
+ if (pkt->pts != AV_NOPTS_VALUE)
+ pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
+ }
}
- if (ifile->loop > 0)
- ifile->loop--;
+ ifile->last_ts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
+}
- return ret;
+static void ts_discontinuity_process(InputFile *ifile, InputStream *ist,
+ AVPacket *pkt)
+{
+ int64_t offset = av_rescale_q(ifile->ts_offset_discont, AV_TIME_BASE_Q,
+ ist->st->time_base);
+
+ // apply previously-detected timestamp-discontinuity offset
+ // (to all streams, not just audio/video)
+ if (pkt->dts != AV_NOPTS_VALUE)
+ pkt->dts += offset;
+ if (pkt->pts != AV_NOPTS_VALUE)
+ pkt->pts += offset;
+
+ // detect timestamp discontinuities for audio/video
+ if ((ist->par->codec_type == AVMEDIA_TYPE_VIDEO ||
+ ist->par->codec_type == AVMEDIA_TYPE_AUDIO) &&
+ pkt->dts != AV_NOPTS_VALUE)
+ ts_discontinuity_detect(ifile, ist, pkt);
}
/*
@@ -3898,48 +3765,19 @@ static int process_input(int file_index)
AVFormatContext *is;
InputStream *ist;
AVPacket *pkt;
- int ret, thread_ret, i, j;
- int64_t duration;
- int64_t pkt_dts;
- int disable_discontinuity_correction = copy_ts;
+ int ret, i;
is = ifile->ctx;
- ret = get_input_packet(ifile, &pkt);
+ ret = ifile_get_packet(ifile, &pkt);
if (ret == AVERROR(EAGAIN)) {
ifile->eagain = 1;
return ret;
}
- if (ret < 0 && ifile->loop) {
- AVCodecContext *avctx;
- for (i = 0; i < ifile->nb_streams; i++) {
- ist = input_streams[ifile->ist_index + i];
- avctx = ist->dec_ctx;
- if (ist->processing_needed) {
- ret = process_input_packet(ist, NULL, 1);
- if (ret>0)
- return 0;
- if (ist->decoding_needed)
- avcodec_flush_buffers(avctx);
- }
- }
-#if HAVE_THREADS
- free_input_thread(file_index);
-#endif
- ret = seek_to_start(ifile, is);
-#if HAVE_THREADS
- thread_ret = init_input_thread(file_index);
- if (thread_ret < 0)
- return thread_ret;
-#endif
- if (ret < 0)
- av_log(NULL, AV_LOG_WARNING, "Seek to start failed.\n");
- else
- ret = get_input_packet(ifile, &pkt);
- if (ret == AVERROR(EAGAIN)) {
- ifile->eagain = 1;
- return ret;
- }
+ if (ret == 1) {
+ /* the input file is looped: flush the decoders */
+ decode_flush(ifile);
+ return AVERROR(EAGAIN);
}
if (ret < 0) {
if (ret != AVERROR_EOF) {
@@ -3949,7 +3787,7 @@ static int process_input(int file_index)
}
for (i = 0; i < ifile->nb_streams; i++) {
- ist = input_streams[ifile->ist_index + i];
+ ist = ifile->streams[i];
if (ist->processing_needed) {
ret = process_input_packet(ist, NULL, 0);
if (ret>0)
@@ -3957,12 +3795,12 @@ static int process_input(int file_index)
}
/* mark all outputs that don't go through lavfi as finished */
- for (j = 0; j < nb_output_streams; j++) {
- OutputStream *ost = output_streams[j];
-
- if (ost->source_index == ifile->ist_index + i &&
- (ost->stream_copy || ost->enc->type == AVMEDIA_TYPE_SUBTITLE))
- finish_output_stream(ost);
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+ if (ost->ist == ist &&
+ (!ost->enc_ctx || ost->enc_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
+ OutputFile *of = output_files[ost->file_index];
+ of_output_packet(of, ost->pkt, ost, 1);
+ }
}
}
@@ -3972,18 +3810,7 @@ static int process_input(int file_index)
reset_eagain();
- if (do_pkt_dump) {
- av_pkt_dump_log2(NULL, AV_LOG_INFO, pkt, do_hex_dump,
- is->streams[pkt->stream_index]);
- }
- /* the following test is needed in case new streams appear
- dynamically in stream : we ignore them */
- if (pkt->stream_index >= ifile->nb_streams) {
- report_new_stream(file_index, pkt);
- goto discard_packet;
- }
-
- ist = input_streams[ifile->ist_index + pkt->stream_index];
+ ist = ifile->streams[pkt->stream_index];
ist->data_size += pkt->size;
ist->nb_packets++;
@@ -3991,61 +3818,6 @@ static int process_input(int file_index)
if (ist->discard)
goto discard_packet;
- if (pkt->flags & AV_PKT_FLAG_CORRUPT) {
- av_log(NULL, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING,
- "%s: corrupt input packet in stream %d\n", is->url, pkt->stream_index);
- if (exit_on_error)
- exit_program(1);
- }
-
- if (debug_ts) {
- av_log(NULL, AV_LOG_INFO, "demuxer -> ist_index:%d type:%s "
- "next_dts:%s next_dts_time:%s next_pts:%s next_pts_time:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s off:%s off_time:%s\n",
- ifile->ist_index + pkt->stream_index, av_get_media_type_string(ist->dec_ctx->codec_type),
- av_ts2str(ist->next_dts), av_ts2timestr(ist->next_dts, &AV_TIME_BASE_Q),
- av_ts2str(ist->next_pts), av_ts2timestr(ist->next_pts, &AV_TIME_BASE_Q),
- av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ist->st->time_base),
- av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ist->st->time_base),
- av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ist->st->time_base),
- av_ts2str(input_files[ist->file_index]->ts_offset),
- av_ts2timestr(input_files[ist->file_index]->ts_offset, &AV_TIME_BASE_Q));
- }
-
- if(!ist->wrap_correction_done && is->start_time != AV_NOPTS_VALUE && ist->st->pts_wrap_bits < 64){
- int64_t stime, stime2;
- // Correcting starttime based on the enabled streams
- // FIXME this ideally should be done before the first use of starttime but we do not know which are the enabled streams at that point.
- // so we instead do it here as part of discontinuity handling
- if ( ist->next_dts == AV_NOPTS_VALUE
- && ifile->ts_offset == -is->start_time
- && (is->iformat->flags & AVFMT_TS_DISCONT)) {
- int64_t new_start_time = INT64_MAX;
- for (i=0; inb_streams; i++) {
- AVStream *st = is->streams[i];
- if(st->discard == AVDISCARD_ALL || st->start_time == AV_NOPTS_VALUE)
- continue;
- new_start_time = FFMIN(new_start_time, av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q));
- }
- if (new_start_time > is->start_time) {
- av_log(is, AV_LOG_VERBOSE, "Correcting start time by %"PRId64"\n", new_start_time - is->start_time);
- ifile->ts_offset = -new_start_time;
- }
- }
-
- stime = av_rescale_q(is->start_time, AV_TIME_BASE_Q, ist->st->time_base);
- stime2= stime + (1ULL<st->pts_wrap_bits);
- ist->wrap_correction_done = 1;
-
- if(stime2 > stime && pkt->dts != AV_NOPTS_VALUE && pkt->dts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) {
- pkt->dts -= 1ULL<st->pts_wrap_bits;
- ist->wrap_correction_done = 0;
- }
- if(stime2 > stime && pkt->pts != AV_NOPTS_VALUE && pkt->pts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) {
- pkt->pts -= 1ULL<st->pts_wrap_bits;
- ist->wrap_correction_done = 0;
- }
- }
-
/* add the stream-global side data to the first packet */
if (ist->nb_packets == 1) {
for (i = 0; i < ist->st->nb_side_data; i++) {
@@ -4060,105 +3832,19 @@ static int process_input(int file_index)
dst_data = av_packet_new_side_data(pkt, src_sd->type, src_sd->size);
if (!dst_data)
- exit_program(1);
+ report_and_exit(AVERROR(ENOMEM));
memcpy(dst_data, src_sd->data, src_sd->size);
}
}
- if (pkt->dts != AV_NOPTS_VALUE)
- pkt->dts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
- if (pkt->pts != AV_NOPTS_VALUE)
- pkt->pts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
-
- if (pkt->pts != AV_NOPTS_VALUE)
- pkt->pts *= ist->ts_scale;
- if (pkt->dts != AV_NOPTS_VALUE)
- pkt->dts *= ist->ts_scale;
-
- pkt_dts = av_rescale_q_rnd(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
- if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
- ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
- pkt_dts != AV_NOPTS_VALUE && ist->next_dts == AV_NOPTS_VALUE && !copy_ts
- && (is->iformat->flags & AVFMT_TS_DISCONT) && ifile->last_ts != AV_NOPTS_VALUE) {
- int64_t delta = pkt_dts - ifile->last_ts;
- if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
- delta > 1LL*dts_delta_threshold*AV_TIME_BASE){
- ifile->ts_offset -= delta;
- av_log(NULL, AV_LOG_DEBUG,
- "Inter stream timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",
- delta, ifile->ts_offset);
- pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
- if (pkt->pts != AV_NOPTS_VALUE)
- pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
- }
- }
-
- duration = av_rescale_q(ifile->duration, ifile->time_base, ist->st->time_base);
- if (pkt->pts != AV_NOPTS_VALUE) {
- pkt->pts += duration;
- ist->max_pts = FFMAX(pkt->pts, ist->max_pts);
- ist->min_pts = FFMIN(pkt->pts, ist->min_pts);
- }
-
- if (pkt->dts != AV_NOPTS_VALUE)
- pkt->dts += duration;
-
- pkt_dts = av_rescale_q_rnd(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
-
- if (copy_ts && pkt_dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&
- (is->iformat->flags & AVFMT_TS_DISCONT) && ist->st->pts_wrap_bits < 60) {
- int64_t wrap_dts = av_rescale_q_rnd(pkt->dts + (1LL<st->pts_wrap_bits),
- ist->st->time_base, AV_TIME_BASE_Q,
- AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
- if (FFABS(wrap_dts - ist->next_dts) < FFABS(pkt_dts - ist->next_dts)/10)
- disable_discontinuity_correction = 0;
- }
-
- if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
- ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
- pkt_dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&
- !disable_discontinuity_correction) {
- int64_t delta = pkt_dts - ist->next_dts;
- if (is->iformat->flags & AVFMT_TS_DISCONT) {
- if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
- delta > 1LL*dts_delta_threshold*AV_TIME_BASE ||
- pkt_dts + AV_TIME_BASE/10 < FFMAX(ist->pts, ist->dts)) {
- ifile->ts_offset -= delta;
- av_log(NULL, AV_LOG_DEBUG,
- "timestamp discontinuity for stream #%d:%d "
- "(id=%d, type=%s): %"PRId64", new offset= %"PRId64"\n",
- ist->file_index, ist->st->index, ist->st->id,
- av_get_media_type_string(ist->dec_ctx->codec_type),
- delta, ifile->ts_offset);
- pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
- if (pkt->pts != AV_NOPTS_VALUE)
- pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
- }
- } else {
- if ( delta < -1LL*dts_error_threshold*AV_TIME_BASE ||
- delta > 1LL*dts_error_threshold*AV_TIME_BASE) {
- av_log(NULL, AV_LOG_WARNING, "DTS %"PRId64", next:%"PRId64" st:%d invalid dropping\n", pkt->dts, ist->next_dts, pkt->stream_index);
- pkt->dts = AV_NOPTS_VALUE;
- }
- if (pkt->pts != AV_NOPTS_VALUE){
- int64_t pkt_pts = av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q);
- delta = pkt_pts - ist->next_dts;
- if ( delta < -1LL*dts_error_threshold*AV_TIME_BASE ||
- delta > 1LL*dts_error_threshold*AV_TIME_BASE) {
- av_log(NULL, AV_LOG_WARNING, "PTS %"PRId64", next:%"PRId64" invalid dropping st:%d\n", pkt->pts, ist->next_dts, pkt->stream_index);
- pkt->pts = AV_NOPTS_VALUE;
- }
- }
- }
- }
-
- if (pkt->dts != AV_NOPTS_VALUE)
- ifile->last_ts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
+ // detect and try to correct for timestamp discontinuities
+ ts_discontinuity_process(ifile, ist, pkt);
if (debug_ts) {
- av_log(NULL, AV_LOG_INFO, "demuxer+ffmpeg -> ist_index:%d type:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s off:%s off_time:%s\n",
- ifile->ist_index + pkt->stream_index, av_get_media_type_string(ist->dec_ctx->codec_type),
+ av_log(NULL, AV_LOG_INFO, "demuxer+ffmpeg -> ist_index:%d:%d type:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s off:%s off_time:%s\n",
+ ifile->index, pkt->stream_index,
+ av_get_media_type_string(ist->par->codec_type),
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ist->st->time_base),
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ist->st->time_base),
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ist->st->time_base),
@@ -4171,12 +3857,7 @@ static int process_input(int file_index)
process_input_packet(ist, pkt, 0);
discard_packet:
-#if HAVE_THREADS
- if (ifile->thread_queue_size)
- av_packet_free(&pkt);
- else
-#endif
- av_packet_unref(pkt);
+ av_packet_free(&pkt);
return 0;
}
@@ -4304,8 +3985,8 @@ static int transcode_step(void)
return 0;
}
} else {
- av_assert0(ost->source_index >= 0);
- ist = input_streams[ost->source_index];
+ ist = ost->ist;
+ av_assert0(ist);
}
ret = process_input(ist->file_index);
@@ -4327,8 +4008,6 @@ static int transcode_step(void)
static int transcode(void)
{
int ret, i;
- AVFormatContext *os;
- OutputStream *ost;
InputStream *ist;
int64_t timer_start;
int64_t total_packets_written = 0;
@@ -4343,11 +4022,6 @@ static int transcode(void)
timer_start = av_gettime_relative();
-#if HAVE_THREADS
- if ((ret = init_input_threads()) < 0)
- goto fail;
-#endif
-
while (!received_sigterm) {
int64_t cur_time= av_gettime_relative();
@@ -4371,13 +4045,9 @@ static int transcode(void)
/* dump report by using the output first video and audio streams */
print_report(0, timer_start, cur_time);
}
-#if HAVE_THREADS
- free_input_threads();
-#endif
/* at the end of stream, we must flush the decoder buffers */
- for (i = 0; i < nb_input_streams; i++) {
- ist = input_streams[i];
+ for (ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
if (!input_files[ist->file_index]->eof_reached) {
process_input_packet(ist, NULL, 0);
}
@@ -4396,27 +4066,13 @@ static int transcode(void)
/* dump report by using the first video and audio streams */
print_report(1, timer_start, av_gettime_relative());
- /* close the output files */
- for (i = 0; i < nb_output_files; i++) {
- os = output_files[i]->ctx;
- if (os && os->oformat && !(os->oformat->flags & AVFMT_NOFILE)) {
- if ((ret = avio_closep(&os->pb)) < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error closing file %s: %s\n", os->url, av_err2str(ret));
- if (exit_on_error)
- exit_program(1);
- }
- }
- }
-
/* close each encoder */
- for (i = 0; i < nb_output_streams; i++) {
- ost = output_streams[i];
- if (ost->encoding_needed) {
- av_freep(&ost->enc_ctx->stats_in);
- }
- total_packets_written += ost->packets_written;
- if (!ost->packets_written && (abort_on_flags & ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM)) {
- av_log(NULL, AV_LOG_FATAL, "Empty output on stream %d.\n", i);
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+ uint64_t packets_written;
+ packets_written = atomic_load(&ost->packets_written);
+ total_packets_written += packets_written;
+ if (!packets_written && (abort_on_flags & ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM)) {
+ av_log(ost, AV_LOG_FATAL, "Empty output\n");
exit_program(1);
}
}
@@ -4426,46 +4082,12 @@ static int transcode(void)
exit_program(1);
}
- /* close each decoder */
- for (i = 0; i < nb_input_streams; i++) {
- ist = input_streams[i];
- if (ist->decoding_needed) {
- avcodec_close(ist->dec_ctx);
- if (ist->hwaccel_uninit)
- ist->hwaccel_uninit(ist->dec_ctx);
- }
- }
-
hw_device_free_all();
/* finished ! */
ret = 0;
fail:
-#if HAVE_THREADS
- free_input_threads();
-#endif
-
- if (output_streams) {
- for (i = 0; i < nb_output_streams; i++) {
- ost = output_streams[i];
- if (ost) {
- if (ost->logfile) {
- if (fclose(ost->logfile))
- av_log(NULL, AV_LOG_ERROR,
- "Error closing logfile, loss of information possible: %s\n",
- av_err2str(AVERROR(errno)));
- ost->logfile = NULL;
- }
- av_freep(&ost->forced_kf_pts);
- av_freep(&ost->apad);
- av_freep(&ost->disposition);
- av_dict_free(&ost->encoder_opts);
- av_dict_free(&ost->sws_dict);
- av_dict_free(&ost->swr_opts);
- }
- }
- }
return ret;
}
@@ -4515,7 +4137,7 @@ static int64_t getmaxrss(void)
int main(int argc, char **argv)
{
- int i, ret;
+ int ret;
BenchmarkTimeStamps ti;
init_dynload();
@@ -4551,11 +4173,6 @@ int main(int argc, char **argv)
exit_program(1);
}
- for (i = 0; i < nb_output_files; i++) {
- if (strcmp(output_files[i]->format->name, "rtp"))
- want_sdp = 0;
- }
-
current_time = ti = get_benchmark_time_stamps();
if (transcode() < 0)
exit_program(1);
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 391a35cf5..f1412f644 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -21,11 +21,13 @@
#include "config.h"
+#include
#include
#include
#include
#include "cmdutils.h"
+#include "sync_queue.h"
#include "libavformat/avformat.h"
#include "libavformat/avio.h"
@@ -47,6 +49,12 @@
#include "libswresample/swresample.h"
+// deprecated features
+#define FFMPEG_OPT_PSNR 1
+#define FFMPEG_OPT_MAP_CHANNEL 1
+#define FFMPEG_OPT_MAP_SYNC 1
+#define FFMPEG_ROTATION_METADATA 1
+
enum VideoSyncMethod {
VSYNC_AUTO = -1,
VSYNC_PASSTHROUGH,
@@ -75,15 +83,15 @@ typedef struct StreamMap {
int disabled; /* 1 is this mapping is disabled by a negative map */
int file_index;
int stream_index;
- int sync_file_index;
- int sync_stream_index;
char *linklabel; /* name of an output link, for mapping lavfi outputs */
} StreamMap;
+#if FFMPEG_OPT_MAP_CHANNEL
typedef struct {
int file_idx, stream_idx, channel_idx; // input
int ofile_idx, ostream_idx; // output
} AudioChannelMap;
+#endif
typedef struct OptionsContext {
OptionGroup *g;
@@ -119,6 +127,7 @@ typedef struct OptionsContext {
int accurate_seek;
int thread_queue_size;
int input_sync_ref;
+ int find_stream_info;
SpecifierOpt *ts_scale;
int nb_ts_scale;
@@ -136,11 +145,10 @@ typedef struct OptionsContext {
/* output options */
StreamMap *stream_maps;
int nb_stream_maps;
+#if FFMPEG_OPT_MAP_CHANNEL
AudioChannelMap *audio_channel_maps; /* one info entry per -map_channel */
int nb_audio_channel_maps; /* number of (valid) -map_channel settings */
- int metadata_global_manual;
- int metadata_streams_manual;
- int metadata_chapters_manual;
+#endif
const char **attachments;
int nb_attachments;
@@ -148,9 +156,10 @@ typedef struct OptionsContext {
int64_t recording_time;
int64_t stop_time;
- uint64_t limit_filesize;
+ int64_t limit_filesize;
float mux_preload;
float mux_max_delay;
+ float shortest_buf_duration;
int shortest;
int bitexact;
@@ -183,6 +192,12 @@ typedef struct OptionsContext {
int nb_force_fps;
SpecifierOpt *frame_aspect_ratios;
int nb_frame_aspect_ratios;
+ SpecifierOpt *display_rotations;
+ int nb_display_rotations;
+ SpecifierOpt *display_hflips;
+ int nb_display_hflips;
+ SpecifierOpt *display_vflips;
+ int nb_display_vflips;
SpecifierOpt *rc_overrides;
int nb_rc_overrides;
SpecifierOpt *intra_matrices;
@@ -209,6 +224,8 @@ typedef struct OptionsContext {
int nb_reinit_filters;
SpecifierOpt *fix_sub_duration;
int nb_fix_sub_duration;
+ SpecifierOpt *fix_sub_duration_heartbeat;
+ int nb_fix_sub_duration_heartbeat;
SpecifierOpt *canvas_sizes;
int nb_canvas_sizes;
SpecifierOpt *pass;
@@ -237,6 +254,18 @@ typedef struct OptionsContext {
int nb_autoscale;
SpecifierOpt *bits_per_raw_sample;
int nb_bits_per_raw_sample;
+ SpecifierOpt *enc_stats_pre;
+ int nb_enc_stats_pre;
+ SpecifierOpt *enc_stats_post;
+ int nb_enc_stats_post;
+ SpecifierOpt *mux_stats;
+ int nb_mux_stats;
+ SpecifierOpt *enc_stats_pre_fmt;
+ int nb_enc_stats_pre_fmt;
+ SpecifierOpt *enc_stats_post_fmt;
+ int nb_enc_stats_post_fmt;
+ SpecifierOpt *mux_stats_fmt;
+ int nb_mux_stats_fmt;
} OptionsContext;
typedef struct InputFilter {
@@ -312,12 +341,22 @@ typedef struct InputStream {
#define DECODING_FOR_OST 1
#define DECODING_FOR_FILTER 2
int processing_needed; /* non zero if the packets must be processed */
+ // should attach FrameData as opaque_ref after decoding
+ int want_frame_data;
+ /**
+ * Codec parameters - to be used by the decoding/streamcopy code.
+ * st->codecpar should not be accessed, because it may be modified
+ * concurrently by the demuxing thread.
+ */
+ AVCodecParameters *par;
AVCodecContext *dec_ctx;
const AVCodec *dec;
AVFrame *decoded_frame;
AVPacket *pkt;
+ AVRational framerate_guessed;
+
int64_t prev_pkt_pts;
int64_t start; /* time when read started */
/* predicted dts of the next packet read for this stream or (when there are
@@ -330,6 +369,12 @@ typedef struct InputStream {
int64_t pts; ///< current pts of the decoded frame (in AV_TIME_BASE units)
int wrap_correction_done;
+ // the value of AVCodecParserContext.repeat_pict from the AVStream parser
+ // for the last packet returned from ifile_get_packet()
+ // -1 if unknown
+ // FIXME: this is a hack, the avstream parser should not be used
+ int last_pkt_repeat_pict;
+
int64_t filter_in_rescale_delta_last;
int64_t min_pts; /* pts with the smallest value in a current stream */
@@ -379,12 +424,8 @@ typedef struct InputStream {
char *hwaccel_device;
enum AVPixelFormat hwaccel_output_format;
- /* hwaccel context */
- void *hwaccel_ctx;
- void (*hwaccel_uninit)(AVCodecContext *s);
int (*hwaccel_retrieve_data)(AVCodecContext *s, AVFrame *frame);
enum AVPixelFormat hwaccel_pix_fmt;
- enum AVPixelFormat hwaccel_retrieved_pix_fmt;
/* stats */
// combined size of all the packets read
@@ -401,38 +442,46 @@ typedef struct InputStream {
int got_output;
} InputStream;
+typedef struct LastFrameDuration {
+ int stream_idx;
+ int64_t duration;
+} LastFrameDuration;
+
typedef struct InputFile {
+ int index;
+
AVFormatContext *ctx;
int eof_reached; /* true if eof reached */
int eagain; /* true if last read attempt returned EAGAIN */
- int ist_index; /* index of first stream in input_streams */
- int loop; /* set number of times input stream should be looped */
- int64_t duration; /* actual duration of the longest stream in a file
- at the moment when looping happens */
- AVRational time_base; /* time base of the duration */
int64_t input_ts_offset;
int input_sync_ref;
-
+ /**
+ * Effective format start time based on enabled streams.
+ */
+ int64_t start_time_effective;
int64_t ts_offset;
+ /**
+ * Extra timestamp offset added by discontinuity handling.
+ */
+ int64_t ts_offset_discont;
int64_t last_ts;
int64_t start_time; /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */
int64_t recording_time;
- int nb_streams; /* number of stream that ffmpeg is aware of; may be different
- from ctx.nb_streams if new streams appear during av_read_frame() */
- int nb_streams_warn; /* number of streams that the user was warned of */
+
+ /* streams that ffmpeg is aware of;
+ * there may be extra streams in ctx that are not mapped to an InputStream
+ * if new streams appear dynamically during demuxing */
+ InputStream **streams;
+ int nb_streams;
+
int rate_emu;
float readrate;
int accurate_seek;
- AVPacket *pkt;
-
-#if HAVE_THREADS
- AVThreadMessageQueue *in_thread_queue;
- pthread_t thread; /* thread reading from this file */
- int non_blocking; /* reading packets from the thread should not block */
- int joined; /* the thread has been joined */
- int thread_queue_size; /* maximum number of queued packets */
-#endif
+ /* 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;
} InputFile;
enum forced_keyframes_const {
@@ -447,6 +496,41 @@ enum forced_keyframes_const {
#define ABORT_ON_FLAG_EMPTY_OUTPUT (1 << 0)
#define ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM (1 << 1)
+enum EncStatsType {
+ ENC_STATS_LITERAL = 0,
+ ENC_STATS_FILE_IDX,
+ ENC_STATS_STREAM_IDX,
+ ENC_STATS_FRAME_NUM,
+ ENC_STATS_FRAME_NUM_IN,
+ ENC_STATS_TIMEBASE,
+ ENC_STATS_TIMEBASE_IN,
+ ENC_STATS_PTS,
+ ENC_STATS_PTS_TIME,
+ ENC_STATS_PTS_IN,
+ ENC_STATS_PTS_TIME_IN,
+ ENC_STATS_DTS,
+ ENC_STATS_DTS_TIME,
+ ENC_STATS_SAMPLE_NUM,
+ ENC_STATS_NB_SAMPLES,
+ ENC_STATS_PKT_SIZE,
+ ENC_STATS_BITRATE,
+ ENC_STATS_AVG_BITRATE,
+};
+
+typedef struct EncStatsComponent {
+ enum EncStatsType type;
+
+ uint8_t *str;
+ size_t str_len;
+} EncStatsComponent;
+
+typedef struct EncStats {
+ EncStatsComponent *components;
+ int nb_components;
+
+ AVIOContext *io;
+} EncStats;
+
extern const char *const forced_keyframes_const_names[];
typedef enum {
@@ -454,68 +538,92 @@ typedef enum {
MUXER_FINISHED = 2,
} OSTFinished ;
+enum {
+ KF_FORCE_SOURCE = 1,
+ KF_FORCE_SOURCE_NO_DROP = 2,
+};
+
+typedef struct KeyframeForceCtx {
+ int type;
+
+ int64_t ref_pts;
+
+ // timestamps of the forced keyframes, in AV_TIME_BASE_Q
+ int64_t *pts;
+ int nb_pts;
+ int index;
+
+ AVExpr *pexpr;
+ double expr_const_values[FKF_NB];
+
+ int dropped_keyframe;
+} KeyframeForceCtx;
+
typedef struct OutputStream {
+ const AVClass *class;
+
int file_index; /* file index */
int index; /* stream index in the output file */
- int source_index; /* InputStream index */
+
+ /* input stream that is the source for this output stream;
+ * may be NULL for streams with no well-defined source, e.g.
+ * attachments or outputs from complex filtergraphs */
+ InputStream *ist;
+
AVStream *st; /* stream in the output file */
- int encoding_needed; /* true if encoding needed for this stream */
- int64_t frame_number;
- /* input pts and corresponding output pts
- for A/V sync */
- struct InputStream *sync_ist; /* input stream to sync against */
- int64_t sync_opts; /* output frame counter, could be changed to some true timestamp */ // FIXME look at frame_number
- /* pts of the first frame encoded for this stream, used for limiting
- * recording time */
- int64_t first_pts;
- /* dts of the last packet sent to the muxer */
+ /* number of frames emitted by the video-encoding sync code */
+ int64_t vsync_frame_number;
+ /* predicted pts of the next frame to be encoded
+ * audio/video encoding only */
+ int64_t next_pts;
+ /* dts of the last packet sent to the muxing queue, in AV_TIME_BASE_Q */
int64_t last_mux_dts;
+ /* pts of the last frame received from the filters, in AV_TIME_BASE_Q */
+ int64_t last_filter_pts;
+
+ // timestamp from which the streamcopied streams should start,
+ // in AV_TIME_BASE_Q;
+ // everything before it should be discarded
+ int64_t ts_copy_start;
+
// the timebase of the packets sent to the muxer
AVRational mux_timebase;
AVRational enc_timebase;
- AVBSFContext *bsf_ctx;
-
AVCodecContext *enc_ctx;
- AVCodecParameters *ref_par; /* associated input codec parameters with encoders options applied */
- const AVCodec *enc;
- int64_t max_frames;
AVFrame *filtered_frame;
AVFrame *last_frame;
+ AVFrame *sq_frame;
AVPacket *pkt;
int64_t last_dropped;
int64_t last_nb0_frames[3];
- void *hwaccel_ctx;
-
/* video only */
AVRational frame_rate;
AVRational max_frame_rate;
enum VideoSyncMethod vsync_method;
int is_cfr;
- const char *fps_mode;
int force_fps;
int top_field_first;
+#if FFMPEG_ROTATION_METADATA
int rotate_overridden;
+#endif
int autoscale;
+ int bitexact;
int bits_per_raw_sample;
+#if FFMPEG_ROTATION_METADATA
double rotate_override_value;
+#endif
AVRational frame_aspect_ratio;
- /* forced key frames */
- int64_t forced_kf_ref_pts;
- int64_t *forced_kf_pts;
- int forced_kf_count;
- int forced_kf_index;
- char *forced_keyframes;
- AVExpr *forced_keyframes_pexpr;
- double forced_keyframes_expr_const_values[FKF_NB];
- int dropped_keyframe;
+ KeyframeForceCtx kf;
/* audio only */
+#if FFMPEG_OPT_MAP_CHANNEL
int *audio_channels_map; /* list of the channels id to pick from the source stream */
int audio_channels_mapped; /* number of channels in audio_channels_map */
+#endif
char *logfile_prefix;
FILE *logfile;
@@ -531,7 +639,6 @@ typedef struct OutputStream {
char *apad;
OSTFinished finished; /* no more packets should be written for this stream */
int unavailable; /* true if the steram is unavailable (possibly temporarily) */
- int stream_copy;
// init_output_stream() has been called for this stream
// The encoder and the bitstream filters have been initialized and the stream
@@ -544,15 +651,16 @@ typedef struct OutputStream {
int streamcopy_started;
int copy_initial_nonkeyframes;
int copy_prior_start;
- char *disposition;
int keep_pix_fmt;
/* stats */
- // combined size of all the packets written
- uint64_t data_size;
+ // combined size of all the packets sent to the muxer
+ uint64_t data_size_mux;
+ // combined size of all the packets received from the encoder
+ uint64_t data_size_enc;
// number of packets send to the muxer
- uint64_t packets_written;
+ atomic_uint_least64_t packets_written;
// number of frames/samples sent to the encoder
uint64_t frames_encoded;
uint64_t samples_encoded;
@@ -562,51 +670,48 @@ typedef struct OutputStream {
/* packet quality factor */
int quality;
- int max_muxing_queue_size;
-
- /* the packets are buffered here until the muxer is ready to be initialized */
- AVFifo *muxing_queue;
-
- /*
- * The size of the AVPackets' buffers in queue.
- * Updated when a packet is either pushed or pulled from the queue.
- */
- size_t muxing_queue_data_size;
-
- /* Threshold after which max_muxing_queue_size will be in effect */
- size_t muxing_queue_data_threshold;
-
/* packet picture type */
int pict_type;
/* frame encode sum of squared error values */
int64_t error[4];
+
+ int sq_idx_encode;
+ int sq_idx_mux;
+
+ EncStats enc_stats_pre;
+ EncStats enc_stats_post;
+
+ /*
+ * bool on whether this stream should be utilized for splitting
+ * subtitles utilizing fix_sub_duration at random access points.
+ */
+ unsigned int fix_sub_duration_heartbeat;
} OutputStream;
typedef struct OutputFile {
+ const AVClass *class;
+
int index;
const AVOutputFormat *format;
+ const char *url;
+
+ OutputStream **streams;
+ int nb_streams;
+
+ SyncQueue *sq_encode;
- AVFormatContext *ctx;
- AVDictionary *opts;
- int ost_index; /* index of the first stream in output_streams */
int64_t recording_time; ///< desired length of the resulting file in microseconds == AV_TIME_BASE units
int64_t start_time; ///< start time in microseconds == AV_TIME_BASE units
- uint64_t limit_filesize; /* filesize limit expressed in bytes */
int shortest;
-
- int header_written;
+ int bitexact;
} OutputFile;
-extern InputStream **input_streams;
-extern int nb_input_streams;
extern InputFile **input_files;
extern int nb_input_files;
-extern OutputStream **output_streams;
-extern int nb_output_streams;
extern OutputFile **output_files;
extern int nb_output_files;
@@ -620,13 +725,10 @@ extern float audio_drift_threshold;
extern float dts_delta_threshold;
extern float dts_error_threshold;
-extern int audio_volume;
-extern int audio_sync_method;
extern enum VideoSyncMethod video_sync_method;
extern float frame_drop_threshold;
extern int do_benchmark;
extern int do_benchmark_all;
-extern int do_deinterlace;
extern int do_hex_dump;
extern int do_pkt_dump;
extern int copy_ts;
@@ -639,7 +741,6 @@ extern int print_stats;
extern int64_t stats_period;
extern int qp_hist;
extern int stdin_interaction;
-extern int frame_bits_per_raw_sample;
extern AVIOContext *progress_avio;
extern float max_error_rate;
@@ -651,15 +752,19 @@ extern int auto_conversion_filters;
extern const AVIOInterruptCB int_cb;
extern const OptionDef options[];
-#if CONFIG_QSV
-extern char *qsv_device;
-#endif
extern HWDevice *filter_hw_device;
-extern int want_sdp;
extern unsigned nb_output_dumped;
extern int main_return_code;
+extern int ignore_unknown_streams;
+extern int copy_unknown_streams;
+
+extern int recast_media;
+
+#if FFMPEG_OPT_PSNR
+extern int do_psnr;
+#endif
void term_init(void);
void term_exit(void);
@@ -669,7 +774,12 @@ void show_usage(void);
void remove_avoptions(AVDictionary **a, AVDictionary *b);
void assert_avoptions(AVDictionary *m);
-int guess_input_channel_layout(InputStream *ist);
+void assert_file_overwrite(const char *filename);
+char *file_read(const char *filename);
+AVDictionary *strip_specifiers(const AVDictionary *dict);
+const AVCodec *find_codec_or_die(void *logctx, const char *name,
+ enum AVMediaType type, int encoder);
+int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_idx, int is_global);
int configure_filtergraph(FilterGraph *fg);
void check_filter_outputs(void);
@@ -683,8 +793,9 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame);
int ffmpeg_parse_options(int argc, char **argv);
-int videotoolbox_init(AVCodecContext *s);
-int qsv_init(AVCodecContext *s);
+void enc_stats_write(OutputStream *ost, EncStats *es,
+ const AVFrame *frame, const AVPacket *pkt,
+ uint64_t frame_num);
HWDevice *hw_device_get_by_name(const char *name);
int hw_device_init_from_string(const char *arg, HWDevice **dev);
@@ -696,12 +807,99 @@ int hw_device_setup_for_filter(FilterGraph *fg);
int hwaccel_decode_init(AVCodecContext *avctx);
-/* open the muxer when all the streams are initialized */
-int of_check_init(OutputFile *of);
+/*
+ * Initialize muxing state for the given stream, should be called
+ * after the codec/streamcopy setup has been done.
+ *
+ * Open the muxer once all the streams have been initialized.
+ */
+int of_stream_init(OutputFile *of, OutputStream *ost);
int of_write_trailer(OutputFile *of);
+int of_open(const OptionsContext *o, const char *filename);
void of_close(OutputFile **pof);
-void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
- int unqueue);
+void of_enc_stats_close(void);
+
+/*
+ * Send a single packet to the output, applying any bitstream filters
+ * associated with the output stream. This may result in any number
+ * of packets actually being written, depending on what bitstream
+ * filters are applied. The supplied packet is consumed and will be
+ * blank (as if newly-allocated) when this function returns.
+ *
+ * If eof is set, instead indicate EOF to all bitstream filters and
+ * therefore flush any delayed packets to the output. A blank packet
+ * must be supplied in this case.
+ */
+void of_output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int eof);
+int64_t of_filesize(OutputFile *of);
+
+int ifile_open(const OptionsContext *o, const char *filename);
+void ifile_close(InputFile **f);
+
+/**
+ * Get next input packet from the demuxer.
+ *
+ * @param pkt the packet is written here when this function returns 0
+ * @return
+ * - 0 when a packet has been read successfully
+ * - 1 when stream end was reached, but the stream is looped;
+ * caller should flush decoders and read from this demuxer again
+ * - a negative error code on failure
+ */
+int ifile_get_packet(InputFile *f, AVPacket **pkt);
+
+/* iterate over all input streams in all input files;
+ * pass NULL to start iteration */
+InputStream *ist_iter(InputStream *prev);
+
+#define SPECIFIER_OPT_FMT_str "%s"
+#define SPECIFIER_OPT_FMT_i "%i"
+#define SPECIFIER_OPT_FMT_i64 "%"PRId64
+#define SPECIFIER_OPT_FMT_ui64 "%"PRIu64
+#define SPECIFIER_OPT_FMT_f "%f"
+#define SPECIFIER_OPT_FMT_dbl "%lf"
+
+#define WARN_MULTIPLE_OPT_USAGE(name, type, so, st)\
+{\
+ char namestr[128] = "";\
+ const char *spec = so->specifier && so->specifier[0] ? so->specifier : "";\
+ for (int _i = 0; opt_name_##name[_i]; _i++)\
+ av_strlcatf(namestr, sizeof(namestr), "-%s%s", opt_name_##name[_i], opt_name_##name[_i+1] ? (opt_name_##name[_i+2] ? ", " : " or ") : "");\
+ av_log(NULL, AV_LOG_WARNING, "Multiple %s options specified for stream %d, only the last option '-%s%s%s "SPECIFIER_OPT_FMT_##type"' will be used.\n",\
+ namestr, st->index, opt_name_##name[0], spec[0] ? ":" : "", spec, so->u.type);\
+}
+
+#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
+{\
+ int _ret, _matches = 0;\
+ SpecifierOpt *so;\
+ for (int _i = 0; _i < o->nb_ ## name; _i++) {\
+ char *spec = o->name[_i].specifier;\
+ if ((_ret = check_stream_specifier(fmtctx, st, spec)) > 0) {\
+ outvar = o->name[_i].u.type;\
+ so = &o->name[_i];\
+ _matches++;\
+ } else if (_ret < 0)\
+ exit_program(1);\
+ }\
+ if (_matches > 1)\
+ WARN_MULTIPLE_OPT_USAGE(name, type, so, st);\
+}
+
+#define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)\
+{\
+ int i;\
+ for (i = 0; i < o->nb_ ## name; i++) {\
+ char *spec = o->name[i].specifier;\
+ if (!strcmp(spec, mediatype))\
+ outvar = o->name[i].u.type;\
+ }\
+}
+
+extern const char * const opt_name_codec_names[];
+extern const char * const opt_name_codec_tags[];
+extern const char * const opt_name_frame_rates[];
+extern const char * const opt_name_top_field_first[];
#endif /* FFTOOLS_FFMPEG_H */
diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
new file mode 100644
index 000000000..ffece6072
--- /dev/null
+++ b/fftools/ffmpeg_demux.c
@@ -0,0 +1,1131 @@
+/*
+ * 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
+#include
+
+#include "ffmpeg.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/display.h"
+#include "libavutil/error.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/time.h"
+#include "libavutil/timestamp.h"
+#include "libavutil/thread.h"
+#include "libavutil/threadmessage.h"
+
+#include "libavcodec/packet.h"
+
+#include "libavformat/avformat.h"
+
+static const char *const opt_name_discard[] = {"discard", NULL};
+static const char *const opt_name_reinit_filters[] = {"reinit_filter", NULL};
+static const char *const opt_name_fix_sub_duration[] = {"fix_sub_duration", NULL};
+static const char *const opt_name_canvas_sizes[] = {"canvas_size", NULL};
+static const char *const opt_name_guess_layout_max[] = {"guess_layout_max", NULL};
+static const char *const opt_name_ts_scale[] = {"itsscale", NULL};
+static const char *const opt_name_hwaccels[] = {"hwaccel", NULL};
+static const char *const opt_name_hwaccel_devices[] = {"hwaccel_device", NULL};
+static const char *const opt_name_hwaccel_output_formats[] = {"hwaccel_output_format", NULL};
+static const char *const opt_name_autorotate[] = {"autorotate", NULL};
+static const char *const opt_name_display_rotations[] = {"display_rotation", NULL};
+static const char *const opt_name_display_hflips[] = {"display_hflip", NULL};
+static const char *const opt_name_display_vflips[] = {"display_vflip", NULL};
+
+typedef struct Demuxer {
+ InputFile f;
+
+ /* 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;
+
+ /* number of streams that the user was warned of */
+ int nb_streams_warn;
+
+ AVThreadMessageQueue *in_thread_queue;
+ int thread_queue_size;
+ pthread_t thread;
+ int non_blocking;
+} Demuxer;
+
+typedef struct DemuxMsg {
+ AVPacket *pkt;
+ int looping;
+
+ // repeat_pict from the demuxer-internal parser
+ int repeat_pict;
+} DemuxMsg;
+
+static Demuxer *demuxer_from_ifile(InputFile *f)
+{
+ return (Demuxer*)f;
+}
+
+static void report_new_stream(Demuxer *d, const AVPacket *pkt)
+{
+ AVStream *st = d->f.ctx->streams[pkt->stream_index];
+
+ if (pkt->stream_index < d->nb_streams_warn)
+ return;
+ av_log(NULL, AV_LOG_WARNING,
+ "New %s stream %d:%d at pos:%"PRId64" and DTS:%ss\n",
+ av_get_media_type_string(st->codecpar->codec_type),
+ d->f.index, pkt->stream_index,
+ pkt->pos, av_ts2timestr(pkt->dts, &st->time_base));
+ d->nb_streams_warn = pkt->stream_index + 1;
+}
+
+static void ifile_duration_update(Demuxer *d, InputStream *ist,
+ 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 (ist->max_pts > ist->min_pts &&
+ ist->max_pts - (uint64_t)ist->min_pts < INT64_MAX - last_duration)
+ last_duration += ist->max_pts - ist->min_pts;
+
+ if (!d->duration ||
+ av_compare_ts(d->duration, d->time_base,
+ last_duration, ist->st->time_base) < 0) {
+ d->duration = last_duration;
+ d->time_base = ist->st->time_base;
+ }
+}
+
+static int seek_to_start(Demuxer *d)
+{
+ InputFile *ifile = &d->f;
+ AVFormatContext *is = ifile->ctx;
+ InputStream *ist;
+ int ret;
+
+ ret = avformat_seek_file(is, -1, INT64_MIN, is->start_time, is->start_time, 0);
+ 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;
+
+ while (got_durations < ifile->audio_duration_queue_size) {
+ LastFrameDuration dur;
+ ret = av_thread_message_queue_recv(ifile->audio_duration_queue, &dur, 0);
+ if (ret < 0)
+ return ret;
+ got_durations++;
+
+ ist = ifile->streams[dur.stream_idx];
+ ifile_duration_update(d, ist, dur.duration);
+ }
+ } else {
+ for (int i = 0; i < ifile->nb_streams; i++) {
+ int64_t duration = 0;
+ ist = ifile->streams[i];
+
+ 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, ist, duration);
+ }
+ }
+
+ if (d->loop > 0)
+ d->loop--;
+
+ return ret;
+}
+
+static void ts_fixup(Demuxer *d, AVPacket *pkt, int *repeat_pict)
+{
+ InputFile *ifile = &d->f;
+ InputStream *ist = ifile->streams[pkt->stream_index];
+ const int64_t start_time = ifile->start_time_effective;
+ int64_t duration;
+
+ if (debug_ts) {
+ av_log(NULL, AV_LOG_INFO, "demuxer -> ist_index:%d:%d type:%s "
+ "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s\n",
+ ifile->index, pkt->stream_index,
+ av_get_media_type_string(ist->st->codecpar->codec_type),
+ av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ist->st->time_base),
+ av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ist->st->time_base),
+ av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ist->st->time_base));
+ }
+
+ if (!ist->wrap_correction_done && start_time != AV_NOPTS_VALUE &&
+ ist->st->pts_wrap_bits < 64) {
+ int64_t stime, stime2;
+
+ stime = av_rescale_q(start_time, AV_TIME_BASE_Q, ist->st->time_base);
+ stime2= stime + (1ULL<st->pts_wrap_bits);
+ ist->wrap_correction_done = 1;
+
+ if(stime2 > stime && pkt->dts != AV_NOPTS_VALUE && pkt->dts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) {
+ pkt->dts -= 1ULL<st->pts_wrap_bits;
+ ist->wrap_correction_done = 0;
+ }
+ if(stime2 > stime && pkt->pts != AV_NOPTS_VALUE && pkt->pts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) {
+ pkt->pts -= 1ULL<st->pts_wrap_bits;
+ ist->wrap_correction_done = 0;
+ }
+ }
+
+ if (pkt->dts != AV_NOPTS_VALUE)
+ pkt->dts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
+ if (pkt->pts != AV_NOPTS_VALUE)
+ pkt->pts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
+
+ if (pkt->pts != AV_NOPTS_VALUE)
+ pkt->pts *= ist->ts_scale;
+ if (pkt->dts != AV_NOPTS_VALUE)
+ pkt->dts *= ist->ts_scale;
+
+ duration = av_rescale_q(d->duration, d->time_base, ist->st->time_base);
+ if (pkt->pts != AV_NOPTS_VALUE) {
+ pkt->pts += duration;
+ ist->max_pts = FFMAX(pkt->pts, ist->max_pts);
+ ist->min_pts = FFMIN(pkt->pts, ist->min_pts);
+ }
+
+ if (pkt->dts != AV_NOPTS_VALUE)
+ pkt->dts += duration;
+
+ *repeat_pict = -1;
+ if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
+ av_stream_get_parser(ist->st))
+ *repeat_pict = av_stream_get_parser(ist->st)->repeat_pict;
+}
+
+static void thread_set_name(InputFile *f)
+{
+ char name[16];
+ snprintf(name, sizeof(name), "dmx%d:%s", f->index, f->ctx->iformat->name);
+ ff_thread_setname(name);
+}
+
+static void *input_thread(void *arg)
+{
+ Demuxer *d = arg;
+ InputFile *f = &d->f;
+ AVPacket *pkt;
+ unsigned flags = d->non_blocking ? AV_THREAD_MESSAGE_NONBLOCK : 0;
+ int ret = 0;
+
+ pkt = av_packet_alloc();
+ if (!pkt) {
+ ret = AVERROR(ENOMEM);
+ goto finish;
+ }
+
+ thread_set_name(f);
+
+ while (1) {
+ DemuxMsg msg = { NULL };
+
+ ret = av_read_frame(f->ctx, pkt);
+
+ if (ret == AVERROR(EAGAIN)) {
+ av_usleep(10000);
+ continue;
+ }
+ if (ret < 0) {
+ if (d->loop) {
+ /* signal looping to the consumer thread */
+ msg.looping = 1;
+ ret = av_thread_message_queue_send(d->in_thread_queue, &msg, 0);
+ if (ret >= 0)
+ ret = seek_to_start(d);
+ if (ret >= 0)
+ continue;
+
+ /* fallthrough to the error path */
+ }
+
+ if (ret == AVERROR_EOF)
+ av_log(NULL, AV_LOG_VERBOSE, "EOF in input file %d\n", f->index);
+ else
+ av_log(NULL, AV_LOG_ERROR, "Error demuxing input file %d: %s\n",
+ f->index, av_err2str(ret));
+
+ break;
+ }
+
+ if (do_pkt_dump) {
+ av_pkt_dump_log2(NULL, AV_LOG_INFO, pkt, do_hex_dump,
+ f->ctx->streams[pkt->stream_index]);
+ }
+
+ /* the following test is needed in case new streams appear
+ dynamically in stream : we ignore them */
+ if (pkt->stream_index >= f->nb_streams) {
+ report_new_stream(d, pkt);
+ av_packet_unref(pkt);
+ continue;
+ }
+
+ if (pkt->flags & AV_PKT_FLAG_CORRUPT) {
+ av_log(NULL, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING,
+ "%s: corrupt input packet in stream %d\n",
+ f->ctx->url, pkt->stream_index);
+ if (exit_on_error) {
+ av_packet_unref(pkt);
+ ret = AVERROR_INVALIDDATA;
+ break;
+ }
+ }
+
+ ts_fixup(d, pkt, &msg.repeat_pict);
+
+ msg.pkt = av_packet_alloc();
+ if (!msg.pkt) {
+ av_packet_unref(pkt);
+ ret = AVERROR(ENOMEM);
+ break;
+ }
+ av_packet_move_ref(msg.pkt, pkt);
+ ret = av_thread_message_queue_send(d->in_thread_queue, &msg, flags);
+ if (flags && ret == AVERROR(EAGAIN)) {
+ flags = 0;
+ ret = av_thread_message_queue_send(d->in_thread_queue, &msg, flags);
+ av_log(f->ctx, AV_LOG_WARNING,
+ "Thread message queue blocking; consider raising the "
+ "thread_queue_size option (current value: %d)\n",
+ d->thread_queue_size);
+ }
+ if (ret < 0) {
+ if (ret != AVERROR_EOF)
+ av_log(f->ctx, AV_LOG_ERROR,
+ "Unable to send packet to main thread: %s\n",
+ av_err2str(ret));
+ av_packet_free(&msg.pkt);
+ break;
+ }
+ }
+
+finish:
+ av_assert0(ret < 0);
+ av_thread_message_queue_set_err_recv(d->in_thread_queue, ret);
+
+ av_packet_free(&pkt);
+
+ av_log(NULL, AV_LOG_VERBOSE, "Terminating demuxer thread %d\n", f->index);
+
+ return NULL;
+}
+
+static void thread_stop(Demuxer *d)
+{
+ InputFile *f = &d->f;
+ DemuxMsg msg;
+
+ if (!d->in_thread_queue)
+ return;
+ av_thread_message_queue_set_err_send(d->in_thread_queue, AVERROR_EOF);
+ while (av_thread_message_queue_recv(d->in_thread_queue, &msg, 0) >= 0)
+ av_packet_free(&msg.pkt);
+
+ pthread_join(d->thread, NULL);
+ av_thread_message_queue_free(&d->in_thread_queue);
+ av_thread_message_queue_free(&f->audio_duration_queue);
+}
+
+static int thread_start(Demuxer *d)
+{
+ int ret;
+ InputFile *f = &d->f;
+
+ if (d->thread_queue_size <= 0)
+ d->thread_queue_size = (nb_input_files > 1 ? 8 : 1);
+
+ if (nb_input_files > 1 &&
+ (f->ctx->pb ? !f->ctx->pb->seekable :
+ strcmp(f->ctx->iformat->name, "lavfi")))
+ d->non_blocking = 1;
+ ret = av_thread_message_queue_alloc(&d->in_thread_queue,
+ d->thread_queue_size, sizeof(DemuxMsg));
+ if (ret < 0)
+ return ret;
+
+ if (d->loop) {
+ int nb_audio_dec = 0;
+
+ for (int i = 0; i < f->nb_streams; i++) {
+ InputStream *ist = f->streams[i];
+ nb_audio_dec += !!(ist->decoding_needed &&
+ ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO);
+ }
+
+ if (nb_audio_dec) {
+ ret = av_thread_message_queue_alloc(&f->audio_duration_queue,
+ nb_audio_dec, sizeof(LastFrameDuration));
+ if (ret < 0)
+ goto fail;
+ f->audio_duration_queue_size = nb_audio_dec;
+ }
+ }
+
+ if ((ret = pthread_create(&d->thread, NULL, input_thread, d))) {
+ av_log(NULL, AV_LOG_ERROR, "pthread_create failed: %s. Try to increase `ulimit -v` or decrease `ulimit -s`.\n", strerror(ret));
+ ret = AVERROR(ret);
+ goto fail;
+ }
+
+ return 0;
+fail:
+ av_thread_message_queue_free(&d->in_thread_queue);
+ return ret;
+}
+
+int ifile_get_packet(InputFile *f, AVPacket **pkt)
+{
+ Demuxer *d = demuxer_from_ifile(f);
+ InputStream *ist;
+ DemuxMsg msg;
+ int ret;
+
+ if (!d->in_thread_queue) {
+ ret = thread_start(d);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (f->readrate || f->rate_emu) {
+ int i;
+ int64_t file_start = copy_ts * (
+ (f->start_time_effective != AV_NOPTS_VALUE ? f->start_time_effective * !start_at_zero : 0) +
+ (f->start_time != AV_NOPTS_VALUE ? f->start_time : 0)
+ );
+ float scale = f->rate_emu ? 1.0 : f->readrate;
+ for (i = 0; i < f->nb_streams; i++) {
+ InputStream *ist = f->streams[i];
+ int64_t stream_ts_offset, pts, now;
+ if (!ist->nb_packets || (ist->decoding_needed && !ist->got_output)) continue;
+ stream_ts_offset = FFMAX(ist->first_dts != AV_NOPTS_VALUE ? ist->first_dts : 0, file_start);
+ pts = av_rescale(ist->dts, 1000000, AV_TIME_BASE);
+ now = (av_gettime_relative() - ist->start) * scale + stream_ts_offset;
+ if (pts > now)
+ return AVERROR(EAGAIN);
+ }
+ }
+
+ ret = av_thread_message_queue_recv(d->in_thread_queue, &msg,
+ d->non_blocking ?
+ AV_THREAD_MESSAGE_NONBLOCK : 0);
+ if (ret < 0)
+ return ret;
+ if (msg.looping)
+ return 1;
+
+ ist = f->streams[msg.pkt->stream_index];
+ ist->last_pkt_repeat_pict = msg.repeat_pict;
+
+ *pkt = msg.pkt;
+ return 0;
+}
+
+static void ist_free(InputStream **pist)
+{
+ InputStream *ist = *pist;
+
+ if (!ist)
+ return;
+
+ av_frame_free(&ist->decoded_frame);
+ av_packet_free(&ist->pkt);
+ av_dict_free(&ist->decoder_opts);
+ avsubtitle_free(&ist->prev_sub.subtitle);
+ av_frame_free(&ist->sub2video.frame);
+ av_freep(&ist->filters);
+ av_freep(&ist->hwaccel_device);
+ av_freep(&ist->dts_buffer);
+
+ avcodec_free_context(&ist->dec_ctx);
+ avcodec_parameters_free(&ist->par);
+
+ av_freep(pist);
+}
+
+void ifile_close(InputFile **pf)
+{
+ InputFile *f = *pf;
+ Demuxer *d = demuxer_from_ifile(f);
+
+ if (!f)
+ return;
+
+ thread_stop(d);
+
+ for (int i = 0; i < f->nb_streams; i++)
+ ist_free(&f->streams[i]);
+ av_freep(&f->streams);
+
+ avformat_close_input(&f->ctx);
+
+ av_freep(pf);
+}
+
+static const AVCodec *choose_decoder(const OptionsContext *o, AVFormatContext *s, AVStream *st,
+ enum HWAccelID hwaccel_id, enum AVHWDeviceType hwaccel_device_type)
+
+{
+ char *codec_name = NULL;
+
+ MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
+ if (codec_name) {
+ const AVCodec *codec = find_codec_or_die(NULL, codec_name, st->codecpar->codec_type, 0);
+ st->codecpar->codec_id = codec->id;
+ if (recast_media && st->codecpar->codec_type != codec->type)
+ st->codecpar->codec_type = codec->type;
+ return codec;
+ } else {
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
+ hwaccel_id == HWACCEL_GENERIC &&
+ hwaccel_device_type != AV_HWDEVICE_TYPE_NONE) {
+ const AVCodec *c;
+ void *i = NULL;
+
+ while ((c = av_codec_iterate(&i))) {
+ const AVCodecHWConfig *config;
+
+ if (c->id != st->codecpar->codec_id ||
+ !av_codec_is_decoder(c))
+ continue;
+
+ for (int j = 0; config = avcodec_get_hw_config(c, j); j++) {
+ if (config->device_type == hwaccel_device_type) {
+ av_log(NULL, AV_LOG_VERBOSE, "Selecting decoder '%s' because of requested hwaccel method %s\n",
+ c->name, av_hwdevice_get_type_name(hwaccel_device_type));
+ return c;
+ }
+ }
+ }
+ }
+
+ return avcodec_find_decoder(st->codecpar->codec_id);
+ }
+}
+
+static int guess_input_channel_layout(InputStream *ist)
+{
+ AVCodecContext *dec = ist->dec_ctx;
+
+ if (dec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
+ char layout_name[256];
+
+ if (dec->ch_layout.nb_channels > ist->guess_layout_max)
+ return 0;
+ av_channel_layout_default(&dec->ch_layout, dec->ch_layout.nb_channels);
+ if (dec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
+ return 0;
+ av_channel_layout_describe(&dec->ch_layout, layout_name, sizeof(layout_name));
+ av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Input Stream "
+ "#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name);
+ }
+ return 1;
+}
+
+static void add_display_matrix_to_stream(const OptionsContext *o,
+ AVFormatContext *ctx, AVStream *st)
+{
+ double rotation = DBL_MAX;
+ int hflip = -1, vflip = -1;
+ int hflip_set = 0, vflip_set = 0, rotation_set = 0;
+ int32_t *buf;
+
+ MATCH_PER_STREAM_OPT(display_rotations, dbl, rotation, ctx, st);
+ MATCH_PER_STREAM_OPT(display_hflips, i, hflip, ctx, st);
+ MATCH_PER_STREAM_OPT(display_vflips, i, vflip, ctx, st);
+
+ rotation_set = rotation != DBL_MAX;
+ hflip_set = hflip != -1;
+ vflip_set = vflip != -1;
+
+ if (!rotation_set && !hflip_set && !vflip_set)
+ return;
+
+ buf = (int32_t *)av_stream_new_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, sizeof(int32_t) * 9);
+ if (!buf) {
+ av_log(NULL, AV_LOG_FATAL, "Failed to generate a display matrix!\n");
+ exit_program(1);
+ }
+
+ av_display_rotation_set(buf,
+ rotation_set ? -(rotation) : -0.0f);
+
+ av_display_matrix_flip(buf,
+ hflip_set ? hflip : 0,
+ vflip_set ? vflip : 0);
+}
+
+/* Add all the streams from the given input file to the demuxer */
+static void add_input_streams(const OptionsContext *o, Demuxer *d)
+{
+ InputFile *f = &d->f;
+ AVFormatContext *ic = f->ctx;
+ int i, ret;
+
+ for (i = 0; i < ic->nb_streams; i++) {
+ AVStream *st = ic->streams[i];
+ AVCodecParameters *par = st->codecpar;
+ InputStream *ist;
+ char *framerate = NULL, *hwaccel_device = NULL;
+ const char *hwaccel = NULL;
+ char *hwaccel_output_format = NULL;
+ char *codec_tag = NULL;
+ char *next;
+ char *discard_str = NULL;
+ const AVClass *cc = avcodec_get_class();
+ const AVOption *discard_opt = av_opt_find(&cc, "skip_frame", NULL,
+ 0, AV_OPT_SEARCH_FAKE_OBJ);
+
+ ist = ALLOC_ARRAY_ELEM(f->streams, f->nb_streams);
+ ist->st = st;
+ ist->file_index = f->index;
+ ist->discard = 1;
+ st->discard = AVDISCARD_ALL;
+ ist->nb_samples = 0;
+ ist->first_dts = AV_NOPTS_VALUE;
+ ist->min_pts = INT64_MAX;
+ ist->max_pts = INT64_MIN;
+
+ ist->ts_scale = 1.0;
+ MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
+
+ ist->autorotate = 1;
+ MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
+
+ MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
+ if (codec_tag) {
+ uint32_t tag = strtol(codec_tag, &next, 0);
+ if (*next)
+ tag = AV_RL32(codec_tag);
+ st->codecpar->codec_tag = tag;
+ }
+
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+ add_display_matrix_to_stream(o, ic, st);
+
+ MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
+ MATCH_PER_STREAM_OPT(hwaccel_output_formats, str,
+ hwaccel_output_format, ic, st);
+
+ if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "cuvid")) {
+ av_log(NULL, AV_LOG_WARNING,
+ "WARNING: defaulting hwaccel_output_format to cuda for compatibility "
+ "with old commandlines. This behaviour is DEPRECATED and will be removed "
+ "in the future. Please explicitly set \"-hwaccel_output_format cuda\".\n");
+ ist->hwaccel_output_format = AV_PIX_FMT_CUDA;
+ } else if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "qsv")) {
+ av_log(NULL, AV_LOG_WARNING,
+ "WARNING: defaulting hwaccel_output_format to qsv for compatibility "
+ "with old commandlines. This behaviour is DEPRECATED and will be removed "
+ "in the future. Please explicitly set \"-hwaccel_output_format qsv\".\n");
+ ist->hwaccel_output_format = AV_PIX_FMT_QSV;
+ } else if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "mediacodec")) {
+ // There is no real AVHWFrameContext implementation. Set
+ // hwaccel_output_format to avoid av_hwframe_transfer_data error.
+ ist->hwaccel_output_format = AV_PIX_FMT_MEDIACODEC;
+ } else if (hwaccel_output_format) {
+ ist->hwaccel_output_format = av_get_pix_fmt(hwaccel_output_format);
+ if (ist->hwaccel_output_format == AV_PIX_FMT_NONE) {
+ av_log(NULL, AV_LOG_FATAL, "Unrecognised hwaccel output "
+ "format: %s", hwaccel_output_format);
+ }
+ } else {
+ ist->hwaccel_output_format = AV_PIX_FMT_NONE;
+ }
+
+ if (hwaccel) {
+ // The NVDEC hwaccels use a CUDA device, so remap the name here.
+ if (!strcmp(hwaccel, "nvdec") || !strcmp(hwaccel, "cuvid"))
+ hwaccel = "cuda";
+
+ if (!strcmp(hwaccel, "none"))
+ ist->hwaccel_id = HWACCEL_NONE;
+ else if (!strcmp(hwaccel, "auto"))
+ ist->hwaccel_id = HWACCEL_AUTO;
+ else {
+ enum AVHWDeviceType type = av_hwdevice_find_type_by_name(hwaccel);
+ if (type != AV_HWDEVICE_TYPE_NONE) {
+ ist->hwaccel_id = HWACCEL_GENERIC;
+ ist->hwaccel_device_type = type;
+ }
+
+ if (!ist->hwaccel_id) {
+ av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n",
+ hwaccel);
+ av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: ");
+ type = AV_HWDEVICE_TYPE_NONE;
+ while ((type = av_hwdevice_iterate_types(type)) !=
+ AV_HWDEVICE_TYPE_NONE)
+ av_log(NULL, AV_LOG_FATAL, "%s ",
+ av_hwdevice_get_type_name(type));
+ av_log(NULL, AV_LOG_FATAL, "\n");
+ exit_program(1);
+ }
+ }
+ }
+
+ MATCH_PER_STREAM_OPT(hwaccel_devices, str, hwaccel_device, ic, st);
+ if (hwaccel_device) {
+ ist->hwaccel_device = av_strdup(hwaccel_device);
+ if (!ist->hwaccel_device)
+ report_and_exit(AVERROR(ENOMEM));
+ }
+
+ ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE;
+ }
+
+ ist->dec = choose_decoder(o, ic, st, ist->hwaccel_id, ist->hwaccel_device_type);
+ ist->decoder_opts = filter_codec_opts(o->g->codec_opts, ist->st->codecpar->codec_id, ic, st, ist->dec);
+
+ ist->reinit_filters = -1;
+ MATCH_PER_STREAM_OPT(reinit_filters, i, ist->reinit_filters, ic, st);
+
+ MATCH_PER_STREAM_OPT(discard, str, discard_str, ic, st);
+ ist->user_set_discard = AVDISCARD_NONE;
+
+ if ((o->video_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) ||
+ (o->audio_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) ||
+ (o->subtitle_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) ||
+ (o->data_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA))
+ ist->user_set_discard = AVDISCARD_ALL;
+
+ if (discard_str && av_opt_eval_int(&cc, discard_opt, discard_str, &ist->user_set_discard) < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Error parsing discard %s.\n",
+ discard_str);
+ exit_program(1);
+ }
+
+ ist->filter_in_rescale_delta_last = AV_NOPTS_VALUE;
+ ist->prev_pkt_pts = AV_NOPTS_VALUE;
+
+ ist->dec_ctx = avcodec_alloc_context3(ist->dec);
+ if (!ist->dec_ctx)
+ report_and_exit(AVERROR(ENOMEM));
+
+ ret = avcodec_parameters_to_context(ist->dec_ctx, par);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Error initializing the decoder context.\n");
+ exit_program(1);
+ }
+
+ ist->decoded_frame = av_frame_alloc();
+ if (!ist->decoded_frame)
+ report_and_exit(AVERROR(ENOMEM));
+
+ ist->pkt = av_packet_alloc();
+ if (!ist->pkt)
+ report_and_exit(AVERROR(ENOMEM));
+
+ if (o->bitexact)
+ ist->dec_ctx->flags |= AV_CODEC_FLAG_BITEXACT;
+
+ switch (par->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ // avformat_find_stream_info() doesn't set this for us anymore.
+ ist->dec_ctx->framerate = st->avg_frame_rate;
+
+ MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
+ if (framerate && av_parse_video_rate(&ist->framerate,
+ framerate) < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
+ framerate);
+ exit_program(1);
+ }
+
+ ist->top_field_first = -1;
+ MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st);
+
+ ist->framerate_guessed = av_guess_frame_rate(ic, st, NULL);
+
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ ist->guess_layout_max = INT_MAX;
+ MATCH_PER_STREAM_OPT(guess_layout_max, i, ist->guess_layout_max, ic, st);
+ guess_input_channel_layout(ist);
+ break;
+ case AVMEDIA_TYPE_DATA:
+ case AVMEDIA_TYPE_SUBTITLE: {
+ char *canvas_size = NULL;
+ MATCH_PER_STREAM_OPT(fix_sub_duration, i, ist->fix_sub_duration, ic, st);
+ MATCH_PER_STREAM_OPT(canvas_sizes, str, canvas_size, ic, st);
+ if (canvas_size &&
+ av_parse_video_size(&ist->dec_ctx->width, &ist->dec_ctx->height, canvas_size) < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Invalid canvas size: %s.\n", canvas_size);
+ exit_program(1);
+ }
+ break;
+ }
+ case AVMEDIA_TYPE_ATTACHMENT:
+ case AVMEDIA_TYPE_UNKNOWN:
+ break;
+ default:
+ abort();
+ }
+
+ ist->par = avcodec_parameters_alloc();
+ if (!ist->par)
+ report_and_exit(AVERROR(ENOMEM));
+
+ ret = avcodec_parameters_from_context(ist->par, ist->dec_ctx);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Error initializing the decoder context.\n");
+ exit_program(1);
+ }
+ }
+}
+
+static void dump_attachment(AVStream *st, const char *filename)
+{
+ int ret;
+ AVIOContext *out = NULL;
+ const AVDictionaryEntry *e;
+
+ if (!st->codecpar->extradata_size) {
+ av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
+ nb_input_files - 1, st->index);
+ return;
+ }
+ if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
+ filename = e->value;
+ if (!*filename) {
+ av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
+ "in stream #%d:%d.\n", nb_input_files - 1, st->index);
+ exit_program(1);
+ }
+
+ assert_file_overwrite(filename);
+
+ if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
+ filename);
+ exit_program(1);
+ }
+
+ avio_write(out, st->codecpar->extradata, st->codecpar->extradata_size);
+ avio_flush(out);
+ avio_close(out);
+}
+
+int ifile_open(const OptionsContext *o, const char *filename)
+{
+ Demuxer *d;
+ InputFile *f;
+ AVFormatContext *ic;
+ const AVInputFormat *file_iformat = NULL;
+ int err, i, ret;
+ int64_t timestamp;
+ AVDictionary *unused_opts = NULL;
+ const AVDictionaryEntry *e = NULL;
+ char * video_codec_name = NULL;
+ char * audio_codec_name = NULL;
+ char *subtitle_codec_name = NULL;
+ char * data_codec_name = NULL;
+ int scan_all_pmts_set = 0;
+
+ int64_t start_time = o->start_time;
+ int64_t start_time_eof = o->start_time_eof;
+ int64_t stop_time = o->stop_time;
+ int64_t recording_time = o->recording_time;
+
+ if (stop_time != INT64_MAX && recording_time != INT64_MAX) {
+ stop_time = INT64_MAX;
+ av_log(NULL, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
+ }
+
+ if (stop_time != INT64_MAX && recording_time == INT64_MAX) {
+ int64_t start = start_time == AV_NOPTS_VALUE ? 0 : start_time;
+ if (stop_time <= start) {
+ av_log(NULL, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n");
+ exit_program(1);
+ } else {
+ recording_time = stop_time - start;
+ }
+ }
+
+ if (o->format) {
+ if (!(file_iformat = av_find_input_format(o->format))) {
+ av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
+ exit_program(1);
+ }
+ }
+
+ if (!strcmp(filename, "-"))
+ filename = "fd:";
+
+ stdin_interaction &= strncmp(filename, "pipe:", 5) &&
+ strcmp(filename, "fd:") &&
+ strcmp(filename, "/dev/stdin");
+
+ /* get default parameters from command line */
+ ic = avformat_alloc_context();
+ if (!ic)
+ report_and_exit(AVERROR(ENOMEM));
+ if (o->nb_audio_sample_rate) {
+ av_dict_set_int(&o->g->format_opts, "sample_rate", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i, 0);
+ }
+ if (o->nb_audio_channels) {
+ const AVClass *priv_class;
+ if (file_iformat && (priv_class = file_iformat->priv_class) &&
+ av_opt_find(&priv_class, "ch_layout", NULL, 0,
+ AV_OPT_SEARCH_FAKE_OBJ)) {
+ char buf[32];
+ snprintf(buf, sizeof(buf), "%dC", o->audio_channels[o->nb_audio_channels - 1].u.i);
+ av_dict_set(&o->g->format_opts, "ch_layout", buf, 0);
+ }
+ }
+ if (o->nb_audio_ch_layouts) {
+ const AVClass *priv_class;
+ if (file_iformat && (priv_class = file_iformat->priv_class) &&
+ av_opt_find(&priv_class, "ch_layout", NULL, 0,
+ AV_OPT_SEARCH_FAKE_OBJ)) {
+ av_dict_set(&o->g->format_opts, "ch_layout", o->audio_ch_layouts[o->nb_audio_ch_layouts - 1].u.str, 0);
+ }
+ }
+ if (o->nb_frame_rates) {
+ const AVClass *priv_class;
+ /* set the format-level framerate option;
+ * this is important for video grabbers, e.g. x11 */
+ if (file_iformat && (priv_class = file_iformat->priv_class) &&
+ av_opt_find(&priv_class, "framerate", NULL, 0,
+ AV_OPT_SEARCH_FAKE_OBJ)) {
+ av_dict_set(&o->g->format_opts, "framerate",
+ o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
+ }
+ }
+ if (o->nb_frame_sizes) {
+ av_dict_set(&o->g->format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
+ }
+ if (o->nb_frame_pix_fmts)
+ av_dict_set(&o->g->format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
+
+ MATCH_PER_TYPE_OPT(codec_names, str, video_codec_name, ic, "v");
+ MATCH_PER_TYPE_OPT(codec_names, str, audio_codec_name, ic, "a");
+ MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, ic, "s");
+ MATCH_PER_TYPE_OPT(codec_names, str, data_codec_name, ic, "d");
+
+ if (video_codec_name)
+ ic->video_codec = find_codec_or_die(NULL, video_codec_name , AVMEDIA_TYPE_VIDEO , 0);
+ if (audio_codec_name)
+ ic->audio_codec = find_codec_or_die(NULL, audio_codec_name , AVMEDIA_TYPE_AUDIO , 0);
+ if (subtitle_codec_name)
+ ic->subtitle_codec = find_codec_or_die(NULL, subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0);
+ if (data_codec_name)
+ ic->data_codec = find_codec_or_die(NULL, data_codec_name , AVMEDIA_TYPE_DATA , 0);
+
+ ic->video_codec_id = video_codec_name ? ic->video_codec->id : AV_CODEC_ID_NONE;
+ ic->audio_codec_id = audio_codec_name ? ic->audio_codec->id : AV_CODEC_ID_NONE;
+ ic->subtitle_codec_id = subtitle_codec_name ? ic->subtitle_codec->id : AV_CODEC_ID_NONE;
+ ic->data_codec_id = data_codec_name ? ic->data_codec->id : AV_CODEC_ID_NONE;
+
+ ic->flags |= AVFMT_FLAG_NONBLOCK;
+ if (o->bitexact)
+ ic->flags |= AVFMT_FLAG_BITEXACT;
+ ic->interrupt_callback = int_cb;
+
+ if (!av_dict_get(o->g->format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
+ av_dict_set(&o->g->format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
+ scan_all_pmts_set = 1;
+ }
+ /* open the input file with generic avformat function */
+ err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
+ if (err < 0) {
+ print_error(filename, err);
+ if (err == AVERROR_PROTOCOL_NOT_FOUND)
+ av_log(NULL, AV_LOG_ERROR, "Did you mean file:%s?\n", filename);
+ exit_program(1);
+ }
+ if (scan_all_pmts_set)
+ av_dict_set(&o->g->format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
+ remove_avoptions(&o->g->format_opts, o->g->codec_opts);
+ assert_avoptions(o->g->format_opts);
+
+ /* apply forced codec ids */
+ for (i = 0; i < ic->nb_streams; i++)
+ choose_decoder(o, ic, ic->streams[i], HWACCEL_NONE, AV_HWDEVICE_TYPE_NONE);
+
+ if (o->find_stream_info) {
+ AVDictionary **opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
+ int orig_nb_streams = ic->nb_streams;
+
+ /* If not enough info to get the stream parameters, we decode the
+ first frames to get it. (used in mpeg case for example) */
+ ret = avformat_find_stream_info(ic, opts);
+
+ for (i = 0; i < orig_nb_streams; i++)
+ av_dict_free(&opts[i]);
+ av_freep(&opts);
+
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
+ if (ic->nb_streams == 0) {
+ avformat_close_input(&ic);
+ exit_program(1);
+ }
+ }
+ }
+
+ if (start_time != AV_NOPTS_VALUE && start_time_eof != AV_NOPTS_VALUE) {
+ av_log(NULL, AV_LOG_WARNING, "Cannot use -ss and -sseof both, using -ss for %s\n", filename);
+ start_time_eof = AV_NOPTS_VALUE;
+ }
+
+ if (start_time_eof != AV_NOPTS_VALUE) {
+ if (start_time_eof >= 0) {
+ av_log(NULL, AV_LOG_ERROR, "-sseof value must be negative; aborting\n");
+ exit_program(1);
+ }
+ if (ic->duration > 0) {
+ start_time = start_time_eof + ic->duration;
+ if (start_time < 0) {
+ av_log(NULL, AV_LOG_WARNING, "-sseof value seeks to before start of file %s; ignored\n", filename);
+ start_time = AV_NOPTS_VALUE;
+ }
+ } else
+ av_log(NULL, AV_LOG_WARNING, "Cannot use -sseof, duration of %s not known\n", filename);
+ }
+ timestamp = (start_time == AV_NOPTS_VALUE) ? 0 : start_time;
+ /* add the stream start time */
+ if (!o->seek_timestamp && ic->start_time != AV_NOPTS_VALUE)
+ timestamp += ic->start_time;
+
+ /* if seeking requested, we execute it */
+ if (start_time != AV_NOPTS_VALUE) {
+ int64_t seek_timestamp = timestamp;
+
+ if (!(ic->iformat->flags & AVFMT_SEEK_TO_PTS)) {
+ int dts_heuristic = 0;
+ for (i=0; inb_streams; i++) {
+ const AVCodecParameters *par = ic->streams[i]->codecpar;
+ if (par->video_delay) {
+ dts_heuristic = 1;
+ break;
+ }
+ }
+ if (dts_heuristic) {
+ seek_timestamp -= 3*AV_TIME_BASE / 23;
+ }
+ }
+ ret = avformat_seek_file(ic, -1, INT64_MIN, seek_timestamp, seek_timestamp, 0);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
+ filename, (double)timestamp / AV_TIME_BASE);
+ }
+ }
+
+ d = allocate_array_elem(&input_files, sizeof(*d), &nb_input_files);
+ f = &d->f;
+
+ f->ctx = ic;
+ f->index = nb_input_files - 1;
+ f->start_time = start_time;
+ f->recording_time = recording_time;
+ f->input_sync_ref = o->input_sync_ref;
+ f->input_ts_offset = o->input_ts_offset;
+ f->ts_offset = o->input_ts_offset - (copy_ts ? (start_at_zero && ic->start_time != AV_NOPTS_VALUE ? ic->start_time : 0) : timestamp);
+ f->rate_emu = o->rate_emu;
+ f->accurate_seek = o->accurate_seek;
+ d->loop = o->loop;
+ d->duration = 0;
+ d->time_base = (AVRational){ 1, 1 };
+
+ f->readrate = o->readrate ? o->readrate : 0.0;
+ if (f->readrate < 0.0f) {
+ av_log(NULL, AV_LOG_ERROR, "Option -readrate for Input #%d is %0.3f; it must be non-negative.\n", f->index, f->readrate);
+ exit_program(1);
+ }
+ if (f->readrate && f->rate_emu) {
+ av_log(NULL, AV_LOG_WARNING, "Both -readrate and -re set for Input #%d. Using -readrate %0.3f.\n", f->index, f->readrate);
+ f->rate_emu = 0;
+ }
+
+ d->thread_queue_size = o->thread_queue_size;
+
+ /* update the current parameters so that they match the one of the input stream */
+ add_input_streams(o, d);
+
+ /* dump the file content */
+ av_dump_format(ic, f->index, filename, 0);
+
+ /* check if all codec options have been used */
+ unused_opts = strip_specifiers(o->g->codec_opts);
+ for (i = 0; i < f->nb_streams; i++) {
+ e = NULL;
+ while ((e = av_dict_iterate(f->streams[i]->decoder_opts, e)))
+ av_dict_set(&unused_opts, e->key, NULL, 0);
+ }
+
+ e = NULL;
+ while ((e = av_dict_iterate(unused_opts, e))) {
+ const AVClass *class = avcodec_get_class();
+ const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
+ AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
+ const AVClass *fclass = avformat_get_class();
+ const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0,
+ AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
+ if (!option || foption)
+ continue;
+
+
+ if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) {
+ av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
+ "input file #%d (%s) is not a decoding option.\n", e->key,
+ option->help ? option->help : "", f->index,
+ filename);
+ exit_program(1);
+ }
+
+ av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
+ "input file #%d (%s) has not been used for any stream. The most "
+ "likely reason is either wrong type (e.g. a video option with "
+ "no video streams) or that it is a private option of some decoder "
+ "which was not actually used for any stream.\n", e->key,
+ option->help ? option->help : "", f->index, filename);
+ }
+ av_dict_free(&unused_opts);
+
+ for (i = 0; i < o->nb_dump_attachment; i++) {
+ int j;
+
+ for (j = 0; j < ic->nb_streams; j++) {
+ AVStream *st = ic->streams[j];
+
+ if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
+ dump_attachment(st, o->dump_attachment[i].u.str);
+ }
+ }
+
+ return 0;
+}
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 0845c631a..1f5bbf6c4 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -52,8 +52,9 @@ static const enum AVPixelFormat *get_compliance_normal_pix_fmts(const AVCodec *c
}
}
-static enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx,
- const AVCodec *codec, enum AVPixelFormat target)
+static enum AVPixelFormat
+choose_pixel_fmt(const AVCodec *codec, enum AVPixelFormat target,
+ int strict_std_compliance)
{
if (codec && codec->pix_fmts) {
const enum AVPixelFormat *p = codec->pix_fmts;
@@ -62,7 +63,7 @@ static enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx
int has_alpha = desc ? desc->nb_components % 2 == 0 : 0;
enum AVPixelFormat best= AV_PIX_FMT_NONE;
- if (enc_ctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
+ if (strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
p = get_compliance_normal_pix_fmts(codec, p);
}
for (; *p != AV_PIX_FMT_NONE; p++) {
@@ -89,6 +90,7 @@ static enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx
static const char *choose_pix_fmts(OutputFilter *ofilter, AVBPrint *bprint)
{
OutputStream *ost = ofilter->ost;
+ AVCodecContext *enc = ost->enc_ctx;
const AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, "strict", NULL, 0);
if (strict_dict)
// used by choose_pixel_fmt() and below
@@ -102,13 +104,14 @@ static const char *choose_pix_fmts(OutputFilter *ofilter, AVBPrint *bprint)
return av_get_pix_fmt_name(ost->enc_ctx->pix_fmt);
}
if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
- return av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc_ctx, ost->enc, ost->enc_ctx->pix_fmt));
- } else if (ost->enc && ost->enc->pix_fmts) {
+ return av_get_pix_fmt_name(choose_pixel_fmt(enc->codec, enc->pix_fmt,
+ ost->enc_ctx->strict_std_compliance));
+ } else if (enc->codec->pix_fmts) {
const enum AVPixelFormat *p;
- p = ost->enc->pix_fmts;
+ p = enc->codec->pix_fmts;
if (ost->enc_ctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
- p = get_compliance_normal_pix_fmts(ost->enc, p);
+ p = get_compliance_normal_pix_fmts(enc->codec, p);
}
for (; *p != AV_PIX_FMT_NONE; p++) {
@@ -116,7 +119,7 @@ static const char *choose_pix_fmts(OutputFilter *ofilter, AVBPrint *bprint)
av_bprintf(bprint, "%s%c", name, p[1] == AV_PIX_FMT_NONE ? '\0' : '|');
}
if (!av_bprint_is_complete(bprint))
- exit_program(1);
+ report_and_exit(AVERROR(ENOMEM));
return bprint->str;
} else
return NULL;
@@ -180,7 +183,7 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
InputFilter *ifilter;
if (!fg)
- exit_program(1);
+ report_and_exit(AVERROR(ENOMEM));
fg->index = nb_filtergraphs;
ofilter = ALLOC_ARRAY_ELEM(fg->outputs, fg->nb_outputs);
@@ -197,7 +200,7 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
ifilter->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
if (!ifilter->frame_queue)
- exit_program(1);
+ report_and_exit(AVERROR(ENOMEM));
GROW_ARRAY(ist->filters, ist->nb_filters);
ist->filters[ist->nb_filters - 1] = ifilter;
@@ -221,7 +224,7 @@ static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
res = av_asprintf("%s:%s", ctx->filter->name,
avfilter_pad_get_name(pads, inout->pad_idx));
if (!res)
- exit_program(1);
+ report_and_exit(AVERROR(ENOMEM));
return res;
}
@@ -268,7 +271,7 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
"matches no streams.\n", p, fg->graph_desc);
exit_program(1);
}
- ist = input_streams[input_files[file_idx]->ist_index + st->index];
+ ist = input_files[file_idx]->streams[st->index];
if (ist->user_set_discard == AVDISCARD_ALL) {
av_log(NULL, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s "
"matches a disabled input stream.\n", p, fg->graph_desc);
@@ -276,14 +279,13 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
}
} else {
/* find the first unused stream of corresponding type */
- for (i = 0; i < nb_input_streams; i++) {
- ist = input_streams[i];
+ for (ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
if (ist->user_set_discard == AVDISCARD_ALL)
continue;
if (ist->dec_ctx->codec_type == type && ist->discard)
break;
}
- if (i == nb_input_streams) {
+ if (!ist) {
av_log(NULL, AV_LOG_FATAL, "Cannot find a matching stream for "
"unlabeled input pad %d on filter %s\n", in->pad_idx,
in->filter_ctx->name);
@@ -306,12 +308,162 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
ifilter->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
if (!ifilter->frame_queue)
- exit_program(1);
+ report_and_exit(AVERROR(ENOMEM));
GROW_ARRAY(ist->filters, ist->nb_filters);
ist->filters[ist->nb_filters - 1] = ifilter;
}
+static int read_binary(const char *path, uint8_t **data, int *len)
+{
+ AVIOContext *io = NULL;
+ int64_t fsize;
+ int ret;
+
+ *data = NULL;
+ *len = 0;
+
+ ret = avio_open2(&io, path, AVIO_FLAG_READ, &int_cb, NULL);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Cannot open file '%s': %s\n",
+ path, av_err2str(ret));
+ return ret;
+ }
+
+ fsize = avio_size(io);
+ if (fsize < 0 || fsize > INT_MAX) {
+ av_log(NULL, AV_LOG_ERROR, "Cannot obtain size of file %s\n", path);
+ ret = AVERROR(EIO);
+ goto fail;
+ }
+
+ *data = av_malloc(fsize);
+ if (!*data) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ ret = avio_read(io, *data, fsize);
+ if (ret != fsize) {
+ av_log(NULL, AV_LOG_ERROR, "Error reading file %s\n", path);
+ ret = ret < 0 ? ret : AVERROR(EIO);
+ goto fail;
+ }
+
+ *len = fsize;
+
+ return 0;
+fail:
+ avio_close(io);
+ av_freep(data);
+ *len = 0;
+ return ret;
+}
+
+static int filter_opt_apply(AVFilterContext *f, const char *key, const char *val)
+{
+ const AVOption *o;
+ int ret;
+
+ ret = av_opt_set(f, key, val, AV_OPT_SEARCH_CHILDREN);
+ if (ret >= 0)
+ return 0;
+
+ if (ret == AVERROR_OPTION_NOT_FOUND && key[0] == '/')
+ o = av_opt_find(f, key + 1, NULL, 0, AV_OPT_SEARCH_CHILDREN);
+ if (!o)
+ goto err_apply;
+
+ // key is a valid option name prefixed with '/'
+ // interpret value as a path from which to load the actual option value
+ key++;
+
+ if (o->type == AV_OPT_TYPE_BINARY) {
+ uint8_t *data;
+ int len;
+
+ ret = read_binary(val, &data, &len);
+ if (ret < 0)
+ goto err_load;
+
+ ret = av_opt_set_bin(f, key, data, len, AV_OPT_SEARCH_CHILDREN);
+ av_freep(&data);
+ } else {
+ char *data = file_read(val);
+ if (!data) {
+ ret = AVERROR(EIO);
+ goto err_load;
+ }
+
+ ret = av_opt_set(f, key, data, AV_OPT_SEARCH_CHILDREN);
+ av_freep(&data);
+ }
+ if (ret < 0)
+ goto err_apply;
+
+ return 0;
+
+err_apply:
+ av_log(NULL, AV_LOG_ERROR,
+ "Error applying option '%s' to filter '%s': %s\n",
+ key, f->filter->name, av_err2str(ret));
+ return ret;
+err_load:
+ av_log(NULL, AV_LOG_ERROR,
+ "Error loading value for option '%s' from file '%s'\n",
+ key, val);
+ return ret;
+}
+
+static int graph_opts_apply(AVFilterGraphSegment *seg)
+{
+ for (size_t i = 0; i < seg->nb_chains; i++) {
+ AVFilterChain *ch = seg->chains[i];
+
+ for (size_t j = 0; j < ch->nb_filters; j++) {
+ AVFilterParams *p = ch->filters[j];
+ const AVDictionaryEntry *e = NULL;
+
+ av_assert0(p->filter);
+
+ while ((e = av_dict_iterate(p->opts, e))) {
+ int ret = filter_opt_apply(p->filter, e->key, e->value);
+ if (ret < 0)
+ return ret;
+ }
+
+ av_dict_free(&p->opts);
+ }
+ }
+
+ return 0;
+}
+
+static int graph_parse(AVFilterGraph *graph, const char *desc,
+ AVFilterInOut **inputs, AVFilterInOut **outputs)
+{
+ AVFilterGraphSegment *seg;
+ int ret;
+
+ ret = avfilter_graph_segment_parse(graph, desc, 0, &seg);
+ if (ret < 0)
+ return ret;
+
+ ret = avfilter_graph_segment_create_filters(seg, 0);
+ if (ret < 0)
+ goto fail;
+
+ ret = graph_opts_apply(seg);
+ if (ret < 0)
+ goto fail;
+
+ ret = avfilter_graph_segment_apply(seg, 0, inputs, outputs);
+
+fail:
+ avfilter_graph_segment_free(&seg);
+ return ret;
+}
+
int init_complex_filtergraph(FilterGraph *fg)
{
AVFilterInOut *inputs, *outputs, *cur;
@@ -325,7 +477,7 @@ int init_complex_filtergraph(FilterGraph *fg)
return AVERROR(ENOMEM);
graph->nb_threads = 1;
- ret = avfilter_graph_parse2(graph, fg->graph_desc, &inputs, &outputs);
+ ret = graph_parse(graph, fg->graph_desc, &inputs, &outputs);
if (ret < 0)
goto fail;
@@ -450,8 +602,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
snprintf(args, sizeof(args), "%d:%d",
ofilter->width, ofilter->height);
- while ((e = av_dict_get(ost->sws_dict, "", e,
- AV_DICT_IGNORE_SUFFIX))) {
+ while ((e = av_dict_iterate(ost->sws_dict, e))) {
av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
}
@@ -558,6 +709,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
pad_idx = 0; \
} while (0)
av_bprint_init(&args, 0, AV_BPRINT_SIZE_UNLIMITED);
+#if FFMPEG_OPT_MAP_CHANNEL
if (ost->audio_channels_mapped) {
AVChannelLayout mapped_layout = { 0 };
int i;
@@ -570,6 +722,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
AUTO_INSERT_FILTER("-map_channel", "pan", args.str);
av_bprint_clear(&args);
}
+#endif
if (codec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
av_channel_layout_default(&codec->ch_layout, codec->ch_layout.nb_channels);
@@ -603,11 +756,11 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
if (ost->apad && of->shortest) {
int i;
- for (i=0; ictx->nb_streams; i++)
- if (of->ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
+ for (i = 0; i < of->nb_streams; i++)
+ if (of->streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
break;
- if (ictx->nb_streams) {
+ if (i < of->nb_streams) {
AUTO_INSERT_FILTER("-apad", "apad", ost->apad);
}
}
@@ -734,7 +887,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
}
if (!fr.num)
- fr = av_guess_frame_rate(input_files[ist->file_index]->ctx, ist->st, NULL);
+ fr = ist->framerate_guessed;
if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
ret = sub2video_prepare(ist, ifilter);
@@ -887,40 +1040,6 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
last_filter = filt_ctx; \
} while (0)
- if (audio_sync_method > 0) {
- char args[256] = {0};
-
- av_strlcatf(args, sizeof(args), "async=%d", audio_sync_method);
- if (audio_drift_threshold != 0.1)
- av_strlcatf(args, sizeof(args), ":min_hard_comp=%f", audio_drift_threshold);
- if (!fg->reconfiguration)
- av_strlcatf(args, sizeof(args), ":first_pts=0");
- AUTO_INSERT_FILTER_INPUT("-async", "aresample", args);
- }
-
-// if (ost->audio_channels_mapped) {
-// int i;
-// AVBPrint pan_buf;
-// av_bprint_init(&pan_buf, 256, 8192);
-// av_bprintf(&pan_buf, "0x%"PRIx64,
-// av_get_default_channel_layout(ost->audio_channels_mapped));
-// for (i = 0; i < ost->audio_channels_mapped; i++)
-// if (ost->audio_channels_map[i] != -1)
-// av_bprintf(&pan_buf, ":c%d=c%d", i, ost->audio_channels_map[i]);
-// AUTO_INSERT_FILTER_INPUT("-map_channel", "pan", pan_buf.str);
-// av_bprint_finalize(&pan_buf, NULL);
-// }
-
- if (audio_volume != 256) {
- char args[256];
-
- av_log(NULL, AV_LOG_WARNING, "-vol has been deprecated. Use the volume "
- "audio filter instead.\n");
-
- snprintf(args, sizeof(args), "%f", audio_volume / 256.);
- AUTO_INSERT_FILTER_INPUT("-vol", "volume", args);
- }
-
snprintf(name, sizeof(name), "trim for input stream %d:%d",
ist->file_index, ist->st->index);
if (copy_ts) {
@@ -1003,44 +1122,39 @@ int configure_filtergraph(FilterGraph *fg)
if (simple) {
OutputStream *ost = fg->outputs[0]->ost;
- char args[512];
- const AVDictionaryEntry *e = NULL;
if (filter_nbthreads) {
ret = av_opt_set(fg->graph, "threads", filter_nbthreads, 0);
if (ret < 0)
goto fail;
} else {
+ const AVDictionaryEntry *e = NULL;
e = av_dict_get(ost->encoder_opts, "threads", NULL, 0);
if (e)
av_opt_set(fg->graph, "threads", e->value, 0);
}
- args[0] = 0;
- e = NULL;
- while ((e = av_dict_get(ost->sws_dict, "", e,
- AV_DICT_IGNORE_SUFFIX))) {
- av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
- }
- if (strlen(args)) {
- args[strlen(args)-1] = 0;
- fg->graph->scale_sws_opts = av_strdup(args);
+ if (av_dict_count(ost->sws_dict)) {
+ ret = av_dict_get_string(ost->sws_dict,
+ &fg->graph->scale_sws_opts,
+ '=', ':');
+ if (ret < 0)
+ goto fail;
}
- args[0] = 0;
- e = NULL;
- while ((e = av_dict_get(ost->swr_opts, "", e,
- AV_DICT_IGNORE_SUFFIX))) {
- av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
+ if (av_dict_count(ost->swr_opts)) {
+ char *args;
+ ret = av_dict_get_string(ost->swr_opts, &args, '=', ':');
+ if (ret < 0)
+ goto fail;
+ av_opt_set(fg->graph, "aresample_swr_opts", args, 0);
+ av_free(args);
}
- if (strlen(args))
- args[strlen(args)-1] = 0;
- av_opt_set(fg->graph, "aresample_swr_opts", args, 0);
} else {
fg->graph->nb_threads = filter_complex_nbthreads;
}
- if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
+ if ((ret = graph_parse(fg->graph, graph_desc, &inputs, &outputs)) < 0)
goto fail;
ret = hw_device_setup_for_filter(fg);
@@ -1114,16 +1228,8 @@ int configure_filtergraph(FilterGraph *fg)
for (i = 0; i < fg->nb_outputs; i++) {
OutputStream *ost = fg->outputs[i]->ost;
- if (!ost->enc) {
- /* identical to the same check in ffmpeg.c, needed because
- complex filter graphs are initialized earlier */
- av_log(NULL, AV_LOG_ERROR, "Encoder (codec %s) not found for output stream #%d:%d\n",
- avcodec_get_name(ost->st->codecpar->codec_id), ost->file_index, ost->index);
- ret = AVERROR(EINVAL);
- goto fail;
- }
- if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
- !(ost->enc->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE))
+ if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO &&
+ !(ost->enc_ctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE))
av_buffersink_set_frame_size(ost->filter->filter,
ost->enc_ctx->frame_size);
}
diff --git a/fftools/ffmpeg_hw.c b/fftools/ffmpeg_hw.c
index 14e702bd9..88fa78247 100644
--- a/fftools/ffmpeg_hw.c
+++ b/fftools/ffmpeg_hw.c
@@ -339,7 +339,7 @@ int hw_device_setup_for_decode(InputStream *ist)
if (ist->hwaccel_id == HWACCEL_AUTO) {
ist->hwaccel_device_type = dev->type;
} else if (ist->hwaccel_device_type != dev->type) {
- av_log(ist->dec_ctx, AV_LOG_ERROR, "Invalid hwaccel device "
+ av_log(NULL, AV_LOG_ERROR, "Invalid hwaccel device "
"specified for decoder: device %s of type %s is not "
"usable with hwaccel %s.\n", dev->name,
av_hwdevice_get_type_name(dev->type),
@@ -390,7 +390,7 @@ int hw_device_setup_for_decode(InputStream *ist)
type = config->device_type;
dev = hw_device_get_by_type(type);
if (dev) {
- av_log(ist->dec_ctx, AV_LOG_INFO, "Using auto "
+ av_log(NULL, AV_LOG_INFO, "Using auto "
"hwaccel type %s with existing device %s.\n",
av_hwdevice_get_type_name(type), dev->name);
}
@@ -408,12 +408,12 @@ int hw_device_setup_for_decode(InputStream *ist)
continue;
}
if (ist->hwaccel_device) {
- av_log(ist->dec_ctx, AV_LOG_INFO, "Using auto "
+ av_log(NULL, AV_LOG_INFO, "Using auto "
"hwaccel type %s with new device created "
"from %s.\n", av_hwdevice_get_type_name(type),
ist->hwaccel_device);
} else {
- av_log(ist->dec_ctx, AV_LOG_INFO, "Using auto "
+ av_log(NULL, AV_LOG_INFO, "Using auto "
"hwaccel type %s with new default device.\n",
av_hwdevice_get_type_name(type));
}
@@ -421,7 +421,7 @@ int hw_device_setup_for_decode(InputStream *ist)
if (dev) {
ist->hwaccel_device_type = type;
} else {
- av_log(ist->dec_ctx, AV_LOG_INFO, "Auto hwaccel "
+ av_log(NULL, AV_LOG_INFO, "Auto hwaccel "
"disabled: no device found.\n");
ist->hwaccel_id = HWACCEL_NONE;
return 0;
@@ -429,7 +429,7 @@ int hw_device_setup_for_decode(InputStream *ist)
}
if (!dev) {
- av_log(ist->dec_ctx, AV_LOG_ERROR, "No device available "
+ av_log(NULL, AV_LOG_ERROR, "No device available "
"for decoder: device type %s needed for codec %s.\n",
av_hwdevice_get_type_name(type), ist->dec->name);
return err;
@@ -461,7 +461,7 @@ int hw_device_setup_for_encode(OutputStream *ost)
}
for (i = 0;; i++) {
- config = avcodec_get_hw_config(ost->enc, i);
+ config = avcodec_get_hw_config(ost->enc_ctx->codec, i);
if (!config)
break;
@@ -472,7 +472,7 @@ int hw_device_setup_for_encode(OutputStream *ost)
av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using input "
"frames context (format %s) with %s encoder.\n",
av_get_pix_fmt_name(ost->enc_ctx->pix_fmt),
- ost->enc->name);
+ ost->enc_ctx->codec->name);
ost->enc_ctx->hw_frames_ctx = av_buffer_ref(frames_ref);
if (!ost->enc_ctx->hw_frames_ctx)
return AVERROR(ENOMEM);
@@ -487,7 +487,7 @@ int hw_device_setup_for_encode(OutputStream *ost)
if (dev) {
av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using device %s "
"(type %s) with %s encoder.\n", dev->name,
- av_hwdevice_get_type_name(dev->type), ost->enc->name);
+ av_hwdevice_get_type_name(dev->type), ost->enc_ctx->codec->name);
ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
if (!ost->enc_ctx->hw_device_ctx)
return AVERROR(ENOMEM);
diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c
index a55fd18f8..cf5805194 100644
--- a/fftools/ffmpeg_mux.c
+++ b/fftools/ffmpeg_mux.c
@@ -16,100 +16,78 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include
#include
#include
#include "ffmpeg.h"
+#include "ffmpeg_mux.h"
+#include "objpool.h"
+#include "sync_queue.h"
+#include "thread_queue.h"
#include "libavutil/fifo.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/mem.h"
#include "libavutil/timestamp.h"
+#include "libavutil/thread.h"
#include "libavcodec/packet.h"
#include "libavformat/avformat.h"
#include "libavformat/avio.h"
-static void close_all_output_streams(OutputStream *ost, OSTFinished this_stream, OSTFinished others)
+int want_sdp = 1;
+
+static Muxer *mux_from_of(OutputFile *of)
{
- int i;
- for (i = 0; i < nb_output_streams; i++) {
- OutputStream *ost2 = output_streams[i];
- ost2->finished |= ost == ost2 ? this_stream : others;
- }
+ return (Muxer*)of;
}
-void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
- int unqueue)
+static int64_t filesize(AVIOContext *pb)
{
- AVFormatContext *s = of->ctx;
+ int64_t ret = -1;
+
+ if (pb) {
+ ret = avio_size(pb);
+ if (ret <= 0) // FIXME improve avio_size() so it works with non seekable output too
+ ret = avio_tell(pb);
+ }
+
+ return ret;
+}
+
+static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
+{
+ MuxStream *ms = ms_from_ost(ost);
+ AVFormatContext *s = mux->fc;
AVStream *st = ost->st;
+ int64_t fs;
+ uint64_t frame_num;
int ret;
- /*
- * Audio encoders may split the packets -- #frames in != #packets out.
- * But there is no reordering, so we can limit the number of output packets
- * by simply dropping them here.
- * Counting encoded video frames needs to be done separately because of
- * reordering, see do_video_out().
- * Do not count the packet when unqueued because it has been counted when queued.
- */
- if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed) && !unqueue) {
- if (ost->frame_number >= ost->max_frames) {
- av_packet_unref(pkt);
- return;
- }
- ost->frame_number++;
+ fs = filesize(s->pb);
+ atomic_store(&mux->last_filesize, fs);
+ if (fs >= mux->limit_filesize) {
+ ret = AVERROR_EOF;
+ goto fail;
}
- if (!of->header_written) {
- AVPacket *tmp_pkt;
- /* the muxer is not initialized yet, buffer the packet */
- if (!av_fifo_can_write(ost->muxing_queue)) {
- size_t cur_size = av_fifo_can_read(ost->muxing_queue);
- unsigned int are_we_over_size =
- (ost->muxing_queue_data_size + pkt->size) > ost->muxing_queue_data_threshold;
- size_t limit = are_we_over_size ? ost->max_muxing_queue_size : SIZE_MAX;
- size_t new_size = FFMIN(2 * cur_size, limit);
-
- if (new_size <= cur_size) {
- av_log(NULL, AV_LOG_ERROR,
- "Too many packets buffered for output stream %d:%d.\n",
- ost->file_index, ost->st->index);
- exit_program(1);
- }
- ret = av_fifo_grow2(ost->muxing_queue, new_size - cur_size);
- if (ret < 0)
- exit_program(1);
- }
- ret = av_packet_make_refcounted(pkt);
- if (ret < 0)
- exit_program(1);
- tmp_pkt = av_packet_alloc();
- if (!tmp_pkt)
- exit_program(1);
- av_packet_move_ref(tmp_pkt, pkt);
- ost->muxing_queue_data_size += tmp_pkt->size;
- av_fifo_write(ost->muxing_queue, &tmp_pkt, 1);
- return;
- }
-
- if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP) ||
- (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0))
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP)
pkt->pts = pkt->dts = AV_NOPTS_VALUE;
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
if (ost->frame_rate.num && ost->is_cfr) {
if (pkt->duration > 0)
- av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
+ av_log(ost, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate),
- ost->mux_timebase);
+ pkt->time_base);
}
}
- av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base);
+ av_packet_rescale_ts(pkt, pkt->time_base, ost->st->time_base);
+ pkt->time_base = ost->st->time_base;
if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
if (pkt->dts != AV_NOPTS_VALUE &&
@@ -119,25 +97,26 @@ void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
pkt->dts, pkt->pts,
ost->file_index, ost->st->index);
pkt->pts =
- pkt->dts = pkt->pts + pkt->dts + ost->last_mux_dts + 1
- - FFMIN3(pkt->pts, pkt->dts, ost->last_mux_dts + 1)
- - FFMAX3(pkt->pts, pkt->dts, ost->last_mux_dts + 1);
+ pkt->dts = pkt->pts + pkt->dts + ms->last_mux_dts + 1
+ - FFMIN3(pkt->pts, pkt->dts, ms->last_mux_dts + 1)
+ - FFMAX3(pkt->pts, pkt->dts, ms->last_mux_dts + 1);
}
if ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) &&
pkt->dts != AV_NOPTS_VALUE &&
- ost->last_mux_dts != AV_NOPTS_VALUE) {
- int64_t max = ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
+ ms->last_mux_dts != AV_NOPTS_VALUE) {
+ int64_t max = ms->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
if (pkt->dts < max) {
int loglevel = max - pkt->dts > 2 || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
if (exit_on_error)
loglevel = AV_LOG_ERROR;
av_log(s, loglevel, "Non-monotonous DTS in output stream "
"%d:%d; previous: %"PRId64", current: %"PRId64"; ",
- ost->file_index, ost->st->index, ost->last_mux_dts, pkt->dts);
+ ost->file_index, ost->st->index, ms->last_mux_dts, pkt->dts);
if (exit_on_error) {
- av_log(NULL, AV_LOG_FATAL, "aborting.\n");
- exit_program(1);
+ ret = AVERROR(EINVAL);
+ goto fail;
}
+
av_log(s, loglevel, "changing to %"PRId64". This may result "
"in incorrect timestamps in the output file.\n",
max);
@@ -147,17 +126,17 @@ void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
}
}
}
- ost->last_mux_dts = pkt->dts;
+ ms->last_mux_dts = pkt->dts;
- ost->data_size += pkt->size;
- ost->packets_written++;
+ ost->data_size_mux += pkt->size;
+ frame_num = atomic_fetch_add(&ost->packets_written, 1);
pkt->stream_index = ost->index;
if (debug_ts) {
- av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
+ av_log(ost, AV_LOG_INFO, "muxer <- type:%s "
"pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s size:%d\n",
- av_get_media_type_string(ost->enc_ctx->codec_type),
+ av_get_media_type_string(st->codecpar->codec_type),
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ost->st->time_base),
@@ -165,12 +144,307 @@ void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
);
}
+ if (ms->stats.io)
+ enc_stats_write(ost, &ms->stats, NULL, pkt, frame_num);
+
ret = av_interleaved_write_frame(s, pkt);
if (ret < 0) {
print_error("av_interleaved_write_frame()", ret);
- main_return_code = 1;
- close_all_output_streams(ost, MUXER_FINISHED | ENCODER_FINISHED, ENCODER_FINISHED);
+ goto fail;
}
+
+ return 0;
+fail:
+ av_packet_unref(pkt);
+ return ret;
+}
+
+static int sync_queue_process(Muxer *mux, OutputStream *ost, AVPacket *pkt, int *stream_eof)
+{
+ OutputFile *of = &mux->of;
+
+ if (ost->sq_idx_mux >= 0) {
+ int ret = sq_send(mux->sq_mux, ost->sq_idx_mux, SQPKT(pkt));
+ if (ret < 0) {
+ if (ret == AVERROR_EOF)
+ *stream_eof = 1;
+
+ return ret;
+ }
+
+ while (1) {
+ ret = sq_receive(mux->sq_mux, -1, SQPKT(mux->sq_pkt));
+ if (ret < 0)
+ return (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) ? 0 : ret;
+
+ ret = write_packet(mux, of->streams[ret],
+ mux->sq_pkt);
+ if (ret < 0)
+ return ret;
+ }
+ } else if (pkt)
+ return write_packet(mux, ost, pkt);
+
+ return 0;
+}
+
+static void thread_set_name(OutputFile *of)
+{
+ char name[16];
+ snprintf(name, sizeof(name), "mux%d:%s", of->index, of->format->name);
+ ff_thread_setname(name);
+}
+
+static void *muxer_thread(void *arg)
+{
+ Muxer *mux = arg;
+ OutputFile *of = &mux->of;
+ AVPacket *pkt = NULL;
+ int ret = 0;
+
+ pkt = av_packet_alloc();
+ if (!pkt) {
+ ret = AVERROR(ENOMEM);
+ goto finish;
+ }
+
+ thread_set_name(of);
+
+ while (1) {
+ OutputStream *ost;
+ int stream_idx, stream_eof = 0;
+
+ ret = tq_receive(mux->tq, &stream_idx, pkt);
+ if (stream_idx < 0) {
+ av_log(mux, AV_LOG_VERBOSE, "All streams finished\n");
+ ret = 0;
+ break;
+ }
+
+ ost = of->streams[stream_idx];
+ ret = sync_queue_process(mux, ost, ret < 0 ? NULL : pkt, &stream_eof);
+ av_packet_unref(pkt);
+ if (ret == AVERROR_EOF && stream_eof)
+ tq_receive_finish(mux->tq, stream_idx);
+ else if (ret < 0) {
+ av_log(mux, AV_LOG_ERROR, "Error muxing a packet\n");
+ break;
+ }
+ }
+
+finish:
+ av_packet_free(&pkt);
+
+ for (unsigned int i = 0; i < mux->fc->nb_streams; i++)
+ tq_receive_finish(mux->tq, i);
+
+ av_log(mux, AV_LOG_VERBOSE, "Terminating muxer thread\n");
+
+ return (void*)(intptr_t)ret;
+}
+
+static int thread_submit_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
+{
+ int ret = 0;
+
+ if (!pkt || ost->finished & MUXER_FINISHED)
+ goto finish;
+
+ ret = tq_send(mux->tq, ost->index, pkt);
+ if (ret < 0)
+ goto finish;
+
+ return 0;
+
+finish:
+ if (pkt)
+ av_packet_unref(pkt);
+
+ ost->finished |= MUXER_FINISHED;
+ tq_send_finish(mux->tq, ost->index);
+ return ret == AVERROR_EOF ? 0 : ret;
+}
+
+static int queue_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
+{
+ MuxStream *ms = ms_from_ost(ost);
+ AVPacket *tmp_pkt = NULL;
+ int ret;
+
+ if (!av_fifo_can_write(ms->muxing_queue)) {
+ size_t cur_size = av_fifo_can_read(ms->muxing_queue);
+ size_t pkt_size = pkt ? pkt->size : 0;
+ unsigned int are_we_over_size =
+ (ms->muxing_queue_data_size + pkt_size) > ms->muxing_queue_data_threshold;
+ size_t limit = are_we_over_size ? ms->max_muxing_queue_size : SIZE_MAX;
+ size_t new_size = FFMIN(2 * cur_size, limit);
+
+ if (new_size <= cur_size) {
+ av_log(ost, AV_LOG_ERROR,
+ "Too many packets buffered for output stream %d:%d.\n",
+ ost->file_index, ost->st->index);
+ return AVERROR(ENOSPC);
+ }
+ ret = av_fifo_grow2(ms->muxing_queue, new_size - cur_size);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (pkt) {
+ ret = av_packet_make_refcounted(pkt);
+ if (ret < 0)
+ return ret;
+
+ tmp_pkt = av_packet_alloc();
+ if (!tmp_pkt)
+ return AVERROR(ENOMEM);
+
+ av_packet_move_ref(tmp_pkt, pkt);
+ ms->muxing_queue_data_size += tmp_pkt->size;
+ }
+ av_fifo_write(ms->muxing_queue, &tmp_pkt, 1);
+
+ return 0;
+}
+
+static int submit_packet(Muxer *mux, AVPacket *pkt, OutputStream *ost)
+{
+ int ret;
+
+ if (mux->tq) {
+ return thread_submit_packet(mux, ost, pkt);
+ } else {
+ /* the muxer is not initialized yet, buffer the packet */
+ ret = queue_packet(mux, ost, pkt);
+ if (ret < 0) {
+ if (pkt)
+ av_packet_unref(pkt);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+void of_output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int eof)
+{
+ Muxer *mux = mux_from_of(of);
+ MuxStream *ms = ms_from_ost(ost);
+ const char *err_msg;
+ int ret = 0;
+
+ if (!eof && pkt->dts != AV_NOPTS_VALUE)
+ ost->last_mux_dts = av_rescale_q(pkt->dts, pkt->time_base, AV_TIME_BASE_Q);
+
+ /* apply the output bitstream filters */
+ if (ms->bsf_ctx) {
+ int bsf_eof = 0;
+
+ ret = av_bsf_send_packet(ms->bsf_ctx, eof ? NULL : pkt);
+ if (ret < 0) {
+ err_msg = "submitting a packet for bitstream filtering";
+ goto fail;
+ }
+
+ while (!bsf_eof) {
+ ret = av_bsf_receive_packet(ms->bsf_ctx, pkt);
+ if (ret == AVERROR(EAGAIN))
+ return;
+ else if (ret == AVERROR_EOF)
+ bsf_eof = 1;
+ else if (ret < 0) {
+ err_msg = "applying bitstream filters to a packet";
+ goto fail;
+ }
+
+ ret = submit_packet(mux, bsf_eof ? NULL : pkt, ost);
+ if (ret < 0)
+ goto mux_fail;
+ }
+ } else {
+ ret = submit_packet(mux, eof ? NULL : pkt, ost);
+ if (ret < 0)
+ goto mux_fail;
+ }
+
+ return;
+
+mux_fail:
+ err_msg = "submitting a packet to the muxer";
+
+fail:
+ av_log(ost, AV_LOG_ERROR, "Error %s\n", err_msg);
+ if (exit_on_error)
+ exit_program(1);
+
+}
+
+static int thread_stop(Muxer *mux)
+{
+ void *ret;
+
+ if (!mux || !mux->tq)
+ return 0;
+
+ for (unsigned int i = 0; i < mux->fc->nb_streams; i++)
+ tq_send_finish(mux->tq, i);
+
+ pthread_join(mux->thread, &ret);
+
+ tq_free(&mux->tq);
+
+ return (int)(intptr_t)ret;
+}
+
+static void pkt_move(void *dst, void *src)
+{
+ av_packet_move_ref(dst, src);
+}
+
+static int thread_start(Muxer *mux)
+{
+ AVFormatContext *fc = mux->fc;
+ ObjPool *op;
+ int ret;
+
+ op = objpool_alloc_packets();
+ if (!op)
+ return AVERROR(ENOMEM);
+
+ mux->tq = tq_alloc(fc->nb_streams, mux->thread_queue_size, op, pkt_move);
+ if (!mux->tq) {
+ objpool_free(&op);
+ return AVERROR(ENOMEM);
+ }
+
+ ret = pthread_create(&mux->thread, NULL, muxer_thread, (void*)mux);
+ if (ret) {
+ tq_free(&mux->tq);
+ return AVERROR(ret);
+ }
+
+ /* flush the muxing queues */
+ for (int i = 0; i < fc->nb_streams; i++) {
+ OutputStream *ost = mux->of.streams[i];
+ MuxStream *ms = ms_from_ost(ost);
+ AVPacket *pkt;
+
+ /* try to improve muxing time_base (only possible if nothing has been written yet) */
+ if (!av_fifo_can_read(ms->muxing_queue))
+ ost->mux_timebase = ost->st->time_base;
+
+ while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0) {
+ ret = thread_submit_packet(mux, ost, pkt);
+ if (pkt) {
+ ms->muxing_queue_data_size -= pkt->size;
+ av_packet_free(&pkt);
+ }
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ return 0;
}
static int print_sdp(void)
@@ -182,16 +456,16 @@ static int print_sdp(void)
AVFormatContext **avc;
for (i = 0; i < nb_output_files; i++) {
- if (!output_files[i]->header_written)
+ if (!mux_from_of(output_files[i])->header_written)
return 0;
}
avc = av_malloc_array(nb_output_files, sizeof(*avc));
if (!avc)
- exit_program(1);
+ return AVERROR(ENOMEM);
for (i = 0, j = 0; i < nb_output_files; i++) {
- if (!strcmp(output_files[i]->ctx->oformat->name, "rtp")) {
- avc[j] = output_files[i]->ctx;
+ if (!strcmp(output_files[i]->format->name, "rtp")) {
+ avc[j] = mux_from_of(output_files[i])->fc;
j++;
}
}
@@ -221,34 +495,36 @@ static int print_sdp(void)
av_freep(&sdp_filename);
}
+ // SDP successfully written, allow muxer threads to start
+ ret = 1;
+
fail:
av_freep(&avc);
return ret;
}
-/* open the muxer when all the streams are initialized */
-int of_check_init(OutputFile *of)
+int mux_check_init(Muxer *mux)
{
+ OutputFile *of = &mux->of;
+ AVFormatContext *fc = mux->fc;
int ret, i;
- for (i = 0; i < of->ctx->nb_streams; i++) {
- OutputStream *ost = output_streams[of->ost_index + i];
+ for (i = 0; i < fc->nb_streams; i++) {
+ OutputStream *ost = of->streams[i];
if (!ost->initialized)
return 0;
}
- ret = avformat_write_header(of->ctx, &of->opts);
+ ret = avformat_write_header(fc, &mux->opts);
if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR,
- "Could not write header for output file #%d "
- "(incorrect codec parameters ?): %s\n",
- of->index, av_err2str(ret));
+ av_log(mux, AV_LOG_ERROR, "Could not write header (incorrect codec "
+ "parameters ?): %s\n", av_err2str(ret));
return ret;
}
//assert_avoptions(of->opts);
- of->header_written = 1;
+ mux->header_written = 1;
- av_dump_format(of->ctx, of->index, of->ctx->url, 1);
+ av_dump_format(fc, of->index, fc->url, 1);
nb_output_dumped++;
if (sdp_filename || want_sdp) {
@@ -256,62 +532,220 @@ int of_check_init(OutputFile *of)
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error writing the SDP.\n");
return ret;
+ } else if (ret == 1) {
+ /* SDP is written only after all the muxers are ready, so now we
+ * start ALL the threads */
+ for (i = 0; i < nb_output_files; i++) {
+ ret = thread_start(mux_from_of(output_files[i]));
+ if (ret < 0)
+ return ret;
+ }
}
+ } else {
+ ret = thread_start(mux_from_of(of));
+ if (ret < 0)
+ return ret;
}
- /* flush the muxing queues */
- for (i = 0; i < of->ctx->nb_streams; i++) {
- OutputStream *ost = output_streams[of->ost_index + i];
- AVPacket *pkt;
+ return 0;
+}
- /* try to improve muxing time_base (only possible if nothing has been written yet) */
- if (!av_fifo_can_read(ost->muxing_queue))
- ost->mux_timebase = ost->st->time_base;
+static int bsf_init(MuxStream *ms)
+{
+ OutputStream *ost = &ms->ost;
+ AVBSFContext *ctx = ms->bsf_ctx;
+ int ret;
- while (av_fifo_read(ost->muxing_queue, &pkt, 1) >= 0) {
- ost->muxing_queue_data_size -= pkt->size;
- of_write_packet(of, pkt, ost, 1);
- av_packet_free(&pkt);
+ if (!ctx)
+ return 0;
+
+ ret = avcodec_parameters_copy(ctx->par_in, ost->st->codecpar);
+ if (ret < 0)
+ return ret;
+
+ ctx->time_base_in = ost->st->time_base;
+
+ ret = av_bsf_init(ctx);
+ if (ret < 0) {
+ av_log(ms, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n",
+ ctx->filter->name);
+ return ret;
+ }
+
+ ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out);
+ if (ret < 0)
+ return ret;
+ ost->st->time_base = ctx->time_base_out;
+
+ return 0;
+}
+
+int of_stream_init(OutputFile *of, OutputStream *ost)
+{
+ Muxer *mux = mux_from_of(of);
+ MuxStream *ms = ms_from_ost(ost);
+ int ret;
+
+ if (ost->sq_idx_mux >= 0)
+ sq_set_tb(mux->sq_mux, ost->sq_idx_mux, ost->mux_timebase);
+
+ /* initialize bitstream filters for the output stream
+ * needs to be done here, because the codec id for streamcopy is not
+ * known until now */
+ ret = bsf_init(ms);
+ if (ret < 0)
+ return ret;
+
+ ost->initialized = 1;
+
+ return mux_check_init(mux);
+}
+
+int of_write_trailer(OutputFile *of)
+{
+ Muxer *mux = mux_from_of(of);
+ AVFormatContext *fc = mux->fc;
+ int ret;
+
+ if (!mux->tq) {
+ av_log(mux, AV_LOG_ERROR,
+ "Nothing was written into output file, because "
+ "at least one of its streams received no packets.\n");
+ return AVERROR(EINVAL);
+ }
+
+ ret = thread_stop(mux);
+ if (ret < 0)
+ main_return_code = ret;
+
+ ret = av_write_trailer(fc);
+ if (ret < 0) {
+ av_log(mux, AV_LOG_ERROR, "Error writing trailer: %s\n", av_err2str(ret));
+ return ret;
+ }
+
+ mux->last_filesize = filesize(fc->pb);
+
+ if (!(of->format->flags & AVFMT_NOFILE)) {
+ ret = avio_closep(&fc->pb);
+ if (ret < 0) {
+ av_log(mux, AV_LOG_ERROR, "Error closing file: %s\n", av_err2str(ret));
+ return ret;
}
}
return 0;
}
-int of_write_trailer(OutputFile *of)
+static void ost_free(OutputStream **post)
{
- int ret;
+ OutputStream *ost = *post;
+ MuxStream *ms;
- if (!of->header_written) {
- av_log(NULL, AV_LOG_ERROR,
- "Nothing was written into output file %d (%s), because "
- "at least one of its streams received no packets.\n",
- of->index, of->ctx->url);
- return AVERROR(EINVAL);
+ if (!ost)
+ return;
+ ms = ms_from_ost(ost);
+
+ if (ost->logfile) {
+ if (fclose(ost->logfile))
+ av_log(ms, AV_LOG_ERROR,
+ "Error closing logfile, loss of information possible: %s\n",
+ av_err2str(AVERROR(errno)));
+ ost->logfile = NULL;
}
- ret = av_write_trailer(of->ctx);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", of->ctx->url, av_err2str(ret));
- return ret;
+ if (ms->muxing_queue) {
+ AVPacket *pkt;
+ while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0)
+ av_packet_free(&pkt);
+ av_fifo_freep2(&ms->muxing_queue);
}
- return 0;
+ av_bsf_free(&ms->bsf_ctx);
+
+ av_frame_free(&ost->filtered_frame);
+ av_frame_free(&ost->sq_frame);
+ av_frame_free(&ost->last_frame);
+ av_packet_free(&ost->pkt);
+ av_dict_free(&ost->encoder_opts);
+
+ av_freep(&ost->kf.pts);
+ av_expr_free(ost->kf.pexpr);
+
+ av_freep(&ost->avfilter);
+ av_freep(&ost->logfile_prefix);
+ av_freep(&ost->apad);
+
+#if FFMPEG_OPT_MAP_CHANNEL
+ av_freep(&ost->audio_channels_map);
+ ost->audio_channels_mapped = 0;
+#endif
+
+ av_dict_free(&ost->sws_dict);
+ av_dict_free(&ost->swr_opts);
+
+ if (ost->enc_ctx)
+ av_freep(&ost->enc_ctx->stats_in);
+ avcodec_free_context(&ost->enc_ctx);
+
+ for (int i = 0; i < ost->enc_stats_pre.nb_components; i++)
+ av_freep(&ost->enc_stats_pre.components[i].str);
+ av_freep(&ost->enc_stats_pre.components);
+
+ for (int i = 0; i < ost->enc_stats_post.nb_components; i++)
+ av_freep(&ost->enc_stats_post.components[i].str);
+ av_freep(&ost->enc_stats_post.components);
+
+ for (int i = 0; i < ms->stats.nb_components; i++)
+ av_freep(&ms->stats.components[i].str);
+ av_freep(&ms->stats.components);
+
+ av_freep(post);
+}
+
+static void fc_close(AVFormatContext **pfc)
+{
+ AVFormatContext *fc = *pfc;
+
+ if (!fc)
+ return;
+
+ if (!(fc->oformat->flags & AVFMT_NOFILE))
+ avio_closep(&fc->pb);
+ avformat_free_context(fc);
+
+ *pfc = NULL;
}
void of_close(OutputFile **pof)
{
OutputFile *of = *pof;
- AVFormatContext *s;
+ Muxer *mux;
if (!of)
return;
+ mux = mux_from_of(of);
- s = of->ctx;
- if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE))
- avio_closep(&s->pb);
- avformat_free_context(s);
- av_dict_free(&of->opts);
+ thread_stop(mux);
+
+ sq_free(&of->sq_encode);
+ sq_free(&mux->sq_mux);
+
+ for (int i = 0; i < of->nb_streams; i++)
+ ost_free(&of->streams[i]);
+ av_freep(&of->streams);
+
+ av_dict_free(&mux->opts);
+
+ av_packet_free(&mux->sq_pkt);
+
+ fc_close(&mux->fc);
av_freep(pof);
}
+
+int64_t of_filesize(OutputFile *of)
+{
+ Muxer *mux = mux_from_of(of);
+ return atomic_load(&mux->last_filesize);
+}
diff --git a/fftools/ffmpeg_mux.h b/fftools/ffmpeg_mux.h
new file mode 100644
index 000000000..c76dc2e52
--- /dev/null
+++ b/fftools/ffmpeg_mux.h
@@ -0,0 +1,102 @@
+/*
+ * Muxer internal APIs - should not be included outside of ffmpeg_mux*
+ *
+ * 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_MUX_H
+#define FFTOOLS_FFMPEG_MUX_H
+
+#include
+#include
+
+#include "thread_queue.h"
+
+#include "libavformat/avformat.h"
+
+#include "libavcodec/packet.h"
+
+#include "libavutil/dict.h"
+#include "libavutil/fifo.h"
+#include "libavutil/thread.h"
+
+typedef struct MuxStream {
+ OutputStream ost;
+
+ // name used for logging
+ char log_name[32];
+
+ /* the packets are buffered here until the muxer is ready to be initialized */
+ AVFifo *muxing_queue;
+
+ AVBSFContext *bsf_ctx;
+
+ EncStats stats;
+
+ int64_t max_frames;
+
+ /*
+ * The size of the AVPackets' buffers in queue.
+ * Updated when a packet is either pushed or pulled from the queue.
+ */
+ size_t muxing_queue_data_size;
+
+ int max_muxing_queue_size;
+
+ /* Threshold after which max_muxing_queue_size will be in effect */
+ size_t muxing_queue_data_threshold;
+
+ /* dts of the last packet sent to the muxer, in the stream timebase
+ * used for making up missing dts values */
+ int64_t last_mux_dts;
+} MuxStream;
+
+typedef struct Muxer {
+ OutputFile of;
+
+ // name used for logging
+ char log_name[32];
+
+ AVFormatContext *fc;
+
+ pthread_t thread;
+ ThreadQueue *tq;
+
+ AVDictionary *opts;
+
+ int thread_queue_size;
+
+ /* filesize limit expressed in bytes */
+ int64_t limit_filesize;
+ atomic_int_least64_t last_filesize;
+ int header_written;
+
+ SyncQueue *sq_mux;
+ AVPacket *sq_pkt;
+} Muxer;
+
+/* whether we want to print an SDP, set in of_open() */
+extern int want_sdp;
+
+int mux_check_init(Muxer *mux);
+
+static MuxStream *ms_from_ost(OutputStream *ost)
+{
+ return (MuxStream*)ost;
+}
+
+#endif /* FFTOOLS_FFMPEG_MUX_H */
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
new file mode 100644
index 000000000..b3cc502fd
--- /dev/null
+++ b/fftools/ffmpeg_mux_init.c
@@ -0,0 +1,2400 @@
+/*
+ * Muxer/output file setup.
+ *
+ * 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
+
+#include "cmdutils.h"
+#include "ffmpeg.h"
+#include "ffmpeg_mux.h"
+#include "fopen_utf8.h"
+
+#include "libavformat/avformat.h"
+#include "libavformat/avio.h"
+
+#include "libavcodec/avcodec.h"
+
+#include "libavfilter/avfilter.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/avutil.h"
+#include "libavutil/bprint.h"
+#include "libavutil/dict.h"
+#include "libavutil/getenv_utf8.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/log.h"
+#include "libavutil/mem.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+
+#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
+
+static const char *const opt_name_apad[] = {"apad", NULL};
+static const char *const opt_name_autoscale[] = {"autoscale", NULL};
+static const char *const opt_name_bits_per_raw_sample[] = {"bits_per_raw_sample", NULL};
+static const char *const opt_name_bitstream_filters[] = {"bsf", "absf", "vbsf", NULL};
+static const char *const opt_name_copy_initial_nonkeyframes[] = {"copyinkf", NULL};
+static const char *const opt_name_copy_prior_start[] = {"copypriorss", NULL};
+static const char *const opt_name_disposition[] = {"disposition", NULL};
+static const char *const opt_name_enc_time_bases[] = {"enc_time_base", NULL};
+static const char *const opt_name_enc_stats_pre[] = {"enc_stats_pre", NULL};
+static const char *const opt_name_enc_stats_post[] = {"enc_stats_post", NULL};
+static const char *const opt_name_mux_stats[] = {"mux_stats", NULL};
+static const char *const opt_name_enc_stats_pre_fmt[] = {"enc_stats_pre_fmt", NULL};
+static const char *const opt_name_enc_stats_post_fmt[] = {"enc_stats_post_fmt", NULL};
+static const char *const opt_name_mux_stats_fmt[] = {"mux_stats_fmt", NULL};
+static const char *const opt_name_filters[] = {"filter", "af", "vf", NULL};
+static const char *const opt_name_filter_scripts[] = {"filter_script", NULL};
+static const char *const opt_name_fix_sub_duration_heartbeat[] = {"fix_sub_duration_heartbeat", NULL};
+static const char *const opt_name_fps_mode[] = {"fps_mode", NULL};
+static const char *const opt_name_force_fps[] = {"force_fps", NULL};
+static const char *const opt_name_forced_key_frames[] = {"forced_key_frames", NULL};
+static const char *const opt_name_frame_aspect_ratios[] = {"aspect", NULL};
+static const char *const opt_name_intra_matrices[] = {"intra_matrix", NULL};
+static const char *const opt_name_inter_matrices[] = {"inter_matrix", NULL};
+static const char *const opt_name_chroma_intra_matrices[] = {"chroma_intra_matrix", NULL};
+static const char *const opt_name_max_frame_rates[] = {"fpsmax", NULL};
+static const char *const opt_name_max_frames[] = {"frames", "aframes", "vframes", "dframes", NULL};
+static const char *const opt_name_max_muxing_queue_size[] = {"max_muxing_queue_size", NULL};
+static const char *const opt_name_muxing_queue_data_threshold[] = {"muxing_queue_data_threshold", NULL};
+static const char *const opt_name_pass[] = {"pass", NULL};
+static const char *const opt_name_passlogfiles[] = {"passlogfile", NULL};
+static const char *const opt_name_presets[] = {"pre", "apre", "vpre", "spre", NULL};
+static const char *const opt_name_qscale[] = {"q", "qscale", NULL};
+static const char *const opt_name_rc_overrides[] = {"rc_override", NULL};
+static const char *const opt_name_time_bases[] = {"time_base", NULL};
+static const char *const opt_name_audio_channels[] = {"ac", NULL};
+static const char *const opt_name_audio_ch_layouts[] = {"channel_layout", "ch_layout", NULL};
+static const char *const opt_name_audio_sample_rate[] = {"ar", NULL};
+static const char *const opt_name_frame_sizes[] = {"s", NULL};
+static const char *const opt_name_frame_pix_fmts[] = {"pix_fmt", NULL};
+static const char *const opt_name_sample_fmts[] = {"sample_fmt", NULL};
+
+static int check_opt_bitexact(void *ctx, const AVDictionary *opts,
+ const char *opt_name, int flag)
+{
+ const AVDictionaryEntry *e = av_dict_get(opts, opt_name, NULL, 0);
+
+ if (e) {
+ const AVOption *o = av_opt_find(ctx, opt_name, NULL, 0, 0);
+ int val = 0;
+ if (!o)
+ return 0;
+ av_opt_eval_flags(ctx, o, e->value, &val);
+ return !!(val & flag);
+ }
+ return 0;
+}
+
+static int choose_encoder(const OptionsContext *o, AVFormatContext *s,
+ OutputStream *ost, const AVCodec **enc)
+{
+ enum AVMediaType type = ost->st->codecpar->codec_type;
+ char *codec_name = NULL;
+
+ *enc = NULL;
+
+ if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO || type == AVMEDIA_TYPE_SUBTITLE) {
+ MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
+ if (!codec_name) {
+ ost->st->codecpar->codec_id = av_guess_codec(s->oformat, NULL, s->url,
+ NULL, ost->st->codecpar->codec_type);
+ *enc = avcodec_find_encoder(ost->st->codecpar->codec_id);
+ if (!*enc) {
+ av_log(ost, AV_LOG_FATAL, "Automatic encoder selection failed "
+ "Default encoder for format %s (codec %s) is "
+ "probably disabled. Please choose an encoder manually.\n",
+ s->oformat->name, avcodec_get_name(ost->st->codecpar->codec_id));
+ return AVERROR_ENCODER_NOT_FOUND;
+ }
+ } else if (strcmp(codec_name, "copy")) {
+ *enc = find_codec_or_die(ost, codec_name, ost->st->codecpar->codec_type, 1);
+ ost->st->codecpar->codec_id = (*enc)->id;
+ }
+ }
+
+ return 0;
+}
+
+static char *get_line(AVIOContext *s, AVBPrint *bprint)
+{
+ char c;
+
+ while ((c = avio_r8(s)) && c != '\n')
+ av_bprint_chars(bprint, c, 1);
+
+ if (!av_bprint_is_complete(bprint))
+ report_and_exit(AVERROR(ENOMEM));
+ return bprint->str;
+}
+
+static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
+{
+ int i, ret = -1;
+ char filename[1000];
+ char *env_avconv_datadir = getenv_utf8("AVCONV_DATADIR");
+ char *env_home = getenv_utf8("HOME");
+ const char *base[3] = { env_avconv_datadir,
+ env_home,
+ AVCONV_DATADIR,
+ };
+
+ for (i = 0; i < FF_ARRAY_ELEMS(base) && ret < 0; i++) {
+ if (!base[i])
+ continue;
+ if (codec_name) {
+ snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
+ i != 1 ? "" : "/.avconv", codec_name, preset_name);
+ ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
+ }
+ if (ret < 0) {
+ snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
+ i != 1 ? "" : "/.avconv", preset_name);
+ ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
+ }
+ }
+ freeenv_utf8(env_home);
+ freeenv_utf8(env_avconv_datadir);
+ return ret;
+}
+
+typedef struct EncStatsFile {
+ char *path;
+ AVIOContext *io;
+} EncStatsFile;
+
+static EncStatsFile *enc_stats_files;
+static int nb_enc_stats_files;
+
+static int enc_stats_get_file(AVIOContext **io, const char *path)
+{
+ EncStatsFile *esf;
+ int ret;
+
+ for (int i = 0; i < nb_enc_stats_files; i++)
+ if (!strcmp(path, enc_stats_files[i].path)) {
+ *io = enc_stats_files[i].io;
+ return 0;
+ }
+
+ GROW_ARRAY(enc_stats_files, nb_enc_stats_files);
+
+ esf = &enc_stats_files[nb_enc_stats_files - 1];
+
+ ret = avio_open2(&esf->io, path, AVIO_FLAG_WRITE, &int_cb, NULL);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Error opening stats file '%s': %s\n",
+ path, av_err2str(ret));
+ return ret;
+ }
+
+ esf->path = av_strdup(path);
+ if (!esf->path)
+ return AVERROR(ENOMEM);
+
+ *io = esf->io;
+
+ return 0;
+}
+
+void of_enc_stats_close(void)
+{
+ for (int i = 0; i < nb_enc_stats_files; i++) {
+ av_freep(&enc_stats_files[i].path);
+ avio_closep(&enc_stats_files[i].io);
+ }
+ av_freep(&enc_stats_files);
+ nb_enc_stats_files = 0;
+}
+
+static int unescape(char **pdst, size_t *dst_len,
+ const char **pstr, char delim)
+{
+ const char *str = *pstr;
+ char *dst;
+ size_t len, idx;
+
+ *pdst = NULL;
+
+ len = strlen(str);
+ if (!len)
+ return 0;
+
+ dst = av_malloc(len + 1);
+ if (!dst)
+ return AVERROR(ENOMEM);
+
+ for (idx = 0; *str; idx++, str++) {
+ if (str[0] == '\\' && str[1])
+ str++;
+ else if (*str == delim)
+ break;
+
+ dst[idx] = *str;
+ }
+ if (!idx) {
+ av_freep(&dst);
+ return 0;
+ }
+
+ dst[idx] = 0;
+
+ *pdst = dst;
+ *dst_len = idx;
+ *pstr = str;
+
+ return 0;
+}
+
+static int enc_stats_init(OutputStream *ost, EncStats *es, int pre,
+ const char *path, const char *fmt_spec)
+{
+ static const struct {
+ enum EncStatsType type;
+ const char *str;
+ int pre_only:1;
+ int post_only:1;
+ int need_input_data:1;
+ } fmt_specs[] = {
+ { ENC_STATS_FILE_IDX, "fidx" },
+ { ENC_STATS_STREAM_IDX, "sidx" },
+ { ENC_STATS_FRAME_NUM, "n" },
+ { ENC_STATS_FRAME_NUM_IN, "ni", 0, 0, 1 },
+ { ENC_STATS_TIMEBASE, "tb" },
+ { ENC_STATS_TIMEBASE_IN, "tbi", 0, 0, 1 },
+ { ENC_STATS_PTS, "pts" },
+ { ENC_STATS_PTS_TIME, "t" },
+ { ENC_STATS_PTS_IN, "ptsi", 0, 0, 1 },
+ { ENC_STATS_PTS_TIME_IN, "ti", 0, 0, 1 },
+ { ENC_STATS_DTS, "dts", 0, 1 },
+ { ENC_STATS_DTS_TIME, "dt", 0, 1 },
+ { ENC_STATS_SAMPLE_NUM, "sn", 1 },
+ { ENC_STATS_NB_SAMPLES, "samp", 1 },
+ { ENC_STATS_PKT_SIZE, "size", 0, 1 },
+ { ENC_STATS_BITRATE, "br", 0, 1 },
+ { ENC_STATS_AVG_BITRATE, "abr", 0, 1 },
+ };
+ const char *next = fmt_spec;
+
+ int ret;
+
+ while (*next) {
+ EncStatsComponent *c;
+ char *val;
+ size_t val_len;
+
+ // get the sequence up until next opening brace
+ ret = unescape(&val, &val_len, &next, '{');
+ if (ret < 0)
+ return ret;
+
+ if (val) {
+ GROW_ARRAY(es->components, es->nb_components);
+
+ c = &es->components[es->nb_components - 1];
+ c->type = ENC_STATS_LITERAL;
+ c->str = val;
+ c->str_len = val_len;
+ }
+
+ if (!*next)
+ break;
+ next++;
+
+ // get the part inside braces
+ ret = unescape(&val, &val_len, &next, '}');
+ if (ret < 0)
+ return ret;
+
+ if (!val) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Empty formatting directive in: %s\n", fmt_spec);
+ return AVERROR(EINVAL);
+ }
+
+ if (!*next) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Missing closing brace in: %s\n", fmt_spec);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ next++;
+
+ GROW_ARRAY(es->components, es->nb_components);
+ c = &es->components[es->nb_components - 1];
+
+ for (size_t i = 0; i < FF_ARRAY_ELEMS(fmt_specs); i++) {
+ if (!strcmp(val, fmt_specs[i].str)) {
+ if ((pre && fmt_specs[i].post_only) || (!pre && fmt_specs[i].pre_only)) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Format directive '%s' may only be used %s-encoding\n",
+ val, pre ? "post" : "pre");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ c->type = fmt_specs[i].type;
+
+ if (fmt_specs[i].need_input_data) {
+ if (ost->ist)
+ ost->ist->want_frame_data = 1;
+ else {
+ av_log(ost, AV_LOG_WARNING,
+ "Format directive '%s' is unavailable, because "
+ "this output stream has no associated input stream\n",
+ val);
+ }
+ }
+
+ break;
+ }
+ }
+
+ if (!c->type) {
+ av_log(NULL, AV_LOG_ERROR, "Invalid format directive: %s\n", val);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+fail:
+ av_freep(&val);
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = enc_stats_get_file(&es->io, path);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static const char *output_stream_item_name(void *obj)
+{
+ const MuxStream *ms = obj;
+
+ return ms->log_name;
+}
+
+static const AVClass output_stream_class = {
+ .class_name = "OutputStream",
+ .version = LIBAVUTIL_VERSION_INT,
+ .item_name = output_stream_item_name,
+ .category = AV_CLASS_CATEGORY_MUXER,
+};
+
+static MuxStream *mux_stream_alloc(Muxer *mux, enum AVMediaType type)
+{
+ const char *type_str = av_get_media_type_string(type);
+ MuxStream *ms = allocate_array_elem(&mux->of.streams, sizeof(*ms),
+ &mux->of.nb_streams);
+
+ ms->ost.file_index = mux->of.index;
+ ms->ost.index = mux->of.nb_streams - 1;
+
+ ms->ost.class = &output_stream_class;
+
+ snprintf(ms->log_name, sizeof(ms->log_name), "%cost#%d:%d",
+ type_str ? *type_str : '?', mux->of.index, ms->ost.index);
+
+ return ms;
+}
+
+static OutputStream *new_output_stream(Muxer *mux, const OptionsContext *o,
+ enum AVMediaType type, InputStream *ist)
+{
+ AVFormatContext *oc = mux->fc;
+ MuxStream *ms;
+ OutputStream *ost;
+ const AVCodec *enc;
+ AVStream *st = avformat_new_stream(oc, NULL);
+ int ret = 0;
+ const char *bsfs = NULL, *time_base = NULL;
+ char *next, *codec_tag = NULL;
+ double qscale = -1;
+ int i;
+
+ if (!st)
+ report_and_exit(AVERROR(ENOMEM));
+
+ if (oc->nb_streams - 1 < o->nb_streamid_map)
+ st->id = o->streamid_map[oc->nb_streams - 1];
+
+ ms = mux_stream_alloc(mux, type);
+ ost = &ms->ost;
+
+ ms->muxing_queue = av_fifo_alloc2(8, sizeof(AVPacket*), 0);
+ if (!ms->muxing_queue)
+ report_and_exit(AVERROR(ENOMEM));
+ ms->last_mux_dts = AV_NOPTS_VALUE;
+
+ ost->st = st;
+ ost->ist = ist;
+ ost->kf.ref_pts = AV_NOPTS_VALUE;
+ st->codecpar->codec_type = type;
+
+ ret = choose_encoder(o, oc, ost, &enc);
+ if (ret < 0) {
+ av_log(ost, AV_LOG_FATAL, "Error selecting an encoder\n");
+ exit_program(1);
+ }
+
+ if (enc) {
+ ost->enc_ctx = avcodec_alloc_context3(enc);
+ if (!ost->enc_ctx)
+ report_and_exit(AVERROR(ENOMEM));
+
+ av_strlcat(ms->log_name, "/", sizeof(ms->log_name));
+ av_strlcat(ms->log_name, enc->name, sizeof(ms->log_name));
+ } else {
+ av_strlcat(ms->log_name, "/copy", sizeof(ms->log_name));
+ }
+
+ ost->filtered_frame = av_frame_alloc();
+ if (!ost->filtered_frame)
+ report_and_exit(AVERROR(ENOMEM));
+
+ ost->pkt = av_packet_alloc();
+ if (!ost->pkt)
+ report_and_exit(AVERROR(ENOMEM));
+
+ if (ost->enc_ctx) {
+ AVCodecContext *enc = ost->enc_ctx;
+ AVIOContext *s = NULL;
+ char *buf = NULL, *arg = NULL, *preset = NULL;
+ const char *enc_stats_pre = NULL, *enc_stats_post = NULL, *mux_stats = NULL;
+
+ ost->encoder_opts = filter_codec_opts(o->g->codec_opts, enc->codec_id,
+ oc, st, enc->codec);
+
+ MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
+ ost->autoscale = 1;
+ MATCH_PER_STREAM_OPT(autoscale, i, ost->autoscale, oc, st);
+ if (preset && (!(ret = get_preset_file_2(preset, enc->codec->name, &s)))) {
+ AVBPrint bprint;
+ av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
+ do {
+ av_bprint_clear(&bprint);
+ buf = get_line(s, &bprint);
+ if (!buf[0] || buf[0] == '#')
+ continue;
+ if (!(arg = strchr(buf, '='))) {
+ av_log(ost, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
+ exit_program(1);
+ }
+ *arg++ = 0;
+ av_dict_set(&ost->encoder_opts, buf, arg, AV_DICT_DONT_OVERWRITE);
+ } while (!s->eof_reached);
+ av_bprint_finalize(&bprint, NULL);
+ avio_closep(&s);
+ }
+ if (ret) {
+ av_log(ost, AV_LOG_FATAL,
+ "Preset %s specified, but could not be opened.\n", preset);
+ exit_program(1);
+ }
+
+ MATCH_PER_STREAM_OPT(enc_stats_pre, str, enc_stats_pre, oc, st);
+ if (enc_stats_pre &&
+ (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) {
+ const char *format = "{fidx} {sidx} {n} {t}";
+
+ MATCH_PER_STREAM_OPT(enc_stats_pre_fmt, str, format, oc, st);
+
+ ret = enc_stats_init(ost, &ost->enc_stats_pre, 1, enc_stats_pre, format);
+ if (ret < 0)
+ exit_program(1);
+ }
+
+ MATCH_PER_STREAM_OPT(enc_stats_post, str, enc_stats_post, oc, st);
+ if (enc_stats_post &&
+ (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) {
+ const char *format = "{fidx} {sidx} {n} {t}";
+
+ MATCH_PER_STREAM_OPT(enc_stats_post_fmt, str, format, oc, st);
+
+ ret = enc_stats_init(ost, &ost->enc_stats_post, 0, enc_stats_post, format);
+ if (ret < 0)
+ exit_program(1);
+ }
+
+ MATCH_PER_STREAM_OPT(mux_stats, str, mux_stats, oc, st);
+ if (mux_stats &&
+ (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) {
+ const char *format = "{fidx} {sidx} {n} {t}";
+
+ MATCH_PER_STREAM_OPT(mux_stats_fmt, str, format, oc, st);
+
+ ret = enc_stats_init(ost, &ms->stats, 0, mux_stats, format);
+ if (ret < 0)
+ exit_program(1);
+ }
+ } else {
+ ost->encoder_opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL);
+ }
+
+
+ if (o->bitexact) {
+ ost->bitexact = 1;
+ } else if (ost->enc_ctx) {
+ ost->bitexact = check_opt_bitexact(ost->enc_ctx, ost->encoder_opts, "flags",
+ AV_CODEC_FLAG_BITEXACT);
+ }
+
+ MATCH_PER_STREAM_OPT(time_bases, str, time_base, oc, st);
+ if (time_base) {
+ AVRational q;
+ if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 ||
+ q.num <= 0 || q.den <= 0) {
+ av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", time_base);
+ exit_program(1);
+ }
+ st->time_base = q;
+ }
+
+ MATCH_PER_STREAM_OPT(enc_time_bases, str, time_base, oc, st);
+ if (time_base) {
+ AVRational q;
+ if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 ||
+ q.den <= 0) {
+ av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", time_base);
+ exit_program(1);
+ }
+ ost->enc_timebase = q;
+ }
+
+ ms->max_frames = INT64_MAX;
+ MATCH_PER_STREAM_OPT(max_frames, i64, ms->max_frames, oc, st);
+ for (i = 0; inb_max_frames; i++) {
+ char *p = o->max_frames[i].specifier;
+ if (!*p && type != AVMEDIA_TYPE_VIDEO) {
+ av_log(ost, AV_LOG_WARNING, "Applying unspecific -frames to non video streams, maybe you meant -vframes ?\n");
+ break;
+ }
+ }
+
+ ost->copy_prior_start = -1;
+ MATCH_PER_STREAM_OPT(copy_prior_start, i, ost->copy_prior_start, oc ,st);
+
+ MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st);
+ if (bsfs && *bsfs) {
+ ret = av_bsf_list_parse_str(bsfs, &ms->bsf_ctx);
+ if (ret < 0) {
+ av_log(ost, AV_LOG_ERROR, "Error parsing bitstream filter sequence '%s': %s\n", bsfs, av_err2str(ret));
+ exit_program(1);
+ }
+ }
+
+ MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
+ if (codec_tag) {
+ uint32_t tag = strtol(codec_tag, &next, 0);
+ if (*next)
+ tag = AV_RL32(codec_tag);
+ ost->st->codecpar->codec_tag = tag;
+ if (ost->enc_ctx)
+ ost->enc_ctx->codec_tag = tag;
+ }
+
+ MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
+ if (ost->enc_ctx && qscale >= 0) {
+ ost->enc_ctx->flags |= AV_CODEC_FLAG_QSCALE;
+ ost->enc_ctx->global_quality = FF_QP2LAMBDA * qscale;
+ }
+
+ ms->max_muxing_queue_size = 128;
+ MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ms->max_muxing_queue_size, oc, st);
+
+ ms->muxing_queue_data_threshold = 50*1024*1024;
+ MATCH_PER_STREAM_OPT(muxing_queue_data_threshold, i, ms->muxing_queue_data_threshold, oc, st);
+
+ MATCH_PER_STREAM_OPT(bits_per_raw_sample, i, ost->bits_per_raw_sample,
+ oc, st);
+
+ MATCH_PER_STREAM_OPT(fix_sub_duration_heartbeat, i, ost->fix_sub_duration_heartbeat,
+ oc, st);
+
+ if (oc->oformat->flags & AVFMT_GLOBALHEADER && ost->enc_ctx)
+ ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
+
+ av_dict_copy(&ost->sws_dict, o->g->sws_dict, 0);
+
+ av_dict_copy(&ost->swr_opts, o->g->swr_opts, 0);
+ if (ost->enc_ctx && av_get_exact_bits_per_sample(ost->enc_ctx->codec_id) == 24)
+ av_dict_set(&ost->swr_opts, "output_sample_bits", "24", 0);
+
+ if (ost->ist) {
+ ost->ist->discard = 0;
+ ost->ist->st->discard = ost->ist->user_set_discard;
+ }
+ ost->last_mux_dts = AV_NOPTS_VALUE;
+ ost->last_filter_pts = AV_NOPTS_VALUE;
+
+ MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i,
+ ost->copy_initial_nonkeyframes, oc, st);
+
+ return ost;
+}
+
+static char *get_ost_filters(const OptionsContext *o, AVFormatContext *oc,
+ OutputStream *ost)
+{
+ AVStream *st = ost->st;
+
+ if (ost->filters_script && ost->filters) {
+ av_log(ost, AV_LOG_ERROR, "Both -filter and -filter_script set\n");
+ exit_program(1);
+ }
+
+ if (ost->filters_script)
+ return file_read(ost->filters_script);
+ else if (ost->filters)
+ return av_strdup(ost->filters);
+
+ return av_strdup(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ?
+ "null" : "anull");
+}
+
+static void check_streamcopy_filters(const OptionsContext *o, AVFormatContext *oc,
+ OutputStream *ost, enum AVMediaType type)
+{
+ if (ost->filters_script || ost->filters) {
+ av_log(ost, AV_LOG_ERROR,
+ "%s '%s' was defined, but codec copy was selected.\n"
+ "Filtering and streamcopy cannot be used together.\n",
+ ost->filters ? "Filtergraph" : "Filtergraph script",
+ ost->filters ? ost->filters : ost->filters_script);
+ exit_program(1);
+ }
+}
+
+static void parse_matrix_coeffs(void *logctx, uint16_t *dest, const char *str)
+{
+ int i;
+ const char *p = str;
+ for (i = 0;; i++) {
+ dest[i] = atoi(p);
+ if (i == 63)
+ break;
+ p = strchr(p, ',');
+ if (!p) {
+ av_log(logctx, AV_LOG_FATAL,
+ "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
+ exit_program(1);
+ }
+ p++;
+ }
+}
+
+static OutputStream *new_video_stream(Muxer *mux, const OptionsContext *o, InputStream *ist)
+{
+ AVFormatContext *oc = mux->fc;
+ AVStream *st;
+ OutputStream *ost;
+ char *frame_rate = NULL, *max_frame_rate = NULL, *frame_aspect_ratio = NULL;
+
+ ost = new_output_stream(mux, o, AVMEDIA_TYPE_VIDEO, ist);
+ st = ost->st;
+
+ MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
+ if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
+ av_log(ost, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
+ exit_program(1);
+ }
+
+ MATCH_PER_STREAM_OPT(max_frame_rates, str, max_frame_rate, oc, st);
+ if (max_frame_rate && av_parse_video_rate(&ost->max_frame_rate, max_frame_rate) < 0) {
+ av_log(ost, AV_LOG_FATAL, "Invalid maximum framerate value: %s\n", max_frame_rate);
+ exit_program(1);
+ }
+
+ if (frame_rate && max_frame_rate) {
+ av_log(ost, AV_LOG_ERROR, "Only one of -fpsmax and -r can be set for a stream.\n");
+ exit_program(1);
+ }
+
+ MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
+ if (frame_aspect_ratio) {
+ AVRational q;
+ if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 ||
+ q.num <= 0 || q.den <= 0) {
+ av_log(ost, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio);
+ exit_program(1);
+ }
+ ost->frame_aspect_ratio = q;
+ }
+
+ MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
+ MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
+
+ if (ost->enc_ctx) {
+ AVCodecContext *video_enc = ost->enc_ctx;
+ const char *p = NULL, *fps_mode = NULL;
+ char *frame_size = NULL;
+ char *frame_pix_fmt = NULL;
+ char *intra_matrix = NULL, *inter_matrix = NULL;
+ char *chroma_intra_matrix = NULL;
+ int do_pass = 0;
+ int i;
+
+ MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
+ if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
+ av_log(ost, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
+ exit_program(1);
+ }
+
+ MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
+ if (frame_pix_fmt && *frame_pix_fmt == '+') {
+ ost->keep_pix_fmt = 1;
+ if (!*++frame_pix_fmt)
+ frame_pix_fmt = NULL;
+ }
+ if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == AV_PIX_FMT_NONE) {
+ av_log(ost, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
+ exit_program(1);
+ }
+ st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
+
+ MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
+ if (intra_matrix) {
+ if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64)))
+ report_and_exit(AVERROR(ENOMEM));
+ parse_matrix_coeffs(ost, video_enc->intra_matrix, intra_matrix);
+ }
+ MATCH_PER_STREAM_OPT(chroma_intra_matrices, str, chroma_intra_matrix, oc, st);
+ if (chroma_intra_matrix) {
+ uint16_t *p = av_mallocz(sizeof(*video_enc->chroma_intra_matrix) * 64);
+ if (!p)
+ report_and_exit(AVERROR(ENOMEM));
+ video_enc->chroma_intra_matrix = p;
+ parse_matrix_coeffs(ost, p, chroma_intra_matrix);
+ }
+ MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
+ if (inter_matrix) {
+ if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64)))
+ report_and_exit(AVERROR(ENOMEM));
+ parse_matrix_coeffs(ost, video_enc->inter_matrix, inter_matrix);
+ }
+
+ MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
+ for (i = 0; p; i++) {
+ int start, end, q;
+ int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
+ if (e != 3) {
+ av_log(ost, AV_LOG_FATAL, "error parsing rc_override\n");
+ exit_program(1);
+ }
+ video_enc->rc_override =
+ av_realloc_array(video_enc->rc_override,
+ i + 1, sizeof(RcOverride));
+ if (!video_enc->rc_override) {
+ av_log(ost, AV_LOG_FATAL, "Could not (re)allocate memory for rc_override.\n");
+ exit_program(1);
+ }
+ video_enc->rc_override[i].start_frame = start;
+ video_enc->rc_override[i].end_frame = end;
+ if (q > 0) {
+ video_enc->rc_override[i].qscale = q;
+ video_enc->rc_override[i].quality_factor = 1.0;
+ }
+ else {
+ video_enc->rc_override[i].qscale = 0;
+ video_enc->rc_override[i].quality_factor = -q/100.0;
+ }
+ p = strchr(p, '/');
+ if (p) p++;
+ }
+ video_enc->rc_override_count = i;
+
+#if FFMPEG_OPT_PSNR
+ if (do_psnr) {
+ av_log(ost, AV_LOG_WARNING, "The -psnr option is deprecated, use -flags +psnr\n");
+ video_enc->flags|= AV_CODEC_FLAG_PSNR;
+ }
+#endif
+
+ /* two pass mode */
+ MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
+ if (do_pass) {
+ if (do_pass & 1) {
+ video_enc->flags |= AV_CODEC_FLAG_PASS1;
+ av_dict_set(&ost->encoder_opts, "flags", "+pass1", AV_DICT_APPEND);
+ }
+ if (do_pass & 2) {
+ video_enc->flags |= AV_CODEC_FLAG_PASS2;
+ av_dict_set(&ost->encoder_opts, "flags", "+pass2", AV_DICT_APPEND);
+ }
+ }
+
+ MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
+ if (ost->logfile_prefix &&
+ !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
+ report_and_exit(AVERROR(ENOMEM));
+
+ if (do_pass) {
+ int ost_idx = -1;
+ char logfilename[1024];
+ FILE *f;
+
+ /* compute this stream's global index */
+ for (int i = 0; i <= ost->file_index; i++)
+ ost_idx += output_files[i]->nb_streams;
+
+ snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
+ ost->logfile_prefix ? ost->logfile_prefix :
+ DEFAULT_PASS_LOGFILENAME_PREFIX,
+ ost_idx);
+ if (!strcmp(ost->enc_ctx->codec->name, "libx264")) {
+ av_dict_set(&ost->encoder_opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
+ } else {
+ if (video_enc->flags & AV_CODEC_FLAG_PASS2) {
+ char *logbuffer = file_read(logfilename);
+
+ if (!logbuffer) {
+ av_log(ost, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
+ logfilename);
+ exit_program(1);
+ }
+ video_enc->stats_in = logbuffer;
+ }
+ if (video_enc->flags & AV_CODEC_FLAG_PASS1) {
+ f = fopen_utf8(logfilename, "wb");
+ if (!f) {
+ av_log(ost, AV_LOG_FATAL,
+ "Cannot write log file '%s' for pass-1 encoding: %s\n",
+ logfilename, strerror(errno));
+ exit_program(1);
+ }
+ ost->logfile = f;
+ }
+ }
+ }
+
+ MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
+
+ ost->top_field_first = -1;
+ MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
+
+ ost->vsync_method = video_sync_method;
+ MATCH_PER_STREAM_OPT(fps_mode, str, fps_mode, oc, st);
+ if (fps_mode)
+ parse_and_set_vsync(fps_mode, &ost->vsync_method, ost->file_index, ost->index, 0);
+
+ if ((ost->frame_rate.num || ost->max_frame_rate.num) &&
+ !(ost->vsync_method == VSYNC_AUTO ||
+ ost->vsync_method == VSYNC_CFR || ost->vsync_method == VSYNC_VSCFR)) {
+ av_log(ost, AV_LOG_FATAL, "One of -r/-fpsmax was specified "
+ "together a non-CFR -vsync/-fps_mode. This is contradictory.\n");
+ exit_program(1);
+ }
+
+ if (ost->vsync_method == VSYNC_AUTO) {
+ if (ost->frame_rate.num || ost->max_frame_rate.num) {
+ ost->vsync_method = VSYNC_CFR;
+ } else if (!strcmp(oc->oformat->name, "avi")) {
+ ost->vsync_method = VSYNC_VFR;
+ } else {
+ ost->vsync_method = (oc->oformat->flags & AVFMT_VARIABLE_FPS) ?
+ ((oc->oformat->flags & AVFMT_NOTIMESTAMPS) ?
+ VSYNC_PASSTHROUGH : VSYNC_VFR) :
+ VSYNC_CFR;
+ }
+
+ if (ost->ist && ost->vsync_method == VSYNC_CFR) {
+ const InputFile *ifile = input_files[ost->ist->file_index];
+
+ if (ifile->nb_streams == 1 && ifile->input_ts_offset == 0)
+ ost->vsync_method = VSYNC_VSCFR;
+ }
+
+ if (ost->vsync_method == VSYNC_CFR && copy_ts) {
+ ost->vsync_method = VSYNC_VSCFR;
+ }
+ }
+ ost->is_cfr = (ost->vsync_method == VSYNC_CFR || ost->vsync_method == VSYNC_VSCFR);
+
+ ost->avfilter = get_ost_filters(o, oc, ost);
+ if (!ost->avfilter)
+ exit_program(1);
+
+ ost->last_frame = av_frame_alloc();
+ if (!ost->last_frame)
+ report_and_exit(AVERROR(ENOMEM));
+ } else
+ check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_VIDEO);
+
+ return ost;
+}
+
+static OutputStream *new_audio_stream(Muxer *mux, const OptionsContext *o, InputStream *ist)
+{
+ AVFormatContext *oc = mux->fc;
+ AVStream *st;
+ OutputStream *ost;
+
+ ost = new_output_stream(mux, o, AVMEDIA_TYPE_AUDIO, ist);
+ st = ost->st;
+
+
+ MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
+ MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
+
+ if (ost->enc_ctx) {
+ AVCodecContext *audio_enc = ost->enc_ctx;
+ int channels = 0;
+ char *layout = NULL;
+ char *sample_fmt = NULL;
+
+ MATCH_PER_STREAM_OPT(audio_channels, i, channels, oc, st);
+ if (channels) {
+ audio_enc->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
+ audio_enc->ch_layout.nb_channels = channels;
+ }
+
+ MATCH_PER_STREAM_OPT(audio_ch_layouts, str, layout, oc, st);
+ if (layout) {
+ if (av_channel_layout_from_string(&audio_enc->ch_layout, layout) < 0) {
+#if FF_API_OLD_CHANNEL_LAYOUT
+ uint64_t mask;
+ AV_NOWARN_DEPRECATED({
+ mask = av_get_channel_layout(layout);
+ })
+ if (!mask) {
+#endif
+ av_log(ost, AV_LOG_FATAL, "Unknown channel layout: %s\n", layout);
+ exit_program(1);
+#if FF_API_OLD_CHANNEL_LAYOUT
+ }
+ av_log(ost, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n",
+ layout);
+ av_channel_layout_from_mask(&audio_enc->ch_layout, mask);
+#endif
+ }
+ }
+
+ MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
+ if (sample_fmt &&
+ (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
+ av_log(ost, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
+ exit_program(1);
+ }
+
+ MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
+
+ MATCH_PER_STREAM_OPT(apad, str, ost->apad, oc, st);
+ ost->apad = av_strdup(ost->apad);
+
+ ost->avfilter = get_ost_filters(o, oc, ost);
+ if (!ost->avfilter)
+ exit_program(1);
+
+#if FFMPEG_OPT_MAP_CHANNEL
+ /* check for channel mapping for this audio stream */
+ for (int n = 0; n < o->nb_audio_channel_maps; n++) {
+ AudioChannelMap *map = &o->audio_channel_maps[n];
+ if ((map->ofile_idx == -1 || ost->file_index == map->ofile_idx) &&
+ (map->ostream_idx == -1 || ost->st->index == map->ostream_idx)) {
+ InputStream *ist;
+
+ if (map->channel_idx == -1) {
+ ist = NULL;
+ } else if (!ost->ist) {
+ av_log(ost, AV_LOG_FATAL, "Cannot determine input stream for channel mapping %d.%d\n",
+ ost->file_index, ost->st->index);
+ continue;
+ } else {
+ ist = ost->ist;
+ }
+
+ if (!ist || (ist->file_index == map->file_idx && ist->st->index == map->stream_idx)) {
+ if (av_reallocp_array(&ost->audio_channels_map,
+ ost->audio_channels_mapped + 1,
+ sizeof(*ost->audio_channels_map)
+ ) < 0 )
+ report_and_exit(AVERROR(ENOMEM));
+
+ ost->audio_channels_map[ost->audio_channels_mapped++] = map->channel_idx;
+ }
+ }
+ }
+#endif
+ } else
+ check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_AUDIO);
+
+ return ost;
+}
+
+static OutputStream *new_data_stream(Muxer *mux, const OptionsContext *o, InputStream *ist)
+{
+ OutputStream *ost;
+
+ ost = new_output_stream(mux, o, AVMEDIA_TYPE_DATA, ist);
+ if (ost->enc_ctx) {
+ av_log(ost, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
+ exit_program(1);
+ }
+
+ return ost;
+}
+
+static OutputStream *new_unknown_stream(Muxer *mux, const OptionsContext *o, InputStream *ist)
+{
+ OutputStream *ost;
+
+ ost = new_output_stream(mux, o, AVMEDIA_TYPE_UNKNOWN, ist);
+ if (ost->enc_ctx) {
+ av_log(ost, AV_LOG_FATAL, "Unknown stream encoding not supported yet (only streamcopy)\n");
+ exit_program(1);
+ }
+
+ return ost;
+}
+
+static OutputStream *new_attachment_stream(Muxer *mux, const OptionsContext *o, InputStream *ist)
+{
+ OutputStream *ost = new_output_stream(mux, o, AVMEDIA_TYPE_ATTACHMENT, ist);
+ ost->finished = 1;
+ return ost;
+}
+
+static OutputStream *new_subtitle_stream(Muxer *mux, const OptionsContext *o, InputStream *ist)
+{
+ AVStream *st;
+ OutputStream *ost;
+
+ ost = new_output_stream(mux, o, AVMEDIA_TYPE_SUBTITLE, ist);
+ st = ost->st;
+
+ if (ost->enc_ctx) {
+ AVCodecContext *subtitle_enc = ost->enc_ctx;
+ char *frame_size = NULL;
+
+ MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, mux->fc, st);
+ if (frame_size && av_parse_video_size(&subtitle_enc->width, &subtitle_enc->height, frame_size) < 0) {
+ av_log(ost, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
+ exit_program(1);
+ }
+ }
+
+ return ost;
+}
+
+static void init_output_filter(OutputFilter *ofilter, const OptionsContext *o,
+ Muxer *mux)
+{
+ OutputStream *ost;
+
+ switch (ofilter->type) {
+ case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(mux, o, NULL); break;
+ case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(mux, o, NULL); break;
+ default:
+ av_log(mux, AV_LOG_FATAL, "Only video and audio filters are supported "
+ "currently.\n");
+ exit_program(1);
+ }
+
+ ost->filter = ofilter;
+
+ ofilter->ost = ost;
+ ofilter->format = -1;
+
+ if (!ost->enc_ctx) {
+ av_log(ost, AV_LOG_ERROR, "Streamcopy requested for output stream fed "
+ "from a complex filtergraph. Filtering and streamcopy "
+ "cannot be used together.\n");
+ exit_program(1);
+ }
+
+ if (ost->avfilter && (ost->filters || ost->filters_script)) {
+ const char *opt = ost->filters ? "-vf/-af/-filter" : "-filter_script";
+ av_log(ost, AV_LOG_ERROR,
+ "%s '%s' was specified through the %s option "
+ "for output stream %d:%d, which is fed from a complex filtergraph.\n"
+ "%s and -filter_complex cannot be used together for the same stream.\n",
+ ost->filters ? "Filtergraph" : "Filtergraph script",
+ ost->filters ? ost->filters : ost->filters_script,
+ opt, ost->file_index, ost->index, opt);
+ exit_program(1);
+ }
+
+ avfilter_inout_free(&ofilter->out_tmp);
+}
+
+static void map_auto_video(Muxer *mux, const OptionsContext *o)
+{
+ AVFormatContext *oc = mux->fc;
+ InputStream *best_ist = NULL;
+ int best_score = 0;
+ int qcr;
+
+ /* video: highest resolution */
+ if (av_guess_codec(oc->oformat, NULL, oc->url, NULL, AVMEDIA_TYPE_VIDEO) == AV_CODEC_ID_NONE)
+ return;
+
+ qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);
+ for (int j = 0; j < nb_input_files; j++) {
+ InputFile *ifile = input_files[j];
+ InputStream *file_best_ist = NULL;
+ int file_best_score = 0;
+ for (int i = 0; i < ifile->nb_streams; i++) {
+ InputStream *ist = ifile->streams[i];
+ int score;
+
+ if (ist->user_set_discard == AVDISCARD_ALL ||
+ ist->st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
+ continue;
+
+ score = ist->st->codecpar->width * ist->st->codecpar->height
+ + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
+ + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
+ if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+ score = 1;
+
+ if (score > file_best_score) {
+ if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+ continue;
+ file_best_score = score;
+ file_best_ist = ist;
+ }
+ }
+ if (file_best_ist) {
+ if((qcr == MKTAG('A', 'P', 'I', 'C')) ||
+ !(file_best_ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+ file_best_score -= 5000000*!!(file_best_ist->st->disposition & AV_DISPOSITION_DEFAULT);
+ if (file_best_score > best_score) {
+ best_score = file_best_score;
+ best_ist = file_best_ist;
+ }
+ }
+ }
+ if (best_ist)
+ new_video_stream(mux, o, best_ist);
+}
+
+static void map_auto_audio(Muxer *mux, const OptionsContext *o)
+{
+ AVFormatContext *oc = mux->fc;
+ InputStream *best_ist = NULL;
+ int best_score = 0;
+
+ /* audio: most channels */
+ if (av_guess_codec(oc->oformat, NULL, oc->url, NULL, AVMEDIA_TYPE_AUDIO) == AV_CODEC_ID_NONE)
+ return;
+
+ for (int j = 0; j < nb_input_files; j++) {
+ InputFile *ifile = input_files[j];
+ InputStream *file_best_ist = NULL;
+ int file_best_score = 0;
+ for (int i = 0; i < ifile->nb_streams; i++) {
+ InputStream *ist = ifile->streams[i];
+ int score;
+
+ if (ist->user_set_discard == AVDISCARD_ALL ||
+ ist->st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
+ continue;
+
+ score = ist->st->codecpar->ch_layout.nb_channels
+ + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
+ + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
+ if (score > file_best_score) {
+ file_best_score = score;
+ file_best_ist = ist;
+ }
+ }
+ if (file_best_ist) {
+ file_best_score -= 5000000*!!(file_best_ist->st->disposition & AV_DISPOSITION_DEFAULT);
+ if (file_best_score > best_score) {
+ best_score = file_best_score;
+ best_ist = file_best_ist;
+ }
+ }
+ }
+ if (best_ist)
+ new_audio_stream(mux, o, best_ist);
+}
+
+static void map_auto_subtitle(Muxer *mux, const OptionsContext *o)
+{
+ AVFormatContext *oc = mux->fc;
+ char *subtitle_codec_name = NULL;
+
+ /* subtitles: pick first */
+ MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, oc, "s");
+ if (!avcodec_find_encoder(oc->oformat->subtitle_codec) && !subtitle_codec_name)
+ return;
+
+ for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist))
+ if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+ AVCodecDescriptor const *input_descriptor =
+ avcodec_descriptor_get(ist->st->codecpar->codec_id);
+ AVCodecDescriptor const *output_descriptor = NULL;
+ AVCodec const *output_codec =
+ avcodec_find_encoder(oc->oformat->subtitle_codec);
+ int input_props = 0, output_props = 0;
+ if (ist->user_set_discard == AVDISCARD_ALL)
+ continue;
+ if (output_codec)
+ output_descriptor = avcodec_descriptor_get(output_codec->id);
+ if (input_descriptor)
+ input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
+ if (output_descriptor)
+ output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
+ if (subtitle_codec_name ||
+ input_props & output_props ||
+ // Map dvb teletext which has neither property to any output subtitle encoder
+ input_descriptor && output_descriptor &&
+ (!input_descriptor->props ||
+ !output_descriptor->props)) {
+ new_subtitle_stream(mux, o, ist);
+ break;
+ }
+ }
+}
+
+static void map_auto_data(Muxer *mux, const OptionsContext *o)
+{
+ AVFormatContext *oc = mux->fc;
+ /* Data only if codec id match */
+ enum AVCodecID codec_id = av_guess_codec(oc->oformat, NULL, oc->url, NULL, AVMEDIA_TYPE_DATA);
+
+ if (codec_id == AV_CODEC_ID_NONE)
+ return;
+
+ for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
+ if (ist->user_set_discard == AVDISCARD_ALL)
+ continue;
+ if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA &&
+ ist->st->codecpar->codec_id == codec_id )
+ new_data_stream(mux, o, ist);
+ }
+}
+
+static void map_manual(Muxer *mux, const OptionsContext *o, const StreamMap *map)
+{
+ InputStream *ist;
+
+ if (map->disabled)
+ return;
+
+ if (map->linklabel) {
+ FilterGraph *fg;
+ OutputFilter *ofilter = NULL;
+ int j, k;
+
+ for (j = 0; j < nb_filtergraphs; j++) {
+ fg = filtergraphs[j];
+ for (k = 0; k < fg->nb_outputs; k++) {
+ AVFilterInOut *out = fg->outputs[k]->out_tmp;
+ if (out && !strcmp(out->name, map->linklabel)) {
+ ofilter = fg->outputs[k];
+ goto loop_end;
+ }
+ }
+ }
+loop_end:
+ if (!ofilter) {
+ av_log(mux, AV_LOG_FATAL, "Output with label '%s' does not exist "
+ "in any defined filter graph, or was already used elsewhere.\n", map->linklabel);
+ exit_program(1);
+ }
+ init_output_filter(ofilter, o, mux);
+ } else {
+ ist = input_files[map->file_index]->streams[map->stream_index];
+ if (ist->user_set_discard == AVDISCARD_ALL) {
+ av_log(mux, AV_LOG_FATAL, "Stream #%d:%d is disabled and cannot be mapped.\n",
+ map->file_index, map->stream_index);
+ exit_program(1);
+ }
+ if(o->subtitle_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
+ return;
+ if(o-> audio_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
+ return;
+ if(o-> video_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
+ return;
+ if(o-> data_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA)
+ return;
+
+ switch (ist->st->codecpar->codec_type) {
+ case AVMEDIA_TYPE_VIDEO: new_video_stream (mux, o, ist); break;
+ case AVMEDIA_TYPE_AUDIO: new_audio_stream (mux, o, ist); break;
+ case AVMEDIA_TYPE_SUBTITLE: new_subtitle_stream (mux, o, ist); break;
+ case AVMEDIA_TYPE_DATA: new_data_stream (mux, o, ist); break;
+ case AVMEDIA_TYPE_ATTACHMENT: new_attachment_stream(mux, o, ist); break;
+ case AVMEDIA_TYPE_UNKNOWN:
+ if (copy_unknown_streams) {
+ new_unknown_stream (mux, o, ist);
+ break;
+ }
+ default:
+ av_log(mux, ignore_unknown_streams ? AV_LOG_WARNING : AV_LOG_FATAL,
+ "Cannot map stream #%d:%d - unsupported type.\n",
+ map->file_index, map->stream_index);
+ if (!ignore_unknown_streams) {
+ av_log(mux, AV_LOG_FATAL,
+ "If you want unsupported types ignored instead "
+ "of failing, please use the -ignore_unknown option\n"
+ "If you want them copied, please use -copy_unknown\n");
+ exit_program(1);
+ }
+ }
+ }
+}
+
+static void of_add_attachments(Muxer *mux, const OptionsContext *o)
+{
+ OutputStream *ost;
+ int err;
+
+ for (int i = 0; i < o->nb_attachments; i++) {
+ AVIOContext *pb;
+ uint8_t *attachment;
+ const char *p;
+ int64_t len;
+
+ if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
+ av_log(mux, AV_LOG_FATAL, "Could not open attachment file %s.\n",
+ o->attachments[i]);
+ exit_program(1);
+ }
+ if ((len = avio_size(pb)) <= 0) {
+ av_log(mux, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
+ o->attachments[i]);
+ exit_program(1);
+ }
+ if (len > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE ||
+ !(attachment = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE))) {
+ av_log(mux, AV_LOG_FATAL, "Attachment %s too large.\n",
+ o->attachments[i]);
+ exit_program(1);
+ }
+ avio_read(pb, attachment, len);
+ memset(attachment + len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+
+ ost = new_attachment_stream(mux, o, NULL);
+ ost->attachment_filename = o->attachments[i];
+ ost->st->codecpar->extradata = attachment;
+ ost->st->codecpar->extradata_size = len;
+
+ p = strrchr(o->attachments[i], '/');
+ av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
+ avio_closep(&pb);
+ }
+}
+
+static void create_streams(Muxer *mux, const OptionsContext *o)
+{
+ AVFormatContext *oc = mux->fc;
+ int auto_disable_v = o->video_disable;
+ int auto_disable_a = o->audio_disable;
+ int auto_disable_s = o->subtitle_disable;
+ int auto_disable_d = o->data_disable;
+
+ /* create streams for all unlabeled output pads */
+ for (int i = 0; i < nb_filtergraphs; i++) {
+ FilterGraph *fg = filtergraphs[i];
+ for (int j = 0; j < fg->nb_outputs; j++) {
+ OutputFilter *ofilter = fg->outputs[j];
+
+ if (!ofilter->out_tmp || ofilter->out_tmp->name)
+ continue;
+
+ switch (ofilter->type) {
+ case AVMEDIA_TYPE_VIDEO: auto_disable_v = 1; break;
+ case AVMEDIA_TYPE_AUDIO: auto_disable_a = 1; break;
+ case AVMEDIA_TYPE_SUBTITLE: auto_disable_s = 1; break;
+ }
+ init_output_filter(ofilter, o, mux);
+ }
+ }
+
+ if (!o->nb_stream_maps) {
+ /* pick the "best" stream of each type */
+ if (!auto_disable_v)
+ map_auto_video(mux, o);
+ if (!auto_disable_a)
+ map_auto_audio(mux, o);
+ if (!auto_disable_s)
+ map_auto_subtitle(mux, o);
+ if (!auto_disable_d)
+ map_auto_data(mux, o);
+ } else {
+ for (int i = 0; i < o->nb_stream_maps; i++)
+ map_manual(mux, o, &o->stream_maps[i]);
+ }
+
+ of_add_attachments(mux, o);
+
+ if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
+ av_dump_format(oc, nb_output_files - 1, oc->url, 1);
+ av_log(mux, AV_LOG_ERROR, "Output file does not contain any stream\n");
+ exit_program(1);
+ }
+}
+
+static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, int64_t buf_size_us)
+{
+ OutputFile *of = &mux->of;
+ int nb_av_enc = 0, nb_interleaved = 0;
+ int limit_frames = 0, limit_frames_av_enc = 0;
+
+#define IS_AV_ENC(ost, type) \
+ (ost->enc_ctx && (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO))
+#define IS_INTERLEAVED(type) (type != AVMEDIA_TYPE_ATTACHMENT)
+
+ for (int i = 0; i < oc->nb_streams; i++) {
+ OutputStream *ost = of->streams[i];
+ MuxStream *ms = ms_from_ost(ost);
+ enum AVMediaType type = ost->st->codecpar->codec_type;
+
+ ost->sq_idx_encode = -1;
+ ost->sq_idx_mux = -1;
+
+ nb_interleaved += IS_INTERLEAVED(type);
+ nb_av_enc += IS_AV_ENC(ost, type);
+
+ limit_frames |= ms->max_frames < INT64_MAX;
+ limit_frames_av_enc |= (ms->max_frames < INT64_MAX) && IS_AV_ENC(ost, type);
+ }
+
+ if (!((nb_interleaved > 1 && of->shortest) ||
+ (nb_interleaved > 0 && limit_frames)))
+ return 0;
+
+ /* if we have more than one encoded audio/video streams, or at least
+ * one encoded audio/video stream is frame-limited, then we
+ * synchronize them before encoding */
+ if ((of->shortest && nb_av_enc > 1) || limit_frames_av_enc) {
+ of->sq_encode = sq_alloc(SYNC_QUEUE_FRAMES, buf_size_us);
+ if (!of->sq_encode)
+ return AVERROR(ENOMEM);
+
+ for (int i = 0; i < oc->nb_streams; i++) {
+ OutputStream *ost = of->streams[i];
+ MuxStream *ms = ms_from_ost(ost);
+ enum AVMediaType type = ost->st->codecpar->codec_type;
+
+ if (!IS_AV_ENC(ost, type))
+ continue;
+
+ ost->sq_idx_encode = sq_add_stream(of->sq_encode,
+ of->shortest || ms->max_frames < INT64_MAX);
+ if (ost->sq_idx_encode < 0)
+ return ost->sq_idx_encode;
+
+ ost->sq_frame = av_frame_alloc();
+ if (!ost->sq_frame)
+ return AVERROR(ENOMEM);
+
+ if (ms->max_frames != INT64_MAX)
+ sq_limit_frames(of->sq_encode, ost->sq_idx_encode, ms->max_frames);
+ }
+ }
+
+ /* if there are any additional interleaved streams, then ALL the streams
+ * are also synchronized before sending them to the muxer */
+ if (nb_interleaved > nb_av_enc) {
+ mux->sq_mux = sq_alloc(SYNC_QUEUE_PACKETS, buf_size_us);
+ if (!mux->sq_mux)
+ return AVERROR(ENOMEM);
+
+ mux->sq_pkt = av_packet_alloc();
+ if (!mux->sq_pkt)
+ return AVERROR(ENOMEM);
+
+ for (int i = 0; i < oc->nb_streams; i++) {
+ OutputStream *ost = of->streams[i];
+ MuxStream *ms = ms_from_ost(ost);
+ enum AVMediaType type = ost->st->codecpar->codec_type;
+
+ if (!IS_INTERLEAVED(type))
+ continue;
+
+ ost->sq_idx_mux = sq_add_stream(mux->sq_mux,
+ of->shortest || ms->max_frames < INT64_MAX);
+ if (ost->sq_idx_mux < 0)
+ return ost->sq_idx_mux;
+
+ if (ms->max_frames != INT64_MAX)
+ sq_limit_frames(mux->sq_mux, ost->sq_idx_mux, ms->max_frames);
+ }
+ }
+
+#undef IS_AV_ENC
+#undef IS_INTERLEAVED
+
+ return 0;
+}
+
+static void of_add_programs(Muxer *mux, const OptionsContext *o)
+{
+ AVFormatContext *oc = mux->fc;
+ /* process manually set programs */
+ for (int i = 0; i < o->nb_program; i++) {
+ const char *p = o->program[i].u.str;
+ int progid = i+1;
+ AVProgram *program;
+
+ while(*p) {
+ const char *p2 = av_get_token(&p, ":");
+ const char *to_dealloc = p2;
+ char *key;
+ if (!p2)
+ break;
+
+ if(*p) p++;
+
+ key = av_get_token(&p2, "=");
+ if (!key || !*p2) {
+ av_freep(&to_dealloc);
+ av_freep(&key);
+ break;
+ }
+ p2++;
+
+ if (!strcmp(key, "program_num"))
+ progid = strtol(p2, NULL, 0);
+ av_freep(&to_dealloc);
+ av_freep(&key);
+ }
+
+ program = av_new_program(oc, progid);
+ if (!program)
+ report_and_exit(AVERROR(ENOMEM));
+
+ p = o->program[i].u.str;
+ while(*p) {
+ const char *p2 = av_get_token(&p, ":");
+ const char *to_dealloc = p2;
+ char *key;
+ if (!p2)
+ break;
+ if(*p) p++;
+
+ key = av_get_token(&p2, "=");
+ if (!key) {
+ av_log(mux, AV_LOG_FATAL,
+ "No '=' character in program string %s.\n",
+ p2);
+ exit_program(1);
+ }
+ if (!*p2)
+ exit_program(1);
+ p2++;
+
+ if (!strcmp(key, "title")) {
+ av_dict_set(&program->metadata, "title", p2, 0);
+ } else if (!strcmp(key, "program_num")) {
+ } else if (!strcmp(key, "st")) {
+ int st_num = strtol(p2, NULL, 0);
+ av_program_add_stream_index(oc, progid, st_num);
+ } else {
+ av_log(mux, AV_LOG_FATAL, "Unknown program key %s.\n", key);
+ exit_program(1);
+ }
+ av_freep(&to_dealloc);
+ av_freep(&key);
+ }
+ }
+}
+
+/**
+ * Parse a metadata specifier passed as 'arg' parameter.
+ * @param arg metadata string to parse
+ * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
+ * @param index for type c/p, chapter/program index is written here
+ * @param stream_spec for type s, the stream specifier is written here
+ */
+static void parse_meta_type(void *logctx, const char *arg,
+ char *type, int *index, const char **stream_spec)
+{
+ if (*arg) {
+ *type = *arg;
+ switch (*arg) {
+ case 'g':
+ break;
+ case 's':
+ if (*(++arg) && *arg != ':') {
+ av_log(logctx, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
+ exit_program(1);
+ }
+ *stream_spec = *arg == ':' ? arg + 1 : "";
+ break;
+ case 'c':
+ case 'p':
+ if (*(++arg) == ':')
+ *index = strtol(++arg, NULL, 0);
+ break;
+ default:
+ av_log(logctx, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
+ exit_program(1);
+ }
+ } else
+ *type = 'g';
+}
+
+static void of_add_metadata(OutputFile *of, AVFormatContext *oc,
+ const OptionsContext *o)
+{
+ for (int i = 0; i < o->nb_metadata; i++) {
+ AVDictionary **m;
+ char type, *val;
+ const char *stream_spec;
+ int index = 0, ret = 0;
+
+ val = strchr(o->metadata[i].u.str, '=');
+ if (!val) {
+ av_log(of, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
+ o->metadata[i].u.str);
+ exit_program(1);
+ }
+ *val++ = 0;
+
+ parse_meta_type(of, o->metadata[i].specifier, &type, &index, &stream_spec);
+ if (type == 's') {
+ for (int j = 0; j < oc->nb_streams; j++) {
+ OutputStream *ost = of->streams[j];
+ if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
+#if FFMPEG_ROTATION_METADATA
+ if (!strcmp(o->metadata[i].u.str, "rotate")) {
+ char *tail;
+ double theta = av_strtod(val, &tail);
+ if (!*tail) {
+ ost->rotate_overridden = 1;
+ ost->rotate_override_value = theta;
+ }
+
+ av_log(ost, AV_LOG_WARNING,
+ "Conversion of a 'rotate' metadata key to a "
+ "proper display matrix rotation is deprecated. "
+ "See -display_rotation for setting rotation "
+ "instead.");
+ } else {
+#endif
+ av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
+#if FFMPEG_ROTATION_METADATA
+ }
+#endif
+ } else if (ret < 0)
+ exit_program(1);
+ }
+ } else {
+ switch (type) {
+ case 'g':
+ m = &oc->metadata;
+ break;
+ case 'c':
+ if (index < 0 || index >= oc->nb_chapters) {
+ av_log(of, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
+ exit_program(1);
+ }
+ m = &oc->chapters[index]->metadata;
+ break;
+ case 'p':
+ if (index < 0 || index >= oc->nb_programs) {
+ av_log(of, AV_LOG_FATAL, "Invalid program index %d in metadata specifier.\n", index);
+ exit_program(1);
+ }
+ m = &oc->programs[index]->metadata;
+ break;
+ default:
+ av_log(of, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
+ exit_program(1);
+ }
+ av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
+ }
+ }
+}
+
+static void set_channel_layout(OutputFilter *f, OutputStream *ost)
+{
+ const AVCodec *c = ost->enc_ctx->codec;
+ int i, err;
+
+ if (ost->enc_ctx->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
+ /* Pass the layout through for all orders but UNSPEC */
+ err = av_channel_layout_copy(&f->ch_layout, &ost->enc_ctx->ch_layout);
+ if (err < 0)
+ report_and_exit(AVERROR(ENOMEM));
+ return;
+ }
+
+ /* Requested layout is of order UNSPEC */
+ if (!c->ch_layouts) {
+ /* Use the default native layout for the requested amount of channels when the
+ encoder doesn't have a list of supported layouts */
+ av_channel_layout_default(&f->ch_layout, ost->enc_ctx->ch_layout.nb_channels);
+ return;
+ }
+ /* Encoder has a list of supported layouts. Pick the first layout in it with the
+ same amount of channels as the requested layout */
+ for (i = 0; c->ch_layouts[i].nb_channels; i++) {
+ if (c->ch_layouts[i].nb_channels == ost->enc_ctx->ch_layout.nb_channels)
+ break;
+ }
+ if (c->ch_layouts[i].nb_channels) {
+ /* Use it if one is found */
+ err = av_channel_layout_copy(&f->ch_layout, &c->ch_layouts[i]);
+ if (err < 0)
+ report_and_exit(AVERROR(ENOMEM));
+ return;
+ }
+ /* If no layout for the amount of channels requested was found, use the default
+ native layout for it. */
+ av_channel_layout_default(&f->ch_layout, ost->enc_ctx->ch_layout.nb_channels);
+}
+
+static int copy_chapters(InputFile *ifile, OutputFile *ofile, AVFormatContext *os,
+ int copy_metadata)
+{
+ AVFormatContext *is = ifile->ctx;
+ AVChapter **tmp;
+ int i;
+
+ tmp = av_realloc_f(os->chapters, is->nb_chapters + os->nb_chapters, sizeof(*os->chapters));
+ if (!tmp)
+ return AVERROR(ENOMEM);
+ os->chapters = tmp;
+
+ for (i = 0; i < is->nb_chapters; i++) {
+ AVChapter *in_ch = is->chapters[i], *out_ch;
+ int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
+ int64_t ts_off = av_rescale_q(start_time - ifile->ts_offset,
+ AV_TIME_BASE_Q, in_ch->time_base);
+ int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
+ av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
+
+
+ if (in_ch->end < ts_off)
+ continue;
+ if (rt != INT64_MAX && in_ch->start > rt + ts_off)
+ break;
+
+ out_ch = av_mallocz(sizeof(AVChapter));
+ if (!out_ch)
+ return AVERROR(ENOMEM);
+
+ out_ch->id = in_ch->id;
+ out_ch->time_base = in_ch->time_base;
+ out_ch->start = FFMAX(0, in_ch->start - ts_off);
+ out_ch->end = FFMIN(rt, in_ch->end - ts_off);
+
+ if (copy_metadata)
+ av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
+
+ os->chapters[os->nb_chapters++] = out_ch;
+ }
+ return 0;
+}
+
+static int copy_metadata(Muxer *mux, AVFormatContext *ic,
+ const char *outspec, const char *inspec,
+ int *metadata_global_manual, int *metadata_streams_manual,
+ int *metadata_chapters_manual, const OptionsContext *o)
+{
+ AVFormatContext *oc = mux->fc;
+ AVDictionary **meta_in = NULL;
+ AVDictionary **meta_out = NULL;
+ int i, ret = 0;
+ char type_in, type_out;
+ const char *istream_spec = NULL, *ostream_spec = NULL;
+ int idx_in = 0, idx_out = 0;
+
+ parse_meta_type(mux, inspec, &type_in, &idx_in, &istream_spec);
+ parse_meta_type(mux, outspec, &type_out, &idx_out, &ostream_spec);
+
+ if (type_in == 'g' || type_out == 'g')
+ *metadata_global_manual = 1;
+ if (type_in == 's' || type_out == 's')
+ *metadata_streams_manual = 1;
+ if (type_in == 'c' || type_out == 'c')
+ *metadata_chapters_manual = 1;
+
+ /* ic is NULL when just disabling automatic mappings */
+ if (!ic)
+ return 0;
+
+#define METADATA_CHECK_INDEX(index, nb_elems, desc)\
+ if ((index) < 0 || (index) >= (nb_elems)) {\
+ av_log(mux, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
+ (desc), (index));\
+ exit_program(1);\
+ }
+
+#define SET_DICT(type, meta, context, index)\
+ switch (type) {\
+ case 'g':\
+ meta = &context->metadata;\
+ break;\
+ case 'c':\
+ METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
+ meta = &context->chapters[index]->metadata;\
+ break;\
+ case 'p':\
+ METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
+ meta = &context->programs[index]->metadata;\
+ break;\
+ case 's':\
+ break; /* handled separately below */ \
+ default: av_assert0(0);\
+ }\
+
+ SET_DICT(type_in, meta_in, ic, idx_in);
+ SET_DICT(type_out, meta_out, oc, idx_out);
+
+ /* for input streams choose first matching stream */
+ if (type_in == 's') {
+ for (i = 0; i < ic->nb_streams; i++) {
+ if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
+ meta_in = &ic->streams[i]->metadata;
+ break;
+ } else if (ret < 0)
+ exit_program(1);
+ }
+ if (!meta_in) {
+ av_log(mux, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec);
+ exit_program(1);
+ }
+ }
+
+ if (type_out == 's') {
+ for (i = 0; i < oc->nb_streams; i++) {
+ if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
+ meta_out = &oc->streams[i]->metadata;
+ av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
+ } else if (ret < 0)
+ exit_program(1);
+ }
+ } else
+ av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
+
+ return 0;
+}
+
+static void copy_meta(Muxer *mux, const OptionsContext *o)
+{
+ OutputFile *of = &mux->of;
+ AVFormatContext *oc = mux->fc;
+ int chapters_input_file = o->chapters_input_file;
+ int metadata_global_manual = 0;
+ int metadata_streams_manual = 0;
+ int metadata_chapters_manual = 0;
+
+ /* copy metadata */
+ for (int i = 0; i < o->nb_metadata_map; i++) {
+ char *p;
+ int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);
+
+ if (in_file_index >= nb_input_files) {
+ av_log(mux, AV_LOG_FATAL, "Invalid input file index %d while "
+ "processing metadata maps\n", in_file_index);
+ exit_program(1);
+ }
+ copy_metadata(mux,
+ in_file_index >= 0 ? input_files[in_file_index]->ctx : NULL,
+ o->metadata_map[i].specifier, *p ? p + 1 : p,
+ &metadata_global_manual, &metadata_streams_manual,
+ &metadata_chapters_manual, o);
+ }
+
+ /* copy chapters */
+ if (chapters_input_file >= nb_input_files) {
+ if (chapters_input_file == INT_MAX) {
+ /* copy chapters from the first input file that has them*/
+ chapters_input_file = -1;
+ for (int i = 0; i < nb_input_files; i++)
+ if (input_files[i]->ctx->nb_chapters) {
+ chapters_input_file = i;
+ break;
+ }
+ } else {
+ av_log(mux, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
+ chapters_input_file);
+ exit_program(1);
+ }
+ }
+ if (chapters_input_file >= 0)
+ copy_chapters(input_files[chapters_input_file], of, oc,
+ !metadata_chapters_manual);
+
+ /* copy global metadata by default */
+ if (!metadata_global_manual && nb_input_files){
+ av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
+ AV_DICT_DONT_OVERWRITE);
+ if (of->recording_time != INT64_MAX)
+ av_dict_set(&oc->metadata, "duration", NULL, 0);
+ av_dict_set(&oc->metadata, "creation_time", NULL, 0);
+ av_dict_set(&oc->metadata, "company_name", NULL, 0);
+ av_dict_set(&oc->metadata, "product_name", NULL, 0);
+ av_dict_set(&oc->metadata, "product_version", NULL, 0);
+ }
+ if (!metadata_streams_manual)
+ for (int i = 0; i < of->nb_streams; i++) {
+ OutputStream *ost = of->streams[i];
+
+ if (!ost->ist) /* this is true e.g. for attached files */
+ continue;
+ av_dict_copy(&ost->st->metadata, ost->ist->st->metadata, AV_DICT_DONT_OVERWRITE);
+ if (ost->enc_ctx) {
+ av_dict_set(&ost->st->metadata, "encoder", NULL, 0);
+ }
+ }
+}
+
+static int set_dispositions(Muxer *mux, const OptionsContext *o)
+{
+ OutputFile *of = &mux->of;
+ AVFormatContext *ctx = mux->fc;
+
+ int nb_streams[AVMEDIA_TYPE_NB] = { 0 };
+ int have_default[AVMEDIA_TYPE_NB] = { 0 };
+ int have_manual = 0;
+ int ret = 0;
+
+ const char **dispositions;
+
+ dispositions = av_calloc(ctx->nb_streams, sizeof(*dispositions));
+ if (!dispositions)
+ return AVERROR(ENOMEM);
+
+ // first, copy the input dispositions
+ for (int i = 0; i < ctx->nb_streams; i++) {
+ OutputStream *ost = of->streams[i];
+
+ nb_streams[ost->st->codecpar->codec_type]++;
+
+ MATCH_PER_STREAM_OPT(disposition, str, dispositions[i], ctx, ost->st);
+
+ have_manual |= !!dispositions[i];
+
+ if (ost->ist) {
+ ost->st->disposition = ost->ist->st->disposition;
+
+ if (ost->st->disposition & AV_DISPOSITION_DEFAULT)
+ have_default[ost->st->codecpar->codec_type] = 1;
+ }
+ }
+
+ if (have_manual) {
+ // process manually set dispositions - they override the above copy
+ for (int i = 0; i < ctx->nb_streams; i++) {
+ OutputStream *ost = of->streams[i];
+ const char *disp = dispositions[i];
+
+ if (!disp)
+ continue;
+
+ ret = av_opt_set(ost->st, "disposition", disp, 0);
+ if (ret < 0)
+ goto finish;
+ }
+ } else {
+ // For each media type with more than one stream, find a suitable stream to
+ // mark as default, unless one is already marked default.
+ // "Suitable" means the first of that type, skipping attached pictures.
+ for (int i = 0; i < ctx->nb_streams; i++) {
+ OutputStream *ost = of->streams[i];
+ enum AVMediaType type = ost->st->codecpar->codec_type;
+
+ if (nb_streams[type] < 2 || have_default[type] ||
+ ost->st->disposition & AV_DISPOSITION_ATTACHED_PIC)
+ continue;
+
+ ost->st->disposition |= AV_DISPOSITION_DEFAULT;
+ have_default[type] = 1;
+ }
+ }
+
+finish:
+ av_freep(&dispositions);
+
+ return ret;
+}
+
+const char *const forced_keyframes_const_names[] = {
+ "n",
+ "n_forced",
+ "prev_forced_n",
+ "prev_forced_t",
+ "t",
+ NULL
+};
+
+static int compare_int64(const void *a, const void *b)
+{
+ return FFDIFFSIGN(*(const int64_t *)a, *(const int64_t *)b);
+}
+
+static void parse_forced_key_frames(KeyframeForceCtx *kf, const Muxer *mux,
+ const char *spec)
+{
+ const char *p;
+ int n = 1, i, size, index = 0;
+ int64_t t, *pts;
+
+ for (p = spec; *p; p++)
+ if (*p == ',')
+ n++;
+ size = n;
+ pts = av_malloc_array(size, sizeof(*pts));
+ if (!pts)
+ report_and_exit(AVERROR(ENOMEM));
+
+ p = spec;
+ for (i = 0; i < n; i++) {
+ char *next = strchr(p, ',');
+
+ if (next)
+ *next++ = 0;
+
+ if (!memcmp(p, "chapters", 8)) {
+ AVChapter * const *ch = mux->fc->chapters;
+ unsigned int nb_ch = mux->fc->nb_chapters;
+ int j;
+
+ if (nb_ch > INT_MAX - size ||
+ !(pts = av_realloc_f(pts, size += nb_ch - 1,
+ sizeof(*pts))))
+ report_and_exit(AVERROR(ENOMEM));
+ t = p[8] ? parse_time_or_die("force_key_frames", p + 8, 1) : 0;
+
+ for (j = 0; j < nb_ch; j++) {
+ const AVChapter *c = ch[j];
+ av_assert1(index < size);
+ pts[index++] = av_rescale_q(c->start, c->time_base,
+ AV_TIME_BASE_Q) + t;
+ }
+
+ } else {
+ av_assert1(index < size);
+ pts[index++] = parse_time_or_die("force_key_frames", p, 1);
+ }
+
+ p = next;
+ }
+
+ av_assert0(index == size);
+ qsort(pts, size, sizeof(*pts), compare_int64);
+ kf->nb_pts = size;
+ kf->pts = pts;
+}
+
+static int process_forced_keyframes(Muxer *mux, const OptionsContext *o)
+{
+ for (int i = 0; i < mux->of.nb_streams; i++) {
+ OutputStream *ost = mux->of.streams[i];
+ const char *forced_keyframes = NULL;
+
+ MATCH_PER_STREAM_OPT(forced_key_frames, str, forced_keyframes, mux->fc, ost->st);
+
+ if (!(ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
+ ost->enc_ctx && forced_keyframes))
+ continue;
+
+ if (!strncmp(forced_keyframes, "expr:", 5)) {
+ int ret = av_expr_parse(&ost->kf.pexpr, forced_keyframes + 5,
+ forced_keyframes_const_names, NULL, NULL, NULL, NULL, 0, NULL);
+ if (ret < 0) {
+ av_log(ost, AV_LOG_ERROR,
+ "Invalid force_key_frames expression '%s'\n", forced_keyframes + 5);
+ return ret;
+ }
+ ost->kf.expr_const_values[FKF_N] = 0;
+ ost->kf.expr_const_values[FKF_N_FORCED] = 0;
+ ost->kf.expr_const_values[FKF_PREV_FORCED_N] = NAN;
+ ost->kf.expr_const_values[FKF_PREV_FORCED_T] = NAN;
+
+ // Don't parse the 'forced_keyframes' in case of 'keep-source-keyframes',
+ // parse it only for static kf timings
+ } else if (!strcmp(forced_keyframes, "source")) {
+ ost->kf.type = KF_FORCE_SOURCE;
+ } else if (!strcmp(forced_keyframes, "source_no_drop")) {
+ ost->kf.type = KF_FORCE_SOURCE_NO_DROP;
+ } else {
+ parse_forced_key_frames(&ost->kf, mux, forced_keyframes);
+ }
+ }
+
+ return 0;
+}
+
+static void validate_enc_avopt(Muxer *mux, const AVDictionary *codec_avopt)
+{
+ const AVClass *class = avcodec_get_class();
+ const AVClass *fclass = avformat_get_class();
+ const OutputFile *of = &mux->of;
+
+ AVDictionary *unused_opts;
+ const AVDictionaryEntry *e;
+
+ unused_opts = strip_specifiers(codec_avopt);
+ for (int i = 0; i < of->nb_streams; i++) {
+ e = NULL;
+ while ((e = av_dict_iterate(of->streams[i]->encoder_opts, e)))
+ av_dict_set(&unused_opts, e->key, NULL, 0);
+ }
+
+ e = NULL;
+ while ((e = av_dict_iterate(unused_opts, e))) {
+ const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
+ AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
+ const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0,
+ AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
+ if (!option || foption)
+ continue;
+
+ if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) {
+ av_log(mux, AV_LOG_ERROR, "Codec AVOption %s (%s) is not an "
+ "encoding option.\n", e->key, option->help ? option->help : "");
+ exit_program(1);
+ }
+
+ // gop_timecode is injected by generic code but not always used
+ if (!strcmp(e->key, "gop_timecode"))
+ continue;
+
+ av_log(mux, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used "
+ "for any stream. The most likely reason is either wrong type "
+ "(e.g. a video option with no video streams) or that it is a "
+ "private option of some encoder which was not actually used for "
+ "any stream.\n", e->key, option->help ? option->help : "");
+ }
+ av_dict_free(&unused_opts);
+}
+
+static const char *output_file_item_name(void *obj)
+{
+ const Muxer *mux = obj;
+
+ return mux->log_name;
+}
+
+static const AVClass output_file_class = {
+ .class_name = "OutputFile",
+ .version = LIBAVUTIL_VERSION_INT,
+ .item_name = output_file_item_name,
+ .category = AV_CLASS_CATEGORY_MUXER,
+};
+
+static Muxer *mux_alloc(void)
+{
+ Muxer *mux = allocate_array_elem(&output_files, sizeof(*mux), &nb_output_files);
+
+ mux->of.class = &output_file_class;
+ mux->of.index = nb_output_files - 1;
+
+ snprintf(mux->log_name, sizeof(mux->log_name), "out#%d", mux->of.index);
+
+ return mux;
+}
+
+int of_open(const OptionsContext *o, const char *filename)
+{
+ Muxer *mux;
+ AVFormatContext *oc;
+ int err;
+ OutputFile *of;
+
+ int64_t recording_time = o->recording_time;
+ int64_t stop_time = o->stop_time;
+
+ mux = mux_alloc();
+ of = &mux->of;
+
+ if (stop_time != INT64_MAX && recording_time != INT64_MAX) {
+ stop_time = INT64_MAX;
+ av_log(mux, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
+ }
+
+ if (stop_time != INT64_MAX && recording_time == INT64_MAX) {
+ int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time;
+ if (stop_time <= start_time) {
+ av_log(mux, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n");
+ exit_program(1);
+ } else {
+ recording_time = stop_time - start_time;
+ }
+ }
+
+ of->recording_time = recording_time;
+ of->start_time = o->start_time;
+ of->shortest = o->shortest;
+
+ mux->thread_queue_size = o->thread_queue_size > 0 ? o->thread_queue_size : 8;
+ mux->limit_filesize = o->limit_filesize;
+ av_dict_copy(&mux->opts, o->g->format_opts, 0);
+
+ if (!strcmp(filename, "-"))
+ filename = "pipe:";
+
+ err = avformat_alloc_output_context2(&oc, NULL, o->format, filename);
+ if (!oc) {
+ print_error(filename, err);
+ exit_program(1);
+ }
+ mux->fc = oc;
+
+ av_strlcat(mux->log_name, "/", sizeof(mux->log_name));
+ av_strlcat(mux->log_name, oc->oformat->name, sizeof(mux->log_name));
+
+ if (strcmp(oc->oformat->name, "rtp"))
+ want_sdp = 0;
+
+ of->format = oc->oformat;
+ if (recording_time != INT64_MAX)
+ oc->duration = recording_time;
+
+ oc->interrupt_callback = int_cb;
+
+ if (o->bitexact) {
+ oc->flags |= AVFMT_FLAG_BITEXACT;
+ of->bitexact = 1;
+ } else {
+ of->bitexact = check_opt_bitexact(oc, mux->opts, "fflags",
+ AVFMT_FLAG_BITEXACT);
+ }
+
+ /* create all output streams for this file */
+ create_streams(mux, o);
+
+ /* check if all codec options have been used */
+ validate_enc_avopt(mux, o->g->codec_opts);
+
+ /* set the decoding_needed flags and create simple filtergraphs */
+ for (int i = 0; i < of->nb_streams; i++) {
+ OutputStream *ost = of->streams[i];
+
+ if (ost->enc_ctx && ost->ist) {
+ InputStream *ist = ost->ist;
+ ist->decoding_needed |= DECODING_FOR_OST;
+ ist->processing_needed = 1;
+
+ if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
+ ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+ err = init_simple_filtergraph(ist, ost);
+ if (err < 0) {
+ av_log(ost, AV_LOG_ERROR,
+ "Error initializing a simple filtergraph\n");
+ exit_program(1);
+ }
+ }
+ } else if (ost->ist) {
+ ost->ist->processing_needed = 1;
+ }
+
+ /* set the filter output constraints */
+ if (ost->filter) {
+ const AVCodec *c = ost->enc_ctx->codec;
+ OutputFilter *f = ost->filter;
+ switch (ost->enc_ctx->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ f->frame_rate = ost->frame_rate;
+ f->width = ost->enc_ctx->width;
+ f->height = ost->enc_ctx->height;
+ if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
+ f->format = ost->enc_ctx->pix_fmt;
+ } else {
+ f->formats = c->pix_fmts;
+ }
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ if (ost->enc_ctx->sample_fmt != AV_SAMPLE_FMT_NONE) {
+ f->format = ost->enc_ctx->sample_fmt;
+ } else {
+ f->formats = c->sample_fmts;
+ }
+ if (ost->enc_ctx->sample_rate) {
+ f->sample_rate = ost->enc_ctx->sample_rate;
+ } else {
+ f->sample_rates = c->supported_samplerates;
+ }
+ if (ost->enc_ctx->ch_layout.nb_channels) {
+ set_channel_layout(f, ost);
+ } else if (c->ch_layouts) {
+ f->ch_layouts = c->ch_layouts;
+ }
+ break;
+ }
+ }
+ }
+
+ /* check filename in case of an image number is expected */
+ if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
+ if (!av_filename_number_test(oc->url)) {
+ print_error(oc->url, AVERROR(EINVAL));
+ exit_program(1);
+ }
+ }
+
+ if (!(oc->oformat->flags & AVFMT_NOFILE)) {
+ /* test if it already exists to avoid losing precious files */
+ assert_file_overwrite(filename);
+
+ /* open the file */
+ if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
+ &oc->interrupt_callback,
+ &mux->opts)) < 0) {
+ print_error(filename, err);
+ exit_program(1);
+ }
+ } else if (strcmp(oc->oformat->name, "image2")==0 && !av_filename_number_test(filename))
+ assert_file_overwrite(filename);
+
+ if (o->mux_preload) {
+ av_dict_set_int(&mux->opts, "preload", o->mux_preload*AV_TIME_BASE, 0);
+ }
+ oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
+
+ /* copy metadata and chapters from input files */
+ copy_meta(mux, o);
+
+ of_add_programs(mux, o);
+ of_add_metadata(of, oc, o);
+
+ err = set_dispositions(mux, o);
+ if (err < 0) {
+ av_log(mux, AV_LOG_FATAL, "Error setting output stream dispositions\n");
+ exit_program(1);
+ }
+
+ // parse forced keyframe specifications;
+ // must be done after chapters are created
+ err = process_forced_keyframes(mux, o);
+ if (err < 0) {
+ av_log(mux, AV_LOG_FATAL, "Error processing forced keyframes\n");
+ exit_program(1);
+ }
+
+ err = setup_sync_queues(mux, oc, o->shortest_buf_duration * AV_TIME_BASE);
+ if (err < 0) {
+ av_log(mux, AV_LOG_FATAL, "Error setting up output sync queues\n");
+ exit_program(1);
+ }
+
+ of->url = filename;
+
+ /* write the header for files with no streams */
+ if (of->format->flags & AVFMT_NOSTREAMS && oc->nb_streams == 0) {
+ int ret = mux_check_init(mux);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 6e18a4a23..055275d81 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -28,9 +28,9 @@
#endif
#include "ffmpeg.h"
-#include "fopen_utf8.h"
#include "cmdutils.h"
#include "opt_common.h"
+#include "sync_queue.h"
#include "libavformat/avformat.h"
@@ -44,7 +44,7 @@
#include "libavutil/avutil.h"
#include "libavutil/bprint.h"
#include "libavutil/channel_layout.h"
-#include "libavutil/getenv_utf8.h"
+#include "libavutil/display.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/fifo.h"
#include "libavutil/mathematics.h"
@@ -53,99 +53,10 @@
#include "libavutil/pixdesc.h"
#include "libavutil/pixfmt.h"
-#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
-
-#define SPECIFIER_OPT_FMT_str "%s"
-#define SPECIFIER_OPT_FMT_i "%i"
-#define SPECIFIER_OPT_FMT_i64 "%"PRId64
-#define SPECIFIER_OPT_FMT_ui64 "%"PRIu64
-#define SPECIFIER_OPT_FMT_f "%f"
-#define SPECIFIER_OPT_FMT_dbl "%lf"
-
-static const char *const opt_name_codec_names[] = {"c", "codec", "acodec", "vcodec", "scodec", "dcodec", NULL};
-static const char *const opt_name_audio_channels[] = {"ac", NULL};
-static const char *const opt_name_audio_ch_layouts[] = {"channel_layout", "ch_layout", NULL};
-static const char *const opt_name_audio_sample_rate[] = {"ar", NULL};
-static const char *const opt_name_frame_rates[] = {"r", NULL};
-static const char *const opt_name_max_frame_rates[] = {"fpsmax", NULL};
-static const char *const opt_name_frame_sizes[] = {"s", NULL};
-static const char *const opt_name_frame_pix_fmts[] = {"pix_fmt", NULL};
-static const char *const opt_name_ts_scale[] = {"itsscale", NULL};
-static const char *const opt_name_hwaccels[] = {"hwaccel", NULL};
-static const char *const opt_name_hwaccel_devices[] = {"hwaccel_device", NULL};
-static const char *const opt_name_hwaccel_output_formats[] = {"hwaccel_output_format", NULL};
-static const char *const opt_name_autorotate[] = {"autorotate", NULL};
-static const char *const opt_name_autoscale[] = {"autoscale", NULL};
-static const char *const opt_name_max_frames[] = {"frames", "aframes", "vframes", "dframes", NULL};
-static const char *const opt_name_bitstream_filters[] = {"bsf", "absf", "vbsf", NULL};
-static const char *const opt_name_codec_tags[] = {"tag", "atag", "vtag", "stag", NULL};
-static const char *const opt_name_sample_fmts[] = {"sample_fmt", NULL};
-static const char *const opt_name_qscale[] = {"q", "qscale", NULL};
-static const char *const opt_name_forced_key_frames[] = {"forced_key_frames", NULL};
-static const char *const opt_name_fps_mode[] = {"fps_mode", NULL};
-static const char *const opt_name_force_fps[] = {"force_fps", NULL};
-static const char *const opt_name_frame_aspect_ratios[] = {"aspect", NULL};
-static const char *const opt_name_rc_overrides[] = {"rc_override", NULL};
-static const char *const opt_name_intra_matrices[] = {"intra_matrix", NULL};
-static const char *const opt_name_inter_matrices[] = {"inter_matrix", NULL};
-static const char *const opt_name_chroma_intra_matrices[] = {"chroma_intra_matrix", NULL};
-static const char *const opt_name_top_field_first[] = {"top", NULL};
-static const char *const opt_name_presets[] = {"pre", "apre", "vpre", "spre", NULL};
-static const char *const opt_name_copy_initial_nonkeyframes[] = {"copyinkf", NULL};
-static const char *const opt_name_copy_prior_start[] = {"copypriorss", NULL};
-static const char *const opt_name_filters[] = {"filter", "af", "vf", NULL};
-static const char *const opt_name_filter_scripts[] = {"filter_script", NULL};
-static const char *const opt_name_reinit_filters[] = {"reinit_filter", NULL};
-static const char *const opt_name_fix_sub_duration[] = {"fix_sub_duration", NULL};
-static const char *const opt_name_canvas_sizes[] = {"canvas_size", NULL};
-static const char *const opt_name_pass[] = {"pass", NULL};
-static const char *const opt_name_passlogfiles[] = {"passlogfile", NULL};
-static const char *const opt_name_max_muxing_queue_size[] = {"max_muxing_queue_size", NULL};
-static const char *const opt_name_muxing_queue_data_threshold[] = {"muxing_queue_data_threshold", NULL};
-static const char *const opt_name_guess_layout_max[] = {"guess_layout_max", NULL};
-static const char *const opt_name_apad[] = {"apad", NULL};
-static const char *const opt_name_discard[] = {"discard", NULL};
-static const char *const opt_name_disposition[] = {"disposition", NULL};
-static const char *const opt_name_time_bases[] = {"time_base", NULL};
-static const char *const opt_name_enc_time_bases[] = {"enc_time_base", NULL};
-static const char *const opt_name_bits_per_raw_sample[] = {"bits_per_raw_sample", NULL};
-
-#define WARN_MULTIPLE_OPT_USAGE(name, type, so, st)\
-{\
- char namestr[128] = "";\
- const char *spec = so->specifier && so->specifier[0] ? so->specifier : "";\
- for (i = 0; opt_name_##name[i]; i++)\
- av_strlcatf(namestr, sizeof(namestr), "-%s%s", opt_name_##name[i], opt_name_##name[i+1] ? (opt_name_##name[i+2] ? ", " : " or ") : "");\
- av_log(NULL, AV_LOG_WARNING, "Multiple %s options specified for stream %d, only the last option '-%s%s%s "SPECIFIER_OPT_FMT_##type"' will be used.\n",\
- namestr, st->index, opt_name_##name[0], spec[0] ? ":" : "", spec, so->u.type);\
-}
-
-#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
-{\
- int i, ret, matches = 0;\
- SpecifierOpt *so;\
- for (i = 0; i < o->nb_ ## name; i++) {\
- char *spec = o->name[i].specifier;\
- if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0) {\
- outvar = o->name[i].u.type;\
- so = &o->name[i];\
- matches++;\
- } else if (ret < 0)\
- exit_program(1);\
- }\
- if (matches > 1)\
- WARN_MULTIPLE_OPT_USAGE(name, type, so, st);\
-}
-
-#define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)\
-{\
- int i;\
- for (i = 0; i < o->nb_ ## name; i++) {\
- char *spec = o->name[i].specifier;\
- if (!strcmp(spec, mediatype))\
- outvar = o->name[i].u.type;\
- }\
-}
+const char *const opt_name_codec_names[] = {"c", "codec", "acodec", "vcodec", "scodec", "dcodec", NULL};
+const char *const opt_name_frame_rates[] = {"r", NULL};
+const char *const opt_name_codec_tags[] = {"tag", "atag", "vtag", "stag", NULL};
+const char *const opt_name_top_field_first[] = {"top", NULL};
HWDevice *filter_hw_device;
@@ -156,8 +67,6 @@ float audio_drift_threshold = 0.1;
float dts_delta_threshold = 10;
float dts_error_threshold = 3600*30;
-int audio_volume = 256;
-int audio_sync_method = 0;
enum VideoSyncMethod video_sync_method = VSYNC_AUTO;
float frame_drop_threshold = 0;
int do_benchmark = 0;
@@ -183,12 +92,12 @@ int64_t stats_period = 500000;
static int file_overwrite = 0;
static int no_file_overwrite = 0;
-static int do_psnr = 0;
-static int input_stream_potentially_available = 0;
-static int ignore_unknown_streams = 0;
-static int copy_unknown_streams = 0;
-static int recast_media = 0;
-static int find_stream_info = 1;
+#if FFMPEG_OPT_PSNR
+int do_psnr = 0;
+#endif
+int ignore_unknown_streams = 0;
+int copy_unknown_streams = 0;
+int recast_media = 0;
static void uninit_options(OptionsContext *o)
{
@@ -217,7 +126,9 @@ static void uninit_options(OptionsContext *o)
for (i = 0; i < o->nb_stream_maps; i++)
av_freep(&o->stream_maps[i].linklabel);
av_freep(&o->stream_maps);
+#if FFMPEG_OPT_MAP_CHANNEL
av_freep(&o->audio_channel_maps);
+#endif
av_freep(&o->streamid_map);
av_freep(&o->attachments);
}
@@ -231,11 +142,13 @@ static void init_options(OptionsContext *o)
o->start_time = AV_NOPTS_VALUE;
o->start_time_eof = AV_NOPTS_VALUE;
o->recording_time = INT64_MAX;
- o->limit_filesize = UINT64_MAX;
+ o->limit_filesize = INT64_MAX;
o->chapters_input_file = INT_MAX;
o->accurate_seek = 1;
o->thread_queue_size = -1;
o->input_sync_ref = -1;
+ o->find_stream_info = 1;
+ o->shortest_buf_duration = 10.f;
}
static int show_hwaccels(void *optctx, const char *opt, const char *arg)
@@ -251,12 +164,12 @@ static int show_hwaccels(void *optctx, const char *opt, const char *arg)
}
/* return a copy of the input with the stream specifiers removed from the keys */
-static AVDictionary *strip_specifiers(AVDictionary *dict)
+AVDictionary *strip_specifiers(const AVDictionary *dict)
{
const AVDictionaryEntry *e = NULL;
AVDictionary *ret = NULL;
- while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
+ while ((e = av_dict_iterate(dict, e))) {
char *p = strchr(e->key, ':');
if (p)
@@ -268,7 +181,7 @@ static AVDictionary *strip_specifiers(AVDictionary *dict)
return ret;
}
-static int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_idx, int is_global)
+int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_idx, int is_global)
{
if (!av_strcasecmp(arg, "cfr")) *vsync_var = VSYNC_CFR;
else if (!av_strcasecmp(arg, "vfr")) *vsync_var = VSYNC_VFR;
@@ -288,6 +201,44 @@ static int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, in
return 0;
}
+/* Correct input file start times based on enabled streams */
+static void correct_input_start_times(void)
+{
+ for (int i = 0; i < nb_input_files; i++) {
+ InputFile *ifile = input_files[i];
+ AVFormatContext *is = ifile->ctx;
+ int64_t new_start_time = INT64_MAX, diff, abs_start_seek;
+
+ ifile->start_time_effective = is->start_time;
+
+ if (is->start_time == AV_NOPTS_VALUE ||
+ !(is->iformat->flags & AVFMT_TS_DISCONT))
+ continue;
+
+ for (int j = 0; j < is->nb_streams; j++) {
+ AVStream *st = is->streams[j];
+ if(st->discard == AVDISCARD_ALL || st->start_time == AV_NOPTS_VALUE)
+ continue;
+ new_start_time = FFMIN(new_start_time, av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q));
+ }
+
+ diff = new_start_time - is->start_time;
+ if (diff) {
+ av_log(NULL, AV_LOG_VERBOSE, "Correcting start time of Input #%d by %"PRId64" us.\n", i, diff);
+ ifile->start_time_effective = new_start_time;
+ if (copy_ts && start_at_zero)
+ ifile->ts_offset = -new_start_time;
+ else if (!copy_ts) {
+ abs_start_seek = is->start_time + (ifile->start_time != AV_NOPTS_VALUE) ? ifile->start_time : 0;
+ ifile->ts_offset = abs_start_seek > new_start_time ? -abs_start_seek : -new_start_time;
+ } else if (copy_ts)
+ ifile->ts_offset = 0;
+
+ ifile->ts_offset += ifile->input_ts_offset;
+ }
+ }
+}
+
static int apply_sync_offsets(void)
{
for (int i = 0; i < nb_input_files; i++) {
@@ -316,9 +267,9 @@ static int apply_sync_offsets(void)
if (self->ctx->start_time_realtime != AV_NOPTS_VALUE && ref->ctx->start_time_realtime != AV_NOPTS_VALUE) {
self_start_time = self->ctx->start_time_realtime;
ref_start_time = ref->ctx->start_time_realtime;
- } else if (self->ctx->start_time != AV_NOPTS_VALUE && ref->ctx->start_time != AV_NOPTS_VALUE) {
- self_start_time = self->ctx->start_time;
- ref_start_time = ref->ctx->start_time;
+ } else if (self->start_time_effective != AV_NOPTS_VALUE && ref->start_time_effective != AV_NOPTS_VALUE) {
+ self_start_time = self->start_time_effective;
+ ref_start_time = ref->start_time_effective;
} else {
start_times_set = 0;
}
@@ -410,9 +361,10 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
OptionsContext *o = optctx;
StreamMap *m = NULL;
int i, negative = 0, file_idx, disabled = 0;
- int sync_file_idx = -1, sync_stream_idx = 0;
- char *p, *sync;
- char *map;
+#if FFMPEG_OPT_MAP_SYNC
+ char *sync;
+#endif
+ char *map, *p;
char *allow_unused;
if (*arg == '-') {
@@ -423,33 +375,13 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
if (!map)
return AVERROR(ENOMEM);
+#if FFMPEG_OPT_MAP_SYNC
/* parse sync stream first, just pick first matching stream */
if (sync = strchr(map, ',')) {
*sync = 0;
- sync_file_idx = strtol(sync + 1, &sync, 0);
- if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
- av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);
- exit_program(1);
- }
- if (*sync)
- sync++;
- for (i = 0; i < input_files[sync_file_idx]->nb_streams; i++)
- if (check_stream_specifier(input_files[sync_file_idx]->ctx,
- input_files[sync_file_idx]->ctx->streams[i], sync) == 1) {
- sync_stream_idx = i;
- break;
- }
- if (i == input_files[sync_file_idx]->nb_streams) {
- av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "
- "match any streams.\n", arg);
- exit_program(1);
- }
- if (input_streams[input_files[sync_file_idx]->ist_index + sync_stream_idx]->user_set_discard == AVDISCARD_ALL) {
- av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s matches a disabled input "
- "stream.\n", arg);
- exit_program(1);
- }
+ av_log(NULL, AV_LOG_WARNING, "Specifying a sync stream is deprecated and has no effect\n");
}
+#endif
if (map[0] == '[') {
@@ -485,7 +417,7 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i],
*p == ':' ? p + 1 : p) <= 0)
continue;
- if (input_streams[input_files[file_idx]->ist_index + i]->user_set_discard == AVDISCARD_ALL) {
+ if (input_files[file_idx]->streams[i]->user_set_discard == AVDISCARD_ALL) {
disabled = 1;
continue;
}
@@ -494,14 +426,6 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
m->file_index = file_idx;
m->stream_index = i;
-
- if (sync_file_idx >= 0) {
- m->sync_file_index = sync_file_idx;
- m->sync_stream_index = sync_stream_idx;
- } else {
- m->sync_file_index = file_idx;
- m->sync_stream_index = i;
- }
}
}
@@ -531,6 +455,7 @@ static int opt_attach(void *optctx, const char *opt, const char *arg)
return 0;
}
+#if FFMPEG_OPT_MAP_CHANNEL
static int opt_map_channel(void *optctx, const char *opt, const char *arg)
{
OptionsContext *o = optctx;
@@ -539,6 +464,12 @@ static int opt_map_channel(void *optctx, const char *opt, const char *arg)
AudioChannelMap *m;
char *allow_unused;
char *mapchan;
+
+ av_log(NULL, AV_LOG_WARNING,
+ "The -%s option is deprecated and will be removed. "
+ "It can be replaced by the 'pan' filter, or in some cases by "
+ "combinations of 'channelsplit', 'channelmap', 'amerge' filters.\n", opt);
+
mapchan = av_strdup(arg);
if (!mapchan)
return AVERROR(ENOMEM);
@@ -592,7 +523,7 @@ static int opt_map_channel(void *optctx, const char *opt, const char *arg)
if (allow_unused = strchr(mapchan, '?'))
*allow_unused = 0;
if (m->channel_idx < 0 || m->channel_idx >= st->codecpar->ch_layout.nb_channels ||
- input_streams[input_files[m->file_idx]->ist_index + m->stream_idx]->user_set_discard == AVDISCARD_ALL) {
+ input_files[m->file_idx]->streams[m->stream_idx]->user_set_discard == AVDISCARD_ALL) {
if (allow_unused) {
av_log(NULL, AV_LOG_VERBOSE, "mapchan: invalid audio channel #%d.%d.%d\n",
m->file_idx, m->stream_idx, m->channel_idx);
@@ -607,6 +538,7 @@ static int opt_map_channel(void *optctx, const char *opt, const char *arg)
av_free(mapchan);
return 0;
}
+#endif
static int opt_sdp_file(void *optctx, const char *opt, const char *arg)
{
@@ -676,130 +608,6 @@ static int opt_filter_hw_device(void *optctx, const char *opt, const char *arg)
return 0;
}
-/**
- * Parse a metadata specifier passed as 'arg' parameter.
- * @param arg metadata string to parse
- * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
- * @param index for type c/p, chapter/program index is written here
- * @param stream_spec for type s, the stream specifier is written here
- */
-static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec)
-{
- if (*arg) {
- *type = *arg;
- switch (*arg) {
- case 'g':
- break;
- case 's':
- if (*(++arg) && *arg != ':') {
- av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
- exit_program(1);
- }
- *stream_spec = *arg == ':' ? arg + 1 : "";
- break;
- case 'c':
- case 'p':
- if (*(++arg) == ':')
- *index = strtol(++arg, NULL, 0);
- break;
- default:
- av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
- exit_program(1);
- }
- } else
- *type = 'g';
-}
-
-static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o)
-{
- AVDictionary **meta_in = NULL;
- AVDictionary **meta_out = NULL;
- int i, ret = 0;
- char type_in, type_out;
- const char *istream_spec = NULL, *ostream_spec = NULL;
- int idx_in = 0, idx_out = 0;
-
- parse_meta_type(inspec, &type_in, &idx_in, &istream_spec);
- parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec);
-
- if (!ic) {
- if (type_out == 'g' || !*outspec)
- o->metadata_global_manual = 1;
- if (type_out == 's' || !*outspec)
- o->metadata_streams_manual = 1;
- if (type_out == 'c' || !*outspec)
- o->metadata_chapters_manual = 1;
- return 0;
- }
-
- if (type_in == 'g' || type_out == 'g')
- o->metadata_global_manual = 1;
- if (type_in == 's' || type_out == 's')
- o->metadata_streams_manual = 1;
- if (type_in == 'c' || type_out == 'c')
- o->metadata_chapters_manual = 1;
-
- /* ic is NULL when just disabling automatic mappings */
- if (!ic)
- return 0;
-
-#define METADATA_CHECK_INDEX(index, nb_elems, desc)\
- if ((index) < 0 || (index) >= (nb_elems)) {\
- av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
- (desc), (index));\
- exit_program(1);\
- }
-
-#define SET_DICT(type, meta, context, index)\
- switch (type) {\
- case 'g':\
- meta = &context->metadata;\
- break;\
- case 'c':\
- METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
- meta = &context->chapters[index]->metadata;\
- break;\
- case 'p':\
- METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
- meta = &context->programs[index]->metadata;\
- break;\
- case 's':\
- break; /* handled separately below */ \
- default: av_assert0(0);\
- }\
-
- SET_DICT(type_in, meta_in, ic, idx_in);
- SET_DICT(type_out, meta_out, oc, idx_out);
-
- /* for input streams choose first matching stream */
- if (type_in == 's') {
- for (i = 0; i < ic->nb_streams; i++) {
- if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
- meta_in = &ic->streams[i]->metadata;
- break;
- } else if (ret < 0)
- exit_program(1);
- }
- if (!meta_in) {
- av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec);
- exit_program(1);
- }
- }
-
- if (type_out == 's') {
- for (i = 0; i < oc->nb_streams; i++) {
- if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
- meta_out = &oc->streams[i]->metadata;
- av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
- } else if (ret < 0)
- exit_program(1);
- }
- } else
- av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
-
- return 0;
-}
-
static int opt_recording_timestamp(void *optctx, const char *opt, const char *arg)
{
OptionsContext *o = optctx;
@@ -815,7 +623,8 @@ static int opt_recording_timestamp(void *optctx, const char *opt, const char *ar
return 0;
}
-static const AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder)
+const AVCodec *find_codec_or_die(void *logctx, const char *name,
+ enum AVMediaType type, int encoder)
{
const AVCodecDescriptor *desc;
const char *codec_string = encoder ? "encoder" : "decoder";
@@ -829,248 +638,22 @@ static const AVCodec *find_codec_or_die(const char *name, enum AVMediaType type,
codec = encoder ? avcodec_find_encoder(desc->id) :
avcodec_find_decoder(desc->id);
if (codec)
- av_log(NULL, AV_LOG_VERBOSE, "Matched %s '%s' for codec '%s'.\n",
+ av_log(logctx, AV_LOG_VERBOSE, "Matched %s '%s' for codec '%s'.\n",
codec_string, codec->name, desc->name);
}
if (!codec) {
- av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
+ av_log(logctx, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
exit_program(1);
}
if (codec->type != type && !recast_media) {
- av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
+ av_log(logctx, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
exit_program(1);
}
return codec;
}
-static const AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
-{
- char *codec_name = NULL;
-
- MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
- if (codec_name) {
- const AVCodec *codec = find_codec_or_die(codec_name, st->codecpar->codec_type, 0);
- st->codecpar->codec_id = codec->id;
- if (recast_media && st->codecpar->codec_type != codec->type)
- st->codecpar->codec_type = codec->type;
- return codec;
- } else
- return avcodec_find_decoder(st->codecpar->codec_id);
-}
-
-/* Add all the streams from the given input file to the global
- * list of input streams. */
-static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
-{
- int i, ret;
-
- for (i = 0; i < ic->nb_streams; i++) {
- AVStream *st = ic->streams[i];
- AVCodecParameters *par = st->codecpar;
- InputStream *ist;
- char *framerate = NULL, *hwaccel_device = NULL;
- const char *hwaccel = NULL;
- char *hwaccel_output_format = NULL;
- char *codec_tag = NULL;
- char *next;
- char *discard_str = NULL;
- const AVClass *cc = avcodec_get_class();
- const AVOption *discard_opt = av_opt_find(&cc, "skip_frame", NULL,
- 0, AV_OPT_SEARCH_FAKE_OBJ);
-
- ist = ALLOC_ARRAY_ELEM(input_streams, nb_input_streams);
- ist->st = st;
- ist->file_index = nb_input_files;
- ist->discard = 1;
- st->discard = AVDISCARD_ALL;
- ist->nb_samples = 0;
- ist->first_dts = AV_NOPTS_VALUE;
- ist->min_pts = INT64_MAX;
- ist->max_pts = INT64_MIN;
-
- ist->ts_scale = 1.0;
- MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
-
- ist->autorotate = 1;
- MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
-
- MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
- if (codec_tag) {
- uint32_t tag = strtol(codec_tag, &next, 0);
- if (*next)
- tag = AV_RL32(codec_tag);
- st->codecpar->codec_tag = tag;
- }
-
- ist->dec = choose_decoder(o, ic, st);
- ist->decoder_opts = filter_codec_opts(o->g->codec_opts, ist->st->codecpar->codec_id, ic, st, ist->dec);
-
- ist->reinit_filters = -1;
- MATCH_PER_STREAM_OPT(reinit_filters, i, ist->reinit_filters, ic, st);
-
- MATCH_PER_STREAM_OPT(discard, str, discard_str, ic, st);
- ist->user_set_discard = AVDISCARD_NONE;
-
- if ((o->video_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) ||
- (o->audio_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) ||
- (o->subtitle_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) ||
- (o->data_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA))
- ist->user_set_discard = AVDISCARD_ALL;
-
- if (discard_str && av_opt_eval_int(&cc, discard_opt, discard_str, &ist->user_set_discard) < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error parsing discard %s.\n",
- discard_str);
- exit_program(1);
- }
-
- ist->filter_in_rescale_delta_last = AV_NOPTS_VALUE;
- ist->prev_pkt_pts = AV_NOPTS_VALUE;
-
- ist->dec_ctx = avcodec_alloc_context3(ist->dec);
- if (!ist->dec_ctx) {
- av_log(NULL, AV_LOG_ERROR, "Error allocating the decoder context.\n");
- exit_program(1);
- }
-
- ret = avcodec_parameters_to_context(ist->dec_ctx, par);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error initializing the decoder context.\n");
- exit_program(1);
- }
-
- ist->decoded_frame = av_frame_alloc();
- if (!ist->decoded_frame)
- exit_program(1);
-
- ist->pkt = av_packet_alloc();
- if (!ist->pkt)
- exit_program(1);
-
- if (o->bitexact)
- ist->dec_ctx->flags |= AV_CODEC_FLAG_BITEXACT;
-
- switch (par->codec_type) {
- case AVMEDIA_TYPE_VIDEO:
- if(!ist->dec)
- ist->dec = avcodec_find_decoder(par->codec_id);
-
- // avformat_find_stream_info() doesn't set this for us anymore.
- ist->dec_ctx->framerate = st->avg_frame_rate;
-
- MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
- if (framerate && av_parse_video_rate(&ist->framerate,
- framerate) < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
- framerate);
- exit_program(1);
- }
-
- ist->top_field_first = -1;
- MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st);
-
- MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
- MATCH_PER_STREAM_OPT(hwaccel_output_formats, str,
- hwaccel_output_format, ic, st);
-
- if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "cuvid")) {
- av_log(NULL, AV_LOG_WARNING,
- "WARNING: defaulting hwaccel_output_format to cuda for compatibility "
- "with old commandlines. This behaviour is DEPRECATED and will be removed "
- "in the future. Please explicitly set \"-hwaccel_output_format cuda\".\n");
- ist->hwaccel_output_format = AV_PIX_FMT_CUDA;
- } else if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "qsv")) {
- av_log(NULL, AV_LOG_WARNING,
- "WARNING: defaulting hwaccel_output_format to qsv for compatibility "
- "with old commandlines. This behaviour is DEPRECATED and will be removed "
- "in the future. Please explicitly set \"-hwaccel_output_format qsv\".\n");
- ist->hwaccel_output_format = AV_PIX_FMT_QSV;
- } else if (hwaccel_output_format) {
- ist->hwaccel_output_format = av_get_pix_fmt(hwaccel_output_format);
- if (ist->hwaccel_output_format == AV_PIX_FMT_NONE) {
- av_log(NULL, AV_LOG_FATAL, "Unrecognised hwaccel output "
- "format: %s", hwaccel_output_format);
- }
- } else {
- ist->hwaccel_output_format = AV_PIX_FMT_NONE;
- }
-
- if (hwaccel) {
- // The NVDEC hwaccels use a CUDA device, so remap the name here.
- if (!strcmp(hwaccel, "nvdec") || !strcmp(hwaccel, "cuvid"))
- hwaccel = "cuda";
-
- if (!strcmp(hwaccel, "none"))
- ist->hwaccel_id = HWACCEL_NONE;
- else if (!strcmp(hwaccel, "auto"))
- ist->hwaccel_id = HWACCEL_AUTO;
- else {
- enum AVHWDeviceType type = av_hwdevice_find_type_by_name(hwaccel);
- if (type != AV_HWDEVICE_TYPE_NONE) {
- ist->hwaccel_id = HWACCEL_GENERIC;
- ist->hwaccel_device_type = type;
- }
-
- if (!ist->hwaccel_id) {
- av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n",
- hwaccel);
- av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: ");
- type = AV_HWDEVICE_TYPE_NONE;
- while ((type = av_hwdevice_iterate_types(type)) !=
- AV_HWDEVICE_TYPE_NONE)
- av_log(NULL, AV_LOG_FATAL, "%s ",
- av_hwdevice_get_type_name(type));
- av_log(NULL, AV_LOG_FATAL, "\n");
- exit_program(1);
- }
- }
- }
-
- MATCH_PER_STREAM_OPT(hwaccel_devices, str, hwaccel_device, ic, st);
- if (hwaccel_device) {
- ist->hwaccel_device = av_strdup(hwaccel_device);
- if (!ist->hwaccel_device)
- exit_program(1);
- }
-
- ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE;
-
- break;
- case AVMEDIA_TYPE_AUDIO:
- ist->guess_layout_max = INT_MAX;
- MATCH_PER_STREAM_OPT(guess_layout_max, i, ist->guess_layout_max, ic, st);
- guess_input_channel_layout(ist);
- break;
- case AVMEDIA_TYPE_DATA:
- case AVMEDIA_TYPE_SUBTITLE: {
- char *canvas_size = NULL;
- if(!ist->dec)
- ist->dec = avcodec_find_decoder(par->codec_id);
- MATCH_PER_STREAM_OPT(fix_sub_duration, i, ist->fix_sub_duration, ic, st);
- MATCH_PER_STREAM_OPT(canvas_sizes, str, canvas_size, ic, st);
- if (canvas_size &&
- av_parse_video_size(&ist->dec_ctx->width, &ist->dec_ctx->height, canvas_size) < 0) {
- av_log(NULL, AV_LOG_FATAL, "Invalid canvas size: %s.\n", canvas_size);
- exit_program(1);
- }
- break;
- }
- case AVMEDIA_TYPE_ATTACHMENT:
- case AVMEDIA_TYPE_UNKNOWN:
- break;
- default:
- abort();
- }
-
- ret = avcodec_parameters_from_context(par, ist->dec_ctx);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error initializing the decoder context.\n");
- exit_program(1);
- }
- }
-}
-
-static void assert_file_overwrite(const char *filename)
+void assert_file_overwrite(const char *filename)
{
const char *proto_name = avio_find_protocol_name(filename);
@@ -1113,625 +696,8 @@ static void assert_file_overwrite(const char *filename)
}
}
-static void dump_attachment(AVStream *st, const char *filename)
-{
- int ret;
- AVIOContext *out = NULL;
- const AVDictionaryEntry *e;
-
- if (!st->codecpar->extradata_size) {
- av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
- nb_input_files - 1, st->index);
- return;
- }
- if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
- filename = e->value;
- if (!*filename) {
- av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
- "in stream #%d:%d.\n", nb_input_files - 1, st->index);
- exit_program(1);
- }
-
- assert_file_overwrite(filename);
-
- if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
- av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
- filename);
- exit_program(1);
- }
-
- avio_write(out, st->codecpar->extradata, st->codecpar->extradata_size);
- avio_flush(out);
- avio_close(out);
-}
-
-static int open_input_file(OptionsContext *o, const char *filename)
-{
- InputFile *f;
- AVFormatContext *ic;
- const AVInputFormat *file_iformat = NULL;
- int err, i, ret;
- int64_t timestamp;
- AVDictionary *unused_opts = NULL;
- const AVDictionaryEntry *e = NULL;
- char * video_codec_name = NULL;
- char * audio_codec_name = NULL;
- char *subtitle_codec_name = NULL;
- char * data_codec_name = NULL;
- int scan_all_pmts_set = 0;
-
- if (o->stop_time != INT64_MAX && o->recording_time != INT64_MAX) {
- o->stop_time = INT64_MAX;
- av_log(NULL, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
- }
-
- if (o->stop_time != INT64_MAX && o->recording_time == INT64_MAX) {
- int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time;
- if (o->stop_time <= start_time) {
- av_log(NULL, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n");
- exit_program(1);
- } else {
- o->recording_time = o->stop_time - start_time;
- }
- }
-
- if (o->format) {
- if (!(file_iformat = av_find_input_format(o->format))) {
- av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
- exit_program(1);
- }
- }
-
- if (!strcmp(filename, "-"))
- filename = "pipe:";
-
- stdin_interaction &= strncmp(filename, "pipe:", 5) &&
- strcmp(filename, "/dev/stdin");
-
- /* get default parameters from command line */
- ic = avformat_alloc_context();
- if (!ic) {
- print_error(filename, AVERROR(ENOMEM));
- exit_program(1);
- }
- if (o->nb_audio_sample_rate) {
- av_dict_set_int(&o->g->format_opts, "sample_rate", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i, 0);
- }
- if (o->nb_audio_channels) {
- const AVClass *priv_class;
- if (file_iformat && (priv_class = file_iformat->priv_class) &&
- av_opt_find(&priv_class, "ch_layout", NULL, 0,
- AV_OPT_SEARCH_FAKE_OBJ)) {
- char buf[32];
- snprintf(buf, sizeof(buf), "%dC", o->audio_channels[o->nb_audio_channels - 1].u.i);
- av_dict_set(&o->g->format_opts, "ch_layout", buf, 0);
- }
- }
- if (o->nb_audio_ch_layouts) {
- const AVClass *priv_class;
- if (file_iformat && (priv_class = file_iformat->priv_class) &&
- av_opt_find(&priv_class, "ch_layout", NULL, 0,
- AV_OPT_SEARCH_FAKE_OBJ)) {
- av_dict_set(&o->g->format_opts, "ch_layout", o->audio_ch_layouts[o->nb_audio_ch_layouts - 1].u.str, 0);
- }
- }
- if (o->nb_frame_rates) {
- const AVClass *priv_class;
- /* set the format-level framerate option;
- * this is important for video grabbers, e.g. x11 */
- if (file_iformat && (priv_class = file_iformat->priv_class) &&
- av_opt_find(&priv_class, "framerate", NULL, 0,
- AV_OPT_SEARCH_FAKE_OBJ)) {
- av_dict_set(&o->g->format_opts, "framerate",
- o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
- }
- }
- if (o->nb_frame_sizes) {
- av_dict_set(&o->g->format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
- }
- if (o->nb_frame_pix_fmts)
- av_dict_set(&o->g->format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
-
- MATCH_PER_TYPE_OPT(codec_names, str, video_codec_name, ic, "v");
- MATCH_PER_TYPE_OPT(codec_names, str, audio_codec_name, ic, "a");
- MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, ic, "s");
- MATCH_PER_TYPE_OPT(codec_names, str, data_codec_name, ic, "d");
-
- if (video_codec_name)
- ic->video_codec = find_codec_or_die(video_codec_name , AVMEDIA_TYPE_VIDEO , 0);
- if (audio_codec_name)
- ic->audio_codec = find_codec_or_die(audio_codec_name , AVMEDIA_TYPE_AUDIO , 0);
- if (subtitle_codec_name)
- ic->subtitle_codec = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0);
- if (data_codec_name)
- ic->data_codec = find_codec_or_die(data_codec_name , AVMEDIA_TYPE_DATA , 0);
-
- ic->video_codec_id = video_codec_name ? ic->video_codec->id : AV_CODEC_ID_NONE;
- ic->audio_codec_id = audio_codec_name ? ic->audio_codec->id : AV_CODEC_ID_NONE;
- ic->subtitle_codec_id = subtitle_codec_name ? ic->subtitle_codec->id : AV_CODEC_ID_NONE;
- ic->data_codec_id = data_codec_name ? ic->data_codec->id : AV_CODEC_ID_NONE;
-
- ic->flags |= AVFMT_FLAG_NONBLOCK;
- if (o->bitexact)
- ic->flags |= AVFMT_FLAG_BITEXACT;
- ic->interrupt_callback = int_cb;
-
- if (!av_dict_get(o->g->format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
- av_dict_set(&o->g->format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
- scan_all_pmts_set = 1;
- }
- /* open the input file with generic avformat function */
- err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
- if (err < 0) {
- print_error(filename, err);
- if (err == AVERROR_PROTOCOL_NOT_FOUND)
- av_log(NULL, AV_LOG_ERROR, "Did you mean file:%s?\n", filename);
- exit_program(1);
- }
- if (scan_all_pmts_set)
- av_dict_set(&o->g->format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
- remove_avoptions(&o->g->format_opts, o->g->codec_opts);
- assert_avoptions(o->g->format_opts);
-
- /* apply forced codec ids */
- for (i = 0; i < ic->nb_streams; i++)
- choose_decoder(o, ic, ic->streams[i]);
-
- if (find_stream_info) {
- AVDictionary **opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
- int orig_nb_streams = ic->nb_streams;
-
- /* If not enough info to get the stream parameters, we decode the
- first frames to get it. (used in mpeg case for example) */
- ret = avformat_find_stream_info(ic, opts);
-
- for (i = 0; i < orig_nb_streams; i++)
- av_dict_free(&opts[i]);
- av_freep(&opts);
-
- if (ret < 0) {
- av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
- if (ic->nb_streams == 0) {
- avformat_close_input(&ic);
- exit_program(1);
- }
- }
- }
-
- if (o->start_time != AV_NOPTS_VALUE && o->start_time_eof != AV_NOPTS_VALUE) {
- av_log(NULL, AV_LOG_WARNING, "Cannot use -ss and -sseof both, using -ss for %s\n", filename);
- o->start_time_eof = AV_NOPTS_VALUE;
- }
-
- if (o->start_time_eof != AV_NOPTS_VALUE) {
- if (o->start_time_eof >= 0) {
- av_log(NULL, AV_LOG_ERROR, "-sseof value must be negative; aborting\n");
- exit_program(1);
- }
- if (ic->duration > 0) {
- o->start_time = o->start_time_eof + ic->duration;
- if (o->start_time < 0) {
- av_log(NULL, AV_LOG_WARNING, "-sseof value seeks to before start of file %s; ignored\n", filename);
- o->start_time = AV_NOPTS_VALUE;
- }
- } else
- av_log(NULL, AV_LOG_WARNING, "Cannot use -sseof, duration of %s not known\n", filename);
- }
- timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time;
- /* add the stream start time */
- if (!o->seek_timestamp && ic->start_time != AV_NOPTS_VALUE)
- timestamp += ic->start_time;
-
- /* if seeking requested, we execute it */
- if (o->start_time != AV_NOPTS_VALUE) {
- int64_t seek_timestamp = timestamp;
-
- if (!(ic->iformat->flags & AVFMT_SEEK_TO_PTS)) {
- int dts_heuristic = 0;
- for (i=0; inb_streams; i++) {
- const AVCodecParameters *par = ic->streams[i]->codecpar;
- if (par->video_delay) {
- dts_heuristic = 1;
- break;
- }
- }
- if (dts_heuristic) {
- seek_timestamp -= 3*AV_TIME_BASE / 23;
- }
- }
- ret = avformat_seek_file(ic, -1, INT64_MIN, seek_timestamp, seek_timestamp, 0);
- if (ret < 0) {
- av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
- filename, (double)timestamp / AV_TIME_BASE);
- }
- }
-
- /* update the current parameters so that they match the one of the input stream */
- add_input_streams(o, ic);
-
- /* dump the file content */
- av_dump_format(ic, nb_input_files, filename, 0);
-
- f = ALLOC_ARRAY_ELEM(input_files, nb_input_files);
-
- f->ctx = ic;
- f->ist_index = nb_input_streams - ic->nb_streams;
- f->start_time = o->start_time;
- f->recording_time = o->recording_time;
- f->input_sync_ref = o->input_sync_ref;
- f->input_ts_offset = o->input_ts_offset;
- f->ts_offset = o->input_ts_offset - (copy_ts ? (start_at_zero && ic->start_time != AV_NOPTS_VALUE ? ic->start_time : 0) : timestamp);
- f->nb_streams = ic->nb_streams;
- f->rate_emu = o->rate_emu;
- f->accurate_seek = o->accurate_seek;
- f->loop = o->loop;
- f->duration = 0;
- f->time_base = (AVRational){ 1, 1 };
-
- f->readrate = o->readrate ? o->readrate : 0.0;
- if (f->readrate < 0.0f) {
- av_log(NULL, AV_LOG_ERROR, "Option -readrate for Input #%d is %0.3f; it must be non-negative.\n", nb_input_files, f->readrate);
- exit_program(1);
- }
- if (f->readrate && f->rate_emu) {
- av_log(NULL, AV_LOG_WARNING, "Both -readrate and -re set for Input #%d. Using -readrate %0.3f.\n", nb_input_files, f->readrate);
- f->rate_emu = 0;
- }
-
- f->pkt = av_packet_alloc();
- if (!f->pkt)
- exit_program(1);
-#if HAVE_THREADS
- f->thread_queue_size = o->thread_queue_size;
-#endif
-
- /* check if all codec options have been used */
- unused_opts = strip_specifiers(o->g->codec_opts);
- for (i = f->ist_index; i < nb_input_streams; i++) {
- e = NULL;
- while ((e = av_dict_get(input_streams[i]->decoder_opts, "", e,
- AV_DICT_IGNORE_SUFFIX)))
- av_dict_set(&unused_opts, e->key, NULL, 0);
- }
-
- e = NULL;
- while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
- const AVClass *class = avcodec_get_class();
- const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
- AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
- const AVClass *fclass = avformat_get_class();
- const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0,
- AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
- if (!option || foption)
- continue;
-
-
- if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) {
- av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
- "input file #%d (%s) is not a decoding option.\n", e->key,
- option->help ? option->help : "", nb_input_files - 1,
- filename);
- exit_program(1);
- }
-
- av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
- "input file #%d (%s) has not been used for any stream. The most "
- "likely reason is either wrong type (e.g. a video option with "
- "no video streams) or that it is a private option of some decoder "
- "which was not actually used for any stream.\n", e->key,
- option->help ? option->help : "", nb_input_files - 1, filename);
- }
- av_dict_free(&unused_opts);
-
- for (i = 0; i < o->nb_dump_attachment; i++) {
- int j;
-
- for (j = 0; j < ic->nb_streams; j++) {
- AVStream *st = ic->streams[j];
-
- if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
- dump_attachment(st, o->dump_attachment[i].u.str);
- }
- }
-
- input_stream_potentially_available = 1;
-
- return 0;
-}
-
-static char *get_line(AVIOContext *s, AVBPrint *bprint)
-{
- char c;
-
- while ((c = avio_r8(s)) && c != '\n')
- av_bprint_chars(bprint, c, 1);
-
- if (!av_bprint_is_complete(bprint)) {
- av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
- exit_program(1);
- }
- return bprint->str;
-}
-
-static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
-{
- int i, ret = -1;
- char filename[1000];
- char *env_avconv_datadir = getenv_utf8("AVCONV_DATADIR");
- char *env_home = getenv_utf8("HOME");
- const char *base[3] = { env_avconv_datadir,
- env_home,
- AVCONV_DATADIR,
- };
-
- for (i = 0; i < FF_ARRAY_ELEMS(base) && ret < 0; i++) {
- if (!base[i])
- continue;
- if (codec_name) {
- snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
- i != 1 ? "" : "/.avconv", codec_name, preset_name);
- ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
- }
- if (ret < 0) {
- snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
- i != 1 ? "" : "/.avconv", preset_name);
- ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
- }
- }
- freeenv_utf8(env_home);
- freeenv_utf8(env_avconv_datadir);
- return ret;
-}
-
-static int choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
-{
- enum AVMediaType type = ost->st->codecpar->codec_type;
- char *codec_name = NULL;
-
- if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO || type == AVMEDIA_TYPE_SUBTITLE) {
- MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
- if (!codec_name) {
- ost->st->codecpar->codec_id = av_guess_codec(s->oformat, NULL, s->url,
- NULL, ost->st->codecpar->codec_type);
- ost->enc = avcodec_find_encoder(ost->st->codecpar->codec_id);
- if (!ost->enc) {
- av_log(NULL, AV_LOG_FATAL, "Automatic encoder selection failed for "
- "output stream #%d:%d. Default encoder for format %s (codec %s) is "
- "probably disabled. Please choose an encoder manually.\n",
- ost->file_index, ost->index, s->oformat->name,
- avcodec_get_name(ost->st->codecpar->codec_id));
- return AVERROR_ENCODER_NOT_FOUND;
- }
- } else if (!strcmp(codec_name, "copy"))
- ost->stream_copy = 1;
- else {
- ost->enc = find_codec_or_die(codec_name, ost->st->codecpar->codec_type, 1);
- ost->st->codecpar->codec_id = ost->enc->id;
- }
- ost->encoding_needed = !ost->stream_copy;
- } else {
- /* no encoding supported for other media types */
- ost->stream_copy = 1;
- ost->encoding_needed = 0;
- }
-
- return 0;
-}
-
-static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type, int source_index)
-{
- OutputStream *ost;
- AVStream *st = avformat_new_stream(oc, NULL);
- int idx = oc->nb_streams - 1, ret = 0;
- const char *bsfs = NULL, *time_base = NULL;
- char *next, *codec_tag = NULL;
- double qscale = -1;
- int i;
-
- if (!st) {
- av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
- exit_program(1);
- }
-
- if (oc->nb_streams - 1 < o->nb_streamid_map)
- st->id = o->streamid_map[oc->nb_streams - 1];
-
- ost = ALLOC_ARRAY_ELEM(output_streams, nb_output_streams);
-
- ost->file_index = nb_output_files - 1;
- ost->index = idx;
- ost->st = st;
- ost->forced_kf_ref_pts = AV_NOPTS_VALUE;
- st->codecpar->codec_type = type;
-
- ret = choose_encoder(o, oc, ost);
- if (ret < 0) {
- av_log(NULL, AV_LOG_FATAL, "Error selecting an encoder for stream "
- "%d:%d\n", ost->file_index, ost->index);
- exit_program(1);
- }
-
- ost->enc_ctx = avcodec_alloc_context3(ost->enc);
- if (!ost->enc_ctx) {
- av_log(NULL, AV_LOG_ERROR, "Error allocating the encoding context.\n");
- exit_program(1);
- }
- ost->enc_ctx->codec_type = type;
-
- ost->ref_par = avcodec_parameters_alloc();
- if (!ost->ref_par) {
- av_log(NULL, AV_LOG_ERROR, "Error allocating the encoding parameters.\n");
- exit_program(1);
- }
-
- ost->filtered_frame = av_frame_alloc();
- if (!ost->filtered_frame)
- exit_program(1);
-
- ost->pkt = av_packet_alloc();
- if (!ost->pkt)
- exit_program(1);
-
- if (ost->enc) {
- AVIOContext *s = NULL;
- char *buf = NULL, *arg = NULL, *preset = NULL;
-
- ost->encoder_opts = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc);
-
- MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
- ost->autoscale = 1;
- MATCH_PER_STREAM_OPT(autoscale, i, ost->autoscale, oc, st);
- if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
- AVBPrint bprint;
- av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
- do {
- av_bprint_clear(&bprint);
- buf = get_line(s, &bprint);
- if (!buf[0] || buf[0] == '#')
- continue;
- if (!(arg = strchr(buf, '='))) {
- av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
- exit_program(1);
- }
- *arg++ = 0;
- av_dict_set(&ost->encoder_opts, buf, arg, AV_DICT_DONT_OVERWRITE);
- } while (!s->eof_reached);
- av_bprint_finalize(&bprint, NULL);
- avio_closep(&s);
- }
- if (ret) {
- av_log(NULL, AV_LOG_FATAL,
- "Preset %s specified for stream %d:%d, but could not be opened.\n",
- preset, ost->file_index, ost->index);
- exit_program(1);
- }
- } else {
- ost->encoder_opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL);
- }
-
-
- if (o->bitexact)
- ost->enc_ctx->flags |= AV_CODEC_FLAG_BITEXACT;
-
- MATCH_PER_STREAM_OPT(time_bases, str, time_base, oc, st);
- if (time_base) {
- AVRational q;
- if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 ||
- q.num <= 0 || q.den <= 0) {
- av_log(NULL, AV_LOG_FATAL, "Invalid time base: %s\n", time_base);
- exit_program(1);
- }
- st->time_base = q;
- }
-
- MATCH_PER_STREAM_OPT(enc_time_bases, str, time_base, oc, st);
- if (time_base) {
- AVRational q;
- if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 ||
- q.den <= 0) {
- av_log(NULL, AV_LOG_FATAL, "Invalid time base: %s\n", time_base);
- exit_program(1);
- }
- ost->enc_timebase = q;
- }
-
- ost->max_frames = INT64_MAX;
- MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
- for (i = 0; inb_max_frames; i++) {
- char *p = o->max_frames[i].specifier;
- if (!*p && type != AVMEDIA_TYPE_VIDEO) {
- av_log(NULL, AV_LOG_WARNING, "Applying unspecific -frames to non video streams, maybe you meant -vframes ?\n");
- break;
- }
- }
-
- ost->copy_prior_start = -1;
- MATCH_PER_STREAM_OPT(copy_prior_start, i, ost->copy_prior_start, oc ,st);
-
- MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st);
- if (bsfs && *bsfs) {
- ret = av_bsf_list_parse_str(bsfs, &ost->bsf_ctx);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error parsing bitstream filter sequence '%s': %s\n", bsfs, av_err2str(ret));
- exit_program(1);
- }
- }
-
- MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
- if (codec_tag) {
- uint32_t tag = strtol(codec_tag, &next, 0);
- if (*next)
- tag = AV_RL32(codec_tag);
- ost->st->codecpar->codec_tag =
- ost->enc_ctx->codec_tag = tag;
- }
-
- MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
- if (qscale >= 0) {
- ost->enc_ctx->flags |= AV_CODEC_FLAG_QSCALE;
- ost->enc_ctx->global_quality = FF_QP2LAMBDA * qscale;
- }
-
- MATCH_PER_STREAM_OPT(disposition, str, ost->disposition, oc, st);
- ost->disposition = av_strdup(ost->disposition);
-
- ost->max_muxing_queue_size = 128;
- MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ost->max_muxing_queue_size, oc, st);
-
- ost->muxing_queue_data_size = 0;
-
- ost->muxing_queue_data_threshold = 50*1024*1024;
- MATCH_PER_STREAM_OPT(muxing_queue_data_threshold, i, ost->muxing_queue_data_threshold, oc, st);
-
- MATCH_PER_STREAM_OPT(bits_per_raw_sample, i, ost->bits_per_raw_sample,
- oc, st);
-
- if (oc->oformat->flags & AVFMT_GLOBALHEADER)
- ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
-
- av_dict_copy(&ost->sws_dict, o->g->sws_dict, 0);
-
- av_dict_copy(&ost->swr_opts, o->g->swr_opts, 0);
- if (ost->enc && av_get_exact_bits_per_sample(ost->enc->id) == 24)
- av_dict_set(&ost->swr_opts, "output_sample_bits", "24", 0);
-
- ost->source_index = source_index;
- if (source_index >= 0) {
- ost->sync_ist = input_streams[source_index];
- input_streams[source_index]->discard = 0;
- input_streams[source_index]->st->discard = input_streams[source_index]->user_set_discard;
- }
- ost->last_mux_dts = AV_NOPTS_VALUE;
-
- ost->muxing_queue = av_fifo_alloc2(8, sizeof(AVPacket*), 0);
- if (!ost->muxing_queue)
- exit_program(1);
-
- MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i,
- ost->copy_initial_nonkeyframes, oc, st);
-
- return ost;
-}
-
-static void parse_matrix_coeffs(uint16_t *dest, const char *str)
-{
- int i;
- const char *p = str;
- for (i = 0;; i++) {
- dest[i] = atoi(p);
- if (i == 63)
- break;
- p = strchr(p, ',');
- if (!p) {
- av_log(NULL, AV_LOG_FATAL, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
- exit_program(1);
- }
- p++;
- }
-}
-
/* read file contents into a string */
-static char *read_file(const char *filename)
+char *file_read(const char *filename)
{
AVIOContext *pb = NULL;
int ret = avio_open(&pb, filename, AVIO_FLAG_READ);
@@ -1756,437 +722,6 @@ static char *read_file(const char *filename)
return str;
}
-static char *get_ost_filters(OptionsContext *o, AVFormatContext *oc,
- OutputStream *ost)
-{
- AVStream *st = ost->st;
-
- if (ost->filters_script && ost->filters) {
- av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for "
- "output stream #%d:%d.\n", nb_output_files, st->index);
- exit_program(1);
- }
-
- if (ost->filters_script)
- return read_file(ost->filters_script);
- else if (ost->filters)
- return av_strdup(ost->filters);
-
- return av_strdup(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ?
- "null" : "anull");
-}
-
-static void check_streamcopy_filters(OptionsContext *o, AVFormatContext *oc,
- const OutputStream *ost, enum AVMediaType type)
-{
- if (ost->filters_script || ost->filters) {
- av_log(NULL, AV_LOG_ERROR,
- "%s '%s' was defined for %s output stream %d:%d but codec copy was selected.\n"
- "Filtering and streamcopy cannot be used together.\n",
- ost->filters ? "Filtergraph" : "Filtergraph script",
- ost->filters ? ost->filters : ost->filters_script,
- av_get_media_type_string(type), ost->file_index, ost->index);
- exit_program(1);
- }
-}
-
-static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
-{
- AVStream *st;
- OutputStream *ost;
- AVCodecContext *video_enc;
- char *frame_rate = NULL, *max_frame_rate = NULL, *frame_aspect_ratio = NULL;
-
- ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO, source_index);
- st = ost->st;
- video_enc = ost->enc_ctx;
-
- MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
- if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
- av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
- exit_program(1);
- }
-
- MATCH_PER_STREAM_OPT(max_frame_rates, str, max_frame_rate, oc, st);
- if (max_frame_rate && av_parse_video_rate(&ost->max_frame_rate, max_frame_rate) < 0) {
- av_log(NULL, AV_LOG_FATAL, "Invalid maximum framerate value: %s\n", max_frame_rate);
- exit_program(1);
- }
-
- if (frame_rate && max_frame_rate) {
- av_log(NULL, AV_LOG_ERROR, "Only one of -fpsmax and -r can be set for a stream.\n");
- exit_program(1);
- }
-
- if ((frame_rate || max_frame_rate) &&
- video_sync_method == VSYNC_PASSTHROUGH)
- av_log(NULL, AV_LOG_ERROR, "Using -vsync passthrough and -r/-fpsmax can produce invalid output files\n");
-
- MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
- if (frame_aspect_ratio) {
- AVRational q;
- if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 ||
- q.num <= 0 || q.den <= 0) {
- av_log(NULL, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio);
- exit_program(1);
- }
- ost->frame_aspect_ratio = q;
- }
-
- MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
- MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
-
- if (!ost->stream_copy) {
- const char *p = NULL;
- char *frame_size = NULL;
- char *frame_pix_fmt = NULL;
- char *intra_matrix = NULL, *inter_matrix = NULL;
- char *chroma_intra_matrix = NULL;
- int do_pass = 0;
- int i;
-
- MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
- if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
- av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
- exit_program(1);
- }
-
- MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
- if (frame_pix_fmt && *frame_pix_fmt == '+') {
- ost->keep_pix_fmt = 1;
- if (!*++frame_pix_fmt)
- frame_pix_fmt = NULL;
- }
- if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == AV_PIX_FMT_NONE) {
- av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
- exit_program(1);
- }
- st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
-
- MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
- if (intra_matrix) {
- if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
- av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
- exit_program(1);
- }
- parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
- }
- MATCH_PER_STREAM_OPT(chroma_intra_matrices, str, chroma_intra_matrix, oc, st);
- if (chroma_intra_matrix) {
- uint16_t *p = av_mallocz(sizeof(*video_enc->chroma_intra_matrix) * 64);
- if (!p) {
- av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
- exit_program(1);
- }
- video_enc->chroma_intra_matrix = p;
- parse_matrix_coeffs(p, chroma_intra_matrix);
- }
- MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
- if (inter_matrix) {
- if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
- av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");
- exit_program(1);
- }
- parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
- }
-
- MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
- for (i = 0; p; i++) {
- int start, end, q;
- int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
- if (e != 3) {
- av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
- exit_program(1);
- }
- video_enc->rc_override =
- av_realloc_array(video_enc->rc_override,
- i + 1, sizeof(RcOverride));
- if (!video_enc->rc_override) {
- av_log(NULL, AV_LOG_FATAL, "Could not (re)allocate memory for rc_override.\n");
- exit_program(1);
- }
- video_enc->rc_override[i].start_frame = start;
- video_enc->rc_override[i].end_frame = end;
- if (q > 0) {
- video_enc->rc_override[i].qscale = q;
- video_enc->rc_override[i].quality_factor = 1.0;
- }
- else {
- video_enc->rc_override[i].qscale = 0;
- video_enc->rc_override[i].quality_factor = -q/100.0;
- }
- p = strchr(p, '/');
- if (p) p++;
- }
- video_enc->rc_override_count = i;
-
- if (do_psnr)
- video_enc->flags|= AV_CODEC_FLAG_PSNR;
-
- /* two pass mode */
- MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
- if (do_pass) {
- if (do_pass & 1) {
- video_enc->flags |= AV_CODEC_FLAG_PASS1;
- av_dict_set(&ost->encoder_opts, "flags", "+pass1", AV_DICT_APPEND);
- }
- if (do_pass & 2) {
- video_enc->flags |= AV_CODEC_FLAG_PASS2;
- av_dict_set(&ost->encoder_opts, "flags", "+pass2", AV_DICT_APPEND);
- }
- }
-
- MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
- if (ost->logfile_prefix &&
- !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
- exit_program(1);
-
- if (do_pass) {
- char logfilename[1024];
- FILE *f;
-
- snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
- ost->logfile_prefix ? ost->logfile_prefix :
- DEFAULT_PASS_LOGFILENAME_PREFIX,
- nb_output_streams - 1);
- if (!strcmp(ost->enc->name, "libx264")) {
- av_dict_set(&ost->encoder_opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
- } else {
- if (video_enc->flags & AV_CODEC_FLAG_PASS2) {
- char *logbuffer = read_file(logfilename);
-
- if (!logbuffer) {
- av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
- logfilename);
- exit_program(1);
- }
- video_enc->stats_in = logbuffer;
- }
- if (video_enc->flags & AV_CODEC_FLAG_PASS1) {
- f = fopen_utf8(logfilename, "wb");
- if (!f) {
- av_log(NULL, AV_LOG_FATAL,
- "Cannot write log file '%s' for pass-1 encoding: %s\n",
- logfilename, strerror(errno));
- exit_program(1);
- }
- ost->logfile = f;
- }
- }
- }
-
- MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
- if (ost->forced_keyframes)
- ost->forced_keyframes = av_strdup(ost->forced_keyframes);
-
- MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
-
- ost->top_field_first = -1;
- MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
-
- ost->vsync_method = video_sync_method;
- MATCH_PER_STREAM_OPT(fps_mode, str, ost->fps_mode, oc, st);
- if (ost->fps_mode)
- parse_and_set_vsync(ost->fps_mode, &ost->vsync_method, ost->file_index, ost->index, 0);
-
- if (ost->vsync_method == VSYNC_AUTO) {
- if (!strcmp(oc->oformat->name, "avi")) {
- ost->vsync_method = VSYNC_VFR;
- } else {
- ost->vsync_method = (oc->oformat->flags & AVFMT_VARIABLE_FPS) ?
- ((oc->oformat->flags & AVFMT_NOTIMESTAMPS) ?
- VSYNC_PASSTHROUGH : VSYNC_VFR) :
- VSYNC_CFR;
- }
-
- if (ost->source_index >= 0 && ost->vsync_method == VSYNC_CFR) {
- const InputStream *ist = input_streams[ost->source_index];
- const InputFile *ifile = input_files[ist->file_index];
-
- if (ifile->nb_streams == 1 && ifile->input_ts_offset == 0)
- ost->vsync_method = VSYNC_VSCFR;
- }
-
- if (ost->vsync_method == VSYNC_CFR && copy_ts) {
- ost->vsync_method = VSYNC_VSCFR;
- }
- }
- ost->is_cfr = (ost->vsync_method == VSYNC_CFR || ost->vsync_method == VSYNC_VSCFR);
-
- ost->avfilter = get_ost_filters(o, oc, ost);
- if (!ost->avfilter)
- exit_program(1);
-
- ost->last_frame = av_frame_alloc();
- if (!ost->last_frame)
- exit_program(1);
- }
-
- if (ost->stream_copy)
- check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_VIDEO);
-
- return ost;
-}
-
-static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
-{
- int n;
- AVStream *st;
- OutputStream *ost;
- AVCodecContext *audio_enc;
-
- ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO, source_index);
- st = ost->st;
-
- audio_enc = ost->enc_ctx;
- audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
-
- MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
- MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
-
- if (!ost->stream_copy) {
- int channels = 0;
- char *layout = NULL;
- char *sample_fmt = NULL;
-
- MATCH_PER_STREAM_OPT(audio_channels, i, channels, oc, st);
- if (channels) {
- audio_enc->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
- audio_enc->ch_layout.nb_channels = channels;
- }
-
- MATCH_PER_STREAM_OPT(audio_ch_layouts, str, layout, oc, st);
- if (layout) {
- if (av_channel_layout_from_string(&audio_enc->ch_layout, layout) < 0) {
-#if FF_API_OLD_CHANNEL_LAYOUT
- uint64_t mask;
- AV_NOWARN_DEPRECATED({
- mask = av_get_channel_layout(layout);
- })
- if (!mask) {
-#endif
- av_log(NULL, AV_LOG_FATAL, "Unknown channel layout: %s\n", layout);
- exit_program(1);
-#if FF_API_OLD_CHANNEL_LAYOUT
- }
- av_log(NULL, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n",
- layout);
- av_channel_layout_from_mask(&audio_enc->ch_layout, mask);
-#endif
- }
- }
-
- MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
- if (sample_fmt &&
- (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
- av_log(NULL, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
- exit_program(1);
- }
-
- MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
-
- MATCH_PER_STREAM_OPT(apad, str, ost->apad, oc, st);
- ost->apad = av_strdup(ost->apad);
-
- ost->avfilter = get_ost_filters(o, oc, ost);
- if (!ost->avfilter)
- exit_program(1);
-
- /* check for channel mapping for this audio stream */
- for (n = 0; n < o->nb_audio_channel_maps; n++) {
- AudioChannelMap *map = &o->audio_channel_maps[n];
- if ((map->ofile_idx == -1 || ost->file_index == map->ofile_idx) &&
- (map->ostream_idx == -1 || ost->st->index == map->ostream_idx)) {
- InputStream *ist;
-
- if (map->channel_idx == -1) {
- ist = NULL;
- } else if (ost->source_index < 0) {
- av_log(NULL, AV_LOG_FATAL, "Cannot determine input stream for channel mapping %d.%d\n",
- ost->file_index, ost->st->index);
- continue;
- } else {
- ist = input_streams[ost->source_index];
- }
-
- if (!ist || (ist->file_index == map->file_idx && ist->st->index == map->stream_idx)) {
- if (av_reallocp_array(&ost->audio_channels_map,
- ost->audio_channels_mapped + 1,
- sizeof(*ost->audio_channels_map)
- ) < 0 )
- exit_program(1);
-
- ost->audio_channels_map[ost->audio_channels_mapped++] = map->channel_idx;
- }
- }
- }
- }
-
- if (ost->stream_copy)
- check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_AUDIO);
-
- return ost;
-}
-
-static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
-{
- OutputStream *ost;
-
- ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA, source_index);
- if (!ost->stream_copy) {
- av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
- exit_program(1);
- }
-
- return ost;
-}
-
-static OutputStream *new_unknown_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
-{
- OutputStream *ost;
-
- ost = new_output_stream(o, oc, AVMEDIA_TYPE_UNKNOWN, source_index);
- if (!ost->stream_copy) {
- av_log(NULL, AV_LOG_FATAL, "Unknown stream encoding not supported yet (only streamcopy)\n");
- exit_program(1);
- }
-
- return ost;
-}
-
-static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
-{
- OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT, source_index);
- ost->stream_copy = 1;
- ost->finished = 1;
- return ost;
-}
-
-static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
-{
- AVStream *st;
- OutputStream *ost;
- AVCodecContext *subtitle_enc;
-
- ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE, source_index);
- st = ost->st;
- subtitle_enc = ost->enc_ctx;
-
- subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
-
- if (!ost->stream_copy) {
- char *frame_size = NULL;
-
- MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
- if (frame_size && av_parse_video_size(&subtitle_enc->width, &subtitle_enc->height, frame_size) < 0) {
- av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
- exit_program(1);
- }
- }
-
- return ost;
-}
-
/* arg format is "output-stream-index:streamid-value". */
static int opt_streamid(void *optctx, const char *opt, const char *arg)
{
@@ -2210,156 +745,6 @@ static int opt_streamid(void *optctx, const char *opt, const char *arg)
return 0;
}
-static int copy_chapters(InputFile *ifile, OutputFile *ofile, AVFormatContext *os,
- int copy_metadata)
-{
- AVFormatContext *is = ifile->ctx;
- AVChapter **tmp;
- int i;
-
- tmp = av_realloc_f(os->chapters, is->nb_chapters + os->nb_chapters, sizeof(*os->chapters));
- if (!tmp)
- return AVERROR(ENOMEM);
- os->chapters = tmp;
-
- for (i = 0; i < is->nb_chapters; i++) {
- AVChapter *in_ch = is->chapters[i], *out_ch;
- int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
- int64_t ts_off = av_rescale_q(start_time - ifile->ts_offset,
- AV_TIME_BASE_Q, in_ch->time_base);
- int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
- av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
-
-
- if (in_ch->end < ts_off)
- continue;
- if (rt != INT64_MAX && in_ch->start > rt + ts_off)
- break;
-
- out_ch = av_mallocz(sizeof(AVChapter));
- if (!out_ch)
- return AVERROR(ENOMEM);
-
- out_ch->id = in_ch->id;
- out_ch->time_base = in_ch->time_base;
- out_ch->start = FFMAX(0, in_ch->start - ts_off);
- out_ch->end = FFMIN(rt, in_ch->end - ts_off);
-
- if (copy_metadata)
- av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
-
- os->chapters[os->nb_chapters++] = out_ch;
- }
- return 0;
-}
-
-static int set_dispositions(OutputFile *of, AVFormatContext *ctx)
-{
- int nb_streams[AVMEDIA_TYPE_NB] = { 0 };
- int have_default[AVMEDIA_TYPE_NB] = { 0 };
- int have_manual = 0;
-
- // first, copy the input dispositions
- for (int i = 0; i < ctx->nb_streams; i++) {
- OutputStream *ost = output_streams[of->ost_index + i];
-
- nb_streams[ost->st->codecpar->codec_type]++;
-
- have_manual |= !!ost->disposition;
-
- if (ost->source_index >= 0) {
- ost->st->disposition = input_streams[ost->source_index]->st->disposition;
-
- if (ost->st->disposition & AV_DISPOSITION_DEFAULT)
- have_default[ost->st->codecpar->codec_type] = 1;
- }
- }
-
- if (have_manual) {
- // process manually set dispositions - they override the above copy
- for (int i = 0; i < ctx->nb_streams; i++) {
- OutputStream *ost = output_streams[of->ost_index + i];
- int ret;
-
- if (!ost->disposition)
- continue;
-
-#if LIBAVFORMAT_VERSION_MAJOR >= 60
- ret = av_opt_set(ost->st, "disposition", ost->disposition, 0);
-#else
- {
- const AVClass *class = av_stream_get_class();
- const AVOption *o = av_opt_find(&class, "disposition", NULL, 0, AV_OPT_SEARCH_FAKE_OBJ);
-
- av_assert0(o);
- ret = av_opt_eval_flags(&class, o, ost->disposition, &ost->st->disposition);
- }
-#endif
-
- if (ret < 0)
- return ret;
- }
- } else {
- // For each media type with more than one stream, find a suitable stream to
- // mark as default, unless one is already marked default.
- // "Suitable" means the first of that type, skipping attached pictures.
- for (int i = 0; i < ctx->nb_streams; i++) {
- OutputStream *ost = output_streams[of->ost_index + i];
- enum AVMediaType type = ost->st->codecpar->codec_type;
-
- if (nb_streams[type] < 2 || have_default[type] ||
- ost->st->disposition & AV_DISPOSITION_ATTACHED_PIC)
- continue;
-
- ost->st->disposition |= AV_DISPOSITION_DEFAULT;
- have_default[type] = 1;
- }
- }
-
- return 0;
-}
-
-static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
- AVFormatContext *oc)
-{
- OutputStream *ost;
-
- switch (ofilter->type) {
- case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc, -1); break;
- case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc, -1); break;
- default:
- av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported "
- "currently.\n");
- exit_program(1);
- }
-
- ost->filter = ofilter;
-
- ofilter->ost = ost;
- ofilter->format = -1;
-
- if (ost->stream_copy) {
- av_log(NULL, AV_LOG_ERROR, "Streamcopy requested for output stream %d:%d, "
- "which is fed from a complex filtergraph. Filtering and streamcopy "
- "cannot be used together.\n", ost->file_index, ost->index);
- exit_program(1);
- }
-
- if (ost->avfilter && (ost->filters || ost->filters_script)) {
- const char *opt = ost->filters ? "-vf/-af/-filter" : "-filter_script";
- av_log(NULL, AV_LOG_ERROR,
- "%s '%s' was specified through the %s option "
- "for output stream %d:%d, which is fed from a complex filtergraph.\n"
- "%s and -filter_complex cannot be used together for the same stream.\n",
- ost->filters ? "Filtergraph" : "Filtergraph script",
- ost->filters ? ost->filters : ost->filters_script,
- opt, ost->file_index, ost->index, opt);
- exit_program(1);
- }
-
- avfilter_inout_free(&ofilter->out_tmp);
-}
-
static int init_complex_filters(void)
{
int i, ret = 0;
@@ -2372,680 +757,6 @@ static int init_complex_filters(void)
return 0;
}
-static void set_channel_layout(OutputFilter *f, OutputStream *ost)
-{
- int i, err;
-
- if (ost->enc_ctx->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
- /* Pass the layout through for all orders but UNSPEC */
- err = av_channel_layout_copy(&f->ch_layout, &ost->enc_ctx->ch_layout);
- if (err < 0)
- exit_program(1);
- return;
- }
-
- /* Requested layout is of order UNSPEC */
- if (!ost->enc->ch_layouts) {
- /* Use the default native layout for the requested amount of channels when the
- encoder doesn't have a list of supported layouts */
- av_channel_layout_default(&f->ch_layout, ost->enc_ctx->ch_layout.nb_channels);
- return;
- }
- /* Encoder has a list of supported layouts. Pick the first layout in it with the
- same amount of channels as the requested layout */
- for (i = 0; ost->enc->ch_layouts[i].nb_channels; i++) {
- if (ost->enc->ch_layouts[i].nb_channels == ost->enc_ctx->ch_layout.nb_channels)
- break;
- }
- if (ost->enc->ch_layouts[i].nb_channels) {
- /* Use it if one is found */
- err = av_channel_layout_copy(&f->ch_layout, &ost->enc->ch_layouts[i]);
- if (err < 0)
- exit_program(1);
- return;
- }
- /* If no layout for the amount of channels requested was found, use the default
- native layout for it. */
- av_channel_layout_default(&f->ch_layout, ost->enc_ctx->ch_layout.nb_channels);
-}
-
-static int open_output_file(OptionsContext *o, const char *filename)
-{
- AVFormatContext *oc;
- int i, j, err;
- OutputFile *of;
- OutputStream *ost;
- InputStream *ist;
- AVDictionary *unused_opts = NULL;
- const AVDictionaryEntry *e = NULL;
-
- if (o->stop_time != INT64_MAX && o->recording_time != INT64_MAX) {
- o->stop_time = INT64_MAX;
- av_log(NULL, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
- }
-
- if (o->stop_time != INT64_MAX && o->recording_time == INT64_MAX) {
- int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time;
- if (o->stop_time <= start_time) {
- av_log(NULL, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n");
- exit_program(1);
- } else {
- o->recording_time = o->stop_time - start_time;
- }
- }
-
- of = ALLOC_ARRAY_ELEM(output_files, nb_output_files);
-
- of->index = nb_output_files - 1;
- of->ost_index = nb_output_streams;
- of->recording_time = o->recording_time;
- of->start_time = o->start_time;
- of->limit_filesize = o->limit_filesize;
- of->shortest = o->shortest;
- av_dict_copy(&of->opts, o->g->format_opts, 0);
-
- if (!strcmp(filename, "-"))
- filename = "pipe:";
-
- err = avformat_alloc_output_context2(&oc, NULL, o->format, filename);
- if (!oc) {
- print_error(filename, err);
- exit_program(1);
- }
-
- of->ctx = oc;
- of->format = oc->oformat;
- if (o->recording_time != INT64_MAX)
- oc->duration = o->recording_time;
-
- oc->interrupt_callback = int_cb;
-
- if (o->bitexact) {
- oc->flags |= AVFMT_FLAG_BITEXACT;
- }
-
- /* create streams for all unlabeled output pads */
- for (i = 0; i < nb_filtergraphs; i++) {
- FilterGraph *fg = filtergraphs[i];
- for (j = 0; j < fg->nb_outputs; j++) {
- OutputFilter *ofilter = fg->outputs[j];
-
- if (!ofilter->out_tmp || ofilter->out_tmp->name)
- continue;
-
- switch (ofilter->type) {
- case AVMEDIA_TYPE_VIDEO: o->video_disable = 1; break;
- case AVMEDIA_TYPE_AUDIO: o->audio_disable = 1; break;
- case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;
- }
- init_output_filter(ofilter, o, oc);
- }
- }
-
- if (!o->nb_stream_maps) {
- char *subtitle_codec_name = NULL;
- /* pick the "best" stream of each type */
-
- /* video: highest resolution */
- if (!o->video_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) {
- int best_score = 0, idx = -1;
- int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);
- for (j = 0; j < nb_input_files; j++) {
- InputFile *ifile = input_files[j];
- int file_best_score = 0, file_best_idx = -1;
- for (i = 0; i < ifile->nb_streams; i++) {
- int score;
- ist = input_streams[ifile->ist_index + i];
- score = ist->st->codecpar->width * ist->st->codecpar->height
- + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
- + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
- if (ist->user_set_discard == AVDISCARD_ALL)
- continue;
- if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
- score = 1;
- if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
- score > file_best_score) {
- if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
- continue;
- file_best_score = score;
- file_best_idx = ifile->ist_index + i;
- }
- }
- if (file_best_idx >= 0) {
- if((qcr == MKTAG('A', 'P', 'I', 'C')) || !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
- file_best_score -= 5000000*!!(input_streams[file_best_idx]->st->disposition & AV_DISPOSITION_DEFAULT);
- if (file_best_score > best_score) {
- best_score = file_best_score;
- idx = file_best_idx;
- }
- }
- }
- if (idx >= 0)
- new_video_stream(o, oc, idx);
- }
-
- /* audio: most channels */
- if (!o->audio_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_AUDIO) != AV_CODEC_ID_NONE) {
- int best_score = 0, idx = -1;
- for (j = 0; j < nb_input_files; j++) {
- InputFile *ifile = input_files[j];
- int file_best_score = 0, file_best_idx = -1;
- for (i = 0; i < ifile->nb_streams; i++) {
- int score;
- ist = input_streams[ifile->ist_index + i];
- score = ist->st->codecpar->ch_layout.nb_channels
- + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
- + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
- if (ist->user_set_discard == AVDISCARD_ALL)
- continue;
- if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
- score > file_best_score) {
- file_best_score = score;
- file_best_idx = ifile->ist_index + i;
- }
- }
- if (file_best_idx >= 0) {
- file_best_score -= 5000000*!!(input_streams[file_best_idx]->st->disposition & AV_DISPOSITION_DEFAULT);
- if (file_best_score > best_score) {
- best_score = file_best_score;
- idx = file_best_idx;
- }
- }
- }
- if (idx >= 0)
- new_audio_stream(o, oc, idx);
- }
-
- /* subtitles: pick first */
- MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, oc, "s");
- if (!o->subtitle_disable && (avcodec_find_encoder(oc->oformat->subtitle_codec) || subtitle_codec_name)) {
- for (i = 0; i < nb_input_streams; i++)
- if (input_streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
- AVCodecDescriptor const *input_descriptor =
- avcodec_descriptor_get(input_streams[i]->st->codecpar->codec_id);
- AVCodecDescriptor const *output_descriptor = NULL;
- AVCodec const *output_codec =
- avcodec_find_encoder(oc->oformat->subtitle_codec);
- int input_props = 0, output_props = 0;
- if (input_streams[i]->user_set_discard == AVDISCARD_ALL)
- continue;
- if (output_codec)
- output_descriptor = avcodec_descriptor_get(output_codec->id);
- if (input_descriptor)
- input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
- if (output_descriptor)
- output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
- if (subtitle_codec_name ||
- input_props & output_props ||
- // Map dvb teletext which has neither property to any output subtitle encoder
- input_descriptor && output_descriptor &&
- (!input_descriptor->props ||
- !output_descriptor->props)) {
- new_subtitle_stream(o, oc, i);
- break;
- }
- }
- }
- /* Data only if codec id match */
- if (!o->data_disable ) {
- enum AVCodecID codec_id = av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_DATA);
- for (i = 0; codec_id != AV_CODEC_ID_NONE && i < nb_input_streams; i++) {
- if (input_streams[i]->user_set_discard == AVDISCARD_ALL)
- continue;
- if (input_streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_DATA
- && input_streams[i]->st->codecpar->codec_id == codec_id )
- new_data_stream(o, oc, i);
- }
- }
- } else {
- for (i = 0; i < o->nb_stream_maps; i++) {
- StreamMap *map = &o->stream_maps[i];
-
- if (map->disabled)
- continue;
-
- if (map->linklabel) {
- FilterGraph *fg;
- OutputFilter *ofilter = NULL;
- int j, k;
-
- for (j = 0; j < nb_filtergraphs; j++) {
- fg = filtergraphs[j];
- for (k = 0; k < fg->nb_outputs; k++) {
- AVFilterInOut *out = fg->outputs[k]->out_tmp;
- if (out && !strcmp(out->name, map->linklabel)) {
- ofilter = fg->outputs[k];
- goto loop_end;
- }
- }
- }
-loop_end:
- if (!ofilter) {
- av_log(NULL, AV_LOG_FATAL, "Output with label '%s' does not exist "
- "in any defined filter graph, or was already used elsewhere.\n", map->linklabel);
- exit_program(1);
- }
- init_output_filter(ofilter, o, oc);
- } else {
- int src_idx = input_files[map->file_index]->ist_index + map->stream_index;
-
- ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
- if (ist->user_set_discard == AVDISCARD_ALL) {
- av_log(NULL, AV_LOG_FATAL, "Stream #%d:%d is disabled and cannot be mapped.\n",
- map->file_index, map->stream_index);
- exit_program(1);
- }
- if(o->subtitle_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
- continue;
- if(o-> audio_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
- continue;
- if(o-> video_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
- continue;
- if(o-> data_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA)
- continue;
-
- ost = NULL;
- switch (ist->st->codecpar->codec_type) {
- case AVMEDIA_TYPE_VIDEO: ost = new_video_stream (o, oc, src_idx); break;
- case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream (o, oc, src_idx); break;
- case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream (o, oc, src_idx); break;
- case AVMEDIA_TYPE_DATA: ost = new_data_stream (o, oc, src_idx); break;
- case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc, src_idx); break;
- case AVMEDIA_TYPE_UNKNOWN:
- if (copy_unknown_streams) {
- ost = new_unknown_stream (o, oc, src_idx);
- break;
- }
- default:
- av_log(NULL, ignore_unknown_streams ? AV_LOG_WARNING : AV_LOG_FATAL,
- "Cannot map stream #%d:%d - unsupported type.\n",
- map->file_index, map->stream_index);
- if (!ignore_unknown_streams) {
- av_log(NULL, AV_LOG_FATAL,
- "If you want unsupported types ignored instead "
- "of failing, please use the -ignore_unknown option\n"
- "If you want them copied, please use -copy_unknown\n");
- exit_program(1);
- }
- }
- if (ost)
- ost->sync_ist = input_streams[ input_files[map->sync_file_index]->ist_index
- + map->sync_stream_index];
- }
- }
- }
-
- /* handle attached files */
- for (i = 0; i < o->nb_attachments; i++) {
- AVIOContext *pb;
- uint8_t *attachment;
- const char *p;
- int64_t len;
-
- if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
- av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
- o->attachments[i]);
- exit_program(1);
- }
- if ((len = avio_size(pb)) <= 0) {
- av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
- o->attachments[i]);
- exit_program(1);
- }
- if (len > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE ||
- !(attachment = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE))) {
- av_log(NULL, AV_LOG_FATAL, "Attachment %s too large.\n",
- o->attachments[i]);
- exit_program(1);
- }
- avio_read(pb, attachment, len);
- memset(attachment + len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
-
- ost = new_attachment_stream(o, oc, -1);
- ost->stream_copy = 0;
- ost->attachment_filename = o->attachments[i];
- ost->st->codecpar->extradata = attachment;
- ost->st->codecpar->extradata_size = len;
-
- p = strrchr(o->attachments[i], '/');
- av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
- avio_closep(&pb);
- }
-
- if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
- av_dump_format(oc, nb_output_files - 1, oc->url, 1);
- av_log(NULL, AV_LOG_ERROR, "Output file #%d does not contain any stream\n", nb_output_files - 1);
- exit_program(1);
- }
-
- /* check if all codec options have been used */
- unused_opts = strip_specifiers(o->g->codec_opts);
- for (i = of->ost_index; i < nb_output_streams; i++) {
- e = NULL;
- while ((e = av_dict_get(output_streams[i]->encoder_opts, "", e,
- AV_DICT_IGNORE_SUFFIX)))
- av_dict_set(&unused_opts, e->key, NULL, 0);
- }
-
- e = NULL;
- while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
- const AVClass *class = avcodec_get_class();
- const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
- AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
- const AVClass *fclass = avformat_get_class();
- const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0,
- AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
- if (!option || foption)
- continue;
-
-
- if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) {
- av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
- "output file #%d (%s) is not an encoding option.\n", e->key,
- option->help ? option->help : "", nb_output_files - 1,
- filename);
- exit_program(1);
- }
-
- // gop_timecode is injected by generic code but not always used
- if (!strcmp(e->key, "gop_timecode"))
- continue;
-
- av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
- "output file #%d (%s) has not been used for any stream. The most "
- "likely reason is either wrong type (e.g. a video option with "
- "no video streams) or that it is a private option of some encoder "
- "which was not actually used for any stream.\n", e->key,
- option->help ? option->help : "", nb_output_files - 1, filename);
- }
- av_dict_free(&unused_opts);
-
- /* set the decoding_needed flags and create simple filtergraphs */
- for (i = of->ost_index; i < nb_output_streams; i++) {
- OutputStream *ost = output_streams[i];
-
- if (ost->encoding_needed && ost->source_index >= 0) {
- InputStream *ist = input_streams[ost->source_index];
- ist->decoding_needed |= DECODING_FOR_OST;
- ist->processing_needed = 1;
-
- if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
- ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
- err = init_simple_filtergraph(ist, ost);
- if (err < 0) {
- av_log(NULL, AV_LOG_ERROR,
- "Error initializing a simple filtergraph between streams "
- "%d:%d->%d:%d\n", ist->file_index, ost->source_index,
- nb_output_files - 1, ost->st->index);
- exit_program(1);
- }
- }
- } else if (ost->stream_copy && ost->source_index >= 0) {
- InputStream *ist = input_streams[ost->source_index];
- ist->processing_needed = 1;
- }
-
- /* set the filter output constraints */
- if (ost->filter) {
- OutputFilter *f = ost->filter;
- switch (ost->enc_ctx->codec_type) {
- case AVMEDIA_TYPE_VIDEO:
- f->frame_rate = ost->frame_rate;
- f->width = ost->enc_ctx->width;
- f->height = ost->enc_ctx->height;
- if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
- f->format = ost->enc_ctx->pix_fmt;
- } else {
- f->formats = ost->enc->pix_fmts;
- }
- break;
- case AVMEDIA_TYPE_AUDIO:
- if (ost->enc_ctx->sample_fmt != AV_SAMPLE_FMT_NONE) {
- f->format = ost->enc_ctx->sample_fmt;
- } else {
- f->formats = ost->enc->sample_fmts;
- }
- if (ost->enc_ctx->sample_rate) {
- f->sample_rate = ost->enc_ctx->sample_rate;
- } else {
- f->sample_rates = ost->enc->supported_samplerates;
- }
- if (ost->enc_ctx->ch_layout.nb_channels) {
- set_channel_layout(f, ost);
- } else if (ost->enc->ch_layouts) {
- f->ch_layouts = ost->enc->ch_layouts;
- }
- break;
- }
- }
- }
-
- /* check filename in case of an image number is expected */
- if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
- if (!av_filename_number_test(oc->url)) {
- print_error(oc->url, AVERROR(EINVAL));
- exit_program(1);
- }
- }
-
- if (!(oc->oformat->flags & AVFMT_NOSTREAMS) && !input_stream_potentially_available) {
- av_log(NULL, AV_LOG_ERROR,
- "No input streams but output needs an input stream\n");
- exit_program(1);
- }
-
- if (!(oc->oformat->flags & AVFMT_NOFILE)) {
- /* test if it already exists to avoid losing precious files */
- assert_file_overwrite(filename);
-
- /* open the file */
- if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
- &oc->interrupt_callback,
- &of->opts)) < 0) {
- print_error(filename, err);
- exit_program(1);
- }
- } else if (strcmp(oc->oformat->name, "image2")==0 && !av_filename_number_test(filename))
- assert_file_overwrite(filename);
-
- if (o->mux_preload) {
- av_dict_set_int(&of->opts, "preload", o->mux_preload*AV_TIME_BASE, 0);
- }
- oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
-
- /* copy metadata */
- for (i = 0; i < o->nb_metadata_map; i++) {
- char *p;
- int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);
-
- if (in_file_index >= nb_input_files) {
- av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index);
- exit_program(1);
- }
- copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc,
- in_file_index >= 0 ?
- input_files[in_file_index]->ctx : NULL, o);
- }
-
- /* copy chapters */
- if (o->chapters_input_file >= nb_input_files) {
- if (o->chapters_input_file == INT_MAX) {
- /* copy chapters from the first input file that has them*/
- o->chapters_input_file = -1;
- for (i = 0; i < nb_input_files; i++)
- if (input_files[i]->ctx->nb_chapters) {
- o->chapters_input_file = i;
- break;
- }
- } else {
- av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
- o->chapters_input_file);
- exit_program(1);
- }
- }
- if (o->chapters_input_file >= 0)
- copy_chapters(input_files[o->chapters_input_file], of, oc,
- !o->metadata_chapters_manual);
-
- /* copy global metadata by default */
- if (!o->metadata_global_manual && nb_input_files){
- av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
- AV_DICT_DONT_OVERWRITE);
- if(o->recording_time != INT64_MAX)
- av_dict_set(&oc->metadata, "duration", NULL, 0);
- av_dict_set(&oc->metadata, "creation_time", NULL, 0);
- av_dict_set(&oc->metadata, "company_name", NULL, 0);
- av_dict_set(&oc->metadata, "product_name", NULL, 0);
- av_dict_set(&oc->metadata, "product_version", NULL, 0);
- }
- if (!o->metadata_streams_manual)
- for (i = of->ost_index; i < nb_output_streams; i++) {
- InputStream *ist;
- if (output_streams[i]->source_index < 0) /* this is true e.g. for attached files */
- continue;
- ist = input_streams[output_streams[i]->source_index];
- av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
- if (!output_streams[i]->stream_copy) {
- av_dict_set(&output_streams[i]->st->metadata, "encoder", NULL, 0);
- }
- }
-
- /* process manually set programs */
- for (i = 0; i < o->nb_program; i++) {
- const char *p = o->program[i].u.str;
- int progid = i+1;
- AVProgram *program;
-
- while(*p) {
- const char *p2 = av_get_token(&p, ":");
- const char *to_dealloc = p2;
- char *key;
- if (!p2)
- break;
-
- if(*p) p++;
-
- key = av_get_token(&p2, "=");
- if (!key || !*p2) {
- av_freep(&to_dealloc);
- av_freep(&key);
- break;
- }
- p2++;
-
- if (!strcmp(key, "program_num"))
- progid = strtol(p2, NULL, 0);
- av_freep(&to_dealloc);
- av_freep(&key);
- }
-
- program = av_new_program(oc, progid);
-
- p = o->program[i].u.str;
- while(*p) {
- const char *p2 = av_get_token(&p, ":");
- const char *to_dealloc = p2;
- char *key;
- if (!p2)
- break;
- if(*p) p++;
-
- key = av_get_token(&p2, "=");
- if (!key) {
- av_log(NULL, AV_LOG_FATAL,
- "No '=' character in program string %s.\n",
- p2);
- exit_program(1);
- }
- if (!*p2)
- exit_program(1);
- p2++;
-
- if (!strcmp(key, "title")) {
- av_dict_set(&program->metadata, "title", p2, 0);
- } else if (!strcmp(key, "program_num")) {
- } else if (!strcmp(key, "st")) {
- int st_num = strtol(p2, NULL, 0);
- av_program_add_stream_index(oc, progid, st_num);
- } else {
- av_log(NULL, AV_LOG_FATAL, "Unknown program key %s.\n", key);
- exit_program(1);
- }
- av_freep(&to_dealloc);
- av_freep(&key);
- }
- }
-
- /* process manually set metadata */
- for (i = 0; i < o->nb_metadata; i++) {
- AVDictionary **m;
- char type, *val;
- const char *stream_spec;
- int index = 0, j, ret = 0;
-
- val = strchr(o->metadata[i].u.str, '=');
- if (!val) {
- av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
- o->metadata[i].u.str);
- exit_program(1);
- }
- *val++ = 0;
-
- parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);
- if (type == 's') {
- for (j = 0; j < oc->nb_streams; j++) {
- ost = output_streams[nb_output_streams - oc->nb_streams + j];
- if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
- if (!strcmp(o->metadata[i].u.str, "rotate")) {
- char *tail;
- double theta = av_strtod(val, &tail);
- if (!*tail) {
- ost->rotate_overridden = 1;
- ost->rotate_override_value = theta;
- }
- } else {
- av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
- }
- } else if (ret < 0)
- exit_program(1);
- }
- }
- else {
- switch (type) {
- case 'g':
- m = &oc->metadata;
- break;
- case 'c':
- if (index < 0 || index >= oc->nb_chapters) {
- av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
- exit_program(1);
- }
- m = &oc->chapters[index]->metadata;
- break;
- case 'p':
- if (index < 0 || index >= oc->nb_programs) {
- av_log(NULL, AV_LOG_FATAL, "Invalid program index %d in metadata specifier.\n", index);
- exit_program(1);
- }
- m = &oc->programs[index]->metadata;
- break;
- default:
- av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
- exit_program(1);
- }
- av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
- }
- }
-
- err = set_dispositions(of, oc);
- if (err < 0) {
- av_log(NULL, AV_LOG_FATAL, "Error setting output stream dispositions\n");
- exit_program(1);
- }
-
- return 0;
-}
-
static int opt_target(void *optctx, const char *opt, const char *arg)
{
OptionsContext *o = optctx;
@@ -3403,15 +1114,13 @@ static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
if (!fg->graph_desc)
return AVERROR(ENOMEM);
- input_stream_potentially_available = 1;
-
return 0;
}
static int opt_filter_complex_script(void *optctx, const char *opt, const char *arg)
{
FilterGraph *fg;
- char *graph_desc = read_file(arg);
+ char *graph_desc = file_read(arg);
if (!graph_desc)
return AVERROR(EINVAL);
@@ -3419,8 +1128,6 @@ static int opt_filter_complex_script(void *optctx, const char *opt, const char *
fg->index = nb_filtergraphs - 1;
fg->graph_desc = graph_desc;
- input_stream_potentially_available = 1;
-
return 0;
}
@@ -3514,7 +1221,7 @@ static const OptionGroupDef groups[] = {
};
static int open_files(OptionGroupList *l, const char *inout,
- int (*open_file)(OptionsContext*, const char*))
+ int (*open_file)(const OptionsContext*, const char*))
{
int i, ret;
@@ -3550,7 +1257,6 @@ static int open_files(OptionGroupList *l, const char *inout,
int ffmpeg_parse_options(int argc, char **argv)
{
OptionParseContext octx;
- uint8_t error[128];
int ret;
memset(&octx, 0, sizeof(octx));
@@ -3574,14 +1280,12 @@ int ffmpeg_parse_options(int argc, char **argv)
term_init();
/* open input files */
- ret = open_files(&octx.groups[GROUP_INFILE], "input", open_input_file);
+ ret = open_files(&octx.groups[GROUP_INFILE], "input", ifile_open);
if (ret < 0) {
av_log(NULL, AV_LOG_FATAL, "Error opening input files: ");
goto fail;
}
- apply_sync_offsets();
-
/* create the complex filtergraphs */
ret = init_complex_filters();
if (ret < 0) {
@@ -3590,19 +1294,22 @@ int ffmpeg_parse_options(int argc, char **argv)
}
/* open output files */
- ret = open_files(&octx.groups[GROUP_OUTFILE], "output", open_output_file);
+ ret = open_files(&octx.groups[GROUP_OUTFILE], "output", of_open);
if (ret < 0) {
av_log(NULL, AV_LOG_FATAL, "Error opening output files: ");
goto fail;
}
+ correct_input_start_times();
+
+ apply_sync_offsets();
+
check_filter_outputs();
fail:
uninit_parse_context(&octx);
if (ret < 0) {
- av_strerror(ret, error, sizeof(error));
- av_log(NULL, AV_LOG_FATAL, "%s\n", error);
+ av_log(NULL, AV_LOG_FATAL, "%s\n", av_err2str(ret));
}
return ret;
}
@@ -3667,8 +1374,10 @@ const OptionDef options[] = {
OPT_OUTPUT, { .func_arg = opt_map },
"set input stream mapping",
"[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" },
+#if FFMPEG_OPT_MAP_CHANNEL
{ "map_channel", HAS_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_map_channel },
- "map an audio channel from one stream to another", "file.stream.channel[:syncfile.syncstream]" },
+ "map an audio channel from one stream to another (deprecated)", "file.stream.channel[:syncfile.syncstream]" },
+#endif
{ "map_metadata", HAS_ARG | OPT_STRING | OPT_SPEC |
OPT_OUTPUT, { .off = OFFSET(metadata_map) },
"set metadata information of outfile from infile",
@@ -3741,8 +1450,6 @@ const OptionDef options[] = {
"set video sync method globally; deprecated, use -fps_mode", "" },
{ "frame_drop_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &frame_drop_threshold },
"frame drop threshold", "" },
- { "async", HAS_ARG | OPT_INT | OPT_EXPERT, { &audio_sync_method },
- "audio sync method", "" },
{ "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &audio_drift_threshold },
"audio drift threshold", "threshold" },
{ "copyts", OPT_BOOL | OPT_EXPERT, { ©_ts },
@@ -3754,6 +1461,8 @@ const OptionDef options[] = {
{ "shortest", OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
OPT_OUTPUT, { .off = OFFSET(shortest) },
"finish encoding within shortest input" },
+ { "shortest_buf_duration", HAS_ARG | OPT_FLOAT | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(shortest_buf_duration) },
+ "maximum buffering duration (in seconds) for the -shortest option" },
{ "bitexact", OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
OPT_OUTPUT | OPT_INPUT, { .off = OFFSET(bitexact) },
"bitexact mode" },
@@ -3826,15 +1535,28 @@ const OptionDef options[] = {
{ "disposition", OPT_STRING | HAS_ARG | OPT_SPEC |
OPT_OUTPUT, { .off = OFFSET(disposition) },
"disposition", "" },
- { "thread_queue_size", HAS_ARG | OPT_INT | OPT_OFFSET | OPT_EXPERT | OPT_INPUT,
+ { "thread_queue_size", HAS_ARG | OPT_INT | OPT_OFFSET | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT,
{ .off = OFFSET(thread_queue_size) },
"set the maximum number of queued packets from the demuxer" },
- { "find_stream_info", OPT_BOOL | OPT_PERFILE | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
+ { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(find_stream_info) },
"read and decode the streams to fill missing information with heuristics" },
{ "bits_per_raw_sample", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_SPEC | OPT_OUTPUT,
{ .off = OFFSET(bits_per_raw_sample) },
"set the number of bits per raw sample", "number" },
+ { "stats_enc_pre", HAS_ARG | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT | OPT_STRING, { .off = OFFSET(enc_stats_pre) },
+ "write encoding stats before encoding" },
+ { "stats_enc_post", HAS_ARG | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT | OPT_STRING, { .off = OFFSET(enc_stats_post) },
+ "write encoding stats after encoding" },
+ { "stats_mux_pre", HAS_ARG | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT | OPT_STRING, { .off = OFFSET(mux_stats) },
+ "write packets stats before muxing" },
+ { "stats_enc_pre_fmt", HAS_ARG | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT | OPT_STRING, { .off = OFFSET(enc_stats_pre_fmt) },
+ "format of the stats written with -stats_enc_pre" },
+ { "stats_enc_post_fmt", HAS_ARG | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT | OPT_STRING, { .off = OFFSET(enc_stats_post_fmt) },
+ "format of the stats written with -stats_enc_post" },
+ { "stats_mux_pre_fmt", HAS_ARG | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT | OPT_STRING, { .off = OFFSET(mux_stats_fmt) },
+ "format of the stats written with -stats_mux_pre" },
+
/* video options */
{ "vframes", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_frames },
"set the number of video frames to output", "number" },
@@ -3853,6 +1575,16 @@ const OptionDef options[] = {
{ "pix_fmt", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_pix_fmts) },
"set pixel format", "format" },
+ { "display_rotation", OPT_VIDEO | HAS_ARG | OPT_DOUBLE | OPT_SPEC |
+ OPT_INPUT, { .off = OFFSET(display_rotations) },
+ "set pure counter-clockwise rotation in degrees for stream(s)",
+ "angle" },
+ { "display_hflip", OPT_VIDEO | OPT_BOOL | OPT_SPEC | OPT_INPUT, { .off = OFFSET(display_hflips) },
+ "set display horizontal flip for stream(s) "
+ "(overrides any display rotation if it is not set)"},
+ { "display_vflip", OPT_VIDEO | OPT_BOOL | OPT_SPEC | OPT_INPUT, { .off = OFFSET(display_vflips) },
+ "set display vertical flip for stream(s) "
+ "(overrides any display rotation if it is not set)"},
{ "vn", OPT_VIDEO | OPT_BOOL | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT,{ .off = OFFSET(video_disable) },
"disable video" },
{ "rc_override", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
@@ -3868,8 +1600,10 @@ const OptionDef options[] = {
{ "passlogfile", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC |
OPT_OUTPUT, { .off = OFFSET(passlogfiles) },
"select two pass log file name prefix", "prefix" },
+#if FFMPEG_OPT_PSNR
{ "psnr", OPT_VIDEO | OPT_BOOL | OPT_EXPERT, { &do_psnr },
- "calculate PSNR of compressed frames" },
+ "calculate PSNR of compressed frames (deprecated, use -flags +psnr)" },
+#endif
{ "vstats", OPT_VIDEO | OPT_EXPERT , { .func_arg = opt_vstats },
"dump video coding statistics to file" },
{ "vstats_file", OPT_VIDEO | HAS_ARG | OPT_EXPERT , { .func_arg = opt_vstats_file },
@@ -3907,8 +1641,6 @@ const OptionDef options[] = {
{ "force_key_frames", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(forced_key_frames) },
"force key frames at specified timestamps", "timestamps" },
- { "ab", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_bitrate },
- "audio bitrate (please use -b:a)", "bitrate" },
{ "b", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_bitrate },
"video bitrate (please use -b:v)", "bitrate" },
{ "hwaccel", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
@@ -3928,6 +1660,11 @@ const OptionDef options[] = {
{ "autoscale", HAS_ARG | OPT_BOOL | OPT_SPEC |
OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(autoscale) },
"automatically insert a scale filter at the end of the filter graph" },
+ { "fix_sub_duration_heartbeat", OPT_VIDEO | OPT_BOOL | OPT_EXPERT |
+ OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(fix_sub_duration_heartbeat) },
+ "set this video output stream to be a heartbeat stream for "
+ "fix_sub_duration, according to which subtitles should be split at "
+ "random access points" },
/* audio options */
{ "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames },
@@ -3945,11 +1682,11 @@ const OptionDef options[] = {
{ "acodec", OPT_AUDIO | HAS_ARG | OPT_PERFILE |
OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_audio_codec },
"force audio codec ('copy' to copy stream)", "codec" },
+ { "ab", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_bitrate },
+ "audio bitrate (please use -b:a)", "bitrate" },
{ "atag", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
OPT_OUTPUT, { .func_arg = opt_old2new },
"force audio tag/fourcc", "fourcc/tag" },
- { "vol", OPT_AUDIO | HAS_ARG | OPT_INT, { &audio_volume },
- "change audio volume (256=normal)" , "volume" },
{ "sample_fmt", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_SPEC |
OPT_STRING | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(sample_fmts) },
"set sample format", "format" },
diff --git a/fftools/ffmpeg_qsv.c b/fftools/ffmpeg_qsv.c
deleted file mode 100644
index 960c88b69..000000000
--- a/fftools/ffmpeg_qsv.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include
-#include
-
-#include "libavutil/dict.h"
-#include "libavutil/hwcontext.h"
-#include "libavutil/hwcontext_qsv.h"
-#include "libavutil/mem.h"
-#include "libavutil/opt.h"
-#include "libavcodec/qsv.h"
-
-#include "ffmpeg.h"
-
-static AVBufferRef *hw_device_ctx;
-char *qsv_device = NULL;
-
-static int qsv_get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
-{
- InputStream *ist = s->opaque;
-
- return av_hwframe_get_buffer(ist->hw_frames_ctx, frame, 0);
-}
-
-static void qsv_uninit(AVCodecContext *s)
-{
- InputStream *ist = s->opaque;
- av_buffer_unref(&ist->hw_frames_ctx);
-}
-
-static int qsv_device_init(InputStream *ist)
-{
- int err;
- AVDictionary *dict = NULL;
-
- if (qsv_device) {
- err = av_dict_set(&dict, "child_device", qsv_device, 0);
- if (err < 0)
- return err;
- }
-
- err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_QSV,
- ist->hwaccel_device, dict, 0);
- if (err < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error creating a QSV device\n");
- goto err_out;
- }
-
-err_out:
- if (dict)
- av_dict_free(&dict);
-
- return err;
-}
-
-int qsv_init(AVCodecContext *s)
-{
- InputStream *ist = s->opaque;
- AVHWFramesContext *frames_ctx;
- AVQSVFramesContext *frames_hwctx;
- int ret;
-
- if (!hw_device_ctx) {
- ret = qsv_device_init(ist);
- if (ret < 0)
- return ret;
- }
-
- av_buffer_unref(&ist->hw_frames_ctx);
- ist->hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx);
- if (!ist->hw_frames_ctx)
- return AVERROR(ENOMEM);
-
- frames_ctx = (AVHWFramesContext*)ist->hw_frames_ctx->data;
- frames_hwctx = frames_ctx->hwctx;
-
- frames_ctx->width = FFALIGN(s->coded_width, 32);
- frames_ctx->height = FFALIGN(s->coded_height, 32);
- frames_ctx->format = AV_PIX_FMT_QSV;
- frames_ctx->sw_format = s->sw_pix_fmt;
- frames_ctx->initial_pool_size = 64 + s->extra_hw_frames;
- frames_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
-
- ret = av_hwframe_ctx_init(ist->hw_frames_ctx);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error initializing a QSV frame pool\n");
- return ret;
- }
-
- ist->hwaccel_get_buffer = qsv_get_buffer;
- ist->hwaccel_uninit = qsv_uninit;
-
- return 0;
-}
diff --git a/fftools/ffmpeg_videotoolbox.c b/fftools/ffmpeg_videotoolbox.c
deleted file mode 100644
index a6b78d0f7..000000000
--- a/fftools/ffmpeg_videotoolbox.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-
-#if HAVE_UTGETOSTYPEFROMSTRING
-#include
-#endif
-
-#include "libavcodec/avcodec.h"
-#include "libavcodec/videotoolbox.h"
-#include "libavutil/imgutils.h"
-#include "ffmpeg.h"
-
-typedef struct VTContext {
- AVFrame *tmp_frame;
-} VTContext;
-
-char *videotoolbox_pixfmt;
-
-static int videotoolbox_retrieve_data(AVCodecContext *s, AVFrame *frame)
-{
- InputStream *ist = s->opaque;
- VTContext *vt = ist->hwaccel_ctx;
- CVPixelBufferRef pixbuf = (CVPixelBufferRef)frame->data[3];
- OSType pixel_format = CVPixelBufferGetPixelFormatType(pixbuf);
- CVReturn err;
- uint8_t *data[4] = { 0 };
- int linesize[4] = { 0 };
- int planes, ret, i;
-
- av_frame_unref(vt->tmp_frame);
-
- switch (pixel_format) {
- case kCVPixelFormatType_420YpCbCr8Planar: vt->tmp_frame->format = AV_PIX_FMT_YUV420P; break;
- case kCVPixelFormatType_422YpCbCr8: vt->tmp_frame->format = AV_PIX_FMT_UYVY422; break;
- case kCVPixelFormatType_32BGRA: vt->tmp_frame->format = AV_PIX_FMT_BGRA; break;
-#ifdef kCFCoreFoundationVersionNumber10_7
- case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:
- case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange: vt->tmp_frame->format = AV_PIX_FMT_NV12; break;
-#endif
-#if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
- case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange:
- case kCVPixelFormatType_420YpCbCr10BiPlanarFullRange: vt->tmp_frame->format = AV_PIX_FMT_P010; break;
-#endif
- default:
- av_log(NULL, AV_LOG_ERROR,
- "%s: Unsupported pixel format: %s\n",
- av_fourcc2str(s->codec_tag), videotoolbox_pixfmt);
- return AVERROR(ENOSYS);
- }
-
- vt->tmp_frame->width = frame->width;
- vt->tmp_frame->height = frame->height;
- ret = av_frame_get_buffer(vt->tmp_frame, 0);
- if (ret < 0)
- return ret;
-
- err = CVPixelBufferLockBaseAddress(pixbuf, kCVPixelBufferLock_ReadOnly);
- if (err != kCVReturnSuccess) {
- av_log(NULL, AV_LOG_ERROR, "Error locking the pixel buffer.\n");
- return AVERROR_UNKNOWN;
- }
-
- if (CVPixelBufferIsPlanar(pixbuf)) {
-
- planes = CVPixelBufferGetPlaneCount(pixbuf);
- for (i = 0; i < planes; i++) {
- data[i] = CVPixelBufferGetBaseAddressOfPlane(pixbuf, i);
- linesize[i] = CVPixelBufferGetBytesPerRowOfPlane(pixbuf, i);
- }
- } else {
- data[0] = CVPixelBufferGetBaseAddress(pixbuf);
- linesize[0] = CVPixelBufferGetBytesPerRow(pixbuf);
- }
-
- av_image_copy(vt->tmp_frame->data, vt->tmp_frame->linesize,
- (const uint8_t **)data, linesize, vt->tmp_frame->format,
- frame->width, frame->height);
-
- ret = av_frame_copy_props(vt->tmp_frame, frame);
- CVPixelBufferUnlockBaseAddress(pixbuf, kCVPixelBufferLock_ReadOnly);
- if (ret < 0)
- return ret;
-
- av_frame_unref(frame);
- av_frame_move_ref(frame, vt->tmp_frame);
-
- return 0;
-}
-
-static void videotoolbox_uninit(AVCodecContext *s)
-{
- InputStream *ist = s->opaque;
- VTContext *vt = ist->hwaccel_ctx;
-
- ist->hwaccel_uninit = NULL;
- ist->hwaccel_retrieve_data = NULL;
-
- av_frame_free(&vt->tmp_frame);
-
- av_videotoolbox_default_free(s);
- av_freep(&ist->hwaccel_ctx);
-}
-
-int videotoolbox_init(AVCodecContext *s)
-{
- InputStream *ist = s->opaque;
- int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
- int ret = 0;
- VTContext *vt;
-
- vt = av_mallocz(sizeof(*vt));
- if (!vt)
- return AVERROR(ENOMEM);
-
- ist->hwaccel_ctx = vt;
- ist->hwaccel_uninit = videotoolbox_uninit;
- ist->hwaccel_retrieve_data = videotoolbox_retrieve_data;
-
- vt->tmp_frame = av_frame_alloc();
- if (!vt->tmp_frame) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
-
- // TODO: reindent
- if (!videotoolbox_pixfmt) {
- ret = av_videotoolbox_default_init(s);
- } else {
- AVVideotoolboxContext *vtctx = av_videotoolbox_alloc_context();
- CFStringRef pixfmt_str = CFStringCreateWithCString(kCFAllocatorDefault,
- videotoolbox_pixfmt,
- kCFStringEncodingUTF8);
-#if HAVE_UTGETOSTYPEFROMSTRING
- vtctx->cv_pix_fmt_type = UTGetOSTypeFromString(pixfmt_str);
-#else
- av_log(s, loglevel, "UTGetOSTypeFromString() is not available "
- "on this platform, %s pixel format can not be honored from "
- "the command line\n", videotoolbox_pixfmt);
-#endif
- ret = av_videotoolbox_default_init2(s, vtctx);
- CFRelease(pixfmt_str);
- }
- if (ret < 0) {
- av_log(NULL, loglevel, "Error creating Videotoolbox decoder.\n");
- goto fail;
- }
-
- return 0;
-fail:
- videotoolbox_uninit(s);
- return ret;
-}
diff --git a/fftools/ffplay.c b/fftools/ffplay.c
index 9242047f5..d6479aef5 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -1860,7 +1860,7 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
}
pix_fmts[nb_pix_fmts] = AV_PIX_FMT_NONE;
- while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
+ while ((e = av_dict_iterate(sws_dict, e))) {
if (!strcmp(e->key, "sws_flags")) {
av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
} else
@@ -1915,8 +1915,14 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
} while (0)
if (autorotate) {
- int32_t *displaymatrix = (int32_t *)av_stream_get_side_data(is->video_st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
- double theta = get_rotation(displaymatrix);
+ double theta = 0.0;
+ int32_t *displaymatrix = NULL;
+ AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
+ if (sd)
+ displaymatrix = (int32_t *)sd->data;
+ if (!displaymatrix)
+ displaymatrix = (int32_t *)av_stream_get_side_data(is->video_st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
+ theta = get_rotation(displaymatrix);
if (fabs(theta - 90) < 1.0) {
INSERT_FILT("transpose", "clock");
@@ -1960,7 +1966,7 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for
av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
- while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
+ while ((e = av_dict_iterate(swr_opts, e)))
av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
if (strlen(aresample_swr_opts))
aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
@@ -3531,7 +3537,7 @@ static void opt_input_file(void *optctx, const char *filename)
exit(1);
}
if (!strcmp(filename, "-"))
- filename = "pipe:";
+ filename = "fd:";
input_filename = filename;
}
diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
index 608d9050f..af927cb08 100644
--- a/fftools/ffprobe.c
+++ b/fftools/ffprobe.c
@@ -27,11 +27,13 @@
#include "libavutil/ffversion.h"
#include
+#include
#include "libavformat/avformat.h"
#include "libavformat/version.h"
#include "libavcodec/avcodec.h"
#include "libavcodec/version.h"
+#include "libavutil/ambient_viewing_environment.h"
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/bprint.h"
@@ -655,7 +657,7 @@ static int writer_open(WriterContext **wctx, const Writer *writer, const char *a
goto fail;
}
- while ((opt = av_dict_get(opts, "", opt, AV_DICT_IGNORE_SUFFIX))) {
+ while ((opt = av_dict_iterate(opts, opt))) {
if ((ret = av_opt_set(*wctx, opt->key, opt->value, AV_OPT_SEARCH_CHILDREN)) < 0) {
av_log(*wctx, AV_LOG_ERROR, "Failed to set option '%s' with value '%s' provided to writer context\n",
opt->key, opt->value);
@@ -1896,12 +1898,14 @@ static void writer_register_all(void)
writer_print_string(w, k, pbuf.str, 0); \
} while (0)
-#define print_list_fmt(k, f, n, ...) do { \
+#define print_list_fmt(k, f, n, m, ...) do { \
av_bprint_clear(&pbuf); \
for (int idx = 0; idx < n; idx++) { \
- if (idx > 0) \
- av_bprint_chars(&pbuf, ' ', 1); \
- av_bprintf(&pbuf, f, __VA_ARGS__); \
+ for (int idx2 = 0; idx2 < m; idx2++) { \
+ if (idx > 0 || idx2 > 0) \
+ av_bprint_chars(&pbuf, ' ', 1); \
+ av_bprintf(&pbuf, f, __VA_ARGS__); \
+ } \
} \
writer_print_string(w, k, pbuf.str, 0); \
} while (0)
@@ -1942,7 +1946,7 @@ static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id
return 0;
writer_print_section_header(w, section_id);
- while ((tag = av_dict_get(tags, "", tag, AV_DICT_IGNORE_SUFFIX))) {
+ while ((tag = av_dict_iterate(tags, tag))) {
if ((ret = print_str_validate(tag->key, tag->value)) < 0)
break;
}
@@ -2012,7 +2016,7 @@ static void print_dovi_metadata(WriterContext *w, const AVDOVIMetadata *dovi)
const AVDOVIReshapingCurve *curve = &mapping->curves[c];
writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_COMPONENT);
- print_list_fmt("pivots", "%"PRIu16, curve->num_pivots, curve->pivots[idx]);
+ print_list_fmt("pivots", "%"PRIu16, curve->num_pivots, 1, curve->pivots[idx]);
writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST);
for (int i = 0; i < curve->num_pivots - 1; i++) {
@@ -2024,7 +2028,7 @@ static void print_dovi_metadata(WriterContext *w, const AVDOVIMetadata *dovi)
print_str("mapping_idc_name", "polynomial");
print_int("poly_order", curve->poly_order[i]);
print_list_fmt("poly_coef", "%"PRIi64,
- curve->poly_order[i] + 1,
+ curve->poly_order[i] + 1, 1,
curve->poly_coef[i][idx]);
break;
case AV_DOVI_MAPPING_MMR:
@@ -2032,8 +2036,8 @@ static void print_dovi_metadata(WriterContext *w, const AVDOVIMetadata *dovi)
print_int("mmr_order", curve->mmr_order[i]);
print_int("mmr_constant", curve->mmr_constant[i]);
print_list_fmt("mmr_coef", "%"PRIi64,
- curve->mmr_order[i] * 7,
- curve->mmr_coef[i][0][idx]);
+ curve->mmr_order[i], 7,
+ curve->mmr_coef[i][idx][idx2]);
break;
default:
print_str("mapping_idc_name", "unknown");
@@ -2071,15 +2075,15 @@ static void print_dovi_metadata(WriterContext *w, const AVDOVIMetadata *dovi)
print_int("dm_metadata_id", color->dm_metadata_id);
print_int("scene_refresh_flag", color->scene_refresh_flag);
print_list_fmt("ycc_to_rgb_matrix", "%d/%d",
- FF_ARRAY_ELEMS(color->ycc_to_rgb_matrix),
+ FF_ARRAY_ELEMS(color->ycc_to_rgb_matrix), 1,
color->ycc_to_rgb_matrix[idx].num,
color->ycc_to_rgb_matrix[idx].den);
print_list_fmt("ycc_to_rgb_offset", "%d/%d",
- FF_ARRAY_ELEMS(color->ycc_to_rgb_offset),
+ FF_ARRAY_ELEMS(color->ycc_to_rgb_offset), 1,
color->ycc_to_rgb_offset[idx].num,
color->ycc_to_rgb_offset[idx].den);
print_list_fmt("rgb_to_lms_matrix", "%d/%d",
- FF_ARRAY_ELEMS(color->rgb_to_lms_matrix),
+ FF_ARRAY_ELEMS(color->rgb_to_lms_matrix), 1,
color->rgb_to_lms_matrix[idx].num,
color->rgb_to_lms_matrix[idx].den);
print_int("signal_eotf", color->signal_eotf);
@@ -2265,6 +2269,17 @@ static void print_dynamic_hdr_vivid(WriterContext *w, const AVDynamicHDRVivid *m
}
}
+static void print_ambient_viewing_environment(WriterContext *w,
+ const AVAmbientViewingEnvironment *env)
+{
+ if (!env)
+ return;
+
+ print_q("ambient_illuminance", env->ambient_illuminance, '/');
+ print_q("ambient_light_x", env->ambient_light_x, '/');
+ print_q("ambient_light_y", env->ambient_light_y, '/');
+}
+
static void print_pkt_side_data(WriterContext *w,
AVCodecParameters *par,
const AVPacketSideData *side_data,
@@ -2282,8 +2297,11 @@ static void print_pkt_side_data(WriterContext *w,
writer_print_section_header(w, id_data);
print_str("side_data_type", name ? name : "unknown");
if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) {
+ double rotation = av_display_rotation_get((int32_t *)sd->data);
+ if (isnan(rotation))
+ rotation = 0;
writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1);
- print_int("rotation", av_display_rotation_get((int32_t *)sd->data));
+ print_int("rotation", rotation);
} else if (sd->type == AV_PKT_DATA_STEREO3D) {
const AVStereo3D *stereo = (AVStereo3D *)sd->data;
print_str("type", av_stereo3d_type_name(stereo->type));
@@ -2495,8 +2513,12 @@ static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int p
print_val("size", pkt->size, unit_byte_str);
if (pkt->pos != -1) print_fmt ("pos", "%"PRId64, pkt->pos);
else print_str_opt("pos", "N/A");
- print_fmt("flags", "%c%c", pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_',
- pkt->flags & AV_PKT_FLAG_DISCARD ? 'D' : '_');
+ print_fmt("flags", "%c%c%c", pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_',
+ pkt->flags & AV_PKT_FLAG_DISCARD ? 'D' : '_',
+ pkt->flags & AV_PKT_FLAG_CORRUPT ? 'C' : '_');
+ if (do_show_data)
+ writer_print_data(w, "data", pkt->data, pkt->size);
+ writer_print_data_hash(w, "data_hash", pkt->data, pkt->size);
if (pkt->side_data_elems) {
size_t size;
@@ -2515,9 +2537,6 @@ static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int p
SECTION_ID_PACKET_SIDE_DATA);
}
- if (do_show_data)
- writer_print_data(w, "data", pkt->data, pkt->size);
- writer_print_data_hash(w, "data_hash", pkt->data, pkt->size);
writer_print_section_footer(w);
av_bprint_finalize(&pbuf, NULL);
@@ -2570,8 +2589,14 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
print_time("pkt_dts_time", frame->pkt_dts, &stream->time_base);
print_ts ("best_effort_timestamp", frame->best_effort_timestamp);
print_time("best_effort_timestamp_time", frame->best_effort_timestamp, &stream->time_base);
+#if LIBAVUTIL_VERSION_MAJOR < 59
+ AV_NOWARN_DEPRECATED(
print_duration_ts ("pkt_duration", frame->pkt_duration);
print_duration_time("pkt_duration_time", frame->pkt_duration, &stream->time_base);
+ )
+#endif
+ print_duration_ts ("duration", frame->duration);
+ print_duration_time("duration_time", frame->duration, &stream->time_base);
if (frame->pkt_pos != -1) print_fmt ("pkt_pos", "%"PRId64, frame->pkt_pos);
else print_str_opt("pkt_pos", "N/A");
if (frame->pkt_size != -1) print_val ("pkt_size", frame->pkt_size, unit_byte_str);
@@ -2593,8 +2618,12 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
print_str_opt("sample_aspect_ratio", "N/A");
}
print_fmt("pict_type", "%c", av_get_picture_type_char(frame->pict_type));
+#if LIBAVUTIL_VERSION_MAJOR < 59
+ AV_NOWARN_DEPRECATED(
print_int("coded_picture_number", frame->coded_picture_number);
print_int("display_picture_number", frame->display_picture_number);
+ )
+#endif
print_int("interlaced_frame", frame->interlaced_frame);
print_int("top_field_first", frame->top_field_first);
print_int("repeat_pict", frame->repeat_pict);
@@ -2633,8 +2662,11 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
name = av_frame_side_data_name(sd->type);
print_str("side_data_type", name ? name : "unknown");
if (sd->type == AV_FRAME_DATA_DISPLAYMATRIX && sd->size >= 9*4) {
+ double rotation = av_display_rotation_get((int32_t *)sd->data);
+ if (isnan(rotation))
+ rotation = 0;
writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1);
- print_int("rotation", av_display_rotation_get((int32_t *)sd->data));
+ print_int("rotation", rotation);
} else if (sd->type == AV_FRAME_DATA_AFD && sd->size > 0) {
print_int("active_format", *sd->data);
} else if (sd->type == AV_FRAME_DATA_GOP_TIMECODE && sd->size >= 8) {
@@ -2689,6 +2721,9 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
} else if (sd->type == AV_FRAME_DATA_DYNAMIC_HDR_VIVID) {
AVDynamicHDRVivid *metadata = (AVDynamicHDRVivid *)sd->data;
print_dynamic_hdr_vivid(w, metadata);
+ } else if (sd->type == AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT) {
+ print_ambient_viewing_environment(
+ w, (const AVAmbientViewingEnvironment *)sd->data);
}
writer_print_section_footer(w);
}
@@ -2703,7 +2738,7 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
static av_always_inline int process_frame(WriterContext *w,
InputFile *ifile,
- AVFrame *frame, AVPacket *pkt,
+ AVFrame *frame, const AVPacket *pkt,
int *packet_new)
{
AVFormatContext *fmt_ctx = ifile->fmt_ctx;
@@ -2844,9 +2879,10 @@ static int read_interval_packets(WriterContext *w, InputFile *ifile,
}
if (selected_streams[pkt->stream_index]) {
AVRational tb = ifile->streams[pkt->stream_index].st->time_base;
+ int64_t pts = pkt->pts != AV_NOPTS_VALUE ? pkt->pts : pkt->dts;
- if (pkt->pts != AV_NOPTS_VALUE)
- *cur_ts = av_rescale_q(pkt->pts, tb, AV_TIME_BASE_Q);
+ if (pts != AV_NOPTS_VALUE)
+ *cur_ts = av_rescale_q(pts, tb, AV_TIME_BASE_Q);
if (!has_start && *cur_ts != AV_NOPTS_VALUE) {
start = *cur_ts;
@@ -2880,7 +2916,7 @@ static int read_interval_packets(WriterContext *w, InputFile *ifile,
}
av_packet_unref(pkt);
//Flush remaining frames that are cached in the decoder
- for (i = 0; i < fmt_ctx->nb_streams; i++) {
+ for (i = 0; i < ifile->nb_streams; i++) {
pkt->stream_index = i;
if (do_read_frames) {
while (process_frame(w, ifile, frame, pkt, &(int){1}) > 0);
@@ -3038,6 +3074,8 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id
}
print_int("bits_per_sample", av_get_bits_per_sample(par->codec_id));
+
+ print_int("initial_padding", par->initial_padding);
break;
case AVMEDIA_TYPE_SUBTITLE:
@@ -3264,15 +3302,9 @@ static int show_format(WriterContext *w, InputFile *ifile)
static void show_error(WriterContext *w, int err)
{
- char errbuf[128];
- const char *errbuf_ptr = errbuf;
-
- if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
- errbuf_ptr = strerror(AVUNERROR(err));
-
writer_print_section_header(w, SECTION_ID_ERROR);
print_int("code", err);
- print_str("string", errbuf_ptr);
+ print_str("string", av_err2str(err));
writer_print_section_footer(w);
}
@@ -3285,10 +3317,8 @@ static int open_input_file(InputFile *ifile, const char *filename,
int scan_all_pmts_set = 0;
fmt_ctx = avformat_alloc_context();
- if (!fmt_ctx) {
- print_error(filename, AVERROR(ENOMEM));
- exit_program(1);
- }
+ if (!fmt_ctx)
+ report_and_exit(AVERROR(ENOMEM));
if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
@@ -3306,7 +3336,7 @@ static int open_input_file(InputFile *ifile, const char *filename,
ifile->fmt_ctx = fmt_ctx;
if (scan_all_pmts_set)
av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
- while ((t = av_dict_get(format_opts, "", t, AV_DICT_IGNORE_SUFFIX)))
+ while ((t = av_dict_iterate(format_opts, t)))
av_log(NULL, AV_LOG_WARNING, "Option %s skipped - not known to demuxer.\n", t->key);
if (find_stream_info) {
@@ -3705,7 +3735,7 @@ static void opt_input_file(void *optctx, const char *arg)
exit_program(1);
}
if (!strcmp(arg, "-"))
- arg = "pipe:";
+ arg = "fd:";
input_filename = arg;
}
@@ -3724,7 +3754,7 @@ static void opt_output_file(void *optctx, const char *arg)
exit_program(1);
}
if (!strcmp(arg, "-"))
- arg = "pipe:";
+ arg = "fd:";
output_filename = arg;
}
diff --git a/fftools/fftools.manifest b/fftools/fftools.manifest
new file mode 100644
index 000000000..f2708ecb1
--- /dev/null
+++ b/fftools/fftools.manifest
@@ -0,0 +1,9 @@
+
+
+
+
+ true
+ PerMonitorV2
+
+
+
diff --git a/fftools/fftoolsres.rc b/fftools/fftoolsres.rc
new file mode 100644
index 000000000..0b8b7c86c
--- /dev/null
+++ b/fftools/fftoolsres.rc
@@ -0,0 +1,2 @@
+#include
+1 RT_MANIFEST fftools.manifest
diff --git a/fftools/objpool.c b/fftools/objpool.c
new file mode 100644
index 000000000..87237cf72
--- /dev/null
+++ b/fftools/objpool.c
@@ -0,0 +1,131 @@
+/*
+ * 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
+
+#include "libavcodec/packet.h"
+
+#include "libavutil/common.h"
+#include "libavutil/error.h"
+#include "libavutil/frame.h"
+#include "libavutil/mem.h"
+
+#include "objpool.h"
+
+struct ObjPool {
+ void *pool[32];
+ unsigned int pool_count;
+
+ ObjPoolCBAlloc alloc;
+ ObjPoolCBReset reset;
+ ObjPoolCBFree free;
+};
+
+ObjPool *objpool_alloc(ObjPoolCBAlloc cb_alloc, ObjPoolCBReset cb_reset,
+ ObjPoolCBFree cb_free)
+{
+ ObjPool *op = av_mallocz(sizeof(*op));
+
+ if (!op)
+ return NULL;
+
+ op->alloc = cb_alloc;
+ op->reset = cb_reset;
+ op->free = cb_free;
+
+ return op;
+}
+
+void objpool_free(ObjPool **pop)
+{
+ ObjPool *op = *pop;
+
+ if (!op)
+ return;
+
+ for (unsigned int i = 0; i < op->pool_count; i++)
+ op->free(&op->pool[i]);
+
+ av_freep(pop);
+}
+
+int objpool_get(ObjPool *op, void **obj)
+{
+ if (op->pool_count) {
+ *obj = op->pool[--op->pool_count];
+ op->pool[op->pool_count] = NULL;
+ } else
+ *obj = op->alloc();
+
+ return *obj ? 0 : AVERROR(ENOMEM);
+}
+
+void objpool_release(ObjPool *op, void **obj)
+{
+ if (!*obj)
+ return;
+
+ op->reset(*obj);
+
+ if (op->pool_count < FF_ARRAY_ELEMS(op->pool))
+ op->pool[op->pool_count++] = *obj;
+ else
+ op->free(obj);
+
+ *obj = NULL;
+}
+
+static void *alloc_packet(void)
+{
+ return av_packet_alloc();
+}
+static void *alloc_frame(void)
+{
+ return av_frame_alloc();
+}
+
+static void reset_packet(void *obj)
+{
+ av_packet_unref(obj);
+}
+static void reset_frame(void *obj)
+{
+ av_frame_unref(obj);
+}
+
+static void free_packet(void **obj)
+{
+ AVPacket *pkt = *obj;
+ av_packet_free(&pkt);
+ *obj = NULL;
+}
+static void free_frame(void **obj)
+{
+ AVFrame *frame = *obj;
+ av_frame_free(&frame);
+ *obj = NULL;
+}
+
+ObjPool *objpool_alloc_packets(void)
+{
+ return objpool_alloc(alloc_packet, reset_packet, free_packet);
+}
+ObjPool *objpool_alloc_frames(void)
+{
+ return objpool_alloc(alloc_frame, reset_frame, free_frame);
+}
diff --git a/fftools/objpool.h b/fftools/objpool.h
new file mode 100644
index 000000000..1b2aea6ac
--- /dev/null
+++ b/fftools/objpool.h
@@ -0,0 +1,37 @@
+/*
+ * 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_OBJPOOL_H
+#define FFTOOLS_OBJPOOL_H
+
+typedef struct ObjPool ObjPool;
+
+typedef void* (*ObjPoolCBAlloc)(void);
+typedef void (*ObjPoolCBReset)(void *);
+typedef void (*ObjPoolCBFree)(void **);
+
+void objpool_free(ObjPool **op);
+ObjPool *objpool_alloc(ObjPoolCBAlloc cb_alloc, ObjPoolCBReset cb_reset,
+ ObjPoolCBFree cb_free);
+ObjPool *objpool_alloc_packets(void);
+ObjPool *objpool_alloc_frames(void);
+
+int objpool_get(ObjPool *op, void **obj);
+void objpool_release(ObjPool *op, void **obj);
+
+#endif // FFTOOLS_OBJPOOL_H
diff --git a/fftools/opt_common.c b/fftools/opt_common.c
index ae5e28a5a..8a06df82d 100644
--- a/fftools/opt_common.c
+++ b/fftools/opt_common.c
@@ -335,9 +335,12 @@ static void print_codec(const AVCodec *c)
printf(" Supported hardware devices: ");
for (int i = 0;; i++) {
const AVCodecHWConfig *config = avcodec_get_hw_config(c, i);
+ const char *name;
if (!config)
break;
- printf("%s ", av_hwdevice_get_type_name(config->device_type));
+ name = av_hwdevice_get_type_name(config->device_type);
+ if (name)
+ printf("%s ", name);
}
printf("\n");
}
@@ -639,10 +642,8 @@ static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
while ((desc = avcodec_descriptor_next(desc)))
nb_codecs++;
- if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs)))) {
- av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
- exit_program(1);
- }
+ if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs))))
+ report_and_exit(AVERROR(ENOMEM));
desc = NULL;
while ((desc = avcodec_descriptor_next(desc)))
codecs[i++] = desc;
diff --git a/fftools/sync_queue.c b/fftools/sync_queue.c
new file mode 100644
index 000000000..c2b23ee4f
--- /dev/null
+++ b/fftools/sync_queue.c
@@ -0,0 +1,448 @@
+/*
+ * 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
+#include
+
+#include "libavutil/avassert.h"
+#include "libavutil/error.h"
+#include "libavutil/fifo.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/mem.h"
+
+#include "objpool.h"
+#include "sync_queue.h"
+
+typedef struct SyncQueueStream {
+ AVFifo *fifo;
+ AVRational tb;
+
+ /* stream head: largest timestamp seen */
+ int64_t head_ts;
+ int limiting;
+ /* no more frames will be sent for this stream */
+ int finished;
+
+ uint64_t frames_sent;
+ uint64_t frames_max;
+} SyncQueueStream;
+
+struct SyncQueue {
+ enum SyncQueueType type;
+
+ /* no more frames will be sent for any stream */
+ int finished;
+ /* sync head: the stream with the _smallest_ head timestamp
+ * this stream determines which frames can be output */
+ int head_stream;
+ /* the finished stream with the smallest finish timestamp or -1 */
+ int head_finished_stream;
+
+ // maximum buffering duration in microseconds
+ int64_t buf_size_us;
+
+ SyncQueueStream *streams;
+ unsigned int nb_streams;
+
+ // pool of preallocated frames to avoid constant allocations
+ ObjPool *pool;
+};
+
+static void frame_move(const SyncQueue *sq, SyncQueueFrame dst,
+ SyncQueueFrame src)
+{
+ if (sq->type == SYNC_QUEUE_PACKETS)
+ av_packet_move_ref(dst.p, src.p);
+ else
+ av_frame_move_ref(dst.f, src.f);
+}
+
+static int64_t frame_ts(const SyncQueue *sq, SyncQueueFrame frame)
+{
+ return (sq->type == SYNC_QUEUE_PACKETS) ?
+ frame.p->pts + frame.p->duration :
+ frame.f->pts + frame.f->duration;
+}
+
+static int frame_null(const SyncQueue *sq, SyncQueueFrame frame)
+{
+ return (sq->type == SYNC_QUEUE_PACKETS) ? (frame.p == NULL) : (frame.f == NULL);
+}
+
+static void finish_stream(SyncQueue *sq, unsigned int stream_idx)
+{
+ SyncQueueStream *st = &sq->streams[stream_idx];
+
+ st->finished = 1;
+
+ if (st->limiting && st->head_ts != AV_NOPTS_VALUE) {
+ /* check if this stream is the new finished head */
+ if (sq->head_finished_stream < 0 ||
+ av_compare_ts(st->head_ts, st->tb,
+ sq->streams[sq->head_finished_stream].head_ts,
+ sq->streams[sq->head_finished_stream].tb) < 0) {
+ sq->head_finished_stream = stream_idx;
+ }
+
+ /* mark as finished all streams that should no longer receive new frames,
+ * due to them being ahead of some finished stream */
+ st = &sq->streams[sq->head_finished_stream];
+ for (unsigned int i = 0; i < sq->nb_streams; i++) {
+ SyncQueueStream *st1 = &sq->streams[i];
+ if (st != st1 && st1->head_ts != AV_NOPTS_VALUE &&
+ av_compare_ts(st->head_ts, st->tb, st1->head_ts, st1->tb) <= 0)
+ st1->finished = 1;
+ }
+ }
+
+ /* mark the whole queue as finished if all streams are finished */
+ for (unsigned int i = 0; i < sq->nb_streams; i++) {
+ if (!sq->streams[i].finished)
+ return;
+ }
+ sq->finished = 1;
+}
+
+static void queue_head_update(SyncQueue *sq)
+{
+ if (sq->head_stream < 0) {
+ /* wait for one timestamp in each stream before determining
+ * the queue head */
+ for (unsigned int i = 0; i < sq->nb_streams; i++) {
+ SyncQueueStream *st = &sq->streams[i];
+ if (st->limiting && st->head_ts == AV_NOPTS_VALUE)
+ return;
+ }
+
+ // placeholder value, correct one will be found below
+ sq->head_stream = 0;
+ }
+
+ for (unsigned int i = 0; i < sq->nb_streams; i++) {
+ SyncQueueStream *st_head = &sq->streams[sq->head_stream];
+ SyncQueueStream *st_other = &sq->streams[i];
+ if (st_other->limiting && st_other->head_ts != AV_NOPTS_VALUE &&
+ av_compare_ts(st_other->head_ts, st_other->tb,
+ st_head->head_ts, st_head->tb) < 0)
+ sq->head_stream = i;
+ }
+}
+
+/* update this stream's head timestamp */
+static void stream_update_ts(SyncQueue *sq, unsigned int stream_idx, int64_t ts)
+{
+ SyncQueueStream *st = &sq->streams[stream_idx];
+
+ if (ts == AV_NOPTS_VALUE ||
+ (st->head_ts != AV_NOPTS_VALUE && st->head_ts >= ts))
+ return;
+
+ st->head_ts = ts;
+
+ /* if this stream is now ahead of some finished stream, then
+ * this stream is also finished */
+ if (sq->head_finished_stream >= 0 &&
+ av_compare_ts(sq->streams[sq->head_finished_stream].head_ts,
+ sq->streams[sq->head_finished_stream].tb,
+ ts, st->tb) <= 0)
+ finish_stream(sq, stream_idx);
+
+ /* update the overall head timestamp if it could have changed */
+ if (st->limiting &&
+ (sq->head_stream < 0 || sq->head_stream == stream_idx))
+ queue_head_update(sq);
+}
+
+/* If the queue for the given stream (or all streams when stream_idx=-1)
+ * is overflowing, trigger a fake heartbeat on lagging streams.
+ *
+ * @return 1 if heartbeat triggered, 0 otherwise
+ */
+static int overflow_heartbeat(SyncQueue *sq, int stream_idx)
+{
+ SyncQueueStream *st;
+ SyncQueueFrame frame;
+ int64_t tail_ts = AV_NOPTS_VALUE;
+
+ /* if no stream specified, pick the one that is most ahead */
+ if (stream_idx < 0) {
+ int64_t ts = AV_NOPTS_VALUE;
+
+ for (int i = 0; i < sq->nb_streams; i++) {
+ st = &sq->streams[i];
+ if (st->head_ts != AV_NOPTS_VALUE &&
+ (ts == AV_NOPTS_VALUE ||
+ av_compare_ts(ts, sq->streams[stream_idx].tb,
+ st->head_ts, st->tb) < 0)) {
+ ts = st->head_ts;
+ stream_idx = i;
+ }
+ }
+ /* no stream has a timestamp yet -> nothing to do */
+ if (stream_idx < 0)
+ return 0;
+ }
+
+ st = &sq->streams[stream_idx];
+
+ /* get the chosen stream's tail timestamp */
+ for (size_t i = 0; tail_ts == AV_NOPTS_VALUE &&
+ av_fifo_peek(st->fifo, &frame, 1, i) >= 0; i++)
+ tail_ts = frame_ts(sq, frame);
+
+ /* overflow triggers when the tail is over specified duration behind the head */
+ if (tail_ts == AV_NOPTS_VALUE || tail_ts >= st->head_ts ||
+ av_rescale_q(st->head_ts - tail_ts, st->tb, AV_TIME_BASE_Q) < sq->buf_size_us)
+ return 0;
+
+ /* signal a fake timestamp for all streams that prevent tail_ts from being output */
+ tail_ts++;
+ for (unsigned int i = 0; i < sq->nb_streams; i++) {
+ SyncQueueStream *st1 = &sq->streams[i];
+ int64_t ts;
+
+ if (st == st1 || st1->finished ||
+ (st1->head_ts != AV_NOPTS_VALUE &&
+ av_compare_ts(tail_ts, st->tb, st1->head_ts, st1->tb) <= 0))
+ continue;
+
+ ts = av_rescale_q(tail_ts, st->tb, st1->tb);
+ if (st1->head_ts != AV_NOPTS_VALUE)
+ ts = FFMAX(st1->head_ts + 1, ts);
+
+ stream_update_ts(sq, i, ts);
+ }
+
+ return 1;
+}
+
+int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame)
+{
+ SyncQueueStream *st;
+ SyncQueueFrame dst;
+ int64_t ts;
+ int ret;
+
+ av_assert0(stream_idx < sq->nb_streams);
+ st = &sq->streams[stream_idx];
+
+ av_assert0(st->tb.num > 0 && st->tb.den > 0);
+
+ if (frame_null(sq, frame)) {
+ finish_stream(sq, stream_idx);
+ return 0;
+ }
+ if (st->finished)
+ return AVERROR_EOF;
+
+ ret = objpool_get(sq->pool, (void**)&dst);
+ if (ret < 0)
+ return ret;
+
+ frame_move(sq, dst, frame);
+
+ ts = frame_ts(sq, dst);
+
+ ret = av_fifo_write(st->fifo, &dst, 1);
+ if (ret < 0) {
+ frame_move(sq, frame, dst);
+ objpool_release(sq->pool, (void**)&dst);
+ return ret;
+ }
+
+ stream_update_ts(sq, stream_idx, ts);
+
+ st->frames_sent++;
+ if (st->frames_sent >= st->frames_max)
+ finish_stream(sq, stream_idx);
+
+ return 0;
+}
+
+static int receive_for_stream(SyncQueue *sq, unsigned int stream_idx,
+ SyncQueueFrame frame)
+{
+ SyncQueueStream *st_head = sq->head_stream >= 0 ?
+ &sq->streams[sq->head_stream] : NULL;
+ SyncQueueStream *st;
+
+ av_assert0(stream_idx < sq->nb_streams);
+ st = &sq->streams[stream_idx];
+
+ if (av_fifo_can_read(st->fifo)) {
+ SyncQueueFrame peek;
+ int64_t ts;
+ int cmp = 1;
+
+ av_fifo_peek(st->fifo, &peek, 1, 0);
+ ts = frame_ts(sq, peek);
+
+ /* check if this stream's tail timestamp does not overtake
+ * the overall queue head */
+ if (ts != AV_NOPTS_VALUE && st_head)
+ cmp = av_compare_ts(ts, st->tb, st_head->head_ts, st_head->tb);
+
+ /* We can release frames that do not end after the queue head.
+ * Frames with no timestamps are just passed through with no conditions.
+ */
+ if (cmp <= 0 || ts == AV_NOPTS_VALUE) {
+ frame_move(sq, frame, peek);
+ objpool_release(sq->pool, (void**)&peek);
+ av_fifo_drain2(st->fifo, 1);
+ return 0;
+ }
+ }
+
+ return (sq->finished || (st->finished && !av_fifo_can_read(st->fifo))) ?
+ AVERROR_EOF : AVERROR(EAGAIN);
+}
+
+static int receive_internal(SyncQueue *sq, int stream_idx, SyncQueueFrame frame)
+{
+ int nb_eof = 0;
+ int ret;
+
+ /* read a frame for a specific stream */
+ if (stream_idx >= 0) {
+ ret = receive_for_stream(sq, stream_idx, frame);
+ return (ret < 0) ? ret : stream_idx;
+ }
+
+ /* read a frame for any stream with available output */
+ for (unsigned int i = 0; i < sq->nb_streams; i++) {
+ ret = receive_for_stream(sq, i, frame);
+ if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) {
+ nb_eof += (ret == AVERROR_EOF);
+ continue;
+ }
+ return (ret < 0) ? ret : i;
+ }
+
+ return (nb_eof == sq->nb_streams) ? AVERROR_EOF : AVERROR(EAGAIN);
+}
+
+int sq_receive(SyncQueue *sq, int stream_idx, SyncQueueFrame frame)
+{
+ int ret = receive_internal(sq, stream_idx, frame);
+
+ /* try again if the queue overflowed and triggered a fake heartbeat
+ * for lagging streams */
+ if (ret == AVERROR(EAGAIN) && overflow_heartbeat(sq, stream_idx))
+ ret = receive_internal(sq, stream_idx, frame);
+
+ return ret;
+}
+
+int sq_add_stream(SyncQueue *sq, int limiting)
+{
+ SyncQueueStream *tmp, *st;
+
+ tmp = av_realloc_array(sq->streams, sq->nb_streams + 1, sizeof(*sq->streams));
+ if (!tmp)
+ return AVERROR(ENOMEM);
+ sq->streams = tmp;
+
+ st = &sq->streams[sq->nb_streams];
+ memset(st, 0, sizeof(*st));
+
+ st->fifo = av_fifo_alloc2(1, sizeof(SyncQueueFrame), AV_FIFO_FLAG_AUTO_GROW);
+ if (!st->fifo)
+ return AVERROR(ENOMEM);
+
+ /* we set a valid default, so that a pathological stream that never
+ * receives even a real timebase (and no frames) won't stall all other
+ * streams forever; cf. overflow_heartbeat() */
+ st->tb = (AVRational){ 1, 1 };
+ st->head_ts = AV_NOPTS_VALUE;
+ st->frames_max = UINT64_MAX;
+ st->limiting = limiting;
+
+ return sq->nb_streams++;
+}
+
+void sq_set_tb(SyncQueue *sq, unsigned int stream_idx, AVRational tb)
+{
+ SyncQueueStream *st;
+
+ av_assert0(stream_idx < sq->nb_streams);
+ st = &sq->streams[stream_idx];
+
+ av_assert0(!av_fifo_can_read(st->fifo));
+
+ if (st->head_ts != AV_NOPTS_VALUE)
+ st->head_ts = av_rescale_q(st->head_ts, st->tb, tb);
+
+ st->tb = tb;
+}
+
+void sq_limit_frames(SyncQueue *sq, unsigned int stream_idx, uint64_t frames)
+{
+ SyncQueueStream *st;
+
+ av_assert0(stream_idx < sq->nb_streams);
+ st = &sq->streams[stream_idx];
+
+ st->frames_max = frames;
+ if (st->frames_sent >= st->frames_max)
+ finish_stream(sq, stream_idx);
+}
+
+SyncQueue *sq_alloc(enum SyncQueueType type, int64_t buf_size_us)
+{
+ SyncQueue *sq = av_mallocz(sizeof(*sq));
+
+ if (!sq)
+ return NULL;
+
+ sq->type = type;
+ sq->buf_size_us = buf_size_us;
+
+ sq->head_stream = -1;
+ sq->head_finished_stream = -1;
+
+ sq->pool = (type == SYNC_QUEUE_PACKETS) ? objpool_alloc_packets() :
+ objpool_alloc_frames();
+ if (!sq->pool) {
+ av_freep(&sq);
+ return NULL;
+ }
+
+ return sq;
+}
+
+void sq_free(SyncQueue **psq)
+{
+ SyncQueue *sq = *psq;
+
+ if (!sq)
+ return;
+
+ for (unsigned int i = 0; i < sq->nb_streams; i++) {
+ SyncQueueFrame frame;
+ while (av_fifo_read(sq->streams[i].fifo, &frame, 1) >= 0)
+ objpool_release(sq->pool, (void**)&frame);
+
+ av_fifo_freep2(&sq->streams[i].fifo);
+ }
+
+ av_freep(&sq->streams);
+
+ objpool_free(&sq->pool);
+
+ av_freep(psq);
+}
diff --git a/fftools/sync_queue.h b/fftools/sync_queue.h
new file mode 100644
index 000000000..3f823ff0d
--- /dev/null
+++ b/fftools/sync_queue.h
@@ -0,0 +1,109 @@
+/*
+ * 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_SYNC_QUEUE_H
+#define FFTOOLS_SYNC_QUEUE_H
+
+#include
+
+#include "libavcodec/packet.h"
+
+#include "libavutil/frame.h"
+
+enum SyncQueueType {
+ SYNC_QUEUE_PACKETS,
+ SYNC_QUEUE_FRAMES,
+};
+
+typedef union SyncQueueFrame {
+ AVFrame *f;
+ AVPacket *p;
+} SyncQueueFrame;
+
+#define SQFRAME(frame) ((SyncQueueFrame){ .f = (frame) })
+#define SQPKT(pkt) ((SyncQueueFrame){ .p = (pkt) })
+
+typedef struct SyncQueue SyncQueue;
+
+/**
+ * Allocate a sync queue of the given type.
+ *
+ * @param buf_size_us maximum duration that will be buffered in microseconds
+ */
+SyncQueue *sq_alloc(enum SyncQueueType type, int64_t buf_size_us);
+void sq_free(SyncQueue **sq);
+
+/**
+ * Add a new stream to the sync queue.
+ *
+ * @param limiting whether the stream is limiting, i.e. no other stream can be
+ * longer than this one
+ * @return
+ * - a non-negative stream index on success
+ * - a negative error code on error
+ */
+int sq_add_stream(SyncQueue *sq, int limiting);
+
+/**
+ * Set the timebase for the stream with index stream_idx. Should be called
+ * before sending any frames for this stream.
+ */
+void sq_set_tb(SyncQueue *sq, unsigned int stream_idx, AVRational tb);
+
+/**
+ * Limit the number of output frames for stream with index stream_idx
+ * to max_frames.
+ */
+void sq_limit_frames(SyncQueue *sq, unsigned int stream_idx,
+ uint64_t max_frames);
+
+/**
+ * Submit a frame for the stream with index stream_idx.
+ *
+ * On success, the sync queue takes ownership of the frame and will reset the
+ * contents of the supplied frame. On failure, the frame remains owned by the
+ * caller.
+ *
+ * Sending a frame with NULL contents marks the stream as finished.
+ *
+ * @return
+ * - 0 on success
+ * - AVERROR_EOF when no more frames should be submitted for this stream
+ * - another a negative error code on failure
+ */
+int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame);
+
+/**
+ * Read a frame from the queue.
+ *
+ * @param stream_idx index of the stream to read a frame for. May be -1, then
+ * try to read a frame from any stream that is ready for
+ * output.
+ * @param frame output frame will be written here on success. The frame is owned
+ * by the caller.
+ *
+ * @return
+ * - a non-negative index of the stream to which the returned frame belongs
+ * - AVERROR(EAGAIN) when more frames need to be submitted to the queue
+ * - AVERROR_EOF when no more frames will be available for this stream (for any
+ * stream if stream_idx is -1)
+ * - another negative error code on failure
+ */
+int sq_receive(SyncQueue *sq, int stream_idx, SyncQueueFrame frame);
+
+#endif // FFTOOLS_SYNC_QUEUE_H
diff --git a/fftools/thread_queue.c b/fftools/thread_queue.c
new file mode 100644
index 000000000..a1ab4ce92
--- /dev/null
+++ b/fftools/thread_queue.c
@@ -0,0 +1,245 @@
+/*
+ * 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
+#include
+
+#include "libavutil/avassert.h"
+#include "libavutil/error.h"
+#include "libavutil/fifo.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mem.h"
+#include "libavutil/thread.h"
+
+#include "objpool.h"
+#include "thread_queue.h"
+
+enum {
+ FINISHED_SEND = (1 << 0),
+ FINISHED_RECV = (1 << 1),
+};
+
+typedef struct FifoElem {
+ void *obj;
+ unsigned int stream_idx;
+} FifoElem;
+
+struct ThreadQueue {
+ int *finished;
+ unsigned int nb_streams;
+
+ AVFifo *fifo;
+
+ ObjPool *obj_pool;
+ void (*obj_move)(void *dst, void *src);
+
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+};
+
+void tq_free(ThreadQueue **ptq)
+{
+ ThreadQueue *tq = *ptq;
+
+ if (!tq)
+ return;
+
+ if (tq->fifo) {
+ FifoElem elem;
+ while (av_fifo_read(tq->fifo, &elem, 1) >= 0)
+ objpool_release(tq->obj_pool, &elem.obj);
+ }
+ av_fifo_freep2(&tq->fifo);
+
+ objpool_free(&tq->obj_pool);
+
+ av_freep(&tq->finished);
+
+ pthread_cond_destroy(&tq->cond);
+ pthread_mutex_destroy(&tq->lock);
+
+ av_freep(ptq);
+}
+
+ThreadQueue *tq_alloc(unsigned int nb_streams, size_t queue_size,
+ ObjPool *obj_pool, void (*obj_move)(void *dst, void *src))
+{
+ ThreadQueue *tq;
+ int ret;
+
+ tq = av_mallocz(sizeof(*tq));
+ if (!tq)
+ return NULL;
+
+ ret = pthread_cond_init(&tq->cond, NULL);
+ if (ret) {
+ av_freep(&tq);
+ return NULL;
+ }
+
+ ret = pthread_mutex_init(&tq->lock, NULL);
+ if (ret) {
+ pthread_cond_destroy(&tq->cond);
+ av_freep(&tq);
+ return NULL;
+ }
+
+ tq->finished = av_calloc(nb_streams, sizeof(*tq->finished));
+ if (!tq->finished)
+ goto fail;
+ tq->nb_streams = nb_streams;
+
+ tq->fifo = av_fifo_alloc2(queue_size, sizeof(FifoElem), 0);
+ if (!tq->fifo)
+ goto fail;
+
+ tq->obj_pool = obj_pool;
+ tq->obj_move = obj_move;
+
+ return tq;
+fail:
+ tq_free(&tq);
+ return NULL;
+}
+
+int tq_send(ThreadQueue *tq, unsigned int stream_idx, void *data)
+{
+ int *finished;
+ int ret;
+
+ av_assert0(stream_idx < tq->nb_streams);
+ finished = &tq->finished[stream_idx];
+
+ pthread_mutex_lock(&tq->lock);
+
+ if (*finished & FINISHED_SEND) {
+ ret = AVERROR(EINVAL);
+ goto finish;
+ }
+
+ while (!(*finished & FINISHED_RECV) && !av_fifo_can_write(tq->fifo))
+ pthread_cond_wait(&tq->cond, &tq->lock);
+
+ if (*finished & FINISHED_RECV) {
+ ret = AVERROR_EOF;
+ *finished |= FINISHED_SEND;
+ } else {
+ FifoElem elem = { .stream_idx = stream_idx };
+
+ ret = objpool_get(tq->obj_pool, &elem.obj);
+ if (ret < 0)
+ goto finish;
+
+ tq->obj_move(elem.obj, data);
+
+ ret = av_fifo_write(tq->fifo, &elem, 1);
+ av_assert0(ret >= 0);
+ pthread_cond_broadcast(&tq->cond);
+ }
+
+finish:
+ pthread_mutex_unlock(&tq->lock);
+
+ return ret;
+}
+
+static int receive_locked(ThreadQueue *tq, int *stream_idx,
+ void *data)
+{
+ FifoElem elem;
+ unsigned int nb_finished = 0;
+
+ if (av_fifo_read(tq->fifo, &elem, 1) >= 0) {
+ tq->obj_move(data, elem.obj);
+ objpool_release(tq->obj_pool, &elem.obj);
+ *stream_idx = elem.stream_idx;
+ return 0;
+ }
+
+ for (unsigned int i = 0; i < tq->nb_streams; i++) {
+ if (!(tq->finished[i] & FINISHED_SEND))
+ continue;
+
+ /* return EOF to the consumer at most once for each stream */
+ if (!(tq->finished[i] & FINISHED_RECV)) {
+ tq->finished[i] |= FINISHED_RECV;
+ *stream_idx = i;
+ return AVERROR_EOF;
+ }
+
+ nb_finished++;
+ }
+
+ return nb_finished == tq->nb_streams ? AVERROR_EOF : AVERROR(EAGAIN);
+}
+
+int tq_receive(ThreadQueue *tq, int *stream_idx, void *data)
+{
+ int ret;
+
+ *stream_idx = -1;
+
+ pthread_mutex_lock(&tq->lock);
+
+ while (1) {
+ ret = receive_locked(tq, stream_idx, data);
+ if (ret == AVERROR(EAGAIN)) {
+ pthread_cond_wait(&tq->cond, &tq->lock);
+ continue;
+ }
+
+ break;
+ }
+
+ if (ret == 0)
+ pthread_cond_broadcast(&tq->cond);
+
+ pthread_mutex_unlock(&tq->lock);
+
+ return ret;
+}
+
+void tq_send_finish(ThreadQueue *tq, unsigned int stream_idx)
+{
+ av_assert0(stream_idx < tq->nb_streams);
+
+ pthread_mutex_lock(&tq->lock);
+
+ /* mark the stream as send-finished;
+ * next time the consumer thread tries to read this stream it will get
+ * an EOF and recv-finished flag will be set */
+ tq->finished[stream_idx] |= FINISHED_SEND;
+ pthread_cond_broadcast(&tq->cond);
+
+ pthread_mutex_unlock(&tq->lock);
+}
+
+void tq_receive_finish(ThreadQueue *tq, unsigned int stream_idx)
+{
+ av_assert0(stream_idx < tq->nb_streams);
+
+ pthread_mutex_lock(&tq->lock);
+
+ /* mark the stream as recv-finished;
+ * next time the producer thread tries to send for this stream, it will
+ * get an EOF and send-finished flag will be set */
+ tq->finished[stream_idx] |= FINISHED_RECV;
+ pthread_cond_broadcast(&tq->cond);
+
+ pthread_mutex_unlock(&tq->lock);
+}
diff --git a/fftools/thread_queue.h b/fftools/thread_queue.h
new file mode 100644
index 000000000..0cc8c71eb
--- /dev/null
+++ b/fftools/thread_queue.h
@@ -0,0 +1,81 @@
+/*
+ * 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_THREAD_QUEUE_H
+#define FFTOOLS_THREAD_QUEUE_H
+
+#include
+
+#include "objpool.h"
+
+typedef struct ThreadQueue ThreadQueue;
+
+/**
+ * Allocate a queue for sending data between threads.
+ *
+ * @param nb_streams number of streams for which a distinct EOF state is
+ * maintained
+ * @param queue_size number of items that can be stored in the queue without
+ * blocking
+ * @param obj_pool object pool that will be used to allocate items stored in the
+ * queue; the pool becomes owned by the queue
+ * @param callback that moves the contents between two data pointers
+ */
+ThreadQueue *tq_alloc(unsigned int nb_streams, size_t queue_size,
+ ObjPool *obj_pool, void (*obj_move)(void *dst, void *src));
+void tq_free(ThreadQueue **tq);
+
+/**
+ * Send an item for the given stream to the queue.
+ *
+ * @param data the item to send, its contents will be moved using the callback
+ * provided to tq_alloc(); on failure the item will be left
+ * untouched
+ * @return
+ * - 0 the item was successfully sent
+ * - AVERROR(ENOMEM) could not allocate an item for writing to the FIFO
+ * - AVERROR(EINVAL) the sending side has previously been marked as finished
+ * - AVERROR_EOF the receiving side has marked the given stream as finished
+ */
+int tq_send(ThreadQueue *tq, unsigned int stream_idx, void *data);
+/**
+ * Mark the given stream finished from the sending side.
+ */
+void tq_send_finish(ThreadQueue *tq, unsigned int stream_idx);
+
+/**
+ * Read the next item from the queue.
+ *
+ * @param stream_idx the index of the stream that was processed or -1 will be
+ * written here
+ * @param data the data item will be written here on success using the
+ * callback provided to tq_alloc()
+ * @return
+ * - 0 a data item was successfully read; *stream_idx contains a non-negative
+ * stream index
+ * - AVERROR_EOF When *stream_idx is non-negative, this signals that the sending
+ * side has marked the given stream as finished. This will happen at most once
+ * for each stream. When *stream_idx is -1, all streams are done.
+ */
+int tq_receive(ThreadQueue *tq, int *stream_idx, void *data);
+/**
+ * Mark the given stream finished from the receiving side.
+ */
+void tq_receive_finish(ThreadQueue *tq, unsigned int stream_idx);
+
+#endif // FFTOOLS_THREAD_QUEUE_H
diff --git a/libavcodec/.gitignore b/libavcodec/.gitignore
deleted file mode 100644
index 28814f723..000000000
--- a/libavcodec/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-/*_tablegen
-/*_tables.c
-/*_tables.h
-/bsf_list.c
-/codec_list.c
-/parser_list.c
diff --git a/libavcodec/012v.c b/libavcodec/012v.c
index c03afd0bc..f0197cd8f 100644
--- a/libavcodec/012v.c
+++ b/libavcodec/012v.c
@@ -22,7 +22,7 @@
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "libavutil/intreadwrite.h"
static av_cold int zero12v_decode_init(AVCodecContext *avctx)
@@ -131,8 +131,8 @@ static int zero12v_decode_frame(AVCodecContext *avctx, AVFrame *pic,
u = x/2 + (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
v = x/2 + (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
memcpy(y, y_temp, sizeof(*y) * (width - x));
- memcpy(u, u_temp, sizeof(*u) * (width - x + 1) / 2);
- memcpy(v, v_temp, sizeof(*v) * (width - x + 1) / 2);
+ memcpy(u, u_temp, sizeof(*u) * ((width - x + 1) / 2));
+ memcpy(v, v_temp, sizeof(*v) * ((width - x + 1) / 2));
}
line_end += stride;
@@ -146,11 +146,10 @@ static int zero12v_decode_frame(AVCodecContext *avctx, AVFrame *pic,
const FFCodec ff_zero12v_decoder = {
.p.name = "012v",
- .p.long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
+ CODEC_LONG_NAME("Uncompressed 4:2:2 10-bit"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_012V,
.init = zero12v_decode_init,
FF_CODEC_DECODE_CB(zero12v_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c
index 7b88631a6..fab3fb5b7 100644
--- a/libavcodec/4xm.c
+++ b/libavcodec/4xm.c
@@ -37,8 +37,8 @@
#include "bswapdsp.h"
#include "bytestream.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
#define BLOCK_TYPE_VLC_BITS 5
@@ -875,7 +875,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
}
for (i = 0; i < CFRAME_BUFFER_COUNT; i++)
- if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
+ if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_num)
av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n",
f->cfrm[i].id);
@@ -910,9 +910,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
buf = cfrm->data;
frame_size = cfrm->size;
- if (id != avctx->frame_number)
- av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n",
- id, avctx->frame_number);
+ if (id != avctx->frame_num)
+ av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %"PRId64"\n",
+ id, avctx->frame_num);
if (f->version <= 1)
return AVERROR_INVALIDDATA;
@@ -950,9 +950,11 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
} else if (frame_4cc == AV_RL32("snd_")) {
av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n",
buf_size);
+ return AVERROR_INVALIDDATA;
} else {
av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n",
buf_size);
+ return AVERROR_INVALIDDATA;
}
picture->key_frame = picture->pict_type == AV_PICTURE_TYPE_I;
@@ -964,8 +966,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
*got_frame = 1;
- emms_c();
-
return buf_size;
}
@@ -1012,7 +1012,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
return AVERROR(ENOMEM);
f->version = AV_RL32(avctx->extradata) >> 16;
- ff_blockdsp_init(&f->bdsp, avctx);
+ ff_blockdsp_init(&f->bdsp);
ff_bswapdsp_init(&f->bbdsp);
f->avctx = avctx;
@@ -1028,7 +1028,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
const FFCodec ff_fourxm_decoder = {
.p.name = "4xm",
- .p.long_name = NULL_IF_CONFIG_SMALL("4X Movie"),
+ CODEC_LONG_NAME("4X Movie"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_4XM,
.priv_data_size = sizeof(FourXContext),
@@ -1036,5 +1036,5 @@ const FFCodec ff_fourxm_decoder = {
.close = decode_end,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c
index 292aa03c6..90d6c96fd 100644
--- a/libavcodec/8bps.c
+++ b/libavcodec/8bps.c
@@ -30,16 +30,13 @@
* : RGB32 (RGB 32bpp, 4th plane is alpha)
*/
-#include
-#include
#include
+#include "libavutil/bswap.h"
#include "libavutil/internal.h"
-#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "codec_internal.h"
#include "decode.h"
-#include "internal.h"
static const enum AVPixelFormat pixfmt_rgb24[] = {
@@ -71,7 +68,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
unsigned char *planemap = c->planemap;
int ret;
- if (buf_size < planes * height *2)
+ if (buf_size < planes * height * 2)
return AVERROR_INVALIDDATA;
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
@@ -178,12 +175,11 @@ static av_cold int decode_init(AVCodecContext *avctx)
const FFCodec ff_eightbps_decoder = {
.p.name = "8bps",
- .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"),
+ CODEC_LONG_NAME("QuickTime 8BPS video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_8BPS,
.priv_data_size = sizeof(EightBpsContext),
.init = decode_init,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/8svx.c b/libavcodec/8svx.c
index 6eb90834b..0a6d311cf 100644
--- a/libavcodec/8svx.c
+++ b/libavcodec/8svx.c
@@ -42,7 +42,7 @@
#include "libavutil/avassert.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "libavutil/common.h"
/** decoder context */
@@ -151,7 +151,7 @@ static int eightsvx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
*got_frame_ptr = 1;
- return ((avctx->frame_number == 0) * hdr_size + buf_size) * channels;
+ return ((avctx->frame_num == 0) * hdr_size + buf_size) * channels;
}
static av_cold int eightsvx_decode_init(AVCodecContext *avctx)
@@ -189,7 +189,7 @@ static av_cold int eightsvx_decode_close(AVCodecContext *avctx)
#if CONFIG_EIGHTSVX_FIB_DECODER
const FFCodec ff_eightsvx_fib_decoder = {
.p.name = "8svx_fib",
- .p.long_name = NULL_IF_CONFIG_SMALL("8SVX fibonacci"),
+ CODEC_LONG_NAME("8SVX fibonacci"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_8SVX_FIB,
.priv_data_size = sizeof (EightSvxContext),
@@ -199,13 +199,12 @@ const FFCodec ff_eightsvx_fib_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
#if CONFIG_EIGHTSVX_EXP_DECODER
const FFCodec ff_eightsvx_exp_decoder = {
.p.name = "8svx_exp",
- .p.long_name = NULL_IF_CONFIG_SMALL("8SVX exponential"),
+ CODEC_LONG_NAME("8SVX exponential"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_8SVX_EXP,
.priv_data_size = sizeof (EightSvxContext),
@@ -215,6 +214,5 @@ const FFCodec ff_eightsvx_exp_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 457ec5837..389253f5d 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -91,16 +91,19 @@ OBJS-$(CONFIG_FDCTDSP) += fdctdsp.o jfdctfst.o jfdctint.o
FFT-OBJS-$(CONFIG_HARDCODED_TABLES) += cos_tables.o
OBJS-$(CONFIG_FFT) += avfft.o fft_float.o fft_fixed_32.o \
fft_init_table.o $(FFT-OBJS-yes)
-OBJS-$(CONFIG_FLACDSP) += flacdsp.o
OBJS-$(CONFIG_FMTCONVERT) += fmtconvert.o
OBJS-$(CONFIG_GOLOMB) += golomb.o
OBJS-$(CONFIG_H263DSP) += h263dsp.o
OBJS-$(CONFIG_H264CHROMA) += h264chroma.o
OBJS-$(CONFIG_H264DSP) += h264dsp.o h264idct.o
-OBJS-$(CONFIG_H264PARSE) += h264_parse.o h2645_parse.o h264_ps.o
+OBJS-$(CONFIG_H264PARSE) += h264_parse.o h264_ps.o h2645data.o \
+ h2645_parse.o h2645_vui.o
OBJS-$(CONFIG_H264PRED) += h264pred.o
OBJS-$(CONFIG_H264QPEL) += h264qpel.o
-OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o h2645_parse.o hevc_ps.o hevc_sei.o hevc_data.o \
+OBJS-$(CONFIG_H264_SEI) += h264_sei.o h2645_sei.o
+OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o hevc_ps.o hevc_data.o \
+ h2645data.o h2645_parse.o h2645_vui.o
+OBJS-$(CONFIG_HEVC_SEI) += hevc_sei.o h2645_sei.o \
dynamic_hdr10_plus.o dynamic_hdr_vivid.o
OBJS-$(CONFIG_HPELDSP) += hpeldsp.o
OBJS-$(CONFIG_HUFFMAN) += huffman.o
@@ -108,12 +111,12 @@ OBJS-$(CONFIG_HUFFYUVDSP) += huffyuvdsp.o
OBJS-$(CONFIG_HUFFYUVENCDSP) += huffyuvencdsp.o
OBJS-$(CONFIG_IDCTDSP) += idctdsp.o simple_idct.o jrevdct.o
OBJS-$(CONFIG_IIRFILTER) += iirfilter.o
-OBJS-$(CONFIG_MDCT15) += mdct15.o
OBJS-$(CONFIG_INFLATE_WRAPPER) += zlib_wrapper.o
OBJS-$(CONFIG_INTRAX8) += intrax8.o intrax8dsp.o msmpeg4data.o
OBJS-$(CONFIG_IVIDSP) += ivi_dsp.o
OBJS-$(CONFIG_JNI) += ffjni.o jni.o
OBJS-$(CONFIG_JPEGTABLES) += jpegtables.o
+OBJS-$(CONFIG_LCMS2) += fflcms2.o
OBJS-$(CONFIG_LLAUDDSP) += lossless_audiodsp.o
OBJS-$(CONFIG_LLVIDDSP) += lossless_videodsp.o
OBJS-$(CONFIG_LLVIDENCDSP) += lossless_videoencdsp.o
@@ -132,7 +135,7 @@ OBJS-$(CONFIG_MPEGAUDIODSP) += mpegaudiodsp.o \
mpegaudiodsp_float.o
OBJS-$(CONFIG_MPEGAUDIOHEADER) += mpegaudiodecheader.o mpegaudiotabs.o
OBJS-$(CONFIG_MPEG4AUDIO) += mpeg4audio.o mpeg4audio_sample_rates.o
-OBJS-$(CONFIG_MPEGVIDEO) += mpegvideo.o mpegvideodsp.o rl.o \
+OBJS-$(CONFIG_MPEGVIDEO) += mpegvideo.o rl.o \
mpegvideo_motion.o \
mpegvideodata.o mpegpicture.o \
to_upper4.o
@@ -140,7 +143,11 @@ OBJS-$(CONFIG_MPEGVIDEODEC) += mpegvideo_dec.o mpegutils.o
OBJS-$(CONFIG_MPEGVIDEOENC) += mpegvideo_enc.o mpeg12data.o \
motion_est.o ratecontrol.o \
mpegvideoencdsp.o
-OBJS-$(CONFIG_MSS34DSP) += mss34dsp.o
+OBJS-$(CONFIG_MSMPEG4DEC) += msmpeg4dec.o msmpeg4.o msmpeg4data.o \
+ msmpeg4_vc1_data.o
+OBJS-$(CONFIG_MSMPEG4ENC) += msmpeg4enc.o msmpeg4.o msmpeg4data.o \
+ msmpeg4_vc1_data.o
+OBJS-$(CONFIG_MSS34DSP) += mss34dsp.o jpegquanttables.o
OBJS-$(CONFIG_PIXBLOCKDSP) += pixblockdsp.o
OBJS-$(CONFIG_QPELDSP) += qpeldsp.o
OBJS-$(CONFIG_QSV) += qsv.o
@@ -156,6 +163,7 @@ OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o
OBJS-$(CONFIG_TEXTUREDSPENC) += texturedspenc.o
OBJS-$(CONFIG_TPELDSP) += tpeldsp.o
OBJS-$(CONFIG_VAAPI_ENCODE) += vaapi_encode.o
+OBJS-$(CONFIG_AV1_AMF_ENCODER) += amfenc_av1.o
OBJS-$(CONFIG_VC1DSP) += vc1dsp.o
OBJS-$(CONFIG_VIDEODSP) += videodsp.o
OBJS-$(CONFIG_VP3DSP) += vp3dsp.o
@@ -194,7 +202,7 @@ OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o ac3enc.o ac3tab.o \
OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o kbdwin.o
OBJS-$(CONFIG_AC3_MF_ENCODER) += mfenc.o mf_utils.o
OBJS-$(CONFIG_ACELP_KELVIN_DECODER) += g729dec.o lsp.o celp_math.o celp_filters.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o g729postfilter.o
-OBJS-$(CONFIG_AGM_DECODER) += agm.o
+OBJS-$(CONFIG_AGM_DECODER) += agm.o jpegquanttables.o
OBJS-$(CONFIG_AIC_DECODER) += aic.o
OBJS-$(CONFIG_ALAC_DECODER) += alac.o alac_data.o alacdsp.o
OBJS-$(CONFIG_ALAC_ENCODER) += alacenc.o alac_data.o
@@ -211,7 +219,10 @@ OBJS-$(CONFIG_AMRWB_DECODER) += amrwbdec.o celp_filters.o \
acelp_pitch_delay.o
OBJS-$(CONFIG_AMV_ENCODER) += mjpegenc.o mjpegenc_common.o
OBJS-$(CONFIG_ANM_DECODER) += anm.o
+OBJS-$(CONFIG_ANULL_DECODER) += null.o
+OBJS-$(CONFIG_ANULL_ENCODER) += null.o
OBJS-$(CONFIG_ANSI_DECODER) += ansi.o cga_data.o
+OBJS-$(CONFIG_APAC_DECODER) += apac.o
OBJS-$(CONFIG_APE_DECODER) += apedec.o
OBJS-$(CONFIG_APTX_DECODER) += aptxdec.o aptx.o
OBJS-$(CONFIG_APTX_ENCODER) += aptxenc.o aptx.o
@@ -241,6 +252,9 @@ OBJS-$(CONFIG_AURA_DECODER) += cyuv.o
OBJS-$(CONFIG_AURA2_DECODER) += aura.o
OBJS-$(CONFIG_AV1_DECODER) += av1dec.o
OBJS-$(CONFIG_AV1_CUVID_DECODER) += cuviddec.o
+OBJS-$(CONFIG_AV1_MEDIACODEC_DECODER) += mediacodecdec.o
+OBJS-$(CONFIG_AV1_NVENC_ENCODER) += nvenc_av1.o nvenc.o
+OBJS-$(CONFIG_AV1_QSV_ENCODER) += qsvenc_av1.o
OBJS-$(CONFIG_AVRN_DECODER) += avrndec.o
OBJS-$(CONFIG_AVRP_DECODER) += r210dec.o
OBJS-$(CONFIG_AVRP_ENCODER) += r210enc.o
@@ -261,10 +275,12 @@ OBJS-$(CONFIG_BMP_DECODER) += bmp.o msrledec.o
OBJS-$(CONFIG_BMP_ENCODER) += bmpenc.o
OBJS-$(CONFIG_BMV_AUDIO_DECODER) += bmvaudio.o
OBJS-$(CONFIG_BMV_VIDEO_DECODER) += bmvvideo.o
+OBJS-$(CONFIG_BONK_DECODER) += bonk.o
OBJS-$(CONFIG_BRENDER_PIX_DECODER) += brenderpix.o
OBJS-$(CONFIG_C93_DECODER) += c93.o
OBJS-$(CONFIG_CAVS_DECODER) += cavs.o cavsdec.o cavsdsp.o \
cavsdata.o
+OBJS-$(CONFIG_CBD2_DECODER) += dpcm.o
OBJS-$(CONFIG_CCAPTION_DECODER) += ccaption_dec.o ass.o
OBJS-$(CONFIG_CDGRAPHICS_DECODER) += cdgraphics.o
OBJS-$(CONFIG_CDTOONS_DECODER) += cdtoons.o
@@ -328,15 +344,15 @@ OBJS-$(CONFIG_EAMAD_DECODER) += eamad.o eaidct.o mpeg12.o \
OBJS-$(CONFIG_EATGQ_DECODER) += eatgq.o eaidct.o
OBJS-$(CONFIG_EATGV_DECODER) += eatgv.o
OBJS-$(CONFIG_EATQI_DECODER) += eatqi.o eaidct.o mpeg12.o \
- mpeg12data.o mpegvideodata.o
+ mpeg12data.o
OBJS-$(CONFIG_EIGHTBPS_DECODER) += 8bps.o
OBJS-$(CONFIG_EIGHTSVX_EXP_DECODER) += 8svx.o
OBJS-$(CONFIG_EIGHTSVX_FIB_DECODER) += 8svx.o
OBJS-$(CONFIG_ESCAPE124_DECODER) += escape124.o
OBJS-$(CONFIG_ESCAPE130_DECODER) += escape130.o
OBJS-$(CONFIG_EVRC_DECODER) += evrcdec.o acelp_vectors.o lsp.o
-OBJS-$(CONFIG_EXR_DECODER) += exr.o exrdsp.o
-OBJS-$(CONFIG_EXR_ENCODER) += exrenc.o
+OBJS-$(CONFIG_EXR_DECODER) += exr.o exrdsp.o half2float.o
+OBJS-$(CONFIG_EXR_ENCODER) += exrenc.o float2half.o
OBJS-$(CONFIG_FASTAUDIO_DECODER) += fastaudio.o
OBJS-$(CONFIG_FFV1_DECODER) += ffv1dec.o ffv1.o
OBJS-$(CONFIG_FFV1_ENCODER) += ffv1enc.o ffv1.o
@@ -344,8 +360,8 @@ OBJS-$(CONFIG_FFWAVESYNTH_DECODER) += ffwavesynth.o
OBJS-$(CONFIG_FIC_DECODER) += fic.o
OBJS-$(CONFIG_FITS_DECODER) += fitsdec.o fits.o
OBJS-$(CONFIG_FITS_ENCODER) += fitsenc.o
-OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o
-OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o
+OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flacdsp.o flac.o
+OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flacencdsp.o
OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o
OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o
OBJS-$(CONFIG_FLASHSV2_ENCODER) += flashsv2enc.o
@@ -357,6 +373,7 @@ OBJS-$(CONFIG_FMVC_DECODER) += fmvc.o
OBJS-$(CONFIG_FOURXM_DECODER) += 4xm.o
OBJS-$(CONFIG_FRAPS_DECODER) += fraps.o
OBJS-$(CONFIG_FRWU_DECODER) += frwu.o
+OBJS-$(CONFIG_FTR_DECODER) += ftr.o
OBJS-$(CONFIG_G2M_DECODER) += g2meet.o elsdec.o mjpegdec_common.o
OBJS-$(CONFIG_G723_1_DECODER) += g723_1dec.o g723_1.o \
acelp_vectors.o celp_filters.o celp_math.o
@@ -383,11 +400,12 @@ OBJS-$(CONFIG_H263_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
OBJS-$(CONFIG_H264_DECODER) += h264dec.o h264_cabac.o h264_cavlc.o \
h264_direct.o h264_loopfilter.o \
h264_mb.o h264_picture.o \
- h264_refs.o h264_sei.o \
+ h264_refs.o \
h264_slice.o h264data.o h274.o
OBJS-$(CONFIG_H264_AMF_ENCODER) += amfenc_h264.o
OBJS-$(CONFIG_H264_CUVID_DECODER) += cuviddec.o
OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec.o
+OBJS-$(CONFIG_H264_MEDIACODEC_ENCODER) += mediacodecenc.o
OBJS-$(CONFIG_H264_MF_ENCODER) += mfenc.o mf_utils.o
OBJS-$(CONFIG_H264_MMAL_DECODER) += mmaldec.o
OBJS-$(CONFIG_H264_NVENC_ENCODER) += nvenc_h264.o nvenc.o
@@ -395,7 +413,8 @@ OBJS-$(CONFIG_H264_OMX_ENCODER) += omx.o
OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec.o
OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o
OBJS-$(CONFIG_H264_RKMPP_DECODER) += rkmppdec.o
-OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o h264_levels.o
+OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o h264_levels.o \
+ h2645data.o
OBJS-$(CONFIG_H264_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
OBJS-$(CONFIG_H264_V4L2M2M_DECODER) += v4l2_m2m_dec.o
OBJS-$(CONFIG_H264_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
@@ -403,6 +422,8 @@ OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o
OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o
OBJS-$(CONFIG_HCA_DECODER) += hcadec.o
OBJS-$(CONFIG_HCOM_DECODER) += hcom.o
+OBJS-$(CONFIG_HDR_DECODER) += hdrdec.o
+OBJS-$(CONFIG_HDR_ENCODER) += hdrenc.o
OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \
hevc_cabac.o hevc_refs.o hevcpred.o \
hevcdsp.o hevc_filter.o hevc_data.o \
@@ -410,13 +431,15 @@ OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \
OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o
OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o
OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o
+OBJS-$(CONFIG_HEVC_MEDIACODEC_ENCODER) += mediacodecenc.o
OBJS-$(CONFIG_HEVC_MF_ENCODER) += mfenc.o mf_utils.o
OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o nvenc.o
OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec.o
OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \
hevc_data.o
OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o
-OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level.o
+OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level.o \
+ h2645data.o
OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o
OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
OBJS-$(CONFIG_HEVC_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
@@ -462,10 +485,11 @@ OBJS-$(CONFIG_MACE6_DECODER) += mace.o
OBJS-$(CONFIG_MAGICYUV_DECODER) += magicyuv.o
OBJS-$(CONFIG_MAGICYUV_ENCODER) += magicyuvenc.o
OBJS-$(CONFIG_MDEC_DECODER) += mdec.o mpeg12.o mpeg12data.o
-OBJS-$(CONFIG_METASOUND_DECODER) += metasound.o metasound_data.o \
- twinvq.o
+OBJS-$(CONFIG_MEDIA100_DECODER) += mjpegbdec.o
+OBJS-$(CONFIG_METASOUND_DECODER) += metasound.o twinvq.o
OBJS-$(CONFIG_MICRODVD_DECODER) += microdvddec.o ass.o
OBJS-$(CONFIG_MIMIC_DECODER) += mimic.o
+OBJS-$(CONFIG_MISC4_DECODER) += misc4.o
OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpegdec_common.o
OBJS-$(CONFIG_MJPEG_QSV_DECODER) += qsvdec.o
OBJS-$(CONFIG_MJPEG_ENCODER) += mjpegenc.o mjpegenc_common.o \
@@ -514,7 +538,7 @@ OBJS-$(CONFIG_MPEG2_CUVID_DECODER) += cuviddec.o
OBJS-$(CONFIG_MPEG2_MEDIACODEC_DECODER) += mediacodecdec.o
OBJS-$(CONFIG_MPEG2_VAAPI_ENCODER) += vaapi_encode_mpeg2.o
OBJS-$(CONFIG_MPEG2_V4L2M2M_DECODER) += v4l2_m2m_dec.o
-OBJS-$(CONFIG_MPEG4_DECODER) += xvididct.o
+OBJS-$(CONFIG_MPEG4_DECODER) += mpeg4videodsp.o xvididct.o
OBJS-$(CONFIG_MPEG4_ENCODER) += mpeg4videoenc.o
OBJS-$(CONFIG_MPEG4_CUVID_DECODER) += cuviddec.o
OBJS-$(CONFIG_MPEG4_MEDIACODEC_DECODER) += mediacodecdec.o
@@ -524,11 +548,6 @@ OBJS-$(CONFIG_MPEG4_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
OBJS-$(CONFIG_MPL2_DECODER) += mpl2dec.o ass.o
OBJS-$(CONFIG_MSA1_DECODER) += mss3.o
OBJS-$(CONFIG_MSCC_DECODER) += mscc.o
-OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
-OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
-OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4enc.o msmpeg4.o msmpeg4data.o
-OBJS-$(CONFIG_MSMPEG4V3_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
-OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4enc.o msmpeg4.o msmpeg4data.o
OBJS-$(CONFIG_MSNSIREN_DECODER) += siren.o
OBJS-$(CONFIG_MSP2_DECODER) += msp2dec.o
OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o
@@ -548,13 +567,13 @@ OBJS-$(CONFIG_MXPEG_DECODER) += mxpegdec.o
OBJS-$(CONFIG_NELLYMOSER_DECODER) += nellymoserdec.o nellymoser.o
OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o
OBJS-$(CONFIG_NOTCHLC_DECODER) += notchlc.o
-OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o
+OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o jpegquanttables.o
OBJS-$(CONFIG_ON2AVC_DECODER) += on2avc.o on2avcdata.o
-OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opus.o opus_celt.o opus_rc.o \
+OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opusdec_celt.o opus_celt.o \
opus_pvq.o opus_silk.o opustab.o vorbis_data.o \
- opusdsp.o
-OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opus.o opus_rc.o opustab.o opus_pvq.o \
- opusenc_psy.o vorbis_data.o
+ opusdsp.o opus_parse.o opus_rc.o
+OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opusenc_psy.o opus_celt.o \
+ opus_pvq.o opus_rc.o opustab.o
OBJS-$(CONFIG_PAF_AUDIO_DECODER) += pafaudio.o
OBJS-$(CONFIG_PAF_VIDEO_DECODER) += pafvideo.o
OBJS-$(CONFIG_PAM_DECODER) += pnmdec.o pnm.o
@@ -571,8 +590,8 @@ OBJS-$(CONFIG_PGMYUV_DECODER) += pnmdec.o pnm.o
OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o
OBJS-$(CONFIG_PGSSUB_DECODER) += pgssubdec.o
OBJS-$(CONFIG_PGX_DECODER) += pgxdec.o
-OBJS-$(CONFIG_PHM_DECODER) += pnmdec.o pnm.o
-OBJS-$(CONFIG_PHM_ENCODER) += pnmenc.o
+OBJS-$(CONFIG_PHM_DECODER) += pnmdec.o pnm.o half2float.o
+OBJS-$(CONFIG_PHM_ENCODER) += pnmenc.o float2half.o
OBJS-$(CONFIG_PHOTOCD_DECODER) += photocd.o
OBJS-$(CONFIG_PICTOR_DECODER) += pictordec.o cga_data.o
OBJS-$(CONFIG_PIXLET_DECODER) += pixlet.o
@@ -612,6 +631,7 @@ OBJS-$(CONFIG_RASC_DECODER) += rasc.o
OBJS-$(CONFIG_RAWVIDEO_DECODER) += rawdec.o
OBJS-$(CONFIG_RAWVIDEO_ENCODER) += rawenc.o
OBJS-$(CONFIG_REALTEXT_DECODER) += realtextdec.o ass.o
+OBJS-$(CONFIG_RKA_DECODER) += rka.o
OBJS-$(CONFIG_RL2_DECODER) += rl2.o
OBJS-$(CONFIG_ROQ_DECODER) += roqvideodec.o roqvideo.o
OBJS-$(CONFIG_ROQ_ENCODER) += roqvideoenc.o roqvideo.o elbg.o
@@ -656,7 +676,8 @@ OBJS-$(CONFIG_SOL_DPCM_DECODER) += dpcm.o
OBJS-$(CONFIG_SONIC_DECODER) += sonic.o
OBJS-$(CONFIG_SONIC_ENCODER) += sonic.o
OBJS-$(CONFIG_SONIC_LS_ENCODER) += sonic.o
-OBJS-$(CONFIG_SPEEDHQ_DECODER) += speedhq.o mpeg12.o mpeg12data.o simple_idct.o
+OBJS-$(CONFIG_SPEEDHQ_DECODER) += speedhqdec.o speedhq.o mpeg12.o \
+ mpeg12data.o
OBJS-$(CONFIG_SPEEDHQ_ENCODER) += speedhq.o mpeg12data.o mpeg12enc.o speedhqenc.o
OBJS-$(CONFIG_SPEEX_DECODER) += speexdec.o
OBJS-$(CONFIG_SP5X_DECODER) += sp5xdec.o
@@ -699,7 +720,7 @@ OBJS-$(CONFIG_TSCC2_DECODER) += tscc2.o
OBJS-$(CONFIG_TTA_DECODER) += tta.o ttadata.o ttadsp.o
OBJS-$(CONFIG_TTA_ENCODER) += ttaenc.o ttaencdsp.o ttadata.o
OBJS-$(CONFIG_TTML_ENCODER) += ttmlenc.o ass_split.o
-OBJS-$(CONFIG_TWINVQ_DECODER) += twinvqdec.o twinvq.o metasound_data.o
+OBJS-$(CONFIG_TWINVQ_DECODER) += twinvqdec.o twinvq.o
OBJS-$(CONFIG_TXD_DECODER) += txd.o
OBJS-$(CONFIG_ULTI_DECODER) += ulti.o
OBJS-$(CONFIG_UTVIDEO_DECODER) += utvideodec.o utvideodsp.o
@@ -719,8 +740,7 @@ OBJS-$(CONFIG_VBN_ENCODER) += vbnenc.o
OBJS-$(CONFIG_VBLE_DECODER) += vble.o
OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1_block.o vc1_loopfilter.o \
vc1_mc.o vc1_pred.o vc1.o vc1data.o \
- msmpeg4dec.o msmpeg4.o msmpeg4data.o \
- wmv2dsp.o wmv2data.o
+ msmpeg4_vc1_data.o wmv2data.o
OBJS-$(CONFIG_VC1_CUVID_DECODER) += cuviddec.o
OBJS-$(CONFIG_VC1_MMAL_DECODER) += mmaldec.o
OBJS-$(CONFIG_VC1_QSV_DECODER) += qsvdec.o
@@ -730,16 +750,18 @@ OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o
OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdaudio.o
OBJS-$(CONFIG_VMDVIDEO_DECODER) += vmdvideo.o
OBJS-$(CONFIG_VMNC_DECODER) += vmnc.o
+OBJS-$(CONFIG_VNULL_DECODER) += null.o
+OBJS-$(CONFIG_VNULL_ENCODER) += null.o
OBJS-$(CONFIG_VORBIS_DECODER) += vorbisdec.o vorbisdsp.o vorbis.o \
vorbis_data.o
OBJS-$(CONFIG_VORBIS_ENCODER) += vorbisenc.o vorbis.o \
vorbis_data.o
-OBJS-$(CONFIG_VP3_DECODER) += vp3.o
-OBJS-$(CONFIG_VP5_DECODER) += vp5.o vp56.o vp56data.o vp56rac.o
+OBJS-$(CONFIG_VP3_DECODER) += vp3.o jpegquanttables.o
+OBJS-$(CONFIG_VP5_DECODER) += vp5.o vp56.o vp56data.o vpx_rac.o
OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o \
- vp6dsp.o vp56rac.o
-OBJS-$(CONFIG_VP7_DECODER) += vp8.o vp56rac.o
-OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp56rac.o
+ vp6dsp.o vpx_rac.o
+OBJS-$(CONFIG_VP7_DECODER) += vp8.o vpx_rac.o
+OBJS-$(CONFIG_VP8_DECODER) += vp8.o vpx_rac.o
OBJS-$(CONFIG_VP8_CUVID_DECODER) += cuviddec.o
OBJS-$(CONFIG_VP8_MEDIACODEC_DECODER) += mediacodecdec.o
OBJS-$(CONFIG_VP8_QSV_DECODER) += qsvdec.o
@@ -748,7 +770,7 @@ OBJS-$(CONFIG_VP8_VAAPI_ENCODER) += vaapi_encode_vp8.o
OBJS-$(CONFIG_VP8_V4L2M2M_DECODER) += v4l2_m2m_dec.o
OBJS-$(CONFIG_VP8_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o vp9lpf.o vp9recon.o \
- vp9block.o vp9prob.o vp9mvs.o vp56rac.o \
+ vp9block.o vp9prob.o vp9mvs.o vpx_rac.o \
vp9dsp_8bpp.o vp9dsp_10bpp.o vp9dsp_12bpp.o
OBJS-$(CONFIG_VP9_CUVID_DECODER) += cuviddec.o
OBJS-$(CONFIG_VP9_MEDIACODEC_DECODER) += mediacodecdec.o
@@ -758,8 +780,13 @@ OBJS-$(CONFIG_VP9_QSV_ENCODER) += qsvenc_vp9.o
OBJS-$(CONFIG_VPLAYER_DECODER) += textdec.o ass.o
OBJS-$(CONFIG_VP9_V4L2M2M_DECODER) += v4l2_m2m_dec.o
OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o
+OBJS-$(CONFIG_VQC_DECODER) += vqcdec.o
+OBJS-$(CONFIG_WADY_DPCM_DECODER) += dpcm.o
+OBJS-$(CONFIG_WAVARC_DECODER) += wavarc.o
OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o wavpackdata.o dsd.o
OBJS-$(CONFIG_WAVPACK_ENCODER) += wavpackdata.o wavpackenc.o
+OBJS-$(CONFIG_WBMP_DECODER) += wbmpdec.o
+OBJS-$(CONFIG_WBMP_ENCODER) += wbmpenc.o
OBJS-$(CONFIG_WCMV_DECODER) += wcmv.o
OBJS-$(CONFIG_WEBP_DECODER) += webp.o
OBJS-$(CONFIG_WEBVTT_DECODER) += webvttdec.o ass.o
@@ -773,12 +800,8 @@ OBJS-$(CONFIG_WMAV2_ENCODER) += wmaenc.o wma.o wma_common.o aactab.o
OBJS-$(CONFIG_WMAVOICE_DECODER) += wmavoice.o \
celp_filters.o \
acelp_vectors.o acelp_filters.o
-OBJS-$(CONFIG_WMV1_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
-OBJS-$(CONFIG_WMV1_ENCODER) += msmpeg4enc.o msmpeg4.o msmpeg4data.o
-OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o wmv2data.o \
- msmpeg4dec.o msmpeg4.o msmpeg4data.o
-OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o wmv2data.o \
- msmpeg4.o msmpeg4enc.o msmpeg4data.o
+OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o wmv2data.o
+OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o wmv2data.o
OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o
OBJS-$(CONFIG_WRAPPED_AVFRAME_DECODER) += wrapped_avframe.o
OBJS-$(CONFIG_WRAPPED_AVFRAME_ENCODER) += wrapped_avframe.o
@@ -942,6 +965,7 @@ OBJS-$(CONFIG_ADPCM_THP_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_THP_LE_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_VIMA_DECODER) += vima.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_XA_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_XMD_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_ZORK_DECODER) += adpcm.o adpcm_data.o
@@ -1052,8 +1076,8 @@ OBJS-$(CONFIG_ALAC_AT_ENCODER) += audiotoolboxenc.o
OBJS-$(CONFIG_ILBC_AT_ENCODER) += audiotoolboxenc.o
OBJS-$(CONFIG_PCM_ALAW_AT_ENCODER) += audiotoolboxenc.o
OBJS-$(CONFIG_PCM_MULAW_AT_ENCODER) += audiotoolboxenc.o
-OBJS-$(CONFIG_LIBAOM_AV1_DECODER) += libaomdec.o
-OBJS-$(CONFIG_LIBAOM_AV1_ENCODER) += libaomenc.o
+OBJS-$(CONFIG_LIBAOM_AV1_DECODER) += libaomdec.o libaom.o
+OBJS-$(CONFIG_LIBAOM_AV1_ENCODER) += libaomenc.o libaom.o
OBJS-$(CONFIG_LIBARIBB24_DECODER) += libaribb24.o ass.o
OBJS-$(CONFIG_LIBCELT_DECODER) += libcelt_dec.o
OBJS-$(CONFIG_LIBCODEC2_DECODER) += libcodec2.o
@@ -1114,7 +1138,7 @@ OBJS-$(CONFIG_AAC_LATM_PARSER) += latm_parser.o
OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o
OBJS-$(CONFIG_AC3_PARSER) += aac_ac3_parser.o ac3tab.o \
ac3_channel_layout_tab.o
-OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o
+OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o
OBJS-$(CONFIG_AMR_PARSER) += amr_parser.o
OBJS-$(CONFIG_AV1_PARSER) += av1_parser.o
OBJS-$(CONFIG_AVS2_PARSER) += avs2.o avs2_parser.o
@@ -1134,16 +1158,19 @@ OBJS-$(CONFIG_DVBSUB_PARSER) += dvbsub_parser.o
OBJS-$(CONFIG_DVD_NAV_PARSER) += dvd_nav_parser.o
OBJS-$(CONFIG_DVDSUB_PARSER) += dvdsub_parser.o
OBJS-$(CONFIG_FLAC_PARSER) += flac_parser.o flacdata.o flac.o
+OBJS-$(CONFIG_FTR_PARSER) += ftr_parser.o
OBJS-$(CONFIG_G723_1_PARSER) += g723_1_parser.o
OBJS-$(CONFIG_G729_PARSER) += g729_parser.o
OBJS-$(CONFIG_GIF_PARSER) += gif_parser.o
OBJS-$(CONFIG_GSM_PARSER) += gsm_parser.o
OBJS-$(CONFIG_H261_PARSER) += h261_parser.o
OBJS-$(CONFIG_H263_PARSER) += h263_parser.o
-OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264_sei.o h264data.o
+OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264data.o
OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o hevc_data.o
+OBJS-$(CONFIG_HDR_PARSER) += hdr_parser.o
OBJS-$(CONFIG_IPU_PARSER) += ipu_parser.o
OBJS-$(CONFIG_JPEG2000_PARSER) += jpeg2000_parser.o
+OBJS-$(CONFIG_MISC4_PARSER) += misc4_parser.o
OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg_parser.o
OBJS-$(CONFIG_MLP_PARSER) += mlp_parse.o mlp_parser.o mlp.o
OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \
@@ -1152,8 +1179,8 @@ OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \
OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o
OBJS-$(CONFIG_MPEGVIDEO_PARSER) += mpegvideo_parser.o \
mpeg12.o mpeg12data.o
-OBJS-$(CONFIG_OPUS_PARSER) += opus_parser.o opus.o opustab.o \
- opus_rc.o vorbis_data.o
+OBJS-$(CONFIG_OPUS_PARSER) += opus_parser.o opus_parse.o \
+ vorbis_data.o
OBJS-$(CONFIG_PNG_PARSER) += png_parser.o
OBJS-$(CONFIG_PNM_PARSER) += pnm_parser.o pnm.o
OBJS-$(CONFIG_QOI_PARSER) += qoi_parser.o
@@ -1163,13 +1190,14 @@ OBJS-$(CONFIG_SBC_PARSER) += sbc_parser.o
OBJS-$(CONFIG_SIPR_PARSER) += sipr_parser.o
OBJS-$(CONFIG_TAK_PARSER) += tak_parser.o tak.o
OBJS-$(CONFIG_VC1_PARSER) += vc1_parser.o vc1.o vc1data.o \
- simple_idct.o wmv2data.o
+ wmv2data.o
OBJS-$(CONFIG_VP3_PARSER) += vp3_parser.o
OBJS-$(CONFIG_VP8_PARSER) += vp8_parser.o
OBJS-$(CONFIG_VP9_PARSER) += vp9_parser.o
OBJS-$(CONFIG_WEBP_PARSER) += webp_parser.o
OBJS-$(CONFIG_XBM_PARSER) += xbm_parser.o
OBJS-$(CONFIG_XMA_PARSER) += xma_parser.o
+OBJS-$(CONFIG_XWD_PARSER) += xwd_parser.o
# bitstream filters
OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o
@@ -1179,18 +1207,22 @@ OBJS-$(CONFIG_AV1_FRAME_SPLIT_BSF) += av1_frame_split_bsf.o
OBJS-$(CONFIG_CHOMP_BSF) += chomp_bsf.o
OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o
OBJS-$(CONFIG_DCA_CORE_BSF) += dca_core_bsf.o
+OBJS-$(CONFIG_DTS2PTS_BSF) += dts2pts_bsf.o
OBJS-$(CONFIG_DV_ERROR_MARKER_BSF) += dv_error_marker_bsf.o
OBJS-$(CONFIG_EAC3_CORE_BSF) += eac3_core_bsf.o
OBJS-$(CONFIG_EXTRACT_EXTRADATA_BSF) += extract_extradata_bsf.o \
av1_parse.o h2645_parse.o
OBJS-$(CONFIG_FILTER_UNITS_BSF) += filter_units_bsf.o
-OBJS-$(CONFIG_H264_METADATA_BSF) += h264_metadata_bsf.o h264_levels.o
+OBJS-$(CONFIG_H264_METADATA_BSF) += h264_metadata_bsf.o h264_levels.o \
+ h2645data.o
OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += h264_mp4toannexb_bsf.o
OBJS-$(CONFIG_H264_REDUNDANT_PPS_BSF) += h264_redundant_pps_bsf.o
OBJS-$(CONFIG_HAPQA_EXTRACT_BSF) += hapqa_extract_bsf.o hap.o
-OBJS-$(CONFIG_HEVC_METADATA_BSF) += h265_metadata_bsf.o h265_profile_level.o
+OBJS-$(CONFIG_HEVC_METADATA_BSF) += h265_metadata_bsf.o h265_profile_level.o \
+ h2645data.o
OBJS-$(CONFIG_HEVC_MP4TOANNEXB_BSF) += hevc_mp4toannexb_bsf.o
OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o
+OBJS-$(CONFIG_MEDIA100_TO_MJPEGB_BSF) += media100_to_mjpegb_bsf.o
OBJS-$(CONFIG_MJPEG2JPEG_BSF) += mjpeg2jpeg_bsf.o
OBJS-$(CONFIG_MJPEGA_DUMP_HEADER_BSF) += mjpega_dump_header_bsf.o
OBJS-$(CONFIG_MPEG4_UNPACK_BFRAMES_BSF) += mpeg4_unpack_bframes_bsf.o
@@ -1221,7 +1253,7 @@ OBJS-$(HAVE_THREADS) += pthread.o pthread_slice.o pthread_fram
OBJS-$(CONFIG_FRAME_THREAD_ENCODER) += frame_thread_encoder.o
# Windows resource file
-SLIBOBJS-$(HAVE_GNU_WINDRES) += avcodecres.o
+SHLIBOBJS-$(HAVE_GNU_WINDRES) += avcodecres.o
SKIPHEADERS += %_tablegen.h \
%_tables.h \
@@ -1231,12 +1263,15 @@ SKIPHEADERS += %_tablegen.h \
aaccoder_trellis.h \
aacenc_quantization.h \
aacenc_quantization_misc.h \
- $(ARCH)/vp56_arith.h \
+ bitstream_template.h \
+ $(ARCH)/vpx_arith.h \
SKIPHEADERS-$(CONFIG_AMF) += amfenc.h
SKIPHEADERS-$(CONFIG_D3D11VA) += d3d11va.h dxva2_internal.h
SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h
SKIPHEADERS-$(CONFIG_JNI) += ffjni.h
+SKIPHEADERS-$(CONFIG_LCMS2) += fflcms2.h
+SKIPHEADERS-$(CONFIG_LIBAOM) += libaom.h
SKIPHEADERS-$(CONFIG_LIBJXL) += libjxl.h
SKIPHEADERS-$(CONFIG_LIBVPX) += libvpx.h
SKIPHEADERS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.h
@@ -1251,9 +1286,12 @@ SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_decode.h vaapi_hevc.h vaapi_enco
SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h
SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.h vt_internal.h
SKIPHEADERS-$(CONFIG_V4L2_M2M) += v4l2_buffers.h v4l2_context.h v4l2_m2m.h
+SKIPHEADERS-$(CONFIG_ZLIB) += zlib_wrapper.h
TESTPROGS = avcodec \
avpacket \
+ bitstream_be \
+ bitstream_le \
celp_math \
codec_desc \
htmlsubtitles \
diff --git a/libavcodec/a64multienc.c b/libavcodec/a64multienc.c
index e80139ee5..26a9debc2 100644
--- a/libavcodec/a64multienc.c
+++ b/libavcodec/a64multienc.c
@@ -76,7 +76,7 @@ static void to_meta_with_crop(AVCodecContext *avctx,
int luma = 0;
int height = FFMIN(avctx->height, C64YRES);
int width = FFMIN(avctx->width , C64XRES);
- uint8_t *src = p->data[0];
+ const uint8_t *src = p->data[0];
for (blocky = 0; blocky < C64YRES; blocky += 8) {
for (blockx = 0; blockx < C64XRES; blockx += 8) {
@@ -395,7 +395,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
#if CONFIG_A64MULTI_ENCODER
const FFCodec ff_a64multi_encoder = {
.p.name = "a64multi",
- .p.long_name = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64"),
+ CODEC_LONG_NAME("Multicolor charset for Commodore 64"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_A64_MULTI,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
@@ -404,13 +404,13 @@ const FFCodec ff_a64multi_encoder = {
FF_CODEC_ENCODE_CB(a64multi_encode_frame),
.close = a64multi_close_encoder,
.p.pix_fmts = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
- .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
#endif
#if CONFIG_A64MULTI5_ENCODER
const FFCodec ff_a64multi5_encoder = {
.p.name = "a64multi5",
- .p.long_name = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64, extended with 5th color (colram)"),
+ CODEC_LONG_NAME("Multicolor charset for Commodore 64, extended with 5th color (colram)"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_A64_MULTI5,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
@@ -419,6 +419,6 @@ const FFCodec ff_a64multi5_encoder = {
FF_CODEC_ENCODE_CB(a64multi_encode_frame),
.close = a64multi_close_encoder,
.p.pix_fmts = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
- .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
#endif
diff --git a/libavcodec/aac.h b/libavcodec/aac.h
index 53be54685..285d3b748 100644
--- a/libavcodec/aac.h
+++ b/libavcodec/aac.h
@@ -36,11 +36,8 @@
#include "libavutil/float_dsp.h"
#include "libavutil/fixed_dsp.h"
#include "libavutil/mem_internal.h"
+#include "libavutil/tx.h"
#include "avcodec.h"
-#if !USE_FIXED
-#include "mdct15.h"
-#endif
-#include "fft.h"
#include "mpeg4audio.h"
#include "sbr.h"
@@ -326,16 +323,24 @@ struct AACContext {
* @name Computed / set up during initialization
* @{
*/
- FFTContext mdct;
- FFTContext mdct_small;
- FFTContext mdct_ld;
- FFTContext mdct_ltp;
+ AVTXContext *mdct120;
+ AVTXContext *mdct128;
+ AVTXContext *mdct480;
+ AVTXContext *mdct512;
+ AVTXContext *mdct960;
+ AVTXContext *mdct1024;
+ AVTXContext *mdct_ltp;
+
+ av_tx_fn mdct120_fn;
+ av_tx_fn mdct128_fn;
+ av_tx_fn mdct480_fn;
+ av_tx_fn mdct512_fn;
+ av_tx_fn mdct960_fn;
+ av_tx_fn mdct1024_fn;
+ av_tx_fn mdct_ltp_fn;
#if USE_FIXED
AVFixedDSPContext *fdsp;
#else
- MDCT15Context *mdct120;
- MDCT15Context *mdct480;
- MDCT15Context *mdct960;
AVFloatDSPContext *fdsp;
#endif /* USE_FIXED */
int random_state;
@@ -366,6 +371,7 @@ struct AACContext {
int warned_960_sbr;
unsigned warned_71_wide;
int warned_gain_control;
+ int warned_he_aac_mono;
/* aacdec functions pointers */
void (*imdct_and_windowing)(AACContext *ac, SingleChannelElement *sce);
diff --git a/libavcodec/aac_ac3_parser.c b/libavcodec/aac_ac3_parser.c
index b14b1e31f..9ab979632 100644
--- a/libavcodec/aac_ac3_parser.c
+++ b/libavcodec/aac_ac3_parser.c
@@ -26,6 +26,8 @@
#include "libavutil/common.h"
#include "parser.h"
#include "aac_ac3_parser.h"
+#include "ac3_parser_internal.h"
+#include "adts_header.h"
int ff_aac_ac3_parse(AVCodecParserContext *s1,
AVCodecContext *avctx,
@@ -38,83 +40,127 @@ int ff_aac_ac3_parse(AVCodecParserContext *s1,
int new_frame_start;
int got_frame = 0;
+ if (s1->flags & PARSER_FLAG_COMPLETE_FRAMES) {
+ i = buf_size;
+ got_frame = 1;
+ } else {
get_next:
- i=END_NOT_FOUND;
- if(s->remaining_size <= buf_size){
- if(s->remaining_size && !s->need_next_header){
- i= s->remaining_size;
- s->remaining_size = 0;
- }else{ //we need a header first
- len=0;
- for(i=s->remaining_size; istate = (s->state<<8) + buf[i];
- if((len=s->sync(s->state, s, &s->need_next_header, &new_frame_start)))
- break;
- }
- if(len<=0){
- i=END_NOT_FOUND;
- }else{
- got_frame = 1;
- s->state=0;
- i-= s->header_size -1;
- s->remaining_size = len;
- if(!new_frame_start || pc->index+i<=0){
- s->remaining_size += i;
- goto get_next;
+ i=END_NOT_FOUND;
+ if(s->remaining_size <= buf_size){
+ if(s->remaining_size && !s->need_next_header){
+ i= s->remaining_size;
+ s->remaining_size = 0;
+ }else{ //we need a header first
+ len=0;
+ for(i=s->remaining_size; istate = (s->state<<8) + buf[i];
+ if((len=s->sync(s->state, &s->need_next_header, &new_frame_start)))
+ break;
}
- else if (i < 0) {
- s->remaining_size += i;
+ if(len<=0){
+ i=END_NOT_FOUND;
+ }else{
+ got_frame = 1;
+ s->state=0;
+ i-= s->header_size -1;
+ s->remaining_size = len;
+ if(!new_frame_start || pc->index+i<=0){
+ s->remaining_size += i;
+ goto get_next;
+ }
+ else if (i < 0) {
+ s->remaining_size += i;
+ }
}
}
}
- }
- if(ff_combine_frame(pc, i, &buf, &buf_size)<0){
- s->remaining_size -= FFMIN(s->remaining_size, buf_size);
- *poutbuf = NULL;
- *poutbuf_size = 0;
- return buf_size;
+ if(ff_combine_frame(pc, i, &buf, &buf_size)<0){
+ s->remaining_size -= FFMIN(s->remaining_size, buf_size);
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
}
*poutbuf = buf;
*poutbuf_size = buf_size;
- /* update codec info */
- if(s->codec_id)
- avctx->codec_id = s->codec_id;
-
if (got_frame) {
+ int bit_rate;
+
/* Due to backwards compatible HE-AAC the sample rate, channel count,
and total number of samples found in an AAC ADTS header are not
reliable. Bit rate is still accurate because the total frame
duration in seconds is still correct (as is the number of bits in
the frame). */
if (avctx->codec_id != AV_CODEC_ID_AAC) {
- avctx->sample_rate = s->sample_rate;
+ AC3HeaderInfo hdr, *phrd = &hdr;
+ int offset = ff_ac3_find_syncword(buf, buf_size);
+
+ if (offset < 0)
+ return i;
+
+ buf += offset;
+ buf_size -= offset;
+ while (buf_size > 0) {
+ int ret = avpriv_ac3_parse_header(&phrd, buf, buf_size);
+
+ if (ret < 0 || hdr.frame_size > buf_size)
+ return i;
+
+ if (buf_size > hdr.frame_size) {
+ buf += hdr.frame_size;
+ buf_size -= hdr.frame_size;
+ continue;
+ }
+ /* Check for false positives since the syncword is not enough.
+ See section 6.1.2 of A/52. */
+ if (av_crc(s->crc_ctx, 0, buf + 2, hdr.frame_size - 2))
+ return i;
+ break;
+ }
+
+ avctx->sample_rate = hdr.sample_rate;
+
+ if (hdr.bitstream_id > 10)
+ avctx->codec_id = AV_CODEC_ID_EAC3;
+
if (!CONFIG_EAC3_DECODER || avctx->codec_id != AV_CODEC_ID_EAC3) {
av_channel_layout_uninit(&avctx->ch_layout);
- if (s->channel_layout) {
- av_channel_layout_from_mask(&avctx->ch_layout, s->channel_layout);
+ if (hdr.channel_layout) {
+ av_channel_layout_from_mask(&avctx->ch_layout, hdr.channel_layout);
} else {
avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
- avctx->ch_layout.nb_channels = s->channels;
+ avctx->ch_layout.nb_channels = hdr.channels;
}
#if FF_API_OLD_CHANNEL_LAYOUT
FF_DISABLE_DEPRECATION_WARNINGS
avctx->channels = avctx->ch_layout.nb_channels;
- avctx->channel_layout = s->channel_layout;
+ avctx->channel_layout = hdr.channel_layout;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
}
- s1->duration = s->samples;
- avctx->audio_service_type = s->service_type;
+ s1->duration = hdr.num_blocks * 256;
+ avctx->audio_service_type = hdr.bitstream_mode;
+ if (hdr.bitstream_mode == 0x7 && hdr.channels > 1)
+ avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
+ bit_rate = hdr.bit_rate;
+ } else {
+ AACADTSHeaderInfo hdr, *phrd = &hdr;
+ int ret = avpriv_adts_header_parse(&phrd, buf, buf_size);
+
+ if (ret < 0)
+ return i;
+
+ bit_rate = hdr.bit_rate;
}
/* Calculate the average bit rate */
s->frame_number++;
if (!CONFIG_EAC3_DECODER || avctx->codec_id != AV_CODEC_ID_EAC3) {
avctx->bit_rate +=
- (s->bit_rate - avctx->bit_rate) / s->frame_number;
+ (bit_rate - avctx->bit_rate) / s->frame_number;
}
}
diff --git a/libavcodec/aac_ac3_parser.h b/libavcodec/aac_ac3_parser.h
index 8b93cbf84..bc16181a1 100644
--- a/libavcodec/aac_ac3_parser.h
+++ b/libavcodec/aac_ac3_parser.h
@@ -24,6 +24,7 @@
#define AVCODEC_AAC_AC3_PARSER_H
#include
+#include "libavutil/crc.h"
#include "avcodec.h"
#include "parser.h"
@@ -39,24 +40,15 @@ typedef enum {
typedef struct AACAC3ParseContext {
ParseContext pc;
- int frame_size;
int header_size;
- int (*sync)(uint64_t state, struct AACAC3ParseContext *hdr_info,
- int *need_next_header, int *new_frame_start);
-
- int channels;
- int sample_rate;
- int bit_rate;
- int samples;
- uint64_t channel_layout;
- int service_type;
+ int (*sync)(uint64_t state, int *need_next_header, int *new_frame_start);
+ const AVCRC *crc_ctx;
int remaining_size;
uint64_t state;
int need_next_header;
int frame_number;
- enum AVCodecID codec_id;
} AACAC3ParseContext;
int ff_aac_ac3_parse(AVCodecParserContext *s1,
diff --git a/libavcodec/aac_adtstoasc_bsf.c b/libavcodec/aac_adtstoasc_bsf.c
index d32fcc5f9..dd5e8b2a3 100644
--- a/libavcodec/aac_adtstoasc_bsf.c
+++ b/libavcodec/aac_adtstoasc_bsf.c
@@ -26,6 +26,7 @@
#include "put_bits.h"
#include "get_bits.h"
#include "mpeg4audio.h"
+#include "mpeg4audio_copy_pce.h"
typedef struct AACBSFContext {
int first_frame_done;
diff --git a/libavcodec/aac_defines.h b/libavcodec/aac_defines.h
index a3c680b65..bd0d93275 100644
--- a/libavcodec/aac_defines.h
+++ b/libavcodec/aac_defines.h
@@ -29,8 +29,6 @@
#include "libavutil/softfloat.h"
-#define FFT_FLOAT 0
-
#define AAC_RENAME(x) x ## _fixed
#define AAC_RENAME_32(x) x ## _fixed_32
#define AAC_RENAME2(x) x ## _fixed
@@ -45,7 +43,7 @@ typedef int AAC_SIGNE;
#define Q23(a) (int)((a) * 8388608.0 + 0.5)
#define Q30(x) (int)((x)*1073741824.0 + 0.5)
#define Q31(x) (int)((x)*2147483648.0 + 0.5)
-#define RANGE15(x) x
+#define TX_SCALE(x) ((x) * 128.0f)
#define GET_GAIN(x, y) (-(y) * (1 << (x))) + 1024
#define AAC_MUL16(x, y) (int)(((int64_t)(x) * (y) + 0x8000) >> 16)
#define AAC_MUL26(x, y) (int)(((int64_t)(x) * (y) + 0x2000000) >> 26)
@@ -78,8 +76,6 @@ typedef int AAC_SIGNE;
#else
-#define FFT_FLOAT 1
-
#define AAC_RENAME(x) x
#define AAC_RENAME_32(x) x
#define AAC_RENAME2(x) ff_ ## x
@@ -94,7 +90,7 @@ typedef unsigned AAC_SIGNE;
#define Q23(x) ((float)(x))
#define Q30(x) ((float)(x))
#define Q31(x) ((float)(x))
-#define RANGE15(x) (32768.0 * (x))
+#define TX_SCALE(x) ((x) / 32768.0f)
#define GET_GAIN(x, y) powf((x), -(y))
#define AAC_MUL16(x, y) ((x) * (y))
#define AAC_MUL26(x, y) ((x) * (y))
diff --git a/libavcodec/aac_parser.c b/libavcodec/aac_parser.c
index f3baf7cde..f295dfccd 100644
--- a/libavcodec/aac_parser.c
+++ b/libavcodec/aac_parser.c
@@ -27,8 +27,7 @@
#include "get_bits.h"
#include "mpeg4audio.h"
-static int aac_sync(uint64_t state, AACAC3ParseContext *hdr_info,
- int *need_next_header, int *new_frame_start)
+static int aac_sync(uint64_t state, int *need_next_header, int *new_frame_start)
{
GetBitContext bits;
AACADTSHeaderInfo hdr;
@@ -46,10 +45,6 @@ static int aac_sync(uint64_t state, AACAC3ParseContext *hdr_info,
return 0;
*need_next_header = 0;
*new_frame_start = 1;
- hdr_info->sample_rate = hdr.sample_rate;
- hdr_info->channels = ff_mpeg4audio_channels[hdr.chan_config];
- hdr_info->samples = hdr.samples;
- hdr_info->bit_rate = hdr.bit_rate;
return size;
}
diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c
index f46047949..6291c1612 100644
--- a/libavcodec/aaccoder.c
+++ b/libavcodec/aaccoder.c
@@ -62,6 +62,229 @@
#include "libavcodec/aaccoder_trellis.h"
+typedef float (*quantize_and_encode_band_func)(struct AACEncContext *s, PutBitContext *pb,
+ const float *in, float *quant, const float *scaled,
+ int size, int scale_idx, int cb,
+ const float lambda, const float uplim,
+ int *bits, float *energy);
+
+/**
+ * Calculate rate distortion cost for quantizing with given codebook
+ *
+ * @return quantization distortion
+ */
+static av_always_inline float quantize_and_encode_band_cost_template(
+ struct AACEncContext *s,
+ PutBitContext *pb, const float *in, float *out,
+ const float *scaled, int size, int scale_idx,
+ int cb, const float lambda, const float uplim,
+ int *bits, float *energy, int BT_ZERO, int BT_UNSIGNED,
+ int BT_PAIR, int BT_ESC, int BT_NOISE, int BT_STEREO,
+ const float ROUNDING)
+{
+ const int q_idx = POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512;
+ const float Q = ff_aac_pow2sf_tab [q_idx];
+ const float Q34 = ff_aac_pow34sf_tab[q_idx];
+ const float IQ = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
+ const float CLIPPED_ESCAPE = 165140.0f*IQ;
+ float cost = 0;
+ float qenergy = 0;
+ const int dim = BT_PAIR ? 2 : 4;
+ int resbits = 0;
+ int off;
+
+ if (BT_ZERO || BT_NOISE || BT_STEREO) {
+ for (int i = 0; i < size; i++)
+ cost += in[i]*in[i];
+ if (bits)
+ *bits = 0;
+ if (energy)
+ *energy = qenergy;
+ if (out) {
+ for (int i = 0; i < size; i += dim)
+ for (int j = 0; j < dim; j++)
+ out[i+j] = 0.0f;
+ }
+ return cost * lambda;
+ }
+ if (!scaled) {
+ s->abs_pow34(s->scoefs, in, size);
+ scaled = s->scoefs;
+ }
+ s->quant_bands(s->qcoefs, in, scaled, size, !BT_UNSIGNED, aac_cb_maxval[cb], Q34, ROUNDING);
+ if (BT_UNSIGNED) {
+ off = 0;
+ } else {
+ off = aac_cb_maxval[cb];
+ }
+ for (int i = 0; i < size; i += dim) {
+ const float *vec;
+ int *quants = s->qcoefs + i;
+ int curidx = 0;
+ int curbits;
+ float quantized, rd = 0.0f;
+ for (int j = 0; j < dim; j++) {
+ curidx *= aac_cb_range[cb];
+ curidx += quants[j] + off;
+ }
+ curbits = ff_aac_spectral_bits[cb-1][curidx];
+ vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
+ if (BT_UNSIGNED) {
+ for (int j = 0; j < dim; j++) {
+ float t = fabsf(in[i+j]);
+ float di;
+ if (BT_ESC && vec[j] == 64.0f) { //FIXME: slow
+ if (t >= CLIPPED_ESCAPE) {
+ quantized = CLIPPED_ESCAPE;
+ curbits += 21;
+ } else {
+ int c = av_clip_uintp2(quant(t, Q, ROUNDING), 13);
+ quantized = c*cbrtf(c)*IQ;
+ curbits += av_log2(c)*2 - 4 + 1;
+ }
+ } else {
+ quantized = vec[j]*IQ;
+ }
+ di = t - quantized;
+ if (out)
+ out[i+j] = in[i+j] >= 0 ? quantized : -quantized;
+ if (vec[j] != 0.0f)
+ curbits++;
+ qenergy += quantized*quantized;
+ rd += di*di;
+ }
+ } else {
+ for (int j = 0; j < dim; j++) {
+ quantized = vec[j]*IQ;
+ qenergy += quantized*quantized;
+ if (out)
+ out[i+j] = quantized;
+ rd += (in[i+j] - quantized)*(in[i+j] - quantized);
+ }
+ }
+ cost += rd * lambda + curbits;
+ resbits += curbits;
+ if (cost >= uplim)
+ return uplim;
+ if (pb) {
+ put_bits(pb, ff_aac_spectral_bits[cb-1][curidx], ff_aac_spectral_codes[cb-1][curidx]);
+ if (BT_UNSIGNED)
+ for (int j = 0; j < dim; j++)
+ if (ff_aac_codebook_vectors[cb-1][curidx*dim+j] != 0.0f)
+ put_bits(pb, 1, in[i+j] < 0.0f);
+ if (BT_ESC) {
+ for (int j = 0; j < 2; j++) {
+ if (ff_aac_codebook_vectors[cb-1][curidx*2+j] == 64.0f) {
+ int coef = av_clip_uintp2(quant(fabsf(in[i+j]), Q, ROUNDING), 13);
+ int len = av_log2(coef);
+
+ put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
+ put_sbits(pb, len, coef);
+ }
+ }
+ }
+ }
+ }
+
+ if (bits)
+ *bits = resbits;
+ if (energy)
+ *energy = qenergy;
+ return cost;
+}
+
+static inline float quantize_and_encode_band_cost_NONE(struct AACEncContext *s, PutBitContext *pb,
+ const float *in, float *quant, const float *scaled,
+ int size, int scale_idx, int cb,
+ const float lambda, const float uplim,
+ int *bits, float *energy) {
+ av_assert0(0);
+ return 0.0f;
+}
+
+#define QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NAME, BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE, BT_STEREO, ROUNDING) \
+static float quantize_and_encode_band_cost_ ## NAME( \
+ struct AACEncContext *s, \
+ PutBitContext *pb, const float *in, float *quant, \
+ const float *scaled, int size, int scale_idx, \
+ int cb, const float lambda, const float uplim, \
+ int *bits, float *energy) { \
+ return quantize_and_encode_band_cost_template( \
+ s, pb, in, quant, scaled, size, scale_idx, \
+ BT_ESC ? ESC_BT : cb, lambda, uplim, bits, energy, \
+ BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE, BT_STEREO, \
+ ROUNDING); \
+}
+
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ZERO, 1, 0, 0, 0, 0, 0, ROUND_STANDARD)
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SQUAD, 0, 0, 0, 0, 0, 0, ROUND_STANDARD)
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UQUAD, 0, 1, 0, 0, 0, 0, ROUND_STANDARD)
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SPAIR, 0, 0, 1, 0, 0, 0, ROUND_STANDARD)
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UPAIR, 0, 1, 1, 0, 0, 0, ROUND_STANDARD)
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC, 0, 1, 1, 1, 0, 0, ROUND_STANDARD)
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC_RTZ, 0, 1, 1, 1, 0, 0, ROUND_TO_ZERO)
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NOISE, 0, 0, 0, 0, 1, 0, ROUND_STANDARD)
+QUANTIZE_AND_ENCODE_BAND_COST_FUNC(STEREO,0, 0, 0, 0, 0, 1, ROUND_STANDARD)
+
+static const quantize_and_encode_band_func quantize_and_encode_band_cost_arr[] =
+{
+ quantize_and_encode_band_cost_ZERO,
+ quantize_and_encode_band_cost_SQUAD,
+ quantize_and_encode_band_cost_SQUAD,
+ quantize_and_encode_band_cost_UQUAD,
+ quantize_and_encode_band_cost_UQUAD,
+ quantize_and_encode_band_cost_SPAIR,
+ quantize_and_encode_band_cost_SPAIR,
+ quantize_and_encode_band_cost_UPAIR,
+ quantize_and_encode_band_cost_UPAIR,
+ quantize_and_encode_band_cost_UPAIR,
+ quantize_and_encode_band_cost_UPAIR,
+ quantize_and_encode_band_cost_ESC,
+ quantize_and_encode_band_cost_NONE, /* CB 12 doesn't exist */
+ quantize_and_encode_band_cost_NOISE,
+ quantize_and_encode_band_cost_STEREO,
+ quantize_and_encode_band_cost_STEREO,
+};
+
+static const quantize_and_encode_band_func quantize_and_encode_band_cost_rtz_arr[] =
+{
+ quantize_and_encode_band_cost_ZERO,
+ quantize_and_encode_band_cost_SQUAD,
+ quantize_and_encode_band_cost_SQUAD,
+ quantize_and_encode_band_cost_UQUAD,
+ quantize_and_encode_band_cost_UQUAD,
+ quantize_and_encode_band_cost_SPAIR,
+ quantize_and_encode_band_cost_SPAIR,
+ quantize_and_encode_band_cost_UPAIR,
+ quantize_and_encode_band_cost_UPAIR,
+ quantize_and_encode_band_cost_UPAIR,
+ quantize_and_encode_band_cost_UPAIR,
+ quantize_and_encode_band_cost_ESC_RTZ,
+ quantize_and_encode_band_cost_NONE, /* CB 12 doesn't exist */
+ quantize_and_encode_band_cost_NOISE,
+ quantize_and_encode_band_cost_STEREO,
+ quantize_and_encode_band_cost_STEREO,
+};
+
+float ff_quantize_and_encode_band_cost(struct AACEncContext *s, PutBitContext *pb,
+ const float *in, float *quant, const float *scaled,
+ int size, int scale_idx, int cb,
+ const float lambda, const float uplim,
+ int *bits, float *energy)
+{
+ return quantize_and_encode_band_cost_arr[cb](s, pb, in, quant, scaled, size,
+ scale_idx, cb, lambda, uplim,
+ bits, energy);
+}
+
+static inline void quantize_and_encode_band(struct AACEncContext *s, PutBitContext *pb,
+ const float *in, float *out, int size, int scale_idx,
+ int cb, const float lambda, int rtz)
+{
+ (rtz ? quantize_and_encode_band_cost_rtz_arr : quantize_and_encode_band_cost_arr)[cb](s, pb, in, out, NULL, size, scale_idx, cb,
+ lambda, INFINITY, NULL, NULL);
+}
+
/**
* structure used in optimal codebook search
*/
@@ -123,7 +346,7 @@ static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce
rd += quantize_band_cost(s, &sce->coeffs[start + w*128],
&s->scoefs[start + w*128], size,
sce->sf_idx[(win+w)*16+swb], aac_cb_out_map[cb],
- lambda / band->threshold, INFINITY, NULL, NULL, 0);
+ lambda / band->threshold, INFINITY, NULL, NULL);
}
cost_stay_here = path[swb][cb].cost + rd;
cost_get_here = minrd + rd + run_bits + 4;
@@ -346,7 +569,7 @@ static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s,
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
dist += quantize_band_cost(s, coefs + w2*128, s->scoefs + start + w2*128, sce->ics.swb_sizes[g],
- q + q0, cb, lambda / band->threshold, INFINITY, NULL, NULL, 0);
+ q + q0, cb, lambda / band->threshold, INFINITY, NULL, NULL);
}
minrd = FFMIN(minrd, dist);
@@ -658,7 +881,7 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne
sce->ics.swb_sizes[g],
sce->sf_idx[(w+w2)*16+g],
sce->band_alt[(w+w2)*16+g],
- lambda/band->threshold, INFINITY, NULL, NULL, 0);
+ lambda/band->threshold, INFINITY, NULL, NULL);
/* Estimate rd on average as 5 bits for SF, 4 for the CB, plus spread energy * lambda/thr */
dist2 += band->energy/(band->spread*band->spread)*lambda*dist_thresh/band->threshold;
}
@@ -842,25 +1065,25 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe)
sce0->ics.swb_sizes[g],
sce0->sf_idx[w*16+g],
sce0->band_type[w*16+g],
- lambda / (band0->threshold + FLT_MIN), INFINITY, &b1, NULL, 0);
+ lambda / (band0->threshold + FLT_MIN), INFINITY, &b1, NULL);
dist1 += quantize_band_cost(s, &sce1->coeffs[start + (w+w2)*128],
R34,
sce1->ics.swb_sizes[g],
sce1->sf_idx[w*16+g],
sce1->band_type[w*16+g],
- lambda / (band1->threshold + FLT_MIN), INFINITY, &b2, NULL, 0);
+ lambda / (band1->threshold + FLT_MIN), INFINITY, &b2, NULL);
dist2 += quantize_band_cost(s, M,
M34,
sce0->ics.swb_sizes[g],
mididx,
midcb,
- lambda / (minthr + FLT_MIN), INFINITY, &b3, NULL, 0);
+ lambda / (minthr + FLT_MIN), INFINITY, &b3, NULL);
dist2 += quantize_band_cost(s, S,
S34,
sce1->ics.swb_sizes[g],
sididx,
sidcb,
- mslambda / (minthr * bmax + FLT_MIN), INFINITY, &b4, NULL, 0);
+ mslambda / (minthr * bmax + FLT_MIN), INFINITY, &b4, NULL);
B0 += b1+b2;
B1 += b3+b4;
dist1 -= b1+b2;
diff --git a/libavcodec/aaccoder_trellis.h b/libavcodec/aaccoder_trellis.h
index 940ebf029..4810ff320 100644
--- a/libavcodec/aaccoder_trellis.h
+++ b/libavcodec/aaccoder_trellis.h
@@ -127,7 +127,7 @@ static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,
&s->scoefs[start + w*128], size,
sce->sf_idx[win*16+swb],
aac_cb_out_map[cb],
- 0, INFINITY, NULL, NULL, 0);
+ 0, INFINITY, NULL, NULL);
}
cost_stay_here = path[swb][cb].cost + bits;
cost_get_here = minbits + bits + run_bits + 4;
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index 88c128f39..ca31540d3 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -32,16 +32,14 @@
* @author Maxim Gavrilov ( maxim.gavrilov gmail com )
*/
-#define FFT_FLOAT 1
#define USE_FIXED 0
+#define TX_TYPE AV_TX_FLOAT_MDCT
#include "libavutil/float_dsp.h"
#include "libavutil/opt.h"
#include "avcodec.h"
#include "codec_internal.h"
#include "get_bits.h"
-#include "fft.h"
-#include "mdct15.h"
#include "lpc.h"
#include "kbdwin.h"
#include "sinewin.h"
@@ -554,7 +552,7 @@ static av_cold int latm_decode_init(AVCodecContext *avctx)
const FFCodec ff_aac_decoder = {
.p.name = "aac",
- .p.long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
+ CODEC_LONG_NAME("AAC (Advanced Audio Coding)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AAC,
.priv_data_size = sizeof(AACContext),
@@ -565,10 +563,8 @@ const FFCodec ff_aac_decoder = {
AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
},
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = aac_channel_layout,
-#endif
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
+ CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(aac_channel_layout)
.p.ch_layouts = aac_ch_layout,
.flush = flush,
.p.priv_class = &aac_decoder_class,
@@ -582,7 +578,7 @@ const FFCodec ff_aac_decoder = {
*/
const FFCodec ff_aac_latm_decoder = {
.p.name = "aac_latm",
- .p.long_name = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Coding LATM syntax)"),
+ CODEC_LONG_NAME("AAC LATM (Advanced Audio Coding LATM syntax)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AAC_LATM,
.priv_data_size = sizeof(struct LATMContext),
@@ -593,10 +589,8 @@ const FFCodec ff_aac_latm_decoder = {
AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
},
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = aac_channel_layout,
-#endif
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
+ CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(aac_channel_layout)
.p.ch_layouts = aac_ch_layout,
.flush = flush,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
diff --git a/libavcodec/aacdec_fixed.c b/libavcodec/aacdec_fixed.c
index c7ac75024..46f0ebf91 100644
--- a/libavcodec/aacdec_fixed.c
+++ b/libavcodec/aacdec_fixed.c
@@ -58,15 +58,14 @@
* @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com )
*/
-#define FFT_FLOAT 0
#define USE_FIXED 1
+#define TX_TYPE AV_TX_INT32_MDCT
#include "libavutil/fixed_dsp.h"
#include "libavutil/opt.h"
#include "avcodec.h"
#include "codec_internal.h"
#include "get_bits.h"
-#include "fft.h"
#include "lpc.h"
#include "kbdwin.h"
#include "sinewin_fixed_tablegen.h"
@@ -87,6 +86,8 @@
DECLARE_ALIGNED(32, static int, AAC_RENAME2(aac_kbd_long_1024))[1024];
DECLARE_ALIGNED(32, static int, AAC_RENAME2(aac_kbd_short_128))[128];
+DECLARE_ALIGNED(32, static int, AAC_RENAME2(aac_kbd_long_960))[960];
+DECLARE_ALIGNED(32, static int, AAC_RENAME2(aac_kbd_short_120))[120];
static av_always_inline void reset_predict_state(PredictorState *ps)
{
@@ -452,7 +453,7 @@ static void apply_independent_coupling_fixed(AACContext *ac,
const FFCodec ff_aac_fixed_decoder = {
.p.name = "aac_fixed",
- .p.long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
+ CODEC_LONG_NAME("AAC (Advanced Audio Coding)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AAC,
.priv_data_size = sizeof(AACContext),
@@ -463,11 +464,10 @@ const FFCodec ff_aac_fixed_decoder = {
AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_NONE
},
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = aac_channel_layout,
-#endif
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
+ CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(aac_channel_layout)
.p.ch_layouts = aac_ch_layout,
+ .p.priv_class = &aac_decoder_class,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
.flush = flush,
};
diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c
index 10fba3d3b..444dc4fa9 100644
--- a/libavcodec/aacdec_template.c
+++ b/libavcodec/aacdec_template.c
@@ -91,6 +91,7 @@
#include "libavutil/channel_layout.h"
#include "libavutil/thread.h"
+#include "decode.h"
#include "internal.h"
static VLC vlc_scalefactors;
@@ -134,9 +135,12 @@ static av_cold int che_configure(AACContext *ac,
return AVERROR_INVALIDDATA;
if (che_pos) {
if (!ac->che[type][id]) {
+ int ret;
if (!(ac->che[type][id] = av_mallocz(sizeof(ChannelElement))))
return AVERROR(ENOMEM);
- AAC_RENAME(ff_aac_sbr_ctx_init)(ac, &ac->che[type][id]->sbr, type);
+ ret = AAC_RENAME(ff_aac_sbr_ctx_init)(ac, &ac->che[type][id]->sbr, type);
+ if (ret < 0)
+ return ret;
}
if (type != TYPE_CCE) {
if (*channels >= MAX_CHANNELS - (type == TYPE_CPE || (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1))) {
@@ -237,13 +241,13 @@ static int assign_pair(struct elem_to_channel e2c_vec[MAX_ELEM_ID],
}
static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos,
- int *current)
+ int current)
{
int num_pos_channels = 0;
int first_cpe = 0;
int sce_parity = 0;
int i;
- for (i = *current; i < tags; i++) {
+ for (i = current; i < tags; i++) {
if (layout_map[i][2] != pos)
break;
if (layout_map[i][0] == TYPE_CPE) {
@@ -258,208 +262,118 @@ static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos,
first_cpe = 1;
} else {
num_pos_channels++;
- sce_parity ^= 1;
+ sce_parity ^= (pos != AAC_CHANNEL_LFE);
}
}
if (sce_parity &&
- ((pos == AAC_CHANNEL_FRONT && first_cpe) || pos == AAC_CHANNEL_SIDE))
+ (pos == AAC_CHANNEL_FRONT && first_cpe))
return -1;
- *current = i;
+
return num_pos_channels;
}
-#define PREFIX_FOR_22POINT2 (AV_CH_LAYOUT_7POINT1_WIDE_BACK|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_LOW_FREQUENCY_2)
+static int assign_channels(struct elem_to_channel e2c_vec[MAX_ELEM_ID], uint8_t (*layout_map)[3],
+ uint64_t *layout, int tags, int layer, int pos, int *current)
+{
+ int i = *current, j = 0;
+ int nb_channels = count_paired_channels(layout_map, tags, pos, i);
+
+ if (nb_channels < 0 || nb_channels > 5)
+ return 0;
+
+ if (pos == AAC_CHANNEL_LFE) {
+ while (nb_channels) {
+ if (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],
+ .syn_ele = layout_map[i][0],
+ .elem_id = layout_map[i][1],
+ .aac_position = pos
+ };
+ *layout |= e2c_vec[i].av_position;
+ i++;
+ j++;
+ nb_channels--;
+ }
+ *current = i;
+
+ return 0;
+ }
+
+ while (nb_channels & 1) {
+ if (aac_channel_map[layer][pos - 1][0] == AV_CHAN_NONE)
+ return -1;
+ if (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],
+ .syn_ele = layout_map[i][0],
+ .elem_id = layout_map[i][1],
+ .aac_position = pos
+ };
+ *layout |= e2c_vec[i].av_position;
+ i++;
+ nb_channels--;
+ }
+
+ 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)
+ 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],
+ pos, layout);
+ j += 2;
+ nb_channels -= 2;
+ }
+ while (nb_channels & 1) {
+ if (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],
+ .syn_ele = layout_map[i][0],
+ .elem_id = layout_map[i][1],
+ .aac_position = pos
+ };
+ *layout |= e2c_vec[i].av_position;
+ i++;
+ nb_channels--;
+ }
+ if (nb_channels)
+ return -1;
+
+ *current = i;
+
+ return 0;
+}
+
static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags)
{
int i, n, total_non_cc_elements;
struct elem_to_channel e2c_vec[4 * MAX_ELEM_ID] = { { 0 } };
- int num_front_channels, num_side_channels, num_back_channels;
uint64_t layout = 0;
if (FF_ARRAY_ELEMS(e2c_vec) < tags)
return 0;
- i = 0;
- num_front_channels =
- count_paired_channels(layout_map, tags, AAC_CHANNEL_FRONT, &i);
- if (num_front_channels < 0)
- return 0;
- num_side_channels =
- count_paired_channels(layout_map, tags, AAC_CHANNEL_SIDE, &i);
- if (num_side_channels < 0)
- return 0;
- num_back_channels =
- count_paired_channels(layout_map, tags, AAC_CHANNEL_BACK, &i);
- if (num_back_channels < 0)
- return 0;
-
- if (num_side_channels == 0 && num_back_channels >= 4) {
- num_side_channels = 2;
- num_back_channels -= 2;
+ for (n = 0, i = 0; n < 3 && i < tags; n++) {
+ int ret = assign_channels(e2c_vec, layout_map, &layout, tags, n, AAC_CHANNEL_FRONT, &i);
+ if (ret < 0)
+ return 0;
+ ret = assign_channels(e2c_vec, layout_map, &layout, tags, n, AAC_CHANNEL_SIDE, &i);
+ if (ret < 0)
+ return 0;
+ ret = assign_channels(e2c_vec, layout_map, &layout, tags, n, AAC_CHANNEL_BACK, &i);
+ if (ret < 0)
+ return 0;
+ ret = assign_channels(e2c_vec, layout_map, &layout, tags, n, AAC_CHANNEL_LFE, &i);
+ if (ret < 0)
+ return 0;
}
- i = 0;
- if (num_front_channels & 1) {
- e2c_vec[i] = (struct elem_to_channel) {
- .av_position = AV_CH_FRONT_CENTER,
- .syn_ele = TYPE_SCE,
- .elem_id = layout_map[i][1],
- .aac_position = AAC_CHANNEL_FRONT
- };
- layout |= e2c_vec[i].av_position;
- i++;
- num_front_channels--;
- }
- if (num_front_channels >= 4) {
- i += assign_pair(e2c_vec, layout_map, i,
- AV_CH_FRONT_LEFT_OF_CENTER,
- AV_CH_FRONT_RIGHT_OF_CENTER,
- AAC_CHANNEL_FRONT, &layout);
- num_front_channels -= 2;
- }
- if (num_front_channels >= 2) {
- i += assign_pair(e2c_vec, layout_map, i,
- AV_CH_FRONT_LEFT,
- AV_CH_FRONT_RIGHT,
- AAC_CHANNEL_FRONT, &layout);
- num_front_channels -= 2;
- }
- while (num_front_channels >= 2) {
- i += assign_pair(e2c_vec, layout_map, i,
- UINT64_MAX,
- UINT64_MAX,
- AAC_CHANNEL_FRONT, &layout);
- num_front_channels -= 2;
- }
-
- if (num_side_channels >= 2) {
- i += assign_pair(e2c_vec, layout_map, i,
- AV_CH_SIDE_LEFT,
- AV_CH_SIDE_RIGHT,
- AAC_CHANNEL_FRONT, &layout);
- num_side_channels -= 2;
- }
- while (num_side_channels >= 2) {
- i += assign_pair(e2c_vec, layout_map, i,
- UINT64_MAX,
- UINT64_MAX,
- AAC_CHANNEL_SIDE, &layout);
- num_side_channels -= 2;
- }
-
- while (num_back_channels >= 4) {
- i += assign_pair(e2c_vec, layout_map, i,
- UINT64_MAX,
- UINT64_MAX,
- AAC_CHANNEL_BACK, &layout);
- num_back_channels -= 2;
- }
- if (num_back_channels >= 2) {
- i += assign_pair(e2c_vec, layout_map, i,
- AV_CH_BACK_LEFT,
- AV_CH_BACK_RIGHT,
- AAC_CHANNEL_BACK, &layout);
- num_back_channels -= 2;
- }
- if (num_back_channels) {
- e2c_vec[i] = (struct elem_to_channel) {
- .av_position = AV_CH_BACK_CENTER,
- .syn_ele = TYPE_SCE,
- .elem_id = layout_map[i][1],
- .aac_position = AAC_CHANNEL_BACK
- };
- layout |= e2c_vec[i].av_position;
- i++;
- num_back_channels--;
- }
-
- if (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) {
- e2c_vec[i] = (struct elem_to_channel) {
- .av_position = AV_CH_LOW_FREQUENCY,
- .syn_ele = TYPE_LFE,
- .elem_id = layout_map[i][1],
- .aac_position = AAC_CHANNEL_LFE
- };
- layout |= e2c_vec[i].av_position;
- i++;
- }
- if (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) {
- e2c_vec[i] = (struct elem_to_channel) {
- .av_position = AV_CH_LOW_FREQUENCY_2,
- .syn_ele = TYPE_LFE,
- .elem_id = layout_map[i][1],
- .aac_position = AAC_CHANNEL_LFE
- };
- layout |= e2c_vec[i].av_position;
- i++;
- }
- while (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) {
- e2c_vec[i] = (struct elem_to_channel) {
- .av_position = UINT64_MAX,
- .syn_ele = TYPE_LFE,
- .elem_id = layout_map[i][1],
- .aac_position = AAC_CHANNEL_LFE
- };
- i++;
- }
-
- // The previous checks would end up at 8 at this point for 22.2
- if (layout == PREFIX_FOR_22POINT2 && tags == 16 && i == 8) {
- const uint8_t (*reference_layout_map)[3] = aac_channel_layout_map[12];
- for (int j = 0; j < tags; j++) {
- if (layout_map[j][0] != reference_layout_map[j][0] ||
- layout_map[j][2] != reference_layout_map[j][2])
- goto end_of_layout_definition;
- }
-
- e2c_vec[i] = (struct elem_to_channel) {
- .av_position = AV_CH_TOP_FRONT_CENTER,
- .syn_ele = layout_map[i][0],
- .elem_id = layout_map[i][1],
- .aac_position = layout_map[i][2]
- }; layout |= e2c_vec[i].av_position; i++;
- i += assign_pair(e2c_vec, layout_map, i,
- AV_CH_TOP_FRONT_LEFT,
- AV_CH_TOP_FRONT_RIGHT,
- AAC_CHANNEL_FRONT,
- &layout);
- i += assign_pair(e2c_vec, layout_map, i,
- AV_CH_TOP_SIDE_LEFT,
- AV_CH_TOP_SIDE_RIGHT,
- AAC_CHANNEL_SIDE,
- &layout);
- e2c_vec[i] = (struct elem_to_channel) {
- .av_position = AV_CH_TOP_CENTER,
- .syn_ele = layout_map[i][0],
- .elem_id = layout_map[i][1],
- .aac_position = layout_map[i][2]
- }; layout |= e2c_vec[i].av_position; i++;
- i += assign_pair(e2c_vec, layout_map, i,
- AV_CH_TOP_BACK_LEFT,
- AV_CH_TOP_BACK_RIGHT,
- AAC_CHANNEL_BACK,
- &layout);
- e2c_vec[i] = (struct elem_to_channel) {
- .av_position = AV_CH_TOP_BACK_CENTER,
- .syn_ele = layout_map[i][0],
- .elem_id = layout_map[i][1],
- .aac_position = layout_map[i][2]
- }; layout |= e2c_vec[i].av_position; i++;
- e2c_vec[i] = (struct elem_to_channel) {
- .av_position = AV_CH_BOTTOM_FRONT_CENTER,
- .syn_ele = layout_map[i][0],
- .elem_id = layout_map[i][1],
- .aac_position = layout_map[i][2]
- }; layout |= e2c_vec[i].av_position; i++;
- i += assign_pair(e2c_vec, layout_map, i,
- AV_CH_BOTTOM_FRONT_LEFT,
- AV_CH_BOTTOM_FRONT_RIGHT,
- AAC_CHANNEL_FRONT,
- &layout);
- }
-
-end_of_layout_definition:
-
total_non_cc_elements = n = i;
if (layout == AV_CH_LAYOUT_22POINT2) {
@@ -632,7 +546,7 @@ static int set_default_channel_config(AACContext *ac, AVCodecContext *avctx,
int channel_config)
{
if (channel_config < 1 || (channel_config > 7 && channel_config < 11) ||
- channel_config > 13) {
+ channel_config > 14) {
av_log(avctx, AV_LOG_ERROR,
"invalid default channel configuration (%d)\n",
channel_config);
@@ -654,7 +568,7 @@ static int set_default_channel_config(AACContext *ac, AVCodecContext *avctx,
* 7.1 layout was intended.
*/
if (channel_config == 7 && avctx->strict_std_compliance < FF_COMPLIANCE_STRICT) {
- layout_map[2][2] = AAC_CHANNEL_SIDE;
+ layout_map[2][2] = AAC_CHANNEL_BACK;
if (!ac || !ac->warned_71_wide++) {
av_log(avctx, AV_LOG_INFO, "Assuming an incorrectly encoded 7.1 channel layout"
@@ -716,6 +630,12 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
/* For indexed channel configurations map the channels solely based
* on position. */
switch (ac->oc[1].m4ac.chan_config) {
+ case 14:
+ if (ac->tags_mapped > 2 && ((type == TYPE_CPE && elem_id < 3) ||
+ (type == TYPE_LFE && elem_id < 1))) {
+ ac->tags_mapped++;
+ return ac->tag_che_map[type][elem_id] = ac->che[type][elem_id];
+ }
case 13:
if (ac->tags_mapped > 3 && ((type == TYPE_CPE && elem_id < 8) ||
(type == TYPE_SCE && elem_id < 6) ||
@@ -730,9 +650,7 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][2];
}
case 11:
- if (ac->tags_mapped == 2 &&
- ac->oc[1].m4ac.chan_config == 11 &&
- type == TYPE_SCE) {
+ if (ac->tags_mapped == 3 && type == TYPE_SCE) {
ac->tags_mapped++;
return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1];
}
@@ -930,13 +848,6 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx,
uint8_t layout_map[MAX_ELEM_ID*4][3];
int tags = 0;
-#if USE_FIXED
- if (get_bits1(gb)) { // frameLengthFlag
- avpriv_report_missing_feature(avctx, "Fixed point 960/120 MDCT window");
- return AVERROR_PATCHWELCOME;
- }
- m4ac->frame_length_short = 0;
-#else
m4ac->frame_length_short = get_bits1(gb);
if (m4ac->frame_length_short && m4ac->sbr == 1) {
avpriv_report_missing_feature(avctx, "SBR with 960 frame length");
@@ -944,7 +855,6 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx,
m4ac->sbr = 0;
m4ac->ps = 0;
}
-#endif
if (get_bits1(gb)) // dependsOnCoreCoder
skip_bits(gb, 14); // coreCoderDelay
@@ -1021,14 +931,8 @@ static int decode_eld_specific_config(AACContext *ac, AVCodecContext *avctx,
m4ac->ps = 0;
m4ac->sbr = 0;
-#if USE_FIXED
- if (get_bits1(gb)) { // frameLengthFlag
- avpriv_request_sample(avctx, "960/120 MDCT window");
- return AVERROR_PATCHWELCOME;
- }
-#else
m4ac->frame_length_short = get_bits1(gb);
-#endif
+
res_flags = get_bits(gb, 3);
if (res_flags) {
avpriv_report_missing_feature(avctx,
@@ -1255,9 +1159,10 @@ static av_cold void aac_static_table_init(void)
352);
// window initialization
-#if !USE_FIXED
AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(aac_kbd_long_960), 4.0, 960);
AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(aac_kbd_short_120), 6.0, 120);
+
+#if !USE_FIXED
AAC_RENAME(ff_sine_window_init)(AAC_RENAME(sine_960), 960);
AAC_RENAME(ff_sine_window_init)(AAC_RENAME(sine_120), 120);
AAC_RENAME(ff_init_ff_sine_windows)(9);
@@ -1275,6 +1180,7 @@ static AVOnce aac_table_init = AV_ONCE_INIT;
static av_cold int aac_decode_init(AVCodecContext *avctx)
{
+ float scale;
AACContext *ac = avctx->priv_data;
int ret;
@@ -1347,21 +1253,25 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
ac->random_state = 0x1f2e3d4c;
- AAC_RENAME_32(ff_mdct_init)(&ac->mdct, 11, 1, 1.0 / RANGE15(1024.0));
- AAC_RENAME_32(ff_mdct_init)(&ac->mdct_ld, 10, 1, 1.0 / RANGE15(512.0));
- AAC_RENAME_32(ff_mdct_init)(&ac->mdct_small, 8, 1, 1.0 / RANGE15(128.0));
- AAC_RENAME_32(ff_mdct_init)(&ac->mdct_ltp, 11, 0, RANGE15(-2.0));
-#if !USE_FIXED
- ret = ff_mdct15_init(&ac->mdct120, 1, 3, 1.0f/(16*1024*120*2));
+#define MDCT_INIT(s, fn, len, sval) \
+ scale = sval; \
+ ret = av_tx_init(&s, &fn, TX_TYPE, 1, len, &scale, 0); \
+ if (ret < 0) \
+ return ret;
+
+ MDCT_INIT(ac->mdct120, ac->mdct120_fn, 120, TX_SCALE(1.0/120))
+ MDCT_INIT(ac->mdct128, ac->mdct128_fn, 128, TX_SCALE(1.0/128))
+ MDCT_INIT(ac->mdct480, ac->mdct480_fn, 480, TX_SCALE(1.0/480))
+ MDCT_INIT(ac->mdct512, ac->mdct512_fn, 512, TX_SCALE(1.0/512))
+ MDCT_INIT(ac->mdct960, ac->mdct960_fn, 960, TX_SCALE(1.0/960))
+ MDCT_INIT(ac->mdct1024, ac->mdct1024_fn, 1024, TX_SCALE(1.0/1024))
+#undef MDCT_INIT
+
+ /* LTP forward MDCT */
+ scale = USE_FIXED ? -1.0 : -32786.0*2 + 36;
+ ret = av_tx_init(&ac->mdct_ltp, &ac->mdct_ltp_fn, TX_TYPE, 0, 1024, &scale, 0);
if (ret < 0)
return ret;
- ret = ff_mdct15_init(&ac->mdct480, 1, 5, 1.0f/(16*1024*960));
- if (ret < 0)
- return ret;
- ret = ff_mdct15_init(&ac->mdct960, 1, 6, 1.0f/(16*1024*960*2));
- if (ret < 0)
- return ret;
-#endif
return 0;
}
@@ -2584,6 +2494,10 @@ static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt,
ac->avctx->profile = FF_PROFILE_AAC_HE;
}
res = AAC_RENAME(ff_decode_sbr_extension)(ac, &che->sbr, gb, crc_flag, cnt, elem_type);
+ if (ac->oc[1].m4ac.ps == 1 && !ac->warned_he_aac_mono) {
+ av_log(ac->avctx, AV_LOG_VERBOSE, "Treating HE-AAC mono as stereo.\n");
+ ac->warned_he_aac_mono = 1;
+ }
break;
case EXT_DYNAMIC_RANGE:
res = decode_dynamic_range(&ac->che_drc, gb);
@@ -2686,7 +2600,7 @@ static void windowing_and_mdct_ltp(AACContext *ac, INTFLOAT *out,
ac->fdsp->vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128);
memset(in + 1024 + 576, 0, 448 * sizeof(*in));
}
- ac->mdct_ltp.mdct_calc(&ac->mdct_ltp, out, in);
+ ac->mdct_ltp_fn(ac->mdct_ltp, out, in, sizeof(INTFLOAT));
}
/**
@@ -2778,13 +2692,9 @@ static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce)
// imdct
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
for (i = 0; i < 1024; i += 128)
- ac->mdct_small.imdct_half(&ac->mdct_small, buf + i, in + i);
+ ac->mdct128_fn(ac->mdct128, buf + i, in + i, sizeof(INTFLOAT));
} else {
- ac->mdct.imdct_half(&ac->mdct, buf, in);
-#if USE_FIXED
- for (i=0; i<1024; i++)
- buf[i] = (buf[i] + 4LL) >> 3;
-#endif /* USE_FIXED */
+ ac->mdct1024_fn(ac->mdct1024, buf, in, sizeof(INTFLOAT));
}
/* window overlapping
@@ -2832,7 +2742,6 @@ static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce)
*/
static void imdct_and_windowing_960(AACContext *ac, SingleChannelElement *sce)
{
-#if !USE_FIXED
IndividualChannelStream *ics = &sce->ics;
INTFLOAT *in = sce->coeffs;
INTFLOAT *out = sce->ret;
@@ -2847,9 +2756,9 @@ static void imdct_and_windowing_960(AACContext *ac, SingleChannelElement *sce)
// imdct
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
for (i = 0; i < 8; i++)
- ac->mdct120->imdct_half(ac->mdct120, buf + i * 120, in + i * 128, 1);
+ ac->mdct120_fn(ac->mdct120, buf + i * 120, in + i * 128, sizeof(INTFLOAT));
} else {
- ac->mdct960->imdct_half(ac->mdct960, buf, in, 1);
+ ac->mdct960_fn(ac->mdct960, buf, in, sizeof(INTFLOAT));
}
/* window overlapping
@@ -2891,7 +2800,6 @@ static void imdct_and_windowing_960(AACContext *ac, SingleChannelElement *sce)
} else { // LONG_STOP or ONLY_LONG
memcpy( saved, buf + 480, 480 * sizeof(*saved));
}
-#endif
}
static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce)
{
@@ -2900,17 +2808,9 @@ static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce)
INTFLOAT *out = sce->ret;
INTFLOAT *saved = sce->saved;
INTFLOAT *buf = ac->buf_mdct;
-#if USE_FIXED
- int i;
-#endif /* USE_FIXED */
// imdct
- ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
-
-#if USE_FIXED
- for (i = 0; i < 1024; i++)
- buf[i] = (buf[i] + 2) >> 2;
-#endif /* USE_FIXED */
+ ac->mdct512_fn(ac->mdct512, buf, in, sizeof(INTFLOAT));
// window overlapping
if (ics->use_kb_window[1]) {
@@ -2949,20 +2849,15 @@ static void imdct_and_windowing_eld(AACContext *ac, SingleChannelElement *sce)
temp = in[i ]; in[i ] = -in[n - 1 - i]; in[n - 1 - i] = temp;
temp = -in[i + 1]; in[i + 1] = in[n - 2 - i]; in[n - 2 - i] = temp;
}
-#if !USE_FIXED
- if (n == 480)
- ac->mdct480->imdct_half(ac->mdct480, buf, in, 1);
- else
-#endif
- ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
-#if USE_FIXED
- for (i = 0; i < 1024; i++)
- buf[i] = (buf[i] + 1) >> 1;
-#endif /* USE_FIXED */
+ if (n == 480)
+ ac->mdct480_fn(ac->mdct480, buf, in, sizeof(INTFLOAT));
+ else
+ ac->mdct512_fn(ac->mdct512, buf, in, sizeof(INTFLOAT));
for (i = 0; i < n; i+=2) {
- buf[i] = -buf[i];
+ buf[i + 0] = -(USE_FIXED + 1)*buf[i + 0];
+ buf[i + 1] = (USE_FIXED + 1)*buf[i + 1];
}
// Like with the regular IMDCT at this point we still have the middle half
// of a transform but with even symmetry on the left and odd symmetry on
@@ -3091,7 +2986,7 @@ static void spectral_to_sample(AACContext *ac, int samples)
/* preparation for resampler */
for(j = 0; jch[0].ret[j] = (int32_t)av_clip64((int64_t)che->ch[0].ret[j]*128, INT32_MIN, INT32_MAX-0x8000)+0x8000;
- if(type == TYPE_CPE)
+ if (type == TYPE_CPE || (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1))
che->ch[1].ret[j] = (int32_t)av_clip64((int64_t)che->ch[1].ret[j]*128, INT32_MIN, INT32_MAX-0x8000)+0x8000;
}
}
@@ -3418,9 +3313,6 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
ac->oc[1].status = OC_LOCKED;
}
- if (multiplier)
- avctx->internal->skip_samples_multiplier = 2;
-
if (!ac->frame->data[0] && samples) {
av_log(avctx, AV_LOG_ERROR, "no frame data found\n");
err = AVERROR_INVALIDDATA;
@@ -3527,15 +3419,14 @@ static av_cold int aac_decode_close(AVCodecContext *avctx)
}
}
- ff_mdct_end(&ac->mdct);
- ff_mdct_end(&ac->mdct_small);
- ff_mdct_end(&ac->mdct_ld);
- ff_mdct_end(&ac->mdct_ltp);
-#if !USE_FIXED
- ff_mdct15_uninit(&ac->mdct120);
- ff_mdct15_uninit(&ac->mdct480);
- ff_mdct15_uninit(&ac->mdct960);
-#endif
+ av_tx_uninit(&ac->mdct120);
+ av_tx_uninit(&ac->mdct128);
+ av_tx_uninit(&ac->mdct480);
+ av_tx_uninit(&ac->mdct512);
+ av_tx_uninit(&ac->mdct960);
+ av_tx_uninit(&ac->mdct1024);
+ av_tx_uninit(&ac->mdct_ltp);
+
av_freep(&ac->fdsp);
return 0;
}
diff --git a/libavcodec/aacdectab.h b/libavcodec/aacdectab.h
index e03026806..41f1db781 100644
--- a/libavcodec/aacdectab.h
+++ b/libavcodec/aacdectab.h
@@ -35,7 +35,7 @@
#include
-static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 4, 5, 16, 5, 0 };
+static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 5, 5, 16, 5, 0 };
static const uint8_t aac_channel_layout_map[16][16][3] = {
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, },
@@ -49,12 +49,12 @@ static const uint8_t aac_channel_layout_map[16][16][3] = {
{ { 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_SIDE }, { TYPE_CPE, 2, 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_SIDE }, // CPE3 = SiL and SiR,
+ { 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,
@@ -62,18 +62,39 @@ static const uint8_t aac_channel_layout_map[16][16][3] = {
{ 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_FRONT }, // SCE4 = TpC,
+ { 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, } },
- /* TODO: Add 7+1 TOP configuration */
+};
+
+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 },
+ },
};
#if FF_API_OLD_CHANNEL_LAYOUT
-static const uint64_t aac_channel_layout[16] = {
+static const uint64_t aac_channel_layout[] = {
AV_CH_LAYOUT_MONO,
AV_CH_LAYOUT_STEREO,
AV_CH_LAYOUT_SURROUND,
@@ -81,18 +102,15 @@ static const uint64_t aac_channel_layout[16] = {
AV_CH_LAYOUT_5POINT0_BACK,
AV_CH_LAYOUT_5POINT1_BACK,
AV_CH_LAYOUT_7POINT1_WIDE_BACK,
- 0,
- 0,
- 0,
- AV_CH_LAYOUT_6POINT1,
+ AV_CH_LAYOUT_6POINT1_BACK,
AV_CH_LAYOUT_7POINT1,
AV_CH_LAYOUT_22POINT2,
+ AV_CH_LAYOUT_7POINT1_TOP_BACK,
0,
- /* AV_CH_LAYOUT_7POINT1_TOP, */
};
#endif
-static const AVChannelLayout aac_ch_layout[16] = {
+static const AVChannelLayout aac_ch_layout[] = {
AV_CHANNEL_LAYOUT_MONO,
AV_CHANNEL_LAYOUT_STEREO,
AV_CHANNEL_LAYOUT_SURROUND,
@@ -100,14 +118,11 @@ static const AVChannelLayout aac_ch_layout[16] = {
AV_CHANNEL_LAYOUT_5POINT0_BACK,
AV_CHANNEL_LAYOUT_5POINT1_BACK,
AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK,
- { 0 },
- { 0 },
- { 0 },
- AV_CHANNEL_LAYOUT_6POINT1,
+ AV_CHANNEL_LAYOUT_6POINT1_BACK,
AV_CHANNEL_LAYOUT_7POINT1,
AV_CHANNEL_LAYOUT_22POINT2,
+ AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK,
{ 0 },
- /* AV_CHANNEL_LAYOUT_7POINT1_TOP, */
};
#endif /* AVCODEC_AACDECTAB_H */
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index 408c03144..ed036209e 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -51,6 +51,279 @@
#include "psymodel.h"
+/**
+ * List of PCE (Program Configuration Element) for the channel layouts listed
+ * in channel_layout.h
+ *
+ * For those wishing in the future to add other layouts:
+ *
+ * - num_ele: number of elements in each group of front, side, back, lfe channels
+ * (an element is of type SCE (single channel), CPE (channel pair) for
+ * the first 3 groups; and is LFE for LFE group).
+ *
+ * - pairing: 0 for an SCE element or 1 for a CPE; does not apply to LFE group
+ *
+ * - index: there are three independent indices for SCE, CPE and LFE;
+ * they are incremented irrespective of the group to which the element belongs;
+ * they are not reset when going from one group to another
+ *
+ * Example: for 7.0 channel layout,
+ * .pairing = { { 1, 0 }, { 1 }, { 1 }, }, (3 CPE and 1 SCE in front group)
+ * .index = { { 0, 0 }, { 1 }, { 2 }, },
+ * (index is 0 for the single SCE but goes from 0 to 2 for the CPEs)
+ *
+ * The index order impacts the channel ordering. But is otherwise arbitrary
+ * (the sequence could have been 2, 0, 1 instead of 0, 1, 2).
+ *
+ * Spec allows for discontinuous indices, e.g. if one has a total of two SCE,
+ * SCE.0 SCE.15 is OK per spec; BUT it won't be decoded by our AAC decoder
+ * which at this time requires that indices fully cover some range starting
+ * from 0 (SCE.1 SCE.0 is OK but not SCE.0 SCE.15).
+ *
+ * - config_map: total number of elements and their types. Beware, the way the
+ * types are ordered impacts the final channel ordering.
+ *
+ * - reorder_map: reorders the channels.
+ *
+ */
+static const AACPCEInfo aac_pce_configs[] = {
+ {
+ .layout = AV_CHANNEL_LAYOUT_MONO,
+ .num_ele = { 1, 0, 0, 0 },
+ .pairing = { { 0 }, },
+ .index = { { 0 }, },
+ .config_map = { 1, TYPE_SCE, },
+ .reorder_map = { 0 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_STEREO,
+ .num_ele = { 1, 0, 0, 0 },
+ .pairing = { { 1 }, },
+ .index = { { 0 }, },
+ .config_map = { 1, TYPE_CPE, },
+ .reorder_map = { 0, 1 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_2POINT1,
+ .num_ele = { 1, 0, 0, 1 },
+ .pairing = { { 1 }, },
+ .index = { { 0 },{ 0 },{ 0 },{ 0 } },
+ .config_map = { 2, TYPE_CPE, TYPE_LFE },
+ .reorder_map = { 0, 1, 2 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_2_1,
+ .num_ele = { 1, 0, 1, 0 },
+ .pairing = { { 1 },{ 0 },{ 0 } },
+ .index = { { 0 },{ 0 },{ 0 }, },
+ .config_map = { 2, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_SURROUND,
+ .num_ele = { 2, 0, 0, 0 },
+ .pairing = { { 1, 0 }, },
+ .index = { { 0, 0 }, },
+ .config_map = { 2, TYPE_CPE, TYPE_SCE, },
+ .reorder_map = { 0, 1, 2 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_3POINT1,
+ .num_ele = { 2, 0, 0, 1 },
+ .pairing = { { 1, 0 }, },
+ .index = { { 0, 0 }, { 0 }, { 0 }, { 0 }, },
+ .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_LFE },
+ .reorder_map = { 0, 1, 2, 3 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_4POINT0,
+ .num_ele = { 2, 0, 1, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 0 }, },
+ .index = { { 0, 0 }, { 0 }, { 1 } },
+ .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_4POINT1,
+ .num_ele = { 2, 1, 1, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 0 }, },
+ .index = { { 0, 0 }, { 1 }, { 2 }, { 0 } },
+ .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_2_2,
+ .num_ele = { 1, 1, 0, 0 },
+ .pairing = { { 1 }, { 1 }, },
+ .index = { { 0 }, { 1 }, },
+ .config_map = { 2, TYPE_CPE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_QUAD,
+ .num_ele = { 1, 0, 1, 0 },
+ .pairing = { { 1 }, { 0 }, { 1 }, },
+ .index = { { 0 }, { 0 }, { 1 } },
+ .config_map = { 2, TYPE_CPE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_5POINT0,
+ .num_ele = { 2, 1, 0, 0 },
+ .pairing = { { 1, 0 }, { 1 }, },
+ .index = { { 0, 0 }, { 1 } },
+ .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_5POINT1,
+ .num_ele = { 2, 1, 1, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 1 }, },
+ .index = { { 0, 0 }, { 1 }, { 1 } },
+ .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_5POINT0_BACK,
+ .num_ele = { 2, 0, 1, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 1 } },
+ .index = { { 0, 0 }, { 0 }, { 1 } },
+ .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_5POINT1_BACK,
+ .num_ele = { 2, 1, 1, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 1 }, },
+ .index = { { 0, 0 }, { 1 }, { 1 } },
+ .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_6POINT0,
+ .num_ele = { 2, 1, 1, 0 },
+ .pairing = { { 1, 0 }, { 1 }, { 0 }, },
+ .index = { { 0, 0 }, { 1 }, { 1 } },
+ .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_6POINT0_FRONT,
+ .num_ele = { 2, 1, 0, 0 },
+ .pairing = { { 1, 1 }, { 1 } },
+ .index = { { 1, 0 }, { 2 }, },
+ .config_map = { 3, TYPE_CPE, TYPE_CPE, TYPE_CPE, },
+ .reorder_map = { 0, 1, 2, 3, 4, 5 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_HEXAGONAL,
+ .num_ele = { 2, 0, 2, 0 },
+ .pairing = { { 1, 0 },{ 0 },{ 1, 0 }, },
+ .index = { { 0, 0 },{ 0 },{ 1, 1 } },
+ .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE, },
+ .reorder_map = { 0, 1, 2, 3, 4, 5 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_6POINT1,
+ .num_ele = { 2, 1, 2, 0 },
+ .pairing = { { 1, 0 },{ 0 },{ 1, 0 }, },
+ .index = { { 0, 0 },{ 1 },{ 1, 2 } },
+ .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_6POINT1_BACK,
+ .num_ele = { 2, 1, 2, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 1, 0 }, },
+ .index = { { 0, 0 }, { 1 }, { 1, 2 } },
+ .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_6POINT1_FRONT,
+ .num_ele = { 2, 1, 2, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 1, 0 }, },
+ .index = { { 0, 0 }, { 1 }, { 1, 2 } },
+ .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_7POINT0,
+ .num_ele = { 2, 1, 1, 0 },
+ .pairing = { { 1, 0 }, { 1 }, { 1 }, },
+ .index = { { 0, 0 }, { 1 }, { 2 }, },
+ .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_7POINT0_FRONT,
+ .num_ele = { 2, 1, 1, 0 },
+ .pairing = { { 1, 0 }, { 1 }, { 1 }, },
+ .index = { { 0, 0 }, { 1 }, { 2 }, },
+ .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_7POINT1,
+ .num_ele = { 2, 1, 2, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 1, 1 }, },
+ .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } },
+ .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_7POINT1_WIDE,
+ .num_ele = { 2, 1, 2, 0 },
+ .pairing = { { 1, 0 }, { 0 },{ 1, 1 }, },
+ .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } },
+ .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK,
+ .num_ele = { 2, 1, 2, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 1, 1 }, },
+ .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } },
+ .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_OCTAGONAL,
+ .num_ele = { 2, 1, 2, 0 },
+ .pairing = { { 1, 0 }, { 1 }, { 1, 0 }, },
+ .index = { { 0, 0 }, { 1 }, { 2, 1 } },
+ .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
+ },
+ { /* Meant for order 2/mixed ambisonics */
+ .layout = { .order = AV_CHANNEL_ORDER_NATIVE, .nb_channels = 9,
+ .u.mask = AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER },
+ .num_ele = { 2, 2, 2, 0 },
+ .pairing = { { 1, 0 }, { 1, 0 }, { 1, 0 }, },
+ .index = { { 0, 0 }, { 1, 1 }, { 2, 2 } },
+ .config_map = { 6, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7, 8 },
+ },
+ { /* Meant for order 2/mixed ambisonics */
+ .layout = { .order = AV_CHANNEL_ORDER_NATIVE, .nb_channels = 10,
+ .u.mask = AV_CH_LAYOUT_6POINT0_FRONT | AV_CH_BACK_CENTER |
+ AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_TOP_CENTER },
+ .num_ele = { 2, 2, 2, 0 },
+ .pairing = { { 1, 1 }, { 1, 0 }, { 1, 0 }, },
+ .index = { { 0, 1 }, { 2, 0 }, { 3, 1 } },
+ .config_map = { 6, TYPE_CPE, TYPE_CPE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
+ },
+ {
+ .layout = AV_CHANNEL_LAYOUT_HEXADECAGONAL,
+ .num_ele = { 4, 2, 4, 0 },
+ .pairing = { { 1, 0, 1, 0 }, { 1, 1 }, { 1, 0, 1, 0 }, },
+ .index = { { 0, 0, 1, 1 }, { 2, 3 }, { 4, 2, 5, 3 } },
+ .config_map = { 10, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+ },
+};
+
static void put_pce(PutBitContext *pb, AVCodecContext *avctx)
{
int i, j;
@@ -202,15 +475,15 @@ static void apply_window_and_mdct(AACEncContext *s, SingleChannelElement *sce,
float *audio)
{
int i;
- const float *output = sce->ret_buf;
+ float *output = sce->ret_buf;
apply_window[sce->ics.window_sequence[0]](s->fdsp, sce, audio);
if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE)
- s->mdct1024.mdct_calc(&s->mdct1024, sce->coeffs, output);
+ s->mdct1024_fn(s->mdct1024, sce->coeffs, output, sizeof(float));
else
for (i = 0; i < 1024; i += 128)
- s->mdct128.mdct_calc(&s->mdct128, &sce->coeffs[i], output + i*2);
+ s->mdct128_fn(s->mdct128, &sce->coeffs[i], output + i*2, sizeof(float));
memcpy(audio, audio + 1024, sizeof(audio[0]) * 1024);
memcpy(sce->pcoeffs, sce->coeffs, sizeof(sce->pcoeffs));
}
@@ -581,7 +854,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
if (s->psypp)
ff_psy_preprocess(s->psypp, s->planar_samples, s->channels);
- if (!avctx->frame_number)
+ if (!avctx->frame_num)
return 0;
start_ch = 0;
@@ -666,7 +939,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
if (s->options.ltp && s->coder->update_ltp) {
s->coder->update_ltp(s, sce);
apply_window[sce->ics.window_sequence[0]](s->fdsp, sce, &sce->ltp_state[0]);
- s->mdct1024.mdct_calc(&s->mdct1024, sce->lcoeffs, sce->ret_buf);
+ s->mdct1024_fn(s->mdct1024, sce->lcoeffs, sce->ret_buf, sizeof(float));
}
for (k = 0; k < 1024; k++) {
@@ -685,7 +958,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
do {
init_put_bits(&s->pb, avpkt->data, avpkt->size);
- if ((avctx->frame_number & 0xFF)==1 && !(avctx->flags & AV_CODEC_FLAG_BITEXACT))
+ if ((avctx->frame_num & 0xFF)==1 && !(avctx->flags & AV_CODEC_FLAG_BITEXACT))
put_bitstream_info(s, LIBAVCODEC_IDENT);
start_ch = 0;
target_bits = 0;
@@ -903,8 +1176,8 @@ static av_cold int aac_encode_end(AVCodecContext *avctx)
av_log(avctx, AV_LOG_INFO, "Qavg: %.3f\n", s->lambda_count ? s->lambda_sum / s->lambda_count : NAN);
- ff_mdct_end(&s->mdct1024);
- ff_mdct_end(&s->mdct128);
+ av_tx_uninit(&s->mdct1024);
+ av_tx_uninit(&s->mdct128);
ff_psy_end(&s->psy);
ff_lpc_end(&s->lpc);
if (s->psypp)
@@ -919,6 +1192,7 @@ static av_cold int aac_encode_end(AVCodecContext *avctx)
static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s)
{
int ret = 0;
+ float scale = 32768.0f;
s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
if (!s->fdsp)
@@ -927,9 +1201,11 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s)
// window init
ff_aac_float_common_init();
- if ((ret = ff_mdct_init(&s->mdct1024, 11, 0, 32768.0)) < 0)
+ if ((ret = av_tx_init(&s->mdct1024, &s->mdct1024_fn, AV_TX_FLOAT_MDCT, 0,
+ 1024, &scale, 0)) < 0)
return ret;
- if ((ret = ff_mdct_init(&s->mdct128, 8, 0, 32768.0)) < 0)
+ if ((ret = av_tx_init(&s->mdct128, &s->mdct128_fn, AV_TX_FLOAT_MDCT, 0,
+ 128, &scale, 0)) < 0)
return ret;
return 0;
@@ -1141,17 +1417,18 @@ static const FFCodecDefault aac_encode_defaults[] = {
const FFCodec ff_aac_encoder = {
.p.name = "aac",
- .p.long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
+ CODEC_LONG_NAME("AAC (Advanced Audio Coding)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AAC,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_SMALL_LAST_FRAME,
.priv_data_size = sizeof(AACEncContext),
.init = aac_encode_init,
FF_CODEC_ENCODE_CB(aac_encode_frame),
.close = aac_encode_end,
.defaults = aac_encode_defaults,
.p.supported_samplerates = ff_mpeg4audio_sample_rates,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
- .p.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
.p.priv_class = &aacenc_class,
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index a001c7ca6..b030c652a 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -102,279 +102,6 @@ typedef struct AACPCEInfo {
uint8_t reorder_map[16]; ///< maps channels from lavc to aac order
} AACPCEInfo;
-/**
- * List of PCE (Program Configuration Element) for the channel layouts listed
- * in channel_layout.h
- *
- * For those wishing in the future to add other layouts:
- *
- * - num_ele: number of elements in each group of front, side, back, lfe channels
- * (an element is of type SCE (single channel), CPE (channel pair) for
- * the first 3 groups; and is LFE for LFE group).
- *
- * - pairing: 0 for an SCE element or 1 for a CPE; does not apply to LFE group
- *
- * - index: there are three independent indices for SCE, CPE and LFE;
- * they are incremented irrespective of the group to which the element belongs;
- * they are not reset when going from one group to another
- *
- * Example: for 7.0 channel layout,
- * .pairing = { { 1, 0 }, { 1 }, { 1 }, }, (3 CPE and 1 SCE in front group)
- * .index = { { 0, 0 }, { 1 }, { 2 }, },
- * (index is 0 for the single SCE but goes from 0 to 2 for the CPEs)
- *
- * The index order impacts the channel ordering. But is otherwise arbitrary
- * (the sequence could have been 2, 0, 1 instead of 0, 1, 2).
- *
- * Spec allows for discontinuous indices, e.g. if one has a total of two SCE,
- * SCE.0 SCE.15 is OK per spec; BUT it won't be decoded by our AAC decoder
- * which at this time requires that indices fully cover some range starting
- * from 0 (SCE.1 SCE.0 is OK but not SCE.0 SCE.15).
- *
- * - config_map: total number of elements and their types. Beware, the way the
- * types are ordered impacts the final channel ordering.
- *
- * - reorder_map: reorders the channels.
- *
- */
-static const AACPCEInfo aac_pce_configs[] = {
- {
- .layout = AV_CHANNEL_LAYOUT_MONO,
- .num_ele = { 1, 0, 0, 0 },
- .pairing = { { 0 }, },
- .index = { { 0 }, },
- .config_map = { 1, TYPE_SCE, },
- .reorder_map = { 0 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_STEREO,
- .num_ele = { 1, 0, 0, 0 },
- .pairing = { { 1 }, },
- .index = { { 0 }, },
- .config_map = { 1, TYPE_CPE, },
- .reorder_map = { 0, 1 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_2POINT1,
- .num_ele = { 1, 0, 0, 1 },
- .pairing = { { 1 }, },
- .index = { { 0 },{ 0 },{ 0 },{ 0 } },
- .config_map = { 2, TYPE_CPE, TYPE_LFE },
- .reorder_map = { 0, 1, 2 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_2_1,
- .num_ele = { 1, 0, 1, 0 },
- .pairing = { { 1 },{ 0 },{ 0 } },
- .index = { { 0 },{ 0 },{ 0 }, },
- .config_map = { 2, TYPE_CPE, TYPE_SCE },
- .reorder_map = { 0, 1, 2 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_SURROUND,
- .num_ele = { 2, 0, 0, 0 },
- .pairing = { { 1, 0 }, },
- .index = { { 0, 0 }, },
- .config_map = { 2, TYPE_CPE, TYPE_SCE, },
- .reorder_map = { 0, 1, 2 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_3POINT1,
- .num_ele = { 2, 0, 0, 1 },
- .pairing = { { 1, 0 }, },
- .index = { { 0, 0 }, { 0 }, { 0 }, { 0 }, },
- .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_LFE },
- .reorder_map = { 0, 1, 2, 3 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_4POINT0,
- .num_ele = { 2, 0, 1, 0 },
- .pairing = { { 1, 0 }, { 0 }, { 0 }, },
- .index = { { 0, 0 }, { 0 }, { 1 } },
- .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_SCE },
- .reorder_map = { 0, 1, 2, 3 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_4POINT1,
- .num_ele = { 2, 1, 1, 0 },
- .pairing = { { 1, 0 }, { 0 }, { 0 }, },
- .index = { { 0, 0 }, { 1 }, { 2 }, { 0 } },
- .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_SCE },
- .reorder_map = { 0, 1, 2, 3, 4 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_2_2,
- .num_ele = { 1, 1, 0, 0 },
- .pairing = { { 1 }, { 1 }, },
- .index = { { 0 }, { 1 }, },
- .config_map = { 2, TYPE_CPE, TYPE_CPE },
- .reorder_map = { 0, 1, 2, 3 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_QUAD,
- .num_ele = { 1, 0, 1, 0 },
- .pairing = { { 1 }, { 0 }, { 1 }, },
- .index = { { 0 }, { 0 }, { 1 } },
- .config_map = { 2, TYPE_CPE, TYPE_CPE },
- .reorder_map = { 0, 1, 2, 3 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_5POINT0,
- .num_ele = { 2, 1, 0, 0 },
- .pairing = { { 1, 0 }, { 1 }, },
- .index = { { 0, 0 }, { 1 } },
- .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_CPE },
- .reorder_map = { 0, 1, 2, 3, 4 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_5POINT1,
- .num_ele = { 2, 1, 1, 0 },
- .pairing = { { 1, 0 }, { 0 }, { 1 }, },
- .index = { { 0, 0 }, { 1 }, { 1 } },
- .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE },
- .reorder_map = { 0, 1, 2, 3, 4, 5 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_5POINT0_BACK,
- .num_ele = { 2, 0, 1, 0 },
- .pairing = { { 1, 0 }, { 0 }, { 1 } },
- .index = { { 0, 0 }, { 0 }, { 1 } },
- .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_CPE },
- .reorder_map = { 0, 1, 2, 3, 4 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_5POINT1_BACK,
- .num_ele = { 2, 1, 1, 0 },
- .pairing = { { 1, 0 }, { 0 }, { 1 }, },
- .index = { { 0, 0 }, { 1 }, { 1 } },
- .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE },
- .reorder_map = { 0, 1, 2, 3, 4, 5 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_6POINT0,
- .num_ele = { 2, 1, 1, 0 },
- .pairing = { { 1, 0 }, { 1 }, { 0 }, },
- .index = { { 0, 0 }, { 1 }, { 1 } },
- .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
- .reorder_map = { 0, 1, 2, 3, 4, 5 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_6POINT0_FRONT,
- .num_ele = { 2, 1, 0, 0 },
- .pairing = { { 1, 1 }, { 1 } },
- .index = { { 1, 0 }, { 2 }, },
- .config_map = { 3, TYPE_CPE, TYPE_CPE, TYPE_CPE, },
- .reorder_map = { 0, 1, 2, 3, 4, 5 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_HEXAGONAL,
- .num_ele = { 2, 0, 2, 0 },
- .pairing = { { 1, 0 },{ 0 },{ 1, 0 }, },
- .index = { { 0, 0 },{ 0 },{ 1, 1 } },
- .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE, },
- .reorder_map = { 0, 1, 2, 3, 4, 5 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_6POINT1,
- .num_ele = { 2, 1, 2, 0 },
- .pairing = { { 1, 0 },{ 0 },{ 1, 0 }, },
- .index = { { 0, 0 },{ 1 },{ 1, 2 } },
- .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
- .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_6POINT1_BACK,
- .num_ele = { 2, 1, 2, 0 },
- .pairing = { { 1, 0 }, { 0 }, { 1, 0 }, },
- .index = { { 0, 0 }, { 1 }, { 1, 2 } },
- .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
- .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_6POINT1_FRONT,
- .num_ele = { 2, 1, 2, 0 },
- .pairing = { { 1, 0 }, { 0 }, { 1, 0 }, },
- .index = { { 0, 0 }, { 1 }, { 1, 2 } },
- .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
- .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_7POINT0,
- .num_ele = { 2, 1, 1, 0 },
- .pairing = { { 1, 0 }, { 1 }, { 1 }, },
- .index = { { 0, 0 }, { 1 }, { 2 }, },
- .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
- .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_7POINT0_FRONT,
- .num_ele = { 2, 1, 1, 0 },
- .pairing = { { 1, 0 }, { 1 }, { 1 }, },
- .index = { { 0, 0 }, { 1 }, { 2 }, },
- .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
- .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_7POINT1,
- .num_ele = { 2, 1, 2, 0 },
- .pairing = { { 1, 0 }, { 0 }, { 1, 1 }, },
- .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } },
- .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
- .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_7POINT1_WIDE,
- .num_ele = { 2, 1, 2, 0 },
- .pairing = { { 1, 0 }, { 0 },{ 1, 1 }, },
- .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } },
- .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
- .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK,
- .num_ele = { 2, 1, 2, 0 },
- .pairing = { { 1, 0 }, { 0 }, { 1, 1 }, },
- .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } },
- .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
- .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_OCTAGONAL,
- .num_ele = { 2, 1, 2, 0 },
- .pairing = { { 1, 0 }, { 1 }, { 1, 0 }, },
- .index = { { 0, 0 }, { 1 }, { 2, 1 } },
- .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_SCE },
- .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
- },
- { /* Meant for order 2/mixed ambisonics */
- .layout = { .order = AV_CHANNEL_ORDER_NATIVE, .nb_channels = 9,
- .u.mask = AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER },
- .num_ele = { 2, 2, 2, 0 },
- .pairing = { { 1, 0 }, { 1, 0 }, { 1, 0 }, },
- .index = { { 0, 0 }, { 1, 1 }, { 2, 2 } },
- .config_map = { 6, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
- .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7, 8 },
- },
- { /* Meant for order 2/mixed ambisonics */
- .layout = { .order = AV_CHANNEL_ORDER_NATIVE, .nb_channels = 10,
- .u.mask = AV_CH_LAYOUT_6POINT0_FRONT | AV_CH_BACK_CENTER |
- AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_TOP_CENTER },
- .num_ele = { 2, 2, 2, 0 },
- .pairing = { { 1, 1 }, { 1, 0 }, { 1, 0 }, },
- .index = { { 0, 1 }, { 2, 0 }, { 3, 1 } },
- .config_map = { 6, TYPE_CPE, TYPE_CPE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
- .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
- },
- {
- .layout = AV_CHANNEL_LAYOUT_HEXADECAGONAL,
- .num_ele = { 4, 2, 4, 0 },
- .pairing = { { 1, 0, 1, 0 }, { 1, 1 }, { 1, 0, 1, 0 }, },
- .index = { { 0, 0, 1, 1 }, { 2, 3 }, { 4, 2, 5, 3 } },
- .config_map = { 10, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
- .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
- },
-};
-
/**
* AAC encoder context
*/
@@ -382,8 +109,10 @@ typedef struct AACEncContext {
AVClass *av_class;
AACEncOptions options; ///< encoding options
PutBitContext pb;
- FFTContext mdct1024; ///< long (1024 samples) frame transform context
- FFTContext mdct128; ///< short (128 samples) frame transform context
+ AVTXContext *mdct1024; ///< long (1024 samples) frame transform context
+ av_tx_fn mdct1024_fn;
+ AVTXContext *mdct128; ///< short (128 samples) frame transform context
+ av_tx_fn mdct128_fn;
AVFloatDSPContext *fdsp;
AACPCEInfo pce; ///< PCE data, if needed
float *planar_samples[16]; ///< saved preprocessed input
diff --git a/libavcodec/aacenc_is.c b/libavcodec/aacenc_is.c
index 2f5b7eb8d..1810790d8 100644
--- a/libavcodec/aacenc_is.c
+++ b/libavcodec/aacenc_is.c
@@ -68,15 +68,15 @@ struct AACISError ff_aac_is_encoding_err(AACEncContext *s, ChannelElement *cpe,
sce0->ics.swb_sizes[g],
sce0->sf_idx[w*16+g],
sce0->band_type[w*16+g],
- s->lambda / band0->threshold, INFINITY, NULL, NULL, 0);
+ s->lambda / band0->threshold, INFINITY, NULL, NULL);
dist1 += quantize_band_cost(s, &R[start + (w+w2)*128], R34,
sce1->ics.swb_sizes[g],
sce1->sf_idx[w*16+g],
sce1->band_type[w*16+g],
- s->lambda / band1->threshold, INFINITY, NULL, NULL, 0);
+ s->lambda / band1->threshold, INFINITY, NULL, NULL);
dist2 += quantize_band_cost(s, IS, I34, sce0->ics.swb_sizes[g],
is_sf_idx, is_band_type,
- s->lambda / minthr, INFINITY, NULL, NULL, 0);
+ s->lambda / minthr, INFINITY, NULL, NULL);
for (i = 0; i < sce0->ics.swb_sizes[g]; i++) {
dist_spec_err += (L34[i] - I34[i])*(L34[i] - I34[i]);
dist_spec_err += (R34[i] - I34[i]*e01_34)*(R34[i] - I34[i]*e01_34);
diff --git a/libavcodec/aacenc_ltp.c b/libavcodec/aacenc_ltp.c
index f77f0b6a7..f7fb85bbf 100644
--- a/libavcodec/aacenc_ltp.c
+++ b/libavcodec/aacenc_ltp.c
@@ -194,11 +194,11 @@ void ff_aac_search_for_ltp(AACEncContext *s, SingleChannelElement *sce,
s->abs_pow34(PCD34, PCD, sce->ics.swb_sizes[g]);
dist1 += quantize_band_cost(s, &sce->coeffs[start+(w+w2)*128], C34, sce->ics.swb_sizes[g],
sce->sf_idx[(w+w2)*16+g], sce->band_type[(w+w2)*16+g],
- s->lambda/band->threshold, INFINITY, &bits_tmp1, NULL, 0);
+ s->lambda/band->threshold, INFINITY, &bits_tmp1, NULL);
dist2 += quantize_band_cost(s, PCD, PCD34, sce->ics.swb_sizes[g],
sce->sf_idx[(w+w2)*16+g],
sce->band_type[(w+w2)*16+g],
- s->lambda/band->threshold, INFINITY, &bits_tmp2, NULL, 0);
+ s->lambda/band->threshold, INFINITY, &bits_tmp2, NULL);
bits1 += bits_tmp1;
bits2 += bits_tmp2;
}
diff --git a/libavcodec/aacenc_pred.c b/libavcodec/aacenc_pred.c
index d111192f0..447444cb8 100644
--- a/libavcodec/aacenc_pred.c
+++ b/libavcodec/aacenc_pred.c
@@ -271,9 +271,9 @@ void ff_aac_search_for_pred(AACEncContext *s, SingleChannelElement *sce)
/* Normal coefficients */
s->abs_pow34(O34, &sce->coeffs[start_coef], num_coeffs);
- dist1 = quantize_and_encode_band_cost(s, NULL, &sce->coeffs[start_coef], NULL,
- O34, num_coeffs, sce->sf_idx[sfb],
- cb_n, s->lambda / band->threshold, INFINITY, &cost1, NULL, 0);
+ dist1 = ff_quantize_and_encode_band_cost(s, NULL, &sce->coeffs[start_coef], NULL,
+ O34, num_coeffs, sce->sf_idx[sfb],
+ cb_n, s->lambda / band->threshold, INFINITY, &cost1, NULL);
cost_coeffs += cost1;
/* Encoded coefficients - needed for #bits, band type and quant. error */
@@ -284,9 +284,9 @@ void ff_aac_search_for_pred(AACEncContext *s, SingleChannelElement *sce)
cb_p = av_clip(find_min_book(find_max_val(1, num_coeffs, S34), sce->sf_idx[sfb]), cb_min, cb_max);
else
cb_p = cb_n;
- quantize_and_encode_band_cost(s, NULL, SENT, QERR, S34, num_coeffs,
- sce->sf_idx[sfb], cb_p, s->lambda / band->threshold, INFINITY,
- &cost2, NULL, 0);
+ ff_quantize_and_encode_band_cost(s, NULL, SENT, QERR, S34, num_coeffs,
+ sce->sf_idx[sfb], cb_p, s->lambda / band->threshold, INFINITY,
+ &cost2, NULL);
/* Reconstructed coefficients - needed for distortion measurements */
for (i = 0; i < num_coeffs; i++)
@@ -296,9 +296,9 @@ void ff_aac_search_for_pred(AACEncContext *s, SingleChannelElement *sce)
cb_p = av_clip(find_min_book(find_max_val(1, num_coeffs, P34), sce->sf_idx[sfb]), cb_min, cb_max);
else
cb_p = cb_n;
- dist2 = quantize_and_encode_band_cost(s, NULL, &sce->prcoeffs[start_coef], NULL,
- P34, num_coeffs, sce->sf_idx[sfb],
- cb_p, s->lambda / band->threshold, INFINITY, NULL, NULL, 0);
+ dist2 = ff_quantize_and_encode_band_cost(s, NULL, &sce->prcoeffs[start_coef], NULL,
+ P34, num_coeffs, sce->sf_idx[sfb],
+ cb_p, s->lambda / band->threshold, INFINITY, NULL, NULL);
for (i = 0; i < num_coeffs; i++)
dist_spec_err += (O34[i] - P34[i])*(O34[i] - P34[i]);
dist_spec_err *= s->lambda / band->threshold;
diff --git a/libavcodec/aacenc_quantization.h b/libavcodec/aacenc_quantization.h
index fc5a46b87..185430b0d 100644
--- a/libavcodec/aacenc_quantization.h
+++ b/libavcodec/aacenc_quantization.h
@@ -28,256 +28,41 @@
#ifndef AVCODEC_AACENC_QUANTIZATION_H
#define AVCODEC_AACENC_QUANTIZATION_H
-#include "aactab.h"
+#include
+
#include "aacenc.h"
-#include "aacenctab.h"
-#include "aacenc_utils.h"
+#include "put_bits.h"
-/**
- * Calculate rate distortion cost for quantizing with given codebook
- *
- * @return quantization distortion
- */
-static av_always_inline float quantize_and_encode_band_cost_template(
- struct AACEncContext *s,
- PutBitContext *pb, const float *in, float *out,
- const float *scaled, int size, int scale_idx,
- int cb, const float lambda, const float uplim,
- int *bits, float *energy, int BT_ZERO, int BT_UNSIGNED,
- int BT_PAIR, int BT_ESC, int BT_NOISE, int BT_STEREO,
- const float ROUNDING)
-{
- const int q_idx = POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512;
- const float Q = ff_aac_pow2sf_tab [q_idx];
- const float Q34 = ff_aac_pow34sf_tab[q_idx];
- const float IQ = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
- const float CLIPPED_ESCAPE = 165140.0f*IQ;
- int i, j;
- float cost = 0;
- float qenergy = 0;
- const int dim = BT_PAIR ? 2 : 4;
- int resbits = 0;
- int off;
- if (BT_ZERO || BT_NOISE || BT_STEREO) {
- for (i = 0; i < size; i++)
- cost += in[i]*in[i];
- if (bits)
- *bits = 0;
- if (energy)
- *energy = qenergy;
- if (out) {
- for (i = 0; i < size; i += dim)
- for (j = 0; j < dim; j++)
- out[i+j] = 0.0f;
- }
- return cost * lambda;
- }
- if (!scaled) {
- s->abs_pow34(s->scoefs, in, size);
- scaled = s->scoefs;
- }
- s->quant_bands(s->qcoefs, in, scaled, size, !BT_UNSIGNED, aac_cb_maxval[cb], Q34, ROUNDING);
- if (BT_UNSIGNED) {
- off = 0;
- } else {
- off = aac_cb_maxval[cb];
- }
- for (i = 0; i < size; i += dim) {
- const float *vec;
- int *quants = s->qcoefs + i;
- int curidx = 0;
- int curbits;
- float quantized, rd = 0.0f;
- for (j = 0; j < dim; j++) {
- curidx *= aac_cb_range[cb];
- curidx += quants[j] + off;
- }
- curbits = ff_aac_spectral_bits[cb-1][curidx];
- vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
- if (BT_UNSIGNED) {
- for (j = 0; j < dim; j++) {
- float t = fabsf(in[i+j]);
- float di;
- if (BT_ESC && vec[j] == 64.0f) { //FIXME: slow
- if (t >= CLIPPED_ESCAPE) {
- quantized = CLIPPED_ESCAPE;
- curbits += 21;
- } else {
- int c = av_clip_uintp2(quant(t, Q, ROUNDING), 13);
- quantized = c*cbrtf(c)*IQ;
- curbits += av_log2(c)*2 - 4 + 1;
- }
- } else {
- quantized = vec[j]*IQ;
- }
- di = t - quantized;
- if (out)
- out[i+j] = in[i+j] >= 0 ? quantized : -quantized;
- if (vec[j] != 0.0f)
- curbits++;
- qenergy += quantized*quantized;
- rd += di*di;
- }
- } else {
- for (j = 0; j < dim; j++) {
- quantized = vec[j]*IQ;
- qenergy += quantized*quantized;
- if (out)
- out[i+j] = quantized;
- rd += (in[i+j] - quantized)*(in[i+j] - quantized);
- }
- }
- cost += rd * lambda + curbits;
- resbits += curbits;
- if (cost >= uplim)
- return uplim;
- if (pb) {
- put_bits(pb, ff_aac_spectral_bits[cb-1][curidx], ff_aac_spectral_codes[cb-1][curidx]);
- if (BT_UNSIGNED)
- for (j = 0; j < dim; j++)
- if (ff_aac_codebook_vectors[cb-1][curidx*dim+j] != 0.0f)
- put_bits(pb, 1, in[i+j] < 0.0f);
- if (BT_ESC) {
- for (j = 0; j < 2; j++) {
- if (ff_aac_codebook_vectors[cb-1][curidx*2+j] == 64.0f) {
- int coef = av_clip_uintp2(quant(fabsf(in[i+j]), Q, ROUNDING), 13);
- int len = av_log2(coef);
-
- put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
- put_sbits(pb, len, coef);
- }
- }
- }
- }
- }
-
- if (bits)
- *bits = resbits;
- if (energy)
- *energy = qenergy;
- return cost;
-}
-
-static inline float quantize_and_encode_band_cost_NONE(struct AACEncContext *s, PutBitContext *pb,
- const float *in, float *quant, const float *scaled,
- int size, int scale_idx, int cb,
- const float lambda, const float uplim,
- int *bits, float *energy) {
- av_assert0(0);
- return 0.0f;
-}
-
-#define QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NAME, BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE, BT_STEREO, ROUNDING) \
-static float quantize_and_encode_band_cost_ ## NAME( \
- struct AACEncContext *s, \
- PutBitContext *pb, const float *in, float *quant, \
- const float *scaled, int size, int scale_idx, \
- int cb, const float lambda, const float uplim, \
- int *bits, float *energy) { \
- return quantize_and_encode_band_cost_template( \
- s, pb, in, quant, scaled, size, scale_idx, \
- BT_ESC ? ESC_BT : cb, lambda, uplim, bits, energy, \
- BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE, BT_STEREO, \
- ROUNDING); \
-}
-
-QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ZERO, 1, 0, 0, 0, 0, 0, ROUND_STANDARD)
-QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SQUAD, 0, 0, 0, 0, 0, 0, ROUND_STANDARD)
-QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UQUAD, 0, 1, 0, 0, 0, 0, ROUND_STANDARD)
-QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SPAIR, 0, 0, 1, 0, 0, 0, ROUND_STANDARD)
-QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UPAIR, 0, 1, 1, 0, 0, 0, ROUND_STANDARD)
-QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC, 0, 1, 1, 1, 0, 0, ROUND_STANDARD)
-QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC_RTZ, 0, 1, 1, 1, 0, 0, ROUND_TO_ZERO)
-QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NOISE, 0, 0, 0, 0, 1, 0, ROUND_STANDARD)
-QUANTIZE_AND_ENCODE_BAND_COST_FUNC(STEREO,0, 0, 0, 0, 0, 1, ROUND_STANDARD)
-
-static float (*const quantize_and_encode_band_cost_arr[])(
- struct AACEncContext *s,
- PutBitContext *pb, const float *in, float *quant,
- const float *scaled, int size, int scale_idx,
- int cb, const float lambda, const float uplim,
- int *bits, float *energy) = {
- quantize_and_encode_band_cost_ZERO,
- quantize_and_encode_band_cost_SQUAD,
- quantize_and_encode_band_cost_SQUAD,
- quantize_and_encode_band_cost_UQUAD,
- quantize_and_encode_band_cost_UQUAD,
- quantize_and_encode_band_cost_SPAIR,
- quantize_and_encode_band_cost_SPAIR,
- quantize_and_encode_band_cost_UPAIR,
- quantize_and_encode_band_cost_UPAIR,
- quantize_and_encode_band_cost_UPAIR,
- quantize_and_encode_band_cost_UPAIR,
- quantize_and_encode_band_cost_ESC,
- quantize_and_encode_band_cost_NONE, /* CB 12 doesn't exist */
- quantize_and_encode_band_cost_NOISE,
- quantize_and_encode_band_cost_STEREO,
- quantize_and_encode_band_cost_STEREO,
-};
-
-static float (*const quantize_and_encode_band_cost_rtz_arr[])(
- struct AACEncContext *s,
- PutBitContext *pb, const float *in, float *quant,
- const float *scaled, int size, int scale_idx,
- int cb, const float lambda, const float uplim,
- int *bits, float *energy) = {
- quantize_and_encode_band_cost_ZERO,
- quantize_and_encode_band_cost_SQUAD,
- quantize_and_encode_band_cost_SQUAD,
- quantize_and_encode_band_cost_UQUAD,
- quantize_and_encode_band_cost_UQUAD,
- quantize_and_encode_band_cost_SPAIR,
- quantize_and_encode_band_cost_SPAIR,
- quantize_and_encode_band_cost_UPAIR,
- quantize_and_encode_band_cost_UPAIR,
- quantize_and_encode_band_cost_UPAIR,
- quantize_and_encode_band_cost_UPAIR,
- quantize_and_encode_band_cost_ESC_RTZ,
- quantize_and_encode_band_cost_NONE, /* CB 12 doesn't exist */
- quantize_and_encode_band_cost_NOISE,
- quantize_and_encode_band_cost_STEREO,
- quantize_and_encode_band_cost_STEREO,
-};
-
-#define quantize_and_encode_band_cost( \
- s, pb, in, quant, scaled, size, scale_idx, cb, \
- lambda, uplim, bits, energy, rtz) \
- ((rtz) ? quantize_and_encode_band_cost_rtz_arr : quantize_and_encode_band_cost_arr)[cb]( \
- s, pb, in, quant, scaled, size, scale_idx, cb, \
- lambda, uplim, bits, energy)
+float ff_quantize_and_encode_band_cost(AACEncContext *s, PutBitContext *pb,
+ const float *in, float *quant, const float *scaled,
+ int size, int scale_idx, int cb,
+ const float lambda, const float uplim,
+ int *bits, float *energy);
static inline float quantize_band_cost(struct AACEncContext *s, const float *in,
const float *scaled, int size, int scale_idx,
int cb, const float lambda, const float uplim,
- int *bits, float *energy, int rtz)
+ int *bits, float *energy)
{
- return quantize_and_encode_band_cost(s, NULL, in, NULL, scaled, size, scale_idx,
- cb, lambda, uplim, bits, energy, rtz);
+ return ff_quantize_and_encode_band_cost(s, NULL, in, NULL, scaled, size, scale_idx,
+ cb, lambda, uplim, bits, energy);
}
static inline int quantize_band_cost_bits(struct AACEncContext *s, const float *in,
const float *scaled, int size, int scale_idx,
int cb, const float lambda, const float uplim,
- int *bits, float *energy, int rtz)
+ int *bits, float *energy)
{
int auxbits;
- quantize_and_encode_band_cost(s, NULL, in, NULL, scaled, size, scale_idx,
- cb, 0.0f, uplim, &auxbits, energy, rtz);
+ ff_quantize_and_encode_band_cost(s, NULL, in, NULL, scaled, size, scale_idx,
+ cb, 0.0f, uplim, &auxbits, energy);
if (bits) {
*bits = auxbits;
}
return auxbits;
}
-static inline void quantize_and_encode_band(struct AACEncContext *s, PutBitContext *pb,
- const float *in, float *out, int size, int scale_idx,
- int cb, const float lambda, int rtz)
-{
- quantize_and_encode_band_cost(s, pb, in, out, NULL, size, scale_idx, cb, lambda,
- INFINITY, NULL, NULL, rtz);
-}
-
#include "aacenc_quantization_misc.h"
#endif /* AVCODEC_AACENC_QUANTIZATION_H */
diff --git a/libavcodec/aacenc_quantization_misc.h b/libavcodec/aacenc_quantization_misc.h
index 28676ca8d..c789754f4 100644
--- a/libavcodec/aacenc_quantization_misc.h
+++ b/libavcodec/aacenc_quantization_misc.h
@@ -38,7 +38,7 @@ static inline float quantize_band_cost_cached(struct AACEncContext *s, int w, in
entry = &s->quantize_band_cost_cache[scale_idx][w*16+g];
if (entry->generation != s->quantize_band_cost_cache_generation || entry->cb != cb || entry->rtz != rtz) {
entry->rd = quantize_band_cost(s, in, scaled, size, scale_idx,
- cb, lambda, uplim, &entry->bits, &entry->energy, rtz);
+ cb, lambda, uplim, &entry->bits, &entry->energy);
entry->cb = cb;
entry->rtz = rtz;
entry->generation = s->quantize_band_cost_cache_generation;
diff --git a/libavcodec/aacenc_tns.c b/libavcodec/aacenc_tns.c
index 2ffe1f8de..195ff5e2b 100644
--- a/libavcodec/aacenc_tns.c
+++ b/libavcodec/aacenc_tns.c
@@ -30,7 +30,6 @@
#include "aacenc_tns.h"
#include "aactab.h"
#include "aacenc_utils.h"
-#include "aacenc_quantization.h"
/* Could be set to 3 to save an additional bit at the cost of little quality */
#define TNS_Q_BITS 4
diff --git a/libavcodec/aacpsdsp.h b/libavcodec/aacpsdsp.h
index 917ac5303..8b32761bd 100644
--- a/libavcodec/aacpsdsp.h
+++ b/libavcodec/aacpsdsp.h
@@ -55,6 +55,7 @@ void AAC_RENAME(ff_psdsp_init)(PSDSPContext *s);
void ff_psdsp_init_arm(PSDSPContext *s);
void ff_psdsp_init_aarch64(PSDSPContext *s);
void ff_psdsp_init_mips(PSDSPContext *s);
+void ff_psdsp_init_riscv(PSDSPContext *s);
void ff_psdsp_init_x86(PSDSPContext *s);
#endif /* AVCODEC_AACPSDSP_H */
diff --git a/libavcodec/aacpsdsp_template.c b/libavcodec/aacpsdsp_template.c
index e64403758..c063788b8 100644
--- a/libavcodec/aacpsdsp_template.c
+++ b/libavcodec/aacpsdsp_template.c
@@ -47,21 +47,24 @@ static void ps_hybrid_analysis_c(INTFLOAT (*out)[2], INTFLOAT (*in)[2],
const INTFLOAT (*filter)[8][2],
ptrdiff_t stride, int n)
{
- int i, j;
+ INT64FLOAT inre0[6], inre1[6], inim0[6], inim1[6];
- for (i = 0; i < n; i++) {
+ for (int j = 0; j < 6; j++) {
+ inre0[j] = in[j][0] + in[12 - j][0];
+ inre1[j] = in[j][1] - in[12 - j][1];
+ inim0[j] = in[j][1] + in[12 - j][1];
+ inim1[j] = in[j][0] - in[12 - j][0];
+ }
+
+ for (int i = 0; i < n; i++) {
INT64FLOAT sum_re = (INT64FLOAT)filter[i][6][0] * in[6][0];
INT64FLOAT sum_im = (INT64FLOAT)filter[i][6][0] * in[6][1];
- for (j = 0; j < 6; j++) {
- INT64FLOAT in0_re = in[j][0];
- INT64FLOAT in0_im = in[j][1];
- INT64FLOAT in1_re = in[12-j][0];
- INT64FLOAT in1_im = in[12-j][1];
- sum_re += (INT64FLOAT)filter[i][j][0] * (in0_re + in1_re) -
- (INT64FLOAT)filter[i][j][1] * (in0_im - in1_im);
- sum_im += (INT64FLOAT)filter[i][j][0] * (in0_im + in1_im) +
- (INT64FLOAT)filter[i][j][1] * (in0_re - in1_re);
+ for (int j = 0; j < 6; j++) {
+ sum_re += (INT64FLOAT)filter[i][j][0] * inre0[j] -
+ (INT64FLOAT)filter[i][j][1] * inre1[j];
+ sum_im += (INT64FLOAT)filter[i][j][0] * inim0[j] +
+ (INT64FLOAT)filter[i][j][1] * inim1[j];
}
#if USE_FIXED
out[i * stride][0] = (int)((sum_re + 0x40000000) >> 31);
@@ -227,6 +230,8 @@ av_cold void AAC_RENAME(ff_psdsp_init)(PSDSPContext *s)
ff_psdsp_init_aarch64(s);
#elif ARCH_MIPS
ff_psdsp_init_mips(s);
+#elif ARCH_RISCV
+ ff_psdsp_init_riscv(s);
#elif ARCH_X86
ff_psdsp_init_x86(s);
#endif
diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c
index b74cd82ac..47aa6cb3c 100644
--- a/libavcodec/aacsbr.c
+++ b/libavcodec/aacsbr.c
@@ -31,7 +31,6 @@
#include "sbr.h"
#include "aacsbr.h"
#include "aacsbrdata.h"
-#include "fft.h"
#include "internal.h"
#include "aacps.h"
#include "sbrdsp.h"
diff --git a/libavcodec/aacsbr.h b/libavcodec/aacsbr.h
index dd8b66c7b..d70b19e11 100644
--- a/libavcodec/aacsbr.h
+++ b/libavcodec/aacsbr.h
@@ -81,7 +81,7 @@ static const int8_t vlc_sbr_lav[10] =
/** Initialize SBR. */
void AAC_RENAME(ff_aac_sbr_init)(void);
/** Initialize one SBR context. */
-void AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr, int id_aac);
+int AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr, int id_aac);
/** Close one SBR context. */
void AAC_RENAME(ff_aac_sbr_ctx_close)(SpectralBandReplication *sbr);
/** Decode one SBR element. */
diff --git a/libavcodec/aacsbr_fixed.c b/libavcodec/aacsbr_fixed.c
index ffa63f264..cac472552 100644
--- a/libavcodec/aacsbr_fixed.c
+++ b/libavcodec/aacsbr_fixed.c
@@ -60,7 +60,6 @@
#include "sbr.h"
#include "aacsbr.h"
#include "aacsbrdata.h"
-#include "fft.h"
#include "aacps.h"
#include "sbrdsp.h"
#include "libavutil/internal.h"
diff --git a/libavcodec/aacsbr_tablegen_common.h b/libavcodec/aacsbr_tablegen_common.h
deleted file mode 100644
index 8e0dd9e1f..000000000
--- a/libavcodec/aacsbr_tablegen_common.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Header file for hardcoded AAC SBR windows
- *
- * Copyright (c) 2014 Reimar Döffinger
- *
- * 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_AACSBR_TABLEGEN_COMMON_H
-#define AVCODEC_AACSBR_TABLEGEN_COMMON_H
-#include "aac_defines.h"
-#include "libavutil/mem.h"
-
-///< window coefficients for analysis/synthesis QMF banks
-static DECLARE_ALIGNED(32, INTFLOAT, sbr_qmf_window_ds)[320];
-static DECLARE_ALIGNED(32, INTFLOAT, sbr_qmf_window_us)[640] = {
- Q31( 0.0000000000f), Q31(-0.0005525286f), Q31(-0.0005617692f), Q31(-0.0004947518f),
- Q31(-0.0004875227f), Q31(-0.0004893791f), Q31(-0.0005040714f), Q31(-0.0005226564f),
- Q31(-0.0005466565f), Q31(-0.0005677802f), Q31(-0.0005870930f), Q31(-0.0006132747f),
- Q31(-0.0006312493f), Q31(-0.0006540333f), Q31(-0.0006777690f), Q31(-0.0006941614f),
- Q31(-0.0007157736f), Q31(-0.0007255043f), Q31(-0.0007440941f), Q31(-0.0007490598f),
- Q31(-0.0007681371f), Q31(-0.0007724848f), Q31(-0.0007834332f), Q31(-0.0007779869f),
- Q31(-0.0007803664f), Q31(-0.0007801449f), Q31(-0.0007757977f), Q31(-0.0007630793f),
- Q31(-0.0007530001f), Q31(-0.0007319357f), Q31(-0.0007215391f), Q31(-0.0006917937f),
- Q31(-0.0006650415f), Q31(-0.0006341594f), Q31(-0.0005946118f), Q31(-0.0005564576f),
- Q31(-0.0005145572f), Q31(-0.0004606325f), Q31(-0.0004095121f), Q31(-0.0003501175f),
- Q31(-0.0002896981f), Q31(-0.0002098337f), Q31(-0.0001446380f), Q31(-0.0000617334f),
- Q31( 0.0000134949f), Q31( 0.0001094383f), Q31( 0.0002043017f), Q31( 0.0002949531f),
- Q31( 0.0004026540f), Q31( 0.0005107388f), Q31( 0.0006239376f), Q31( 0.0007458025f),
- Q31( 0.0008608443f), Q31( 0.0009885988f), Q31( 0.0011250155f), Q31( 0.0012577884f),
- Q31( 0.0013902494f), Q31( 0.0015443219f), Q31( 0.0016868083f), Q31( 0.0018348265f),
- Q31( 0.0019841140f), Q31( 0.0021461583f), Q31( 0.0023017254f), Q31( 0.0024625616f),
- Q31( 0.0026201758f), Q31( 0.0027870464f), Q31( 0.0029469447f), Q31( 0.0031125420f),
- Q31( 0.0032739613f), Q31( 0.0034418874f), Q31( 0.0036008268f), Q31( 0.0037603922f),
- Q31( 0.0039207432f), Q31( 0.0040819753f), Q31( 0.0042264269f), Q31( 0.0043730719f),
- Q31( 0.0045209852f), Q31( 0.0046606460f), Q31( 0.0047932560f), Q31( 0.0049137603f),
- Q31( 0.0050393022f), Q31( 0.0051407353f), Q31( 0.0052461166f), Q31( 0.0053471681f),
- Q31( 0.0054196775f), Q31( 0.0054876040f), Q31( 0.0055475714f), Q31( 0.0055938023f),
- Q31( 0.0056220643f), Q31( 0.0056455196f), Q31( 0.0056389199f), Q31( 0.0056266114f),
- Q31( 0.0055917128f), Q31( 0.0055404363f), Q31( 0.0054753783f), Q31( 0.0053838975f),
- Q31( 0.0052715758f), Q31( 0.0051382275f), Q31( 0.0049839687f), Q31( 0.0048109469f),
- Q31( 0.0046039530f), Q31( 0.0043801861f), Q31( 0.0041251642f), Q31( 0.0038456408f),
- Q31( 0.0035401246f), Q31( 0.0032091885f), Q31( 0.0028446757f), Q31( 0.0024508540f),
- Q31( 0.0020274176f), Q31( 0.0015784682f), Q31( 0.0010902329f), Q31( 0.0005832264f),
- Q31( 0.0000276045f), Q31(-0.0005464280f), Q31(-0.0011568135f), Q31(-0.0018039472f),
- Q31(-0.0024826723f), Q31(-0.0031933778f), Q31(-0.0039401124f), Q31(-0.0047222596f),
- Q31(-0.0055337211f), Q31(-0.0063792293f), Q31(-0.0072615816f), Q31(-0.0081798233f),
- Q31(-0.0091325329f), Q31(-0.0101150215f), Q31(-0.0111315548f), Q31(-0.0121849995f),
- Q31( 0.0132718220f), Q31( 0.0143904666f), Q31( 0.0155405553f), Q31( 0.0167324712f),
- Q31( 0.0179433381f), Q31( 0.0191872431f), Q31( 0.0204531793f), Q31( 0.0217467550f),
- Q31( 0.0230680169f), Q31( 0.0244160992f), Q31( 0.0257875847f), Q31( 0.0271859429f),
- Q31( 0.0286072173f), Q31( 0.0300502657f), Q31( 0.0315017608f), Q31( 0.0329754081f),
- Q31( 0.0344620948f), Q31( 0.0359697560f), Q31( 0.0374812850f), Q31( 0.0390053679f),
- Q31( 0.0405349170f), Q31( 0.0420649094f), Q31( 0.0436097542f), Q31( 0.0451488405f),
- Q31( 0.0466843027f), Q31( 0.0482165720f), Q31( 0.0497385755f), Q31( 0.0512556155f),
- Q31( 0.0527630746f), Q31( 0.0542452768f), Q31( 0.0557173648f), Q31( 0.0571616450f),
- Q31( 0.0585915683f), Q31( 0.0599837480f), Q31( 0.0613455171f), Q31( 0.0626857808f),
- Q31( 0.0639715898f), Q31( 0.0652247106f), Q31( 0.0664367512f), Q31( 0.0676075985f),
- Q31( 0.0687043828f), Q31( 0.0697630244f), Q31( 0.0707628710f), Q31( 0.0717002673f),
- Q31( 0.0725682583f), Q31( 0.0733620255f), Q31( 0.0741003642f), Q31( 0.0747452558f),
- Q31( 0.0753137336f), Q31( 0.0758008358f), Q31( 0.0761992479f), Q31( 0.0764992170f),
- Q31( 0.0767093490f), Q31( 0.0768173975f), Q31( 0.0768230011f), Q31( 0.0767204924f),
- Q31( 0.0765050718f), Q31( 0.0761748321f), Q31( 0.0757305756f), Q31( 0.0751576255f),
- Q31( 0.0744664394f), Q31( 0.0736406005f), Q31( 0.0726774642f), Q31( 0.0715826364f),
- Q31( 0.0703533073f), Q31( 0.0689664013f), Q31( 0.0674525021f), Q31( 0.0657690668f),
- Q31( 0.0639444805f), Q31( 0.0619602779f), Q31( 0.0598166570f), Q31( 0.0575152691f),
- Q31( 0.0550460034f), Q31( 0.0524093821f), Q31( 0.0495978676f), Q31( 0.0466303305f),
- Q31( 0.0434768782f), Q31( 0.0401458278f), Q31( 0.0366418116f), Q31( 0.0329583930f),
- Q31( 0.0290824006f), Q31( 0.0250307561f), Q31( 0.0207997072f), Q31( 0.0163701258f),
- Q31( 0.0117623832f), Q31( 0.0069636862f), Q31( 0.0019765601f), Q31(-0.0032086896f),
- Q31(-0.0085711749f), Q31(-0.0141288827f), Q31(-0.0198834129f), Q31(-0.0258227288f),
- Q31(-0.0319531274f), Q31(-0.0382776572f), Q31(-0.0447806821f), Q31(-0.0514804176f),
- Q31(-0.0583705326f), Q31(-0.0654409853f), Q31(-0.0726943300f), Q31(-0.0801372934f),
- Q31(-0.0877547536f), Q31(-0.0955533352f), Q31(-0.1035329531f), Q31(-0.1116826931f),
- Q31(-0.1200077984f), Q31(-0.1285002850f), Q31(-0.1371551761f), Q31(-0.1459766491f),
- Q31(-0.1549607071f), Q31(-0.1640958855f), Q31(-0.1733808172f), Q31(-0.1828172548f),
- Q31(-0.1923966745f), Q31(-0.2021250176f), Q31(-0.2119735853f), Q31(-0.2219652696f),
- Q31(-0.2320690870f), Q31(-0.2423016884f), Q31(-0.2526480309f), Q31(-0.2631053299f),
- Q31(-0.2736634040f), Q31(-0.2843214189f), Q31(-0.2950716717f), Q31(-0.3059098575f),
- Q31(-0.3168278913f), Q31(-0.3278113727f), Q31(-0.3388722693f), Q31(-0.3499914122f),
- Q31( 0.3611589903f), Q31( 0.3723795546f), Q31( 0.3836350013f), Q31( 0.3949211761f),
- Q31( 0.4062317676f), Q31( 0.4175696896f), Q31( 0.4289119920f), Q31( 0.4402553754f),
- Q31( 0.4515996535f), Q31( 0.4629308085f), Q31( 0.4742453214f), Q31( 0.4855253091f),
- Q31( 0.4967708254f), Q31( 0.5079817500f), Q31( 0.5191234970f), Q31( 0.5302240895f),
- Q31( 0.5412553448f), Q31( 0.5522051258f), Q31( 0.5630789140f), Q31( 0.5738524131f),
- Q31( 0.5845403235f), Q31( 0.5951123086f), Q31( 0.6055783538f), Q31( 0.6159109932f),
- Q31( 0.6261242695f), Q31( 0.6361980107f), Q31( 0.6461269695f), Q31( 0.6559016302f),
- Q31( 0.6655139880f), Q31( 0.6749663190f), Q31( 0.6842353293f), Q31( 0.6933282376f),
- Q31( 0.7022388719f), Q31( 0.7109410426f), Q31( 0.7194462634f), Q31( 0.7277448900f),
- Q31( 0.7358211758f), Q31( 0.7436827863f), Q31( 0.7513137456f), Q31( 0.7587080760f),
- Q31( 0.7658674865f), Q31( 0.7727780881f), Q31( 0.7794287519f), Q31( 0.7858353120f),
- Q31( 0.7919735841f), Q31( 0.7978466413f), Q31( 0.8034485751f), Q31( 0.8087695004f),
- Q31( 0.8138191270f), Q31( 0.8185776004f), Q31( 0.8230419890f), Q31( 0.8272275347f),
- Q31( 0.8311038457f), Q31( 0.8346937361f), Q31( 0.8379717337f), Q31( 0.8409541392f),
- Q31( 0.8436238281f), Q31( 0.8459818469f), Q31( 0.8480315777f), Q31( 0.8497805198f),
- Q31( 0.8511971524f), Q31( 0.8523047035f), Q31( 0.8531020949f), Q31( 0.8535720573f),
- Q31( 0.8537385600f),
-};
-
-#endif /* AVCODEC_AACSBR_TABLEGEN_COMMON_H */
diff --git a/libavcodec/aacsbr_template.c b/libavcodec/aacsbr_template.c
index b72c94b76..cdca402f0 100644
--- a/libavcodec/aacsbr_template.c
+++ b/libavcodec/aacsbr_template.c
@@ -89,10 +89,14 @@ static void sbr_turnoff(SpectralBandReplication *sbr) {
memset(&sbr->spectrum_params, -1, sizeof(SpectrumParameters));
}
-av_cold void AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr, int id_aac)
+av_cold int AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr, int id_aac)
{
- if(sbr->mdct.mdct_bits)
- return;
+ int ret;
+ float scale;
+
+ if (sbr->mdct)
+ return 0;
+
sbr->kx[0] = sbr->kx[1];
sbr->id_aac = id_aac;
sbr_turnoff(sbr);
@@ -101,17 +105,32 @@ av_cold void AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplica
/* SBR requires samples to be scaled to +/-32768.0 to work correctly.
* mdct scale factors are adjusted to scale up from +/-1.0 at analysis
* and scale back down at synthesis. */
- AAC_RENAME_32(ff_mdct_init)(&sbr->mdct, 7, 1, 1.0 / (64 * 32768.0));
- AAC_RENAME_32(ff_mdct_init)(&sbr->mdct_ana, 7, 1, -2.0 * 32768.0);
+
+ scale = USE_FIXED ? 1 : 1.0 / (64 * 32768);
+ ret = av_tx_init(&sbr->mdct, &sbr->mdct_fn,
+ USE_FIXED ? AV_TX_INT32_MDCT : AV_TX_FLOAT_MDCT,
+ 1, 64, &scale, 0);
+ if (ret < 0)
+ return ret;
+
+ scale = USE_FIXED ? -1.0 : -2.0 * 32768;
+ ret = av_tx_init(&sbr->mdct_ana, &sbr->mdct_ana_fn,
+ USE_FIXED ? AV_TX_INT32_MDCT : AV_TX_FLOAT_MDCT,
+ 1, 64, &scale, 0);
+ if (ret < 0)
+ return ret;
+
AAC_RENAME(ff_ps_ctx_init)(&sbr->ps);
AAC_RENAME(ff_sbrdsp_init)(&sbr->dsp);
aacsbr_func_ptr_init(&sbr->c);
+
+ return 0;
}
av_cold void AAC_RENAME(ff_aac_sbr_ctx_close)(SpectralBandReplication *sbr)
{
- AAC_RENAME_32(ff_mdct_end)(&sbr->mdct);
- AAC_RENAME_32(ff_mdct_end)(&sbr->mdct_ana);
+ av_tx_uninit(&sbr->mdct);
+ av_tx_uninit(&sbr->mdct_ana);
}
static int qsort_comparison_function_int16(const void *a, const void *b)
@@ -955,6 +974,8 @@ static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
} else {
*num_bits_left -= ff_ps_read_data(ac->avctx, gb, &sbr->ps.common, *num_bits_left);
ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
+ // ensure the warning is not printed if PS extension is present
+ ac->warned_he_aac_mono = 1;
}
break;
default:
@@ -1162,9 +1183,11 @@ int AAC_RENAME(ff_decode_sbr_extension)(AACContext *ac, SpectralBandReplication
*/
#ifndef sbr_qmf_analysis
#if USE_FIXED
-static void sbr_qmf_analysis(AVFixedDSPContext *dsp, FFTContext *mdct,
+static void sbr_qmf_analysis(AVFixedDSPContext *dsp, AVTXContext *mdct,
+ av_tx_fn mdct_fn,
#else
-static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
+static void sbr_qmf_analysis(AVFloatDSPContext *dsp, AVTXContext *mdct,
+ av_tx_fn mdct_fn,
#endif /* USE_FIXED */
SBRDSPContext *sbrdsp, const INTFLOAT *in, INTFLOAT *x,
INTFLOAT z[320], INTFLOAT W[2][32][32][2], int buf_idx)
@@ -1195,7 +1218,7 @@ static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
}
}
#endif
- mdct->imdct_half(mdct, z, z+64);
+ mdct_fn(mdct, z, z + 64, sizeof(INTFLOAT));
sbrdsp->qmf_post_shuffle(W[buf_idx][i], z);
x += 32;
}
@@ -1207,7 +1230,7 @@ static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
* (14496-3 sp04 p206)
*/
#ifndef sbr_qmf_synthesis
-static void sbr_qmf_synthesis(FFTContext *mdct,
+static void sbr_qmf_synthesis(AVTXContext *mdct, av_tx_fn mdct_fn,
#if USE_FIXED
SBRDSPContext *sbrdsp, AVFixedDSPContext *dsp,
#else
@@ -1235,12 +1258,12 @@ static void sbr_qmf_synthesis(FFTContext *mdct,
X[0][i][ n] = -X[0][i][n];
X[0][i][32+n] = X[1][i][31-n];
}
- mdct->imdct_half(mdct, mdct_buf[0], X[0][i]);
+ mdct_fn(mdct, mdct_buf[0], X[0][i], sizeof(INTFLOAT));
sbrdsp->qmf_deint_neg(v, mdct_buf[0]);
} else {
sbrdsp->neg_odd_64(X[1][i]);
- mdct->imdct_half(mdct, mdct_buf[0], X[0][i]);
- mdct->imdct_half(mdct, mdct_buf[1], X[1][i]);
+ mdct_fn(mdct, mdct_buf[0], X[0][i], sizeof(INTFLOAT));
+ mdct_fn(mdct, mdct_buf[1], X[1][i], sizeof(INTFLOAT));
sbrdsp->qmf_deint_bfly(v, mdct_buf[1], mdct_buf[0]);
}
dsp->vector_fmul (out, v , sbr_qmf_window , 64 >> div);
@@ -1505,7 +1528,8 @@ void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication *sbr, int
}
for (ch = 0; ch < nch; ch++) {
/* decode channel */
- sbr_qmf_analysis(ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
+ sbr_qmf_analysis(ac->fdsp, sbr->mdct_ana, sbr->mdct_ana_fn, &sbr->dsp,
+ ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
(INTFLOAT*)sbr->qmf_filter_scratch,
sbr->data[ch].W, sbr->data[ch].Ypos);
sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low,
@@ -1552,13 +1576,13 @@ void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication *sbr, int
nch = 2;
}
- sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, ac->fdsp,
+ sbr_qmf_synthesis(sbr->mdct, sbr->mdct_fn, &sbr->dsp, ac->fdsp,
L, sbr->X[0], sbr->qmf_filter_scratch,
sbr->data[0].synthesis_filterbank_samples,
&sbr->data[0].synthesis_filterbank_samples_offset,
downsampled);
if (nch == 2)
- sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, ac->fdsp,
+ sbr_qmf_synthesis(sbr->mdct, sbr->mdct_fn, &sbr->dsp, ac->fdsp,
R, sbr->X[1], sbr->qmf_filter_scratch,
sbr->data[1].synthesis_filterbank_samples,
&sbr->data[1].synthesis_filterbank_samples_offset,
diff --git a/libavcodec/aacsbrdata.h b/libavcodec/aacsbrdata.h
index 7a11594c9..7bb45b229 100644
--- a/libavcodec/aacsbrdata.h
+++ b/libavcodec/aacsbrdata.h
@@ -29,6 +29,7 @@
#define AVCODEC_AACSBRDATA_H
#include
+#include "libavutil/attributes_internal.h"
#include "libavutil/mem_internal.h"
#include "aac_defines.h"
@@ -268,7 +269,7 @@ static const int8_t sbr_offset[6][16] = {
};
/* First eight entries repeated at end to simplify SIMD implementations. */
-const DECLARE_ALIGNED(16, INTFLOAT, AAC_RENAME(ff_sbr_noise_table))[][2] = {
+const attribute_visibility_hidden DECLARE_ALIGNED(16, INTFLOAT, AAC_RENAME(ff_sbr_noise_table))[][2] = {
{Q31(-0.99948153278296f), Q31(-0.59483417516607f)}, {Q31( 0.97113454393991f), Q31(-0.67528515225647f)},
{Q31( 0.14130051758487f), Q31(-0.95090983575689f)}, {Q31(-0.47005496701697f), Q31(-0.37340549728647f)},
{Q31( 0.80705063769351f), Q31( 0.29653668284408f)}, {Q31(-0.38981478896926f), Q31( 0.89572605717087f)},
diff --git a/libavcodec/aarch64/Makefile b/libavcodec/aarch64/Makefile
index 9ce21566c..02fb51c3a 100644
--- a/libavcodec/aarch64/Makefile
+++ b/libavcodec/aarch64/Makefile
@@ -67,4 +67,5 @@ NEON-OBJS-$(CONFIG_VP9_DECODER) += aarch64/vp9itxfm_16bpp_neon.o \
aarch64/vp9mc_neon.o
NEON-OBJS-$(CONFIG_HEVC_DECODER) += aarch64/hevcdsp_idct_neon.o \
aarch64/hevcdsp_init_aarch64.o \
+ aarch64/hevcdsp_qpel_neon.o \
aarch64/hevcdsp_sao_neon.o
diff --git a/libavcodec/aarch64/fft_init_aarch64.c b/libavcodec/aarch64/fft_init_aarch64.c
index db285205a..77f560796 100644
--- a/libavcodec/aarch64/fft_init_aarch64.c
+++ b/libavcodec/aarch64/fft_init_aarch64.c
@@ -38,8 +38,10 @@ av_cold void ff_fft_init_aarch64(FFTContext *s)
int cpu_flags = av_get_cpu_flags();
if (have_neon(cpu_flags)) {
- s->fft_permute = ff_fft_permute_neon;
- s->fft_calc = ff_fft_calc_neon;
+ if (s->nbits < 17) {
+ s->fft_permute = ff_fft_permute_neon;
+ s->fft_calc = ff_fft_calc_neon;
+ }
#if CONFIG_MDCT
s->imdct_calc = ff_imdct_calc_neon;
s->imdct_half = ff_imdct_half_neon;
diff --git a/libavcodec/aarch64/fft_neon.S b/libavcodec/aarch64/fft_neon.S
index 9ff3f9c52..d7225511d 100644
--- a/libavcodec/aarch64/fft_neon.S
+++ b/libavcodec/aarch64/fft_neon.S
@@ -342,8 +342,7 @@ endfunc
function fft\n\()_neon, align=6
AARCH64_VALID_JUMP_TARGET
AARCH64_SIGN_LINK_REGISTER
- sub sp, sp, #16
- stp x28, x30, [sp]
+ stp x28, x30, [sp, #-16]!
add x28, x0, #\n4*2*8
bl fft\n2\()_neon
mov x0, x28
diff --git a/libavcodec/aarch64/fmtconvert_init.c b/libavcodec/aarch64/fmtconvert_init.c
index 210e74b65..e0990afab 100644
--- a/libavcodec/aarch64/fmtconvert_init.c
+++ b/libavcodec/aarch64/fmtconvert_init.c
@@ -22,7 +22,6 @@
#include "libavutil/attributes.h"
#include "libavutil/aarch64/cpu.h"
-#include "libavcodec/avcodec.h"
#include "libavcodec/fmtconvert.h"
void ff_int32_to_float_fmul_array8_neon(FmtConvertContext *c, float *dst,
@@ -31,8 +30,7 @@ void ff_int32_to_float_fmul_array8_neon(FmtConvertContext *c, float *dst,
void ff_int32_to_float_fmul_scalar_neon(float *dst, const int32_t *src,
float mul, int len);
-av_cold void ff_fmt_convert_init_aarch64(FmtConvertContext *c,
- AVCodecContext *avctx)
+av_cold void ff_fmt_convert_init_aarch64(FmtConvertContext *c)
{
int cpu_flags = av_get_cpu_flags();
diff --git a/libavcodec/aarch64/h264chroma_init_aarch64.c b/libavcodec/aarch64/h264chroma_init_aarch64.c
index fa6e0eaf1..00fc7b20f 100644
--- a/libavcodec/aarch64/h264chroma_init_aarch64.c
+++ b/libavcodec/aarch64/h264chroma_init_aarch64.c
@@ -28,18 +28,18 @@
#include "config.h"
-void ff_put_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_h264_chroma_mc8_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_put_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_h264_chroma_mc4_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_put_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_h264_chroma_mc2_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_avg_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_avg_h264_chroma_mc8_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_avg_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_avg_h264_chroma_mc4_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_avg_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_avg_h264_chroma_mc2_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
av_cold void ff_h264chroma_init_aarch64(H264ChromaContext *c, int bit_depth)
diff --git a/libavcodec/aarch64/h264cmc_neon.S b/libavcodec/aarch64/h264cmc_neon.S
index f8e940785..88ccd727d 100644
--- a/libavcodec/aarch64/h264cmc_neon.S
+++ b/libavcodec/aarch64/h264cmc_neon.S
@@ -23,7 +23,7 @@
#include "libavutil/aarch64/asm.S"
-/* chroma_mc8(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y) */
+/* chroma_mc8(uint8_t *dst, const uint8_t *src, ptrdiff_t stride, int h, int x, int y) */
.macro h264_chroma_mc8 type, codec=h264
function ff_\type\()_\codec\()_chroma_mc8_neon, export=1
.ifc \type,avg
@@ -193,7 +193,7 @@ function ff_\type\()_\codec\()_chroma_mc8_neon, export=1
endfunc
.endm
-/* chroma_mc4(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y) */
+/* chroma_mc4(uint8_t *dst, const uint8_t *src, ptrdiff_t stride, int h, int x, int y) */
.macro h264_chroma_mc4 type, codec=h264
function ff_\type\()_\codec\()_chroma_mc4_neon, export=1
.ifc \type,avg
diff --git a/libavcodec/aarch64/h264idct_neon.S b/libavcodec/aarch64/h264idct_neon.S
index 7d2879b0c..375da31d6 100644
--- a/libavcodec/aarch64/h264idct_neon.S
+++ b/libavcodec/aarch64/h264idct_neon.S
@@ -157,8 +157,7 @@ function ff_h264_idct_add16intra_neon, export=1
endfunc
function ff_h264_idct_add8_neon, export=1
- sub sp, sp, #0x40
- stp x19, x20, [sp]
+ stp x19, x20, [sp, #-0x40]!
mov x12, x30
ldp x6, x15, [x0] // dest[0], dest[1]
add x5, x1, #16*4 // block_offset
@@ -187,8 +186,7 @@ function ff_h264_idct_add8_neon, export=1
csel x6, x15, x6, eq
cmp x10, #20
b.lt 1b
- ldp x19, x20, [sp]
- add sp, sp, #0x40
+ ldp x19, x20, [sp], #0x40
ret x12
endfunc
diff --git a/libavcodec/aarch64/hevcdsp_idct_neon.S b/libavcodec/aarch64/hevcdsp_idct_neon.S
index 086943129..124c50998 100644
--- a/libavcodec/aarch64/hevcdsp_idct_neon.S
+++ b/libavcodec/aarch64/hevcdsp_idct_neon.S
@@ -5,7 +5,7 @@
*
* Ported from arm/hevcdsp_idct_neon.S by
* Copyright (c) 2020 Reimar Döffinger
- * Copyright (c) 2020 Josh Dekker
+ * Copyright (c) 2020 J. Dekker
*
* This file is part of FFmpeg.
*
@@ -27,21 +27,21 @@
#include "libavutil/aarch64/asm.S"
const trans, align=4
- .short 64, 83, 64, 36
- .short 89, 75, 50, 18
- .short 90, 87, 80, 70
- .short 57, 43, 25, 9
- .short 90, 90, 88, 85
- .short 82, 78, 73, 67
- .short 61, 54, 46, 38
- .short 31, 22, 13, 4
+ .short 64, 83, 64, 36
+ .short 89, 75, 50, 18
+ .short 90, 87, 80, 70
+ .short 57, 43, 25, 9
+ .short 90, 90, 88, 85
+ .short 82, 78, 73, 67
+ .short 61, 54, 46, 38
+ .short 31, 22, 13, 4
endconst
-.macro clip10 in1, in2, c1, c2
- smax \in1, \in1, \c1
- smax \in2, \in2, \c1
- smin \in1, \in1, \c2
- smin \in2, \in2, \c2
+.macro clip2 in1, in2, min, max
+ smax \in1, \in1, \min
+ smax \in2, \in2, \min
+ smin \in1, \in1, \max
+ smin \in2, \in2, \max
.endm
function ff_hevc_add_residual_4x4_8_neon, export=1
@@ -50,13 +50,13 @@ function ff_hevc_add_residual_4x4_8_neon, export=1
ld1 {v2.s}[1], [x0], x2
ld1 {v2.s}[2], [x0], x2
ld1 {v2.s}[3], [x0], x2
- sub x0, x0, x2, lsl #2
- uxtl v6.8h, v2.8b
- uxtl2 v7.8h, v2.16b
- sqadd v0.8h, v0.8h, v6.8h
- sqadd v1.8h, v1.8h, v7.8h
- sqxtun v0.8b, v0.8h
- sqxtun2 v0.16b, v1.8h
+ sub x0, x0, x2, lsl #2
+ uxtl v6.8h, v2.8b
+ uxtl2 v7.8h, v2.16b
+ sqadd v0.8h, v0.8h, v6.8h
+ sqadd v1.8h, v1.8h, v7.8h
+ sqxtun v0.8b, v0.8h
+ sqxtun2 v0.16b, v1.8h
st1 {v0.s}[0], [x0], x2
st1 {v0.s}[1], [x0], x2
st1 {v0.s}[2], [x0], x2
@@ -64,69 +64,31 @@ function ff_hevc_add_residual_4x4_8_neon, export=1
ret
endfunc
-function ff_hevc_add_residual_4x4_10_neon, export=1
- mov x12, x0
- ld1 {v0.8h-v1.8h}, [x1]
- ld1 {v2.d}[0], [x12], x2
- ld1 {v2.d}[1], [x12], x2
- ld1 {v3.d}[0], [x12], x2
- sqadd v0.8h, v0.8h, v2.8h
- ld1 {v3.d}[1], [x12], x2
- movi v4.8h, #0
- sqadd v1.8h, v1.8h, v3.8h
- mvni v5.8h, #0xFC, lsl #8 // movi #0x3FF
- clip10 v0.8h, v1.8h, v4.8h, v5.8h
- st1 {v0.d}[0], [x0], x2
- st1 {v0.d}[1], [x0], x2
- st1 {v1.d}[0], [x0], x2
- st1 {v1.d}[1], [x0], x2
- ret
-endfunc
-
function ff_hevc_add_residual_8x8_8_neon, export=1
- add x12, x0, x2
- add x2, x2, x2
- mov x3, #8
-1: subs x3, x3, #2
- ld1 {v2.d}[0], [x0]
- ld1 {v2.d}[1], [x12]
- uxtl v3.8h, v2.8b
+ add x12, x0, x2
+ add x2, x2, x2
+ mov x3, #8
+1: subs x3, x3, #2
+ ld1 {v2.d}[0], [x0]
+ ld1 {v2.d}[1], [x12]
+ uxtl v3.8h, v2.8b
ld1 {v0.8h-v1.8h}, [x1], #32
- uxtl2 v2.8h, v2.16b
- sqadd v0.8h, v0.8h, v3.8h
- sqadd v1.8h, v1.8h, v2.8h
- sqxtun v0.8b, v0.8h
- sqxtun2 v0.16b, v1.8h
- st1 {v0.d}[0], [x0], x2
- st1 {v0.d}[1], [x12], x2
- bne 1b
- ret
-endfunc
-
-function ff_hevc_add_residual_8x8_10_neon, export=1
- add x12, x0, x2
- add x2, x2, x2
- mov x3, #8
- movi v4.8h, #0
- mvni v5.8h, #0xFC, lsl #8 // movi #0x3FF
-1: subs x3, x3, #2
- ld1 {v0.8h-v1.8h}, [x1], #32
- ld1 {v2.8h}, [x0]
- sqadd v0.8h, v0.8h, v2.8h
- ld1 {v3.8h}, [x12]
- sqadd v1.8h, v1.8h, v3.8h
- clip10 v0.8h, v1.8h, v4.8h, v5.8h
- st1 {v0.8h}, [x0], x2
- st1 {v1.8h}, [x12], x2
- bne 1b
+ uxtl2 v2.8h, v2.16b
+ sqadd v0.8h, v0.8h, v3.8h
+ sqadd v1.8h, v1.8h, v2.8h
+ sqxtun v0.8b, v0.8h
+ sqxtun2 v0.16b, v1.8h
+ st1 {v0.d}[0], [x0], x2
+ st1 {v0.d}[1], [x12], x2
+ bne 1b
ret
endfunc
function ff_hevc_add_residual_16x16_8_neon, export=1
- mov x3, #16
+ mov x3, #16
add x12, x0, x2
- add x2, x2, x2
-1: subs x3, x3, #2
+ add x2, x2, x2
+1: subs x3, x3, #2
ld1 {v16.16b}, [x0]
ld1 {v0.8h-v3.8h}, [x1], #64
ld1 {v19.16b}, [x12]
@@ -134,47 +96,25 @@ function ff_hevc_add_residual_16x16_8_neon, export=1
uxtl2 v18.8h, v16.16b
uxtl v20.8h, v19.8b
uxtl2 v21.8h, v19.16b
- sqadd v0.8h, v0.8h, v17.8h
- sqadd v1.8h, v1.8h, v18.8h
- sqadd v2.8h, v2.8h, v20.8h
- sqadd v3.8h, v3.8h, v21.8h
- sqxtun v0.8b, v0.8h
+ sqadd v0.8h, v0.8h, v17.8h
+ sqadd v1.8h, v1.8h, v18.8h
+ sqadd v2.8h, v2.8h, v20.8h
+ sqadd v3.8h, v3.8h, v21.8h
+ sqxtun v0.8b, v0.8h
sqxtun2 v0.16b, v1.8h
- sqxtun v1.8b, v2.8h
+ sqxtun v1.8b, v2.8h
sqxtun2 v1.16b, v3.8h
st1 {v0.16b}, [x0], x2
st1 {v1.16b}, [x12], x2
- bne 1b
- ret
-endfunc
-
-function ff_hevc_add_residual_16x16_10_neon, export=1
- mov x3, #16
- movi v20.8h, #0
- mvni v21.8h, #0xFC, lsl #8 // movi #0x3FF
- add x12, x0, x2
- add x2, x2, x2
-1: subs x3, x3, #2
- ld1 {v16.8h-v17.8h}, [x0]
- ld1 {v0.8h-v3.8h}, [x1], #64
- sqadd v0.8h, v0.8h, v16.8h
- ld1 {v18.8h-v19.8h}, [x12]
- sqadd v1.8h, v1.8h, v17.8h
- sqadd v2.8h, v2.8h, v18.8h
- sqadd v3.8h, v3.8h, v19.8h
- clip10 v0.8h, v1.8h, v20.8h, v21.8h
- clip10 v2.8h, v3.8h, v20.8h, v21.8h
- st1 {v0.8h-v1.8h}, [x0], x2
- st1 {v2.8h-v3.8h}, [x12], x2
- bne 1b
+ bne 1b
ret
endfunc
function ff_hevc_add_residual_32x32_8_neon, export=1
add x12, x0, x2
- add x2, x2, x2
- mov x3, #32
-1: subs x3, x3, #2
+ add x2, x2, x2
+ mov x3, #32
+1: subs x3, x3, #2
ld1 {v20.16b, v21.16b}, [x0]
uxtl v16.8h, v20.8b
uxtl2 v17.8h, v20.16b
@@ -187,43 +127,121 @@ function ff_hevc_add_residual_32x32_8_neon, export=1
uxtl2 v21.8h, v22.16b
uxtl v22.8h, v23.8b
uxtl2 v23.8h, v23.16b
- sqadd v0.8h, v0.8h, v16.8h
- sqadd v1.8h, v1.8h, v17.8h
- sqadd v2.8h, v2.8h, v18.8h
- sqadd v3.8h, v3.8h, v19.8h
- sqadd v4.8h, v4.8h, v20.8h
- sqadd v5.8h, v5.8h, v21.8h
- sqadd v6.8h, v6.8h, v22.8h
- sqadd v7.8h, v7.8h, v23.8h
- sqxtun v0.8b, v0.8h
+ sqadd v0.8h, v0.8h, v16.8h
+ sqadd v1.8h, v1.8h, v17.8h
+ sqadd v2.8h, v2.8h, v18.8h
+ sqadd v3.8h, v3.8h, v19.8h
+ sqadd v4.8h, v4.8h, v20.8h
+ sqadd v5.8h, v5.8h, v21.8h
+ sqadd v6.8h, v6.8h, v22.8h
+ sqadd v7.8h, v7.8h, v23.8h
+ sqxtun v0.8b, v0.8h
sqxtun2 v0.16b, v1.8h
- sqxtun v1.8b, v2.8h
+ sqxtun v1.8b, v2.8h
sqxtun2 v1.16b, v3.8h
- sqxtun v2.8b, v4.8h
+ sqxtun v2.8b, v4.8h
sqxtun2 v2.16b, v5.8h
- st1 {v0.16b, v1.16b}, [x0], x2
- sqxtun v3.8b, v6.8h
+ st1 {v0.16b, v1.16b}, [x0], x2
+ sqxtun v3.8b, v6.8h
sqxtun2 v3.16b, v7.8h
st1 {v2.16b, v3.16b}, [x12], x2
- bne 1b
+ bne 1b
ret
endfunc
-function ff_hevc_add_residual_32x32_10_neon, export=1
- mov x3, #32
+.macro add_res bitdepth
+function ff_hevc_add_residual_4x4_\bitdepth\()_neon, export=1
+ mvni v21.8h, #((0xFF << (\bitdepth - 8)) & 0xFF), lsl #8
+ b hevc_add_residual_4x4_16_neon
+endfunc
+function ff_hevc_add_residual_8x8_\bitdepth\()_neon, export=1
+ mvni v21.8h, #((0xFF << (\bitdepth - 8)) & 0xFF), lsl #8
+ b hevc_add_residual_8x8_16_neon
+endfunc
+function ff_hevc_add_residual_16x16_\bitdepth\()_neon, export=1
+ mvni v21.8h, #((0xFF << (\bitdepth - 8)) & 0xFF), lsl #8
+ b hevc_add_residual_16x16_16_neon
+endfunc
+function ff_hevc_add_residual_32x32_\bitdepth\()_neon, export=1
+ mvni v21.8h, #((0xFF << (\bitdepth - 8)) & 0xFF), lsl #8
+ b hevc_add_residual_32x32_16_neon
+endfunc
+.endm
+
+add_res 10
+add_res 12
+
+function hevc_add_residual_4x4_16_neon, export=0
+ mov x12, x0
+ ld1 {v0.8h-v1.8h}, [x1]
+ ld1 {v2.d}[0], [x12], x2
+ ld1 {v2.d}[1], [x12], x2
+ ld1 {v3.d}[0], [x12], x2
+ sqadd v0.8h, v0.8h, v2.8h
+ ld1 {v3.d}[1], [x12], x2
+ movi v4.8h, #0
+ sqadd v1.8h, v1.8h, v3.8h
+ clip2 v0.8h, v1.8h, v4.8h, v21.8h
+ st1 {v0.d}[0], [x0], x2
+ st1 {v0.d}[1], [x0], x2
+ st1 {v1.d}[0], [x0], x2
+ st1 {v1.d}[1], [x0], x2
+ ret
+endfunc
+
+function hevc_add_residual_8x8_16_neon, export=0
+ add x12, x0, x2
+ add x2, x2, x2
+ mov x3, #8
+ movi v4.8h, #0
+1: subs x3, x3, #2
+ ld1 {v0.8h-v1.8h}, [x1], #32
+ ld1 {v2.8h}, [x0]
+ sqadd v0.8h, v0.8h, v2.8h
+ ld1 {v3.8h}, [x12]
+ sqadd v1.8h, v1.8h, v3.8h
+ clip2 v0.8h, v1.8h, v4.8h, v21.8h
+ st1 {v0.8h}, [x0], x2
+ st1 {v1.8h}, [x12], x2
+ bne 1b
+ ret
+endfunc
+
+function hevc_add_residual_16x16_16_neon, export=0
+ mov x3, #16
movi v20.8h, #0
- mvni v21.8h, #0xFC, lsl #8 // movi #0x3FF
-1: subs x3, x3, #1
+ add x12, x0, x2
+ add x2, x2, x2
+1: subs x3, x3, #2
+ ld1 {v16.8h-v17.8h}, [x0]
ld1 {v0.8h-v3.8h}, [x1], #64
+ sqadd v0.8h, v0.8h, v16.8h
+ ld1 {v18.8h-v19.8h}, [x12]
+ sqadd v1.8h, v1.8h, v17.8h
+ sqadd v2.8h, v2.8h, v18.8h
+ sqadd v3.8h, v3.8h, v19.8h
+ clip2 v0.8h, v1.8h, v20.8h, v21.8h
+ clip2 v2.8h, v3.8h, v20.8h, v21.8h
+ st1 {v0.8h-v1.8h}, [x0], x2
+ st1 {v2.8h-v3.8h}, [x12], x2
+ bne 1b
+ ret
+endfunc
+
+function hevc_add_residual_32x32_16_neon, export=0
+ mov x3, #32
+ movi v20.8h, #0
+1: subs x3, x3, #1
+ ld1 {v0.8h -v3.8h}, [x1], #64
ld1 {v16.8h-v19.8h}, [x0]
- sqadd v0.8h, v0.8h, v16.8h
- sqadd v1.8h, v1.8h, v17.8h
- sqadd v2.8h, v2.8h, v18.8h
- sqadd v3.8h, v3.8h, v19.8h
- clip10 v0.8h, v1.8h, v20.8h, v21.8h
- clip10 v2.8h, v3.8h, v20.8h, v21.8h
- st1 {v0.8h-v3.8h}, [x0], x2
- bne 1b
+ sqadd v0.8h, v0.8h, v16.8h
+ sqadd v1.8h, v1.8h, v17.8h
+ sqadd v2.8h, v2.8h, v18.8h
+ sqadd v3.8h, v3.8h, v19.8h
+ clip2 v0.8h, v1.8h, v20.8h, v21.8h
+ clip2 v2.8h, v3.8h, v20.8h, v21.8h
+ st1 {v0.8h-v3.8h}, [x0], x2
+ bne 1b
ret
endfunc
diff --git a/libavcodec/aarch64/hevcdsp_init_aarch64.c b/libavcodec/aarch64/hevcdsp_init_aarch64.c
index 200253026..88a797f39 100644
--- a/libavcodec/aarch64/hevcdsp_init_aarch64.c
+++ b/libavcodec/aarch64/hevcdsp_init_aarch64.c
@@ -25,21 +25,29 @@
#include "libavutil/aarch64/cpu.h"
#include "libavcodec/hevcdsp.h"
-void ff_hevc_add_residual_4x4_8_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_4x4_8_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
-void ff_hevc_add_residual_4x4_10_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_4x4_10_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
-void ff_hevc_add_residual_8x8_8_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_4x4_12_neon(uint8_t *_dst, const int16_t *coeffs,
+ ptrdiff_t stride);
+void ff_hevc_add_residual_8x8_8_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
-void ff_hevc_add_residual_8x8_10_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_8x8_10_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
-void ff_hevc_add_residual_16x16_8_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_8x8_12_neon(uint8_t *_dst, const int16_t *coeffs,
+ ptrdiff_t stride);
+void ff_hevc_add_residual_16x16_8_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
-void ff_hevc_add_residual_16x16_10_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_16x16_10_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
-void ff_hevc_add_residual_32x32_8_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_16x16_12_neon(uint8_t *_dst, const int16_t *coeffs,
+ ptrdiff_t stride);
+void ff_hevc_add_residual_32x32_8_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
-void ff_hevc_add_residual_32x32_10_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_32x32_10_neon(uint8_t *_dst, const int16_t *coeffs,
+ ptrdiff_t stride);
+void ff_hevc_add_residual_32x32_12_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
void ff_hevc_idct_8x8_8_neon(int16_t *coeffs, int col_limit);
void ff_hevc_idct_8x8_10_neon(int16_t *coeffs, int col_limit);
@@ -53,14 +61,54 @@ void ff_hevc_idct_4x4_dc_10_neon(int16_t *coeffs);
void ff_hevc_idct_8x8_dc_10_neon(int16_t *coeffs);
void ff_hevc_idct_16x16_dc_10_neon(int16_t *coeffs);
void ff_hevc_idct_32x32_dc_10_neon(int16_t *coeffs);
-void ff_hevc_sao_band_filter_8x8_8_neon(uint8_t *_dst, uint8_t *_src,
+void ff_hevc_sao_band_filter_8x8_8_neon(uint8_t *_dst, const uint8_t *_src,
ptrdiff_t stride_dst, ptrdiff_t stride_src,
- int16_t *sao_offset_val, int sao_left_class,
+ const int16_t *sao_offset_val, int sao_left_class,
int width, int height);
-void ff_hevc_sao_edge_filter_16x16_8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride_dst,
- int16_t *sao_offset_val, int eo, int width, int height);
-void ff_hevc_sao_edge_filter_8x8_8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride_dst,
- int16_t *sao_offset_val, int eo, int width, int height);
+void ff_hevc_sao_edge_filter_16x16_8_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride_dst,
+ const int16_t *sao_offset_val, int eo, int width, int height);
+void ff_hevc_sao_edge_filter_8x8_8_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride_dst,
+ const int16_t *sao_offset_val, int eo, int width, int height);
+void ff_hevc_put_hevc_qpel_h4_8_neon(int16_t *dst, const uint8_t *_src, ptrdiff_t _srcstride, int height,
+ intptr_t mx, intptr_t my, int width);
+void ff_hevc_put_hevc_qpel_h6_8_neon(int16_t *dst, const uint8_t *_src, ptrdiff_t _srcstride, int height,
+ intptr_t mx, intptr_t my, int width);
+void ff_hevc_put_hevc_qpel_h8_8_neon(int16_t *dst, const uint8_t *_src, ptrdiff_t _srcstride, int height,
+ intptr_t mx, intptr_t my, int width);
+void ff_hevc_put_hevc_qpel_h12_8_neon(int16_t *dst, const uint8_t *_src, ptrdiff_t _srcstride, int height,
+ intptr_t mx, intptr_t my, int width);
+void ff_hevc_put_hevc_qpel_h16_8_neon(int16_t *dst, const uint8_t *_src, ptrdiff_t _srcstride, int height,
+ intptr_t mx, intptr_t my, int width);
+void ff_hevc_put_hevc_qpel_uni_h4_8_neon(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src,
+ ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,
+ int width);
+void ff_hevc_put_hevc_qpel_uni_h6_8_neon(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src,
+ ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,
+ int width);
+void ff_hevc_put_hevc_qpel_uni_h8_8_neon(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src,
+ ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,
+ int width);
+void ff_hevc_put_hevc_qpel_uni_h12_8_neon(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src,
+ ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t
+ my, int width);
+void ff_hevc_put_hevc_qpel_uni_h16_8_neon(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src,
+ ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t
+ my, int width);
+void ff_hevc_put_hevc_qpel_bi_h4_8_neon(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src,
+ ptrdiff_t _srcstride, const int16_t *src2, int height, intptr_t
+ mx, intptr_t my, int width);
+void ff_hevc_put_hevc_qpel_bi_h6_8_neon(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src,
+ ptrdiff_t _srcstride, const int16_t *src2, int height, intptr_t
+ mx, intptr_t my, int width);
+void ff_hevc_put_hevc_qpel_bi_h8_8_neon(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src,
+ ptrdiff_t _srcstride, const int16_t *src2, int height, intptr_t
+ mx, intptr_t my, int width);
+void ff_hevc_put_hevc_qpel_bi_h12_8_neon(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src,
+ ptrdiff_t _srcstride, const int16_t *src2, int height, intptr_t
+ mx, intptr_t my, int width);
+void ff_hevc_put_hevc_qpel_bi_h16_8_neon(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src,
+ ptrdiff_t _srcstride, const int16_t *src2, int height, intptr_t
+ mx, intptr_t my, int width);
av_cold void ff_hevc_dsp_init_aarch64(HEVCDSPContext *c, const int bit_depth)
{
@@ -87,6 +135,33 @@ av_cold void ff_hevc_dsp_init_aarch64(HEVCDSPContext *c, const int bit_depth)
c->sao_edge_filter[2] =
c->sao_edge_filter[3] =
c->sao_edge_filter[4] = ff_hevc_sao_edge_filter_16x16_8_neon;
+ c->put_hevc_qpel[1][0][1] = ff_hevc_put_hevc_qpel_h4_8_neon;
+ c->put_hevc_qpel[2][0][1] = ff_hevc_put_hevc_qpel_h6_8_neon;
+ c->put_hevc_qpel[3][0][1] = ff_hevc_put_hevc_qpel_h8_8_neon;
+ c->put_hevc_qpel[4][0][1] =
+ c->put_hevc_qpel[6][0][1] = ff_hevc_put_hevc_qpel_h12_8_neon;
+ c->put_hevc_qpel[5][0][1] =
+ c->put_hevc_qpel[7][0][1] =
+ c->put_hevc_qpel[8][0][1] =
+ c->put_hevc_qpel[9][0][1] = ff_hevc_put_hevc_qpel_h16_8_neon;
+ c->put_hevc_qpel_uni[1][0][1] = ff_hevc_put_hevc_qpel_uni_h4_8_neon;
+ c->put_hevc_qpel_uni[2][0][1] = ff_hevc_put_hevc_qpel_uni_h6_8_neon;
+ c->put_hevc_qpel_uni[3][0][1] = ff_hevc_put_hevc_qpel_uni_h8_8_neon;
+ c->put_hevc_qpel_uni[4][0][1] =
+ c->put_hevc_qpel_uni[6][0][1] = ff_hevc_put_hevc_qpel_uni_h12_8_neon;
+ c->put_hevc_qpel_uni[5][0][1] =
+ c->put_hevc_qpel_uni[7][0][1] =
+ c->put_hevc_qpel_uni[8][0][1] =
+ c->put_hevc_qpel_uni[9][0][1] = ff_hevc_put_hevc_qpel_uni_h16_8_neon;
+ c->put_hevc_qpel_bi[1][0][1] = ff_hevc_put_hevc_qpel_bi_h4_8_neon;
+ c->put_hevc_qpel_bi[2][0][1] = ff_hevc_put_hevc_qpel_bi_h6_8_neon;
+ c->put_hevc_qpel_bi[3][0][1] = ff_hevc_put_hevc_qpel_bi_h8_8_neon;
+ c->put_hevc_qpel_bi[4][0][1] =
+ c->put_hevc_qpel_bi[6][0][1] = ff_hevc_put_hevc_qpel_bi_h12_8_neon;
+ c->put_hevc_qpel_bi[5][0][1] =
+ c->put_hevc_qpel_bi[7][0][1] =
+ 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;
}
if (bit_depth == 10) {
c->add_residual[0] = ff_hevc_add_residual_4x4_10_neon;
@@ -100,4 +175,10 @@ av_cold void ff_hevc_dsp_init_aarch64(HEVCDSPContext *c, const int bit_depth)
c->idct_dc[2] = ff_hevc_idct_16x16_dc_10_neon;
c->idct_dc[3] = ff_hevc_idct_32x32_dc_10_neon;
}
+ if (bit_depth == 12) {
+ c->add_residual[0] = ff_hevc_add_residual_4x4_12_neon;
+ c->add_residual[1] = ff_hevc_add_residual_8x8_12_neon;
+ c->add_residual[2] = ff_hevc_add_residual_16x16_12_neon;
+ c->add_residual[3] = ff_hevc_add_residual_32x32_12_neon;
+ }
}
diff --git a/libavcodec/aarch64/hevcdsp_qpel_neon.S b/libavcodec/aarch64/hevcdsp_qpel_neon.S
new file mode 100644
index 000000000..0e7b91267
--- /dev/null
+++ b/libavcodec/aarch64/hevcdsp_qpel_neon.S
@@ -0,0 +1,484 @@
+/* -*-arm64-*-
+ * vim: syntax=arm64asm
+ *
+ * Copyright (c) 2022 J. Dekker
+ *
+ * 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/aarch64/asm.S"
+#define MAX_PB_SIZE 64
+
+const qpel_filters, align=4
+ .byte 0, 0, 0, 0, 0, 0, 0, 0
+ .byte -1, 4,-10, 58, 17, -5, 1, 0
+ .byte -1, 4,-11, 40, 40,-11, 4, -1
+ .byte 0, 1, -5, 17, 58,-10, 4, -1
+endconst
+
+.macro load_filter m
+ movrel x15, qpel_filters
+ add x15, x15, \m, lsl #3
+ ld1 {v0.8b}, [x15]
+ sxtl v0.8h, v0.8b
+.endm
+
+.macro put_hevc type
+.ifc \type, qpel
+ // void put_hevc_qpel_h(int16_t *dst,
+ // uint8_t *_src, ptrdiff_t _srcstride,
+ // int height, intptr_t mx, intptr_t my, int width)
+ dst .req x0
+ dststride .req x7
+ src .req x1
+ srcstride .req x2
+ height .req x3
+ heightw .req w3
+ mx .req x4
+ width .req w6
+.endif
+.ifc \type, qpel_uni
+ // void put_hevc_qpel_uni_h(uint8_t *_dst, ptrdiff_t _dststride,
+ // uint8_t *_src, ptrdiff_t _srcstride,
+ // int height, intptr_t mx, intptr_t my, int width)
+ dst .req x0
+ dststride .req x1
+ src .req x2
+ srcstride .req x3
+ height .req x4
+ heightw .req w4
+ mx .req x5
+ width .req w7
+.endif
+.ifc \type, qpel_bi
+ // void put_hevc_qpel_bi_h(uint8_t *_dst, ptrdiff_t _dststride,
+ // uint8_t *_src, ptrdiff_t _srcstride,
+ // int16_t *src2, int height, intptr_t mx,
+ // intptr_t my, int width)
+ dst .req x0
+ dststride .req x1
+ src .req x2
+ srcstride .req x3
+ height .req x5
+ heightw .req w5
+ mx .req x6
+ width .req w8
+.endif
+
+.ifc \type, qpel
+function ff_hevc_put_hevc_h4_8_neon, export=0
+ uxtl v16.8h, v16.8b
+ uxtl v17.8h, v17.8b
+ uxtl v18.8h, v18.8b
+ uxtl v19.8h, v19.8b
+
+ mul v23.4h, v16.4h, v0.h[0]
+ mul v24.4h, v18.4h, v0.h[0]
+
+.irpc i, 1234567
+ ext v20.16b, v16.16b, v17.16b, #(2*\i)
+ ext v21.16b, v18.16b, v19.16b, #(2*\i)
+ mla v23.4h, v20.4h, v0.h[\i]
+ mla v24.4h, v21.4h, v0.h[\i]
+.endr
+ ret
+endfunc
+.endif
+
+function ff_hevc_put_hevc_\type\()_h4_8_neon, export=1
+ load_filter mx
+.ifc \type, qpel_bi
+ mov x16, #(MAX_PB_SIZE << 2) // src2bstridel
+ add x15, x4, #(MAX_PB_SIZE << 1) // src2b
+.endif
+ sub src, src, #3
+ mov mx, x30
+.ifc \type, qpel
+ mov dststride, #(MAX_PB_SIZE << 1)
+ lsl x13, srcstride, #1 // srcstridel
+ mov x14, #(MAX_PB_SIZE << 2)
+.else
+ lsl x14, dststride, #1 // dststridel
+ lsl x13, srcstride, #1 // srcstridel
+.endif
+ add x10, dst, dststride // dstb
+ add x12, src, srcstride // srcb
+0: ld1 {v16.8b, v17.8b}, [src], x13
+ ld1 {v18.8b, v19.8b}, [x12], x13
+.ifc \type, qpel_bi
+ ld1 {v25.8h}, [ x4], x16
+ ld1 {v26.8h}, [x15], x16
+.endif
+
+ bl ff_hevc_put_hevc_h4_8_neon
+ subs heightw, heightw, #2
+
+.ifc \type, qpel
+ st1 {v23.4h}, [dst], x14
+ st1 {v24.4h}, [x10], x14
+.else
+.ifc \type, qpel_bi
+ sqadd v23.4h, v23.4h, v25.4h
+ sqadd v24.4h, v24.4h, v26.4h
+ sqrshrun v23.8b, v23.8h, #7
+ sqrshrun v24.8b, v24.8h, #7
+.else
+ sqrshrun v23.8b, v23.8h, #6
+ sqrshrun v24.8b, v24.8h, #6
+.endif
+ st1 {v23.s}[0], [dst], x14
+ st1 {v24.s}[0], [x10], x14
+.endif
+ b.gt 0b // double line
+ ret mx
+endfunc
+
+.ifc \type, qpel
+function ff_hevc_put_hevc_h8_8_neon, export=0
+ uxtl v16.8h, v16.8b
+ uxtl v17.8h, v17.8b
+ uxtl v18.8h, v18.8b
+ uxtl v19.8h, v19.8b
+
+ mul v23.8h, v16.8h, v0.h[0]
+ mul v24.8h, v18.8h, v0.h[0]
+
+.irpc i, 1234567
+ ext v20.16b, v16.16b, v17.16b, #(2*\i)
+ ext v21.16b, v18.16b, v19.16b, #(2*\i)
+ mla v23.8h, v20.8h, v0.h[\i]
+ mla v24.8h, v21.8h, v0.h[\i]
+.endr
+ ret
+endfunc
+.endif
+
+function ff_hevc_put_hevc_\type\()_h6_8_neon, export=1
+ load_filter mx
+.ifc \type, qpel_bi
+ mov x16, #(MAX_PB_SIZE << 2) // src2bstridel
+ add x15, x4, #(MAX_PB_SIZE << 1) // src2b
+.endif
+ sub src, src, #3
+ mov mx, x30
+.ifc \type, qpel
+ mov dststride, #(MAX_PB_SIZE << 1)
+ lsl x13, srcstride, #1 // srcstridel
+ mov x14, #((MAX_PB_SIZE << 2) - 8)
+.else
+ lsl x14, dststride, #1 // dststridel
+ lsl x13, srcstride, #1 // srcstridel
+ sub x14, x14, #4
+.endif
+ add x10, dst, dststride // dstb
+ add x12, src, srcstride // srcb
+0: ld1 {v16.8b, v17.8b}, [src], x13
+ ld1 {v18.8b, v19.8b}, [x12], x13
+.ifc \type, qpel_bi
+ ld1 {v25.8h}, [ x4], x16
+ ld1 {v26.8h}, [x15], x16
+.endif
+
+ bl ff_hevc_put_hevc_h8_8_neon
+ subs heightw, heightw, #2
+
+.ifc \type, qpel
+ st1 {v23.4h}, [dst], #8
+ st1 {v24.4h}, [x10], #8
+ st1 {v23.s}[2], [dst], x14
+ st1 {v24.s}[2], [x10], x14
+.else
+.ifc \type, qpel_bi
+ sqadd v23.8h, v23.8h, v25.8h
+ sqadd v24.8h, v24.8h, v26.8h
+ sqrshrun v23.8b, v23.8h, #7
+ sqrshrun v24.8b, v24.8h, #7
+.else
+ sqrshrun v23.8b, v23.8h, #6
+ sqrshrun v24.8b, v24.8h, #6
+.endif
+ st1 {v23.s}[0], [dst], #4
+ st1 {v24.s}[0], [x10], #4
+ st1 {v23.h}[2], [dst], x14
+ st1 {v24.h}[2], [x10], x14
+.endif
+ b.gt 0b // double line
+ ret mx
+endfunc
+
+function ff_hevc_put_hevc_\type\()_h8_8_neon, export=1
+ load_filter mx
+.ifc \type, qpel_bi
+ mov x16, #(MAX_PB_SIZE << 2) // src2bstridel
+ add x15, x4, #(MAX_PB_SIZE << 1) // src2b
+.endif
+ sub src, src, #3
+ mov mx, x30
+.ifc \type, qpel
+ mov dststride, #(MAX_PB_SIZE << 1)
+ lsl x13, srcstride, #1 // srcstridel
+ mov x14, #(MAX_PB_SIZE << 2)
+.else
+ lsl x14, dststride, #1 // dststridel
+ lsl x13, srcstride, #1 // srcstridel
+.endif
+ add x10, dst, dststride // dstb
+ add x12, src, srcstride // srcb
+0: ld1 {v16.8b, v17.8b}, [src], x13
+ ld1 {v18.8b, v19.8b}, [x12], x13
+.ifc \type, qpel_bi
+ ld1 {v25.8h}, [ x4], x16
+ ld1 {v26.8h}, [x15], x16
+.endif
+
+ bl ff_hevc_put_hevc_h8_8_neon
+ subs heightw, heightw, #2
+
+.ifc \type, qpel
+ st1 {v23.8h}, [dst], x14
+ st1 {v24.8h}, [x10], x14
+.else
+.ifc \type, qpel_bi
+ sqadd v23.8h, v23.8h, v25.8h
+ sqadd v24.8h, v24.8h, v26.8h
+ sqrshrun v23.8b, v23.8h, #7
+ sqrshrun v24.8b, v24.8h, #7
+.else
+ sqrshrun v23.8b, v23.8h, #6
+ sqrshrun v24.8b, v24.8h, #6
+.endif
+ st1 {v23.8b}, [dst], x14
+ st1 {v24.8b}, [x10], x14
+.endif
+ b.gt 0b // double line
+ ret mx
+endfunc
+
+.ifc \type, qpel
+function ff_hevc_put_hevc_h16_8_neon, export=0
+ uxtl v16.8h, v16.8b
+ uxtl v17.8h, v17.8b
+ uxtl v18.8h, v18.8b
+
+ uxtl v19.8h, v19.8b
+ uxtl v20.8h, v20.8b
+ uxtl v21.8h, v21.8b
+
+ mul v26.8h, v16.8h, v0.h[0]
+ mul v27.8h, v17.8h, v0.h[0]
+ mul v28.8h, v19.8h, v0.h[0]
+ mul v29.8h, v20.8h, v0.h[0]
+.irpc i, 1234567
+ ext v22.16b, v16.16b, v17.16b, #(2*\i)
+ ext v23.16b, v17.16b, v18.16b, #(2*\i)
+
+ ext v24.16b, v19.16b, v20.16b, #(2*\i)
+ ext v25.16b, v20.16b, v21.16b, #(2*\i)
+
+ mla v26.8h, v22.8h, v0.h[\i]
+ mla v27.8h, v23.8h, v0.h[\i]
+
+ mla v28.8h, v24.8h, v0.h[\i]
+ mla v29.8h, v25.8h, v0.h[\i]
+.endr
+ subs x9, x9, #2
+ ret
+endfunc
+.endif
+
+function ff_hevc_put_hevc_\type\()_h12_8_neon, export=1
+ load_filter mx
+ sxtw height, heightw
+.ifc \type, qpel_bi
+ ldrh w8, [sp] // width
+ mov x16, #(MAX_PB_SIZE << 2) // src2bstridel
+ lsl x17, height, #7 // src2b reset (height * (MAX_PB_SIZE << 1))
+ add x15, x4, #(MAX_PB_SIZE << 1) // src2b
+.endif
+ sub src, src, #3
+ mov mx, x30
+.ifc \type, qpel
+ mov dststride, #(MAX_PB_SIZE << 1)
+ lsl x13, srcstride, #1 // srcstridel
+ mov x14, #((MAX_PB_SIZE << 2) - 16)
+.else
+ lsl x14, dststride, #1 // dststridel
+ lsl x13, srcstride, #1 // srcstridel
+ sub x14, x14, #8
+.endif
+ add x10, dst, dststride // dstb
+ add x12, src, srcstride // srcb
+0: mov x9, height
+1: ld1 {v16.8b-v18.8b}, [src], x13
+ ld1 {v19.8b-v21.8b}, [x12], x13
+
+ bl ff_hevc_put_hevc_h16_8_neon
+
+.ifc \type, qpel
+ st1 {v26.8h}, [dst], #16
+ st1 {v28.8h}, [x10], #16
+ st1 {v27.4h}, [dst], x14
+ st1 {v29.4h}, [x10], x14
+.else
+.ifc \type, qpel_bi
+ ld1 {v16.8h, v17.8h}, [ x4], x16
+ ld1 {v18.8h, v19.8h}, [x15], x16
+ sqadd v26.8h, v26.8h, v16.8h
+ sqadd v27.8h, v27.8h, v17.8h
+ sqadd v28.8h, v28.8h, v18.8h
+ sqadd v29.8h, v29.8h, v19.8h
+ sqrshrun v26.8b, v26.8h, #7
+ sqrshrun v27.8b, v27.8h, #7
+ sqrshrun v28.8b, v28.8h, #7
+ sqrshrun v29.8b, v29.8h, #7
+.else
+ sqrshrun v26.8b, v26.8h, #6
+ sqrshrun v27.8b, v27.8h, #6
+ sqrshrun v28.8b, v28.8h, #6
+ sqrshrun v29.8b, v29.8h, #6
+.endif
+ st1 {v26.8b}, [dst], #8
+ st1 {v28.8b}, [x10], #8
+ st1 {v27.s}[0], [dst], x14
+ st1 {v29.s}[0], [x10], x14
+.endif
+ b.gt 1b // double line
+ subs width, width, #12
+ // reset src
+ msub src, srcstride, height, src
+ msub x12, srcstride, height, x12
+ // reset dst
+ msub dst, dststride, height, dst
+ msub x10, dststride, height, x10
+.ifc \type, qpel_bi
+ // reset xsrc
+ sub x4, x4, x17
+ sub x15, x15, x17
+ add x4, x4, #24
+ add x15, x15, #24
+.endif
+ add src, src, #12
+ add x12, x12, #12
+.ifc \type, qpel
+ add dst, dst, #24
+ add x10, x10, #24
+.else
+ add dst, dst, #12
+ add x10, x10, #12
+.endif
+ b.gt 0b
+ ret mx
+endfunc
+
+function ff_hevc_put_hevc_\type\()_h16_8_neon, export=1
+ load_filter mx
+ sxtw height, heightw
+ mov mx, x30
+.ifc \type, qpel_bi
+ ldrh w8, [sp] // width
+ mov x16, #(MAX_PB_SIZE << 2) // src2bstridel
+ lsl x17, x5, #7 // src2b reset
+ add x15, x4, #(MAX_PB_SIZE << 1) // src2b
+.endif
+ sub src, src, #3
+ mov mx, x30
+.ifc \type, qpel
+ mov dststride, #(MAX_PB_SIZE << 1)
+ lsl x13, srcstride, #1 // srcstridel
+ mov x14, #((MAX_PB_SIZE << 2) - 16)
+.else
+ lsl x14, dststride, #1 // dststridel
+ lsl x13, srcstride, #1 // srcstridel
+ sub x14, x14, #8
+.endif
+ add x10, dst, dststride // dstb
+ add x12, src, srcstride // srcb
+0: mov x9, height
+1: ld1 {v16.8b-v18.8b}, [src], x13
+ ld1 {v19.8b-v21.8b}, [x12], x13
+
+ bl ff_hevc_put_hevc_h16_8_neon
+
+.ifc \type, qpel
+ st1 {v26.8h}, [dst], #16
+ st1 {v28.8h}, [x10], #16
+ st1 {v27.8h}, [dst], x14
+ st1 {v29.8h}, [x10], x14
+.else
+.ifc \type, qpel_bi
+ ld1 {v16.8h, v17.8h}, [ x4], x16
+ ld1 {v18.8h, v19.8h}, [x15], x16
+ sqadd v26.8h, v26.8h, v16.8h
+ sqadd v27.8h, v27.8h, v17.8h
+ sqadd v28.8h, v28.8h, v18.8h
+ sqadd v29.8h, v29.8h, v19.8h
+ sqrshrun v26.8b, v26.8h, #7
+ sqrshrun v27.8b, v27.8h, #7
+ sqrshrun v28.8b, v28.8h, #7
+ sqrshrun v29.8b, v29.8h, #7
+.else
+ sqrshrun v26.8b, v26.8h, #6
+ sqrshrun v27.8b, v27.8h, #6
+ sqrshrun v28.8b, v28.8h, #6
+ sqrshrun v29.8b, v29.8h, #6
+.endif
+ st1 {v26.8b}, [dst], #8
+ st1 {v28.8b}, [x10], #8
+ st1 {v27.8b}, [dst], x14
+ st1 {v29.8b}, [x10], x14
+.endif
+ b.gt 1b // double line
+ subs width, width, #16
+ // reset src
+ msub src, srcstride, height, src
+ msub x12, srcstride, height, x12
+ // reset dst
+ msub dst, dststride, height, dst
+ msub x10, dststride, height, x10
+.ifc \type, qpel_bi
+ // reset xsrc
+ sub x4, x4, x17
+ sub x15, x15, x17
+ add x4, x4, #32
+ add x15, x15, #32
+.endif
+ add src, src, #16
+ add x12, x12, #16
+.ifc \type, qpel
+ add dst, dst, #32
+ add x10, x10, #32
+.else
+ add dst, dst, #16
+ add x10, x10, #16
+.endif
+ b.gt 0b
+ ret mx
+endfunc
+
+.unreq height
+.unreq heightw
+.unreq width
+.unreq src
+.unreq dst
+.unreq srcstride
+.unreq dststride
+.unreq mx
+.endm
+
+put_hevc qpel
+put_hevc qpel_uni
+put_hevc qpel_bi
diff --git a/libavcodec/aarch64/hevcdsp_sao_neon.S b/libavcodec/aarch64/hevcdsp_sao_neon.S
index d4decfde3..30e83dda5 100644
--- a/libavcodec/aarch64/hevcdsp_sao_neon.S
+++ b/libavcodec/aarch64/hevcdsp_sao_neon.S
@@ -33,8 +33,7 @@
// int16_t *sao_offset_val, int sao_left_class,
// int width, int height)
function ff_hevc_sao_band_filter_8x8_8_neon, export=1
- sub sp, sp, #64
- stp xzr, xzr, [sp]
+ stp xzr, xzr, [sp, #-64]!
stp xzr, xzr, [sp, #16]
stp xzr, xzr, [sp, #32]
stp xzr, xzr, [sp, #48]
diff --git a/libavcodec/aarch64/mdct_neon.S b/libavcodec/aarch64/mdct_neon.S
index 6091e7202..98b09bf1a 100644
--- a/libavcodec/aarch64/mdct_neon.S
+++ b/libavcodec/aarch64/mdct_neon.S
@@ -23,8 +23,7 @@
#include "libavutil/aarch64/asm.S"
function ff_imdct_half_neon, export=1
- sub sp, sp, #32
- stp x19, x20, [sp]
+ stp x19, x20, [sp, #-32]!
AARCH64_SIGN_LINK_REGISTER
str x30, [sp, #16]
mov x12, #1
@@ -120,17 +119,15 @@ function ff_imdct_half_neon, export=1
st2 {v4.2s,v5.2s}, [x0]
st2 {v6.2s,v7.2s}, [x8]
- ldp x19, x20, [sp]
ldr x30, [sp, #16]
AARCH64_VALIDATE_LINK_REGISTER
- add sp, sp, #32
+ ldp x19, x20, [sp], #32
ret
endfunc
function ff_imdct_calc_neon, export=1
- sub sp, sp, #32
- stp x19, x20, [sp]
+ stp x19, x20, [sp, #-32]!
AARCH64_SIGN_LINK_REGISTER
str x30, [sp, #16]
ldr w3, [x0, #28] // mdct_bits
@@ -163,18 +160,16 @@ function ff_imdct_calc_neon, export=1
subs x19, x19, #16
b.gt 1b
- ldp x19, x20, [sp]
ldr x30, [sp, #16]
AARCH64_VALIDATE_LINK_REGISTER
- add sp, sp, #32
+ ldp x19, x20, [sp], #32
ret
endfunc
function ff_mdct_calc_neon, export=1
- sub sp, sp, #32
- stp x19, x20, [sp]
+ stp x19, x20, [sp, #-32]!
AARCH64_SIGN_LINK_REGISTER
str x30, [sp, #16]
@@ -323,10 +318,9 @@ function ff_mdct_calc_neon, export=1
st2 {v4.2s,v5.2s}, [x0]
st2 {v6.2s,v7.2s}, [x8]
- ldp x19, x20, [sp]
ldr x30, [sp, #16]
AARCH64_VALIDATE_LINK_REGISTER
- add sp, sp, #32
+ ldp x19, x20, [sp], #32
ret
endfunc
diff --git a/libavcodec/aarch64/me_cmp_init_aarch64.c b/libavcodec/aarch64/me_cmp_init_aarch64.c
index bec9148a1..1e0f1cf4f 100644
--- a/libavcodec/aarch64/me_cmp_init_aarch64.c
+++ b/libavcodec/aarch64/me_cmp_init_aarch64.c
@@ -23,10 +23,59 @@
#include "libavutil/aarch64/cpu.h"
#include "libavcodec/mpegvideo.h"
-int ff_pix_abs16_neon(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
+int ff_pix_abs16_neon(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
ptrdiff_t stride, int h);
-int ff_pix_abs16_xy2_neon(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
+int ff_pix_abs16_xy2_neon(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
+ ptrdiff_t stride, int h);
+int ff_pix_abs16_x2_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_pix_abs16_y2_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_pix_abs8_neon(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
+ ptrdiff_t stride, int h);
+
+int sse16_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int sse8_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int sse4_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t stride, int h);
+
+int vsad16_neon(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+ ptrdiff_t stride, int h);
+int vsad_intra16_neon(MpegEncContext *c, const uint8_t *s, const uint8_t *dummy,
+ ptrdiff_t stride, int h) ;
+int vsad_intra8_neon(MpegEncContext *c, const uint8_t *s, const uint8_t *dummy,
+ ptrdiff_t stride, int h) ;
+int vsse16_neon(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+ ptrdiff_t stride, int h);
+int vsse_intra16_neon(MpegEncContext *c, const uint8_t *s, const uint8_t *dummy,
ptrdiff_t stride, int h);
+int nsse16_neon(int multiplier, const uint8_t *s, const uint8_t *s2,
+ ptrdiff_t stride, int h);
+int nsse16_neon_wrapper(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+ ptrdiff_t stride, int h);
+int pix_median_abs16_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int pix_median_abs8_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_pix_abs8_x2_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_pix_abs8_y2_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_pix_abs8_xy2_neon(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t stride, int h);
+
+int nsse8_neon(int multiplier, const uint8_t *s, const uint8_t *s2,
+ ptrdiff_t stride, int h);
+int nsse8_neon_wrapper(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+ ptrdiff_t stride, int h);
+
+int vsse8_neon(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+ ptrdiff_t stride, int h);
+
+int vsse_intra8_neon(MpegEncContext *c, const uint8_t *s, const uint8_t *dummy,
+ ptrdiff_t stride, int h);
av_cold void ff_me_cmp_init_aarch64(MECmpContext *c, AVCodecContext *avctx)
{
@@ -34,8 +83,52 @@ av_cold void ff_me_cmp_init_aarch64(MECmpContext *c, AVCodecContext *avctx)
if (have_neon(cpu_flags)) {
c->pix_abs[0][0] = ff_pix_abs16_neon;
+ c->pix_abs[0][1] = ff_pix_abs16_x2_neon;
+ c->pix_abs[0][2] = ff_pix_abs16_y2_neon;
c->pix_abs[0][3] = ff_pix_abs16_xy2_neon;
+ c->pix_abs[1][0] = ff_pix_abs8_neon;
+ c->pix_abs[1][1] = ff_pix_abs8_x2_neon;
+ c->pix_abs[1][2] = ff_pix_abs8_y2_neon;
+ c->pix_abs[1][3] = ff_pix_abs8_xy2_neon;
c->sad[0] = ff_pix_abs16_neon;
+ c->sad[1] = ff_pix_abs8_neon;
+ c->sse[0] = sse16_neon;
+ c->sse[1] = sse8_neon;
+ c->sse[2] = sse4_neon;
+
+ c->vsad[0] = vsad16_neon;
+ c->vsad[4] = vsad_intra16_neon;
+ c->vsad[5] = vsad_intra8_neon;
+
+ c->vsse[0] = vsse16_neon;
+ c->vsse[1] = vsse8_neon;
+
+ c->vsse[4] = vsse_intra16_neon;
+ c->vsse[5] = vsse_intra8_neon;
+
+ c->nsse[0] = nsse16_neon_wrapper;
+ c->nsse[1] = nsse8_neon_wrapper;
+
+ c->median_sad[0] = pix_median_abs16_neon;
+ c->median_sad[1] = pix_median_abs8_neon;
}
}
+
+int nsse16_neon_wrapper(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+ ptrdiff_t stride, int h)
+{
+ if (c)
+ return nsse16_neon(c->avctx->nsse_weight, s1, s2, stride, h);
+ else
+ return nsse16_neon(8, s1, s2, stride, h);
+}
+
+int nsse8_neon_wrapper(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+ ptrdiff_t stride, int h)
+{
+ if (c)
+ return nsse8_neon(c->avctx->nsse_weight, s1, s2, stride, h);
+ else
+ return nsse8_neon(8, s1, s2, stride, h);
+}
diff --git a/libavcodec/aarch64/me_cmp_neon.S b/libavcodec/aarch64/me_cmp_neon.S
index a7937bd8b..cf86e5081 100644
--- a/libavcodec/aarch64/me_cmp_neon.S
+++ b/libavcodec/aarch64/me_cmp_neon.S
@@ -27,15 +27,16 @@ function ff_pix_abs16_neon, export=1
// x3 ptrdiff_t stride
// w4 int h
cmp w4, #4 // if h < 4, jump to completion section
- movi v18.4S, #0 // clear result accumulator
+ movi v16.8h, #0 // clear result accumulator
+ movi v17.8h, #0 // clear result accumulator
b.lt 2f
1:
ld1 {v0.16b}, [x1], x3 // load pix1
ld1 {v4.16b}, [x2], x3 // load pix2
ld1 {v1.16b}, [x1], x3 // load pix1
ld1 {v5.16b}, [x2], x3 // load pix2
- uabdl v16.8h, v0.8b, v4.8b // absolute difference accumulate
- uabdl2 v17.8h, v0.16b, v4.16b
+ uabal v16.8h, v0.8b, v4.8b // absolute difference accumulate
+ uabal2 v17.8h, v0.16b, v4.16b
ld1 {v2.16b}, [x1], x3 // load pix1
ld1 {v6.16b}, [x2], x3 // load pix2
uabal v16.8h, v1.8b, v5.8b // absolute difference accumulate
@@ -48,30 +49,268 @@ function ff_pix_abs16_neon, export=1
uabal v16.8h, v3.8b, v7.8b
uabal2 v17.8h, v3.16b, v7.16b
cmp w4, #4 // if h >= 4, loop
- add v16.8h, v16.8h, v17.8h
- uaddlv s16, v16.8h // add up everything in v16 accumulator
- add d18, d16, d18 // add to the end result register
b.ge 1b
cbnz w4, 2f // if iterations remain, jump to completion section
- fmov w0, s18 // copy result to general purpose register
+ add v16.8h, v16.8h, v17.8h
+ uaddlv s16, v16.8h // add up everything in v16 accumulator
+ fmov w0, s16 // copy result to general purpose register
ret
2:
ld1 {v0.16b}, [x1], x3 // load pix1
ld1 {v4.16b}, [x2], x3 // load pix2
- uabdl v16.8h, v0.8b, v4.8b // absolute difference accumulate
- uabal2 v16.8h, v0.16b, v4.16b
subs w4, w4, #1 // h -= 1
- addv h16, v16.8h // add up v16
- add d18, d16, d18 // add to result
+ uabal v16.8h, v0.8b, v4.8b // absolute difference accumulate
+ uabal2 v17.8h, v0.16b, v4.16b
b.ne 2b
- fmov w0, s18 // copy result to general purpose register
+ add v16.8h, v16.8h, v17.8h
+ uaddlv s16, v16.8h // add up everything in v16 accumulator
+ fmov w0, s16 // copy result to general purpose register
ret
endfunc
+function ff_pix_abs8_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *pix2
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ movi v30.8h, #0
+ cmp w4, #4
+ b.lt 2f
+
+// make 4 iterations at once
+1:
+ ld1 {v0.8b}, [x1], x3 // Load pix1 for first iteration
+ ld1 {v1.8b}, [x2], x3 // Load pix2 for first iteration
+ ld1 {v2.8b}, [x1], x3 // Load pix1 for second iteration
+ uabal v30.8h, v0.8b, v1.8b // Absolute difference, first iteration
+ ld1 {v3.8b}, [x2], x3 // Load pix2 for second iteration
+ ld1 {v4.8b}, [x1], x3 // Load pix1 for third iteration
+ uabal v30.8h, v2.8b, v3.8b // Absolute difference, second iteration
+ ld1 {v5.8b}, [x2], x3 // Load pix2 for third iteration
+ sub w4, w4, #4 // h -= 4
+ ld1 {v6.8b}, [x1], x3 // Load pix1 for foruth iteration
+ ld1 {v7.8b}, [x2], x3 // Load pix2 for fourth iteration
+ uabal v30.8h, v4.8b, v5.8b // Absolute difference, third iteration
+ cmp w4, #4
+ uabal v30.8h, v6.8b, v7.8b // Absolute difference, foruth iteration
+ b.ge 1b
+
+ cbz w4, 3f
+
+// iterate by one
+2:
+ ld1 {v0.8b}, [x1], x3 // Load pix1
+ ld1 {v1.8b}, [x2], x3 // Load pix2
+
+ subs w4, w4, #1
+ uabal v30.8h, v0.8b, v1.8b
+ b.ne 2b
+
+3:
+ uaddlv s20, v30.8h // Add up vector
+ fmov w0, s20
+
+ ret
+endfunc
+
+function ff_pix_abs8_x2_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *pix2
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ cmp w4, #4
+ movi v26.8h, #0
+ add x5, x2, #1 // pix2 + 1
+ b.lt 2f
+
+// make 4 iterations at once
+1:
+ ld1 {v1.8b}, [x2], x3
+ ld1 {v2.8b}, [x5], x3
+ ld1 {v0.8b}, [x1], x3
+ ld1 {v4.8b}, [x2], x3
+ urhadd v30.8b, v1.8b, v2.8b
+ ld1 {v5.8b}, [x5], x3
+ uabal v26.8h, v0.8b, v30.8b
+ ld1 {v6.8b}, [x1], x3
+ urhadd v29.8b, v4.8b, v5.8b
+ ld1 {v7.8b}, [x2], x3
+ ld1 {v20.8b}, [x5], x3
+ uabal v26.8h, v6.8b, v29.8b
+ ld1 {v21.8b}, [x1], x3
+ urhadd v28.8b, v7.8b, v20.8b
+ ld1 {v22.8b}, [x2], x3
+ ld1 {v23.8b}, [x5], x3
+ uabal v26.8h, v21.8b, v28.8b
+ sub w4, w4, #4
+ ld1 {v24.8b}, [x1], x3
+ urhadd v27.8b, v22.8b, v23.8b
+ cmp w4, #4
+ uabal v26.8h, v24.8b, v27.8b
+
+ b.ge 1b
+ cbz w4, 3f
+
+// iterate by one
+2:
+ ld1 {v1.8b}, [x2], x3
+ ld1 {v2.8b}, [x5], x3
+ ld1 {v0.8b}, [x1], x3
+ urhadd v30.8b, v1.8b, v2.8b
+ subs w4, w4, #1
+ uabal v26.8h, v0.8b, v30.8b
+
+ b.ne 2b
+3:
+ uaddlv s20, v26.8h
+ fmov w0, s20
+
+ ret
+
+endfunc
+
+function ff_pix_abs8_y2_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *pix2
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ cmp w4, #4
+ movi v26.8h, #0
+ ld1 {v1.8b}, [x2], x3
+ b.lt 2f
+
+// make 4 iterations at once
+1:
+ ld1 {v2.8b}, [x2], x3
+ ld1 {v0.8b}, [x1], x3
+ urhadd v30.8b, v1.8b, v2.8b
+ ld1 {v5.8b}, [x2], x3
+ ld1 {v6.8b}, [x1], x3
+ uabal v26.8h, v0.8b, v30.8b
+ urhadd v29.8b, v2.8b, v5.8b
+ ld1 {v20.8b}, [x2], x3
+ ld1 {v21.8b}, [x1], x3
+ uabal v26.8h, v6.8b, v29.8b
+ urhadd v28.8b, v5.8b, v20.8b
+ ld1 {v1.8b}, [x2], x3
+ ld1 {v24.8b}, [x1], x3
+ urhadd v27.8b, v20.8b, v1.8b
+ sub w4, w4, #4
+ uabal v26.8h, v21.8b, v28.8b
+ cmp w4, #4
+ uabal v26.8h, v24.8b, v27.8b
+
+ b.ge 1b
+ cbz w4, 3f
+
+// iterate by one
+2:
+ ld1 {v0.8b}, [x1], x3
+ ld1 {v2.8b}, [x2], x3
+ urhadd v30.8b, v1.8b, v2.8b
+ subs w4, w4, #1
+ uabal v26.8h, v0.8b, v30.8b
+ mov v1.8b, v2.8b
+
+ b.ne 2b
+3:
+ uaddlv s20, v26.8h
+ fmov w0, s20
+
+ ret
+
+endfunc
+
+function ff_pix_abs8_xy2_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *pix2
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ movi v31.8h, #0
+ add x0, x2, 1 // pix2 + 1
+
+ add x5, x2, x3 // pix2 + stride = pix3
+ cmp w4, #4
+ add x6, x5, 1 // pix3 + stride + 1
+
+ ld1 {v0.8b}, [x2], x3
+ ld1 {v1.8b}, [x0], x3
+ uaddl v2.8h, v0.8b, v1.8b
+
+ b.lt 2f
+
+// make 4 iterations at once
+1:
+ ld1 {v4.8b}, [x5], x3
+ ld1 {v5.8b}, [x6], x3
+ ld1 {v7.8b}, [x5], x3
+ uaddl v0.8h, v4.8b, v5.8b
+ ld1 {v16.8b}, [x6], x3
+ add v4.8h, v0.8h, v2.8h
+ ld1 {v5.8b}, [x1], x3
+ rshrn v4.8b, v4.8h, #2
+ uaddl v7.8h, v7.8b, v16.8b
+ uabal v31.8h, v5.8b, v4.8b
+ add v2.8h, v0.8h, v7.8h
+ ld1 {v17.8b}, [x1], x3
+ rshrn v2.8b, v2.8h, #2
+ ld1 {v20.8b}, [x5], x3
+ uabal v31.8h, v17.8b, v2.8b
+ ld1 {v21.8b}, [x6], x3
+ ld1 {v25.8b}, [x5], x3
+ uaddl v20.8h, v20.8b, v21.8b
+ ld1 {v26.8b}, [x6], x3
+ add v7.8h, v7.8h, v20.8h
+ uaddl v25.8h, v25.8b, v26.8b
+ rshrn v7.8b, v7.8h, #2
+ ld1 {v22.8b}, [x1], x3
+ mov v2.16b, v25.16b
+ uabal v31.8h, v22.8b, v7.8b
+ add v20.8h, v20.8h, v25.8h
+ ld1 {v27.8b}, [x1], x3
+ sub w4, w4, #4
+ rshrn v20.8b, v20.8h, #2
+ cmp w4, #4
+ uabal v31.8h, v27.8b, v20.8b
+
+ b.ge 1b
+
+ cbz w4, 3f
+
+// iterate by one
+2:
+ ld1 {v0.8b}, [x5], x3
+ ld1 {v1.8b}, [x6], x3
+ ld1 {v4.8b}, [x1], x3
+ uaddl v21.8h, v0.8b, v1.8b
+ subs w4, w4, #1
+ add v3.8h, v2.8h, v21.8h
+ mov v2.16b, v21.16b
+ rshrn v3.8b, v3.8h, #2
+ uabal v31.8h, v4.8b, v3.8b
+ b.ne 2b
+
+3:
+ uaddlv s18, v31.8h
+ fmov w0, s18
+
+ ret
+
+endfunc
+
+
function ff_pix_abs16_xy2_neon, export=1
// x0 unused
// x1 uint8_t *pix1
@@ -80,7 +319,8 @@ function ff_pix_abs16_xy2_neon, export=1
// w4 int h
add x5, x2, x3 // use x5 to hold uint8_t *pix3
- movi v0.2d, #0 // initialize the result register
+ movi v21.8h, #0 // initialize the result register
+ movi v22.8h, #0 // initialize the result register
// Load initial pix2 values for either the unrolled version or completion version.
ldur q4, [x2, #1] // load pix2+1
@@ -101,26 +341,35 @@ function ff_pix_abs16_xy2_neon, export=1
ld1 {v6.16b}, [x5], x3 // load pix3
ld1 {v16.16b}, [x1], x3 // load pix1
- ldur q19, [x5, #1] // load pix3+1
- ld1 {v18.16b}, [x5], x3 // load pix3
- ld1 {v17.16b}, [x1], x3 // load pix1
-
- ldur q22, [x5, #1] // load pix3+1
- ld1 {v21.16b}, [x5], x3 // load pix3
- ld1 {v20.16b}, [x1], x3 // load pix1
-
// These blocks compute the average: avg(pix2[n], pix2[n+1], pix3[n], pix3[n+1])
uaddl v30.8h, v4.8b, v5.8b // pix3 + pix3+1 0..7
uaddl2 v31.8h, v4.16b, v5.16b // pix3 + pix3+1 8..15
+
+ ldur q19, [x5, #1] // load pix3+1
+
add v23.8h, v2.8h, v30.8h // add up 0..7, using pix2 + pix2+1 values from previous iteration
add v24.8h, v3.8h, v31.8h // add up 8..15, using pix2 + pix2+1 values from previous iteration
+
+ ld1 {v18.16b}, [x5], x3 // load pix3
+ ld1 {v17.16b}, [x1], x3 // load pix1
+
rshrn v23.8b, v23.8h, #2 // shift right 2 0..7 (rounding shift right)
rshrn2 v23.16b, v24.8h, #2 // shift right 2 8..15
uaddl v2.8h, v6.8b, v7.8b // pix3 + pix3+1 0..7
uaddl2 v3.8h, v6.16b, v7.16b // pix3 + pix3+1 8..15
+
+ ldur q7, [x5, #1] // load pix3+1
+
add v26.8h, v30.8h, v2.8h // add up 0..7, using pix2 + pix2+1 values from pix3 above
add v27.8h, v31.8h, v3.8h // add up 8..15, using pix2 + pix2+1 values from pix3 above
+
+ uabal v21.8h, v1.8b, v23.8b // absolute difference 0..7, i=0
+ uabal2 v22.8h, v1.16b, v23.16b // absolute difference 8..15, i=0
+
+ ld1 {v6.16b}, [x5], x3 // load pix3
+ ld1 {v20.16b}, [x1], x3 // load pix1
+
rshrn v26.8b, v26.8h, #2 // shift right 2 0..7 (rounding shift right)
rshrn2 v26.16b, v27.8h, #2 // shift right 2 8..15
@@ -131,46 +380,33 @@ function ff_pix_abs16_xy2_neon, export=1
rshrn v28.8b, v28.8h, #2 // shift right 2 0..7 (rounding shift right)
rshrn2 v28.16b, v29.8h, #2 // shift right 2 8..15
- uaddl v2.8h, v21.8b, v22.8b // pix3 + pix3+1 0..7
- uaddl2 v3.8h, v21.16b, v22.16b // pix3 + pix3+1 8..15
+ uabal v21.8h, v16.8b, v26.8b // absolute difference 0..7, i=1
+ uabal2 v22.8h, v16.16b, v26.16b // absolute difference 8..15, i=1
+
+ uaddl v2.8h, v6.8b, v7.8b // pix3 + pix3+1 0..7
+ uaddl2 v3.8h, v6.16b, v7.16b // pix3 + pix3+1 8..15
add v30.8h, v4.8h, v2.8h // add up 0..7, using pix2 + pix2+1 values from pix3 above
add v31.8h, v5.8h, v3.8h // add up 8..15, using pix2 + pix2+1 values from pix3 above
rshrn v30.8b, v30.8h, #2 // shift right 2 0..7 (rounding shift right)
rshrn2 v30.16b, v31.8h, #2 // shift right 2 8..15
- // Averages are now stored in these registers:
- // v23, v16, v28, v30
- // pix1 values in these registers:
- // v1, v16, v17, v20
- // available:
- // v4, v5, v7, v18, v19, v24, v25, v27, v29, v31
-
sub w4, w4, #4 // h -= 4
- // Using absolute-difference instructions instead of absolute-difference-accumulate allows
- // us to keep the results in 16b vectors instead of widening values with twice the instructions.
- // This approach also has fewer data dependencies, allowing better instruction level parallelism.
- uabd v4.16b, v1.16b, v23.16b // absolute difference 0..15, i=0
- uabd v5.16b, v16.16b, v26.16b // absolute difference 0..15, i=1
- uabd v6.16b, v17.16b, v28.16b // absolute difference 0..15, i=2
- uabd v7.16b, v20.16b, v30.16b // absolute difference 0..15, i=3
+ uabal v21.8h, v17.8b, v28.8b // absolute difference 0..7, i=2
+ uabal2 v22.8h, v17.16b, v28.16b // absolute difference 8..15, i=2
cmp w4, #4 // loop if h >= 4
- // Now add up all the values in each vector, v4-v7 with widening adds
- uaddl v19.8h, v4.8b, v5.8b
- uaddl2 v18.8h, v4.16b, v5.16b
- uaddl v4.8h, v6.8b, v7.8b
- uaddl2 v5.8h, v6.16b, v7.16b
- add v4.8h, v4.8h, v5.8h
- add v4.8h, v4.8h, v18.8h
- add v4.8h, v4.8h, v19.8h
- uaddlv s4, v4.8h // finish adding up accumulated values
- add d0, d0, d4 // add the value to the top level accumulator
+
+ uabal v21.8h, v20.8b, v30.8b // absolute difference 0..7, i=3
+ uabal2 v22.8h, v20.16b, v30.16b // absolute difference 8..15, i=3
b.ge 1b
cbnz w4, 2f // if iterations remain jump to completion section
+ add v4.8h, v21.8h, v22.8h
+ uaddlv s0, v4.8h // finish adding up accumulated values
+
fmov w0, s0 // copy result to general purpose register
ret
2:
@@ -186,20 +422,1140 @@ function ff_pix_abs16_xy2_neon, export=1
add v16.8h, v2.8h, v18.8h // add up 0..7, using pix2 + pix2+1 values from previous iteration
add v17.8h, v3.8h, v19.8h // add up 8..15, using pix2 + pix2+1 values from previous iteration
// divide by 4 to compute the average of values summed above
- urshr v16.8h, v16.8h, #2 // shift right by 2 0..7 (rounding shift right)
- urshr v17.8h, v17.8h, #2 // shift right by 2 8..15
+ rshrn v16.8b, v16.8h, #2 // shift right by 2 0..7 (rounding shift right)
+ rshrn2 v16.16b, v17.8h, #2 // shift right by 2 8..15
- uxtl2 v8.8h, v1.16b // 8->16 bits pix1 8..15
- uxtl v1.8h, v1.8b // 8->16 bits pix1 0..7
-
- uabd v6.8h, v1.8h, v16.8h // absolute difference 0..7
- uaba v6.8h, v8.8h, v17.8h // absolute difference accumulate 8..15
+ uabal v21.8h, v1.8b, v16.8b // absolute difference 0..7
+ uabal2 v22.8h, v1.16b, v16.16b // absolute difference accumulate 8..15
mov v2.16b, v18.16b // pix3 -> pix2
mov v3.16b, v19.16b // pix3+1 -> pix2+1
- uaddlv s6, v6.8h // add up accumulator in v6
- add d0, d0, d6 // add to the final result
b.ne 2b // loop if h > 0
+
+ add v4.8h, v21.8h, v22.8h
+ uaddlv s0, v4.8h // finish adding up accumulated values
fmov w0, s0 // copy result to general purpose register
ret
endfunc
+
+function ff_pix_abs16_x2_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *pix2
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ cmp w4, #4
+ // initialize buffers
+ movi v16.8h, #0
+ movi v17.8h, #0
+ add x5, x2, #1 // pix2 + 1
+ b.lt 2f
+
+// make 4 iterations at once
+1:
+
+ // abs(pix1[0] - avg2(pix2[0], pix2[1]))
+ // avg2(a,b) = (((a) + (b) + 1) >> 1)
+ // abs(x) = (x < 0 ? -x : x)
+
+ ld1 {v1.16b}, [x2], x3
+ ld1 {v2.16b}, [x5], x3
+ urhadd v30.16b, v1.16b, v2.16b
+ ld1 {v0.16b}, [x1], x3
+ uabal v16.8h, v0.8b, v30.8b
+ ld1 {v4.16b}, [x2], x3
+ uabal2 v17.8h, v0.16b, v30.16b
+ ld1 {v5.16b}, [x5], x3
+ urhadd v29.16b, v4.16b, v5.16b
+ ld1 {v3.16b}, [x1], x3
+ uabal v16.8h, v3.8b, v29.8b
+ ld1 {v7.16b}, [x2], x3
+ uabal2 v17.8h, v3.16b, v29.16b
+ ld1 {v22.16b}, [x5], x3
+ urhadd v28.16b, v7.16b, v22.16b
+ ld1 {v6.16b}, [x1], x3
+ uabal v16.8h, v6.8b, v28.8b
+ ld1 {v24.16b}, [x2], x3
+ sub w4, w4, #4
+ uabal2 v17.8h, v6.16b, v28.16b
+ ld1 {v25.16b}, [x5], x3
+ urhadd v27.16b, v24.16b, v25.16b
+ ld1 {v23.16b}, [x1], x3
+ cmp w4, #4
+ uabal v16.8h, v23.8b, v27.8b
+ uabal2 v17.8h, v23.16b, v27.16b
+
+ b.ge 1b
+ cbz w4, 3f
+
+// iterate by one
+2:
+ ld1 {v1.16b}, [x2], x3
+ ld1 {v2.16b}, [x5], x3
+ subs w4, w4, #1
+ urhadd v29.16b, v1.16b, v2.16b
+ ld1 {v0.16b}, [x1], x3
+ uabal v16.8h, v0.8b, v29.8b
+ uabal2 v17.8h, v0.16b, v29.16b
+
+
+ b.ne 2b
+
+3:
+ add v16.8h, v16.8h, v17.8h
+ uaddlv s16, v16.8h
+ fmov w0, s16
+
+ ret
+endfunc
+
+function ff_pix_abs16_y2_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *pix2
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ // initialize buffers
+ ld1 {v1.16b}, [x2], x3 // Load pix2
+ movi v29.8h, #0 // clear the accumulator
+ movi v28.8h, #0 // clear the accumulator
+ cmp w4, #4
+ b.lt 2f
+
+// make 4 iterations at once
+1:
+
+ // abs(pix1[0], avg2(pix2[0], pix2[0 + stride]))
+ // avg2(a, b) = (((a) + (b) + 1) >> 1)
+ // abs(x) = (x < 0 ? (-x) : (x))
+
+ ld1 {v2.16b}, [x2], x3 // Load pix3 for first iteration
+ ld1 {v0.16b}, [x1], x3 // Load pix1 for first iteration
+ urhadd v30.16b, v1.16b, v2.16b // Rounding halving add, first iteration
+ ld1 {v5.16b}, [x2], x3 // Load pix3 for second iteartion
+ uabal v29.8h, v0.8b, v30.8b // Absolute difference of lower half, first iteration
+ uabal2 v28.8h, v0.16b, v30.16b // Absolute difference of upper half, first iteration
+ ld1 {v3.16b}, [x1], x3 // Load pix1 for second iteration
+ urhadd v27.16b, v2.16b, v5.16b // Rounding halving add, second iteration
+ ld1 {v20.16b}, [x2], x3 // Load pix3 for third iteration
+ uabal v29.8h, v3.8b, v27.8b // Absolute difference of lower half for second iteration
+ uabal2 v28.8h, v3.16b, v27.16b // Absolute difference of upper half for second iteration
+ ld1 {v6.16b}, [x1], x3 // Load pix1 for third iteration
+ urhadd v26.16b, v5.16b, v20.16b // Rounding halving add, third iteration
+ ld1 {v1.16b}, [x2], x3 // Load pix3 for fourth iteration
+ uabal v29.8h, v6.8b, v26.8b // Absolute difference of lower half for third iteration
+ uabal2 v28.8h, v6.16b, v26.16b // Absolute difference of upper half for third iteration
+ ld1 {v21.16b}, [x1], x3 // Load pix1 for fourth iteration
+ sub w4, w4, #4 // h-= 4
+ urhadd v25.16b, v20.16b, v1.16b // Rounding halving add
+ cmp w4, #4
+ uabal v29.8h, v21.8b, v25.8b // Absolute difference of lower half for fourth iteration
+ uabal2 v28.8h, v21.16b, v25.16b // Absolute difference of upper half for fourth iteration
+
+ b.ge 1b
+ cbz w4, 3f
+
+// iterate by one
+2:
+
+ ld1 {v2.16b}, [x2], x3 // Load pix3
+ subs w4, w4, #1
+ ld1 {v0.16b}, [x1], x3 // Load pix1
+ urhadd v30.16b, v1.16b, v2.16b // Rounding halving add
+ mov v1.16b, v2.16b // Shift pix3->pix2
+ uabal v29.8h, v30.8b, v0.8b
+ uabal2 v28.8h, v30.16b, v0.16b
+
+ b.ne 2b
+
+3:
+ add v29.8h, v29.8h, v28.8h // Add vectors together
+ uaddlv s16, v29.8h // Add up vector values
+
+ fmov w0, s16
+
+ ret
+endfunc
+
+function sse16_neon, export=1
+ // x0 - unused
+ // x1 - pix1
+ // x2 - pix2
+ // x3 - stride
+ // w4 - h
+
+ cmp w4, #4
+ movi v17.4s, #0
+ b.lt 2f
+
+// Make 4 iterations at once
+1:
+
+ // res = abs(pix1[0] - pix2[0])
+ // res * res
+
+ ld1 {v0.16b}, [x1], x3 // Load pix1 vector for first iteration
+ ld1 {v1.16b}, [x2], x3 // Load pix2 vector for first iteration
+ ld1 {v2.16b}, [x1], x3 // Load pix1 vector for second iteration
+ uabd v30.16b, v0.16b, v1.16b // Absolute difference, first iteration
+ ld1 {v3.16b}, [x2], x3 // Load pix2 vector for second iteration
+ umull v29.8h, v30.8b, v30.8b // Multiply lower half of vectors, first iteration
+ umull2 v28.8h, v30.16b, v30.16b // Multiply upper half of vectors, first iteration
+ uabd v27.16b, v2.16b, v3.16b // Absolute difference, second iteration
+ uadalp v17.4s, v29.8h // Pairwise add, first iteration
+ ld1 {v4.16b}, [x1], x3 // Load pix1 for third iteration
+ umull v26.8h, v27.8b, v27.8b // Mulitply lower half, second iteration
+ umull2 v25.8h, v27.16b, v27.16b // Multiply upper half, second iteration
+ ld1 {v5.16b}, [x2], x3 // Load pix2 for third iteration
+ uadalp v17.4s, v26.8h // Pairwise add and accumulate, second iteration
+ uabd v24.16b, v4.16b, v5.16b // Absolute difference, third iteration
+ ld1 {v6.16b}, [x1], x3 // Load pix1 for fourth iteration
+ uadalp v17.4s, v25.8h // Pairwise add and accumulate, second iteration
+ umull v23.8h, v24.8b, v24.8b // Multiply lower half, third iteration
+ umull2 v22.8h, v24.16b, v24.16b // Multiply upper half, third iteration
+ uadalp v17.4s, v23.8h // Pairwise add and accumulate, third iteration
+ ld1 {v7.16b}, [x2], x3 // Load pix2 for fouth iteration
+ uadalp v17.4s, v22.8h // Pairwise add and accumulate, third iteration
+ uabd v21.16b, v6.16b, v7.16b // Absolute difference, fourth iteration
+ uadalp v17.4s, v28.8h // Pairwise add and accumulate, first iteration
+ umull v20.8h, v21.8b, v21.8b // Multiply lower half, fourth iteration
+ sub w4, w4, #4 // h -= 4
+ umull2 v19.8h, v21.16b, v21.16b // Multiply upper half, fourth iteration
+ uadalp v17.4s, v20.8h // Pairwise add and accumulate, fourth iteration
+ cmp w4, #4
+ uadalp v17.4s, v19.8h // Pairwise add and accumulate, fourth iteration
+ b.ge 1b
+
+ cbz w4, 3f
+
+// iterate by one
+2:
+
+ ld1 {v0.16b}, [x1], x3 // Load pix1
+ ld1 {v1.16b}, [x2], x3 // Load pix2
+
+ uabd v30.16b, v0.16b, v1.16b
+ umull v29.8h, v30.8b, v30.8b
+ umull2 v28.8h, v30.16b, v30.16b
+ uadalp v17.4s, v29.8h
+ subs w4, w4, #1
+ uadalp v17.4s, v28.8h
+
+ b.ne 2b
+
+3:
+ uaddlv d16, v17.4s // add up accumulator vector
+
+ fmov w0, s16
+
+ ret
+endfunc
+
+function sse8_neon, export=1
+ // x0 - unused
+ // x1 - pix1
+ // x2 - pix2
+ // x3 - stride
+ // w4 - h
+
+ movi v21.4s, #0
+ movi v20.4s, #0
+ cmp w4, #4
+ b.lt 2f
+
+// make 4 iterations at once
+1:
+
+ // res = abs(pix1[0] - pix2[0])
+ // res * res
+
+ ld1 {v0.8b}, [x1], x3 // Load pix1 for first iteration
+ ld1 {v1.8b}, [x2], x3 // Load pix2 for second iteration
+ ld1 {v2.8b}, [x1], x3 // Load pix1 for second iteration
+ ld1 {v3.8b}, [x2], x3 // Load pix2 for second iteration
+ uabdl v30.8h, v0.8b, v1.8b // Absolute difference, first iteration
+ ld1 {v4.8b}, [x1], x3 // Load pix1 for third iteration
+ ld1 {v5.8b}, [x2], x3 // Load pix2 for third iteration
+ uabdl v29.8h, v2.8b, v3.8b // Absolute difference, second iteration
+ umlal v21.4s, v30.4h, v30.4h // Multiply lower half, first iteration
+ ld1 {v6.8b}, [x1], x3 // Load pix1 for fourth iteration
+ ld1 {v7.8b}, [x2], x3 // Load pix2 for fourth iteration
+ uabdl v28.8h, v4.8b, v5.8b // Absolute difference, third iteration
+ umlal v21.4s, v29.4h, v29.4h // Multiply lower half, second iteration
+ umlal2 v20.4s, v30.8h, v30.8h // Multiply upper half, first iteration
+ uabdl v27.8h, v6.8b, v7.8b // Absolute difference, fourth iteration
+ umlal v21.4s, v28.4h, v28.4h // Multiply lower half, third iteration
+ umlal2 v20.4s, v29.8h, v29.8h // Multiply upper half, second iteration
+ sub w4, w4, #4 // h -= 4
+ umlal2 v20.4s, v28.8h, v28.8h // Multiply upper half, third iteration
+ umlal v21.4s, v27.4h, v27.4h // Multiply lower half, fourth iteration
+ cmp w4, #4
+ umlal2 v20.4s, v27.8h, v27.8h // Multiply upper half, fourth iteration
+ b.ge 1b
+
+ cbz w4, 3f
+
+// iterate by one
+2:
+ ld1 {v0.8b}, [x1], x3 // Load pix1
+ ld1 {v1.8b}, [x2], x3 // Load pix2
+ subs w4, w4, #1
+ uabdl v30.8h, v0.8b, v1.8b
+ umlal v21.4s, v30.4h, v30.4h
+ umlal2 v20.4s, v30.8h, v30.8h
+
+ b.ne 2b
+
+3:
+ add v21.4s, v21.4s, v20.4s // Add accumulator vectors together
+ uaddlv d17, v21.4s // Add up vector
+
+ fmov w0, s17
+ ret
+
+endfunc
+
+function sse4_neon, export=1
+ // x0 - unused
+ // x1 - pix1
+ // x2 - pix2
+ // x3 - stride
+ // w4 - h
+
+ movi v16.4s, #0 // clear the result accumulator
+ cmp w4, #4
+ b.lt 2f
+
+// make 4 iterations at once
+1:
+
+ // res = abs(pix1[0] - pix2[0])
+ // res * res
+
+ ld1 {v0.s}[0], [x1], x3 // Load pix1, first iteration
+ ld1 {v1.s}[0], [x2], x3 // Load pix2, first iteration
+ ld1 {v2.s}[0], [x1], x3 // Load pix1, second iteration
+ ld1 {v3.s}[0], [x2], x3 // Load pix2, second iteration
+ uabdl v30.8h, v0.8b, v1.8b // Absolute difference, first iteration
+ ld1 {v4.s}[0], [x1], x3 // Load pix1, third iteration
+ ld1 {v5.s}[0], [x2], x3 // Load pix2, third iteration
+ uabdl v29.8h, v2.8b, v3.8b // Absolute difference, second iteration
+ umlal v16.4s, v30.4h, v30.4h // Multiply vectors, first iteration
+ ld1 {v6.s}[0], [x1], x3 // Load pix1, fourth iteration
+ ld1 {v7.s}[0], [x2], x3 // Load pix2, fourth iteration
+ uabdl v28.8h, v4.8b, v5.8b // Absolute difference, third iteration
+ umlal v16.4s, v29.4h, v29.4h // Multiply and accumulate, second iteration
+ sub w4, w4, #4
+ uabdl v27.8h, v6.8b, v7.8b // Absolue difference, fourth iteration
+ umlal v16.4s, v28.4h, v28.4h // Multiply and accumulate, third iteration
+ cmp w4, #4
+ umlal v16.4s, v27.4h, v27.4h // Multiply and accumulate, fourth iteration
+ b.ge 1b
+
+ cbz w4, 3f
+
+// iterate by one
+2:
+ ld1 {v0.s}[0], [x1], x3 // Load pix1
+ ld1 {v1.s}[0], [x2], x3 // Load pix2
+ uabdl v30.8h, v0.8b, v1.8b
+ subs w4, w4, #1
+ umlal v16.4s, v30.4h, v30.4h
+
+ b.ne 2b
+
+3:
+ uaddlv d17, v16.4s // Add vector
+ fmov w0, s17
+
+ ret
+endfunc
+
+function vsad16_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *pix2
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ ld1 {v0.16b}, [x1], x3 // Load pix1[0], first iteration
+ ld1 {v1.16b}, [x2], x3 // Load pix2[0], first iteration
+
+ sub w4, w4, #1 // we need to make h-1 iterations
+ movi v16.8h, #0
+
+ cmp w4, #3 // check if we can make 3 iterations at once
+ usubl v31.8h, v0.8b, v1.8b // Signed difference pix1[0] - pix2[0], first iteration
+ usubl2 v30.8h, v0.16b, v1.16b // Signed difference pix1[0] - pix2[0], first iteration
+
+ b.lt 2f
+
+1:
+ // abs(pix1[0] - pix2[0] - pix1[0 + stride] + pix2[0 + stride])
+ ld1 {v0.16b}, [x1], x3 // Load pix1[0 + stride], first iteration
+ ld1 {v1.16b}, [x2], x3 // Load pix2[0 + stride], first iteration
+ ld1 {v2.16b}, [x1], x3 // Load pix1[0 + stride], second iteration
+ ld1 {v3.16b}, [x2], x3 // Load pix2[0 + stride], second iteration
+ usubl v29.8h, v0.8b, v1.8b // Signed difference pix1[0 + stride] - pix2[0 + stride], first iteration
+ usubl2 v28.8h, v0.16b, v1.16b // Signed difference pix1[0 + stride] - pix2[0 + stride], first iteration
+ ld1 {v4.16b}, [x1], x3 // Load pix1[0 + stride], third iteration
+ ld1 {v5.16b}, [x2], x3 // Load pix2[0 + stride], third iteration
+ usubl v27.8h, v2.8b, v3.8b // Signed difference pix1[0 + stride] - pix2[0 + stride], second iteration
+ saba v16.8h, v31.8h, v29.8h // Signed absolute difference and accumulate the result. first iteration
+ usubl2 v26.8h, v2.16b, v3.16b // Signed difference pix1[0 + stride] - pix2[0 + stride], second iteration
+ saba v16.8h, v30.8h, v28.8h // Signed absolute difference and accumulate the result. first iteration
+ usubl v25.8h, v4.8b, v5.8b // Signed difference pix1[0 + stride] - pix2[0 + stride], third iteration
+ usubl2 v24.8h, v4.16b, v5.16b // Signed difference pix1[0 + stride] - pix2[0 + stride], third iteration
+ saba v16.8h, v29.8h, v27.8h // Signed absolute difference and accumulate the result. second iteration
+ mov v31.16b, v25.16b
+ saba v16.8h, v28.8h, v26.8h // Signed absolute difference and accumulate the result. second iteration
+ sub w4, w4, #3 // h -= 3
+ mov v30.16b, v24.16b
+ saba v16.8h, v27.8h, v25.8h // Signed absolute difference and accumulate the result. third iteration
+ cmp w4, #3
+ saba v16.8h, v26.8h, v24.8h // Signed absolute difference and accumulate the result. third iteration
+
+ b.ge 1b
+ cbz w4, 3f
+2:
+ ld1 {v0.16b}, [x1], x3
+ ld1 {v1.16b}, [x2], x3
+ subs w4, w4, #1
+ usubl v29.8h, v0.8b, v1.8b
+ usubl2 v28.8h, v0.16b, v1.16b
+ saba v16.8h, v31.8h, v29.8h
+ mov v31.16b, v29.16b
+ saba v16.8h, v30.8h, v28.8h
+ mov v30.16b, v28.16b
+
+ b.ne 2b
+3:
+ uaddlv s17, v16.8h
+ fmov w0, s17
+
+ ret
+endfunc
+
+function vsse8_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *pix2
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ ld1 {v0.8b}, [x1], x3 // Load pix1[0], first iteration
+ ld1 {v1.8b}, [x2], x3 // Load pix2[0], first iteration
+
+ sub w4, w4, #1 // we need to make h-1 iterations
+ movi v16.4s, #0
+ movi v17.4s, #0
+
+ cmp w4, #3 // check if we can make 3 iterations at once
+ usubl v31.8h, v0.8b, v1.8b // Signed difference of pix1[0] - pix2[0], first iteration
+ b.lt 2f
+
+
+1:
+ // x = abs(pix1[0] - pix2[0] - pix1[0 + stride] + pix2[0 + stride])
+ // res = (x) * (x)
+ ld1 {v0.8b}, [x1], x3 // Load pix1[0 + stride], first iteration
+ ld1 {v1.8b}, [x2], x3 // Load pix2[0 + stride], first iteration
+ ld1 {v2.8b}, [x1], x3 // Load pix1[0 + stride], second iteration
+ ld1 {v3.8b}, [x2], x3 // Load pix2[0 + stride], second iteration
+ usubl v29.8h, v0.8b, v1.8b
+ usubl2 v28.8h, v0.16b, v1.16b
+ ld1 {v4.8b}, [x1], x3 // Load pix1[0 + stride], third iteration
+ ld1 {v5.8b}, [x2], x3 // Load pix1[0 + stride], third iteration
+ sabd v31.8h, v31.8h, v29.8h
+ usubl v27.8h, v2.8b, v3.8b
+ usubl v25.8h, v4.8b, v5.8b
+ sabd v29.8h, v29.8h, v27.8h
+ sabd v27.8h, v27.8h, v25.8h
+ umlal v16.4s, v31.4h, v31.4h
+ umlal2 v17.4s, v31.8h, v31.8h
+ mov v31.16b, v25.16b
+ umlal v16.4s, v29.4h, v29.4h
+ umlal2 v17.4s, v29.8h, v29.8h
+ sub w4, w4, #3
+ umlal v16.4s, v27.4h, v27.4h
+ umlal2 v17.4s, v27.8h, v27.8h
+ cmp w4, #3
+
+ b.ge 1b
+
+ cbz w4, 3f
+
+// iterate by once
+2:
+ ld1 {v0.8b}, [x1], x3
+ ld1 {v1.8b}, [x2], x3
+ subs w4, w4, #1
+ usubl v29.8h, v0.8b, v1.8b
+ sabd v31.8h, v31.8h, v29.8h
+ umlal v16.4s, v31.4h, v31.4h
+ umlal2 v17.4s, v31.8h, v31.8h
+ mov v31.16b, v29.16b
+ b.ne 2b
+
+3:
+ add v16.4s, v16.4s, v17.4s
+ uaddlv d17, v16.4s
+ fmov w0, s17
+
+ ret
+endfunc
+
+
+function vsse16_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *pix2
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ ld1 {v0.16b}, [x1], x3 // Load pix1[0], first iteration
+ ld1 {v1.16b}, [x2], x3 // Load pix2[0], first iteration
+
+ sub w4, w4, #1 // we need to make h-1 iterations
+ movi v16.4s, #0
+ movi v17.4s, #0
+
+ cmp w4, #3 // check if we can make 3 iterations at once
+ usubl v31.8h, v0.8b, v1.8b // Signed difference of pix1[0] - pix2[0], first iteration
+ usubl2 v30.8h, v0.16b, v1.16b // Signed difference of pix1[0] - pix2[0], first iteration
+ b.lt 2f
+
+
+1:
+ // x = abs(pix1[0] - pix2[0] - pix1[0 + stride] + pix2[0 + stride])
+ // res = (x) * (x)
+ ld1 {v0.16b}, [x1], x3 // Load pix1[0 + stride], first iteration
+ ld1 {v1.16b}, [x2], x3 // Load pix2[0 + stride], first iteration
+ ld1 {v2.16b}, [x1], x3 // Load pix1[0 + stride], second iteration
+ ld1 {v3.16b}, [x2], x3 // Load pix2[0 + stride], second iteration
+ usubl v29.8h, v0.8b, v1.8b
+ usubl2 v28.8h, v0.16b, v1.16b
+ ld1 {v4.16b}, [x1], x3 // Load pix1[0 + stride], third iteration
+ ld1 {v5.16b}, [x2], x3 // Load pix1[0 + stride], third iteration
+ sabd v31.8h, v31.8h, v29.8h
+ sabd v30.8h, v30.8h, v28.8h
+ usubl v27.8h, v2.8b, v3.8b
+ usubl2 v26.8h, v2.16b, v3.16b
+ usubl v25.8h, v4.8b, v5.8b
+ usubl2 v24.8h, v4.16b, v5.16b
+ sabd v29.8h, v29.8h, v27.8h
+ sabd v27.8h, v27.8h, v25.8h
+ umlal v16.4s, v31.4h, v31.4h
+ umlal2 v17.4s, v31.8h, v31.8h
+ sabd v28.8h, v28.8h, v26.8h
+ sabd v26.8h, v26.8h, v24.8h
+ umlal v16.4s, v30.4h, v30.4h
+ umlal2 v17.4s, v30.8h, v30.8h
+ mov v31.16b, v25.16b
+ umlal v16.4s, v29.4h, v29.4h
+ umlal2 v17.4s, v29.8h, v29.8h
+ mov v30.16b, v24.16b
+ umlal v16.4s, v28.4h, v28.4h
+ umlal2 v17.4s, v28.8h, v28.8h
+ sub w4, w4, #3
+ umlal v16.4s, v27.4h, v27.4h
+ umlal2 v17.4s, v27.8h, v27.8h
+ cmp w4, #3
+ umlal v16.4s, v26.4h, v26.4h
+ umlal2 v17.4s, v26.8h, v26.8h
+
+ b.ge 1b
+
+ cbz w4, 3f
+
+// iterate by once
+2:
+ ld1 {v0.16b}, [x1], x3
+ ld1 {v1.16b}, [x2], x3
+ subs w4, w4, #1
+ usubl v29.8h, v0.8b, v1.8b
+ usubl2 v28.8h, v0.16b, v1.16b
+ sabd v31.8h, v31.8h, v29.8h
+ sabd v30.8h, v30.8h, v28.8h
+ umlal v16.4s, v31.4h, v31.4h
+ umlal2 v17.4s, v31.8h, v31.8h
+ mov v31.16b, v29.16b
+ umlal v16.4s, v30.4h, v30.4h
+ umlal2 v17.4s, v30.8h, v30.8h
+ mov v30.16b, v28.16b
+ b.ne 2b
+
+3:
+ add v16.4s, v16.4s, v17.4s
+ uaddlv d17, v16.4s
+ fmov w0, s17
+
+ ret
+endfunc
+
+function vsad_intra16_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *dummy
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ ld1 {v0.16b}, [x1], x3
+ sub w4, w4, #1 // we need to make h-1 iterations
+ cmp w4, #3
+ movi v16.8h, #0
+ b.lt 2f
+
+// make 4 iterations at once
+1:
+ // v = abs( pix1[0] - pix1[0 + stride] )
+ // score = sum(v)
+ ld1 {v1.16b}, [x1], x3
+ ld1 {v2.16b}, [x1], x3
+ uabal v16.8h, v0.8b, v1.8b
+ ld1 {v3.16b}, [x1], x3
+ uabal2 v16.8h, v0.16b, v1.16b
+ sub w4, w4, #3
+ uabal v16.8h, v1.8b, v2.8b
+ cmp w4, #3
+ uabal2 v16.8h, v1.16b, v2.16b
+ mov v0.16b, v3.16b
+ uabal v16.8h, v2.8b, v3.8b
+ uabal2 v16.8h, v2.16b, v3.16b
+ b.ge 1b
+ cbz w4, 3f
+
+// iterate by one
+2:
+ ld1 {v1.16b}, [x1], x3
+ subs w4, w4, #1
+ uabal v16.8h, v0.8b, v1.8b
+ uabal2 v16.8h, v0.16b, v1.16b
+ mov v0.16b, v1.16b
+ cbnz w4, 2b
+
+3:
+ uaddlv s17, v16.8h
+ fmov w0, s17
+
+ ret
+endfunc
+
+function vsse_intra16_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *dummy
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ ld1 {v0.16b}, [x1], x3
+ movi v16.4s, #0
+ movi v17.4s, #0
+
+ sub w4, w4, #1 // we need to make h-1 iterations
+ cmp w4, #3
+ b.lt 2f
+
+1:
+ // v = abs( pix1[0] - pix1[0 + stride] )
+ // score = sum( v * v )
+ ld1 {v1.16b}, [x1], x3
+ ld1 {v2.16b}, [x1], x3
+ uabd v30.16b, v0.16b, v1.16b
+ ld1 {v3.16b}, [x1], x3
+ umull v29.8h, v30.8b, v30.8b
+ umull2 v28.8h, v30.16b, v30.16b
+ uabd v27.16b, v1.16b, v2.16b
+ uadalp v16.4s, v29.8h
+ umull v26.8h, v27.8b, v27.8b
+ umull2 v27.8h, v27.16b, v27.16b
+ uadalp v17.4s, v28.8h
+ uabd v25.16b, v2.16b, v3.16b
+ uadalp v16.4s, v26.8h
+ umull v24.8h, v25.8b, v25.8b
+ umull2 v25.8h, v25.16b, v25.16b
+ uadalp v17.4s, v27.8h
+ sub w4, w4, #3
+ uadalp v16.4s, v24.8h
+ cmp w4, #3
+ uadalp v17.4s, v25.8h
+ mov v0.16b, v3.16b
+
+ b.ge 1b
+ cbz w4, 3f
+
+// iterate by one
+2:
+ ld1 {v1.16b}, [x1], x3
+ subs w4, w4, #1
+ uabd v30.16b, v0.16b, v1.16b
+ mov v0.16b, v1.16b
+ umull v29.8h, v30.8b, v30.8b
+ umull2 v30.8h, v30.16b, v30.16b
+ uadalp v16.4s, v29.8h
+ uadalp v17.4s, v30.8h
+ cbnz w4, 2b
+
+3:
+ add v16.4s, v16.4s, v17.4S
+ uaddlv d17, v16.4s
+ fmov w0, s17
+
+ ret
+endfunc
+
+function vsse_intra8_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *dummy
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ sub w4, w4, #1 // we need to make h-1 iterations
+ ld1 {v0.8b}, [x1], x3
+ cmp w4, #3
+ movi v16.4s, #0
+
+ b.lt 2f
+
+1:
+ // v = abs( pix1[0] - pix1[0 + stride] )
+ // score = sum( v * v )
+ ld1 {v1.8b}, [x1], x3
+ ld1 {v2.8b}, [x1], x3
+ uabd v30.8b, v0.8b, v1.8b
+ ld1 {v3.8b}, [x1], x3
+ uabd v27.8b, v1.8b, v2.8b
+ umull v29.8h, v30.8b, v30.8b
+ uabd v25.8b, v2.8b, v3.8b
+ umull v26.8h, v27.8b, v27.8b
+ uadalp v16.4s, v29.8h
+ umull v24.8h, v25.8b, v25.8b
+ uadalp v16.4s, v26.8h
+ sub w4, w4, #3
+ uadalp v16.4s, v24.8h
+ cmp w4, #3
+ mov v0.8b, v3.8b
+
+ b.ge 1b
+ cbz w4, 3f
+
+// iterate by one
+2:
+ ld1 {v1.8b}, [x1], x3
+ subs w4, w4, #1
+ uabd v30.8b, v0.8b, v1.8b
+ mov v0.8b, v1.8b
+ umull v29.8h, v30.8b, v30.8b
+ uadalp v16.4s, v29.8h
+ cbnz w4, 2b
+
+3:
+ uaddlv d17, v16.4s
+ fmov w0, s17
+
+ ret
+endfunc
+
+function nsse16_neon, export=1
+ // x0 multiplier
+ // x1 uint8_t *pix1
+ // x2 uint8_t *pix2
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ str x0, [sp, #-0x40]!
+ stp x1, x2, [sp, #0x10]
+ stp x3, x4, [sp, #0x20]
+ str x30, [sp, #0x30]
+ bl X(sse16_neon)
+ ldr x30, [sp, #0x30]
+ mov w9, w0 // here we store score1
+ ldp x1, x2, [sp, #0x10]
+ ldp x3, x4, [sp, #0x20]
+ ldr x5, [sp], #0x40
+
+ movi v16.8h, #0
+ movi v17.8h, #0
+ movi v18.8h, #0
+ movi v19.8h, #0
+
+ ld1 {v0.16b}, [x1], x3
+ subs w4, w4, #1 // we need to make h-1 iterations
+ ld1 {v2.16b}, [x2], x3
+ ext v1.16b, v0.16b, v0.16b, #1 // x1 + 1
+ cmp w4, #2
+ ext v3.16b, v2.16b, v2.16b, #1 // x2 + 1
+
+ b.lt 2f
+
+// make 2 iterations at once
+1:
+ ld1 {v4.16b}, [x1], x3
+ ld1 {v6.16b}, [x2], x3
+ ld1 {v20.16b}, [x1], x3
+ ext v5.16b, v4.16b, v4.16b, #1 // x1 + stride + 1
+ usubl v31.8h, v0.8b, v4.8b
+ usubl2 v30.8h, v0.16b, v4.16b
+ ld1 {v22.16b}, [x2], x3
+ usubl v29.8h, v1.8b, v5.8b
+ usubl2 v28.8h, v1.16b, v5.16b
+ ext v7.16b, v6.16b, v6.16b, #1 // x2 + stride + 1
+ saba v16.8h, v31.8h, v29.8h
+ ext v21.16b, v20.16b, v20.16b, #1
+ saba v17.8h, v30.8h, v28.8h
+ usubl v27.8h, v2.8b, v6.8b
+ usubl2 v26.8h, v2.16b, v6.16b
+ ext v23.16b, v22.16b, v22.16b, #1
+ usubl v25.8h, v3.8b, v7.8b
+ usubl2 v24.8h, v3.16b, v7.16b
+ saba v18.8h, v27.8h, v25.8h
+ saba v19.8h, v26.8h, v24.8h
+
+ usubl v31.8h, v4.8b, v20.8b
+ usubl2 v30.8h, v4.16b, v20.16b
+ usubl v29.8h, v5.8b, v21.8b
+ usubl2 v28.8h, v5.16b, v21.16b
+ saba v16.8h, v31.8h, v29.8h
+ saba v17.8h, v30.8h, v28.8h
+ usubl v27.8h, v6.8b, v22.8b
+ usubl2 v26.8h, v6.16b, v22.16b
+ usubl v25.8h, v7.8b, v23.8b
+ usubl2 v24.8h, v7.16b, v23.16b
+ saba v18.8h, v27.8h, v25.8h
+ saba v19.8h, v26.8h, v24.8h
+ sub w4, w4, #2
+
+ mov v0.16b, v20.16b
+ mov v1.16b, v21.16b
+ cmp w4, #2
+ mov v2.16b, v22.16b
+ mov v3.16b, v23.16b
+
+ b.ge 1b
+ cbz w4, 3f
+
+// iterate by one
+2:
+ ld1 {v4.16b}, [x1], x3
+ subs w4, w4, #1
+ ld1 {v6.16b}, [x2], x3
+ ext v5.16b, v4.16b, v4.16b, #1 // x1 + stride + 1
+ usubl v31.8h, v0.8b, v4.8b
+ ext v7.16b, v6.16b, v6.16b, #1 // x2 + stride + 1
+
+ usubl2 v30.8h, v0.16b, v4.16b
+ usubl v29.8h, v1.8b, v5.8b
+ usubl2 v28.8h, v1.16b, v5.16b
+ saba v16.8h, v31.8h, v29.8h
+ saba v17.8h, v30.8h, v28.8h
+ usubl v27.8h, v2.8b, v6.8b
+ usubl2 v26.8h, v2.16b, v6.16b
+ usubl v25.8h, v3.8b, v7.8b
+ usubl2 v24.8h, v3.16b, v7.16b
+ saba v18.8h, v27.8h, v25.8h
+ saba v19.8h, v26.8h, v24.8h
+
+ mov v0.16b, v4.16b
+ mov v1.16b, v5.16b
+ mov v2.16b, v6.16b
+ mov v3.16b, v7.16b
+
+ cbnz w4, 2b
+
+3:
+ sqsub v17.8h, v17.8h, v19.8h
+ sqsub v16.8h, v16.8h, v18.8h
+ ins v17.h[7], wzr
+ sqadd v16.8h, v16.8h, v17.8h
+ saddlv s16, v16.8h
+ sqabs s16, s16
+ fmov w0, s16
+
+ mul w0, w0, w5
+ add w0, w0, w9
+
+ ret
+endfunc
+
+function nsse8_neon, export=1
+ // x0 multiplier
+ // x1 uint8_t *pix1
+ // x2 uint8_t *pix2
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ str x0, [sp, #-0x40]!
+ stp x1, x2, [sp, #0x10]
+ stp x3, x4, [sp, #0x20]
+ str x30, [sp, #0x30]
+ bl X(sse8_neon)
+ ldr x30, [sp, #0x30]
+ mov w9, w0 // here we store score1
+ ldp x1, x2, [sp, #0x10]
+ ldp x3, x4, [sp, #0x20]
+ ldr x5, [sp], #0x40
+
+ movi v16.8h, #0
+ movi v17.8h, #0
+ movi v18.8h, #0
+ movi v19.8h, #0
+
+ ld1 {v0.8b}, [x1], x3
+ subs w4, w4, #1 // we need to make h-1 iterations
+ ext v1.8b, v0.8b, v0.8b, #1 // x1 + 1
+ ld1 {v2.8b}, [x2], x3
+ cmp w4, #2
+ ext v3.8b, v2.8b, v2.8b, #1 // x2 + 1
+
+ b.lt 2f
+
+// make 2 iterations at once
+1:
+ ld1 {v4.8b}, [x1], x3
+ ld1 {v20.8b}, [x1], x3
+ ld1 {v6.8b}, [x2], x3
+ ext v5.8b, v4.8b, v4.8b, #1 // x1 + stride + 1
+ ext v21.8b, v20.8b, v20.8b, #1
+ ld1 {v22.8b}, [x2], x3
+ ext v7.8b, v6.8b, v6.8b, #1 // x2 + stride + 1
+ usubl v31.8h, v0.8b, v4.8b
+ ext v23.8b, v22.8b, v22.8b, #1
+ usubl v29.8h, v1.8b, v5.8b
+ usubl v27.8h, v2.8b, v6.8b
+ usubl v25.8h, v3.8b, v7.8b
+ saba v16.8h, v31.8h, v29.8h
+ usubl v31.8h, v4.8b, v20.8b
+ saba v18.8h, v27.8h, v25.8h
+ sub w4, w4, #2
+ usubl v29.8h, v5.8b, v21.8b
+ mov v0.16b, v20.16b
+ mov v1.16b, v21.16b
+ saba v16.8h, v31.8h, v29.8h
+ usubl v27.8h, v6.8b, v22.8b
+ usubl v25.8h, v7.8b, v23.8b
+ mov v2.16b, v22.16b
+ mov v3.16b, v23.16b
+ cmp w4, #2
+ saba v18.8h, v27.8h, v25.8h
+ b.ge 1b
+ cbz w4, 3f
+
+// iterate by one
+2:
+ ld1 {v4.8b}, [x1], x3
+ subs w4, w4, #1
+ ext v5.8b, v4.8b, v4.8b, #1 // x1 + stride + 1
+ ld1 {v6.8b}, [x2], x3
+ usubl v31.8h, v0.8b, v4.8b
+ ext v7.8b, v6.8b, v6.8b, #1 // x2 + stride + 1
+
+ usubl v29.8h, v1.8b, v5.8b
+ saba v16.8h, v31.8h, v29.8h
+ usubl v27.8h, v2.8b, v6.8b
+ usubl v25.8h, v3.8b, v7.8b
+ saba v18.8h, v27.8h, v25.8h
+
+ mov v0.16b, v4.16b
+ mov v1.16b, v5.16b
+ mov v2.16b, v6.16b
+ mov v3.16b, v7.16b
+
+ cbnz w4, 2b
+
+3:
+ sqsub v16.8h, v16.8h, v18.8h
+ ins v16.h[7], wzr
+ saddlv s16, v16.8h
+ sqabs s16, s16
+ fmov w0, s16
+
+ mul w0, w0, w5
+ add w0, w0, w9
+
+ ret
+endfunc
+
+function pix_median_abs16_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *pix2
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ ld1 {v2.16b}, [x1], x3
+ ld1 {v3.16b}, [x2], x3
+ movi v31.8h, #0
+ movi v16.8h, #0
+ ext v0.16b, v2.16b, v2.16b, #1
+ ext v1.16b, v3.16b, v3.16b, #1
+ usubl v28.8h, v2.8b, v3.8b
+ usubl2 v27.8h, v2.16b, v3.16b
+ usubl v26.8h, v0.8b, v1.8b
+ usubl2 v25.8h, v0.16b, v1.16b
+ sub w4, w4, #1 // we need to make h-1 iterations
+ saba v31.8h, v26.8h, v28.8h
+ saba v16.8h, v25.8h, v27.8h
+ mov h18, v28.h[0]
+ cmp w4, #1
+ sqabs h18, h18
+ movi v0.8h, #0
+
+ b.lt 2f
+1:
+
+ ld1 {v6.16b}, [x1], x3 // pix1 vector for V(j-1)
+ ld1 {v7.16b}, [x2], x3 // pix2 vector for V(j-1)
+ subs w4, w4, #1
+ ext v4.16b, v6.16b, v6.16b, #1 // pix1 vector for V(j)
+ ext v5.16b, v7.16b, v7.16b, #1 // pix2 vector for V(j)
+
+ // protected registers: v30, v29, v28, v27, v26, v25, v24, v23
+ // scratch registers: v22, v21, v20, v19, v17
+
+ // To find median of three values, calculate sum of them
+ // and subtract max and min value from it.
+ usubl v30.8h, v6.8b, v7.8b // V(j-1)
+ usubl2 v29.8h, v6.16b, v7.16b // V(j-1)
+ usubl v24.8h, v4.8b, v5.8b // V(j)
+ usubl2 v23.8h, v4.16b, v5.16b // V(j)
+ saba v0.8h, v30.8h, v28.8h
+ add v22.8h, v26.8h, v30.8h
+ smin v20.8h, v26.8h, v30.8h
+ add v21.8h, v25.8h, v29.8h
+ smax v19.8h, v26.8h, v30.8h
+ sub v22.8h, v22.8h, v28.8h
+ sub v21.8h, v21.8h, v27.8h
+ smin v17.8h, v19.8h, v22.8h
+ smin v22.8h, v25.8h, v29.8h
+ mov v28.16b, v30.16b
+ smax v20.8h, v20.8h, v17.8h // median values lower half
+ smax v19.8h, v25.8h, v29.8h
+ saba v31.8h, v24.8h, v20.8h
+ mov v27.16b, v29.16b
+ smin v19.8h, v19.8h, v21.8h
+ mov v26.16b, v24.16b
+ smax v17.8h, v22.8h, v19.8h // median values upper half
+ mov v25.16b, v23.16b
+ saba v16.8h, v23.8h, v17.8h
+
+ b.ne 1b
+
+2:
+ mov h17, v0.h[0]
+ ins v16.h[7], wzr
+ add d18, d18, d17
+ add v31.8h, v31.8h, v16.8h
+ uaddlv s17, v31.8h
+ add d18, d18, d17
+ fmov w0, s18
+
+ ret
+
+endfunc
+
+function vsad_intra8_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *dummy
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ ld1 {v0.8b}, [x1], x3
+ sub w4, w4, #1 // we need to make h-1 iterations
+ cmp w4, #3
+ movi v16.8h, #0
+ b.lt 2f
+
+1:
+ // v = abs( pix1[0] - pix1[0 + stride] )
+ // score = sum(v)
+ ld1 {v1.8b}, [x1], x3
+ sub w4, w4, #3
+ ld1 {v2.8b}, [x1], x3
+ uabal v16.8h, v0.8b, v1.8b
+ ld1 {v3.8b}, [x1], x3
+ uabal v16.8h, v1.8b, v2.8b
+ cmp w4, #3
+ mov v0.8b, v3.8b
+ uabal v16.8h, v2.8b, v3.8b
+ b.ge 1b
+ cbz w4, 3f
+
+2:
+ ld1 {v1.8b}, [x1], x3
+ subs w4, w4, #1
+ uabal v16.8h, v0.8b, v1.8b
+ mov v0.8b, v1.8b
+ cbnz w4, 2b
+
+3:
+ uaddlv s17, v16.8h
+ fmov w0, s17
+
+ ret
+endfunc
+
+function pix_median_abs8_neon, export=1
+ // x0 unused
+ // x1 uint8_t *pix1
+ // x2 uint8_t *pix2
+ // x3 ptrdiff_t stride
+ // w4 int h
+
+ ld1 {v2.8b}, [x1], x3
+ ld1 {v3.8b}, [x2], x3
+ movi v31.8h, #0
+ ext v0.8b, v2.8b, v2.8b, #1
+ ext v1.8b, v3.8b, v3.8b, #1
+ usubl v28.8h, v2.8b, v3.8b
+ usubl v26.8h, v0.8b, v1.8b
+ sub w4, w4, #1 // we need to make h-1 iterations
+ saba v31.8h, v26.8h, v28.8h
+ mov h18, v28.h[0]
+ cmp w4, #1
+ sqabs h18, h18
+ movi v0.8h, #0
+
+ b.lt 2f
+1:
+ ld1 {v6.8b}, [x1], x3 // pix1 vector for V(j-1)
+ ld1 {v7.8b}, [x2], x3 // pix2 vector for V(j-1)
+ subs w4, w4, #1
+ ext v4.8b, v6.8b, v6.8b, #1 // pix1 vector for V(j)
+ ext v5.8b, v7.8b, v7.8b, #1 // pix2 vector for V(j)
+
+ // protected registers: v30, v29, v28, v27, v26, v25, v24, v23
+ // scratch registers: v22, v21, v20, v19, v17
+
+ // To find median of three values, calculate sum of them
+ // and subtract max and min value from it.
+ usubl v30.8h, v6.8b, v7.8b // V(j-1)
+ usubl v24.8h, v4.8b, v5.8b // V(j)
+ saba v0.8h, v30.8h, v28.8h
+ add v22.8h, v26.8h, v30.8h
+ smin v20.8h, v26.8h, v30.8h
+ smax v19.8h, v26.8h, v30.8h
+ sub v22.8h, v22.8h, v28.8h
+ smin v17.8h, v19.8h, v22.8h
+ mov v28.16b, v30.16b
+ smax v20.8h, v20.8h, v17.8h // median values lower half
+ smax v19.8h, v25.8h, v29.8h
+ saba v31.8h, v24.8h, v20.8h
+ mov v26.16b, v24.16b
+ smax v17.8h, v22.8h, v19.8h // median values upper half
+
+ b.ne 1b
+2:
+ mov h17, v0.h[0]
+ ins v31.h[7], wzr
+ add d18, d18, d17
+ uaddlv s17, v31.8h
+ add d18, d18, d17
+ fmov w0, s18
+
+ ret
+
+endfunc
diff --git a/libavcodec/aarch64/rv40dsp_init_aarch64.c b/libavcodec/aarch64/rv40dsp_init_aarch64.c
index 142705db9..2b91d6835 100644
--- a/libavcodec/aarch64/rv40dsp_init_aarch64.c
+++ b/libavcodec/aarch64/rv40dsp_init_aarch64.c
@@ -25,14 +25,14 @@
#include "config.h"
-void ff_put_rv40_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_rv40_chroma_mc8_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_put_rv40_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_rv40_chroma_mc4_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_avg_rv40_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_avg_rv40_chroma_mc8_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_avg_rv40_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_avg_rv40_chroma_mc4_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
av_cold void ff_rv40dsp_init_aarch64(RV34DSPContext *c)
diff --git a/libavcodec/aarch64/synth_filter_init.c b/libavcodec/aarch64/synth_filter_init.c
index 767b01112..801b46e21 100644
--- a/libavcodec/aarch64/synth_filter_init.c
+++ b/libavcodec/aarch64/synth_filter_init.c
@@ -32,11 +32,11 @@
AV_CHECK_OFFSET(FFTContext, imdct_half, IMDCT_HALF);
#endif
-void ff_synth_filter_float_neon(FFTContext *imdct,
+void ff_synth_filter_float_neon(AVTXContext *imdct,
float *synth_buf_ptr, int *synth_buf_offset,
float synth_buf2[32], const float window[512],
- float out[32], const float in[32],
- float scale);
+ float out[32], float in[32],
+ float scale, av_tx_fn imdct_fn);
av_cold void ff_synth_filter_init_aarch64(SynthFilterContext *s)
{
diff --git a/libavcodec/aarch64/synth_filter_neon.S b/libavcodec/aarch64/synth_filter_neon.S
index ba79ba968..259fa6e66 100644
--- a/libavcodec/aarch64/synth_filter_neon.S
+++ b/libavcodec/aarch64/synth_filter_neon.S
@@ -43,8 +43,8 @@
.endm
function ff_synth_filter_float_neon, export=1
+ mov x9, x7 // imdct_fn parameter
ldr w7, [x2] // *synth_buf_offset
- ldr x9, [x0, #IMDCT_HALF] // imdct_half function pointer
sxtw x7, w7
stp x3, x4, [sp, #-64]!
add x1, x1, x7, lsl #2 // synth_buf
@@ -58,14 +58,15 @@ function ff_synth_filter_float_neon, export=1
str s0, [sp, #48]
mov x2, x6 // in
+ mov x3, #4 // sizeof(float)
blr x9
- ldp x2, x4, [sp] // synct_buf_2, window
ldp x13, x9, [sp, #16] // out, synth_buf
ldp x0, x30, [sp, #32] // *synth_buf_offset
AARCH64_VALIDATE_LINK_REGISTER
ldr s0, [sp, #48]
+ ldp x2, x4, [sp], #64 // synct_buf_2, window
add x3, x2, #16*4 // synct_buf_2 + 16
add x14, x13, #16*4 // out + 16
@@ -116,6 +117,5 @@ function ff_synth_filter_float_neon, export=1
b 1b
10:
- add sp, sp, #64
ret
endfunc
diff --git a/libavcodec/aarch64/vc1dsp_init_aarch64.c b/libavcodec/aarch64/vc1dsp_init_aarch64.c
index a7976fd59..3bc0bd17e 100644
--- a/libavcodec/aarch64/vc1dsp_init_aarch64.c
+++ b/libavcodec/aarch64/vc1dsp_init_aarch64.c
@@ -43,13 +43,13 @@ void ff_vc1_h_loop_filter8_neon(uint8_t *src, ptrdiff_t stride, int pq);
void ff_vc1_v_loop_filter16_neon(uint8_t *src, ptrdiff_t stride, int pq);
void ff_vc1_h_loop_filter16_neon(uint8_t *src, ptrdiff_t stride, int pq);
-void ff_put_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_vc1_chroma_mc8_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_avg_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_avg_vc1_chroma_mc8_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_put_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_vc1_chroma_mc4_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_avg_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_avg_vc1_chroma_mc4_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
int ff_vc1_unescape_buffer_helper_neon(const uint8_t *src, int size, uint8_t *dst);
diff --git a/libavcodec/aarch64/videodsp_init.c b/libavcodec/aarch64/videodsp_init.c
index 6f667a6d3..1f77a918d 100644
--- a/libavcodec/aarch64/videodsp_init.c
+++ b/libavcodec/aarch64/videodsp_init.c
@@ -21,7 +21,7 @@
#include "libavutil/aarch64/cpu.h"
#include "libavcodec/videodsp.h"
-void ff_prefetch_aarch64(uint8_t *mem, ptrdiff_t stride, int h);
+void ff_prefetch_aarch64(const uint8_t *mem, ptrdiff_t stride, int h);
av_cold void ff_videodsp_init_aarch64(VideoDSPContext *ctx, int bpc)
{
diff --git a/libavcodec/aarch64/vorbisdsp_init.c b/libavcodec/aarch64/vorbisdsp_init.c
index c796f95e6..969343934 100644
--- a/libavcodec/aarch64/vorbisdsp_init.c
+++ b/libavcodec/aarch64/vorbisdsp_init.c
@@ -22,7 +22,7 @@
#include "libavcodec/vorbisdsp.h"
void ff_vorbis_inverse_coupling_neon(float *mag, float *ang,
- intptr_t blocksize);
+ ptrdiff_t blocksize);
av_cold void ff_vorbisdsp_init_aarch64(VorbisDSPContext *c)
{
diff --git a/libavcodec/aarch64/vp8dsp.h b/libavcodec/aarch64/vp8dsp.h
index 871fed7a9..4e59de28b 100644
--- a/libavcodec/aarch64/vp8dsp.h
+++ b/libavcodec/aarch64/vp8dsp.h
@@ -53,7 +53,7 @@
#define VP8_MC(n, opt) \
void ff_put_vp8_##n##_##opt(uint8_t *dst, ptrdiff_t dststride, \
- uint8_t *src, ptrdiff_t srcstride, \
+ const uint8_t *src, ptrdiff_t srcstride,\
int h, int x, int y)
#define VP8_EPEL(w, opt) \
diff --git a/libavcodec/aarch64/vp9itxfm_neon.S b/libavcodec/aarch64/vp9itxfm_neon.S
index 03272eae8..a27f7b8ae 100644
--- a/libavcodec/aarch64/vp9itxfm_neon.S
+++ b/libavcodec/aarch64/vp9itxfm_neon.S
@@ -850,10 +850,10 @@ function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1
mov x15, x30
// iadst16 requires clobbering v8-v15, but idct16 doesn't need to.
.ifnc \txfm1\()_\txfm2,idct_idct
- stp d14, d15, [sp, #-0x10]!
- stp d12, d13, [sp, #-0x10]!
- stp d10, d11, [sp, #-0x10]!
- stp d8, d9, [sp, #-0x10]!
+ stp d8, d9, [sp, #-0x40]!
+ stp d14, d15, [sp, #0x30]
+ stp d12, d13, [sp, #0x20]
+ stp d10, d11, [sp, #0x10]
.endif
sub sp, sp, #512
@@ -920,10 +920,10 @@ function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1
add sp, sp, #512
.ifnc \txfm1\()_\txfm2,idct_idct
- ldp d8, d9, [sp], 0x10
- ldp d10, d11, [sp], 0x10
- ldp d12, d13, [sp], 0x10
- ldp d14, d15, [sp], 0x10
+ ldp d10, d11, [sp, #0x10]
+ ldp d12, d13, [sp, #0x20]
+ ldp d14, d15, [sp, #0x30]
+ ldp d8, d9, [sp], #0x40
.endif
ret x15
endfunc
@@ -1486,8 +1486,8 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1
mov x15, x30
- stp d10, d11, [sp, #-0x10]!
- stp d8, d9, [sp, #-0x10]!
+ stp d8, d9, [sp, #-0x20]!
+ stp d10, d11, [sp, #0x10]
sub sp, sp, #2048
@@ -1544,8 +1544,8 @@ function ff_vp9_idct_idct_32x32_add_neon, export=1
add sp, sp, #2048
- ldp d8, d9, [sp], 0x10
- ldp d10, d11, [sp], 0x10
+ ldp d10, d11, [sp, #0x10]
+ ldp d8, d9, [sp], #0x20
ret x15
endfunc
@@ -1569,8 +1569,8 @@ function idct32x32_\size\()_add_neon
add sp, sp, #2048
- ldp d8, d9, [sp], 0x10
- ldp d10, d11, [sp], 0x10
+ ldp d10, d11, [sp, #0x10]
+ ldp d8, d9, [sp], #0x20
ret x15
endfunc
diff --git a/libavcodec/aarch64/vp9lpf_16bpp_neon.S b/libavcodec/aarch64/vp9lpf_16bpp_neon.S
index a092617b9..e3e70491c 100644
--- a/libavcodec/aarch64/vp9lpf_16bpp_neon.S
+++ b/libavcodec/aarch64/vp9lpf_16bpp_neon.S
@@ -417,10 +417,10 @@ endfunc
function ff_\func\()_\bpp\()_neon, export=1
.if \push
mov x16, x30
- stp d14, d15, [sp, #-0x10]!
- stp d12, d13, [sp, #-0x10]!
- stp d10, d11, [sp, #-0x10]!
- stp d8, d9, [sp, #-0x10]!
+ stp d8, d9, [sp, #-0x40]!
+ stp d14, d15, [sp, #0x30]
+ stp d12, d13, [sp, #0x20]
+ stp d10, d11, [sp, #0x10]
.endif
lsl w2, w2, #\bpp - 8
lsl w3, w3, #\bpp - 8
@@ -430,10 +430,10 @@ function ff_\func\()_\bpp\()_neon, export=1
mov x7, #((1 << \bpp) - 1)
.if \push
bl \func\()_16_neon
- ldp d8, d9, [sp], 0x10
- ldp d10, d11, [sp], 0x10
- ldp d12, d13, [sp], 0x10
- ldp d14, d15, [sp], 0x10
+ ldp d10, d11, [sp, #0x10]
+ ldp d12, d13, [sp, #0x20]
+ ldp d14, d15, [sp, #0x30]
+ ldp d8, d9, [sp], #0x40
ret x16
.else
b \func\()_16_neon
@@ -450,10 +450,10 @@ endfunc
function ff_\func\()_\suffix\()_\bpp\()_neon, export=1
mov x16, x30
.if \push
- stp d14, d15, [sp, #-0x10]!
- stp d12, d13, [sp, #-0x10]!
- stp d10, d11, [sp, #-0x10]!
- stp d8, d9, [sp, #-0x10]!
+ stp d8, d9, [sp, #-0x40]!
+ stp d14, d15, [sp, #0x30]
+ stp d12, d13, [sp, #0x20]
+ stp d10, d11, [sp, #0x10]
.endif
lsl w2, w2, #\bpp - 8
lsl w3, w3, #\bpp - 8
@@ -469,10 +469,10 @@ function ff_\func\()_\suffix\()_\bpp\()_neon, export=1
.endif
bl \func\()_\int_suffix\()_16_neon
.if \push
- ldp d8, d9, [sp], 0x10
- ldp d10, d11, [sp], 0x10
- ldp d12, d13, [sp], 0x10
- ldp d14, d15, [sp], 0x10
+ ldp d10, d11, [sp, #0x10]
+ ldp d12, d13, [sp, #0x20]
+ ldp d14, d15, [sp, #0x30]
+ ldp d8, d9, [sp], 0x40
.endif
ret x16
endfunc
diff --git a/libavcodec/aarch64/vp9lpf_neon.S b/libavcodec/aarch64/vp9lpf_neon.S
index 694ff8956..9a79f48df 100644
--- a/libavcodec/aarch64/vp9lpf_neon.S
+++ b/libavcodec/aarch64/vp9lpf_neon.S
@@ -564,10 +564,10 @@ function vp9_loop_filter_16
loop_filter 16, .8b, 0, v8, v9, v10, v11, v12, v13, v14, v15
ret
9:
- ldp d8, d9, [sp], 0x10
- ldp d10, d11, [sp], 0x10
- ldp d12, d13, [sp], 0x10
- ldp d14, d15, [sp], 0x10
+ ldp d10, d11, [sp, #0x10]
+ ldp d12, d13, [sp, #0x20]
+ ldp d14, d15, [sp, #0x30]
+ ldp d8, d9, [sp], #0x40
ret x10
endfunc
@@ -575,10 +575,10 @@ function vp9_loop_filter_16_16b
loop_filter 16, .16b, 0, v8, v9, v10, v11, v12, v13, v14, v15
ret
9:
- ldp d8, d9, [sp], 0x10
- ldp d10, d11, [sp], 0x10
- ldp d12, d13, [sp], 0x10
- ldp d14, d15, [sp], 0x10
+ ldp d10, d11, [sp, #0x10]
+ ldp d12, d13, [sp, #0x20]
+ ldp d14, d15, [sp, #0x30]
+ ldp d8, d9, [sp], #0x40
ret x10
endfunc
@@ -973,10 +973,10 @@ mix_h_16 88
function ff_vp9_loop_filter_v_16_8_neon, export=1
mov x10, x30
- stp d14, d15, [sp, #-0x10]!
- stp d12, d13, [sp, #-0x10]!
- stp d10, d11, [sp, #-0x10]!
- stp d8, d9, [sp, #-0x10]!
+ stp d8, d9, [sp, #-0x40]!
+ stp d14, d15, [sp, #0x30]
+ stp d12, d13, [sp, #0x20]
+ stp d10, d11, [sp, #0x10]
sub x9, x0, x1, lsl #3
ld1 {v16.8b}, [x9], x1 // p7
ld1 {v24.8b}, [x0], x1 // q0
@@ -1018,10 +1018,10 @@ function ff_vp9_loop_filter_v_16_8_neon, export=1
st1 {v9.8b}, [x9], x1
st1 {v17.8b}, [x0], x1
9:
- ldp d8, d9, [sp], 0x10
- ldp d10, d11, [sp], 0x10
- ldp d12, d13, [sp], 0x10
- ldp d14, d15, [sp], 0x10
+ ldp d10, d11, [sp, #0x10]
+ ldp d12, d13, [sp, #0x20]
+ ldp d14, d15, [sp, #0x30]
+ ldp d8, d9, [sp], #0x40
ret x10
8:
add x9, x9, x1, lsl #2
@@ -1045,10 +1045,10 @@ endfunc
function ff_vp9_loop_filter_v_16_16_neon, export=1
mov x10, x30
- stp d14, d15, [sp, #-0x10]!
- stp d12, d13, [sp, #-0x10]!
- stp d10, d11, [sp, #-0x10]!
- stp d8, d9, [sp, #-0x10]!
+ stp d8, d9, [sp, #-0x40]!
+ stp d14, d15, [sp, #0x30]
+ stp d12, d13, [sp, #0x20]
+ stp d10, d11, [sp, #0x10]
sub x9, x0, x1, lsl #3
ld1 {v16.16b}, [x9], x1 // p7
ld1 {v24.16b}, [x0], x1 // q0
@@ -1087,10 +1087,10 @@ function ff_vp9_loop_filter_v_16_16_neon, export=1
st1 {v9.16b}, [x9], x1
st1 {v17.16b}, [x0], x1
9:
- ldp d8, d9, [sp], 0x10
- ldp d10, d11, [sp], 0x10
- ldp d12, d13, [sp], 0x10
- ldp d14, d15, [sp], 0x10
+ ldp d10, d11, [sp, #0x10]
+ ldp d12, d13, [sp, #0x20]
+ ldp d14, d15, [sp, #0x30]
+ ldp d8, d9, [sp], #0x40
ret x10
8:
add x9, x9, x1, lsl #2
@@ -1112,10 +1112,10 @@ endfunc
function ff_vp9_loop_filter_h_16_8_neon, export=1
mov x10, x30
- stp d14, d15, [sp, #-0x10]!
- stp d12, d13, [sp, #-0x10]!
- stp d10, d11, [sp, #-0x10]!
- stp d8, d9, [sp, #-0x10]!
+ stp d8, d9, [sp, #-0x40]!
+ stp d14, d15, [sp, #0x30]
+ stp d12, d13, [sp, #0x20]
+ stp d10, d11, [sp, #0x10]
sub x9, x0, #8
ld1 {v16.8b}, [x9], x1
ld1 {v24.8b}, [x0], x1
@@ -1164,10 +1164,10 @@ function ff_vp9_loop_filter_h_16_8_neon, export=1
st1 {v9.8b}, [x9], x1
st1 {v31.8b}, [x0], x1
9:
- ldp d8, d9, [sp], 0x10
- ldp d10, d11, [sp], 0x10
- ldp d12, d13, [sp], 0x10
- ldp d14, d15, [sp], 0x10
+ ldp d10, d11, [sp, #0x10]
+ ldp d12, d13, [sp, #0x20]
+ ldp d14, d15, [sp, #0x30]
+ ldp d8, d9, [sp], #0x40
ret x10
8:
// The same writeback as in loop_filter_h_8_8
@@ -1202,10 +1202,10 @@ endfunc
function ff_vp9_loop_filter_h_16_16_neon, export=1
mov x10, x30
- stp d14, d15, [sp, #-0x10]!
- stp d12, d13, [sp, #-0x10]!
- stp d10, d11, [sp, #-0x10]!
- stp d8, d9, [sp, #-0x10]!
+ stp d8, d9, [sp, #-0x40]!
+ stp d14, d15, [sp, #0x30]
+ stp d12, d13, [sp, #0x20]
+ stp d10, d11, [sp, #0x10]
sub x9, x0, #8
ld1 {v16.8b}, [x9], x1
ld1 {v24.8b}, [x0], x1
@@ -1283,10 +1283,10 @@ function ff_vp9_loop_filter_h_16_16_neon, export=1
st1 {v9.d}[1], [x9], x1
st1 {v31.d}[1], [x0], x1
9:
- ldp d8, d9, [sp], 0x10
- ldp d10, d11, [sp], 0x10
- ldp d12, d13, [sp], 0x10
- ldp d14, d15, [sp], 0x10
+ ldp d10, d11, [sp, #0x10]
+ ldp d12, d13, [sp, #0x20]
+ ldp d14, d15, [sp, #0x30]
+ ldp d8, d9, [sp], #0x40
ret x10
8:
sub x9, x0, #4
diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c
index 528ee58cd..c8e15772b 100644
--- a/libavcodec/aasc.c
+++ b/libavcodec/aasc.c
@@ -24,13 +24,11 @@
* Autodesk RLE Video Decoder by Konstantin Shishkov
*/
-#include
-#include
#include
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "msrledec.h"
typedef struct AascContext {
@@ -151,7 +149,7 @@ static av_cold int aasc_decode_end(AVCodecContext *avctx)
const FFCodec ff_aasc_decoder = {
.p.name = "aasc",
- .p.long_name = NULL_IF_CONFIG_SMALL("Autodesk RLE"),
+ CODEC_LONG_NAME("Autodesk RLE"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AASC,
.priv_data_size = sizeof(AascContext),
@@ -159,5 +157,4 @@ const FFCodec ff_aasc_decoder = {
.close = aasc_decode_end,
FF_CODEC_DECODE_CB(aasc_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/ac3.h b/libavcodec/ac3.h
index 29f9f9df8..2386c15ad 100644
--- a/libavcodec/ac3.h
+++ b/libavcodec/ac3.h
@@ -38,8 +38,6 @@
#if USE_FIXED
-#define FFT_FLOAT 0
-
#define FIXR(a) ((int)((a) * 0 + 0.5))
#define FIXR12(a) ((int)((a) * 4096 + 0.5))
#define FIXR15(a) ((int)((a) * 32768 + 0.5))
@@ -55,6 +53,7 @@
#define AC3_DYNAMIC_RANGE1 0
typedef int INTFLOAT;
+typedef unsigned int UINTFLOAT;
typedef int16_t SHORTFLOAT;
#else /* USE_FIXED */
@@ -75,6 +74,7 @@ typedef int16_t SHORTFLOAT;
#define AC3_DYNAMIC_RANGE1 1.0f
typedef float INTFLOAT;
+typedef float UINTFLOAT;
typedef float SHORTFLOAT;
#endif /* USE_FIXED */
diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c
index 4f154bb7c..13b8d3b7d 100644
--- a/libavcodec/ac3_parser.c
+++ b/libavcodec/ac3_parser.c
@@ -53,6 +53,25 @@ static const uint8_t center_levels[4] = { 4, 5, 6, 5 };
*/
static const uint8_t surround_levels[4] = { 4, 6, 7, 6 };
+int ff_ac3_find_syncword(const uint8_t *buf, int buf_size)
+{
+ int i;
+
+ for (i = 1; i < buf_size; i += 2) {
+ if (buf[i] == 0x77 || buf[i] == 0x0B) {
+ if ((buf[i] ^ buf[i-1]) == (0x77 ^ 0x0B)) {
+ i--;
+ break;
+ } else if ((buf[i] ^ buf[i+1]) == (0x77 ^ 0x0B)) {
+ break;
+ }
+ }
+ }
+ if (i >= buf_size)
+ return AVERROR_INVALIDDATA;
+
+ return i;
+}
int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr)
{
@@ -196,8 +215,7 @@ int av_ac3_parse_header(const uint8_t *buf, size_t size,
return 0;
}
-static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info,
- int *need_next_header, int *new_frame_start)
+static int ac3_sync(uint64_t state, int *need_next_header, int *new_frame_start)
{
int err;
union {
@@ -219,19 +237,6 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info,
if(err < 0)
return 0;
- hdr_info->sample_rate = hdr.sample_rate;
- hdr_info->bit_rate = hdr.bit_rate;
- hdr_info->channels = hdr.channels;
- hdr_info->channel_layout = hdr.channel_layout;
- hdr_info->samples = hdr.num_blocks * 256;
- hdr_info->service_type = hdr.bitstream_mode;
- if (hdr.bitstream_mode == 0x7 && hdr.channels > 1)
- hdr_info->service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
- if(hdr.bitstream_id>10)
- hdr_info->codec_id = AV_CODEC_ID_EAC3;
- else if (hdr_info->codec_id == AV_CODEC_ID_NONE)
- hdr_info->codec_id = AV_CODEC_ID_AC3;
-
*new_frame_start = (hdr.frame_type != EAC3_FRAME_TYPE_DEPENDENT);
*need_next_header = *new_frame_start || (hdr.frame_type != EAC3_FRAME_TYPE_AC3_CONVERT);
return hdr.frame_size;
@@ -241,6 +246,7 @@ static av_cold int ac3_parse_init(AVCodecParserContext *s1)
{
AACAC3ParseContext *s = s1->priv_data;
s->header_size = AC3_HEADER_SIZE;
+ s->crc_ctx = av_crc_get_table(AV_CRC_16_ANSI);
s->sync = ac3_sync;
return 0;
}
diff --git a/libavcodec/ac3_parser_internal.h b/libavcodec/ac3_parser_internal.h
index bd4e1bbff..2ac0e67ec 100644
--- a/libavcodec/ac3_parser_internal.h
+++ b/libavcodec/ac3_parser_internal.h
@@ -79,4 +79,6 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr);
int avpriv_ac3_parse_header(AC3HeaderInfo **hdr, const uint8_t *buf,
size_t size);
+int ff_ac3_find_syncword(const uint8_t *buf, int buf_size);
+
#endif /* AVCODEC_AC3_PARSER_INTERNAL_H */
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index ad2b3615c..0b120e614 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -38,12 +38,12 @@
#include "libavutil/opt.h"
#include "libavutil/thread.h"
#include "bswapdsp.h"
-#include "internal.h"
#include "aac_ac3_parser.h"
#include "ac3_parser_internal.h"
#include "ac3dec.h"
#include "ac3dec_data.h"
#include "ac3defs.h"
+#include "decode.h"
#include "kbdwin.h"
/**
@@ -183,41 +183,11 @@ static av_cold void ac3_tables_init(void)
#endif
}
-/**
- * AVCodec initialization
- */
-static av_cold int ac3_decode_init(AVCodecContext *avctx)
+static void ac3_downmix(AVCodecContext *avctx)
{
- static AVOnce init_static_once = AV_ONCE_INIT;
AC3DecodeContext *s = avctx->priv_data;
const AVChannelLayout mono = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
const AVChannelLayout stereo = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
- int i, ret;
-
- s->avctx = avctx;
-
- if ((ret = ff_mdct_init(&s->imdct_256, 8, 1, 1.0)) < 0 ||
- (ret = ff_mdct_init(&s->imdct_512, 9, 1, 1.0)) < 0)
- return ret;
- AC3_RENAME(ff_kbd_window_init)(s->window, 5.0, 256);
- ff_bswapdsp_init(&s->bdsp);
-
-#if (USE_FIXED)
- s->fdsp = avpriv_alloc_fixed_dsp(avctx->flags & AV_CODEC_FLAG_BITEXACT);
-#else
- ff_fmt_convert_init(&s->fmt_conv, avctx);
- s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
-#endif
- if (!s->fdsp)
- return AVERROR(ENOMEM);
-
- ff_ac3dsp_init(&s->ac3dsp, avctx->flags & AV_CODEC_FLAG_BITEXACT);
- av_lfg_init(&s->dith_state, 0);
-
- if (USE_FIXED)
- avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
- else
- avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
/* allow downmixing to stereo or mono */
#if FF_API_OLD_CHANNEL_LAYOUT
@@ -238,6 +208,47 @@ FF_ENABLE_DEPRECATION_WARNINGS
avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
}
s->downmixed = 1;
+}
+
+/**
+ * AVCodec initialization
+ */
+static av_cold int ac3_decode_init(AVCodecContext *avctx)
+{
+ static AVOnce init_static_once = AV_ONCE_INIT;
+ AC3DecodeContext *s = avctx->priv_data;
+ const float scale = 1.0f;
+ int i, ret;
+
+ s->avctx = avctx;
+
+ if ((ret = av_tx_init(&s->tx_128, &s->tx_fn_128, IMDCT_TYPE, 1, 128, &scale, 0)))
+ return ret;
+
+ if ((ret = av_tx_init(&s->tx_256, &s->tx_fn_256, IMDCT_TYPE, 1, 256, &scale, 0)))
+ return ret;
+
+ AC3_RENAME(ff_kbd_window_init)(s->window, 5.0, 256);
+ ff_bswapdsp_init(&s->bdsp);
+
+#if (USE_FIXED)
+ s->fdsp = avpriv_alloc_fixed_dsp(avctx->flags & AV_CODEC_FLAG_BITEXACT);
+#else
+ ff_fmt_convert_init(&s->fmt_conv);
+ s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
+#endif
+ if (!s->fdsp)
+ return AVERROR(ENOMEM);
+
+ ff_ac3dsp_init(&s->ac3dsp);
+ av_lfg_init(&s->dith_state, 0);
+
+ if (USE_FIXED)
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+ else
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
+
+ ac3_downmix(avctx);
for (i = 0; i < AC3_MAX_CHANNELS; i++) {
s->xcfptr[i] = s->transform_coeffs[i];
@@ -714,10 +725,10 @@ static inline void do_imdct(AC3DecodeContext *s, int channels, int offset)
for (ch = 1; ch <= channels; ch++) {
if (s->block_switch[ch]) {
int i;
- FFTSample *x = s->tmp_output + 128;
+ INTFLOAT *x = s->tmp_output + 128;
for (i = 0; i < 128; i++)
x[i] = s->transform_coeffs[ch][2 * i];
- s->imdct_256.imdct_half(&s->imdct_256, s->tmp_output, x);
+ s->tx_fn_128(s->tx_128, s->tmp_output, x, sizeof(INTFLOAT));
#if USE_FIXED
s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1 + offset],
s->tmp_output, s->window, 128, 8);
@@ -727,9 +738,9 @@ static inline void do_imdct(AC3DecodeContext *s, int channels, int offset)
#endif
for (i = 0; i < 128; i++)
x[i] = s->transform_coeffs[ch][2 * i + 1];
- s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch - 1 + offset], x);
+ s->tx_fn_128(s->tx_128, s->delay[ch - 1 + offset], x, sizeof(INTFLOAT));
} else {
- s->imdct_512.imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]);
+ s->tx_fn_256(s->tx_256, s->tmp_output, s->transform_coeffs[ch], sizeof(INTFLOAT));
#if USE_FIXED
s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1 + offset],
s->tmp_output, s->window, 128, 8);
@@ -737,7 +748,7 @@ static inline void do_imdct(AC3DecodeContext *s, int channels, int offset)
s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1 + offset],
s->tmp_output, s->window, 128);
#endif
- memcpy(s->delay[ch - 1 + offset], s->tmp_output + 128, 128 * sizeof(FFTSample));
+ memcpy(s->delay[ch - 1 + offset], s->tmp_output + 128, 128 * sizeof(INTFLOAT));
}
}
}
@@ -1501,19 +1512,8 @@ static int ac3_decode_frame(AVCodecContext *avctx, AVFrame *frame,
s->superframe_size = 0;
buf_size = full_buf_size;
- for (i = 1; i < buf_size; i += 2) {
- if (buf[i] == 0x77 || buf[i] == 0x0B) {
- if ((buf[i] ^ buf[i-1]) == (0x77 ^ 0x0B)) {
- i--;
- break;
- } else if ((buf[i] ^ buf[i+1]) == (0x77 ^ 0x0B)) {
- break;
- }
- }
- }
- if (i >= buf_size)
- return AVERROR_INVALIDDATA;
- if (i > 10)
+ i = ff_ac3_find_syncword(buf, buf_size);
+ if (i < 0 || i > 10)
return i;
buf += i;
buf_size -= i;
@@ -1716,6 +1716,11 @@ skip:
avctx->bit_rate = s->bit_rate + s->prev_bit_rate;
}
+ if (!avctx->sample_rate) {
+ av_log(avctx, AV_LOG_ERROR, "Could not determine the sample rate\n");
+ return AVERROR_INVALIDDATA;
+ }
+
for (ch = 0; ch < EAC3_MAX_CHANNELS; ch++)
extended_channel_map[ch] = ch;
@@ -1751,7 +1756,7 @@ skip:
if (index < 0)
return AVERROR_INVALIDDATA;
if (extend >= channel_map_size)
- return AVERROR_INVALIDDATA;
+ break;
extended_channel_map[index] = offset + channel_map[extend++];
} else {
@@ -1763,7 +1768,7 @@ skip:
if (index < 0)
return AVERROR_INVALIDDATA;
if (extend >= channel_map_size)
- return AVERROR_INVALIDDATA;
+ break;
extended_channel_map[index] = offset + channel_map[extend++];
}
@@ -1771,6 +1776,8 @@ skip:
}
}
}
+
+ ac3_downmix(avctx);
}
/* get output buffer */
@@ -1856,8 +1863,8 @@ skip:
static av_cold int ac3_decode_end(AVCodecContext *avctx)
{
AC3DecodeContext *s = avctx->priv_data;
- ff_mdct_end(&s->imdct_512);
- ff_mdct_end(&s->imdct_256);
+ av_tx_uninit(&s->tx_256);
+ av_tx_uninit(&s->tx_128);
av_freep(&s->fdsp);
av_freep(&s->downmix_coeffs[0]);
diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h
index 944412497..138b462ab 100644
--- a/libavcodec/ac3dec.h
+++ b/libavcodec/ac3dec.h
@@ -50,6 +50,7 @@
#ifndef AVCODEC_AC3DEC_H
#define AVCODEC_AC3DEC_H
+#include "libavutil/tx.h"
#include "libavutil/float_dsp.h"
#include "libavutil/fixed_dsp.h"
#include "libavutil/lfg.h"
@@ -57,9 +58,9 @@
#include "ac3.h"
#include "ac3dsp.h"
+#include "avcodec.h"
#include "bswapdsp.h"
#include "get_bits.h"
-#include "fft.h"
#include "fmtconvert.h"
#define AC3_OUTPUT_LFEON 8
@@ -222,8 +223,8 @@ typedef struct AC3DecodeContext {
///@name IMDCT
int block_switch[AC3_MAX_CHANNELS]; ///< block switch flags (blksw)
- FFTContext imdct_512; ///< for 512 sample IMDCT
- FFTContext imdct_256; ///< for 256 sample IMDCT
+ AVTXContext *tx_128, *tx_256;
+ av_tx_fn tx_fn_128, tx_fn_256;
///@}
///@name Optimization
diff --git a/libavcodec/ac3dec_fixed.c b/libavcodec/ac3dec_fixed.c
index 4c0d4d6f5..c9e5cda69 100644
--- a/libavcodec/ac3dec_fixed.c
+++ b/libavcodec/ac3dec_fixed.c
@@ -47,11 +47,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define FFT_FLOAT 0
#define USE_FIXED 1
#include "ac3dec.h"
#include "codec_internal.h"
+#define IMDCT_TYPE AV_TX_INT32_MDCT
+#include "ac3dec.h"
static const int end_freq_inv_tab[8] =
{
@@ -171,7 +172,7 @@ static const AVClass ac3_decoder_class = {
const FFCodec ff_ac3_fixed_decoder = {
.p.name = "ac3_fixed",
- .p.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
+ CODEC_LONG_NAME("ATSC A/52A (AC-3)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AC3,
.p.priv_class = &ac3_decoder_class,
@@ -183,5 +184,5 @@ const FFCodec ff_ac3_fixed_decoder = {
AV_CODEC_CAP_DR1,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/ac3dec_float.c b/libavcodec/ac3dec_float.c
index 2147b36af..b8868d8ee 100644
--- a/libavcodec/ac3dec_float.c
+++ b/libavcodec/ac3dec_float.c
@@ -29,6 +29,7 @@
*/
#include "config_components.h"
+#define IMDCT_TYPE AV_TX_FLOAT_MDCT
#include "ac3dec.h"
#include "codec_internal.h"
@@ -69,11 +70,11 @@ const FFCodec ff_ac3_decoder = {
FF_CODEC_DECODE_CB(ac3_decode_frame),
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
AV_CODEC_CAP_DR1,
- .p.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
+ CODEC_LONG_NAME("ATSC A/52A (AC-3)"),
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
.p.priv_class = &ac3_eac3_decoder_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
#if CONFIG_EAC3_DECODER
@@ -87,10 +88,10 @@ const FFCodec ff_eac3_decoder = {
FF_CODEC_DECODE_CB(ac3_decode_frame),
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
AV_CODEC_CAP_DR1,
- .p.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"),
+ CODEC_LONG_NAME("ATSC A/52B (AC-3, E-AC-3)"),
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
.p.priv_class = &ac3_eac3_decoder_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
#endif
diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c
index afd6b557b..22cb5f242 100644
--- a/libavcodec/ac3dsp.c
+++ b/libavcodec/ac3dsp.c
@@ -374,7 +374,7 @@ void ff_ac3dsp_downmix(AC3DSPContext *c, float **samples, float **matrix,
ac3_downmix_c(samples, matrix, out_ch, in_ch, len);
}
-av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact)
+av_cold void ff_ac3dsp_init(AC3DSPContext *c)
{
c->ac3_exponent_min = ac3_exponent_min_c;
c->float_to_fixed24 = float_to_fixed24_c;
@@ -390,10 +390,10 @@ av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact)
c->downmix_fixed = NULL;
#if ARCH_ARM
- ff_ac3dsp_init_arm(c, bit_exact);
+ ff_ac3dsp_init_arm(c);
#elif ARCH_X86
- ff_ac3dsp_init_x86(c, bit_exact);
+ ff_ac3dsp_init_x86(c);
#elif ARCH_MIPS
- ff_ac3dsp_init_mips(c, bit_exact);
+ ff_ac3dsp_init_mips(c);
#endif
}
diff --git a/libavcodec/ac3dsp.h b/libavcodec/ac3dsp.h
index a23b11526..33e51e202 100644
--- a/libavcodec/ac3dsp.h
+++ b/libavcodec/ac3dsp.h
@@ -105,10 +105,10 @@ typedef struct AC3DSPContext {
void (*downmix_fixed)(int32_t **samples, int16_t **matrix, int len);
} AC3DSPContext;
-void ff_ac3dsp_init (AC3DSPContext *c, int bit_exact);
-void ff_ac3dsp_init_arm(AC3DSPContext *c, int bit_exact);
-void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact);
-void ff_ac3dsp_init_mips(AC3DSPContext *c, int bit_exact);
+void ff_ac3dsp_init (AC3DSPContext *c);
+void ff_ac3dsp_init_arm(AC3DSPContext *c);
+void ff_ac3dsp_init_x86(AC3DSPContext *c);
+void ff_ac3dsp_init_mips(AC3DSPContext *c);
void ff_ac3dsp_downmix(AC3DSPContext *c, float **samples, float **matrix,
int out_ch, int in_ch, int len);
diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
index c57904b01..3cb4e5f02 100644
--- a/libavcodec/ac3enc.c
+++ b/libavcodec/ac3enc.c
@@ -41,7 +41,6 @@
#include "codec_internal.h"
#include "config_components.h"
#include "encode.h"
-#include "internal.h"
#include "me_cmp.h"
#include "put_bits.h"
#include "audiodsp.h"
@@ -49,7 +48,6 @@
#include "ac3.h"
#include "ac3defs.h"
#include "ac3tab.h"
-#include "fft.h"
#include "ac3enc.h"
#include "eac3enc.h"
@@ -2204,7 +2202,7 @@ av_cold int ff_ac3_encode_close(AVCodecContext *avctx)
av_freep(&block->cpl_coord_mant);
}
- s->mdct_end(s);
+ av_tx_uninit(&s->tx);
return 0;
}
@@ -2614,7 +2612,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
ff_audiodsp_init(&s->adsp);
ff_me_cmp_init(&s->mecc, avctx);
- ff_ac3dsp_init(&s->ac3dsp, avctx->flags & AV_CODEC_FLAG_BITEXACT);
+ ff_ac3dsp_init(&s->ac3dsp);
dprint_options(s);
diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
index f0dc00675..55e88d69e 100644
--- a/libavcodec/ac3enc.h
+++ b/libavcodec/ac3enc.h
@@ -31,12 +31,13 @@
#include
#include "libavutil/opt.h"
+#include "libavutil/tx.h"
+
#include "ac3.h"
#include "ac3defs.h"
#include "ac3dsp.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "fft.h"
#include "mathops.h"
#include "me_cmp.h"
#include "put_bits.h"
@@ -167,7 +168,8 @@ typedef struct AC3EncodeContext {
#endif
MECmpContext mecc;
AC3DSPContext ac3dsp; ///< AC-3 optimized functions
- FFTContext mdct; ///< FFT context for MDCT calculation
+ AVTXContext *tx; ///< FFT context for MDCT calculation
+ av_tx_fn tx_fn;
const SampleType *mdct_window; ///< MDCT window function array
AC3Block blocks[AC3_MAX_BLOCKS]; ///< per-block info
@@ -257,7 +259,6 @@ typedef struct AC3EncodeContext {
int warned_alternate_bitstream;
/* fixed vs. float function pointers */
- void (*mdct_end)(struct AC3EncodeContext *s);
int (*mdct_init)(struct AC3EncodeContext *s);
/* fixed vs. float templated function pointers */
diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c
index 92bf31b03..88dfd66b9 100644
--- a/libavcodec/ac3enc_fixed.c
+++ b/libavcodec/ac3enc_fixed.c
@@ -27,7 +27,6 @@
*/
#define AC3ENC_FLOAT 0
-#define FFT_FLOAT 0
#include "audiodsp.h"
#include "ac3enc.h"
#include "codec_internal.h"
@@ -66,20 +65,8 @@ static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl)
}
}
-
#include "ac3enc_template.c"
-
-/**
- * Finalize MDCT and free allocated memory.
- *
- * @param s AC-3 encoder private context
- */
-static av_cold void ac3_fixed_mdct_end(AC3EncodeContext *s)
-{
- ff_mdct_end(&s->mdct);
-}
-
/**
* Initialize MDCT tables.
*
@@ -89,6 +76,7 @@ static av_cold void ac3_fixed_mdct_end(AC3EncodeContext *s)
static av_cold int ac3_fixed_mdct_init(AC3EncodeContext *s)
{
float fwin[AC3_BLOCK_SIZE];
+ const float scale = -1.0f;
int32_t *iwin = av_malloc_array(AC3_BLOCK_SIZE, sizeof(*iwin));
if (!iwin)
@@ -104,7 +92,8 @@ static av_cold int ac3_fixed_mdct_init(AC3EncodeContext *s)
if (!s->fdsp)
return AVERROR(ENOMEM);
- return ff_mdct_init(&s->mdct, 9, 0, -1.0);
+ return av_tx_init(&s->tx, &s->tx_fn, AV_TX_INT32_MDCT, 0,
+ AC3_BLOCK_SIZE, &scale, 0);
}
@@ -112,20 +101,18 @@ static av_cold int ac3_fixed_encode_init(AVCodecContext *avctx)
{
AC3EncodeContext *s = avctx->priv_data;
s->fixed_point = 1;
- s->mdct_end = ac3_fixed_mdct_end;
s->mdct_init = ac3_fixed_mdct_init;
s->allocate_sample_buffers = allocate_sample_buffers;
return ff_ac3_encode_init(avctx);
}
-FF_DISABLE_DEPRECATION_WARNINGS
const FFCodec ff_ac3_fixed_encoder = {
.p.name = "ac3_fixed",
- .p.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
+ CODEC_LONG_NAME("ATSC A/52A (AC-3)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AC3,
- .p.capabilities = AV_CODEC_CAP_DR1,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(AC3EncodeContext),
.init = ac3_fixed_encode_init,
FF_CODEC_ENCODE_CB(ff_ac3_fixed_encode_frame),
@@ -133,12 +120,9 @@ const FFCodec ff_ac3_fixed_encoder = {
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32P,
AV_SAMPLE_FMT_NONE },
.p.priv_class = &ff_ac3enc_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.supported_samplerates = ff_ac3_sample_rate_tab,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = ff_ac3_channel_layouts,
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(ff_ac3_channel_layouts)
.p.ch_layouts = ff_ac3_ch_layouts,
.defaults = ff_ac3_enc_defaults,
};
-FF_ENABLE_DEPRECATION_WARNINGS
diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c
index 9f5341cf2..ae351a535 100644
--- a/libavcodec/ac3enc_float.c
+++ b/libavcodec/ac3enc_float.c
@@ -75,21 +75,8 @@ static void sum_square_butterfly(AC3EncodeContext *s, float sum[4],
s->ac3dsp.sum_square_butterfly_float(sum, coef0, coef1, len);
}
-
#include "ac3enc_template.c"
-
-/**
- * Finalize MDCT and free allocated memory.
- *
- * @param s AC-3 encoder private context
- */
-static av_cold void ac3_float_mdct_end(AC3EncodeContext *s)
-{
- ff_mdct_end(&s->mdct);
-}
-
-
/**
* Initialize MDCT tables.
*
@@ -98,6 +85,7 @@ static av_cold void ac3_float_mdct_end(AC3EncodeContext *s)
*/
static av_cold int ac3_float_mdct_init(AC3EncodeContext *s)
{
+ const float scale = -2.0 / AC3_WINDOW_SIZE;
float *window = av_malloc_array(AC3_BLOCK_SIZE, sizeof(*window));
if (!window) {
av_log(s->avctx, AV_LOG_ERROR, "Cannot allocate memory.\n");
@@ -107,14 +95,14 @@ static av_cold int ac3_float_mdct_init(AC3EncodeContext *s)
ff_kbd_window_init(window, 5.0, AC3_BLOCK_SIZE);
s->mdct_window = window;
- return ff_mdct_init(&s->mdct, 9, 0, -2.0 / AC3_WINDOW_SIZE);
+ return av_tx_init(&s->tx, &s->tx_fn, AV_TX_FLOAT_MDCT, 0,
+ AC3_BLOCK_SIZE, &scale, 0);
}
av_cold int ff_ac3_float_encode_init(AVCodecContext *avctx)
{
AC3EncodeContext *s = avctx->priv_data;
- s->mdct_end = ac3_float_mdct_end;
s->mdct_init = ac3_float_mdct_init;
s->allocate_sample_buffers = allocate_sample_buffers;
s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
@@ -123,13 +111,12 @@ av_cold int ff_ac3_float_encode_init(AVCodecContext *avctx)
return ff_ac3_encode_init(avctx);
}
-FF_DISABLE_DEPRECATION_WARNINGS
const FFCodec ff_ac3_encoder = {
.p.name = "ac3",
- .p.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
+ CODEC_LONG_NAME("ATSC A/52A (AC-3)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AC3,
- .p.capabilities = AV_CODEC_CAP_DR1,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(AC3EncodeContext),
.init = ff_ac3_float_encode_init,
FF_CODEC_ENCODE_CB(ff_ac3_float_encode_frame),
@@ -138,11 +125,8 @@ const FFCodec ff_ac3_encoder = {
AV_SAMPLE_FMT_NONE },
.p.priv_class = &ff_ac3enc_class,
.p.supported_samplerates = ff_ac3_sample_rate_tab,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = ff_ac3_channel_layouts,
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(ff_ac3_channel_layouts)
.p.ch_layouts = ff_ac3_ch_layouts,
.defaults = ff_ac3_enc_defaults,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
-FF_ENABLE_DEPRECATION_WARNINGS
diff --git a/libavcodec/ac3enc_opts_template.c b/libavcodec/ac3enc_opts_template.c
deleted file mode 100644
index 57b65a7a9..000000000
--- a/libavcodec/ac3enc_opts_template.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * AC-3 encoder options
- * Copyright (c) 2011 Justin Ruggles
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "libavutil/opt.h"
-#include "internal.h"
-#include "ac3.h"
-
-static const AVOption ac3_options[] = {
-/* Metadata Options */
-{"per_frame_metadata", "Allow Changing Metadata Per-Frame", OFFSET(allow_per_frame_metadata), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, AC3ENC_PARAM},
-#if AC3ENC_TYPE != AC3ENC_TYPE_EAC3
-/* AC-3 downmix levels */
-{"center_mixlev", "Center Mix Level", OFFSET(center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = LEVEL_MINUS_4POINT5DB }, 0.0, 1.0, AC3ENC_PARAM},
-{"surround_mixlev", "Surround Mix Level", OFFSET(surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = LEVEL_MINUS_6DB }, 0.0, 1.0, AC3ENC_PARAM},
-#endif
-/* audio production information */
-{"mixing_level", "Mixing Level", OFFSET(mixing_level), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 111, AC3ENC_PARAM},
-{"room_type", "Room Type", OFFSET(room_type), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_SMALL_ROOM, AC3ENC_PARAM, "room_type"},
- {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"},
- {"large", "Large Room", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_LARGE_ROOM }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"},
- {"small", "Small Room", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_SMALL_ROOM }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"},
-/* other metadata options */
-{"copyright", "Copyright Bit", OFFSET(copyright), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 1, AC3ENC_PARAM},
-{"dialnorm", "Dialogue Level (dB)", OFFSET(dialogue_level), AV_OPT_TYPE_INT, {.i64 = -31 }, -31, -1, AC3ENC_PARAM},
-{"dsur_mode", "Dolby Surround Mode", OFFSET(dolby_surround_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_MODE_ON, AC3ENC_PARAM, "dsur_mode"},
- {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"},
- {"on", "Dolby Surround Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"},
- {"off", "Not Dolby Surround Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"},
-{"original", "Original Bit Stream", OFFSET(original), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 1, AC3ENC_PARAM},
-/* extended bitstream information */
-{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_DOWNMIX_DPLII, AC3ENC_PARAM, "dmix_mode"},
- {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
- {"ltrt", "Lt/Rt Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_LTRT }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
- {"loro", "Lo/Ro Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_LORO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
- {"dplii", "Dolby Pro Logic II Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_DPLII }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
-{"ltrt_cmixlev", "Lt/Rt Center Mix Level", OFFSET(ltrt_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
-{"ltrt_surmixlev", "Lt/Rt Surround Mix Level", OFFSET(ltrt_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
-{"loro_cmixlev", "Lo/Ro Center Mix Level", OFFSET(loro_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
-{"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
-{"dsurex_mode", "Dolby Surround EX Mode", OFFSET(dolby_surround_ex_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_DSUREX_DPLIIZ, AC3ENC_PARAM, "dsurex_mode"},
- {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
- {"on", "Dolby Surround EX Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
- {"off", "Not Dolby Surround EX Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
- {"dpliiz", "Dolby Pro Logic IIz-encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DSUREX_DPLIIZ }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
-{"dheadphone_mode", "Dolby Headphone Mode", OFFSET(dolby_headphone_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_MODE_ON, AC3ENC_PARAM, "dheadphone_mode"},
- {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"},
- {"on", "Dolby Headphone Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"},
- {"off", "Not Dolby Headphone Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"},
-{"ad_conv_type", "A/D Converter Type", OFFSET(ad_converter_type), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_ADCONV_HDCD, AC3ENC_PARAM, "ad_conv_type"},
- {"standard", "Standard (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_ADCONV_STANDARD }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"},
- {"hdcd", "HDCD", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_ADCONV_HDCD }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"},
-/* Other Encoding Options */
-{"stereo_rematrixing", "Stereo Rematrixing", OFFSET(stereo_rematrixing), AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, AC3ENC_PARAM},
-{"channel_coupling", "Channel Coupling", OFFSET(channel_coupling), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_AUTO }, AC3ENC_OPT_AUTO, AC3ENC_OPT_ON, AC3ENC_PARAM, "channel_coupling"},
- {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_AUTO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "channel_coupling"},
-{"cpl_start_band", "Coupling Start Band", OFFSET(cpl_start), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_AUTO }, AC3ENC_OPT_AUTO, 15, AC3ENC_PARAM, "cpl_start_band"},
- {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_AUTO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "cpl_start_band"},
-{NULL}
-};
-
-static const AVCodecDefault ac3_defaults[] = {
- { "b", "0" },
- { NULL }
-};
diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c
index de66964d0..be4ecebc9 100644
--- a/libavcodec/ac3enc_template.c
+++ b/libavcodec/ac3enc_template.c
@@ -98,8 +98,8 @@ static void apply_mdct(AC3EncodeContext *s)
&input_samples[AC3_BLOCK_SIZE],
s->mdct_window, AC3_BLOCK_SIZE);
- s->mdct.mdct_calc(&s->mdct, block->mdct_coef[ch+1],
- s->windowed_samples);
+ s->tx_fn(s->tx, block->mdct_coef[ch+1],
+ s->windowed_samples, sizeof(float));
}
}
}
diff --git a/libavcodec/acelp_filters.c b/libavcodec/acelp_filters.c
index 918257933..db4908f31 100644
--- a/libavcodec/acelp_filters.c
+++ b/libavcodec/acelp_filters.c
@@ -20,8 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include
#include
+#include
#include "config.h"
#include "libavutil/avassert.h"
diff --git a/libavcodec/acelp_pitch_delay.c b/libavcodec/acelp_pitch_delay.c
index 1eca97ec6..6cf880e4a 100644
--- a/libavcodec/acelp_pitch_delay.c
+++ b/libavcodec/acelp_pitch_delay.c
@@ -23,8 +23,6 @@
#include "libavutil/common.h"
#include "libavutil/ffmath.h"
#include "libavutil/float_dsp.h"
-#include "libavutil/mathematics.h"
-#include "avcodec.h"
#include "acelp_pitch_delay.h"
#include "celp_math.h"
#include "audiodsp.h"
diff --git a/libavcodec/acelp_vectors.c b/libavcodec/acelp_vectors.c
index b8a2b50dd..04cbffd79 100644
--- a/libavcodec/acelp_vectors.c
+++ b/libavcodec/acelp_vectors.c
@@ -20,12 +20,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include
+#include
+#include "config.h"
#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "libavutil/float_dsp.h"
-#include "avcodec.h"
#include "acelp_vectors.h"
const uint8_t ff_fc_2pulses_9bits_track1_gray[16] =
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index b2ef7dfbe..451696932 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -43,7 +43,7 @@
#include "adpcm.h"
#include "adpcm_data.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
/**
* @file
@@ -324,6 +324,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx)
case AV_CODEC_ID_ADPCM_IMA_WAV:
case AV_CODEC_ID_ADPCM_4XM:
case AV_CODEC_ID_ADPCM_XA:
+ case AV_CODEC_ID_ADPCM_XMD:
case AV_CODEC_ID_ADPCM_EA_R1:
case AV_CODEC_ID_ADPCM_EA_R2:
case AV_CODEC_ID_ADPCM_EA_R3:
@@ -1043,6 +1044,9 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
case AV_CODEC_ID_ADPCM_XA:
nb_samples = (buf_size / 128) * 224 / ch;
break;
+ case AV_CODEC_ID_ADPCM_XMD:
+ nb_samples = buf_size / (21 * ch) * 32;
+ break;
case AV_CODEC_ID_ADPCM_DTK:
case AV_CODEC_ID_ADPCM_PSX:
nb_samples = buf_size / (16 * ch) * 28;
@@ -1553,6 +1557,45 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
}
bytestream2_seek(&gb, 0, SEEK_END);
) /* End of CASE */
+ CASE(ADPCM_XMD,
+ int bytes_remaining, block = 0;
+ while (bytestream2_get_bytes_left(&gb) >= 21 * channels) {
+ for (int channel = 0; channel < channels; channel++) {
+ int16_t *out = samples_p[channel] + block * 32;
+ int16_t history[2];
+ uint16_t scale;
+
+ history[1] = sign_extend(bytestream2_get_le16(&gb), 16);
+ history[0] = sign_extend(bytestream2_get_le16(&gb), 16);
+ scale = bytestream2_get_le16(&gb);
+
+ out[0] = history[1];
+ out[1] = history[0];
+
+ for (int n = 0; n < 15; n++) {
+ unsigned byte = bytestream2_get_byte(&gb);
+ int32_t nibble[2];
+
+ nibble[0] = sign_extend(byte & 15, 4);
+ nibble[1] = sign_extend(byte >> 4, 4);
+
+ out[2+n*2] = (nibble[0]*(scale<<14) + (history[0]*29336) - (history[1]*13136)) >> 14;
+ history[1] = history[0];
+ history[0] = out[2+n*2];
+
+ out[2+n*2+1] = (nibble[1]*(scale<<14) + (history[0]*29336) - (history[1]*13136)) >> 14;
+ history[1] = history[0];
+ history[0] = out[2+n*2+1];
+ }
+ }
+
+ block++;
+ }
+ bytes_remaining = bytestream2_get_bytes_left(&gb);
+ if (bytes_remaining > 0) {
+ bytestream2_skip(&gb, bytes_remaining);
+ }
+ ) /* End of CASE */
CASE(ADPCM_XA,
int16_t *out0 = samples_p[0];
int16_t *out1 = samples_p[1];
@@ -2287,7 +2330,7 @@ static const enum AVSampleFormat sample_fmts_both[] = { AV_SAMPLE_FMT_S16,
#define ADPCM_DECODER_1(id_, sample_fmts_, name_, long_name_) \
const FFCodec ff_ ## name_ ## _decoder = { \
.p.name = #name_, \
- .p.long_name = NULL_IF_CONFIG_SMALL(long_name_), \
+ CODEC_LONG_NAME(long_name_), \
.p.type = AVMEDIA_TYPE_AUDIO, \
.p.id = id_, \
.p.capabilities = AV_CODEC_CAP_DR1, \
@@ -2296,7 +2339,6 @@ const FFCodec ff_ ## name_ ## _decoder = { \
.init = adpcm_decode_init, \
FF_CODEC_DECODE_CB(adpcm_decode_frame), \
.flush = adpcm_flush, \
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, \
};
#define ADPCM_DECODER_2(enabled, codec_id, name, sample_fmts, long_name) \
ADPCM_DECODER_ ## enabled(codec_id, name, sample_fmts, long_name)
@@ -2351,5 +2393,6 @@ ADPCM_DECODER(ADPCM_SWF, sample_fmts_s16, adpcm_swf, "ADPCM Sho
ADPCM_DECODER(ADPCM_THP_LE, sample_fmts_s16p, adpcm_thp_le, "ADPCM Nintendo THP (little-endian)")
ADPCM_DECODER(ADPCM_THP, sample_fmts_s16p, adpcm_thp, "ADPCM Nintendo THP")
ADPCM_DECODER(ADPCM_XA, sample_fmts_s16p, adpcm_xa, "ADPCM CDROM XA")
+ADPCM_DECODER(ADPCM_XMD, sample_fmts_s16p, adpcm_xmd, "ADPCM Konami XMD")
ADPCM_DECODER(ADPCM_YAMAHA, sample_fmts_s16, adpcm_yamaha, "ADPCM Yamaha")
ADPCM_DECODER(ADPCM_ZORK, sample_fmts_s16, adpcm_zork, "ADPCM Zork")
diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c
index 4ff77662b..63afffc58 100644
--- a/libavcodec/adpcmenc.c
+++ b/libavcodec/adpcmenc.c
@@ -601,20 +601,20 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
{
int st, pkt_size, ret;
const int16_t *samples;
- int16_t **samples_p;
+ const int16_t *const *samples_p;
uint8_t *dst;
ADPCMEncodeContext *c = avctx->priv_data;
int channels = avctx->ch_layout.nb_channels;
samples = (const int16_t *)frame->data[0];
- samples_p = (int16_t **)frame->extended_data;
+ samples_p = (const int16_t *const *)frame->extended_data;
st = channels == 2;
if (avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_SSI ||
avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_ALP ||
avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_APM ||
avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_WS)
- pkt_size = (frame->nb_samples * channels) / 2;
+ pkt_size = (frame->nb_samples * channels + 1) / 2;
else
pkt_size = avctx->block_align;
if ((ret = ff_get_encode_buffer(avctx, avpkt, pkt_size, 0)) < 0)
@@ -998,18 +998,19 @@ static const AVClass adpcm_encoder_class = {
#define ADPCM_ENCODER_1(id_, name_, sample_fmts_, capabilities_, long_name_) \
const FFCodec ff_ ## name_ ## _encoder = { \
.p.name = #name_, \
- .p.long_name = NULL_IF_CONFIG_SMALL(long_name_), \
+ CODEC_LONG_NAME(long_name_), \
.p.type = AVMEDIA_TYPE_AUDIO, \
.p.id = id_, \
.p.sample_fmts = sample_fmts_, \
.p.ch_layouts = ch_layouts, \
- .p.capabilities = capabilities_ | AV_CODEC_CAP_DR1, \
+ .p.capabilities = capabilities_ | AV_CODEC_CAP_DR1 | \
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, \
.p.priv_class = &adpcm_encoder_class, \
.priv_data_size = sizeof(ADPCMEncodeContext), \
.init = adpcm_encode_init, \
FF_CODEC_ENCODE_CB(adpcm_encode_frame), \
.close = adpcm_encode_close, \
- .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, \
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \
};
#define ADPCM_ENCODER_2(enabled, codec_id, name, sample_fmts, capabilities, long_name) \
ADPCM_ENCODER_ ## enabled(codec_id, name, sample_fmts, capabilities, long_name)
diff --git a/libavcodec/adts_header.c b/libavcodec/adts_header.c
index ff4efafbf..00fa0a5a9 100644
--- a/libavcodec/adts_header.c
+++ b/libavcodec/adts_header.c
@@ -32,6 +32,8 @@ int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr)
int size, rdb, ch, sr;
int aot, crc_abs;
+ memset(hdr, 0, sizeof(*hdr));
+
if (get_bits(gbc, 12) != 0xfff)
return AAC_AC3_PARSE_ERROR_SYNC;
diff --git a/libavcodec/adts_parser.c b/libavcodec/adts_parser.c
index 4a1a8fd5f..f2e155fc9 100644
--- a/libavcodec/adts_parser.c
+++ b/libavcodec/adts_parser.c
@@ -47,24 +47,30 @@ int avpriv_adts_header_parse(AACADTSHeaderInfo **phdr, const uint8_t *buf, size_
{
#if CONFIG_ADTS_HEADER
int ret = 0;
+ int allocated = 0;
GetBitContext gb;
if (!phdr || !buf || size < AV_AAC_ADTS_HEADER_SIZE)
return AVERROR_INVALIDDATA;
- *phdr = av_mallocz(sizeof(AACADTSHeaderInfo));
+ if (!*phdr) {
+ allocated = 1;
+ *phdr = av_mallocz(sizeof(AACADTSHeaderInfo));
+ }
if (!*phdr)
return AVERROR(ENOMEM);
ret = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE);
if (ret < 0) {
- av_freep(phdr);
+ if (allocated)
+ av_freep(phdr);
return ret;
}
ret = ff_adts_header_parse(&gb, *phdr);
if (ret < 0) {
- av_freep(phdr);
+ if (allocated)
+ av_freep(phdr);
return ret;
}
diff --git a/libavcodec/adx.c b/libavcodec/adx.c
index c60fabb40..6323e5c85 100644
--- a/libavcodec/adx.c
+++ b/libavcodec/adx.c
@@ -19,7 +19,6 @@
*/
#include "libavutil/common.h"
-#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "adx.h"
@@ -34,55 +33,3 @@ void ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff)
coeff[0] = lrintf(c * 2.0 * (1 << bits));
coeff[1] = lrintf(-(c * c) * (1 << bits));
}
-
-int ff_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf,
- int bufsize, int *header_size, int *coeff)
-{
- int offset, cutoff, channels;
-
- if (bufsize < 24)
- return AVERROR_INVALIDDATA;
-
- if (AV_RB16(buf) != 0x8000)
- return AVERROR_INVALIDDATA;
- offset = AV_RB16(buf + 2) + 4;
-
- /* if copyright string is within the provided data, validate it */
- if (bufsize >= offset && offset >= 6 && memcmp(buf + offset - 6, "(c)CRI", 6))
- return AVERROR_INVALIDDATA;
-
- /* check for encoding=3 block_size=18, sample_size=4 */
- if (buf[4] != 3 || buf[5] != 18 || buf[6] != 4) {
- avpriv_request_sample(avctx, "Support for this ADX format");
- return AVERROR_PATCHWELCOME;
- }
-
- /* channels */
- channels = buf[7];
- if (channels <= 0 || channels > 2)
- return AVERROR_INVALIDDATA;
-
- if (avctx->ch_layout.nb_channels != channels) {
- av_channel_layout_uninit(&avctx->ch_layout);
- avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
- avctx->ch_layout.nb_channels = channels;
- }
-
- /* sample rate */
- avctx->sample_rate = AV_RB32(buf + 8);
- if (avctx->sample_rate < 1 ||
- avctx->sample_rate > INT_MAX / (channels * BLOCK_SIZE * 8))
- return AVERROR_INVALIDDATA;
-
- /* bit rate */
- avctx->bit_rate = avctx->sample_rate * channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES;
-
- /* LPC coefficients */
- if (coeff) {
- cutoff = AV_RB16(buf + 16);
- ff_adx_calculate_coeffs(cutoff, avctx->sample_rate, COEFF_BITS, coeff);
- }
-
- *header_size = offset;
- return 0;
-}
diff --git a/libavcodec/adx.h b/libavcodec/adx.h
index 08f749a04..8d5e0869a 100644
--- a/libavcodec/adx.h
+++ b/libavcodec/adx.h
@@ -31,10 +31,6 @@
#ifndef AVCODEC_ADX_H
#define AVCODEC_ADX_H
-#include
-
-#include "avcodec.h"
-
typedef struct ADXChannelState {
int s1,s2;
} ADXChannelState;
@@ -63,18 +59,4 @@ typedef struct ADXContext {
*/
void ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff);
-/**
- * Decode ADX stream header.
- * Sets avctx->channels and avctx->sample_rate.
- *
- * @param avctx codec context
- * @param buf header data
- * @param bufsize data size, should be at least 24 bytes
- * @param[out] header_size size of ADX header
- * @param[out] coeff 2 LPC coefficients, can be NULL
- * @return data offset or negative error code if header is invalid
- */
-int ff_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf,
- int bufsize, int *header_size, int *coeff);
-
#endif /* AVCODEC_ADX_H */
diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c
index 1ebc250e4..97a7e5968 100644
--- a/libavcodec/adxdec.c
+++ b/libavcodec/adxdec.c
@@ -23,8 +23,8 @@
#include "avcodec.h"
#include "adx.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
/**
* @file
@@ -35,15 +35,78 @@
* adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/
*/
+/**
+ * Decode ADX stream header.
+ * Sets avctx->channels and avctx->sample_rate.
+ *
+ * @param avctx codec context
+ * @param buf header data
+ * @param bufsize data size, should be at least 24 bytes
+ * @param[out] header_size size of ADX header
+ * @param[out] coeff 2 LPC coefficients, can be NULL
+ * @return data offset or negative error code if header is invalid
+ */
+static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf,
+ int bufsize, int *header_size, int *coeff)
+{
+ int offset, cutoff, channels;
+
+ if (bufsize < 24)
+ return AVERROR_INVALIDDATA;
+
+ if (AV_RB16(buf) != 0x8000)
+ return AVERROR_INVALIDDATA;
+ offset = AV_RB16(buf + 2) + 4;
+
+ /* if copyright string is within the provided data, validate it */
+ if (bufsize >= offset && offset >= 6 && memcmp(buf + offset - 6, "(c)CRI", 6))
+ return AVERROR_INVALIDDATA;
+
+ /* check for encoding=3 block_size=18, sample_size=4 */
+ if (buf[4] != 3 || buf[5] != 18 || buf[6] != 4) {
+ avpriv_request_sample(avctx, "Support for this ADX format");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ /* channels */
+ channels = buf[7];
+ if (channels <= 0 || channels > 2)
+ return AVERROR_INVALIDDATA;
+
+ if (avctx->ch_layout.nb_channels != channels) {
+ av_channel_layout_uninit(&avctx->ch_layout);
+ avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
+ avctx->ch_layout.nb_channels = channels;
+ }
+
+ /* sample rate */
+ avctx->sample_rate = AV_RB32(buf + 8);
+ if (avctx->sample_rate < 1 ||
+ avctx->sample_rate > INT_MAX / (channels * BLOCK_SIZE * 8))
+ return AVERROR_INVALIDDATA;
+
+ /* bit rate */
+ avctx->bit_rate = avctx->sample_rate * channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES;
+
+ /* LPC coefficients */
+ if (coeff) {
+ cutoff = AV_RB16(buf + 16);
+ ff_adx_calculate_coeffs(cutoff, avctx->sample_rate, COEFF_BITS, coeff);
+ }
+
+ *header_size = offset;
+ return 0;
+}
+
static av_cold int adx_decode_init(AVCodecContext *avctx)
{
ADXContext *c = avctx->priv_data;
int ret, header_size;
if (avctx->extradata_size >= 24) {
- if ((ret = ff_adx_decode_header(avctx, avctx->extradata,
- avctx->extradata_size, &header_size,
- c->coeff)) < 0) {
+ if ((ret = adx_decode_header(avctx, avctx->extradata,
+ avctx->extradata_size, &header_size,
+ c->coeff)) < 0) {
av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n");
return AVERROR_INVALIDDATA;
}
@@ -110,9 +173,9 @@ static int adx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
&new_extradata_size);
if (new_extradata && new_extradata_size > 0) {
int header_size;
- if ((ret = ff_adx_decode_header(avctx, new_extradata,
- new_extradata_size, &header_size,
- c->coeff)) < 0) {
+ if ((ret = adx_decode_header(avctx, new_extradata,
+ new_extradata_size, &header_size,
+ c->coeff)) < 0) {
av_log(avctx, AV_LOG_ERROR, "error parsing new ADX extradata\n");
return AVERROR_INVALIDDATA;
}
@@ -127,8 +190,8 @@ static int adx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
if (!c->header_parsed && buf_size >= 2 && AV_RB16(buf) == 0x8000) {
int header_size;
- if ((ret = ff_adx_decode_header(avctx, buf, buf_size, &header_size,
- c->coeff)) < 0) {
+ if ((ret = adx_decode_header(avctx, buf, buf_size, &header_size,
+ c->coeff)) < 0) {
av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n");
return AVERROR_INVALIDDATA;
}
@@ -192,7 +255,7 @@ static void adx_decode_flush(AVCodecContext *avctx)
const FFCodec ff_adpcm_adx_decoder = {
.p.name = "adpcm_adx",
- .p.long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
+ CODEC_LONG_NAME("SEGA CRI ADX ADPCM"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ADPCM_ADX,
.priv_data_size = sizeof(ADXContext),
@@ -203,5 +266,4 @@ const FFCodec ff_adpcm_adx_decoder = {
AV_CODEC_CAP_DR1,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c
index 9277cab7c..796efdab6 100644
--- a/libavcodec/adxenc.c
+++ b/libavcodec/adxenc.c
@@ -183,22 +183,21 @@ static int adx_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
dst += BLOCK_SIZE;
}
- avpkt->pts = frame->pts;
- avpkt->duration = frame->nb_samples;
*got_packet_ptr = 1;
return 0;
}
const FFCodec ff_adpcm_adx_encoder = {
.p.name = "adpcm_adx",
- .p.long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
+ CODEC_LONG_NAME("SEGA CRI ADX ADPCM"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ADPCM_ADX,
- .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(ADXContext),
.init = adx_encode_init,
FF_CODEC_ENCODE_CB(adx_encode_frame),
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
+ .caps_internal = FF_CODEC_CAP_EOF_FLUSH,
};
diff --git a/libavcodec/agm.c b/libavcodec/agm.c
index 27438dd1a..b37f1a42c 100644
--- a/libavcodec/agm.c
+++ b/libavcodec/agm.c
@@ -20,8 +20,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include
-#include
#include
#define BITSTREAM_READER_LE
@@ -32,27 +30,10 @@
#include "bytestream.h"
#include "codec_internal.h"
#include "copy_block.h"
+#include "decode.h"
#include "get_bits.h"
#include "idctdsp.h"
-#include "internal.h"
-
-static const uint8_t unscaled_luma[64] = {
- 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19,
- 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56,
- 68,109,103, 77, 24, 35, 55, 64, 81,104,113, 92,
- 49, 64, 78, 87,103,121,120,101, 72, 92, 95, 98,
- 112,100,103,99
-};
-
-static const uint8_t unscaled_chroma[64] = {
- 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66,
- 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99
-};
+#include "jpegquanttables.h"
typedef struct MotionVector {
int16_t x, y;
@@ -90,7 +71,7 @@ typedef struct AGMContext {
int luma_quant_matrix[64];
int chroma_quant_matrix[64];
- ScanTable scantable;
+ uint8_t permutated_scantable[64];
DECLARE_ALIGNED(32, int16_t, block)[64];
int16_t *wblocks;
@@ -197,7 +178,7 @@ static int read_code(GetBitContext *gb, int *oskip, int *level, int *map, int mo
static int decode_intra_blocks(AGMContext *s, GetBitContext *gb,
const int *quant_matrix, int *skip, int *dc_level)
{
- const uint8_t *scantable = s->scantable.permutated;
+ const uint8_t *scantable = s->permutated_scantable;
int level, ret, map = 0;
memset(s->wblocks, 0, s->wblocks_size);
@@ -239,7 +220,7 @@ static int decode_inter_blocks(AGMContext *s, GetBitContext *gb,
const int *quant_matrix, int *skip,
int *map)
{
- const uint8_t *scantable = s->scantable.permutated;
+ const uint8_t *scantable = s->permutated_scantable;
int level, ret;
memset(s->wblocks, 0, s->wblocks_size);
@@ -274,7 +255,7 @@ static int decode_inter_blocks(AGMContext *s, GetBitContext *gb,
static int decode_intra_block(AGMContext *s, GetBitContext *gb,
const int *quant_matrix, int *skip, int *dc_level)
{
- const uint8_t *scantable = s->scantable.permutated;
+ const uint8_t *scantable = s->permutated_scantable;
const int offset = s->plus ? 0 : 1024;
int16_t *block = s->block;
int level, ret, map = 0;
@@ -364,7 +345,7 @@ static int decode_inter_block(AGMContext *s, GetBitContext *gb,
const int *quant_matrix, int *skip,
int *map)
{
- const uint8_t *scantable = s->scantable.permutated;
+ const uint8_t *scantable = s->permutated_scantable;
int16_t *block = s->block;
int level, ret;
@@ -552,13 +533,13 @@ static void compute_quant_matrix(AGMContext *s, double qscale)
} else {
if (qscale >= 0.0) {
for (int i = 0; i < 64; i++) {
- luma[i] = FFMAX(1, unscaled_luma [(i & 7) * 8 + (i >> 3)] * f);
- chroma[i] = FFMAX(1, unscaled_chroma[(i & 7) * 8 + (i >> 3)] * f);
+ luma[i] = FFMAX(1, ff_mjpeg_std_luminance_quant_tbl [(i & 7) * 8 + (i >> 3)] * f);
+ chroma[i] = FFMAX(1, ff_mjpeg_std_chrominance_quant_tbl[(i & 7) * 8 + (i >> 3)] * f);
}
} else {
for (int i = 0; i < 64; i++) {
- luma[i] = FFMAX(1, 255.0 - (255 - unscaled_luma [(i & 7) * 8 + (i >> 3)]) * f);
- chroma[i] = FFMAX(1, 255.0 - (255 - unscaled_chroma[(i & 7) * 8 + (i >> 3)]) * f);
+ luma[i] = FFMAX(1, 255.0 - (255 - ff_mjpeg_std_luminance_quant_tbl [(i & 7) * 8 + (i >> 3)]) * f);
+ chroma[i] = FFMAX(1, 255.0 - (255 - ff_mjpeg_std_chrominance_quant_tbl[(i & 7) * 8 + (i >> 3)]) * f);
}
}
}
@@ -1251,7 +1232,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
avctx->idct_algo = FF_IDCT_SIMPLE;
ff_idctdsp_init(&s->idsp, avctx);
- ff_init_scantable(s->idsp.idct_permutation, &s->scantable, ff_zigzag_direct);
+ ff_permute_scantable(s->permutated_scantable, ff_zigzag_direct,
+ s->idsp.idct_permutation);
s->prev_frame = av_frame_alloc();
if (!s->prev_frame)
@@ -1287,7 +1269,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
const FFCodec ff_agm_decoder = {
.p.name = "agm",
- .p.long_name = NULL_IF_CONFIG_SMALL("Amuse Graphics Movie"),
+ CODEC_LONG_NAME("Amuse Graphics Movie"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AGM,
.p.capabilities = AV_CODEC_CAP_DR1,
@@ -1296,7 +1278,6 @@ const FFCodec ff_agm_decoder = {
.close = decode_close,
FF_CODEC_DECODE_CB(decode_frame),
.flush = decode_flush,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP |
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP |
FF_CODEC_CAP_EXPORTS_CROPPING,
};
diff --git a/libavcodec/aic.c b/libavcodec/aic.c
index 5f0eec6b8..7ba1c02fd 100644
--- a/libavcodec/aic.c
+++ b/libavcodec/aic.c
@@ -143,7 +143,6 @@ typedef struct AICContext {
AVCodecContext *avctx;
AVFrame *frame;
IDCTDSPContext idsp;
- ScanTable scantable;
int num_x_slices;
int slice_width;
@@ -348,10 +347,10 @@ static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y,
for (mb = 0; mb < slice_width; mb++) {
for (blk = 0; blk < 4; blk++) {
if (!ctx->interlaced)
- recombine_block(ctx->block, ctx->scantable.permutated,
+ recombine_block(ctx->block, ctx->idsp.idct_permutation,
&base_y, &ext_y);
else
- recombine_block_il(ctx->block, ctx->scantable.permutated,
+ recombine_block_il(ctx->block, ctx->idsp.idct_permutation,
&base_y, &ext_y, blk);
unquant_block(ctx->block, ctx->quant, ctx->quant_matrix);
ctx->idsp.idct(ctx->block);
@@ -368,7 +367,7 @@ static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y,
Y += 16;
for (blk = 0; blk < 2; blk++) {
- recombine_block(ctx->block, ctx->scantable.permutated,
+ recombine_block(ctx->block, ctx->idsp.idct_permutation,
&base_c, &ext_c);
unquant_block(ctx->block, ctx->quant, ctx->quant_matrix);
ctx->idsp.idct(ctx->block);
@@ -444,7 +443,6 @@ static av_cold int aic_decode_init(AVCodecContext *avctx)
{
AICContext *ctx = avctx->priv_data;
int i;
- uint8_t scan[64];
ctx->avctx = avctx;
@@ -452,9 +450,6 @@ static av_cold int aic_decode_init(AVCodecContext *avctx)
ff_idctdsp_init(&ctx->idsp, avctx);
- for (i = 0; i < 64; i++)
- scan[i] = i;
- ff_init_scantable(ctx->idsp.idct_permutation, &ctx->scantable, scan);
for (i = 0; i < 64; i++)
ctx->quant_matrix[ctx->idsp.idct_permutation[i]] = aic_quant_matrix[i];
@@ -497,7 +492,7 @@ static av_cold int aic_decode_close(AVCodecContext *avctx)
const FFCodec ff_aic_decoder = {
.p.name = "aic",
- .p.long_name = NULL_IF_CONFIG_SMALL("Apple Intermediate Codec"),
+ CODEC_LONG_NAME("Apple Intermediate Codec"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AIC,
.priv_data_size = sizeof(AICContext),
@@ -505,5 +500,4 @@ const FFCodec ff_aic_decoder = {
.close = aic_decode_close,
FF_CODEC_DECODE_CB(aic_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/alac.c b/libavcodec/alac.c
index 4aab82d60..d10ecba7e 100644
--- a/libavcodec/alac.c
+++ b/libavcodec/alac.c
@@ -614,7 +614,7 @@ static const AVClass alac_class = {
const FFCodec ff_alac_decoder = {
.p.name = "alac",
- .p.long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
+ CODEC_LONG_NAME("ALAC (Apple Lossless Audio Codec)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ALAC,
.priv_data_size = sizeof(ALACContext),
@@ -622,6 +622,6 @@ const FFCodec ff_alac_decoder = {
.close = alac_decode_close,
FF_CODEC_DECODE_CB(alac_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_CHANNEL_CONF,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.priv_class = &alac_class
};
diff --git a/libavcodec/alacdsp.c b/libavcodec/alacdsp.c
index b033a2797..a604566af 100644
--- a/libavcodec/alacdsp.c
+++ b/libavcodec/alacdsp.c
@@ -58,7 +58,9 @@ av_cold void ff_alacdsp_init(ALACDSPContext *c)
c->append_extra_bits[0] =
c->append_extra_bits[1] = append_extra_bits;
-#if ARCH_X86
+#if ARCH_RISCV
+ ff_alacdsp_init_riscv(c);
+#elif ARCH_X86
ff_alacdsp_init_x86(c);
#endif
}
diff --git a/libavcodec/alacdsp.h b/libavcodec/alacdsp.h
index f8b56dd5d..489ebc670 100644
--- a/libavcodec/alacdsp.h
+++ b/libavcodec/alacdsp.h
@@ -29,6 +29,7 @@ typedef struct ALACDSPContext {
} ALACDSPContext;
void ff_alacdsp_init(ALACDSPContext *c);
+void ff_alacdsp_init_riscv(ALACDSPContext *c);
void ff_alacdsp_init_x86(ALACDSPContext *c);
#endif /* AVCODEC_ALACDSP_H */
diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c
index 72ce65e26..9598e5861 100644
--- a/libavcodec/alacenc.c
+++ b/libavcodec/alacenc.c
@@ -648,25 +648,21 @@ static const AVClass alacenc_class = {
.version = LIBAVUTIL_VERSION_INT,
};
-FF_DISABLE_DEPRECATION_WARNINGS
const FFCodec ff_alac_encoder = {
.p.name = "alac",
- .p.long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
+ CODEC_LONG_NAME("ALAC (Apple Lossless Audio Codec)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ALAC,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(AlacEncodeContext),
.p.priv_class = &alacenc_class,
.init = alac_encode_init,
FF_CODEC_ENCODE_CB(alac_encode_frame),
.close = alac_encode_close,
- .p.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = alac_channel_layouts,
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(alac_channel_layouts)
.p.ch_layouts = ff_alac_ch_layouts,
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32P,
AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
-FF_ENABLE_DEPRECATION_WARNINGS
diff --git a/libavcodec/aliaspixdec.c b/libavcodec/aliaspixdec.c
index 73c83528f..45155d79c 100644
--- a/libavcodec/aliaspixdec.c
+++ b/libavcodec/aliaspixdec.c
@@ -24,7 +24,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#define ALIAS_HEADER_SIZE 10
@@ -123,7 +123,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *f,
const FFCodec ff_alias_pix_decoder = {
.p.name = "alias_pix",
- .p.long_name = NULL_IF_CONFIG_SMALL("Alias/Wavefront PIX image"),
+ CODEC_LONG_NAME("Alias/Wavefront PIX image"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_ALIAS_PIX,
.p.capabilities = AV_CODEC_CAP_DR1,
diff --git a/libavcodec/aliaspixenc.c b/libavcodec/aliaspixenc.c
index 9c43cfa9e..90d2a6331 100644
--- a/libavcodec/aliaspixenc.c
+++ b/libavcodec/aliaspixenc.c
@@ -103,9 +103,10 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const FFCodec ff_alias_pix_encoder = {
.p.name = "alias_pix",
- .p.long_name = NULL_IF_CONFIG_SMALL("Alias/Wavefront PIX image"),
+ CODEC_LONG_NAME("Alias/Wavefront PIX image"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_ALIAS_PIX,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
FF_CODEC_ENCODE_CB(encode_frame),
.p.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_BGR24, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index bdfc2f6f4..e593ad19a 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -61,8 +61,10 @@ extern const FFCodec ff_avrn_decoder;
extern const FFCodec ff_avs_decoder;
extern const FFCodec ff_avui_encoder;
extern const FFCodec ff_avui_decoder;
+#if FF_API_AYUV_CODECID
extern const FFCodec ff_ayuv_encoder;
extern const FFCodec ff_ayuv_decoder;
+#endif
extern const FFCodec ff_bethsoftvid_decoder;
extern const FFCodec ff_bfi_decoder;
extern const FFCodec ff_bink_decoder;
@@ -152,6 +154,7 @@ extern const FFCodec ff_h264_decoder;
extern const FFCodec ff_h264_crystalhd_decoder;
extern const FFCodec ff_h264_v4l2m2m_decoder;
extern const FFCodec ff_h264_mediacodec_decoder;
+extern const FFCodec ff_h264_mediacodec_encoder;
extern const FFCodec ff_h264_mmal_decoder;
extern const FFCodec ff_h264_qsv_decoder;
extern const FFCodec ff_h264_rkmpp_decoder;
@@ -192,6 +195,7 @@ extern const FFCodec ff_m101_decoder;
extern const FFCodec ff_magicyuv_encoder;
extern const FFCodec ff_magicyuv_decoder;
extern const FFCodec ff_mdec_decoder;
+extern const FFCodec ff_media100_decoder;
extern const FFCodec ff_mimic_decoder;
extern const FFCodec ff_mjpeg_encoder;
extern const FFCodec ff_mjpeg_decoder;
@@ -283,6 +287,7 @@ extern const FFCodec ff_r210_decoder;
extern const FFCodec ff_rasc_decoder;
extern const FFCodec ff_rawvideo_encoder;
extern const FFCodec ff_rawvideo_decoder;
+extern const FFCodec ff_rka_decoder;
extern const FFCodec ff_rl2_decoder;
extern const FFCodec ff_roq_encoder;
extern const FFCodec ff_roq_decoder;
@@ -378,6 +383,9 @@ extern const FFCodec ff_vp9_decoder;
extern const FFCodec ff_vp9_rkmpp_decoder;
extern const FFCodec ff_vp9_v4l2m2m_decoder;
extern const FFCodec ff_vqa_decoder;
+extern const FFCodec ff_vqc_decoder;
+extern const FFCodec ff_wbmp_decoder;
+extern const FFCodec ff_wbmp_encoder;
extern const FFCodec ff_webp_decoder;
extern const FFCodec ff_wcmv_decoder;
extern const FFCodec ff_wrapped_avframe_encoder;
@@ -428,6 +436,7 @@ extern const FFCodec ff_alac_decoder;
extern const FFCodec ff_als_decoder;
extern const FFCodec ff_amrnb_decoder;
extern const FFCodec ff_amrwb_decoder;
+extern const FFCodec ff_apac_decoder;
extern const FFCodec ff_ape_decoder;
extern const FFCodec ff_aptx_encoder;
extern const FFCodec ff_aptx_decoder;
@@ -442,6 +451,7 @@ extern const FFCodec ff_atrac9_decoder;
extern const FFCodec ff_binkaudio_dct_decoder;
extern const FFCodec ff_binkaudio_rdft_decoder;
extern const FFCodec ff_bmv_audio_decoder;
+extern const FFCodec ff_bonk_decoder;
extern const FFCodec ff_cook_decoder;
extern const FFCodec ff_dca_encoder;
extern const FFCodec ff_dca_decoder;
@@ -462,6 +472,7 @@ extern const FFCodec ff_fastaudio_decoder;
extern const FFCodec ff_ffwavesynth_decoder;
extern const FFCodec ff_flac_encoder;
extern const FFCodec ff_flac_decoder;
+extern const FFCodec ff_ftr_decoder;
extern const FFCodec ff_g723_1_encoder;
extern const FFCodec ff_g723_1_decoder;
extern const FFCodec ff_g729_decoder;
@@ -469,6 +480,8 @@ extern const FFCodec ff_gsm_decoder;
extern const FFCodec ff_gsm_ms_decoder;
extern const FFCodec ff_hca_decoder;
extern const FFCodec ff_hcom_decoder;
+extern const FFCodec ff_hdr_encoder;
+extern const FFCodec ff_hdr_decoder;
extern const FFCodec ff_iac_decoder;
extern const FFCodec ff_ilbc_decoder;
extern const FFCodec ff_imc_decoder;
@@ -476,6 +489,7 @@ extern const FFCodec ff_interplay_acm_decoder;
extern const FFCodec ff_mace3_decoder;
extern const FFCodec ff_mace6_decoder;
extern const FFCodec ff_metasound_decoder;
+extern const FFCodec ff_misc4_decoder;
extern const FFCodec ff_mlp_encoder;
extern const FFCodec ff_mlp_decoder;
extern const FFCodec ff_mp1_decoder;
@@ -525,6 +539,7 @@ extern const FFCodec ff_twinvq_decoder;
extern const FFCodec ff_vmdaudio_decoder;
extern const FFCodec ff_vorbis_encoder;
extern const FFCodec ff_vorbis_decoder;
+extern const FFCodec ff_wavarc_decoder;
extern const FFCodec ff_wavpack_encoder;
extern const FFCodec ff_wavpack_decoder;
extern const FFCodec ff_wmalossless_decoder;
@@ -607,6 +622,7 @@ extern const FFCodec ff_pcm_vidc_encoder;
extern const FFCodec ff_pcm_vidc_decoder;
/* DPCM codecs */
+extern const FFCodec ff_cbd2_dpcm_decoder;
extern const FFCodec ff_derf_dpcm_decoder;
extern const FFCodec ff_gremlin_dpcm_decoder;
extern const FFCodec ff_interplay_dpcm_decoder;
@@ -615,6 +631,7 @@ extern const FFCodec ff_roq_dpcm_decoder;
extern const FFCodec ff_sdx2_dpcm_decoder;
extern const FFCodec ff_sol_dpcm_decoder;
extern const FFCodec ff_xan_dpcm_decoder;
+extern const FFCodec ff_wady_dpcm_decoder;
/* ADPCM codecs */
extern const FFCodec ff_adpcm_4xm_decoder;
@@ -680,6 +697,7 @@ extern const FFCodec ff_adpcm_thp_decoder;
extern const FFCodec ff_adpcm_thp_le_decoder;
extern const FFCodec ff_adpcm_vima_decoder;
extern const FFCodec ff_adpcm_xa_decoder;
+extern const FFCodec ff_adpcm_xmd_decoder;
extern const FFCodec ff_adpcm_yamaha_encoder;
extern const FFCodec ff_adpcm_yamaha_decoder;
extern const FFCodec ff_adpcm_zork_decoder;
@@ -815,7 +833,11 @@ extern const FFCodec ff_libaom_av1_decoder;
/* hwaccel hooks only, so prefer external decoders */
extern const FFCodec ff_av1_decoder;
extern const FFCodec ff_av1_cuvid_decoder;
+extern const FFCodec ff_av1_mediacodec_decoder;
+extern const FFCodec ff_av1_nvenc_encoder;
extern const FFCodec ff_av1_qsv_decoder;
+extern const FFCodec ff_av1_qsv_encoder;
+extern const FFCodec ff_av1_amf_encoder;
extern const FFCodec ff_libopenh264_encoder;
extern const FFCodec ff_libopenh264_decoder;
extern const FFCodec ff_h264_amf_encoder;
@@ -830,6 +852,7 @@ extern const FFCodec ff_h264_videotoolbox_encoder;
extern const FFCodec ff_hevc_amf_encoder;
extern const FFCodec ff_hevc_cuvid_decoder;
extern const FFCodec ff_hevc_mediacodec_decoder;
+extern const FFCodec ff_hevc_mediacodec_encoder;
extern const FFCodec ff_hevc_mf_encoder;
extern const FFCodec ff_hevc_nvenc_encoder;
extern const FFCodec ff_hevc_qsv_encoder;
@@ -863,6 +886,12 @@ extern const FFCodec ff_vp9_qsv_decoder;
extern const FFCodec ff_vp9_vaapi_encoder;
extern const FFCodec ff_vp9_qsv_encoder;
+// null codecs
+extern const FFCodec ff_vnull_decoder;
+extern const FFCodec ff_vnull_encoder;
+extern const FFCodec ff_anull_decoder;
+extern const FFCodec ff_anull_encoder;
+
// The iterate API is not usable with ossfuzz due to the excessive size of binaries created
#if CONFIG_OSSFUZZ
const FFCodec * codec_list[] = {
diff --git a/libavcodec/alpha/me_cmp_alpha.c b/libavcodec/alpha/me_cmp_alpha.c
index 8f360190f..0c1a4a62c 100644
--- a/libavcodec/alpha/me_cmp_alpha.c
+++ b/libavcodec/alpha/me_cmp_alpha.c
@@ -23,7 +23,8 @@
#include "libavcodec/me_cmp.h"
#include "asm.h"
-int pix_abs16x16_mvi_asm(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
+int pix_abs16x16_mvi_asm(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t line_size, int h);
static inline uint64_t avg2(uint64_t a, uint64_t b)
{
@@ -44,7 +45,8 @@ static inline uint64_t avg4(uint64_t l1, uint64_t l2, uint64_t l3, uint64_t l4)
return r1 + r2;
}
-static int pix_abs8x8_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+static int pix_abs8x8_mvi(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t line_size, int h)
{
int result = 0;
@@ -76,50 +78,8 @@ static int pix_abs8x8_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size,
return result;
}
-#if 0 /* now done in assembly */
-int pix_abs16x16_mvi(uint8_t *pix1, uint8_t *pix2, int line_size)
-{
- int result = 0;
- int h = 16;
-
- if ((size_t) pix2 & 0x7) {
- /* works only when pix2 is actually unaligned */
- do { /* do 16 pixel a time */
- uint64_t p1_l, p1_r, p2_l, p2_r;
- uint64_t t;
-
- p1_l = ldq(pix1);
- p1_r = ldq(pix1 + 8);
- t = ldq_u(pix2 + 8);
- p2_l = extql(ldq_u(pix2), pix2) | extqh(t, pix2);
- p2_r = extql(t, pix2) | extqh(ldq_u(pix2 + 16), pix2);
- pix1 += line_size;
- pix2 += line_size;
-
- result += perr(p1_l, p2_l)
- + perr(p1_r, p2_r);
- } while (--h);
- } else {
- do {
- uint64_t p1_l, p1_r, p2_l, p2_r;
-
- p1_l = ldq(pix1);
- p1_r = ldq(pix1 + 8);
- p2_l = ldq(pix2);
- p2_r = ldq(pix2 + 8);
- pix1 += line_size;
- pix2 += line_size;
-
- result += perr(p1_l, p2_l)
- + perr(p1_r, p2_r);
- } while (--h);
- }
-
- return result;
-}
-#endif
-
-static int pix_abs16x16_x2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+static int pix_abs16x16_x2_mvi(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t line_size, int h)
{
int result = 0;
uint64_t disalign = (size_t) pix2 & 0x7;
@@ -192,7 +152,8 @@ static int pix_abs16x16_x2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_s
return result;
}
-static int pix_abs16x16_y2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+static int pix_abs16x16_y2_mvi(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t line_size, int h)
{
int result = 0;
@@ -245,7 +206,8 @@ static int pix_abs16x16_y2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_s
return result;
}
-static int pix_abs16x16_xy2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+static int pix_abs16x16_xy2_mvi(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+ ptrdiff_t line_size, int h)
{
int result = 0;
diff --git a/libavcodec/alpha/me_cmp_mvi_asm.S b/libavcodec/alpha/me_cmp_mvi_asm.S
index 2399085bc..183feeb40 100644
--- a/libavcodec/alpha/me_cmp_mvi_asm.S
+++ b/libavcodec/alpha/me_cmp_mvi_asm.S
@@ -38,7 +38,7 @@
.text
/*****************************************************************************
- * int pix_abs16x16_mvi_asm(uint8_t *pix1, uint8_t *pix2, int line_size)
+ * int pix_abs16x16_mvi_asm(const uint8_t *pix1, const uint8_t *pix2, int line_size)
*
* This code is written with a pca56 in mind. For ev6, one should
* really take the increased latency of 3 cycles for MVI instructions
diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c
index 7031fa0ac..4605b2248 100644
--- a/libavcodec/alsdec.c
+++ b/libavcodec/alsdec.c
@@ -34,6 +34,7 @@
#include "bgmc.h"
#include "bswapdsp.h"
#include "codec_internal.h"
+#include "decode.h"
#include "internal.h"
#include "mlz.h"
#include "libavutil/samplefmt.h"
@@ -1027,7 +1028,7 @@ static int read_block(ALSDecContext *ctx, ALSBlockData *bd)
*bd->shift_lsbs = 0;
- if (get_bits_left(gb) < 1)
+ if (get_bits_left(gb) < 7)
return AVERROR_INVALIDDATA;
// read block type flag and read the samples accordingly
@@ -1659,7 +1660,8 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame)
if (!sconf->mc_coding || ctx->js_switch) {
int independent_bs = !sconf->joint_stereo;
-
+ if (get_bits_left(gb) < 7*channels*ctx->num_blocks)
+ return AVERROR_INVALIDDATA;
for (c = 0; c < channels; c++) {
js_blocks[0] = 0;
js_blocks[1] = 0;
@@ -2180,7 +2182,7 @@ static av_cold void flush(AVCodecContext *avctx)
const FFCodec ff_als_decoder = {
.p.name = "als",
- .p.long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Audio Lossless Coding (ALS)"),
+ CODEC_LONG_NAME("MPEG-4 Audio Lossless Coding (ALS)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_MP4ALS,
.priv_data_size = sizeof(ALSDecContext),
@@ -2189,5 +2191,5 @@ const FFCodec ff_als_decoder = {
FF_CODEC_DECODE_CB(decode_frame),
.flush = flush,
.p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index a033e1220..c487fc48a 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -349,6 +349,9 @@ static int amf_init_encoder(AVCodecContext *avctx)
case AV_CODEC_ID_HEVC:
codec_id = AMFVideoEncoder_HEVC;
break;
+ case AV_CODEC_ID_AV1 :
+ codec_id = AMFVideoEncoder_AV1;
+ break;
default:
break;
}
@@ -460,6 +463,11 @@ static int amf_copy_buffer(AVCodecContext *avctx, AVPacket *pkt, AMFBuffer *buff
pkt->flags = AV_PKT_FLAG_KEY;
}
break;
+ case AV_CODEC_ID_AV1:
+ buffer->pVtbl->GetProperty(buffer, AMF_VIDEO_ENCODER_AV1_OUTPUT_FRAME_TYPE, &var);
+ if (var.int64Value == AMF_VIDEO_ENCODER_AV1_OUTPUT_FRAME_TYPE_KEY) {
+ pkt->flags = AV_PKT_FLAG_KEY;
+ }
default:
break;
}
@@ -681,6 +689,7 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
case AV_CODEC_ID_HEVC:
AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_INSERT_AUD, !!ctx->aud);
break;
+ //case AV_CODEC_ID_AV1 not supported
default:
break;
}
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 1ab98d2f7..66e068071 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -23,6 +23,7 @@
#include
#include
+#include
#include "libavutil/fifo.h"
@@ -116,6 +117,11 @@ typedef struct AmfContext {
int min_qp_p;
int max_qp_p;
int tier;
+
+ // AV1 - specific options
+
+ enum AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_ENUM align;
+
} AmfContext;
extern const AVCodecHWConfigInternal *const ff_amfenc_hw_configs[];
diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
new file mode 100644
index 000000000..8093cb735
--- /dev/null
+++ b/libavcodec/amfenc_av1.c
@@ -0,0 +1,361 @@
+/*
+ * 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/internal.h"
+#include "libavutil/opt.h"
+#include "amfenc.h"
+#include "codec_internal.h"
+#include "internal.h"
+
+#define OFFSET(x) offsetof(AmfContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "usage", "Set the encoding usage", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING }, AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING, AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY, VE, "usage" },
+ { "transcoding", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING }, 0, 0, VE, "usage" },
+ { "lowlatency", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY }, 0, 0, VE, "usage" },
+
+ { "profile", "Set the profile (default main)", OFFSET(profile), AV_OPT_TYPE_INT,{.i64 = AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN }, AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, VE, "profile" },
+ { "main", "", 0, AV_OPT_TYPE_CONST,{.i64 = AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN }, 0, 0, VE, "profile" },
+
+ { "level", "Set the encoding level (default auto)", OFFSET(level), AV_OPT_TYPE_INT,{.i64 = 0 }, 0, AMF_VIDEO_ENCODER_AV1_LEVEL_7_3, VE, "level" },
+ { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, VE, "level" },
+ { "2.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_2_0 }, 0, 0, VE, "level" },
+ { "2.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_2_1 }, 0, 0, VE, "level" },
+ { "2.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_2_2 }, 0, 0, VE, "level" },
+ { "2.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_2_3 }, 0, 0, VE, "level" },
+ { "3.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_3_0 }, 0, 0, VE, "level" },
+ { "3.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_3_1 }, 0, 0, VE, "level" },
+ { "3.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_3_2 }, 0, 0, VE, "level" },
+ { "3.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_3_3 }, 0, 0, VE, "level" },
+ { "4.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_4_0 }, 0, 0, VE, "level" },
+ { "4.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_4_1 }, 0, 0, VE, "level" },
+ { "4.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_4_2 }, 0, 0, VE, "level" },
+ { "4.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_4_3 }, 0, 0, VE, "level" },
+ { "5.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_5_0 }, 0, 0, VE, "level" },
+ { "5.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_5_1 }, 0, 0, VE, "level" },
+ { "5.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_5_2 }, 0, 0, VE, "level" },
+ { "5.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_5_3 }, 0, 0, VE, "level" },
+ { "6.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_6_0 }, 0, 0, VE, "level" },
+ { "6.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_6_1 }, 0, 0, VE, "level" },
+ { "6.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_6_2 }, 0, 0, VE, "level" },
+ { "6.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_6_3 }, 0, 0, VE, "level" },
+ { "7.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_7_0 }, 0, 0, VE, "level" },
+ { "7.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_7_1 }, 0, 0, VE, "level" },
+ { "7.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_7_2 }, 0, 0, VE, "level" },
+ { "7.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_7_3 }, 0, 0, VE, "level" },
+
+ { "quality", "Set the encoding quality", OFFSET(quality), AV_OPT_TYPE_INT, {.i64 = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED }, AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_HIGH_QUALITY, AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED, VE, "quality" },
+ { "balanced", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_BALANCED }, 0, 0, VE, "quality" },
+ { "speed", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED }, 0, 0, VE, "quality" },
+ { "quality", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_QUALITY }, 0, 0, VE, "quality" },
+ { "high_quality", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_HIGH_QUALITY }, 0, 0, VE, "quality" },
+
+ { "rc", "Set the rate control mode", OFFSET(rate_control_mode), AV_OPT_TYPE_INT, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_UNKNOWN }, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_UNKNOWN, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR, VE, "rc" },
+ { "cqp", "Constant Quantization Parameter", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CONSTANT_QP }, 0, 0, VE, "rc" },
+ { "vbr_latency", "Latency Constrained Variable Bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR }, 0, 0, VE, "rc" },
+ { "vbr_peak", "Peak Contrained Variable Bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR }, 0, 0, VE, "rc" },
+ { "cbr", "Constant Bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR }, 0, 0, VE, "rc" },
+
+ { "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" },
+ { "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" },
+
+ { "preanalysis", "Enable preanalysis", OFFSET(preanalysis), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, VE},
+ { "enforce_hrd", "Enforce HRD", OFFSET(enforce_hrd), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, VE},
+ { "filler_data", "Filler Data Enable", OFFSET(filler_data), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, VE},
+
+ // min_qp_i -> min_qp_intra, min_qp_p -> min_qp_inter
+ { "min_qp_i", "min quantization parameter for I-frame", OFFSET(min_qp_i), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE },
+ { "max_qp_i", "max quantization parameter for I-frame", OFFSET(max_qp_i), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE },
+ { "min_qp_p", "min quantization parameter for P-frame", OFFSET(min_qp_p), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE },
+ { "max_qp_p", "max quantization parameter for P-frame", OFFSET(max_qp_p), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE },
+ { "qp_p", "quantization parameter for P-frame", OFFSET(qp_p), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE },
+ { "qp_i", "quantization parameter for I-frame", OFFSET(qp_i), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE },
+ { "skip_frame", "Rate Control Based Frame Skip", OFFSET(skip_frame), AV_OPT_TYPE_BOOL,{.i64 = 0 }, 0, 1, VE },
+
+ { "align", "alignment mode", OFFSET(align), AV_OPT_TYPE_INT, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS }, AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_ONLY, AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS, VE, "align" },
+ { "64x16", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_ONLY }, 0, 0, VE, "align" },
+ { "1080p", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_1080P_CODED_1082 }, 0, 0, VE, "align" },
+ { "none", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS }, 0, 0, VE, "align" },
+
+ { NULL }
+
+};
+
+static av_cold int amf_encode_init_av1(AVCodecContext* avctx)
+{
+ int ret = 0;
+ AMF_RESULT res = AMF_OK;
+ AmfContext* ctx = avctx->priv_data;
+ AMFVariantStruct var = { 0 };
+ amf_int64 profile = 0;
+ amf_int64 profile_level = 0;
+ AMFBuffer* buffer;
+ AMFGuid guid;
+ AMFRate framerate;
+ AMFSize framesize = AMFConstructSize(avctx->width, avctx->height);
+
+
+
+ if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
+ framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den);
+ }
+ else {
+ framerate = AMFConstructRate(avctx->time_base.den, avctx->time_base.num * avctx->ticks_per_frame);
+ }
+
+ if ((ret = ff_amf_encode_init(avctx)) < 0)
+ return ret;
+
+ // init static parameters
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_USAGE, ctx->usage);
+
+ AMF_ASSIGN_PROPERTY_SIZE(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_FRAMESIZE, framesize);
+
+ AMF_ASSIGN_PROPERTY_RATE(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_FRAMERATE, framerate);
+
+ switch (avctx->profile) {
+ case FF_PROFILE_AV1_MAIN:
+ profile = AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN;
+ break;
+ default:
+ break;
+ }
+ if (profile == 0) {
+ profile = ctx->profile;
+ }
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_PROFILE, profile);
+
+ profile_level = avctx->level;
+ if (profile_level == FF_LEVEL_UNKNOWN) {
+ profile_level = ctx->level;
+ }
+ if (profile_level != 0) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_LEVEL, profile_level);
+ }
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET, ctx->quality);
+
+ // Maximum Reference Frames
+ if (avctx->refs != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_NUM_REFRAMES, avctx->refs);
+ }
+
+ // 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);
+
+ // Rate control
+ // autodetect rate control method
+ if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_UNKNOWN) {
+ if (ctx->min_qp_i != -1 || ctx->max_qp_i != -1 ||
+ ctx->min_qp_p != -1 || ctx->max_qp_p != -1 ||
+ ctx->qp_i != -1 || ctx->qp_p != -1) {
+ ctx->rate_control_mode = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CONSTANT_QP;
+ av_log(ctx, AV_LOG_DEBUG, "Rate control turned to CQP\n");
+ }
+ else if (avctx->rc_max_rate > 0) {
+ ctx->rate_control_mode = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
+ av_log(ctx, AV_LOG_DEBUG, "Rate control turned to Peak VBR\n");
+ }
+ else {
+ ctx->rate_control_mode = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR;
+ av_log(ctx, AV_LOG_DEBUG, "Rate control turned to CBR\n");
+ }
+ }
+
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD, ctx->rate_control_mode);
+ if (avctx->rc_buffer_size) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_VBV_BUFFER_SIZE, avctx->rc_buffer_size);
+
+ if (avctx->rc_initial_buffer_occupancy != 0) {
+ int amf_buffer_fullness = avctx->rc_initial_buffer_occupancy * 64 / avctx->rc_buffer_size;
+ if (amf_buffer_fullness > 64)
+ amf_buffer_fullness = 64;
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_INITIAL_VBV_BUFFER_FULLNESS, amf_buffer_fullness);
+ }
+ }
+
+ // Pre-Pass, Pre-Analysis, Two-Pass
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_PRE_ANALYSIS_ENABLE, ctx->preanalysis);
+
+ // init dynamic rate control params
+ if (ctx->max_au_size)
+ ctx->enforce_hrd = 1;
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_ENFORCE_HRD, ctx->enforce_hrd);
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_FILLER_DATA, ctx->filler_data);
+
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_TARGET_BITRATE, avctx->bit_rate);
+
+ if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_PEAK_BITRATE, avctx->bit_rate);
+ }
+ if (avctx->rc_max_rate) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_PEAK_BITRATE, avctx->rc_max_rate);
+ }
+ else if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR) {
+ av_log(ctx, AV_LOG_WARNING, "rate control mode is PEAK_CONSTRAINED_VBR but rc_max_rate is not set\n");
+ }
+ if (avctx->bit_rate > 0) {
+ ctx->rate_control_mode = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR;
+ av_log(ctx, AV_LOG_DEBUG, "Rate control turned to CBR\n");
+ }
+
+ switch (ctx->align)
+ {
+ case AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_ONLY:
+ if (avctx->width / 64 * 64 != avctx->width || avctx->height / 16 * 16 != avctx->height)
+ {
+ res = AMF_NOT_SUPPORTED;
+ av_log(ctx, AV_LOG_ERROR, "Resolution incorrect for alignment mode\n");
+ return AVERROR_EXIT;
+ }
+ break;
+ case AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_1080P_CODED_1082:
+ if ((avctx->width / 64 * 64 == avctx->width && avctx->height / 16 * 16 == avctx->height) || (avctx->width == 1920 && avctx->height == 1080))
+ {
+ res = AMF_OK;
+ }
+ else
+ {
+ res = AMF_NOT_SUPPORTED;
+ av_log(ctx, AV_LOG_ERROR, "Resolution incorrect for alignment mode\n");
+ return AVERROR_EXIT;
+ }
+ break;
+ case AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS:
+ res = AMF_OK;
+ break;
+ default:
+ res = AMF_NOT_SUPPORTED;
+ av_log(ctx, AV_LOG_ERROR, "Invalid alignment mode\n");
+ return AVERROR_EXIT;
+ }
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE, ctx->align);
+
+
+ // init encoder
+ res = ctx->encoder->pVtbl->Init(ctx->encoder, ctx->format, avctx->width, avctx->height);
+ AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "encoder->Init() failed with error %d\n", res);
+
+ // init dynamic picture control params
+ if (ctx->min_qp_i != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MIN_Q_INDEX_INTRA, ctx->min_qp_i);
+ }
+ else if (avctx->qmin != -1) {
+ int qval = avctx->qmin > 255 ? 255 : avctx->qmin;
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MIN_Q_INDEX_INTRA, qval);
+ }
+ if (ctx->max_qp_i != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_Q_INDEX_INTRA, ctx->max_qp_i);
+ }
+ else if (avctx->qmax != -1) {
+ int qval = avctx->qmax > 255 ? 255 : avctx->qmax;
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_Q_INDEX_INTRA, qval);
+ }
+ if (ctx->min_qp_p != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MIN_Q_INDEX_INTER, ctx->min_qp_p);
+ }
+ else if (avctx->qmin != -1) {
+ int qval = avctx->qmin > 255 ? 255 : avctx->qmin;
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MIN_Q_INDEX_INTER, qval);
+ }
+ if (ctx->max_qp_p != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_Q_INDEX_INTER, ctx->max_qp_p);
+ }
+ else if (avctx->qmax != -1) {
+ int qval = avctx->qmax > 255 ? 255 : avctx->qmax;
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_Q_INDEX_INTER, qval);
+ }
+
+ if (ctx->qp_p != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_Q_INDEX_INTER, ctx->qp_p);
+ }
+ if (ctx->qp_i != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_Q_INDEX_INTRA, ctx->qp_i);
+ }
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_SKIP_FRAME, ctx->skip_frame);
+
+
+ // fill extradata
+ res = AMFVariantInit(&var);
+ AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "AMFVariantInit() failed with error %d\n", res);
+
+ res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_AV1_EXTRA_DATA, &var);
+ AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "GetProperty(AMF_VIDEO_ENCODER_EXTRADATA) failed with error %d\n", res);
+ AMF_RETURN_IF_FALSE(ctx, var.pInterface != NULL, AVERROR_BUG, "GetProperty(AMF_VIDEO_ENCODER_EXTRADATA) returned NULL\n");
+
+ guid = IID_AMFBuffer();
+
+ res = var.pInterface->pVtbl->QueryInterface(var.pInterface, &guid, (void**)&buffer); // query for buffer interface
+ if (res != AMF_OK) {
+ var.pInterface->pVtbl->Release(var.pInterface);
+ }
+ AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "QueryInterface(IID_AMFBuffer) failed with error %d\n", res);
+
+ avctx->extradata_size = (int)buffer->pVtbl->GetSize(buffer);
+ avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!avctx->extradata) {
+ buffer->pVtbl->Release(buffer);
+ var.pInterface->pVtbl->Release(var.pInterface);
+ return AVERROR(ENOMEM);
+ }
+ memcpy(avctx->extradata, buffer->pVtbl->GetNative(buffer), avctx->extradata_size);
+
+ buffer->pVtbl->Release(buffer);
+ var.pInterface->pVtbl->Release(var.pInterface);
+
+ return 0;
+}
+
+static const FFCodecDefault defaults[] = {
+ { "refs", "-1" },
+ { "aspect", "0" },
+ { "b", "2M" },
+ { "g", "250" },
+ { "qmin", "-1" },
+ { "qmax", "-1" },
+ { NULL },
+};
+
+static const AVClass av1_amf_class = {
+ .class_name = "av1_amf",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+const FFCodec ff_av1_amf_encoder = {
+ .p.name = "av1_amf",
+ CODEC_LONG_NAME("AMD AMF AV1 encoder"),
+ .p.type = AVMEDIA_TYPE_VIDEO,
+ .p.id = AV_CODEC_ID_AV1,
+ .init = amf_encode_init_av1,
+ FF_CODEC_RECEIVE_PACKET_CB(ff_amf_receive_packet),
+ .close = ff_amf_encode_close,
+ .priv_data_size = sizeof(AmfContext),
+ .p.priv_class = &av1_amf_class,
+ .defaults = defaults,
+ .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
+ AV_CODEC_CAP_DR1,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
+ .p.pix_fmts = ff_amf_pix_fmts,
+ .p.wrapper_name = "amf",
+ .hw_configs = ff_amfenc_hw_configs,
+};
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index efb04589f..eaf7f974f 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -380,7 +380,7 @@ static const AVClass h264_amf_class = {
const FFCodec ff_h264_amf_encoder = {
.p.name = "h264_amf",
- .p.long_name = NULL_IF_CONFIG_SMALL("AMD AMF H.264 Encoder"),
+ CODEC_LONG_NAME("AMD AMF H.264 Encoder"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_H264,
.init = amf_encode_init_h264,
@@ -391,7 +391,8 @@ const FFCodec ff_h264_amf_encoder = {
.defaults = defaults,
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_INIT_CLEANUP,
.p.pix_fmts = ff_amf_pix_fmts,
.p.wrapper_name = "amf",
.hw_configs = ff_amfenc_hw_configs,
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index 8ab933073..9b46946f1 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -312,7 +312,7 @@ static const AVClass hevc_amf_class = {
const FFCodec ff_hevc_amf_encoder = {
.p.name = "hevc_amf",
- .p.long_name = NULL_IF_CONFIG_SMALL("AMD AMF HEVC encoder"),
+ CODEC_LONG_NAME("AMD AMF HEVC encoder"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_HEVC,
.init = amf_encode_init_hevc,
@@ -323,7 +323,8 @@ const FFCodec ff_hevc_amf_encoder = {
.defaults = defaults,
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_INIT_CLEANUP,
.p.pix_fmts = ff_amf_pix_fmts,
.p.wrapper_name = "amf",
.hw_configs = ff_amfenc_hw_configs,
diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c
index f67ed1d02..bfdcbba77 100644
--- a/libavcodec/amrnbdec.c
+++ b/libavcodec/amrnbdec.c
@@ -44,7 +44,6 @@
#include
#include "libavutil/channel_layout.h"
-#include "libavutil/float_dsp.h"
#include "avcodec.h"
#include "libavutil/common.h"
#include "libavutil/avassert.h"
@@ -56,7 +55,7 @@
#include "lsp.h"
#include "amr.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "amrnbdata.h"
@@ -1092,13 +1091,13 @@ static int amrnb_decode_frame(AVCodecContext *avctx, AVFrame *frame,
*got_frame_ptr = 1;
- return avpkt->size;
+ return buf - avpkt->data;
}
const FFCodec ff_amrnb_decoder = {
.p.name = "amrnb",
- .p.long_name = NULL_IF_CONFIG_SMALL("AMR-NB (Adaptive Multi-Rate NarrowBand)"),
+ CODEC_LONG_NAME("AMR-NB (Adaptive Multi-Rate NarrowBand)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AMR_NB,
.priv_data_size = sizeof(AMRChannelsContext),
@@ -1107,5 +1106,4 @@ const FFCodec ff_amrnb_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 7566f250d..9d75b972f 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -24,9 +24,10 @@
* AMR wideband decoder
*/
+#include "config.h"
+
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
-#include "libavutil/float_dsp.h"
#include "libavutil/lfg.h"
#include "avcodec.h"
@@ -37,13 +38,15 @@
#include "acelp_vectors.h"
#include "acelp_pitch_delay.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#define AMR_USE_16BIT_TABLES
#include "amr.h"
#include "amrwbdata.h"
+#if ARCH_MIPS
#include "mips/amrwbdec_mips.h"
+#endif /* ARCH_MIPS */
typedef struct AMRWBContext {
AMRWBFrame frame; ///< AMRWB parameters decoded from bitstream
@@ -1289,19 +1292,18 @@ static int amrwb_decode_frame(AVCodecContext *avctx, AVFrame *frame,
*got_frame_ptr = 1;
- return avpkt->size;
+ return buf - avpkt->data;
}
const FFCodec ff_amrwb_decoder = {
.p.name = "amrwb",
- .p.long_name = NULL_IF_CONFIG_SMALL("AMR-WB (Adaptive Multi-Rate WideBand)"),
+ CODEC_LONG_NAME("AMR-WB (Adaptive Multi-Rate WideBand)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AMR_WB,
.priv_data_size = sizeof(AMRWBChannelsContext),
.init = amrwb_decode_init,
FF_CODEC_DECODE_CB(amrwb_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
- .p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
+ .p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/anm.c b/libavcodec/anm.c
index a9006be9c..4aabe853b 100644
--- a/libavcodec/anm.c
+++ b/libavcodec/anm.c
@@ -27,7 +27,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
typedef struct AnmContext {
AVFrame *frame;
@@ -191,7 +191,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
const FFCodec ff_anm_decoder = {
.p.name = "anm",
- .p.long_name = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"),
+ CODEC_LONG_NAME("Deluxe Paint Animation"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_ANM,
.priv_data_size = sizeof(AnmContext),
@@ -199,5 +199,4 @@ const FFCodec ff_anm_decoder = {
.close = decode_end,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c
index ff4437cc6..c1e31266e 100644
--- a/libavcodec/ansi.c
+++ b/libavcodec/ansi.c
@@ -26,12 +26,11 @@
#include "libavutil/common.h"
#include "libavutil/frame.h"
-#include "libavutil/lfg.h"
#include "libavutil/xga_font_data.h"
#include "avcodec.h"
#include "cga_data.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#define ATTR_BOLD 0x01 /**< Bold/Bright-foreground (mode 1) */
#define ATTR_FAINT 0x02 /**< Faint (mode 2) */
@@ -365,7 +364,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
return ret;
- if (!avctx->frame_number) {
+ if (!avctx->frame_num) {
for (i=0; iheight; i++)
memset(s->frame->data[0]+ i*s->frame->linesize[0], 0, avctx->width);
memset(s->frame->data[1], 0, AVPALETTE_SIZE);
@@ -482,7 +481,7 @@ static const FFCodecDefault ansi_defaults[] = {
const FFCodec ff_ansi_decoder = {
.p.name = "ansi",
- .p.long_name = NULL_IF_CONFIG_SMALL("ASCII/ANSI art"),
+ CODEC_LONG_NAME("ASCII/ANSI art"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_ANSI,
.priv_data_size = sizeof(AnsiContext),
@@ -490,6 +489,5 @@ const FFCodec ff_ansi_decoder = {
.close = decode_close,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
.defaults = ansi_defaults,
};
diff --git a/libavcodec/apac.c b/libavcodec/apac.c
new file mode 100644
index 000000000..3408f7529
--- /dev/null
+++ b/libavcodec/apac.c
@@ -0,0 +1,278 @@
+/*
+ * APAC audio decoder
+ *
+ * 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/audio_fifo.h"
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "codec_internal.h"
+#include "decode.h"
+#include "get_bits.h"
+
+typedef struct ChContext {
+ int have_code;
+ int last_sample;
+ int last_delta;
+ int bit_length;
+ int block_length;
+ uint8_t block[32 * 2];
+ AVAudioFifo *samples;
+} ChContext;
+
+typedef struct APACContext {
+ GetBitContext gb;
+ int skip;
+
+ int cur_ch;
+ ChContext ch[2];
+
+ uint8_t *bitstream;
+ int64_t max_framesize;
+ int bitstream_size;
+ int bitstream_index;
+} APACContext;
+
+static av_cold int apac_close(AVCodecContext *avctx)
+{
+ APACContext *s = avctx->priv_data;
+
+ av_freep(&s->bitstream);
+ s->bitstream_size = 0;
+
+ for (int ch = 0; ch < 2; ch++) {
+ ChContext *c = &s->ch[ch];
+
+ av_audio_fifo_free(c->samples);
+ }
+
+ return 0;
+}
+
+static av_cold int apac_init(AVCodecContext *avctx)
+{
+ APACContext *s = avctx->priv_data;
+
+ if (avctx->bits_per_coded_sample > 8)
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+ else
+ avctx->sample_fmt = AV_SAMPLE_FMT_U8P;
+
+ if (avctx->ch_layout.nb_channels < 1 ||
+ avctx->ch_layout.nb_channels > 2 ||
+ avctx->bits_per_coded_sample < 8 ||
+ avctx->bits_per_coded_sample > 16
+ )
+ return AVERROR_INVALIDDATA;
+
+ for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
+ ChContext *c = &s->ch[ch];
+
+ c->bit_length = avctx->bits_per_coded_sample;
+ c->block_length = 8;
+ c->have_code = 0;
+ c->samples = av_audio_fifo_alloc(avctx->sample_fmt, 1, 1024);
+ if (!c->samples)
+ return AVERROR(ENOMEM);
+ }
+
+ s->max_framesize = 1024;
+ s->bitstream = av_realloc_f(s->bitstream, s->max_framesize + AV_INPUT_BUFFER_PADDING_SIZE, sizeof(*s->bitstream));
+ if (!s->bitstream)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static int get_code(ChContext *c, GetBitContext *gb)
+{
+ if (get_bits1(gb)) {
+ int code = get_bits(gb, 2);
+
+ switch (code) {
+ case 0:
+ c->bit_length--;
+ break;
+ case 1:
+ c->bit_length++;
+ break;
+ case 2:
+ c->bit_length = get_bits(gb, 5);
+ break;
+ case 3:
+ c->block_length = get_bits(gb, 4);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int apac_decode(AVCodecContext *avctx, AVFrame *frame,
+ int *got_frame_ptr, AVPacket *pkt)
+{
+ APACContext *s = avctx->priv_data;
+ GetBitContext *gb = &s->gb;
+ int ret, n, buf_size, input_buf_size;
+ const uint8_t *buf;
+ int nb_samples;
+
+ if (!pkt->size && s->bitstream_size <= 0) {
+ *got_frame_ptr = 0;
+ return 0;
+ }
+
+ buf_size = pkt->size;
+ input_buf_size = buf_size;
+
+ if (s->bitstream_index > 0 && s->bitstream_size > 0) {
+ memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size);
+ s->bitstream_index = 0;
+ }
+
+ if (s->bitstream_index + s->bitstream_size + buf_size > s->max_framesize) {
+ s->bitstream = av_realloc_f(s->bitstream, s->bitstream_index +
+ s->bitstream_size +
+ buf_size + AV_INPUT_BUFFER_PADDING_SIZE,
+ sizeof(*s->bitstream));
+ if (!s->bitstream)
+ return AVERROR(ENOMEM);
+ s->max_framesize = s->bitstream_index + s->bitstream_size + buf_size;
+ }
+ if (pkt->data)
+ memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], pkt->data, buf_size);
+ buf = &s->bitstream[s->bitstream_index];
+ buf_size += s->bitstream_size;
+ s->bitstream_size = buf_size;
+
+ frame->nb_samples = s->bitstream_size * 16 * 8;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+
+ if ((ret = init_get_bits8(gb, buf, buf_size)) < 0)
+ return ret;
+
+ skip_bits(gb, s->skip);
+ s->skip = 0;
+
+ while (get_bits_left(gb) > 0) {
+ for (int ch = s->cur_ch; ch < avctx->ch_layout.nb_channels; ch++) {
+ ChContext *c = &s->ch[ch];
+ int16_t *dst16 = (int16_t *)c->block;
+ uint8_t *dst8 = (uint8_t *)c->block;
+ void *samples[4];
+
+ samples[0] = &c->block[0];
+ if (get_bits_left(gb) < 16 && pkt->size) {
+ s->cur_ch = ch;
+ goto end;
+ }
+
+ if (!c->have_code && get_code(c, gb))
+ get_code(c, gb);
+ c->have_code = 0;
+
+ if (c->block_length <= 0)
+ continue;
+
+ if (c->bit_length < 0 ||
+ c->bit_length > 17) {
+ c->bit_length = avctx->bits_per_coded_sample;
+ s->bitstream_index = 0;
+ s->bitstream_size = 0;
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (get_bits_left(gb) < c->block_length * c->bit_length) {
+ if (pkt->size) {
+ c->have_code = 1;
+ s->cur_ch = ch;
+ goto end;
+ } else {
+ break;
+ }
+ }
+
+ for (int i = 0; i < c->block_length; i++) {
+ int val = get_bits_long(gb, c->bit_length);
+ unsigned delta = (val & 1) ? ~(val >> 1) : (val >> 1);
+ int sample;
+
+ delta += c->last_delta;
+ sample = c->last_sample + delta;
+ c->last_delta = delta;
+ c->last_sample = sample;
+
+ switch (avctx->sample_fmt) {
+ case AV_SAMPLE_FMT_S16P:
+ dst16[i] = sample;
+ break;
+ case AV_SAMPLE_FMT_U8P:
+ dst8[i] = sample;
+ break;
+ }
+ }
+
+ av_audio_fifo_write(c->samples, samples, c->block_length);
+ }
+
+ s->cur_ch = 0;
+ }
+end:
+ nb_samples = frame->nb_samples;
+ for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++)
+ nb_samples = FFMIN(av_audio_fifo_size(s->ch[ch].samples), nb_samples);
+
+ frame->nb_samples = nb_samples;
+ for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
+ void *samples[1] = { frame->extended_data[ch] };
+ av_audio_fifo_read(s->ch[ch].samples, samples, nb_samples);
+ }
+
+ s->skip = get_bits_count(gb) - 8 * (get_bits_count(gb) / 8);
+ n = get_bits_count(gb) / 8;
+
+ if (nb_samples > 0 || pkt->size)
+ *got_frame_ptr = 1;
+
+ if (s->bitstream_size > 0) {
+ s->bitstream_index += n;
+ s->bitstream_size -= n;
+ return input_buf_size;
+ }
+ return n;
+}
+
+const FFCodec ff_apac_decoder = {
+ .p.name = "apac",
+ CODEC_LONG_NAME("Marian's A-pac audio"),
+ .p.type = AVMEDIA_TYPE_AUDIO,
+ .p.id = AV_CODEC_ID_APAC,
+ .priv_data_size = sizeof(APACContext),
+ .init = apac_init,
+ FF_CODEC_DECODE_CB(apac_decode),
+ .close = apac_close,
+ .p.capabilities = AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_DR1 |
+ AV_CODEC_CAP_SUBFRAMES,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
+ .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
+ AV_SAMPLE_FMT_S16P,
+ AV_SAMPLE_FMT_NONE },
+};
diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index 24877c559..c08d13d6c 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -31,7 +31,7 @@
#include "bswapdsp.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "get_bits.h"
#include "unary.h"
@@ -1577,7 +1577,6 @@ static int ape_decode_frame(AVCodecContext *avctx, AVFrame *frame,
ape_unpack_mono(s, blockstodecode);
else
ape_unpack_stereo(s, blockstodecode);
- emms_c();
if (s->error) {
s->samples=0;
@@ -1660,7 +1659,7 @@ static const AVClass ape_decoder_class = {
const FFCodec ff_ape_decoder = {
.p.name = "ape",
- .p.long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"),
+ CODEC_LONG_NAME("Monkey's Audio"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_APE,
.priv_data_size = sizeof(APEContext),
@@ -1669,7 +1668,7 @@ const FFCodec ff_ape_decoder = {
FF_CODEC_DECODE_CB(ape_decode_frame),
.p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.flush = ape_flush,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
AV_SAMPLE_FMT_S16P,
diff --git a/libavcodec/aptx.c b/libavcodec/aptx.c
index f2604be60..ed814ad1c 100644
--- a/libavcodec/aptx.c
+++ b/libavcodec/aptx.c
@@ -516,15 +516,6 @@ av_cold int ff_aptx_init(AVCodecContext *avctx)
s->hd = avctx->codec->id == AV_CODEC_ID_APTX_HD;
s->block_size = s->hd ? 6 : 4;
- if (avctx->frame_size == 0)
- avctx->frame_size = 256 * s->block_size;
-
- if (avctx->frame_size % s->block_size) {
- av_log(avctx, AV_LOG_ERROR,
- "Frame size must be a multiple of %d samples\n", s->block_size);
- return AVERROR(EINVAL);
- }
-
for (chan = 0; chan < NB_CHANNELS; chan++) {
Channel *channel = &s->channels[chan];
for (subband = 0; subband < NB_SUBBANDS; subband++) {
@@ -534,6 +525,5 @@ av_cold int ff_aptx_init(AVCodecContext *avctx)
}
}
- ff_af_queue_init(avctx, &s->afq);
return 0;
}
diff --git a/libavcodec/aptx.h b/libavcodec/aptx.h
index abb49e6fa..da0697e65 100644
--- a/libavcodec/aptx.h
+++ b/libavcodec/aptx.h
@@ -26,7 +26,6 @@
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "mathops.h"
-#include "audio_frame_queue.h"
enum channels {
@@ -95,7 +94,6 @@ typedef struct {
int block_size;
int32_t sync_idx;
Channel channels[NB_CHANNELS];
- AudioFrameQueue afq;
} AptXContext;
typedef const struct {
diff --git a/libavcodec/aptxdec.c b/libavcodec/aptxdec.c
index 6ac070ba9..3ae7a0080 100644
--- a/libavcodec/aptxdec.c
+++ b/libavcodec/aptxdec.c
@@ -25,7 +25,7 @@
#include "libavutil/channel_layout.h"
#include "aptx.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
/*
* Half-band QMF synthesis filter realized with a polyphase FIR filter.
@@ -151,7 +151,7 @@ static int aptx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
/* get output buffer */
frame->ch_layout.nb_channels = NB_CHANNELS;
frame->format = AV_SAMPLE_FMT_S32P;
- frame->nb_samples = 4 * avpkt->size / s->block_size;
+ frame->nb_samples = 4 * (avpkt->size / s->block_size);
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret;
@@ -176,17 +176,14 @@ static int aptx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
#if CONFIG_APTX_DECODER
const FFCodec ff_aptx_decoder = {
.p.name = "aptx",
- .p.long_name = NULL_IF_CONFIG_SMALL("aptX (Audio Processing Technology for Bluetooth)"),
+ CODEC_LONG_NAME("aptX (Audio Processing Technology for Bluetooth)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_APTX,
.priv_data_size = sizeof(AptXContext),
.init = ff_aptx_init,
FF_CODEC_DECODE_CB(aptx_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_STEREO, 0},
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS(AV_CH_LAYOUT_STEREO)
.p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_STEREO, { 0 } },
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
AV_SAMPLE_FMT_NONE },
@@ -196,17 +193,14 @@ const FFCodec ff_aptx_decoder = {
#if CONFIG_APTX_HD_DECODER
const FFCodec ff_aptx_hd_decoder = {
.p.name = "aptx_hd",
- .p.long_name = NULL_IF_CONFIG_SMALL("aptX HD (Audio Processing Technology for Bluetooth)"),
+ CODEC_LONG_NAME("aptX HD (Audio Processing Technology for Bluetooth)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_APTX_HD,
.priv_data_size = sizeof(AptXContext),
.init = ff_aptx_init,
FF_CODEC_DECODE_CB(aptx_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_STEREO, 0},
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS(AV_CH_LAYOUT_STEREO)
.p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_STEREO, { 0 } },
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/aptxenc.c b/libavcodec/aptxenc.c
index 89ab3974c..6deebaf2c 100644
--- a/libavcodec/aptxenc.c
+++ b/libavcodec/aptxenc.c
@@ -24,8 +24,15 @@
#include "libavutil/channel_layout.h"
#include "aptx.h"
+#include "audio_frame_queue.h"
#include "codec_internal.h"
#include "encode.h"
+#include "internal.h"
+
+typedef struct AptXEncContext {
+ AptXContext common;
+ AudioFrameQueue afq;
+} AptXEncContext;
/*
* Half-band QMF analysis filter realized with a polyphase FIR filter.
@@ -212,10 +219,11 @@ static void aptx_encode_samples(AptXContext *ctx,
static int aptx_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
const AVFrame *frame, int *got_packet_ptr)
{
- AptXContext *s = avctx->priv_data;
+ AptXEncContext *const s0 = avctx->priv_data;
+ AptXContext *const s = &s0->common;
int pos, ipos, channel, sample, output_size, ret;
- if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
+ if ((ret = ff_af_queue_add(&s0->afq, frame)) < 0)
return ret;
output_size = s->block_size * frame->nb_samples/4;
@@ -232,33 +240,43 @@ static int aptx_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
aptx_encode_samples(s, samples, avpkt->data + pos);
}
- ff_af_queue_remove(&s->afq, frame->nb_samples, &avpkt->pts, &avpkt->duration);
+ ff_af_queue_remove(&s0->afq, frame->nb_samples, &avpkt->pts, &avpkt->duration);
*got_packet_ptr = 1;
return 0;
}
static av_cold int aptx_close(AVCodecContext *avctx)
{
- AptXContext *s = avctx->priv_data;
+ AptXEncContext *const s = avctx->priv_data;
ff_af_queue_close(&s->afq);
return 0;
}
+static av_cold int aptx_encode_init(AVCodecContext *avctx)
+{
+ AptXEncContext *const s = avctx->priv_data;
+
+ ff_af_queue_init(avctx, &s->afq);
+
+ if (!avctx->frame_size || avctx->frame_size % 4)
+ avctx->frame_size = 1024;
+ avctx->internal->pad_samples = 4;
+
+ return ff_aptx_init(avctx);
+}
+
#if CONFIG_APTX_ENCODER
const FFCodec ff_aptx_encoder = {
.p.name = "aptx",
- .p.long_name = NULL_IF_CONFIG_SMALL("aptX (Audio Processing Technology for Bluetooth)"),
+ CODEC_LONG_NAME("aptX (Audio Processing Technology for Bluetooth)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_APTX,
- .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
- .priv_data_size = sizeof(AptXContext),
- .init = ff_aptx_init,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ .priv_data_size = sizeof(AptXEncContext),
+ .init = aptx_encode_init,
FF_CODEC_ENCODE_CB(aptx_encode_frame),
.close = aptx_close,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_STEREO, 0},
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS(AV_CH_LAYOUT_STEREO)
.p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_STEREO, { 0 } },
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
AV_SAMPLE_FMT_NONE },
@@ -269,18 +287,15 @@ const FFCodec ff_aptx_encoder = {
#if CONFIG_APTX_HD_ENCODER
const FFCodec ff_aptx_hd_encoder = {
.p.name = "aptx_hd",
- .p.long_name = NULL_IF_CONFIG_SMALL("aptX HD (Audio Processing Technology for Bluetooth)"),
+ CODEC_LONG_NAME("aptX HD (Audio Processing Technology for Bluetooth)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_APTX_HD,
- .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
- .priv_data_size = sizeof(AptXContext),
- .init = ff_aptx_init,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ .priv_data_size = sizeof(AptXEncContext),
+ .init = aptx_encode_init,
FF_CODEC_ENCODE_CB(aptx_encode_frame),
.close = aptx_close,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_STEREO, 0},
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS(AV_CH_LAYOUT_STEREO)
.p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_STEREO, { 0 } },
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/arbc.c b/libavcodec/arbc.c
index 78600963e..343c56695 100644
--- a/libavcodec/arbc.c
+++ b/libavcodec/arbc.c
@@ -19,18 +19,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include
-#include
-#include
-
-#include "libavutil/imgutils.h"
#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
typedef struct ARBCContext {
GetByteContext gb;
@@ -213,7 +208,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
const FFCodec ff_arbc_decoder = {
.p.name = "arbc",
- .p.long_name = NULL_IF_CONFIG_SMALL("Gryphon's Anim Compressor"),
+ CODEC_LONG_NAME("Gryphon's Anim Compressor"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_ARBC,
.priv_data_size = sizeof(ARBCContext),
@@ -222,5 +217,5 @@ const FFCodec ff_arbc_decoder = {
.flush = decode_flush,
.close = decode_close,
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/argo.c b/libavcodec/argo.c
index efd1056f1..9bedb1394 100644
--- a/libavcodec/argo.c
+++ b/libavcodec/argo.c
@@ -19,18 +19,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include
-#include
#include
-#include "libavutil/imgutils.h"
#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
typedef struct ArgoContext {
GetByteContext gb;
@@ -735,7 +732,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
const FFCodec ff_argo_decoder = {
.p.name = "argo",
- .p.long_name = NULL_IF_CONFIG_SMALL("Argonaut Games Video"),
+ CODEC_LONG_NAME("Argonaut Games Video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_ARGO,
.priv_data_size = sizeof(ArgoContext),
@@ -744,5 +741,5 @@ const FFCodec ff_argo_decoder = {
.flush = decode_flush,
.close = decode_close,
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile
index c4ab93aee..5d284bdc0 100644
--- a/libavcodec/arm/Makefile
+++ b/libavcodec/arm/Makefile
@@ -6,8 +6,6 @@ OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_init_arm.o \
OBJS-$(CONFIG_AUDIODSP) += arm/audiodsp_init_arm.o
OBJS-$(CONFIG_BLOCKDSP) += arm/blockdsp_init_arm.o
OBJS-$(CONFIG_FFT) += arm/fft_init_arm.o
-OBJS-$(CONFIG_FLACDSP) += arm/flacdsp_init_arm.o \
- arm/flacdsp_arm.o
OBJS-$(CONFIG_FMTCONVERT) += arm/fmtconvert_init_arm.o
OBJS-$(CONFIG_G722DSP) += arm/g722dsp_init_arm.o
OBJS-$(CONFIG_H264CHROMA) += arm/h264chroma_init_arm.o
@@ -38,6 +36,8 @@ OBJS-$(CONFIG_VP8DSP) += arm/vp8dsp_init_arm.o
OBJS-$(CONFIG_AAC_DECODER) += arm/aacpsdsp_init_arm.o \
arm/sbrdsp_init_arm.o
OBJS-$(CONFIG_DCA_DECODER) += arm/synth_filter_init_arm.o
+OBJS-$(CONFIG_FLAC_DECODER) += arm/flacdsp_init_arm.o \
+ arm/flacdsp_arm.o
OBJS-$(CONFIG_HEVC_DECODER) += arm/hevcdsp_init_arm.o
OBJS-$(CONFIG_MLP_DECODER) += arm/mlpdsp_init_arm.o
OBJS-$(CONFIG_RV40_DECODER) += arm/rv40dsp_init_arm.o
diff --git a/libavcodec/arm/ac3dsp_init_arm.c b/libavcodec/arm/ac3dsp_init_arm.c
index 9217a7d0c..a64aa6ae8 100644
--- a/libavcodec/arm/ac3dsp_init_arm.c
+++ b/libavcodec/arm/ac3dsp_init_arm.c
@@ -44,7 +44,7 @@ void ff_ac3_bit_alloc_calc_bap_armv6(int16_t *mask, int16_t *psd,
void ff_ac3_update_bap_counts_arm(uint16_t mant_cnt[16], uint8_t *bap, int len);
-av_cold void ff_ac3dsp_init_arm(AC3DSPContext *c, int bit_exact)
+av_cold void ff_ac3dsp_init_arm(AC3DSPContext *c)
{
int cpu_flags = av_get_cpu_flags();
diff --git a/libavcodec/arm/fft_fixed_neon.S b/libavcodec/arm/fft_fixed_neon.S
deleted file mode 100644
index 265160754..000000000
--- a/libavcodec/arm/fft_fixed_neon.S
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (c) 2011 Mans Rullgard
- *
- * 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/arm/asm.S"
-
-.macro bflies d0, d1, r0, r1
- vrev64.32 \r0, \d1 @ t5, t6, t1, t2
- vhsub.s16 \r1, \d1, \r0 @ t1-t5, t2-t6, t5-t1, t6-t2
- vhadd.s16 \r0, \d1, \r0 @ t1+t5, t2+t6, t5+t1, t6+t2
- vext.16 \r1, \r1, \r1, #1 @ t2-t6, t5-t1, t6-t2, t1-t5
- vtrn.32 \r0, \r1 @ t1+t5, t2+t6, t2-t6, t5-t1
- @ t5, t6, t4, t3
- vhsub.s16 \d1, \d0, \r0
- vhadd.s16 \d0, \d0, \r0
-.endm
-
-.macro transform01 q0, q1, d3, c0, c1, r0, w0, w1
- vrev32.16 \r0, \d3
- vmull.s16 \w0, \d3, \c0
- vmlal.s16 \w0, \r0, \c1
- vshrn.s32 \d3, \w0, #15
- bflies \q0, \q1, \w0, \w1
-.endm
-
-.macro transform2 d0, d1, d2, d3, q0, q1, c0, c1, c2, c3, \
- r0, r1, w0, w1
- vrev32.16 \r0, \d1
- vrev32.16 \r1, \d3
- vmull.s16 \w0, \d1, \c0
- vmlal.s16 \w0, \r0, \c1
- vmull.s16 \w1, \d3, \c2
- vmlal.s16 \w1, \r1, \c3
- vshrn.s32 \d1, \w0, #15
- vshrn.s32 \d3, \w1, #15
- bflies \q0, \q1, \w0, \w1
-.endm
-
-.macro fft4 d0, d1, r0, r1
- vhsub.s16 \r0, \d0, \d1 @ t3, t4, t8, t7
- vhsub.s16 \r1, \d1, \d0
- vhadd.s16 \d0, \d0, \d1 @ t1, t2, t6, t5
- vmov.i64 \d1, #0xffff00000000
- vbit \r0, \r1, \d1
- vrev64.16 \r1, \r0 @ t7, t8, t4, t3
- vtrn.32 \r0, \r1 @ t3, t4, t7, t8
- vtrn.32 \d0, \r0 @ t1, t2, t3, t4, t6, t5, t8, t7
- vhsub.s16 \d1, \d0, \r0 @ r2, i2, r3, i1
- vhadd.s16 \d0, \d0, \r0 @ r0, i0, r1, i3
-.endm
-
-.macro fft8 d0, d1, d2, d3, q0, q1, c0, c1, r0, r1, w0, w1
- fft4 \d0, \d1, \r0, \r1
- vtrn.32 \d0, \d1 @ z0, z2, z1, z3
- vhadd.s16 \r0, \d2, \d3 @ t1, t2, t3, t4
- vhsub.s16 \d3, \d2, \d3 @ z5, z7
- vmov \d2, \r0
- transform01 \q0, \q1, \d3, \c0, \c1, \r0, \w0, \w1
-.endm
-
-function fft4_neon
- vld1.16 {d0-d1}, [r0]
- fft4 d0, d1, d2, d3
- vst1.16 {d0-d1}, [r0]
- bx lr
-endfunc
-
-function fft8_neon
- vld1.16 {d0-d3}, [r0,:128]
- movrel r1, coefs
- vld1.16 {d30}, [r1,:64]
- vdup.16 d31, d30[0]
- fft8 d0, d1, d2, d3, q0, q1, d31, d30, d20, d21, q8, q9
- vtrn.32 d0, d1
- vtrn.32 d2, d3
- vst1.16 {d0-d3}, [r0,:128]
- bx lr
-endfunc
-
-function fft16_neon
- vld1.16 {d0-d3}, [r0,:128]!
- vld1.16 {d4-d7}, [r0,:128]
- movrel r1, coefs
- sub r0, r0, #32
- vld1.16 {d28-d31},[r1,:128]
- vdup.16 d31, d28[0]
- fft8 d0, d1, d2, d3, q0, q1, d31, d28, d20, d21, q8, q9
- vswp d5, d6
- fft4 q2, q3, q8, q9
- vswp d5, d6
- vtrn.32 q0, q1 @ z0, z4, z2, z6, z1, z5, z3, z7
- vtrn.32 q2, q3 @ z8, z12,z10,z14,z9, z13,z11,z15
- vswp d1, d2
- vdup.16 d31, d28[0]
- transform01 q0, q2, d5, d31, d28, d20, q8, q9
- vdup.16 d26, d29[0]
- vdup.16 d27, d30[0]
- transform2 d2, d6, d3, d7, q1, q3, d26, d30, d27, d29, \
- d20, d21, q8, q9
- vtrn.32 q0, q1
- vtrn.32 q2, q3
- vst1.16 {d0-d3}, [r0,:128]!
- vst1.16 {d4-d7}, [r0,:128]
- bx lr
-endfunc
-
-function fft_pass_neon
- push {r4,lr}
- movrel lr, coefs + 24
- vld1.16 {d30}, [lr,:64]
- lsl r12, r2, #3
- vmov d31, d30
- add r3, r1, r2, lsl #2
- mov lr, #-8
- sub r3, r3, #2
- mov r4, r0
- vld1.16 {d27[]}, [r3,:16]
- sub r3, r3, #6
- vld1.16 {q0}, [r4,:128], r12
- vld1.16 {q1}, [r4,:128], r12
- vld1.16 {q2}, [r4,:128], r12
- vld1.16 {q3}, [r4,:128], r12
- vld1.16 {d28}, [r1,:64]!
- vld1.16 {d29}, [r3,:64], lr
- vswp d1, d2
- vswp d5, d6
- vtrn.32 d0, d1
- vtrn.32 d4, d5
- vdup.16 d25, d28[1]
- vmul.s16 d27, d27, d31
- transform01 q0, q2, d5, d25, d27, d20, q8, q9
- b 2f
-1:
- mov r4, r0
- vdup.16 d26, d29[0]
- vld1.16 {q0}, [r4,:128], r12
- vld1.16 {q1}, [r4,:128], r12
- vld1.16 {q2}, [r4,:128], r12
- vld1.16 {q3}, [r4,:128], r12
- vld1.16 {d28}, [r1,:64]!
- vld1.16 {d29}, [r3,:64], lr
- vswp d1, d2
- vswp d5, d6
- vtrn.32 d0, d1
- vtrn.32 d4, d5
- vdup.16 d24, d28[0]
- vdup.16 d25, d28[1]
- vdup.16 d27, d29[3]
- vmul.s16 q13, q13, q15
- transform2 d0, d4, d1, d5, q0, q2, d24, d26, d25, d27, \
- d16, d17, q9, q10
-2:
- vtrn.32 d2, d3
- vtrn.32 d6, d7
- vdup.16 d24, d28[2]
- vdup.16 d26, d29[2]
- vdup.16 d25, d28[3]
- vdup.16 d27, d29[1]
- vmul.s16 q13, q13, q15
- transform2 d2, d6, d3, d7, q1, q3, d24, d26, d25, d27, \
- d16, d17, q9, q10
- vtrn.32 d0, d1
- vtrn.32 d2, d3
- vtrn.32 d4, d5
- vtrn.32 d6, d7
- vswp d1, d2
- vswp d5, d6
- mov r4, r0
- vst1.16 {q0}, [r4,:128], r12
- vst1.16 {q1}, [r4,:128], r12
- vst1.16 {q2}, [r4,:128], r12
- vst1.16 {q3}, [r4,:128], r12
- add r0, r0, #16
- subs r2, r2, #2
- bgt 1b
- pop {r4,pc}
-endfunc
-
-#define F_SQRT1_2 23170
-#define F_COS_16_1 30274
-#define F_COS_16_3 12540
-
-const coefs, align=4
- .short F_SQRT1_2, -F_SQRT1_2, -F_SQRT1_2, F_SQRT1_2
- .short F_COS_16_1,-F_COS_16_1,-F_COS_16_1, F_COS_16_1
- .short F_COS_16_3,-F_COS_16_3,-F_COS_16_3, F_COS_16_3
- .short 1, -1, -1, 1
-endconst
-
-.macro def_fft n, n2, n4
-function fft\n\()_neon
- push {r4, lr}
- mov r4, r0
- bl fft\n2\()_neon
- add r0, r4, #\n4*2*4
- bl fft\n4\()_neon
- add r0, r4, #\n4*3*4
- bl fft\n4\()_neon
- mov r0, r4
- pop {r4, lr}
- movrelx r1, X(ff_cos_\n\()_fixed)
- mov r2, #\n4/2
- b fft_pass_neon
-endfunc
-.endm
-
- def_fft 32, 16, 8
- def_fft 64, 32, 16
- def_fft 128, 64, 32
- def_fft 256, 128, 64
- def_fft 512, 256, 128
- def_fft 1024, 512, 256
- def_fft 2048, 1024, 512
- def_fft 4096, 2048, 1024
- def_fft 8192, 4096, 2048
- def_fft 16384, 8192, 4096
- def_fft 32768, 16384, 8192
- def_fft 65536, 32768, 16384
-
-function ff_fft_fixed_calc_neon, export=1
- ldr r2, [r0]
- sub r2, r2, #2
- movrel r3, fft_fixed_tab_neon
- ldr r3, [r3, r2, lsl #2]
- mov r0, r1
- bx r3
-endfunc
-
-const fft_fixed_tab_neon, relocate=1
- .word fft4_neon
- .word fft8_neon
- .word fft16_neon
- .word fft32_neon
- .word fft64_neon
- .word fft128_neon
- .word fft256_neon
- .word fft512_neon
- .word fft1024_neon
- .word fft2048_neon
- .word fft4096_neon
- .word fft8192_neon
- .word fft16384_neon
- .word fft32768_neon
- .word fft65536_neon
-endconst
diff --git a/libavcodec/arm/fft_init_arm.c b/libavcodec/arm/fft_init_arm.c
index 331bd65e5..8ae22dfb4 100644
--- a/libavcodec/arm/fft_init_arm.c
+++ b/libavcodec/arm/fft_init_arm.c
@@ -48,8 +48,10 @@ av_cold void ff_fft_init_arm(FFTContext *s)
if (have_neon(cpu_flags)) {
#if CONFIG_FFT
- s->fft_permute = ff_fft_permute_neon;
- s->fft_calc = ff_fft_calc_neon;
+ if (s->nbits < 17) {
+ s->fft_permute = ff_fft_permute_neon;
+ s->fft_calc = ff_fft_calc_neon;
+ }
#endif
#if CONFIG_MDCT
s->imdct_calc = ff_imdct_calc_neon;
diff --git a/libavcodec/arm/flacdsp_init_arm.c b/libavcodec/arm/flacdsp_init_arm.c
index bac9ff195..9962cc89f 100644
--- a/libavcodec/arm/flacdsp_init_arm.c
+++ b/libavcodec/arm/flacdsp_init_arm.c
@@ -20,15 +20,11 @@
#include "libavutil/attributes.h"
#include "libavcodec/flacdsp.h"
-#include "config.h"
-#include "config_components.h"
void ff_flac_lpc_16_arm(int32_t *samples, const int coeffs[32], int order,
int qlevel, int len);
-av_cold void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt, int channels,
- int bps)
+av_cold void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt, int channels)
{
- if (CONFIG_FLAC_DECODER)
- c->lpc16 = ff_flac_lpc_16_arm;
+ c->lpc16 = ff_flac_lpc_16_arm;
}
diff --git a/libavcodec/arm/fmtconvert_init_arm.c b/libavcodec/arm/fmtconvert_init_arm.c
index e88255d61..e12f83c84 100644
--- a/libavcodec/arm/fmtconvert_init_arm.c
+++ b/libavcodec/arm/fmtconvert_init_arm.c
@@ -22,7 +22,6 @@
#include "libavutil/attributes.h"
#include "libavutil/arm/cpu.h"
-#include "libavcodec/avcodec.h"
#include "libavcodec/fmtconvert.h"
void ff_int32_to_float_fmul_array8_neon(FmtConvertContext *c, float *dst,
@@ -37,7 +36,7 @@ void ff_int32_to_float_fmul_array8_vfp(FmtConvertContext *c, float *dst,
const int32_t *src, const float *mul,
int len);
-av_cold void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx)
+av_cold void ff_fmt_convert_init_arm(FmtConvertContext *c)
{
int cpu_flags = av_get_cpu_flags();
diff --git a/libavcodec/arm/h264chroma_init_arm.c b/libavcodec/arm/h264chroma_init_arm.c
index aae804b62..5c7d52318 100644
--- a/libavcodec/arm/h264chroma_init_arm.c
+++ b/libavcodec/arm/h264chroma_init_arm.c
@@ -26,18 +26,18 @@
#include "libavutil/arm/cpu.h"
#include "libavcodec/h264chroma.h"
-void ff_put_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_h264_chroma_mc8_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_put_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_h264_chroma_mc4_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_put_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_h264_chroma_mc2_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_avg_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_avg_h264_chroma_mc8_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_avg_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_avg_h264_chroma_mc4_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_avg_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_avg_h264_chroma_mc2_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
av_cold void ff_h264chroma_init_arm(H264ChromaContext *c, int bit_depth)
diff --git a/libavcodec/arm/h264cmc_neon.S b/libavcodec/arm/h264cmc_neon.S
index 3687b02ed..7272b571d 100644
--- a/libavcodec/arm/h264cmc_neon.S
+++ b/libavcodec/arm/h264cmc_neon.S
@@ -22,7 +22,7 @@
#include "libavutil/arm/asm.S"
-/* chroma_mc8(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y) */
+/* chroma_mc8(uint8_t *dst, const uint8_t *src, ptrdiff_t stride, int h, int x, int y) */
.macro h264_chroma_mc8 type, codec=h264
function ff_\type\()_\codec\()_chroma_mc8_neon, export=1
push {r4-r7, lr}
@@ -197,7 +197,7 @@ T cmp r7, #0
endfunc
.endm
-/* chroma_mc4(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y) */
+/* chroma_mc4(uint8_t *dst, const uint8_t *src, ptrdiff_t stride, int h, int x, int y) */
.macro h264_chroma_mc4 type, codec=h264
function ff_\type\()_\codec\()_chroma_mc4_neon, export=1
push {r4-r7, lr}
diff --git a/libavcodec/arm/hevcdsp_init_neon.c b/libavcodec/arm/hevcdsp_init_neon.c
index 112edb5ed..8094e6c62 100644
--- a/libavcodec/arm/hevcdsp_init_neon.c
+++ b/libavcodec/arm/hevcdsp_init_neon.c
@@ -24,32 +24,32 @@
#include "libavcodec/avcodec.h"
#include "hevcdsp_arm.h"
-void ff_hevc_sao_band_filter_neon_8_wrapper(uint8_t *_dst, uint8_t *_src,
+void ff_hevc_sao_band_filter_neon_8_wrapper(uint8_t *_dst, const uint8_t *_src,
ptrdiff_t stride_dst, ptrdiff_t stride_src,
- int16_t *sao_offset_val, int sao_left_class,
+ const int16_t *sao_offset_val, int sao_left_class,
int width, int height);
-void ff_hevc_sao_edge_filter_neon_8_wrapper(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val,
+void ff_hevc_sao_edge_filter_neon_8_wrapper(uint8_t *_dst, const uint8_t *_src, ptrdiff_t stride_dst, const int16_t *sao_offset_val,
int eo, int width, int height);
-void ff_hevc_v_loop_filter_luma_neon(uint8_t *_pix, ptrdiff_t _stride, int _beta, int *_tc, uint8_t *_no_p, uint8_t *_no_q);
-void ff_hevc_h_loop_filter_luma_neon(uint8_t *_pix, ptrdiff_t _stride, int _beta, int *_tc, uint8_t *_no_p, uint8_t *_no_q);
-void ff_hevc_v_loop_filter_chroma_neon(uint8_t *_pix, ptrdiff_t _stride, int *_tc, uint8_t *_no_p, uint8_t *_no_q);
-void ff_hevc_h_loop_filter_chroma_neon(uint8_t *_pix, ptrdiff_t _stride, int *_tc, uint8_t *_no_p, uint8_t *_no_q);
-void ff_hevc_add_residual_4x4_8_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_v_loop_filter_luma_neon(uint8_t *_pix, ptrdiff_t _stride, int _beta, const int *_tc, const uint8_t *_no_p, const uint8_t *_no_q);
+void ff_hevc_h_loop_filter_luma_neon(uint8_t *_pix, ptrdiff_t _stride, int _beta, const int *_tc, const uint8_t *_no_p, const uint8_t *_no_q);
+void ff_hevc_v_loop_filter_chroma_neon(uint8_t *_pix, ptrdiff_t _stride, const int *_tc, const uint8_t *_no_p, const uint8_t *_no_q);
+void ff_hevc_h_loop_filter_chroma_neon(uint8_t *_pix, ptrdiff_t _stride, const int *_tc, const uint8_t *_no_p, const uint8_t *_no_q);
+void ff_hevc_add_residual_4x4_8_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
-void ff_hevc_add_residual_4x4_10_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_4x4_10_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
-void ff_hevc_add_residual_8x8_8_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_8x8_8_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
-void ff_hevc_add_residual_8x8_10_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_8x8_10_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
-void ff_hevc_add_residual_16x16_8_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_16x16_8_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
-void ff_hevc_add_residual_16x16_10_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_16x16_10_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
-void ff_hevc_add_residual_32x32_8_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_32x32_8_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
-void ff_hevc_add_residual_32x32_10_neon(uint8_t *_dst, int16_t *coeffs,
+void ff_hevc_add_residual_32x32_10_neon(uint8_t *_dst, const int16_t *coeffs,
ptrdiff_t stride);
void ff_hevc_idct_4x4_dc_8_neon(int16_t *coeffs);
void ff_hevc_idct_8x8_dc_8_neon(int16_t *coeffs);
@@ -70,7 +70,7 @@ void ff_hevc_idct_32x32_10_neon(int16_t *coeffs, int col_limit);
void ff_hevc_transform_luma_4x4_neon_8(int16_t *coeffs);
#define PUT_PIXELS(name) \
- void name(int16_t *dst, uint8_t *src, \
+ void name(int16_t *dst, const uint8_t *src, \
ptrdiff_t srcstride, int height, \
intptr_t mx, intptr_t my, int width)
PUT_PIXELS(ff_hevc_put_pixels_w2_neon_8);
@@ -85,19 +85,19 @@ PUT_PIXELS(ff_hevc_put_pixels_w48_neon_8);
PUT_PIXELS(ff_hevc_put_pixels_w64_neon_8);
#undef PUT_PIXELS
-static void (*put_hevc_qpel_neon[4][4])(int16_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
+static void (*put_hevc_qpel_neon[4][4])(int16_t *dst, ptrdiff_t dststride, const uint8_t *src, ptrdiff_t srcstride,
int height, int width);
-static void (*put_hevc_qpel_uw_neon[4][4])(uint8_t *dst, ptrdiff_t dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int width, int height, int16_t* src2, ptrdiff_t src2stride);
-void ff_hevc_put_qpel_neon_wrapper(int16_t *dst, uint8_t *src, ptrdiff_t srcstride,
+static void (*put_hevc_qpel_uw_neon[4][4])(uint8_t *dst, ptrdiff_t dststride, const uint8_t *_src, ptrdiff_t _srcstride,
+ int width, int height, const int16_t *src2, ptrdiff_t src2stride);
+void ff_hevc_put_qpel_neon_wrapper(int16_t *dst, const uint8_t *src, ptrdiff_t srcstride,
int height, intptr_t mx, intptr_t my, int width);
-void ff_hevc_put_qpel_uni_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
+void ff_hevc_put_qpel_uni_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, const uint8_t *src, ptrdiff_t srcstride,
int height, intptr_t mx, intptr_t my, int width);
-void ff_hevc_put_qpel_bi_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
- int16_t *src2,
+void ff_hevc_put_qpel_bi_neon_wrapper(uint8_t *dst, ptrdiff_t dststride,
+ const uint8_t *src, ptrdiff_t srcstride, const int16_t *src2,
int height, intptr_t mx, intptr_t my, int width);
#define QPEL_FUNC(name) \
- void name(int16_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, \
+ void name(int16_t *dst, ptrdiff_t dststride, const uint8_t *src, ptrdiff_t srcstride, \
int height, int width)
QPEL_FUNC(ff_hevc_put_qpel_v1_neon_8);
@@ -118,7 +118,7 @@ QPEL_FUNC(ff_hevc_put_qpel_h3v3_neon_8);
#undef QPEL_FUNC
#define QPEL_FUNC_UW_PIX(name) \
- void name(uint8_t *dst, ptrdiff_t dststride, uint8_t *_src, ptrdiff_t _srcstride, \
+ void name(uint8_t *dst, ptrdiff_t dststride, const uint8_t *_src, ptrdiff_t _srcstride, \
int height, intptr_t mx, intptr_t my, int width);
QPEL_FUNC_UW_PIX(ff_hevc_put_qpel_uw_pixels_w4_neon_8);
QPEL_FUNC_UW_PIX(ff_hevc_put_qpel_uw_pixels_w8_neon_8);
@@ -130,8 +130,8 @@ QPEL_FUNC_UW_PIX(ff_hevc_put_qpel_uw_pixels_w64_neon_8);
#undef QPEL_FUNC_UW_PIX
#define QPEL_FUNC_UW(name) \
- void name(uint8_t *dst, ptrdiff_t dststride, uint8_t *_src, ptrdiff_t _srcstride, \
- int width, int height, int16_t* src2, ptrdiff_t src2stride);
+ void name(uint8_t *dst, ptrdiff_t dststride, const uint8_t *_src, ptrdiff_t _srcstride, \
+ int width, int height, const int16_t* src2, ptrdiff_t src2stride);
QPEL_FUNC_UW(ff_hevc_put_qpel_uw_pixels_neon_8);
QPEL_FUNC_UW(ff_hevc_put_qpel_uw_v1_neon_8);
QPEL_FUNC_UW(ff_hevc_put_qpel_uw_v2_neon_8);
@@ -150,14 +150,14 @@ QPEL_FUNC_UW(ff_hevc_put_qpel_uw_h3v2_neon_8);
QPEL_FUNC_UW(ff_hevc_put_qpel_uw_h3v3_neon_8);
#undef QPEL_FUNC_UW
-void ff_hevc_sao_band_filter_neon_8(uint8_t *dst, uint8_t *src, ptrdiff_t stride_dst, ptrdiff_t stride_src, int width, int height, int16_t *offset_table);
+void ff_hevc_sao_band_filter_neon_8(uint8_t *dst, const uint8_t *src, ptrdiff_t stride_dst, ptrdiff_t stride_src, int width, int height, int16_t *offset_table);
-void ff_hevc_sao_band_filter_neon_8_wrapper(uint8_t *_dst, uint8_t *_src,
+void ff_hevc_sao_band_filter_neon_8_wrapper(uint8_t *_dst, const uint8_t *_src,
ptrdiff_t stride_dst, ptrdiff_t stride_src,
- int16_t *sao_offset_val, int sao_left_class,
+ const int16_t *sao_offset_val, int sao_left_class,
int width, int height) {
uint8_t *dst = _dst;
- uint8_t *src = _src;
+ const uint8_t *src = _src;
int16_t offset_table[32] = {0};
int k;
@@ -168,10 +168,10 @@ void ff_hevc_sao_band_filter_neon_8_wrapper(uint8_t *_dst, uint8_t *_src,
ff_hevc_sao_band_filter_neon_8(dst, src, stride_dst, stride_src, width, height, offset_table);
}
-void ff_hevc_sao_edge_filter_neon_8(uint8_t *dst, uint8_t *src, ptrdiff_t stride_dst, ptrdiff_t stride_src, int width, int height,
- int a_stride, int b_stride, int16_t *sao_offset_val, uint8_t *edge_idx);
+void ff_hevc_sao_edge_filter_neon_8(uint8_t *dst, const uint8_t *src, ptrdiff_t stride_dst, ptrdiff_t stride_src, int width, int height,
+ int a_stride, int b_stride, const int16_t *sao_offset_val, const uint8_t *edge_idx);
-void ff_hevc_sao_edge_filter_neon_8_wrapper(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val,
+void ff_hevc_sao_edge_filter_neon_8_wrapper(uint8_t *_dst, const uint8_t *_src, ptrdiff_t stride_dst, const int16_t *sao_offset_val,
int eo, int width, int height) {
static uint8_t edge_idx[] = { 1, 2, 0, 3, 4 };
static const int8_t pos[4][2][2] = {
@@ -181,7 +181,7 @@ void ff_hevc_sao_edge_filter_neon_8_wrapper(uint8_t *_dst, uint8_t *_src, ptrdif
{ { 1, -1 }, { -1, 1 } }, // 135 degree
};
uint8_t *dst = _dst;
- uint8_t *src = _src;
+ const uint8_t *src = _src;
int a_stride, b_stride;
ptrdiff_t stride_src = (2*MAX_PB_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
@@ -191,20 +191,20 @@ void ff_hevc_sao_edge_filter_neon_8_wrapper(uint8_t *_dst, uint8_t *_src, ptrdif
ff_hevc_sao_edge_filter_neon_8(dst, src, stride_dst, stride_src, width, height, a_stride, b_stride, sao_offset_val, edge_idx);
}
-void ff_hevc_put_qpel_neon_wrapper(int16_t *dst, uint8_t *src, ptrdiff_t srcstride,
+void ff_hevc_put_qpel_neon_wrapper(int16_t *dst, const uint8_t *src, ptrdiff_t srcstride,
int height, intptr_t mx, intptr_t my, int width) {
put_hevc_qpel_neon[my][mx](dst, MAX_PB_SIZE, src, srcstride, height, width);
}
-void ff_hevc_put_qpel_uni_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
+void ff_hevc_put_qpel_uni_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, const uint8_t *src, ptrdiff_t srcstride,
int height, intptr_t mx, intptr_t my, int width) {
put_hevc_qpel_uw_neon[my][mx](dst, dststride, src, srcstride, width, height, NULL, 0);
}
-void ff_hevc_put_qpel_bi_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
- int16_t *src2,
+void ff_hevc_put_qpel_bi_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, const uint8_t *src, ptrdiff_t srcstride,
+ const int16_t *src2,
int height, intptr_t mx, intptr_t my, int width) {
put_hevc_qpel_uw_neon[my][mx](dst, dststride, src, srcstride, width, height, src2, MAX_PB_SIZE);
}
diff --git a/libavcodec/arm/mdct_fixed_neon.S b/libavcodec/arm/mdct_fixed_neon.S
deleted file mode 100644
index 365c5e7fa..000000000
--- a/libavcodec/arm/mdct_fixed_neon.S
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2011 Mans Rullgard
- *
- * 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/arm/asm.S"
-
-.macro prerot dst, rt
- lsr r3, r6, #2 @ n4
- add \rt, r4, r6, lsr #1 @ revtab + n4
- add r9, r3, r3, lsl #1 @ n3
- add r8, r7, r6 @ tcos + n4
- add r3, r2, r6, lsr #1 @ in + n4
- add r9, r2, r9, lsl #1 @ in + n3
- sub r8, r8, #16
- sub r10, r3, #16
- sub r11, r9, #16
- mov r12, #-16
-1:
- vld2.16 {d0,d1}, [r9, :128]!
- vld2.16 {d2,d3}, [r11,:128], r12
- vld2.16 {d4,d5}, [r3, :128]!
- vld2.16 {d6,d7}, [r10,:128], r12
- vld2.16 {d16,d17},[r7, :128]! @ cos, sin
- vld2.16 {d18,d19},[r8, :128], r12
- vrev64.16 q1, q1
- vrev64.16 q3, q3
- vrev64.16 q9, q9
- vneg.s16 d0, d0
- vneg.s16 d2, d2
- vneg.s16 d16, d16
- vneg.s16 d18, d18
- vhsub.s16 d0, d0, d3 @ re
- vhsub.s16 d4, d7, d4 @ im
- vhsub.s16 d6, d6, d5
- vhsub.s16 d2, d2, d1
- vmull.s16 q10, d0, d16
- vmlsl.s16 q10, d4, d17
- vmull.s16 q11, d0, d17
- vmlal.s16 q11, d4, d16
- vmull.s16 q12, d6, d18
- vmlsl.s16 q12, d2, d19
- vmull.s16 q13, d6, d19
- vmlal.s16 q13, d2, d18
- vshrn.s32 d0, q10, #15
- vshrn.s32 d1, q11, #15
- vshrn.s32 d2, q12, #15
- vshrn.s32 d3, q13, #15
- vzip.16 d0, d1
- vzip.16 d2, d3
- ldrh lr, [r4], #2
- ldrh r2, [\rt, #-2]!
- add lr, \dst, lr, lsl #2
- add r2, \dst, r2, lsl #2
- vst1.32 {d0[0]}, [lr,:32]
- vst1.32 {d2[0]}, [r2,:32]
- ldrh lr, [r4], #2
- ldrh r2, [\rt, #-2]!
- add lr, \dst, lr, lsl #2
- add r2, \dst, r2, lsl #2
- vst1.32 {d0[1]}, [lr,:32]
- vst1.32 {d2[1]}, [r2,:32]
- ldrh lr, [r4], #2
- ldrh r2, [\rt, #-2]!
- add lr, \dst, lr, lsl #2
- add r2, \dst, r2, lsl #2
- vst1.32 {d1[0]}, [lr,:32]
- vst1.32 {d3[0]}, [r2,:32]
- ldrh lr, [r4], #2
- ldrh r2, [\rt, #-2]!
- add lr, \dst, lr, lsl #2
- add r2, \dst, r2, lsl #2
- vst1.32 {d1[1]}, [lr,:32]
- vst1.32 {d3[1]}, [r2,:32]
- subs r6, r6, #32
- bgt 1b
-.endm
-
-function ff_mdct_fixed_calc_neon, export=1
- push {r1,r4-r11,lr}
-
- ldr r4, [r0, #8] @ revtab
- ldr r6, [r0, #16] @ mdct_size; n
- ldr r7, [r0, #24] @ tcos
-
- prerot r1, r5
-
- mov r4, r0
- bl X(ff_fft_fixed_calc_neon)
-
- pop {r5}
- mov r12, #-16
- ldr r6, [r4, #16] @ mdct_size; n
- ldr r7, [r4, #24] @ tcos
- add r5, r5, r6, lsr #1
- add r7, r7, r6, lsr #1
- sub r1, r5, #16
- sub r2, r7, #16
-1:
- vld2.16 {d4,d5}, [r7,:128]!
- vld2.16 {d6,d7}, [r2,:128], r12
- vld2.16 {d0,d1}, [r5,:128]
- vld2.16 {d2,d3}, [r1,:128]
- vrev64.16 q3, q3
- vrev64.16 q1, q1
- vneg.s16 q3, q3
- vneg.s16 q2, q2
- vmull.s16 q11, d2, d6
- vmlal.s16 q11, d3, d7
- vmull.s16 q8, d0, d5
- vmlsl.s16 q8, d1, d4
- vmull.s16 q9, d0, d4
- vmlal.s16 q9, d1, d5
- vmull.s16 q10, d2, d7
- vmlsl.s16 q10, d3, d6
- vshrn.s32 d0, q11, #15
- vshrn.s32 d1, q8, #15
- vshrn.s32 d2, q9, #15
- vshrn.s32 d3, q10, #15
- vrev64.16 q0, q0
- vst2.16 {d2,d3}, [r5,:128]!
- vst2.16 {d0,d1}, [r1,:128], r12
- subs r6, r6, #32
- bgt 1b
-
- pop {r4-r11,pc}
-endfunc
-
-function ff_mdct_fixed_calcw_neon, export=1
- push {r1,r4-r11,lr}
-
- ldrd r4, r5, [r0, #8] @ revtab, tmp_buf
- ldr r6, [r0, #16] @ mdct_size; n
- ldr r7, [r0, #24] @ tcos
-
- prerot r5, r1
-
- mov r4, r0
- mov r1, r5
- bl X(ff_fft_fixed_calc_neon)
-
- pop {r7}
- mov r12, #-16
- ldr r6, [r4, #16] @ mdct_size; n
- ldr r9, [r4, #24] @ tcos
- add r5, r5, r6, lsr #1
- add r7, r7, r6
- add r9, r9, r6, lsr #1
- sub r3, r5, #16
- sub r1, r7, #16
- sub r2, r9, #16
-1:
- vld2.16 {d4,d5}, [r9,:128]!
- vld2.16 {d6,d7}, [r2,:128], r12
- vld2.16 {d0,d1}, [r5,:128]!
- vld2.16 {d2,d3}, [r3,:128], r12
- vrev64.16 q3, q3
- vrev64.16 q1, q1
- vneg.s16 q3, q3
- vneg.s16 q2, q2
- vmull.s16 q8, d2, d6
- vmlal.s16 q8, d3, d7
- vmull.s16 q9, d0, d5
- vmlsl.s16 q9, d1, d4
- vmull.s16 q10, d0, d4
- vmlal.s16 q10, d1, d5
- vmull.s16 q11, d2, d7
- vmlsl.s16 q11, d3, d6
- vrev64.32 q8, q8
- vrev64.32 q9, q9
- vst2.32 {q10,q11},[r7,:128]!
- vst2.32 {d16,d18},[r1,:128], r12
- vst2.32 {d17,d19},[r1,:128], r12
- subs r6, r6, #32
- bgt 1b
-
- pop {r4-r11,pc}
-endfunc
diff --git a/libavcodec/arm/me_cmp_init_arm.c b/libavcodec/arm/me_cmp_init_arm.c
index 03870a2bf..8c556f175 100644
--- a/libavcodec/arm/me_cmp_init_arm.c
+++ b/libavcodec/arm/me_cmp_init_arm.c
@@ -25,17 +25,17 @@
#include "libavcodec/me_cmp.h"
#include "libavcodec/mpegvideo.h"
-int ff_pix_abs16_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
+int ff_pix_abs16_armv6(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
ptrdiff_t stride, int h);
-int ff_pix_abs16_x2_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
+int ff_pix_abs16_x2_armv6(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
ptrdiff_t stride, int h);
-int ff_pix_abs16_y2_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
+int ff_pix_abs16_y2_armv6(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
ptrdiff_t stride, int h);
-int ff_pix_abs8_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
+int ff_pix_abs8_armv6(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
ptrdiff_t stride, int h);
-int ff_sse16_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
+int ff_sse16_armv6(MpegEncContext *s, const uint8_t *blk1, const uint8_t *blk2,
ptrdiff_t stride, int h);
av_cold void ff_me_cmp_init_arm(MECmpContext *c, AVCodecContext *avctx)
diff --git a/libavcodec/arm/mpegvideoencdsp_init_arm.c b/libavcodec/arm/mpegvideoencdsp_init_arm.c
index 31d147441..a95b5bebe 100644
--- a/libavcodec/arm/mpegvideoencdsp_init_arm.c
+++ b/libavcodec/arm/mpegvideoencdsp_init_arm.c
@@ -24,8 +24,8 @@
#include "libavcodec/avcodec.h"
#include "libavcodec/mpegvideoencdsp.h"
-int ff_pix_norm1_armv6(uint8_t *pix, int line_size);
-int ff_pix_sum_armv6(uint8_t *pix, int line_size);
+int ff_pix_norm1_armv6(const uint8_t *pix, int line_size);
+int ff_pix_sum_armv6(const uint8_t *pix, int line_size);
av_cold void ff_mpegvideoencdsp_init_arm(MpegvideoEncDSPContext *c,
AVCodecContext *avctx)
diff --git a/libavcodec/arm/rv40dsp_init_arm.c b/libavcodec/arm/rv40dsp_init_arm.c
index c24854d1c..2e584af47 100644
--- a/libavcodec/arm/rv40dsp_init_arm.c
+++ b/libavcodec/arm/rv40dsp_init_arm.c
@@ -49,11 +49,11 @@ DECL_QPEL_Y(1);
DECL_QPEL_Y(2);
DECL_QPEL_Y(3);
-void ff_put_rv40_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int);
-void ff_put_rv40_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int);
+void ff_put_rv40_chroma_mc8_neon(uint8_t *, const uint8_t *, ptrdiff_t, int, int, int);
+void ff_put_rv40_chroma_mc4_neon(uint8_t *, const uint8_t *, ptrdiff_t, int, int, int);
-void ff_avg_rv40_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int);
-void ff_avg_rv40_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int);
+void ff_avg_rv40_chroma_mc8_neon(uint8_t *, const uint8_t *, ptrdiff_t, int, int, int);
+void ff_avg_rv40_chroma_mc4_neon(uint8_t *, const uint8_t *, ptrdiff_t, int, int, int);
void ff_rv40_weight_func_16_neon(uint8_t *, uint8_t *, uint8_t *, int, int, ptrdiff_t);
void ff_rv40_weight_func_8_neon(uint8_t *, uint8_t *, uint8_t *, int, int, ptrdiff_t);
diff --git a/libavcodec/arm/synth_filter_init_arm.c b/libavcodec/arm/synth_filter_init_arm.c
index ea0ce148d..858c117d3 100644
--- a/libavcodec/arm/synth_filter_init_arm.c
+++ b/libavcodec/arm/synth_filter_init_arm.c
@@ -26,17 +26,17 @@
#include "libavcodec/fft.h"
#include "libavcodec/synth_filter.h"
-void ff_synth_filter_float_vfp(FFTContext *imdct,
+void ff_synth_filter_float_vfp(AVTXContext *imdct,
float *synth_buf_ptr, int *synth_buf_offset,
float synth_buf2[32], const float window[512],
- float out[32], const float in[32],
- float scale);
+ float out[32], float in[32],
+ float scale, av_tx_fn imdct_fn);
-void ff_synth_filter_float_neon(FFTContext *imdct,
+void ff_synth_filter_float_neon(AVTXContext *imdct,
float *synth_buf_ptr, int *synth_buf_offset,
float synth_buf2[32], const float window[512],
- float out[32], const float in[32],
- float scale);
+ float out[32], float in[32],
+ float scale, av_tx_fn imdct_fn);
av_cold void ff_synth_filter_init_arm(SynthFilterContext *s)
{
diff --git a/libavcodec/arm/synth_filter_neon.S b/libavcodec/arm/synth_filter_neon.S
index 5417be7d5..17dd5c89a 100644
--- a/libavcodec/arm/synth_filter_neon.S
+++ b/libavcodec/arm/synth_filter_neon.S
@@ -31,10 +31,13 @@ function ff_synth_filter_float_neon, export=1
str r12, [r2]
ldr r2, [sp, #12*4] @ in
+VFP ldr r12, [sp, #13*4] @ imdct_fn
+NOVFP ldr r12, [sp, #14*4] @ imdct_fn
+ mov r3, #4 @ sizeof(float)
mov r9, r1 @ synth_buf
VFP vpush {d0}
- bl X(ff_imdct_half_neon)
+ blx r12
VFP vpop {d0}
pop {r3}
diff --git a/libavcodec/arm/synth_filter_vfp.S b/libavcodec/arm/synth_filter_vfp.S
index 596734c5b..4ff69ada4 100644
--- a/libavcodec/arm/synth_filter_vfp.S
+++ b/libavcodec/arm/synth_filter_vfp.S
@@ -131,8 +131,11 @@ function ff_synth_filter_float_vfp, export=1
and lr, lr, #512-32
str lr, [P_SB_OFF] @ rotate offset, modulo buffer size, ready for next call
ldr a3, [sp, #(16+6+2)*4] @ fetch in from stack, to pass to imdct_half
+ mov a4, #4 @ sizeof(float)
+VFP ldr r12, [sp, #(16+6+3)*4] @ fetch imdct_fn from stack
+NOVFP ldr r12, [sp, #(16+6+4)*4] @ fetch imdct_fn from stack
VFP vmov s16, SCALE @ imdct_half is free to corrupt s0, but it contains one of our arguments in hardfp case
- bl X(ff_imdct_half_vfp)
+ blx r12
VFP vmov SCALE, s16
fmrx OLDFPSCR, FPSCR
diff --git a/libavcodec/arm/vc1dsp_init_neon.c b/libavcodec/arm/vc1dsp_init_neon.c
index 48cb816b7..b5615624d 100644
--- a/libavcodec/arm/vc1dsp_init_neon.c
+++ b/libavcodec/arm/vc1dsp_init_neon.c
@@ -33,12 +33,12 @@ void ff_vc1_inv_trans_4x8_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *bloc
void ff_vc1_inv_trans_8x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block);
void ff_vc1_inv_trans_4x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block);
-void ff_vc1_v_loop_filter4_neon(uint8_t *src, int stride, int pq);
-void ff_vc1_h_loop_filter4_neon(uint8_t *src, int stride, int pq);
-void ff_vc1_v_loop_filter8_neon(uint8_t *src, int stride, int pq);
-void ff_vc1_h_loop_filter8_neon(uint8_t *src, int stride, int pq);
-void ff_vc1_v_loop_filter16_neon(uint8_t *src, int stride, int pq);
-void ff_vc1_h_loop_filter16_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_v_loop_filter4_neon(uint8_t *src, ptrdiff_t stride, int pq);
+void ff_vc1_h_loop_filter4_neon(uint8_t *src, ptrdiff_t stride, int pq);
+void ff_vc1_v_loop_filter8_neon(uint8_t *src, ptrdiff_t stride, int pq);
+void ff_vc1_h_loop_filter8_neon(uint8_t *src, ptrdiff_t stride, int pq);
+void ff_vc1_v_loop_filter16_neon(uint8_t *src, ptrdiff_t stride, int pq);
+void ff_vc1_h_loop_filter16_neon(uint8_t *src, ptrdiff_t stride, int pq);
void ff_put_pixels8x8_neon(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int rnd);
@@ -76,13 +76,13 @@ DECL_PUT(3, 1)
DECL_PUT(3, 2)
DECL_PUT(3, 3)
-void ff_put_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_vc1_chroma_mc8_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_avg_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_avg_vc1_chroma_mc8_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_put_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_vc1_chroma_mc4_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_avg_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_avg_vc1_chroma_mc4_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
int ff_vc1_unescape_buffer_helper_neon(const uint8_t *src, int size, uint8_t *dst);
diff --git a/libavcodec/arm/vc1dsp_neon.S b/libavcodec/arm/vc1dsp_neon.S
index 96014fbeb..cdfb4a3f6 100644
--- a/libavcodec/arm/vc1dsp_neon.S
+++ b/libavcodec/arm/vc1dsp_neon.S
@@ -1310,17 +1310,17 @@ endfunc
function ff_vc1_v_loop_filter8_neon, export=1
sub r3, r0, r1, lsl #2
vldr d0, .Lcoeffs
- vld1.32 {d1}, [r0 :64], r1 @ P5
- vld1.32 {d2}, [r3 :64], r1 @ P1
- vld1.32 {d3}, [r3 :64], r1 @ P2
- vld1.32 {d4}, [r0 :64], r1 @ P6
- vld1.32 {d5}, [r3 :64], r1 @ P3
- vld1.32 {d6}, [r0 :64], r1 @ P7
+ vld1.32 {d1}, [r0, :64], r1 @ P5
+ vld1.32 {d2}, [r3, :64], r1 @ P1
+ vld1.32 {d3}, [r3, :64], r1 @ P2
+ vld1.32 {d4}, [r0, :64], r1 @ P6
+ vld1.32 {d5}, [r3, :64], r1 @ P3
+ vld1.32 {d6}, [r0, :64], r1 @ P7
vshll.u8 q8, d1, #1 @ 2*P5
vshll.u8 q9, d2, #1 @ 2*P1
- vld1.32 {d7}, [r3 :64] @ P4
+ vld1.32 {d7}, [r3, :64] @ P4
vmovl.u8 q1, d3 @ P2
- vld1.32 {d20}, [r0 :64] @ P8
+ vld1.32 {d20}, [r0, :64] @ P8
vmovl.u8 q11, d4 @ P6
vdup.16 q12, r2 @ pq
vmovl.u8 q13, d5 @ P3
@@ -1375,8 +1375,8 @@ function ff_vc1_v_loop_filter8_neon, export=1
vmla.i16 q1, q0, q2 @ invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P5
vqmovun.s16 d0, q3
vqmovun.s16 d1, q1
- vst1.32 {d0}, [r3 :64], r1
- vst1.32 {d1}, [r3 :64]
+ vst1.32 {d0}, [r3, :64], r1
+ vst1.32 {d1}, [r3, :64]
1: bx lr
endfunc
@@ -1491,17 +1491,17 @@ function ff_vc1_v_loop_filter16_neon, export=1
vpush {d8-d15}
sub r3, r0, r1, lsl #2
vldr d0, .Lcoeffs
- vld1.64 {q1}, [r0 :128], r1 @ P5
- vld1.64 {q2}, [r3 :128], r1 @ P1
- vld1.64 {q3}, [r3 :128], r1 @ P2
- vld1.64 {q4}, [r0 :128], r1 @ P6
- vld1.64 {q5}, [r3 :128], r1 @ P3
- vld1.64 {q6}, [r0 :128], r1 @ P7
+ vld1.64 {q1}, [r0, :128], r1 @ P5
+ vld1.64 {q2}, [r3, :128], r1 @ P1
+ vld1.64 {q3}, [r3, :128], r1 @ P2
+ vld1.64 {q4}, [r0, :128], r1 @ P6
+ vld1.64 {q5}, [r3, :128], r1 @ P3
+ vld1.64 {q6}, [r0, :128], r1 @ P7
vshll.u8 q7, d2, #1 @ 2*P5[0..7]
vshll.u8 q8, d4, #1 @ 2*P1[0..7]
- vld1.64 {q9}, [r3 :128] @ P4
+ vld1.64 {q9}, [r3, :128] @ P4
vmovl.u8 q10, d6 @ P2[0..7]
- vld1.64 {q11}, [r0 :128] @ P8
+ vld1.64 {q11}, [r0, :128] @ P8
vmovl.u8 q12, d8 @ P6[0..7]
vdup.16 q13, r2 @ pq
vshll.u8 q2, d5, #1 @ 2*P1[8..15]
@@ -1611,8 +1611,8 @@ function ff_vc1_v_loop_filter16_neon, export=1
vqmovun.s16 d0, q6
vqmovun.s16 d5, q9
vqmovun.s16 d1, q1
- vst1.64 {q2}, [r3 :128], r1
- vst1.64 {q0}, [r3 :128]
+ vst1.64 {q2}, [r3, :128], r1
+ vst1.64 {q0}, [r3, :128]
1: vpop {d8-d15}
bx lr
endfunc
diff --git a/libavcodec/arm/videodsp_init_armv5te.c b/libavcodec/arm/videodsp_init_armv5te.c
index 1ea1f3438..eaa8c5bbf 100644
--- a/libavcodec/arm/videodsp_init_armv5te.c
+++ b/libavcodec/arm/videodsp_init_armv5te.c
@@ -23,7 +23,7 @@
#include "libavcodec/videodsp.h"
#include "videodsp_arm.h"
-void ff_prefetch_arm(uint8_t *mem, ptrdiff_t stride, int h);
+void ff_prefetch_arm(const uint8_t *mem, ptrdiff_t stride, int h);
av_cold void ff_videodsp_init_armv5te(VideoDSPContext *ctx, int bpc)
{
diff --git a/libavcodec/arm/vorbisdsp_init_arm.c b/libavcodec/arm/vorbisdsp_init_arm.c
index f4b3d80ef..acda34f46 100644
--- a/libavcodec/arm/vorbisdsp_init_arm.c
+++ b/libavcodec/arm/vorbisdsp_init_arm.c
@@ -25,7 +25,7 @@
#include "libavcodec/vorbisdsp.h"
void ff_vorbis_inverse_coupling_neon(float *mag, float *ang,
- intptr_t blocksize);
+ ptrdiff_t blocksize);
av_cold void ff_vorbisdsp_init_arm(VorbisDSPContext *c)
{
diff --git a/libavcodec/arm/vp8.h b/libavcodec/arm/vp8.h
index 965342d93..7c59a7d63 100644
--- a/libavcodec/arm/vp8.h
+++ b/libavcodec/arm/vp8.h
@@ -22,12 +22,12 @@
#include
#include "config.h"
-#include "libavcodec/vp56.h"
+#include "libavcodec/vpx_rac.h"
#include "libavcodec/vp8.h"
#if HAVE_ARMV6_EXTERNAL
#define vp8_decode_block_coeffs_internal ff_decode_block_coeffs_armv6
-int ff_decode_block_coeffs_armv6(VP56RangeCoder *rc, int16_t block[16],
+int ff_decode_block_coeffs_armv6(VPXRangeCoder *rc, int16_t block[16],
uint8_t probs[8][3][NUM_DCT_TOKENS-1],
int i, uint8_t *token_prob, int16_t qmul[2]);
#endif
diff --git a/libavcodec/arm/vp8_armv6.S b/libavcodec/arm/vp8_armv6.S
index e7d25a45c..7ecf2641f 100644
--- a/libavcodec/arm/vp8_armv6.S
+++ b/libavcodec/arm/vp8_armv6.S
@@ -65,7 +65,7 @@ T orrcs \cw, \cw, \t1
function ff_decode_block_coeffs_armv6, export=1
push {r0,r1,r4-r11,lr}
- movrelx lr, X(ff_vp56_norm_shift)
+ movrelx lr, X(ff_vpx_norm_shift)
ldrd r4, r5, [sp, #44] @ token_prob, qmul
cmp r3, #0
ldr r11, [r5]
diff --git a/libavcodec/arm/vp8dsp.h b/libavcodec/arm/vp8dsp.h
index 7281d0bfb..11dcc78d7 100644
--- a/libavcodec/arm/vp8dsp.h
+++ b/libavcodec/arm/vp8dsp.h
@@ -58,7 +58,7 @@ void ff_vp8dsp_init_neon(VP8DSPContext *dsp);
#define VP8_MC(n, opt) \
void ff_put_vp8_##n##_##opt(uint8_t *dst, ptrdiff_t dststride, \
- uint8_t *src, ptrdiff_t srcstride, \
+ const uint8_t *src, ptrdiff_t srcstride,\
int h, int x, int y)
#define VP8_EPEL(w, opt) \
diff --git a/libavcodec/arm/vp8dsp_armv6.S b/libavcodec/arm/vp8dsp_armv6.S
index 2320bf4d2..395debe86 100644
--- a/libavcodec/arm/vp8dsp_armv6.S
+++ b/libavcodec/arm/vp8dsp_armv6.S
@@ -1113,7 +1113,7 @@ endfunc
@ MC
-@ void put_vp8_pixels16(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+@ void put_vp8_pixels16(uint8_t *dst, ptrdiff_t dststride, const uint8_t *src,
@ ptrdiff_t srcstride, int h, int mx, int my)
function ff_put_vp8_pixels16_armv6, export=1
push {r4-r11}
@@ -1137,7 +1137,7 @@ function ff_put_vp8_pixels16_armv6, export=1
bx lr
endfunc
-@ void put_vp8_pixels8(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+@ void put_vp8_pixels8(uint8_t *dst, ptrdiff_t dststride, const uint8_t *src,
@ ptrdiff_t srcstride, int h, int mx, int my)
function ff_put_vp8_pixels8_armv6, export=1
push {r4-r11}
@@ -1161,7 +1161,7 @@ function ff_put_vp8_pixels8_armv6, export=1
bx lr
endfunc
-@ void put_vp8_pixels4(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+@ void put_vp8_pixels4(uint8_t *dst, ptrdiff_t dststride, const uint8_t *src,
@ ptrdiff_t srcstride, int h, int mx, int my)
function ff_put_vp8_pixels4_armv6, export=1
ldr r12, [sp, #0] @ h
diff --git a/libavcodec/arm/vp56_arith.h b/libavcodec/arm/vpx_arith.h
similarity index 88%
rename from libavcodec/arm/vp56_arith.h
rename to libavcodec/arm/vpx_arith.h
index feb124791..1ead2284c 100644
--- a/libavcodec/arm/vp56_arith.h
+++ b/libavcodec/arm/vpx_arith.h
@@ -18,8 +18,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef AVCODEC_ARM_VP56_ARITH_H
-#define AVCODEC_ARM_VP56_ARITH_H
+#ifndef AVCODEC_ARM_VPX_ARITH_H
+#define AVCODEC_ARM_VPX_ARITH_H
#if CONFIG_THUMB
# define A(x)
@@ -39,10 +39,10 @@
#if HAVE_ARMV6_INLINE
-#define vp56_rac_get_prob vp56_rac_get_prob_armv6
-static inline int vp56_rac_get_prob_armv6(VP56RangeCoder *c, int pr)
+#define vpx_rac_get_prob vp56_rac_get_prob_armv6
+static inline int vp56_rac_get_prob_armv6(VPXRangeCoder *c, int pr)
{
- unsigned shift = ff_vp56_norm_shift[c->high];
+ unsigned shift = ff_vpx_norm_shift[c->high];
unsigned code_word = c->code_word << shift;
unsigned high = c->high << shift;
unsigned bit;
@@ -76,10 +76,10 @@ static inline int vp56_rac_get_prob_armv6(VP56RangeCoder *c, int pr)
return bit;
}
-#define vp56_rac_get_prob_branchy vp56_rac_get_prob_branchy_armv6
-static inline int vp56_rac_get_prob_branchy_armv6(VP56RangeCoder *c, int pr)
+#define vpx_rac_get_prob_branchy vp56_rac_get_prob_branchy_armv6
+static inline int vp56_rac_get_prob_branchy_armv6(VPXRangeCoder *c, int pr)
{
- unsigned shift = ff_vp56_norm_shift[c->high];
+ unsigned shift = ff_vpx_norm_shift[c->high];
unsigned code_word = c->code_word << shift;
unsigned high = c->high << shift;
unsigned low;
@@ -118,4 +118,4 @@ static inline int vp56_rac_get_prob_branchy_armv6(VP56RangeCoder *c, int pr)
#endif
-#endif /* AVCODEC_ARM_VP56_ARITH_H */
+#endif /* AVCODEC_ARM_VPX_ARITH_H */
diff --git a/libavcodec/ass.c b/libavcodec/ass.c
index a1e560d7f..5058dc833 100644
--- a/libavcodec/ass.c
+++ b/libavcodec/ass.c
@@ -24,6 +24,7 @@
#include "libavutil/avstring.h"
#include "libavutil/bprint.h"
#include "libavutil/common.h"
+#include "version.h"
int ff_ass_subtitle_header_full(AVCodecContext *avctx,
int play_res_x, int play_res_y,
@@ -40,10 +41,11 @@ int ff_ass_subtitle_header_full(AVCodecContext *avctx,
"PlayResX: %d\r\n"
"PlayResY: %d\r\n"
"ScaledBorderAndShadow: yes\r\n"
+ "YCbCr Matrix: None\r\n"
"\r\n"
"[V4+ Styles]\r\n"
- /* ASSv4 header */
+ /* ASS (v4+) header */
"Format: Name, "
"Fontname, Fontsize, "
"PrimaryColour, SecondaryColour, OutlineColour, BackColour, "
@@ -63,7 +65,7 @@ int ff_ass_subtitle_header_full(AVCodecContext *avctx,
"0,0," /* Spacing, Angle */
"%d,1,0," /* BorderStyle, Outline, Shadow */
"%d,10,10,10," /* Alignment, Margin[LRV] */
- "0\r\n" /* Encoding */
+ "1\r\n" /* Encoding */
"\r\n"
"[Events]\r\n"
diff --git a/libavcodec/assdec.c b/libavcodec/assdec.c
index f43b500aa..89d7b5189 100644
--- a/libavcodec/assdec.c
+++ b/libavcodec/assdec.c
@@ -64,23 +64,21 @@ static int ass_decode_frame(AVCodecContext *avctx, AVSubtitle *sub,
#if CONFIG_SSA_DECODER
const FFCodec ff_ssa_decoder = {
.p.name = "ssa",
- .p.long_name = NULL_IF_CONFIG_SMALL("ASS (Advanced SubStation Alpha) subtitle"),
+ CODEC_LONG_NAME("ASS (Advanced SubStation Alpha) subtitle"),
.p.type = AVMEDIA_TYPE_SUBTITLE,
.p.id = AV_CODEC_ID_ASS,
.init = ass_decode_init,
FF_CODEC_DECODE_SUB_CB(ass_decode_frame),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
#if CONFIG_ASS_DECODER
const FFCodec ff_ass_decoder = {
.p.name = "ass",
- .p.long_name = NULL_IF_CONFIG_SMALL("ASS (Advanced SubStation Alpha) subtitle"),
+ CODEC_LONG_NAME("ASS (Advanced SubStation Alpha) subtitle"),
.p.type = AVMEDIA_TYPE_SUBTITLE,
.p.id = AV_CODEC_ID_ASS,
.init = ass_decode_init,
FF_CODEC_DECODE_SUB_CB(ass_decode_frame),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
diff --git a/libavcodec/assenc.c b/libavcodec/assenc.c
index 2ac40d5af..db6fd25dd 100644
--- a/libavcodec/assenc.c
+++ b/libavcodec/assenc.c
@@ -71,23 +71,21 @@ static int ass_encode_frame(AVCodecContext *avctx,
#if CONFIG_SSA_ENCODER
const FFCodec ff_ssa_encoder = {
.p.name = "ssa",
- .p.long_name = NULL_IF_CONFIG_SMALL("ASS (Advanced SubStation Alpha) subtitle"),
+ CODEC_LONG_NAME("ASS (Advanced SubStation Alpha) subtitle"),
.p.type = AVMEDIA_TYPE_SUBTITLE,
.p.id = AV_CODEC_ID_ASS,
.init = ass_encode_init,
FF_CODEC_ENCODE_SUB_CB(ass_encode_frame),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
#if CONFIG_ASS_ENCODER
const FFCodec ff_ass_encoder = {
.p.name = "ass",
- .p.long_name = NULL_IF_CONFIG_SMALL("ASS (Advanced SubStation Alpha) subtitle"),
+ CODEC_LONG_NAME("ASS (Advanced SubStation Alpha) subtitle"),
.p.type = AVMEDIA_TYPE_SUBTITLE,
.p.id = AV_CODEC_ID_ASS,
.init = ass_encode_init,
FF_CODEC_ENCODE_SUB_CB(ass_encode_frame),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
diff --git a/libavcodec/asv.c b/libavcodec/asv.c
index dcae90982..3aa08c30c 100644
--- a/libavcodec/asv.c
+++ b/libavcodec/asv.c
@@ -25,6 +25,8 @@
#include
+#include "libavutil/attributes.h"
+
#include "asv.h"
#include "avcodec.h"
#include "bswapdsp.h"
@@ -88,7 +90,7 @@ const uint16_t ff_asv2_level_tab[63][2] = {
av_cold void ff_asv_common_init(AVCodecContext *avctx)
{
- ASV1Context *const a = avctx->priv_data;
+ ASVCommonContext *const a = avctx->priv_data;
ff_bswapdsp_init(&a->bbdsp);
diff --git a/libavcodec/asv.h b/libavcodec/asv.h
index 269bbe7c1..7c0983a49 100644
--- a/libavcodec/asv.h
+++ b/libavcodec/asv.h
@@ -28,38 +28,17 @@
#include
-#include "libavutil/mem_internal.h"
-
#include "avcodec.h"
-#include "blockdsp.h"
#include "bswapdsp.h"
-#include "fdctdsp.h"
-#include "idctdsp.h"
-#include "get_bits.h"
-#include "pixblockdsp.h"
-#include "put_bits.h"
-typedef struct ASV1Context {
+typedef struct ASVCommonContext {
AVCodecContext *avctx;
- BlockDSPContext bdsp;
BswapDSPContext bbdsp;
- FDCTDSPContext fdsp;
- IDCTDSPContext idsp;
- PixblockDSPContext pdsp;
- PutBitContext pb;
- GetBitContext gb;
- ScanTable scantable;
- int inv_qscale;
int mb_width;
int mb_height;
int mb_width2;
int mb_height2;
- DECLARE_ALIGNED(32, int16_t, block)[6][64];
- uint16_t intra_matrix[64];
- int q_intra_matrix[64];
- uint8_t *bitstream_buffer;
- unsigned int bitstream_buffer_size;
-} ASV1Context;
+} ASVCommonContext;
extern const uint8_t ff_asv_scantab[64];
extern const uint8_t ff_asv_ccp_tab[17][2];
diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c
index 57ba4c5b5..699aab9f8 100644
--- a/libavcodec/asvdec.c
+++ b/libavcodec/asvdec.c
@@ -25,6 +25,7 @@
#include "libavutil/attributes.h"
#include "libavutil/mem.h"
+#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"
#include "asv.h"
@@ -32,9 +33,11 @@
#include "blockdsp.h"
#include "codec_internal.h"
#include "config_components.h"
+#include "decode.h"
+#include "get_bits.h"
#include "idctdsp.h"
-#include "internal.h"
#include "mpeg12data.h"
+#include "vlc.h"
#define CCP_VLC_BITS 5
#define DC_CCP_VLC_BITS 4
@@ -48,6 +51,20 @@ static VLC dc_ccp_vlc;
static VLC ac_ccp_vlc;
static VLC asv2_level_vlc;
+typedef struct ASVDecContext {
+ ASVCommonContext c;
+
+ GetBitContext gb;
+
+ BlockDSPContext bdsp;
+ IDCTDSPContext idsp;
+ uint8_t permutated_scantable[64];
+ DECLARE_ALIGNED(32, int16_t, block)[6][64];
+ uint16_t intra_matrix[64];
+ uint8_t *bitstream_buffer;
+ unsigned int bitstream_buffer_size;
+} ASVDecContext;
+
static av_cold void init_vlcs(void)
{
INIT_VLC_STATIC(&ccp_vlc, CCP_VLC_BITS, 17,
@@ -106,7 +123,7 @@ static inline int asv2_get_level(GetBitContext *gb)
return code - 31;
}
-static inline int asv1_decode_block(ASV1Context *a, int16_t block[64])
+static inline int asv1_decode_block(ASVDecContext *a, int16_t block[64])
{
int i;
@@ -119,25 +136,25 @@ static inline int asv1_decode_block(ASV1Context *a, int16_t block[64])
if (ccp == 16)
break;
if (ccp < 0 || i >= 10) {
- av_log(a->avctx, AV_LOG_ERROR, "coded coeff pattern damaged\n");
+ av_log(a->c.avctx, AV_LOG_ERROR, "coded coeff pattern damaged\n");
return AVERROR_INVALIDDATA;
}
if (ccp & 8)
- block[a->scantable.permutated[4 * i + 0]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 0]) >> 4;
+ block[a->permutated_scantable[4 * i + 0]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 0]) >> 4;
if (ccp & 4)
- block[a->scantable.permutated[4 * i + 1]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 1]) >> 4;
+ block[a->permutated_scantable[4 * i + 1]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 1]) >> 4;
if (ccp & 2)
- block[a->scantable.permutated[4 * i + 2]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 2]) >> 4;
+ block[a->permutated_scantable[4 * i + 2]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 2]) >> 4;
if (ccp & 1)
- block[a->scantable.permutated[4 * i + 3]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 3]) >> 4;
+ block[a->permutated_scantable[4 * i + 3]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 3]) >> 4;
}
}
return 0;
}
-static inline int asv2_decode_block(ASV1Context *a, int16_t block[64])
+static inline int asv2_decode_block(ASVDecContext *a, int16_t block[64])
{
int i, count, ccp;
@@ -148,11 +165,11 @@ static inline int asv2_decode_block(ASV1Context *a, int16_t block[64])
ccp = asv2_get_vlc2(&a->gb, dc_ccp_vlc.table, DC_CCP_VLC_BITS);
if (ccp) {
if (ccp & 4)
- block[a->scantable.permutated[1]] = (asv2_get_level(&a->gb) * a->intra_matrix[1]) >> 4;
+ block[a->permutated_scantable[1]] = (asv2_get_level(&a->gb) * a->intra_matrix[1]) >> 4;
if (ccp & 2)
- block[a->scantable.permutated[2]] = (asv2_get_level(&a->gb) * a->intra_matrix[2]) >> 4;
+ block[a->permutated_scantable[2]] = (asv2_get_level(&a->gb) * a->intra_matrix[2]) >> 4;
if (ccp & 1)
- block[a->scantable.permutated[3]] = (asv2_get_level(&a->gb) * a->intra_matrix[3]) >> 4;
+ block[a->permutated_scantable[3]] = (asv2_get_level(&a->gb) * a->intra_matrix[3]) >> 4;
}
for (i = 1; i < count + 1; i++) {
@@ -160,26 +177,26 @@ static inline int asv2_decode_block(ASV1Context *a, int16_t block[64])
if (ccp) {
if (ccp & 8)
- block[a->scantable.permutated[4 * i + 0]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 0]) >> 4;
+ block[a->permutated_scantable[4 * i + 0]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 0]) >> 4;
if (ccp & 4)
- block[a->scantable.permutated[4 * i + 1]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 1]) >> 4;
+ block[a->permutated_scantable[4 * i + 1]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 1]) >> 4;
if (ccp & 2)
- block[a->scantable.permutated[4 * i + 2]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 2]) >> 4;
+ block[a->permutated_scantable[4 * i + 2]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 2]) >> 4;
if (ccp & 1)
- block[a->scantable.permutated[4 * i + 3]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 3]) >> 4;
+ block[a->permutated_scantable[4 * i + 3]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 3]) >> 4;
}
}
return 0;
}
-static inline int decode_mb(ASV1Context *a, int16_t block[6][64])
+static inline int decode_mb(ASVDecContext *a, int16_t block[6][64])
{
int i, ret;
a->bdsp.clear_blocks(block[0]);
- if (a->avctx->codec_id == AV_CODEC_ID_ASV1) {
+ if (a->c.avctx->codec_id == AV_CODEC_ID_ASV1) {
for (i = 0; i < 6; i++) {
if ((ret = asv1_decode_block(a, block[i])) < 0)
return ret;
@@ -193,7 +210,7 @@ static inline int decode_mb(ASV1Context *a, int16_t block[6][64])
return 0;
}
-static inline void idct_put(ASV1Context *a, AVFrame *frame, int mb_x, int mb_y)
+static inline void idct_put(ASVDecContext *a, AVFrame *frame, int mb_x, int mb_y)
{
int16_t(*block)[64] = a->block;
int linesize = frame->linesize[0];
@@ -207,7 +224,7 @@ static inline void idct_put(ASV1Context *a, AVFrame *frame, int mb_x, int mb_y)
a->idsp.idct_put(dest_y + 8 * linesize, linesize, block[2]);
a->idsp.idct_put(dest_y + 8 * linesize + 8, linesize, block[3]);
- if (!(a->avctx->flags & AV_CODEC_FLAG_GRAY)) {
+ if (!(a->c.avctx->flags & AV_CODEC_FLAG_GRAY)) {
a->idsp.idct_put(dest_cb, frame->linesize[1], block[4]);
a->idsp.idct_put(dest_cr, frame->linesize[2], block[5]);
}
@@ -216,12 +233,13 @@ static inline void idct_put(ASV1Context *a, AVFrame *frame, int mb_x, int mb_y)
static int decode_frame(AVCodecContext *avctx, AVFrame *p,
int *got_frame, AVPacket *avpkt)
{
- ASV1Context *const a = avctx->priv_data;
+ ASVDecContext *const a = avctx->priv_data;
+ const ASVCommonContext *const c = &a->c;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- int mb_x, mb_y, ret;
+ int ret;
- if (buf_size * 8LL < a->mb_height * a->mb_width * 13LL)
+ if (buf_size * 8LL < c->mb_height * c->mb_width * 13LL)
return AVERROR_INVALIDDATA;
if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
@@ -235,7 +253,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
if (!a->bitstream_buffer)
return AVERROR(ENOMEM);
- a->bbdsp.bswap_buf((uint32_t *) a->bitstream_buffer,
+ c->bbdsp.bswap_buf((uint32_t *) a->bitstream_buffer,
(const uint32_t *) buf, buf_size / 4);
ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size);
} else {
@@ -244,8 +262,8 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
if (ret < 0)
return ret;
- for (mb_y = 0; mb_y < a->mb_height2; mb_y++) {
- for (mb_x = 0; mb_x < a->mb_width2; mb_x++) {
+ for (int mb_y = 0; mb_y < c->mb_height2; mb_y++) {
+ for (int mb_x = 0; mb_x < c->mb_width2; mb_x++) {
if ((ret = decode_mb(a, a->block)) < 0)
return ret;
@@ -253,9 +271,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
}
}
- if (a->mb_width2 != a->mb_width) {
- mb_x = a->mb_width2;
- for (mb_y = 0; mb_y < a->mb_height2; mb_y++) {
+ if (c->mb_width2 != c->mb_width) {
+ int mb_x = c->mb_width2;
+ for (int mb_y = 0; mb_y < c->mb_height2; mb_y++) {
if ((ret = decode_mb(a, a->block)) < 0)
return ret;
@@ -263,9 +281,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
}
}
- if (a->mb_height2 != a->mb_height) {
- mb_y = a->mb_height2;
- for (mb_x = 0; mb_x < a->mb_width; mb_x++) {
+ if (c->mb_height2 != c->mb_height) {
+ int mb_y = c->mb_height2;
+ for (int mb_x = 0; mb_x < c->mb_width; mb_x++) {
if ((ret = decode_mb(a, a->block)) < 0)
return ret;
@@ -275,16 +293,15 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
*got_frame = 1;
- emms_c();
-
return (get_bits_count(&a->gb) + 31) / 32 * 4;
}
static av_cold int decode_init(AVCodecContext *avctx)
{
static AVOnce init_static_once = AV_ONCE_INIT;
- ASV1Context *const a = avctx->priv_data;
+ ASVDecContext *const a = avctx->priv_data;
const int scale = avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2;
+ int inv_qscale;
int i;
if (avctx->extradata_size < 1) {
@@ -292,24 +309,25 @@ static av_cold int decode_init(AVCodecContext *avctx)
}
ff_asv_common_init(avctx);
- ff_blockdsp_init(&a->bdsp, avctx);
+ ff_blockdsp_init(&a->bdsp);
ff_idctdsp_init(&a->idsp, avctx);
- ff_init_scantable(a->idsp.idct_permutation, &a->scantable, ff_asv_scantab);
+ ff_permute_scantable(a->permutated_scantable, ff_asv_scantab,
+ a->idsp.idct_permutation);
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- if (avctx->extradata_size < 1 || (a->inv_qscale = avctx->extradata[0]) == 0) {
+ if (avctx->extradata_size < 1 || (inv_qscale = avctx->extradata[0]) == 0) {
av_log(avctx, AV_LOG_ERROR, "illegal qscale 0\n");
if (avctx->codec_id == AV_CODEC_ID_ASV1)
- a->inv_qscale = 6;
+ inv_qscale = 6;
else
- a->inv_qscale = 10;
+ inv_qscale = 10;
}
for (i = 0; i < 64; i++) {
int index = ff_asv_scantab[i];
a->intra_matrix[i] = 64 * scale * ff_mpeg1_default_intra_matrix[index] /
- a->inv_qscale;
+ inv_qscale;
}
ff_thread_once(&init_static_once, init_vlcs);
@@ -319,7 +337,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
static av_cold int decode_end(AVCodecContext *avctx)
{
- ASV1Context *const a = avctx->priv_data;
+ ASVDecContext *const a = avctx->priv_data;
av_freep(&a->bitstream_buffer);
a->bitstream_buffer_size = 0;
@@ -330,28 +348,26 @@ static av_cold int decode_end(AVCodecContext *avctx)
#if CONFIG_ASV1_DECODER
const FFCodec ff_asv1_decoder = {
.p.name = "asv1",
- .p.long_name = NULL_IF_CONFIG_SMALL("ASUS V1"),
+ CODEC_LONG_NAME("ASUS V1"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_ASV1,
- .priv_data_size = sizeof(ASV1Context),
+ .priv_data_size = sizeof(ASVDecContext),
.init = decode_init,
.close = decode_end,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
#if CONFIG_ASV2_DECODER
const FFCodec ff_asv2_decoder = {
.p.name = "asv2",
- .p.long_name = NULL_IF_CONFIG_SMALL("ASUS V2"),
+ CODEC_LONG_NAME("ASUS V2"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_ASV2,
- .priv_data_size = sizeof(ASV1Context),
+ .priv_data_size = sizeof(ASVDecContext),
.init = decode_init,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
diff --git a/libavcodec/asvenc.c b/libavcodec/asvenc.c
index 520173e6c..4a14bcf8f 100644
--- a/libavcodec/asvenc.c
+++ b/libavcodec/asvenc.c
@@ -27,6 +27,7 @@
#include "libavutil/attributes.h"
#include "libavutil/mem.h"
+#include "libavutil/mem_internal.h"
#include "aandcttab.h"
#include "asv.h"
@@ -36,6 +37,19 @@
#include "encode.h"
#include "fdctdsp.h"
#include "mpeg12data.h"
+#include "pixblockdsp.h"
+#include "put_bits.h"
+
+typedef struct ASVEncContext {
+ ASVCommonContext c;
+
+ PutBitContext pb;
+
+ PixblockDSPContext pdsp;
+ FDCTDSPContext fdsp;
+ DECLARE_ALIGNED(32, int16_t, block)[6][64];
+ int q_intra_matrix[64];
+} ASVEncContext;
static inline void asv1_put_level(PutBitContext *pb, int level)
{
@@ -49,7 +63,7 @@ static inline void asv1_put_level(PutBitContext *pb, int level)
}
}
-static inline void asv2_put_level(ASV1Context *a, PutBitContext *pb, int level)
+static inline void asv2_put_level(ASVEncContext *a, PutBitContext *pb, int level)
{
unsigned int index = level + 31;
@@ -58,14 +72,14 @@ static inline void asv2_put_level(ASV1Context *a, PutBitContext *pb, int level)
} else {
put_bits_le(pb, 5, 0); /* Escape code */
if (level < -128 || level > 127) {
- av_log(a->avctx, AV_LOG_WARNING, "Clipping level %d, increase qscale\n", level);
+ av_log(a->c.avctx, AV_LOG_WARNING, "Clipping level %d, increase qscale\n", level);
level = av_clip_int8(level);
}
put_bits_le(pb, 8, level & 0xFF);
}
}
-static inline void asv1_encode_block(ASV1Context *a, int16_t block[64])
+static inline void asv1_encode_block(ASVEncContext *a, int16_t block[64])
{
int i;
int nc_count = 0;
@@ -111,7 +125,7 @@ static inline void asv1_encode_block(ASV1Context *a, int16_t block[64])
put_bits(&a->pb, 5, 0xF); /* End of block */
}
-static inline void asv2_encode_block(ASV1Context *a, int16_t block[64])
+static inline void asv2_encode_block(ASVEncContext *a, int16_t block[64])
{
int i;
int count = 0;
@@ -166,13 +180,13 @@ static inline void asv2_encode_block(ASV1Context *a, int16_t block[64])
#define MAX_MB_SIZE (30 * 16 * 16 * 3 / 2 / 8)
-static inline int encode_mb(ASV1Context *a, int16_t block[6][64])
+static inline int encode_mb(ASVEncContext *a, int16_t block[6][64])
{
int i;
av_assert0(put_bytes_left(&a->pb, 0) >= MAX_MB_SIZE);
- if (a->avctx->codec_id == AV_CODEC_ID_ASV1) {
+ if (a->c.avctx->codec_id == AV_CODEC_ID_ASV1) {
for (i = 0; i < 6; i++)
asv1_encode_block(a, block[i]);
} else {
@@ -183,16 +197,16 @@ static inline int encode_mb(ASV1Context *a, int16_t block[6][64])
return 0;
}
-static inline void dct_get(ASV1Context *a, const AVFrame *frame,
+static inline void dct_get(ASVEncContext *a, const AVFrame *frame,
int mb_x, int mb_y)
{
int16_t (*block)[64] = a->block;
int linesize = frame->linesize[0];
int i;
- uint8_t *ptr_y = frame->data[0] + (mb_y * 16 * linesize) + mb_x * 16;
- uint8_t *ptr_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8;
- uint8_t *ptr_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8;
+ const uint8_t *ptr_y = frame->data[0] + (mb_y * 16 * linesize) + mb_x * 16;
+ const uint8_t *ptr_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8;
+ const uint8_t *ptr_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8;
a->pdsp.get_pixels(block[0], ptr_y, linesize);
a->pdsp.get_pixels(block[1], ptr_y + 8, linesize);
@@ -201,7 +215,7 @@ static inline void dct_get(ASV1Context *a, const AVFrame *frame,
for (i = 0; i < 4; i++)
a->fdsp.fdct(block[i]);
- if (!(a->avctx->flags & AV_CODEC_FLAG_GRAY)) {
+ if (!(a->c.avctx->flags & AV_CODEC_FLAG_GRAY)) {
a->pdsp.get_pixels(block[4], ptr_cb, frame->linesize[1]);
a->pdsp.get_pixels(block[5], ptr_cr, frame->linesize[2]);
for (i = 4; i < 6; i++)
@@ -212,9 +226,9 @@ static inline void dct_get(ASV1Context *a, const AVFrame *frame,
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *pict, int *got_packet)
{
- ASV1Context *const a = avctx->priv_data;
+ ASVEncContext *const a = avctx->priv_data;
+ const ASVCommonContext *const c = &a->c;
int size, ret;
- int mb_x, mb_y;
if (pict->width % 16 || pict->height % 16) {
AVFrame *clone = av_frame_alloc();
@@ -258,35 +272,34 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
return ret;
}
- if ((ret = ff_alloc_packet(avctx, pkt, a->mb_height * a->mb_width * MAX_MB_SIZE +
+ if ((ret = ff_alloc_packet(avctx, pkt, c->mb_height * c->mb_width * MAX_MB_SIZE +
AV_INPUT_BUFFER_MIN_SIZE)) < 0)
return ret;
init_put_bits(&a->pb, pkt->data, pkt->size);
- for (mb_y = 0; mb_y < a->mb_height2; mb_y++) {
- for (mb_x = 0; mb_x < a->mb_width2; mb_x++) {
+ for (int mb_y = 0; mb_y < c->mb_height2; mb_y++) {
+ for (int mb_x = 0; mb_x < c->mb_width2; mb_x++) {
dct_get(a, pict, mb_x, mb_y);
encode_mb(a, a->block);
}
}
- if (a->mb_width2 != a->mb_width) {
- mb_x = a->mb_width2;
- for (mb_y = 0; mb_y < a->mb_height2; mb_y++) {
+ if (c->mb_width2 != c->mb_width) {
+ int mb_x = c->mb_width2;
+ for (int mb_y = 0; mb_y < c->mb_height2; mb_y++) {
dct_get(a, pict, mb_x, mb_y);
encode_mb(a, a->block);
}
}
- if (a->mb_height2 != a->mb_height) {
- mb_y = a->mb_height2;
- for (mb_x = 0; mb_x < a->mb_width; mb_x++) {
+ if (c->mb_height2 != c->mb_height) {
+ int mb_y = c->mb_height2;
+ for (int mb_x = 0; mb_x < c->mb_width; mb_x++) {
dct_get(a, pict, mb_x, mb_y);
encode_mb(a, a->block);
}
}
- emms_c();
if (avctx->codec_id == AV_CODEC_ID_ASV1)
flush_put_bits(&a->pb);
@@ -296,7 +309,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
size = (put_bytes_output(&a->pb) + 3) / 4;
if (avctx->codec_id == AV_CODEC_ID_ASV1) {
- a->bbdsp.bswap_buf((uint32_t *) pkt->data,
+ c->bbdsp.bswap_buf((uint32_t *) pkt->data,
(uint32_t *) pkt->data, size);
}
@@ -308,9 +321,10 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
static av_cold int encode_init(AVCodecContext *avctx)
{
- ASV1Context *const a = avctx->priv_data;
+ ASVEncContext *const a = avctx->priv_data;
int i;
const int scale = avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2;
+ int inv_qscale;
ff_asv_common_init(avctx);
ff_fdctdsp_init(&a->fdsp, avctx);
@@ -319,23 +333,23 @@ static av_cold int encode_init(AVCodecContext *avctx)
if (avctx->global_quality <= 0)
avctx->global_quality = 4 * FF_QUALITY_SCALE;
- a->inv_qscale = (32 * scale * FF_QUALITY_SCALE +
+ inv_qscale = (32 * scale * FF_QUALITY_SCALE +
avctx->global_quality / 2) / avctx->global_quality;
avctx->extradata = av_mallocz(8);
if (!avctx->extradata)
return AVERROR(ENOMEM);
avctx->extradata_size = 8;
- ((uint32_t *) avctx->extradata)[0] = av_le2ne32(a->inv_qscale);
+ AV_WLA(32, avctx->extradata, inv_qscale);
((uint32_t *) avctx->extradata)[1] = av_le2ne32(AV_RL32("ASUS"));
for (i = 0; i < 64; i++) {
if (a->fdsp.fdct == ff_fdct_ifast) {
int q = 32LL * scale * ff_mpeg1_default_intra_matrix[i] * ff_aanscales[i];
- a->q_intra_matrix[i] = (((int64_t)a->inv_qscale << 30) + q / 2) / q;
+ a->q_intra_matrix[i] = (((int64_t)inv_qscale << 30) + q / 2) / q;
} else {
int q = 32 * scale * ff_mpeg1_default_intra_matrix[i];
- a->q_intra_matrix[i] = ((a->inv_qscale << 16) + q / 2) / q;
+ a->q_intra_matrix[i] = ((inv_qscale << 16) + q / 2) / q;
}
}
@@ -345,29 +359,29 @@ static av_cold int encode_init(AVCodecContext *avctx)
#if CONFIG_ASV1_ENCODER
const FFCodec ff_asv1_encoder = {
.p.name = "asv1",
- .p.long_name = NULL_IF_CONFIG_SMALL("ASUS V1"),
+ CODEC_LONG_NAME("ASUS V1"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_ASV1,
- .priv_data_size = sizeof(ASV1Context),
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ .priv_data_size = sizeof(ASVEncContext),
.init = encode_init,
FF_CODEC_ENCODE_CB(encode_frame),
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
#if CONFIG_ASV2_ENCODER
const FFCodec ff_asv2_encoder = {
.p.name = "asv2",
- .p.long_name = NULL_IF_CONFIG_SMALL("ASUS V2"),
+ CODEC_LONG_NAME("ASUS V2"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_ASV2,
- .priv_data_size = sizeof(ASV1Context),
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ .priv_data_size = sizeof(ASVEncContext),
.init = encode_init,
FF_CODEC_ENCODE_CB(encode_frame),
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c
index 7265891ac..1309bb95a 100644
--- a/libavcodec/atrac1.c
+++ b/libavcodec/atrac1.c
@@ -29,17 +29,15 @@
/* Many thanks to Tim Craig for all the help! */
#include
-#include
-#include
#include "libavutil/float_dsp.h"
#include "libavutil/mem_internal.h"
+#include "libavutil/tx.h"
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "fft.h"
-#include "internal.h"
#include "sinewin.h"
#include "atrac.h"
@@ -82,7 +80,8 @@ typedef struct AT1Ctx {
DECLARE_ALIGNED(32, float, mid)[256];
DECLARE_ALIGNED(32, float, high)[512];
float* bands[3];
- FFTContext mdct_ctx[3];
+ AVTXContext *mdct_ctx[3];
+ av_tx_fn mdct_fn[3];
void (*vector_fmul_window)(float *dst, const float *src0,
const float *src1, const float *win, int len);
} AT1Ctx;
@@ -95,7 +94,8 @@ static const uint8_t mdct_long_nbits[3] = {7, 7, 8};
static void at1_imdct(AT1Ctx *q, float *spec, float *out, int nbits,
int rev_spec)
{
- FFTContext* mdct_context = &q->mdct_ctx[nbits - 5 - (nbits > 6)];
+ AVTXContext *mdct_context = q->mdct_ctx[nbits - 5 - (nbits > 6)];
+ av_tx_fn mdct_fn = q->mdct_fn[nbits - 5 - (nbits > 6)];
int transf_size = 1 << nbits;
if (rev_spec) {
@@ -103,7 +103,7 @@ static void at1_imdct(AT1Ctx *q, float *spec, float *out, int nbits,
for (i = 0; i < transf_size / 2; i++)
FFSWAP(float, spec[i], spec[transf_size - 1 - i]);
}
- mdct_context->imdct_half(mdct_context, out, spec);
+ mdct_fn(mdct_context, out, spec, sizeof(float));
}
@@ -324,9 +324,9 @@ static av_cold int atrac1_decode_end(AVCodecContext * avctx)
{
AT1Ctx *q = avctx->priv_data;
- ff_mdct_end(&q->mdct_ctx[0]);
- ff_mdct_end(&q->mdct_ctx[1]);
- ff_mdct_end(&q->mdct_ctx[2]);
+ av_tx_uninit(&q->mdct_ctx[0]);
+ av_tx_uninit(&q->mdct_ctx[1]);
+ av_tx_uninit(&q->mdct_ctx[2]);
return 0;
}
@@ -337,6 +337,7 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx)
AT1Ctx *q = avctx->priv_data;
AVFloatDSPContext *fdsp;
int channels = avctx->ch_layout.nb_channels;
+ float scale = -1.0 / (1 << 15);
int ret;
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
@@ -353,12 +354,15 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx)
}
/* Init the mdct transforms */
- if ((ret = ff_mdct_init(&q->mdct_ctx[0], 6, 1, -1.0/ (1 << 15))) ||
- (ret = ff_mdct_init(&q->mdct_ctx[1], 8, 1, -1.0/ (1 << 15))) ||
- (ret = ff_mdct_init(&q->mdct_ctx[2], 9, 1, -1.0/ (1 << 15)))) {
- av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n");
+ if ((ret = av_tx_init(&q->mdct_ctx[0], &q->mdct_fn[0], AV_TX_FLOAT_MDCT,
+ 1, 32, &scale, 0) < 0))
+ return ret;
+ if ((ret = av_tx_init(&q->mdct_ctx[1], &q->mdct_fn[1], AV_TX_FLOAT_MDCT,
+ 1, 128, &scale, 0) < 0))
+ return ret;
+ if ((ret = av_tx_init(&q->mdct_ctx[2], &q->mdct_fn[2], AV_TX_FLOAT_MDCT,
+ 1, 256, &scale, 0) < 0))
return ret;
- }
ff_init_ff_sine_windows(5);
@@ -386,7 +390,7 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx)
const FFCodec ff_atrac1_decoder = {
.p.name = "atrac1",
- .p.long_name = NULL_IF_CONFIG_SMALL("ATRAC1 (Adaptive TRansform Acoustic Coding)"),
+ CODEC_LONG_NAME("ATRAC1 (Adaptive TRansform Acoustic Coding)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ATRAC1,
.priv_data_size = sizeof(AT1Ctx),
@@ -396,5 +400,5 @@ const FFCodec ff_atrac1_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c
index d5f6fea4d..7415da590 100644
--- a/libavcodec/atrac3.c
+++ b/libavcodec/atrac3.c
@@ -34,20 +34,19 @@
#include
#include
-#include
#include "libavutil/attributes.h"
#include "libavutil/float_dsp.h"
#include "libavutil/libm.h"
#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"
+#include "libavutil/tx.h"
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "fft.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
#include "atrac.h"
#include "atrac3data.h"
@@ -116,7 +115,8 @@ typedef struct ATRAC3Context {
//@}
AtracGCContext gainc_ctx;
- FFTContext mdct_ctx;
+ AVTXContext *mdct_ctx;
+ av_tx_fn mdct_fn;
void (*vector_fmul)(float *dst, const float *src0, const float *src1,
int len);
} ATRAC3Context;
@@ -148,7 +148,7 @@ static void imlt(ATRAC3Context *q, float *input, float *output, int odd_band)
FFSWAP(float, input[i], input[255 - i]);
}
- q->mdct_ctx.imdct_calc(&q->mdct_ctx, output, input);
+ q->mdct_fn(q->mdct_ctx, output, input, sizeof(float));
/* Perform windowing on the output. */
q->vector_fmul(output, output, mdct_window, MDCT_SIZE);
@@ -202,7 +202,7 @@ static av_cold int atrac3_decode_close(AVCodecContext *avctx)
av_freep(&q->units);
av_freep(&q->decoded_bytes_buffer);
- ff_mdct_end(&q->mdct_ctx);
+ av_tx_uninit(&q->mdct_ctx);
return 0;
}
@@ -880,6 +880,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx)
const uint8_t *edata_ptr = avctx->extradata;
ATRAC3Context *q = avctx->priv_data;
AVFloatDSPContext *fdsp;
+ float scale = 1.0 / 32768;
int channels = avctx->ch_layout.nb_channels;
if (channels < MIN_CHANNELS || channels > MAX_CHANNELS) {
@@ -978,7 +979,8 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx)
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
/* initialize the MDCT transform */
- if ((ret = ff_mdct_init(&q->mdct_ctx, 9, 1, 1.0 / 32768)) < 0) {
+ if ((ret = av_tx_init(&q->mdct_ctx, &q->mdct_fn, AV_TX_FLOAT_MDCT, 1, 256,
+ &scale, AV_TX_FULL_IMDCT)) < 0) {
av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n");
return ret;
}
@@ -1017,7 +1019,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx)
const FFCodec ff_atrac3_decoder = {
.p.name = "atrac3",
- .p.long_name = NULL_IF_CONFIG_SMALL("ATRAC3 (Adaptive TRansform Acoustic Coding 3)"),
+ CODEC_LONG_NAME("ATRAC3 (Adaptive TRansform Acoustic Coding 3)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ATRAC3,
.priv_data_size = sizeof(ATRAC3Context),
@@ -1027,12 +1029,12 @@ const FFCodec ff_atrac3_decoder = {
.p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
const FFCodec ff_atrac3al_decoder = {
.p.name = "atrac3al",
- .p.long_name = NULL_IF_CONFIG_SMALL("ATRAC3 AL (Adaptive TRansform Acoustic Coding 3 Advanced Lossless)"),
+ CODEC_LONG_NAME("ATRAC3 AL (Adaptive TRansform Acoustic Coding 3 Advanced Lossless)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ATRAC3AL,
.priv_data_size = sizeof(ATRAC3Context),
@@ -1042,5 +1044,5 @@ const FFCodec ff_atrac3al_decoder = {
.p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/atrac3plus.c b/libavcodec/atrac3plus.c
index a0836f117..5661654ce 100644
--- a/libavcodec/atrac3plus.c
+++ b/libavcodec/atrac3plus.c
@@ -1391,9 +1391,9 @@ static int decode_band_numwavs(GetBitContext *gb, Atrac3pChanUnitCtx *ctx,
if (band_has_tones[sb]) {
if (ctx->waves_info->tones_index + dst[sb].num_wavs > 48) {
av_log(avctx, AV_LOG_ERROR,
- "Too many tones: %d (max. 48), frame: %d!\n",
+ "Too many tones: %d (max. 48), frame: %"PRId64"!\n",
ctx->waves_info->tones_index + dst[sb].num_wavs,
- avctx->frame_number);
+ avctx->frame_num);
return AVERROR_INVALIDDATA;
}
dst[sb].start_index = ctx->waves_info->tones_index;
diff --git a/libavcodec/atrac3plus.h b/libavcodec/atrac3plus.h
index a588436e2..aa949a7e4 100644
--- a/libavcodec/atrac3plus.h
+++ b/libavcodec/atrac3plus.h
@@ -32,10 +32,10 @@
#include "libavutil/float_dsp.h"
#include "libavutil/mem_internal.h"
+#include "libavutil/tx.h"
#include "atrac.h"
#include "avcodec.h"
-#include "fft.h"
#include "get_bits.h"
/** Global unit sizes */
@@ -172,14 +172,6 @@ void ff_atrac3p_init_vlcs(void);
int ff_atrac3p_decode_channel_unit(GetBitContext *gb, Atrac3pChanUnitCtx *ctx,
int num_channels, AVCodecContext *avctx);
-/**
- * Initialize IMDCT transform.
- *
- * @param[in] avctx ptr to the AVCodecContext
- * @param[in] mdct_ctx pointer to MDCT transform context
- */
-void ff_atrac3p_init_imdct(AVCodecContext *avctx, FFTContext *mdct_ctx);
-
/**
* Initialize sine waves synthesizer and ff_sine_* tables.
*/
@@ -221,8 +213,9 @@ void ff_atrac3p_power_compensation(Atrac3pChanUnitCtx *ctx, AVFloatDSPContext *f
* @param[in] wind_id which MDCT window to apply
* @param[in] sb subband number
*/
-void ff_atrac3p_imdct(AVFloatDSPContext *fdsp, FFTContext *mdct_ctx, float *pIn,
- float *pOut, int wind_id, int sb);
+void ff_atrac3p_imdct(AVFloatDSPContext *fdsp, AVTXContext *mdct_ctx,
+ av_tx_fn mdct_fn, float *pIn, float *pOut,
+ int wind_id, int sb);
/**
* Subband synthesis filter based on the polyphase quadrature (pseudo-QMF)
@@ -233,8 +226,8 @@ void ff_atrac3p_imdct(AVFloatDSPContext *fdsp, FFTContext *mdct_ctx, float *pIn,
* @param[in] in input data to process
* @param[out] out receives processed data
*/
-void ff_atrac3p_ipqf(FFTContext *dct_ctx, Atrac3pIPQFChannelCtx *hist,
- const float *in, float *out);
+void ff_atrac3p_ipqf(AVTXContext *dct_ctx, av_tx_fn dct_fn,
+ Atrac3pIPQFChannelCtx *hist, const float *in, float *out);
extern const uint16_t ff_atrac3p_qu_to_spec_pos[33];
extern const float ff_atrac3p_sf_tab[64];
diff --git a/libavcodec/atrac3plusdec.c b/libavcodec/atrac3plusdec.c
index f87ffb893..aa4d42f44 100644
--- a/libavcodec/atrac3plusdec.c
+++ b/libavcodec/atrac3plusdec.c
@@ -43,11 +43,22 @@
#include "libavutil/thread.h"
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
#include "atrac.h"
#include "atrac3plus.h"
+static const uint8_t channel_map[8][8] = {
+ { 0, },
+ { 0, 1, },
+ { 0, 1, 2, },
+ { 0, 1, 2, 3, },
+ { 0, },
+ { 0, 1, 2, 4, 5, 3, },
+ { 0, 1, 2, 4, 5, 6, 3, },
+ { 0, 1, 2, 4, 5, 6, 7, 3, },
+};
+
typedef struct ATRAC3PContext {
GetBitContext gb;
AVFloatDSPContext *fdsp;
@@ -58,13 +69,16 @@ typedef struct ATRAC3PContext {
DECLARE_ALIGNED(32, float, outp_buf)[2][ATRAC3P_FRAME_SAMPLES];
AtracGCContext gainc_ctx; ///< gain compensation context
- FFTContext mdct_ctx;
- FFTContext ipqf_dct_ctx; ///< IDCT context used by IPQF
+ AVTXContext *mdct_ctx;
+ av_tx_fn mdct_fn;
+ AVTXContext *ipqf_dct_ctx; ///< IDCT context used by IPQF
+ av_tx_fn ipqf_dct_fn;
Atrac3pChanUnitCtx *ch_units; ///< global channel units
int num_channel_blocks; ///< number of channel blocks
uint8_t channel_blocks[5]; ///< channel configuration descriptor
+ const uint8_t *channel_map; ///< channel layout map
} ATRAC3PContext;
static av_cold int atrac3p_decode_close(AVCodecContext *avctx)
@@ -74,8 +88,8 @@ static av_cold int atrac3p_decode_close(AVCodecContext *avctx)
av_freep(&ctx->ch_units);
av_freep(&ctx->fdsp);
- ff_mdct_end(&ctx->mdct_ctx);
- ff_mdct_end(&ctx->ipqf_dct_ctx);
+ av_tx_uninit(&ctx->mdct_ctx);
+ av_tx_uninit(&ctx->ipqf_dct_ctx);
return 0;
}
@@ -143,6 +157,8 @@ static av_cold int set_channel_params(ATRAC3PContext *ctx,
return AVERROR_INVALIDDATA;
}
+ ctx->channel_map = channel_map[channels - 1];
+
return 0;
}
@@ -156,6 +172,7 @@ static av_cold int atrac3p_decode_init(AVCodecContext *avctx)
{
static AVOnce init_static_once = AV_ONCE_INIT;
ATRAC3PContext *ctx = avctx->priv_data;
+ float scale;
int i, ch, ret;
if (!avctx->block_align) {
@@ -164,9 +181,17 @@ static av_cold int atrac3p_decode_init(AVCodecContext *avctx)
}
/* initialize IPQF */
- ff_mdct_init(&ctx->ipqf_dct_ctx, 5, 1, 32.0 / 32768.0);
+ scale = 32.0 / 32768.0;
+ ret = av_tx_init(&ctx->ipqf_dct_ctx, &ctx->ipqf_dct_fn, AV_TX_FLOAT_MDCT,
+ 1, 16, &scale, 0);
+ if (ret < 0)
+ return ret;
- ff_atrac3p_init_imdct(avctx, &ctx->mdct_ctx);
+ scale = -1.0f;
+ ret = av_tx_init(&ctx->mdct_ctx, &ctx->mdct_fn, AV_TX_FLOAT_MDCT,
+ 1, 128, &scale, AV_TX_FULL_IMDCT);
+ if (ret < 0)
+ return ret;
ff_atrac_init_gain_compensation(&ctx->gainc_ctx, 6, 2);
@@ -274,7 +299,7 @@ static void reconstruct_frame(ATRAC3PContext *ctx, Atrac3pChanUnitCtx *ch_unit,
for (ch = 0; ch < num_channels; ch++) {
for (sb = 0; sb < ch_unit->num_subbands; sb++) {
/* inverse transform and windowing */
- ff_atrac3p_imdct(ctx->fdsp, &ctx->mdct_ctx,
+ ff_atrac3p_imdct(ctx->fdsp, ctx->mdct_ctx, ctx->mdct_fn,
&ctx->samples[ch][sb * ATRAC3P_SUBBAND_SAMPLES],
&ctx->mdct_buf[ch][sb * ATRAC3P_SUBBAND_SAMPLES],
(ch_unit->channels[ch].wnd_shape_prev[sb] << 1) +
@@ -314,8 +339,9 @@ static void reconstruct_frame(ATRAC3PContext *ctx, Atrac3pChanUnitCtx *ch_unit,
}
/* subband synthesis and acoustic signal output */
- ff_atrac3p_ipqf(&ctx->ipqf_dct_ctx, &ch_unit->ipqf_ctx[ch],
- &ctx->time_buf[ch][0], &ctx->outp_buf[ch][0]);
+ ff_atrac3p_ipqf(ctx->ipqf_dct_ctx, ctx->ipqf_dct_fn,
+ &ch_unit->ipqf_ctx[ch], &ctx->time_buf[ch][0],
+ &ctx->outp_buf[ch][0]);
}
/* swap window shape and gain control buffers. */
@@ -378,7 +404,7 @@ static int atrac3p_decode_frame(AVCodecContext *avctx, AVFrame *frame,
channels_to_process, avctx);
for (i = 0; i < channels_to_process; i++)
- memcpy(samples_p[out_ch_index + i], ctx->outp_buf[i],
+ memcpy(samples_p[ctx->channel_map[out_ch_index + i]], ctx->outp_buf[i],
ATRAC3P_FRAME_SAMPLES * sizeof(**samples_p));
ch_block++;
@@ -392,11 +418,11 @@ static int atrac3p_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_atrac3p_decoder = {
.p.name = "atrac3plus",
- .p.long_name = NULL_IF_CONFIG_SMALL("ATRAC3+ (Adaptive TRansform Acoustic Coding 3+)"),
+ CODEC_LONG_NAME("ATRAC3+ (Adaptive TRansform Acoustic Coding 3+)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ATRAC3P,
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.priv_data_size = sizeof(ATRAC3PContext),
.init = atrac3p_decode_init,
.close = atrac3p_decode_close,
@@ -405,11 +431,11 @@ const FFCodec ff_atrac3p_decoder = {
const FFCodec ff_atrac3pal_decoder = {
.p.name = "atrac3plusal",
- .p.long_name = NULL_IF_CONFIG_SMALL("ATRAC3+ AL (Adaptive TRansform Acoustic Coding 3+ Advanced Lossless)"),
+ CODEC_LONG_NAME("ATRAC3+ AL (Adaptive TRansform Acoustic Coding 3+ Advanced Lossless)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ATRAC3PAL,
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.priv_data_size = sizeof(ATRAC3PContext),
.init = atrac3p_decode_init,
.close = atrac3p_decode_close,
diff --git a/libavcodec/atrac3plusdsp.c b/libavcodec/atrac3plusdsp.c
index e32c5c817..802f12aec 100644
--- a/libavcodec/atrac3plusdsp.c
+++ b/libavcodec/atrac3plusdsp.c
@@ -31,9 +31,7 @@
#include "libavutil/libm.h"
#include "libavutil/mem_internal.h"
-#include "avcodec.h"
#include "sinewin.h"
-#include "fft.h"
#include "atrac3plus.h"
/**
@@ -79,12 +77,6 @@ const float ff_atrac3p_mant_tab[8] = {
#define ATRAC3P_MDCT_SIZE (ATRAC3P_SUBBAND_SAMPLES * 2)
-av_cold void ff_atrac3p_init_imdct(AVCodecContext *avctx, FFTContext *mdct_ctx)
-{
- /* Initialize the MDCT transform. */
- ff_mdct_init(mdct_ctx, 8, 1, -1.0);
-}
-
#define TWOPI (2 * M_PI)
#define DEQUANT_PHASE(ph) (((ph) & 0x1F) << 6)
@@ -463,8 +455,9 @@ void ff_atrac3p_power_compensation(Atrac3pChanUnitCtx *ctx, AVFloatDSPContext *f
}
}
-void ff_atrac3p_imdct(AVFloatDSPContext *fdsp, FFTContext *mdct_ctx, float *pIn,
- float *pOut, int wind_id, int sb)
+void ff_atrac3p_imdct(AVFloatDSPContext *fdsp, AVTXContext *mdct_ctx,
+ av_tx_fn mdct_fn, float *pIn, float *pOut,
+ int wind_id, int sb)
{
int i;
@@ -472,7 +465,7 @@ void ff_atrac3p_imdct(AVFloatDSPContext *fdsp, FFTContext *mdct_ctx, float *pIn,
for (i = 0; i < ATRAC3P_SUBBAND_SAMPLES / 2; i++)
FFSWAP(float, pIn[i], pIn[ATRAC3P_SUBBAND_SAMPLES - 1 - i]);
- mdct_ctx->imdct_calc(mdct_ctx, pOut, pIn);
+ mdct_fn(mdct_ctx, pOut, pIn, sizeof(float));
/* Perform windowing on the output.
* ATRAC3+ uses two different MDCT windows:
@@ -604,8 +597,8 @@ static const float ipqf_coeffs2[ATRAC3P_PQF_FIR_LEN][16] = {
-4.4400572e-8, -4.2005411e-7, -8.0604229e-7, -5.8336207e-7 }
};
-void ff_atrac3p_ipqf(FFTContext *dct_ctx, Atrac3pIPQFChannelCtx *hist,
- const float *in, float *out)
+void ff_atrac3p_ipqf(AVTXContext *dct_ctx, av_tx_fn dct_fn,
+ Atrac3pIPQFChannelCtx *hist, const float *in, float *out)
{
int i, s, sb, t, pos_now, pos_next;
LOCAL_ALIGNED(32, float, idct_in, [ATRAC3P_SUBBANDS]);
@@ -619,7 +612,7 @@ void ff_atrac3p_ipqf(FFTContext *dct_ctx, Atrac3pIPQFChannelCtx *hist,
idct_in[sb] = in[sb * ATRAC3P_SUBBAND_SAMPLES + s];
/* Calculate the sine and cosine part of the PQF using IDCT-IV */
- dct_ctx->imdct_half(dct_ctx, idct_out, idct_in);
+ dct_fn(dct_ctx, idct_out, idct_in, sizeof(float));
/* append the result to the history */
for (i = 0; i < 8; i++) {
diff --git a/libavcodec/atrac9dec.c b/libavcodec/atrac9dec.c
index 6c1f0d175..60962b167 100644
--- a/libavcodec/atrac9dec.c
+++ b/libavcodec/atrac9dec.c
@@ -23,10 +23,10 @@
#include "libavutil/thread.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "fft.h"
#include "atrac9tab.h"
+#include "libavutil/tx.h"
#include "libavutil/lfg.h"
#include "libavutil/float_dsp.h"
#include "libavutil/mem_internal.h"
@@ -86,7 +86,8 @@ typedef struct ATRAC9BlockData {
typedef struct ATRAC9Context {
AVCodecContext *avctx;
AVFloatDSPContext *fdsp;
- FFTContext imdct;
+ AVTXContext *tx;
+ av_tx_fn tx_fn;
ATRAC9BlockData block[5];
AVLFG lfg;
@@ -101,7 +102,7 @@ typedef struct ATRAC9Context {
uint8_t alloc_curve[48][48];
DECLARE_ALIGNED(32, float, imdct_win)[256];
- DECLARE_ALIGNED(32, float, temp)[256];
+ DECLARE_ALIGNED(32, float, temp)[2048];
} ATRAC9Context;
static VLC sf_vlc[2][8]; /* Signed/unsigned, length */
@@ -778,7 +779,7 @@ imdct:
const ptrdiff_t offset = wsize*frame_idx*sizeof(float);
float *dst = (float *)(frame->extended_data[dst_idx] + offset);
- s->imdct.imdct_half(&s->imdct, s->temp, c->coeffs);
+ s->tx_fn(s->tx, s->temp, c->coeffs, sizeof(float));
s->fdsp->vector_fmul_window(dst, c->prev_win, s->temp,
s->imdct_win, wsize >> 1);
memcpy(c->prev_win, s->temp + (wsize >> 1), sizeof(float)*wsize >> 1);
@@ -834,7 +835,7 @@ static av_cold int atrac9_decode_close(AVCodecContext *avctx)
{
ATRAC9Context *s = avctx->priv_data;
- ff_mdct_end(&s->imdct);
+ av_tx_uninit(&s->tx);
av_freep(&s->fdsp);
return 0;
@@ -896,10 +897,11 @@ static av_cold void atrac9_init_static(void)
static av_cold int atrac9_decode_init(AVCodecContext *avctx)
{
+ float scale;
static AVOnce static_table_init = AV_ONCE_INIT;
GetBitContext gb;
ATRAC9Context *s = avctx->priv_data;
- int version, block_config_idx, superframe_idx, alloc_c_len;
+ int err, version, block_config_idx, superframe_idx, alloc_c_len;
s->avctx = avctx;
@@ -959,8 +961,11 @@ static av_cold int atrac9_decode_init(AVCodecContext *avctx)
s->frame_count = 1 << superframe_idx;
s->frame_log2 = at9_tab_sri_frame_log2[s->samplerate_idx];
- if (ff_mdct_init(&s->imdct, s->frame_log2 + 1, 1, 1.0f / 32768.0f))
- return AVERROR(ENOMEM);
+ scale = 1.0f / 32768.0;
+ err = av_tx_init(&s->tx, &s->tx_fn, AV_TX_FLOAT_MDCT, 1,
+ 1 << s->frame_log2, &scale, 0);
+ if (err < 0)
+ return err;
s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
if (!s->fdsp)
@@ -989,7 +994,7 @@ static av_cold int atrac9_decode_init(AVCodecContext *avctx)
const FFCodec ff_atrac9_decoder = {
.p.name = "atrac9",
- .p.long_name = NULL_IF_CONFIG_SMALL("ATRAC9 (Adaptive TRansform Acoustic Coding 9)"),
+ CODEC_LONG_NAME("ATRAC9 (Adaptive TRansform Acoustic Coding 9)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ATRAC9,
.priv_data_size = sizeof(ATRAC9Context),
@@ -997,6 +1002,6 @@ const FFCodec ff_atrac9_decoder = {
.close = atrac9_decode_close,
FF_CODEC_DECODE_CB(atrac9_decode_frame),
.flush = atrac9_decode_flush,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
};
diff --git a/libavcodec/audio_frame_queue.c b/libavcodec/audio_frame_queue.c
index f2ccd6928..08b4b368c 100644
--- a/libavcodec/audio_frame_queue.c
+++ b/libavcodec/audio_frame_queue.c
@@ -22,7 +22,7 @@
#include "libavutil/attributes.h"
#include "libavutil/common.h"
#include "audio_frame_queue.h"
-#include "internal.h"
+#include "encode.h"
#include "libavutil/avassert.h"
av_cold void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
diff --git a/libavcodec/audiodsp.c b/libavcodec/audiodsp.c
index ff43e87dc..eba6e809f 100644
--- a/libavcodec/audiodsp.c
+++ b/libavcodec/audiodsp.c
@@ -113,6 +113,8 @@ av_cold void ff_audiodsp_init(AudioDSPContext *c)
ff_audiodsp_init_arm(c);
#elif ARCH_PPC
ff_audiodsp_init_ppc(c);
+#elif ARCH_RISCV
+ ff_audiodsp_init_riscv(c);
#elif ARCH_X86
ff_audiodsp_init_x86(c);
#endif
diff --git a/libavcodec/audiodsp.h b/libavcodec/audiodsp.h
index aa6fa7898..485b51283 100644
--- a/libavcodec/audiodsp.h
+++ b/libavcodec/audiodsp.h
@@ -55,6 +55,7 @@ typedef struct AudioDSPContext {
void ff_audiodsp_init(AudioDSPContext *c);
void ff_audiodsp_init_arm(AudioDSPContext *c);
void ff_audiodsp_init_ppc(AudioDSPContext *c);
+void ff_audiodsp_init_riscv(AudioDSPContext *c);
void ff_audiodsp_init_x86(AudioDSPContext *c);
#endif /* AVCODEC_AUDIODSP_H */
diff --git a/libavcodec/audiotoolboxdec.c b/libavcodec/audiotoolboxdec.c
index daccf4abf..82babe3d3 100644
--- a/libavcodec/audiotoolboxdec.c
+++ b/libavcodec/audiotoolboxdec.c
@@ -28,7 +28,7 @@
#include "ac3_parser_internal.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "mpegaudiodecheader.h"
#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
@@ -591,7 +591,7 @@ static av_cold int ffat_close_decoder(AVCodecContext *avctx)
FFAT_DEC_CLASS(NAME) \
const FFCodec ff_##NAME##_at_decoder = { \
.p.name = #NAME "_at", \
- .p.long_name = NULL_IF_CONFIG_SMALL(#NAME " (AudioToolbox)"), \
+ CODEC_LONG_NAME(#NAME " (AudioToolbox)"), \
.p.type = AVMEDIA_TYPE_AUDIO, \
.p.id = ID, \
.priv_data_size = sizeof(ATDecodeContext), \
@@ -602,7 +602,7 @@ static av_cold int ffat_close_decoder(AVCodecContext *avctx)
.p.priv_class = &ffat_##NAME##_dec_class, \
.bsfs = bsf_name, \
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_CHANNEL_CONF, \
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, \
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \
.p.wrapper_name = "at", \
};
diff --git a/libavcodec/audiotoolboxenc.c b/libavcodec/audiotoolboxenc.c
index 00293154b..1ccfda4d2 100644
--- a/libavcodec/audiotoolboxenc.c
+++ b/libavcodec/audiotoolboxenc.c
@@ -554,13 +554,12 @@ static int ffat_encode(AVCodecContext *avctx, AVPacket *avpkt,
avctx->frame_size,
&avpkt->pts,
&avpkt->duration);
- ret = 0;
} else if (ret && ret != 1) {
av_log(avctx, AV_LOG_ERROR, "Encode error: %i\n", ret);
- ret = AVERROR_EXTERNAL;
+ return AVERROR_EXTERNAL;
}
- return ret;
+ return 0;
}
static av_cold void ffat_encode_flush(AVCodecContext *avctx)
@@ -617,7 +616,7 @@ static const AVOption options[] = {
FFAT_ENC_CLASS(NAME) \
const FFCodec ff_##NAME##_at_encoder = { \
.p.name = #NAME "_at", \
- .p.long_name = NULL_IF_CONFIG_SMALL(#NAME " (AudioToolbox)"), \
+ CODEC_LONG_NAME(#NAME " (AudioToolbox)"), \
.p.type = AVMEDIA_TYPE_AUDIO, \
.p.id = ID, \
.priv_data_size = sizeof(ATDecodeContext), \
@@ -628,13 +627,12 @@ static const AVOption options[] = {
.p.priv_class = &ffat_##NAME##_enc_class, \
.p.capabilities = AV_CODEC_CAP_DELAY | \
AV_CODEC_CAP_ENCODER_FLUSH CAPS, \
- .p.channel_layouts = CHANNEL_LAYOUTS, \
+ CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(CHANNEL_LAYOUTS) \
.p.ch_layouts = CH_LAYOUTS, \
.p.sample_fmts = (const enum AVSampleFormat[]) { \
AV_SAMPLE_FMT_S16, \
AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_NONE \
}, \
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, \
.p.profiles = PROFILES, \
.p.wrapper_name = "at", \
};
diff --git a/libavcodec/aura.c b/libavcodec/aura.c
index b4167cacf..78914fe9f 100644
--- a/libavcodec/aura.c
+++ b/libavcodec/aura.c
@@ -25,7 +25,7 @@
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "libavutil/internal.h"
static av_cold int aura_decode_init(AVCodecContext *avctx)
@@ -98,11 +98,10 @@ static int aura_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_aura2_decoder = {
.p.name = "aura2",
- .p.long_name = NULL_IF_CONFIG_SMALL("Auravision Aura 2"),
+ CODEC_LONG_NAME("Auravision Aura 2"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AURA2,
.init = aura_decode_init,
FF_CODEC_DECODE_CB(aura_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/av1_parser.c b/libavcodec/av1_parser.c
index 4cbd7408a..14dae92fe 100644
--- a/libavcodec/av1_parser.c
+++ b/libavcodec/av1_parser.c
@@ -162,8 +162,11 @@ static int av1_parser_parse(AVCodecParserContext *ctx,
avctx->color_trc = (enum AVColorTransferCharacteristic) color->transfer_characteristics;
avctx->color_range = color->color_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
- if (avctx->framerate.num)
- avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));
+ if (seq->timing_info_present_flag) {
+ const AV1RawTimingInfo *timing = &seq->timing_info;
+ av_reduce(&avctx->framerate.den, &avctx->framerate.num,
+ timing->num_units_in_display_tick, timing->time_scale, INT_MAX);
+ }
end:
ff_cbs_fragment_reset(td);
diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c
index dd83373dd..d83c902f1 100644
--- a/libavcodec/av1dec.c
+++ b/libavcodec/av1dec.c
@@ -27,8 +27,8 @@
#include "av1dec.h"
#include "bytestream.h"
#include "codec_internal.h"
+#include "decode.h"
#include "hwconfig.h"
-#include "internal.h"
#include "profiles.h"
#include "thread.h"
@@ -194,7 +194,7 @@ static uint8_t get_shear_params_valid(AV1DecContext *s, int idx)
}
/**
-* update gm type/params, since cbs already implemented part of this funcation,
+* update gm type/params, since cbs already implemented part of this function,
* so we don't need to full implement spec.
*/
static void global_motion_params(AV1DecContext *s)
@@ -567,7 +567,7 @@ static int get_pixel_format(AVCodecContext *avctx)
* implemented in the future, need remove this check.
*/
if (!avctx->hwaccel) {
- av_log(avctx, AV_LOG_ERROR, "Your platform doesn't suppport"
+ av_log(avctx, AV_LOG_ERROR, "Your platform doesn't support"
" hardware accelerated AV1 decoding.\n");
return AVERROR(ENOSYS);
}
@@ -1247,7 +1247,7 @@ static const AVClass av1_class = {
const FFCodec ff_av1_decoder = {
.p.name = "av1",
- .p.long_name = NULL_IF_CONFIG_SMALL("Alliance for Open Media AV1"),
+ CODEC_LONG_NAME("Alliance for Open Media AV1"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AV1,
.priv_data_size = sizeof(AV1DecContext),
@@ -1255,8 +1255,7 @@ const FFCodec ff_av1_decoder = {
.close = av1_decode_free,
FF_CODEC_DECODE_CB(av1_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP |
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP |
FF_CODEC_CAP_SETS_PKT_DTS,
.flush = av1_decode_flush,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles),
diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
index 5f6e71a39..fb1362290 100644
--- a/libavcodec/avcodec.c
+++ b/libavcodec/avcodec.c
@@ -72,13 +72,13 @@ static AVMutex codec_mutex = AV_MUTEX_INITIALIZER;
static void lock_avcodec(const FFCodec *codec)
{
- if (!(codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE) && codec->init)
+ if (codec->caps_internal & FF_CODEC_CAP_NOT_INIT_THREADSAFE && codec->init)
ff_mutex_lock(&codec_mutex);
}
static void unlock_avcodec(const FFCodec *codec)
{
- if (!(codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE) && codec->init)
+ if (codec->caps_internal & FF_CODEC_CAP_NOT_INIT_THREADSAFE && codec->init)
ff_mutex_unlock(&codec_mutex);
}
@@ -161,8 +161,6 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
goto free_and_end;
}
- avci->skip_samples_multiplier = 1;
-
if (codec2->priv_data_size > 0) {
if (!avctx->priv_data) {
avctx->priv_data = av_mallocz(codec2->priv_data_size);
@@ -234,26 +232,46 @@ FF_DISABLE_DEPRECATION_WARNINGS
if (avctx->channel_layout && !avctx->channels)
avctx->channels = av_popcount64(avctx->channel_layout);
- if ((avctx->channels > 0 && avctx->ch_layout.nb_channels != avctx->channels) ||
+ if ((avctx->channels && avctx->ch_layout.nb_channels != avctx->channels) ||
(avctx->channel_layout && (avctx->ch_layout.order != AV_CHANNEL_ORDER_NATIVE ||
avctx->ch_layout.u.mask != avctx->channel_layout))) {
+ av_channel_layout_uninit(&avctx->ch_layout);
if (avctx->channel_layout) {
av_channel_layout_from_mask(&avctx->ch_layout, avctx->channel_layout);
} else {
avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
- avctx->ch_layout.nb_channels = avctx->channels;
}
+ avctx->ch_layout.nb_channels = avctx->channels;
}
FF_ENABLE_DEPRECATION_WARNINGS
#endif
+ /* AV_CODEC_CAP_CHANNEL_CONF is a decoder-only flag; so the code below
+ * in particular checks that nb_channels is set for all audio encoders. */
+ if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && !avctx->ch_layout.nb_channels
+ && !(codec->capabilities & AV_CODEC_CAP_CHANNEL_CONF)) {
+ av_log(avctx, AV_LOG_ERROR, "%s requires channel layout to be set\n",
+ av_codec_is_decoder(codec) ? "Decoder" : "Encoder");
+ ret = AVERROR(EINVAL);
+ goto free_and_end;
+ }
+ if (avctx->ch_layout.nb_channels && !av_channel_layout_check(&avctx->ch_layout)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid channel layout\n");
+ ret = AVERROR(EINVAL);
+ goto free_and_end;
+ }
if (avctx->ch_layout.nb_channels > FF_SANE_NB_CHANNELS) {
av_log(avctx, AV_LOG_ERROR, "Too many channels: %d\n", avctx->ch_layout.nb_channels);
ret = AVERROR(EINVAL);
goto free_and_end;
}
- avctx->frame_number = 0;
+ avctx->frame_num = 0;
+#if FF_API_AVCTX_FRAME_NUMBER
+FF_DISABLE_DEPRECATION_WARNINGS
+ avctx->frame_number = avctx->frame_num;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
avctx->codec_descriptor = avcodec_descriptor_get(avctx->codec_id);
if ((avctx->codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) &&
@@ -285,14 +303,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (ret < 0)
goto free_and_end;
- if (CONFIG_FRAME_THREAD_ENCODER && av_codec_is_encoder(avctx->codec)) {
- ret = ff_frame_thread_encoder_init(avctx);
- if (ret < 0)
- goto free_and_end;
- }
-
- if (HAVE_THREADS
- && !(avci->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME))) {
+ if (HAVE_THREADS && !avci->frame_thread_encoder) {
/* Frame-threaded decoders call FFCodec.init for their child contexts. */
lock_avcodec(codec2);
ret = ff_thread_init(avctx);
@@ -330,24 +341,12 @@ FF_DISABLE_DEPRECATION_WARNINGS
avctx->channels = avctx->ch_layout.nb_channels;
avctx->channel_layout = avctx->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
avctx->ch_layout.u.mask : 0;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
/* validate channel layout from the decoder */
- if (avctx->channel_layout) {
- int channels = av_get_channel_layout_nb_channels(avctx->channel_layout);
- if (!avctx->channels)
- avctx->channels = channels;
- else if (channels != avctx->channels) {
- char buf[512];
- av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout);
- av_log(avctx, AV_LOG_WARNING,
- "Channel layout '%s' with %d channels does not match specified number of channels %d: "
- "ignoring specified channel layout\n",
- buf, channels, avctx->channels);
- avctx->channel_layout = 0;
- }
- }
- if (avctx->channels && avctx->channels < 0 ||
- avctx->channels > FF_SANE_NB_CHANNELS) {
+ if ((avctx->ch_layout.nb_channels && !av_channel_layout_check(&avctx->ch_layout)) ||
+ avctx->ch_layout.nb_channels > FF_SANE_NB_CHANNELS) {
ret = AVERROR(EINVAL);
goto free_and_end;
}
@@ -355,13 +354,6 @@ FF_DISABLE_DEPRECATION_WARNINGS
ret = AVERROR(EINVAL);
goto free_and_end;
}
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
-#if FF_API_AVCTX_TIMEBASE
- if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
- avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));
-#endif
}
if (codec->priv_class)
av_assert0(*(const AVClass **)avctx->priv_data == codec->priv_class);
@@ -390,11 +382,10 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
}
if (avci->in_frame)
av_frame_unref(avci->in_frame);
+ if (avci->recon_frame)
+ av_frame_unref(avci->recon_frame);
} else {
av_packet_unref(avci->last_pkt_props);
- while (av_fifo_read(avci->pkt_props, avci->last_pkt_props, 1) >= 0)
- av_packet_unref(avci->last_pkt_props);
-
av_packet_unref(avci->in_pkt);
avctx->pts_correction_last_pts =
@@ -459,17 +450,11 @@ av_cold int avcodec_close(AVCodecContext *avctx)
av_freep(&avci->byte_buffer);
av_frame_free(&avci->buffer_frame);
av_packet_free(&avci->buffer_pkt);
- if (avci->pkt_props) {
- while (av_fifo_can_read(avci->pkt_props)) {
- av_packet_unref(avci->last_pkt_props);
- av_fifo_read(avci->pkt_props, avci->last_pkt_props, 1);
- }
- av_fifo_freep2(&avci->pkt_props);
- }
av_packet_free(&avci->last_pkt_props);
av_packet_free(&avci->in_pkt);
av_frame_free(&avci->in_frame);
+ av_frame_free(&avci->recon_frame);
av_buffer_unref(&avci->pool);
@@ -481,6 +466,10 @@ av_cold int avcodec_close(AVCodecContext *avctx)
av_channel_layout_uninit(&avci->initial_ch_layout);
+#if CONFIG_LCMS2
+ ff_icc_context_uninit(&avci->icc);
+#endif
+
av_freep(&avctx->internal);
}
@@ -716,3 +705,12 @@ int avcodec_is_open(AVCodecContext *s)
{
return !!s->internal;
}
+
+int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
+{
+ av_frame_unref(frame);
+
+ if (av_codec_is_decoder(avctx->codec))
+ return ff_decode_receive_frame(avctx, frame);
+ return ff_encode_receive_frame(avctx, frame);
+}
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index cb5c25bf6..39881a1d2 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -231,6 +231,58 @@ typedef struct RcOverride{
* decoded frame in stream.
*/
#define AV_CODEC_FLAG_DROPCHANGED (1 << 5)
+/**
+ * Request the encoder to output reconstructed frames, i.e.\ frames that would
+ * be produced by decoding the encoded bistream. These frames may be retrieved
+ * by calling avcodec_receive_frame() immediately after a successful call to
+ * avcodec_receive_packet().
+ *
+ * Should only be used with encoders flagged with the
+ * @ref AV_CODEC_CAP_ENCODER_RECON_FRAME capability.
+ */
+#define AV_CODEC_FLAG_RECON_FRAME (1 << 6)
+/**
+ * @par decoding
+ * Request the decoder to propagate each packets AVPacket.opaque and
+ * AVPacket.opaque_ref to its corresponding output AVFrame.
+ *
+ * @par encoding:
+ * Request the encoder to propagate each frame's AVFrame.opaque and
+ * AVFrame.opaque_ref values to its corresponding output AVPacket.
+ *
+ * @par
+ * May only be set on encoders that have the
+ * @ref AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability flag.
+ *
+ * @note
+ * While in typical cases one input frame produces exactly one output packet
+ * (perhaps after a delay), in general the mapping of frames to packets is
+ * M-to-N, so
+ * - Any number of input frames may be associated with any given output packet.
+ * This includes zero - e.g. some encoders may output packets that carry only
+ * metadata about the whole stream.
+ * - A given input frame may be associated with any number of output packets.
+ * Again this includes zero - e.g. some encoders may drop frames under certain
+ * conditions.
+ * .
+ * This implies that when using this flag, the caller must NOT assume that
+ * - a given input frame's opaques will necessarily appear on some output packet;
+ * - every output packet will have some non-NULL opaque value.
+ * .
+ * When an output packet contains multiple frames, the opaque values will be
+ * taken from the first of those.
+ *
+ * @note
+ * The converse holds for decoders, with frames and packets switched.
+ */
+#define AV_CODEC_FLAG_COPY_OPAQUE (1 << 7)
+/**
+ * Signal to the encoder that the values of AVFrame.duration are valid and
+ * should be used (typically for transferring them to output packets).
+ *
+ * If this flag is not set, frame durations are ignored.
+ */
+#define AV_CODEC_FLAG_FRAME_DURATION (1 << 8)
/**
* Use internal 2pass ratecontrol in first pass mode.
*/
@@ -251,15 +303,6 @@ typedef struct RcOverride{
* error[?] variables will be set during encoding.
*/
#define AV_CODEC_FLAG_PSNR (1 << 15)
-#if FF_API_FLAG_TRUNCATED
-/**
- * Input bitstream might be truncated at a random location
- * instead of only at frame boundaries.
- *
- * @deprecated use codec parsers for packetizing input
- */
-#define AV_CODEC_FLAG_TRUNCATED (1 << 16)
-#endif
/**
* Use interlaced DCT.
*/
@@ -300,11 +343,6 @@ typedef struct RcOverride{
*/
#define AV_CODEC_FLAG2_LOCAL_HEADER (1 << 3)
-/**
- * timecode is in drop frame format. DEPRECATED!!!!
- */
-#define AV_CODEC_FLAG2_DROP_FRAME_TIMECODE (1 << 13)
-
/**
* Input bitstream might be truncated at a packet boundaries
* instead of only at frame boundaries.
@@ -331,13 +369,12 @@ typedef struct RcOverride{
* Do not reset ASS ReadOrder field on flush (subtitles decoding)
*/
#define AV_CODEC_FLAG2_RO_FLUSH_NOOP (1 << 30)
-
-/* Unsupported options :
- * Syntax Arithmetic coding (SAC)
- * Reference Picture Selection
- * Independent Segment Decoding */
-/* /Fx */
-/* codec capabilities */
+/**
+ * Generate/parse ICC profiles on encode/decode, as appropriate for the type of
+ * file. No effect on codecs which cannot contain embedded ICC profiles, or
+ * when compiled without support for lcms2.
+ */
+#define AV_CODEC_FLAG2_ICC_PROFILES (1U << 31)
/* Exported side data.
These flags can be passed in AVCodecContext.export_side_data before initialization.
@@ -506,8 +543,7 @@ typedef struct AVCodecContext {
* (fixed_vop_rate == 0 implies that it is different from the framerate)
*
* - encoding: MUST be set by user.
- * - decoding: the use of this field for decoding is deprecated.
- * Use framerate instead.
+ * - decoding: unused.
*/
AVRational time_base;
@@ -1025,6 +1061,7 @@ typedef struct AVCodecContext {
*/
int frame_size;
+#if FF_API_AVCTX_FRAME_NUMBER
/**
* Frame counter, set by libavcodec.
*
@@ -1033,8 +1070,11 @@ typedef struct AVCodecContext {
*
* @note the counter is not incremented if encoding/decoding resulted in
* an error.
+ * @deprecated use frame_num instead
*/
+ attribute_deprecated
int frame_number;
+#endif
/**
* number of bytes per packet if constant and known or 0
@@ -1296,13 +1336,9 @@ typedef struct AVCodecContext {
* unofficial and experimental (that is, they always try to decode things
* when they can) unless they are explicitly asked to behave stupidly
* (=strictly conform to the specs)
+ * This may only be set to one of the FF_COMPLIANCE_* values in defs.h.
*/
int strict_std_compliance;
-#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to an older more strict version of the spec or reference software.
-#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences.
-#define FF_COMPLIANCE_NORMAL 0
-#define FF_COMPLIANCE_UNOFFICIAL -1 ///< Allow unofficial extensions
-#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things.
/**
* error concealment flags
@@ -1338,28 +1374,14 @@ typedef struct AVCodecContext {
/**
* Error recognition; may misdetect some more or less valid parts as errors.
+ * This is a bitfield of the AV_EF_* values defined in defs.h.
+ *
* - encoding: Set by user.
* - decoding: Set by user.
*/
int err_recognition;
-/**
- * Verify checksums embedded in the bitstream (could be of either encoded or
- * decoded data, depending on the codec) and print an error message on mismatch.
- * If AV_EF_EXPLODE is also set, a mismatching checksum will result in the
- * decoder returning an error.
- */
-#define AV_EF_CRCCHECK (1<<0)
-#define AV_EF_BITSTREAM (1<<1) ///< detect bitstream specification deviations
-#define AV_EF_BUFFER (1<<2) ///< detect improper bitstream length
-#define AV_EF_EXPLODE (1<<3) ///< abort decoding on minor error detection
-
-#define AV_EF_IGNORE_ERR (1<<15) ///< ignore errors and continue
-#define AV_EF_CAREFUL (1<<16) ///< consider things that violate the spec, are fast to calculate and have not been seen in the wild as errors
-#define AV_EF_COMPLIANT (1<<17) ///< consider all spec non compliances as errors
-#define AV_EF_AGGRESSIVE (1<<18) ///< consider things that a sane encoder should not do as an error
-
-
+#if FF_API_REORDERED_OPAQUE
/**
* opaque 64-bit number (generally a PTS) that will be reordered and
* output in AVFrame.reordered_opaque
@@ -1368,8 +1390,12 @@ typedef struct AVCodecContext {
* supported by encoders with the
* AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability.
* - decoding: Set by user.
+ *
+ * @deprecated Use AV_CODEC_FLAG_COPY_OPAQUE instead
*/
+ attribute_deprecated
int64_t reordered_opaque;
+#endif
/**
* Hardware accelerator in use
@@ -1379,13 +1405,26 @@ typedef struct AVCodecContext {
const struct AVHWAccel *hwaccel;
/**
- * Hardware accelerator context.
- * For some hardware accelerators, a global context needs to be
- * provided by the user. In that case, this holds display-dependent
- * data FFmpeg cannot instantiate itself. Please refer to the
- * FFmpeg HW accelerator documentation to know how to fill this.
- * - encoding: unused
- * - decoding: Set by user
+ * Legacy hardware accelerator context.
+ *
+ * For some hardware acceleration methods, the caller may use this field to
+ * signal hwaccel-specific data to the codec. The struct pointed to by this
+ * pointer is hwaccel-dependent and defined in the respective header. Please
+ * refer to the FFmpeg HW accelerator documentation to know how to fill
+ * this.
+ *
+ * In most cases this field is optional - the necessary information may also
+ * be provided to libavcodec through @ref hw_frames_ctx or @ref
+ * hw_device_ctx (see avcodec_get_hw_config()). However, in some cases it
+ * may be the only method of signalling some (optional) information.
+ *
+ * The struct and its contents are owned by the caller.
+ *
+ * - encoding: May be set by the caller before avcodec_open2(). Must remain
+ * valid until avcodec_free_context().
+ * - decoding: May be set by the caller in the get_format() callback.
+ * Must remain valid until the next get_format() call,
+ * or avcodec_free_context() (whichever comes first).
*/
void *hwaccel_context;
@@ -1481,27 +1520,6 @@ typedef struct AVCodecContext {
*/
int active_thread_type;
-#if FF_API_THREAD_SAFE_CALLBACKS
- /**
- * Set by the client if its custom get_buffer() callback can be called
- * synchronously from another thread, which allows faster multithreaded decoding.
- * draw_horiz_band() will be called from other threads regardless of this setting.
- * Ignored if the default get_buffer() is used.
- * - encoding: Set by user.
- * - decoding: Set by user.
- *
- * @deprecated the custom get_buffer2() callback should always be
- * thread-safe. Thread-unsafe get_buffer2() implementations will be
- * invalid starting with LIBAVCODEC_VERSION_MAJOR=60; in other words,
- * libavcodec will behave as if this field was always set to 1.
- * Callers that want to be forward compatible with future libavcodec
- * versions should wrap access to this field in
- * #if LIBAVCODEC_VERSION_MAJOR < 60
- */
- attribute_deprecated
- int thread_safe_callbacks;
-#endif
-
/**
* The codec may call this to execute several independent things.
* It will return only after finishing all tasks.
@@ -1802,17 +1820,6 @@ typedef struct AVCodecContext {
*/
int seek_preroll;
-#if FF_API_DEBUG_MV
- /**
- * @deprecated unused
- */
- attribute_deprecated
- int debug_mv;
-#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames
-#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames
-#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames
-#endif
-
/**
* custom intra quantization matrix
* - encoding: Set by user, can be NULL.
@@ -1879,15 +1886,6 @@ typedef struct AVCodecContext {
*/
AVBufferRef *hw_frames_ctx;
-#if FF_API_SUB_TEXT_FORMAT
- /**
- * @deprecated unused
- */
- attribute_deprecated
- int sub_text_format;
-#define FF_SUB_TEXT_FMT_ASS 0
-#endif
-
/**
* Audio only. The amount of padding (in samples) appended by the encoder to
* the end of the audio. I.e. this number of decoded samples must be
@@ -2054,6 +2052,17 @@ typedef struct AVCodecContext {
* The decoder can then override during decoding as needed.
*/
AVChannelLayout ch_layout;
+
+ /**
+ * Frame counter, set by libavcodec.
+ *
+ * - decoding: total number of frames returned from the decoder so far.
+ * - encoding: total number of frames passed to the encoder so far.
+ *
+ * @note the counter is not incremented if encoding/decoding resulted in
+ * an error.
+ */
+ int64_t frame_num;
} AVCodecContext;
/**
@@ -2250,6 +2259,22 @@ typedef struct AVHWAccel {
*/
#define AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH (1 << 2)
+/**
+ * Some hardware decoders (namely nvdec) can either output direct decoder
+ * surfaces, or make an on-device copy and return said copy.
+ * There is a hard limit on how many decoder surfaces there can be, and it
+ * cannot be accurately guessed ahead of time.
+ * For some processing chains, this can be okay, but others will run into the
+ * limit and in turn produce very confusing errors that require fine tuning of
+ * more or less obscure options by the user, or in extreme cases cannot be
+ * resolved at all without inserting an avfilter that forces a copy.
+ *
+ * Thus, the hwaccel will by default make a copy for safety and resilience.
+ * If a users really wants to minimize the amount of copies, they can set this
+ * flag and ensure their processing chain does not exhaust the surface pool.
+ */
+#define AV_HWACCEL_FLAG_UNSAFE_OUTPUT (1 << 3)
+
/**
* @}
*/
@@ -2355,14 +2380,6 @@ void avcodec_free_context(AVCodecContext **avctx);
*/
const AVClass *avcodec_get_class(void);
-#if FF_API_GET_FRAME_CLASS
-/**
- * @deprecated This function should not be used.
- */
-attribute_deprecated
-const AVClass *avcodec_get_frame_class(void);
-#endif
-
/**
* Get the AVClass for AVSubtitleRect. It can be used in combination with
* AV_OPT_SEARCH_FAKE_OBJ for examining options.
@@ -2493,6 +2510,7 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height);
void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
int linesize_align[AV_NUM_DATA_POINTERS]);
+#ifdef FF_API_AVCODEC_CHROMA_POS
/**
* Converts AVChromaLocation to swscale x/y chroma position.
*
@@ -2501,7 +2519,9 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
*
* @param xpos horizontal chroma sample position
* @param ypos vertical chroma sample position
+ * @deprecated Use av_chroma_location_enum_to_pos() instead.
*/
+ attribute_deprecated
int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos);
/**
@@ -2512,8 +2532,11 @@ int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos);
*
* @param xpos horizontal chroma sample position
* @param ypos vertical chroma sample position
+ * @deprecated Use av_chroma_location_pos_to_enum() instead.
*/
+ attribute_deprecated
enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos);
+#endif
/**
* Decode a subtitle message.
@@ -2543,8 +2566,7 @@ enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos);
* @param[in] avpkt The input AVPacket containing the input buffer.
*/
int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
- int *got_sub_ptr,
- AVPacket *avpkt);
+ int *got_sub_ptr, const AVPacket *avpkt);
/**
* Supply raw packet data as input to a decoder.
@@ -2580,40 +2602,41 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
* still has frames buffered, it will return them after sending
* a flush packet.
*
- * @return 0 on success, otherwise negative error code:
- * AVERROR(EAGAIN): input is not accepted in the current state - user
- * must read output with avcodec_receive_frame() (once
- * all output is read, the packet should be resent, and
- * the call will not fail with EAGAIN).
- * AVERROR_EOF: the decoder has been flushed, and no new packets can
- * be sent to it (also returned if more than 1 flush
- * packet is sent)
- * AVERROR(EINVAL): codec not opened, it is an encoder, or requires flush
- * AVERROR(ENOMEM): failed to add packet to internal queue, or similar
- * other errors: legitimate decoding errors
+ * @retval 0 success
+ * @retval AVERROR(EAGAIN) input is not accepted in the current state - user
+ * must read output with avcodec_receive_frame() (once
+ * all output is read, the packet should be resent,
+ * and the call will not fail with EAGAIN).
+ * @retval AVERROR_EOF the decoder has been flushed, and no new packets can be
+ * sent to it (also returned if more than 1 flush
+ * packet is sent)
+ * @retval AVERROR(EINVAL) codec not opened, it is an encoder, or requires flush
+ * @retval AVERROR(ENOMEM) failed to add packet to internal queue, or similar
+ * @retval "another negative error code" legitimate decoding errors
*/
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);
/**
- * Return decoded output data from a decoder.
+ * Return decoded output data from a decoder or encoder (when the
+ * AV_CODEC_FLAG_RECON_FRAME flag is used).
*
* @param avctx codec context
* @param frame This will be set to a reference-counted video or audio
* frame (depending on the decoder type) allocated by the
- * decoder. Note that the function will always call
+ * codec. Note that the function will always call
* av_frame_unref(frame) before doing anything else.
*
- * @return
- * 0: success, a frame was returned
- * AVERROR(EAGAIN): output is not available in this state - user must try
- * to send new input
- * AVERROR_EOF: the decoder has been fully flushed, and there will be
- * no more output frames
- * AVERROR(EINVAL): codec not opened, or it is an encoder
- * AVERROR_INPUT_CHANGED: current decoded frame has changed parameters
- * with respect to first decoded frame. Applicable
- * when flag AV_CODEC_FLAG_DROPCHANGED is set.
- * other negative values: legitimate decoding errors
+ * @retval 0 success, a frame was returned
+ * @retval AVERROR(EAGAIN) output is not available in this state - user must
+ * try to send new input
+ * @retval AVERROR_EOF the codec has been fully flushed, and there will be
+ * no more output frames
+ * @retval AVERROR(EINVAL) codec not opened, or it is an encoder without the
+ * AV_CODEC_FLAG_RECON_FRAME flag enabled
+ * @retval AVERROR_INPUT_CHANGED current decoded frame has changed parameters with
+ * respect to first decoded frame. Applicable when flag
+ * AV_CODEC_FLAG_DROPCHANGED is set.
+ * @retval "other negative error code" legitimate decoding errors
*/
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);
@@ -2640,16 +2663,16 @@ int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);
* If it is not set, frame->nb_samples must be equal to
* avctx->frame_size for all frames except the last.
* The final frame may be smaller than avctx->frame_size.
- * @return 0 on success, otherwise negative error code:
- * AVERROR(EAGAIN): input is not accepted in the current state - user
- * must read output with avcodec_receive_packet() (once
- * all output is read, the packet should be resent, and
- * the call will not fail with EAGAIN).
- * AVERROR_EOF: the encoder has been flushed, and no new frames can
- * be sent to it
- * AVERROR(EINVAL): codec not opened, it is a decoder, or requires flush
- * AVERROR(ENOMEM): failed to add packet to internal queue, or similar
- * other errors: legitimate encoding errors
+ * @retval 0 success
+ * @retval AVERROR(EAGAIN) input is not accepted in the current state - user must
+ * read output with avcodec_receive_packet() (once all
+ * output is read, the packet should be resent, and the
+ * call will not fail with EAGAIN).
+ * @retval AVERROR_EOF the encoder has been flushed, and no new frames can
+ * be sent to it
+ * @retval AVERROR(EINVAL) codec not opened, it is a decoder, or requires flush
+ * @retval AVERROR(ENOMEM) failed to add packet to internal queue, or similar
+ * @retval "another negative error code" legitimate encoding errors
*/
int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame);
@@ -2660,13 +2683,13 @@ int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame);
* @param avpkt This will be set to a reference-counted packet allocated by the
* encoder. Note that the function will always call
* av_packet_unref(avpkt) before doing anything else.
- * @return 0 on success, otherwise negative error code:
- * AVERROR(EAGAIN): output is not available in the current state - user
- * must try to send input
- * AVERROR_EOF: the encoder has been fully flushed, and there will be
- * no more output packets
- * AVERROR(EINVAL): codec not opened, or it is a decoder
- * other errors: legitimate encoding errors
+ * @retval 0 success
+ * @retval AVERROR(EAGAIN) output is not available in the current state - user must
+ * try to send input
+ * @retval AVERROR_EOF the encoder has been fully flushed, and there will be no
+ * more output packets
+ * @retval AVERROR(EINVAL) codec not opened, or it is a decoder
+ * @retval "another negative error code" legitimate encoding errors
*/
int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
@@ -2780,10 +2803,10 @@ int avcodec_get_hw_frames_parameters(AVCodecContext *avctx,
*/
enum AVPictureStructure {
- AV_PICTURE_STRUCTURE_UNKNOWN, //< unknown
- AV_PICTURE_STRUCTURE_TOP_FIELD, //< coded as top field
- AV_PICTURE_STRUCTURE_BOTTOM_FIELD, //< coded as bottom field
- AV_PICTURE_STRUCTURE_FRAME, //< coded as frame
+ AV_PICTURE_STRUCTURE_UNKNOWN, ///< unknown
+ AV_PICTURE_STRUCTURE_TOP_FIELD, ///< coded as top field
+ AV_PICTURE_STRUCTURE_BOTTOM_FIELD, ///< coded as bottom field
+ AV_PICTURE_STRUCTURE_FRAME, ///< coded as frame
};
typedef struct AVCodecParserContext {
diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index bcbc4166c..5fef65e97 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -316,7 +316,7 @@ uint8_t *av_packet_pack_dictionary(AVDictionary *dict, size_t *size)
const AVDictionaryEntry *t = NULL;
size_t total_length = 0;
- while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) {
+ while ((t = av_dict_iterate(dict, t))) {
for (int i = 0; i < 2; i++) {
const char *str = i ? t->value : t->key;
const size_t len = strlen(str) + 1;
diff --git a/libavcodec/avpicture.c b/libavcodec/avpicture.c
deleted file mode 100644
index 56435f4fc..000000000
--- a/libavcodec/avpicture.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * AVPicture management routines
- * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * AVPicture management routines
- */
-
-#include "avcodec.h"
-#include "internal.h"
-#include "libavutil/common.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/internal.h"
-#include "libavutil/colorspace.h"
-
-#if FF_API_AVPICTURE
-FF_DISABLE_DEPRECATION_WARNINGS
-int avpicture_fill(AVPicture *picture, const uint8_t *ptr,
- enum AVPixelFormat pix_fmt, int width, int height)
-{
- return av_image_fill_arrays(picture->data, picture->linesize,
- ptr, pix_fmt, width, height, 1);
-}
-
-int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt, int width, int height,
- unsigned char *dest, int dest_size)
-{
- return av_image_copy_to_buffer(dest, dest_size,
- (const uint8_t * const*)src->data, src->linesize,
- pix_fmt, width, height, 1);
-}
-
-int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height)
-{
- return av_image_get_buffer_size(pix_fmt, width, height, 1);
-}
-
-int avpicture_alloc(AVPicture *picture,
- enum AVPixelFormat pix_fmt, int width, int height)
-{
- int ret = av_image_alloc(picture->data, picture->linesize,
- width, height, pix_fmt, 1);
- if (ret < 0) {
- memset(picture, 0, sizeof(AVPicture));
- return ret;
- }
-
- return 0;
-}
-
-void avpicture_free(AVPicture *picture)
-{
- av_freep(&picture->data[0]);
-}
-
-void av_picture_copy(AVPicture *dst, const AVPicture *src,
- enum AVPixelFormat pix_fmt, int width, int height)
-{
- av_image_copy(dst->data, dst->linesize, (const uint8_t **)src->data,
- src->linesize, pix_fmt, width, height);
-}
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif /* FF_API_AVPICTURE */
diff --git a/libavcodec/avrndec.c b/libavcodec/avrndec.c
index 9bb0c1ffa..ef194058f 100644
--- a/libavcodec/avrndec.c
+++ b/libavcodec/avrndec.c
@@ -21,7 +21,7 @@
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "libavutil/imgutils.h"
typedef struct {
@@ -91,12 +91,12 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
const FFCodec ff_avrn_decoder = {
.p.name = "avrn",
- .p.long_name = NULL_IF_CONFIG_SMALL("Avid AVI Codec"),
+ CODEC_LONG_NAME("Avid AVI Codec"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AVRN,
.priv_data_size = sizeof(AVRnContext),
.init = init,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/avs.c b/libavcodec/avs.c
index 6dda3393b..a1c9d3c43 100644
--- a/libavcodec/avs.c
+++ b/libavcodec/avs.c
@@ -21,8 +21,8 @@
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
typedef struct AvsContext {
AVFrame *frame;
@@ -177,7 +177,7 @@ static av_cold int avs_decode_end(AVCodecContext *avctx)
const FFCodec ff_avs_decoder = {
.p.name = "avs",
- .p.long_name = NULL_IF_CONFIG_SMALL("AVS (Audio Video Standard) video"),
+ CODEC_LONG_NAME("AVS (Audio Video Standard) video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AVS,
.priv_data_size = sizeof(AvsContext),
@@ -185,5 +185,4 @@ const FFCodec ff_avs_decoder = {
FF_CODEC_DECODE_CB(avs_decode_frame),
.close = avs_decode_end,
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/avs2_parser.c b/libavcodec/avs2_parser.c
index 035051749..200134f91 100644
--- a/libavcodec/avs2_parser.c
+++ b/libavcodec/avs2_parser.c
@@ -112,9 +112,9 @@ static void parse_avs2_seq_header(AVCodecParserContext *s, const uint8_t *buf,
s->height = height;
s->coded_width = FFALIGN(width, 8);
s->coded_height = FFALIGN(height, 8);
- avctx->framerate.num = avctx->time_base.den =
+ avctx->framerate.num =
ff_avs2_frame_rate_tab[frame_rate_code].num;
- avctx->framerate.den = avctx->time_base.num =
+ avctx->framerate.den =
ff_avs2_frame_rate_tab[frame_rate_code].den;
avctx->has_b_frames = FFMAX(avctx->has_b_frames, !low_delay);
diff --git a/libavcodec/avs3_parser.c b/libavcodec/avs3_parser.c
index a9fd879e9..a819b5783 100644
--- a/libavcodec/avs3_parser.c
+++ b/libavcodec/avs3_parser.c
@@ -117,8 +117,8 @@ static void parse_avs3_nal_units(AVCodecParserContext *s, const uint8_t *buf,
low_delay = get_bits(&gb, 1);
avctx->has_b_frames = FFMAX(avctx->has_b_frames, !low_delay);
- avctx->framerate.num = avctx->time_base.den = ff_avs3_frame_rate_tab[ratecode].num;
- avctx->framerate.den = avctx->time_base.num = ff_avs3_frame_rate_tab[ratecode].den;
+ avctx->framerate.num = ff_avs3_frame_rate_tab[ratecode].num;
+ avctx->framerate.den = ff_avs3_frame_rate_tab[ratecode].den;
s->width = s->coded_width = avctx->width;
s->height = s->coded_height = avctx->height;
diff --git a/libavcodec/avuidec.c b/libavcodec/avuidec.c
index f545c4115..ba157e167 100644
--- a/libavcodec/avuidec.c
+++ b/libavcodec/avuidec.c
@@ -22,7 +22,7 @@
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "libavutil/intreadwrite.h"
static av_cold int avui_decode_init(AVCodecContext *avctx)
@@ -121,11 +121,10 @@ static int avui_decode_frame(AVCodecContext *avctx, AVFrame *pic,
const FFCodec ff_avui_decoder = {
.p.name = "avui",
- .p.long_name = NULL_IF_CONFIG_SMALL("Avid Meridien Uncompressed"),
+ CODEC_LONG_NAME("Avid Meridien Uncompressed"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AVUI,
.p.capabilities = AV_CODEC_CAP_DR1,
.init = avui_decode_init,
FF_CODEC_DECODE_CB(avui_decode_frame),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/avuienc.c b/libavcodec/avuienc.c
index e2bd3181f..8a093d3d1 100644
--- a/libavcodec/avuienc.c
+++ b/libavcodec/avuienc.c
@@ -72,7 +72,7 @@ static int avui_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
}
for (i = 0; i <= interlaced; i++) {
- uint8_t *src;
+ const uint8_t *src;
if (interlaced && avctx->height == 486) {
src = pic->data[0] + (1 - i) * pic->linesize[0];
} else {
@@ -93,12 +93,12 @@ static int avui_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const FFCodec ff_avui_encoder = {
.p.name = "avui",
- .p.long_name = NULL_IF_CONFIG_SMALL("Avid Meridien Uncompressed"),
+ CODEC_LONG_NAME("Avid Meridien Uncompressed"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AVUI,
- .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_UYVY422, AV_PIX_FMT_NONE },
.init = avui_encode_init,
FF_CODEC_ENCODE_CB(avui_encode_frame),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/bethsoftvideo.c b/libavcodec/bethsoftvideo.c
index 9fc286fb0..e095d04fa 100644
--- a/libavcodec/bethsoftvideo.c
+++ b/libavcodec/bethsoftvideo.c
@@ -32,7 +32,7 @@
#include "bethsoftvideo.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
typedef struct BethsoftvidContext {
AVFrame *frame;
@@ -51,16 +51,16 @@ static av_cold int bethsoftvid_decode_init(AVCodecContext *avctx)
return 0;
}
-static int set_palette(BethsoftvidContext *ctx)
+static int set_palette(BethsoftvidContext *ctx, GetByteContext *g)
{
uint32_t *palette = (uint32_t *)ctx->frame->data[1];
int a;
- if (bytestream2_get_bytes_left(&ctx->g) < 256*3)
+ if (bytestream2_get_bytes_left(g) < 256*3)
return AVERROR_INVALIDDATA;
for(a = 0; a < 256; a++){
- palette[a] = 0xFFU << 24 | bytestream2_get_be24u(&ctx->g) * 4;
+ palette[a] = 0xFFU << 24 | bytestream2_get_be24u(g) * 4;
palette[a] |= palette[a] >> 6 & 0x30303;
}
ctx->frame->palette_has_changed = 1;
@@ -79,26 +79,31 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
int code, ret;
int yoffset;
+ bytestream2_init(&vid->g, avpkt->data, avpkt->size);
+ block_type = bytestream2_get_byte(&vid->g);
+ if (block_type < 1 || block_type > 4)
+ return AVERROR_INVALIDDATA;
+
if ((ret = ff_reget_buffer(avctx, vid->frame, 0)) < 0)
return ret;
wrap_to_next_line = vid->frame->linesize[0] - avctx->width;
if (avpkt->side_data_elems > 0 &&
avpkt->side_data[0].type == AV_PKT_DATA_PALETTE) {
- bytestream2_init(&vid->g, avpkt->side_data[0].data,
+ GetByteContext g;
+ bytestream2_init(&g, avpkt->side_data[0].data,
avpkt->side_data[0].size);
- if ((ret = set_palette(vid)) < 0)
+ if ((ret = set_palette(vid, &g)) < 0)
return ret;
}
- bytestream2_init(&vid->g, avpkt->data, avpkt->size);
dst = vid->frame->data[0];
frame_end = vid->frame->data[0] + vid->frame->linesize[0] * avctx->height;
- switch(block_type = bytestream2_get_byte(&vid->g)){
+ switch(block_type){
case PALETTE_BLOCK: {
*got_frame = 0;
- if ((ret = set_palette(vid)) < 0) {
+ if ((ret = set_palette(vid, &vid->g)) < 0) {
av_log(avctx, AV_LOG_ERROR, "error reading palette\n");
return ret;
}
@@ -160,7 +165,7 @@ static av_cold int bethsoftvid_decode_end(AVCodecContext *avctx)
const FFCodec ff_bethsoftvid_decoder = {
.p.name = "bethsoftvid",
- .p.long_name = NULL_IF_CONFIG_SMALL("Bethesda VID video"),
+ CODEC_LONG_NAME("Bethesda VID video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_BETHSOFTVID,
.priv_data_size = sizeof(BethsoftvidContext),
@@ -168,5 +173,4 @@ const FFCodec ff_bethsoftvid_decoder = {
.close = bethsoftvid_decode_end,
FF_CODEC_DECODE_CB(bethsoftvid_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/bfi.c b/libavcodec/bfi.c
index 6f9fbb0e9..c26827245 100644
--- a/libavcodec/bfi.c
+++ b/libavcodec/bfi.c
@@ -30,7 +30,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
typedef struct BFIContext {
AVCodecContext *avctx;
@@ -66,7 +66,7 @@ static int bfi_decode_frame(AVCodecContext *avctx, AVFrame *frame,
bytestream2_init(&g, avpkt->data, buf_size);
/* Set frame parameters and palette, if necessary */
- if (!avctx->frame_number) {
+ if (!avctx->frame_num) {
frame->pict_type = AV_PICTURE_TYPE_I;
frame->key_frame = 1;
/* Setting the palette */
@@ -177,7 +177,7 @@ static av_cold int bfi_decode_close(AVCodecContext *avctx)
const FFCodec ff_bfi_decoder = {
.p.name = "bfi",
- .p.long_name = NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"),
+ CODEC_LONG_NAME("Brute Force & Ignorance"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_BFI,
.priv_data_size = sizeof(BFIContext),
@@ -185,5 +185,4 @@ const FFCodec ff_bfi_decoder = {
.close = bfi_decode_close,
FF_CODEC_DECODE_CB(bfi_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/bink.c b/libavcodec/bink.c
index 3ba3068e0..15fc9d29e 100644
--- a/libavcodec/bink.c
+++ b/libavcodec/bink.c
@@ -32,10 +32,9 @@
#include "binkdsp.h"
#include "blockdsp.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
#include "hpeldsp.h"
-#include "internal.h"
-#include "mathops.h"
#define BINK_FLAG_ALPHA 0x00100000
#define BINK_FLAG_GRAY 0x00020000
@@ -871,7 +870,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
binkb_init_bundles(c);
ref_start = frame->data[plane_idx];
- ref_end = frame->data[plane_idx] + (bh * frame->linesize[plane_idx] + bw) * 8;
+ ref_end = frame->data[plane_idx] + ((bh - 1) * frame->linesize[plane_idx] + bw - 1) * 8;
for (i = 0; i < 64; i++)
coordmap[i] = (i & 7) + (i >> 3) * stride;
@@ -927,7 +926,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
xoff = binkb_get_value(c, BINKB_SRC_X_OFF);
yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias;
ref = dst + xoff + yoff * stride;
- if (ref < ref_start || ref + 8*stride > ref_end) {
+ if (ref < ref_start || ref > ref_end) {
av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n");
} else if (ref + 8*stride < dst || ref >= dst + 8*stride) {
c->put_pixels_tab(dst, ref, stride, 8);
@@ -943,7 +942,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
xoff = binkb_get_value(c, BINKB_SRC_X_OFF);
yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias;
ref = dst + xoff + yoff * stride;
- if (ref < ref_start || ref + 8 * stride > ref_end) {
+ if (ref < ref_start || ref > ref_end) {
av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n");
} else if (ref + 8*stride < dst || ref >= dst + 8*stride) {
c->put_pixels_tab(dst, ref, stride, 8);
@@ -975,7 +974,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
xoff = binkb_get_value(c, BINKB_SRC_X_OFF);
yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias;
ref = dst + xoff + yoff * stride;
- if (ref < ref_start || ref + 8 * stride > ref_end) {
+ if (ref < ref_start || ref > ref_end) {
av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n");
} else if (ref + 8*stride < dst || ref >= dst + 8*stride) {
c->put_pixels_tab(dst, ref, stride, 8);
@@ -1385,7 +1384,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
avctx->pix_fmt = c->has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P;
avctx->color_range = c->version == 'k' ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
- ff_blockdsp_init(&c->bdsp, avctx);
+ ff_blockdsp_init(&c->bdsp);
ff_hpeldsp_init(&hdsp, avctx->flags);
c->put_pixels_tab = hdsp.put_pixels_tab[1][0];
ff_binkdsp_init(&c->binkdsp);
@@ -1421,7 +1420,7 @@ static void flush(AVCodecContext *avctx)
const FFCodec ff_bink_decoder = {
.p.name = "binkvideo",
- .p.long_name = NULL_IF_CONFIG_SMALL("Bink video"),
+ CODEC_LONG_NAME("Bink video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_BINKVIDEO,
.priv_data_size = sizeof(BinkContext),
@@ -1430,5 +1429,5 @@ const FFCodec ff_bink_decoder = {
FF_CODEC_DECODE_CB(decode_frame),
.flush = flush,
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
index 8bac8e03f..f28ecba76 100644
--- a/libavcodec/binkaudio.c
+++ b/libavcodec/binkaudio.c
@@ -33,15 +33,14 @@
#include "libavutil/channel_layout.h"
#include "libavutil/intfloat.h"
#include "libavutil/mem_internal.h"
+#include "libavutil/tx.h"
#define BITSTREAM_READER_LE
#include "avcodec.h"
-#include "dct.h"
#include "decode.h"
#include "get_bits.h"
#include "codec_internal.h"
#include "internal.h"
-#include "rdft.h"
#include "wma_freqs.h"
#define MAX_DCT_CHANNELS 6
@@ -63,10 +62,8 @@ typedef struct BinkAudioContext {
float previous[MAX_DCT_CHANNELS][BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block
float quant_table[96];
AVPacket *pkt;
- union {
- RDFTContext rdft;
- DCTContext dct;
- } trans;
+ AVTXContext *tx;
+ av_tx_fn tx_fn;
} BinkAudioContext;
@@ -138,12 +135,15 @@ static av_cold int decode_init(AVCodecContext *avctx)
s->first = 1;
- if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT)
- ret = ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R);
- else if (CONFIG_BINKAUDIO_DCT_DECODER)
- ret = ff_dct_init(&s->trans.dct, frame_len_bits, DCT_III);
- else
+ if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) {
+ float scale = 0.5;
+ ret = av_tx_init(&s->tx, &s->tx_fn, AV_TX_FLOAT_RDFT, 1, 1 << frame_len_bits, &scale, 0);
+ } else if (CONFIG_BINKAUDIO_DCT_DECODER) {
+ float scale = 1.0 / (1 << frame_len_bits);
+ ret = av_tx_init(&s->tx, &s->tx_fn, AV_TX_FLOAT_DCT, 1, 1 << (frame_len_bits - 1), &scale, 0);
+ } else {
av_assert0(0);
+ }
if (ret < 0)
return ret;
@@ -177,13 +177,12 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct,
float q, quant[25];
int width, coeff;
GetBitContext *gb = &s->gb;
+ LOCAL_ALIGNED_32(float, coeffs, [4098]);
if (use_dct)
skip_bits(gb, 2);
for (ch = 0; ch < channels; ch++) {
- FFTSample *coeffs = out[ch + ch_offset];
-
if (s->version_b) {
if (get_bits_left(gb) < 64)
return AVERROR_INVALIDDATA;
@@ -251,10 +250,15 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct,
if (CONFIG_BINKAUDIO_DCT_DECODER && use_dct) {
coeffs[0] /= 0.5;
- s->trans.dct.dct_calc(&s->trans.dct, coeffs);
+ s->tx_fn(s->tx, out[ch + ch_offset], coeffs, sizeof(float));
+ } else if (CONFIG_BINKAUDIO_RDFT_DECODER) {
+ for (int i = 2; i < s->frame_len; i += 2)
+ coeffs[i + 1] *= -1;
+
+ coeffs[s->frame_len + 0] = coeffs[1];
+ coeffs[s->frame_len + 1] = coeffs[1] = 0;
+ s->tx_fn(s->tx, out[ch + ch_offset], coeffs, sizeof(AVComplexFloat));
}
- else if (CONFIG_BINKAUDIO_RDFT_DECODER)
- s->trans.rdft.rdft_calc(&s->trans.rdft, coeffs);
}
for (ch = 0; ch < channels; ch++) {
@@ -278,11 +282,7 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct,
static av_cold int decode_end(AVCodecContext *avctx)
{
BinkAudioContext * s = avctx->priv_data;
- if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT)
- ff_rdft_end(&s->trans.rdft);
- else if (CONFIG_BINKAUDIO_DCT_DECODER)
- ff_dct_end(&s->trans.dct);
-
+ av_tx_uninit(&s->tx);
return 0;
}
@@ -296,9 +296,10 @@ static int binkaudio_receive_frame(AVCodecContext *avctx, AVFrame *frame)
{
BinkAudioContext *s = avctx->priv_data;
GetBitContext *gb = &s->gb;
- int ret;
+ int new_pkt, ret;
again:
+ new_pkt = !s->pkt->data;
if (!s->pkt->data) {
ret = ff_decode_get_packet(avctx, s->pkt);
if (ret < 0) {
@@ -325,6 +326,8 @@ again:
frame->nb_samples = s->frame_len;
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret;
+ if (!new_pkt)
+ frame->pts = AV_NOPTS_VALUE;
}
if (decode_block(s, (float **)frame->extended_data,
@@ -367,7 +370,7 @@ static void decode_flush(AVCodecContext *avctx)
const FFCodec ff_binkaudio_rdft_decoder = {
.p.name = "binkaudio_rdft",
- .p.long_name = NULL_IF_CONFIG_SMALL("Bink Audio (RDFT)"),
+ CODEC_LONG_NAME("Bink Audio (RDFT)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_BINKAUDIO_RDFT,
.priv_data_size = sizeof(BinkAudioContext),
@@ -376,12 +379,12 @@ const FFCodec ff_binkaudio_rdft_decoder = {
.close = decode_end,
FF_CODEC_RECEIVE_FRAME_CB(binkaudio_receive_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
const FFCodec ff_binkaudio_dct_decoder = {
.p.name = "binkaudio_dct",
- .p.long_name = NULL_IF_CONFIG_SMALL("Bink Audio (DCT)"),
+ CODEC_LONG_NAME("Bink Audio (DCT)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_BINKAUDIO_DCT,
.priv_data_size = sizeof(BinkAudioContext),
@@ -390,5 +393,5 @@ const FFCodec ff_binkaudio_dct_decoder = {
.close = decode_end,
FF_CODEC_RECEIVE_FRAME_CB(binkaudio_receive_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/bintext.c b/libavcodec/bintext.c
index e153198c3..ce814f769 100644
--- a/libavcodec/bintext.c
+++ b/libavcodec/bintext.c
@@ -36,7 +36,7 @@
#include "cga_data.h"
#include "bintext.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#define FONT_WIDTH 8
@@ -219,39 +219,36 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
#if CONFIG_BINTEXT_DECODER
const FFCodec ff_bintext_decoder = {
.p.name = "bintext",
- .p.long_name = NULL_IF_CONFIG_SMALL("Binary text"),
+ CODEC_LONG_NAME("Binary text"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_BINTEXT,
.priv_data_size = sizeof(XbinContext),
.init = decode_init,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
#if CONFIG_XBIN_DECODER
const FFCodec ff_xbin_decoder = {
.p.name = "xbin",
- .p.long_name = NULL_IF_CONFIG_SMALL("eXtended BINary text"),
+ CODEC_LONG_NAME("eXtended BINary text"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_XBIN,
.priv_data_size = sizeof(XbinContext),
.init = decode_init,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
#if CONFIG_IDF_DECODER
const FFCodec ff_idf_decoder = {
.p.name = "idf",
- .p.long_name = NULL_IF_CONFIG_SMALL("iCEDraw text"),
+ CODEC_LONG_NAME("iCEDraw text"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_IDF,
.priv_data_size = sizeof(XbinContext),
.init = decode_init,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
diff --git a/libavcodec/bitpacked.c b/libavcodec/bitpacked.c
deleted file mode 100644
index 23e82c69b..000000000
--- a/libavcodec/bitpacked.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Unpack bit-packed streams to formats supported by FFmpeg
- * Copyright (c) 2017 Savoir-faire Linux, Inc
- *
- * 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
- */
-
-/* Development sponsored by CBC/Radio-Canada */
-
-/**
- * @file
- * Bitpacked
- */
-
-#include "avcodec.h"
-#include "internal.h"
-#include "get_bits.h"
-#include "libavutil/imgutils.h"
-
-struct BitpackedContext {
- int (*decode)(AVCodecContext *avctx, AVFrame *frame,
- const AVPacket *pkt);
-};
-
-/* For this format, it's a simple passthrough */
-static int bitpacked_decode_uyvy422(AVCodecContext *avctx, AVFrame *frame,
- const AVPacket *avpkt)
-{
- int ret;
-
- /* there is no need to copy as the data already match
- * a known pixel format */
- frame->buf[0] = av_buffer_ref(avpkt->buf);
- ret = av_image_fill_arrays(frame->data, frame->linesize, avpkt->data,
- avctx->pix_fmt, avctx->width, avctx->height, 1);
- if (ret < 0) {
- av_buffer_unref(&frame->buf[0]);
- return ret;
- }
-
- return 0;
-}
-
-static int bitpacked_decode_yuv422p10(AVCodecContext *avctx, AVFrame *frame,
- const AVPacket *avpkt)
-{
- uint64_t frame_size = (uint64_t)avctx->width * (uint64_t)avctx->height * 20;
- uint64_t packet_size = (uint64_t)avpkt->size * 8;
- GetBitContext bc;
- uint16_t *y, *u, *v;
- int ret, i, j;
-
- ret = ff_get_buffer(avctx, frame, 0);
- if (ret < 0)
- return ret;
-
- if (frame_size > packet_size)
- return AVERROR_INVALIDDATA;
-
- if (avctx->width % 2)
- return AVERROR_PATCHWELCOME;
-
- ret = init_get_bits(&bc, avpkt->data, avctx->width * avctx->height * 20);
- if (ret)
- return ret;
-
- for (i = 0; i < avctx->height; i++) {
- y = (uint16_t*)(frame->data[0] + i * frame->linesize[0]);
- u = (uint16_t*)(frame->data[1] + i * frame->linesize[1]);
- v = (uint16_t*)(frame->data[2] + i * frame->linesize[2]);
-
- for (j = 0; j < avctx->width; j += 2) {
- *u++ = get_bits(&bc, 10);
- *y++ = get_bits(&bc, 10);
- *v++ = get_bits(&bc, 10);
- *y++ = get_bits(&bc, 10);
- }
- }
-
- return 0;
-}
-
-static av_cold int bitpacked_init_decoder(AVCodecContext *avctx)
-{
- struct BitpackedContext *bc = avctx->priv_data;
-
- if (!avctx->codec_tag || !avctx->width || !avctx->height)
- return AVERROR_INVALIDDATA;
-
- if (avctx->codec_tag == MKTAG('U', 'Y', 'V', 'Y')) {
- if (avctx->bits_per_coded_sample == 16 &&
- avctx->pix_fmt == AV_PIX_FMT_UYVY422)
- bc->decode = bitpacked_decode_uyvy422;
- else if (avctx->bits_per_coded_sample == 20 &&
- avctx->pix_fmt == AV_PIX_FMT_YUV422P10)
- bc->decode = bitpacked_decode_yuv422p10;
- else
- return AVERROR_INVALIDDATA;
- } else {
- return AVERROR_INVALIDDATA;
- }
-
- return 0;
-}
-
-static int bitpacked_decode(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *avpkt)
-{
- struct BitpackedContext *bc = avctx->priv_data;
- int buf_size = avpkt->size;
- AVFrame *frame = data;
- int res;
-
- frame->pict_type = AV_PICTURE_TYPE_I;
- frame->key_frame = 1;
-
- res = bc->decode(avctx, frame, avpkt);
- if (res)
- return res;
-
- *got_frame = 1;
- return buf_size;
-
-}
-
-AVCodec ff_bitpacked_decoder = {
- .name = "bitpacked",
- .long_name = NULL_IF_CONFIG_SMALL("Bitpacked"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_BITPACKED,
- .priv_data_size = sizeof(struct BitpackedContext),
- .init = bitpacked_init_decoder,
- .decode = bitpacked_decode,
- .capabilities = AV_CODEC_CAP_EXPERIMENTAL,
- .codec_tags = (const uint32_t []){
- MKTAG('U', 'Y', 'V', 'Y'),
- FF_CODEC_TAGS_END,
- },
-};
diff --git a/libavcodec/bitpacked_dec.c b/libavcodec/bitpacked_dec.c
index 4723a3c7e..a1ffef185 100644
--- a/libavcodec/bitpacked_dec.c
+++ b/libavcodec/bitpacked_dec.c
@@ -143,7 +143,7 @@ static int bitpacked_decode(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_bitpacked_decoder = {
.p.name = "bitpacked",
- .p.long_name = NULL_IF_CONFIG_SMALL("Bitpacked"),
+ CODEC_LONG_NAME("Bitpacked"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_BITPACKED,
.p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
@@ -154,5 +154,4 @@ const FFCodec ff_bitpacked_decoder = {
MKTAG('U', 'Y', 'V', 'Y'),
FF_CODEC_TAGS_END,
},
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/bitpacked_enc.c b/libavcodec/bitpacked_enc.c
index 127f1af59..3c4e11293 100644
--- a/libavcodec/bitpacked_enc.c
+++ b/libavcodec/bitpacked_enc.c
@@ -106,14 +106,14 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const FFCodec ff_bitpacked_encoder = {
.p.name = "bitpacked",
- .p.long_name = NULL_IF_CONFIG_SMALL("Bitpacked"),
+ CODEC_LONG_NAME("Bitpacked"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_BITPACKED,
.priv_data_size = sizeof(struct BitpackedContext),
- .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.init = encode_init,
FF_CODEC_ENCODE_CB(encode_frame),
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV422P10,
AV_PIX_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/bitstream.h b/libavcodec/bitstream.h
new file mode 100644
index 000000000..b60f0c296
--- /dev/null
+++ b/libavcodec/bitstream.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2016 Alexandra Hájková
+ *
+ * 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
+ * bitstream reader API header.
+ */
+
+/*
+ * Bit order (endianness) is controlled by #defining BITSTREAM_BE and/or
+ * BITSTREAM_LE before #including this header. The corresponding bitreading
+ * functions are provided as bits_*_be()/bits_*_le() respectively.
+ *
+ * If neither or only BITSTREAM_BE is defined, then the default (unsuffixed)
+ * bits_*() will resolve to the big-endian implementation. If only BITSTREAM_LE
+ * is defined, little-endian will be the default.
+ *
+ * If both are defined, then the default can be controlled by defining at most
+ * one of BITSTREAM_DEFAULT_LE/BE. When BITSTREAM_DEFAULT_* is not defined, no
+ * default is provided and you must always explicitly use the _be() or _le()
+ * variants.
+ */
+
+#ifndef AVCODEC_BITSTREAM_H
+#define AVCODEC_BITSTREAM_H
+
+#include
+
+#include "config.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/common.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/log.h"
+
+#include "mathops.h"
+#include "vlc.h"
+
+#ifndef UNCHECKED_BITSTREAM_READER
+#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER
+#endif
+
+// select the default endianness, if any
+#if defined(BITSTREAM_LE) && defined(BITSTREAM_BE)
+
+# if defined(BITSTREAM_DEFAULT_BE) && defined(BITSTREAM_DEFAULT_LE)
+# error "At most one of BITSTREAM_DEFAULT_BE/LE must be defined"
+# elif defined(BITSTREAM_DEFAULT_BE)
+# define BITS_DEFAULT_BE
+# elif defined(BITSTREAM_DEFAULT_LE)
+# define BITS_DEFAULT_LE
+# endif
+
+#elif defined(BITSTREAM_LE)
+# define BITS_DEFAULT_LE
+#else // select BE if nothing is requested explicitly
+# define BITS_DEFAULT_BE
+# define BITSTREAM_WANT_BE
+#endif
+
+#if defined(BITS_DEFAULT_LE)
+
+# define BitstreamContext BitstreamContextLE
+# define bits_init bits_init_le
+# define bits_init8 bits_init8_le
+# define bits_tell bits_tell_le
+# define bits_size bits_size_le
+# define bits_left bits_left_le
+# define bits_read_bit bits_read_bit_le
+# define bits_read_nz bits_read_nz_le
+# define bits_read bits_read_le
+# define bits_read_63 bits_read_63_le
+# define bits_read_64 bits_read_64_le
+# define bits_read_signed bits_read_signed_le
+# define bits_read_signed_nz bits_read_signed_nz_le
+# define bits_peek_nz bits_peek_nz_le
+# define bits_peek bits_peek_le
+# define bits_peek_signed bits_peek_signed_le
+# define bits_peek_signed_nz bits_peek_signed_nz_le
+# define bits_skip bits_skip_le
+# define bits_seek bits_seek_le
+# define bits_align bits_align_le
+# define bits_read_xbits bits_read_xbits_le
+# define bits_decode012 bits_decode012_le
+# define bits_decode210 bits_decode210_le
+# define bits_apply_sign bits_apply_sign_le
+# define bits_read_vlc bits_read_vlc_le
+
+#elif defined(BITS_DEFAULT_BE)
+
+# define BitstreamContext BitstreamContextBE
+# define bits_init bits_init_be
+# define bits_init8 bits_init8_be
+# define bits_tell bits_tell_be
+# define bits_size bits_size_be
+# define bits_left bits_left_be
+# define bits_read_bit bits_read_bit_be
+# define bits_read_nz bits_read_nz_be
+# define bits_read bits_read_be
+# define bits_read_63 bits_read_63_be
+# define bits_read_64 bits_read_64_be
+# define bits_read_signed bits_read_signed_be
+# define bits_read_signed_nz bits_read_signed_nz_be
+# define bits_peek_nz bits_peek_nz_be
+# define bits_peek bits_peek_be
+# define bits_peek_signed bits_peek_signed_be
+# define bits_peek_signed_nz bits_peek_signed_nz_be
+# define bits_skip bits_skip_be
+# define bits_seek bits_seek_be
+# define bits_align bits_align_be
+# define bits_read_xbits bits_read_xbits_be
+# define bits_decode012 bits_decode012_be
+# define bits_decode210 bits_decode210_be
+# define bits_apply_sign bits_apply_sign_be
+# define bits_read_vlc bits_read_vlc_be
+
+#endif
+
+#undef BITS_DEFAULT_LE
+#undef BITS_DEFAULT_BE
+
+#define BITS_RL_VLC(level, run, bc, table, bits, max_depth) \
+ do { \
+ int n, nb_bits; \
+ unsigned int index = bits_peek(bc, bits); \
+ level = table[index].level; \
+ n = table[index].len; \
+ \
+ if (max_depth > 1 && n < 0) { \
+ bits_skip(bc, bits); \
+ \
+ nb_bits = -n; \
+ \
+ index = bits_peek(bc, nb_bits) + level; \
+ level = table[index].level; \
+ n = table[index].len; \
+ if (max_depth > 2 && n < 0) { \
+ bits_skip(bc, nb_bits); \
+ nb_bits = -n; \
+ \
+ index = bits_peek(bc, nb_bits) + level; \
+ level = table[index].level; \
+ n = table[index].len; \
+ } \
+ } \
+ run = table[index].run; \
+ bits_skip(bc, n); \
+ } while (0)
+
+#endif /* AVCODEC_BITSTREAM_H */
+
+// the following is deliberately outside of the standard #include guards
+
+#if defined(BITSTREAM_LE) && !defined(BITSTREAM_WANT_LE)
+# define BITSTREAM_WANT_LE
+#endif
+
+#if defined(BITSTREAM_BE) && !defined(BITSTREAM_WANT_BE)
+# define BITSTREAM_WANT_BE
+#endif
+
+#if defined(BITSTREAM_WANT_LE) && !defined(AVCODEC_BITSTREAM_LE)
+#define AVCODEC_BITSTREAM_LE
+
+#define BITSTREAM_TEMPLATE_LE
+#include "bitstream_template.h"
+#undef BITSTREAM_TEMPLATE_LE
+
+#endif
+
+#if defined(BITSTREAM_WANT_BE) && !defined(AVCODEC_BITSTREAM_BE)
+#define AVCODEC_BITSTREAM_BE
+
+#include "bitstream_template.h"
+
+#endif
+
+#undef BITSTREAM_WANT_LE
+#undef BITSTREAM_WANT_BE
diff --git a/libavcodec/bitstream_filter.c b/libavcodec/bitstream_filter.c
deleted file mode 100644
index ca11ed371..000000000
--- a/libavcodec/bitstream_filter.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * copyright (c) 2006 Michael Niedermayer
- *
- * 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
-
-#include "avcodec.h"
-#include "libavutil/internal.h"
-#include "libavutil/mem.h"
-#include "libavutil/opt.h"
-
-#if FF_API_OLD_BSF
-FF_DISABLE_DEPRECATION_WARNINGS
-
-const AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f)
-{
- const AVBitStreamFilter *filter = NULL;
- void *opaque = NULL;
-
- while (filter != f)
- filter = av_bsf_iterate(&opaque);
-
- return av_bsf_iterate(&opaque);
-}
-
-void av_register_bitstream_filter(AVBitStreamFilter *bsf)
-{
-}
-
-typedef struct BSFCompatContext {
- AVBSFContext *ctx;
- int extradata_updated;
-} BSFCompatContext;
-
-AVBitStreamFilterContext *av_bitstream_filter_init(const char *name)
-{
- AVBitStreamFilterContext *ctx = NULL;
- BSFCompatContext *priv = NULL;
- const AVBitStreamFilter *bsf;
-
- bsf = av_bsf_get_by_name(name);
- if (!bsf)
- return NULL;
-
- ctx = av_mallocz(sizeof(*ctx));
- if (!ctx)
- return NULL;
-
- priv = av_mallocz(sizeof(*priv));
- if (!priv)
- goto fail;
-
-
- ctx->filter = bsf;
- ctx->priv_data = priv;
-
- return ctx;
-
-fail:
- if (priv)
- av_bsf_free(&priv->ctx);
- av_freep(&priv);
- av_freep(&ctx);
- return NULL;
-}
-
-void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc)
-{
- BSFCompatContext *priv;
-
- if (!bsfc)
- return;
-
- priv = bsfc->priv_data;
-
- av_bsf_free(&priv->ctx);
- av_freep(&bsfc->priv_data);
- av_free(bsfc);
-}
-
-int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
- AVCodecContext *avctx, const char *args,
- uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *buf, int buf_size, int keyframe)
-{
- BSFCompatContext *priv = bsfc->priv_data;
- AVPacket pkt = { 0 };
- int ret;
-
- if (!priv->ctx) {
- ret = av_bsf_alloc(bsfc->filter, &priv->ctx);
- if (ret < 0)
- return ret;
-
- ret = avcodec_parameters_from_context(priv->ctx->par_in, avctx);
- if (ret < 0)
- return ret;
-
- priv->ctx->time_base_in = avctx->time_base;
-
- if (bsfc->args && bsfc->filter->priv_class) {
- const AVOption *opt = av_opt_next(priv->ctx->priv_data, NULL);
- const char * shorthand[2] = {NULL};
-
- if (opt)
- shorthand[0] = opt->name;
-
- ret = av_opt_set_from_string(priv->ctx->priv_data, bsfc->args, shorthand, "=", ":");
- if (ret < 0)
- return ret;
- }
-
- ret = av_bsf_init(priv->ctx);
- if (ret < 0)
- return ret;
- }
-
- pkt.data = (uint8_t *)buf;
- pkt.size = buf_size;
-
- ret = av_bsf_send_packet(priv->ctx, &pkt);
- if (ret < 0)
- return ret;
-
- *poutbuf = NULL;
- *poutbuf_size = 0;
-
- ret = av_bsf_receive_packet(priv->ctx, &pkt);
- if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
- return 0;
- else if (ret < 0)
- return ret;
-
- *poutbuf = av_malloc(pkt.size + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!*poutbuf) {
- av_packet_unref(&pkt);
- return AVERROR(ENOMEM);
- }
-
- *poutbuf_size = pkt.size;
- memcpy(*poutbuf, pkt.data, pkt.size);
-
- av_packet_unref(&pkt);
-
- /* drain all the remaining packets we cannot return */
- while (ret >= 0) {
- ret = av_bsf_receive_packet(priv->ctx, &pkt);
- av_packet_unref(&pkt);
- }
-
- if (!priv->extradata_updated) {
- /* update extradata in avctx from the output codec parameters */
- if (priv->ctx->par_out->extradata_size && (!args || !strstr(args, "private_spspps_buf"))) {
- av_freep(&avctx->extradata);
- avctx->extradata_size = 0;
- avctx->extradata = av_mallocz(priv->ctx->par_out->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!avctx->extradata)
- return AVERROR(ENOMEM);
- memcpy(avctx->extradata, priv->ctx->par_out->extradata, priv->ctx->par_out->extradata_size);
- avctx->extradata_size = priv->ctx->par_out->extradata_size;
- }
-
- priv->extradata_updated = 1;
- }
-
- return 1;
-}
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c
index 444423ae9..e8216819c 100644
--- a/libavcodec/bitstream_filters.c
+++ b/libavcodec/bitstream_filters.c
@@ -31,6 +31,7 @@ extern const FFBitStreamFilter ff_av1_metadata_bsf;
extern const FFBitStreamFilter ff_chomp_bsf;
extern const FFBitStreamFilter ff_dump_extradata_bsf;
extern const FFBitStreamFilter ff_dca_core_bsf;
+extern const FFBitStreamFilter ff_dts2pts_bsf;
extern const FFBitStreamFilter ff_dv_error_marker_bsf;
extern const FFBitStreamFilter ff_eac3_core_bsf;
extern const FFBitStreamFilter ff_extract_extradata_bsf;
@@ -42,6 +43,7 @@ extern const FFBitStreamFilter ff_hapqa_extract_bsf;
extern const FFBitStreamFilter ff_hevc_metadata_bsf;
extern const FFBitStreamFilter ff_hevc_mp4toannexb_bsf;
extern const FFBitStreamFilter ff_imx_dump_header_bsf;
+extern const FFBitStreamFilter ff_media100_to_mjpegb_bsf;
extern const FFBitStreamFilter ff_mjpeg2jpeg_bsf;
extern const FFBitStreamFilter ff_mjpega_dump_header_bsf;
extern const FFBitStreamFilter ff_mp3_header_decompress_bsf;
diff --git a/libavcodec/bitstream_template.h b/libavcodec/bitstream_template.h
new file mode 100644
index 000000000..30bea84ad
--- /dev/null
+++ b/libavcodec/bitstream_template.h
@@ -0,0 +1,528 @@
+/*
+ * Copyright (c) 2016 Alexandra Hájková
+ *
+ * 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
+ */
+
+#ifdef BITSTREAM_TEMPLATE_LE
+# define BS_SUFFIX_LOWER _le
+# define BS_SUFFIX_UPPER LE
+#else
+# define BS_SUFFIX_LOWER _be
+# define BS_SUFFIX_UPPER BE
+#endif
+
+#define BS_JOIN(x, y, z) x ## y ## z
+#define BS_JOIN3(x, y, z) BS_JOIN(x, y, z)
+#define BS_FUNC(x) BS_JOIN3(bits_, x, BS_SUFFIX_LOWER)
+
+#define BSCTX BS_JOIN3(Bitstream, Context, BS_SUFFIX_UPPER)
+
+typedef struct BSCTX {
+ uint64_t bits; // stores bits read from the buffer
+ const uint8_t *buffer, *buffer_end;
+ const uint8_t *ptr; // pointer to the position inside a buffer
+ unsigned bits_valid; // number of bits left in bits field
+ unsigned size_in_bits;
+} BSCTX;
+
+/**
+ * @return
+ * - 0 on successful refill
+ * - a negative number when bitstream end is hit
+ *
+ * Always succeeds when UNCHECKED_BITSTREAM_READER is enabled.
+ */
+static inline int BS_FUNC(priv_refill_64)(BSCTX *bc)
+{
+#if !UNCHECKED_BITSTREAM_READER
+ if (bc->ptr >= bc->buffer_end)
+ return -1;
+#endif
+
+#ifdef BITSTREAM_TEMPLATE_LE
+ bc->bits = AV_RL64(bc->ptr);
+#else
+ bc->bits = AV_RB64(bc->ptr);
+#endif
+ bc->ptr += 8;
+ bc->bits_valid = 64;
+
+ return 0;
+}
+
+/**
+ * @return
+ * - 0 on successful refill
+ * - a negative number when bitstream end is hit
+ *
+ * Always succeeds when UNCHECKED_BITSTREAM_READER is enabled.
+ */
+static inline int BS_FUNC(priv_refill_32)(BSCTX *bc)
+{
+#if !UNCHECKED_BITSTREAM_READER
+ if (bc->ptr >= bc->buffer_end)
+ return -1;
+#endif
+
+#ifdef BITSTREAM_TEMPLATE_LE
+ bc->bits |= (uint64_t)AV_RL32(bc->ptr) << bc->bits_valid;
+#else
+ bc->bits |= (uint64_t)AV_RB32(bc->ptr) << (32 - bc->bits_valid);
+#endif
+ bc->ptr += 4;
+ bc->bits_valid += 32;
+
+ return 0;
+}
+
+/**
+ * Initialize BitstreamContext.
+ * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes
+ * larger than the actual read bits because some optimized bitstream
+ * readers read 32 or 64 bits at once and could read over the end
+ * @param bit_size the size of the buffer in bits
+ * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
+ */
+static inline int BS_FUNC(init)(BSCTX *bc, const uint8_t *buffer,
+ unsigned int bit_size)
+{
+ unsigned int buffer_size;
+
+ if (bit_size > INT_MAX - 7 || !buffer) {
+ bc->buffer = NULL;
+ bc->ptr = NULL;
+ bc->bits_valid = 0;
+ return AVERROR_INVALIDDATA;
+ }
+
+ buffer_size = (bit_size + 7) >> 3;
+
+ bc->buffer = buffer;
+ bc->buffer_end = buffer + buffer_size;
+ bc->ptr = bc->buffer;
+ bc->size_in_bits = bit_size;
+ bc->bits_valid = 0;
+ bc->bits = 0;
+
+ BS_FUNC(priv_refill_64)(bc);
+
+ return 0;
+}
+
+/**
+ * Initialize BitstreamContext.
+ * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes
+ * larger than the actual read bits because some optimized bitstream
+ * readers read 32 or 64 bits at once and could read over the end
+ * @param byte_size the size of the buffer in bytes
+ * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow
+ */
+static inline int BS_FUNC(init8)(BSCTX *bc, const uint8_t *buffer,
+ unsigned int byte_size)
+{
+ if (byte_size > INT_MAX / 8)
+ return AVERROR_INVALIDDATA;
+ return BS_FUNC(init)(bc, buffer, byte_size * 8);
+}
+
+/**
+ * Return number of bits already read.
+ */
+static inline int BS_FUNC(tell)(const BSCTX *bc)
+{
+ return (bc->ptr - bc->buffer) * 8 - bc->bits_valid;
+}
+
+/**
+ * Return buffer size in bits.
+ */
+static inline int BS_FUNC(size)(const BSCTX *bc)
+{
+ return bc->size_in_bits;
+}
+
+/**
+ * Return the number of the bits left in a buffer.
+ */
+static inline int BS_FUNC(left)(const BSCTX *bc)
+{
+ return (bc->buffer - bc->ptr) * 8 + bc->size_in_bits + bc->bits_valid;
+}
+
+static inline uint64_t BS_FUNC(priv_val_show)(BSCTX *bc, unsigned int n)
+{
+ av_assert2(n > 0 && n <= 64);
+
+#ifdef BITSTREAM_TEMPLATE_LE
+ return bc->bits & (UINT64_MAX >> (64 - n));
+#else
+ return bc->bits >> (64 - n);
+#endif
+}
+
+static inline void BS_FUNC(priv_skip_remaining)(BSCTX *bc, unsigned int n)
+{
+#ifdef BITSTREAM_TEMPLATE_LE
+ bc->bits >>= n;
+#else
+ bc->bits <<= n;
+#endif
+ bc->bits_valid -= n;
+}
+
+static inline uint64_t BS_FUNC(priv_val_get)(BSCTX *bc, unsigned int n)
+{
+ uint64_t ret;
+
+ av_assert2(n > 0 && n < 64);
+
+ ret = BS_FUNC(priv_val_show)(bc, n);
+ BS_FUNC(priv_skip_remaining)(bc, n);
+
+ return ret;
+}
+
+/**
+ * Return one bit from the buffer.
+ */
+static inline unsigned int BS_FUNC(read_bit)(BSCTX *bc)
+{
+ if (!bc->bits_valid && BS_FUNC(priv_refill_64)(bc) < 0)
+ return 0;
+
+ return BS_FUNC(priv_val_get)(bc, 1);
+}
+
+/**
+ * Return n bits from the buffer, n has to be in the 1-32 range.
+ * May be faster than bits_read() when n is not a compile-time constant and is
+ * known to be non-zero;
+ */
+static inline uint32_t BS_FUNC(read_nz)(BSCTX *bc, unsigned int n)
+{
+ av_assert2(n > 0 && n <= 32);
+
+ if (n > bc->bits_valid) {
+ if (BS_FUNC(priv_refill_32)(bc) < 0)
+ bc->bits_valid = n;
+ }
+
+ return BS_FUNC(priv_val_get)(bc, n);
+}
+
+/**
+ * Return n bits from the buffer, n has to be in the 0-32 range.
+ */
+static inline uint32_t BS_FUNC(read)(BSCTX *bc, unsigned int n)
+{
+ av_assert2(n <= 32);
+
+ if (!n)
+ return 0;
+
+ return BS_FUNC(read_nz)(bc, n);
+}
+
+/**
+ * Return n bits from the buffer, n has to be in the 0-63 range.
+ */
+static inline uint64_t BS_FUNC(read_63)(BSCTX *bc, unsigned int n)
+{
+ uint64_t ret = 0;
+ unsigned left = 0;
+
+ av_assert2(n <= 63);
+
+ if (!n)
+ return 0;
+
+ if (n > bc->bits_valid) {
+ left = bc->bits_valid;
+ n -= left;
+
+ if (left)
+ ret = BS_FUNC(priv_val_get)(bc, left);
+
+ if (BS_FUNC(priv_refill_64)(bc) < 0)
+ bc->bits_valid = n;
+
+ }
+
+#ifdef BITSTREAM_TEMPLATE_LE
+ ret = BS_FUNC(priv_val_get)(bc, n) << left | ret;
+#else
+ ret = BS_FUNC(priv_val_get)(bc, n) | ret << n;
+#endif
+
+ return ret;
+}
+
+/**
+ * Return n bits from the buffer, n has to be in the 0-64 range.
+ */
+static inline uint64_t BS_FUNC(read_64)(BSCTX *bc, unsigned int n)
+{
+ av_assert2(n <= 64);
+
+ if (n == 64) {
+ uint64_t ret = BS_FUNC(read_63)(bc, 63);
+#ifdef BITSTREAM_TEMPLATE_LE
+ return ret | ((uint64_t)BS_FUNC(read_bit)(bc) << 63);
+#else
+ return (ret << 1) | (uint64_t)BS_FUNC(read_bit)(bc);
+#endif
+ }
+ return BS_FUNC(read_63)(bc, n);
+}
+
+/**
+ * Return n bits from the buffer as a signed integer, n has to be in the 1-32
+ * range. May be faster than bits_read_signed() when n is not a compile-time
+ * constant and is known to be non-zero;
+ */
+static inline int32_t BS_FUNC(read_signed_nz)(BSCTX *bc, unsigned int n)
+{
+ av_assert2(n > 0 && n <= 32);
+ return sign_extend(BS_FUNC(read_nz)(bc, n), n);
+}
+
+/**
+ * Return n bits from the buffer as a signed integer.
+ * n has to be in the 0-32 range.
+ */
+static inline int32_t BS_FUNC(read_signed)(BSCTX *bc, unsigned int n)
+{
+ av_assert2(n <= 32);
+
+ if (!n)
+ return 0;
+
+ return BS_FUNC(read_signed_nz)(bc, n);
+}
+
+/**
+ * Return n bits from the buffer but do not change the buffer state.
+ * n has to be in the 1-32 range. May
+ */
+static inline uint32_t BS_FUNC(peek_nz)(BSCTX *bc, unsigned int n)
+{
+ av_assert2(n > 0 && n <= 32);
+
+ if (n > bc->bits_valid)
+ BS_FUNC(priv_refill_32)(bc);
+
+ return BS_FUNC(priv_val_show)(bc, n);
+}
+
+/**
+ * Return n bits from the buffer but do not change the buffer state.
+ * n has to be in the 0-32 range.
+ */
+static inline uint32_t BS_FUNC(peek)(BSCTX *bc, unsigned int n)
+{
+ av_assert2(n <= 32);
+
+ if (!n)
+ return 0;
+
+ return BS_FUNC(peek_nz)(bc, n);
+}
+
+/**
+ * Return n bits from the buffer as a signed integer, do not change the buffer
+ * state. n has to be in the 1-32 range. May be faster than bits_peek_signed()
+ * when n is not a compile-time constant and is known to be non-zero;
+ */
+static inline int BS_FUNC(peek_signed_nz)(BSCTX *bc, unsigned int n)
+{
+ av_assert2(n > 0 && n <= 32);
+ return sign_extend(BS_FUNC(peek_nz)(bc, n), n);
+}
+
+/**
+ * Return n bits from the buffer as a signed integer,
+ * do not change the buffer state.
+ * n has to be in the 0-32 range.
+ */
+static inline int BS_FUNC(peek_signed)(BSCTX *bc, unsigned int n)
+{
+ av_assert2(n <= 32);
+
+ if (!n)
+ return 0;
+
+ return BS_FUNC(peek_signed_nz)(bc, n);
+}
+
+/**
+ * Skip n bits in the buffer.
+ */
+static inline void BS_FUNC(skip)(BSCTX *bc, unsigned int n)
+{
+ if (n < bc->bits_valid)
+ BS_FUNC(priv_skip_remaining)(bc, n);
+ else {
+ n -= bc->bits_valid;
+ bc->bits = 0;
+ bc->bits_valid = 0;
+
+ if (n >= 64) {
+ unsigned int skip = n / 8;
+
+ n -= skip * 8;
+ bc->ptr += skip;
+ }
+ BS_FUNC(priv_refill_64)(bc);
+ if (n)
+ BS_FUNC(priv_skip_remaining)(bc, n);
+ }
+}
+
+/**
+ * Seek to the given bit position.
+ */
+static inline void BS_FUNC(seek)(BSCTX *bc, unsigned pos)
+{
+ bc->ptr = bc->buffer;
+ bc->bits = 0;
+ bc->bits_valid = 0;
+
+ BS_FUNC(skip)(bc, pos);
+}
+
+/**
+ * Skip bits to a byte boundary.
+ */
+static inline const uint8_t *BS_FUNC(align)(BSCTX *bc)
+{
+ unsigned int n = -BS_FUNC(tell)(bc) & 7;
+ if (n)
+ BS_FUNC(skip)(bc, n);
+ return bc->buffer + (BS_FUNC(tell)(bc) >> 3);
+}
+
+/**
+ * Read MPEG-1 dc-style VLC (sign bit + mantissa with no MSB).
+ * If MSB not set it is negative.
+ * @param n length in bits
+ */
+static inline int BS_FUNC(read_xbits)(BSCTX *bc, unsigned int n)
+{
+ int32_t cache = BS_FUNC(peek)(bc, 32);
+ int sign = ~cache >> 31;
+ BS_FUNC(priv_skip_remaining)(bc, n);
+
+ return ((((uint32_t)(sign ^ cache)) >> (32 - n)) ^ sign) - sign;
+}
+
+/**
+ * Return decoded truncated unary code for the values 0, 1, 2.
+ */
+static inline int BS_FUNC(decode012)(BSCTX *bc)
+{
+ if (!BS_FUNC(read_bit)(bc))
+ return 0;
+ else
+ return BS_FUNC(read_bit)(bc) + 1;
+}
+
+/**
+ * Return decoded truncated unary code for the values 2, 1, 0.
+ */
+static inline int BS_FUNC(decode210)(BSCTX *bc)
+{
+ if (BS_FUNC(read_bit)(bc))
+ return 0;
+ else
+ return 2 - BS_FUNC(read_bit)(bc);
+}
+
+/* Read sign bit and flip the sign of the provided value accordingly. */
+static inline int BS_FUNC(apply_sign)(BSCTX *bc, int val)
+{
+ int sign = BS_FUNC(read_signed)(bc, 1);
+ return (val ^ sign) - sign;
+}
+
+static inline int BS_FUNC(skip_1stop_8data)(BSCTX *s)
+{
+ if (BS_FUNC(left)(s) <= 0)
+ return AVERROR_INVALIDDATA;
+
+ while (BS_FUNC(read_bit)(s)) {
+ BS_FUNC(skip)(s, 8);
+ if (BS_FUNC(left)(s) <= 0)
+ return AVERROR_INVALIDDATA;
+ }
+
+ return 0;
+}
+
+/**
+ * Return the LUT element for the given bitstream configuration.
+ */
+static inline int BS_FUNC(priv_set_idx)(BSCTX *bc, int code, int *n,
+ int *nb_bits, const VLCElem *table)
+{
+ unsigned idx;
+
+ *nb_bits = -*n;
+ idx = BS_FUNC(peek)(bc, *nb_bits) + code;
+ *n = table[idx].len;
+
+ return table[idx].sym;
+}
+
+/**
+ * Parse a vlc code.
+ * @param bits is the number of bits which will be read at once, must be
+ * identical to nb_bits in init_vlc()
+ * @param max_depth is the number of times bits bits must be read to completely
+ * read the longest vlc code
+ * = (max_vlc_length + bits - 1) / bits
+ * If the vlc code is invalid and max_depth=1, then no bits will be removed.
+ * If the vlc code is invalid and max_depth>1, then the number of bits removed
+ * is undefined.
+ */
+static inline int BS_FUNC(read_vlc)(BSCTX *bc, const VLCElem *table,
+ int bits, int max_depth)
+{
+ int nb_bits;
+ unsigned idx = BS_FUNC(peek)(bc, bits);
+ int code = table[idx].sym;
+ int n = table[idx].len;
+
+ if (max_depth > 1 && n < 0) {
+ BS_FUNC(priv_skip_remaining)(bc, bits);
+ code = BS_FUNC(priv_set_idx)(bc, code, &n, &nb_bits, table);
+ if (max_depth > 2 && n < 0) {
+ BS_FUNC(priv_skip_remaining)(bc, nb_bits);
+ code = BS_FUNC(priv_set_idx)(bc, code, &n, &nb_bits, table);
+ }
+ }
+ BS_FUNC(priv_skip_remaining)(bc, n);
+
+ return code;
+}
+
+#undef BSCTX
+#undef BS_FUNC
+#undef BS_JOIN3
+#undef BS_JOIN
+#undef BS_SUFFIX_UPPER
+#undef BS_SUFFIX_LOWER
diff --git a/libavcodec/blockdsp.c b/libavcodec/blockdsp.c
index c8f85dd20..98f06c5d1 100644
--- a/libavcodec/blockdsp.c
+++ b/libavcodec/blockdsp.c
@@ -21,7 +21,6 @@
#include "config.h"
#include "libavutil/attributes.h"
-#include "avcodec.h"
#include "blockdsp.h"
static void clear_block_c(int16_t *block)
@@ -56,7 +55,7 @@ static void fill_block8_c(uint8_t *block, uint8_t value, ptrdiff_t line_size,
}
}
-av_cold void ff_blockdsp_init(BlockDSPContext *c, AVCodecContext *avctx)
+av_cold void ff_blockdsp_init(BlockDSPContext *c)
{
c->clear_block = clear_block_c;
c->clear_blocks = clear_blocks_c;
@@ -71,7 +70,7 @@ av_cold void ff_blockdsp_init(BlockDSPContext *c, AVCodecContext *avctx)
#elif ARCH_PPC
ff_blockdsp_init_ppc(c);
#elif ARCH_X86
- ff_blockdsp_init_x86(c, avctx);
+ ff_blockdsp_init_x86(c);
#elif ARCH_MIPS
ff_blockdsp_init_mips(c);
#endif
diff --git a/libavcodec/blockdsp.h b/libavcodec/blockdsp.h
index 58eecffb0..d853adada 100644
--- a/libavcodec/blockdsp.h
+++ b/libavcodec/blockdsp.h
@@ -22,8 +22,6 @@
#include
#include
-#include "avcodec.h"
-
/* add and put pixel (decoding)
* Block sizes for op_pixels_func are 8x4,8x8 16x8 16x16.
* h for op_pixels_func is limited to { width / 2, width },
@@ -38,12 +36,12 @@ typedef struct BlockDSPContext {
op_fill_func fill_block_tab[2];
} BlockDSPContext;
-void ff_blockdsp_init(BlockDSPContext *c, AVCodecContext *avctx);
+void ff_blockdsp_init(BlockDSPContext *c);
void ff_blockdsp_init_alpha(BlockDSPContext *c);
void ff_blockdsp_init_arm(BlockDSPContext *c);
void ff_blockdsp_init_ppc(BlockDSPContext *c);
-void ff_blockdsp_init_x86(BlockDSPContext *c, AVCodecContext *avctx);
+void ff_blockdsp_init_x86(BlockDSPContext *c);
void ff_blockdsp_init_mips(BlockDSPContext *c);
#endif /* AVCODEC_BLOCKDSP_H */
diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c
index 410065aba..d7e01f072 100644
--- a/libavcodec/bmp.c
+++ b/libavcodec/bmp.c
@@ -25,7 +25,7 @@
#include "bytestream.h"
#include "bmp.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "msrledec.h"
static int bmp_decode_frame(AVCodecContext *avctx, AVFrame *p,
@@ -366,7 +366,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, AVFrame *p,
const FFCodec ff_bmp_decoder = {
.p.name = "bmp",
- .p.long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
+ CODEC_LONG_NAME("BMP (Windows and OS/2 bitmap)"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_BMP,
.p.capabilities = AV_CODEC_CAP_DR1,
diff --git a/libavcodec/bmpenc.c b/libavcodec/bmpenc.c
index f28ce01f5..3e3ca324e 100644
--- a/libavcodec/bmpenc.c
+++ b/libavcodec/bmpenc.c
@@ -72,7 +72,8 @@ static int bmp_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
uint32_t palette256[256];
int pad_bytes_per_row, pal_entries = 0, compression = BMP_RGB;
int bit_count = avctx->bits_per_coded_sample;
- uint8_t *ptr, *buf;
+ const uint8_t *ptr;
+ uint8_t *buf;
switch (avctx->pix_fmt) {
case AV_PIX_FMT_RGB444:
@@ -157,10 +158,10 @@ static int bmp_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const FFCodec ff_bmp_encoder = {
.p.name = "bmp",
- .p.long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
+ CODEC_LONG_NAME("BMP (Windows and OS/2 bitmap)"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_BMP,
- .p.capabilities = AV_CODEC_CAP_DR1,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.init = bmp_encode_init,
FF_CODEC_ENCODE_CB(bmp_encode_frame),
.p.pix_fmts = (const enum AVPixelFormat[]){
@@ -170,5 +171,4 @@ const FFCodec ff_bmp_encoder = {
AV_PIX_FMT_MONOBLACK,
AV_PIX_FMT_NONE
},
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/bmvaudio.c b/libavcodec/bmvaudio.c
index f57ece032..fc211732b 100644
--- a/libavcodec/bmvaudio.c
+++ b/libavcodec/bmvaudio.c
@@ -24,7 +24,7 @@
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
static const int bmv_aud_mults[16] = {
16512, 8256, 4128, 2064, 1032, 516, 258, 192, 129, 88, 64, 56, 48, 40, 36, 32
@@ -80,11 +80,10 @@ static int bmv_aud_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_bmv_audio_decoder = {
.p.name = "bmv_audio",
- .p.long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV audio"),
+ CODEC_LONG_NAME("Discworld II BMV audio"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_BMV_AUDIO,
.init = bmv_aud_decode_init,
FF_CODEC_DECODE_CB(bmv_aud_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/bmvvideo.c b/libavcodec/bmvvideo.c
index c492d7fcf..92ce41c83 100644
--- a/libavcodec/bmvvideo.c
+++ b/libavcodec/bmvvideo.c
@@ -25,7 +25,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
enum BMVFlags{
BMV_NOP = 0,
@@ -287,12 +287,11 @@ static av_cold int decode_init(AVCodecContext *avctx)
const FFCodec ff_bmv_video_decoder = {
.p.name = "bmv_video",
- .p.long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV video"),
+ CODEC_LONG_NAME("Discworld II BMV video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_BMV_VIDEO,
.priv_data_size = sizeof(BMVDecContext),
.init = decode_init,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/bonk.c b/libavcodec/bonk.c
new file mode 100644
index 000000000..5f510e491
--- /dev/null
+++ b/libavcodec/bonk.c
@@ -0,0 +1,431 @@
+/*
+ * Bonk audio decoder
+ *
+ * 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/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "codec_internal.h"
+#include "decode.h"
+#define BITSTREAM_READER_LE
+#include "get_bits.h"
+#include "bytestream.h"
+
+typedef struct BitCount {
+ uint8_t bit;
+ unsigned count;
+} BitCount;
+
+typedef struct BonkContext {
+ GetBitContext gb;
+ int skip;
+
+ uint8_t *bitstream;
+ int64_t max_framesize;
+ int bitstream_size;
+ int bitstream_index;
+
+ uint64_t nb_samples;
+ int lossless;
+ int mid_side;
+ int n_taps;
+ int down_sampling;
+ int samples_per_packet;
+
+ int state[2][2048], k[2048];
+ int *samples[2];
+ int *input_samples;
+ uint8_t quant[2048];
+ BitCount *bits;
+} BonkContext;
+
+static av_cold int bonk_close(AVCodecContext *avctx)
+{
+ BonkContext *s = avctx->priv_data;
+
+ av_freep(&s->bitstream);
+ av_freep(&s->input_samples);
+ av_freep(&s->samples[0]);
+ av_freep(&s->samples[1]);
+ av_freep(&s->bits);
+ s->bitstream_size = 0;
+
+ return 0;
+}
+
+static av_cold int bonk_init(AVCodecContext *avctx)
+{
+ BonkContext *s = avctx->priv_data;
+
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+ if (avctx->extradata_size < 17)
+ return AVERROR(EINVAL);
+
+ if (avctx->extradata[0]) {
+ av_log(avctx, AV_LOG_ERROR, "Unsupported version.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (avctx->ch_layout.nb_channels < 1 || avctx->ch_layout.nb_channels > 2)
+ return AVERROR_INVALIDDATA;
+
+ s->nb_samples = AV_RL32(avctx->extradata + 1) / avctx->ch_layout.nb_channels;
+ if (!s->nb_samples)
+ s->nb_samples = UINT64_MAX;
+ s->lossless = avctx->extradata[10] != 0;
+ s->mid_side = avctx->extradata[11] != 0;
+ s->n_taps = AV_RL16(avctx->extradata + 12);
+ if (!s->n_taps || s->n_taps > 2048)
+ return AVERROR(EINVAL);
+
+ s->down_sampling = avctx->extradata[14];
+ if (!s->down_sampling)
+ return AVERROR(EINVAL);
+
+ s->samples_per_packet = AV_RL16(avctx->extradata + 15);
+ if (!s->samples_per_packet)
+ return AVERROR(EINVAL);
+
+ if (s->down_sampling * s->samples_per_packet < s->n_taps)
+ return AVERROR_INVALIDDATA;
+
+ s->max_framesize = s->samples_per_packet * avctx->ch_layout.nb_channels * s->down_sampling * 16LL;
+ if (s->max_framesize > (INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) / 8)
+ return AVERROR_INVALIDDATA;
+
+ s->bitstream = av_calloc(s->max_framesize + AV_INPUT_BUFFER_PADDING_SIZE, sizeof(*s->bitstream));
+ if (!s->bitstream)
+ return AVERROR(ENOMEM);
+
+ s->input_samples = av_calloc(s->samples_per_packet, sizeof(*s->input_samples));
+ if (!s->input_samples)
+ return AVERROR(ENOMEM);
+
+ s->samples[0] = av_calloc(s->samples_per_packet * s->down_sampling, sizeof(*s->samples[0]));
+ s->samples[1] = av_calloc(s->samples_per_packet * s->down_sampling, sizeof(*s->samples[0]));
+ if (!s->samples[0] || !s->samples[1])
+ return AVERROR(ENOMEM);
+
+ s->bits = av_calloc(s->max_framesize * 8, sizeof(*s->bits));
+ if (!s->bits)
+ return AVERROR(ENOMEM);
+
+ for (int i = 0; i < 512; i++) {
+ s->quant[i] = sqrt(i + 1);
+ }
+
+ return 0;
+}
+
+static unsigned read_uint_max(BonkContext *s, uint32_t max)
+{
+ unsigned value = 0;
+
+ if (max == 0)
+ return 0;
+
+ av_assert0(max >> 31 == 0);
+
+ for (unsigned i = 1; i <= max - value; i+=i)
+ if (get_bits1(&s->gb))
+ value += i;
+
+ return value;
+}
+
+static int intlist_read(BonkContext *s, int *buf, int entries, int base_2_part)
+{
+ int i, low_bits = 0, x = 0, max_x;
+ int n_zeros = 0, step = 256, dominant = 0;
+ int pos = 0, level = 0;
+ BitCount *bits = s->bits;
+
+ memset(buf, 0, entries * sizeof(*buf));
+ if (base_2_part) {
+ low_bits = get_bits(&s->gb, 4);
+
+ if (low_bits)
+ for (i = 0; i < entries; i++)
+ buf[i] = get_bits(&s->gb, low_bits);
+ }
+
+ while (n_zeros < entries) {
+ int steplet = step >> 8;
+
+ if (get_bits_left(&s->gb) <= 0)
+ return AVERROR_INVALIDDATA;
+
+ if (!get_bits1(&s->gb)) {
+ av_assert0(steplet >= 0);
+
+ if (steplet > 0) {
+ bits[x ].bit = dominant;
+ bits[x++].count = steplet;
+ }
+
+ if (!dominant)
+ n_zeros += steplet;
+
+ if (step > INT32_MAX*8LL/9 + 1)
+ return AVERROR_INVALIDDATA;
+ step += step / 8;
+ } else if (steplet > 0) {
+ int actual_run = read_uint_max(s, steplet - 1);
+
+ av_assert0(actual_run >= 0);
+
+ if (actual_run > 0) {
+ bits[x ].bit = dominant;
+ bits[x++].count = actual_run;
+ }
+
+ bits[x ].bit = !dominant;
+ bits[x++].count = 1;
+
+ if (!dominant)
+ n_zeros += actual_run;
+ else
+ n_zeros++;
+
+ step -= step / 8;
+ }
+
+ if (step < 256) {
+ step = 65536 / step;
+ dominant = !dominant;
+ }
+ }
+
+ max_x = x;
+ x = 0;
+ n_zeros = 0;
+ for (i = 0; n_zeros < entries; i++) {
+ if (pos >= entries) {
+ pos = 0;
+ level += 1 << low_bits;
+ }
+
+ if (level > 1 << 16)
+ return AVERROR_INVALIDDATA;
+
+ if (x >= max_x)
+ return AVERROR_INVALIDDATA;
+
+ if (buf[pos] >= level) {
+ if (bits[x].bit)
+ buf[pos] += 1 << low_bits;
+ else
+ n_zeros++;
+
+ bits[x].count--;
+ x += bits[x].count == 0;
+ }
+
+ pos++;
+ }
+
+ for (i = 0; i < entries; i++) {
+ if (buf[i] && get_bits1(&s->gb)) {
+ buf[i] = -buf[i];
+ }
+ }
+
+ return 0;
+}
+
+static inline int shift_down(int a, int b)
+{
+ return (a >> b) + (a < 0);
+}
+
+static inline int shift(int a, int b)
+{
+ return a + (1 << b - 1) >> b;
+}
+
+#define LATTICE_SHIFT 10
+#define SAMPLE_SHIFT 4
+#define SAMPLE_FACTOR (1 << SAMPLE_SHIFT)
+
+static int predictor_calc_error(int *k, int *state, int order, int error)
+{
+ int i, x = error - shift_down(k[order-1] * state[order-1], LATTICE_SHIFT);
+ int *k_ptr = &(k[order-2]),
+ *state_ptr = &(state[order-2]);
+
+ for (i = order-2; i >= 0; i--, k_ptr--, state_ptr--) {
+ unsigned k_value = *k_ptr, state_value = *state_ptr;
+
+ x -= shift_down(k_value * state_value, LATTICE_SHIFT);
+ state_ptr[1] = state_value + shift_down(k_value * x, LATTICE_SHIFT);
+ }
+
+ // don't drift too far, to avoid overflows
+ x = av_clip(x, -(SAMPLE_FACTOR << 16), SAMPLE_FACTOR << 16);
+
+ state[0] = x;
+
+ return x;
+}
+
+static void predictor_init_state(int *k, unsigned *state, int order)
+{
+ for (int i = order - 2; i >= 0; i--) {
+ unsigned x = state[i];
+
+ for (int j = 0, p = i + 1; p < order; j++, p++) {
+ int tmp = x + shift_down(k[j] * state[p], LATTICE_SHIFT);
+
+ state[p] += shift_down(k[j] * x, LATTICE_SHIFT);
+ x = tmp;
+ }
+ }
+}
+
+static int bonk_decode(AVCodecContext *avctx, AVFrame *frame,
+ int *got_frame_ptr, AVPacket *pkt)
+{
+ BonkContext *s = avctx->priv_data;
+ GetBitContext *gb = &s->gb;
+ const uint8_t *buf;
+ int quant, n, buf_size, input_buf_size;
+ int ret = AVERROR_INVALIDDATA;
+
+ if ((!pkt->size && !s->bitstream_size) || s->nb_samples == 0) {
+ *got_frame_ptr = 0;
+ return pkt->size;
+ }
+
+ buf_size = FFMIN(pkt->size, s->max_framesize - s->bitstream_size);
+ input_buf_size = buf_size;
+ if (s->bitstream_index + s->bitstream_size + buf_size + AV_INPUT_BUFFER_PADDING_SIZE > s->max_framesize) {
+ memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size);
+ s->bitstream_index = 0;
+ }
+ if (pkt->data)
+ memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], pkt->data, buf_size);
+ buf = &s->bitstream[s->bitstream_index];
+ buf_size += s->bitstream_size;
+ s->bitstream_size = buf_size;
+ if (buf_size < s->max_framesize && pkt->data) {
+ *got_frame_ptr = 0;
+ return input_buf_size;
+ }
+
+ frame->nb_samples = FFMIN(s->samples_per_packet * s->down_sampling, s->nb_samples);
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ goto fail;
+
+ if ((ret = init_get_bits8(gb, buf, buf_size)) < 0)
+ goto fail;
+
+ skip_bits(gb, s->skip);
+ if ((ret = intlist_read(s, s->k, s->n_taps, 0)) < 0)
+ goto fail;
+
+ for (int i = 0; i < s->n_taps; i++)
+ s->k[i] *= s->quant[i];
+ quant = s->lossless ? 1 : get_bits(&s->gb, 16) * SAMPLE_FACTOR;
+
+ for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
+ const int samples_per_packet = s->samples_per_packet;
+ const int down_sampling = s->down_sampling;
+ const int offset = samples_per_packet * down_sampling - 1;
+ int *state = s->state[ch];
+ int *sample = s->samples[ch];
+
+ predictor_init_state(s->k, state, s->n_taps);
+ if ((ret = intlist_read(s, s->input_samples, samples_per_packet, 1)) < 0)
+ goto fail;
+
+ for (int i = 0; i < samples_per_packet; i++) {
+ for (int j = 0; j < s->down_sampling - 1; j++) {
+ sample[0] = predictor_calc_error(s->k, state, s->n_taps, 0);
+ sample++;
+ }
+
+ sample[0] = predictor_calc_error(s->k, state, s->n_taps, s->input_samples[i] * (unsigned)quant);
+ sample++;
+ }
+
+ sample = s->samples[ch];
+ for (int i = 0; i < s->n_taps; i++)
+ state[i] = sample[offset - i];
+ }
+
+ if (s->mid_side && avctx->ch_layout.nb_channels == 2) {
+ for (int i = 0; i < frame->nb_samples; i++) {
+ s->samples[1][i] += shift(s->samples[0][i], 1);
+ s->samples[0][i] -= s->samples[1][i];
+ }
+ }
+
+ if (!s->lossless) {
+ for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
+ int *samples = s->samples[ch];
+ for (int i = 0; i < frame->nb_samples; i++)
+ samples[i] = shift(samples[i], 4);
+ }
+ }
+
+ for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
+ int16_t *osamples = (int16_t *)frame->extended_data[ch];
+ int *samples = s->samples[ch];
+ for (int i = 0; i < frame->nb_samples; i++)
+ osamples[i] = av_clip_int16(samples[i]);
+ }
+
+ s->nb_samples -= frame->nb_samples;
+
+ s->skip = get_bits_count(gb) - 8 * (get_bits_count(gb) / 8);
+ n = get_bits_count(gb) / 8;
+
+ if (n > buf_size) {
+fail:
+ s->bitstream_size = 0;
+ s->bitstream_index = 0;
+ return AVERROR_INVALIDDATA;
+ }
+
+ *got_frame_ptr = 1;
+
+ if (s->bitstream_size) {
+ s->bitstream_index += n;
+ s->bitstream_size -= n;
+ return input_buf_size;
+ }
+ return n;
+}
+
+const FFCodec ff_bonk_decoder = {
+ .p.name = "bonk",
+ CODEC_LONG_NAME("Bonk audio"),
+ .p.type = AVMEDIA_TYPE_AUDIO,
+ .p.id = AV_CODEC_ID_BONK,
+ .priv_data_size = sizeof(BonkContext),
+ .init = bonk_init,
+ FF_CODEC_DECODE_CB(bonk_decode),
+ .close = bonk_close,
+ .p.capabilities = AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_DR1 |
+ AV_CODEC_CAP_SUBFRAMES,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
+ .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+ AV_SAMPLE_FMT_NONE },
+};
diff --git a/libavcodec/brenderpix.c b/libavcodec/brenderpix.c
index 9807a11cf..e95ab3d4a 100644
--- a/libavcodec/brenderpix.c
+++ b/libavcodec/brenderpix.c
@@ -26,7 +26,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#define HEADER1_CHUNK 0x03
#define HEADER2_CHUNK 0x3D
@@ -286,7 +286,7 @@ static int pix_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_brender_pix_decoder = {
.p.name = "brender_pix",
- .p.long_name = NULL_IF_CONFIG_SMALL("BRender PIX image"),
+ CODEC_LONG_NAME("BRender PIX image"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_BRENDER_PIX,
.p.capabilities = AV_CODEC_CAP_DR1,
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index 69d91a16a..a09c69f24 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -164,6 +164,8 @@ int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **ctx);
/**
* Prepare the filter for use, after all the parameters and options have been
* set.
+ *
+ * @param ctx a AVBSFContext previously allocated with av_bsf_alloc()
*/
int av_bsf_init(AVBSFContext *ctx);
@@ -174,6 +176,7 @@ int av_bsf_init(AVBSFContext *ctx);
* av_bsf_receive_packet() repeatedly until it returns AVERROR(EAGAIN) or
* AVERROR_EOF.
*
+ * @param ctx an initialized AVBSFContext
* @param pkt the packet to filter. The bitstream filter will take ownership of
* the packet and reset the contents of pkt. pkt is not touched if an error occurs.
* If pkt is empty (i.e. NULL, or pkt->data is NULL and pkt->side_data_elems zero),
@@ -192,6 +195,7 @@ int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt);
/**
* Retrieve a filtered packet.
*
+ * @param ctx an initialized AVBSFContext
* @param[out] pkt this struct will be filled with the contents of the filtered
* packet. It is owned by the caller and must be freed using
* av_packet_unref() when it is no longer needed.
diff --git a/libavcodec/bswapdsp.c b/libavcodec/bswapdsp.c
index 4c4ea10ac..f0ea2b55c 100644
--- a/libavcodec/bswapdsp.c
+++ b/libavcodec/bswapdsp.c
@@ -51,7 +51,9 @@ av_cold void ff_bswapdsp_init(BswapDSPContext *c)
c->bswap_buf = bswap_buf;
c->bswap16_buf = bswap16_buf;
-#if ARCH_X86
+#if ARCH_RISCV
+ ff_bswapdsp_init_riscv(c);
+#elif ARCH_X86
ff_bswapdsp_init_x86(c);
#endif
}
diff --git a/libavcodec/bswapdsp.h b/libavcodec/bswapdsp.h
index 4d1909225..6f4db6611 100644
--- a/libavcodec/bswapdsp.h
+++ b/libavcodec/bswapdsp.h
@@ -27,6 +27,7 @@ typedef struct BswapDSPContext {
} BswapDSPContext;
void ff_bswapdsp_init(BswapDSPContext *c);
+void ff_bswapdsp_init_riscv(BswapDSPContext *c);
void ff_bswapdsp_init_x86(BswapDSPContext *c);
#endif /* AVCODEC_BSWAPDSP_H */
diff --git a/libavcodec/c93.c b/libavcodec/c93.c
index 050bb4274..bfcbc7c15 100644
--- a/libavcodec/c93.c
+++ b/libavcodec/c93.c
@@ -22,7 +22,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
typedef struct C93DecoderContext {
AVFrame *pictures[2];
@@ -130,7 +130,8 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
AVFrame * const oldpic = c93->pictures[c93->currentpic^1];
GetByteContext gb;
uint8_t *out;
- int stride, ret, i, x, y, b, bt = 0;
+ int ret, i, x, y, b, bt = 0;
+ ptrdiff_t stride;
if ((ret = ff_set_dimensions(avctx, WIDTH, HEIGHT)) < 0)
return ret;
@@ -156,7 +157,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
out = newpic->data[0] + y * stride;
for (x = 0; x < WIDTH; x += 8) {
uint8_t *copy_from = oldpic->data[0];
- unsigned int offset, j;
uint8_t cols[4], grps[4];
C93BlockType block_type;
@@ -165,16 +165,17 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
block_type= bt & 0x0F;
switch (block_type) {
- case C93_8X8_FROM_PREV:
- offset = bytestream2_get_le16(&gb);
+ case C93_8X8_FROM_PREV: {
+ int offset = bytestream2_get_le16(&gb);
if ((ret = copy_block(avctx, out, copy_from, offset, 8, stride)) < 0)
return ret;
break;
+ }
case C93_4X4_FROM_CURR:
copy_from = newpic->data[0];
case C93_4X4_FROM_PREV:
- for (j = 0; j < 8; j += 4) {
+ for (int j = 0; j < 8; j += 4) {
for (i = 0; i < 8; i += 4) {
int offset = bytestream2_get_le16(&gb);
int from_x = offset % WIDTH;
@@ -203,7 +204,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
case C93_4X4_2COLOR:
case C93_4X4_4COLOR:
case C93_4X4_4COLOR_GRP:
- for (j = 0; j < 8; j += 4) {
+ for (int j = 0; j < 8; j += 4) {
for (i = 0; i < 8; i += 4) {
if (block_type == C93_4X4_2COLOR) {
bytestream2_get_buffer(&gb, cols, 2);
@@ -226,7 +227,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
break;
case C93_8X8_INTRA:
- for (j = 0; j < 8; j++)
+ for (int j = 0; j < 8; j++)
bytestream2_get_buffer(&gb, out + j*stride, 8);
break;
@@ -260,7 +261,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
const FFCodec ff_c93_decoder = {
.p.name = "c93",
- .p.long_name = NULL_IF_CONFIG_SMALL("Interplay C93"),
+ CODEC_LONG_NAME("Interplay C93"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_C93,
.priv_data_size = sizeof(C93DecoderContext),
@@ -268,5 +269,5 @@ const FFCodec ff_c93_decoder = {
.close = decode_end,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/cavs.c b/libavcodec/cavs.c
index 87bbe26f9..fdd577f7f 100644
--- a/libavcodec/cavs.c
+++ b/libavcodec/cavs.c
@@ -792,15 +792,14 @@ int ff_cavs_init_top_lines(AVSContext *h)
av_cold int ff_cavs_init(AVCodecContext *avctx)
{
AVSContext *h = avctx->priv_data;
+ uint8_t permutation[64];
- ff_blockdsp_init(&h->bdsp, avctx);
+ ff_blockdsp_init(&h->bdsp);
ff_h264chroma_init(&h->h264chroma, 8);
- ff_idctdsp_init(&h->idsp, avctx);
ff_videodsp_init(&h->vdsp, 8);
- ff_cavsdsp_init(&h->cdsp, avctx);
- ff_init_scantable_permutation(h->idsp.idct_permutation,
- h->cdsp.idct_perm);
- ff_init_scantable(h->idsp.idct_permutation, &h->scantable, ff_zigzag_direct);
+ ff_cavsdsp_init(&h->cdsp);
+ ff_init_scantable_permutation(permutation, h->cdsp.idct_perm);
+ ff_permute_scantable(h->permutated_scantable, ff_zigzag_direct, permutation);
h->avctx = avctx;
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
diff --git a/libavcodec/cavs.h b/libavcodec/cavs.h
index cbc163fb4..244c322b3 100644
--- a/libavcodec/cavs.h
+++ b/libavcodec/cavs.h
@@ -22,12 +22,16 @@
#ifndef AVCODEC_CAVS_H
#define AVCODEC_CAVS_H
+#include
+#include
+
+#include "libavutil/frame.h"
#include "libavutil/mem_internal.h"
+#include "avcodec.h"
#include "cavsdsp.h"
#include "blockdsp.h"
#include "h264chroma.h"
-#include "idctdsp.h"
#include "get_bits.h"
#include "videodsp.h"
@@ -166,7 +170,6 @@ typedef struct AVSContext {
AVCodecContext *avctx;
BlockDSPContext bdsp;
H264ChromaContext h264chroma;
- IDCTDSPContext idsp;
VideoDSPContext vdsp;
CAVSDSPContext cdsp;
GetBitContext gb;
@@ -220,7 +223,7 @@ typedef struct AVSContext {
int qp_fixed;
int pic_qp_fixed;
int cbp;
- ScanTable scantable;
+ uint8_t permutated_scantable[64];
/** intra prediction is done with un-deblocked samples
they are saved here before deblocking the MB */
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c
index 6c69c2c94..b1fa9a981 100644
--- a/libavcodec/cavsdec.c
+++ b/libavcodec/cavsdec.c
@@ -31,7 +31,7 @@
#include "golomb.h"
#include "cavs.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "mathops.h"
#include "mpeg12data.h"
#include "startcode.h"
@@ -521,7 +521,7 @@ static inline int dequant(AVSContext *h, int16_t *level_buf, uint8_t *run_buf,
{
int round = 1 << (shift - 1);
int pos = -1;
- const uint8_t *scantab = h->scantable.permutated;
+ const uint8_t *scantab = h->permutated_scantable;
/* inverse scan and dequantization */
while (--coeff_num >= 0) {
@@ -1317,7 +1317,7 @@ static int cavs_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
const FFCodec ff_cavs_decoder = {
.p.name = "cavs",
- .p.long_name = NULL_IF_CONFIG_SMALL("Chinese AVS (Audio Video Standard) (AVS1-P2, JiZhun profile)"),
+ CODEC_LONG_NAME("Chinese AVS (Audio Video Standard) (AVS1-P2, JiZhun profile)"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CAVS,
.priv_data_size = sizeof(AVSContext),
@@ -1326,5 +1326,5 @@ const FFCodec ff_cavs_decoder = {
FF_CODEC_DECODE_CB(cavs_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
.flush = cavs_flush,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/cavsdsp.c b/libavcodec/cavsdsp.c
index b096de452..69420242d 100644
--- a/libavcodec/cavsdsp.c
+++ b/libavcodec/cavsdsp.c
@@ -22,8 +22,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include
-
#include "idctdsp.h"
#include "mathops.h"
#include "cavsdsp.h"
@@ -427,13 +425,14 @@ static void OPNAME ## cavs_filt8_hv_ ## NAME(uint8_t *dst, const uint8_t *src1,
\
static void OPNAME ## cavs_filt16_hv_ ## NAME(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, ptrdiff_t dstStride, ptrdiff_t srcStride)\
{ \
- OPNAME ## cavs_filt8_hv_ ## NAME(dst , src1, src2 , dstStride, srcStride); \
- OPNAME ## cavs_filt8_hv_ ## NAME(dst+8, src1+8, src2+8, dstStride, srcStride); \
+ OPNAME ## cavs_filt8_hv_ ## NAME(dst , src1, FULL ? src2 : NULL, dstStride, srcStride); \
+ OPNAME ## cavs_filt8_hv_ ## NAME(dst+8, src1+8, FULL ? src2 + 8 : NULL, dstStride, srcStride); \
src1 += 8*srcStride;\
- src2 += 8*srcStride;\
+ if (FULL) \
+ src2 += 8*srcStride;\
dst += 8*dstStride;\
- OPNAME ## cavs_filt8_hv_ ## NAME(dst , src1, src2 , dstStride, srcStride); \
- OPNAME ## cavs_filt8_hv_ ## NAME(dst+8, src1+8, src2+8, dstStride, srcStride); \
+ OPNAME ## cavs_filt8_hv_ ## NAME(dst , src1, FULL ? src2 : NULL, dstStride, srcStride); \
+ OPNAME ## cavs_filt8_hv_ ## NAME(dst+8, src1+8, FULL ? src2 + 8 : NULL, dstStride, srcStride); \
}\
#define CAVS_MC(OPNAME, SIZE) \
@@ -494,22 +493,22 @@ static void OPNAME ## cavs_qpel ## SIZE ## _mc33_c(uint8_t *dst, const uint8_t *
\
static void OPNAME ## cavs_qpel ## SIZE ## _mc21_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
{\
- OPNAME ## cavs_filt ## SIZE ## _hv_ff(dst, src, src+stride+1,stride, stride); \
+ OPNAME ## cavs_filt ## SIZE ## _hv_ff(dst, src, NULL, stride, stride); \
}\
\
static void OPNAME ## cavs_qpel ## SIZE ## _mc12_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
{\
- OPNAME ## cavs_filt ## SIZE ## _hv_ii(dst, src, src+stride+1,stride, stride); \
+ OPNAME ## cavs_filt ## SIZE ## _hv_ii(dst, src, NULL, stride, stride); \
}\
\
static void OPNAME ## cavs_qpel ## SIZE ## _mc32_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
{\
- OPNAME ## cavs_filt ## SIZE ## _hv_kk(dst, src, src+stride+1,stride, stride); \
+ OPNAME ## cavs_filt ## SIZE ## _hv_kk(dst, src, NULL, stride, stride); \
}\
\
static void OPNAME ## cavs_qpel ## SIZE ## _mc23_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
{\
- OPNAME ## cavs_filt ## SIZE ## _hv_qq(dst, src, src+stride+1,stride, stride); \
+ OPNAME ## cavs_filt ## SIZE ## _hv_qq(dst, src, NULL, stride, stride); \
}\
#define op_put1(a, b) a = cm[((b)+4)>>3]
@@ -548,7 +547,8 @@ CAVS_MC(avg_, 16)
#define put_cavs_qpel16_mc00_c ff_put_pixels16x16_c
#define avg_cavs_qpel16_mc00_c ff_avg_pixels16x16_c
-av_cold void ff_cavsdsp_init(CAVSDSPContext* c, AVCodecContext *avctx) {
+av_cold void ff_cavsdsp_init(CAVSDSPContext* c)
+{
#define dspfunc(PFX, IDX, NUM) \
c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_c; \
c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_c; \
@@ -578,6 +578,6 @@ av_cold void ff_cavsdsp_init(CAVSDSPContext* c, AVCodecContext *avctx) {
c->idct_perm = FF_IDCT_PERM_NONE;
#if ARCH_X86
- ff_cavsdsp_init_x86(c, avctx);
+ ff_cavsdsp_init_x86(c);
#endif
}
diff --git a/libavcodec/cavsdsp.h b/libavcodec/cavsdsp.h
index 9ccaa0add..2cd929896 100644
--- a/libavcodec/cavsdsp.h
+++ b/libavcodec/cavsdsp.h
@@ -22,9 +22,9 @@
#ifndef AVCODEC_CAVSDSP_H
#define AVCODEC_CAVSDSP_H
+#include
#include
-#include "avcodec.h"
#include "qpeldsp.h"
typedef struct CAVSDSPContext {
@@ -38,7 +38,7 @@ typedef struct CAVSDSPContext {
int idct_perm;
} CAVSDSPContext;
-void ff_cavsdsp_init(CAVSDSPContext* c, AVCodecContext *avctx);
-void ff_cavsdsp_init_x86(CAVSDSPContext* c, AVCodecContext *avctx);
+void ff_cavsdsp_init(CAVSDSPContext* c);
+void ff_cavsdsp_init_x86(CAVSDSPContext* c);
#endif /* AVCODEC_CAVSDSP_H */
diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c
index 8c0a5b571..504197e06 100644
--- a/libavcodec/cbs.c
+++ b/libavcodec/cbs.c
@@ -438,6 +438,10 @@ int ff_cbs_write_extradata(CodedBitstreamContext *ctx,
return err;
av_freep(&par->extradata);
+ par->extradata_size = 0;
+
+ if (!frag->data_size)
+ return 0;
par->extradata = av_malloc(frag->data_size +
AV_INPUT_BUFFER_PADDING_SIZE);
@@ -695,26 +699,6 @@ int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc,
}
-int ff_cbs_alloc_unit_content(CodedBitstreamUnit *unit,
- size_t size,
- void (*free)(void *opaque, uint8_t *data))
-{
- av_assert0(!unit->content && !unit->content_ref);
-
- unit->content = av_mallocz(size);
- if (!unit->content)
- return AVERROR(ENOMEM);
-
- unit->content_ref = av_buffer_create(unit->content, size,
- free, NULL, 0);
- if (!unit->content_ref) {
- av_freep(&unit->content);
- return AVERROR(ENOMEM);
- }
-
- return 0;
-}
-
static int cbs_insert_unit(CodedBitstreamFragment *frag,
int position)
{
@@ -855,12 +839,10 @@ void ff_cbs_delete_unit(CodedBitstreamFragment *frag,
static void cbs_default_free_unit_content(void *opaque, uint8_t *data)
{
const CodedBitstreamUnitTypeDescriptor *desc = opaque;
- if (desc->content_type == CBS_CONTENT_TYPE_INTERNAL_REFS) {
- int i;
- for (i = 0; i < desc->nb_ref_offsets; i++) {
- void **ptr = (void**)(data + desc->ref_offsets[i]);
- av_buffer_unref((AVBufferRef**)(ptr + 1));
- }
+
+ for (int i = 0; i < desc->type.ref.nb_offsets; i++) {
+ void **ptr = (void**)(data + desc->type.ref.offsets[i]);
+ av_buffer_unref((AVBufferRef**)(ptr + 1));
}
av_free(data);
}
@@ -880,12 +862,12 @@ static const CodedBitstreamUnitTypeDescriptor
if (desc->nb_unit_types == 0)
break;
if (desc->nb_unit_types == CBS_UNIT_TYPE_RANGE) {
- if (unit->type >= desc->unit_type_range_start &&
- unit->type <= desc->unit_type_range_end)
+ if (unit->type >= desc->unit_type.range.start &&
+ unit->type <= desc->unit_type.range.end)
return desc;
} else {
for (j = 0; j < desc->nb_unit_types; j++) {
- if (desc->unit_types[j] == unit->type)
+ if (desc->unit_type.list[j] == unit->type)
return desc;
}
}
@@ -893,8 +875,8 @@ static const CodedBitstreamUnitTypeDescriptor
return NULL;
}
-int ff_cbs_alloc_unit_content2(CodedBitstreamContext *ctx,
- CodedBitstreamUnit *unit)
+int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx,
+ CodedBitstreamUnit *unit)
{
const CodedBitstreamUnitTypeDescriptor *desc;
@@ -910,7 +892,8 @@ int ff_cbs_alloc_unit_content2(CodedBitstreamContext *ctx,
unit->content_ref =
av_buffer_create(unit->content, desc->content_size,
- desc->content_free ? desc->content_free
+ desc->content_type == CBS_CONTENT_TYPE_COMPLEX
+ ? desc->type.complex.content_free
: cbs_default_free_unit_content,
(void*)desc, 0);
if (!unit->content_ref) {
@@ -921,13 +904,12 @@ int ff_cbs_alloc_unit_content2(CodedBitstreamContext *ctx,
return 0;
}
-static int cbs_clone_unit_content(AVBufferRef **clone_ref,
- CodedBitstreamUnit *unit,
- const CodedBitstreamUnitTypeDescriptor *desc)
+static int cbs_clone_internal_refs_unit_content(AVBufferRef **clone_ref,
+ const CodedBitstreamUnit *unit,
+ const CodedBitstreamUnitTypeDescriptor *desc)
{
- uint8_t *src, *copy;
- uint8_t **src_ptr, **copy_ptr;
- AVBufferRef **src_buf, **copy_buf;
+ const uint8_t *src;
+ uint8_t *copy;
int err, i;
av_assert0(unit->content);
@@ -937,17 +919,17 @@ static int cbs_clone_unit_content(AVBufferRef **clone_ref,
if (!copy)
return AVERROR(ENOMEM);
- for (i = 0; i < desc->nb_ref_offsets; i++) {
- src_ptr = (uint8_t**)(src + desc->ref_offsets[i]);
- src_buf = (AVBufferRef**)(src_ptr + 1);
- copy_ptr = (uint8_t**)(copy + desc->ref_offsets[i]);
- copy_buf = (AVBufferRef**)(copy_ptr + 1);
+ for (i = 0; i < desc->type.ref.nb_offsets; i++) {
+ const uint8_t *const *src_ptr = (const uint8_t* const*)(src + desc->type.ref.offsets[i]);
+ const AVBufferRef *src_buf = *(AVBufferRef**)(src_ptr + 1);
+ uint8_t **copy_ptr = (uint8_t**)(copy + desc->type.ref.offsets[i]);
+ AVBufferRef **copy_buf = (AVBufferRef**)(copy_ptr + 1);
if (!*src_ptr) {
- av_assert0(!*src_buf);
+ av_assert0(!src_buf);
continue;
}
- if (!*src_buf) {
+ if (!src_buf) {
// We can't handle a non-refcounted pointer here - we don't
// have enough information to handle whatever structure lies
// at the other end of it.
@@ -955,21 +937,14 @@ static int cbs_clone_unit_content(AVBufferRef **clone_ref,
goto fail;
}
- // src_ptr is required to point somewhere inside src_buf. If it
- // doesn't, there is a bug somewhere.
- av_assert0(*src_ptr >= (*src_buf)->data &&
- *src_ptr < (*src_buf)->data + (*src_buf)->size);
-
- *copy_buf = av_buffer_ref(*src_buf);
+ *copy_buf = av_buffer_ref(src_buf);
if (!*copy_buf) {
err = AVERROR(ENOMEM);
goto fail;
}
- *copy_ptr = (*copy_buf)->data + (*src_ptr - (*src_buf)->data);
}
*clone_ref = av_buffer_create(copy, desc->content_size,
- desc->content_free ? desc->content_free :
cbs_default_free_unit_content,
(void*)desc, 0);
if (!*clone_ref) {
@@ -981,46 +956,37 @@ static int cbs_clone_unit_content(AVBufferRef **clone_ref,
fail:
for (--i; i >= 0; i--)
- av_buffer_unref((AVBufferRef**)(copy + desc->ref_offsets[i]));
+ av_buffer_unref((AVBufferRef**)(copy + desc->type.ref.offsets[i]));
av_freep(©);
*clone_ref = NULL;
return err;
}
-int ff_cbs_make_unit_refcounted(CodedBitstreamContext *ctx,
- CodedBitstreamUnit *unit)
+/*
+ * On success, unit->content and unit->content_ref are updated with
+ * the new content; unit is untouched on failure.
+ * Any old content_ref is simply overwritten and not freed.
+ */
+static int cbs_clone_unit_content(CodedBitstreamContext *ctx,
+ CodedBitstreamUnit *unit)
{
const CodedBitstreamUnitTypeDescriptor *desc;
AVBufferRef *ref;
int err;
- av_assert0(unit->content);
- if (unit->content_ref) {
- // Already refcounted, nothing to do.
- return 0;
- }
-
desc = cbs_find_unit_type_desc(ctx, unit);
if (!desc)
return AVERROR(ENOSYS);
switch (desc->content_type) {
- case CBS_CONTENT_TYPE_POD:
- ref = av_buffer_alloc(desc->content_size);
- if (!ref)
- return AVERROR(ENOMEM);
- memcpy(ref->data, unit->content, desc->content_size);
- err = 0;
- break;
-
case CBS_CONTENT_TYPE_INTERNAL_REFS:
- err = cbs_clone_unit_content(&ref, unit, desc);
+ err = cbs_clone_internal_refs_unit_content(&ref, unit, desc);
break;
case CBS_CONTENT_TYPE_COMPLEX:
- if (!desc->content_clone)
+ if (!desc->type.complex.content_clone)
return AVERROR_PATCHWELCOME;
- err = desc->content_clone(&ref, unit);
+ err = desc->type.complex.content_clone(&ref, unit);
break;
default:
@@ -1035,51 +1001,28 @@ int ff_cbs_make_unit_refcounted(CodedBitstreamContext *ctx,
return 0;
}
+int ff_cbs_make_unit_refcounted(CodedBitstreamContext *ctx,
+ CodedBitstreamUnit *unit)
+{
+ av_assert0(unit->content);
+ if (unit->content_ref)
+ return 0;
+ return cbs_clone_unit_content(ctx, unit);
+}
+
int ff_cbs_make_unit_writable(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit)
{
- const CodedBitstreamUnitTypeDescriptor *desc;
- AVBufferRef *ref;
+ AVBufferRef *ref = unit->content_ref;
int err;
- // This can only be applied to refcounted units.
- err = ff_cbs_make_unit_refcounted(ctx, unit);
- if (err < 0)
- return err;
- av_assert0(unit->content && unit->content_ref);
-
- if (av_buffer_is_writable(unit->content_ref))
+ av_assert0(unit->content);
+ if (ref && av_buffer_is_writable(ref))
return 0;
- desc = cbs_find_unit_type_desc(ctx, unit);
- if (!desc)
- return AVERROR(ENOSYS);
-
- switch (desc->content_type) {
- case CBS_CONTENT_TYPE_POD:
- err = av_buffer_make_writable(&unit->content_ref);
- break;
-
- case CBS_CONTENT_TYPE_INTERNAL_REFS:
- err = cbs_clone_unit_content(&ref, unit, desc);
- break;
-
- case CBS_CONTENT_TYPE_COMPLEX:
- if (!desc->content_clone)
- return AVERROR_PATCHWELCOME;
- err = desc->content_clone(&ref, unit);
- break;
-
- default:
- av_assert0(0 && "Invalid content type.");
- }
+ err = cbs_clone_unit_content(ctx, unit);
if (err < 0)
return err;
-
- if (desc->content_type != CBS_CONTENT_TYPE_POD) {
- av_buffer_unref(&unit->content_ref);
- unit->content_ref = ref;
- }
- unit->content = unit->content_ref->data;
+ av_buffer_unref(&ref);
return 0;
}
diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h
index 5583063b5..ee21623da 100644
--- a/libavcodec/cbs.h
+++ b/libavcodec/cbs.h
@@ -363,22 +363,13 @@ void ff_cbs_fragment_reset(CodedBitstreamFragment *frag);
*/
void ff_cbs_fragment_free(CodedBitstreamFragment *frag);
-/**
- * Allocate a new internal content buffer of the given size in the unit.
- *
- * The content will be zeroed.
- */
-int ff_cbs_alloc_unit_content(CodedBitstreamUnit *unit,
- size_t size,
- void (*free)(void *opaque, uint8_t *content));
-
/**
* Allocate a new internal content buffer matching the type of the unit.
*
* The content will be zeroed.
*/
-int ff_cbs_alloc_unit_content2(CodedBitstreamContext *ctx,
- CodedBitstreamUnit *unit);
+int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx,
+ CodedBitstreamUnit *unit);
/**
* Insert a new unit into a fragment with the given content.
diff --git a/libavcodec/cbs_av1.c b/libavcodec/cbs_av1.c
index 122948056..45e1288a5 100644
--- a/libavcodec/cbs_av1.c
+++ b/libavcodec/cbs_av1.c
@@ -878,7 +878,7 @@ static int cbs_av1_read_unit(CodedBitstreamContext *ctx,
GetBitContext gbc;
int err, start_pos, end_pos;
- err = ff_cbs_alloc_unit_content2(ctx, unit);
+ err = ff_cbs_alloc_unit_content(ctx, unit);
if (err < 0)
return err;
obu = unit->content;
@@ -1058,15 +1058,31 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
AV1RawTileData *td;
size_t header_size;
int err, start_pos, end_pos, data_pos;
+ CodedBitstreamAV1Context av1ctx;
// OBUs in the normal bitstream format must contain a size field
// in every OBU (in annex B it is optional, but we don't support
// writing that).
obu->header.obu_has_size_field = 1;
+ av1ctx = *priv;
+
+ if (priv->sequence_header_ref) {
+ av1ctx.sequence_header_ref = av_buffer_ref(priv->sequence_header_ref);
+ if (!av1ctx.sequence_header_ref)
+ return AVERROR(ENOMEM);
+ }
+
+ if (priv->frame_header_ref) {
+ av1ctx.frame_header_ref = av_buffer_ref(priv->frame_header_ref);
+ if (!av1ctx.frame_header_ref) {
+ err = AVERROR(ENOMEM);
+ goto error;
+ }
+ }
err = cbs_av1_write_obu_header(ctx, pbc, &obu->header);
if (err < 0)
- return err;
+ goto error;
if (obu->header.obu_has_size_field) {
pbc_tmp = *pbc;
@@ -1084,18 +1100,21 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
err = cbs_av1_write_sequence_header_obu(ctx, pbc,
&obu->obu.sequence_header);
if (err < 0)
- return err;
+ goto error;
av_buffer_unref(&priv->sequence_header_ref);
priv->sequence_header = NULL;
err = ff_cbs_make_unit_refcounted(ctx, unit);
if (err < 0)
- return err;
+ goto error;
priv->sequence_header_ref = av_buffer_ref(unit->content_ref);
- if (!priv->sequence_header_ref)
- return AVERROR(ENOMEM);
+ if (!priv->sequence_header_ref) {
+ err = AVERROR(ENOMEM);
+ goto error;
+ }
+
priv->sequence_header = &obu->obu.sequence_header;
}
break;
@@ -1103,7 +1122,7 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
{
err = cbs_av1_write_temporal_delimiter_obu(ctx, pbc);
if (err < 0)
- return err;
+ goto error;
}
break;
case AV1_OBU_FRAME_HEADER:
@@ -1115,7 +1134,7 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
AV1_OBU_REDUNDANT_FRAME_HEADER,
NULL);
if (err < 0)
- return err;
+ goto error;
}
break;
case AV1_OBU_TILE_GROUP:
@@ -1123,7 +1142,7 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
err = cbs_av1_write_tile_group_obu(ctx, pbc,
&obu->obu.tile_group);
if (err < 0)
- return err;
+ goto error;
td = &obu->obu.tile_group.tile_data;
}
@@ -1132,7 +1151,7 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
{
err = cbs_av1_write_frame_obu(ctx, pbc, &obu->obu.frame, NULL);
if (err < 0)
- return err;
+ goto error;
td = &obu->obu.frame.tile_group.tile_data;
}
@@ -1141,7 +1160,7 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
{
err = cbs_av1_write_tile_list_obu(ctx, pbc, &obu->obu.tile_list);
if (err < 0)
- return err;
+ goto error;
td = &obu->obu.tile_list.tile_data;
}
@@ -1150,18 +1169,19 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
{
err = cbs_av1_write_metadata_obu(ctx, pbc, &obu->obu.metadata);
if (err < 0)
- return err;
+ goto error;
}
break;
case AV1_OBU_PADDING:
{
err = cbs_av1_write_padding_obu(ctx, pbc, &obu->obu.padding);
if (err < 0)
- return err;
+ goto error;
}
break;
default:
- return AVERROR(ENOSYS);
+ err = AVERROR(ENOSYS);
+ goto error;
}
end_pos = put_bits_count(pbc);
@@ -1172,7 +1192,7 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
// Add trailing bits and recalculate.
err = cbs_av1_write_trailing_bits(ctx, pbc, 8 - end_pos % 8);
if (err < 0)
- return err;
+ goto error;
end_pos = put_bits_count(pbc);
obu->obu_size = header_size = (end_pos - start_pos + 7) / 8;
} else {
@@ -1190,14 +1210,19 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
*pbc = pbc_tmp;
err = cbs_av1_write_leb128(ctx, pbc, "obu_size", obu->obu_size);
if (err < 0)
- return err;
+ goto error;
data_pos = put_bits_count(pbc) / 8;
flush_put_bits(pbc);
av_assert0(data_pos <= start_pos);
- if (8 * obu->obu_size > put_bits_left(pbc))
+ if (8 * obu->obu_size > put_bits_left(pbc)) {
+ av_buffer_unref(&priv->sequence_header_ref);
+ av_buffer_unref(&priv->frame_header_ref);
+ *priv = av1ctx;
+
return AVERROR(ENOSPC);
+ }
if (obu->obu_size > 0) {
memmove(pbc->buf + data_pos,
@@ -1213,8 +1238,13 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
// OBU data must be byte-aligned.
av_assert0(put_bits_count(pbc) % 8 == 0);
+ err = 0;
- return 0;
+error:
+ av_buffer_unref(&av1ctx.sequence_header_ref);
+ av_buffer_unref(&av1ctx.frame_header_ref);
+
+ return err;
}
static int cbs_av1_assemble_fragment(CodedBitstreamContext *ctx,
diff --git a/libavcodec/cbs_av1_syntax_template.c b/libavcodec/cbs_av1_syntax_template.c
index d98d3d42d..e95925a49 100644
--- a/libavcodec/cbs_av1_syntax_template.c
+++ b/libavcodec/cbs_av1_syntax_template.c
@@ -1862,11 +1862,8 @@ static int FUNC(metadata_hdr_mdcv)(CodedBitstreamContext *ctx, RWContext *rw,
fb(16, white_point_chromaticity_x);
fb(16, white_point_chromaticity_y);
- fc(32, luminance_max, 1, MAX_UINT_BITS(32));
- // luminance_min must be lower than luminance_max. Convert luminance_max from
- // 24.8 fixed point to 18.14 fixed point in order to compare them.
- fc(32, luminance_min, 0, FFMIN(((uint64_t)current->luminance_max << 6) - 1,
- MAX_UINT_BITS(32)));
+ fb(32, luminance_max);
+ fb(32, luminance_min);
return 0;
}
diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c
index 12e38c80b..80e48829a 100644
--- a/libavcodec/cbs_h2645.c
+++ b/libavcodec/cbs_h2645.c
@@ -666,13 +666,7 @@ static int cbs_h26 ## h26n ## _replace_ ## ps_var(CodedBitstreamContext *ctx, \
CodedBitstreamH26 ## h26n ## Context *priv = ctx->priv_data; \
H26 ## h26n ## Raw ## ps_name *ps_var = unit->content; \
unsigned int id = ps_var->id_element; \
- int err; \
- if (id >= FF_ARRAY_ELEMS(priv->ps_var)) { \
- av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid " #ps_name \
- " id : %d.\n", id); \
- return AVERROR_INVALIDDATA; \
- } \
- err = ff_cbs_make_unit_refcounted(ctx, unit); \
+ int err = ff_cbs_make_unit_refcounted(ctx, unit); \
if (err < 0) \
return err; \
if (priv->ps_var[id] == priv->active_ ## ps_var) \
@@ -702,7 +696,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
if (err < 0)
return err;
- err = ff_cbs_alloc_unit_content2(ctx, unit);
+ err = ff_cbs_alloc_unit_content(ctx, unit);
if (err < 0)
return err;
@@ -821,7 +815,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
if (err < 0)
return err;
- err = ff_cbs_alloc_unit_content2(ctx, unit);
+ err = ff_cbs_alloc_unit_content(ctx, unit);
if (err < 0)
return err;
@@ -1396,18 +1390,9 @@ static const CodedBitstreamUnitTypeDescriptor cbs_h264_unit_types[] = {
CBS_UNIT_TYPE_INTERNAL_REF(H264_NAL_PPS, H264RawPPS, slice_group_id),
- {
- .nb_unit_types = 3,
- .unit_types = {
- H264_NAL_IDR_SLICE,
- H264_NAL_SLICE,
- H264_NAL_AUXILIARY_SLICE,
- },
- .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS,
- .content_size = sizeof(H264RawSlice),
- .nb_ref_offsets = 1,
- .ref_offsets = { offsetof(H264RawSlice, data) },
- },
+ CBS_UNIT_TYPES_INTERNAL_REF((H264_NAL_IDR_SLICE,
+ H264_NAL_SLICE,
+ H264_NAL_AUXILIARY_SLICE), H264RawSlice, data),
CBS_UNIT_TYPE_POD(H264_NAL_AUD, H264RawAUD),
CBS_UNIT_TYPE_POD(H264_NAL_FILLER_DATA, H264RawFiller),
@@ -1433,40 +1418,15 @@ static const CodedBitstreamUnitTypeDescriptor cbs_h265_unit_types[] = {
CBS_UNIT_TYPE_POD(HEVC_NAL_AUD, H265RawAUD),
- {
- // Slices of non-IRAP pictures.
- .nb_unit_types = CBS_UNIT_TYPE_RANGE,
- .unit_type_range_start = HEVC_NAL_TRAIL_N,
- .unit_type_range_end = HEVC_NAL_RASL_R,
+ // Slices of non-IRAP pictures.
+ CBS_UNIT_RANGE_INTERNAL_REF(HEVC_NAL_TRAIL_N, HEVC_NAL_RASL_R,
+ H265RawSlice, data),
+ // Slices of IRAP pictures.
+ CBS_UNIT_RANGE_INTERNAL_REF(HEVC_NAL_BLA_W_LP, HEVC_NAL_CRA_NUT,
+ H265RawSlice, data),
- .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS,
- .content_size = sizeof(H265RawSlice),
- .nb_ref_offsets = 1,
- .ref_offsets = { offsetof(H265RawSlice, data) },
- },
-
- {
- // Slices of IRAP pictures.
- .nb_unit_types = CBS_UNIT_TYPE_RANGE,
- .unit_type_range_start = HEVC_NAL_BLA_W_LP,
- .unit_type_range_end = HEVC_NAL_CRA_NUT,
-
- .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS,
- .content_size = sizeof(H265RawSlice),
- .nb_ref_offsets = 1,
- .ref_offsets = { offsetof(H265RawSlice, data) },
- },
-
- {
- .nb_unit_types = 2,
- .unit_types = {
- HEVC_NAL_SEI_PREFIX,
- HEVC_NAL_SEI_SUFFIX
- },
- .content_type = CBS_CONTENT_TYPE_COMPLEX,
- .content_size = sizeof(H265RawSEI),
- .content_free = &cbs_h265_free_sei,
- },
+ CBS_UNIT_TYPES_COMPLEX((HEVC_NAL_SEI_PREFIX, HEVC_NAL_SEI_SUFFIX),
+ H265RawSEI, cbs_h265_free_sei),
CBS_UNIT_TYPE_END_OF_LIST
};
@@ -1540,6 +1500,12 @@ static const SEIMessageTypeDescriptor cbs_sei_common_types[] = {
sizeof(SEIRawAlternativeTransferCharacteristics),
SEI_MESSAGE_RW(sei, alternative_transfer_characteristics),
},
+ {
+ SEI_TYPE_AMBIENT_VIEWING_ENVIRONMENT,
+ 1, 0,
+ sizeof(SEIRawAmbientViewingEnvironment),
+ SEI_MESSAGE_RW(sei, ambient_viewing_environment),
+ },
SEI_MESSAGE_TYPE_END,
};
diff --git a/libavcodec/cbs_internal.h b/libavcodec/cbs_internal.h
index f853086fa..e585c7793 100644
--- a/libavcodec/cbs_internal.h
+++ b/libavcodec/cbs_internal.h
@@ -31,9 +31,7 @@
enum CBSContentType {
- // Unit content is a simple structure.
- CBS_CONTENT_TYPE_POD,
- // Unit content contains some references to other structures, but all
+ // Unit content may contain some references to other structures, but all
// managed via buffer reference counting. The descriptor defines the
// structure offsets of every buffer reference.
CBS_CONTENT_TYPE_INTERNAL_REFS,
@@ -43,9 +41,9 @@ enum CBSContentType {
};
enum {
- // Maximum number of unit types described by the same unit type
- // descriptor.
- CBS_MAX_UNIT_TYPES = 3,
+ // Maximum number of unit types described by the same non-range
+ // unit type descriptor.
+ CBS_MAX_LIST_UNIT_TYPES = 3,
// Maximum number of reference buffer offsets in any one unit.
CBS_MAX_REF_OFFSETS = 2,
// Special value used in a unit type descriptor to indicate that it
@@ -60,13 +58,16 @@ typedef const struct CodedBitstreamUnitTypeDescriptor {
// used instead.
int nb_unit_types;
- // Array of unit types that this entry describes.
- const CodedBitstreamUnitType unit_types[CBS_MAX_UNIT_TYPES];
-
- // Start and end of unit type range, used if nb_unit_types is
- // CBS_UNIT_TYPE_RANGE.
- const CodedBitstreamUnitType unit_type_range_start;
- const CodedBitstreamUnitType unit_type_range_end;
+ union {
+ // Array of unit types that this entry describes.
+ CodedBitstreamUnitType list[CBS_MAX_LIST_UNIT_TYPES];
+ // Start and end of unit type range, used if nb_unit_types is
+ // CBS_UNIT_TYPE_RANGE.
+ struct {
+ CodedBitstreamUnitType start;
+ CodedBitstreamUnitType end;
+ } range;
+ } unit_type;
// The type of content described.
enum CBSContentType content_type;
@@ -74,18 +75,27 @@ typedef const struct CodedBitstreamUnitTypeDescriptor {
// the decomposed content of this type of unit.
size_t content_size;
- // Number of entries in the ref_offsets array. Only used if the
- // content_type is CBS_CONTENT_TYPE_INTERNAL_REFS.
- int nb_ref_offsets;
- // The structure must contain two adjacent elements:
- // type *field;
- // AVBufferRef *field_ref;
- // where field points to something in the buffer referred to by
- // field_ref. This offset is then set to offsetof(struct, field).
- size_t ref_offsets[CBS_MAX_REF_OFFSETS];
+ union {
+ // This union's state is determined by content_type:
+ // ref for CBS_CONTENT_TYPE_INTERNAL_REFS,
+ // complex for CBS_CONTENT_TYPE_COMPLEX.
+ struct {
+ // Number of entries in the ref_offsets array.
+ // May be zero, then the structure is POD-like.
+ int nb_offsets;
+ // The structure must contain two adjacent elements:
+ // type *field;
+ // AVBufferRef *field_ref;
+ // where field points to something in the buffer referred to by
+ // field_ref. This offset is then set to offsetof(struct, field).
+ size_t offsets[CBS_MAX_REF_OFFSETS];
+ } ref;
- void (*content_free)(void *opaque, uint8_t *data);
- int (*content_clone)(AVBufferRef **ref, CodedBitstreamUnit *unit);
+ struct {
+ void (*content_free)(void *opaque, uint8_t *data);
+ int (*content_clone)(AVBufferRef **ref, CodedBitstreamUnit *unit);
+ } complex;
+ } type;
} CodedBitstreamUnitTypeDescriptor;
typedef struct CodedBitstreamType {
@@ -181,28 +191,54 @@ int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc,
// range_min in the above functions.
#define MIN_INT_BITS(length) (-(INT64_C(1) << ((length) - 1)))
-
-#define CBS_UNIT_TYPE_POD(type, structure) { \
+#define TYPE_LIST(...) { __VA_ARGS__ }
+#define CBS_UNIT_TYPE_POD(type_, structure) { \
.nb_unit_types = 1, \
- .unit_types = { type }, \
- .content_type = CBS_CONTENT_TYPE_POD, \
- .content_size = sizeof(structure), \
- }
-#define CBS_UNIT_TYPE_INTERNAL_REF(type, structure, ref_field) { \
- .nb_unit_types = 1, \
- .unit_types = { type }, \
+ .unit_type.list = { type_ }, \
.content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, \
.content_size = sizeof(structure), \
- .nb_ref_offsets = 1, \
- .ref_offsets = { offsetof(structure, ref_field) }, \
+ .type.ref = { .nb_offsets = 0 }, \
}
-#define CBS_UNIT_TYPE_COMPLEX(type, structure, free_func) { \
- .nb_unit_types = 1, \
- .unit_types = { type }, \
+#define CBS_UNIT_RANGE_POD(range_start, range_end, structure) { \
+ .nb_unit_types = CBS_UNIT_TYPE_RANGE, \
+ .unit_type.range.start = range_start, \
+ .unit_type.range.end = range_end, \
+ .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, \
+ .content_size = sizeof(structure), \
+ .type.ref = { .nb_offsets = 0 }, \
+ }
+
+#define CBS_UNIT_TYPES_INTERNAL_REF(types, structure, ref_field) { \
+ .nb_unit_types = FF_ARRAY_ELEMS((CodedBitstreamUnitType[])TYPE_LIST types), \
+ .unit_type.list = TYPE_LIST types, \
+ .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, \
+ .content_size = sizeof(structure), \
+ .type.ref = { .nb_offsets = 1, \
+ .offsets = { offsetof(structure, ref_field) } }, \
+ }
+#define CBS_UNIT_TYPE_INTERNAL_REF(type, structure, ref_field) \
+ CBS_UNIT_TYPES_INTERNAL_REF((type), structure, ref_field)
+
+#define CBS_UNIT_RANGE_INTERNAL_REF(range_start, range_end, structure, ref_field) { \
+ .nb_unit_types = CBS_UNIT_TYPE_RANGE, \
+ .unit_type.range.start = range_start, \
+ .unit_type.range.end = range_end, \
+ .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, \
+ .content_size = sizeof(structure), \
+ .type.ref = { .nb_offsets = 1, \
+ .offsets = { offsetof(structure, ref_field) } }, \
+ }
+
+#define CBS_UNIT_TYPES_COMPLEX(types, structure, free_func) { \
+ .nb_unit_types = FF_ARRAY_ELEMS((CodedBitstreamUnitType[])TYPE_LIST types), \
+ .unit_type.list = TYPE_LIST types, \
.content_type = CBS_CONTENT_TYPE_COMPLEX, \
.content_size = sizeof(structure), \
- .content_free = free_func, \
+ .type.complex = { .content_free = free_func }, \
}
+#define CBS_UNIT_TYPE_COMPLEX(type, structure, free_func) \
+ CBS_UNIT_TYPES_COMPLEX((type), structure, free_func)
+
#define CBS_UNIT_TYPE_END_OF_LIST { .nb_unit_types = 0 }
diff --git a/libavcodec/cbs_jpeg.c b/libavcodec/cbs_jpeg.c
index da7ee808c..5921d624a 100644
--- a/libavcodec/cbs_jpeg.c
+++ b/libavcodec/cbs_jpeg.c
@@ -82,27 +82,6 @@
#undef xu
-static void cbs_jpeg_free_application_data(void *opaque, uint8_t *content)
-{
- JPEGRawApplicationData *ad = (JPEGRawApplicationData*)content;
- av_buffer_unref(&ad->Ap_ref);
- av_freep(&content);
-}
-
-static void cbs_jpeg_free_comment(void *opaque, uint8_t *content)
-{
- JPEGRawComment *comment = (JPEGRawComment*)content;
- av_buffer_unref(&comment->Cm_ref);
- av_freep(&content);
-}
-
-static void cbs_jpeg_free_scan(void *opaque, uint8_t *content)
-{
- JPEGRawScan *scan = (JPEGRawScan*)content;
- av_buffer_unref(&scan->data_ref);
- av_freep(&content);
-}
-
static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag,
int header)
@@ -248,41 +227,26 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx,
if (err < 0)
return err;
+ err = ff_cbs_alloc_unit_content(ctx, unit);
+ if (err < 0)
+ return err;
+
if (unit->type >= JPEG_MARKER_SOF0 &&
unit->type <= JPEG_MARKER_SOF3) {
- err = ff_cbs_alloc_unit_content(unit,
- sizeof(JPEGRawFrameHeader),
- NULL);
- if (err < 0)
- return err;
-
err = cbs_jpeg_read_frame_header(ctx, &gbc, unit->content);
if (err < 0)
return err;
} else if (unit->type >= JPEG_MARKER_APPN &&
unit->type <= JPEG_MARKER_APPN + 15) {
- err = ff_cbs_alloc_unit_content(unit,
- sizeof(JPEGRawApplicationData),
- &cbs_jpeg_free_application_data);
- if (err < 0)
- return err;
-
err = cbs_jpeg_read_application_data(ctx, &gbc, unit->content);
if (err < 0)
return err;
} else if (unit->type == JPEG_MARKER_SOS) {
- JPEGRawScan *scan;
+ JPEGRawScan *scan = unit->content;
int pos;
- err = ff_cbs_alloc_unit_content(unit,
- sizeof(JPEGRawScan),
- &cbs_jpeg_free_scan);
- if (err < 0)
- return err;
- scan = unit->content;
-
err = cbs_jpeg_read_scan_header(ctx, &gbc, &scan->header);
if (err < 0)
return err;
@@ -299,21 +263,17 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx,
} else {
switch (unit->type) {
-#define SEGMENT(marker, type, func, free) \
+#define SEGMENT(marker, func) \
case JPEG_MARKER_ ## marker: \
{ \
- err = ff_cbs_alloc_unit_content(unit, \
- sizeof(type), free); \
- if (err < 0) \
- return err; \
err = cbs_jpeg_read_ ## func(ctx, &gbc, unit->content); \
if (err < 0) \
return err; \
} \
break
- SEGMENT(DQT, JPEGRawQuantisationTableSpecification, dqt, NULL);
- SEGMENT(DHT, JPEGRawHuffmanTableSpecification, dht, NULL);
- SEGMENT(COM, JPEGRawComment, comment, &cbs_jpeg_free_comment);
+ SEGMENT(DQT, dqt);
+ SEGMENT(DHT, dht);
+ SEGMENT(COM, comment);
#undef SEGMENT
default:
return AVERROR(ENOSYS);
@@ -456,9 +416,27 @@ static int cbs_jpeg_assemble_fragment(CodedBitstreamContext *ctx,
return 0;
}
+static const CodedBitstreamUnitTypeDescriptor cbs_jpeg_unit_types[] = {
+ CBS_UNIT_RANGE_POD(JPEG_MARKER_SOF0, JPEG_MARKER_SOF3, JPEGRawFrameHeader),
+
+ CBS_UNIT_RANGE_INTERNAL_REF(JPEG_MARKER_APPN, JPEG_MARKER_APPN + 15,
+ JPEGRawApplicationData, Ap),
+
+ CBS_UNIT_TYPE_INTERNAL_REF(JPEG_MARKER_SOS, JPEGRawScan, data),
+
+ CBS_UNIT_TYPE_POD(JPEG_MARKER_DQT, JPEGRawQuantisationTableSpecification),
+ CBS_UNIT_TYPE_POD(JPEG_MARKER_DHT, JPEGRawHuffmanTableSpecification),
+
+ CBS_UNIT_TYPE_INTERNAL_REF(JPEG_MARKER_COM, JPEGRawComment, Cm),
+
+ CBS_UNIT_TYPE_END_OF_LIST
+};
+
const CodedBitstreamType ff_cbs_type_jpeg = {
.codec_id = AV_CODEC_ID_MJPEG,
+ .unit_types = cbs_jpeg_unit_types,
+
.split_fragment = &cbs_jpeg_split_fragment,
.read_unit = &cbs_jpeg_read_unit,
.write_unit = &cbs_jpeg_write_unit,
diff --git a/libavcodec/cbs_mpeg2.c b/libavcodec/cbs_mpeg2.c
index 33bd3e099..04b0c7f87 100644
--- a/libavcodec/cbs_mpeg2.c
+++ b/libavcodec/cbs_mpeg2.c
@@ -204,7 +204,7 @@ static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx,
if (err < 0)
return err;
- err = ff_cbs_alloc_unit_content2(ctx, unit);
+ err = ff_cbs_alloc_unit_content(ctx, unit);
if (err < 0)
return err;
@@ -392,14 +392,14 @@ static const CodedBitstreamUnitTypeDescriptor cbs_mpeg2_unit_types[] = {
{
.nb_unit_types = CBS_UNIT_TYPE_RANGE,
- .unit_type_range_start = 0x01,
- .unit_type_range_end = 0xaf,
+ .unit_type.range.start = 0x01,
+ .unit_type.range.end = 0xaf,
.content_type = CBS_CONTENT_TYPE_INTERNAL_REFS,
.content_size = sizeof(MPEG2RawSlice),
- .nb_ref_offsets = 2,
- .ref_offsets = { offsetof(MPEG2RawSlice, header.extra_information_slice.extra_information),
- offsetof(MPEG2RawSlice, data) },
+ .type.ref = { .nb_offsets = 2,
+ .offsets = { offsetof(MPEG2RawSlice, header.extra_information_slice.extra_information),
+ offsetof(MPEG2RawSlice, data) } },
},
CBS_UNIT_TYPE_INTERNAL_REF(MPEG2_START_USER_DATA, MPEG2RawUserData,
diff --git a/libavcodec/cbs_sei.c b/libavcodec/cbs_sei.c
index 141e97ec5..50a513f59 100644
--- a/libavcodec/cbs_sei.c
+++ b/libavcodec/cbs_sei.c
@@ -179,7 +179,7 @@ static int cbs_sei_get_unit(CodedBitstreamContext *ctx,
unit = &au->units[position];
unit->type = sei_type;
- err = ff_cbs_alloc_unit_content2(ctx, unit);
+ err = ff_cbs_alloc_unit_content(ctx, unit);
if (err < 0)
return err;
diff --git a/libavcodec/cbs_sei.h b/libavcodec/cbs_sei.h
index c7a7a95be..1c327a468 100644
--- a/libavcodec/cbs_sei.h
+++ b/libavcodec/cbs_sei.h
@@ -65,6 +65,12 @@ typedef struct SEIRawAlternativeTransferCharacteristics {
uint8_t preferred_transfer_characteristics;
} SEIRawAlternativeTransferCharacteristics;
+typedef struct SEIRawAmbientViewingEnvironment {
+ uint32_t ambient_illuminance;
+ uint16_t ambient_light_x;
+ uint16_t ambient_light_y;
+} SEIRawAmbientViewingEnvironment;
+
typedef struct SEIRawMessage {
uint32_t payload_type;
uint32_t payload_size;
diff --git a/libavcodec/cbs_sei_syntax_template.c b/libavcodec/cbs_sei_syntax_template.c
index 0ef7b42ed..6a7cc36dd 100644
--- a/libavcodec/cbs_sei_syntax_template.c
+++ b/libavcodec/cbs_sei_syntax_template.c
@@ -144,6 +144,23 @@ static int FUNC(alternative_transfer_characteristics)
return 0;
}
+static int FUNC(ambient_viewing_environment)
+ (CodedBitstreamContext *ctx, RWContext *rw,
+ SEIRawAmbientViewingEnvironment *current,
+ SEIMessageState *state)
+{
+ static const uint16_t max_ambient_light_value = 50000;
+ int err;
+
+ HEADER("Ambient Viewing Environment");
+
+ u(32, ambient_illuminance, 1, MAX_UINT_BITS(32));
+ u(16, ambient_light_x, 0, max_ambient_light_value);
+ u(16, ambient_light_y, 0, max_ambient_light_value);
+
+ return 0;
+}
+
static int FUNC(message)(CodedBitstreamContext *ctx, RWContext *rw,
SEIRawMessage *current)
{
diff --git a/libavcodec/cbs_vp9.c b/libavcodec/cbs_vp9.c
index ae7f88a8a..184fdcade 100644
--- a/libavcodec/cbs_vp9.c
+++ b/libavcodec/cbs_vp9.c
@@ -489,7 +489,7 @@ static int cbs_vp9_read_unit(CodedBitstreamContext *ctx,
if (err < 0)
return err;
- err = ff_cbs_alloc_unit_content2(ctx, unit);
+ err = ff_cbs_alloc_unit_content(ctx, unit);
if (err < 0)
return err;
frame = unit->content;
diff --git a/libavcodec/ccaption_dec.c b/libavcodec/ccaption_dec.c
index 34f0513b1..61eda9ff5 100644
--- a/libavcodec/ccaption_dec.c
+++ b/libavcodec/ccaption_dec.c
@@ -946,7 +946,7 @@ static const AVClass ccaption_dec_class = {
const FFCodec ff_ccaption_decoder = {
.p.name = "cc_dec",
- .p.long_name = NULL_IF_CONFIG_SMALL("Closed Caption (EIA-608 / CEA-708)"),
+ CODEC_LONG_NAME("Closed Caption (EIA-608 / CEA-708)"),
.p.type = AVMEDIA_TYPE_SUBTITLE,
.p.id = AV_CODEC_ID_EIA_608,
.p.priv_class = &ccaption_dec_class,
@@ -956,5 +956,4 @@ const FFCodec ff_ccaption_decoder = {
.close = close_decoder,
.flush = flush_decoder,
FF_CODEC_DECODE_SUB_CB(decode),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c
index 73654019e..431e99cd7 100644
--- a/libavcodec/cdgraphics.c
+++ b/libavcodec/cdgraphics.c
@@ -22,7 +22,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
/**
* @file
@@ -374,7 +374,7 @@ static void cdg_decode_flush(AVCodecContext *avctx)
return;
memset(cc->frame->data[0], 0, cc->frame->linesize[0] * avctx->height);
- if (!avctx->frame_number)
+ if (!avctx->frame_num)
memset(cc->frame->data[1], 0, AVPALETTE_SIZE);
}
@@ -389,7 +389,7 @@ static av_cold int cdg_decode_end(AVCodecContext *avctx)
const FFCodec ff_cdgraphics_decoder = {
.p.name = "cdgraphics",
- .p.long_name = NULL_IF_CONFIG_SMALL("CD Graphics video"),
+ CODEC_LONG_NAME("CD Graphics video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CDGRAPHICS,
.priv_data_size = sizeof(CDGraphicsContext),
@@ -398,5 +398,4 @@ const FFCodec ff_cdgraphics_decoder = {
FF_CODEC_DECODE_CB(cdg_decode_frame),
.flush = cdg_decode_flush,
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/cdtoons.c b/libavcodec/cdtoons.c
index eb53a324d..3ebed2267 100644
--- a/libavcodec/cdtoons.c
+++ b/libavcodec/cdtoons.c
@@ -32,7 +32,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#define CDTOONS_HEADER_SIZE 44
#define CDTOONS_MAX_SPRITES 1200
@@ -445,7 +445,7 @@ static av_cold int cdtoons_decode_end(AVCodecContext *avctx)
const FFCodec ff_cdtoons_decoder = {
.p.name = "cdtoons",
- .p.long_name = NULL_IF_CONFIG_SMALL("CDToons video"),
+ CODEC_LONG_NAME("CDToons video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CDTOONS,
.priv_data_size = sizeof(CDToonsContext),
@@ -454,5 +454,4 @@ const FFCodec ff_cdtoons_decoder = {
FF_CODEC_DECODE_CB(cdtoons_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
.flush = cdtoons_flush,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/cdxl.c b/libavcodec/cdxl.c
index 1f25d8eb9..6b3b3e85e 100644
--- a/libavcodec/cdxl.c
+++ b/libavcodec/cdxl.c
@@ -28,12 +28,11 @@
#define UNCHECKED_BITSTREAM_READER 1
#include "libavutil/intreadwrite.h"
-#include "libavutil/imgutils.h"
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
#define BIT_PLANAR 0x00
#define CHUNKY 0x20
@@ -338,7 +337,7 @@ static av_cold int cdxl_decode_end(AVCodecContext *avctx)
const FFCodec ff_cdxl_decoder = {
.p.name = "cdxl",
- .p.long_name = NULL_IF_CONFIG_SMALL("Commodore CDXL video"),
+ CODEC_LONG_NAME("Commodore CDXL video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CDXL,
.priv_data_size = sizeof(CDXLVideoContext),
@@ -346,5 +345,4 @@ const FFCodec ff_cdxl_decoder = {
.close = cdxl_decode_end,
FF_CODEC_DECODE_CB(cdxl_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c
index 5adb0b200..c23eb069c 100644
--- a/libavcodec/cfhd.c
+++ b/libavcodec/cfhd.c
@@ -26,13 +26,13 @@
#include "libavutil/attributes.h"
#include "libavutil/buffer.h"
#include "libavutil/common.h"
-#include "libavutil/imgutils.h"
#include "libavutil/intreadwrite.h"
-#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
#include "internal.h"
#include "thread.h"
@@ -819,7 +819,7 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
VLC_BITS, 3, 1);
/* escape */
- if (level == 64)
+ if (!run)
break;
count += run;
@@ -850,7 +850,7 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
VLC_BITS, 3, 1);
/* escape */
- if (level == 255 && run == 2)
+ if (!run)
break;
count += run;
@@ -1404,9 +1404,6 @@ static av_cold int cfhd_close(AVCodecContext *avctx)
free_buffers(s);
- ff_free_vlc(&s->vlc_9);
- ff_free_vlc(&s->vlc_18);
-
return 0;
}
@@ -1457,14 +1454,14 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
const FFCodec ff_cfhd_decoder = {
.p.name = "cfhd",
- .p.long_name = NULL_IF_CONFIG_SMALL("GoPro CineForm HD"),
+ CODEC_LONG_NAME("GoPro CineForm HD"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CFHD,
.priv_data_size = sizeof(CFHDContext),
.init = cfhd_init,
.close = cfhd_close,
FF_CODEC_DECODE_CB(cfhd_decode),
- .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
+ UPDATE_THREAD_CONTEXT(update_thread_context),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/cfhd.h b/libavcodec/cfhd.h
index 4c066da5f..9b09c9126 100644
--- a/libavcodec/cfhd.h
+++ b/libavcodec/cfhd.h
@@ -26,7 +26,6 @@
#include "avcodec.h"
#include "bytestream.h"
#include "get_bits.h"
-#include "vlc.h"
#include "cfhddsp.h"
enum CFHDParam {
@@ -141,10 +140,7 @@ typedef struct CFHDContext {
AVCodecContext *avctx;
CFHD_RL_VLC_ELEM table_9_rl_vlc[2088];
- VLC vlc_9;
-
CFHD_RL_VLC_ELEM table_18_rl_vlc[4572];
- VLC vlc_18;
int lut[2][256];
diff --git a/libavcodec/cfhddata.c b/libavcodec/cfhddata.c
index 55c8004bd..fd5cc8174 100644
--- a/libavcodec/cfhddata.c
+++ b/libavcodec/cfhddata.c
@@ -23,349 +23,177 @@
#include "libavutil/attributes.h"
#include "cfhd.h"
-
-/* some special codewords, not sure what they all mean */
-#define TABLE_9_BAND_END1 0x1C7859Eh
-#define TABLE_9_BAND_END_LEN1 25
-#define TABLE_9_BAND_END2 0x38F0B3Fh
-#define TABLE_9_BAND_END_LEN2 26
-#define TABLE_9_BAND_END3 0x38F0B3Eh
-#define TABLE_9_BAND_END_LEN3 26
+#include "vlc.h"
#define NB_VLC_TABLE_9 (71 + 3)
#define NB_VLC_TABLE_18 (263 + 1)
-static const uint32_t table_9_vlc_bits[NB_VLC_TABLE_9] = {
- 0, 0x2, 0xc, 0x1a,
- 0x1d, 0x1e, 0x39, 0x3e,
- 0x37, 0x7e, 0x6c, 0xe2,
- 0xfe, 0xdb, 0xe0, 0x1c3,
- 0x1c6, 0x1ff, 0x1fe, 0x1b5,
- 0x369, 0x385, 0x71d, 0x6d0,
- 0x708, 0x71f, 0xe3d, 0xe39,
- 0xe13, 0xe12, 0x1c71, 0x1b45,
- 0x1b47, 0x3689, 0x38f2, 0x38e1,
- 0x38e0, 0x38f1, 0x3688, 0x6d1b,
- 0x71e0, 0x6d19, 0x71e7, 0xe3cd,
- 0xda35, 0xda30, 0xe3c3, 0x1b469,
- 0x1b462, 0x1c798, 0x1b463, 0x1c799,
- 0x38f08, 0x38f09, 0x38f0a, 0x6d1a0,
- 0x6d1a3, 0x6d1a1, 0xda345, 0xda344,
- 0xe3c2d, 0xe3c2f, 0xe3c2e, 0x38f0b2,
- 0x71e160, 0x71e162, 0x71e166, 0x71e161,
- 0xe3c2ce, 0xe3c2c6, 0xe3c2c7, 0x1C7859E,
- 0x38F0B3F, 0x38F0B3E,
+typedef struct CFHD_RL_ELEM {
+ uint16_t run;
+ uint8_t level;
+ uint8_t len;
+} CFHD_RL_ELEM;
+
+static const CFHD_RL_ELEM table_9_vlc[NB_VLC_TABLE_9] = {
+ { 1, 0, 1 }, { 1, 1, 2 }, { 1, 2, 4 }, { 1, 3, 5 },
+ { 1, 6, 7 }, { 1, 15, 11 }, { 1, 26, 14 }, { 1, 27, 14 },
+ { 1, 23, 13 }, { 1, 36, 16 }, { 1, 40, 17 }, { 1, 41, 17 },
+ { 1, 32, 15 }, { 1, 48, 19 }, { 1, 49, 19 }, { 1, 51, 20 },
+ { 1, 52, 20 }, { 1, 50, 19 }, { 1, 42, 17 }, { 1, 37, 16 },
+ { 1, 33, 15 }, { 1, 24, 13 }, { 1, 13, 10 }, { 1, 10, 9 },
+ { 1, 8, 8 }, { 1, 5, 6 }, { 80, 0, 8 }, { 1, 16, 11 },
+ { 1, 19, 12 }, { 1, 20, 12 }, { 1, 14, 10 }, { 120, 0, 9 },
+ { 320, 0, 8 }, { 1, 11, 9 }, { 1, 28, 14 }, { 1, 29, 14 },
+ { 1, 25, 13 }, { 1, 21, 12 }, { 1, 17, 11 }, { 1, 34, 15 },
+ { 1, 45, 18 }, { 1, 46, 18 }, { 1, 47, 18 }, { 1, 57, 23 },
+ { 1, 58, 23 }, { 1, 59, 23 }, { 1, 62, 24 }, { 1, 63, 24 },
+ { 1, 56, 22 }, { 1, 60, 23 }, { 1, 61, 24 }, { 1, 64, 25 },
+ { 0, 64, 26 }, { 1, 64, 26 }, { 1, 53, 20 }, { 1, 54, 20 },
+ { 1, 55, 20 }, { 1, 38, 16 }, { 1, 30, 14 }, { 1, 31, 14 },
+ { 1, 43, 17 }, { 1, 44, 17 }, { 1, 39, 16 }, { 1, 35, 15 },
+ { 1, 22, 12 }, { 1, 18, 11 }, { 32, 0, 6 }, { 12, 0, 5 },
+ { 1, 4, 5 }, { 160, 0, 6 }, { 1, 7, 7 }, { 1, 9, 8 },
+ { 100, 0, 9 }, { 1, 12, 9 },
};
-static const uint8_t table_9_vlc_len[NB_VLC_TABLE_9] = {
- 1, 2, 4, 5, 5, 5, 6, 6,
- 6, 7, 7, 8, 8, 8, 8, 9,
- 9, 9, 9, 9, 10, 10, 11, 11,
- 11, 11, 12, 12, 12, 12, 13, 13,
- 13, 14, 14, 14, 14, 14, 14, 15,
- 15, 15, 15, 16, 16, 16, 16, 17,
- 17, 17, 17, 17, 18, 18, 18, 19,
- 19, 19, 20, 20, 20, 20, 20, 22,
- 23, 23, 23, 23, 24, 24, 24, 25,
- 26, 26,
+static const CFHD_RL_ELEM table_18_vlc[NB_VLC_TABLE_18] = {
+ { 1, 0, 1 }, { 1, 1, 2 }, { 1, 4, 6 }, { 1, 14, 10 },
+ { 1, 23, 12 }, { 1, 41, 15 }, { 1, 54, 17 }, { 1, 69, 19 },
+ { 1, 77, 20 }, { 1, 85, 21 }, { 1, 108, 24 }, { 1, 237, 25 },
+ { 1, 238, 25 }, { 1, 101, 23 }, { 1, 172, 25 }, { 1, 173, 25 },
+ { 1, 170, 25 }, { 1, 171, 25 }, { 1, 227, 25 }, { 1, 162, 25 },
+ { 1, 156, 25 }, { 1, 157, 25 }, { 1, 243, 25 }, { 1, 134, 25 },
+ { 1, 135, 25 }, { 1, 136, 25 }, { 1, 128, 25 }, { 1, 129, 25 },
+ { 1, 247, 25 }, { 1, 127, 25 }, { 1, 178, 25 }, { 1, 179, 25 },
+ { 1, 214, 25 }, { 1, 118, 25 }, { 1, 204, 25 }, { 1, 205, 25 },
+ { 1, 198, 25 }, { 1, 199, 25 }, { 1, 245, 25 }, { 1, 246, 25 },
+ { 1, 242, 25 }, { 1, 244, 25 }, { 1, 230, 25 }, { 1, 119, 25 },
+ { 1, 193, 25 }, { 1, 194, 25 }, { 1, 186, 25 }, { 1, 187, 25 },
+ { 1, 211, 25 }, { 1, 190, 25 }, { 1, 163, 25 }, { 1, 164, 25 },
+ { 1, 220, 25 }, { 1, 221, 25 }, { 1, 216, 25 }, { 1, 217, 25 },
+ { 1, 212, 25 }, { 1, 213, 25 }, { 1, 206, 25 }, { 1, 208, 25 },
+ { 1, 209, 25 }, { 1, 210, 25 }, { 1, 122, 25 }, { 1, 248, 25 },
+ { 1, 235, 25 }, { 1, 148, 25 }, { 1, 253, 25 }, { 1, 254, 25 },
+ { 1, 123, 25 }, { 1, 124, 25 }, { 1, 215, 25 }, { 1, 117, 25 },
+ { 1, 234, 25 }, { 1, 236, 25 }, { 1, 142, 25 }, { 1, 143, 25 },
+ { 1, 153, 25 }, { 1, 154, 25 }, { 1, 176, 25 }, { 1, 177, 25 },
+ { 1, 174, 25 }, { 1, 175, 25 }, { 1, 184, 25 }, { 1, 185, 25 },
+ { 1, 240, 25 }, { 1, 241, 25 }, { 1, 239, 25 }, { 1, 141, 25 },
+ { 1, 139, 25 }, { 1, 140, 25 }, { 1, 125, 25 }, { 1, 126, 25 },
+ { 1, 130, 25 }, { 1, 131, 25 }, { 1, 228, 25 }, { 1, 229, 25 },
+ { 1, 232, 25 }, { 1, 233, 25 }, { 1, 132, 25 }, { 1, 133, 25 },
+ { 1, 137, 25 }, { 1, 138, 25 }, { 1, 255, 25 }, { 1, 116, 26 },
+ { 0, 255, 26 }, { 1, 249, 25 }, { 1, 250, 25 }, { 1, 251, 25 },
+ { 1, 252, 25 }, { 1, 120, 25 }, { 1, 121, 25 }, { 1, 222, 25 },
+ { 1, 224, 25 }, { 1, 218, 25 }, { 1, 219, 25 }, { 1, 200, 25 },
+ { 1, 201, 25 }, { 1, 191, 25 }, { 1, 192, 25 }, { 1, 149, 25 },
+ { 1, 150, 25 }, { 1, 151, 25 }, { 1, 152, 25 }, { 1, 146, 25 },
+ { 1, 147, 25 }, { 1, 144, 25 }, { 1, 145, 25 }, { 1, 165, 25 },
+ { 1, 166, 25 }, { 1, 167, 25 }, { 1, 168, 25 }, { 1, 158, 25 },
+ { 1, 159, 25 }, { 1, 223, 25 }, { 1, 169, 25 }, { 1, 207, 25 },
+ { 1, 197, 25 }, { 1, 202, 25 }, { 1, 203, 25 }, { 1, 188, 25 },
+ { 1, 189, 25 }, { 1, 225, 25 }, { 1, 226, 25 }, { 1, 195, 25 },
+ { 1, 196, 25 }, { 1, 182, 25 }, { 1, 183, 25 }, { 1, 231, 25 },
+ { 1, 155, 25 }, { 1, 160, 25 }, { 1, 161, 25 }, { 1, 48, 16 },
+ { 1, 36, 14 }, { 1, 30, 13 }, { 1, 19, 11 }, { 1, 11, 9 },
+ { 32, 0, 9 }, { 1, 15, 10 }, { 1, 24, 12 }, { 1, 42, 15 },
+ { 1, 62, 18 }, { 1, 70, 19 }, { 1, 94, 22 }, { 1, 180, 25 },
+ { 1, 181, 25 }, { 1, 109, 24 }, { 1, 102, 23 }, { 1, 86, 21 },
+ { 1, 78, 20 }, { 1, 55, 17 }, { 1, 49, 16 }, { 1, 37, 14 },
+ { 1, 31, 13 }, { 1, 25, 12 }, { 1, 43, 15 }, { 1, 63, 18 },
+ { 1, 71, 19 }, { 1, 79, 20 }, { 1, 87, 21 }, { 1, 88, 21 },
+ { 1, 56, 17 }, { 1, 50, 16 }, { 1, 38, 14 }, { 180, 0, 13 },
+ { 1, 6, 7 }, { 1, 3, 5 }, { 1, 12, 9 }, { 1, 20, 11 },
+ { 100, 0, 11 }, { 60, 0, 10 }, { 20, 0, 8 }, { 12, 0, 7 },
+ { 1, 9, 8 }, { 1, 16, 10 }, { 1, 32, 13 }, { 1, 44, 15 },
+ { 1, 64, 18 }, { 1, 72, 19 }, { 1, 80, 20 }, { 1, 95, 22 },
+ { 1, 96, 22 }, { 1, 110, 24 }, { 1, 111, 24 }, { 1, 103, 23 },
+ { 1, 104, 23 }, { 1, 105, 23 }, { 1, 57, 17 }, { 1, 65, 18 },
+ { 1, 73, 19 }, { 1, 81, 20 }, { 1, 89, 21 }, { 1, 97, 22 },
+ { 1, 98, 22 }, { 1, 58, 17 }, { 1, 39, 14 }, { 1, 26, 12 },
+ { 1, 21, 11 }, { 1, 13, 9 }, { 1, 7, 7 }, { 1, 5, 6 },
+ { 1, 10, 8 }, { 1, 33, 13 }, { 1, 51, 16 }, { 1, 66, 18 },
+ { 1, 74, 19 }, { 1, 82, 20 }, { 1, 90, 21 }, { 1, 91, 21 },
+ { 1, 59, 17 }, { 1, 45, 15 }, { 1, 52, 16 }, { 1, 67, 18 },
+ { 1, 75, 19 }, { 1, 83, 20 }, { 1, 112, 24 }, { 1, 113, 24 },
+ { 1, 106, 23 }, { 1, 99, 22 }, { 1, 92, 21 }, { 1, 68, 18 },
+ { 1, 76, 19 }, { 1, 84, 20 }, { 1, 107, 23 }, { 1, 114, 24 },
+ { 1, 115, 24 }, { 1, 100, 22 }, { 1, 93, 21 }, { 1, 46, 15 },
+ { 1, 27, 12 }, { 1, 34, 13 }, { 320, 0, 13 }, { 1, 28, 12 },
+ { 1, 17, 10 }, { 1, 22, 11 }, { 1, 40, 14 }, { 1, 53, 16 },
+ { 1, 60, 17 }, { 1, 61, 17 }, { 1, 47, 15 }, { 1, 35, 13 },
+ { 1, 29, 12 }, { 1, 18, 10 }, { 1, 8, 7 }, { 1, 2, 3 },
};
-static const uint16_t table_9_vlc_run[NB_VLC_TABLE_9] = {
- 1, 1, 1, 1, 12, 1, 32, 160,
- 1, 1, 1, 320, 1, 1, 80, 120,
- 1, 1, 100, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1
-};
-
-static const uint8_t table_9_vlc_level[NB_VLC_TABLE_9] = {
- 0, 1, 2, 3, 0, 4, 0, 0,
- 5, 7, 6, 0, 9, 8, 0, 0,
- 11, 12, 0, 10, 13, 14, 17, 15,
- 16, 18, 22, 21, 20, 19, 25, 23,
- 24, 27, 31, 29, 28, 30, 26, 33,
- 34, 32, 35, 39, 37, 36, 38, 42,
- 40, 43, 41, 44, 45, 46, 47, 48,
- 50, 49, 52, 51, 53, 55, 54, 56,
- 57, 59, 60, 58, 61, 62, 63, 64,
- 64, 64,
-};
-
-static const uint32_t table_18_vlc_bits[NB_VLC_TABLE_18] = {
- 0, 0x2, 0x7, 0x19,
- 0x30, 0x36, 0x6f, 0x63,
- 0x69, 0x6b, 0xd1, 0xd4,
- 0xdc, 0x189, 0x18a, 0x1a0,
- 0x1ab, 0x377, 0x310, 0x316,
- 0x343, 0x354, 0x375, 0x623,
- 0x684, 0x685, 0x6ab, 0x6ec,
- 0xddb, 0xc5c, 0xc5e, 0xc44,
- 0xd55, 0xdd1, 0xdd3, 0x1bb5,
- 0x188b, 0x18bb, 0x18bf, 0x1aa8,
- 0x1ba0, 0x1ba5, 0x1ba4, 0x3115,
- 0x3175, 0x317d, 0x3553, 0x3768,
- 0x6e87, 0x6ed3, 0x62e8, 0x62f8,
- 0x6228, 0x6aa4, 0x6e85, 0xc453,
- 0xc5d3, 0xc5f3, 0xdda4, 0xdd08,
- 0xdd0c, 0x1bb4b, 0x1bb4a, 0x18ba5,
- 0x18be5, 0x1aa95, 0x1aa97, 0x188a4,
- 0x1ba13, 0x31748, 0x317c8, 0x35528,
- 0x3552c, 0x37424, 0x37434, 0x37436,
- 0x62294, 0x62e92, 0x62f92, 0x6aa52,
- 0x6aa5a, 0x6e86a, 0x6e86e, 0x6e84a,
- 0xc452a, 0xc5d27, 0xc5f26, 0xd54a6,
- 0xd54b6, 0xdd096, 0xdd0d6, 0xdd0de,
- 0x188a56, 0x18ba4d, 0x18be4e, 0x18be4f,
- 0x1aa96e, 0x1ba12e, 0x1ba12f, 0x1ba1af,
- 0x1ba1bf, 0x37435d, 0x37437d, 0x317498,
- 0x35529c, 0x35529d, 0x3552de, 0x3552df,
- 0x62e933, 0x62295d, 0x6aa53d, 0x6aa53f,
- 0x6aa53e, 0x6e86b9, 0x6e86f8, 0xd54a79,
- 0xc5d265, 0xc452b8, 0xdd0d71, 0xd54a78,
- 0xdd0d70, 0xdd0df2, 0xdd0df3, 0x188a5f6,
- 0x188a5f5, 0x188a5f4, 0x188a5f3, 0x188a5f2,
- 0x188a5f1, 0x188a5f0, 0x188a5ef, 0x188a5ee,
- 0x188a5ed, 0x188a5aa, 0x188a5e3, 0x188a5df,
- 0x188a589, 0x188a5dd, 0x188a578, 0x188a5e0,
- 0x188a588, 0x188a5d6, 0x188a5db, 0x188a5e1,
- 0x188a587, 0x188a59a, 0x188a5c4, 0x188a5ec,
- 0x188a586, 0x188a573, 0x188a59c, 0x188a5c8,
- 0x188a5fb, 0x188a5a1, 0x188a5eb, 0x188a5a8,
- 0x188a584, 0x188a5d2, 0x188a599, 0x188a598,
- 0x188a583, 0x18ba4c9, 0x188a5d0, 0x188a594,
- 0x188a582, 0x188a5cb, 0x188a5d8, 0x188a5e7,
- 0x188a581, 0x188a5ea, 0x188a5a9, 0x188a5a6,
- 0x188a580, 0x188a5a0, 0x188a59d, 0x188a5c3,
- 0x188a57f, 0x188a5c0, 0x188a5de, 0x188a5d4,
- 0x188a57e, 0x188a5c2, 0x188a592, 0x188a5cd,
- 0x188a57d, 0x188a5a3, 0x188a5e8, 0x188a5a2,
- 0x188a57c, 0x188a58e, 0x188a5b3, 0x188a5b2,
- 0x188a5b1, 0x188a5b0, 0x188a5af, 0x188a5ae,
- 0x188a5ad, 0x188a5ac, 0x188a5ab, 0x188a5da,
- 0x188a5e4, 0x188a5e5, 0x188a5d9, 0x188a5b5,
- 0x188a5bc, 0x188a5bd, 0x188a5e9, 0x188a5cc,
- 0x188a585, 0x188a5d3, 0x188a5e2, 0x188a595,
- 0x188a596, 0x188a5b8, 0x188a590, 0x188a5c9,
- 0x188a5a4, 0x188a5e6, 0x188a5a5, 0x188a5ce,
- 0x188a5bf, 0x188a572, 0x188a59b, 0x188a5be,
- 0x188a5c7, 0x188a5ca, 0x188a5d5, 0x188a57b,
- 0x188a58d, 0x188a58c, 0x188a58b, 0x188a58a,
- 0x18ba4c8, 0x188a5c5, 0x188a5fa, 0x188a5bb,
- 0x188a5c1, 0x188a5cf, 0x188a5b9, 0x188a5b6,
- 0x188a597, 0x188a5fe, 0x188a5d7, 0x188a5ba,
- 0x188a591, 0x188a5c6, 0x188a5dc, 0x188a57a,
- 0x188a59f, 0x188a5f9, 0x188a5b4, 0x188a5a7,
- 0x188a58f, 0x188a5fd, 0x188a5b7, 0x188a593,
- 0x188a59e, 0x188a5f8, 0x188a5ff, 0x188a5fc,
- 0x188a579, 0x188a5f7, 0x3114ba2, 0x3114ba3,
-};
-
-static const uint8_t table_18_vlc_len[NB_VLC_TABLE_18] = {
- 1, 2, 3, 5, 6, 6, 7, 7,
- 7, 7, 8, 8, 8, 9, 9, 9,
- 9, 10, 10, 10, 10, 10, 10, 11,
- 11, 11, 11, 11, 12, 12, 12, 12,
- 12, 12, 12, 13, 13, 13, 13, 13,
- 13, 13, 13, 14, 14, 14, 14, 14,
- 15, 15, 15, 15, 15, 15, 15, 16,
- 16, 16, 16, 16, 16, 17, 17, 17,
- 17, 17, 17, 17, 17, 18, 18, 18,
- 18, 18, 18, 18, 19, 19, 19, 19,
- 19, 19, 19, 19, 20, 20, 20, 20,
- 20, 20, 20, 20, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 22, 22, 22,
- 22, 22, 22, 22, 23, 23, 23, 23,
- 23, 23, 23, 24, 24, 24, 24, 24,
- 24, 24, 24, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 26, 26,
-};
-
-static const uint16_t table_18_vlc_run[NB_VLC_TABLE_18] = {
- 1, 1, 1, 1, 1, 1, 1, 1,
- 12, 1, 20, 1, 1, 1, 32, 1,
- 1, 1, 1, 1, 60, 1, 1, 1,
- 1, 100, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 180, 1,
- 1, 320, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 2,
-};
-
-static const uint8_t table_18_vlc_level[NB_VLC_TABLE_18] = {
- 0, 1, 2, 3, 4, 5, 8, 6,
- 0, 7, 0, 9, 10, 11, 0, 12,
- 13, 18, 14, 15, 0, 16, 17, 19,
- 20, 0, 21, 22, 29, 24, 25, 23,
- 26, 27, 28, 35, 30, 31, 0, 32,
- 33, 0, 34, 36, 37, 38, 39, 40,
- 46, 47, 42, 43, 41, 44, 45, 48,
- 49, 50, 53, 51, 52, 61, 60, 55,
- 56, 57, 58, 54, 59, 62, 63, 64,
- 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 75, 76, 74, 77, 78, 79, 80,
- 81, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 91, 92, 93, 99, 100, 94,
- 95, 96, 97, 98, 102, 101, 103, 105,
- 104, 106, 107, 111, 109, 108, 113, 110,
- 112, 114, 115, 225, 189, 188, 203, 202,
- 197, 207, 169, 223, 159, 235, 152, 192,
- 179, 201, 172, 149, 178, 120, 219, 150,
- 127, 211, 125, 158, 247, 238, 163, 228,
- 183, 217, 168, 122, 128, 249, 187, 186,
- 136, 181, 255, 230, 135, 233, 222, 145,
- 134, 167, 248, 209, 243, 216, 164, 140,
- 157, 239, 191, 251, 156, 139, 242, 133,
- 162, 213, 165, 212, 227, 198, 236, 234,
- 117, 215, 124, 123, 254, 253, 148, 218,
- 146, 147, 224, 143, 184, 185, 166, 132,
- 129, 250, 151, 119, 193, 176, 245, 229,
- 206, 144, 208, 137, 241, 237, 190, 240,
- 131, 232, 252, 171, 205, 204, 118, 214,
- 180, 126, 182, 175, 141, 138, 177, 153,
- 194, 160, 121, 174, 246, 130, 200, 170,
- 221, 196, 142, 210, 199, 155, 154, 244,
- 220, 195, 161, 231, 173, 226, 116, 255,
-};
-
-av_cold int ff_cfhd_init_vlcs(CFHDContext *s)
+static av_cold int cfhd_init_vlc(CFHD_RL_VLC_ELEM out[], unsigned out_size,
+ const CFHD_RL_ELEM table_vlc[], unsigned table_size,
+ CFHD_RL_VLC_ELEM tmp[], void *logctx)
{
- int i, j, ret = 0;
- uint32_t new_cfhd_vlc_bits[NB_VLC_TABLE_18 * 2];
- uint8_t new_cfhd_vlc_len[NB_VLC_TABLE_18 * 2];
- uint16_t new_cfhd_vlc_run[NB_VLC_TABLE_18 * 2];
- int16_t new_cfhd_vlc_level[NB_VLC_TABLE_18 * 2];
+ VLC vlc;
+ unsigned j;
+ int ret;
/** Similar to dv.c, generate signed VLC tables **/
- /* Table 9 */
- for (i = 0, j = 0; i < NB_VLC_TABLE_9; i++, j++) {
- new_cfhd_vlc_bits[j] = table_9_vlc_bits[i];
- new_cfhd_vlc_len[j] = table_9_vlc_len[i];
- new_cfhd_vlc_run[j] = table_9_vlc_run[i];
- new_cfhd_vlc_level[j] = table_9_vlc_level[i];
+ for (unsigned i = j = 0; i < table_size; i++, j++) {
+ tmp[j].len = table_vlc[i].len;
+ tmp[j].run = table_vlc[i].run;
+ tmp[j].level = table_vlc[i].level;
/* Don't include the zero level nor escape bits */
- if (table_9_vlc_level[i] &&
- new_cfhd_vlc_bits[j] != table_9_vlc_bits[NB_VLC_TABLE_9-1]) {
- new_cfhd_vlc_bits[j] <<= 1;
- new_cfhd_vlc_len[j]++;
+ if (table_vlc[i].level && table_vlc[i].run) {
+ tmp[j].len++;
j++;
- new_cfhd_vlc_bits[j] = (table_9_vlc_bits[i] << 1) | 1;
- new_cfhd_vlc_len[j] = table_9_vlc_len[i] + 1;
- new_cfhd_vlc_run[j] = table_9_vlc_run[i];
- new_cfhd_vlc_level[j] = -table_9_vlc_level[i];
+ tmp[j].len = table_vlc[i].len + 1;
+ tmp[j].run = table_vlc[i].run;
+ tmp[j].level = -table_vlc[i].level;
}
}
- ret = init_vlc(&s->vlc_9, VLC_BITS, j, new_cfhd_vlc_len,
- 1, 1, new_cfhd_vlc_bits, 4, 4, 0);
+ ret = ff_init_vlc_from_lengths(&vlc, VLC_BITS, j,
+ &tmp[0].len, sizeof(tmp[0]),
+ NULL, 0, 0, 0, 0, logctx);
if (ret < 0)
return ret;
- for (i = 0; i < s->vlc_9.table_size; i++) {
- int code = s->vlc_9.table[i].sym;
- int len = s->vlc_9.table[i].len;
+ av_assert0(vlc.table_size == out_size);
+
+ for (unsigned i = out_size; i-- > 0;) {
+ int code = vlc.table[i].sym;
+ int len = vlc.table[i].len;
int level, run;
if (len < 0) { // more bits needed
run = 0;
level = code;
} else {
- run = new_cfhd_vlc_run[code];
- level = new_cfhd_vlc_level[code];
+ run = tmp[code].run;
+ level = tmp[code].level;
}
- s->table_9_rl_vlc[i].len = len;
- s->table_9_rl_vlc[i].level = level;
- s->table_9_rl_vlc[i].run = run;
+ out[i].len = len;
+ out[i].level = level;
+ out[i].run = run;
}
+ ff_free_vlc(&vlc);
- /* Table 18 */
- for (i = 0, j = 0; i < NB_VLC_TABLE_18; i++, j++) {
- new_cfhd_vlc_bits[j] = table_18_vlc_bits[i];
- new_cfhd_vlc_len[j] = table_18_vlc_len[i];
- new_cfhd_vlc_run[j] = table_18_vlc_run[i];
- new_cfhd_vlc_level[j] = table_18_vlc_level[i];
+ return 0;
+}
- /* Don't include the zero level nor escape bits */
- if (table_18_vlc_level[i] &&
- new_cfhd_vlc_bits[j] != table_18_vlc_bits[NB_VLC_TABLE_18-1]) {
- new_cfhd_vlc_bits[j] <<= 1;
- new_cfhd_vlc_len[j]++;
- j++;
- new_cfhd_vlc_bits[j] = (table_18_vlc_bits[i] << 1) | 1;
- new_cfhd_vlc_len[j] = table_18_vlc_len[i] + 1;
- new_cfhd_vlc_run[j] = table_18_vlc_run[i];
- new_cfhd_vlc_level[j] = -table_18_vlc_level[i];
- }
- }
+av_cold int ff_cfhd_init_vlcs(CFHDContext *s)
+{
+ int ret;
- ret = init_vlc(&s->vlc_18, VLC_BITS, j, new_cfhd_vlc_len,
- 1, 1, new_cfhd_vlc_bits, 4, 4, 0);
+ /* Table 18 - we reuse the unused table_9_rl_vlc as scratch buffer here */
+ ret = cfhd_init_vlc(s->table_18_rl_vlc, FF_ARRAY_ELEMS(s->table_18_rl_vlc),
+ table_18_vlc, FF_ARRAY_ELEMS(table_18_vlc),
+ s->table_9_rl_vlc, s->avctx);
if (ret < 0)
return ret;
- av_assert0(s->vlc_18.table_size == 4572);
-
- for (i = 0; i < s->vlc_18.table_size; i++) {
- int code = s->vlc_18.table[i].sym;
- int len = s->vlc_18.table[i].len;
- int level, run;
-
- if (len < 0) { // more bits needed
- run = 0;
- level = code;
- } else {
- run = new_cfhd_vlc_run[code];
- level = new_cfhd_vlc_level[code];
- }
- s->table_18_rl_vlc[i].len = len;
- s->table_18_rl_vlc[i].level = level;
- s->table_18_rl_vlc[i].run = run;
- }
-
- return ret;
+ /* Table 9 - table_9_rl_vlc itself is used as scratch buffer; it works
+ * because we are counting down in the final loop */
+ ret = cfhd_init_vlc(s->table_9_rl_vlc, FF_ARRAY_ELEMS(s->table_9_rl_vlc),
+ table_9_vlc, FF_ARRAY_ELEMS(table_9_vlc),
+ s->table_9_rl_vlc, s->avctx);
+ if (ret < 0)
+ return ret;
+ return 0;
}
diff --git a/libavcodec/cfhdenc.c b/libavcodec/cfhdenc.c
index 6b33b29da..f44743849 100644
--- a/libavcodec/cfhdenc.c
+++ b/libavcodec/cfhdenc.c
@@ -258,6 +258,11 @@ static av_cold int cfhd_encode_init(AVCodecContext *avctx)
if (ret < 0)
return ret;
+ if (avctx->height < 4) {
+ av_log(avctx, AV_LOG_ERROR, "Height must be >= 4.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
if (avctx->width & 15) {
av_log(avctx, AV_LOG_ERROR, "Width must be multiple of 16.\n");
return AVERROR_INVALIDDATA;
@@ -267,22 +272,21 @@ static av_cold int cfhd_encode_init(AVCodecContext *avctx)
for (int i = 0; i < s->planes; i++) {
int w8, h8, w4, h4, w2, h2;
- int width = i ? avctx->width >> s->chroma_h_shift : avctx->width;
- int height = i ? FFALIGN(avctx->height >> s->chroma_v_shift, 8) :
- FFALIGN(avctx->height >> s->chroma_v_shift, 8);
- ptrdiff_t stride = (FFALIGN(width / 8, 8) + 64) * 8;
+ const int a_height = FFALIGN(avctx->height, 8);
+ int width = i ? AV_CEIL_RSHIFT(avctx->width, s->chroma_h_shift) : avctx->width;
+ int height = i ? a_height >> s->chroma_v_shift: a_height;
- w8 = FFALIGN(width / 8, 8) + 64;
- h8 = FFALIGN(height, 8) / 8;
+ w8 = width / 8 + 64;
+ h8 = height / 8;
w4 = w8 * 2;
h4 = h8 * 2;
w2 = w4 * 2;
h2 = h4 * 2;
s->plane[i].dwt_buf =
- av_calloc(height * stride, sizeof(*s->plane[i].dwt_buf));
+ av_calloc(h8 * 8 * w8 * 8, sizeof(*s->plane[i].dwt_buf));
s->plane[i].dwt_tmp =
- av_malloc_array(height * stride, sizeof(*s->plane[i].dwt_tmp));
+ av_malloc_array(h8 * 8 * w8 * 8, sizeof(*s->plane[i].dwt_tmp));
if (!s->plane[i].dwt_buf || !s->plane[i].dwt_tmp)
return AVERROR(ENOMEM);
@@ -300,7 +304,7 @@ static av_cold int cfhd_encode_init(AVCodecContext *avctx)
for (int j = 0; j < DWT_LEVELS; j++) {
for (int k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) {
s->plane[i].band[j][k].width = (width / 8) << j;
- s->plane[i].band[j][k].height = (height / 8) << j;
+ s->plane[i].band[j][k].height = height >> (DWT_LEVELS - j);
s->plane[i].band[j][k].a_width = w8 << j;
s->plane[i].band[j][k].a_height = h8 << j;
}
@@ -433,11 +437,13 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
int ret;
for (int plane = 0; plane < s->planes; plane++) {
+ const int h_shift = plane ? s->chroma_h_shift : 0;
int width = s->plane[plane].band[2][0].width;
int a_width = s->plane[plane].band[2][0].a_width;
int height = s->plane[plane].band[2][0].height;
int act_plane = plane == 1 ? 2 : plane == 2 ? 1 : plane;
- int16_t *input = (int16_t *)frame->data[act_plane];
+ const int16_t *input = (int16_t *)frame->data[act_plane];
+ int16_t *buf;
int16_t *low = s->plane[plane].l_h[6];
int16_t *high = s->plane[plane].l_h[7];
ptrdiff_t in_stride = frame->linesize[act_plane] / 2;
@@ -452,7 +458,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
dsp->horiz_filter(input, low, high,
in_stride, a_width, a_width,
- width * 2, height * 2);
+ avctx->width >> h_shift, avctx->height);
input = s->plane[plane].l_h[7];
low = s->plane[plane].subband[7];
@@ -481,13 +487,13 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
high = s->plane[plane].l_h[4];
high_stride = s->plane[plane].band[1][0].a_width;
+ buf = s->plane[plane].l_h[7];
for (int i = 0; i < height * 2; i++) {
for (int j = 0; j < width * 2; j++)
- input[j] /= 4;
- input += a_width * 2;
+ buf[j] /= 4;
+ buf += a_width * 2;
}
- input = s->plane[plane].l_h[7];
dsp->horiz_filter(input, low, high,
a_width * 2, low_stride, high_stride,
width * 2, height * 2);
@@ -518,14 +524,14 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
high_stride = s->plane[plane].band[0][0].a_width;
if (avctx->pix_fmt != AV_PIX_FMT_YUV422P10) {
+ int16_t *buf = s->plane[plane].l_h[4];
for (int i = 0; i < height * 2; i++) {
for (int j = 0; j < width * 2; j++)
- input[j] /= 4;
- input += a_width * 2;
+ buf[j] /= 4;
+ buf += a_width * 2;
}
}
- input = s->plane[plane].l_h[4];
dsp->horiz_filter(input, low, high,
a_width * 2, low_stride, high_stride,
width * 2, height * 2);
@@ -547,7 +553,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
width, height * 2);
}
- ret = ff_alloc_packet(avctx, pkt, 64LL + s->planes * (2LL * avctx->width * avctx->height + 1000LL));
+ ret = ff_alloc_packet(avctx, pkt, 256LL + s->planes * (2LL * avctx->width * (avctx->height + 15) + 2048LL));
if (ret < 0)
return ret;
@@ -590,6 +596,9 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
bytestream2_put_be16(pby, avctx->width);
bytestream2_put_be16(pby, ImageHeight);
+ bytestream2_put_be16(pby, FFALIGN(avctx->height, 8));
+
+ bytestream2_put_be16(pby, -DisplayHeight);
bytestream2_put_be16(pby, avctx->height);
bytestream2_put_be16(pby, -FrameNumber);
@@ -847,20 +856,21 @@ static const AVClass cfhd_class = {
const FFCodec ff_cfhd_encoder = {
.p.name = "cfhd",
- .p.long_name = NULL_IF_CONFIG_SMALL("GoPro CineForm HD"),
+ CODEC_LONG_NAME("GoPro CineForm HD"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CFHD,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(CFHDEncContext),
.p.priv_class = &cfhd_class,
.init = cfhd_encode_init,
.close = cfhd_encode_close,
FF_CODEC_ENCODE_CB(cfhd_encode_frame),
- .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
.p.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV422P10,
AV_PIX_FMT_GBRP12,
AV_PIX_FMT_GBRAP12,
AV_PIX_FMT_NONE
},
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/cfhdencdsp.c b/libavcodec/cfhdencdsp.c
index 3a35522d6..a122bcaf1 100644
--- a/libavcodec/cfhdencdsp.c
+++ b/libavcodec/cfhdencdsp.c
@@ -23,7 +23,7 @@
#include "cfhdencdsp.h"
-static av_always_inline void filter(int16_t *input, ptrdiff_t in_stride,
+static av_always_inline void filter(const int16_t *input, ptrdiff_t in_stride,
int16_t *low, ptrdiff_t low_stride,
int16_t *high, ptrdiff_t high_stride,
int len)
@@ -46,7 +46,7 @@ static av_always_inline void filter(int16_t *input, ptrdiff_t in_stride,
1 * input[((len-2)-3)*in_stride] + 1 * input[((len-2)-4)*in_stride] + 4) >> 3);
}
-static void horiz_filter(int16_t *input, int16_t *low, int16_t *high,
+static void horiz_filter(const int16_t *input, int16_t *low, int16_t *high,
ptrdiff_t in_stride, ptrdiff_t low_stride,
ptrdiff_t high_stride,
int width, int height)
@@ -59,7 +59,7 @@ static void horiz_filter(int16_t *input, int16_t *low, int16_t *high,
}
}
-static void vert_filter(int16_t *input, int16_t *low, int16_t *high,
+static void vert_filter(const int16_t *input, int16_t *low, int16_t *high,
ptrdiff_t in_stride, ptrdiff_t low_stride,
ptrdiff_t high_stride,
int width, int height)
diff --git a/libavcodec/cfhdencdsp.h b/libavcodec/cfhdencdsp.h
index b3aac8d0a..d234b9379 100644
--- a/libavcodec/cfhdencdsp.h
+++ b/libavcodec/cfhdencdsp.h
@@ -23,12 +23,12 @@
#include
typedef struct CFHDEncDSPContext {
- void (*horiz_filter)(int16_t *input, int16_t *low, int16_t *high,
+ void (*horiz_filter)(const int16_t *input, int16_t *low, int16_t *high,
ptrdiff_t in_stride, ptrdiff_t low_stride,
ptrdiff_t high_stride,
int width, int height);
- void (*vert_filter)(int16_t *input, int16_t *low, int16_t *high,
+ void (*vert_filter)(const int16_t *input, int16_t *low, int16_t *high,
ptrdiff_t in_stride, ptrdiff_t low_stride,
ptrdiff_t high_stride,
int width, int height);
diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c
index e69232efb..282614fd1 100644
--- a/libavcodec/cinepak.c
+++ b/libavcodec/cinepak.c
@@ -34,7 +34,6 @@
*/
#include
-#include
#include
#include "libavutil/common.h"
@@ -42,7 +41,6 @@
#include "avcodec.h"
#include "codec_internal.h"
#include "decode.h"
-#include "internal.h"
typedef uint8_t cvid_codebook[12];
@@ -508,7 +506,7 @@ static av_cold int cinepak_decode_end(AVCodecContext *avctx)
const FFCodec ff_cinepak_decoder = {
.p.name = "cinepak",
- .p.long_name = NULL_IF_CONFIG_SMALL("Cinepak"),
+ CODEC_LONG_NAME("Cinepak"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CINEPAK,
.priv_data_size = sizeof(CinepakContext),
@@ -516,5 +514,4 @@ const FFCodec ff_cinepak_decoder = {
.close = cinepak_decode_end,
FF_CODEC_DECODE_CB(cinepak_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/cinepakenc.c b/libavcodec/cinepakenc.c
index 6cfe8de20..f15325ad0 100644
--- a/libavcodec/cinepakenc.c
+++ b/libavcodec/cinepakenc.c
@@ -429,7 +429,7 @@ static int encode_codebook(CinepakEncContext *s, int *codebook, int size,
// sets out to the sub picture starting at (x,y) in in
static void get_sub_picture(CinepakEncContext *s, int x, int y,
- uint8_t * in_data[4], int in_linesize[4],
+ uint8_t *const in_data[4], const int in_linesize[4],
uint8_t *out_data[4], int out_linesize[4])
{
out_data[0] = in_data[0] + x + y * in_linesize[0];
@@ -1019,7 +1019,7 @@ static int rd_frame(CinepakEncContext *s, const AVFrame *frame,
// build a copy of the given frame in the correct colorspace
for (y = 0; y < s->h; y += 2)
for (x = 0; x < s->w; x += 2) {
- uint8_t *ir[2];
+ const uint8_t *ir[2];
int32_t r, g, b, rr, gg, bb;
ir[0] = frame->data[0] + x * 3 + y * frame->linesize[0];
ir[1] = ir[0] + frame->linesize[0];
@@ -1097,7 +1097,7 @@ static int rd_frame(CinepakEncContext *s, const AVFrame *frame,
data, linesize);
else
get_sub_picture(s, 0, y,
- (uint8_t **)frame->data, (int *)frame->linesize,
+ frame->data, frame->linesize,
data, linesize);
get_sub_picture(s, 0, y,
s->last_frame->data, s->last_frame->linesize,
@@ -1216,14 +1216,15 @@ static av_cold int cinepak_encode_end(AVCodecContext *avctx)
const FFCodec ff_cinepak_encoder = {
.p.name = "cinepak",
- .p.long_name = NULL_IF_CONFIG_SMALL("Cinepak"),
+ CODEC_LONG_NAME("Cinepak"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CINEPAK,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(CinepakEncContext),
.init = cinepak_encode_init,
FF_CODEC_ENCODE_CB(cinepak_encode_frame),
.close = cinepak_encode_end,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB24, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE },
.p.priv_class = &cinepak_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/clearvideo.c b/libavcodec/clearvideo.c
index 075c6e946..e77661d18 100644
--- a/libavcodec/clearvideo.c
+++ b/libavcodec/clearvideo.c
@@ -30,9 +30,9 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
#include "idctdsp.h"
-#include "internal.h"
#include "mathops.h"
#include "clearvideodata.h"
@@ -59,13 +59,6 @@ typedef struct MVInfo {
MV *mv;
} MVInfo;
-typedef struct TileInfo {
- uint16_t flags;
- int16_t bias;
- MV mv;
- struct TileInfo *child[4];
-} TileInfo;
-
typedef struct CLVContext {
AVCodecContext *avctx;
IDCTDSPContext idsp;
@@ -222,14 +215,15 @@ static int decode_mb(CLVContext *c, int x, int y)
return 0;
}
-static int copy_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
+static int copy_block(AVCodecContext *avctx, AVFrame *dst, const AVFrame *src,
int plane, int x, int y, int dx, int dy, int size)
{
int shift = plane > 0;
int sx = x + dx;
int sy = y + dy;
int sstride, dstride, soff, doff;
- uint8_t *sbuf, *dbuf;
+ uint8_t *dbuf;
+ const uint8_t *sbuf;
int i;
if (x < 0 || sx < 0 || y < 0 || sy < 0 ||
@@ -248,7 +242,7 @@ static int copy_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
for (i = 0; i < size; i++) {
uint8_t *dptr = &dbuf[doff];
- uint8_t *sptr = &sbuf[soff];
+ const uint8_t *sptr = &sbuf[soff];
memcpy(dptr, sptr, size);
doff += dstride;
@@ -258,7 +252,7 @@ static int copy_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
return 0;
}
-static int copyadd_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
+static int copyadd_block(AVCodecContext *avctx, AVFrame *dst, const AVFrame *src,
int plane, int x, int y, int dx, int dy, int size, int bias)
{
int shift = plane > 0;
@@ -267,7 +261,7 @@ static int copyadd_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
int sstride = src->linesize[plane];
int dstride = dst->linesize[plane];
int soff = sx + sy * sstride;
- uint8_t *sbuf = src->data[plane];
+ const uint8_t *sbuf = src->data[plane];
int doff = x + y * dstride;
uint8_t *dbuf = dst->data[plane];
int i, j;
@@ -281,7 +275,7 @@ static int copyadd_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
for (j = 0; j < size; j++) {
uint8_t *dptr = &dbuf[doff];
- uint8_t *sptr = &sbuf[soff];
+ const uint8_t *sptr = &sbuf[soff];
for (i = 0; i < size; i++) {
int val = sptr[i] + bias;
@@ -296,7 +290,7 @@ static int copyadd_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
return 0;
}
-static MV mvi_predict(MVInfo *mvi, int mb_x, int mb_y, MV diff)
+static MV *mvi_predict(MVInfo *mvi, int mb_x, int mb_y)
{
MV res, pred_mv;
int left_mv, right_mv, top_mv, bot_mv;
@@ -336,10 +330,16 @@ static MV mvi_predict(MVInfo *mvi, int mb_x, int mb_y, MV diff)
res.y = bot_mv;
}
- mvi->mv[mvi->mb_stride + mb_x].x = res.x + diff.x;
- mvi->mv[mvi->mb_stride + mb_x].y = res.y + diff.y;
+ mvi->mv[mvi->mb_stride + mb_x].x = res.x;
+ mvi->mv[mvi->mb_stride + mb_x].y = res.y;
- return res;
+ return &mvi->mv[mvi->mb_stride + mb_x];
+}
+
+static void mvi_update_prediction(MV *mv, MV diff)
+{
+ mv->x += diff.x;
+ mv->y += diff.y;
}
static void mvi_reset(MVInfo *mvi, int mb_w, int mb_h, int mb_size)
@@ -362,60 +362,7 @@ static void mvi_update_row(MVInfo *mvi)
}
}
-static TileInfo *decode_tile_info(GetBitContext *gb, const LevelCodes *lc, int level)
-{
- TileInfo *ti;
- int i, flags = 0;
- int16_t bias = 0;
- MV mv = { 0 };
-
- if (lc[level].flags_cb.table) {
- flags = get_vlc2(gb, lc[level].flags_cb.table, CLV_VLC_BITS, 2);
- }
-
- if (lc[level].mv_cb.table) {
- uint16_t mv_code = get_vlc2(gb, lc[level].mv_cb.table, CLV_VLC_BITS, 2);
-
- if (mv_code != MV_ESC) {
- mv.x = (int8_t)(mv_code & 0xff);
- mv.y = (int8_t)(mv_code >> 8);
- } else {
- mv.x = get_sbits(gb, 8);
- mv.y = get_sbits(gb, 8);
- }
- }
-
- if (lc[level].bias_cb.table) {
- uint16_t bias_val = get_vlc2(gb, lc[level].bias_cb.table, CLV_VLC_BITS, 2);
-
- if (bias_val != BIAS_ESC) {
- bias = (int16_t)(bias_val);
- } else {
- bias = get_sbits(gb, 16);
- }
- }
-
- ti = av_calloc(1, sizeof(*ti));
- if (!ti)
- return NULL;
-
- ti->flags = flags;
- ti->mv = mv;
- ti->bias = bias;
-
- if (ti->flags) {
- for (i = 0; i < 4; i++) {
- if (ti->flags & (1 << i)) {
- TileInfo *subti = decode_tile_info(gb, lc, level + 1);
- ti->child[i] = subti;
- }
- }
- }
-
- return ti;
-}
-
-static int tile_do_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
+static int tile_do_block(AVCodecContext *avctx, AVFrame *dst, const AVFrame *src,
int plane, int x, int y, int dx, int dy, int size, int bias)
{
int ret;
@@ -429,35 +376,69 @@ static int tile_do_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
return ret;
}
-static int restore_tree(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
- int plane, int x, int y, int size,
- TileInfo *tile, MV root_mv)
+static int decode_tile(AVCodecContext *avctx, GetBitContext *gb,
+ const LevelCodes *lc,
+ AVFrame *dst, const AVFrame *src,
+ int plane, int x, int y, int size,
+ MV root_mv, MV *pred)
{
- int ret;
- MV mv;
+ int i, flags = 0;
+ int16_t bias = 0;
+ MV mv = { 0 };
+ int err;
- mv.x = root_mv.x + tile->mv.x;
- mv.y = root_mv.y + tile->mv.y;
+ if (lc->flags_cb.table)
+ flags = get_vlc2(gb, lc->flags_cb.table, CLV_VLC_BITS, 2);
- if (!tile->flags) {
- ret = tile_do_block(avctx, dst, src, plane, x, y, mv.x, mv.y, size, tile->bias);
- } else {
- int i, hsize = size >> 1;
+ if (lc->mv_cb.table) {
+ uint16_t mv_code = get_vlc2(gb, lc->mv_cb.table, CLV_VLC_BITS, 2);
+ if (mv_code != MV_ESC) {
+ mv.x = (int8_t)(mv_code & 0xff);
+ mv.y = (int8_t)(mv_code >> 8);
+ } else {
+ mv.x = get_sbits(gb, 8);
+ mv.y = get_sbits(gb, 8);
+ }
+ if (pred)
+ mvi_update_prediction(pred, mv);
+ }
+ 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 (bias_val != BIAS_ESC) {
+ bias = (int16_t)(bias_val);
+ } else {
+ bias = get_sbits(gb, 16);
+ }
+ }
+
+ if (flags) {
+ int hsize = size >> 1;
for (i = 0; i < 4; i++) {
int xoff = (i & 2) == 0 ? 0 : hsize;
int yoff = (i & 1) == 0 ? 0 : hsize;
- if (tile->child[i]) {
- ret = restore_tree(avctx, dst, src, plane, x + xoff, y + yoff, hsize, tile->child[i], root_mv);
- av_freep(&tile->child[i]);
+ if (flags & (1 << i)) {
+ err = decode_tile(avctx, gb, lc + 1, dst, src, plane,
+ x + xoff, y + yoff, hsize, root_mv, NULL);
} else {
- ret = tile_do_block(avctx, dst, src, plane, x + xoff, y + yoff, mv.x, mv.y, hsize, tile->bias);
+ err = tile_do_block(avctx, dst, src, plane, x + xoff, y + yoff,
+ mv.x, mv.y, hsize, bias);
}
+ if (err < 0)
+ return err;
}
+ } else {
+ err = tile_do_block(avctx, dst, src, plane, x, y, mv.x, mv.y, size, bias);
+ if (err < 0)
+ return err;
}
- return ret;
+ return 0;
}
static void extend_edges(AVFrame *buf, int tile_size)
@@ -576,11 +557,13 @@ static int clv_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
for (j = 0; j < c->pmb_height; j++) {
for (i = 0; i < c->pmb_width; i++) {
+ MV *mvp, mv;
if (get_bits_left(&c->gb) <= 0)
return AVERROR_INVALIDDATA;
- if (get_bits1(&c->gb)) {
- MV mv = mvi_predict(&c->mvi, i, j, zero_mv);
+ mvp = mvi_predict(&c->mvi, i, j);
+ mv = *mvp;
+ if (get_bits1(&c->gb)) {
for (plane = 0; plane < 3; plane++) {
int16_t x = plane == 0 ? i << c->tile_shift : i << (c->tile_shift - 1);
int16_t y = plane == 0 ? j << c->tile_shift : j << (c->tile_shift - 1);
@@ -596,38 +579,26 @@ static int clv_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
int x = i << c->tile_shift;
int y = j << c->tile_shift;
int size = 1 << c->tile_shift;
- TileInfo *tile;
- MV mv, cmv;
+ MV cmv;
- tile = decode_tile_info(&c->gb, &lev[0], 0); // Y
- if (!tile)
- return AVERROR(ENOMEM);
- mv = mvi_predict(&c->mvi, i, j, tile->mv);
- ret = restore_tree(avctx, c->pic, c->prev, 0, x, y, size, tile, mv);
+ ret = decode_tile(avctx, &c->gb, &lev[0], c->pic, c->prev, // Y
+ 0, x, y, size, mv, mvp);
if (ret < 0)
mb_ret = ret;
x = i << (c->tile_shift - 1);
y = j << (c->tile_shift - 1);
size = 1 << (c->tile_shift - 1);
- cmv.x = mv.x + tile->mv.x;
- cmv.y = mv.y + tile->mv.y;
+ cmv = *mvp;
cmv.x /= 2;
cmv.y /= 2;
- av_freep(&tile);
- tile = decode_tile_info(&c->gb, &lev[4], 0); // U
- if (!tile)
- return AVERROR(ENOMEM);
- ret = restore_tree(avctx, c->pic, c->prev, 1, x, y, size, tile, cmv);
+ ret = decode_tile(avctx, &c->gb, &lev[4], c->pic, c->prev, // U
+ 1, x, y, size, cmv, NULL);
if (ret < 0)
mb_ret = ret;
- av_freep(&tile);
- tile = decode_tile_info(&c->gb, &lev[7], 0); // V
- if (!tile)
- return AVERROR(ENOMEM);
- ret = restore_tree(avctx, c->pic, c->prev, 2, x, y, size, tile, cmv);
+ ret = decode_tile(avctx, &c->gb, &lev[7], c->pic, c->prev, // U
+ 2, x, y, size, cmv, NULL);
if (ret < 0)
mb_ret = ret;
- av_freep(&tile);
}
}
mvi_update_row(&c->mvi);
@@ -769,7 +740,7 @@ static av_cold int clv_decode_end(AVCodecContext *avctx)
const FFCodec ff_clearvideo_decoder = {
.p.name = "clearvideo",
- .p.long_name = NULL_IF_CONFIG_SMALL("Iterated Systems ClearVideo"),
+ CODEC_LONG_NAME("Iterated Systems ClearVideo"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CLEARVIDEO,
.priv_data_size = sizeof(CLVContext),
@@ -777,5 +748,5 @@ const FFCodec ff_clearvideo_decoder = {
.close = clv_decode_end,
FF_CODEC_DECODE_CB(clv_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/cljrdec.c b/libavcodec/cljrdec.c
index bb7c9bfb6..914f853c8 100644
--- a/libavcodec/cljrdec.c
+++ b/libavcodec/cljrdec.c
@@ -26,8 +26,8 @@
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
static int decode_frame(AVCodecContext *avctx, AVFrame *p,
int *got_frame, AVPacket *avpkt)
@@ -83,12 +83,11 @@ static av_cold int decode_init(AVCodecContext *avctx)
const FFCodec ff_cljr_decoder = {
.p.name = "cljr",
- .p.long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
+ CODEC_LONG_NAME("Cirrus Logic AccuPak"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CLJR,
.init = decode_init,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/cljrenc.c b/libavcodec/cljrenc.c
index 2d171a937..31ad5ce0c 100644
--- a/libavcodec/cljrenc.c
+++ b/libavcodec/cljrenc.c
@@ -42,7 +42,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
CLJRContext *a = avctx->priv_data;
PutBitContext pb;
int x, y, ret;
- uint32_t dither= avctx->frame_number;
+ uint32_t dither= avctx->frame_num;
static const uint32_t ordered_dither[2][2] =
{
{ 0x10400000, 0x104F0000 },
@@ -63,9 +63,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
init_put_bits(&pb, pkt->data, pkt->size);
for (y = 0; y < avctx->height; y++) {
- uint8_t *luma = &p->data[0][y * p->linesize[0]];
- uint8_t *cb = &p->data[1][y * p->linesize[1]];
- uint8_t *cr = &p->data[2][y * p->linesize[2]];
+ const uint8_t *luma = &p->data[0][y * p->linesize[0]];
+ const uint8_t *cb = &p->data[1][y * p->linesize[1]];
+ const uint8_t *cr = &p->data[2][y * p->linesize[2]];
uint8_t luma_tmp[4];
for (x = 0; x < avctx->width; x += 4) {
switch (a->dither_type) {
@@ -110,10 +110,10 @@ static const AVClass cljr_class = {
const FFCodec ff_cljr_encoder = {
.p.name = "cljr",
- .p.long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
+ CODEC_LONG_NAME("Cirrus Logic AccuPak"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CLJR,
- .p.capabilities = AV_CODEC_CAP_DR1,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(CLJRContext),
FF_CODEC_ENCODE_CB(encode_frame),
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P,
diff --git a/libavcodec/cllc.c b/libavcodec/cllc.c
index 4866c5b2d..911717b68 100644
--- a/libavcodec/cllc.c
+++ b/libavcodec/cllc.c
@@ -493,7 +493,7 @@ static av_cold int cllc_decode_init(AVCodecContext *avctx)
const FFCodec ff_cllc_decoder = {
.p.name = "cllc",
- .p.long_name = NULL_IF_CONFIG_SMALL("Canopus Lossless Codec"),
+ CODEC_LONG_NAME("Canopus Lossless Codec"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CLLC,
.priv_data_size = sizeof(CLLCContext),
@@ -501,5 +501,4 @@ const FFCodec ff_cllc_decoder = {
FF_CODEC_DECODE_CB(cllc_decode_frame),
.close = cllc_decode_close,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/cngdec.c b/libavcodec/cngdec.c
index d549ff4c0..5cf5dc9bc 100644
--- a/libavcodec/cngdec.c
+++ b/libavcodec/cngdec.c
@@ -27,6 +27,7 @@
#include "avcodec.h"
#include "celp_filters.h"
#include "codec_internal.h"
+#include "decode.h"
#include "internal.h"
#include "libavutil/lfg.h"
@@ -164,7 +165,7 @@ static int cng_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_comfortnoise_decoder = {
.p.name = "comfortnoise",
- .p.long_name = NULL_IF_CONFIG_SMALL("RFC 3389 comfort noise generator"),
+ CODEC_LONG_NAME("RFC 3389 comfort noise generator"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_COMFORT_NOISE,
.priv_data_size = sizeof(CNGContext),
@@ -175,6 +176,5 @@ const FFCodec ff_comfortnoise_decoder = {
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_NONE },
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/cngenc.c b/libavcodec/cngenc.c
index 1f5d25e5b..596d6f8c2 100644
--- a/libavcodec/cngenc.c
+++ b/libavcodec/cngenc.c
@@ -67,7 +67,7 @@ static int cng_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
int ret, i;
double energy = 0;
int qdbov;
- int16_t *samples = (int16_t*) frame->data[0];
+ const int16_t *samples = (const int16_t*) frame->data[0];
if ((ret = ff_get_encode_buffer(avctx, avpkt, 1 + p->order, 0))) {
av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
@@ -98,10 +98,10 @@ static int cng_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
const FFCodec ff_comfortnoise_encoder = {
.p.name = "comfortnoise",
- .p.long_name = NULL_IF_CONFIG_SMALL("RFC 3389 comfort noise generator"),
+ CODEC_LONG_NAME("RFC 3389 comfort noise generator"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_COMFORT_NOISE,
- .p.capabilities = AV_CODEC_CAP_DR1,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(CNGContext),
.init = cng_encode_init,
FF_CODEC_ENCODE_CB(cng_encode_frame),
@@ -109,5 +109,5 @@ const FFCodec ff_comfortnoise_encoder = {
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_NONE },
.p.ch_layouts = (const AVChannelLayout[]){ AV_CHANNEL_LAYOUT_MONO, { 0 } },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/codec.h b/libavcodec/codec.h
index 03e8be90a..3b1995bcf 100644
--- a/libavcodec/codec.h
+++ b/libavcodec/codec.h
@@ -50,12 +50,6 @@
* avcodec_default_get_buffer2 or avcodec_default_get_encode_buffer.
*/
#define AV_CODEC_CAP_DR1 (1 << 1)
-#if FF_API_FLAG_TRUNCATED
-/**
- * @deprecated Use parsers to always send proper frames.
- */
-#define AV_CODEC_CAP_TRUNCATED (1 << 3)
-#endif
/**
* Encoder or decoder requires flushing with NULL input at the end in order to
* give the complete and correct output.
@@ -125,9 +119,6 @@
* multithreading-capable external libraries.
*/
#define AV_CODEC_CAP_OTHER_THREADS (1 << 15)
-#if FF_API_AUTO_THREADS
-#define AV_CODEC_CAP_AUTO_THREADS AV_CODEC_CAP_OTHER_THREADS
-#endif
/**
* Audio encoder supports receiving a different number of samples in each call.
*/
@@ -143,17 +134,6 @@
*/
#define AV_CODEC_CAP_AVOID_PROBING (1 << 17)
-#if FF_API_UNUSED_CODEC_CAPS
-/**
- * Deprecated and unused. Use AVCodecDescriptor.props instead
- */
-#define AV_CODEC_CAP_INTRA_ONLY 0x40000000
-/**
- * Deprecated and unused. Use AVCodecDescriptor.props instead
- */
-#define AV_CODEC_CAP_LOSSLESS 0x80000000
-#endif
-
/**
* Codec is backed by a hardware implementation. Typically used to
* identify a non-hwaccel hardware decoder. For information about hwaccels, use
@@ -169,9 +149,9 @@
#define AV_CODEC_CAP_HYBRID (1 << 19)
/**
- * This codec takes the reordered_opaque field from input AVFrames
- * and returns it in the corresponding field in AVCodecContext after
- * encoding.
+ * This encoder can reorder user opaque values from input AVFrames and return
+ * them with corresponding output packets.
+ * @see AV_CODEC_FLAG_COPY_OPAQUE
*/
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE (1 << 20)
@@ -182,6 +162,14 @@
*/
#define AV_CODEC_CAP_ENCODER_FLUSH (1 << 21)
+/**
+ * The encoder is able to output reconstructed frame data, i.e. raw frames that
+ * would be produced by decoding the encoded bitstream.
+ *
+ * Reconstructed frame output is enabled by the AV_CODEC_FLAG_RECON_FRAME flag.
+ */
+#define AV_CODEC_CAP_ENCODER_RECON_FRAME (1 << 22)
+
/**
* AVProfile.
*/
diff --git a/libavcodec/codec2utils.c b/libavcodec/codec2utils.c
deleted file mode 100644
index a94266240..000000000
--- a/libavcodec/codec2utils.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * codec2 utility functions
- * Copyright (c) 2017 Tomas Härdin
- *
- * 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
-#include "internal.h"
-#include "libavcodec/codec2utils.h"
-
-#if LIBAVCODEC_VERSION_MAJOR < 59
-int avpriv_codec2_mode_bit_rate(void *logctx, int mode)
-{
- int frame_size = avpriv_codec2_mode_frame_size(logctx, mode);
- int block_align = avpriv_codec2_mode_block_align(logctx, mode);
-
- if (frame_size <= 0 || block_align <= 0) {
- return 0;
- }
-
- return 8 * 8000 * block_align / frame_size;
-}
-
-int avpriv_codec2_mode_frame_size(void *logctx, int mode)
-{
- int frame_size_table[CODEC2_MODE_MAX+1] = {
- 160, // 3200
- 160, // 2400
- 320, // 1600
- 320, // 1400
- 320, // 1300
- 320, // 1200
- 320, // 700
- 320, // 700B
- 320, // 700C
- };
-
- if (mode < 0 || mode > CODEC2_MODE_MAX) {
- av_log(logctx, AV_LOG_ERROR, "unknown codec2 mode %i, can't find frame_size\n", mode);
- return 0;
- } else {
- return frame_size_table[mode];
- }
-}
-
-int avpriv_codec2_mode_block_align(void *logctx, int mode)
-{
- int block_align_table[CODEC2_MODE_MAX+1] = {
- 8, // 3200
- 6, // 2400
- 8, // 1600
- 7, // 1400
- 7, // 1300
- 6, // 1200
- 4, // 700
- 4, // 700B
- 4, // 700C
- };
-
- if (mode < 0 || mode > CODEC2_MODE_MAX) {
- av_log(logctx, AV_LOG_ERROR, "unknown codec2 mode %i, can't find block_align\n", mode);
- return 0;
- } else {
- return block_align_table[mode];
- }
-}
-#endif
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 44ad2d1fe..199f62df1 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -1462,6 +1462,7 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("Avid Meridien Uncompressed"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
},
+#if FF_API_AYUV_CODECID
{
.id = AV_CODEC_ID_AYUV,
.type = AVMEDIA_TYPE_VIDEO,
@@ -1469,6 +1470,7 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed MS 4:4:4:4"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
},
+#endif
{
.id = AV_CODEC_ID_TARGA_Y216,
.type = AVMEDIA_TYPE_VIDEO,
@@ -1893,6 +1895,34 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("PHM (Portable HalfFloatMap) image"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
},
+ {
+ .id = AV_CODEC_ID_RADIANCE_HDR,
+ .type = AVMEDIA_TYPE_VIDEO,
+ .name = "hdr",
+ .long_name = NULL_IF_CONFIG_SMALL("HDR (Radiance RGBE format) image"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
+ {
+ .id = AV_CODEC_ID_WBMP,
+ .type = AVMEDIA_TYPE_VIDEO,
+ .name = "wbmp",
+ .long_name = NULL_IF_CONFIG_SMALL("WBMP (Wireless Application Protocol Bitmap) image"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
+ },
+ {
+ .id = AV_CODEC_ID_MEDIA100,
+ .type = AVMEDIA_TYPE_VIDEO,
+ .name = "media100",
+ .long_name = NULL_IF_CONFIG_SMALL("Media 100i"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
+ {
+ .id = AV_CODEC_ID_VQC,
+ .type = AVMEDIA_TYPE_VIDEO,
+ .name = "vqc",
+ .long_name = NULL_IF_CONFIG_SMALL("ViewQuest VQC"),
+ .props = AV_CODEC_PROP_LOSSY,
+ },
/* various PCM "codecs" */
{
@@ -2506,6 +2536,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Acorn Replay"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_ADPCM_XMD,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "adpcm_xmd",
+ .long_name = NULL_IF_CONFIG_SMALL("ADPCM Konami XMD"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
/* AMR */
{
@@ -2589,6 +2626,20 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("DPCM Xilam DERF"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_WADY_DPCM,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "wady_dpcm",
+ .long_name = NULL_IF_CONFIG_SMALL("DPCM Marble WADY"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
+ {
+ .id = AV_CODEC_ID_CBD2_DPCM,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "cbd2_dpcm",
+ .long_name = NULL_IF_CONFIG_SMALL("DPCM Cuberoot-Delta-Exact"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
/* audio codecs */
{
@@ -3274,6 +3325,48 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("DFPWM (Dynamic Filter Pulse Width Modulation)"),
.props = AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_BONK,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "bonk",
+ .long_name = NULL_IF_CONFIG_SMALL("Bonk audio"),
+ .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
+ },
+ {
+ .id = AV_CODEC_ID_MISC4,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "misc4",
+ .long_name = NULL_IF_CONFIG_SMALL("Micronas SC-4 Audio"),
+ .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_INTRA_ONLY,
+ },
+ {
+ .id = AV_CODEC_ID_APAC,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "apac",
+ .long_name = NULL_IF_CONFIG_SMALL("Marian's A-pac audio"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
+ },
+ {
+ .id = AV_CODEC_ID_FTR,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "ftr",
+ .long_name = NULL_IF_CONFIG_SMALL("FTR Voice"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
+ {
+ .id = AV_CODEC_ID_WAVARC,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "wavarc",
+ .long_name = NULL_IF_CONFIG_SMALL("Waveform Archiver"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
+ },
+ {
+ .id = AV_CODEC_ID_RKA,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "rka",
+ .long_name = NULL_IF_CONFIG_SMALL("RKA (RK Audio)"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS,
+ },
/* subtitle codecs */
{
@@ -3546,6 +3639,18 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("AVFrame to AVPacket passthrough"),
.props = AV_CODEC_PROP_LOSSLESS,
},
+ {
+ .id = AV_CODEC_ID_VNULL,
+ .type = AVMEDIA_TYPE_VIDEO,
+ .name = "vnull",
+ .long_name = NULL_IF_CONFIG_SMALL("Null video codec"),
+ },
+ {
+ .id = AV_CODEC_ID_ANULL,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "anull",
+ .long_name = NULL_IF_CONFIG_SMALL("Null audio codec"),
+ },
};
static int descriptor_compare(const void *key, const void *member)
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index 81fb316cf..89a4a0cb8 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -24,6 +24,8 @@
#include "libavutil/avutil.h"
#include "libavutil/samplefmt.h"
+#include "version_major.h"
+
/**
* @addtogroup lavc_core
* @{
@@ -251,7 +253,9 @@ enum AVCodecID {
AV_CODEC_ID_AVRP,
AV_CODEC_ID_012V,
AV_CODEC_ID_AVUI,
+#if FF_API_AYUV_CODECID
AV_CODEC_ID_AYUV,
+#endif
AV_CODEC_ID_TARGA_Y216,
AV_CODEC_ID_V308,
AV_CODEC_ID_V408,
@@ -312,6 +316,10 @@ enum AVCodecID {
AV_CODEC_ID_JPEGXL,
AV_CODEC_ID_QOI,
AV_CODEC_ID_PHM,
+ AV_CODEC_ID_RADIANCE_HDR,
+ AV_CODEC_ID_WBMP,
+ AV_CODEC_ID_MEDIA100,
+ AV_CODEC_ID_VQC,
/* various PCM "codecs" */
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
@@ -405,6 +413,7 @@ enum AVCodecID {
AV_CODEC_ID_ADPCM_IMA_CUNNING,
AV_CODEC_ID_ADPCM_IMA_MOFLEX,
AV_CODEC_ID_ADPCM_IMA_ACORN,
+ AV_CODEC_ID_ADPCM_XMD,
/* AMR */
AV_CODEC_ID_AMR_NB = 0x12000,
@@ -422,6 +431,8 @@ enum AVCodecID {
AV_CODEC_ID_SDX2_DPCM,
AV_CODEC_ID_GREMLIN_DPCM,
AV_CODEC_ID_DERF_DPCM,
+ AV_CODEC_ID_WADY_DPCM,
+ AV_CODEC_ID_CBD2_DPCM,
/* audio codecs */
AV_CODEC_ID_MP2 = 0x15000,
@@ -521,6 +532,12 @@ enum AVCodecID {
AV_CODEC_ID_FASTAUDIO,
AV_CODEC_ID_MSNSIREN,
AV_CODEC_ID_DFPWM,
+ AV_CODEC_ID_BONK,
+ AV_CODEC_ID_MISC4,
+ AV_CODEC_ID_APAC,
+ AV_CODEC_ID_FTR,
+ AV_CODEC_ID_WAVARC,
+ AV_CODEC_ID_RKA,
/* subtitle codecs */
AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs.
@@ -575,6 +592,16 @@ enum AVCodecID {
* stream (only used by libavformat) */
AV_CODEC_ID_FFMETADATA = 0x21000, ///< Dummy codec for streams containing only metadata information.
AV_CODEC_ID_WRAPPED_AVFRAME = 0x21001, ///< Passthrough codec, AVFrames wrapped in AVPacket
+ /**
+ * Dummy null video codec, useful mainly for development and debugging.
+ * Null encoder/decoder discard all input and never return any output.
+ */
+ AV_CODEC_ID_VNULL,
+ /**
+ * Dummy null audio codec, useful mainly for development and debugging.
+ * Null encoder/decoder discard all input and never return any output.
+ */
+ AV_CODEC_ID_ANULL,
};
/**
diff --git a/libavcodec/codec_internal.h b/libavcodec/codec_internal.h
index 5df286ce5..130a7dc3c 100644
--- a/libavcodec/codec_internal.h
+++ b/libavcodec/codec_internal.h
@@ -23,12 +23,15 @@
#include "libavutil/attributes.h"
#include "codec.h"
+#include "config.h"
/**
- * The codec does not modify any global variables in the init function,
- * allowing to call the init function without locking any global mutexes.
+ * The codec is not known to be init-threadsafe (i.e. it might be unsafe
+ * to initialize this codec and another codec concurrently, typically because
+ * the codec calls external APIs that are not known to be thread-safe).
+ * Therefore calling the codec's init function needs to be guarded with a lock.
*/
-#define FF_CODEC_CAP_INIT_THREADSAFE (1 << 0)
+#define FF_CODEC_CAP_NOT_INIT_THREADSAFE (1 << 0)
/**
* The codec allows calling the close function for deallocation even if
* the init function returned a failure. Without this capability flag, a
@@ -73,6 +76,18 @@
* internal logic derive them from AVCodecInternal.last_pkt_props.
*/
#define FF_CODEC_CAP_SETS_FRAME_PROPS (1 << 8)
+/**
+ * Codec supports embedded ICC profiles (AV_FRAME_DATA_ICC_PROFILE).
+ */
+#define FF_CODEC_CAP_ICC_PROFILES (1 << 9)
+/**
+ * The encoder has AV_CODEC_CAP_DELAY set, but does not actually have delay - it
+ * only wants to be flushed at the end to update some context variables (e.g.
+ * 2pass stats) or produce a trailing packet. Besides that it immediately
+ * produces exactly one output packet per each input frame, just as no-delay
+ * encoders do.
+ */
+#define FF_CODEC_CAP_EOF_FLUSH (1 << 10)
/**
* FFCodec.codec_tags termination value
@@ -251,6 +266,43 @@ typedef struct FFCodec {
const uint32_t *codec_tags;
} FFCodec;
+#if CONFIG_SMALL
+#define CODEC_LONG_NAME(str) .p.long_name = NULL
+#else
+#define CODEC_LONG_NAME(str) .p.long_name = str
+#endif
+
+#if HAVE_THREADS
+#define UPDATE_THREAD_CONTEXT(func) \
+ .update_thread_context = (func)
+#define UPDATE_THREAD_CONTEXT_FOR_USER(func) \
+ .update_thread_context_for_user = (func)
+#else
+#define UPDATE_THREAD_CONTEXT(func) \
+ .update_thread_context = NULL
+#define UPDATE_THREAD_CONTEXT_FOR_USER(func) \
+ .update_thread_context_for_user = NULL
+#endif
+
+#if FF_API_OLD_CHANNEL_LAYOUT
+#define CODEC_OLD_CHANNEL_LAYOUTS(...) CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(((const uint64_t[]) { __VA_ARGS__, 0 }))
+#if defined(__clang__)
+#define CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(array) \
+ FF_DISABLE_DEPRECATION_WARNINGS \
+ .p.channel_layouts = (array), \
+ FF_ENABLE_DEPRECATION_WARNINGS
+#else
+#define CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(array) .p.channel_layouts = (array),
+#endif
+#else
+/* This is only provided to allow to test disabling FF_API_OLD_CHANNEL_LAYOUT
+ * without removing all the FF_API_OLD_CHANNEL_LAYOUT codeblocks.
+ * It is of course still expected to be removed when FF_API_OLD_CHANNEL_LAYOUT
+ * will be finally removed (along with all usages of these macros). */
+#define CODEC_OLD_CHANNEL_LAYOUTS(...)
+#define CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(array)
+#endif
+
#define FF_CODEC_DECODE_CB(func) \
.cb_type = FF_CODEC_CB_TYPE_DECODE, \
.cb.decode = (func)
diff --git a/libavcodec/codec_par.h b/libavcodec/codec_par.h
index 7660791a1..f51d27c59 100644
--- a/libavcodec/codec_par.h
+++ b/libavcodec/codec_par.h
@@ -32,15 +32,16 @@
/**
* @addtogroup lavc_core
+ * @{
*/
enum AVFieldOrder {
AV_FIELD_UNKNOWN,
AV_FIELD_PROGRESSIVE,
- AV_FIELD_TT, //< Top coded_first, top displayed first
- AV_FIELD_BB, //< Bottom coded first, bottom displayed first
- AV_FIELD_TB, //< Top coded first, bottom displayed first
- AV_FIELD_BT, //< Bottom coded first, top displayed first
+ AV_FIELD_TT, ///< Top coded_first, top displayed first
+ AV_FIELD_BB, ///< Bottom coded first, bottom displayed first
+ AV_FIELD_TB, ///< Top coded first, bottom displayed first
+ AV_FIELD_BT, ///< Bottom coded first, top displayed first
};
/**
diff --git a/libavcodec/cook.c b/libavcodec/cook.c
index 7161209db..7d05afcca 100644
--- a/libavcodec/cook.c
+++ b/libavcodec/cook.c
@@ -46,14 +46,14 @@
#include "libavutil/lfg.h"
#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"
+#include "libavutil/tx.h"
#include "audiodsp.h"
#include "avcodec.h"
#include "get_bits.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "fft.h"
-#include "internal.h"
+#include "decode.h"
#include "sinewin.h"
#include "unary.h"
@@ -140,7 +140,8 @@ typedef struct cook {
int discarded_packets;
/* transform data */
- FFTContext mdct_ctx;
+ AVTXContext *mdct_ctx;
+ av_tx_fn mdct_fn;
float* mlt_window;
/* VLC data */
@@ -248,6 +249,7 @@ static av_cold int init_cook_mlt(COOKContext *q)
{
int j, ret;
int mlt_size = q->samples_per_channel;
+ const float scale = 1.0 / 32768.0;
if (!(q->mlt_window = av_malloc_array(mlt_size, sizeof(*q->mlt_window))))
return AVERROR(ENOMEM);
@@ -258,11 +260,10 @@ static av_cold int init_cook_mlt(COOKContext *q)
q->mlt_window[j] *= sqrt(2.0 / q->samples_per_channel);
/* Initialize the MDCT. */
- ret = ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size) + 1, 1, 1.0 / 32768.0);
+ ret = av_tx_init(&q->mdct_ctx, &q->mdct_fn, AV_TX_FLOAT_MDCT,
+ 1, mlt_size, &scale, AV_TX_FULL_IMDCT);
if (ret < 0)
return ret;
- av_log(q->avctx, AV_LOG_DEBUG, "MDCT initialized, order = %d.\n",
- av_log2(mlt_size) + 1);
return 0;
}
@@ -336,7 +337,7 @@ static av_cold int cook_decode_close(AVCodecContext *avctx)
av_freep(&q->decoded_bytes_buffer);
/* Free the transform. */
- ff_mdct_end(&q->mdct_ctx);
+ av_tx_uninit(&q->mdct_ctx);
/* Free the VLC tables. */
for (i = 0; i < 13; i++)
@@ -743,7 +744,7 @@ static void imlt_gain(COOKContext *q, float *inbuffer,
int i;
/* Inverse modified discrete cosine transform */
- q->mdct_ctx.imdct_calc(&q->mdct_ctx, q->mono_mdct_output, inbuffer);
+ q->mdct_fn(q->mdct_ctx, q->mono_mdct_output, inbuffer, sizeof(float));
q->imlt_window(q, buffer1, gains_ptr, previous_buffer);
@@ -1298,7 +1299,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
const FFCodec ff_cook_decoder = {
.p.name = "cook",
- .p.long_name = NULL_IF_CONFIG_SMALL("Cook / Cooker / Gecko (RealAudio G2)"),
+ CODEC_LONG_NAME("Cook / Cooker / Gecko (RealAudio G2)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_COOK,
.priv_data_size = sizeof(COOKContext),
@@ -1308,5 +1309,5 @@ const FFCodec ff_cook_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/cpia.c b/libavcodec/cpia.c
index fcf2621e6..bfd270dae 100644
--- a/libavcodec/cpia.c
+++ b/libavcodec/cpia.c
@@ -22,10 +22,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "get_bits.h"
-#include "internal.h"
+#include "decode.h"
#define FRAME_HEADER_SIZE 64
@@ -198,14 +198,6 @@ static av_cold int cpia_decode_init(AVCodecContext *avctx)
// output pixel format
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- /* The default timebase set by the v4l2 demuxer leads to probing which is buggy.
- * Set some reasonable time_base to skip this.
- */
- if (avctx->time_base.num == 1 && avctx->time_base.den == 1000000) {
- avctx->time_base.num = 1;
- avctx->time_base.den = 60;
- }
-
s->frame = av_frame_alloc();
if (!s->frame)
return AVERROR(ENOMEM);
@@ -224,7 +216,7 @@ static av_cold int cpia_decode_end(AVCodecContext *avctx)
const FFCodec ff_cpia_decoder = {
.p.name = "cpia",
- .p.long_name = NULL_IF_CONFIG_SMALL("CPiA video format"),
+ CODEC_LONG_NAME("CPiA video format"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CPIA,
.priv_data_size = sizeof(CpiaContext),
@@ -232,5 +224,4 @@ const FFCodec ff_cpia_decoder = {
.close = cpia_decode_end,
FF_CODEC_DECODE_CB(cpia_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/cri.c b/libavcodec/cri.c
index 728983797..5761152c2 100644
--- a/libavcodec/cri.c
+++ b/libavcodec/cri.c
@@ -32,8 +32,8 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
#include "thread.h"
typedef struct CRIContext {
@@ -317,6 +317,9 @@ skip:
if (!s->data || !s->data_size)
return AVERROR_INVALIDDATA;
+ if (avctx->skip_frame >= AVDISCARD_ALL)
+ return avpkt->size;
+
if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
return ret;
@@ -432,6 +435,7 @@ const FFCodec ff_cri_decoder = {
FF_CODEC_DECODE_CB(cri_decode_frame),
.close = cri_decode_close,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
- .p.long_name = NULL_IF_CONFIG_SMALL("Cintel RAW"),
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP |
+ FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
+ CODEC_LONG_NAME("Cintel RAW"),
};
diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c
index cf74f22e7..688cdffbc 100644
--- a/libavcodec/crystalhd.c
+++ b/libavcodec/crystalhd.c
@@ -329,6 +329,10 @@ static av_cold int init(AVCodecContext *avctx)
av_log(avctx, AV_LOG_VERBOSE, "CrystalHD Init for %s\n",
avctx->codec->name);
+ av_log(avctx, AV_LOG_WARNING, "CrystalHD support is deprecated and will "
+ "be removed. Please contact the developers if you are interested in "
+ "maintaining it.\n");
+
avctx->pix_fmt = AV_PIX_FMT_YUYV422;
/* Initialize the library */
@@ -546,7 +550,7 @@ static inline CopyRet copy_frame(AVCodecContext *avctx,
frame->pts = pkt_pts;
frame->pkt_pos = -1;
- frame->pkt_duration = 0;
+ frame->duration = 0;
frame->pkt_size = -1;
if (!priv->need_second_field) {
@@ -776,7 +780,7 @@ static int crystalhd_receive_frame(AVCodecContext *avctx, AVFrame *frame)
}; \
const FFCodec ff_##x##_crystalhd_decoder = { \
.p.name = #x "_crystalhd", \
- .p.long_name = NULL_IF_CONFIG_SMALL("CrystalHD " #X " decoder"), \
+ CODEC_LONG_NAME("CrystalHD " #X " decoder"), \
.p.type = AVMEDIA_TYPE_VIDEO, \
.p.id = AV_CODEC_ID_##X, \
.priv_data_size = sizeof(CHDContext), \
@@ -787,7 +791,8 @@ static int crystalhd_receive_frame(AVCodecContext *avctx, AVFrame *frame)
.flush = flush, \
.bsfs = bsf_name, \
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
- .caps_internal = FF_CODEC_CAP_SETS_FRAME_PROPS, \
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | \
+ FF_CODEC_CAP_SETS_FRAME_PROPS, \
.p.pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, \
.p.wrapper_name = "crystalhd", \
};
diff --git a/libavcodec/cscd.c b/libavcodec/cscd.c
index ea8471129..b4ed3332a 100644
--- a/libavcodec/cscd.c
+++ b/libavcodec/cscd.c
@@ -18,12 +18,10 @@
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include
-#include
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "libavutil/common.h"
#if CONFIG_ZLIB
@@ -169,7 +167,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
const FFCodec ff_cscd_decoder = {
.p.name = "camstudio",
- .p.long_name = NULL_IF_CONFIG_SMALL("CamStudio"),
+ CODEC_LONG_NAME("CamStudio"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CSCD,
.priv_data_size = sizeof(CamStudioContext),
@@ -177,5 +175,5 @@ const FFCodec ff_cscd_decoder = {
.close = decode_end,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c
index b544b3361..4ba7918b6 100644
--- a/libavcodec/cuviddec.c
+++ b/libavcodec/cuviddec.c
@@ -624,7 +624,7 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame)
* So set pkt_pts and clear all the other pkt_ fields.
*/
frame->pkt_pos = -1;
- frame->pkt_duration = 0;
+ frame->duration = 0;
frame->pkt_size = -1;
frame->interlaced_frame = !parsed_frame.is_deinterlacing && !parsed_frame.dispinfo.progressive_frame;
@@ -1118,7 +1118,7 @@ static const AVCodecHWConfigInternal *const cuvid_hw_configs[] = {
}; \
const FFCodec ff_##x##_cuvid_decoder = { \
.p.name = #x "_cuvid", \
- .p.long_name = NULL_IF_CONFIG_SMALL("Nvidia CUVID " #X " decoder"), \
+ CODEC_LONG_NAME("Nvidia CUVID " #X " decoder"), \
.p.type = AVMEDIA_TYPE_VIDEO, \
.p.id = AV_CODEC_ID_##X, \
.priv_data_size = sizeof(CuvidContext), \
@@ -1129,7 +1129,8 @@ static const AVCodecHWConfigInternal *const cuvid_hw_configs[] = {
.flush = cuvid_flush, \
.bsfs = bsf_name, \
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
- .caps_internal = FF_CODEC_CAP_SETS_FRAME_PROPS, \
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | \
+ FF_CODEC_CAP_SETS_FRAME_PROPS, \
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, \
AV_PIX_FMT_NV12, \
AV_PIX_FMT_P010, \
diff --git a/libavcodec/cyuv.c b/libavcodec/cyuv.c
index 8fa4d1f3a..0765f41ca 100644
--- a/libavcodec/cyuv.c
+++ b/libavcodec/cyuv.c
@@ -30,31 +30,18 @@
#include "config_components.h"
-#include
-#include
#include
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "libavutil/internal.h"
-
-typedef struct CyuvDecodeContext {
- AVCodecContext *avctx;
- int width, height;
-} CyuvDecodeContext;
-
static av_cold int cyuv_decode_init(AVCodecContext *avctx)
{
- CyuvDecodeContext *s = avctx->priv_data;
-
- s->avctx = avctx;
- s->width = avctx->width;
/* width needs to be divisible by 4 for this codec to work */
- if (s->width & 0x3)
+ if (avctx->width & 0x3)
return AVERROR_INVALIDDATA;
- s->height = avctx->height;
return 0;
}
@@ -64,7 +51,6 @@ static int cyuv_decode_frame(AVCodecContext *avctx, AVFrame *frame,
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- CyuvDecodeContext *s=avctx->priv_data;
unsigned char *y_plane;
unsigned char *u_plane;
@@ -82,7 +68,7 @@ static int cyuv_decode_frame(AVCodecContext *avctx, AVFrame *frame,
int stream_ptr;
unsigned char cur_byte;
int pixel_groups;
- int rawsize = s->height * FFALIGN(s->width,2) * 2;
+ int rawsize = avctx->height * FFALIGN(avctx->width,2) * 2;
int ret;
if (avctx->codec_id == AV_CODEC_ID_AURA) {
@@ -93,13 +79,13 @@ static int cyuv_decode_frame(AVCodecContext *avctx, AVFrame *frame,
* followed by (height) lines each with 3 bytes to represent groups
* of 4 pixels. Thus, the total size of the buffer ought to be:
* (3 * 16) + height * (width * 3 / 4) */
- if (buf_size == 48 + s->height * (s->width * 3 / 4)) {
+ if (buf_size == 48 + avctx->height * (avctx->width * 3 / 4)) {
avctx->pix_fmt = AV_PIX_FMT_YUV411P;
} else if(buf_size == rawsize ) {
avctx->pix_fmt = AV_PIX_FMT_UYVY422;
} else {
av_log(avctx, AV_LOG_ERROR, "got a buffer with %d bytes when %d were expected\n",
- buf_size, 48 + s->height * (s->width * 3 / 4));
+ buf_size, 48 + avctx->height * (avctx->width * 3 / 4));
return AVERROR_INVALIDDATA;
}
@@ -114,8 +100,8 @@ static int cyuv_decode_frame(AVCodecContext *avctx, AVFrame *frame,
v_plane = frame->data[2];
if (buf_size == rawsize) {
- int linesize = FFALIGN(s->width,2) * 2;
- y_plane += frame->linesize[0] * s->height;
+ int linesize = FFALIGN(avctx->width, 2) * 2;
+ y_plane += frame->linesize[0] * avctx->height;
for (stream_ptr = 0; stream_ptr < rawsize; stream_ptr += linesize) {
y_plane -= frame->linesize[0];
memcpy(y_plane, buf+stream_ptr, linesize);
@@ -124,10 +110,10 @@ static int cyuv_decode_frame(AVCodecContext *avctx, AVFrame *frame,
/* iterate through each line in the height */
for (y_ptr = 0, u_ptr = 0, v_ptr = 0;
- y_ptr < (s->height * frame->linesize[0]);
- y_ptr += frame->linesize[0] - s->width,
- u_ptr += frame->linesize[1] - s->width / 4,
- v_ptr += frame->linesize[2] - s->width / 4) {
+ y_ptr < (avctx->height * frame->linesize[0]);
+ y_ptr += frame->linesize[0] - avctx->width,
+ u_ptr += frame->linesize[1] - avctx->width / 4,
+ v_ptr += frame->linesize[2] - avctx->width / 4) {
/* reset predictors */
cur_byte = buf[stream_ptr++];
@@ -146,7 +132,7 @@ static int cyuv_decode_frame(AVCodecContext *avctx, AVFrame *frame,
y_plane[y_ptr++] = y_pred;
/* iterate through the remaining pixel groups (4 pixels/group) */
- pixel_groups = s->width / 4 - 1;
+ pixel_groups = avctx->width / 4 - 1;
while (pixel_groups--) {
cur_byte = buf[stream_ptr++];
@@ -179,27 +165,23 @@ static int cyuv_decode_frame(AVCodecContext *avctx, AVFrame *frame,
#if CONFIG_AURA_DECODER
const FFCodec ff_aura_decoder = {
.p.name = "aura",
- .p.long_name = NULL_IF_CONFIG_SMALL("Auravision AURA"),
+ CODEC_LONG_NAME("Auravision AURA"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AURA,
- .priv_data_size = sizeof(CyuvDecodeContext),
.init = cyuv_decode_init,
FF_CODEC_DECODE_CB(cyuv_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
#if CONFIG_CYUV_DECODER
const FFCodec ff_cyuv_decoder = {
.p.name = "cyuv",
- .p.long_name = NULL_IF_CONFIG_SMALL("Creative YUV (CYUV)"),
+ CODEC_LONG_NAME("Creative YUV (CYUV)"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CYUV,
- .priv_data_size = sizeof(CyuvDecodeContext),
.init = cyuv_decode_init,
FF_CODEC_DECODE_CB(cyuv_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
diff --git a/libavcodec/dca_core.c b/libavcodec/dca_core.c
index 2b19807ef..c50d005a5 100644
--- a/libavcodec/dca_core.c
+++ b/libavcodec/dca_core.c
@@ -25,7 +25,7 @@
#include "dcahuff.h"
#include "dcamath.h"
#include "dca_syncwords.h"
-#include "internal.h"
+#include "decode.h"
#if ARCH_ARM
#include "arm/dca.h"
@@ -67,9 +67,9 @@ static const uint8_t block_code_nbits[7] = {
7, 10, 12, 13, 15, 17, 19
};
-static int dca_get_vlc(GetBitContext *s, DCAVLC *v, int i)
+static int dca_get_vlc(GetBitContext *s, const VLC *vlc)
{
- return get_vlc2(s, v->vlc[i].table, v->vlc[i].bits, v->max_depth) + v->offset;
+ return get_vlc2(s, vlc->table, vlc->bits, 2);
}
static void get_array(GetBitContext *s, int32_t *array, int size, int n)
@@ -362,7 +362,8 @@ static inline int parse_scale(DCACoreDecoder *s, int *scale_index, int sel)
// If Huffman code was used, the difference of scales was encoded
if (sel < 5)
- *scale_index += dca_get_vlc(&s->gb, &ff_dca_vlc_scale_factor, sel);
+ *scale_index += get_vlc2(&s->gb, ff_dca_vlc_scale_factor[sel].table,
+ DCA_SCALES_VLC_BITS, 2);
else
*scale_index = get_bits(&s->gb, sel + 1);
@@ -381,7 +382,8 @@ static inline int parse_joint_scale(DCACoreDecoder *s, int sel)
// Absolute value was encoded even when Huffman code was used
if (sel < 5)
- scale_index = dca_get_vlc(&s->gb, &ff_dca_vlc_scale_factor, sel);
+ scale_index = get_vlc2(&s->gb, ff_dca_vlc_scale_factor[sel].table,
+ DCA_SCALES_VLC_BITS, 2);
else
scale_index = get_bits(&s->gb, sel + 1);
@@ -433,7 +435,7 @@ static int parse_subframe_header(DCACoreDecoder *s, int sf,
int abits;
if (sel < 5)
- abits = dca_get_vlc(&s->gb, &ff_dca_vlc_bit_allocation, sel);
+ abits = dca_get_vlc(&s->gb, &ff_dca_vlc_bit_allocation[sel]);
else
abits = get_bits(&s->gb, sel - 1);
@@ -456,7 +458,8 @@ static int parse_subframe_header(DCACoreDecoder *s, int sf,
int sel = s->transition_mode_sel[ch];
for (band = 0; band < s->subband_vq_start[ch]; band++)
if (s->bit_allocation[ch][band])
- s->transition_mode[sf][ch][band] = dca_get_vlc(&s->gb, &ff_dca_vlc_transition_mode, sel);
+ s->transition_mode[sf][ch][band] = get_vlc2(&s->gb, ff_dca_vlc_transition_mode[sel].table,
+ DCA_TMODE_VLC_BITS, 1);
}
}
@@ -567,7 +570,7 @@ static inline int parse_huffman_codes(DCACoreDecoder *s, int32_t *audio, int abi
// Extract Huffman codes from the bit stream
for (i = 0; i < DCA_SUBBAND_SAMPLES; i++)
- audio[i] = dca_get_vlc(&s->gb, &ff_dca_vlc_quant_index[abits - 1], sel);
+ audio[i] = dca_get_vlc(&s->gb, &ff_dca_vlc_quant_index[abits - 1][sel]);
return 1;
}
@@ -767,7 +770,9 @@ static void erase_adpcm_history(DCACoreDecoder *s)
for (band = 0; band < DCA_SUBBANDS; band++)
AV_ZERO128(s->subband_samples[ch][band] - DCA_ADPCM_COEFFS);
+#ifdef FF_COPY_SWAP_ZERO_USES_MMX
emms_c();
+#endif
}
static int alloc_sample_buffer(DCACoreDecoder *s)
@@ -831,7 +836,9 @@ static int parse_frame_data(DCACoreDecoder *s, enum HeaderType header, int xch_b
}
}
+#ifdef FF_COPY_SWAP_ZERO_USES_MMX
emms_c();
+#endif
return 0;
}
@@ -1276,7 +1283,9 @@ static void erase_x96_adpcm_history(DCACoreDecoder *s)
for (band = 0; band < DCA_SUBBANDS_X96; band++)
AV_ZERO128(s->x96_subband_samples[ch][band] - DCA_ADPCM_COEFFS);
+#ifdef FF_COPY_SWAP_ZERO_USES_MMX
emms_c();
+#endif
}
static int alloc_x96_sample_buffer(DCACoreDecoder *s)
@@ -1331,7 +1340,7 @@ static int parse_x96_subframe_header(DCACoreDecoder *s, int xch_base)
for (band = s->x96_subband_start; band < s->nsubbands[ch]; band++) {
// If Huffman code was used, the difference of abits was encoded
if (sel < 7)
- abits += dca_get_vlc(&s->gb, &ff_dca_vlc_quant_index[5 + 2 * s->x96_high_res], sel);
+ abits += dca_get_vlc(&s->gb, &ff_dca_vlc_quant_index[5 + 2 * s->x96_high_res][sel]);
else
abits = get_bits(&s->gb, 3 + s->x96_high_res);
@@ -1506,7 +1515,9 @@ static int parse_x96_frame_data(DCACoreDecoder *s, int exss, int xch_base)
}
}
+#ifdef FF_COPY_SWAP_ZERO_USES_MMX
emms_c();
+#endif
return 0;
}
@@ -2224,7 +2235,8 @@ static int filter_frame_float(DCACoreDecoder *s, AVFrame *frame)
// Filter bank reconstruction
s->dcadsp->sub_qmf_float[x96_synth](
&s->synth,
- &s->imdct[x96_synth],
+ s->imdct[x96_synth],
+ s->imdct_fn[x96_synth],
output_samples[spkr],
s->subband_samples[ch],
ch < x96_nchannels ? s->x96_subband_samples[ch] : NULL,
@@ -2413,16 +2425,24 @@ av_cold void ff_dca_core_flush(DCACoreDecoder *s)
av_cold int ff_dca_core_init(DCACoreDecoder *s)
{
+ int ret;
+ float scale = 1.0f;
+
if (!(s->float_dsp = avpriv_float_dsp_alloc(0)))
return -1;
if (!(s->fixed_dsp = avpriv_alloc_fixed_dsp(0)))
return -1;
ff_dcadct_init(&s->dcadct);
- if (ff_mdct_init(&s->imdct[0], 6, 1, 1.0) < 0)
- return -1;
- if (ff_mdct_init(&s->imdct[1], 7, 1, 1.0) < 0)
- return -1;
+
+ if ((ret = av_tx_init(&s->imdct[0], &s->imdct_fn[0], AV_TX_FLOAT_MDCT,
+ 1, 32, &scale, 0)) < 0)
+ return ret;
+
+ if ((ret = av_tx_init(&s->imdct[1], &s->imdct_fn[1], AV_TX_FLOAT_MDCT,
+ 1, 64, &scale, 0)) < 0)
+ return ret;
+
ff_synth_filter_init(&s->synth);
s->x96_rand = 1;
@@ -2434,8 +2454,8 @@ av_cold void ff_dca_core_close(DCACoreDecoder *s)
av_freep(&s->float_dsp);
av_freep(&s->fixed_dsp);
- ff_mdct_end(&s->imdct[0]);
- ff_mdct_end(&s->imdct[1]);
+ av_tx_uninit(&s->imdct[0]);
+ av_tx_uninit(&s->imdct[1]);
av_freep(&s->subband_buffer);
s->subband_size = 0;
diff --git a/libavcodec/dca_core.h b/libavcodec/dca_core.h
index a01d642e7..347566d6e 100644
--- a/libavcodec/dca_core.h
+++ b/libavcodec/dca_core.h
@@ -24,6 +24,7 @@
#include "libavutil/float_dsp.h"
#include "libavutil/fixed_dsp.h"
#include "libavutil/mem_internal.h"
+#include "libavutil/tx.h"
#include "avcodec.h"
#include "get_bits.h"
@@ -33,7 +34,6 @@
#include "dcadct.h"
#include "dcamath.h"
#include "dcahuff.h"
-#include "fft.h"
#include "synth_filter.h"
#define DCA_CHANNELS 7
@@ -190,7 +190,8 @@ typedef struct DCACoreDecoder {
DCADSPData dcadsp_data[DCA_CHANNELS]; ///< FIR history buffers
DCADSPContext *dcadsp;
DCADCTContext dcadct;
- FFTContext imdct[2];
+ AVTXContext *imdct[2];
+ av_tx_fn imdct_fn[2];
SynthFilterContext synth;
AVFloatDSPContext *float_dsp;
AVFixedDSPContext *fixed_dsp;
diff --git a/libavcodec/dca_lbr.c b/libavcodec/dca_lbr.c
index 2b8594cd7..bef0054db 100644
--- a/libavcodec/dca_lbr.c
+++ b/libavcodec/dca_lbr.c
@@ -28,7 +28,7 @@
#include "dcahuff.h"
#include "dca_syncwords.h"
#include "bytestream.h"
-#include "internal.h"
+#include "decode.h"
#define AMP_MAX 56
@@ -119,7 +119,17 @@ static const uint16_t channel_layouts[7] = {
};
static float cos_tab[256];
-static float lpc_tab[16];
+static const float lpc_tab[16] = {
+ /* lpc_tab[i] = sin((i - 8) * (M_PI / ((i < 8) ? 17 : 15))) */
+ -0.995734176295034521871191178905, -0.961825643172819070408796290732,
+ -0.895163291355062322067016499754, -0.798017227280239503332805112796,
+ -0.673695643646557211712691912426, -0.526432162877355800244607799141,
+ -0.361241666187152948744714596184, -0.183749517816570331574408839621,
+ 0.0, 0.207911690817759337101742284405,
+ 0.406736643075800207753985990341, 0.587785252292473129168705954639,
+ 0.743144825477394235014697048974, 0.866025403784438646763723170753,
+ 0.951056516295153572116439333379, 0.994521895368273336922691944981
+};
av_cold void ff_dca_lbr_init_tables(void)
{
@@ -127,9 +137,6 @@ av_cold void ff_dca_lbr_init_tables(void)
for (i = 0; i < 256; i++)
cos_tab[i] = cos(M_PI * i / 128);
-
- for (i = 0; i < 16; i++)
- lpc_tab[i] = sin((i - 8) * (M_PI / ((i < 8) ? 17 : 15)));
}
static int parse_lfe_24(DCALbrDecoder *s)
@@ -260,11 +267,12 @@ static int parse_lfe_chunk(DCALbrDecoder *s, LBRChunk *chunk)
return AVERROR_INVALIDDATA;
}
-static inline int parse_vlc(GetBitContext *s, VLC *vlc, int max_depth)
+static inline int parse_vlc(GetBitContext *s, const VLC *vlc,
+ int nb_bits, int max_depth)
{
- int v = get_vlc2(s, vlc->table, vlc->bits, max_depth);
- if (v > 0)
- return v - 1;
+ int v = get_vlc2(s, vlc->table, nb_bits, max_depth);
+ if (v >= 0)
+ return v;
// Rare value
return get_bits(s, get_bits(s, 3) + 1);
}
@@ -289,7 +297,7 @@ static int parse_tonal(DCALbrDecoder *s, int group)
return AVERROR_INVALIDDATA;
}
- diff = parse_vlc(&s->gb, &ff_dca_vlc_tnl_grp[group], 2);
+ diff = parse_vlc(&s->gb, &ff_dca_vlc_tnl_grp[group], DCA_TNL_GRP_VLC_BITS, 2);
if (diff >= FF_ARRAY_ELEMS(ff_dca_fst_amp)) {
av_log(s->avctx, AV_LOG_ERROR, "Invalid tonal frequency diff\n");
return AVERROR_INVALIDDATA;
@@ -307,7 +315,7 @@ static int parse_tonal(DCALbrDecoder *s, int group)
// Main channel
main_ch = get_bitsz(&s->gb, ch_nbits);
- main_amp = parse_vlc(&s->gb, &ff_dca_vlc_tnl_scf, 2)
+ main_amp = parse_vlc(&s->gb, &ff_dca_vlc_tnl_scf, DCA_TNL_SCF_VLC_BITS, 2)
+ s->tonal_scf[ff_dca_freq_to_sb[freq >> (7 - group)]]
+ s->limited_range - 2;
amp[main_ch] = main_amp < AMP_MAX ? main_amp : 0;
@@ -318,8 +326,8 @@ static int parse_tonal(DCALbrDecoder *s, int group)
if (ch == main_ch)
continue;
if (get_bits1(&s->gb)) {
- amp[ch] = amp[main_ch] - parse_vlc(&s->gb, &ff_dca_vlc_damp, 1);
- phs[ch] = phs[main_ch] - parse_vlc(&s->gb, &ff_dca_vlc_dph, 1);
+ amp[ch] = amp[main_ch] - parse_vlc(&s->gb, &ff_dca_vlc_damp, DCA_DAMP_VLC_BITS, 1);
+ phs[ch] = phs[main_ch] - parse_vlc(&s->gb, &ff_dca_vlc_dph, DCA_DPH_VLC_BITS, 1);
} else {
amp[ch] = 0;
phs[ch] = 0;
@@ -423,7 +431,7 @@ static int parse_scale_factors(DCALbrDecoder *s, uint8_t *scf)
return 0;
// Initial scale factor
- prev = parse_vlc(&s->gb, &ff_dca_vlc_fst_rsd_amp, 2);
+ prev = parse_vlc(&s->gb, &ff_dca_vlc_fst_rsd_amp, DCA_FST_RSD_VLC_BITS, 2);
for (sf = 0; sf < 7; sf += dist) {
scf[sf] = prev; // Store previous value
@@ -432,7 +440,7 @@ static int parse_scale_factors(DCALbrDecoder *s, uint8_t *scf)
return 0;
// Interpolation distance
- dist = parse_vlc(&s->gb, &ff_dca_vlc_rsd_apprx, 1) + 1;
+ dist = parse_vlc(&s->gb, &ff_dca_vlc_rsd_apprx, DCA_RSD_APPRX_VLC_BITS, 1) + 1;
if (dist > 7 - sf) {
av_log(s->avctx, AV_LOG_ERROR, "Invalid scale factor distance\n");
return AVERROR_INVALIDDATA;
@@ -442,7 +450,7 @@ static int parse_scale_factors(DCALbrDecoder *s, uint8_t *scf)
return 0;
// Final interpolation point
- next = parse_vlc(&s->gb, &ff_dca_vlc_rsd_amp, 2);
+ next = parse_vlc(&s->gb, &ff_dca_vlc_rsd_amp, DCA_RSD_AMP_VLC_BITS, 2);
if (next & 1)
next = prev + ((next + 1) >> 1);
@@ -486,7 +494,7 @@ static int parse_scale_factors(DCALbrDecoder *s, uint8_t *scf)
static int parse_st_code(GetBitContext *s, int min_v)
{
- unsigned int v = parse_vlc(s, &ff_dca_vlc_st_grid, 2) + min_v;
+ unsigned int v = parse_vlc(s, &ff_dca_vlc_st_grid, DCA_ST_GRID_VLC_BITS, 2) + min_v;
if (v & 1)
v = 16 + (v >> 1);
@@ -527,10 +535,10 @@ static int parse_grid_1_chunk(DCALbrDecoder *s, LBRChunk *chunk, int ch1, int ch
// Average values for third grid
for (sb = 0; sb < s->nsubbands - 4; sb++) {
- s->grid_3_avg[ch1][sb] = parse_vlc(&s->gb, &ff_dca_vlc_avg_g3, 2) - 16;
+ s->grid_3_avg[ch1][sb] = parse_vlc(&s->gb, &ff_dca_vlc_avg_g3, DCA_AVG_G3_VLC_BITS, 2) - 16;
if (ch1 != ch2) {
if (sb + 4 < s->min_mono_subband)
- s->grid_3_avg[ch2][sb] = parse_vlc(&s->gb, &ff_dca_vlc_avg_g3, 2) - 16;
+ s->grid_3_avg[ch2][sb] = parse_vlc(&s->gb, &ff_dca_vlc_avg_g3, DCA_AVG_G3_VLC_BITS, 2) - 16;
else
s->grid_3_avg[ch2][sb] = s->grid_3_avg[ch1][sb];
}
@@ -585,7 +593,7 @@ static int parse_grid_1_sec_ch(DCALbrDecoder *s, int ch2)
if (sb + 4 >= s->min_mono_subband) {
if (ensure_bits(&s->gb, 20))
return 0;
- s->grid_3_avg[ch2][sb] = parse_vlc(&s->gb, &ff_dca_vlc_avg_g3, 2) - 16;
+ s->grid_3_avg[ch2][sb] = parse_vlc(&s->gb, &ff_dca_vlc_avg_g3, DCA_AVG_G3_VLC_BITS, 2) - 16;
}
}
@@ -606,7 +614,7 @@ static void parse_grid_3(DCALbrDecoder *s, int ch1, int ch2, int sb, int flag)
for (i = 0; i < 8; i++) {
if (ensure_bits(&s->gb, 20))
return;
- s->grid_3_scf[ch][sb][i] = parse_vlc(&s->gb, &ff_dca_vlc_grid_3, 2) - 16;
+ s->grid_3_scf[ch][sb][i] = parse_vlc(&s->gb, &ff_dca_vlc_grid_3, DCA_GRID_VLC_BITS, 2) - 16;
}
// Flag scale factors for this subband parsed
@@ -889,7 +897,7 @@ static int parse_grid_2(DCALbrDecoder *s, int ch1, int ch2,
for (j = 0; j < 8; j++) {
if (ensure_bits(&s->gb, 20))
break;
- g2_scf[j] = parse_vlc(&s->gb, &ff_dca_vlc_grid_2, 2);
+ g2_scf[j] = parse_vlc(&s->gb, &ff_dca_vlc_grid_2, DCA_GRID_VLC_BITS, 2);
}
} else {
memset(g2_scf, 0, 8);
@@ -945,12 +953,14 @@ static int parse_ts2_chunk(DCALbrDecoder *s, LBRChunk *chunk, int ch1, int ch2)
static int init_sample_rate(DCALbrDecoder *s)
{
double scale = (-1.0 / (1 << 17)) * sqrt(1 << (2 - s->limited_range));
+ float scale_t = scale;
int i, br_per_ch = s->bit_rate_scaled / s->nchannels_total;
int ret;
- ff_mdct_end(&s->imdct);
+ av_tx_uninit(&s->imdct);
- ret = ff_mdct_init(&s->imdct, s->freq_range + 6, 1, scale);
+ ret = av_tx_init(&s->imdct, &s->imdct_fn, AV_TX_FLOAT_MDCT, 1,
+ 1 << (s->freq_range + 5), &scale_t, AV_TX_FULL_IMDCT);
if (ret < 0)
return ret;
@@ -1706,7 +1716,7 @@ static void transform_channel(DCALbrDecoder *s, int ch, float *output)
base_func_synth(s, ch, values[0], sf);
- s->imdct.imdct_calc(&s->imdct, result[0], values[0]);
+ s->imdct_fn(s->imdct, result[0], values[0], sizeof(float));
// Long window and overlap-add
s->fdsp->vector_fmul_add(output, result[0], s->window,
@@ -1826,5 +1836,5 @@ av_cold void ff_dca_lbr_close(DCALbrDecoder *s)
s->ts_size = 0;
av_freep(&s->fdsp);
- ff_mdct_end(&s->imdct);
+ av_tx_uninit(&s->imdct);
}
diff --git a/libavcodec/dca_lbr.h b/libavcodec/dca_lbr.h
index 9e1abec0b..8ff66afcb 100644
--- a/libavcodec/dca_lbr.h
+++ b/libavcodec/dca_lbr.h
@@ -23,13 +23,13 @@
#include "libavutil/float_dsp.h"
#include "libavutil/mem_internal.h"
+#include "libavutil/tx.h"
#include "avcodec.h"
#include "get_bits.h"
#include "dca.h"
#include "dca_exss.h"
#include "dcadsp.h"
-#include "fft.h"
#define DCA_LBR_CHANNELS 6
#define DCA_LBR_CHANNELS_TOTAL 32
@@ -119,7 +119,8 @@ typedef struct DCALbrDecoder {
DCALbrTone tones[DCA_LBR_TONES]; ///< Circular buffer of tones
int ntones; ///< Circular buffer head position
- FFTContext imdct;
+ AVTXContext *imdct;
+ av_tx_fn imdct_fn;
AVFloatDSPContext *fdsp;
DCADSPContext *dcadsp;
} DCALbrDecoder;
diff --git a/libavcodec/dca_xll.c b/libavcodec/dca_xll.c
index 17626b361..fe2c766d9 100644
--- a/libavcodec/dca_xll.c
+++ b/libavcodec/dca_xll.c
@@ -23,7 +23,7 @@
#include "dcadata.h"
#include "dcamath.h"
#include "dca_syncwords.h"
-#include "internal.h"
+#include "decode.h"
#include "unary.h"
static int get_linear(GetBitContext *gb, int n)
diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c
index 498e0c86f..3e3e3053b 100644
--- a/libavcodec/dcadec.c
+++ b/libavcodec/dcadec.c
@@ -412,7 +412,7 @@ static const AVClass dcadec_class = {
const FFCodec ff_dca_decoder = {
.p.name = "dca",
- .p.long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
+ CODEC_LONG_NAME("DCA (DTS Coherent Acoustics)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_DTS,
.priv_data_size = sizeof(DCAContext),
@@ -425,5 +425,5 @@ const FFCodec ff_dca_decoder = {
AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE },
.p.priv_class = &dcadec_class,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_dca_profiles),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/dcadsp.c b/libavcodec/dcadsp.c
index d7e0328c8..5ad1f644f 100644
--- a/libavcodec/dcadsp.c
+++ b/libavcodec/dcadsp.c
@@ -114,7 +114,8 @@ static void lfe_x96_float_c(float *dst, const float *src,
}
static void sub_qmf32_float_c(SynthFilterContext *synth,
- FFTContext *imdct,
+ AVTXContext *imdct,
+ av_tx_fn imdct_fn,
float *pcm_samples,
int32_t **subband_samples_lo,
int32_t **subband_samples_hi,
@@ -137,13 +138,14 @@ static void sub_qmf32_float_c(SynthFilterContext *synth,
// One subband sample generates 32 interpolated ones
synth->synth_filter_float(imdct, hist1, offset,
hist2, filter_coeff,
- pcm_samples, input, scale);
+ pcm_samples, input, scale, imdct_fn);
pcm_samples += 32;
}
}
static void sub_qmf64_float_c(SynthFilterContext *synth,
- FFTContext *imdct,
+ AVTXContext *imdct,
+ av_tx_fn imdct_fn,
float *pcm_samples,
int32_t **subband_samples_lo,
int32_t **subband_samples_hi,
@@ -186,7 +188,7 @@ static void sub_qmf64_float_c(SynthFilterContext *synth,
// One subband sample generates 64 interpolated ones
synth->synth_filter_float_64(imdct, hist1, offset,
hist2, filter_coeff,
- pcm_samples, input, scale);
+ pcm_samples, input, scale, imdct_fn);
pcm_samples += 64;
}
}
diff --git a/libavcodec/dcadsp.h b/libavcodec/dcadsp.h
index 8f2f46707..c29755267 100644
--- a/libavcodec/dcadsp.h
+++ b/libavcodec/dcadsp.h
@@ -22,8 +22,8 @@
#define AVCODEC_DCADSP_H
#include "libavutil/common.h"
+#include "libavutil/tx.h"
-#include "fft.h"
#include "dcadct.h"
#include "synth_filter.h"
@@ -47,7 +47,8 @@ typedef struct DCADSPContext {
float *hist, ptrdiff_t len);
void (*sub_qmf_float[2])(SynthFilterContext *synth,
- FFTContext *imdct,
+ AVTXContext *imdct,
+ av_tx_fn imdct_fn,
float *pcm_samples,
int32_t **subband_samples_lo,
int32_t **subband_samples_hi,
diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c
index aad06adb7..c731d7938 100644
--- a/libavcodec/dcaenc.c
+++ b/libavcodec/dcaenc.c
@@ -21,14 +21,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define FFT_FLOAT 0
-
#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/ffmath.h"
#include "libavutil/mem_internal.h"
#include "libavutil/opt.h"
+#include "libavutil/thread.h"
+#include "libavutil/tx.h"
#include "avcodec.h"
#include "codec_internal.h"
#include "dca.h"
@@ -38,9 +38,6 @@
#include "dcadata.h"
#include "dcaenc.h"
#include "encode.h"
-#include "fft.h"
-#include "internal.h"
-#include "mathops.h"
#include "put_bits.h"
#define MAX_CHANNELS 6
@@ -64,7 +61,8 @@ typedef struct DCAEncContext {
AVClass *class;
PutBitContext pb;
DCAADPCMEncContext adpcm_ctx;
- FFTContext mdct;
+ AVTXContext *mdct;
+ av_tx_fn mdct_fn;
CompressionOptions options;
int frame_size;
int frame_bits;
@@ -161,11 +159,53 @@ static void subband_bufer_free(DCAEncContext *c)
}
}
+static uint16_t bitalloc_12_table[DCA_BITALLOC_12_COUNT][12 + 1][2];
+
+static uint16_t bitalloc_table[DCA_NUM_BITALLOC_CODES][2];
+static const uint16_t (*bitalloc_tables[DCA_CODE_BOOKS][8])[2];
+
+static av_cold void create_enc_table(uint16_t dst[][2], unsigned count,
+ const uint8_t (**src_tablep)[2])
+{
+ const uint8_t (*src_table)[2] = *src_tablep;
+ uint16_t code = 0;
+
+ for (unsigned i = 0; i < count; i++) {
+ unsigned dst_idx = src_table[i][0];
+
+ dst[dst_idx][0] = code >> (16 - src_table[i][1]);
+ dst[dst_idx][1] = src_table[i][1];
+
+ code += 1 << (16 - src_table[i][1]);
+ }
+ *src_tablep += count;
+}
+
+static av_cold void dcaenc_init_static_tables(void)
+{
+ uint16_t (*bitalloc_dst)[2] = bitalloc_table;
+ const uint8_t (*src_table)[2] = ff_dca_vlc_src_tables;
+
+ for (unsigned i = 0; i < DCA_CODE_BOOKS; i++) {
+ for (unsigned j = 0; j < ff_dca_quant_index_group_size[i]; j++) {
+ create_enc_table(bitalloc_dst, ff_dca_bitalloc_sizes[i],
+ &src_table);
+ bitalloc_tables[i][j] = bitalloc_dst - ff_dca_bitalloc_offsets[i];
+ bitalloc_dst += ff_dca_bitalloc_sizes[i];
+ }
+ }
+
+ for (unsigned i = 0; i < DCA_BITALLOC_12_COUNT; i++)
+ create_enc_table(&bitalloc_12_table[i][1], 12, &src_table);
+}
+
static int encode_init(AVCodecContext *avctx)
{
+ static AVOnce init_static_once = AV_ONCE_INIT;
DCAEncContext *c = avctx->priv_data;
AVChannelLayout layout = avctx->ch_layout;
int i, j, k, min_frame_bits;
+ float scale = 1.0f;
int ret;
if ((ret = subband_bufer_alloc(c)) < 0)
@@ -182,26 +222,24 @@ static int encode_init(AVCodecContext *avctx)
if (ff_dcaadpcm_init(&c->adpcm_ctx))
return AVERROR(ENOMEM);
- if (layout.order == AV_CHANNEL_ORDER_UNSPEC) {
- av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The "
- "encoder will guess the layout, but it "
- "might be incorrect.\n");
- av_channel_layout_default(&layout, layout.nb_channels);
- }
-
- if (!av_channel_layout_compare(&layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_MONO))
+ switch (layout.nb_channels) {
+ case 1: /* mono */
c->channel_config = 0;
- else if (!av_channel_layout_compare(&layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO))
+ break;
+ case 2: /* stereo */
c->channel_config = 2;
- else if (!av_channel_layout_compare(&layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_2_2))
+ break;
+ case 4: /* 2.2 */
c->channel_config = 8;
- else if (!av_channel_layout_compare(&layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0))
+ break;
+ case 5: /* 5.0 */
c->channel_config = 9;
- else if (!av_channel_layout_compare(&layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1))
+ break;
+ case 6: /* 5.1 */
c->channel_config = 9;
- else {
- av_log(avctx, AV_LOG_ERROR, "Unsupported channel layout!\n");
- return AVERROR_PATCHWELCOME;
+ break;
+ default:
+ av_assert1(!"impossible channel layout");
}
if (c->lfe_channel) {
@@ -249,7 +287,7 @@ static int encode_init(AVCodecContext *avctx)
avctx->frame_size = 32 * SUBBAND_SAMPLES;
- if ((ret = ff_mdct_init(&c->mdct, 9, 0, 1.0)) < 0)
+ if ((ret = av_tx_init(&c->mdct, &c->mdct_fn, AV_TX_INT32_MDCT, 0, 256, &scale, 0)) < 0)
return ret;
/* Init all tables */
@@ -309,13 +347,14 @@ static int encode_init(AVCodecContext *avctx)
c->band_spectrum_tab[1][j] = (int32_t)(200 * log10(accum));
}
+ ff_thread_once(&init_static_once, dcaenc_init_static_tables);
return 0;
}
static av_cold int encode_close(AVCodecContext *avctx)
{
DCAEncContext *c = avctx->priv_data;
- ff_mdct_end(&c->mdct);
+ av_tx_uninit(&c->mdct);
subband_bufer_free(c);
ff_dcaadpcm_free(&c->adpcm_ctx);
@@ -402,6 +441,39 @@ static void lfe_downsample(DCAEncContext *c, const int32_t *input)
}
}
+static uint32_t dca_vlc_calc_alloc_bits(const int values[], uint8_t n, uint8_t sel)
+{
+ uint32_t sum = 0;
+ for (unsigned i = 0; i < n; i++)
+ sum += bitalloc_12_table[sel][values[i]][1];
+ return sum;
+}
+
+static void dca_vlc_enc_alloc(PutBitContext *pb, const int values[],
+ uint8_t n, uint8_t sel)
+{
+ for (unsigned i = 0; i < n; i++)
+ put_bits(pb, bitalloc_12_table[sel][values[i]][1],
+ bitalloc_12_table[sel][values[i]][0]);
+}
+
+static uint32_t dca_vlc_calc_quant_bits(const int values[], uint8_t n,
+ uint8_t sel, uint8_t table)
+{
+ uint32_t sum = 0;
+ for (unsigned i = 0; i < n; i++)
+ sum += bitalloc_tables[table][sel][values[i]][1];
+ return sum;
+}
+
+static void dca_vlc_enc_quant(PutBitContext *pb, const int values[],
+ uint8_t n, uint8_t sel, uint8_t table)
+{
+ for (unsigned i = 0; i < n; i++)
+ put_bits(pb, bitalloc_tables[table][sel][values[i]][1],
+ bitalloc_tables[table][sel][values[i]][0]);
+}
+
static int32_t get_cb(DCAEncContext *c, int32_t in)
{
int i, res = 0;
@@ -434,7 +506,7 @@ static void calc_power(DCAEncContext *c,
for (i = 0; i < 512; i++)
data[i] = norm__(mul32(in[i], 0x3fffffff - (COS_T(4 * i + 2) >> 1)), 4);
- c->mdct.mdct_calc(&c->mdct, coeff, data);
+ c->mdct_fn(c->mdct, coeff, data, sizeof(int32_t));
for (i = 0; i < 256; i++) {
const int32_t cb = get_cb(c, coeff[i]);
power[i] = add_cb(c, cb, cb);
@@ -697,8 +769,8 @@ static void accumulate_huff_bit_consumption(int abits, int32_t *quantized,
{
uint8_t sel, id = abits - 1;
for (sel = 0; sel < ff_dca_quant_index_group_size[id]; sel++)
- result[sel] += ff_dca_vlc_calc_quant_bits(quantized, SUBBAND_SAMPLES,
- sel, id);
+ result[sel] += dca_vlc_calc_quant_bits(quantized, SUBBAND_SAMPLES,
+ sel, id);
}
static uint32_t set_best_code(uint32_t vlc_bits[DCA_CODE_BOOKS][7],
@@ -759,7 +831,7 @@ static uint32_t set_best_abits_code(int abits[DCAENC_SUBBANDS], int bands,
}
for (i = 0; i < DCA_BITALLOC_12_COUNT; i++) {
- t = ff_dca_vlc_calc_alloc_bits(abits, bands, i);
+ t = dca_vlc_calc_alloc_bits(abits, bands, i);
if (t < best_bits) {
best_bits = t;
best_sel = i;
@@ -1083,8 +1155,8 @@ static void put_subframe_samples(DCAEncContext *c, int ss, int band, int ch)
sel = c->quant_index_sel[ch][c->abits[ch][band] - 1];
// Huffman codes
if (sel < ff_dca_quant_index_group_size[c->abits[ch][band] - 1]) {
- ff_dca_vlc_enc_quant(&c->pb, &c->quantized[ch][band][ss * 8], 8,
- sel, c->abits[ch][band] - 1);
+ dca_vlc_enc_quant(&c->pb, &c->quantized[ch][band][ss * 8], 8,
+ sel, c->abits[ch][band] - 1);
return;
}
@@ -1137,8 +1209,8 @@ static void put_subframe(DCAEncContext *c, int subframe)
put_bits(&c->pb, 5, c->abits[ch][band]);
}
} else {
- ff_dca_vlc_enc_alloc(&c->pb, c->abits[ch], DCAENC_SUBBANDS,
- c->bit_allocation_sel[ch]);
+ dca_vlc_enc_alloc(&c->pb, c->abits[ch], DCAENC_SUBBANDS,
+ c->bit_allocation_sel[ch]);
}
}
@@ -1215,8 +1287,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
flush_put_bits(&c->pb);
memset(put_bits_ptr(&c->pb), 0, put_bytes_left(&c->pb, 0));
- avpkt->pts = frame->pts;
- avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
*got_packet_ptr = 1;
return 0;
}
@@ -1242,26 +1312,22 @@ static const FFCodecDefault defaults[] = {
const FFCodec ff_dca_encoder = {
.p.name = "dca",
- .p.long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
+ CODEC_LONG_NAME("DCA (DTS Coherent Acoustics)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_DTS,
- .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(DCAEncContext),
.init = encode_init,
.close = encode_close,
FF_CODEC_ENCODE_CB(encode_frame),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32,
AV_SAMPLE_FMT_NONE },
.p.supported_samplerates = sample_rates,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
- AV_CH_LAYOUT_STEREO,
- AV_CH_LAYOUT_2_2,
- AV_CH_LAYOUT_5POINT0,
- AV_CH_LAYOUT_5POINT1,
- 0 },
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS(AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO,
+ AV_CH_LAYOUT_2_2, AV_CH_LAYOUT_5POINT0,
+ AV_CH_LAYOUT_5POINT1)
.p.ch_layouts = (const AVChannelLayout[]){
AV_CHANNEL_LAYOUT_MONO,
AV_CHANNEL_LAYOUT_STEREO,
diff --git a/libavcodec/dcahuff.c b/libavcodec/dcahuff.c
index 8d5541f9d..af3a6e532 100644
--- a/libavcodec/dcahuff.c
+++ b/libavcodec/dcahuff.c
@@ -22,971 +22,23 @@
#include
-#include "libavutil/avassert.h"
#include "libavutil/macros.h"
+#include "dcadata.h"
#include "dcahuff.h"
-#include "put_bits.h"
-#define TMODE_COUNT 4
-static const uint8_t tmode_vlc_bits[TMODE_COUNT] = { 3, 3, 3, 2 };
-static const uint16_t tmode_codes[TMODE_COUNT][4] = {
- { 0x0000, 0x0002, 0x0006, 0x0007 },
- { 0x0002, 0x0006, 0x0007, 0x0000 },
- { 0x0006, 0x0007, 0x0000, 0x0002 },
- { 0x0000, 0x0001, 0x0002, 0x0003 }
-};
-
-static const uint8_t tmode_bits[TMODE_COUNT][4] = {
- { 1, 2, 3, 3 },
- { 2, 3, 3, 1 },
- { 3, 3, 1, 2 },
- { 2, 2, 2, 2 }
-};
-
-#define BITALLOC_12_VLC_BITS 9
static const uint8_t bitalloc_12_vlc_bits[DCA_BITALLOC_12_COUNT] = {
9, 7, 7, 9, 9
};
-static const uint16_t bitalloc_12_codes[DCA_BITALLOC_12_COUNT][12] = {
- { 0x0000, 0x0002, 0x0006, 0x000E, 0x001E, 0x003E, 0x00FF, 0x00FE,
- 0x01FB, 0x01FA, 0x01F9, 0x01F8, },
- { 0x0001, 0x0000, 0x0002, 0x000F, 0x000C, 0x001D, 0x0039, 0x0038,
- 0x0037, 0x0036, 0x0035, 0x0034, },
- { 0x0000, 0x0007, 0x0005, 0x0004, 0x0002, 0x000D, 0x000C, 0x0006,
- 0x000F, 0x001D, 0x0039, 0x0038, },
- { 0x0003, 0x0002, 0x0000, 0x0002, 0x0006, 0x000E, 0x001E, 0x003E,
- 0x007E, 0x00FE, 0x01FF, 0x01FE, },
- { 0x0001, 0x0000, 0x0002, 0x0006, 0x000E, 0x003F, 0x003D, 0x007C,
- 0x0079, 0x0078, 0x00FB, 0x00FA, }
-};
-
-static const uint8_t bitalloc_12_bits[DCA_BITALLOC_12_COUNT][12] = {
- { 1, 2, 3, 4, 5, 6, 8, 8, 9, 9, 9, 9 },
- { 1, 2, 3, 5, 5, 6, 7, 7, 7, 7, 7, 7 },
- { 2, 3, 3, 3, 3, 4, 4, 4, 5, 6, 7, 7 },
- { 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10 },
- { 1, 2, 3, 4, 5, 7, 7, 8, 8, 8, 9, 9 }
-};
-
-#define SCALES_COUNT 5
#define SCALES_VLC_BITS 9
-static const uint16_t scales_codes[SCALES_COUNT][129] = {
- { 0x3AB0, 0x3AB2, 0x3AB4, 0x3AB6, 0x3AB8, 0x3ABA, 0x3ABC, 0x3ABE,
- 0x3AC0, 0x3AC2, 0x3AC4, 0x3AC6, 0x3AC8, 0x3ACA, 0x3ACC, 0x3ACE,
- 0x3AD0, 0x3AD2, 0x3AD4, 0x3AD6, 0x3AD8, 0x3ADA, 0x3ADC, 0x3ADE,
- 0x3AE0, 0x3AE2, 0x3AE4, 0x3AE6, 0x3AE8, 0x3AEA, 0x3AEC, 0x3AEE,
- 0x3AF0, 0x3AF2, 0x3AF4, 0x3AF6, 0x3AF8, 0x3AFA, 0x3AFC, 0x3AFE,
- 0x0540, 0x0542, 0x0544, 0x0546, 0x0548, 0x054A, 0x054C, 0x054E,
- 0x0558, 0x055E, 0x02AD, 0x0154, 0x0754, 0x03A8, 0x0056, 0x0028,
- 0x00E8, 0x004A, 0x000B, 0x003B, 0x0013, 0x0003, 0x000F, 0x0005,
- 0x0001, 0x0006, 0x0000, 0x0008, 0x001C, 0x0004, 0x0024, 0x004B,
- 0x00E9, 0x0029, 0x0057, 0x03A9, 0x0755, 0x0155, 0x02AE, 0x055F,
- 0x0559, 0x054F, 0x054D, 0x054B, 0x0549, 0x0547, 0x0545, 0x0543,
- 0x0541, 0x3AFF, 0x3AFD, 0x3AFB, 0x3AF9, 0x3AF7, 0x3AF5, 0x3AF3,
- 0x3AF1, 0x3AEF, 0x3AED, 0x3AEB, 0x3AE9, 0x3AE7, 0x3AE5, 0x3AE3,
- 0x3AE1, 0x3ADF, 0x3ADD, 0x3ADB, 0x3AD9, 0x3AD7, 0x3AD5, 0x3AD3,
- 0x3AD1, 0x3ACF, 0x3ACD, 0x3ACB, 0x3AC9, 0x3AC7, 0x3AC5, 0x3AC3,
- 0x3AC1, 0x3ABF, 0x3ABD, 0x3ABB, 0x3AB9, 0x3AB7, 0x3AB5, 0x3AB3,
- 0x3AB1, },
- { 0x0F60, 0x0F62, 0x0F64, 0x0F66, 0x0F68, 0x0F6A, 0x0F6C, 0x0F6E,
- 0x0F70, 0x0F72, 0x0F74, 0x0F76, 0x0F78, 0x0F7A, 0x0F7C, 0x0F7E,
- 0x0F80, 0x0F82, 0x0F84, 0x0F86, 0x0F88, 0x0F8A, 0x0F8C, 0x0F8E,
- 0x0F90, 0x0F92, 0x0F94, 0x0F96, 0x0F98, 0x0F9A, 0x0F9C, 0x0F9E,
- 0x0FA0, 0x0FA2, 0x0FA4, 0x0FA6, 0x0FA8, 0x0FAA, 0x0FAC, 0x0FAE,
- 0x0FB0, 0x0FB2, 0x0FB4, 0x0FB6, 0x0FB8, 0x0FBA, 0x0FBC, 0x0FBE,
- 0x07A0, 0x07A2, 0x03D2, 0x01EA, 0x00FC, 0x007F, 0x001C, 0x000C,
- 0x0004, 0x0034, 0x0010, 0x001B, 0x0009, 0x000B, 0x000E, 0x0001,
- 0x0003, 0x0002, 0x000F, 0x000C, 0x000A, 0x0000, 0x0011, 0x0035,
- 0x0005, 0x000D, 0x001D, 0x003C, 0x00FD, 0x01EB, 0x03D3, 0x07A3,
- 0x07A1, 0x0FBF, 0x0FBD, 0x0FBB, 0x0FB9, 0x0FB7, 0x0FB5, 0x0FB3,
- 0x0FB1, 0x0FAF, 0x0FAD, 0x0FAB, 0x0FA9, 0x0FA7, 0x0FA5, 0x0FA3,
- 0x0FA1, 0x0F9F, 0x0F9D, 0x0F9B, 0x0F99, 0x0F97, 0x0F95, 0x0F93,
- 0x0F91, 0x0F8F, 0x0F8D, 0x0F8B, 0x0F89, 0x0F87, 0x0F85, 0x0F83,
- 0x0F81, 0x0F7F, 0x0F7D, 0x0F7B, 0x0F79, 0x0F77, 0x0F75, 0x0F73,
- 0x0F71, 0x0F6F, 0x0F6D, 0x0F6B, 0x0F69, 0x0F67, 0x0F65, 0x0F63,
- 0x0F61, },
- { 0x51D0, 0x51D2, 0x51D4, 0x51D6, 0x51D8, 0x51DA, 0x51DC, 0x51DE,
- 0x51E0, 0x51E2, 0x51E4, 0x51E6, 0x51E8, 0x51EA, 0x51EC, 0x51EE,
- 0x51F0, 0x51F2, 0x51F4, 0x51F6, 0x51F8, 0x51FA, 0x51FC, 0x51FE,
- 0x70C0, 0x70C2, 0x70C4, 0x70C6, 0x70C8, 0x70CA, 0x70CC, 0x70CE,
- 0x70EC, 0x10EA, 0x3868, 0x3877, 0x0876, 0x1C35, 0x0434, 0x0A34,
- 0x0E1B, 0x021B, 0x051B, 0x070F, 0x010F, 0x0380, 0x0080, 0x0140,
- 0x01C1, 0x0041, 0x00A1, 0x00E2, 0x0022, 0x0052, 0x0072, 0x0012,
- 0x002A, 0x003A, 0x000A, 0x0016, 0x001E, 0x0006, 0x000C, 0x0000,
- 0x0004, 0x0001, 0x000D, 0x0007, 0x001F, 0x0017, 0x000B, 0x003B,
- 0x002B, 0x0013, 0x0073, 0x0053, 0x0023, 0x00E3, 0x00A2, 0x0042,
- 0x01C2, 0x0141, 0x0081, 0x0381, 0x028C, 0x010C, 0x051C, 0x021C,
- 0x0E1C, 0x0A35, 0x0435, 0x1C3A, 0x0877, 0x0874, 0x3869, 0x10EB,
- 0x70ED, 0x70CF, 0x70CD, 0x70CB, 0x70C9, 0x70C7, 0x70C5, 0x70C3,
- 0x70C1, 0x51FF, 0x51FD, 0x51FB, 0x51F9, 0x51F7, 0x51F5, 0x51F3,
- 0x51F1, 0x51EF, 0x51ED, 0x51EB, 0x51E9, 0x51E7, 0x51E5, 0x51E3,
- 0x51E1, 0x51DF, 0x51DD, 0x51DB, 0x51D9, 0x51D7, 0x51D5, 0x51D3,
- 0x51D1, },
- { 0x6F64, 0x6F66, 0x6F68, 0x6F6A, 0x6F6C, 0x6F6E, 0x6F70, 0x6F72,
- 0x6F74, 0x6F76, 0x6F78, 0x6F7A, 0x6F7C, 0x6F7E, 0x6F80, 0x6F82,
- 0x6F84, 0x6F86, 0x6F88, 0x6F8A, 0x6F8C, 0x6F8E, 0x6F90, 0x6F92,
- 0x6F94, 0x6F96, 0x6F98, 0x6F9A, 0x6F9C, 0x6F9E, 0x6FA0, 0x6FA2,
- 0x6FA4, 0x6FA6, 0x6FA8, 0x6FAA, 0x6FAC, 0x6FAE, 0x6FB0, 0x6FB2,
- 0x6FB4, 0x6FB6, 0x17B4, 0x37DC, 0x0BDB, 0x1BEF, 0x05EE, 0x0DF8,
- 0x02F8, 0x06FD, 0x017D, 0x037F, 0x00BF, 0x0040, 0x00C0, 0x0021,
- 0x0061, 0x0011, 0x0031, 0x0009, 0x0019, 0x0006, 0x000E, 0x0004,
- 0x0000, 0x0005, 0x000F, 0x0007, 0x001A, 0x000A, 0x0036, 0x0016,
- 0x006E, 0x002E, 0x00C1, 0x0041, 0x01BC, 0x00BC, 0x037A, 0x017A,
- 0x02F9, 0x0DF9, 0x05EF, 0x05EC, 0x1BD8, 0x37DD, 0x17B5, 0x6FB7,
- 0x6FB5, 0x6FB3, 0x6FB1, 0x6FAF, 0x6FAD, 0x6FAB, 0x6FA9, 0x6FA7,
- 0x6FA5, 0x6FA3, 0x6FA1, 0x6F9F, 0x6F9D, 0x6F9B, 0x6F99, 0x6F97,
- 0x6F95, 0x6F93, 0x6F91, 0x6F8F, 0x6F8D, 0x6F8B, 0x6F89, 0x6F87,
- 0x6F85, 0x6F83, 0x6F81, 0x6F7F, 0x6F7D, 0x6F7B, 0x6F79, 0x6F77,
- 0x6F75, 0x6F73, 0x6F71, 0x6F6F, 0x6F6D, 0x6F6B, 0x6F69, 0x6F67,
- 0x6F65, },
- { 0xDF54, 0xDF56, 0xDFC8, 0xDFCA, 0xDFCC, 0xDFCE, 0xDFD0, 0xDFD2,
- 0xDFD4, 0xDFD6, 0xDFD8, 0xDFDA, 0xDFDC, 0xDFDE, 0xDFE0, 0xDFE2,
- 0x0FE8, 0x2FEA, 0x6FA8, 0x6FF6, 0x07F5, 0x07F7, 0x37D2, 0x37F9,
- 0x03F8, 0x0BF8, 0x0BFB, 0x1BEB, 0x01FA, 0x05FA, 0x09FA, 0x0DFA,
- 0x0DFF, 0x00FF, 0x02FF, 0x06FB, 0x007C, 0x017C, 0x027C, 0x027F,
- 0x003C, 0x00BC, 0x013C, 0x01BC, 0x001C, 0x005C, 0x009C, 0x00DC,
- 0x000C, 0x002C, 0x004C, 0x006C, 0x0004, 0x0014, 0x0024, 0x0034,
- 0x0000, 0x0008, 0x0010, 0x0018, 0x001E, 0x0002, 0x0006, 0x000A,
- 0x000E, 0x000B, 0x0007, 0x0003, 0x001F, 0x0019, 0x0011, 0x0009,
- 0x0001, 0x0035, 0x0025, 0x0015, 0x0005, 0x006D, 0x004D, 0x002D,
- 0x000D, 0x00DD, 0x009D, 0x005D, 0x001D, 0x01BD, 0x013D, 0x00BD,
- 0x003D, 0x037C, 0x027D, 0x017D, 0x007D, 0x06FC, 0x04FC, 0x02FC,
- 0x00FC, 0x0DFB, 0x09FB, 0x05FB, 0x01FB, 0x1BF8, 0x1BE8, 0x0BF9,
- 0x03F9, 0x37FA, 0x37D3, 0x17F4, 0x07F6, 0x6FF7, 0x6FA9, 0x2FEB,
- 0x0FE9, 0xDFE3, 0xDFE1, 0xDFDF, 0xDFDD, 0xDFDB, 0xDFD9, 0xDFD7,
- 0xDFD5, 0xDFD3, 0xDFD1, 0xDFCF, 0xDFCD, 0xDFCB, 0xDFC9, 0xDF57,
- 0xDF55, }
-};
+static const uint8_t tnl_grp_sizes[] = { 37, 34, 31, 28, 23 };
-static const uint8_t scales_bits[SCALES_COUNT][129] = {
- { 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 12, 11, 11, 10, 9, 8,
- 8, 7, 6, 6, 5, 4, 4, 3,
- 2, 3, 3, 4, 5, 5, 6, 7,
- 8, 8, 9, 10, 11, 11, 12, 13,
- 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, },
- { 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 14, 14, 13, 12, 11, 10, 8, 7,
- 6, 6, 5, 5, 4, 4, 4, 3,
- 3, 3, 4, 4, 4, 4, 5, 6,
- 6, 7, 8, 9, 11, 12, 13, 14,
- 14, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, },
- { 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 14, 14, 14, 13, 13, 12, 12,
- 12, 11, 11, 11, 10, 10, 9, 9,
- 9, 8, 8, 8, 7, 7, 7, 6,
- 6, 6, 5, 5, 5, 4, 4, 3,
- 3, 3, 4, 4, 5, 5, 5, 6,
- 6, 6, 7, 7, 7, 8, 8, 8,
- 9, 9, 9, 10, 10, 10, 11, 11,
- 12, 12, 12, 13, 13, 13, 14, 14,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, },
- { 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 14, 14, 13, 13, 12, 12,
- 11, 11, 10, 10, 9, 8, 8, 7,
- 7, 6, 6, 5, 5, 4, 4, 3,
- 2, 3, 4, 4, 5, 5, 6, 6,
- 7, 7, 8, 8, 9, 9, 10, 10,
- 11, 12, 12, 12, 13, 14, 14, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, },
- { 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 15, 15, 15, 15, 14, 14, 14, 14,
- 13, 13, 13, 13, 12, 12, 12, 12,
- 12, 11, 11, 11, 10, 10, 10, 10,
- 9, 9, 9, 9, 8, 8, 8, 8,
- 7, 7, 7, 7, 6, 6, 6, 6,
- 5, 5, 5, 5, 5, 4, 4, 4,
- 4, 4, 4, 4, 5, 5, 5, 5,
- 5, 6, 6, 6, 6, 7, 7, 7,
- 7, 8, 8, 8, 8, 9, 9, 9,
- 9, 10, 10, 10, 10, 11, 11, 11,
- 11, 12, 12, 12, 12, 13, 13, 13,
- 13, 14, 14, 14, 14, 15, 15, 15,
- 15, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16,
- }
-};
-
-static const uint16_t bitalloc_3_codes[3] = {
- 0x0003, 0x0000, 0x0002,
-};
-
-static const uint8_t bitalloc_3_bits[3] = {
- 2, 1, 2,
-};
-
-static const uint16_t bitalloc_5_codes_a[5] = {
- 0x000F, 0x0006, 0x0000, 0x0002, 0x000E,
-};
-
-static const uint16_t bitalloc_5_codes_b[5] = {
- 0x0007, 0x0001, 0x0002, 0x0000, 0x0006,
-};
-
-static const uint16_t bitalloc_5_codes_c[5] = {
- 0x0007, 0x0005, 0x0000, 0x0004, 0x0006,
-};
-
-static const uint8_t bitalloc_5_bits_a[5] = {
- 4, 3, 1, 2, 4,
-};
-
-static const uint8_t bitalloc_5_bits_b[5] = {
- 3, 2, 2, 2, 3,
-};
-
-static const uint8_t bitalloc_5_bits_c[5] = {
- 3, 3, 1, 3, 3,
-};
-
-static const uint16_t bitalloc_7_codes_a[7] = {
- 0x001E, 0x000E, 0x0005, 0x0000, 0x0006, 0x0004, 0x001F,
-};
-
-static const uint16_t bitalloc_7_codes_b[7] = {
- 0x0014, 0x000B, 0x0000, 0x0003, 0x0001, 0x0004, 0x0015,
-};
-
-static const uint16_t bitalloc_7_codes_c[7] = {
- 0x0000, 0x0002, 0x0001, 0x0003, 0x0002, 0x0003, 0x0001,
-};
-
-static const uint8_t bitalloc_7_bits_a[7] = {
- 5, 4, 3, 1, 3, 3, 5,
-};
-
-static const uint8_t bitalloc_7_bits_b[7] = {
- 5, 4, 2, 2, 2, 3, 5,
-};
-
-static const uint8_t bitalloc_7_bits_c[7] = {
- 4, 4, 2, 2, 2, 4, 4,
-};
-
-static const uint16_t bitalloc_9_codes_a[9] = {
- 0x0030, 0x0019, 0x0009, 0x0005, 0x0000, 0x0007, 0x000D, 0x0008,
- 0x0031,
-};
-
-static const uint16_t bitalloc_9_codes_b[9] = {
- 0x0018, 0x001A, 0x0002, 0x0007, 0x0002, 0x0000, 0x0003, 0x001B,
- 0x0019,
-};
-
-static const uint16_t bitalloc_9_codes_c[9] = {
- 0x001C, 0x000F, 0x0002, 0x0007, 0x0002, 0x0000, 0x0006, 0x0006,
- 0x001D,
-};
-
-static const uint8_t bitalloc_9_bits_a[9] = {
- 6, 5, 4, 3, 1, 3, 4, 4, 6,
-};
-
-static const uint8_t bitalloc_9_bits_b[9] = {
- 5, 5, 3, 3, 2, 2, 3, 5, 5,
-};
-
-static const uint8_t bitalloc_9_bits_c[9] = {
- 6, 5, 3, 3, 2, 2, 3, 4, 6,
-};
-
-static const uint16_t bitalloc_13_codes_a[13] = {
- 0x0070, 0x002E, 0x0039, 0x001D, 0x000C, 0x000F, 0x0000, 0x0004,
- 0x000D, 0x000A, 0x0016, 0x002F, 0x0071,
-};
-
-static const uint16_t bitalloc_13_codes_b[13] = {
- 0x0038, 0x0010, 0x001D, 0x0007, 0x000F, 0x0005, 0x0000, 0x0006,
- 0x0002, 0x0009, 0x0006, 0x0011, 0x0039,
-};
-
-static const uint16_t bitalloc_13_codes_c[13] = {
- 0x0004, 0x001A, 0x0003, 0x000E, 0x0000, 0x0003, 0x0005, 0x0004,
- 0x0002, 0x000F, 0x000C, 0x001B, 0x0005,
-};
-
-static const uint8_t bitalloc_13_bits_a[13] = {
- 7, 6, 6, 5, 4, 4, 1, 3, 4, 4, 5, 6, 7,
-};
-
-static const uint8_t bitalloc_13_bits_b[13] = {
- 6, 5, 5, 4, 4, 3, 2, 3, 3, 4, 4, 5, 6,
-};
-
-static const uint8_t bitalloc_13_bits_c[13] = {
- 5, 5, 4, 4, 3, 3, 3, 3, 3, 4, 4, 5, 5,
-};
-
-static const uint16_t bitalloc_17_codes_a[17] = {
- 0x0154, 0x00AB, 0x002B, 0x000B, 0x0003, 0x000A, 0x0001, 0x0006,
- 0x0001, 0x0007, 0x0004, 0x000B, 0x0000, 0x0004, 0x0014, 0x0054,
- 0x0155,
-};
-
-static const uint16_t bitalloc_17_codes_b[17] = {
- 0x007C, 0x003F, 0x0019, 0x000D, 0x001C, 0x0008, 0x000F, 0x0005,
- 0x0000, 0x0006, 0x0002, 0x0009, 0x001D, 0x000E, 0x001E, 0x0018,
- 0x007D,
-};
-
-static const uint16_t bitalloc_17_codes_c[17] = {
- 0x002C, 0x0017, 0x0005, 0x001C, 0x0003, 0x000A, 0x000F, 0x0003,
- 0x0006, 0x0004, 0x0000, 0x000B, 0x0004, 0x001D, 0x000A, 0x0004,
- 0x002D,
-};
-
-static const uint16_t bitalloc_17_codes_d[17] = {
- 0x0100, 0x0102, 0x0082, 0x0042, 0x0022, 0x0012, 0x000A, 0x0006,
- 0x0000, 0x0007, 0x000B, 0x0013, 0x0023, 0x0043, 0x0083, 0x0103,
- 0x0101,
-};
-
-static const uint16_t bitalloc_17_codes_e[17] = {
- 0x00E8, 0x00F6, 0x0075, 0x0034, 0x003B, 0x001B, 0x001F, 0x0004,
- 0x0000, 0x0005, 0x000C, 0x001C, 0x003C, 0x0035, 0x007A, 0x00F7,
- 0x00E9,
-};
-
-static const uint16_t bitalloc_17_codes_f[17] = {
- 0x0004, 0x0003, 0x001E, 0x0001, 0x0001, 0x000E, 0x0001, 0x0004,
- 0x0006, 0x0005, 0x0002, 0x000F, 0x0006, 0x000E, 0x001F, 0x0000,
- 0x0005,
-};
-
-static const uint16_t bitalloc_17_codes_g[17] = {
- 0x0060, 0x007E, 0x0031, 0x0019, 0x000D, 0x0004, 0x0000, 0x0006,
- 0x0002, 0x0007, 0x0001, 0x0005, 0x000E, 0x001E, 0x003E, 0x007F,
- 0x0061,
-};
-
-static const uint8_t bitalloc_17_bits_a[17] = {
- 12, 11, 9, 7, 5, 4, 3, 3, 2, 3, 3, 4, 4, 6, 8, 10,
- 12,
-};
-
-static const uint8_t bitalloc_17_bits_b[17] = {
- 8, 7, 6, 5, 5, 4, 4, 3, 2, 3, 3, 4, 5, 5, 6, 6,
- 8,
-};
-
-static const uint8_t bitalloc_17_bits_c[17] = {
- 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 4, 4, 5, 5, 5,
- 7,
-};
-
-static const uint8_t bitalloc_17_bits_d[17] = {
- 9, 9, 8, 7, 6, 5, 4, 3, 1, 3, 4, 5, 6, 7, 8, 9,
- 9,
-};
-
-static const uint8_t bitalloc_17_bits_e[17] = {
- 8, 8, 7, 6, 6, 5, 5, 3, 1, 3, 4, 5, 6, 6, 7, 8,
- 8,
-};
-
-static const uint8_t bitalloc_17_bits_f[17] = {
- 8, 7, 6, 5, 4, 4, 3, 3, 3, 3, 3, 4, 4, 5, 6, 6,
- 8,
-};
-
-static const uint8_t bitalloc_17_bits_g[17] = {
- 8, 8, 7, 6, 5, 4, 3, 3, 2, 3, 3, 4, 5, 6, 7, 8,
- 8,
-};
-
-static const uint16_t bitalloc_25_codes_a[25] = {
- 0x2854, 0x142B, 0x050B, 0x0143, 0x00A2, 0x0052, 0x002E, 0x0015,
- 0x0004, 0x000E, 0x0000, 0x0003, 0x0006, 0x0004, 0x0001, 0x000F,
- 0x0005, 0x0016, 0x002F, 0x0053, 0x00A3, 0x00A0, 0x0284, 0x0A14,
- 0x2855,
-};
-
-static const uint16_t bitalloc_25_codes_b[25] = {
- 0x001C, 0x000F, 0x0005, 0x0000, 0x0030, 0x0036, 0x000E, 0x0019,
- 0x0001, 0x0008, 0x000E, 0x0001, 0x0005, 0x0002, 0x000F, 0x0009,
- 0x0006, 0x001A, 0x000F, 0x0037, 0x0031, 0x0001, 0x0006, 0x0004,
- 0x001D,
-};
-
-static const uint16_t bitalloc_25_codes_c[25] = {
- 0x004C, 0x0027, 0x006D, 0x0028, 0x0037, 0x000E, 0x0015, 0x0000,
- 0x0005, 0x0008, 0x000B, 0x000E, 0x0001, 0x000F, 0x000C, 0x0009,
- 0x0006, 0x0001, 0x001A, 0x000F, 0x0008, 0x0029, 0x0012, 0x006C,
- 0x004D,
-};
-
-static const uint16_t bitalloc_25_codes_d[25] = {
- 0x0780, 0x0782, 0x03C2, 0x01E2, 0x00FE, 0x0079, 0x003D, 0x001C,
- 0x000C, 0x0004, 0x0000, 0x0006, 0x0002, 0x0007, 0x0001, 0x0005,
- 0x000D, 0x001D, 0x003E, 0x007E, 0x00FF, 0x01E3, 0x03C3, 0x0783,
- 0x0781,
-};
-
-static const uint16_t bitalloc_25_codes_e[25] = {
- 0x003C, 0x0092, 0x0018, 0x001F, 0x004E, 0x000D, 0x0025, 0x0004,
- 0x0010, 0x0000, 0x000A, 0x0002, 0x0003, 0x0003, 0x000B, 0x0001,
- 0x0011, 0x0005, 0x0026, 0x000E, 0x004F, 0x0048, 0x0019, 0x0093,
- 0x003D,
-};
-
-static const uint16_t bitalloc_25_codes_f[25] = {
- 0x0324, 0x0193, 0x00CE, 0x0065, 0x0024, 0x000C, 0x0013, 0x0004,
- 0x0007, 0x000A, 0x000D, 0x000F, 0x0001, 0x0000, 0x000E, 0x000B,
- 0x0008, 0x0005, 0x0018, 0x000D, 0x0025, 0x0066, 0x00CF, 0x00C8,
- 0x0325,
-};
-
-static const uint16_t bitalloc_25_codes_g[25] = {
- 0x03A8, 0x03AE, 0x01D5, 0x0094, 0x0014, 0x004B, 0x000B, 0x003B,
- 0x0013, 0x0003, 0x000F, 0x0005, 0x0001, 0x0006, 0x0000, 0x0008,
- 0x001C, 0x0004, 0x0024, 0x0074, 0x0015, 0x0095, 0x01D6, 0x03AF,
- 0x03A9,
-};
-
-static const uint8_t bitalloc_25_bits_a[25] = {
- 14, 13, 11, 9, 8, 7, 6, 5, 4, 4, 3, 3, 3, 3, 3, 4,
- 4, 5, 6, 7, 8, 8, 10, 12, 14,
-};
-
-static const uint8_t bitalloc_25_bits_b[25] = {
- 9, 8, 7, 6, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 4, 4,
- 4, 5, 5, 6, 6, 6, 7, 7, 9,
-};
-
-static const uint8_t bitalloc_25_bits_c[25] = {
- 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 4, 4, 3, 4, 4, 4,
- 4, 4, 5, 5, 5, 6, 6, 7, 8,
-};
-
-static const uint8_t bitalloc_25_bits_d[25] = {
- 12, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 3, 2, 3, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 12,
-};
-
-static const uint8_t bitalloc_25_bits_e[25] = {
- 8, 8, 7, 7, 7, 6, 6, 5, 5, 4, 4, 3, 2, 3, 4, 4,
- 5, 5, 6, 6, 7, 7, 7, 8, 8,
-};
-
-static const uint8_t bitalloc_25_bits_f[25] = {
- 10, 9, 8, 7, 6, 5, 5, 4, 4, 4, 4, 4, 3, 3, 4, 4,
- 4, 4, 5, 5, 6, 7, 8, 8, 10,
-};
-
-static const uint8_t bitalloc_25_bits_g[25] = {
- 10, 10, 9, 8, 7, 7, 6, 6, 5, 4, 4, 3, 2, 3, 3, 4,
- 5, 5, 6, 7, 7, 8, 9, 10, 10,
-};
-
-static const uint16_t bitalloc_33_codes_a[33] = {
- 0x1580, 0x1582, 0x0AC2, 0x0562, 0x02B2, 0x015E, 0x00AD, 0x0054,
- 0x001C, 0x003C, 0x000F, 0x001F, 0x0008, 0x000B, 0x000D, 0x0000,
- 0x0002, 0x0001, 0x000E, 0x000C, 0x0009, 0x0006, 0x0014, 0x003D,
- 0x001D, 0x0055, 0x00AE, 0x015F, 0x02B3, 0x0563, 0x0AC3, 0x1583,
- 0x1581,
-};
-
-static const uint16_t bitalloc_33_codes_b[33] = {
- 0x030C, 0x0187, 0x006D, 0x0028, 0x0037, 0x0066, 0x0015, 0x0031,
- 0x0000, 0x000B, 0x0012, 0x001A, 0x0001, 0x0007, 0x000A, 0x000E,
- 0x0001, 0x000F, 0x000B, 0x0008, 0x0004, 0x001B, 0x0013, 0x000C,
- 0x0001, 0x0032, 0x001A, 0x0067, 0x0060, 0x0029, 0x00C2, 0x006C,
- 0x030D,
-};
-
-static const uint16_t bitalloc_33_codes_c[33] = {
- 0x00CC, 0x0067, 0x0005, 0x0070, 0x0003, 0x001A, 0x0039, 0x003F,
- 0x000A, 0x0012, 0x0018, 0x001D, 0x0001, 0x0003, 0x0007, 0x000A,
- 0x000D, 0x000B, 0x0008, 0x0004, 0x0002, 0x001E, 0x0019, 0x0013,
- 0x000B, 0x0000, 0x003E, 0x001B, 0x0018, 0x0071, 0x0032, 0x0004,
- 0x00CD,
-};
-
-static const uint16_t bitalloc_33_codes_d[33] = {
- 0x3AF8, 0x3AFA, 0x1D7E, 0x0EBC, 0x075C, 0x03AC, 0x01D4, 0x0094,
- 0x0014, 0x004B, 0x000B, 0x003B, 0x0013, 0x0003, 0x000F, 0x0005,
- 0x0001, 0x0006, 0x0000, 0x0008, 0x001C, 0x0004, 0x0024, 0x0074,
- 0x0015, 0x0095, 0x01D5, 0x03AD, 0x075D, 0x0EBD, 0x1D7F, 0x3AFB,
- 0x3AF9,
-};
-
-static const uint16_t bitalloc_33_codes_e[33] = {
- 0x01C8, 0x01E6, 0x0064, 0x00E2, 0x00E5, 0x0030, 0x0033, 0x0073,
- 0x007A, 0x001A, 0x003A, 0x0002, 0x001A, 0x001F, 0x0007, 0x0001,
- 0x0002, 0x0002, 0x000C, 0x0000, 0x001B, 0x0003, 0x003B, 0x001B,
- 0x007B, 0x0078, 0x0070, 0x0031, 0x00F2, 0x00E3, 0x0065, 0x01E7,
- 0x01C9,
-};
-
-static const uint16_t bitalloc_33_codes_f[33] = {
- 0x0724, 0x0393, 0x01CE, 0x00E5, 0x002C, 0x0008, 0x0017, 0x003E,
- 0x0005, 0x0014, 0x001D, 0x0000, 0x0003, 0x0006, 0x0008, 0x000B,
- 0x000D, 0x000C, 0x0009, 0x0007, 0x0004, 0x0001, 0x001E, 0x0015,
- 0x000A, 0x003F, 0x0038, 0x0009, 0x002D, 0x00E6, 0x01CF, 0x01C8,
- 0x0725,
-};
-
-static const uint16_t bitalloc_33_codes_g[33] = {
- 0x0284, 0x0042, 0x0140, 0x0143, 0x003E, 0x00BE, 0x0011, 0x0051,
- 0x0009, 0x0029, 0x0005, 0x0015, 0x0000, 0x0008, 0x000E, 0x0002,
- 0x0006, 0x0003, 0x000F, 0x0009, 0x0001, 0x0016, 0x0006, 0x002E,
- 0x000E, 0x005E, 0x001E, 0x00BF, 0x003F, 0x0020, 0x0141, 0x0043,
- 0x0285,
-};
-
-static const uint8_t bitalloc_33_bits_a[33] = {
- 13, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4, 3,
- 3, 3, 4, 4, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13,
- 13,
-};
-
-static const uint8_t bitalloc_33_bits_b[33] = {
- 10, 9, 8, 7, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4,
- 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8,
- 10,
-};
-
-static const uint8_t bitalloc_33_bits_c[33] = {
- 9, 8, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7,
- 9,
-};
-
-static const uint8_t bitalloc_33_bits_d[33] = {
- 14, 14, 13, 12, 11, 10, 9, 8, 7, 7, 6, 6, 5, 4, 4, 3,
- 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14,
- 14,
-};
-
-static const uint8_t bitalloc_33_bits_e[33] = {
- 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 5, 5, 5, 4, 3,
- 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9,
- 9,
-};
-
-static const uint8_t bitalloc_33_bits_f[33] = {
- 11, 10, 9, 8, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 9, 9,
- 11,
-};
-
-static const uint8_t bitalloc_33_bits_g[33] = {
- 10, 9, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 3,
- 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9,
- 10,
-};
-
-static const uint16_t bitalloc_65_codes_a[65] = {
- 0x9E5C, 0x9E5E, 0x4F2C, 0x2794, 0x13C4, 0x1E44, 0x09E3, 0x0F23,
- 0x04F3, 0x0792, 0x027E, 0x03CE, 0x013D, 0x01E5, 0x009C, 0x00CC,
- 0x0040, 0x0058, 0x0067, 0x001E, 0x0021, 0x002D, 0x003D, 0x0007,
- 0x0011, 0x0014, 0x0017, 0x001A, 0x001C, 0x001F, 0x0001, 0x0004,
- 0x0006, 0x0005, 0x0002, 0x0000, 0x001D, 0x001B, 0x0018, 0x0015,
- 0x0012, 0x000E, 0x0006, 0x0032, 0x0026, 0x001F, 0x0078, 0x0059,
- 0x0041, 0x00CD, 0x009D, 0x01E6, 0x013E, 0x03CF, 0x027F, 0x0793,
- 0x0790, 0x04F0, 0x09E4, 0x1E45, 0x13C5, 0x2795, 0x4F2D, 0x9E5F,
- 0x9E5D,
-};
-
-static const uint16_t bitalloc_65_codes_b[65] = {
- 0x0A8C, 0x0547, 0x01B5, 0x0008, 0x00DB, 0x0152, 0x0005, 0x000B,
- 0x008E, 0x00AE, 0x00E4, 0x0003, 0x0037, 0x0039, 0x0055, 0x006C,
- 0x0073, 0x0003, 0x0015, 0x001D, 0x0028, 0x0030, 0x0037, 0x003E,
- 0x0006, 0x000B, 0x000F, 0x0012, 0x0016, 0x0019, 0x001D, 0x0001,
- 0x0004, 0x0002, 0x001E, 0x001A, 0x0017, 0x0013, 0x0010, 0x000C,
- 0x0007, 0x003F, 0x0038, 0x0031, 0x0029, 0x0022, 0x001A, 0x0014,
- 0x0000, 0x006D, 0x0056, 0x0046, 0x0038, 0x0004, 0x00E5, 0x00AF,
- 0x008F, 0x006C, 0x000A, 0x0153, 0x0150, 0x0009, 0x02A2, 0x01B4,
- 0x0A8D,
-};
-
-static const uint16_t bitalloc_65_codes_c[65] = {
- 0x045C, 0x022F, 0x03F5, 0x01BC, 0x01FB, 0x0059, 0x00D0, 0x00DF,
- 0x000A, 0x002D, 0x002F, 0x0052, 0x0069, 0x0078, 0x007F, 0x000A,
- 0x0010, 0x001C, 0x0023, 0x002A, 0x0035, 0x003A, 0x003D, 0x0000,
- 0x0003, 0x0006, 0x0009, 0x000C, 0x000F, 0x0012, 0x0016, 0x0018,
- 0x001C, 0x0019, 0x0017, 0x0013, 0x0010, 0x000D, 0x000A, 0x0007,
- 0x0004, 0x0001, 0x003E, 0x003B, 0x0036, 0x002B, 0x0028, 0x001D,
- 0x0011, 0x000B, 0x0004, 0x0079, 0x006E, 0x0053, 0x0044, 0x002E,
- 0x000B, 0x00FC, 0x00D1, 0x008A, 0x0058, 0x01BD, 0x0116, 0x03F4,
- 0x045D,
-};
-
-static const uint16_t bitalloc_65_codes_d[65] = {
- 0x70B0, 0x70B2, 0x70B4, 0x2852, 0x385B, 0x142E, 0x1C2E, 0x0A15,
- 0x0E14, 0x0214, 0x0704, 0x0104, 0x010B, 0x0383, 0x0083, 0x0143,
- 0x01C3, 0x0043, 0x00A2, 0x00E2, 0x0022, 0x0052, 0x0072, 0x0012,
- 0x002A, 0x003A, 0x000A, 0x0016, 0x001E, 0x0006, 0x000C, 0x0000,
- 0x0004, 0x0001, 0x000D, 0x0007, 0x001F, 0x0017, 0x000B, 0x003B,
- 0x002B, 0x0013, 0x0073, 0x0053, 0x0023, 0x00E3, 0x00A3, 0x00A0,
- 0x0040, 0x01C0, 0x0084, 0x0384, 0x0284, 0x0105, 0x0705, 0x0215,
- 0x0E15, 0x0A16, 0x1C2F, 0x142F, 0x1428, 0x2853, 0x70B5, 0x70B3,
- 0x70B1,
-};
-
-static const uint16_t bitalloc_65_codes_e[65] = {
- 0x032C, 0x0332, 0x0378, 0x037E, 0x008C, 0x014A, 0x0188, 0x0197,
- 0x019E, 0x01BD, 0x0044, 0x0047, 0x00AA, 0x00C5, 0x00CD, 0x00DC,
- 0x001C, 0x002C, 0x0053, 0x0063, 0x0068, 0x0008, 0x000F, 0x0017,
- 0x002B, 0x0035, 0x0005, 0x0009, 0x0016, 0x001C, 0x0006, 0x000F,
- 0x0004, 0x0000, 0x0007, 0x001D, 0x0017, 0x000A, 0x0006, 0x0036,
- 0x0030, 0x0028, 0x0010, 0x0009, 0x0069, 0x0064, 0x0054, 0x002D,
- 0x001D, 0x00DD, 0x00CE, 0x00CA, 0x00AB, 0x00A4, 0x0045, 0x01BE,
- 0x019F, 0x0198, 0x0189, 0x014B, 0x008D, 0x037F, 0x0379, 0x0333,
- 0x032D,
-};
-
-static const uint16_t bitalloc_65_codes_f[65] = {
- 0x0FE0, 0x0FE2, 0x0FE8, 0x0FEA, 0x0FEC, 0x0FEE, 0x0FF0, 0x0FF2,
- 0x0FF4, 0x2FF2, 0x07F2, 0x07FB, 0x03F6, 0x0BFA, 0x0BFD, 0x01FF,
- 0x05FF, 0x02FC, 0x007C, 0x017C, 0x003C, 0x00BC, 0x001C, 0x005C,
- 0x000C, 0x002C, 0x0004, 0x0014, 0x0000, 0x0008, 0x000E, 0x0002,
- 0x0006, 0x0003, 0x000F, 0x0009, 0x0001, 0x0015, 0x0005, 0x002D,
- 0x000D, 0x005D, 0x001D, 0x00BD, 0x003D, 0x017D, 0x007D, 0x02FD,
- 0x00FC, 0x05FC, 0x01FA, 0x0BFB, 0x03F7, 0x17F8, 0x07F3, 0x2FF3,
- 0x0FF5, 0x0FF3, 0x0FF1, 0x0FEF, 0x0FED, 0x0FEB, 0x0FE9, 0x0FE3,
- 0x0FE1,
-};
-
-static const uint16_t bitalloc_65_codes_g[65] = {
- 0x010C, 0x038A, 0x0608, 0x0786, 0x0084, 0x0087, 0x0302, 0x0305,
- 0x0040, 0x00E0, 0x00E3, 0x0183, 0x001E, 0x005E, 0x009E, 0x00DE,
- 0x00F1, 0x0011, 0x0039, 0x0061, 0x0079, 0x0009, 0x001D, 0x0031,
- 0x003D, 0x0005, 0x000F, 0x0019, 0x001F, 0x0003, 0x0006, 0x000A,
- 0x000E, 0x000B, 0x0008, 0x0004, 0x0000, 0x001A, 0x0012, 0x000A,
- 0x0002, 0x0036, 0x0026, 0x0016, 0x0006, 0x006E, 0x004E, 0x002E,
- 0x000E, 0x00DF, 0x009F, 0x005F, 0x001F, 0x01E0, 0x0180, 0x00E1,
- 0x0041, 0x03C2, 0x0303, 0x01C4, 0x0085, 0x0787, 0x0609, 0x038B,
- 0x010D,
-};
-
-static const uint8_t bitalloc_65_bits_a[65] = {
- 16, 16, 15, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8,
- 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 4,
- 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7,
- 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 13, 13, 14, 15, 16,
- 16,
-};
-
-static const uint8_t bitalloc_65_bits_b[65] = {
- 12, 11, 10, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7,
- 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4,
- 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6,
- 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 10, 10,
- 12,
-};
-
-static const uint8_t bitalloc_65_bits_c[65] = {
- 11, 10, 10, 9, 9, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6,
- 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 10,
- 11,
-};
-
-static const uint8_t bitalloc_65_bits_d[65] = {
- 15, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 10, 9, 9,
- 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 3,
- 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8,
- 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 15, 15,
- 15,
-};
-
-static const uint8_t bitalloc_65_bits_e[65] = {
- 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8,
- 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4,
- 3, 3, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7,
- 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10,
- 10,
-};
-
-static const uint8_t bitalloc_65_bits_f[65] = {
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 12, 12, 12, 11,
- 11, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 3,
- 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
- 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14,
-};
-
-static const uint8_t bitalloc_65_bits_g[65] = {
- 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8,
- 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4,
- 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
- 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11,
- 11,
-};
-
-static const uint16_t bitalloc_129_codes_a[129] = {
- 0x0660, 0x0666, 0x06EC, 0x0722, 0x0760, 0x076E, 0x004C, 0x004E,
- 0x00F4, 0x010A, 0x0148, 0x0156, 0x01D4, 0x01F2, 0x0331, 0x0370,
- 0x0377, 0x0396, 0x03B1, 0x0024, 0x0064, 0x007B, 0x008A, 0x00A5,
- 0x00D4, 0x00EB, 0x00FA, 0x019A, 0x01B9, 0x01C9, 0x01D9, 0x0010,
- 0x0030, 0x0033, 0x0043, 0x0053, 0x006B, 0x007A, 0x00CA, 0x00D2,
- 0x00DE, 0x00E6, 0x00F6, 0x000E, 0x001F, 0x0023, 0x002B, 0x003B,
- 0x003F, 0x0067, 0x0070, 0x0077, 0x0005, 0x000D, 0x0012, 0x001B,
- 0x002C, 0x0035, 0x003A, 0x0004, 0x000B, 0x0017, 0x001F, 0x0009,
- 0x0008, 0x000A, 0x0000, 0x0018, 0x000C, 0x0005, 0x003C, 0x0036,
- 0x002D, 0x001C, 0x0013, 0x000E, 0x0006, 0x007A, 0x0071, 0x0068,
- 0x0064, 0x003C, 0x0034, 0x0028, 0x0020, 0x000F, 0x00F7, 0x00E7,
- 0x00DF, 0x00D3, 0x00CB, 0x007B, 0x0074, 0x0054, 0x0044, 0x003C,
- 0x0031, 0x0011, 0x01DA, 0x01CA, 0x01BA, 0x019B, 0x00FB, 0x00F8,
- 0x00D5, 0x00AA, 0x008B, 0x0084, 0x0065, 0x0025, 0x03B6, 0x0397,
- 0x0390, 0x0371, 0x0332, 0x01F3, 0x01D5, 0x0157, 0x0149, 0x010B,
- 0x00F5, 0x004F, 0x004D, 0x076F, 0x0761, 0x0723, 0x06ED, 0x0667,
- 0x0661,
-};
-
-static const uint16_t bitalloc_129_codes_b[129] = {
- 0x29DC, 0x14EF, 0x0455, 0x0E9C, 0x022B, 0x0489, 0x0740, 0x074F,
- 0x0172, 0x0245, 0x0247, 0x030A, 0x03A1, 0x001C, 0x008B, 0x00D6,
- 0x010C, 0x0148, 0x014F, 0x0186, 0x01D1, 0x0008, 0x000F, 0x0046,
- 0x005D, 0x0078, 0x0087, 0x0096, 0x00A5, 0x00BC, 0x00D8, 0x00DE,
- 0x00F6, 0x0005, 0x0014, 0x0024, 0x002F, 0x003A, 0x003D, 0x0049,
- 0x0050, 0x0058, 0x005F, 0x0066, 0x006D, 0x0075, 0x007C, 0x0004,
- 0x000B, 0x0013, 0x0018, 0x001B, 0x001F, 0x0022, 0x0026, 0x002A,
- 0x002D, 0x0031, 0x0034, 0x0038, 0x003B, 0x003F, 0x0003, 0x0006,
- 0x000A, 0x0007, 0x0004, 0x0000, 0x003C, 0x0039, 0x0035, 0x0032,
- 0x002E, 0x002B, 0x0027, 0x0023, 0x0020, 0x001C, 0x0019, 0x0016,
- 0x0010, 0x0005, 0x007D, 0x007A, 0x006E, 0x0067, 0x0060, 0x0059,
- 0x0051, 0x004A, 0x0042, 0x003B, 0x0034, 0x0025, 0x0015, 0x0006,
- 0x00F7, 0x00DF, 0x00D9, 0x00BD, 0x00A6, 0x0097, 0x0090, 0x0079,
- 0x006A, 0x0047, 0x0044, 0x0009, 0x01D2, 0x0187, 0x0184, 0x0149,
- 0x010D, 0x00D7, 0x00B8, 0x001D, 0x03A6, 0x030B, 0x029C, 0x0246,
- 0x0173, 0x0114, 0x0741, 0x053A, 0x0488, 0x0E9D, 0x0A76, 0x0454,
- 0x29DD,
-};
-
-static const uint16_t bitalloc_129_codes_c[129] = {
- 0x0E5C, 0x072F, 0x001D, 0x0724, 0x000F, 0x010D, 0x0324, 0x0393,
- 0x03E9, 0x0080, 0x0087, 0x00FA, 0x0164, 0x0193, 0x01DE, 0x01F5,
- 0x0010, 0x002A, 0x0041, 0x0064, 0x0073, 0x008E, 0x00A4, 0x00B3,
- 0x00D6, 0x00E5, 0x00F4, 0x00FB, 0x0002, 0x0009, 0x0013, 0x001E,
- 0x0026, 0x002C, 0x0033, 0x003F, 0x0041, 0x004C, 0x0053, 0x005E,
- 0x0065, 0x0070, 0x0073, 0x0078, 0x007B, 0x007E, 0x0002, 0x0005,
- 0x0007, 0x000B, 0x000D, 0x0011, 0x0014, 0x0017, 0x001A, 0x001D,
- 0x0021, 0x0024, 0x0027, 0x002A, 0x002D, 0x0030, 0x0033, 0x0036,
- 0x003A, 0x0037, 0x0034, 0x0031, 0x002E, 0x002B, 0x0028, 0x0025,
- 0x0022, 0x001E, 0x001B, 0x0018, 0x0015, 0x0012, 0x000E, 0x000C,
- 0x0008, 0x0006, 0x0003, 0x007F, 0x007C, 0x0079, 0x0076, 0x0071,
- 0x006A, 0x005F, 0x0058, 0x004D, 0x0046, 0x0040, 0x0038, 0x002D,
- 0x0027, 0x001F, 0x0014, 0x0012, 0x0003, 0x0000, 0x00F5, 0x00EE,
- 0x00D7, 0x00C8, 0x00A5, 0x008F, 0x007C, 0x0065, 0x0042, 0x002B,
- 0x0011, 0x0002, 0x01DF, 0x01C8, 0x0165, 0x00FB, 0x00E4, 0x0081,
- 0x0006, 0x03E8, 0x0325, 0x01CA, 0x010C, 0x0725, 0x0396, 0x001C,
- 0x0E5D,
-};
-
-static const uint16_t bitalloc_129_codes_d[129] = {
- 0xA598, 0xA59A, 0xA59C, 0xA59E, 0xC598, 0xE586, 0x3ACC, 0x52CA,
- 0x62CD, 0x0D48, 0x1D67, 0x2978, 0x3167, 0x3966, 0x06A5, 0x0EBC,
- 0x14BD, 0x1CB1, 0x0350, 0x0353, 0x075F, 0x0A5F, 0x0C5E, 0x0E5E,
- 0x01AE, 0x03AD, 0x052D, 0x062D, 0x072D, 0x00D5, 0x01D4, 0x0294,
- 0x0314, 0x0394, 0x0014, 0x0094, 0x0114, 0x0174, 0x01B4, 0x01F4,
- 0x000B, 0x004B, 0x008B, 0x00BB, 0x00DB, 0x00FB, 0x001B, 0x003B,
- 0x0053, 0x0063, 0x0073, 0x0003, 0x0013, 0x0023, 0x002F, 0x0037,
- 0x003F, 0x0007, 0x000F, 0x0015, 0x0019, 0x001D, 0x0001, 0x0005,
- 0x0009, 0x0006, 0x0002, 0x001E, 0x001A, 0x0016, 0x0010, 0x0008,
- 0x0000, 0x0038, 0x0030, 0x0028, 0x001C, 0x000C, 0x007C, 0x006C,
- 0x005C, 0x0044, 0x0024, 0x0004, 0x00E4, 0x00C4, 0x00A4, 0x0074,
- 0x0034, 0x01F5, 0x01B5, 0x0175, 0x0115, 0x0095, 0x0015, 0x0395,
- 0x0315, 0x0295, 0x01D5, 0x00D6, 0x072E, 0x062E, 0x052E, 0x03AE,
- 0x01AF, 0x0E5F, 0x0C5F, 0x0C58, 0x0A58, 0x0758, 0x0351, 0x1CB2,
- 0x18B2, 0x0EBD, 0x0EB2, 0x3967, 0x3960, 0x2979, 0x2964, 0x0D49,
- 0x72C2, 0x52CB, 0x3ACD, 0xE587, 0xC599, 0xA59F, 0xA59D, 0xA59B,
- 0xA599,
-};
-
-static const uint16_t bitalloc_129_codes_e[129] = {
- 0xA13C, 0xC720, 0xA13F, 0xA13E, 0xA13D, 0xE722, 0x5090, 0x6393,
- 0x7392, 0x2849, 0x31CE, 0x39CE, 0x1425, 0x18E5, 0x1CE5, 0x0844,
- 0x0A1C, 0x0C7C, 0x036C, 0x0423, 0x050F, 0x063F, 0x01B7, 0x0216,
- 0x0285, 0x031D, 0x039D, 0x0109, 0x0140, 0x0180, 0x01C8, 0x01CF,
- 0x007A, 0x008A, 0x00A2, 0x00C1, 0x00E5, 0x0014, 0x0037, 0x0043,
- 0x004E, 0x0056, 0x0061, 0x006C, 0x007C, 0x000B, 0x001C, 0x001F,
- 0x0023, 0x0025, 0x0029, 0x002C, 0x002E, 0x0032, 0x0034, 0x0037,
- 0x003A, 0x003C, 0x003F, 0x0001, 0x0003, 0x0006, 0x0008, 0x000A,
- 0x000C, 0x000B, 0x0009, 0x0007, 0x0004, 0x0002, 0x0000, 0x003D,
- 0x003B, 0x0038, 0x0035, 0x0033, 0x002F, 0x002D, 0x002A, 0x0026,
- 0x0024, 0x0020, 0x001D, 0x001A, 0x007D, 0x006D, 0x0062, 0x0057,
- 0x004F, 0x0044, 0x003C, 0x0015, 0x00E6, 0x00C6, 0x00A3, 0x008B,
- 0x007B, 0x006C, 0x01C9, 0x0181, 0x0141, 0x010A, 0x00DA, 0x031E,
- 0x0286, 0x0217, 0x0210, 0x0738, 0x0638, 0x0508, 0x036D, 0x0C7D,
- 0x0A1D, 0x0845, 0x1CE6, 0x18E6, 0x1426, 0x39CF, 0x31CF, 0x284E,
- 0x7393, 0x7390, 0x5091, 0xE723, 0xC724, 0xC725, 0xC722, 0xC723,
- 0xC721,
-};
-
-static const uint16_t bitalloc_129_codes_f[129] = {
- 0x762C, 0x3B17, 0x1555, 0x0608, 0x0AAB, 0x0FF2, 0x0305, 0x0307,
- 0x0763, 0x0046, 0x010C, 0x01BC, 0x02AB, 0x03B6, 0x03FD, 0x0080,
- 0x0087, 0x00DF, 0x0156, 0x01D9, 0x01F8, 0x01FF, 0x002A, 0x0041,
- 0x0061, 0x0094, 0x00D4, 0x00EA, 0x00F2, 0x00FD, 0x0009, 0x000B,
- 0x001A, 0x0026, 0x0031, 0x0040, 0x004B, 0x006B, 0x0073, 0x0077,
- 0x007A, 0x007C, 0x0000, 0x0002, 0x0006, 0x0008, 0x000B, 0x000E,
- 0x0011, 0x0014, 0x0016, 0x0019, 0x001C, 0x001E, 0x0021, 0x0023,
- 0x0026, 0x0028, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0036,
- 0x0038, 0x0037, 0x0034, 0x0032, 0x0030, 0x002E, 0x002C, 0x0029,
- 0x0027, 0x0024, 0x0022, 0x001F, 0x001D, 0x001A, 0x0017, 0x0015,
- 0x0012, 0x000F, 0x000C, 0x0009, 0x0007, 0x0003, 0x0001, 0x007D,
- 0x007B, 0x0078, 0x0074, 0x0072, 0x0054, 0x0041, 0x0036, 0x0027,
- 0x001B, 0x0014, 0x000A, 0x00FE, 0x00F3, 0x00EB, 0x00D5, 0x0095,
- 0x006E, 0x0042, 0x002B, 0x0010, 0x01F9, 0x01DA, 0x0157, 0x0154,
- 0x00C0, 0x0081, 0x0022, 0x03B7, 0x03B0, 0x01BD, 0x010D, 0x0047,
- 0x07F8, 0x0554, 0x0306, 0x0FF3, 0x0EC4, 0x0609, 0x1D8A, 0x1554,
- 0x762D,
-};
-
-static const uint16_t bitalloc_129_codes_g[129] = {
- 0x1E20, 0x1E5E, 0x031C, 0x051A, 0x0718, 0x0916, 0x0B14, 0x0D12,
- 0x0F11, 0x0090, 0x018F, 0x028E, 0x038D, 0x048C, 0x058B, 0x068A,
- 0x0789, 0x0049, 0x00C8, 0x0148, 0x01C7, 0x0247, 0x02C6, 0x0346,
- 0x03C5, 0x0025, 0x0065, 0x00A5, 0x00E4, 0x0124, 0x0164, 0x01A4,
- 0x01E3, 0x0013, 0x0033, 0x0053, 0x0073, 0x0093, 0x00B3, 0x00D3,
- 0x00F3, 0x000A, 0x001A, 0x002A, 0x003A, 0x004A, 0x005A, 0x006A,
- 0x007A, 0x0006, 0x000E, 0x0016, 0x001E, 0x0026, 0x002E, 0x0036,
- 0x003E, 0x0004, 0x0008, 0x000C, 0x0010, 0x0014, 0x0018, 0x001C,
- 0x0000, 0x001D, 0x0019, 0x0015, 0x0011, 0x000D, 0x0009, 0x0005,
- 0x003F, 0x0037, 0x002F, 0x0027, 0x001F, 0x0017, 0x000F, 0x0007,
- 0x007B, 0x006B, 0x005B, 0x004B, 0x003B, 0x002B, 0x001B, 0x000B,
- 0x0008, 0x00F0, 0x00D0, 0x00B0, 0x0090, 0x0070, 0x0050, 0x0030,
- 0x01E4, 0x01A5, 0x0165, 0x0125, 0x00E5, 0x00E2, 0x00A2, 0x0062,
- 0x03CA, 0x0347, 0x02C7, 0x02C4, 0x0244, 0x0149, 0x00C9, 0x00C6,
- 0x0796, 0x068B, 0x0688, 0x048D, 0x048A, 0x028F, 0x028C, 0x0091,
- 0x0F2E, 0x0D13, 0x0B15, 0x0917, 0x0719, 0x051B, 0x031D, 0x1E5F,
- 0x1E21,
-};
-
-static const uint8_t bitalloc_129_bits_a[129] = {
- 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4,
- 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11,
- 11,
-};
-
-static const uint8_t bitalloc_129_bits_b[129] = {
- 14, 13, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9,
- 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5,
- 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
- 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12,
- 14,
-};
-
-static const uint8_t bitalloc_129_bits_c[129] = {
- 13, 12, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11,
- 13,
-};
-
-static const uint8_t bitalloc_129_bits_d[129] = {
- 16, 16, 16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13,
- 13, 13, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 10, 10, 10,
- 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7,
- 7, 7, 7, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4,
- 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7,
- 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10,
- 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13,
- 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16,
- 16,
-};
-
-static const uint8_t bitalloc_129_bits_e[129] = {
- 16, 16, 16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12,
- 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9,
- 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,
- 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12,
- 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16,
- 16,
-};
-
-static const uint8_t bitalloc_129_bits_f[129] = {
- 15, 14, 13, 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 10, 10, 9,
- 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
- 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13,
- 15,
-};
-
-static const uint8_t bitalloc_129_bits_g[129] = {
- 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11,
- 11, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9,
- 9, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7,
- 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5,
- 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8,
- 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
- 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 13,
- 13,
-};
-
-static const uint8_t bitalloc_sizes[DCA_CODE_BOOKS] = {
+const uint8_t ff_dca_bitalloc_sizes[DCA_CODE_BOOKS] = {
3, 5, 7, 9, 13, 17, 25, 33, 65, 129
};
-static const int8_t bitalloc_offsets[DCA_CODE_BOOKS] = {
+const int8_t ff_dca_bitalloc_offsets[DCA_CODE_BOOKS] = {
-1, -2, -3, -4, -6, -8, -12, -16, -32, -64
};
@@ -1003,251 +55,723 @@ static const uint8_t bitalloc_maxbits[DCA_CODE_BOOKS][7] = {
{ 9, 9, 9, 9, 9, 9, 9 }
};
-static const uint16_t *const bitalloc_codes[DCA_CODE_BOOKS][8] = {
- { bitalloc_3_codes, NULL },
- { bitalloc_5_codes_a, bitalloc_5_codes_b, bitalloc_5_codes_c, NULL },
- { bitalloc_7_codes_a, bitalloc_7_codes_b, bitalloc_7_codes_c, NULL },
- { bitalloc_9_codes_a, bitalloc_9_codes_b, bitalloc_9_codes_c, NULL },
- { bitalloc_13_codes_a, bitalloc_13_codes_b, bitalloc_13_codes_c, NULL },
- { bitalloc_17_codes_a, bitalloc_17_codes_b, bitalloc_17_codes_c, bitalloc_17_codes_d,
- bitalloc_17_codes_e, bitalloc_17_codes_f, bitalloc_17_codes_g, NULL },
- { bitalloc_25_codes_a, bitalloc_25_codes_b, bitalloc_25_codes_c, bitalloc_25_codes_d,
- bitalloc_25_codes_e, bitalloc_25_codes_f, bitalloc_25_codes_g, NULL },
- { bitalloc_33_codes_a, bitalloc_33_codes_b, bitalloc_33_codes_c, bitalloc_33_codes_d,
- bitalloc_33_codes_e, bitalloc_33_codes_f, bitalloc_33_codes_g, NULL },
- { bitalloc_65_codes_a, bitalloc_65_codes_b, bitalloc_65_codes_c, bitalloc_65_codes_d,
- bitalloc_65_codes_e, bitalloc_65_codes_f, bitalloc_65_codes_g, NULL },
- { bitalloc_129_codes_a, bitalloc_129_codes_b, bitalloc_129_codes_c, bitalloc_129_codes_d,
- bitalloc_129_codes_e, bitalloc_129_codes_f, bitalloc_129_codes_g, NULL }
+const uint8_t ff_dca_vlc_src_tables[][2] = {
+ /* bitalloc_3 - 3 entries */
+ { 1, 1 }, { 2, 2 }, { 0, 2 },
+ /* bitalloc_5_a - 5 entries */
+ { 2, 1 }, { 3, 2 }, { 1, 3 }, { 4, 4 }, { 0, 4 },
+ /* bitalloc_5_b - 5 entries */
+ { 3, 2 }, { 1, 2 }, { 2, 2 }, { 4, 3 }, { 0, 3 },
+ /* bitalloc_5_c - 5 entries */
+ { 2, 1 }, { 3, 3 }, { 1, 3 }, { 4, 3 }, { 0, 3 },
+ /* bitalloc_7_a - 7 entries */
+ { 3, 1 }, { 5, 3 }, { 2, 3 }, { 4, 3 }, { 1, 4 },
+ { 0, 5 }, { 6, 5 },
+ /* bitalloc_7_b - 7 entries */
+ { 2, 2 }, { 4, 2 }, { 5, 3 }, { 0, 5 }, { 6, 5 },
+ { 1, 4 }, { 3, 2 },
+ /* bitalloc_7_c - 7 entries */
+ { 0, 4 }, { 6, 4 }, { 1, 4 }, { 5, 4 }, { 2, 2 },
+ { 4, 2 }, { 3, 2 },
+ /* bitalloc_9_a - 9 entries */
+ { 4, 1 }, { 7, 4 }, { 2, 4 }, { 3, 3 }, { 0, 6 },
+ { 8, 6 }, { 1, 5 }, { 6, 4 }, { 5, 3 },
+ /* bitalloc_9_b - 9 entries */
+ { 5, 2 }, { 2, 3 }, { 6, 3 }, { 4, 2 }, { 0, 5 },
+ { 8, 5 }, { 1, 5 }, { 7, 5 }, { 3, 3 },
+ /* bitalloc_9_c - 9 entries */
+ { 5, 2 }, { 2, 3 }, { 7, 4 }, { 0, 6 }, { 8, 6 },
+ { 1, 5 }, { 4, 2 }, { 6, 3 }, { 3, 3 },
+ /* bitalloc_13_a - 13 entries */
+ { 6, 1 }, { 7, 3 }, { 9, 4 }, { 10, 5 }, { 1, 6 },
+ { 11, 6 }, { 4, 4 }, { 8, 4 }, { 0, 7 }, { 12, 7 },
+ { 2, 6 }, { 3, 5 }, { 5, 4 },
+ /* bitalloc_13_b - 13 entries */
+ { 6, 2 }, { 8, 3 }, { 10, 4 }, { 3, 4 }, { 1, 5 },
+ { 11, 5 }, { 9, 4 }, { 5, 3 }, { 7, 3 }, { 0, 6 },
+ { 12, 6 }, { 2, 5 }, { 4, 4 },
+ /* bitalloc_13_c - 13 entries */
+ { 4, 3 }, { 0, 5 }, { 12, 5 }, { 2, 4 }, { 8, 3 },
+ { 5, 3 }, { 7, 3 }, { 6, 3 }, { 10, 4 }, { 1, 5 },
+ { 11, 5 }, { 3, 4 }, { 9, 4 },
+ /* bitalloc_17_a - 17 entries */
+ { 12, 4 }, { 13, 6 }, { 14, 8 }, { 15, 10 }, { 0, 12 },
+ { 16, 12 }, { 1, 11 }, { 2, 9 }, { 3, 7 }, { 4, 5 },
+ { 6, 3 }, { 8, 2 }, { 10, 3 }, { 5, 4 }, { 11, 4 },
+ { 7, 3 }, { 9, 3 },
+ /* bitalloc_17_b - 17 entries */
+ { 8, 2 }, { 10, 3 }, { 15, 6 }, { 2, 6 }, { 3, 5 },
+ { 13, 5 }, { 14, 6 }, { 0, 8 }, { 16, 8 }, { 1, 7 },
+ { 5, 4 }, { 11, 4 }, { 7, 3 }, { 9, 3 }, { 4, 5 },
+ { 12, 5 }, { 6, 4 },
+ /* bitalloc_17_c - 17 entries */
+ { 10, 3 }, { 15, 5 }, { 2, 5 }, { 4, 4 }, { 12, 4 },
+ { 14, 5 }, { 0, 7 }, { 16, 7 }, { 1, 6 }, { 7, 3 },
+ { 9, 3 }, { 5, 4 }, { 11, 4 }, { 8, 3 }, { 3, 5 },
+ { 13, 5 }, { 6, 4 },
+ /* bitalloc_17_d - 17 entries */
+ { 8, 1 }, { 0, 9 }, { 16, 9 }, { 1, 9 }, { 15, 9 },
+ { 2, 8 }, { 14, 8 }, { 3, 7 }, { 13, 7 }, { 4, 6 },
+ { 12, 6 }, { 5, 5 }, { 11, 5 }, { 6, 4 }, { 10, 4 },
+ { 7, 3 }, { 9, 3 },
+ /* bitalloc_17_e - 17 entries */
+ { 8, 1 }, { 7, 3 }, { 9, 3 }, { 10, 4 }, { 3, 6 },
+ { 13, 6 }, { 5, 5 }, { 11, 5 }, { 0, 8 }, { 16, 8 },
+ { 2, 7 }, { 4, 6 }, { 12, 6 }, { 14, 7 }, { 1, 8 },
+ { 15, 8 }, { 6, 5 },
+ /* bitalloc_17_f - 17 entries */
+ { 15, 6 }, { 0, 8 }, { 16, 8 }, { 1, 7 }, { 3, 5 },
+ { 4, 4 }, { 6, 3 }, { 10, 3 }, { 12, 4 }, { 13, 5 },
+ { 2, 6 }, { 14, 6 }, { 7, 3 }, { 9, 3 }, { 8, 3 },
+ { 5, 4 }, { 11, 4 },
+ /* bitalloc_17_g - 17 entries */
+ { 6, 3 }, { 10, 3 }, { 5, 4 }, { 11, 4 }, { 0, 8 },
+ { 16, 8 }, { 2, 7 }, { 3, 6 }, { 4, 5 }, { 12, 5 },
+ { 13, 6 }, { 14, 7 }, { 1, 8 }, { 15, 8 }, { 8, 2 },
+ { 7, 3 }, { 9, 3 },
+ /* bitalloc_25_a - 25 entries */
+ { 10, 3 }, { 14, 3 }, { 8, 4 }, { 16, 4 }, { 11, 3 },
+ { 13, 3 }, { 21, 8 }, { 22, 10 }, { 23, 12 }, { 0, 14 },
+ { 24, 14 }, { 1, 13 }, { 2, 11 }, { 3, 9 }, { 4, 8 },
+ { 20, 8 }, { 5, 7 }, { 19, 7 }, { 7, 5 }, { 17, 5 },
+ { 6, 6 }, { 18, 6 }, { 12, 3 }, { 9, 4 }, { 15, 4 },
+ /* bitalloc_25_b - 25 entries */
+ { 3, 6 }, { 21, 6 }, { 23, 7 }, { 2, 7 }, { 22, 7 },
+ { 0, 9 }, { 24, 9 }, { 1, 8 }, { 8, 4 }, { 11, 3 },
+ { 13, 3 }, { 16, 4 }, { 6, 5 }, { 18, 5 }, { 9, 4 },
+ { 15, 4 }, { 12, 3 }, { 4, 6 }, { 20, 6 }, { 7, 5 },
+ { 17, 5 }, { 5, 6 }, { 19, 6 }, { 10, 4 }, { 14, 4 },
+ /* bitalloc_25_c - 25 entries */
+ { 7, 4 }, { 17, 4 }, { 12, 3 }, { 20, 5 }, { 22, 6 },
+ { 0, 8 }, { 24, 8 }, { 1, 7 }, { 8, 4 }, { 16, 4 },
+ { 5, 5 }, { 19, 5 }, { 9, 4 }, { 15, 4 }, { 3, 6 },
+ { 21, 6 }, { 6, 5 }, { 10, 4 }, { 14, 4 }, { 18, 5 },
+ { 23, 7 }, { 2, 7 }, { 4, 6 }, { 11, 4 }, { 13, 4 },
+ /* bitalloc_25_d - 25 entries */
+ { 10, 3 }, { 14, 3 }, { 9, 4 }, { 15, 4 }, { 8, 5 },
+ { 16, 5 }, { 7, 6 }, { 17, 6 }, { 0, 12 }, { 24, 12 },
+ { 1, 12 }, { 23, 12 }, { 2, 11 }, { 22, 11 }, { 3, 10 },
+ { 21, 10 }, { 5, 8 }, { 6, 7 }, { 18, 7 }, { 19, 8 },
+ { 4, 9 }, { 20, 9 }, { 12, 2 }, { 11, 3 }, { 13, 3 },
+ /* bitalloc_25_e - 25 entries */
+ { 9, 4 }, { 15, 4 }, { 7, 5 }, { 17, 5 }, { 2, 7 },
+ { 22, 7 }, { 5, 6 }, { 19, 6 }, { 0, 8 }, { 24, 8 },
+ { 3, 7 }, { 11, 3 }, { 13, 3 }, { 8, 5 }, { 16, 5 },
+ { 21, 7 }, { 1, 8 }, { 23, 8 }, { 6, 6 }, { 18, 6 },
+ { 4, 7 }, { 20, 7 }, { 10, 4 }, { 14, 4 }, { 12, 2 },
+ /* bitalloc_25_f - 25 entries */
+ { 13, 3 }, { 12, 3 }, { 7, 4 }, { 17, 4 }, { 5, 5 },
+ { 19, 5 }, { 8, 4 }, { 16, 4 }, { 4, 6 }, { 20, 6 },
+ { 6, 5 }, { 9, 4 }, { 15, 4 }, { 18, 5 }, { 23, 8 },
+ { 0, 10 }, { 24, 10 }, { 1, 9 }, { 3, 7 }, { 21, 7 },
+ { 2, 8 }, { 22, 8 }, { 10, 4 }, { 14, 4 }, { 11, 4 },
+ /* bitalloc_25_g - 25 entries */
+ { 14, 3 }, { 17, 5 }, { 4, 7 }, { 20, 7 }, { 6, 6 },
+ { 9, 4 }, { 12, 2 }, { 15, 4 }, { 18, 6 }, { 3, 8 },
+ { 21, 8 }, { 5, 7 }, { 8, 5 }, { 11, 3 }, { 13, 3 },
+ { 16, 5 }, { 19, 7 }, { 0, 10 }, { 24, 10 }, { 2, 9 },
+ { 22, 9 }, { 1, 10 }, { 23, 10 }, { 7, 6 }, { 10, 4 },
+ /* bitalloc_33_a - 33 entries */
+ { 15, 3 }, { 17, 3 }, { 16, 3 }, { 21, 4 }, { 8, 6 },
+ { 24, 6 }, { 10, 5 }, { 12, 4 }, { 20, 4 }, { 22, 5 },
+ { 7, 7 }, { 25, 7 }, { 0, 13 }, { 32, 13 }, { 1, 13 },
+ { 31, 13 }, { 2, 12 }, { 30, 12 }, { 3, 11 }, { 29, 11 },
+ { 4, 10 }, { 28, 10 }, { 6, 8 }, { 26, 8 }, { 5, 9 },
+ { 27, 9 }, { 13, 4 }, { 19, 4 }, { 14, 4 }, { 18, 4 },
+ { 9, 6 }, { 23, 6 }, { 11, 5 },
+ /* bitalloc_33_b - 33 entries */
+ { 8, 5 }, { 24, 5 }, { 12, 4 }, { 16, 3 }, { 20, 4 },
+ { 3, 7 }, { 29, 7 }, { 6, 6 }, { 9, 5 }, { 23, 5 },
+ { 26, 6 }, { 31, 8 }, { 2, 8 }, { 4, 7 }, { 13, 4 },
+ { 19, 4 }, { 10, 5 }, { 22, 5 }, { 14, 4 }, { 18, 4 },
+ { 28, 7 }, { 30, 8 }, { 0, 10 }, { 32, 10 }, { 1, 9 },
+ { 7, 6 }, { 25, 6 }, { 5, 7 }, { 27, 7 }, { 11, 5 },
+ { 21, 5 }, { 15, 4 }, { 17, 4 },
+ /* bitalloc_33_c - 33 entries */
+ { 25, 5 }, { 31, 7 }, { 2, 7 }, { 4, 6 }, { 12, 4 },
+ { 20, 4 }, { 13, 4 }, { 19, 4 }, { 8, 5 }, { 24, 5 },
+ { 28, 6 }, { 30, 7 }, { 0, 9 }, { 32, 9 }, { 1, 8 },
+ { 5, 6 }, { 27, 6 }, { 14, 4 }, { 18, 4 }, { 9, 5 },
+ { 23, 5 }, { 15, 4 }, { 17, 4 }, { 10, 5 }, { 22, 5 },
+ { 16, 4 }, { 3, 7 }, { 29, 7 }, { 6, 6 }, { 11, 5 },
+ { 21, 5 }, { 26, 6 }, { 7, 6 },
+ /* bitalloc_33_d - 33 entries */
+ { 18, 3 }, { 21, 5 }, { 8, 7 }, { 24, 7 }, { 10, 6 },
+ { 13, 4 }, { 16, 2 }, { 19, 4 }, { 22, 6 }, { 7, 8 },
+ { 25, 8 }, { 9, 7 }, { 12, 5 }, { 15, 3 }, { 17, 3 },
+ { 20, 5 }, { 23, 7 }, { 6, 9 }, { 26, 9 }, { 5, 10 },
+ { 27, 10 }, { 4, 11 }, { 28, 11 }, { 3, 12 }, { 29, 12 },
+ { 0, 14 }, { 32, 14 }, { 1, 14 }, { 31, 14 }, { 2, 13 },
+ { 30, 13 }, { 11, 6 }, { 14, 4 },
+ /* bitalloc_33_e - 33 entries */
+ { 19, 4 }, { 11, 5 }, { 21, 5 }, { 15, 3 }, { 17, 3 },
+ { 5, 7 }, { 27, 7 }, { 2, 8 }, { 30, 8 }, { 6, 7 },
+ { 9, 6 }, { 23, 6 }, { 14, 4 }, { 16, 2 }, { 18, 4 },
+ { 12, 5 }, { 20, 5 }, { 26, 7 }, { 3, 8 }, { 29, 8 },
+ { 0, 9 }, { 32, 9 }, { 4, 8 }, { 7, 7 }, { 10, 6 },
+ { 22, 6 }, { 25, 7 }, { 28, 8 }, { 1, 9 }, { 31, 9 },
+ { 8, 7 }, { 24, 7 }, { 13, 5 },
+ /* bitalloc_33_f - 33 entries */
+ { 11, 4 }, { 21, 4 }, { 5, 6 }, { 27, 6 }, { 8, 5 },
+ { 12, 4 }, { 20, 4 }, { 24, 5 }, { 4, 7 }, { 28, 7 },
+ { 6, 6 }, { 13, 4 }, { 19, 4 }, { 14, 4 }, { 18, 4 },
+ { 9, 5 }, { 23, 5 }, { 15, 4 }, { 17, 4 }, { 16, 4 },
+ { 26, 6 }, { 31, 9 }, { 0, 11 }, { 32, 11 }, { 1, 10 },
+ { 3, 8 }, { 29, 8 }, { 2, 9 }, { 30, 9 }, { 10, 5 },
+ { 22, 5 }, { 7, 6 }, { 25, 6 },
+ /* bitalloc_33_g - 33 entries */
+ { 12, 4 }, { 20, 4 }, { 29, 8 }, { 1, 9 }, { 31, 9 },
+ { 6, 7 }, { 8, 6 }, { 10, 5 }, { 22, 5 }, { 24, 6 },
+ { 26, 7 }, { 4, 8 }, { 28, 8 }, { 15, 3 }, { 17, 3 },
+ { 13, 4 }, { 19, 4 }, { 2, 9 }, { 30, 9 }, { 0, 10 },
+ { 32, 10 }, { 3, 9 }, { 7, 7 }, { 9, 6 }, { 11, 5 },
+ { 21, 5 }, { 23, 6 }, { 25, 7 }, { 5, 8 }, { 27, 8 },
+ { 16, 3 }, { 14, 4 }, { 18, 4 },
+ /* bitalloc_65_a - 65 entries */
+ { 35, 4 }, { 30, 4 }, { 34, 4 }, { 42, 5 }, { 23, 5 },
+ { 31, 4 }, { 33, 4 }, { 32, 4 }, { 41, 5 }, { 19, 6 },
+ { 45, 6 }, { 16, 7 }, { 48, 7 }, { 20, 6 }, { 24, 5 },
+ { 40, 5 }, { 44, 6 }, { 14, 8 }, { 50, 8 }, { 57, 11 },
+ { 4, 13 }, { 60, 13 }, { 6, 12 }, { 58, 12 }, { 3, 14 },
+ { 61, 14 }, { 2, 15 }, { 62, 15 }, { 0, 16 }, { 64, 16 },
+ { 1, 16 }, { 63, 16 }, { 8, 11 }, { 12, 9 }, { 52, 9 },
+ { 10, 10 }, { 54, 10 }, { 25, 5 }, { 39, 5 }, { 17, 7 },
+ { 47, 7 }, { 21, 6 }, { 26, 5 }, { 38, 5 }, { 43, 6 },
+ { 15, 8 }, { 49, 8 }, { 18, 7 }, { 27, 5 }, { 37, 5 },
+ { 28, 5 }, { 36, 5 }, { 46, 7 }, { 56, 11 }, { 5, 13 },
+ { 59, 13 }, { 7, 12 }, { 9, 11 }, { 55, 11 }, { 13, 9 },
+ { 51, 9 }, { 11, 10 }, { 53, 10 }, { 22, 6 }, { 29, 5 },
+ /* bitalloc_65_b - 65 entries */
+ { 48, 6 }, { 3, 9 }, { 61, 9 }, { 6, 8 }, { 11, 7 },
+ { 53, 7 }, { 58, 8 }, { 7, 8 }, { 17, 6 }, { 31, 4 },
+ { 33, 4 }, { 24, 5 }, { 40, 5 }, { 32, 4 }, { 47, 6 },
+ { 18, 6 }, { 25, 5 }, { 39, 5 }, { 46, 6 }, { 57, 8 },
+ { 63, 10 }, { 2, 10 }, { 4, 9 }, { 12, 7 }, { 52, 7 },
+ { 13, 7 }, { 19, 6 }, { 26, 5 }, { 38, 5 }, { 45, 6 },
+ { 51, 7 }, { 8, 8 }, { 56, 8 }, { 27, 5 }, { 37, 5 },
+ { 20, 6 }, { 44, 6 }, { 60, 9 }, { 62, 10 }, { 0, 12 },
+ { 64, 12 }, { 1, 11 }, { 5, 9 }, { 59, 9 }, { 14, 7 },
+ { 50, 7 }, { 9, 8 }, { 55, 8 }, { 28, 5 }, { 36, 5 },
+ { 21, 6 }, { 43, 6 }, { 29, 5 }, { 35, 5 }, { 15, 7 },
+ { 49, 7 }, { 22, 6 }, { 42, 6 }, { 10, 8 }, { 54, 8 },
+ { 16, 7 }, { 30, 5 }, { 34, 5 }, { 23, 6 }, { 41, 6 },
+ /* bitalloc_65_c - 65 entries */
+ { 23, 5 }, { 41, 5 }, { 50, 6 }, { 8, 7 }, { 56, 7 },
+ { 24, 5 }, { 40, 5 }, { 15, 6 }, { 49, 6 }, { 25, 5 },
+ { 39, 5 }, { 16, 6 }, { 48, 6 }, { 26, 5 }, { 38, 5 },
+ { 60, 8 }, { 5, 8 }, { 9, 7 }, { 55, 7 }, { 10, 7 },
+ { 27, 5 }, { 37, 5 }, { 17, 6 }, { 47, 6 }, { 28, 5 },
+ { 36, 5 }, { 54, 7 }, { 59, 8 }, { 62, 9 }, { 0, 11 },
+ { 64, 11 }, { 1, 10 }, { 18, 6 }, { 29, 5 }, { 35, 5 },
+ { 46, 6 }, { 11, 7 }, { 53, 7 }, { 19, 6 }, { 45, 6 },
+ { 30, 5 }, { 34, 5 }, { 31, 5 }, { 33, 5 }, { 6, 8 },
+ { 58, 8 }, { 12, 7 }, { 20, 6 }, { 44, 6 }, { 52, 7 },
+ { 3, 9 }, { 61, 9 }, { 7, 8 }, { 32, 5 }, { 21, 6 },
+ { 43, 6 }, { 13, 7 }, { 51, 7 }, { 22, 6 }, { 42, 6 },
+ { 57, 8 }, { 63, 10 }, { 2, 10 }, { 4, 9 }, { 14, 7 },
+ /* bitalloc_65_d - 65 entries */
+ { 31, 3 }, { 33, 3 }, { 48, 8 }, { 11, 10 }, { 53, 10 },
+ { 14, 9 }, { 50, 9 }, { 9, 11 }, { 55, 11 }, { 12, 10 },
+ { 17, 8 }, { 20, 7 }, { 44, 7 }, { 23, 6 }, { 41, 6 },
+ { 26, 5 }, { 38, 5 }, { 29, 4 }, { 35, 4 }, { 32, 3 },
+ { 47, 8 }, { 52, 10 }, { 60, 13 }, { 3, 14 }, { 61, 14 },
+ { 7, 12 }, { 57, 12 }, { 5, 13 }, { 59, 13 }, { 15, 9 },
+ { 18, 8 }, { 46, 8 }, { 21, 7 }, { 43, 7 }, { 24, 6 },
+ { 40, 6 }, { 27, 5 }, { 37, 5 }, { 30, 4 }, { 34, 4 },
+ { 49, 9 }, { 10, 11 }, { 54, 11 }, { 13, 10 }, { 51, 10 },
+ { 8, 12 }, { 56, 12 }, { 0, 15 }, { 64, 15 }, { 1, 15 },
+ { 63, 15 }, { 2, 15 }, { 62, 15 }, { 4, 14 }, { 6, 13 },
+ { 58, 13 }, { 16, 9 }, { 19, 8 }, { 45, 8 }, { 22, 7 },
+ { 42, 7 }, { 25, 6 }, { 39, 6 }, { 28, 5 }, { 36, 5 },
+ /* bitalloc_65_e - 65 entries */
+ { 33, 3 }, { 21, 6 }, { 43, 6 }, { 26, 5 }, { 38, 5 },
+ { 16, 7 }, { 48, 7 }, { 22, 6 }, { 42, 6 }, { 10, 8 },
+ { 54, 8 }, { 4, 9 }, { 60, 9 }, { 11, 8 }, { 27, 5 },
+ { 37, 5 }, { 17, 7 }, { 47, 7 }, { 23, 6 }, { 30, 4 },
+ { 34, 4 }, { 32, 3 }, { 41, 6 }, { 53, 8 }, { 5, 9 },
+ { 59, 9 }, { 18, 7 }, { 46, 7 }, { 12, 8 }, { 52, 8 },
+ { 24, 6 }, { 28, 5 }, { 36, 5 }, { 40, 6 }, { 6, 9 },
+ { 58, 9 }, { 13, 8 }, { 19, 7 }, { 45, 7 }, { 51, 8 },
+ { 0, 10 }, { 64, 10 }, { 7, 9 }, { 57, 9 }, { 1, 10 },
+ { 63, 10 }, { 14, 8 }, { 50, 8 }, { 8, 9 }, { 56, 9 },
+ { 20, 7 }, { 44, 7 }, { 25, 6 }, { 39, 6 }, { 15, 8 },
+ { 49, 8 }, { 2, 10 }, { 62, 10 }, { 9, 9 }, { 55, 9 },
+ { 3, 10 }, { 61, 10 }, { 29, 5 }, { 35, 5 }, { 31, 4 },
+ /* bitalloc_65_f - 65 entries */
+ { 28, 4 }, { 36, 4 }, { 26, 5 }, { 38, 5 }, { 24, 6 },
+ { 40, 6 }, { 22, 7 }, { 42, 7 }, { 20, 8 }, { 44, 8 },
+ { 18, 9 }, { 46, 9 }, { 48, 10 }, { 50, 11 }, { 12, 12 },
+ { 52, 12 }, { 0, 14 }, { 64, 14 }, { 1, 14 }, { 63, 14 },
+ { 10, 13 }, { 54, 13 }, { 2, 14 }, { 62, 14 }, { 3, 14 },
+ { 61, 14 }, { 4, 14 }, { 60, 14 }, { 5, 14 }, { 59, 14 },
+ { 6, 14 }, { 58, 14 }, { 7, 14 }, { 57, 14 }, { 8, 14 },
+ { 56, 14 }, { 11, 13 }, { 15, 11 }, { 31, 3 }, { 33, 3 },
+ { 29, 4 }, { 35, 4 }, { 27, 5 }, { 37, 5 }, { 25, 6 },
+ { 39, 6 }, { 23, 7 }, { 41, 7 }, { 21, 8 }, { 43, 8 },
+ { 19, 9 }, { 45, 9 }, { 17, 10 }, { 47, 10 }, { 49, 11 },
+ { 13, 12 }, { 51, 12 }, { 53, 13 }, { 9, 14 }, { 55, 14 },
+ { 14, 12 }, { 16, 11 }, { 32, 3 }, { 30, 4 }, { 34, 4 },
+ /* bitalloc_65_g - 65 entries */
+ { 36, 4 }, { 40, 5 }, { 44, 6 }, { 48, 7 }, { 12, 8 },
+ { 52, 8 }, { 8, 9 }, { 56, 9 }, { 4, 10 }, { 60, 10 },
+ { 0, 11 }, { 64, 11 }, { 5, 10 }, { 17, 7 }, { 21, 6 },
+ { 25, 5 }, { 29, 4 }, { 35, 4 }, { 39, 5 }, { 43, 6 },
+ { 47, 7 }, { 13, 8 }, { 51, 8 }, { 30, 4 }, { 9, 9 },
+ { 55, 9 }, { 59, 10 }, { 1, 11 }, { 63, 11 }, { 10, 9 },
+ { 18, 7 }, { 22, 6 }, { 26, 5 }, { 34, 4 }, { 38, 5 },
+ { 42, 6 }, { 46, 7 }, { 14, 8 }, { 50, 8 }, { 31, 4 },
+ { 33, 4 }, { 54, 9 }, { 6, 10 }, { 58, 10 }, { 2, 11 },
+ { 62, 11 }, { 7, 10 }, { 11, 9 }, { 19, 7 }, { 23, 6 },
+ { 27, 5 }, { 37, 5 }, { 41, 6 }, { 45, 7 }, { 15, 8 },
+ { 49, 8 }, { 32, 4 }, { 53, 9 }, { 57, 10 }, { 3, 11 },
+ { 61, 11 }, { 16, 8 }, { 20, 7 }, { 24, 6 }, { 28, 5 },
+ /* bitalloc_129_a - 129 entries */
+ { 66, 4 }, { 31, 8 }, { 97, 8 }, { 19, 9 }, { 109, 9 },
+ { 6, 10 }, { 122, 10 }, { 7, 10 }, { 121, 10 }, { 52, 6 },
+ { 76, 6 }, { 43, 7 }, { 85, 7 }, { 59, 5 }, { 69, 5 },
+ { 32, 8 }, { 96, 8 }, { 20, 9 }, { 108, 9 }, { 33, 8 },
+ { 53, 6 }, { 75, 6 }, { 95, 8 }, { 8, 10 }, { 120, 10 },
+ { 21, 9 }, { 44, 7 }, { 84, 7 }, { 107, 9 }, { 9, 10 },
+ { 119, 10 }, { 34, 8 }, { 94, 8 }, { 22, 9 }, { 106, 9 },
+ { 45, 7 }, { 54, 6 }, { 74, 6 }, { 83, 7 }, { 10, 10 },
+ { 118, 10 }, { 23, 9 }, { 35, 8 }, { 93, 8 }, { 105, 9 },
+ { 11, 10 }, { 117, 10 }, { 46, 7 }, { 60, 5 }, { 68, 5 },
+ { 82, 7 }, { 24, 9 }, { 104, 9 }, { 36, 8 }, { 55, 6 },
+ { 73, 6 }, { 92, 8 }, { 12, 10 }, { 116, 10 }, { 25, 9 },
+ { 47, 7 }, { 81, 7 }, { 37, 8 }, { 91, 8 }, { 103, 9 },
+ { 13, 10 }, { 115, 10 }, { 26, 9 }, { 102, 9 }, { 48, 7 },
+ { 64, 4 }, { 63, 4 }, { 65, 4 }, { 56, 6 }, { 72, 6 },
+ { 61, 5 }, { 67, 5 }, { 80, 7 }, { 38, 8 }, { 90, 8 },
+ { 0, 11 }, { 128, 11 }, { 14, 10 }, { 114, 10 }, { 1, 11 },
+ { 127, 11 }, { 27, 9 }, { 101, 9 }, { 49, 7 }, { 79, 7 },
+ { 39, 8 }, { 89, 8 }, { 57, 6 }, { 71, 6 }, { 15, 10 },
+ { 113, 10 }, { 28, 9 }, { 100, 9 }, { 2, 11 }, { 126, 11 },
+ { 16, 10 }, { 40, 8 }, { 88, 8 }, { 50, 7 }, { 78, 7 },
+ { 112, 10 }, { 3, 11 }, { 125, 11 }, { 29, 9 }, { 99, 9 },
+ { 17, 10 }, { 111, 10 }, { 41, 8 }, { 87, 8 }, { 58, 6 },
+ { 4, 11 }, { 124, 11 }, { 18, 10 }, { 30, 9 }, { 98, 9 },
+ { 110, 10 }, { 5, 11 }, { 123, 11 }, { 51, 7 }, { 70, 6 },
+ { 77, 7 }, { 42, 8 }, { 86, 8 }, { 62, 5 },
+ /* bitalloc_129_b - 129 entries */
+ { 67, 5 }, { 21, 8 }, { 107, 8 }, { 33, 7 }, { 95, 7 },
+ { 13, 9 }, { 115, 9 }, { 22, 8 }, { 47, 6 }, { 81, 6 },
+ { 62, 5 }, { 66, 5 }, { 34, 7 }, { 94, 7 }, { 48, 6 },
+ { 63, 5 }, { 65, 5 }, { 80, 6 }, { 106, 8 }, { 121, 10 },
+ { 127, 12 }, { 2, 12 }, { 4, 11 }, { 14, 9 }, { 23, 8 },
+ { 105, 8 }, { 35, 7 }, { 93, 7 }, { 49, 6 }, { 64, 5 },
+ { 79, 6 }, { 114, 9 }, { 8, 10 }, { 120, 10 }, { 24, 8 },
+ { 36, 7 }, { 50, 6 }, { 78, 6 }, { 92, 7 }, { 104, 8 },
+ { 15, 9 }, { 113, 9 }, { 51, 6 }, { 77, 6 }, { 37, 7 },
+ { 91, 7 }, { 25, 8 }, { 103, 8 }, { 38, 7 }, { 52, 6 },
+ { 76, 6 }, { 90, 7 }, { 16, 9 }, { 112, 9 }, { 26, 8 },
+ { 53, 6 }, { 75, 6 }, { 102, 8 }, { 124, 11 }, { 5, 11 },
+ { 9, 10 }, { 119, 10 }, { 10, 10 }, { 39, 7 }, { 89, 7 },
+ { 27, 8 }, { 101, 8 }, { 54, 6 }, { 74, 6 }, { 40, 7 },
+ { 88, 7 }, { 17, 9 }, { 111, 9 }, { 28, 8 }, { 100, 8 },
+ { 118, 10 }, { 123, 11 }, { 126, 12 }, { 0, 14 }, { 128, 14 },
+ { 1, 13 }, { 18, 9 }, { 55, 6 }, { 73, 6 }, { 41, 7 },
+ { 87, 7 }, { 56, 6 }, { 72, 6 }, { 29, 8 }, { 99, 8 },
+ { 42, 7 }, { 86, 7 }, { 110, 9 }, { 11, 10 }, { 117, 10 },
+ { 19, 9 }, { 109, 9 }, { 57, 6 }, { 71, 6 }, { 43, 7 },
+ { 85, 7 }, { 58, 6 }, { 70, 6 }, { 30, 8 }, { 98, 8 },
+ { 44, 7 }, { 84, 7 }, { 31, 8 }, { 97, 8 }, { 59, 6 },
+ { 69, 6 }, { 6, 11 }, { 122, 11 }, { 12, 10 }, { 20, 9 },
+ { 108, 9 }, { 116, 10 }, { 3, 12 }, { 125, 12 }, { 7, 11 },
+ { 45, 7 }, { 60, 6 }, { 68, 6 }, { 83, 7 }, { 32, 8 },
+ { 96, 8 }, { 46, 7 }, { 82, 7 }, { 61, 6 },
+ /* bitalloc_129_c - 129 entries */
+ { 101, 7 }, { 113, 8 }, { 120, 9 }, { 127, 11 }, { 2, 11 },
+ { 4, 10 }, { 28, 7 }, { 100, 7 }, { 46, 6 }, { 82, 6 },
+ { 16, 8 }, { 112, 8 }, { 29, 7 }, { 47, 6 }, { 81, 6 },
+ { 48, 6 }, { 80, 6 }, { 99, 7 }, { 30, 7 }, { 98, 7 },
+ { 17, 8 }, { 111, 8 }, { 49, 6 }, { 79, 6 }, { 50, 6 },
+ { 78, 6 }, { 31, 7 }, { 97, 7 }, { 9, 9 }, { 119, 9 },
+ { 18, 8 }, { 110, 8 }, { 124, 10 }, { 5, 10 }, { 10, 9 },
+ { 51, 6 }, { 77, 6 }, { 32, 7 }, { 96, 7 }, { 52, 6 },
+ { 76, 6 }, { 33, 7 }, { 95, 7 }, { 53, 6 }, { 75, 6 },
+ { 19, 8 }, { 109, 8 }, { 34, 7 }, { 54, 6 }, { 74, 6 },
+ { 94, 7 }, { 118, 9 }, { 123, 10 }, { 126, 11 }, { 0, 13 },
+ { 128, 13 }, { 1, 12 }, { 20, 8 }, { 55, 6 }, { 73, 6 },
+ { 108, 8 }, { 11, 9 }, { 117, 9 }, { 35, 7 }, { 93, 7 },
+ { 36, 7 }, { 56, 6 }, { 72, 6 }, { 92, 7 }, { 21, 8 },
+ { 107, 8 }, { 57, 6 }, { 71, 6 }, { 37, 7 }, { 91, 7 },
+ { 58, 6 }, { 70, 6 }, { 22, 8 }, { 106, 8 }, { 38, 7 },
+ { 59, 6 }, { 69, 6 }, { 90, 7 }, { 12, 9 }, { 116, 9 },
+ { 23, 8 }, { 60, 6 }, { 68, 6 }, { 39, 7 }, { 89, 7 },
+ { 61, 6 }, { 67, 6 }, { 105, 8 }, { 6, 10 }, { 122, 10 },
+ { 13, 9 }, { 40, 7 }, { 62, 6 }, { 66, 6 }, { 88, 7 },
+ { 24, 8 }, { 104, 8 }, { 63, 6 }, { 65, 6 }, { 41, 7 },
+ { 87, 7 }, { 115, 9 }, { 3, 11 }, { 125, 11 }, { 7, 10 },
+ { 25, 8 }, { 42, 7 }, { 64, 6 }, { 86, 7 }, { 103, 8 },
+ { 14, 9 }, { 114, 9 }, { 43, 7 }, { 85, 7 }, { 26, 8 },
+ { 102, 8 }, { 44, 7 }, { 84, 7 }, { 121, 10 }, { 8, 10 },
+ { 15, 9 }, { 27, 8 }, { 45, 7 }, { 83, 7 },
+ /* bitalloc_129_d - 129 entries */
+ { 72, 5 }, { 83, 7 }, { 34, 9 }, { 94, 9 }, { 40, 8 },
+ { 51, 6 }, { 62, 4 }, { 66, 4 }, { 77, 6 }, { 88, 8 },
+ { 18, 12 }, { 110, 12 }, { 9, 14 }, { 119, 14 }, { 14, 13 },
+ { 19, 12 }, { 29, 10 }, { 99, 10 }, { 24, 11 }, { 104, 11 },
+ { 46, 7 }, { 57, 5 }, { 71, 5 }, { 82, 7 }, { 35, 9 },
+ { 93, 9 }, { 41, 8 }, { 52, 6 }, { 63, 4 }, { 65, 4 },
+ { 76, 6 }, { 87, 8 }, { 30, 10 }, { 98, 10 }, { 109, 12 },
+ { 114, 13 }, { 6, 15 }, { 122, 15 }, { 10, 14 }, { 25, 11 },
+ { 103, 11 }, { 15, 13 }, { 113, 13 }, { 20, 12 }, { 47, 7 },
+ { 58, 5 }, { 70, 5 }, { 81, 7 }, { 36, 9 }, { 92, 9 },
+ { 42, 8 }, { 53, 6 }, { 64, 4 }, { 75, 6 }, { 86, 8 },
+ { 31, 10 }, { 97, 10 }, { 108, 12 }, { 118, 14 }, { 7, 15 },
+ { 121, 15 }, { 0, 16 }, { 128, 16 }, { 1, 16 }, { 127, 16 },
+ { 2, 16 }, { 126, 16 }, { 3, 16 }, { 125, 16 }, { 26, 11 },
+ { 102, 11 }, { 11, 14 }, { 117, 14 }, { 16, 13 }, { 21, 12 },
+ { 48, 7 }, { 59, 5 }, { 69, 5 }, { 80, 7 }, { 37, 9 },
+ { 91, 9 }, { 43, 8 }, { 54, 6 }, { 74, 6 }, { 85, 8 },
+ { 32, 10 }, { 96, 10 }, { 107, 12 }, { 112, 13 }, { 4, 16 },
+ { 124, 16 }, { 8, 15 }, { 12, 14 }, { 27, 11 }, { 101, 11 },
+ { 22, 12 }, { 106, 12 }, { 49, 7 }, { 60, 5 }, { 68, 5 },
+ { 79, 7 }, { 38, 9 }, { 90, 9 }, { 44, 8 }, { 55, 6 },
+ { 73, 6 }, { 84, 8 }, { 33, 10 }, { 95, 10 }, { 116, 14 },
+ { 120, 15 }, { 5, 16 }, { 123, 16 }, { 17, 13 }, { 111, 13 },
+ { 13, 14 }, { 115, 14 }, { 28, 11 }, { 100, 11 }, { 23, 12 },
+ { 105, 12 }, { 50, 7 }, { 61, 5 }, { 67, 5 }, { 78, 7 },
+ { 39, 9 }, { 89, 9 }, { 45, 8 }, { 56, 6 },
+ /* bitalloc_129_e - 129 entries */
+ { 70, 5 }, { 59, 5 }, { 69, 5 }, { 60, 5 }, { 68, 5 },
+ { 37, 7 }, { 91, 7 }, { 45, 6 }, { 61, 5 }, { 67, 5 },
+ { 62, 5 }, { 66, 5 }, { 63, 5 }, { 65, 5 }, { 64, 5 },
+ { 83, 6 }, { 97, 8 }, { 102, 9 }, { 18, 11 }, { 110, 11 },
+ { 22, 10 }, { 38, 7 }, { 46, 6 }, { 82, 6 }, { 90, 7 },
+ { 32, 8 }, { 96, 8 }, { 47, 6 }, { 81, 6 }, { 106, 10 },
+ { 15, 12 }, { 113, 12 }, { 19, 11 }, { 27, 9 }, { 101, 9 },
+ { 23, 10 }, { 105, 10 }, { 39, 7 }, { 89, 7 }, { 33, 8 },
+ { 95, 8 }, { 48, 6 }, { 80, 6 }, { 49, 6 }, { 79, 6 },
+ { 40, 7 }, { 88, 7 }, { 28, 9 }, { 100, 9 }, { 109, 11 },
+ { 6, 15 }, { 122, 15 }, { 9, 14 }, { 12, 13 }, { 116, 13 },
+ { 119, 14 }, { 0, 16 }, { 4, 16 }, { 3, 16 }, { 2, 16 },
+ { 24, 10 }, { 104, 10 }, { 16, 12 }, { 112, 12 }, { 20, 11 },
+ { 34, 8 }, { 94, 8 }, { 50, 6 }, { 78, 6 }, { 41, 7 },
+ { 87, 7 }, { 51, 6 }, { 77, 6 }, { 52, 6 }, { 76, 6 },
+ { 29, 9 }, { 99, 9 }, { 35, 8 }, { 42, 7 }, { 86, 7 },
+ { 93, 8 }, { 108, 11 }, { 1, 16 }, { 128, 16 }, { 126, 16 },
+ { 127, 16 }, { 124, 16 }, { 125, 16 }, { 7, 15 }, { 13, 13 },
+ { 115, 13 }, { 10, 14 }, { 118, 14 }, { 25, 10 }, { 103, 10 },
+ { 17, 12 }, { 111, 12 }, { 21, 11 }, { 53, 6 }, { 75, 6 },
+ { 54, 6 }, { 74, 6 }, { 43, 7 }, { 85, 7 }, { 55, 6 },
+ { 73, 6 }, { 30, 9 }, { 98, 9 }, { 36, 8 }, { 92, 8 },
+ { 107, 11 }, { 121, 15 }, { 5, 16 }, { 123, 16 }, { 8, 15 },
+ { 120, 15 }, { 14, 13 }, { 114, 13 }, { 11, 14 }, { 117, 14 },
+ { 26, 10 }, { 31, 9 }, { 56, 6 }, { 72, 6 }, { 57, 6 },
+ { 71, 6 }, { 44, 7 }, { 84, 7 }, { 58, 6 },
+ /* bitalloc_129_f - 129 entries */
+ { 42, 6 }, { 86, 6 }, { 43, 6 }, { 85, 6 }, { 107, 8 },
+ { 114, 9 }, { 9, 10 }, { 119, 10 }, { 30, 7 }, { 98, 7 },
+ { 31, 7 }, { 44, 6 }, { 84, 6 }, { 45, 6 }, { 83, 6 },
+ { 97, 7 }, { 22, 8 }, { 106, 8 }, { 46, 6 }, { 82, 6 },
+ { 32, 7 }, { 96, 7 }, { 47, 6 }, { 81, 6 }, { 15, 9 },
+ { 113, 9 }, { 23, 8 }, { 105, 8 }, { 10, 10 }, { 118, 10 },
+ { 16, 9 }, { 48, 6 }, { 80, 6 }, { 33, 7 }, { 95, 7 },
+ { 49, 6 }, { 79, 6 }, { 50, 6 }, { 78, 6 }, { 112, 9 },
+ { 3, 12 }, { 125, 12 }, { 6, 11 }, { 122, 11 }, { 7, 11 },
+ { 24, 8 }, { 34, 7 }, { 51, 6 }, { 77, 6 }, { 94, 7 },
+ { 104, 8 }, { 11, 10 }, { 117, 10 }, { 17, 9 }, { 52, 6 },
+ { 76, 6 }, { 53, 6 }, { 75, 6 }, { 35, 7 }, { 93, 7 },
+ { 54, 6 }, { 74, 6 }, { 55, 6 }, { 73, 6 }, { 25, 8 },
+ { 103, 8 }, { 36, 7 }, { 56, 6 }, { 72, 6 }, { 57, 6 },
+ { 71, 6 }, { 92, 7 }, { 111, 9 }, { 121, 11 }, { 127, 13 },
+ { 2, 13 }, { 4, 12 }, { 12, 10 }, { 18, 9 }, { 110, 9 },
+ { 58, 6 }, { 70, 6 }, { 59, 6 }, { 69, 6 }, { 60, 6 },
+ { 68, 6 }, { 61, 6 }, { 67, 6 }, { 62, 6 }, { 66, 6 },
+ { 26, 8 }, { 102, 8 }, { 37, 7 }, { 63, 6 }, { 65, 6 },
+ { 64, 6 }, { 91, 7 }, { 38, 7 }, { 90, 7 }, { 27, 8 },
+ { 101, 8 }, { 116, 10 }, { 124, 12 }, { 126, 13 }, { 0, 15 },
+ { 128, 15 }, { 1, 14 }, { 8, 11 }, { 19, 9 }, { 109, 9 },
+ { 13, 10 }, { 115, 10 }, { 39, 7 }, { 89, 7 }, { 28, 8 },
+ { 100, 8 }, { 40, 7 }, { 88, 7 }, { 41, 7 }, { 87, 7 },
+ { 20, 9 }, { 108, 9 }, { 29, 8 }, { 99, 8 }, { 120, 11 },
+ { 5, 12 }, { 123, 12 }, { 14, 10 }, { 21, 9 },
+ /* bitalloc_129_g - 129 entries */
+ { 64, 4 }, { 88, 7 }, { 9, 11 }, { 119, 11 }, { 17, 10 },
+ { 25, 9 }, { 33, 8 }, { 41, 7 }, { 87, 7 }, { 49, 6 },
+ { 79, 6 }, { 57, 5 }, { 71, 5 }, { 95, 8 }, { 103, 9 },
+ { 111, 10 }, { 2, 12 }, { 126, 12 }, { 10, 11 }, { 18, 10 },
+ { 110, 10 }, { 26, 9 }, { 34, 8 }, { 42, 7 }, { 86, 7 },
+ { 50, 6 }, { 78, 6 }, { 58, 5 }, { 70, 5 }, { 94, 8 },
+ { 102, 9 }, { 118, 11 }, { 3, 12 }, { 125, 12 }, { 11, 11 },
+ { 117, 11 }, { 19, 10 }, { 109, 10 }, { 27, 9 }, { 35, 8 },
+ { 43, 7 }, { 85, 7 }, { 51, 6 }, { 77, 6 }, { 59, 5 },
+ { 69, 5 }, { 93, 8 }, { 101, 9 }, { 4, 12 }, { 124, 12 },
+ { 12, 11 }, { 20, 10 }, { 28, 9 }, { 100, 9 }, { 36, 8 },
+ { 44, 7 }, { 84, 7 }, { 52, 6 }, { 76, 6 }, { 60, 5 },
+ { 68, 5 }, { 92, 8 }, { 108, 10 }, { 116, 11 }, { 5, 12 },
+ { 123, 12 }, { 13, 11 }, { 115, 11 }, { 21, 10 }, { 29, 9 },
+ { 99, 9 }, { 37, 8 }, { 45, 7 }, { 83, 7 }, { 53, 6 },
+ { 75, 6 }, { 61, 5 }, { 67, 5 }, { 91, 8 }, { 107, 10 },
+ { 6, 12 }, { 122, 12 }, { 14, 11 }, { 22, 10 }, { 106, 10 },
+ { 30, 9 }, { 98, 9 }, { 38, 8 }, { 46, 7 }, { 82, 7 },
+ { 54, 6 }, { 74, 6 }, { 62, 5 }, { 66, 5 }, { 90, 8 },
+ { 114, 11 }, { 7, 12 }, { 121, 12 }, { 15, 11 }, { 113, 11 },
+ { 23, 10 }, { 105, 10 }, { 31, 9 }, { 97, 9 }, { 39, 8 },
+ { 47, 7 }, { 81, 7 }, { 55, 6 }, { 73, 6 }, { 63, 5 },
+ { 65, 5 }, { 89, 8 }, { 0, 13 }, { 128, 13 }, { 8, 12 },
+ { 16, 11 }, { 24, 10 }, { 32, 9 }, { 96, 9 }, { 104, 10 },
+ { 112, 11 }, { 120, 12 }, { 1, 13 }, { 127, 13 }, { 40, 8 },
+ { 48, 7 }, { 80, 7 }, { 56, 6 }, { 72, 6 },
+ /* bit_alloc_12[0] - 12 entries */
+ { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 5 },
+ { 5, 6 }, { 11, 9 }, { 10, 9 }, { 9, 9 }, { 8, 9 },
+ { 7, 8 }, { 6, 8 },
+ /* bit_alloc_12[1] - 12 entries */
+ { 1, 2 }, { 2, 3 }, { 4, 5 }, { 11, 7 }, { 10, 7 },
+ { 9, 7 }, { 8, 7 }, { 7, 7 }, { 6, 7 }, { 5, 6 },
+ { 3, 5 }, { 0, 1 },
+ /* bit_alloc_12[2] - 12 entries */
+ { 0, 2 }, { 4, 3 }, { 7, 4 }, { 11, 7 }, { 10, 7 },
+ { 9, 6 }, { 8, 5 }, { 3, 3 }, { 2, 3 }, { 6, 4 },
+ { 5, 4 }, { 1, 3 },
+ /* bit_alloc_12[3] - 12 entries */
+ { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 },
+ { 7, 7 }, { 8, 8 }, { 9, 9 }, { 11, 10 }, { 10, 10 },
+ { 1, 2 }, { 0, 2 },
+ /* bit_alloc_12[4] - 12 entries */
+ { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 5 }, { 9, 8 },
+ { 8, 8 }, { 6, 7 }, { 7, 8 }, { 11, 9 }, { 10, 9 },
+ { 5, 7 }, { 0, 1 },
+ /* scale_factor[0] - 129 entries */
+ { 66, 3 }, { 69, 5 }, { 55, 8 }, { 73, 8 }, { 40, 13 },
+ { 88, 13 }, { 41, 13 }, { 87, 13 }, { 42, 13 }, { 86, 13 },
+ { 43, 13 }, { 85, 13 }, { 44, 13 }, { 84, 13 }, { 45, 13 },
+ { 83, 13 }, { 46, 13 }, { 82, 13 }, { 47, 13 }, { 81, 13 },
+ { 51, 11 }, { 77, 11 }, { 48, 13 }, { 80, 13 }, { 50, 12 },
+ { 78, 12 }, { 49, 13 }, { 79, 13 }, { 54, 9 }, { 74, 9 },
+ { 58, 6 }, { 61, 4 }, { 64, 2 }, { 67, 4 }, { 70, 6 },
+ { 57, 7 }, { 71, 7 }, { 60, 5 }, { 63, 3 }, { 65, 3 },
+ { 68, 5 }, { 56, 8 }, { 72, 8 }, { 53, 10 }, { 75, 10 },
+ { 52, 11 }, { 76, 11 }, { 0, 14 }, { 128, 14 }, { 1, 14 },
+ { 127, 14 }, { 2, 14 }, { 126, 14 }, { 3, 14 }, { 125, 14 },
+ { 4, 14 }, { 124, 14 }, { 5, 14 }, { 123, 14 }, { 6, 14 },
+ { 122, 14 }, { 7, 14 }, { 121, 14 }, { 8, 14 }, { 120, 14 },
+ { 9, 14 }, { 119, 14 }, { 10, 14 }, { 118, 14 }, { 11, 14 },
+ { 117, 14 }, { 12, 14 }, { 116, 14 }, { 13, 14 }, { 115, 14 },
+ { 14, 14 }, { 114, 14 }, { 15, 14 }, { 113, 14 }, { 16, 14 },
+ { 112, 14 }, { 17, 14 }, { 111, 14 }, { 18, 14 }, { 110, 14 },
+ { 19, 14 }, { 109, 14 }, { 20, 14 }, { 108, 14 }, { 21, 14 },
+ { 107, 14 }, { 22, 14 }, { 106, 14 }, { 23, 14 }, { 105, 14 },
+ { 24, 14 }, { 104, 14 }, { 25, 14 }, { 103, 14 }, { 26, 14 },
+ { 102, 14 }, { 27, 14 }, { 101, 14 }, { 28, 14 }, { 100, 14 },
+ { 29, 14 }, { 99, 14 }, { 30, 14 }, { 98, 14 }, { 31, 14 },
+ { 97, 14 }, { 32, 14 }, { 96, 14 }, { 33, 14 }, { 95, 14 },
+ { 34, 14 }, { 94, 14 }, { 35, 14 }, { 93, 14 }, { 36, 14 },
+ { 92, 14 }, { 37, 14 }, { 91, 14 }, { 38, 14 }, { 90, 14 },
+ { 39, 14 }, { 89, 14 }, { 59, 6 }, { 62, 4 },
+ /* scale_factor[1] - 129 entries */
+ { 69, 4 }, { 56, 6 }, { 72, 6 }, { 55, 7 }, { 73, 7 },
+ { 54, 8 }, { 74, 8 }, { 75, 9 }, { 48, 14 }, { 80, 14 },
+ { 49, 14 }, { 79, 14 }, { 50, 13 }, { 78, 13 }, { 51, 12 },
+ { 77, 12 }, { 0, 15 }, { 128, 15 }, { 1, 15 }, { 127, 15 },
+ { 2, 15 }, { 126, 15 }, { 3, 15 }, { 125, 15 }, { 4, 15 },
+ { 124, 15 }, { 5, 15 }, { 123, 15 }, { 6, 15 }, { 122, 15 },
+ { 7, 15 }, { 121, 15 }, { 8, 15 }, { 120, 15 }, { 9, 15 },
+ { 119, 15 }, { 10, 15 }, { 118, 15 }, { 11, 15 }, { 117, 15 },
+ { 12, 15 }, { 116, 15 }, { 13, 15 }, { 115, 15 }, { 14, 15 },
+ { 114, 15 }, { 15, 15 }, { 113, 15 }, { 16, 15 }, { 112, 15 },
+ { 17, 15 }, { 111, 15 }, { 18, 15 }, { 110, 15 }, { 19, 15 },
+ { 109, 15 }, { 20, 15 }, { 108, 15 }, { 21, 15 }, { 107, 15 },
+ { 22, 15 }, { 106, 15 }, { 23, 15 }, { 105, 15 }, { 24, 15 },
+ { 104, 15 }, { 25, 15 }, { 103, 15 }, { 26, 15 }, { 102, 15 },
+ { 27, 15 }, { 101, 15 }, { 28, 15 }, { 100, 15 }, { 29, 15 },
+ { 99, 15 }, { 30, 15 }, { 98, 15 }, { 31, 15 }, { 97, 15 },
+ { 32, 15 }, { 96, 15 }, { 33, 15 }, { 95, 15 }, { 34, 15 },
+ { 94, 15 }, { 35, 15 }, { 93, 15 }, { 36, 15 }, { 92, 15 },
+ { 37, 15 }, { 91, 15 }, { 38, 15 }, { 90, 15 }, { 39, 15 },
+ { 89, 15 }, { 40, 15 }, { 88, 15 }, { 41, 15 }, { 87, 15 },
+ { 42, 15 }, { 86, 15 }, { 43, 15 }, { 85, 15 }, { 44, 15 },
+ { 84, 15 }, { 45, 15 }, { 83, 15 }, { 46, 15 }, { 82, 15 },
+ { 47, 15 }, { 81, 15 }, { 52, 11 }, { 76, 11 }, { 53, 10 },
+ { 63, 3 }, { 65, 3 }, { 64, 3 }, { 58, 5 }, { 70, 5 },
+ { 60, 4 }, { 68, 4 }, { 61, 4 }, { 67, 4 }, { 57, 6 },
+ { 71, 6 }, { 59, 5 }, { 62, 4 }, { 66, 4 },
+ /* scale_factor[2] - 129 entries */
+ { 63, 3 }, { 65, 3 }, { 46, 9 }, { 82, 9 }, { 49, 8 },
+ { 79, 8 }, { 85, 10 }, { 38, 12 }, { 90, 12 }, { 41, 11 },
+ { 87, 11 }, { 93, 13 }, { 33, 14 }, { 95, 14 }, { 36, 13 },
+ { 92, 13 }, { 44, 10 }, { 52, 7 }, { 76, 7 }, { 55, 6 },
+ { 73, 6 }, { 58, 5 }, { 70, 5 }, { 61, 4 }, { 67, 4 },
+ { 64, 3 }, { 47, 9 }, { 81, 9 }, { 50, 8 }, { 78, 8 },
+ { 84, 10 }, { 39, 12 }, { 89, 12 }, { 42, 11 }, { 86, 11 },
+ { 0, 15 }, { 128, 15 }, { 1, 15 }, { 127, 15 }, { 2, 15 },
+ { 126, 15 }, { 3, 15 }, { 125, 15 }, { 4, 15 }, { 124, 15 },
+ { 5, 15 }, { 123, 15 }, { 6, 15 }, { 122, 15 }, { 7, 15 },
+ { 121, 15 }, { 8, 15 }, { 120, 15 }, { 9, 15 }, { 119, 15 },
+ { 10, 15 }, { 118, 15 }, { 11, 15 }, { 117, 15 }, { 12, 15 },
+ { 116, 15 }, { 13, 15 }, { 115, 15 }, { 14, 15 }, { 114, 15 },
+ { 15, 15 }, { 113, 15 }, { 16, 15 }, { 112, 15 }, { 17, 15 },
+ { 111, 15 }, { 18, 15 }, { 110, 15 }, { 19, 15 }, { 109, 15 },
+ { 20, 15 }, { 108, 15 }, { 21, 15 }, { 107, 15 }, { 22, 15 },
+ { 106, 15 }, { 23, 15 }, { 105, 15 }, { 53, 7 }, { 75, 7 },
+ { 56, 6 }, { 72, 6 }, { 59, 5 }, { 69, 5 }, { 62, 4 },
+ { 66, 4 }, { 45, 10 }, { 83, 10 }, { 48, 9 }, { 80, 9 },
+ { 24, 15 }, { 104, 15 }, { 25, 15 }, { 103, 15 }, { 26, 15 },
+ { 102, 15 }, { 27, 15 }, { 101, 15 }, { 28, 15 }, { 100, 15 },
+ { 29, 15 }, { 99, 15 }, { 30, 15 }, { 98, 15 }, { 31, 15 },
+ { 97, 15 }, { 34, 14 }, { 94, 14 }, { 37, 13 }, { 40, 12 },
+ { 88, 12 }, { 91, 13 }, { 32, 15 }, { 96, 15 }, { 35, 14 },
+ { 43, 11 }, { 51, 8 }, { 77, 8 }, { 54, 7 }, { 74, 7 },
+ { 57, 6 }, { 71, 6 }, { 60, 5 }, { 68, 5 },
+ /* scale_factor[3] - 129 entries */
+ { 64, 2 }, { 53, 8 }, { 75, 8 }, { 55, 7 }, { 57, 6 },
+ { 59, 5 }, { 69, 5 }, { 71, 6 }, { 73, 7 }, { 77, 9 },
+ { 79, 10 }, { 83, 12 }, { 42, 14 }, { 86, 14 }, { 44, 13 },
+ { 46, 12 }, { 82, 12 }, { 48, 11 }, { 80, 11 }, { 50, 10 },
+ { 52, 9 }, { 61, 4 }, { 67, 4 }, { 63, 3 }, { 65, 3 },
+ { 54, 8 }, { 74, 8 }, { 56, 7 }, { 58, 6 }, { 60, 5 },
+ { 68, 5 }, { 70, 6 }, { 72, 7 }, { 76, 9 }, { 78, 10 },
+ { 84, 13 }, { 0, 15 }, { 128, 15 }, { 1, 15 }, { 127, 15 },
+ { 2, 15 }, { 126, 15 }, { 3, 15 }, { 125, 15 }, { 4, 15 },
+ { 124, 15 }, { 5, 15 }, { 123, 15 }, { 6, 15 }, { 122, 15 },
+ { 7, 15 }, { 121, 15 }, { 8, 15 }, { 120, 15 }, { 9, 15 },
+ { 119, 15 }, { 10, 15 }, { 118, 15 }, { 11, 15 }, { 117, 15 },
+ { 12, 15 }, { 116, 15 }, { 13, 15 }, { 115, 15 }, { 14, 15 },
+ { 114, 15 }, { 15, 15 }, { 113, 15 }, { 16, 15 }, { 112, 15 },
+ { 17, 15 }, { 111, 15 }, { 18, 15 }, { 110, 15 }, { 19, 15 },
+ { 109, 15 }, { 20, 15 }, { 108, 15 }, { 21, 15 }, { 107, 15 },
+ { 22, 15 }, { 106, 15 }, { 23, 15 }, { 105, 15 }, { 24, 15 },
+ { 104, 15 }, { 25, 15 }, { 103, 15 }, { 26, 15 }, { 102, 15 },
+ { 27, 15 }, { 101, 15 }, { 28, 15 }, { 100, 15 }, { 29, 15 },
+ { 99, 15 }, { 30, 15 }, { 98, 15 }, { 31, 15 }, { 97, 15 },
+ { 32, 15 }, { 96, 15 }, { 33, 15 }, { 95, 15 }, { 34, 15 },
+ { 94, 15 }, { 35, 15 }, { 93, 15 }, { 36, 15 }, { 92, 15 },
+ { 37, 15 }, { 91, 15 }, { 38, 15 }, { 90, 15 }, { 39, 15 },
+ { 89, 15 }, { 40, 15 }, { 88, 15 }, { 41, 15 }, { 87, 15 },
+ { 43, 14 }, { 85, 14 }, { 45, 13 }, { 47, 12 }, { 81, 12 },
+ { 49, 11 }, { 51, 10 }, { 62, 4 }, { 66, 4 },
+ /* scale_factor[4] - 129 entries */
+ { 56, 5 }, { 72, 5 }, { 52, 6 }, { 76, 6 }, { 48, 7 },
+ { 80, 7 }, { 44, 8 }, { 84, 8 }, { 40, 9 }, { 88, 9 },
+ { 36, 10 }, { 92, 10 }, { 96, 11 }, { 28, 12 }, { 100, 12 },
+ { 24, 13 }, { 104, 13 }, { 16, 15 }, { 112, 15 }, { 20, 14 },
+ { 108, 14 }, { 21, 14 }, { 33, 11 }, { 61, 4 }, { 67, 4 },
+ { 57, 5 }, { 71, 5 }, { 53, 6 }, { 75, 6 }, { 49, 7 },
+ { 79, 7 }, { 45, 8 }, { 83, 8 }, { 41, 9 }, { 87, 9 },
+ { 37, 10 }, { 91, 10 }, { 95, 11 }, { 29, 12 }, { 99, 12 },
+ { 25, 13 }, { 103, 13 }, { 107, 14 }, { 17, 15 }, { 111, 15 },
+ { 26, 13 }, { 34, 11 }, { 62, 4 }, { 66, 4 }, { 58, 5 },
+ { 70, 5 }, { 54, 6 }, { 74, 6 }, { 50, 7 }, { 78, 7 },
+ { 46, 8 }, { 82, 8 }, { 42, 9 }, { 86, 9 }, { 38, 10 },
+ { 90, 10 }, { 94, 11 }, { 30, 12 }, { 98, 12 }, { 39, 10 },
+ { 63, 4 }, { 65, 4 }, { 59, 5 }, { 69, 5 }, { 55, 6 },
+ { 73, 6 }, { 51, 7 }, { 77, 7 }, { 47, 8 }, { 81, 8 },
+ { 43, 9 }, { 85, 9 }, { 89, 10 }, { 102, 13 }, { 22, 14 },
+ { 106, 14 }, { 18, 15 }, { 110, 15 }, { 0, 16 }, { 128, 16 },
+ { 1, 16 }, { 127, 16 }, { 27, 13 }, { 35, 11 }, { 93, 11 },
+ { 31, 12 }, { 97, 12 }, { 101, 13 }, { 2, 16 }, { 126, 16 },
+ { 3, 16 }, { 125, 16 }, { 4, 16 }, { 124, 16 }, { 5, 16 },
+ { 123, 16 }, { 6, 16 }, { 122, 16 }, { 7, 16 }, { 121, 16 },
+ { 8, 16 }, { 120, 16 }, { 9, 16 }, { 119, 16 }, { 10, 16 },
+ { 118, 16 }, { 11, 16 }, { 117, 16 }, { 12, 16 }, { 116, 16 },
+ { 13, 16 }, { 115, 16 }, { 14, 16 }, { 114, 16 }, { 15, 16 },
+ { 113, 16 }, { 23, 14 }, { 105, 14 }, { 19, 15 }, { 109, 15 },
+ { 32, 12 }, { 64, 4 }, { 60, 5 }, { 68, 5 },
+ /* transition_mode[0] - 4 entries */
+ { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 3 },
+ /* transition_mode[1] - 4 entries */
+ { 3, 1 }, { 0, 2 }, { 1, 3 }, { 2, 3 },
+ /* transition_mode[2] - 4 entries */
+ { 2, 1 }, { 3, 2 }, { 0, 3 }, { 1, 3 },
+ /* transition_mode[3] - 4 entries */
+ { 0, 2 }, { 1, 2 }, { 2, 2 }, { 3, 2 },
+ /* tnl_group[0] - 37 entries */
+ { 5, 3 }, { 4, 3 }, { 19, 8 }, { 33, 12 }, { 31, 12 },
+ { 28, 11 }, { 34, 14 }, { 37, 14 }, { 35, 15 }, { 0, 15 },
+ { 36, 14 }, { 32, 12 }, { 30, 11 }, { 24, 9 }, { 22, 8 },
+ { 23, 9 }, { 29, 10 }, { 27, 10 }, { 17, 6 }, { 14, 5 },
+ { 7, 4 }, { 12, 5 }, { 1, 6 }, { 26, 9 }, { 3, 9 },
+ { 25, 8 }, { 20, 7 }, { 8, 4 }, { 10, 4 }, { 13, 4 },
+ { 15, 6 }, { 16, 6 }, { 18, 6 }, { 21, 6 }, { 11, 4 },
+ { 9, 3 }, { 6, 3 },
+ /* tnl_group[1] - 34 entries */
+ { 4, 4 }, { 7, 4 }, { 10, 4 }, { 3, 10 }, { 27, 10 },
+ { 29, 10 }, { 28, 10 }, { 22, 8 }, { 21, 7 }, { 15, 6 },
+ { 14, 5 }, { 8, 4 }, { 16, 6 }, { 19, 7 }, { 23, 8 },
+ { 26, 9 }, { 30, 10 }, { 33, 13 }, { 34, 14 }, { 0, 14 },
+ { 32, 12 }, { 31, 11 }, { 12, 5 }, { 5, 3 }, { 9, 3 },
+ { 1, 4 }, { 20, 7 }, { 25, 8 }, { 24, 8 }, { 18, 6 },
+ { 17, 5 }, { 6, 3 }, { 11, 4 }, { 13, 4 },
+ /* tnl_group[2] - 31 entries */
+ { 14, 7 }, { 17, 7 }, { 15, 7 }, { 23, 9 }, { 28, 10 },
+ { 29, 11 }, { 30, 13 }, { 0, 13 }, { 31, 12 }, { 25, 8 },
+ { 10, 5 }, { 8, 4 }, { 9, 4 }, { 4, 4 }, { 22, 8 },
+ { 3, 8 }, { 21, 8 }, { 26, 9 }, { 27, 9 }, { 12, 6 },
+ { 11, 5 }, { 16, 7 }, { 18, 7 }, { 20, 8 }, { 24, 8 },
+ { 19, 7 }, { 13, 5 }, { 5, 3 }, { 1, 2 }, { 6, 3 },
+ { 7, 3 },
+ /* tnl_group[3] - 28 entries */
+ { 8, 6 }, { 2, 6 }, { 7, 6 }, { 23, 7 }, { 12, 7 },
+ { 5, 4 }, { 10, 6 }, { 20, 8 }, { 25, 9 }, { 26, 10 },
+ { 27, 11 }, { 0, 11 }, { 22, 7 }, { 9, 5 }, { 13, 6 },
+ { 17, 6 }, { 4, 5 }, { 14, 6 }, { 19, 7 }, { 24, 7 },
+ { 3, 6 }, { 11, 6 }, { 21, 6 }, { 18, 6 }, { 16, 6 },
+ { 15, 6 }, { 6, 3 }, { 1, 1 },
+ /* tnl_group[4] - 23 entries */
+ { 2, 2 }, { 7, 7 }, { 15, 8 }, { 21, 8 }, { 3, 6 },
+ { 6, 6 }, { 13, 7 }, { 14, 8 }, { 18, 8 }, { 4, 4 },
+ { 5, 5 }, { 11, 7 }, { 10, 7 }, { 20, 6 }, { 12, 8 },
+ { 16, 9 }, { 22, 10 }, { 0, 10 }, { 17, 7 }, { 19, 6 },
+ { 8, 6 }, { 9, 6 }, { 1, 1 },
+ /* tnl_scf - 20 entries */
+ { 3, 3 }, { 11, 6 }, { 16, 9 }, { 17, 10 }, { 18, 11 },
+ { 19, 12 }, { 0, 12 }, { 15, 8 }, { 14, 7 }, { 9, 5 },
+ { 7, 4 }, { 2, 3 }, { 4, 3 }, { 1, 3 }, { 5, 3 },
+ { 12, 6 }, { 13, 6 }, { 10, 5 }, { 8, 4 }, { 6, 3 },
+ /* damp - 7 entries */
+ { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 },
+ { 0, 6 }, { 1, 1 },
+ /* dph - 9 entries */
+ { 2, 2 }, { 1, 2 }, { 3, 4 }, { 7, 4 }, { 6, 5 },
+ { 5, 6 }, { 0, 6 }, { 4, 4 }, { 8, 2 },
+ /* fst_rsd_amp - 24 entries */
+ { 12, 4 }, { 17, 4 }, { 1, 6 }, { 8, 6 }, { 9, 5 },
+ { 20, 7 }, { 3, 7 }, { 5, 6 }, { 6, 6 }, { 2, 7 },
+ { 22, 9 }, { 23, 10 }, { 0, 10 }, { 21, 8 }, { 11, 4 },
+ { 19, 5 }, { 7, 6 }, { 4, 6 }, { 16, 3 }, { 10, 4 },
+ { 18, 4 }, { 15, 3 }, { 13, 3 }, { 14, 3 },
+ /* rsd_apprx - 6 entries */
+ { 1, 1 }, { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 },
+ { 0, 5 },
+ /* rsd_amp - 33 entries */
+ { 2, 3 }, { 1, 3 }, { 5, 3 }, { 14, 8 }, { 20, 9 },
+ { 26, 10 }, { 25, 12 }, { 32, 12 }, { 19, 11 }, { 16, 8 },
+ { 24, 9 }, { 17, 9 }, { 12, 7 }, { 13, 7 }, { 9, 5 },
+ { 7, 4 }, { 3, 2 }, { 4, 3 }, { 8, 6 }, { 11, 6 },
+ { 18, 8 }, { 15, 8 }, { 30, 11 }, { 36, 13 }, { 34, 13 },
+ { 29, 13 }, { 0, 13 }, { 21, 10 }, { 28, 10 }, { 23, 10 },
+ { 22, 8 }, { 10, 6 }, { 6, 4 },
+ /* avg_g3 - 18 entries */
+ { 14, 4 }, { 11, 6 }, { 19, 7 }, { 9, 7 }, { 13, 5 },
+ { 10, 6 }, { 20, 8 }, { 8, 8 }, { 6, 10 }, { 23, 11 },
+ { 0, 11 }, { 21, 9 }, { 7, 8 }, { 12, 5 }, { 18, 4 },
+ { 16, 2 }, { 15, 2 }, { 17, 2 },
+ /* st_grid - 22 entries */
+ { 4, 4 }, { 3, 4 }, { 8, 4 }, { 14, 8 }, { 7, 9 },
+ { 9, 10 }, { 22, 10 }, { 12, 7 }, { 16, 9 }, { 11, 10 },
+ { 13, 11 }, { 17, 13 }, { 15, 13 }, { 24, 13 }, { 0, 13 },
+ { 18, 9 }, { 20, 10 }, { 2, 10 }, { 5, 7 }, { 10, 5 },
+ { 1, 2 }, { 6, 1 },
+ /* grid_2 - 20 entries */
+ { 3, 2 }, { 2, 2 }, { 4, 3 }, { 5, 4 }, { 6, 5 },
+ { 11, 11 }, { 13, 12 }, { 17, 12 }, { 19, 14 }, { 14, 14 },
+ { 18, 13 }, { 15, 13 }, { 16, 14 }, { 0, 14 }, { 12, 11 },
+ { 10, 9 }, { 9, 8 }, { 8, 7 }, { 7, 6 }, { 1, 2 },
+ /* grid_3 - 13 entries */
+ { 18, 3 }, { 15, 4 }, { 19, 5 }, { 14, 6 }, { 13, 8 },
+ { 12, 10 }, { 11, 12 }, { 0, 12 }, { 22, 11 }, { 21, 9 },
+ { 20, 7 }, { 16, 2 }, { 17, 1 },
+ /* rsd - 9 entries */
+ { 1, 3 }, { 5, 4 }, { 6, 5 }, { 7, 6 }, { 4, 6 },
+ { 4, 3 }, { 0, 3 }, { 2, 2 }, { 3, 2 },
};
-static const uint8_t *const bitalloc_bits[DCA_CODE_BOOKS][8] = {
- { bitalloc_3_bits, NULL },
- { bitalloc_5_bits_a, bitalloc_5_bits_b, bitalloc_5_bits_c, NULL },
- { bitalloc_7_bits_a, bitalloc_7_bits_b, bitalloc_7_bits_c, NULL },
- { bitalloc_9_bits_a, bitalloc_9_bits_b, bitalloc_9_bits_c, NULL },
- { bitalloc_13_bits_a, bitalloc_13_bits_b, bitalloc_13_bits_c, NULL },
- { bitalloc_17_bits_a, bitalloc_17_bits_b, bitalloc_17_bits_c, bitalloc_17_bits_d,
- bitalloc_17_bits_e, bitalloc_17_bits_f, bitalloc_17_bits_g, NULL },
- { bitalloc_25_bits_a, bitalloc_25_bits_b, bitalloc_25_bits_c, bitalloc_25_bits_d,
- bitalloc_25_bits_e, bitalloc_25_bits_f, bitalloc_25_bits_g, NULL },
- { bitalloc_33_bits_a, bitalloc_33_bits_b, bitalloc_33_bits_c, bitalloc_33_bits_d,
- bitalloc_33_bits_e, bitalloc_33_bits_f, bitalloc_33_bits_g, NULL },
- { bitalloc_65_bits_a, bitalloc_65_bits_b, bitalloc_65_bits_c, bitalloc_65_bits_d,
- bitalloc_65_bits_e, bitalloc_65_bits_f, bitalloc_65_bits_g, NULL },
- { bitalloc_129_bits_a, bitalloc_129_bits_b, bitalloc_129_bits_c, bitalloc_129_bits_d,
- bitalloc_129_bits_e, bitalloc_129_bits_f, bitalloc_129_bits_g, NULL }
-};
-
-static const uint16_t tnl_grp_0_codes[37] = {
- 0x0000, 0x0003, 0x0004, 0x0007, 0x0001, 0x0009, 0x000a, 0x000d,
- 0x000e, 0x0006, 0x0012, 0x0005, 0x0015, 0x0016, 0x0022, 0x0025,
- 0x0035, 0x0076, 0x0002, 0x0042, 0x00b6, 0x0036, 0x00c2, 0x0136,
- 0x0182, 0x01c2, 0x03c2, 0x0482, 0x0682, 0x0082, 0x0882, 0x0a82,
- 0x0282, 0x2282, 0x3282, 0x1282, 0x5282,
-};
-
-static const uint16_t tnl_grp_1_codes[34] = {
- 0x0001, 0x0003, 0x0006, 0x0000, 0x0002, 0x0004, 0x0005, 0x0007,
- 0x0008, 0x000f, 0x001a, 0x001c, 0x001d, 0x000a, 0x002c, 0x002d,
- 0x000d, 0x002a, 0x004c, 0x004d, 0x006a, 0x008c, 0x00cd, 0x00ea,
- 0x000c, 0x010c, 0x01ea, 0x020c, 0x030c, 0x07ea, 0x0bea, 0x03ea,
- 0x13ea, 0x33ea,
-};
-
-static const uint16_t tnl_grp_2_codes[31] = {
- 0x0001, 0x0003, 0x0006, 0x0007, 0x0004, 0x0008, 0x000c, 0x0010,
- 0x0012, 0x001a, 0x0022, 0x0000, 0x000a, 0x0020, 0x0040, 0x004a,
- 0x006a, 0x0002, 0x002a, 0x0042, 0x0082, 0x00aa, 0x00e0, 0x0060,
- 0x00c2, 0x01c2, 0x0160, 0x0360, 0x0f60, 0x0760, 0x1760,
-};
-
-static const uint16_t tnl_grp_3_codes[28] = {
- 0x0001, 0x0006, 0x0008, 0x0014, 0x001c, 0x0000, 0x0002, 0x0004,
- 0x000a, 0x000c, 0x0010, 0x0012, 0x001a, 0x0020, 0x002a, 0x002c,
- 0x0032, 0x003a, 0x0022, 0x0030, 0x0062, 0x0064, 0x0070, 0x0024,
- 0x00a4, 0x01a4, 0x03a4, 0x07a4,
-};
-
-static const uint16_t tnl_grp_4_codes[23] = {
- 0x0001, 0x0000, 0x000a, 0x0006, 0x0012, 0x001e, 0x0022, 0x002e,
- 0x0036, 0x003e, 0x0002, 0x0016, 0x0032, 0x004e, 0x0056, 0x000e,
- 0x0042, 0x0072, 0x00c2, 0x00f2, 0x008e, 0x018e, 0x038e,
-};
-
-static const uint16_t tnl_scf_codes[20] = {
- 0x0000, 0x0001, 0x0002, 0x0005, 0x0006, 0x0007, 0x000b, 0x000c,
- 0x0013, 0x0014, 0x0003, 0x0004, 0x0023, 0x0064, 0x00a4, 0x0024,
- 0x0124, 0x0324, 0x0724, 0x0f24,
-};
-
-static const uint16_t damp_codes[7] = {
- 0x0001, 0x0000, 0x0002, 0x0006, 0x000e, 0x001e, 0x003e,
-};
-
-static const uint16_t dph_codes[9] = {
- 0x0000, 0x0002, 0x0003, 0x0001, 0x0009, 0x000d, 0x0005, 0x0015,
- 0x0035,
-};
-
-static const uint16_t fst_rsd_amp_codes[24] = {
- 0x0003, 0x0005, 0x0006, 0x0007, 0x0000, 0x0001, 0x0002, 0x0008,
- 0x0009, 0x000a, 0x0014, 0x0004, 0x001a, 0x001c, 0x0024, 0x002c,
- 0x003a, 0x000c, 0x003c, 0x004c, 0x00fc, 0x007c, 0x017c, 0x037c,
-};
-
-static const uint16_t rsd_apprx_codes[6] = {
- 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f,
-};
-
-static const uint16_t rsd_amp_codes[33] = {
- 0x0001, 0x0000, 0x0002, 0x0003, 0x0004, 0x000e, 0x000f, 0x0016,
- 0x0007, 0x0027, 0x0037, 0x0026, 0x0066, 0x0006, 0x0017, 0x0046,
- 0x0097, 0x00d7, 0x0086, 0x00c6, 0x01c6, 0x0157, 0x0186, 0x0257,
- 0x0357, 0x0057, 0x0786, 0x0386, 0x0b86, 0x0457, 0x0c57, 0x1457,
- 0x1c57,
-};
-
-static const uint16_t avg_g3_codes[18] = {
- 0x0001, 0x0002, 0x0003, 0x0000, 0x000c, 0x0014, 0x0018, 0x0004,
- 0x0008, 0x0028, 0x0068, 0x0024, 0x00a4, 0x00e4, 0x0164, 0x0064,
- 0x0264, 0x0664,
-};
-
-static const uint16_t st_grid_codes[22] = {
- 0x0001, 0x0002, 0x0000, 0x0004, 0x0008, 0x001c, 0x004c, 0x006c,
- 0x000c, 0x002c, 0x008c, 0x00ac, 0x012c, 0x018c, 0x01ac, 0x038c,
- 0x03ac, 0x032c, 0x072c, 0x0f2c, 0x172c, 0x1f2c,
-};
-
-static const uint16_t grid_2_codes[20] = {
- 0x0000, 0x0002, 0x0003, 0x0001, 0x0005, 0x000d, 0x003d, 0x005d,
- 0x009d, 0x011d, 0x001d, 0x061d, 0x041d, 0x0c1d, 0x0a1d, 0x121d,
- 0x021d, 0x1a1d, 0x221d, 0x3a1d,
-};
-
-static const uint16_t grid_3_codes[13] = {
- 0x0001, 0x0002, 0x0000, 0x0004, 0x000c, 0x001c, 0x007c, 0x003c,
- 0x01bc, 0x00bc, 0x06bc, 0x02bc, 0x0abc,
-};
-
-static const uint16_t rsd_codes[9] = {
- 0x0001, 0x0003, 0x0000, 0x0002, 0x0006, 0x0004, 0x000c, 0x001c,
- 0x003c,
-};
-
-static const uint8_t tnl_grp_0_bitvals[74] = {
- 3, 5, 3, 9, 3, 4, 3, 6, 4, 10, 4, 13, 4, 7, 4, 11,
- 4, 8, 5, 12, 5, 14, 6, 15, 6, 18, 6, 1, 6, 17, 6, 16,
- 6, 21, 7, 20, 8, 19, 8, 22, 8, 25, 9, 26, 9, 23, 9, 3,
- 9, 24, 10, 29, 10, 27, 11, 28, 11, 30, 12, 33, 12, 31, 12, 32,
- 14, 34, 14, 37, 14, 36, 15, 35, 15, 0,
-};
-
-static const uint8_t tnl_grp_1_bitvals[68] = {
- 3, 9, 3, 6, 3, 5, 4, 4, 4, 8, 4, 10, 4, 1, 4, 11,
- 4, 7, 4, 13, 5, 12, 5, 14, 5, 17, 6, 16, 6, 15, 6, 18,
- 7, 20, 7, 19, 7, 21, 8, 25, 8, 23, 8, 22, 8, 24, 9, 26,
- 10, 3, 10, 29, 10, 30, 10, 27, 10, 28, 11, 31, 12, 32, 13, 33,
- 14, 34, 14, 0,
-};
-
-static const uint8_t tnl_grp_2_bitvals[62] = {
- 2, 1, 3, 6, 3, 5, 3, 7, 4, 9, 4, 8, 4, 4, 5, 10,
- 5, 11, 5, 13, 6, 12, 7, 14, 7, 16, 7, 15, 7, 17, 7, 18,
- 7, 19, 8, 22, 8, 20, 8, 21, 8, 3, 8, 24, 8, 25, 9, 23,
- 9, 26, 9, 27, 10, 28, 11, 29, 12, 31, 13, 30, 13, 0,
-};
-
-static const uint8_t tnl_grp_3_bitvals[56] = {
- 1, 1, 3, 6, 4, 5, 5, 9, 5, 4, 6, 8, 6, 14, 6, 10,
- 6, 21, 6, 13, 6, 7, 6, 3, 6, 16, 6, 2, 6, 18, 6, 17,
- 6, 11, 6, 15, 7, 19, 7, 23, 7, 24, 7, 22, 7, 12, 8, 20,
- 9, 25, 10, 26, 11, 27, 11, 0,
-};
-
-static const uint8_t tnl_grp_4_bitvals[46] = {
- 1, 1, 2, 2, 4, 4, 5, 5, 6, 6, 6, 8, 6, 3, 6, 19,
- 6, 20, 6, 9, 7, 7, 7, 11, 7, 13, 7, 17, 7, 10, 8, 12,
- 8, 15, 8, 14, 8, 21, 8, 18, 9, 16, 10, 22, 10, 0,
-};
-
-static const uint8_t tnl_scf_bitvals[40] = {
- 3, 3, 3, 1, 3, 2, 3, 5, 3, 4, 3, 6, 4, 8, 4, 7,
- 5, 10, 5, 9, 6, 12, 6, 11, 6, 13, 7, 14, 8, 15, 9, 16,
- 10, 17, 11, 18, 12, 19, 12, 0,
-};
-
-static const uint8_t damp_bitvals[14] = {
- 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 0,
-};
-
-static const uint8_t dph_bitvals[18] = {
- 2, 2, 2, 1, 2, 8, 4, 3, 4, 7, 4, 4, 5, 6, 6, 5,
- 6, 0,
-};
-
-static const uint8_t fst_rsd_amp_bitvals[48] = {
- 3, 13, 3, 15, 3, 16, 3, 14, 4, 12, 4, 10, 4, 11, 4, 17,
- 4, 18, 5, 19, 5, 9, 6, 1, 6, 7, 6, 6, 6, 8, 6, 5,
- 6, 4, 7, 20, 7, 2, 7, 3, 8, 21, 9, 22, 10, 23, 10, 0,
-};
-
-static const uint8_t rsd_apprx_bitvals[12] = {
- 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 0,
-};
-
-static const uint8_t rsd_amp_bitvals[66] = {
- 2, 3, 3, 2, 3, 5, 3, 4, 3, 1, 4, 7, 4, 6, 5, 9,
- 6, 8, 6, 11, 6, 10, 7, 12, 7, 13, 8, 14, 8, 18, 8, 16,
- 8, 15, 8, 22, 9, 20, 9, 24, 9, 17, 10, 28, 10, 26, 10, 21,
- 10, 23, 11, 30, 11, 19, 12, 25, 12, 32, 13, 36, 13, 29, 13, 34,
- 13, 0,
-};
-
-static const uint8_t avg_g3_bitvals[36] = {
- 2, 15, 2, 16, 2, 17, 4, 14, 4, 18, 5, 12, 5, 13, 6, 10,
- 6, 11, 7, 19, 7, 9, 8, 20, 8, 8, 8, 7, 9, 21, 10, 6,
- 11, 23, 11, 0,
-};
-
-static const uint8_t st_grid_bitvals[44] = {
- 1, 6, 2, 1, 4, 4, 4, 8, 4, 3, 5, 10, 7, 12, 7, 5,
- 8, 14, 9, 16, 9, 7, 9, 18, 10, 11, 10, 9, 10, 20, 10, 22,
- 10, 2, 11, 13, 13, 17, 13, 24, 13, 15, 13, 0,
-};
-
-static const uint8_t grid_2_bitvals[40] = {
- 2, 3, 2, 2, 2, 1, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
- 8, 9, 9, 10, 11, 11, 11, 12, 12, 13, 12, 17, 13, 15, 13, 18,
- 14, 19, 14, 16, 14, 14, 14, 0,
-};
-
-static const uint8_t grid_3_bitvals[26] = {
- 1, 17, 2, 16, 3, 18, 4, 15, 5, 19, 6, 14, 7, 20, 8, 13,
- 9, 21, 10, 12, 11, 22, 12, 11, 12, 0,
-};
-
-static const uint8_t rsd_bitvals[18] = {
- 2, 2, 2, 3, 3, 1, 3, 4, 3, 0, 4, 5, 5, 6, 6, 7,
- 6, 4,
-};
-
-static const uint16_t vlc_offs[80] = {
- 0, 512, 640, 768, 1282, 1794, 2436, 3080, 3770, 4454, 5364,
- 5372, 5380, 5388, 5392, 5396, 5412, 5420, 5428, 5460, 5492, 5508,
- 5572, 5604, 5668, 5796, 5860, 5892, 6412, 6668, 6796, 7308, 7564,
- 7820, 8076, 8620, 9132, 9388, 9910, 10166, 10680, 11196, 11726, 12240,
- 12752, 13298, 13810, 14326, 14840, 15500, 16022, 16540, 17158, 17678, 18264,
- 18796, 19352, 19926, 20468, 21472, 22398, 23014, 23622, 24200, 24748, 25276,
- 25792, 26306, 26826, 26890, 26954, 27468, 27500, 28038, 28554, 29086, 29630,
- 30150, 30214
-};
-
-DCAVLC ff_dca_vlc_bit_allocation;
-DCAVLC ff_dca_vlc_transition_mode;
-DCAVLC ff_dca_vlc_scale_factor;
-DCAVLC ff_dca_vlc_quant_index[DCA_CODE_BOOKS];
+VLC ff_dca_vlc_bit_allocation[5];
+VLC ff_dca_vlc_transition_mode[4];
+VLC ff_dca_vlc_scale_factor[5];
+VLC ff_dca_vlc_quant_index[DCA_CODE_BOOKS][7];
VLC ff_dca_vlc_tnl_grp[5];
VLC ff_dca_vlc_tnl_scf;
@@ -1264,111 +788,59 @@ VLC ff_dca_vlc_rsd;
av_cold void ff_dca_init_vlcs(void)
{
- static VLCElem dca_table[30214];
- int i, j, k = 0;
+ static VLCElem dca_table[30218];
+ const uint8_t (*src_table)[2] = ff_dca_vlc_src_tables;
+ unsigned offset = 0;
-#define DCA_INIT_VLC(vlc, a, b, c, d) \
+#define DCA_INIT_VLC(vlc, nb_bits, nb_codes, entry_offset) \
do { \
- vlc.table = &dca_table[vlc_offs[k]]; \
- vlc.table_allocated = vlc_offs[k + 1] - vlc_offs[k]; \
- init_vlc(&vlc, a, b, c, 1, 1, d, 2, 2, INIT_VLC_USE_NEW_STATIC); \
- k++; \
+ vlc.table = &dca_table[offset]; \
+ vlc.table_allocated = FF_ARRAY_ELEMS(dca_table) - offset; \
+ ff_init_vlc_from_lengths(&vlc, nb_bits, nb_codes, &src_table[0][1], 2, \
+ &src_table[0][0], 2, 1, entry_offset, \
+ INIT_VLC_STATIC_OVERLONG, NULL); \
+ offset += vlc.table_size; \
+ src_table += nb_codes; \
} while (0)
- ff_dca_vlc_bit_allocation.offset = 1;
- ff_dca_vlc_bit_allocation.max_depth = 2;
- for (i = 0; i < 5; i++)
- DCA_INIT_VLC(ff_dca_vlc_bit_allocation.vlc[i], bitalloc_12_vlc_bits[i], 12,
- bitalloc_12_bits[i], bitalloc_12_codes[i]);
-
- ff_dca_vlc_scale_factor.offset = -64;
- ff_dca_vlc_scale_factor.max_depth = 2;
- for (i = 0; i < 5; i++)
- DCA_INIT_VLC(ff_dca_vlc_scale_factor.vlc[i], SCALES_VLC_BITS, 129,
- scales_bits[i], scales_codes[i]);
-
- ff_dca_vlc_transition_mode.offset = 0;
- ff_dca_vlc_transition_mode.max_depth = 1;
- for (i = 0; i < 4; i++)
- DCA_INIT_VLC(ff_dca_vlc_transition_mode.vlc[i], tmode_vlc_bits[i], 4,
- tmode_bits[i], tmode_codes[i]);
-
- for (i = 0; i < DCA_CODE_BOOKS; i++) {
- ff_dca_vlc_quant_index[i].offset = bitalloc_offsets[i];
- ff_dca_vlc_quant_index[i].max_depth = 1 + (i > 4);
- for (j = 0; bitalloc_codes[i][j]; j++)
- DCA_INIT_VLC(ff_dca_vlc_quant_index[i].vlc[j], bitalloc_maxbits[i][j],
- bitalloc_sizes[i], bitalloc_bits[i][j], bitalloc_codes[i][j]);
+ for (unsigned i = 0; i < DCA_CODE_BOOKS; i++) {
+ for (unsigned j = 0; j < ff_dca_quant_index_group_size[i]; j++)
+ DCA_INIT_VLC(ff_dca_vlc_quant_index[i][j], bitalloc_maxbits[i][j],
+ ff_dca_bitalloc_sizes[i], ff_dca_bitalloc_offsets[i]);
}
-#define LBR_INIT_VLC(vlc, tab, nb_bits) \
+ for (unsigned i = 0; i < FF_ARRAY_ELEMS(ff_dca_vlc_bit_allocation); i++)
+ DCA_INIT_VLC(ff_dca_vlc_bit_allocation[i], bitalloc_12_vlc_bits[i], 12, 1);
+
+ for (unsigned i = 0; i < FF_ARRAY_ELEMS(ff_dca_vlc_scale_factor); i++)
+ DCA_INIT_VLC(ff_dca_vlc_scale_factor[i], DCA_SCALES_VLC_BITS, 129, -64);
+
+ for (unsigned i = 0; i < FF_ARRAY_ELEMS(ff_dca_vlc_transition_mode); i++)
+ DCA_INIT_VLC(ff_dca_vlc_transition_mode[i], DCA_TMODE_VLC_BITS, 4, 0);
+
+#define LBR_INIT_VLC(vlc, nb_bits, nb_codes, entry_offset) \
do { \
- vlc.table = &dca_table[vlc_offs[k]]; \
- vlc.table_allocated = vlc_offs[k + 1] - vlc_offs[k]; \
- ff_init_vlc_sparse(&vlc, nb_bits, FF_ARRAY_ELEMS(tab##_codes), \
- &tab##_bitvals[0], 2, 1, \
- tab##_codes, 2, 2, \
- &tab##_bitvals[1], 2, 1, \
- INIT_VLC_LE | INIT_VLC_USE_NEW_STATIC); \
- k++; \
+ vlc.table = &dca_table[offset]; \
+ vlc.table_allocated = FF_ARRAY_ELEMS(dca_table) - offset; \
+ ff_init_vlc_from_lengths(&vlc, nb_bits, nb_codes, &src_table[0][1], 2, \
+ &src_table[0][0], 2, 1, entry_offset, \
+ INIT_VLC_STATIC_OVERLONG | INIT_VLC_LE,\
+ NULL); \
+ offset += vlc.table_size; \
+ src_table += nb_codes; \
} while (0)
- LBR_INIT_VLC(ff_dca_vlc_tnl_grp[0], tnl_grp_0, 9);
- LBR_INIT_VLC(ff_dca_vlc_tnl_grp[1], tnl_grp_1, 9);
- LBR_INIT_VLC(ff_dca_vlc_tnl_grp[2], tnl_grp_2, 9);
- LBR_INIT_VLC(ff_dca_vlc_tnl_grp[3], tnl_grp_3, 9);
- LBR_INIT_VLC(ff_dca_vlc_tnl_grp[4], tnl_grp_4, 9);
- LBR_INIT_VLC(ff_dca_vlc_tnl_scf, tnl_scf, 9);
- LBR_INIT_VLC(ff_dca_vlc_damp, damp, 6);
- LBR_INIT_VLC(ff_dca_vlc_dph, dph, 6);
- LBR_INIT_VLC(ff_dca_vlc_fst_rsd_amp, fst_rsd_amp, 9);
- LBR_INIT_VLC(ff_dca_vlc_rsd_apprx, rsd_apprx, 5);
- LBR_INIT_VLC(ff_dca_vlc_rsd_amp, rsd_amp, 9);
- LBR_INIT_VLC(ff_dca_vlc_avg_g3, avg_g3, 9);
- LBR_INIT_VLC(ff_dca_vlc_st_grid, st_grid, 9);
- LBR_INIT_VLC(ff_dca_vlc_grid_2, grid_2, 9);
- LBR_INIT_VLC(ff_dca_vlc_grid_3, grid_3, 9);
- LBR_INIT_VLC(ff_dca_vlc_rsd, rsd, 6);
-}
-
-uint32_t ff_dca_vlc_calc_quant_bits(int *values, uint8_t n, uint8_t sel, uint8_t table)
-{
- uint8_t i, id;
- uint32_t sum = 0;
- for (i = 0; i < n; i++) {
- id = values[i] - bitalloc_offsets[table];
- av_assert0(id < bitalloc_sizes[table]);
- sum += bitalloc_bits[table][sel][id];
- }
- return sum;
-}
-
-void ff_dca_vlc_enc_quant(PutBitContext *pb, int *values, uint8_t n, uint8_t sel, uint8_t table)
-{
- uint8_t i, id;
- for (i = 0; i < n; i++) {
- id = values[i] - bitalloc_offsets[table];
- av_assert0(id < bitalloc_sizes[table]);
- put_bits(pb, bitalloc_bits[table][sel][id], bitalloc_codes[table][sel][id]);
- }
-}
-
-uint32_t ff_dca_vlc_calc_alloc_bits(int *values, uint8_t n, uint8_t sel)
-{
- uint8_t i, id;
- uint32_t sum = 0;
- for (i = 0; i < n; i++) {
- id = values[i] - 1;
- sum += bitalloc_12_bits[sel][id];
- }
- return sum;
-}
-
-void ff_dca_vlc_enc_alloc(PutBitContext *pb, int *values, uint8_t n, uint8_t sel)
-{
- uint8_t i, id;
- for (i = 0; i < n; i++) {
- id = values[i] - 1;
- put_bits(pb, bitalloc_12_bits[sel][id], bitalloc_12_codes[sel][id]);
- }
+ for (unsigned i = 0; i < FF_ARRAY_ELEMS(ff_dca_vlc_tnl_grp); i++)
+ LBR_INIT_VLC(ff_dca_vlc_tnl_grp[i], DCA_TNL_GRP_VLC_BITS, tnl_grp_sizes[i], -1);
+ LBR_INIT_VLC(ff_dca_vlc_tnl_scf, DCA_TNL_SCF_VLC_BITS, 20, -1);
+ LBR_INIT_VLC(ff_dca_vlc_damp, DCA_DAMP_VLC_BITS, 7, -1);
+ LBR_INIT_VLC(ff_dca_vlc_dph, DCA_DPH_VLC_BITS, 9, -1);
+ LBR_INIT_VLC(ff_dca_vlc_fst_rsd_amp, DCA_FST_RSD_VLC_BITS, 24, -1);
+ LBR_INIT_VLC(ff_dca_vlc_rsd_apprx, DCA_RSD_APPRX_VLC_BITS, 6, -1);
+ LBR_INIT_VLC(ff_dca_vlc_rsd_amp, DCA_RSD_AMP_VLC_BITS, 33, -1);
+ LBR_INIT_VLC(ff_dca_vlc_avg_g3, DCA_AVG_G3_VLC_BITS, 18, -1);
+ LBR_INIT_VLC(ff_dca_vlc_st_grid, DCA_ST_GRID_VLC_BITS, 22, -1);
+ LBR_INIT_VLC(ff_dca_vlc_grid_2, DCA_GRID_VLC_BITS, 20, -1);
+ LBR_INIT_VLC(ff_dca_vlc_grid_3, DCA_GRID_VLC_BITS, 13, -1);
+ LBR_INIT_VLC(ff_dca_vlc_rsd, DCA_RSD_VLC_BITS, 9, 0);
}
diff --git a/libavcodec/dcahuff.h b/libavcodec/dcahuff.h
index c0e04b725..fdfe7e922 100644
--- a/libavcodec/dcahuff.h
+++ b/libavcodec/dcahuff.h
@@ -27,40 +27,49 @@
#include "libavutil/attributes.h"
-#include "put_bits.h"
#include "vlc.h"
#define DCA_CODE_BOOKS 10
#define DCA_BITALLOC_12_COUNT 5
+#define DCA_NUM_BITALLOC_CODES (1 * 3 + \
+ 3 * (5 + 7 + 9 + 13) \
+ + 7 * (17 + 25 + 33 + 65 + 129))
-typedef struct DCAVLC {
- int offset; ///< Code values offset
- int max_depth; ///< Parameter for get_vlc2()
- VLC vlc[7]; ///< Actual codes
-} DCAVLC;
-
-extern DCAVLC ff_dca_vlc_bit_allocation;
-extern DCAVLC ff_dca_vlc_transition_mode;
-extern DCAVLC ff_dca_vlc_scale_factor;
-extern DCAVLC ff_dca_vlc_quant_index[DCA_CODE_BOOKS];
+extern VLC ff_dca_vlc_bit_allocation[5];
+#define DCA_TMODE_VLC_BITS 3
+extern VLC ff_dca_vlc_transition_mode[4];
+#define DCA_SCALES_VLC_BITS 9
+extern VLC ff_dca_vlc_scale_factor[5];
+extern VLC ff_dca_vlc_quant_index[DCA_CODE_BOOKS][7];
+#define DCA_TNL_GRP_VLC_BITS 9
extern VLC ff_dca_vlc_tnl_grp[5];
+#define DCA_TNL_SCF_VLC_BITS 9
extern VLC ff_dca_vlc_tnl_scf;
+#define DCA_DAMP_VLC_BITS 6
extern VLC ff_dca_vlc_damp;
+#define DCA_DPH_VLC_BITS 6
extern VLC ff_dca_vlc_dph;
+#define DCA_FST_RSD_VLC_BITS 9
extern VLC ff_dca_vlc_fst_rsd_amp;
+#define DCA_RSD_APPRX_VLC_BITS 5
extern VLC ff_dca_vlc_rsd_apprx;
+#define DCA_RSD_AMP_VLC_BITS 9
extern VLC ff_dca_vlc_rsd_amp;
+#define DCA_AVG_G3_VLC_BITS 9
extern VLC ff_dca_vlc_avg_g3;
+#define DCA_ST_GRID_VLC_BITS 9
extern VLC ff_dca_vlc_st_grid;
+#define DCA_GRID_VLC_BITS 9
extern VLC ff_dca_vlc_grid_2;
extern VLC ff_dca_vlc_grid_3;
+#define DCA_RSD_VLC_BITS 6
extern VLC ff_dca_vlc_rsd;
+extern const int8_t ff_dca_bitalloc_offsets[DCA_CODE_BOOKS];
+extern const uint8_t ff_dca_bitalloc_sizes[DCA_CODE_BOOKS];
+extern const uint8_t ff_dca_vlc_src_tables[][2];
+
av_cold void ff_dca_init_vlcs(void);
-uint32_t ff_dca_vlc_calc_quant_bits(int *values, uint8_t n, uint8_t sel, uint8_t abits);
-void ff_dca_vlc_enc_quant(PutBitContext *pb, int *values, uint8_t n, uint8_t sel, uint8_t abits);
-uint32_t ff_dca_vlc_calc_alloc_bits(int *values, uint8_t n, uint8_t sel);
-void ff_dca_vlc_enc_alloc(PutBitContext *pb, int *values, uint8_t n, uint8_t sel);
#endif /* AVCODEC_DCAHUFF_H */
diff --git a/libavcodec/dds.c b/libavcodec/dds.c
index 30788f177..4bb425dbb 100644
--- a/libavcodec/dds.c
+++ b/libavcodec/dds.c
@@ -34,9 +34,8 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "texturedsp.h"
-#include "thread.h"
#define DDPF_FOURCC (1 << 2)
#define DDPF_PALETTE (1 << 5)
@@ -711,11 +710,10 @@ static int dds_decode(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_dds_decoder = {
.p.name = "dds",
- .p.long_name = NULL_IF_CONFIG_SMALL("DirectDraw Surface image decoder"),
+ CODEC_LONG_NAME("DirectDraw Surface image decoder"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DDS,
FF_CODEC_DECODE_CB(dds_decode),
.priv_data_size = sizeof(DDSContext),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE
};
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 1893caa6a..be2be8108 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -132,38 +132,16 @@ fail2:
return 0;
}
-#define IS_EMPTY(pkt) (!(pkt)->data)
-
-static int copy_packet_props(AVPacket *dst, const AVPacket *src)
-{
- int ret = av_packet_copy_props(dst, src);
- if (ret < 0)
- return ret;
-
- dst->size = src->size; // HACK: Needed for ff_decode_frame_props().
- dst->data = (void*)1; // HACK: Needed for IS_EMPTY().
-
- return 0;
-}
-
static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt)
{
- AVPacket tmp = { 0 };
int ret = 0;
- if (IS_EMPTY(avci->last_pkt_props)) {
- if (av_fifo_read(avci->pkt_props, avci->last_pkt_props, 1) < 0)
- return copy_packet_props(avci->last_pkt_props, pkt);
+ av_packet_unref(avci->last_pkt_props);
+ if (pkt) {
+ ret = av_packet_copy_props(avci->last_pkt_props, pkt);
+ if (!ret)
+ avci->last_pkt_props->opaque = (void *)(intptr_t)pkt->size; // Needed for ff_decode_frame_props().
}
-
- ret = copy_packet_props(&tmp, pkt);
- if (ret < 0)
- return ret;
-
- ret = av_fifo_write(avci->pkt_props, &tmp, 1);
- if (ret < 0)
- av_packet_unref(&tmp);
-
return ret;
}
@@ -359,7 +337,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
side= av_packet_get_side_data(avci->last_pkt_props, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
if(side && side_size>=10) {
- avci->skip_samples = AV_RL32(side) * avci->skip_samples_multiplier;
+ avci->skip_samples = AV_RL32(side);
avci->skip_samples = FFMAX(0, avci->skip_samples);
discard_padding = AV_RL32(side + 4);
av_log(avctx, AV_LOG_DEBUG, "skip %d / discard %d samples due to side data\n",
@@ -394,8 +372,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
frame->pts += diff_ts;
if(frame->pkt_dts!=AV_NOPTS_VALUE)
frame->pkt_dts += diff_ts;
- if (frame->pkt_duration >= diff_ts)
- frame->pkt_duration -= diff_ts;
+ if (frame->duration >= diff_ts)
+ frame->duration -= diff_ts;
} else {
av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for skipped samples.\n");
}
@@ -417,7 +395,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
int64_t diff_ts = av_rescale_q(frame->nb_samples - discard_padding,
(AVRational){1, avctx->sample_rate},
avctx->pkt_timebase);
- frame->pkt_duration = diff_ts;
+ frame->duration = diff_ts;
} else {
av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for discarded samples.\n");
}
@@ -449,18 +427,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (!got_frame)
av_frame_unref(frame);
-#if FF_API_FLAG_TRUNCATED
- if (ret >= 0 && avctx->codec->type == AVMEDIA_TYPE_VIDEO && !(avctx->flags & AV_CODEC_FLAG_TRUNCATED))
-#else
if (ret >= 0 && avctx->codec->type == AVMEDIA_TYPE_VIDEO)
-#endif
ret = pkt->size;
-#if FF_API_AVCTX_TIMEBASE
- if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
- avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));
-#endif
-
/* do not stop draining when actual_got_frame != 0 or ret < 0 */
/* got_frame == 0 but actual_got_frame != 0 when frame is discarded */
if (avci->draining && !actual_got_frame) {
@@ -483,7 +452,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (ret >= pkt->size || ret < 0) {
av_packet_unref(pkt);
- av_packet_unref(avci->last_pkt_props);
} else {
int consumed = ret;
@@ -492,7 +460,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
pkt->pts = AV_NOPTS_VALUE;
pkt->dts = AV_NOPTS_VALUE;
if (!(codec->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) {
- avci->last_pkt_props->size -= consumed; // See extract_packet_props() comment.
+ // See extract_packet_props() comment.
+ avci->last_pkt_props->opaque = (void *)((intptr_t)avci->last_pkt_props->opaque - consumed);
avci->last_pkt_props->pts = AV_NOPTS_VALUE;
avci->last_pkt_props->dts = AV_NOPTS_VALUE;
}
@@ -504,6 +473,54 @@ FF_ENABLE_DEPRECATION_WARNINGS
return ret < 0 ? ret : 0;
}
+#if CONFIG_LCMS2
+static int detect_colorspace(AVCodecContext *avctx, AVFrame *frame)
+{
+ AVCodecInternal *avci = avctx->internal;
+ enum AVColorTransferCharacteristic trc;
+ AVColorPrimariesDesc coeffs;
+ enum AVColorPrimaries prim;
+ cmsHPROFILE profile;
+ AVFrameSideData *sd;
+ int ret;
+ if (!(avctx->flags2 & AV_CODEC_FLAG2_ICC_PROFILES))
+ return 0;
+
+ sd = av_frame_get_side_data(frame, AV_FRAME_DATA_ICC_PROFILE);
+ if (!sd || !sd->size)
+ return 0;
+
+ if (!avci->icc.avctx) {
+ ret = ff_icc_context_init(&avci->icc, avctx);
+ if (ret < 0)
+ return ret;
+ }
+
+ profile = cmsOpenProfileFromMemTHR(avci->icc.ctx, sd->data, sd->size);
+ if (!profile)
+ return AVERROR_INVALIDDATA;
+
+ ret = ff_icc_profile_read_primaries(&avci->icc, profile, &coeffs);
+ if (!ret)
+ ret = ff_icc_profile_detect_transfer(&avci->icc, profile, &trc);
+ cmsCloseProfile(profile);
+ if (ret < 0)
+ return ret;
+
+ prim = av_csp_primaries_id_from_desc(&coeffs);
+ if (prim != AVCOL_PRI_UNSPECIFIED)
+ frame->color_primaries = prim;
+ if (trc != AVCOL_TRC_UNSPECIFIED)
+ frame->color_trc = trc;
+ return 0;
+}
+#else /* !CONFIG_LCMS2 */
+static int detect_colorspace(av_unused AVCodecContext *c, av_unused AVFrame *f)
+{
+ return 0;
+}
+#endif
+
static int decode_simple_receive_frame(AVCodecContext *avctx, AVFrame *frame)
{
int ret;
@@ -524,24 +541,23 @@ static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame)
{
AVCodecInternal *avci = avctx->internal;
const FFCodec *const codec = ffcodec(avctx->codec);
- int ret;
+ int ret, ok;
av_assert0(!frame->buf[0]);
if (codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_FRAME) {
ret = codec->cb.receive_frame(avctx, frame);
- if (ret != AVERROR(EAGAIN))
- av_packet_unref(avci->last_pkt_props);
} else
ret = decode_simple_receive_frame(avctx, frame);
if (ret == AVERROR_EOF)
avci->draining_done = 1;
- if (!(codec->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS) &&
- IS_EMPTY(avci->last_pkt_props)) {
- // May fail if the FIFO is empty.
- av_fifo_read(avci->pkt_props, avci->last_pkt_props, 1);
+ /* preserve ret */
+ ok = detect_colorspace(avctx, frame);
+ if (ok < 0) {
+ av_frame_unref(frame);
+ return ok;
}
if (!ret) {
@@ -549,6 +565,12 @@ static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame)
frame->pts,
frame->pkt_dts);
+#if FF_API_PKT_DURATION
+FF_DISABLE_DEPRECATION_WARNINGS
+ frame->pkt_duration = frame->duration;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
/* the only case where decode data is not set should be decoders
* that do not call ff_get_buffer() */
av_assert0((frame->private_ref && frame->private_ref->size == sizeof(FrameDecodeData)) ||
@@ -636,13 +658,38 @@ static int apply_cropping(AVCodecContext *avctx, AVFrame *frame)
AV_FRAME_CROP_UNALIGNED : 0);
}
-int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
+// make sure frames returned to the caller are valid
+static int frame_validate(AVCodecContext *avctx, AVFrame *frame)
+{
+ if (!frame->buf[0] || frame->format < 0)
+ goto fail;
+
+ switch (avctx->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ if (frame->width <= 0 || frame->height <= 0)
+ goto fail;
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ if (!av_channel_layout_check(&frame->ch_layout) ||
+ frame->sample_rate <= 0)
+ goto fail;
+
+ break;
+ default: av_assert0(0);
+ }
+
+ return 0;
+fail:
+ av_log(avctx, AV_LOG_ERROR, "An invalid frame was output by a decoder. "
+ "This is a bug, please report it.\n");
+ return AVERROR_BUG;
+}
+
+int ff_decode_receive_frame(AVCodecContext *avctx, AVFrame *frame)
{
AVCodecInternal *avci = avctx->internal;
int ret, changed;
- av_frame_unref(frame);
-
if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec))
return AVERROR(EINVAL);
@@ -654,19 +701,26 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr
return ret;
}
+ ret = frame_validate(avctx, frame);
+ if (ret < 0)
+ goto fail;
+
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
ret = apply_cropping(avctx, frame);
- if (ret < 0) {
- av_frame_unref(frame);
- return ret;
- }
+ if (ret < 0)
+ goto fail;
}
- avctx->frame_number++;
+ avctx->frame_num++;
+#if FF_API_AVCTX_FRAME_NUMBER
+FF_DISABLE_DEPRECATION_WARNINGS
+ avctx->frame_number = avctx->frame_num;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
if (avctx->flags & AV_CODEC_FLAG_DROPCHANGED) {
- if (avctx->frame_number == 1) {
+ if (avctx->frame_num == 1) {
avci->initial_format = frame->format;
switch(avctx->codec_type) {
case AVMEDIA_TYPE_VIDEO:
@@ -676,22 +730,14 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr
case AVMEDIA_TYPE_AUDIO:
avci->initial_sample_rate = frame->sample_rate ? frame->sample_rate :
avctx->sample_rate;
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- avci->initial_channels = frame->ch_layout.nb_channels;
- avci->initial_channel_layout = frame->channel_layout;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
ret = av_channel_layout_copy(&avci->initial_ch_layout, &frame->ch_layout);
- if (ret < 0) {
- av_frame_unref(frame);
- return ret;
- }
+ if (ret < 0)
+ goto fail;
break;
}
}
- if (avctx->frame_number > 1) {
+ if (avctx->frame_num > 1) {
changed = avci->initial_format != frame->format;
switch(avctx->codec_type) {
@@ -700,30 +746,27 @@ FF_ENABLE_DEPRECATION_WARNINGS
avci->initial_height != frame->height;
break;
case AVMEDIA_TYPE_AUDIO:
-FF_DISABLE_DEPRECATION_WARNINGS
changed |= avci->initial_sample_rate != frame->sample_rate ||
avci->initial_sample_rate != avctx->sample_rate ||
-#if FF_API_OLD_CHANNEL_LAYOUT
- avci->initial_channels != frame->channels ||
- avci->initial_channel_layout != frame->channel_layout ||
-#endif
av_channel_layout_compare(&avci->initial_ch_layout, &frame->ch_layout);
-FF_ENABLE_DEPRECATION_WARNINGS
break;
}
if (changed) {
avci->changed_frames_dropped++;
- av_log(avctx, AV_LOG_INFO, "dropped changed frame #%d pts %"PRId64
+ av_log(avctx, AV_LOG_INFO, "dropped changed frame #%"PRId64" pts %"PRId64
" drop count: %d \n",
- avctx->frame_number, frame->pts,
+ avctx->frame_num, frame->pts,
avci->changed_frames_dropped);
- av_frame_unref(frame);
- return AVERROR_INPUT_CHANGED;
+ ret = AVERROR_INPUT_CHANGED;
+ goto fail;
}
}
}
return 0;
+fail:
+ av_frame_unref(frame);
+ return ret;
}
static void get_subtitle_defaults(AVSubtitle *sub)
@@ -733,8 +776,8 @@ static void get_subtitle_defaults(AVSubtitle *sub)
}
#define UTF8_MAX_BYTES 4 /* 5 and 6 bytes sequences should not be used */
-static int recode_subtitle(AVCodecContext *avctx, AVPacket **outpkt,
- AVPacket *inpkt, AVPacket *buf_pkt)
+static int recode_subtitle(AVCodecContext *avctx, const AVPacket **outpkt,
+ const AVPacket *inpkt, AVPacket *buf_pkt)
{
#if CONFIG_ICONV
iconv_t cd = (iconv_t)-1;
@@ -814,8 +857,7 @@ static int utf8_check(const uint8_t *str)
}
int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
- int *got_sub_ptr,
- AVPacket *avpkt)
+ int *got_sub_ptr, const AVPacket *avpkt)
{
int ret = 0;
@@ -835,7 +877,7 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) {
AVCodecInternal *avci = avctx->internal;
- AVPacket *pkt;
+ const AVPacket *pkt;
ret = recode_subtitle(avctx, &pkt, avpkt, avci->buffer_pkt);
if (ret < 0)
@@ -879,7 +921,12 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
}
if (*got_sub_ptr)
- avctx->frame_number++;
+ avctx->frame_num++;
+#if FF_API_AVCTX_FRAME_NUMBER
+FF_DISABLE_DEPRECATION_WARNINGS
+ avctx->frame_number = avctx->frame_num;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
}
return ret;
@@ -1244,9 +1291,9 @@ static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame)
return av_packet_unpack_dictionary(side_metadata, size, frame_md);
}
-int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
+int ff_decode_frame_props_from_pkt(const AVCodecContext *avctx,
+ AVFrame *frame, const AVPacket *pkt)
{
- AVPacket *pkt = avctx->internal->last_pkt_props;
static const struct {
enum AVPacketSideDataType packet;
enum AVFrameSideDataType frame;
@@ -1264,34 +1311,57 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
{ AV_PKT_DATA_DYNAMIC_HDR10_PLUS, AV_FRAME_DATA_DYNAMIC_HDR_PLUS },
};
- if (!(ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) {
- frame->pts = pkt->pts;
- frame->pkt_pos = pkt->pos;
- frame->pkt_duration = pkt->duration;
- frame->pkt_size = pkt->size;
+ frame->pts = pkt->pts;
+ frame->pkt_pos = pkt->pos;
+ frame->duration = pkt->duration;
+ frame->pkt_size = pkt->size;
- for (int i = 0; i < FF_ARRAY_ELEMS(sd); i++) {
- size_t size;
- uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size);
- if (packet_sd) {
- AVFrameSideData *frame_sd = av_frame_new_side_data(frame,
- sd[i].frame,
- size);
- if (!frame_sd)
- return AVERROR(ENOMEM);
+ for (int i = 0; i < FF_ARRAY_ELEMS(sd); i++) {
+ size_t size;
+ uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size);
+ if (packet_sd) {
+ AVFrameSideData *frame_sd = av_frame_new_side_data(frame,
+ sd[i].frame,
+ size);
+ if (!frame_sd)
+ return AVERROR(ENOMEM);
- memcpy(frame_sd->data, packet_sd, size);
- }
- }
- add_metadata_from_side_data(pkt, frame);
-
- if (pkt->flags & AV_PKT_FLAG_DISCARD) {
- frame->flags |= AV_FRAME_FLAG_DISCARD;
- } else {
- frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD);
+ memcpy(frame_sd->data, packet_sd, size);
}
}
+ add_metadata_from_side_data(pkt, frame);
+
+ if (pkt->flags & AV_PKT_FLAG_DISCARD) {
+ frame->flags |= AV_FRAME_FLAG_DISCARD;
+ } else {
+ frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD);
+ }
+
+ if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+ int ret = av_buffer_replace(&frame->opaque_ref, pkt->opaque_ref);
+ if (ret < 0)
+ return ret;
+ frame->opaque = pkt->opaque;
+ }
+
+ return 0;
+}
+
+int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
+{
+ const AVPacket *pkt = avctx->internal->last_pkt_props;
+
+ if (!(ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) {
+ int ret = ff_decode_frame_props_from_pkt(avctx, frame, pkt);
+ if (ret < 0)
+ return ret;
+ frame->pkt_size = (int)(intptr_t)pkt->opaque;
+ }
+#if FF_API_REORDERED_OPAQUE
+FF_DISABLE_DEPRECATION_WARNINGS
frame->reordered_opaque = avctx->reordered_opaque;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
if (frame->color_primaries == AVCOL_PRI_UNSPECIFIED)
frame->color_primaries = avctx->color_primaries;
@@ -1535,24 +1605,6 @@ int ff_decode_preinit(AVCodecContext *avctx)
* free the already allocated subtitle_header before overwriting it */
av_freep(&avctx->subtitle_header);
-#if FF_API_THREAD_SAFE_CALLBACKS
-FF_DISABLE_DEPRECATION_WARNINGS
- if ((avctx->thread_type & FF_THREAD_FRAME) &&
- avctx->get_buffer2 != avcodec_default_get_buffer2 &&
- !avctx->thread_safe_callbacks) {
- av_log(avctx, AV_LOG_WARNING, "Requested frame threading with a "
- "custom get_buffer2() implementation which is not marked as "
- "thread safe. This is not supported anymore, make your "
- "callback thread-safe.\n");
- }
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
- if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && avctx->ch_layout.nb_channels == 0 &&
- !(avctx->codec->capabilities & AV_CODEC_CAP_CHANNEL_CONF)) {
- av_log(avctx, AV_LOG_ERROR, "Decoder requires channel count but channels not set\n");
- return AVERROR(EINVAL);
- }
if (avctx->codec->max_lowres < avctx->lowres || avctx->lowres < 0) {
av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
avctx->codec->max_lowres);
@@ -1609,9 +1661,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
avci->in_pkt = av_packet_alloc();
avci->last_pkt_props = av_packet_alloc();
- avci->pkt_props = av_fifo_alloc2(1, sizeof(*avci->last_pkt_props),
- AV_FIFO_FLAG_AUTO_GROW);
- if (!avci->in_pkt || !avci->last_pkt_props || !avci->pkt_props)
+ if (!avci->in_pkt || !avci->last_pkt_props)
return AVERROR(ENOMEM);
ret = decode_bsfs_init(avctx);
diff --git a/libavcodec/decode.h b/libavcodec/decode.h
index 1b40f714e..8430ffbd6 100644
--- a/libavcodec/decode.h
+++ b/libavcodec/decode.h
@@ -53,6 +53,11 @@ typedef struct FrameDecodeData {
void (*hwaccel_priv_free)(void *priv);
} FrameDecodeData;
+/**
+ * avcodec_receive_frame() implementation for decoders.
+ */
+int ff_decode_receive_frame(AVCodecContext *avctx, AVFrame *frame);
+
/**
* Called by decoders to get the next packet for decoding.
*
@@ -64,6 +69,12 @@ typedef struct FrameDecodeData {
*/
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt);
+/**
+ * Set various frame properties from the provided packet.
+ */
+int ff_decode_frame_props_from_pkt(const AVCodecContext *avctx,
+ AVFrame *frame, const AVPacket *pkt);
+
/**
* Set various frame properties from the codec context / packet data.
*/
@@ -94,4 +105,49 @@ int ff_copy_palette(void *dst, const AVPacket *src, void *logctx);
*/
int ff_decode_preinit(AVCodecContext *avctx);
+/**
+ * Check that the provided frame dimensions are valid and set them on the codec
+ * context.
+ */
+int ff_set_dimensions(AVCodecContext *s, int width, int height);
+
+/**
+ * Check that the provided sample aspect ratio is valid and set it on the codec
+ * context.
+ */
+int ff_set_sar(AVCodecContext *avctx, AVRational sar);
+
+/**
+ * Select the (possibly hardware accelerated) pixel format.
+ * This is a wrapper around AVCodecContext.get_format() and should be used
+ * instead of calling get_format() directly.
+ *
+ * The list of pixel formats must contain at least one valid entry, and is
+ * terminated with AV_PIX_FMT_NONE. If it is possible to decode to software,
+ * the last entry in the list must be the most accurate software format.
+ * If it is not possible to decode to software, AVCodecContext.sw_pix_fmt
+ * must be set before calling this function.
+ */
+int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt);
+
+/**
+ * Get a buffer for a frame. This is a wrapper around
+ * AVCodecContext.get_buffer() and should be used instead calling get_buffer()
+ * directly.
+ */
+int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags);
+
+#define FF_REGET_BUFFER_FLAG_READONLY 1 ///< the returned buffer does not need to be writable
+/**
+ * Identical in function to ff_get_buffer(), except it reuses the existing buffer
+ * if available.
+ */
+int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags);
+
+/**
+ * Add or update AV_FRAME_DATA_MATRIXENCODING side data.
+ */
+int ff_side_data_update_matrix_encoding(AVFrame *frame,
+ enum AVMatrixEncoding matrix_encoding);
+
#endif /* AVCODEC_DECODE_H */
diff --git a/libavcodec/defs.h b/libavcodec/defs.h
index 420a042b8..fbe3254db 100644
--- a/libavcodec/defs.h
+++ b/libavcodec/defs.h
@@ -39,6 +39,28 @@
*/
#define AV_INPUT_BUFFER_PADDING_SIZE 64
+/**
+ * Verify checksums embedded in the bitstream (could be of either encoded or
+ * decoded data, depending on the format) and print an error message on mismatch.
+ * If AV_EF_EXPLODE is also set, a mismatching checksum will result in the
+ * decoder/demuxer returning an error.
+ */
+#define AV_EF_CRCCHECK (1<<0)
+#define AV_EF_BITSTREAM (1<<1) ///< detect bitstream specification deviations
+#define AV_EF_BUFFER (1<<2) ///< detect improper bitstream length
+#define AV_EF_EXPLODE (1<<3) ///< abort decoding on minor error detection
+
+#define AV_EF_IGNORE_ERR (1<<15) ///< ignore errors and continue
+#define AV_EF_CAREFUL (1<<16) ///< consider things that violate the spec, are fast to calculate and have not been seen in the wild as errors
+#define AV_EF_COMPLIANT (1<<17) ///< consider all spec non compliances as errors
+#define AV_EF_AGGRESSIVE (1<<18) ///< consider things that a sane encoder/muxer should not do as an error
+
+#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to an older more strict version of the spec or reference software.
+#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences.
+#define FF_COMPLIANCE_NORMAL 0
+#define FF_COMPLIANCE_UNOFFICIAL -1 ///< Allow unofficial extensions
+#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things.
+
/**
* @ingroup lavc_decoding
*/
diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c
index 057dfffa2..114c803f3 100644
--- a/libavcodec/dfa.c
+++ b/libavcodec/dfa.c
@@ -25,7 +25,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
@@ -423,7 +423,7 @@ static av_cold int dfa_decode_end(AVCodecContext *avctx)
const FFCodec ff_dfa_decoder = {
.p.name = "dfa",
- .p.long_name = NULL_IF_CONFIG_SMALL("Chronomaster DFA"),
+ CODEC_LONG_NAME("Chronomaster DFA"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DFA,
.priv_data_size = sizeof(DfaContext),
@@ -431,5 +431,4 @@ const FFCodec ff_dfa_decoder = {
.close = dfa_decode_end,
FF_CODEC_DECODE_CB(dfa_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/dfpwmdec.c b/libavcodec/dfpwmdec.c
index d013d4c21..4ddb80656 100644
--- a/libavcodec/dfpwmdec.c
+++ b/libavcodec/dfpwmdec.c
@@ -29,7 +29,7 @@
#include "avcodec.h"
#include "codec_id.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
typedef struct {
int fq, q, s, lt;
@@ -85,11 +85,6 @@ static av_cold int dfpwm_dec_init(struct AVCodecContext *ctx)
{
DFPWMState *state = ctx->priv_data;
- if (ctx->ch_layout.nb_channels <= 0) {
- av_log(ctx, AV_LOG_ERROR, "Invalid number of channels\n");
- return AVERROR(EINVAL);
- }
-
state->fq = 0;
state->q = 0;
state->s = 0;
@@ -127,12 +122,11 @@ static int dfpwm_dec_frame(struct AVCodecContext *ctx, AVFrame *frame,
const FFCodec ff_dfpwm_decoder = {
.p.name = "dfpwm",
- .p.long_name = NULL_IF_CONFIG_SMALL("DFPWM1a audio"),
+ CODEC_LONG_NAME("DFPWM1a audio"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_DFPWM,
.priv_data_size = sizeof(DFPWMState),
.init = dfpwm_dec_init,
FF_CODEC_DECODE_CB(dfpwm_dec_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/dfpwmenc.c b/libavcodec/dfpwmenc.c
index 85ee1a980..5318b04a3 100644
--- a/libavcodec/dfpwmenc.c
+++ b/libavcodec/dfpwmenc.c
@@ -39,7 +39,7 @@ typedef struct {
// Licensed in the public domain
// note, len denotes how many compressed bytes there are (uncompressed bytes / 8).
-static void au_compress(DFPWMState *state, int len, uint8_t *outbuf, uint8_t *inbuf)
+static void au_compress(DFPWMState *state, int len, uint8_t *outbuf, const uint8_t *inbuf)
{
unsigned d = 0;
for (int i = 0; i < len; i++) {
@@ -109,13 +109,13 @@ static int dfpwm_enc_frame(struct AVCodecContext *ctx, struct AVPacket *packet,
const FFCodec ff_dfpwm_encoder = {
.p.name = "dfpwm",
- .p.long_name = NULL_IF_CONFIG_SMALL("DFPWM1a audio"),
+ CODEC_LONG_NAME("DFPWM1a audio"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_DFPWM,
.priv_data_size = sizeof(DFPWMState),
.init = dfpwm_enc_init,
FF_CODEC_ENCODE_CB(dfpwm_enc_frame),
.p.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_NONE},
- .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
};
diff --git a/libavcodec/dirac_dwt.c b/libavcodec/dirac_dwt.c
index af29932c6..4039899cf 100644
--- a/libavcodec/dirac_dwt.c
+++ b/libavcodec/dirac_dwt.c
@@ -45,11 +45,11 @@ int ff_spatial_idwt_init(DWTContext *d, DWTPlane *p, enum dwt_type type,
d->decomposition_count = decomposition_count;
if (bit_depth == 8)
- ret = ff_spatial_idwt_init_8bit(d, type);
+ ret = spatial_idwt_init_8bit(d, type);
else if (bit_depth == 10)
- ret = ff_spatial_idwt_init_10bit(d, type);
+ ret = spatial_idwt_init_10bit(d, type);
else if (bit_depth == 12)
- ret = ff_spatial_idwt_init_12bit(d, type);
+ ret = spatial_idwt_init_12bit(d, type);
else
av_log(NULL, AV_LOG_WARNING, "Unsupported bit depth = %i\n", bit_depth);
diff --git a/libavcodec/dirac_dwt.h b/libavcodec/dirac_dwt.h
index 994dc21d7..84f71d912 100644
--- a/libavcodec/dirac_dwt.h
+++ b/libavcodec/dirac_dwt.h
@@ -61,11 +61,14 @@ typedef struct DWTContext {
int support;
void (*spatial_compose)(struct DWTContext *cs, int level, int width, int height, int stride);
- void (*vertical_compose_l0)(void);
- void (*vertical_compose_h0)(void);
- void (*vertical_compose_l1)(void);
- void (*vertical_compose_h1)(void);
- void (*vertical_compose)(void); ///< one set of lowpass and highpass combined
+ union {
+ vertical_compose_3tap tap3;
+ vertical_compose_5tap tap5;
+ vertical_compose_9tap tap9;
+ } vertical_compose_l0, vertical_compose_h0;
+ vertical_compose_3tap vertical_compose_l1;
+ vertical_compose_3tap vertical_compose_h1;
+ vertical_compose_2tap vertical_compose; ///< one set of lowpass and highpass combined
void (*horizontal_compose)(uint8_t *b, uint8_t *tmp, int width);
DWTCompose cs[MAX_DECOMPOSITIONS];
diff --git a/libavcodec/dirac_dwt_template.c b/libavcodec/dirac_dwt_template.c
index 5d55d932a..0d39754ed 100644
--- a/libavcodec/dirac_dwt_template.c
+++ b/libavcodec/dirac_dwt_template.c
@@ -338,8 +338,8 @@ static void RENAME(vertical_compose_daub97iL1)(uint8_t *_b0, uint8_t *_b1, uint8
static void RENAME(spatial_compose_dd97i_dy)(DWTContext *d, int level, int width, int height, int stride)
{
- vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
- vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
+ vertical_compose_3tap vertical_compose_l0 = d->vertical_compose_l0.tap3;
+ vertical_compose_5tap vertical_compose_h0 = d->vertical_compose_h0.tap5;
DWTCompose *cs = d->cs + level;
int i, y = cs->y;
@@ -362,8 +362,8 @@ static void RENAME(spatial_compose_dd97i_dy)(DWTContext *d, int level, int width
static void RENAME(spatial_compose_dirac53i_dy)(DWTContext *d, int level, int width, int height, int stride)
{
- vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
- vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
+ vertical_compose_3tap vertical_compose_l0 = d->vertical_compose_l0.tap3;
+ vertical_compose_3tap vertical_compose_h0 = d->vertical_compose_h0.tap3;
DWTCompose *cs = d->cs + level;
int y= cs->y;
@@ -384,8 +384,8 @@ static void RENAME(spatial_compose_dirac53i_dy)(DWTContext *d, int level, int wi
static void RENAME(spatial_compose_dd137i_dy)(DWTContext *d, int level, int width, int height, int stride)
{
- vertical_compose_5tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
- vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
+ vertical_compose_5tap vertical_compose_l0 = d->vertical_compose_l0.tap5;
+ vertical_compose_5tap vertical_compose_h0 = d->vertical_compose_h0.tap5;
DWTCompose *cs = d->cs + level;
int i, y = cs->y;
@@ -409,7 +409,7 @@ static void RENAME(spatial_compose_dd137i_dy)(DWTContext *d, int level, int widt
// haar makes the assumption that height is even (always true for dirac)
static void RENAME(spatial_compose_haari_dy)(DWTContext *d, int level, int width, int height, int stride)
{
- vertical_compose_2tap vertical_compose = (void*)d->vertical_compose;
+ vertical_compose_2tap vertical_compose = d->vertical_compose;
int y = d->cs[level].y;
uint8_t *b0 = d->buffer + (y-1)*stride;
uint8_t *b1 = d->buffer + (y )*stride;
@@ -425,8 +425,8 @@ static void RENAME(spatial_compose_haari_dy)(DWTContext *d, int level, int width
// Fortunately, this filter isn't used in practice.
static void RENAME(spatial_compose_fidelity)(DWTContext *d, int level, int width, int height, int stride)
{
- vertical_compose_9tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
- vertical_compose_9tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
+ vertical_compose_9tap vertical_compose_l0 = d->vertical_compose_l0.tap9;
+ vertical_compose_9tap vertical_compose_h0 = d->vertical_compose_h0.tap9;
int i, y;
uint8_t *b[8];
@@ -450,10 +450,10 @@ static void RENAME(spatial_compose_fidelity)(DWTContext *d, int level, int width
static void RENAME(spatial_compose_daub97i_dy)(DWTContext *d, int level, int width, int height, int stride)
{
- vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
- vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
- vertical_compose_3tap vertical_compose_l1 = (void*)d->vertical_compose_l1;
- vertical_compose_3tap vertical_compose_h1 = (void*)d->vertical_compose_h1;
+ vertical_compose_3tap vertical_compose_l0 = d->vertical_compose_l0.tap3;
+ vertical_compose_3tap vertical_compose_h0 = d->vertical_compose_h0.tap3;
+ vertical_compose_3tap vertical_compose_l1 = d->vertical_compose_l1;
+ vertical_compose_3tap vertical_compose_h1 = d->vertical_compose_h1;
DWTCompose *cs = d->cs + level;
int i, y = cs->y;
@@ -516,7 +516,7 @@ static void RENAME(spatial_compose_dd137i_init)(DWTCompose *cs, uint8_t *buffer,
cs->y = -5;
}
-static int RENAME(ff_spatial_idwt_init)(DWTContext *d, enum dwt_type type)
+static int RENAME(spatial_idwt_init)(DWTContext *d, enum dwt_type type)
{
int level;
@@ -552,29 +552,29 @@ static int RENAME(ff_spatial_idwt_init)(DWTContext *d, enum dwt_type type)
switch (type) {
case DWT_DIRAC_DD9_7:
d->spatial_compose = RENAME(spatial_compose_dd97i_dy);
- d->vertical_compose_l0 = (void*)RENAME(vertical_compose53iL0);
- d->vertical_compose_h0 = (void*)RENAME(vertical_compose_dd97iH0);
+ d->vertical_compose_l0.tap3 = RENAME(vertical_compose53iL0);
+ d->vertical_compose_h0.tap5 = RENAME(vertical_compose_dd97iH0);
d->horizontal_compose = RENAME(horizontal_compose_dd97i);
d->support = 7;
break;
case DWT_DIRAC_LEGALL5_3:
d->spatial_compose = RENAME(spatial_compose_dirac53i_dy);
- d->vertical_compose_l0 = (void*)RENAME(vertical_compose53iL0);
- d->vertical_compose_h0 = (void*)RENAME(vertical_compose_dirac53iH0);
+ d->vertical_compose_l0.tap3 = RENAME(vertical_compose53iL0);
+ d->vertical_compose_h0.tap3 = RENAME(vertical_compose_dirac53iH0);
d->horizontal_compose = RENAME(horizontal_compose_dirac53i);
d->support = 3;
break;
case DWT_DIRAC_DD13_7:
d->spatial_compose = RENAME(spatial_compose_dd137i_dy);
- d->vertical_compose_l0 = (void*)RENAME(vertical_compose_dd137iL0);
- d->vertical_compose_h0 = (void*)RENAME(vertical_compose_dd97iH0);
+ d->vertical_compose_l0.tap5 = RENAME(vertical_compose_dd137iL0);
+ d->vertical_compose_h0.tap5 = RENAME(vertical_compose_dd97iH0);
d->horizontal_compose = RENAME(horizontal_compose_dd137i);
d->support = 7;
break;
case DWT_DIRAC_HAAR0:
case DWT_DIRAC_HAAR1:
d->spatial_compose = RENAME(spatial_compose_haari_dy);
- d->vertical_compose = (void*)RENAME(vertical_compose_haar);
+ d->vertical_compose = RENAME(vertical_compose_haar);
if (type == DWT_DIRAC_HAAR0)
d->horizontal_compose = RENAME(horizontal_compose_haar0i);
else
@@ -583,17 +583,17 @@ static int RENAME(ff_spatial_idwt_init)(DWTContext *d, enum dwt_type type)
break;
case DWT_DIRAC_FIDELITY:
d->spatial_compose = RENAME(spatial_compose_fidelity);
- d->vertical_compose_l0 = (void*)RENAME(vertical_compose_fidelityiL0);
- d->vertical_compose_h0 = (void*)RENAME(vertical_compose_fidelityiH0);
+ d->vertical_compose_l0.tap9 = RENAME(vertical_compose_fidelityiL0);
+ d->vertical_compose_h0.tap9 = RENAME(vertical_compose_fidelityiH0);
d->horizontal_compose = RENAME(horizontal_compose_fidelityi);
d->support = 0; // not really used
break;
case DWT_DIRAC_DAUB9_7:
d->spatial_compose = RENAME(spatial_compose_daub97i_dy);
- d->vertical_compose_l0 = (void*)RENAME(vertical_compose_daub97iL0);
- d->vertical_compose_h0 = (void*)RENAME(vertical_compose_daub97iH0);
- d->vertical_compose_l1 = (void*)RENAME(vertical_compose_daub97iL1);
- d->vertical_compose_h1 = (void*)RENAME(vertical_compose_daub97iH1);
+ d->vertical_compose_l0.tap3 = RENAME(vertical_compose_daub97iL0);
+ d->vertical_compose_h0.tap3 = RENAME(vertical_compose_daub97iH0);
+ d->vertical_compose_l1 = RENAME(vertical_compose_daub97iL1);
+ d->vertical_compose_h1 = RENAME(vertical_compose_daub97iH1);
d->horizontal_compose = RENAME(horizontal_compose_daub97i);
d->support = 5;
break;
diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c
index 50d1d2e1d..0ae582bef 100644
--- a/libavcodec/diracdec.c
+++ b/libavcodec/diracdec.c
@@ -31,13 +31,11 @@
#include "libavutil/thread.h"
#include "avcodec.h"
#include "get_bits.h"
-#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "golomb.h"
#include "dirac_arith.h"
#include "dirac_vlc.h"
-#include "mpeg12data.h"
#include "mpegpicture.h"
#include "mpegvideoencdsp.h"
#include "dirac_dwt.h"
@@ -79,6 +77,7 @@ typedef struct {
uint8_t *hpel[3][4];
uint8_t *hpel_base[3][4];
int reference;
+ unsigned picture_number;
} DiracFrame;
typedef struct {
@@ -254,13 +253,13 @@ static inline int divide3(int x)
return (int)((x+1U)*21845 + 10922) >> 16;
}
-static DiracFrame *remove_frame(DiracFrame *framelist[], int picnum)
+static DiracFrame *remove_frame(DiracFrame *framelist[], unsigned picnum)
{
DiracFrame *remove_pic = NULL;
int i, remove_idx = -1;
for (i = 0; framelist[i]; i++)
- if (framelist[i]->avframe->display_picture_number == picnum) {
+ if (framelist[i]->picture_number == picnum) {
remove_pic = framelist[i];
remove_idx = i;
}
@@ -486,7 +485,7 @@ UNPACK_ARITH(10, int32_t)
* Decode the coeffs in the rectangle defined by left, right, top, bottom
* [DIRAC_STD] 13.4.3.2 Codeblock unpacking loop. codeblock()
*/
-static inline int codeblock(DiracContext *s, SubBand *b,
+static inline int codeblock(const DiracContext *s, SubBand *b,
GetBitContext *gb, DiracArith *c,
int left, int right, int top, int bottom,
int blockcnt_one, int is_arith)
@@ -596,7 +595,8 @@ INTRA_DC_PRED(10, uint32_t)
* Dirac Specification ->
* 13.4.2 Non-skipped subbands. subband_coeffs()
*/
-static av_always_inline int decode_subband_internal(DiracContext *s, SubBand *b, int is_arith)
+static av_always_inline int decode_subband_internal(const DiracContext *s,
+ SubBand *b, int is_arith)
{
int cb_x, cb_y, left, right, top, bottom;
DiracArith c;
@@ -640,13 +640,13 @@ static av_always_inline int decode_subband_internal(DiracContext *s, SubBand *b,
static int decode_subband_arith(AVCodecContext *avctx, void *b)
{
- DiracContext *s = avctx->priv_data;
+ const DiracContext *s = avctx->priv_data;
return decode_subband_internal(s, b, 1);
}
static int decode_subband_golomb(AVCodecContext *avctx, void *arg)
{
- DiracContext *s = avctx->priv_data;
+ const DiracContext *s = avctx->priv_data;
SubBand **b = arg;
return decode_subband_internal(s, *b, 0);
}
@@ -721,9 +721,9 @@ static int decode_component(DiracContext *s, int comp)
return; \
} \
-static void decode_subband(DiracContext *s, GetBitContext *gb, int quant,
+static void decode_subband(const DiracContext *s, GetBitContext *gb, int quant,
int slice_x, int slice_y, int bits_end,
- SubBand *b1, SubBand *b2)
+ const SubBand *b1, const SubBand *b2)
{
int left = b1->width * slice_x / s->num_x;
int right = b1->width *(slice_x+1) / s->num_x;
@@ -775,7 +775,7 @@ static void decode_subband(DiracContext *s, GetBitContext *gb, int quant,
*/
static int decode_lowdelay_slice(AVCodecContext *avctx, void *arg)
{
- DiracContext *s = avctx->priv_data;
+ const DiracContext *s = avctx->priv_data;
DiracSlice *slice = arg;
GetBitContext *gb = &slice->gb;
enum dirac_subband orientation;
@@ -819,13 +819,13 @@ typedef struct SliceCoeffs {
int tot;
} SliceCoeffs;
-static int subband_coeffs(DiracContext *s, int x, int y, int p,
+static int subband_coeffs(const DiracContext *s, int x, int y, int p,
SliceCoeffs c[MAX_DWT_LEVELS])
{
int level, coef = 0;
for (level = 0; level < s->wavelet_depth; level++) {
SliceCoeffs *o = &c[level];
- SubBand *b = &s->plane[p].band[level][3]; /* orientation doens't matter */
+ const SubBand *b = &s->plane[p].band[level][3]; /* orientation doens't matter */
o->top = b->height * y / s->num_y;
o->left = b->width * x / s->num_x;
o->tot_h = ((b->width * (x + 1)) / s->num_x) - o->left;
@@ -840,7 +840,7 @@ static int subband_coeffs(DiracContext *s, int x, int y, int p,
* VC-2 Specification ->
* 13.5.3 hq_slice(sx,sy)
*/
-static int decode_hq_slice(DiracContext *s, DiracSlice *slice, uint8_t *tmp_buf)
+static int decode_hq_slice(const DiracContext *s, DiracSlice *slice, uint8_t *tmp_buf)
{
int i, level, orientation, quant_idx;
int qfactor[MAX_DWT_LEVELS][4], qoffset[MAX_DWT_LEVELS][4];
@@ -917,7 +917,7 @@ static int decode_hq_slice(DiracContext *s, DiracSlice *slice, uint8_t *tmp_buf)
static int decode_hq_slice_row(AVCodecContext *avctx, void *arg, int jobnr, int threadnr)
{
int i;
- DiracContext *s = avctx->priv_data;
+ const DiracContext *s = avctx->priv_data;
DiracSlice *slices = ((DiracSlice *)arg) + s->num_x*jobnr;
uint8_t *thread_buf = &s->thread_buf[s->thread_buf_size*threadnr];
for (i = 0; i < s->num_x; i++)
@@ -2003,7 +2003,7 @@ static int dirac_decode_picture_header(DiracContext *s)
GetBitContext *gb = &s->gb;
/* [DIRAC_STD] 11.1.1 Picture Header. picture_header() PICTURE_NUM */
- picnum = s->current_picture->avframe->display_picture_number = get_bits_long(gb, 32);
+ picnum = s->current_picture->picture_number = get_bits_long(gb, 32);
av_log(s->avctx,AV_LOG_DEBUG,"PICTURE_NUM: %d\n",picnum);
@@ -2022,9 +2022,9 @@ static int dirac_decode_picture_header(DiracContext *s)
/* Jordi: this is needed if the referenced picture hasn't yet arrived */
for (j = 0; j < MAX_REFERENCE_FRAMES && refdist; j++)
if (s->ref_frames[j]
- && FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum) < refdist) {
+ && FFABS(s->ref_frames[j]->picture_number - refnum) < refdist) {
s->ref_pics[i] = s->ref_frames[j];
- refdist = FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum);
+ refdist = FFABS(s->ref_frames[j]->picture_number - refnum);
}
if (!s->ref_pics[i] || refdist)
@@ -2063,7 +2063,7 @@ static int dirac_decode_picture_header(DiracContext *s)
/* if reference array is full, remove the oldest as per the spec */
while (add_frame(s->ref_frames, MAX_REFERENCE_FRAMES, s->current_picture)) {
av_log(s->avctx, AV_LOG_ERROR, "Reference frame overflow\n");
- remove_frame(s->ref_frames, s->ref_frames[0]->avframe->display_picture_number)->reference &= DELAYED_PIC_REF;
+ remove_frame(s->ref_frames, s->ref_frames[0]->picture_number)->reference &= DELAYED_PIC_REF;
}
}
@@ -2091,7 +2091,7 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame)
/* find frame with lowest picture number */
for (i = 1; s->delay_frames[i]; i++)
- if (s->delay_frames[i]->avframe->display_picture_number < out->avframe->display_picture_number) {
+ if (s->delay_frames[i]->picture_number < out->picture_number) {
out = s->delay_frames[i];
out_idx = i;
}
@@ -2103,6 +2103,11 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame)
out->reference ^= DELAYED_PIC_REF;
if((ret = av_frame_ref(picture, out->avframe)) < 0)
return ret;
+#if FF_API_FRAME_PICTURE_NUMBER
+FF_DISABLE_DEPRECATION_WARNINGS
+ picture->display_picture_number = out->picture_number;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
*got_frame = 1;
}
@@ -2319,19 +2324,19 @@ static int dirac_decode_frame(AVCodecContext *avctx, AVFrame *picture,
if (!s->current_picture)
return buf_size;
- if (s->current_picture->avframe->display_picture_number > s->frame_number) {
+ if (s->current_picture->picture_number > s->frame_number) {
DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number);
s->current_picture->reference |= DELAYED_PIC_REF;
if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) {
- int min_num = s->delay_frames[0]->avframe->display_picture_number;
+ unsigned min_num = s->delay_frames[0]->picture_number;
/* Too many delayed frames, so we display the frame with the lowest pts */
av_log(avctx, AV_LOG_ERROR, "Delay frame overflow\n");
for (i = 1; s->delay_frames[i]; i++)
- if (s->delay_frames[i]->avframe->display_picture_number < min_num)
- min_num = s->delay_frames[i]->avframe->display_picture_number;
+ if (s->delay_frames[i]->picture_number < min_num)
+ min_num = s->delay_frames[i]->picture_number;
delayed_frame = remove_frame(s->delay_frames, min_num);
add_frame(s->delay_frames, MAX_DELAY, s->current_picture);
@@ -2341,24 +2346,33 @@ static int dirac_decode_frame(AVCodecContext *avctx, AVFrame *picture,
delayed_frame->reference ^= DELAYED_PIC_REF;
if((ret = av_frame_ref(picture, delayed_frame->avframe)) < 0)
return ret;
+ s->frame_number = delayed_frame->picture_number + 1LL;
+#if FF_API_FRAME_PICTURE_NUMBER
+FF_DISABLE_DEPRECATION_WARNINGS
+ picture->display_picture_number = delayed_frame->picture_number;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
*got_frame = 1;
}
- } else if (s->current_picture->avframe->display_picture_number == s->frame_number) {
+ } else if (s->current_picture->picture_number == s->frame_number) {
/* The right frame at the right time :-) */
if((ret = av_frame_ref(picture, s->current_picture->avframe)) < 0)
return ret;
+ s->frame_number = s->current_picture->picture_number + 1LL;
+#if FF_API_FRAME_PICTURE_NUMBER
+FF_DISABLE_DEPRECATION_WARNINGS
+ picture->display_picture_number = s->current_picture->picture_number;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
*got_frame = 1;
}
- if (*got_frame)
- s->frame_number = picture->display_picture_number + 1LL;
-
return buf_idx;
}
const FFCodec ff_dirac_decoder = {
.p.name = "dirac",
- .p.long_name = NULL_IF_CONFIG_SMALL("BBC Dirac VC-2"),
+ CODEC_LONG_NAME("BBC Dirac VC-2"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DIRAC,
.priv_data_size = sizeof(DiracContext),
@@ -2366,6 +2380,5 @@ const FFCodec ff_dirac_decoder = {
.close = dirac_decode_end,
FF_CODEC_DECODE_CB(dirac_decode_frame),
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
.flush = dirac_decode_flush,
};
diff --git a/libavcodec/diracdsp.c b/libavcodec/diracdsp.c
index aafdddcdc..284f914f9 100644
--- a/libavcodec/diracdsp.c
+++ b/libavcodec/diracdsp.c
@@ -139,7 +139,7 @@ ADD_OBMC(32)
static void put_signed_rect_clamped_8bit_c(uint8_t *dst, int dst_stride, const uint8_t *_src, int src_stride, int width, int height)
{
int x, y;
- int16_t *src = (int16_t *)_src;
+ const int16_t *src = (const int16_t *)_src;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x+=4) {
dst[x ] = av_clip_uint8(src[x ] + 128);
@@ -158,7 +158,7 @@ static void put_signed_rect_clamped_ ## PX ## bit_c(uint8_t *_dst, int dst_strid
{ \
int x, y; \
uint16_t *dst = (uint16_t *)_dst; \
- int32_t *src = (int32_t *)_src; \
+ const int32_t *src = (const int32_t *)_src; \
for (y = 0; y < height; y++) { \
for (x = 0; x < width; x+=4) { \
dst[x ] = av_clip_uintp2(src[x ] + (1U << (PX - 1)), PX); \
diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c
index 65cd6d939..7cc4f94c7 100644
--- a/libavcodec/dnxhddec.c
+++ b/libavcodec/dnxhddec.c
@@ -24,17 +24,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "libavutil/imgutils.h"
#include "libavutil/mem_internal.h"
+#include "libavutil/pixdesc.h"
#include "avcodec.h"
#include "blockdsp.h"
#include "codec_internal.h"
+#include "decode.h"
#define UNCHECKED_BITSTREAM_READER 1
#include "get_bits.h"
#include "dnxhddata.h"
#include "idctdsp.h"
-#include "internal.h"
#include "profiles.h"
#include "thread.h"
@@ -65,7 +65,7 @@ typedef struct DNXHDContext {
int cur_field; ///< current interlaced field
VLC ac_vlc, dc_vlc, run_vlc;
IDCTDSPContext idsp;
- ScanTable scantable;
+ uint8_t permutated_scantable[64];
const CIDEntry *cid_table;
int bit_depth; // 8, 10, 12 or 0 if not initialized at all.
int is_444;
@@ -273,10 +273,10 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame,
ctx->avctx->bits_per_raw_sample = ctx->bit_depth = bitdepth;
if (ctx->bit_depth != old_bit_depth) {
- ff_blockdsp_init(&ctx->bdsp, ctx->avctx);
+ ff_blockdsp_init(&ctx->bdsp);
ff_idctdsp_init(&ctx->idsp, ctx->avctx);
- ff_init_scantable(ctx->idsp.idct_permutation, &ctx->scantable,
- ff_zigzag_direct);
+ ff_permute_scantable(ctx->permutated_scantable, ff_zigzag_direct,
+ ctx->idsp.idct_permutation);
}
// make sure profile size constraints are respected
@@ -436,7 +436,7 @@ static av_always_inline int dnxhd_decode_dct_block(const DNXHDContext *ctx,
break;
}
- j = ctx->scantable.permutated[i];
+ j = ctx->permutated_scantable[i];
level *= scale[i];
level += scale[i] >> 1;
if (level_bias < 32 || weight_matrix[i] != level_bias)
@@ -726,7 +726,7 @@ static av_cold int dnxhd_decode_close(AVCodecContext *avctx)
const FFCodec ff_dnxhd_decoder = {
.p.name = "dnxhd",
- .p.long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
+ CODEC_LONG_NAME("VC3/DNxHD"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DNXHD,
.priv_data_size = sizeof(DNXHDContext),
@@ -736,5 +736,4 @@ const FFCodec ff_dnxhd_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
AV_CODEC_CAP_SLICE_THREADS,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_dnxhd_profiles),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c
index 481793c15..176bf972d 100644
--- a/libavcodec/dnxhdenc.c
+++ b/libavcodec/dnxhdenc.c
@@ -419,7 +419,7 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx)
avctx->bits_per_raw_sample = ctx->bit_depth;
- ff_blockdsp_init(&ctx->bdsp, avctx);
+ ff_blockdsp_init(&ctx->bdsp);
ff_fdctdsp_init(&ctx->m.fdsp, avctx);
ff_mpv_idct_init(&ctx->m);
ff_mpegvideoencdsp_init(&ctx->m.mpvencdsp, avctx);
@@ -944,7 +944,7 @@ static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg,
ctx = ctx->thread[threadnr];
if (ctx->bit_depth == 8) {
- uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.linesize);
+ const uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.linesize);
for (mb_x = 0; mb_x < ctx->m.mb_width; ++mb_x, pix += 16) {
unsigned mb = mb_y * ctx->m.mb_width + mb_x;
int sum;
@@ -973,8 +973,8 @@ static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg,
} else { // 10-bit
const int linesize = ctx->m.linesize >> 1;
for (mb_x = 0; mb_x < ctx->m.mb_width; ++mb_x) {
- uint16_t *pix = (uint16_t *)ctx->thread[0]->src[0] +
- ((mb_y << 4) * linesize) + (mb_x << 4);
+ const uint16_t *pix = (const uint16_t *)ctx->thread[0]->src[0] +
+ ((mb_y << 4) * linesize) + (mb_x << 4);
unsigned mb = mb_y * ctx->m.mb_width + mb_x;
int sum = 0;
int sqsum = 0;
@@ -1355,11 +1355,11 @@ static const FFCodecDefault dnxhd_defaults[] = {
const FFCodec ff_dnxhd_encoder = {
.p.name = "dnxhd",
- .p.long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
+ CODEC_LONG_NAME("VC3/DNxHD"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DNXHD,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
- AV_CODEC_CAP_SLICE_THREADS,
+ AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(DNXHDEncContext),
.init = dnxhd_encode_init,
FF_CODEC_ENCODE_CB(dnxhd_encode_picture),
@@ -1374,5 +1374,5 @@ const FFCodec ff_dnxhd_encoder = {
.p.priv_class = &dnxhd_class,
.defaults = dnxhd_defaults,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_dnxhd_profiles),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h
index 7726a3915..e581312ce 100644
--- a/libavcodec/dnxhdenc.h
+++ b/libavcodec/dnxhdenc.h
@@ -86,7 +86,7 @@ typedef struct DNXHDEncContext {
uint16_t (*qmatrix_c16)[2][64];
unsigned frame_bits;
- uint8_t *src[3];
+ const uint8_t *src[3];
uint32_t *orig_vlc_codes;
uint8_t *orig_vlc_bits;
diff --git a/libavcodec/dolby_e.c b/libavcodec/dolby_e.c
index a734af8d4..921c33f3b 100644
--- a/libavcodec/dolby_e.c
+++ b/libavcodec/dolby_e.c
@@ -24,13 +24,13 @@
#include "libavutil/mem.h"
#include "libavutil/mem_internal.h"
#include "libavutil/opt.h"
+#include "libavutil/tx.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "get_bits.h"
#include "dolby_e.h"
#include "kbdwin.h"
-#include "fft.h"
#define MAX_SEGMENTS 2
@@ -85,7 +85,8 @@ typedef struct DBEDecodeContext {
DECLARE_ALIGNED(32, float, history)[MAX_CHANNELS][256];
- FFTContext imdct[3];
+ AVTXContext *imdct[2][3];
+ av_tx_fn imdct_fn[2][3];
AVFloatDSPContext *fdsp;
} DBEDecodeContext;
@@ -989,23 +990,23 @@ static int parse_meter(DBEDecodeContext *s1)
static void imdct_calc(DBEDecodeContext *s1, DBEGroup *g, float *result, float *values)
{
- FFTContext *imdct = &s1->imdct[g->imdct_idx];
+ AVTXContext *imdct = s1->imdct[g->imdct_phs == 1][g->imdct_idx];
+ av_tx_fn imdct_fn = s1->imdct_fn[g->imdct_phs == 1][g->imdct_idx];
int n = 1 << imdct_bits_tab[g->imdct_idx];
int n2 = n >> 1;
- int i;
switch (g->imdct_phs) {
case 0:
- imdct->imdct_half(imdct, result, values);
- for (i = 0; i < n2; i++)
+ imdct_fn(imdct, result, values, sizeof(float));
+ for (int i = 0; i < n2; i++)
result[n2 + i] = result[n2 - i - 1];
break;
case 1:
- imdct->imdct_calc(imdct, result, values);
+ imdct_fn(imdct, result, values, sizeof(float));
break;
case 2:
- imdct->imdct_half(imdct, result + n2, values);
- for (i = 0; i < n2; i++)
+ imdct_fn(imdct, result + n2, values, sizeof(float));
+ for (int i = 0; i < n2; i++)
result[i] = -result[n - i - 1];
break;
default:
@@ -1152,10 +1153,11 @@ static av_cold void dolby_e_flush(AVCodecContext *avctx)
static av_cold int dolby_e_close(AVCodecContext *avctx)
{
DBEDecodeContext *s = avctx->priv_data;
- int i;
- for (i = 0; i < 3; i++)
- ff_mdct_end(&s->imdct[i]);
+ for (int i = 0; i < 3; i++) {
+ av_tx_uninit(&s->imdct[0][i]);
+ av_tx_uninit(&s->imdct[1][i]);
+ }
av_freep(&s->fdsp);
return 0;
@@ -1252,14 +1254,20 @@ static av_cold int dolby_e_init(AVCodecContext *avctx)
{
static AVOnce init_once = AV_ONCE_INIT;
DBEDecodeContext *s = avctx->priv_data;
- int i;
+ float scale = 2.0f;
+ int ret;
if (ff_thread_once(&init_once, init_tables))
return AVERROR_UNKNOWN;
- for (i = 0; i < 3; i++)
- if (ff_mdct_init(&s->imdct[i], imdct_bits_tab[i], 1, 2.0) < 0)
- return AVERROR(ENOMEM);
+ for (int i = 0; i < 3; i++) {
+ if ((ret = av_tx_init(&s->imdct[0][i], &s->imdct_fn[0][i], AV_TX_FLOAT_MDCT,
+ 1, 1 << imdct_bits_tab[i] - 1, &scale, 0)) < 0)
+ return ret;
+ if ((ret = av_tx_init(&s->imdct[1][i], &s->imdct_fn[1][i], AV_TX_FLOAT_MDCT,
+ 1, 1 << imdct_bits_tab[i] - 1, &scale, AV_TX_FULL_IMDCT)) < 0)
+ return ret;
+ }
if (!(s->fdsp = avpriv_float_dsp_alloc(0)))
return AVERROR(ENOMEM);
@@ -1299,7 +1307,7 @@ static const AVClass dolby_e_decoder_class = {
const FFCodec ff_dolby_e_decoder = {
.p.name = "dolby_e",
- .p.long_name = NULL_IF_CONFIG_SMALL("Dolby E"),
+ CODEC_LONG_NAME("Dolby E"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_DOLBY_E,
.priv_data_size = sizeof(DBEDecodeContext),
@@ -1310,5 +1318,5 @@ const FFCodec ff_dolby_e_decoder = {
.flush = dolby_e_flush,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/dolby_e_parser.c b/libavcodec/dolby_e_parser.c
index 9f5462735..d2566e544 100644
--- a/libavcodec/dolby_e_parser.c
+++ b/libavcodec/dolby_e_parser.c
@@ -21,8 +21,6 @@
#include "libavutil/channel_layout.h"
#include "avcodec.h"
#include "dolby_e.h"
-#include "get_bits.h"
-#include "put_bits.h"
typedef struct DBEParseContext {
DBEContext dectx;
diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c
index ad020b52f..6ea9e2c06 100644
--- a/libavcodec/dpcm.c
+++ b/libavcodec/dpcm.c
@@ -37,16 +37,16 @@
* the fourcc 'Axan' in the 'auds' chunk of the AVI header.
*/
-#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "mathops.h"
typedef struct DPCMContext {
int16_t array[256];
- int sample[2]; ///< previous sample (for SOL_DPCM)
+ int sample[2]; ///< previous sample (for SOL_DPCM and WADY_DPCM)
+ int scale; ///< scale for WADY_DPCM
const int8_t *sol_table; ///< delta table for SOL_DPCM
} DPCMContext;
@@ -127,6 +127,24 @@ static const int16_t sol_table_16[128] = {
0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
};
+static const int16_t wady_table[128] = {
+ 0, 2, 4, 6, 8, 10, 12, 15,
+ 18, 21, 24, 28, 32, 36, 40, 44,
+ 49, 54, 59, 64, 70, 76, 82, 88,
+ 95, 102, 109, 116, 124, 132, 140, 148,
+ 160, 170, 180, 190, 200, 210, 220, 230,
+ 240, 255, 270, 285, 300, 320, 340, 360,
+ 380, 400, 425, 450, 475, 500, 525, 550,
+ 580, 610, 650, 700, 750, 800, 900, 1000,
+ -0, -2, -4, -6, -8, -10, -12, -15,
+ -18, -21, -24, -28, -32, -36, -40, -44,
+ -49, -54, -59, -64, -70, -76, -82, -88,
+ -95, -102,-109,-116,-124,-132,-140,-148,
+ -160,-170,-180,-190,-200,-210,-220,-230,
+ -240,-255,-270,-285,-300,-320,-340,-360,
+ -380,-400,-425,-450,-475,-500,-525,-550,
+ -580,-610,-650,-700,-750,-800,-900,-1000,
+};
static av_cold int dpcm_decode_init(AVCodecContext *avctx)
{
@@ -140,7 +158,7 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx)
s->sample[0] = s->sample[1] = 0;
- switch(avctx->codec->id) {
+ switch (avctx->codec->id) {
case AV_CODEC_ID_ROQ_DPCM:
/* initialize square table */
@@ -176,6 +194,13 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx)
}
break;
+ case AV_CODEC_ID_CBD2_DPCM:
+ for (i = -128; i < 128; i++) {
+ int16_t cube = (i * i * i) / 64;
+ s->array[i+128] = cube;
+ }
+ break;
+
case AV_CODEC_ID_GREMLIN_DPCM: {
int delta = 0;
int code = 64;
@@ -194,6 +219,10 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx)
}
break;
+ case AV_CODEC_ID_WADY_DPCM:
+ s->scale = (avctx->extradata && avctx->extradata_size > 0) ? avctx->extradata[0] : 1;
+ break;
+
default:
break;
}
@@ -240,8 +269,10 @@ static int dpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
else
out = buf_size;
break;
+ case AV_CODEC_ID_WADY_DPCM:
case AV_CODEC_ID_DERF_DPCM:
case AV_CODEC_ID_GREMLIN_DPCM:
+ case AV_CODEC_ID_CBD2_DPCM:
case AV_CODEC_ID_SDX2_DPCM:
out = buf_size;
break;
@@ -363,6 +394,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
}
break;
+ case AV_CODEC_ID_CBD2_DPCM:
case AV_CODEC_ID_SDX2_DPCM:
while (output_samples < samples_end) {
int8_t n = bytestream2_get_byteu(&gb);
@@ -402,6 +434,22 @@ static int dpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
}
}
break;
+
+ case AV_CODEC_ID_WADY_DPCM: {
+ int idx = 0;
+
+ while (output_samples < samples_end) {
+ const uint8_t n = bytestream2_get_byteu(&gb);
+
+ if (n & 0x80)
+ s->sample[idx] = sign_extend((n & 0x7f) << 9, 16);
+ else
+ s->sample[idx] += s->scale * wady_table[n & 0x7f];
+ *output_samples++ = av_clip_int16(s->sample[idx]);
+ idx ^= stereo;
+ }
+ }
+ break;
}
*got_frame_ptr = 1;
@@ -409,19 +457,27 @@ static int dpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
return avpkt->size;
}
+static void dpcm_flush(AVCodecContext *avctx)
+{
+ DPCMContext *s = avctx->priv_data;
+
+ s->sample[0] = s->sample[1] = 0;
+}
+
#define DPCM_DECODER(id_, name_, long_name_) \
const FFCodec ff_ ## name_ ## _decoder = { \
.p.name = #name_, \
- .p.long_name = NULL_IF_CONFIG_SMALL(long_name_), \
+ CODEC_LONG_NAME(long_name_), \
.p.type = AVMEDIA_TYPE_AUDIO, \
.p.id = id_, \
.p.capabilities = AV_CODEC_CAP_DR1, \
.priv_data_size = sizeof(DPCMContext), \
.init = dpcm_decode_init, \
+ .flush = dpcm_flush, \
FF_CODEC_DECODE_CB(dpcm_decode_frame), \
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, \
}
+DPCM_DECODER(AV_CODEC_ID_CBD2_DPCM, cbd2_dpcm, "DPCM Cuberoot-Delta-Exact");
DPCM_DECODER(AV_CODEC_ID_DERF_DPCM, derf_dpcm, "DPCM Xilam DERF");
DPCM_DECODER(AV_CODEC_ID_GREMLIN_DPCM, gremlin_dpcm, "DPCM Gremlin");
DPCM_DECODER(AV_CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay");
@@ -429,3 +485,4 @@ DPCM_DECODER(AV_CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ");
DPCM_DECODER(AV_CODEC_ID_SDX2_DPCM, sdx2_dpcm, "DPCM Squareroot-Delta-Exact");
DPCM_DECODER(AV_CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol");
DPCM_DECODER(AV_CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan");
+DPCM_DECODER(AV_CODEC_ID_WADY_DPCM, wady_dpcm, "DPCM Marble WADY");
diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index bb2c5e588..4f5060846 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -24,10 +24,9 @@
#include "libavutil/intfloat.h"
#include "libavutil/imgutils.h"
#include "libavutil/timecode.h"
-#include "bytestream.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
enum DPX_TRC {
DPX_TRC_USER_DEFINED = 0,
@@ -762,7 +761,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
const FFCodec ff_dpx_decoder = {
.p.name = "dpx",
- .p.long_name = NULL_IF_CONFIG_SMALL("DPX (Digital Picture Exchange) image"),
+ CODEC_LONG_NAME("DPX (Digital Picture Exchange) image"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DPX,
FF_CODEC_DECODE_CB(decode_frame),
diff --git a/libavcodec/dpxenc.c b/libavcodec/dpxenc.c
index 1f2b1b8f5..e136cc1b9 100644
--- a/libavcodec/dpxenc.c
+++ b/libavcodec/dpxenc.c
@@ -276,7 +276,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const FFCodec ff_dpx_encoder = {
.p.name = "dpx",
- .p.long_name = NULL_IF_CONFIG_SMALL("DPX (Digital Picture Exchange) image"),
+ CODEC_LONG_NAME("DPX (Digital Picture Exchange) image"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DPX,
.p.capabilities = AV_CODEC_CAP_DR1,
@@ -292,5 +292,4 @@ const FFCodec ff_dpx_encoder = {
AV_PIX_FMT_GBRP10LE, AV_PIX_FMT_GBRP10BE,
AV_PIX_FMT_GBRP12LE, AV_PIX_FMT_GBRP12BE,
AV_PIX_FMT_NONE},
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/dsd_tablegen.h b/libavcodec/dsd_tablegen.h
deleted file mode 100644
index e5da86a1d..000000000
--- a/libavcodec/dsd_tablegen.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Header file for hardcoded DSD tables
- * based on BSD licensed dsd2pcm by Sebastian Gesemann
- * Copyright (c) 2009, 2011 Sebastian Gesemann. All rights reserved.
- *
- * 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_DSD_TABLEGEN_H
-#define AVCODEC_DSD_TABLEGEN_H
-
-#include
-#include "libavutil/attributes.h"
-#include "dsd.h"
-
-#define HTAPS 48 /** number of FIR constants */
-#define CTABLES ((HTAPS + 7) / 8) /** number of "8 MACs" lookup tables */
-
-#include "libavutil/common.h"
-
-/*
- * Properties of this 96-tap lowpass filter when applied on a signal
- * with sampling rate of 44100*64 Hz:
- *
- * () has a delay of 17 microseconds.
- *
- * () flat response up to 48 kHz
- *
- * () if you downsample afterwards by a factor of 8, the
- * spectrum below 70 kHz is practically alias-free.
- *
- * () stopband rejection is about 160 dB
- *
- * The coefficient tables ("ctables") take only 6 Kibi Bytes and
- * should fit into a modern processor's fast cache.
- */
-
-/**
- * The 2nd half (48 coeffs) of a 96-tap symmetric lowpass filter
- */
-static const double htaps[HTAPS] = {
- 0.09950731974056658, 0.09562845727714668, 0.08819647126516944,
- 0.07782552527068175, 0.06534876523171299, 0.05172629311427257,
- 0.0379429484910187, 0.02490921351762261, 0.0133774746265897,
- 0.003883043418804416, -0.003284703416210726, -0.008080250212687497,
- -0.01067241812471033, -0.01139427235000863, -0.0106813877974587,
- -0.009007905078766049, -0.006828859761015335, -0.004535184322001496,
- -0.002425035959059578, -0.0006922187080790708, 0.0005700762133516592,
- 0.001353838005269448, 0.001713709169690937, 0.001742046839472948,
- 0.001545601648013235, 0.001226696225277855, 0.0008704322683580222,
- 0.0005381636200535649, 0.000266446345425276, 7.002968738383528e-05,
- -5.279407053811266e-05, -0.0001140625650874684, -0.0001304796361231895,
- -0.0001189970287491285, -9.396247155265073e-05, -6.577634378272832e-05,
- -4.07492895872535e-05, -2.17407957554587e-05, -9.163058931391722e-06,
- -2.017460145032201e-06, 1.249721855219005e-06, 2.166655190537392e-06,
- 1.930520892991082e-06, 1.319400334374195e-06, 7.410039764949091e-07,
- 3.423230509967409e-07, 1.244182214744588e-07, 3.130441005359396e-08
-};
-
-static float ctables[CTABLES][256];
-#endif /* AVCODEC_DSD_TABLEGEN_H */
diff --git a/libavcodec/dsddec.c b/libavcodec/dsddec.c
index f0e54db10..396207577 100644
--- a/libavcodec/dsddec.c
+++ b/libavcodec/dsddec.c
@@ -29,6 +29,7 @@
#include "libavcodec/internal.h"
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "dsd.h"
#define DSD_SILENCE 0x69
@@ -117,7 +118,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
#define DSD_DECODER(id_, name_, long_name_) \
const FFCodec ff_ ## name_ ## _decoder = { \
.p.name = #name_, \
- .p.long_name = NULL_IF_CONFIG_SMALL(long_name_), \
+ CODEC_LONG_NAME(long_name_), \
.p.type = AVMEDIA_TYPE_AUDIO, \
.p.id = AV_CODEC_ID_##id_, \
.init = decode_init, \
@@ -125,7 +126,6 @@ const FFCodec ff_ ## name_ ## _decoder = { \
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS, \
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, \
AV_SAMPLE_FMT_NONE }, \
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, \
};
DSD_DECODER(DSD_LSBF, dsd_lsbf, "DSD (Direct Stream Digital), least significant bit first")
diff --git a/libavcodec/dsicinaudio.c b/libavcodec/dsicinaudio.c
index 2cfaebca4..aa14966c7 100644
--- a/libavcodec/dsicinaudio.c
+++ b/libavcodec/dsicinaudio.c
@@ -25,11 +25,11 @@
*/
#include "libavutil/channel_layout.h"
+#include "libavutil/intreadwrite.h"
#include "avcodec.h"
-#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "mathops.h"
typedef struct CinAudioContext {
@@ -123,12 +123,11 @@ static int cinaudio_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_dsicinaudio_decoder = {
.p.name = "dsicinaudio",
- .p.long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
+ CODEC_LONG_NAME("Delphine Software International CIN audio"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_DSICINAUDIO,
.priv_data_size = sizeof(CinAudioContext),
.init = cinaudio_decode_init,
FF_CODEC_DECODE_CB(cinaudio_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/dsicinvideo.c b/libavcodec/dsicinvideo.c
index 71f607141..222044d12 100644
--- a/libavcodec/dsicinvideo.c
+++ b/libavcodec/dsicinvideo.c
@@ -27,7 +27,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
typedef enum CinVideoBitmapIndex {
CIN_CUR_BMP = 0, /* current */
@@ -323,13 +323,13 @@ static av_cold int cinvideo_decode_end(AVCodecContext *avctx)
const FFCodec ff_dsicinvideo_decoder = {
.p.name = "dsicinvideo",
- .p.long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
+ CODEC_LONG_NAME("Delphine Software International CIN video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DSICINVIDEO,
.priv_data_size = sizeof(CinVideoContext),
.init = cinvideo_decode_init,
.close = cinvideo_decode_end,
FF_CODEC_DECODE_CB(cinvideo_decode_frame),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.capabilities = AV_CODEC_CAP_DR1,
};
diff --git a/libavcodec/dss_sp.c b/libavcodec/dss_sp.c
index b465bfe93..9337371bc 100644
--- a/libavcodec/dss_sp.c
+++ b/libavcodec/dss_sp.c
@@ -22,12 +22,11 @@
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/mem_internal.h"
-#include "libavutil/opt.h"
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
#define SUBFRAMES 4
#define PULSE_MAX 8
@@ -774,12 +773,11 @@ static int dss_sp_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_dss_sp_decoder = {
.p.name = "dss_sp",
- .p.long_name = NULL_IF_CONFIG_SMALL("Digital Speech Standard - Standard Play mode (DSS SP)"),
+ CODEC_LONG_NAME("Digital Speech Standard - Standard Play mode (DSS SP)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_DSS_SP,
.priv_data_size = sizeof(DssSpContext),
.init = dss_sp_decode_init,
FF_CODEC_DECODE_CB(dss_sp_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/dstdec.c b/libavcodec/dstdec.c
index ba6651b09..4b1762db3 100644
--- a/libavcodec/dstdec.c
+++ b/libavcodec/dstdec.c
@@ -29,11 +29,10 @@
#include "libavutil/mem_internal.h"
#include "libavutil/reverse.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "get_bits.h"
#include "avcodec.h"
#include "golomb.h"
-#include "mathops.h"
#include "dsd.h"
#define DST_MAX_CHANNELS 6
@@ -386,7 +385,7 @@ dsd:
const FFCodec ff_dst_decoder = {
.p.name = "dst",
- .p.long_name = NULL_IF_CONFIG_SMALL("DST (Digital Stream Transfer)"),
+ CODEC_LONG_NAME("DST (Digital Stream Transfer)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_DST,
.priv_data_size = sizeof(DSTContext),
@@ -395,5 +394,4 @@ const FFCodec ff_dst_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/dts2pts_bsf.c b/libavcodec/dts2pts_bsf.c
new file mode 100644
index 000000000..263514faa
--- /dev/null
+++ b/libavcodec/dts2pts_bsf.c
@@ -0,0 +1,540 @@
+/*
+ * Copyright (c) 2022 James Almer
+ *
+ * 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
+ * Derive PTS by reordering DTS from supported streams
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/fifo.h"
+#include "libavutil/tree.h"
+
+#include "bsf.h"
+#include "bsf_internal.h"
+#include "cbs.h"
+#include "cbs_h264.h"
+#include "h264_parse.h"
+#include "h264_ps.h"
+
+typedef struct DTS2PTSNode {
+ int64_t dts;
+ int64_t duration;
+ int poc;
+ int gop;
+} DTS2PTSNode;
+
+typedef struct DTS2PTSFrame {
+ AVPacket *pkt;
+ int poc;
+ int poc_diff;
+ int gop;
+} DTS2PTSFrame;
+
+typedef struct DTS2PTSH264Context {
+ H264POCContext poc;
+ SPS sps;
+ int poc_diff;
+ int last_poc;
+ int highest_poc;
+ int picture_structure;
+} DTS2PTSH264Context;
+
+typedef struct DTS2PTSContext {
+ struct AVTreeNode *root;
+ AVFifo *fifo;
+
+ // Codec specific function pointers and constants
+ int (*init)(AVBSFContext *ctx);
+ int (*filter)(AVBSFContext *ctx);
+ void (*flush)(AVBSFContext *ctx);
+ size_t fifo_size;
+
+ CodedBitstreamContext *cbc;
+ CodedBitstreamFragment au;
+
+ union {
+ DTS2PTSH264Context h264;
+ } u;
+
+ int nb_frame;
+ int gop;
+ int eof;
+} DTS2PTSContext;
+
+// AVTreeNode callbacks
+static int cmp_insert(const void *key, const void *node)
+{
+ int ret = ((const DTS2PTSNode *)key)->poc - ((const DTS2PTSNode *)node)->poc;
+ if (!ret)
+ ret = ((const DTS2PTSNode *)key)->gop - ((const DTS2PTSNode *)node)->gop;
+ return ret;
+}
+
+static int cmp_find(const void *key, const void *node)
+{
+ const DTS2PTSFrame * key1 = key;
+ const DTS2PTSNode *node1 = node;
+ int ret = FFDIFFSIGN(key1->poc, node1->poc);
+ if (!ret)
+ ret = key1->gop - node1->gop;
+ return ret;
+}
+
+static int dec_poc(void *opaque, void *elem)
+{
+ DTS2PTSNode *node = elem;
+ int dec = *(int *)opaque;
+ node->poc -= dec;
+ return 0;
+}
+
+static int free_node(void *opaque, void *elem)
+{
+ DTS2PTSNode *node = elem;
+ av_free(node);
+ return 0;
+}
+
+// Shared functions
+static int alloc_and_insert_node(AVBSFContext *ctx, int64_t ts, int64_t duration,
+ int poc, int poc_diff, int gop)
+{
+ DTS2PTSContext *s = ctx->priv_data;
+ for (int i = 0; i < poc_diff; i++) {
+ struct AVTreeNode *node = av_tree_node_alloc();
+ DTS2PTSNode *poc_node, *ret;
+ if (!node)
+ return AVERROR(ENOMEM);
+ poc_node = av_malloc(sizeof(*poc_node));
+ if (!poc_node) {
+ av_free(node);
+ return AVERROR(ENOMEM);
+ }
+ if (i && ts != AV_NOPTS_VALUE)
+ ts += duration / poc_diff;
+ *poc_node = (DTS2PTSNode) { ts, duration, poc++, gop };
+ ret = av_tree_insert(&s->root, poc_node, cmp_insert, &node);
+ if (ret && ret != poc_node) {
+ *ret = *poc_node;
+ av_free(poc_node);
+ av_free(node);
+ }
+ }
+ return 0;
+}
+
+// H.264
+static const CodedBitstreamUnitType h264_decompose_unit_types[] = {
+ H264_NAL_SPS,
+ H264_NAL_PPS,
+ H264_NAL_IDR_SLICE,
+ H264_NAL_SLICE,
+};
+
+static int h264_init(AVBSFContext *ctx)
+{
+ DTS2PTSContext *s = ctx->priv_data;
+ DTS2PTSH264Context *h264 = &s->u.h264;
+
+ s->cbc->decompose_unit_types = h264_decompose_unit_types;
+ s->cbc->nb_decompose_unit_types = FF_ARRAY_ELEMS(h264_decompose_unit_types);
+
+ s->nb_frame = -(ctx->par_in->video_delay << 1);
+ h264->last_poc = h264->highest_poc = INT_MIN;
+
+ return 0;
+}
+
+static int get_mmco_reset(const H264RawSliceHeader *header)
+{
+ if (header->nal_unit_header.nal_ref_idc == 0 ||
+ !header->adaptive_ref_pic_marking_mode_flag)
+ return 0;
+
+ for (int i = 0; i < H264_MAX_MMCO_COUNT; i++) {
+ if (header->mmco[i].memory_management_control_operation == 0)
+ return 0;
+ else if (header->mmco[i].memory_management_control_operation == 5)
+ return 1;
+ }
+
+ return 0;
+}
+
+static int h264_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, int *queued)
+{
+ DTS2PTSContext *s = ctx->priv_data;
+ DTS2PTSH264Context *h264 = &s->u.h264;
+ DTS2PTSFrame frame;
+ int poc_diff, ret;
+
+ poc_diff = (h264->picture_structure == 3) + 1;
+ if (h264->sps.frame_mbs_only_flag && h264->poc_diff)
+ poc_diff = FFMIN(poc_diff, h264->poc_diff);
+ if (poc < 0) {
+ av_tree_enumerate(s->root, &poc_diff, NULL, dec_poc);
+ s->nb_frame -= poc_diff;
+ }
+ // Check if there was a POC reset (Like an IDR slice)
+ if (s->nb_frame > h264->highest_poc) {
+ s->nb_frame = 0;
+ s->gop = (s->gop + 1) % s->fifo_size;
+ h264->highest_poc = h264->last_poc;
+ }
+
+ ret = alloc_and_insert_node(ctx, pkt->dts, pkt->duration, s->nb_frame, poc_diff, s->gop);
+ if (ret < 0)
+ return ret;
+ av_log(ctx, AV_LOG_DEBUG, "Queueing frame with POC %d, GOP %d, dts %"PRId64"\n",
+ poc, s->gop, pkt->dts);
+ s->nb_frame += poc_diff;
+
+ // Add frame to output FIFO only once
+ if (*queued)
+ return 0;
+
+ frame = (DTS2PTSFrame) { pkt, poc, poc_diff, s->gop };
+ ret = av_fifo_write(s->fifo, &frame, 1);
+ av_assert2(ret >= 0);
+ *queued = 1;
+
+ return 0;
+}
+
+static int h264_filter(AVBSFContext *ctx)
+{
+ DTS2PTSContext *s = ctx->priv_data;
+ DTS2PTSH264Context *h264 = &s->u.h264;
+ CodedBitstreamFragment *au = &s->au;
+ AVPacket *in;
+ int output_picture_number = INT_MIN;
+ int field_poc[2];
+ int queued = 0, ret;
+
+ ret = ff_bsf_get_packet(ctx, &in);
+ if (ret < 0)
+ return ret;
+
+ ret = ff_cbs_read_packet(s->cbc, au, in);
+ if (ret < 0) {
+ av_log(ctx, AV_LOG_WARNING, "Failed to parse access unit.\n");
+ goto fail;
+ }
+
+ for (int i = 0; i < au->nb_units; i++) {
+ CodedBitstreamUnit *unit = &au->units[i];
+
+ switch (unit->type) {
+ case H264_NAL_IDR_SLICE:
+ h264->poc.prev_frame_num = 0;
+ h264->poc.prev_frame_num_offset = 0;
+ h264->poc.prev_poc_msb =
+ h264->poc.prev_poc_lsb = 0;
+ // fall-through
+ case H264_NAL_SLICE: {
+ const H264RawSlice *slice = unit->content;
+ const H264RawSliceHeader *header = &slice->header;
+ const CodedBitstreamH264Context *cbs_h264 = s->cbc->priv_data;
+ const H264RawSPS *sps = cbs_h264->active_sps;
+ int got_reset;
+
+ if (!sps) {
+ av_log(ctx, AV_LOG_ERROR, "No active SPS for a slice\n");
+ goto fail;
+ }
+ // Initialize the SPS struct with the fields ff_h264_init_poc() cares about
+ h264->sps.frame_mbs_only_flag = sps->frame_mbs_only_flag;
+ h264->sps.log2_max_frame_num = sps->log2_max_frame_num_minus4 + 4;
+ h264->sps.poc_type = sps->pic_order_cnt_type;
+ h264->sps.log2_max_poc_lsb = sps->log2_max_pic_order_cnt_lsb_minus4 + 4;
+ h264->sps.offset_for_non_ref_pic = sps->offset_for_non_ref_pic;
+ h264->sps.offset_for_top_to_bottom_field = sps->offset_for_top_to_bottom_field;
+ h264->sps.poc_cycle_length = sps->num_ref_frames_in_pic_order_cnt_cycle;
+ for (int i = 0; i < h264->sps.poc_cycle_length; i++)
+ h264->sps.offset_for_ref_frame[i] = sps->offset_for_ref_frame[i];
+
+ h264->picture_structure = sps->frame_mbs_only_flag ? 3 :
+ (header->field_pic_flag ?
+ header->field_pic_flag + header->bottom_field_flag : 3);
+
+ h264->poc.frame_num = header->frame_num;
+ h264->poc.poc_lsb = header->pic_order_cnt_lsb;
+ h264->poc.delta_poc_bottom = header->delta_pic_order_cnt_bottom;
+ h264->poc.delta_poc[0] = header->delta_pic_order_cnt[0];
+ h264->poc.delta_poc[1] = header->delta_pic_order_cnt[1];
+
+ field_poc[0] = field_poc[1] = INT_MAX;
+ ret = ff_h264_init_poc(field_poc, &output_picture_number, &h264->sps,
+ &h264->poc, h264->picture_structure,
+ header->nal_unit_header.nal_ref_idc);
+ if (ret < 0) {
+ av_log(ctx, AV_LOG_ERROR, "ff_h264_init_poc() failure\n");
+ goto fail;
+ }
+
+ got_reset = get_mmco_reset(header);
+ h264->poc.prev_frame_num = got_reset ? 0 : h264->poc.frame_num;
+ h264->poc.prev_frame_num_offset = got_reset ? 0 : h264->poc.frame_num_offset;
+ if (header->nal_unit_header.nal_ref_idc != 0) {
+ h264->poc.prev_poc_msb = got_reset ? 0 : h264->poc.poc_msb;
+ if (got_reset)
+ h264->poc.prev_poc_lsb = h264->picture_structure == 2 ? 0 : field_poc[0];
+ else
+ h264->poc.prev_poc_lsb = h264->poc.poc_lsb;
+ }
+
+ if (output_picture_number != h264->last_poc) {
+ if (h264->last_poc != INT_MIN) {
+ int64_t diff = FFABS(h264->last_poc - (int64_t)output_picture_number);
+
+ if ((output_picture_number < 0) && !h264->last_poc)
+ h264->poc_diff = 0;
+ else if (FFABS((int64_t)output_picture_number) < h264->poc_diff) {
+ diff = FFABS(output_picture_number);
+ h264->poc_diff = 0;
+ }
+ if ((!h264->poc_diff || (h264->poc_diff > diff)) && diff <= INT_MAX) {
+ h264->poc_diff = diff;
+ if (h264->poc_diff == 1 && h264->sps.frame_mbs_only_flag) {
+ av_tree_enumerate(s->root, &h264->poc_diff, NULL, dec_poc);
+ s->nb_frame -= 2;
+ }
+ }
+ }
+ h264->last_poc = output_picture_number;
+ h264->highest_poc = FFMAX(h264->highest_poc, output_picture_number);
+
+ ret = h264_queue_frame(ctx, in, output_picture_number, &queued);
+ if (ret < 0)
+ goto fail;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (output_picture_number == INT_MIN) {
+ av_log(ctx, AV_LOG_ERROR, "No slices in access unit\n");
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ ret = 0;
+fail:
+ ff_cbs_fragment_reset(au);
+ if (!queued)
+ av_packet_free(&in);
+
+ return ret;
+}
+
+static void h264_flush(AVBSFContext *ctx)
+{
+ DTS2PTSContext *s = ctx->priv_data;
+ DTS2PTSH264Context *h264 = &s->u.h264;
+
+ memset(&h264->sps, 0, sizeof(h264->sps));
+ memset(&h264->poc, 0, sizeof(h264->poc));
+ s->nb_frame = -(ctx->par_in->video_delay << 1);
+ h264->last_poc = h264->highest_poc = INT_MIN;
+}
+
+// Core functions
+static const struct {
+ enum AVCodecID id;
+ int (*init)(AVBSFContext *ctx);
+ int (*filter)(AVBSFContext *ctx);
+ void (*flush)(AVBSFContext *ctx);
+ size_t fifo_size;
+} func_tab[] = {
+ { AV_CODEC_ID_H264, h264_init, h264_filter, h264_flush, H264_MAX_DPB_FRAMES * 2 * 2 },
+};
+
+static int dts2pts_init(AVBSFContext *ctx)
+{
+ DTS2PTSContext *s = ctx->priv_data;
+ CodedBitstreamFragment *au = &s->au;
+ int i, ret;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(func_tab); i++) {
+ if (func_tab[i].id == ctx->par_in->codec_id) {
+ s->init = func_tab[i].init;
+ s->filter = func_tab[i].filter;
+ s->flush = func_tab[i].flush;
+ s->fifo_size = func_tab[i].fifo_size;
+ break;
+ }
+ }
+ if (i == FF_ARRAY_ELEMS(func_tab))
+ return AVERROR_BUG;
+ av_assert0(s->filter && s->fifo_size);
+
+ s->fifo = av_fifo_alloc2(s->fifo_size, sizeof(DTS2PTSFrame), 0);
+ if (!s->fifo)
+ return AVERROR(ENOMEM);
+
+ ret = ff_cbs_init(&s->cbc, ctx->par_in->codec_id, ctx);
+ if (ret < 0)
+ return ret;
+
+ if (s->init) {
+ ret = s->init(ctx);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (!ctx->par_in->extradata_size)
+ return 0;
+
+ ret = ff_cbs_read_extradata(s->cbc, au, ctx->par_in);
+ if (ret < 0)
+ av_log(ctx, AV_LOG_WARNING, "Failed to parse extradata.\n");
+
+ ff_cbs_fragment_reset(au);
+
+ return 0;
+}
+
+static int dts2pts_filter(AVBSFContext *ctx, AVPacket *out)
+{
+ DTS2PTSContext *s = ctx->priv_data;
+ DTS2PTSNode *poc_node = NULL, *next[2] = { NULL, NULL };
+ DTS2PTSFrame frame;
+ int ret;
+
+ // Fill up the FIFO and POC tree
+ while (!s->eof && av_fifo_can_write(s->fifo)) {
+ ret = s->filter(ctx);
+ if (ret < 0) {
+ if (ret != AVERROR_EOF)
+ return ret;
+ s->eof = 1;
+ }
+ }
+
+ if (!av_fifo_can_read(s->fifo))
+ return AVERROR_EOF;
+
+ // Fetch a packet from the FIFO
+ ret = av_fifo_read(s->fifo, &frame, 1);
+ av_assert2(ret >= 0);
+ av_packet_move_ref(out, frame.pkt);
+ av_packet_free(&frame.pkt);
+
+ // Search the timestamp for the requested POC and set PTS
+ poc_node = av_tree_find(s->root, &frame, cmp_find, (void **)next);
+ if (!poc_node) {
+ poc_node = next[1];
+ if (!poc_node || poc_node->poc != frame.poc)
+ poc_node = next[0];
+ }
+ if (poc_node && poc_node->poc == frame.poc) {
+ out->pts = poc_node->dts;
+ if (!s->eof) {
+ // Remove the found entry from the tree
+ DTS2PTSFrame dup = (DTS2PTSFrame) { NULL, frame.poc + 1, frame.poc_diff, frame.gop };
+ for (; dup.poc_diff > 0; dup.poc++, dup.poc_diff--) {
+ struct AVTreeNode *node = NULL;
+ if (!poc_node || poc_node->dts != out->pts)
+ continue;
+ av_tree_insert(&s->root, poc_node, cmp_insert, &node);
+ av_free(poc_node);
+ av_free(node);
+ poc_node = av_tree_find(s->root, &dup, cmp_find, NULL);
+ }
+ }
+ } else if (s->eof && frame.poc > INT_MIN) {
+ DTS2PTSFrame dup = (DTS2PTSFrame) { NULL, frame.poc - 1, frame.poc_diff, frame.gop };
+ poc_node = av_tree_find(s->root, &dup, cmp_find, NULL);
+ if (poc_node && poc_node->poc == dup.poc) {
+ out->pts = poc_node->dts;
+ if (out->pts != AV_NOPTS_VALUE)
+ out->pts += poc_node->duration;
+ ret = alloc_and_insert_node(ctx, out->pts, out->duration,
+ frame.poc, frame.poc_diff, frame.gop);
+ if (ret < 0) {
+ av_packet_unref(out);
+ return ret;
+ }
+ if (!ret)
+ av_log(ctx, AV_LOG_DEBUG, "Queueing frame for POC %d, GOP %d, dts %"PRId64", "
+ "generated from POC %d, GOP %d, dts %"PRId64", duration %"PRId64"\n",
+ frame.poc, frame.gop, out->pts,
+ poc_node->poc, poc_node->gop, poc_node->dts, poc_node->duration);
+ } else
+ av_log(ctx, AV_LOG_WARNING, "No timestamp for POC %d in tree\n", frame.poc);
+ } else
+ av_log(ctx, AV_LOG_WARNING, "No timestamp for POC %d in tree\n", frame.poc);
+ av_log(ctx, AV_LOG_DEBUG, "Returning frame for POC %d, GOP %d, dts %"PRId64", pts %"PRId64"\n",
+ frame.poc, frame.gop, out->dts, out->pts);
+
+ return 0;
+}
+
+static void dts2pts_flush(AVBSFContext *ctx)
+{
+ DTS2PTSContext *s = ctx->priv_data;
+ DTS2PTSFrame frame;
+
+ if (s->flush)
+ s->flush(ctx);
+ s->eof = 0;
+ s->gop = 0;
+
+ while (s->fifo && av_fifo_read(s->fifo, &frame, 1) >= 0)
+ av_packet_free(&frame.pkt);
+
+ av_tree_enumerate(s->root, NULL, NULL, free_node);
+ av_tree_destroy(s->root);
+ s->root = NULL;
+
+ ff_cbs_fragment_reset(&s->au);
+ if (s->cbc)
+ ff_cbs_flush(s->cbc);
+}
+
+static void dts2pts_close(AVBSFContext *ctx)
+{
+ DTS2PTSContext *s = ctx->priv_data;
+
+ dts2pts_flush(ctx);
+
+ av_fifo_freep2(&s->fifo);
+ ff_cbs_fragment_free(&s->au);
+ ff_cbs_close(&s->cbc);
+}
+
+static const enum AVCodecID dts2pts_codec_ids[] = {
+ AV_CODEC_ID_H264,
+ AV_CODEC_ID_NONE,
+};
+
+const FFBitStreamFilter ff_dts2pts_bsf = {
+ .p.name = "dts2pts",
+ .p.codec_ids = dts2pts_codec_ids,
+ .priv_data_size = sizeof(DTS2PTSContext),
+ .init = dts2pts_init,
+ .flush = dts2pts_flush,
+ .close = dts2pts_close,
+ .filter = dts2pts_filter,
+};
diff --git a/libavcodec/dv.c b/libavcodec/dv.c
index e2550c4cc..eb49978ad 100644
--- a/libavcodec/dv.c
+++ b/libavcodec/dv.c
@@ -38,8 +38,12 @@
* DV codec.
*/
-#include "avcodec.h"
-#include "dv.h"
+#include
+
+#include "libavutil/pixfmt.h"
+
+#include "dv_internal.h"
+#include "dv_profile.h"
static inline void dv_calc_mb_coordinates(const AVDVProfile *d, int chan,
int seq, int slot, uint16_t *tbl)
@@ -162,7 +166,7 @@ static inline void dv_calc_mb_coordinates(const AVDVProfile *d, int chan,
}
}
-int ff_dv_init_dynamic_tables(DVVideoContext *ctx, const AVDVProfile *d)
+int ff_dv_init_dynamic_tables(DVwork_chunk *work_chunks, const AVDVProfile *d)
{
int j, i, c, s, p;
@@ -174,8 +178,8 @@ int ff_dv_init_dynamic_tables(DVVideoContext *ctx, const AVDVProfile *d)
p += !(j % 3);
if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) &&
!(DV_PROFILE_IS_720p50(d) && s > 9)) {
- dv_calc_mb_coordinates(d, c, s, j, &ctx->work_chunks[i].mb_coordinates[0]);
- ctx->work_chunks[i++].buf_offset = p;
+ dv_calc_mb_coordinates(d, c, s, j, &work_chunks[i].mb_coordinates[0]);
+ work_chunks[i++].buf_offset = p;
}
p += 5;
}
@@ -184,13 +188,3 @@ int ff_dv_init_dynamic_tables(DVVideoContext *ctx, const AVDVProfile *d)
return 0;
}
-
-av_cold int ff_dvvideo_init(AVCodecContext *avctx)
-{
- DVVideoContext *s = avctx->priv_data;
-
- s->avctx = avctx;
- avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
-
- return 0;
-}
diff --git a/libavcodec/dv.h b/libavcodec/dv.h
index 855afcc75..29f97b608 100644
--- a/libavcodec/dv.h
+++ b/libavcodec/dv.h
@@ -27,57 +27,27 @@
#ifndef AVCODEC_DV_H
#define AVCODEC_DV_H
-#include "avcodec.h"
-#include "dv_profile.h"
-#include "me_cmp.h"
-#include "idctdsp.h"
-
-typedef struct DVwork_chunk {
- uint16_t buf_offset;
- uint16_t mb_coordinates[5];
-} DVwork_chunk;
-
-typedef struct DVVideoContext {
- AVClass *avclass;
- const AVDVProfile *sys;
- const AVFrame *frame;
- AVCodecContext *avctx;
- uint8_t *buf;
-
- uint8_t dv_zigzag[2][64];
-
- void (*get_pixels)(int16_t *block, const uint8_t *pixels, ptrdiff_t linesize);
- void (*fdct[2])(int16_t *block);
- void (*idct_put[2])(uint8_t *dest, ptrdiff_t stride, int16_t *block);
- me_cmp_func ildct_cmp;
- DVwork_chunk work_chunks[4 * 12 * 27];
- uint32_t idct_factor[2 * 4 * 16 * 64];
- IDCTDSPContext idsp;
-
- int quant_deadzone;
-} DVVideoContext;
-
-enum dv_section_type {
- dv_sect_header = 0x1f,
- dv_sect_subcode = 0x3f,
- dv_sect_vaux = 0x56,
- dv_sect_audio = 0x76,
- dv_sect_video = 0x96,
+enum DVSectionType {
+ DV_SECT_HEADER = 0x1f,
+ DV_SECT_SUBCODE = 0x3f,
+ DV_SECT_VAUX = 0x56,
+ DV_SECT_AUDIO = 0x76,
+ DV_SECT_VIDEO = 0x96,
};
-enum dv_pack_type {
- dv_header525 = 0x3f, /* see dv_write_pack for important details on */
- dv_header625 = 0xbf, /* these two packs */
- dv_timecode = 0x13,
- dv_audio_source = 0x50,
- dv_audio_control = 0x51,
- dv_audio_recdate = 0x52,
- dv_audio_rectime = 0x53,
- dv_video_source = 0x60,
- dv_video_control = 0x61,
- dv_video_recdate = 0x62,
- dv_video_rectime = 0x63,
- dv_unknown_pack = 0xff,
+enum DVPackType {
+ DV_HEADER525 = 0x3f, /* see dv_write_pack for important details on */
+ DV_HEADER625 = 0xbf, /* these two packs */
+ DV_TIMECODE = 0x13,
+ DV_AUDIO_SOURCE = 0x50,
+ DV_AUDIO_CONTROL = 0x51,
+ DV_AUDIO_RECDATE = 0x52,
+ DV_AUDIO_RECTIME = 0x53,
+ DV_VIDEO_SOURCE = 0x60,
+ DV_VIDEO_CONTROL = 0x61,
+ DV_VIDEO_RECDATE = 0x62,
+ DV_VIDEO_RECTIME = 0x63,
+ DV_UNKNOWN_PACK = 0xff,
};
#define DV_PROFILE_IS_HD(p) ((p)->video_stype & 0x10)
@@ -95,32 +65,4 @@ enum dv_pack_type {
*/
#define DV_MAX_BPM 8
-int ff_dv_init_dynamic_tables(DVVideoContext *s, const AVDVProfile *d);
-
-int ff_dvvideo_init(AVCodecContext *avctx);
-
-static inline int dv_work_pool_size(const AVDVProfile *d)
-{
- int size = d->n_difchan * d->difseg_size * 27;
- if (DV_PROFILE_IS_1080i50(d))
- size -= 3 * 27;
- if (DV_PROFILE_IS_720p50(d))
- size -= 4 * 27;
- return size;
-}
-
-static inline void dv_calculate_mb_xy(DVVideoContext *s,
- DVwork_chunk *work_chunk,
- int m, int *mb_x, int *mb_y)
-{
- *mb_x = work_chunk->mb_coordinates[m] & 0xff;
- *mb_y = work_chunk->mb_coordinates[m] >> 8;
-
- /* We work with 720p frames split in half.
- * The odd half-frame (chan == 2,3) is displaced :-( */
- if (s->sys->height == 720 && !(s->buf[1] & 0x0C))
- /* shifting the Y coordinate down by 72/2 macro blocks */
- *mb_y -= (*mb_y > 17) ? 18 : -72;
-}
-
#endif /* AVCODEC_DV_H */
diff --git a/libavcodec/dv_internal.h b/libavcodec/dv_internal.h
new file mode 100644
index 000000000..4b4151c88
--- /dev/null
+++ b/libavcodec/dv_internal.h
@@ -0,0 +1,62 @@
+/*
+ * DV encoder/decoder shared code
+ * Copyright (c) 2002 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_DV_INTERNAL_H
+#define AVCODEC_DV_INTERNAL_H
+
+#include
+
+#include "dv.h"
+#include "dv_profile.h"
+
+typedef struct DVwork_chunk {
+ uint16_t buf_offset;
+ uint16_t mb_coordinates[5];
+} DVwork_chunk;
+
+int ff_dv_init_dynamic_tables(DVwork_chunk *work_chunks, const AVDVProfile *d);
+
+static inline int dv_work_pool_size(const AVDVProfile *d)
+{
+ int size = d->n_difchan * d->difseg_size * 27;
+ if (DV_PROFILE_IS_1080i50(d))
+ size -= 3 * 27;
+ if (DV_PROFILE_IS_720p50(d))
+ size -= 4 * 27;
+ return size;
+}
+
+static inline void dv_calculate_mb_xy(const AVDVProfile *sys,
+ const uint8_t *buf,
+ const DVwork_chunk *work_chunk,
+ int m, int *mb_x, int *mb_y)
+{
+ *mb_x = work_chunk->mb_coordinates[m] & 0xff;
+ *mb_y = work_chunk->mb_coordinates[m] >> 8;
+
+ /* We work with 720p frames split in half.
+ * The odd half-frame (chan == 2,3) is displaced :-( */
+ if (sys->height == 720 && !(buf[1] & 0x0C))
+ /* shifting the Y coordinate down by 72/2 macro blocks */
+ *mb_y -= (*mb_y > 17) ? 18 : -72;
+}
+
+#endif // AVCODEC_DV_INTERNAL_H
diff --git a/libavcodec/dv_tablegen.h b/libavcodec/dv_tablegen.h
index 941b5572b..7f0ab53fa 100644
--- a/libavcodec/dv_tablegen.h
+++ b/libavcodec/dv_tablegen.h
@@ -50,8 +50,11 @@ static struct dv_vlc_pair dv_vlc_map[DV_VLC_MAP_RUN_SIZE][DV_VLC_MAP_LEV_SIZE];
static av_cold void dv_vlc_map_tableinit(void)
{
+ uint32_t code = 0;
int i, j;
- for (i = 0; i < NB_DV_VLC - 1; i++) {
+ for (int i = 0; i < NB_DV_VLC; i++) {
+ uint32_t cur_code = code >> (32 - ff_dv_vlc_len[i]);
+ code += 1U << (32 - ff_dv_vlc_len[i]);
if (ff_dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE)
continue;
#if CONFIG_SMALL
@@ -63,7 +66,7 @@ static av_cold void dv_vlc_map_tableinit(void)
continue;
dv_vlc_map[ff_dv_vlc_run[i]][ff_dv_vlc_level[i]].vlc =
- ff_dv_vlc_bits[i] << (!!ff_dv_vlc_level[i]);
+ cur_code << (!!ff_dv_vlc_level[i]);
dv_vlc_map[ff_dv_vlc_run[i]][ff_dv_vlc_level[i]].size =
ff_dv_vlc_len[i] + (!!ff_dv_vlc_level[i]);
}
diff --git a/libavcodec/dvaudiodec.c b/libavcodec/dvaudiodec.c
index 56d9c3573..1c8344095 100644
--- a/libavcodec/dvaudiodec.c
+++ b/libavcodec/dvaudiodec.c
@@ -22,7 +22,7 @@
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "dvaudio.h"
typedef struct DVAudioContext {
@@ -120,12 +120,11 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_dvaudio_decoder = {
.p.name = "dvaudio",
- .p.long_name = NULL_IF_CONFIG_SMALL("Ulead DV Audio"),
+ CODEC_LONG_NAME("Ulead DV Audio"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_DVAUDIO,
.init = decode_init,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
.priv_data_size = sizeof(DVAudioContext),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/dvbsub.c b/libavcodec/dvbsub.c
deleted file mode 100644
index 5c081f2b7..000000000
--- a/libavcodec/dvbsub.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * DVB subtitle encoding
- * Copyright (c) 2005 Fabrice Bellard
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "avcodec.h"
-#include "bytestream.h"
-#include "libavutil/colorspace.h"
-
-typedef struct DVBSubtitleContext {
- int object_version;
-} DVBSubtitleContext;
-
-#define PUTBITS2(val)\
-{\
- bitbuf |= (val) << bitcnt;\
- bitcnt -= 2;\
- if (bitcnt < 0) {\
- bitcnt = 6;\
- *q++ = bitbuf;\
- bitbuf = 0;\
- }\
-}
-
-static int dvb_encode_rle2(uint8_t **pq, int buf_size,
- const uint8_t *bitmap, int linesize,
- int w, int h)
-{
- uint8_t *q, *line_begin;
- unsigned int bitbuf;
- int bitcnt;
- int x, y, len, x1, v, color;
-
- q = *pq;
-
- for(y = 0; y < h; y++) {
- // Worst case line is 3 bits per value + 4 bytes overhead
- if (buf_size * 8 < w * 3 + 32)
- return AVERROR_BUFFER_TOO_SMALL;
- line_begin = q;
- *q++ = 0x10;
- bitbuf = 0;
- bitcnt = 6;
-
- x = 0;
- while (x < w) {
- x1 = x;
- color = bitmap[x1++];
- while (x1 < w && bitmap[x1] == color)
- x1++;
- len = x1 - x;
- if (color == 0 && len == 2) {
- PUTBITS2(0);
- PUTBITS2(0);
- PUTBITS2(1);
- } else if (len >= 3 && len <= 10) {
- v = len - 3;
- PUTBITS2(0);
- PUTBITS2((v >> 2) | 2);
- PUTBITS2(v & 3);
- PUTBITS2(color);
- } else if (len >= 12 && len <= 27) {
- v = len - 12;
- PUTBITS2(0);
- PUTBITS2(0);
- PUTBITS2(2);
- PUTBITS2(v >> 2);
- PUTBITS2(v & 3);
- PUTBITS2(color);
- } else if (len >= 29) {
- /* length = 29 ... 284 */
- if (len > 284)
- len = 284;
- v = len - 29;
- PUTBITS2(0);
- PUTBITS2(0);
- PUTBITS2(3);
- PUTBITS2((v >> 6));
- PUTBITS2((v >> 4) & 3);
- PUTBITS2((v >> 2) & 3);
- PUTBITS2(v & 3);
- PUTBITS2(color);
- } else {
- PUTBITS2(color);
- if (color == 0) {
- PUTBITS2(1);
- }
- len = 1;
- }
- x += len;
- }
- /* end of line */
- PUTBITS2(0);
- PUTBITS2(0);
- PUTBITS2(0);
- if (bitcnt != 6) {
- *q++ = bitbuf;
- }
- *q++ = 0xf0;
- bitmap += linesize;
- buf_size -= q - line_begin;
- }
- len = q - *pq;
- *pq = q;
- return len;
-}
-
-#define PUTBITS4(val)\
-{\
- bitbuf |= (val) << bitcnt;\
- bitcnt -= 4;\
- if (bitcnt < 0) {\
- bitcnt = 4;\
- *q++ = bitbuf;\
- bitbuf = 0;\
- }\
-}
-
-/* some DVB decoders only implement 4 bits/pixel */
-static int dvb_encode_rle4(uint8_t **pq, int buf_size,
- const uint8_t *bitmap, int linesize,
- int w, int h)
-{
- uint8_t *q, *line_begin;
- unsigned int bitbuf;
- int bitcnt;
- int x, y, len, x1, v, color;
-
- q = *pq;
-
- for(y = 0; y < h; y++) {
- // Worst case line is 6 bits per value, + 4 bytes overhead
- if (buf_size * 8 < w * 6 + 32)
- return AVERROR_BUFFER_TOO_SMALL;
- line_begin = q;
- *q++ = 0x11;
- bitbuf = 0;
- bitcnt = 4;
-
- x = 0;
- while (x < w) {
- x1 = x;
- color = bitmap[x1++];
- while (x1 < w && bitmap[x1] == color)
- x1++;
- len = x1 - x;
- if (color == 0 && len == 2) {
- PUTBITS4(0);
- PUTBITS4(0xd);
- } else if (color == 0 && (len >= 3 && len <= 9)) {
- PUTBITS4(0);
- PUTBITS4(len - 2);
- } else if (len >= 4 && len <= 7) {
- PUTBITS4(0);
- PUTBITS4(8 + len - 4);
- PUTBITS4(color);
- } else if (len >= 9 && len <= 24) {
- PUTBITS4(0);
- PUTBITS4(0xe);
- PUTBITS4(len - 9);
- PUTBITS4(color);
- } else if (len >= 25) {
- if (len > 280)
- len = 280;
- v = len - 25;
- PUTBITS4(0);
- PUTBITS4(0xf);
- PUTBITS4(v >> 4);
- PUTBITS4(v & 0xf);
- PUTBITS4(color);
- } else {
- PUTBITS4(color);
- if (color == 0) {
- PUTBITS4(0xc);
- }
- len = 1;
- }
- x += len;
- }
- /* end of line */
- PUTBITS4(0);
- PUTBITS4(0);
- if (bitcnt != 4) {
- *q++ = bitbuf;
- }
- *q++ = 0xf0;
- bitmap += linesize;
- buf_size -= q - line_begin;
- }
- len = q - *pq;
- *pq = q;
- return len;
-}
-
-static int dvb_encode_rle8(uint8_t **pq, int buf_size,
- const uint8_t *bitmap, int linesize,
- int w, int h)
-{
- uint8_t *q, *line_begin;
- int x, y, len, x1, color;
-
- q = *pq;
-
- for (y = 0; y < h; y++) {
- // Worst case line is 12 bits per value, + 3 bytes overhead
- if (buf_size * 8 < w * 12 + 24)
- return AVERROR_BUFFER_TOO_SMALL;
- line_begin = q;
- *q++ = 0x12;
-
- x = 0;
- while (x < w) {
- x1 = x;
- color = bitmap[x1++];
- while (x1 < w && bitmap[x1] == color)
- x1++;
- len = x1 - x;
- if (len == 1 && color) {
- // 00000001 to 11111111 1 pixel in colour x
- *q++ = color;
- } else {
- if (color == 0x00) {
- // 00000000 0LLLLLLL L pixels (1-127) in colour 0 (L > 0)
- len = FFMIN(len, 127);
- *q++ = 0x00;
- *q++ = len;
- } else if (len > 2) {
- // 00000000 1LLLLLLL CCCCCCCC L pixels (3-127) in colour C (L > 2)
- len = FFMIN(len, 127);
- *q++ = 0x00;
- *q++ = 0x80+len;
- *q++ = color;
- }
- else if (len == 2) {
- *q++ = color;
- *q++ = color;
- } else {
- *q++ = color;
- len = 1;
- }
- }
- x += len;
- }
- /* end of line */
- // 00000000 end of 8-bit/pixel_code_string
- *q++ = 0x00;
- *q++ = 0xf0;
- bitmap += linesize;
- buf_size -= q - line_begin;
- }
- len = q - *pq;
- *pq = q;
- return len;
-}
-
-static int encode_dvb_subtitles(AVCodecContext *avctx,
- uint8_t *outbuf, int buf_size,
- const AVSubtitle *h)
-{
- DVBSubtitleContext *s = avctx->priv_data;
- uint8_t *q, *pseg_len;
- int page_id, region_id, clut_id, object_id, i, bpp_index, page_state;
-
-
- q = outbuf;
-
- page_id = 1;
-
- if (h->num_rects && !h->rects)
- return AVERROR(EINVAL);
-
- if (avctx->width > 0 && avctx->height > 0) {
- if (buf_size < 11)
- return AVERROR_BUFFER_TOO_SMALL;
- /* display definition segment */
- *q++ = 0x0f; /* sync_byte */
- *q++ = 0x14; /* segment_type */
- bytestream_put_be16(&q, page_id);
- pseg_len = q;
- q += 2; /* segment length */
- *q++ = 0x00; /* dds version number & display window flag */
- bytestream_put_be16(&q, avctx->width - 1); /* display width */
- bytestream_put_be16(&q, avctx->height - 1); /* display height */
- bytestream_put_be16(&pseg_len, q - pseg_len - 2);
- buf_size -= 11;
- }
-
- /* page composition segment */
-
- if (buf_size < 8 + h->num_rects * 6)
- return AVERROR_BUFFER_TOO_SMALL;
- *q++ = 0x0f; /* sync_byte */
- *q++ = 0x10; /* segment_type */
- bytestream_put_be16(&q, page_id);
- pseg_len = q;
- q += 2; /* segment length */
- *q++ = 30; /* page_timeout (seconds) */
- page_state = 2; /* mode change */
- /* page_version = 0 + page_state */
- *q++ = (s->object_version << 4) | (page_state << 2) | 3;
-
- for (region_id = 0; region_id < h->num_rects; region_id++) {
- *q++ = region_id;
- *q++ = 0xff; /* reserved */
- bytestream_put_be16(&q, h->rects[region_id]->x); /* left pos */
- bytestream_put_be16(&q, h->rects[region_id]->y); /* top pos */
- }
-
- bytestream_put_be16(&pseg_len, q - pseg_len - 2);
- buf_size -= 8 + h->num_rects * 6;
-
- if (h->num_rects) {
- for (clut_id = 0; clut_id < h->num_rects; clut_id++) {
- if (buf_size < 6 + h->rects[clut_id]->nb_colors * 6)
- return AVERROR_BUFFER_TOO_SMALL;
-
- /* CLUT segment */
-
- if (h->rects[clut_id]->nb_colors <= 4) {
- /* 2 bpp, some decoders do not support it correctly */
- bpp_index = 0;
- } else if (h->rects[clut_id]->nb_colors <= 16) {
- /* 4 bpp, standard encoding */
- bpp_index = 1;
- } else if (h->rects[clut_id]->nb_colors <= 256) {
- /* 8 bpp, standard encoding */
- bpp_index = 2;
- } else {
- return AVERROR(EINVAL);
- }
-
-
- /* CLUT segment */
- *q++ = 0x0f; /* sync byte */
- *q++ = 0x12; /* CLUT definition segment */
- bytestream_put_be16(&q, page_id);
- pseg_len = q;
- q += 2; /* segment length */
- *q++ = clut_id;
- *q++ = (0 << 4) | 0xf; /* version = 0 */
-
- for(i = 0; i < h->rects[clut_id]->nb_colors; i++) {
- *q++ = i; /* clut_entry_id */
- *q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */
- {
- int a, r, g, b;
- uint32_t x= ((uint32_t*)h->rects[clut_id]->data[1])[i];
- a = (x >> 24) & 0xff;
- r = (x >> 16) & 0xff;
- g = (x >> 8) & 0xff;
- b = (x >> 0) & 0xff;
-
- *q++ = RGB_TO_Y_CCIR(r, g, b);
- *q++ = RGB_TO_V_CCIR(r, g, b, 0);
- *q++ = RGB_TO_U_CCIR(r, g, b, 0);
- *q++ = 255 - a;
- }
- }
-
- bytestream_put_be16(&pseg_len, q - pseg_len - 2);
- buf_size -= 6 + h->rects[clut_id]->nb_colors * 6;
- }
- }
-
- if (buf_size < h->num_rects * 22)
- return AVERROR_BUFFER_TOO_SMALL;
- for (region_id = 0; region_id < h->num_rects; region_id++) {
-
- /* region composition segment */
-
- if (h->rects[region_id]->nb_colors <= 4) {
- /* 2 bpp, some decoders do not support it correctly */
- bpp_index = 0;
- } else if (h->rects[region_id]->nb_colors <= 16) {
- /* 4 bpp, standard encoding */
- bpp_index = 1;
- } else if (h->rects[region_id]->nb_colors <= 256) {
- /* 8 bpp, standard encoding */
- bpp_index = 2;
- } else {
- return AVERROR(EINVAL);
- }
-
- *q++ = 0x0f; /* sync_byte */
- *q++ = 0x11; /* segment_type */
- bytestream_put_be16(&q, page_id);
- pseg_len = q;
- q += 2; /* segment length */
- *q++ = region_id;
- *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */
- bytestream_put_be16(&q, h->rects[region_id]->w); /* region width */
- bytestream_put_be16(&q, h->rects[region_id]->h); /* region height */
- *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03;
- *q++ = region_id; /* clut_id == region_id */
- *q++ = 0; /* 8 bit fill colors */
- *q++ = 0x03; /* 4 bit and 2 bit fill colors */
-
- bytestream_put_be16(&q, region_id); /* object_id == region_id */
- *q++ = (0 << 6) | (0 << 4);
- *q++ = 0;
- *q++ = 0xf0;
- *q++ = 0;
-
- bytestream_put_be16(&pseg_len, q - pseg_len - 2);
- }
- buf_size -= h->num_rects * 22;
-
- if (h->num_rects) {
-
- for (object_id = 0; object_id < h->num_rects; object_id++) {
- int (*dvb_encode_rle)(uint8_t **pq, int buf_size,
- const uint8_t *bitmap, int linesize,
- int w, int h);
-
- if (buf_size < 13)
- return AVERROR_BUFFER_TOO_SMALL;
-
- /* bpp_index maths */
- if (h->rects[object_id]->nb_colors <= 4) {
- /* 2 bpp, some decoders do not support it correctly */
- dvb_encode_rle = dvb_encode_rle2;
- } else if (h->rects[object_id]->nb_colors <= 16) {
- /* 4 bpp, standard encoding */
- dvb_encode_rle = dvb_encode_rle4;
- } else if (h->rects[object_id]->nb_colors <= 256) {
- /* 8 bpp, standard encoding */
- dvb_encode_rle = dvb_encode_rle8;
- } else {
- return AVERROR(EINVAL);
- }
-
- /* Object Data segment */
- *q++ = 0x0f; /* sync byte */
- *q++ = 0x13;
- bytestream_put_be16(&q, page_id);
- pseg_len = q;
- q += 2; /* segment length */
-
- bytestream_put_be16(&q, object_id);
- *q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0,
- onject_coding_method,
- non_modifying_color_flag */
- {
- uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr;
- int ret;
-
- ptop_field_len = q;
- q += 2;
- pbottom_field_len = q;
- q += 2;
- buf_size -= 13;
-
- top_ptr = q;
- ret = dvb_encode_rle(&q, buf_size,
- h->rects[object_id]->data[0],
- h->rects[object_id]->w * 2,
- h->rects[object_id]->w,
- h->rects[object_id]->h >> 1);
- if (ret < 0)
- return ret;
- buf_size -= ret;
- bottom_ptr = q;
- ret = dvb_encode_rle(&q, buf_size,
- h->rects[object_id]->data[0] + h->rects[object_id]->w,
- h->rects[object_id]->w * 2,
- h->rects[object_id]->w,
- h->rects[object_id]->h >> 1);
- if (ret < 0)
- return ret;
- buf_size -= ret;
-
- bytestream_put_be16(&ptop_field_len, bottom_ptr - top_ptr);
- bytestream_put_be16(&pbottom_field_len, q - bottom_ptr);
- }
-
- bytestream_put_be16(&pseg_len, q - pseg_len - 2);
- }
- }
-
- /* end of display set segment */
-
- if (buf_size < 6)
- return AVERROR_BUFFER_TOO_SMALL;
- *q++ = 0x0f; /* sync_byte */
- *q++ = 0x80; /* segment_type */
- bytestream_put_be16(&q, page_id);
- pseg_len = q;
- q += 2; /* segment length */
-
- bytestream_put_be16(&pseg_len, q - pseg_len - 2);
- buf_size -= 6;
-
- s->object_version = (s->object_version + 1) & 0xf;
- return q - outbuf;
-}
-
-static int dvbsub_encode(AVCodecContext *avctx,
- unsigned char *buf, int buf_size,
- const AVSubtitle *sub)
-{
- int ret;
-
- ret = encode_dvb_subtitles(avctx, buf, buf_size, sub);
- return ret;
-}
-
-AVCodec ff_dvbsub_encoder = {
- .name = "dvbsub",
- .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
- .type = AVMEDIA_TYPE_SUBTITLE,
- .id = AV_CODEC_ID_DVB_SUBTITLE,
- .priv_data_size = sizeof(DVBSubtitleContext),
- .encode_sub = dvbsub_encode,
-};
diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c
index 4d4007ffd..bcc607d1d 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -23,7 +23,7 @@
#include "get_bits.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "libavutil/colorspace.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
@@ -1571,7 +1571,7 @@ static const AVClass dvbsubdec_class = {
const FFCodec ff_dvbsub_decoder = {
.p.name = "dvbsub",
- .p.long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
+ CODEC_LONG_NAME("DVB subtitles"),
.p.type = AVMEDIA_TYPE_SUBTITLE,
.p.id = AV_CODEC_ID_DVB_SUBTITLE,
.priv_data_size = sizeof(DVBSubContext),
@@ -1579,5 +1579,4 @@ const FFCodec ff_dvbsub_decoder = {
.close = dvbsub_close_decoder,
FF_CODEC_DECODE_SUB_CB(dvbsub_decode),
.p.priv_class = &dvbsubdec_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/dvbsubenc.c b/libavcodec/dvbsubenc.c
index 06087b058..822e3a530 100644
--- a/libavcodec/dvbsubenc.c
+++ b/libavcodec/dvbsubenc.c
@@ -508,7 +508,7 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size,
const FFCodec ff_dvbsub_encoder = {
.p.name = "dvbsub",
- .p.long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
+ CODEC_LONG_NAME("DVB subtitles"),
.p.type = AVMEDIA_TYPE_SUBTITLE,
.p.id = AV_CODEC_ID_DVB_SUBTITLE,
.priv_data_size = sizeof(DVBSubtitleContext),
diff --git a/libavcodec/dvdata.c b/libavcodec/dvdata.c
index 231569a32..0cd10aed1 100644
--- a/libavcodec/dvdata.c
+++ b/libavcodec/dvdata.c
@@ -74,63 +74,8 @@ const uint8_t ff_dv_quant_offset[4] = { 6, 3, 0, 1 };
* between (run, level) and vlc is not 1-1. So you have to watch out for that
* when building misc. tables. E.g. (1, 0) can be either 0x7cf or 0x1f82.
*/
-const uint16_t ff_dv_vlc_bits[NB_DV_VLC] = {
- 0x0000, 0x0002, 0x0007, 0x0008, 0x0009, 0x0014, 0x0015, 0x0016,
- 0x0017, 0x0030, 0x0031, 0x0032, 0x0033, 0x0068, 0x0069, 0x006a,
- 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x00e0, 0x00e1, 0x00e2,
- 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea,
- 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x01e0, 0x01e1, 0x01e2,
- 0x01e3, 0x01e4, 0x01e5, 0x01e6, 0x01e7, 0x01e8, 0x01e9, 0x01ea,
- 0x01eb, 0x01ec, 0x01ed, 0x01ee, 0x01ef, 0x03e0, 0x03e1, 0x03e2,
- 0x03e3, 0x03e4, 0x03e5, 0x03e6, 0x07ce, 0x07cf, 0x07d0, 0x07d1,
- 0x07d2, 0x07d3, 0x07d4, 0x07d5, 0x0fac, 0x0fad, 0x0fae, 0x0faf,
- 0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7,
- 0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf,
- 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87,
- 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f,
- 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97,
- 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f,
- 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7,
- 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf,
- 0x1fb0, 0x1fb1, 0x1fb2, 0x1fb3, 0x1fb4, 0x1fb5, 0x1fb6, 0x1fb7,
- 0x1fb8, 0x1fb9, 0x1fba, 0x1fbb, 0x1fbc, 0x1fbd, 0x1fbe, 0x1fbf,
- 0x7f00, 0x7f01, 0x7f02, 0x7f03, 0x7f04, 0x7f05, 0x7f06, 0x7f07,
- 0x7f08, 0x7f09, 0x7f0a, 0x7f0b, 0x7f0c, 0x7f0d, 0x7f0e, 0x7f0f,
- 0x7f10, 0x7f11, 0x7f12, 0x7f13, 0x7f14, 0x7f15, 0x7f16, 0x7f17,
- 0x7f18, 0x7f19, 0x7f1a, 0x7f1b, 0x7f1c, 0x7f1d, 0x7f1e, 0x7f1f,
- 0x7f20, 0x7f21, 0x7f22, 0x7f23, 0x7f24, 0x7f25, 0x7f26, 0x7f27,
- 0x7f28, 0x7f29, 0x7f2a, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2e, 0x7f2f,
- 0x7f30, 0x7f31, 0x7f32, 0x7f33, 0x7f34, 0x7f35, 0x7f36, 0x7f37,
- 0x7f38, 0x7f39, 0x7f3a, 0x7f3b, 0x7f3c, 0x7f3d, 0x7f3e, 0x7f3f,
- 0x7f40, 0x7f41, 0x7f42, 0x7f43, 0x7f44, 0x7f45, 0x7f46, 0x7f47,
- 0x7f48, 0x7f49, 0x7f4a, 0x7f4b, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f4f,
- 0x7f50, 0x7f51, 0x7f52, 0x7f53, 0x7f54, 0x7f55, 0x7f56, 0x7f57,
- 0x7f58, 0x7f59, 0x7f5a, 0x7f5b, 0x7f5c, 0x7f5d, 0x7f5e, 0x7f5f,
- 0x7f60, 0x7f61, 0x7f62, 0x7f63, 0x7f64, 0x7f65, 0x7f66, 0x7f67,
- 0x7f68, 0x7f69, 0x7f6a, 0x7f6b, 0x7f6c, 0x7f6d, 0x7f6e, 0x7f6f,
- 0x7f70, 0x7f71, 0x7f72, 0x7f73, 0x7f74, 0x7f75, 0x7f76, 0x7f77,
- 0x7f78, 0x7f79, 0x7f7a, 0x7f7b, 0x7f7c, 0x7f7d, 0x7f7e, 0x7f7f,
- 0x7f80, 0x7f81, 0x7f82, 0x7f83, 0x7f84, 0x7f85, 0x7f86, 0x7f87,
- 0x7f88, 0x7f89, 0x7f8a, 0x7f8b, 0x7f8c, 0x7f8d, 0x7f8e, 0x7f8f,
- 0x7f90, 0x7f91, 0x7f92, 0x7f93, 0x7f94, 0x7f95, 0x7f96, 0x7f97,
- 0x7f98, 0x7f99, 0x7f9a, 0x7f9b, 0x7f9c, 0x7f9d, 0x7f9e, 0x7f9f,
- 0x7fa0, 0x7fa1, 0x7fa2, 0x7fa3, 0x7fa4, 0x7fa5, 0x7fa6, 0x7fa7,
- 0x7fa8, 0x7fa9, 0x7faa, 0x7fab, 0x7fac, 0x7fad, 0x7fae, 0x7faf,
- 0x7fb0, 0x7fb1, 0x7fb2, 0x7fb3, 0x7fb4, 0x7fb5, 0x7fb6, 0x7fb7,
- 0x7fb8, 0x7fb9, 0x7fba, 0x7fbb, 0x7fbc, 0x7fbd, 0x7fbe, 0x7fbf,
- 0x7fc0, 0x7fc1, 0x7fc2, 0x7fc3, 0x7fc4, 0x7fc5, 0x7fc6, 0x7fc7,
- 0x7fc8, 0x7fc9, 0x7fca, 0x7fcb, 0x7fcc, 0x7fcd, 0x7fce, 0x7fcf,
- 0x7fd0, 0x7fd1, 0x7fd2, 0x7fd3, 0x7fd4, 0x7fd5, 0x7fd6, 0x7fd7,
- 0x7fd8, 0x7fd9, 0x7fda, 0x7fdb, 0x7fdc, 0x7fdd, 0x7fde, 0x7fdf,
- 0x7fe0, 0x7fe1, 0x7fe2, 0x7fe3, 0x7fe4, 0x7fe5, 0x7fe6, 0x7fe7,
- 0x7fe8, 0x7fe9, 0x7fea, 0x7feb, 0x7fec, 0x7fed, 0x7fee, 0x7fef,
- 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7,
- 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffd, 0x7ffe, 0x7fff,
- 0x0006,
-};
-
const uint8_t ff_dv_vlc_len[NB_DV_VLC] = {
- 2, 3, 4, 4, 4, 5, 5, 5,
+ 2, 3, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7,
7, 7, 7, 7, 7, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
@@ -181,11 +126,10 @@ const uint8_t ff_dv_vlc_len[NB_DV_VLC] = {
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
- 4,
};
const uint8_t ff_dv_vlc_run[NB_DV_VLC] = {
- 0, 0, 1, 0, 0, 2, 1, 0,
+ 0, 0, 127, 1, 0, 0, 2, 1, 0,
0, 3, 4, 0, 0, 5, 6, 2,
1, 1, 0, 0, 0, 7, 8, 9,
10, 3, 4, 2, 1, 1, 1, 0,
@@ -236,11 +180,10 @@ const uint8_t ff_dv_vlc_run[NB_DV_VLC] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 127,
};
const uint8_t ff_dv_vlc_level[NB_DV_VLC] = {
- 1, 2, 1, 3, 4, 1, 2, 5,
+ 1, 2, 0, 1, 3, 4, 1, 2, 5,
6, 1, 1, 7, 8, 1, 1, 2,
3, 4, 9, 10, 11, 1, 1, 1,
1, 2, 2, 3, 5, 6, 7, 12,
@@ -291,5 +234,4 @@ const uint8_t ff_dv_vlc_level[NB_DV_VLC] = {
232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 244, 245, 246, 247,
248, 249, 250, 251, 252, 253, 254, 255,
- 0,
};
diff --git a/libavcodec/dvdata.h b/libavcodec/dvdata.h
index e0ed043c4..31191a847 100644
--- a/libavcodec/dvdata.h
+++ b/libavcodec/dvdata.h
@@ -27,8 +27,9 @@ extern const uint8_t ff_dv_quant_shifts[22][4];
extern const uint8_t ff_dv_quant_offset[4];
#define NB_DV_VLC 409
+/* The number of entries with value zero in ff_dv_vlc_level. */
+#define NB_DV_ZERO_LEVEL_ENTRIES 72
-extern const uint16_t ff_dv_vlc_bits[NB_DV_VLC];
extern const uint8_t ff_dv_vlc_len[NB_DV_VLC];
extern const uint8_t ff_dv_vlc_run[NB_DV_VLC];
extern const uint8_t ff_dv_vlc_level[NB_DV_VLC];
diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c
index d6f073058..afc4bb0bc 100644
--- a/libavcodec/dvdec.c
+++ b/libavcodec/dvdec.c
@@ -36,19 +36,19 @@
*/
#include "libavutil/avassert.h"
-#include "libavutil/imgutils.h"
#include "libavutil/internal.h"
#include "libavutil/mem_internal.h"
-#include "libavutil/pixdesc.h"
#include "libavutil/thread.h"
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "dv.h"
+#include "dv_internal.h"
#include "dv_profile_internal.h"
#include "dvdata.h"
#include "get_bits.h"
-#include "internal.h"
+#include "idctdsp.h"
#include "put_bits.h"
#include "simple_idct.h"
#include "thread.h"
@@ -63,6 +63,19 @@ typedef struct BlockInfo {
int shift_offset;
} BlockInfo;
+typedef struct DVDecContext {
+ const AVDVProfile *sys;
+ const AVFrame *frame;
+ const uint8_t *buf;
+
+ uint8_t dv_zigzag[2][64];
+ DVwork_chunk work_chunks[4 * 12 * 27];
+ uint32_t idct_factor[2 * 4 * 16 * 64];
+ void (*idct_put[2])(uint8_t *dest, ptrdiff_t stride, int16_t *block);
+
+ IDCTDSPContext idsp;
+} DVDecContext;
+
static const int dv_iweight_bits = 14;
static const uint16_t dv_iweight_88[64] = {
@@ -135,39 +148,35 @@ static const uint16_t dv_iweight_720_c[64] = {
/* XXX: also include quantization */
static RL_VLC_ELEM dv_rl_vlc[1664];
-static void dv_init_static(void)
+static av_cold void dv_init_static(void)
{
VLCElem vlc_buf[FF_ARRAY_ELEMS(dv_rl_vlc)] = { 0 };
VLC dv_vlc = { .table = vlc_buf, .table_allocated = FF_ARRAY_ELEMS(vlc_buf) };
- uint16_t new_dv_vlc_bits[NB_DV_VLC * 2];
- uint8_t new_dv_vlc_len[NB_DV_VLC * 2];
- uint8_t new_dv_vlc_run[NB_DV_VLC * 2];
- int16_t new_dv_vlc_level[NB_DV_VLC * 2];
+ const unsigned offset = FF_ARRAY_ELEMS(dv_rl_vlc) - (2 * NB_DV_VLC - NB_DV_ZERO_LEVEL_ENTRIES);
+ RL_VLC_ELEM *tmp = dv_rl_vlc + offset;
int i, j;
/* it's faster to include sign bit in a generic VLC parsing scheme */
for (i = 0, j = 0; i < NB_DV_VLC; i++, j++) {
- new_dv_vlc_bits[j] = ff_dv_vlc_bits[i];
- new_dv_vlc_len[j] = ff_dv_vlc_len[i];
- new_dv_vlc_run[j] = ff_dv_vlc_run[i];
- new_dv_vlc_level[j] = ff_dv_vlc_level[i];
+ tmp[j].len = ff_dv_vlc_len[i];
+ tmp[j].run = ff_dv_vlc_run[i];
+ tmp[j].level = ff_dv_vlc_level[i];
if (ff_dv_vlc_level[i]) {
- new_dv_vlc_bits[j] <<= 1;
- new_dv_vlc_len[j]++;
+ tmp[j].len++;
j++;
- new_dv_vlc_bits[j] = (ff_dv_vlc_bits[i] << 1) | 1;
- new_dv_vlc_len[j] = ff_dv_vlc_len[i] + 1;
- new_dv_vlc_run[j] = ff_dv_vlc_run[i];
- new_dv_vlc_level[j] = -ff_dv_vlc_level[i];
+ tmp[j].len = ff_dv_vlc_len[i] + 1;
+ tmp[j].run = ff_dv_vlc_run[i];
+ tmp[j].level = -ff_dv_vlc_level[i];
}
}
/* NOTE: as a trick, we use the fact the no codes are unused
* to accelerate the parsing of partial codes */
- init_vlc(&dv_vlc, TEX_VLC_BITS, j, new_dv_vlc_len,
- 1, 1, new_dv_vlc_bits, 2, 2, INIT_VLC_USE_NEW_STATIC);
+ ff_init_vlc_from_lengths(&dv_vlc, TEX_VLC_BITS, j,
+ &tmp[0].len, sizeof(tmp[0]),
+ NULL, 0, 0, 0, INIT_VLC_USE_NEW_STATIC, NULL);
av_assert1(dv_vlc.table_size == 1664);
for (int i = 0; i < dv_vlc.table_size; i++) {
@@ -179,8 +188,9 @@ static void dv_init_static(void)
run = 0;
level = code;
} else {
- run = new_dv_vlc_run[code] + 1;
- level = new_dv_vlc_level[code];
+ av_assert1(i <= code + offset);
+ run = tmp[code].run + 1;
+ level = tmp[code].level;
}
dv_rl_vlc[i].len = len;
dv_rl_vlc[i].level = level;
@@ -188,7 +198,7 @@ static void dv_init_static(void)
}
}
-static void dv_init_weight_tables(DVVideoContext *ctx, const AVDVProfile *d)
+static void dv_init_weight_tables(DVDecContext *ctx, const AVDVProfile *d)
{
int j, i, c, s;
uint32_t *factor1 = &ctx->idct_factor[0],
@@ -237,9 +247,11 @@ static void dv_init_weight_tables(DVVideoContext *ctx, const AVDVProfile *d)
static av_cold int dvvideo_decode_init(AVCodecContext *avctx)
{
static AVOnce init_static_once = AV_ONCE_INIT;
- DVVideoContext *s = avctx->priv_data;
+ DVDecContext *s = avctx->priv_data;
int i;
+ avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
+
ff_idctdsp_init(&s->idsp, avctx);
for (i = 0; i < 64; i++)
@@ -258,7 +270,7 @@ static av_cold int dvvideo_decode_init(AVCodecContext *avctx)
ff_thread_once(&init_static_once, dv_init_static);
- return ff_dvvideo_init(avctx);
+ return 0;
}
/* decode AC coefficients */
@@ -345,7 +357,7 @@ static av_always_inline void put_block_8x4(int16_t *block, uint8_t *av_restrict
}
}
-static void dv100_idct_put_last_row_field_chroma(DVVideoContext *s, uint8_t *data,
+static void dv100_idct_put_last_row_field_chroma(const DVDecContext *s, uint8_t *data,
int stride, int16_t *blocks)
{
s->idsp.idct(blocks + 0*64);
@@ -357,7 +369,7 @@ static void dv100_idct_put_last_row_field_chroma(DVVideoContext *s, uint8_t *dat
put_block_8x4(blocks+1*64 + 4*8, data + 8 + stride, stride<<1);
}
-static void dv100_idct_put_last_row_field_luma(DVVideoContext *s, uint8_t *data,
+static void dv100_idct_put_last_row_field_luma(const DVDecContext *s, uint8_t *data,
int stride, int16_t *blocks)
{
s->idsp.idct(blocks + 0*64);
@@ -378,7 +390,7 @@ static void dv100_idct_put_last_row_field_luma(DVVideoContext *s, uint8_t *data,
/* mb_x and mb_y are in units of 8 pixels */
static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
{
- DVVideoContext *s = avctx->priv_data;
+ const DVDecContext *s = avctx->priv_data;
DVwork_chunk *work_chunk = arg;
int quant, dc, dct_mode, class1, j;
int mb_index, mb_x, mb_y, last_index;
@@ -393,7 +405,7 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
LOCAL_ALIGNED_16(int16_t, sblock, [5 * DV_MAX_BPM], [64]);
LOCAL_ALIGNED_16(uint8_t, mb_bit_buffer, [80 + AV_INPUT_BUFFER_PADDING_SIZE]); /* allow some slack */
LOCAL_ALIGNED_16(uint8_t, vs_bit_buffer, [80 * 5 + AV_INPUT_BUFFER_PADDING_SIZE]); /* allow some slack */
- const int log2_blocksize = 3-s->avctx->lowres;
+ const int log2_blocksize = 3 - avctx->lowres;
int is_field_mode[5];
int vs_bit_buffer_damaged = 0;
int mb_bit_buffer_damaged[5] = {0};
@@ -533,7 +545,7 @@ retry:
block = &sblock[0][0];
mb = mb_data;
for (mb_index = 0; mb_index < 5; mb_index++) {
- dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
+ dv_calculate_mb_xy(s->sys, s->buf, work_chunk, mb_index, &mb_x, &mb_y);
/* idct_put'ting luminance */
if ((s->sys->pix_fmt == AV_PIX_FMT_YUV420P) ||
@@ -612,7 +624,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, AVFrame *frame,
{
uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- DVVideoContext *s = avctx->priv_data;
+ DVDecContext *s = avctx->priv_data;
const uint8_t *vsc_pack;
int apt, is16_9, ret;
const AVDVProfile *sys;
@@ -624,7 +636,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, AVFrame *frame,
}
if (sys != s->sys) {
- ret = ff_dv_init_dynamic_tables(s, sys);
+ ret = ff_dv_init_dynamic_tables(s->work_chunks, sys);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error initializing the work tables.\n");
return ret;
@@ -645,7 +657,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, AVFrame *frame,
/* Determine the codec's sample_aspect ratio from the packet */
vsc_pack = buf + 80 * 5 + 48 + 5;
- if (*vsc_pack == dv_video_control) {
+ if (*vsc_pack == DV_VIDEO_CONTROL) {
apt = buf[4] & 0x07;
is16_9 = (vsc_pack[2] & 0x07) == 0x02 ||
(!apt && (vsc_pack[2] & 0x07) == 0x07);
@@ -656,7 +668,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, AVFrame *frame,
return ret;
/* Determine the codec's field order from the packet */
- if ( *vsc_pack == dv_video_control ) {
+ if ( *vsc_pack == DV_VIDEO_CONTROL ) {
if (avctx->height == 720) {
frame->interlaced_frame = 0;
frame->top_field_first = 0;
@@ -683,13 +695,12 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_dvvideo_decoder = {
.p.name = "dvvideo",
- .p.long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
+ CODEC_LONG_NAME("DV (Digital Video)"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DVVIDEO,
- .priv_data_size = sizeof(DVVideoContext),
+ .priv_data_size = sizeof(DVDecContext),
.init = dvvideo_decode_init,
FF_CODEC_DECODE_CB(dvvideo_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS,
.p.max_lowres = 3,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/dvdsub.c b/libavcodec/dvdsub.c
index 87215d2bd..fb415677d 100644
--- a/libavcodec/dvdsub.c
+++ b/libavcodec/dvdsub.c
@@ -19,10 +19,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "internal.h"
#include "libavutil/avstring.h"
#include
+#include "dvdsub.h"
+
void ff_dvdsub_parse_palette(uint32_t *palette, const char *p)
{
for (int i = 0; i < 16; i++) {
diff --git a/libavcodec/dvdsub.h b/libavcodec/dvdsub.h
new file mode 100644
index 000000000..3f51c3f80
--- /dev/null
+++ b/libavcodec/dvdsub.h
@@ -0,0 +1,26 @@
+/*
+ * 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_DVDSUB_H
+#define AVCODEC_DVDSUB_H
+
+#include
+
+void ff_dvdsub_parse_palette(uint32_t *palette, const char *p);
+
+#endif /* AVCODEC_DVDSUB_H */
diff --git a/libavcodec/dvdsub_parser.c b/libavcodec/dvdsub_parser.c
index 44738a73d..8871b6a38 100644
--- a/libavcodec/dvdsub_parser.c
+++ b/libavcodec/dvdsub_parser.c
@@ -43,7 +43,7 @@ static int dvdsub_parse(AVCodecParserContext *s,
*poutbuf_size = buf_size;
if (pc->packet_index == 0) {
- if (buf_size < 2 || AV_RB16(buf) && buf_size < 6) {
+ if (buf_size < 2 || (AV_RB16(buf) == 0 && buf_size < 6)) {
if (buf_size)
av_log(avctx, AV_LOG_DEBUG, "Parser input %d too small\n", buf_size);
return buf_size;
diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c
index 97f366cc7..a5da0d7b0 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -21,13 +21,14 @@
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
+#include "dvdsub.h"
#include "get_bits.h"
-#include "internal.h"
#include "libavutil/attributes.h"
#include "libavutil/colorspace.h"
+#include "libavutil/file_open.h"
#include "libavutil/opt.h"
-#include "libavutil/imgutils.h"
#include "libavutil/bswap.h"
typedef struct DVDSubContext
@@ -707,7 +708,7 @@ static const AVClass dvdsub_class = {
const FFCodec ff_dvdsub_decoder = {
.p.name = "dvdsub",
- .p.long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
+ CODEC_LONG_NAME("DVD subtitles"),
.p.type = AVMEDIA_TYPE_SUBTITLE,
.p.id = AV_CODEC_ID_DVD_SUBTITLE,
.priv_data_size = sizeof(DVDSubContext),
@@ -715,5 +716,4 @@ const FFCodec ff_dvdsub_decoder = {
FF_CODEC_DECODE_SUB_CB(dvdsub_decode),
.flush = dvdsub_flush,
.p.priv_class = &dvdsub_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/dvdsubenc.c b/libavcodec/dvdsubenc.c
index d29db7d49..d272b5767 100644
--- a/libavcodec/dvdsubenc.c
+++ b/libavcodec/dvdsubenc.c
@@ -21,7 +21,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "dvdsub.h"
#include "libavutil/avassert.h"
#include "libavutil/bprint.h"
#include "libavutil/imgutils.h"
@@ -379,7 +379,7 @@ static int encode_dvd_subtitles(AVCodecContext *avctx,
if (x2 > avctx->width || y2 > avctx->height) {
av_log(avctx, AV_LOG_ERROR, "canvas_size(%d:%d) is too small(%d:%d) for render\n",
avctx->width, avctx->height, x2, y2);
- ret = AVERROR(EINVAL);;
+ ret = AVERROR(EINVAL);
goto fail;
}
*q++ = 0x05;
@@ -502,12 +502,11 @@ static const AVClass dvdsubenc_class = {
const FFCodec ff_dvdsub_encoder = {
.p.name = "dvdsub",
- .p.long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
+ CODEC_LONG_NAME("DVD subtitles"),
.p.type = AVMEDIA_TYPE_SUBTITLE,
.p.id = AV_CODEC_ID_DVD_SUBTITLE,
.init = dvdsub_init,
FF_CODEC_ENCODE_SUB_CB(dvdsub_encode),
.p.priv_class = &dvdsubenc_class,
.priv_data_size = sizeof(DVDSubtitleContext),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/dvenc.c b/libavcodec/dvenc.c
index 2922829dc..11dd5763a 100644
--- a/libavcodec/dvenc.c
+++ b/libavcodec/dvenc.c
@@ -38,6 +38,7 @@
#include "avcodec.h"
#include "codec_internal.h"
#include "dv.h"
+#include "dv_internal.h"
#include "dv_profile_internal.h"
#include "dv_tablegen.h"
#include "encode.h"
@@ -47,14 +48,41 @@
#include "pixblockdsp.h"
#include "put_bits.h"
+typedef struct DVEncContext {
+ const AVClass *class;
+ const AVDVProfile *sys;
+ const AVFrame *frame;
+ AVCodecContext *avctx;
+ uint8_t *buf;
+
+ void (*get_pixels)(int16_t *block, const uint8_t *pixels, ptrdiff_t linesize);
+ void (*fdct[2])(int16_t *block);
+
+ me_cmp_func ildct_cmp;
+ DVwork_chunk work_chunks[4 * 12 * 27];
+
+ int quant_deadzone;
+} DVEncContext;
+
+
static av_cold int dvvideo_encode_init(AVCodecContext *avctx)
{
- DVVideoContext *s = avctx->priv_data;
+ DVEncContext *s = avctx->priv_data;
FDCTDSPContext fdsp;
MECmpContext mecc;
PixblockDSPContext pdsp;
int ret;
+ s->avctx = avctx;
+
+ if (avctx->chroma_sample_location != AVCHROMA_LOC_TOPLEFT) {
+ const char *name = av_chroma_location_name(avctx->chroma_sample_location);
+ av_log(avctx, AV_LOG_WARNING, "Only top-left chroma location is supported "
+ "in DV, input value is: %s\n", name ? name : "unknown");
+ if (avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL)
+ return AVERROR(EINVAL);
+ }
+
s->sys = av_dv_codec_profile2(avctx->width, avctx->height, avctx->pix_fmt, avctx->time_base);
if (!s->sys) {
av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video. "
@@ -64,7 +92,7 @@ static av_cold int dvvideo_encode_init(AVCodecContext *avctx)
return AVERROR(EINVAL);
}
- ret = ff_dv_init_dynamic_tables(s, s->sys);
+ ret = ff_dv_init_dynamic_tables(s->work_chunks, s->sys);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error initializing work tables.\n");
return ret;
@@ -91,7 +119,7 @@ static av_cold int dvvideo_encode_init(AVCodecContext *avctx)
}
#endif
- return ff_dvvideo_init(avctx);
+ return 0;
}
/* bit budget for AC only in 5 MBs */
@@ -217,7 +245,7 @@ static av_always_inline PutBitContext *dv_encode_ac(EncBlockInfo *bi,
return pb;
}
-static av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data,
+static av_always_inline int dv_guess_dct_mode(DVEncContext *s, const uint8_t *data,
ptrdiff_t linesize)
{
if (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
@@ -365,7 +393,7 @@ static const int dv_weight_720[2][64] = {
2661, 2583, 2509, 2394, 2509, 2260, 2260, 2131, }
};
-static av_always_inline int dv_set_class_number_sd(DVVideoContext *s,
+static av_always_inline int dv_set_class_number_sd(DVEncContext *s,
int16_t *blk, EncBlockInfo *bi,
const uint8_t *zigzag_scan,
const int *weight, int bias)
@@ -449,7 +477,7 @@ static av_always_inline int dv_set_class_number_sd(DVVideoContext *s,
/* this function just copies the DCT coefficients and performs
the initial (non-)quantization. */
-static inline void dv_set_class_number_hd(DVVideoContext *s,
+static inline void dv_set_class_number_hd(DVEncContext *s,
int16_t *blk, EncBlockInfo *bi,
const uint8_t *zigzag_scan,
const int *weight, int bias)
@@ -506,8 +534,8 @@ static inline void dv_set_class_number_hd(DVVideoContext *s,
bi->cno = 0;
}
-static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, int linesize,
- DVVideoContext *s, int chroma)
+static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, const uint8_t *data, int linesize,
+ DVEncContext *s, int chroma)
{
LOCAL_ALIGNED_16(int16_t, blk, [64]);
@@ -844,12 +872,12 @@ static inline void dv_revise_cnos(uint8_t *dif, EncBlockInfo *blk, const AVDVPro
static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
{
- DVVideoContext *s = avctx->priv_data;
+ DVEncContext *s = avctx->priv_data;
DVwork_chunk *work_chunk = arg;
int mb_index, i, j;
int mb_x, mb_y, c_offset;
ptrdiff_t linesize, y_stride;
- uint8_t *y_ptr;
+ const uint8_t *y_ptr;
uint8_t *dif, *p;
LOCAL_ALIGNED_8(uint8_t, scratch, [128]);
EncBlockInfo enc_blks[5 * DV_MAX_BPM];
@@ -863,7 +891,7 @@ static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
p = dif = &s->buf[work_chunk->buf_offset * 80];
enc_blk = &enc_blks[0];
for (mb_index = 0; mb_index < 5; mb_index++) {
- dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
+ dv_calculate_mb_xy(s->sys, s->buf, work_chunk, mb_index, &mb_x, &mb_y);
qnos[mb_index] = DV_PROFILE_IS_HD(s->sys) ? 1 : 15;
@@ -908,14 +936,13 @@ static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
c_offset = ((mb_y >> (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->frame->linesize[1] +
(mb_x >> ((s->sys->pix_fmt == AV_PIX_FMT_YUV411P) ? 2 : 1))) * 8;
for (j = 2; j; j--) {
- uint8_t *c_ptr = s->frame->data[j] + c_offset;
+ const uint8_t *c_ptr = s->frame->data[j] + c_offset;
linesize = s->frame->linesize[j];
y_stride = (mb_y == 134) ? 8 : (s->frame->linesize[j] * (1 << (3*!enc_blk->dct_mode)));
if (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
- uint8_t *d;
uint8_t *b = scratch;
for (i = 0; i < 8; i++) {
- d = c_ptr + linesize * 8;
+ const uint8_t *d = c_ptr + linesize * 8;
b[0] = c_ptr[0];
b[1] = c_ptr[1];
b[2] = c_ptr[2];
@@ -993,7 +1020,7 @@ static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
return 0;
}
-static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
+static inline int dv_write_pack(enum DVPackType pack_id, DVEncContext *c,
uint8_t *buf)
{
/*
@@ -1031,8 +1058,8 @@ static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
buf[0] = (uint8_t) pack_id;
switch (pack_id) {
- case dv_header525: /* I can't imagine why these two weren't defined as real */
- case dv_header625: /* packs in SMPTE314M -- they definitely look like ones */
+ case DV_HEADER525: /* I can't imagine why these two weren't defined as real */
+ case DV_HEADER625: /* packs in SMPTE314M -- they definitely look like ones */
buf[1] = 0xf8 | /* reserved -- always 1 */
(apt & 0x07); /* APT: Track application ID */
buf[2] = (0 << 7) | /* TF1: audio data is 0 - valid; 1 - invalid */
@@ -1045,7 +1072,7 @@ static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
(0x0f << 3) | /* reserved -- always 1 */
(apt & 0x07); /* AP3: Subcode application ID */
break;
- case dv_video_source:
+ case DV_VIDEO_SOURCE:
buf[1] = 0xff; /* reserved -- always 1 */
buf[2] = (1 << 7) | /* B/W: 0 - b/w, 1 - color */
(1 << 6) | /* following CLF is valid - 0, invalid - 1 */
@@ -1056,7 +1083,7 @@ static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
c->sys->video_stype; /* signal type video compression */
buf[4] = 0xff; /* VISC: 0xff -- no information */
break;
- case dv_video_control:
+ case DV_VIDEO_CONTROL:
buf[1] = (0 << 6) | /* Copy generation management (CGMS) 0 -- free */
0x3f; /* reserved -- always 1 */
buf[2] = 0xc8 | /* reserved -- always b11001xxx */
@@ -1077,7 +1104,7 @@ static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
return 5;
}
-static inline int dv_write_dif_id(enum dv_section_type t, uint8_t chan_num,
+static inline int dv_write_dif_id(enum DVSectionType t, uint8_t chan_num,
uint8_t seq_num, uint8_t dif_num,
uint8_t *buf)
{
@@ -1113,25 +1140,25 @@ static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t *buf)
return 3;
}
-static void dv_format_frame(DVVideoContext *c, uint8_t *buf)
+static void dv_format_frame(DVEncContext *c, uint8_t *buf)
{
int chan, i, j, k;
/* We work with 720p frames split in half. The odd half-frame is chan 2,3 */
- int chan_offset = 2*(c->sys->height == 720 && c->avctx->frame_number & 1);
+ int chan_offset = 2*(c->sys->height == 720 && c->avctx->frame_num & 1);
for (chan = 0; chan < c->sys->n_difchan; chan++) {
for (i = 0; i < c->sys->difseg_size; i++) {
memset(buf, 0xff, 80 * 6); /* first 6 DIF blocks are for control data */
/* DV header: 1DIF */
- buf += dv_write_dif_id(dv_sect_header, chan+chan_offset, i, 0, buf);
- buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525),
+ buf += dv_write_dif_id(DV_SECT_HEADER, chan+chan_offset, i, 0, buf);
+ buf += dv_write_pack((c->sys->dsf ? DV_HEADER625 : DV_HEADER525),
c, buf);
buf += 72; /* unused bytes */
/* DV subcode: 2DIFs */
for (j = 0; j < 2; j++) {
- buf += dv_write_dif_id(dv_sect_subcode, chan+chan_offset, i, j, buf);
+ buf += dv_write_dif_id(DV_SECT_SUBCODE, chan+chan_offset, i, j, buf);
for (k = 0; k < 6; k++)
buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size / 2), buf) + 5;
buf += 29; /* unused bytes */
@@ -1139,12 +1166,12 @@ static void dv_format_frame(DVVideoContext *c, uint8_t *buf)
/* DV VAUX: 3DIFS */
for (j = 0; j < 3; j++) {
- buf += dv_write_dif_id(dv_sect_vaux, chan+chan_offset, i, j, buf);
- buf += dv_write_pack(dv_video_source, c, buf);
- buf += dv_write_pack(dv_video_control, c, buf);
+ buf += dv_write_dif_id(DV_SECT_VAUX, chan+chan_offset, i, j, buf);
+ buf += dv_write_pack(DV_VIDEO_SOURCE, c, buf);
+ buf += dv_write_pack(DV_VIDEO_CONTROL, c, buf);
buf += 7 * 5;
- buf += dv_write_pack(dv_video_source, c, buf);
- buf += dv_write_pack(dv_video_control, c, buf);
+ buf += dv_write_pack(DV_VIDEO_SOURCE, c, buf);
+ buf += dv_write_pack(DV_VIDEO_CONTROL, c, buf);
buf += 4 * 5 + 2; /* unused bytes */
}
@@ -1152,10 +1179,10 @@ static void dv_format_frame(DVVideoContext *c, uint8_t *buf)
for (j = 0; j < 135; j++) {
if (j % 15 == 0) {
memset(buf, 0xff, 80);
- buf += dv_write_dif_id(dv_sect_audio, chan+chan_offset, i, j/15, buf);
+ buf += dv_write_dif_id(DV_SECT_AUDIO, chan+chan_offset, i, j/15, buf);
buf += 77; /* audio control & shuffled PCM audio */
}
- buf += dv_write_dif_id(dv_sect_video, chan+chan_offset, i, j, buf);
+ buf += dv_write_dif_id(DV_SECT_VIDEO, chan+chan_offset, i, j, buf);
buf += 77; /* 1 video macroblock: 1 bytes control
* 4 * 14 bytes Y 8x8 data
* 10 bytes Cr 8x8 data
@@ -1168,7 +1195,7 @@ static void dv_format_frame(DVVideoContext *c, uint8_t *buf)
static int dvvideo_encode_frame(AVCodecContext *c, AVPacket *pkt,
const AVFrame *frame, int *got_packet)
{
- DVVideoContext *s = c->priv_data;
+ DVEncContext *s = c->priv_data;
int ret;
if ((ret = ff_get_encode_buffer(c, pkt, s->sys->frame_size, 0)) < 0)
@@ -1193,7 +1220,7 @@ static int dvvideo_encode_frame(AVCodecContext *c, AVPacket *pkt,
}
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
-#define OFFSET(x) offsetof(DVVideoContext, x)
+#define OFFSET(x) offsetof(DVEncContext, x)
static const AVOption dv_options[] = {
{ "quant_deadzone", "Quantizer dead zone", OFFSET(quant_deadzone), AV_OPT_TYPE_INT, { .i64 = 7 }, 0, 1024, VE },
{ NULL },
@@ -1208,12 +1235,13 @@ static const AVClass dvvideo_encode_class = {
const FFCodec ff_dvvideo_encoder = {
.p.name = "dvvideo",
- .p.long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
+ CODEC_LONG_NAME("DV (Digital Video)"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DVVIDEO,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
- AV_CODEC_CAP_SLICE_THREADS,
- .priv_data_size = sizeof(DVVideoContext),
+ AV_CODEC_CAP_SLICE_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ .priv_data_size = sizeof(DVEncContext),
.init = dvvideo_encode_init,
FF_CODEC_ENCODE_CB(dvvideo_encode_frame),
.p.pix_fmts = (const enum AVPixelFormat[]) {
@@ -1221,5 +1249,4 @@ const FFCodec ff_dvvideo_encoder = {
AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
},
.p.priv_class = &dvvideo_encode_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c
index 93a172474..8d2d2d771 100644
--- a/libavcodec/dxa.c
+++ b/libavcodec/dxa.c
@@ -24,15 +24,12 @@
* DXA Video decoder
*/
-#include
-#include
-
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
#include "bytestream.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include
@@ -363,7 +360,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
const FFCodec ff_dxa_decoder = {
.p.name = "dxa",
- .p.long_name = NULL_IF_CONFIG_SMALL("Feeble Files/ScummVM DXA"),
+ CODEC_LONG_NAME("Feeble Files/ScummVM DXA"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DXA,
.priv_data_size = sizeof(DxaDecContext),
@@ -371,5 +368,5 @@ const FFCodec ff_dxa_decoder = {
.close = decode_end,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c
index b7dfff475..e13d27486 100644
--- a/libavcodec/dxtory.c
+++ b/libavcodec/dxtory.c
@@ -872,7 +872,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *pic,
const FFCodec ff_dxtory_decoder = {
.p.name = "dxtory",
- .p.long_name = NULL_IF_CONFIG_SMALL("Dxtory"),
+ CODEC_LONG_NAME("Dxtory"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DXTORY,
FF_CODEC_DECODE_CB(decode_frame),
diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c
index d75f8b040..7c8487422 100644
--- a/libavcodec/dxv.c
+++ b/libavcodec/dxv.c
@@ -193,7 +193,7 @@ static int yao_block(uint8_t *plane0, ptrdiff_t stride0,
static int decompress_texture_thread(AVCodecContext *avctx, void *arg,
int slice, int thread_nb)
{
- DXVContext *ctx = avctx->priv_data;
+ const DXVContext *ctx = avctx->priv_data;
AVFrame *frame = arg;
const uint8_t *d = ctx->tex_data;
int w_block = avctx->coded_width / ctx->texture_block_w;
@@ -432,7 +432,7 @@ static int get_opcodes(GetByteContext *gb, uint32_t *table, uint8_t *dst, int op
int64_t size_in_bits;
unsigned endoffset, newoffset, offset;
unsigned next;
- uint8_t *src = (uint8_t *)gb->buffer;
+ const uint8_t *src = gb->buffer;
ret = fill_optable(table, optable, nb_elements);
if (ret < 0)
@@ -1262,7 +1262,7 @@ static int dxv_close(AVCodecContext *avctx)
const FFCodec ff_dxv_decoder = {
.p.name = "dxv",
- .p.long_name = NULL_IF_CONFIG_SMALL("Resolume DXV"),
+ CODEC_LONG_NAME("Resolume DXV"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DXV,
.init = dxv_init,
@@ -1272,6 +1272,5 @@ const FFCodec ff_dxv_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_SLICE_THREADS |
AV_CODEC_CAP_FRAME_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/dxva2_vc1.c b/libavcodec/dxva2_vc1.c
index cf660a50d..12e3de59e 100644
--- a/libavcodec/dxva2_vc1.c
+++ b/libavcodec/dxva2_vc1.c
@@ -372,8 +372,6 @@ static int dxva2_vc1_end_frame(AVCodecContext *avctx)
&ctx_pic->pp, sizeof(ctx_pic->pp),
NULL, 0,
commit_bitstream_and_slice_buffer);
- if (!ret)
- ff_mpeg_draw_horiz_band(&v->s, 0, avctx->height);
return ret;
}
diff --git a/libavcodec/eac3dec.c b/libavcodec/eac3dec.c
index d360b0269..deca51dd3 100644
--- a/libavcodec/eac3dec.c
+++ b/libavcodec/eac3dec.c
@@ -138,9 +138,11 @@ static void ff_eac3_apply_spectral_extension(AC3DecodeContext *s)
// spx_noise_blend and spx_signal_blend are both FP.23
nscale *= 1.0 / (1<<23);
sscale *= 1.0 / (1<<23);
+ if (nscale < -1.0)
+ nscale = -1.0;
#endif
for (i = 0; i < s->spx_band_sizes[bnd]; i++) {
- float noise = nscale * (int32_t)av_lfg_get(&s->dith_state);
+ UINTFLOAT noise = (INTFLOAT)(nscale * (int32_t)av_lfg_get(&s->dith_state));
s->transform_coeffs[ch][bin] *= sscale;
s->transform_coeffs[ch][bin++] += noise;
}
diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c
index 79611cee0..4b3236d4e 100644
--- a/libavcodec/eac3enc.c
+++ b/libavcodec/eac3enc.c
@@ -189,7 +189,7 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
put_bits(&s->pb, 1, 0);
}
if (s->num_blocks != 6)
- put_bits(&s->pb, 1, !(s->avctx->frame_number % 6)); /* converter sync flag */
+ put_bits(&s->pb, 1, !(s->avctx->frame_num % 6)); /* converter sync flag */
put_bits(&s->pb, 1, 0); /* no additional bit stream info */
/* frame header */
@@ -249,13 +249,12 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
}
-FF_DISABLE_DEPRECATION_WARNINGS
const FFCodec ff_eac3_encoder = {
.p.name = "eac3",
- .p.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52 E-AC-3"),
+ CODEC_LONG_NAME("ATSC A/52 E-AC-3"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_EAC3,
- .p.capabilities = AV_CODEC_CAP_DR1,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(AC3EncodeContext),
.init = ff_ac3_float_encode_init,
FF_CODEC_ENCODE_CB(ff_ac3_float_encode_frame),
@@ -264,11 +263,8 @@ const FFCodec ff_eac3_encoder = {
AV_SAMPLE_FMT_NONE },
.p.priv_class = &eac3enc_class,
.p.supported_samplerates = ff_ac3_sample_rate_tab,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = ff_ac3_channel_layouts,
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(ff_ac3_channel_layouts)
.p.ch_layouts = ff_ac3_ch_layouts,
.defaults = ff_ac3_enc_defaults,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
-FF_ENABLE_DEPRECATION_WARNINGS
diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c
index 0a13a74bb..18f27dfdf 100644
--- a/libavcodec/eacmv.c
+++ b/libavcodec/eacmv.c
@@ -33,7 +33,7 @@
#include "libavutil/imgutils.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
typedef struct CmvContext {
AVCodecContext *avctx;
@@ -231,7 +231,7 @@ static av_cold int cmv_decode_end(AVCodecContext *avctx){
const FFCodec ff_eacmv_decoder = {
.p.name = "eacmv",
- .p.long_name = NULL_IF_CONFIG_SMALL("Electronic Arts CMV video"),
+ CODEC_LONG_NAME("Electronic Arts CMV video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CMV,
.priv_data_size = sizeof(CmvContext),
@@ -239,5 +239,5 @@ const FFCodec ff_eacmv_decoder = {
.close = cmv_decode_end,
FF_CODEC_DECODE_CB(cmv_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c
index 337a9c144..45012c62b 100644
--- a/libavcodec/eamad.c
+++ b/libavcodec/eamad.c
@@ -35,11 +35,10 @@
#include "bytestream.h"
#include "bswapdsp.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
#include "aandcttab.h"
#include "eaidct.h"
-#include "idctdsp.h"
-#include "internal.h"
#include "mpeg12data.h"
#include "mpeg12vlc.h"
@@ -52,13 +51,11 @@ typedef struct MadContext {
AVCodecContext *avctx;
BlockDSPContext bdsp;
BswapDSPContext bbdsp;
- IDCTDSPContext idsp;
AVFrame *last_frame;
GetBitContext gb;
void *bitstream_buf;
unsigned int bitstream_buf_size;
DECLARE_ALIGNED(32, int16_t, block)[64];
- ScanTable scantable;
uint16_t quant_matrix[64];
int mb_x;
int mb_y;
@@ -69,11 +66,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
MadContext *s = avctx->priv_data;
s->avctx = avctx;
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- ff_blockdsp_init(&s->bdsp, avctx);
+ ff_blockdsp_init(&s->bdsp);
ff_bswapdsp_init(&s->bbdsp);
- ff_idctdsp_init(&s->idsp, avctx);
- ff_init_scantable_permutation(s->idsp.idct_permutation, FF_IDCT_PERM_NONE);
- ff_init_scantable(s->idsp.idct_permutation, &s->scantable, ff_zigzag_direct);
ff_mpeg12_init_vlcs();
s->last_frame = av_frame_alloc();
@@ -134,8 +128,7 @@ static inline void idct_put(MadContext *t, AVFrame *frame, int16_t *block,
static inline int decode_block_intra(MadContext *s, int16_t * block)
{
int level, i, j, run;
- RLTable *rl = &ff_rl_mpeg1;
- const uint8_t *scantable = s->scantable.permutated;
+ const uint8_t *scantable = ff_zigzag_direct;
int16_t *quant_matrix = s->quant_matrix;
block[0] = (128 + get_sbits(&s->gb, 8)) * quant_matrix[0];
@@ -148,7 +141,7 @@ static inline int decode_block_intra(MadContext *s, int16_t * block)
/* now quantify & encode AC coefficients */
for (;;) {
UPDATE_CACHE(re, &s->gb);
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+ GET_RL_VLC(level, run, re, &s->gb, ff_mpeg1_rl_vlc, TEX_VLC_BITS, 2, 0);
if (level == 127) {
break;
@@ -342,7 +335,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
const FFCodec ff_eamad_decoder = {
.p.name = "eamad",
- .p.long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Madcow Video"),
+ CODEC_LONG_NAME("Electronic Arts Madcow Video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_MAD,
.priv_data_size = sizeof(MadContext),
@@ -350,5 +343,4 @@ const FFCodec ff_eamad_decoder = {
.close = decode_end,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c
index 2e9d2fe13..01e1acd4e 100644
--- a/libavcodec/eatgq.c
+++ b/libavcodec/eatgq.c
@@ -36,60 +36,58 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
+#include "decode.h"
#include "eaidct.h"
#include "get_bits.h"
-#include "idctdsp.h"
-#include "internal.h"
typedef struct TgqContext {
AVCodecContext *avctx;
int width, height;
- ScanTable scantable;
int qtable[64];
DECLARE_ALIGNED(16, int16_t, block)[6][64];
- GetByteContext gb;
} TgqContext;
static av_cold int tgq_decode_init(AVCodecContext *avctx)
{
TgqContext *s = avctx->priv_data;
- uint8_t idct_permutation[64];
s->avctx = avctx;
- ff_init_scantable_permutation(idct_permutation, FF_IDCT_PERM_NONE);
- ff_init_scantable(idct_permutation, &s->scantable, ff_zigzag_direct);
avctx->framerate = (AVRational){ 15, 1 };
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
return 0;
}
-static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb)
+static int tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb)
{
- uint8_t *perm = s->scantable.permutated;
+ const uint8_t *scantable = ff_zigzag_direct;
int i, j, value;
block[0] = get_sbits(gb, 8) * s->qtable[0];
for (i = 1; i < 64;) {
switch (show_bits(gb, 3)) {
case 4:
- block[perm[i++]] = 0;
+ if (i >= 63)
+ return AVERROR_INVALIDDATA;
+ block[scantable[i++]] = 0;
case 0:
- block[perm[i++]] = 0;
+ block[scantable[i++]] = 0;
skip_bits(gb, 3);
break;
case 5:
case 1:
skip_bits(gb, 2);
value = get_bits(gb, 6);
+ if (value > 64 - i)
+ return AVERROR_INVALIDDATA;
for (j = 0; j < value; j++)
- block[perm[i++]] = 0;
+ block[scantable[i++]] = 0;
break;
case 6:
skip_bits(gb, 3);
- block[perm[i]] = -s->qtable[perm[i]];
+ block[scantable[i]] = -s->qtable[scantable[i]];
i++;
break;
case 2:
skip_bits(gb, 3);
- block[perm[i]] = s->qtable[perm[i]];
+ block[scantable[i]] = s->qtable[scantable[i]];
i++;
break;
case 7: // 111b
@@ -97,15 +95,16 @@ static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb
skip_bits(gb, 2);
if (show_bits(gb, 6) == 0x3F) {
skip_bits(gb, 6);
- block[perm[i]] = get_sbits(gb, 8) * s->qtable[perm[i]];
+ block[scantable[i]] = get_sbits(gb, 8) * s->qtable[scantable[i]];
} else {
- block[perm[i]] = get_sbits(gb, 6) * s->qtable[perm[i]];
+ block[scantable[i]] = get_sbits(gb, 6) * s->qtable[scantable[i]];
}
i++;
break;
}
}
block[0] += 128 << 4;
+ return 0;
}
static void tgq_idct_put_mb(TgqContext *s, int16_t (*block)[64], AVFrame *frame,
@@ -152,34 +151,38 @@ static void tgq_idct_put_mb_dconly(TgqContext *s, AVFrame *frame,
}
}
-static int tgq_decode_mb(TgqContext *s, AVFrame *frame, int mb_y, int mb_x)
+static int tgq_decode_mb(TgqContext *s, GetByteContext *gbyte,
+ AVFrame *frame, int mb_y, int mb_x)
{
int mode;
int i;
int8_t dc[6];
- mode = bytestream2_get_byte(&s->gb);
+ mode = bytestream2_get_byte(gbyte);
if (mode > 12) {
GetBitContext gb;
- int ret = init_get_bits8(&gb, s->gb.buffer, FFMIN(bytestream2_get_bytes_left(&s->gb), mode));
+ int ret = init_get_bits8(&gb, gbyte->buffer, FFMIN(bytestream2_get_bytes_left(gbyte), mode));
if (ret < 0)
return ret;
- for (i = 0; i < 6; i++)
- tgq_decode_block(s, s->block[i], &gb);
+ for (i = 0; i < 6; i++) {
+ int ret = tgq_decode_block(s, s->block[i], &gb);
+ if (ret < 0)
+ return ret;
+ }
tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y);
- bytestream2_skip(&s->gb, mode);
+ bytestream2_skip(gbyte, mode);
} else {
if (mode == 3) {
- memset(dc, bytestream2_get_byte(&s->gb), 4);
- dc[4] = bytestream2_get_byte(&s->gb);
- dc[5] = bytestream2_get_byte(&s->gb);
+ memset(dc, bytestream2_get_byte(gbyte), 4);
+ dc[4] = bytestream2_get_byte(gbyte);
+ dc[5] = bytestream2_get_byte(gbyte);
} else if (mode == 6) {
- bytestream2_get_buffer(&s->gb, dc, 6);
+ bytestream2_get_buffer(gbyte, dc, 6);
} else if (mode == 12) {
for (i = 0; i < 6; i++) {
- dc[i] = bytestream2_get_byte(&s->gb);
- bytestream2_skip(&s->gb, 1);
+ dc[i] = bytestream2_get_byte(gbyte);
+ bytestream2_skip(gbyte, 1);
}
} else {
av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode);
@@ -207,6 +210,7 @@ static int tgq_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
TgqContext *s = avctx->priv_data;
+ GetByteContext gbyte;
int x, y, ret;
int big_endian;
@@ -215,21 +219,21 @@ static int tgq_decode_frame(AVCodecContext *avctx, AVFrame *frame,
return AVERROR_INVALIDDATA;
}
big_endian = AV_RL32(&buf[4]) > 0x000FFFFF;
- bytestream2_init(&s->gb, buf + 8, buf_size - 8);
+ bytestream2_init(&gbyte, buf + 8, buf_size - 8);
if (big_endian) {
- s->width = bytestream2_get_be16u(&s->gb);
- s->height = bytestream2_get_be16u(&s->gb);
+ s->width = bytestream2_get_be16u(&gbyte);
+ s->height = bytestream2_get_be16u(&gbyte);
} else {
- s->width = bytestream2_get_le16u(&s->gb);
- s->height = bytestream2_get_le16u(&s->gb);
+ s->width = bytestream2_get_le16u(&gbyte);
+ s->height = bytestream2_get_le16u(&gbyte);
}
ret = ff_set_dimensions(s->avctx, s->width, s->height);
if (ret < 0)
return ret;
- tgq_calculate_qtable(s, bytestream2_get_byteu(&s->gb));
- bytestream2_skip(&s->gb, 3);
+ tgq_calculate_qtable(s, bytestream2_get_byteu(&gbyte));
+ bytestream2_skipu(&gbyte, 3);
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret;
@@ -238,7 +242,7 @@ static int tgq_decode_frame(AVCodecContext *avctx, AVFrame *frame,
for (y = 0; y < FFALIGN(avctx->height, 16) >> 4; y++)
for (x = 0; x < FFALIGN(avctx->width, 16) >> 4; x++)
- if (tgq_decode_mb(s, frame, y, x) < 0)
+ if (tgq_decode_mb(s, &gbyte, frame, y, x) < 0)
return AVERROR_INVALIDDATA;
*got_frame = 1;
@@ -248,12 +252,11 @@ static int tgq_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_eatgq_decoder = {
.p.name = "eatgq",
- .p.long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"),
+ CODEC_LONG_NAME("Electronic Arts TGQ video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_TGQ,
.priv_data_size = sizeof(TgqContext),
.init = tgq_decode_init,
FF_CODEC_DECODE_CB(tgq_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c
index 23cf7300c..29f7ee12f 100644
--- a/libavcodec/eatgv.c
+++ b/libavcodec/eatgv.c
@@ -28,14 +28,13 @@
* http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TGV
*/
-#include "libavutil/imgutils.h"
#include "libavutil/mem.h"
#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "get_bits.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#define EA_PREAMBLE_SIZE 8
#define kVGT_TAG MKTAG('k', 'V', 'G', 'T')
@@ -360,7 +359,7 @@ static av_cold int tgv_decode_end(AVCodecContext *avctx)
const FFCodec ff_eatgv_decoder = {
.p.name = "eatgv",
- .p.long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGV video"),
+ CODEC_LONG_NAME("Electronic Arts TGV video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_TGV,
.priv_data_size = sizeof(TgvContext),
@@ -368,5 +367,4 @@ const FFCodec ff_eatgv_decoder = {
.close = tgv_decode_end,
FF_CODEC_DECODE_CB(tgv_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c
index 305ea4ba2..e4f12b3db 100644
--- a/libavcodec/eatqi.c
+++ b/libavcodec/eatqi.c
@@ -32,11 +32,10 @@
#include "blockdsp.h"
#include "bswapdsp.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
#include "aandcttab.h"
#include "eaidct.h"
-#include "idctdsp.h"
-#include "internal.h"
#include "mpeg12data.h"
#include "mpeg12dec.h"
@@ -45,8 +44,6 @@ typedef struct TqiContext {
GetBitContext gb;
BlockDSPContext bdsp;
BswapDSPContext bsdsp;
- IDCTDSPContext idsp;
- ScanTable intra_scantable;
void *bitstream_buf;
unsigned int bitstream_buf_size;
@@ -62,11 +59,8 @@ static av_cold int tqi_decode_init(AVCodecContext *avctx)
{
TqiContext *t = avctx->priv_data;
- ff_blockdsp_init(&t->bdsp, avctx);
+ ff_blockdsp_init(&t->bdsp);
ff_bswapdsp_init(&t->bsdsp);
- ff_idctdsp_init(&t->idsp, avctx);
- ff_init_scantable_permutation(t->idsp.idct_permutation, FF_IDCT_PERM_NONE);
- ff_init_scantable(t->idsp.idct_permutation, &t->intra_scantable, ff_zigzag_direct);
avctx->framerate = (AVRational){ 15, 1 };
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
@@ -82,7 +76,7 @@ static int tqi_decode_mb(TqiContext *t, int16_t (*block)[64])
for (n = 0; n < 6; n++) {
int ret = ff_mpeg1_decode_block_intra(&t->gb,
t->intra_matrix,
- t->intra_scantable.permutated,
+ ff_zigzag_direct,
t->last_dc, block[n], n, 1);
if (ret < 0) {
av_log(t->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n",
@@ -183,7 +177,7 @@ static av_cold int tqi_decode_end(AVCodecContext *avctx)
const FFCodec ff_eatqi_decoder = {
.p.name = "eatqi",
- .p.long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TQI Video"),
+ CODEC_LONG_NAME("Electronic Arts TQI Video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_TQI,
.priv_data_size = sizeof(TqiContext),
@@ -191,5 +185,4 @@ const FFCodec ff_eatqi_decoder = {
.close = tqi_decode_end,
FF_CODEC_DECODE_CB(tqi_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 1f39ab1a2..041fc7670 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -107,15 +107,32 @@ fail:
return ret;
}
+static int encode_make_refcounted(AVCodecContext *avctx, AVPacket *avpkt)
+{
+ uint8_t *data = avpkt->data;
+ int ret;
+
+ if (avpkt->buf)
+ return 0;
+
+ avpkt->data = NULL;
+ ret = ff_get_encode_buffer(avctx, avpkt, avpkt->size, 0);
+ if (ret < 0)
+ return ret;
+ memcpy(avpkt->data, data, avpkt->size);
+
+ return 0;
+}
+
/**
* Pad last frame with silence.
*/
-static int pad_last_frame(AVCodecContext *s, AVFrame *frame, const AVFrame *src)
+static int pad_last_frame(AVCodecContext *s, AVFrame *frame, const AVFrame *src, int out_samples)
{
int ret;
frame->format = src->format;
- frame->nb_samples = s->frame_size;
+ frame->nb_samples = out_samples;
ret = av_channel_layout_copy(&frame->ch_layout, &s->ch_layout);
if (ret < 0)
goto fail;
@@ -140,6 +157,7 @@ static int pad_last_frame(AVCodecContext *s, AVFrame *frame, const AVFrame *src)
fail:
av_frame_unref(frame);
+ s->internal->last_audio_frame = 0;
return ret;
}
@@ -153,7 +171,12 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
}
ret = ffcodec(avctx->codec)->cb.encode_sub(avctx, buf, buf_size, sub);
- avctx->frame_number++;
+ avctx->frame_num++;
+#if FF_API_AVCTX_FRAME_NUMBER
+FF_DISABLE_DEPRECATION_WARNINGS
+ avctx->frame_number = avctx->frame_num;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
return ret;
}
@@ -172,6 +195,82 @@ int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
return 0;
}
+int ff_encode_reordered_opaque(AVCodecContext *avctx,
+ AVPacket *pkt, const AVFrame *frame)
+{
+#if FF_API_REORDERED_OPAQUE
+FF_DISABLE_DEPRECATION_WARNINGS
+ avctx->reordered_opaque = frame->reordered_opaque;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+ int ret = av_buffer_replace(&pkt->opaque_ref, frame->opaque_ref);
+ if (ret < 0)
+ return ret;
+ pkt->opaque = frame->opaque;
+ }
+
+ return 0;
+}
+
+int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt,
+ AVFrame *frame, int *got_packet)
+{
+ const FFCodec *const codec = ffcodec(avctx->codec);
+ int ret;
+
+ ret = codec->cb.encode(avctx, avpkt, frame, got_packet);
+ emms_c();
+ av_assert0(ret <= 0);
+
+ if (!ret && *got_packet) {
+ if (avpkt->data) {
+ ret = encode_make_refcounted(avctx, avpkt);
+ if (ret < 0)
+ goto unref;
+ // Date returned by encoders must always be ref-counted
+ av_assert0(avpkt->buf);
+ }
+
+ // set the timestamps for the simple no-delay case
+ // encoders with delay have to set the timestamps themselves
+ if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) ||
+ (frame && (codec->caps_internal & FF_CODEC_CAP_EOF_FLUSH))) {
+ if (avpkt->pts == AV_NOPTS_VALUE)
+ avpkt->pts = frame->pts;
+
+ if (!avpkt->duration) {
+ if (frame->duration)
+ avpkt->duration = frame->duration;
+ else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {
+ avpkt->duration = ff_samples_to_time_base(avctx,
+ frame->nb_samples);
+ }
+ }
+
+ ret = ff_encode_reordered_opaque(avctx, avpkt, frame);
+ if (ret < 0)
+ goto unref;
+ }
+
+ // dts equals pts unless there is reordering
+ // there can be no reordering if there is no encoder delay
+ if (!(avctx->codec_descriptor->props & AV_CODEC_PROP_REORDER) ||
+ !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) ||
+ (codec->caps_internal & FF_CODEC_CAP_EOF_FLUSH))
+ avpkt->dts = avpkt->pts;
+ } else {
+unref:
+ av_packet_unref(avpkt);
+ }
+
+ if (frame)
+ av_frame_unref(frame);
+
+ return ret;
+}
+
static int encode_simple_internal(AVCodecContext *avctx, AVPacket *avpkt)
{
AVCodecInternal *avci = avctx->internal;
@@ -192,7 +291,7 @@ static int encode_simple_internal(AVCodecContext *avctx, AVPacket *avpkt)
if (!frame->buf[0]) {
if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY ||
- (avci->frame_thread_encoder && avctx->active_thread_type & FF_THREAD_FRAME)))
+ avci->frame_thread_encoder))
return AVERROR_EOF;
// Flushing is signaled with a NULL frame
@@ -203,61 +302,16 @@ static int encode_simple_internal(AVCodecContext *avctx, AVPacket *avpkt)
av_assert0(codec->cb_type == FF_CODEC_CB_TYPE_ENCODE);
- if (CONFIG_FRAME_THREAD_ENCODER &&
- avci->frame_thread_encoder && (avctx->active_thread_type & FF_THREAD_FRAME))
- /* This might modify frame, but it doesn't matter, because
- * the frame properties used below are not used for video
- * (due to the delay inherent in frame threaded encoding, it makes
- * no sense to use the properties of the current frame anyway). */
+ if (CONFIG_FRAME_THREAD_ENCODER && avci->frame_thread_encoder)
+ /* This will unref frame. */
ret = ff_thread_video_encode_frame(avctx, avpkt, frame, &got_packet);
else {
- ret = codec->cb.encode(avctx, avpkt, frame, &got_packet);
- if (avctx->codec->type == AVMEDIA_TYPE_VIDEO && !ret && got_packet &&
- !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY))
- avpkt->pts = avpkt->dts = frame->pts;
- }
-
- av_assert0(ret <= 0);
-
- emms_c();
-
- if (!ret && got_packet) {
- if (avpkt->data) {
- ret = av_packet_make_refcounted(avpkt);
- if (ret < 0)
- goto end;
- }
-
- if (frame && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) {
- if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {
- if (avpkt->pts == AV_NOPTS_VALUE)
- avpkt->pts = frame->pts;
- if (!avpkt->duration)
- avpkt->duration = ff_samples_to_time_base(avctx,
- frame->nb_samples);
- }
- }
- if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {
- avpkt->dts = avpkt->pts;
- }
- avpkt->flags |= avci->intra_only_flag;
+ ret = ff_encode_encode_cb(avctx, avpkt, frame, &got_packet);
}
if (avci->draining && !got_packet)
avci->draining_done = 1;
-end:
- if (ret < 0 || !got_packet)
- av_packet_unref(avpkt);
-
- if (frame)
- av_frame_unref(frame);
-
- if (got_packet)
- // Encoders must always return ref-counted buffers.
- // Side-data only packets have no data and can be not ref-counted.
- av_assert0(!avpkt->data || avpkt->buf);
-
return ret;
}
@@ -301,6 +355,8 @@ static int encode_receive_packet_internal(AVCodecContext *avctx, AVPacket *avpkt
av_assert0(!avpkt->data || avpkt->buf);
} else
ret = encode_simple_receive_packet(avctx, avpkt);
+ if (ret >= 0)
+ avpkt->flags |= avci->intra_only_flag;
if (ret == AVERROR_EOF)
avci->draining_done = 1;
@@ -308,6 +364,53 @@ static int encode_receive_packet_internal(AVCodecContext *avctx, AVPacket *avpkt
return ret;
}
+#if CONFIG_LCMS2
+static int encode_generate_icc_profile(AVCodecContext *avctx, AVFrame *frame)
+{
+ enum AVColorTransferCharacteristic trc = frame->color_trc;
+ enum AVColorPrimaries prim = frame->color_primaries;
+ const FFCodec *const codec = ffcodec(avctx->codec);
+ AVCodecInternal *avci = avctx->internal;
+ cmsHPROFILE profile;
+ int ret;
+
+ /* don't generate ICC profiles if disabled or unsupported */
+ if (!(avctx->flags2 & AV_CODEC_FLAG2_ICC_PROFILES))
+ return 0;
+ if (!(codec->caps_internal & FF_CODEC_CAP_ICC_PROFILES))
+ return 0;
+
+ if (trc == AVCOL_TRC_UNSPECIFIED)
+ trc = avctx->color_trc;
+ if (prim == AVCOL_PRI_UNSPECIFIED)
+ prim = avctx->color_primaries;
+ if (trc == AVCOL_TRC_UNSPECIFIED || prim == AVCOL_PRI_UNSPECIFIED)
+ return 0; /* can't generate ICC profile with missing csp tags */
+
+ if (av_frame_get_side_data(frame, AV_FRAME_DATA_ICC_PROFILE))
+ return 0; /* don't overwrite existing ICC profile */
+
+ if (!avci->icc.avctx) {
+ ret = ff_icc_context_init(&avci->icc, avctx);
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = ff_icc_profile_generate(&avci->icc, prim, trc, &profile);
+ if (ret < 0)
+ return ret;
+
+ ret = ff_icc_profile_attach(&avci->icc, profile, frame);
+ cmsCloseProfile(profile);
+ return ret;
+}
+#else /* !CONFIG_LCMS2 */
+static int encode_generate_icc_profile(av_unused AVCodecContext *c, av_unused AVFrame *f)
+{
+ return 0;
+}
+#endif
+
static int encode_send_frame_internal(AVCodecContext *avctx, const AVFrame *src)
{
AVCodecInternal *avci = avctx->internal;
@@ -321,29 +424,30 @@ static int encode_send_frame_internal(AVCodecContext *avctx, const AVFrame *src)
avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data;
/* check for valid frame size */
- if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) {
- if (src->nb_samples > avctx->frame_size) {
- av_log(avctx, AV_LOG_ERROR, "more samples than frame size\n");
- return AVERROR(EINVAL);
- }
- } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) {
+ if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) {
/* if we already got an undersized frame, that must have been the last */
if (avctx->internal->last_audio_frame) {
av_log(avctx, AV_LOG_ERROR, "frame_size (%d) was not respected for a non-last frame\n", avctx->frame_size);
return AVERROR(EINVAL);
}
-
- if (src->nb_samples < avctx->frame_size) {
- ret = pad_last_frame(avctx, dst, src);
- if (ret < 0)
- return ret;
-
- avctx->internal->last_audio_frame = 1;
- return 0;
- } else if (src->nb_samples > avctx->frame_size) {
- av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d)\n", src->nb_samples, avctx->frame_size);
+ if (src->nb_samples > avctx->frame_size) {
+ av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) > frame_size (%d)\n", src->nb_samples, avctx->frame_size);
return AVERROR(EINVAL);
}
+ if (src->nb_samples < avctx->frame_size) {
+ avctx->internal->last_audio_frame = 1;
+ if (!(avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME)) {
+ int pad_samples = avci->pad_samples ? avci->pad_samples : avctx->frame_size;
+ int out_samples = (src->nb_samples + pad_samples - 1) / pad_samples * pad_samples;
+
+ if (out_samples != src->nb_samples) {
+ ret = pad_last_frame(avctx, dst, src, out_samples);
+ if (ret < 0)
+ return ret;
+ goto finish;
+ }
+ }
+ }
}
}
@@ -351,6 +455,28 @@ static int encode_send_frame_internal(AVCodecContext *avctx, const AVFrame *src)
if (ret < 0)
return ret;
+finish:
+
+#if FF_API_PKT_DURATION
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (dst->pkt_duration && dst->pkt_duration != dst->duration)
+ dst->duration = dst->pkt_duration;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) {
+ ret = encode_generate_icc_profile(avctx, dst);
+ if (ret < 0)
+ return ret;
+ }
+
+ // unset frame duration unless AV_CODEC_FLAG_FRAME_DURATION is set,
+ // since otherwise we cannot be sure that whatever value it has is in the
+ // right timebase, so we would produce an incorrect value, which is worse
+ // than none at all
+ if (!(avctx->flags & AV_CODEC_FLAG_FRAME_DURATION))
+ dst->duration = 0;
+
return 0;
}
@@ -382,7 +508,12 @@ int attribute_align_arg avcodec_send_frame(AVCodecContext *avctx, const AVFrame
return ret;
}
- avctx->frame_number++;
+ avctx->frame_num++;
+#if FF_API_AVCTX_FRAME_NUMBER
+FF_DISABLE_DEPRECATION_WARNINGS
+ avctx->frame_number = avctx->frame_num;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
return 0;
}
@@ -514,11 +645,6 @@ static int encode_preinit_audio(AVCodecContext *avctx)
return AVERROR(EINVAL);
}
if (avctx->codec->ch_layouts) {
- if (!av_channel_layout_check(&avctx->ch_layout)) {
- av_log(avctx, AV_LOG_WARNING, "Channel layout not specified correctly\n");
- return AVERROR(EINVAL);
- }
-
for (i = 0; avctx->codec->ch_layouts[i].nb_channels; i++) {
if (!av_channel_layout_compare(&avctx->ch_layout, &avctx->codec->ch_layouts[i]))
break;
@@ -531,28 +657,6 @@ static int encode_preinit_audio(AVCodecContext *avctx)
return AVERROR(EINVAL);
}
}
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- if (avctx->channel_layout && avctx->channels) {
- int channels = av_get_channel_layout_nb_channels(avctx->channel_layout);
- if (channels != avctx->channels) {
- char buf[512];
- av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout);
- av_log(avctx, AV_LOG_ERROR,
- "Channel layout '%s' with %d channels does not match number of specified channels %d\n",
- buf, channels, avctx->channels);
- return AVERROR(EINVAL);
- }
- } else if (avctx->channel_layout) {
- avctx->channels = av_get_channel_layout_nb_channels(avctx->channel_layout);
- }
- if (avctx->channels < 0) {
- av_log(avctx, AV_LOG_ERROR, "Specified number of channels %d is not supported\n",
- avctx->channels);
- return AVERROR(EINVAL);
- }
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
if (!avctx->bits_per_raw_sample)
avctx->bits_per_raw_sample = 8 * av_get_bytes_per_sample(avctx->sample_fmt);
@@ -570,6 +674,13 @@ int ff_encode_preinit(AVCodecContext *avctx)
return AVERROR(EINVAL);
}
+ if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE &&
+ !(avctx->codec->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE)) {
+ av_log(avctx, AV_LOG_ERROR, "The copy_opaque flag is set, but the "
+ "encoder does not support it.\n");
+ return AVERROR(EINVAL);
+ }
+
switch (avctx->codec_type) {
case AVMEDIA_TYPE_VIDEO: ret = encode_preinit_video(avctx); break;
case AVMEDIA_TYPE_AUDIO: ret = encode_preinit_audio(avctx); break;
@@ -594,6 +705,24 @@ int ff_encode_preinit(AVCodecContext *avctx)
return AVERROR(ENOMEM);
}
+ if ((avctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
+ if (!(avctx->codec->capabilities & AV_CODEC_CAP_ENCODER_RECON_FRAME)) {
+ av_log(avctx, AV_LOG_ERROR, "Reconstructed frame output requested "
+ "from an encoder not supporting it\n");
+ return AVERROR(ENOSYS);
+ }
+
+ avci->recon_frame = av_frame_alloc();
+ if (!avci->recon_frame)
+ return AVERROR(ENOMEM);
+ }
+
+ if (CONFIG_FRAME_THREAD_ENCODER) {
+ ret = ff_frame_thread_encoder_init(avctx);
+ if (ret < 0)
+ return ret;
+ }
+
return 0;
}
@@ -630,3 +759,16 @@ int ff_encode_alloc_frame(AVCodecContext *avctx, AVFrame *frame)
return 0;
}
+
+int ff_encode_receive_frame(AVCodecContext *avctx, AVFrame *frame)
+{
+ AVCodecInternal *avci = avctx->internal;
+
+ if (!avci->recon_frame)
+ return AVERROR(EINVAL);
+ if (!avci->recon_frame->buf[0])
+ return avci->draining_done ? AVERROR_EOF : AVERROR(EAGAIN);
+
+ av_frame_move_ref(frame, avci->recon_frame);
+ return 0;
+}
diff --git a/libavcodec/encode.h b/libavcodec/encode.h
index b2536bf0f..26a330404 100644
--- a/libavcodec/encode.h
+++ b/libavcodec/encode.h
@@ -26,6 +26,11 @@
#include "avcodec.h"
#include "packet.h"
+/**
+ * avcodec_receive_frame() implementation for encoders.
+ */
+int ff_encode_receive_frame(AVCodecContext *avctx, AVFrame *frame);
+
/**
* Called by encoders to get the next frame for encoding.
*
@@ -52,7 +57,7 @@ int ff_encode_alloc_frame(AVCodecContext *avctx, AVFrame *frame);
/**
* Check AVPacket size and allocate data.
*
- * Encoders supporting FFCodec.encode2() can use this as a convenience to
+ * Encoders of type FF_CODEC_CB_TYPE_ENCODE can use this as a convenience to
* obtain a big enough buffer for the encoded bitstream.
*
* @param avctx the AVCodecContext of the encoder
@@ -64,10 +69,31 @@ int ff_encode_alloc_frame(AVCodecContext *avctx, AVFrame *frame);
*/
int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size);
+/**
+ * Propagate user opaque values from the frame to avctx/pkt as needed.
+ */
+int ff_encode_reordered_opaque(AVCodecContext *avctx,
+ AVPacket *pkt, const AVFrame *frame);
+
/*
* Perform encoder initialization and validation.
* Called when opening the encoder, before the FFCodec.init() call.
*/
int ff_encode_preinit(AVCodecContext *avctx);
+int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt,
+ AVFrame *frame, int *got_packet);
+
+/**
+ * Rescale from sample rate to AVCodecContext.time_base.
+ */
+static av_always_inline int64_t ff_samples_to_time_base(const AVCodecContext *avctx,
+ int64_t samples)
+{
+ if (samples == AV_NOPTS_VALUE)
+ return AV_NOPTS_VALUE;
+ return av_rescale_q(samples, (AVRational){ 1, avctx->sample_rate },
+ avctx->time_base);
+}
+
#endif /* AVCODEC_ENCODE_H */
diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index f957c68d2..2aa6f1d86 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -946,17 +946,17 @@ void ff_er_frame_end(ERContext *s)
av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
for (i = 0; i < 2; i++) {
- s->ref_index_buf[i] = av_buffer_allocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
- s->motion_val_buf[i] = av_buffer_allocz((size + 4) * 2 * sizeof(uint16_t));
- if (!s->ref_index_buf[i] || !s->motion_val_buf[i])
+ s->ref_index[i] = av_calloc(s->mb_stride * s->mb_height, 4 * sizeof(uint8_t));
+ s->motion_val_base[i] = av_calloc(size + 4, 2 * sizeof(uint16_t));
+ if (!s->ref_index[i] || !s->motion_val_base[i])
break;
- s->cur_pic.ref_index[i] = s->ref_index_buf[i]->data;
- s->cur_pic.motion_val[i] = (int16_t (*)[2])s->motion_val_buf[i]->data + 4;
+ s->cur_pic.ref_index[i] = s->ref_index[i];
+ s->cur_pic.motion_val[i] = s->motion_val_base[i] + 4;
}
if (i < 2) {
for (i = 0; i < 2; i++) {
- av_buffer_unref(&s->ref_index_buf[i]);
- av_buffer_unref(&s->motion_val_buf[i]);
+ av_freep(&s->ref_index[i]);
+ av_freep(&s->motion_val_base[i]);
s->cur_pic.ref_index[i] = NULL;
s->cur_pic.motion_val[i] = NULL;
}
@@ -1343,8 +1343,8 @@ void ff_er_frame_end(ERContext *s)
}
for (i = 0; i < 2; i++) {
- av_buffer_unref(&s->ref_index_buf[i]);
- av_buffer_unref(&s->motion_val_buf[i]);
+ av_freep(&s->ref_index[i]);
+ av_freep(&s->motion_val_base[i]);
s->cur_pic.ref_index[i] = NULL;
s->cur_pic.motion_val[i] = NULL;
}
diff --git a/libavcodec/error_resilience.h b/libavcodec/error_resilience.h
index 53e5cf262..47cc8a4fc 100644
--- a/libavcodec/error_resilience.h
+++ b/libavcodec/error_resilience.h
@@ -75,8 +75,8 @@ typedef struct ERContext {
ERPicture last_pic;
ERPicture next_pic;
- AVBufferRef *ref_index_buf[2];
- AVBufferRef *motion_val_buf[2];
+ int8_t *ref_index[2];
+ int16_t (*motion_val_base[2])[2];
uint16_t pp_time;
uint16_t pb_time;
diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c
index 2fdffff13..024eec59c 100644
--- a/libavcodec/escape124.c
+++ b/libavcodec/escape124.c
@@ -22,8 +22,8 @@
#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
typedef union MacroBlock {
uint16_t pixels[4];
@@ -178,8 +178,8 @@ static void insert_mb_into_sb(SuperBlock* sb, MacroBlock mb, unsigned index) {
dst[4] = mb.pixels32[1];
}
-static void copy_superblock(uint16_t* dest, unsigned dest_stride,
- uint16_t* src, unsigned src_stride)
+static void copy_superblock(uint16_t* dest, ptrdiff_t dest_stride,
+ uint16_t* src, ptrdiff_t src_stride)
{
unsigned y;
if (src)
@@ -211,7 +211,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, AVFrame *frame,
superblocks_per_row = avctx->width / 8, skip = -1;
uint16_t* old_frame_data, *new_frame_data;
- unsigned old_stride, new_stride;
+ ptrdiff_t old_stride, new_stride;
int ret;
@@ -377,7 +377,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_escape124_decoder = {
.p.name = "escape124",
- .p.long_name = NULL_IF_CONFIG_SMALL("Escape 124"),
+ CODEC_LONG_NAME("Escape 124"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_ESCAPE124,
.priv_data_size = sizeof(Escape124Context),
@@ -385,5 +385,4 @@ const FFCodec ff_escape124_decoder = {
.close = escape124_decode_close,
FF_CODEC_DECODE_CB(escape124_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/escape130.c b/libavcodec/escape130.c
index cd6dd7690..3b0460fd7 100644
--- a/libavcodec/escape130.c
+++ b/libavcodec/escape130.c
@@ -25,8 +25,8 @@
#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
typedef struct Escape130Context {
uint8_t *old_y_avg;
@@ -347,7 +347,7 @@ static int escape130_decode_frame(AVCodecContext *avctx, AVFrame *pic,
const FFCodec ff_escape130_decoder = {
.p.name = "escape130",
- .p.long_name = NULL_IF_CONFIG_SMALL("Escape 130"),
+ CODEC_LONG_NAME("Escape 130"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_ESCAPE130,
.priv_data_size = sizeof(Escape130Context),
@@ -355,5 +355,5 @@ const FFCodec ff_escape130_decoder = {
.close = escape130_decode_close,
FF_CODEC_DECODE_CB(escape130_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/evrcdec.c b/libavcodec/evrcdec.c
index a6475199c..af7640d7e 100644
--- a/libavcodec/evrcdec.c
+++ b/libavcodec/evrcdec.c
@@ -30,7 +30,7 @@
#include "libavutil/opt.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "get_bits.h"
#include "evrcdata.h"
#include "acelp_vectors.h"
@@ -221,8 +221,8 @@ static evrc_packet_rate determine_bitrate(AVCodecContext *avctx,
static void warn_insufficient_frame_quality(AVCodecContext *avctx,
const char *message)
{
- av_log(avctx, AV_LOG_WARNING, "Frame #%d, %s\n",
- avctx->frame_number, message);
+ av_log(avctx, AV_LOG_WARNING, "Frame #%"PRId64", %s\n",
+ avctx->frame_num, message);
}
/**
@@ -931,7 +931,7 @@ static const AVClass evrcdec_class = {
const FFCodec ff_evrc_decoder = {
.p.name = "evrc",
- .p.long_name = NULL_IF_CONFIG_SMALL("EVRC (Enhanced Variable Rate Codec)"),
+ CODEC_LONG_NAME("EVRC (Enhanced Variable Rate Codec)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_EVRC,
.init = evrc_decode_init,
@@ -939,5 +939,4 @@ const FFCodec ff_evrc_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
.priv_data_size = sizeof(EVRCContext),
.p.priv_class = &evrcdec_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index 91a567cd4..2f1766c17 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -36,11 +36,12 @@
#include "libavutil/avassert.h"
#include "libavutil/common.h"
+#include "libavutil/csp.h"
#include "libavutil/imgutils.h"
#include "libavutil/intfloat.h"
#include "libavutil/avstring.h"
#include "libavutil/opt.h"
-#include "libavutil/color_utils.h"
+#include "libavutil/half2float.h"
#include "avcodec.h"
#include "bytestream.h"
@@ -50,10 +51,9 @@
#endif
#include "codec_internal.h"
+#include "decode.h"
#include "exrdsp.h"
#include "get_bits.h"
-#include "internal.h"
-#include "half2float.h"
#include "mathops.h"
#include "thread.h"
@@ -191,12 +191,12 @@ typedef struct EXRContext {
float gamma;
union av_intfloat32 gamma_table[65536];
- uint32_t mantissatable[2048];
- uint32_t exponenttable[64];
- uint16_t offsettable[64];
+ uint8_t *offset_table;
+
+ Half2FloatTables h2f_tables;
} EXRContext;
-static int zip_uncompress(EXRContext *s, const uint8_t *src, int compressed_size,
+static int zip_uncompress(const EXRContext *s, const uint8_t *src, int compressed_size,
int uncompressed_size, EXRThreadData *td)
{
unsigned long dest_len = uncompressed_size;
@@ -255,7 +255,7 @@ static int rle(uint8_t *dst, const uint8_t *src,
return 0;
}
-static int rle_uncompress(EXRContext *ctx, const uint8_t *src, int compressed_size,
+static int rle_uncompress(const EXRContext *ctx, const uint8_t *src, int compressed_size,
int uncompressed_size, EXRThreadData *td)
{
rle(td->tmp, src, compressed_size, uncompressed_size);
@@ -365,7 +365,7 @@ static int huf_unpack_enc_table(GetByteContext *gb,
return 0;
}
-static int huf_build_dec_table(EXRContext *s,
+static int huf_build_dec_table(const EXRContext *s,
EXRThreadData *td, int im, int iM)
{
int j = 0;
@@ -440,7 +440,7 @@ static int huf_decode(VLC *vlc, GetByteContext *gb, int nbits, int run_sym,
return 0;
}
-static int huf_uncompress(EXRContext *s,
+static int huf_uncompress(const EXRContext *s,
EXRThreadData *td,
GetByteContext *gb,
uint16_t *dst, int dst_size)
@@ -588,7 +588,7 @@ static void wav_decode(uint16_t *in, int nx, int ox,
}
}
-static int piz_uncompress(EXRContext *s, const uint8_t *src, int ssize,
+static int piz_uncompress(const EXRContext *s, const uint8_t *src, int ssize,
int dsize, EXRThreadData *td)
{
GetByteContext gb;
@@ -674,7 +674,7 @@ static int piz_uncompress(EXRContext *s, const uint8_t *src, int ssize,
return 0;
}
-static int pxr24_uncompress(EXRContext *s, const uint8_t *src,
+static int pxr24_uncompress(const EXRContext *s, const uint8_t *src,
int compressed_size, int uncompressed_size,
EXRThreadData *td)
{
@@ -809,7 +809,7 @@ static void unpack_3(const uint8_t b[3], uint16_t s[16])
}
-static int b44_uncompress(EXRContext *s, const uint8_t *src, int compressed_size,
+static int b44_uncompress(const EXRContext *s, const uint8_t *src, int compressed_size,
int uncompressed_size, EXRThreadData *td) {
const int8_t *sr = src;
int stay_to_uncompress = compressed_size;
@@ -832,20 +832,16 @@ static int b44_uncompress(EXRContext *s, const uint8_t *src, int compressed_size
if (s->channels[c].pixel_type == EXR_HALF) {/* B44 only compress half float data */
for (iY = 0; iY < nb_b44_block_h; iY++) {
for (iX = 0; iX < nb_b44_block_w; iX++) {/* For each B44 block */
- if (stay_to_uncompress < 3) {
- av_log(s, AV_LOG_ERROR, "Not enough data for B44A block: %d", stay_to_uncompress);
+ if (stay_to_uncompress < 3)
return AVERROR_INVALIDDATA;
- }
if (src[compressed_size - stay_to_uncompress + 2] == 0xfc) { /* B44A block */
unpack_3(sr, tmp_buffer);
sr += 3;
stay_to_uncompress -= 3;
} else {/* B44 Block */
- if (stay_to_uncompress < 14) {
- av_log(s, AV_LOG_ERROR, "Not enough data for B44 block: %d", stay_to_uncompress);
+ if (stay_to_uncompress < 14)
return AVERROR_INVALIDDATA;
- }
unpack_14(sr, tmp_buffer);
sr += 14;
stay_to_uncompress -= 14;
@@ -867,10 +863,8 @@ static int b44_uncompress(EXRContext *s, const uint8_t *src, int compressed_size
}
target_channel_offset += 2;
} else {/* Float or UINT 32 channel */
- if (stay_to_uncompress < td->ysize * td->xsize * 4) {
- av_log(s, AV_LOG_ERROR, "Not enough data for uncompress channel: %d", stay_to_uncompress);
+ if (stay_to_uncompress < td->ysize * td->xsize * 4)
return AVERROR_INVALIDDATA;
- }
for (y = 0; y < td->ysize; y++) {
index_out = target_channel_offset * td->xsize + y * td->channel_line_size;
@@ -886,7 +880,7 @@ static int b44_uncompress(EXRContext *s, const uint8_t *src, int compressed_size
return 0;
}
-static int ac_uncompress(EXRContext *s, GetByteContext *gb, float *block)
+static int ac_uncompress(const EXRContext *s, GetByteContext *gb, float *block)
{
int ret = 0, n = 1;
@@ -899,10 +893,7 @@ static int ac_uncompress(EXRContext *s, GetByteContext *gb, float *block)
n += val & 0xff;
} else {
ret = n;
- block[ff_zigzag_direct[n]] = av_int2float(half2float(val,
- s->mantissatable,
- s->exponenttable,
- s->offsettable));
+ block[ff_zigzag_direct[n]] = av_int2float(half2float(val, &s->h2f_tables));
n++;
}
}
@@ -986,7 +977,7 @@ static float to_linear(float x, float scale)
}
}
-static int dwa_uncompress(EXRContext *s, const uint8_t *src, int compressed_size,
+static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compressed_size,
int uncompressed_size, EXRThreadData *td)
{
int64_t version, lo_usize, lo_size;
@@ -1120,8 +1111,7 @@ static int dwa_uncompress(EXRContext *s, const uint8_t *src, int compressed_size
uint16_t *dc = (uint16_t *)td->dc_data;
union av_intfloat32 dc_val;
- dc_val.i = half2float(dc[idx], s->mantissatable,
- s->exponenttable, s->offsettable);
+ dc_val.i = half2float(dc[idx], &s->h2f_tables);
block[0] = dc_val.f;
ac_uncompress(s, &agb, block);
@@ -1171,7 +1161,7 @@ static int dwa_uncompress(EXRContext *s, const uint8_t *src, int compressed_size
for (int x = 0; x < td->xsize; x++) {
uint16_t ha = ai0[x] | (ai1[x] << 8);
- ao[x] = half2float(ha, s->mantissatable, s->exponenttable, s->offsettable);
+ ao[x] = half2float(ha, &s->h2f_tables);
}
}
@@ -1181,7 +1171,7 @@ static int dwa_uncompress(EXRContext *s, const uint8_t *src, int compressed_size
static int decode_block(AVCodecContext *avctx, void *tdata,
int jobnr, int threadnr)
{
- EXRContext *s = avctx->priv_data;
+ const EXRContext *s = avctx->priv_data;
AVFrame *const p = s->picture;
EXRThreadData *td = &s->thread_data[threadnr];
const uint8_t *channel_buffer[4] = { 0 };
@@ -1199,7 +1189,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
int i, x, buf_size = s->buf_size;
int c, rgb_channel_count;
float one_gamma = 1.0f / s->gamma;
- avpriv_trc_function trc_func = avpriv_get_trc_function_from_trc(s->apply_trc_type);
+ av_csp_trc_function trc_func = av_csp_trc_func_from_id(s->apply_trc_type);
int ret;
line_offset = AV_RL64(s->gb.buffer + jobnr * 8);
@@ -1427,10 +1417,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
}
} else {
for (x = 0; x < xsize; x++) {
- ptr_x[0].i = half2float(bytestream_get_le16(&src),
- s->mantissatable,
- s->exponenttable,
- s->offsettable);
+ ptr_x[0].i = half2float(bytestream_get_le16(&src), &s->h2f_tables);
ptr_x++;
}
}
@@ -1975,7 +1962,7 @@ static int decode_header(EXRContext *s, AVFrame *frame)
{
uint8_t name[256] = { 0 };
uint8_t type[256] = { 0 };
- uint8_t value[256] = { 0 };
+ uint8_t value[8192] = { 0 };
int i = 0, size;
while (bytestream2_get_bytes_left(gb) > 0 &&
@@ -1993,6 +1980,8 @@ static int decode_header(EXRContext *s, AVFrame *frame)
size = bytestream2_get_le32(gb);
bytestream2_get_buffer(gb, value, FFMIN(sizeof(value) - 1, size));
+ if (size > sizeof(value) - 1)
+ bytestream2_skip(gb, size - (sizeof(value) - 1));
if (!strcmp(type, "string"))
av_dict_set(&metadata, name, value, 0);
}
@@ -2041,7 +2030,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
int nb_blocks; /* nb scanline or nb tile */
uint64_t start_offset_table;
uint64_t start_next_scanline;
- PutByteContext offset_table_writer;
bytestream2_init(gb, avpkt->data, avpkt->size);
@@ -2133,6 +2121,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
ff_set_sar(s->avctx, av_d2q(av_int2float(s->sar), 255));
+ if (avctx->skip_frame >= AVDISCARD_ALL)
+ return avpkt->size;
+
s->desc = av_pix_fmt_desc_get(avctx->pix_fmt);
if (!s->desc)
return AVERROR_INVALIDDATA;
@@ -2161,11 +2152,17 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
// check offset table and recreate it if need
if (!s->is_tile && bytestream2_peek_le64(gb) == 0) {
+ PutByteContext offset_table_writer;
+
av_log(s->avctx, AV_LOG_DEBUG, "recreating invalid scanline offset table\n");
+ s->offset_table = av_realloc_f(s->offset_table, nb_blocks, 8);
+ if (!s->offset_table)
+ return AVERROR(ENOMEM);
+
start_offset_table = bytestream2_tell(gb);
start_next_scanline = start_offset_table + nb_blocks * 8;
- bytestream2_init_writer(&offset_table_writer, &avpkt->data[start_offset_table], nb_blocks * 8);
+ bytestream2_init_writer(&offset_table_writer, s->offset_table, nb_blocks * 8);
for (y = 0; y < nb_blocks; y++) {
/* write offset of prev scanline in offset table */
@@ -2175,7 +2172,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
bytestream2_seek(gb, start_next_scanline + 4, SEEK_SET);/* skip line number */
start_next_scanline += (bytestream2_get_le32(gb) + 8);
}
- bytestream2_seek(gb, start_offset_table, SEEK_SET);
+ bytestream2_init(gb, s->offset_table, nb_blocks * 8);
}
// save pointer we are going to use in decode_block
@@ -2218,9 +2215,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
uint32_t i;
union av_intfloat32 t;
float one_gamma = 1.0f / s->gamma;
- avpriv_trc_function trc_func = NULL;
+ av_csp_trc_function trc_func = NULL;
- half2float_table(s->mantissatable, s->exponenttable, s->offsettable);
+ ff_init_half2float_tables(&s->h2f_tables);
s->avctx = avctx;
@@ -2230,21 +2227,21 @@ static av_cold int decode_init(AVCodecContext *avctx)
ff_bswapdsp_init(&s->bbdsp);
#endif
- trc_func = avpriv_get_trc_function_from_trc(s->apply_trc_type);
+ trc_func = av_csp_trc_func_from_id(s->apply_trc_type);
if (trc_func) {
for (i = 0; i < 65536; ++i) {
- t.i = half2float(i, s->mantissatable, s->exponenttable, s->offsettable);
+ t.i = half2float(i, &s->h2f_tables);
t.f = trc_func(t.f);
s->gamma_table[i] = t;
}
} else {
if (one_gamma > 0.9999f && one_gamma < 1.0001f) {
for (i = 0; i < 65536; ++i) {
- s->gamma_table[i].i = half2float(i, s->mantissatable, s->exponenttable, s->offsettable);
+ s->gamma_table[i].i = half2float(i, &s->h2f_tables);
}
} else {
for (i = 0; i < 65536; ++i) {
- t.i = half2float(i, s->mantissatable, s->exponenttable, s->offsettable);
+ t.i = half2float(i, &s->h2f_tables);
/* If negative value we reuse half value */
if (t.f <= 0.0f) {
s->gamma_table[i] = t;
@@ -2285,6 +2282,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
av_freep(&s->thread_data);
av_freep(&s->channels);
+ av_freep(&s->offset_table);
return 0;
}
@@ -2347,7 +2345,7 @@ static const AVClass exr_class = {
const FFCodec ff_exr_decoder = {
.p.name = "exr",
- .p.long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"),
+ CODEC_LONG_NAME("OpenEXR image"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_EXR,
.priv_data_size = sizeof(EXRContext),
@@ -2356,6 +2354,6 @@ const FFCodec ff_exr_decoder = {
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
AV_CODEC_CAP_SLICE_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
+ .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.p.priv_class = &exr_class,
};
diff --git a/libavcodec/exrenc.c b/libavcodec/exrenc.c
index 8eb138ea0..36327f498 100644
--- a/libavcodec/exrenc.c
+++ b/libavcodec/exrenc.c
@@ -31,11 +31,11 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/imgutils.h"
#include "libavutil/pixdesc.h"
+#include "libavutil/float2half.h"
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
#include "encode.h"
-#include "float2half.h"
enum ExrCompr {
EXR_RAW,
@@ -87,15 +87,14 @@ typedef struct EXRContext {
EXRScanlineData *scanline;
- uint16_t basetable[512];
- uint8_t shifttable[512];
+ Float2HalfTables f2h_tables;
} EXRContext;
static av_cold int encode_init(AVCodecContext *avctx)
{
EXRContext *s = avctx->priv_data;
- float2half_tables(s->basetable, s->shifttable);
+ ff_init_float2half_tables(&s->f2h_tables);
switch (avctx->pix_fmt) {
case AV_PIX_FMT_GBRPF32:
@@ -253,10 +252,10 @@ static int encode_scanline_rle(EXRContext *s, const AVFrame *frame)
for (int p = 0; p < s->planes; p++) {
int ch = s->ch_order[p];
uint16_t *dst = (uint16_t *)(scanline->uncompressed_data + frame->width * 2 * p);
- uint32_t *src = (uint32_t *)(frame->data[ch] + y * frame->linesize[ch]);
+ const uint32_t *src = (const uint32_t *)(frame->data[ch] + y * frame->linesize[ch]);
for (int x = 0; x < frame->width; x++)
- dst[x] = float2half(src[x], s->basetable, s->shifttable);
+ dst[x] = float2half(src[x], &s->f2h_tables);
}
break;
}
@@ -321,10 +320,10 @@ static int encode_scanline_zip(EXRContext *s, const AVFrame *frame)
for (int p = 0; p < s->planes; p++) {
int ch = s->ch_order[p];
uint16_t *dst = (uint16_t *)(scanline->uncompressed_data + scanline_size * l + p * frame->width * 2);
- uint32_t *src = (uint32_t *)(frame->data[ch] + (y * s->scanline_height + l) * frame->linesize[ch]);
+ const uint32_t *src = (const uint32_t *)(frame->data[ch] + (y * s->scanline_height + l) * frame->linesize[ch]);
for (int x = 0; x < frame->width; x++)
- dst[x] = float2half(src[x], s->basetable, s->shifttable);
+ dst[x] = float2half(src[x], &s->f2h_tables);
}
}
break;
@@ -479,10 +478,10 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
bytestream2_put_le32(pb, s->planes * avctx->width * 2);
for (int p = 0; p < s->planes; p++) {
int ch = s->ch_order[p];
- uint32_t *src = (uint32_t *)(frame->data[ch] + y * frame->linesize[ch]);
+ const uint32_t *src = (const uint32_t *)(frame->data[ch] + y * frame->linesize[ch]);
for (int x = 0; x < frame->width; x++)
- bytestream2_put_le16(pb, float2half(src[x], s->basetable, s->shifttable));
+ bytestream2_put_le16(pb, float2half(src[x], &s->f2h_tables));
}
}
}
@@ -543,12 +542,13 @@ static const AVClass exr_class = {
const FFCodec ff_exr_encoder = {
.p.name = "exr",
- .p.long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"),
+ CODEC_LONG_NAME("OpenEXR image"),
.priv_data_size = sizeof(EXRContext),
.p.priv_class = &exr_class,
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_EXR,
- .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.init = encode_init,
FF_CODEC_ENCODE_CB(encode_frame),
.close = encode_close,
@@ -557,5 +557,4 @@ const FFCodec ff_exr_encoder = {
AV_PIX_FMT_GBRPF32,
AV_PIX_FMT_GBRAPF32,
AV_PIX_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/fastaudio.c b/libavcodec/fastaudio.c
index 46fffaf8b..f5569f520 100644
--- a/libavcodec/fastaudio.c
+++ b/libavcodec/fastaudio.c
@@ -21,13 +21,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "libavutil/intreadwrite.h"
-
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
-#include "mathops.h"
+#include "decode.h"
typedef struct ChannelItems {
float f[8];
@@ -189,7 +186,7 @@ static av_cold int fastaudio_close(AVCodecContext *avctx)
const FFCodec ff_fastaudio_decoder = {
.p.name = "fastaudio",
- .p.long_name = NULL_IF_CONFIG_SMALL("MobiClip FastAudio"),
+ CODEC_LONG_NAME("MobiClip FastAudio"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_FASTAUDIO,
.priv_data_size = sizeof(FastAudioContext),
@@ -199,5 +196,4 @@ const FFCodec ff_fastaudio_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/fflcms2.c b/libavcodec/fflcms2.c
new file mode 100644
index 000000000..5443f178b
--- /dev/null
+++ b/libavcodec/fflcms2.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2022 Niklas Haas
+ * 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/csp.h"
+
+#include "fflcms2.h"
+
+static void log_cb(cmsContext ctx, cmsUInt32Number error, const char *str)
+{
+ FFIccContext *s = cmsGetContextUserData(ctx);
+ av_log(s->avctx, AV_LOG_ERROR, "lcms2: [%"PRIu32"] %s\n", error, str);
+}
+
+int ff_icc_context_init(FFIccContext *s, void *avctx)
+{
+ memset(s, 0, sizeof(*s));
+ s->avctx = avctx;
+ s->ctx = cmsCreateContext(NULL, s);
+ if (!s->ctx)
+ return AVERROR(ENOMEM);
+
+ cmsSetLogErrorHandlerTHR(s->ctx, log_cb);
+ return 0;
+}
+
+void ff_icc_context_uninit(FFIccContext *s)
+{
+ for (int i = 0; i < FF_ARRAY_ELEMS(s->curves); i++)
+ cmsFreeToneCurve(s->curves[i]);
+ cmsDeleteContext(s->ctx);
+ memset(s, 0, sizeof(*s));
+}
+
+static int get_curve(FFIccContext *s, enum AVColorTransferCharacteristic trc,
+ cmsToneCurve **out_curve)
+{
+ if (trc >= AVCOL_TRC_NB)
+ return AVERROR_INVALIDDATA;
+
+ if (s->curves[trc])
+ goto done;
+
+ switch (trc) {
+ case AVCOL_TRC_LINEAR:
+ s->curves[trc] = cmsBuildGamma(s->ctx, 1.0);
+ break;
+ case AVCOL_TRC_GAMMA22:
+ s->curves[trc] = cmsBuildGamma(s->ctx, 2.2);
+ break;
+ case AVCOL_TRC_GAMMA28:
+ s->curves[trc] = cmsBuildGamma(s->ctx, 2.8);
+ break;
+ case AVCOL_TRC_BT709:
+ case AVCOL_TRC_SMPTE170M:
+ case AVCOL_TRC_BT2020_10:
+ case AVCOL_TRC_BT2020_12:
+ s->curves[trc] = cmsBuildParametricToneCurve(s->ctx, 4, (double[5]) {
+ /* γ = */ 1/0.45,
+ /* a = */ 1/1.099296826809442,
+ /* b = */ 1 - 1/1.099296826809442,
+ /* c = */ 1/4.5,
+ /* d = */ 4.5 * 0.018053968510807,
+ });
+ break;
+ case AVCOL_TRC_SMPTE240M:
+ s->curves[trc] = cmsBuildParametricToneCurve(s->ctx, 4, (double[5]) {
+ /* γ = */ 1/0.45,
+ /* a = */ 1/1.1115,
+ /* b = */ 1 - 1/1.1115,
+ /* c = */ 1/4.0,
+ /* d = */ 4.0 * 0.0228,
+ });
+ break;
+ case AVCOL_TRC_LOG:
+ s->curves[trc] = cmsBuildParametricToneCurve(s->ctx, 8, (double[5]) {
+ /* a = */ 1.0,
+ /* b = */ 10.0,
+ /* c = */ 2.0,
+ /* d = */ -1.0,
+ /* e = */ 0.0
+ });
+ break;
+ case AVCOL_TRC_LOG_SQRT:
+ s->curves[trc] = cmsBuildParametricToneCurve(s->ctx, 8, (double[5]) {
+ /* a = */ 1.0,
+ /* b = */ 10.0,
+ /* c = */ 2.5,
+ /* d = */ -1.0,
+ /* e = */ 0.0
+ });
+ break;
+ case AVCOL_TRC_IEC61966_2_1:
+ s->curves[trc] = cmsBuildParametricToneCurve(s->ctx, 4, (double[5]) {
+ /* γ = */ 2.4,
+ /* a = */ 1/1.055,
+ /* b = */ 1 - 1/1.055,
+ /* c = */ 1/12.92,
+ /* d = */ 12.92 * 0.0031308,
+ });
+ break;
+ case AVCOL_TRC_SMPTE428:
+ s->curves[trc] = cmsBuildParametricToneCurve(s->ctx, 2, (double[3]) {
+ /* γ = */ 2.6,
+ /* a = */ pow(52.37/48.0, 1/2.6),
+ /* b = */ 0.0
+ });
+ break;
+
+ /* Can't be represented using the existing parametric tone curves.
+ * FIXME: use cmsBuildTabulatedToneCurveFloat instead */
+ case AVCOL_TRC_IEC61966_2_4:
+ case AVCOL_TRC_BT1361_ECG:
+ case AVCOL_TRC_SMPTE2084:
+ case AVCOL_TRC_ARIB_STD_B67:
+ return AVERROR_PATCHWELCOME;
+
+ default:
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!s->curves[trc])
+ return AVERROR(ENOMEM);
+
+done:
+ *out_curve = s->curves[trc];
+ return 0;
+}
+
+int ff_icc_profile_generate(FFIccContext *s,
+ enum AVColorPrimaries color_prim,
+ enum AVColorTransferCharacteristic color_trc,
+ cmsHPROFILE *out_profile)
+{
+ cmsToneCurve *tonecurve;
+ const AVColorPrimariesDesc *prim;
+ int ret;
+
+ if (!(prim = av_csp_primaries_desc_from_id(color_prim)))
+ return AVERROR_INVALIDDATA;
+ if ((ret = get_curve(s, color_trc, &tonecurve)) < 0)
+ return ret;
+
+ *out_profile = cmsCreateRGBProfileTHR(s->ctx,
+ &(cmsCIExyY) { av_q2d(prim->wp.x), av_q2d(prim->wp.y), 1.0 },
+ &(cmsCIExyYTRIPLE) {
+ .Red = { av_q2d(prim->prim.r.x), av_q2d(prim->prim.r.y), 1.0 },
+ .Green = { av_q2d(prim->prim.g.x), av_q2d(prim->prim.g.y), 1.0 },
+ .Blue = { av_q2d(prim->prim.b.x), av_q2d(prim->prim.b.y), 1.0 },
+ },
+ (cmsToneCurve *[3]) { tonecurve, tonecurve, tonecurve }
+ );
+
+ return *out_profile == NULL ? AVERROR(ENOMEM) : 0;
+}
+
+int ff_icc_profile_attach(FFIccContext *s, cmsHPROFILE profile, AVFrame *frame)
+{
+ cmsUInt32Number size;
+ AVBufferRef *buf;
+
+ if (!cmsSaveProfileToMem(profile, NULL, &size))
+ return AVERROR_EXTERNAL;
+
+ buf = av_buffer_alloc(size);
+ if (!buf)
+ return AVERROR(ENOMEM);
+
+ if (!cmsSaveProfileToMem(profile, buf->data, &size) || size != buf->size) {
+ av_buffer_unref(&buf);
+ return AVERROR_EXTERNAL;
+ }
+
+ if (!av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_ICC_PROFILE, buf)) {
+ av_buffer_unref(&buf);
+ return AVERROR(ENOMEM);
+ }
+
+ return 0;
+}
+
+static av_always_inline void XYZ_xy(cmsCIEXYZ XYZ, AVCIExy *xy)
+{
+ double k = 1.0 / (XYZ.X + XYZ.Y + XYZ.Z);
+ xy->x = av_d2q(k * XYZ.X, 100000);
+ xy->y = av_d2q(k * XYZ.Y, 100000);
+}
+
+int ff_icc_profile_read_primaries(FFIccContext *s, cmsHPROFILE profile,
+ AVColorPrimariesDesc *out_primaries)
+{
+ static const uint8_t testprimaries[4][3] = {
+ { 0xFF, 0, 0 }, /* red */
+ { 0, 0xFF, 0 }, /* green */
+ { 0, 0, 0xFF }, /* blue */
+ { 0xFF, 0xFF, 0xFF }, /* white */
+ };
+
+ AVWhitepointCoefficients *wp = &out_primaries->wp;
+ AVPrimaryCoefficients *prim = &out_primaries->prim;
+ cmsFloat64Number prev_adapt;
+ cmsHPROFILE xyz;
+ cmsHTRANSFORM tf;
+ cmsCIEXYZ dst[4];
+
+ xyz = cmsCreateXYZProfileTHR(s->ctx);
+ if (!xyz)
+ return AVERROR(ENOMEM);
+
+ /* We need to use an unadapted observer to get the raw values */
+ prev_adapt = cmsSetAdaptationStateTHR(s->ctx, 0.0);
+ tf = cmsCreateTransformTHR(s->ctx, profile, TYPE_RGB_8, xyz, TYPE_XYZ_DBL,
+ INTENT_ABSOLUTE_COLORIMETRIC,
+ /* Note: These flags mostly don't do anything
+ * anyway, but specify them regardless */
+ cmsFLAGS_NOCACHE |
+ cmsFLAGS_NOOPTIMIZE |
+ cmsFLAGS_LOWRESPRECALC |
+ cmsFLAGS_GRIDPOINTS(2));
+ cmsSetAdaptationStateTHR(s->ctx, prev_adapt);
+ cmsCloseProfile(xyz);
+ if (!tf) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid ICC profile (e.g. CMYK)\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ cmsDoTransform(tf, testprimaries, dst, 4);
+ cmsDeleteTransform(tf);
+ XYZ_xy(dst[0], &prim->r);
+ XYZ_xy(dst[1], &prim->g);
+ XYZ_xy(dst[2], &prim->b);
+ XYZ_xy(dst[3], wp);
+ return 0;
+}
+
+int ff_icc_profile_detect_transfer(FFIccContext *s, cmsHPROFILE profile,
+ enum AVColorTransferCharacteristic *out_trc)
+{
+ /* 8-bit linear grayscale ramp */
+ static const uint8_t testramp[16][3] = {
+ { 1, 1, 1}, /* avoid exact zero due to log100 etc. */
+ { 17, 17, 17},
+ { 34, 34, 34},
+ { 51, 51, 51},
+ { 68, 68, 68},
+ { 85, 85, 85},
+ { 02, 02, 02},
+ {119, 119, 119},
+ {136, 136, 136},
+ {153, 153, 153},
+ {170, 170, 170},
+ {187, 187, 187},
+ {204, 204, 204},
+ {221, 221, 221},
+ {238, 238, 238},
+ {255, 255, 255},
+ };
+
+ double dst[FF_ARRAY_ELEMS(testramp)];
+
+ for (enum AVColorTransferCharacteristic trc = 0; trc < AVCOL_TRC_NB; trc++) {
+ cmsToneCurve *tonecurve;
+ cmsHPROFILE ref;
+ cmsHTRANSFORM tf;
+ double delta = 0.0;
+ if (get_curve(s, trc, &tonecurve) < 0)
+ continue;
+
+ ref = cmsCreateGrayProfileTHR(s->ctx, cmsD50_xyY(), tonecurve);
+ if (!ref)
+ return AVERROR(ENOMEM);
+
+ tf = cmsCreateTransformTHR(s->ctx, profile, TYPE_RGB_8, ref, TYPE_GRAY_DBL,
+ INTENT_RELATIVE_COLORIMETRIC,
+ cmsFLAGS_NOCACHE | cmsFLAGS_NOOPTIMIZE);
+ cmsCloseProfile(ref);
+ if (!tf) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid ICC profile (e.g. CMYK)\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ cmsDoTransform(tf, testramp, dst, FF_ARRAY_ELEMS(dst));
+ cmsDeleteTransform(tf);
+
+ for (int i = 0; i < FF_ARRAY_ELEMS(dst); i++)
+ delta += fabs(testramp[i][0] / 255.0 - dst[i]);
+ if (delta < 0.01) {
+ *out_trc = trc;
+ return 0;
+ }
+ }
+
+ *out_trc = AVCOL_TRC_UNSPECIFIED;
+ return 0;
+}
diff --git a/libavcodec/fflcms2.h b/libavcodec/fflcms2.h
new file mode 100644
index 000000000..af63c9a13
--- /dev/null
+++ b/libavcodec/fflcms2.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2022 Niklas Haas
+ * 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
+ * Various functions for dealing with ICC profiles
+ */
+
+#ifndef AVCODEC_FFLCMS2_H
+#define AVCODEC_FFLCMS2_H
+
+#include "libavutil/csp.h"
+#include "libavutil/frame.h"
+#include "libavutil/pixfmt.h"
+
+#include
+
+typedef struct FFIccContext {
+ void *avctx;
+ cmsContext ctx;
+ cmsToneCurve *curves[AVCOL_TRC_NB]; /* tone curve cache */
+} FFIccContext;
+
+/**
+ * Initializes an FFIccContext. This must be done prior to using it.
+ *
+ * Returns 0 on success, or a negative error code.
+ */
+int ff_icc_context_init(FFIccContext *s, void *avctx);
+void ff_icc_context_uninit(FFIccContext *s);
+
+/**
+ * Generate an ICC profile for a given combination of color primaries and
+ * transfer function. Both values must be set to valid entries (not
+ * "undefined") for this function to work.
+ *
+ * Returns 0 on success, or a negative error code.
+ */
+int ff_icc_profile_generate(FFIccContext *s,
+ enum AVColorPrimaries color_prim,
+ enum AVColorTransferCharacteristic color_trc,
+ cmsHPROFILE *out_profile);
+
+/**
+ * Attach an ICC profile to a frame. Helper wrapper around cmsSaveProfileToMem
+ * and av_frame_new_side_data_from_buf.
+ *
+ * Returns 0 on success, or a negative error code.
+ */
+int ff_icc_profile_attach(FFIccContext *s, cmsHPROFILE profile, AVFrame *frame);
+
+/**
+ * Read the color primaries and white point coefficients encoded by an ICC
+ * profile, and return the raw values in `out_primaries`.
+ *
+ * Returns 0 on success, or a negative error code.
+ */
+int ff_icc_profile_read_primaries(FFIccContext *s, cmsHPROFILE profile,
+ AVColorPrimariesDesc *out_primaries);
+
+/**
+ * Attempt detecting the transfer characteristic that best approximates the
+ * transfer function encoded by an ICC profile. Sets `out_trc` to
+ * AVCOL_TRC_UNSPECIFIED if no clear match can be identified.
+ *
+ * Returns 0 on success (including no match), or a negative error code.
+ */
+int ff_icc_profile_detect_transfer(FFIccContext *s, cmsHPROFILE profile,
+ enum AVColorTransferCharacteristic *out_trc);
+
+#endif /* AVCODEC_FFLCMS2_H */
diff --git a/libavcodec/fft.h b/libavcodec/fft.h
index 706c9d07f..d46e5a3f0 100644
--- a/libavcodec/fft.h
+++ b/libavcodec/fft.h
@@ -29,6 +29,7 @@
#include
#include "config.h"
+#include "libavutil/attributes_internal.h"
#include "libavutil/mem_internal.h"
#if FFT_FLOAT
@@ -114,7 +115,7 @@ void ff_init_ff_cos_tabs(int index);
#endif
#define COSTABLE(size) \
- COSTABLE_CONST DECLARE_ALIGNED(32, FFTSample, FFT_NAME(ff_cos_##size))[size/2]
+ COSTABLE_CONST attribute_visibility_hidden DECLARE_ALIGNED(32, FFTSample, FFT_NAME(ff_cos_##size))[size/2]
extern COSTABLE(16);
extern COSTABLE(32);
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index c8781cdaa..b6204740e 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -43,11 +43,6 @@ av_cold int ff_ffv1_common_init(AVCodecContext *avctx)
s->avctx = avctx;
s->flags = avctx->flags;
- s->picture.f = av_frame_alloc();
- s->last_picture.f = av_frame_alloc();
- if (!s->picture.f || !s->last_picture.f)
- return AVERROR(ENOMEM);
-
s->width = avctx->width;
s->height = avctx->height;
@@ -198,14 +193,6 @@ av_cold int ff_ffv1_close(AVCodecContext *avctx)
FFV1Context *s = avctx->priv_data;
int i, j;
- if (s->picture.f)
- ff_thread_release_ext_buffer(avctx, &s->picture);
- av_frame_free(&s->picture.f);
-
- if (s->last_picture.f)
- ff_thread_release_ext_buffer(avctx, &s->last_picture);
- av_frame_free(&s->last_picture.f);
-
for (j = 0; j < s->max_slice_count; j++) {
FFV1Context *fs = s->slice_context[j];
for (i = 0; i < s->plane_count; i++) {
diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h
index ac80fa85c..04869da5c 100644
--- a/libavcodec/ffv1.h
+++ b/libavcodec/ffv1.h
@@ -85,12 +85,13 @@ typedef struct FFV1Context {
int chroma_h_shift, chroma_v_shift;
int transparency;
int flags;
- int picture_number;
+ int64_t picture_number;
int key_frame;
ThreadFrame picture, last_picture;
struct FFV1Context *fsrc;
AVFrame *cur;
+ const AVFrame *cur_enc_frame;
int plane_count;
int ac; ///< 1=range coder <-> 0=golomb rice
int ac_byte_count; ///< number of bytes used for AC coding
@@ -181,16 +182,4 @@ static inline void update_vlc_state(VlcState *const state, const int v)
state->count = count;
}
-#define TYPE int16_t
-#define RENAME(name) name
-#include "ffv1_template.c"
-#undef TYPE
-#undef RENAME
-
-#define TYPE int32_t
-#define RENAME(name) name ## 32
-#include "ffv1_template.c"
-#undef TYPE
-#undef RENAME
-
#endif /* AVCODEC_FFV1_H */
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index 930029726..180d24e69 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -168,24 +168,31 @@ static int decode_slice_header(const FFV1Context *f, FFV1Context *fs)
RangeCoder *c = &fs->c;
uint8_t state[CONTEXT_SIZE];
unsigned ps, i, context_count;
+ int sx, sy, sw, sh;
+
memset(state, 128, sizeof(state));
+ sx = get_symbol(c, state, 0);
+ sy = get_symbol(c, state, 0);
+ sw = get_symbol(c, state, 0) + 1U;
+ sh = get_symbol(c, state, 0) + 1U;
av_assert0(f->version > 2);
- fs->slice_x = get_symbol(c, state, 0) * f->width ;
- fs->slice_y = get_symbol(c, state, 0) * f->height;
- fs->slice_width = (get_symbol(c, state, 0) + 1) * f->width + fs->slice_x;
- fs->slice_height = (get_symbol(c, state, 0) + 1) * f->height + fs->slice_y;
- fs->slice_x /= f->num_h_slices;
- fs->slice_y /= f->num_v_slices;
- fs->slice_width = fs->slice_width /f->num_h_slices - fs->slice_x;
- fs->slice_height = fs->slice_height/f->num_v_slices - fs->slice_y;
- if ((unsigned)fs->slice_width > f->width || (unsigned)fs->slice_height > f->height)
- return -1;
- if ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width > f->width
- || (unsigned)fs->slice_y + (uint64_t)fs->slice_height > f->height)
- return -1;
+ if (sx < 0 || sy < 0 || sw <= 0 || sh <= 0)
+ return AVERROR_INVALIDDATA;
+ if (sx > f->num_h_slices - sw || sy > f->num_v_slices - sh)
+ return AVERROR_INVALIDDATA;
+
+ fs->slice_x = sx * (int64_t)f->width / f->num_h_slices;
+ fs->slice_y = sy * (int64_t)f->height / f->num_v_slices;
+ fs->slice_width = (sx + sw) * (int64_t)f->width / f->num_h_slices - fs->slice_x;
+ fs->slice_height = (sy + sh) * (int64_t)f->height / f->num_v_slices - fs->slice_y;
+
+ av_assert0((unsigned)fs->slice_width <= f->width &&
+ (unsigned)fs->slice_height <= f->height);
+ av_assert0 ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width <= f->width
+ && (unsigned)fs->slice_y + (uint64_t)fs->slice_height <= f->height);
if (fs->ac == AC_GOLOMB_RICE && fs->slice_width >= (1<<23))
return AVERROR_INVALIDDATA;
@@ -303,8 +310,11 @@ static int decode_slice(AVCodecContext *c, void *arg)
}
if ((ret = ff_ffv1_init_slice_state(f, fs)) < 0)
return ret;
- if (f->cur->key_frame || fs->slice_reset_contexts)
+ if (f->cur->key_frame || fs->slice_reset_contexts) {
ff_ffv1_clear_slice_state(f, fs);
+ } else if (fs->slice_damaged) {
+ return AVERROR_INVALIDDATA;
+ }
width = fs->slice_width;
height = fs->slice_height;
@@ -360,8 +370,6 @@ static int decode_slice(AVCodecContext *c, void *arg)
}
}
- emms_c();
-
ff_thread_report_progress(&f->picture, si, 0);
return 0;
@@ -467,6 +475,11 @@ static int read_extra_header(FFV1Context *f)
return AVERROR_INVALIDDATA;
}
+ if (f->num_h_slices > MAX_SLICES / f->num_v_slices) {
+ av_log(f->avctx, AV_LOG_ERROR, "slice count unsupported\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
f->quant_table_count = get_symbol(c, state, 0);
if (f->quant_table_count > (unsigned)MAX_QUANT_TABLES || !f->quant_table_count) {
av_log(f->avctx, AV_LOG_ERROR, "quant table count %d is invalid\n", f->quant_table_count);
@@ -769,21 +782,25 @@ static int read_header(FFV1Context *f)
fs->slice_damaged = 0;
if (f->version == 2) {
- fs->slice_x = get_symbol(c, state, 0) * f->width ;
- fs->slice_y = get_symbol(c, state, 0) * f->height;
- fs->slice_width = (get_symbol(c, state, 0) + 1) * f->width + fs->slice_x;
- fs->slice_height = (get_symbol(c, state, 0) + 1) * f->height + fs->slice_y;
+ int sx = get_symbol(c, state, 0);
+ int sy = get_symbol(c, state, 0);
+ int sw = get_symbol(c, state, 0) + 1U;
+ int sh = get_symbol(c, state, 0) + 1U;
- fs->slice_x /= f->num_h_slices;
- fs->slice_y /= f->num_v_slices;
- fs->slice_width = fs->slice_width / f->num_h_slices - fs->slice_x;
- fs->slice_height = fs->slice_height / f->num_v_slices - fs->slice_y;
- if ((unsigned)fs->slice_width > f->width ||
- (unsigned)fs->slice_height > f->height)
+ if (sx < 0 || sy < 0 || sw <= 0 || sh <= 0)
return AVERROR_INVALIDDATA;
- if ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width > f->width
- || (unsigned)fs->slice_y + (uint64_t)fs->slice_height > f->height)
+ if (sx > f->num_h_slices - sw || sy > f->num_v_slices - sh)
return AVERROR_INVALIDDATA;
+
+ fs->slice_x = sx * (int64_t)f->width / f->num_h_slices;
+ fs->slice_y = sy * (int64_t)f->height / f->num_v_slices;
+ fs->slice_width = (sx + sw) * (int64_t)f->width / f->num_h_slices - fs->slice_x;
+ fs->slice_height = (sy + sh) * (int64_t)f->height / f->num_v_slices - fs->slice_y;
+
+ av_assert0((unsigned)fs->slice_width <= f->width &&
+ (unsigned)fs->slice_height <= f->height);
+ av_assert0 ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width <= f->width
+ && (unsigned)fs->slice_y + (uint64_t)fs->slice_height <= f->height);
}
for (i = 0; i < f->plane_count; i++) {
@@ -825,6 +842,11 @@ static av_cold int decode_init(AVCodecContext *avctx)
if ((ret = ff_ffv1_common_init(avctx)) < 0)
return ret;
+ f->picture.f = av_frame_alloc();
+ f->last_picture.f = av_frame_alloc();
+ if (!f->picture.f || !f->last_picture.f)
+ return AVERROR(ENOMEM);
+
if (avctx->extradata_size > 0 && (ret = read_extra_header(f)) < 0)
return ret;
@@ -1070,18 +1092,34 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
}
#endif
+static av_cold int ffv1_decode_close(AVCodecContext *avctx)
+{
+ FFV1Context *const s = avctx->priv_data;
+
+ if (s->picture.f) {
+ ff_thread_release_ext_buffer(avctx, &s->picture);
+ av_frame_free(&s->picture.f);
+ }
+
+ if (s->last_picture.f) {
+ ff_thread_release_ext_buffer(avctx, &s->last_picture);
+ av_frame_free(&s->last_picture.f);
+ }
+ return ff_ffv1_close(avctx);
+}
+
const FFCodec ff_ffv1_decoder = {
.p.name = "ffv1",
- .p.long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
+ CODEC_LONG_NAME("FFmpeg video codec #1"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FFV1,
.priv_data_size = sizeof(FFV1Context),
.init = decode_init,
- .close = ff_ffv1_close,
+ .close = ffv1_decode_close,
FF_CODEC_DECODE_CB(decode_frame),
- .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
- .p.capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/ |
+ UPDATE_THREAD_CONTEXT(update_thread_context),
+ .p.capabilities = AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP |
FF_CODEC_CAP_ALLOCATE_PROGRESS,
};
diff --git a/libavcodec/ffv1dec_template.c b/libavcodec/ffv1dec_template.c
index 9b1d65e82..590ccac02 100644
--- a/libavcodec/ffv1dec_template.c
+++ b/libavcodec/ffv1dec_template.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "ffv1_template.c"
+
static av_always_inline int RENAME(decode_line)(FFV1Context *s, int w,
TYPE *sample[2],
int plane_index, int bits)
diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
index 9849082e4..fb12776cc 100644
--- a/libavcodec/ffv1enc.c
+++ b/libavcodec/ffv1enc.c
@@ -270,7 +270,7 @@ static inline void put_vlc_symbol(PutBitContext *pb, VlcState *const state,
#define RENAME(name) name ## 32
#include "ffv1enc_template.c"
-static int encode_plane(FFV1Context *s, uint8_t *src, int w, int h,
+static int encode_plane(FFV1Context *s, const uint8_t *src, int w, int h,
int stride, int plane_index, int pixel_stride)
{
int x, y, i, ret;
@@ -916,12 +916,12 @@ static void encode_slice_header(FFV1Context *f, FFV1Context *fs)
put_symbol(c, state, f->plane[j].quant_table_index, 0);
av_assert0(f->plane[j].quant_table_index == f->context_model);
}
- if (!f->picture.f->interlaced_frame)
+ if (!f->cur_enc_frame->interlaced_frame)
put_symbol(c, state, 3, 0);
else
- put_symbol(c, state, 1 + !f->picture.f->top_field_first, 0);
- put_symbol(c, state, f->picture.f->sample_aspect_ratio.num, 0);
- put_symbol(c, state, f->picture.f->sample_aspect_ratio.den, 0);
+ put_symbol(c, state, 1 + !f->cur_enc_frame->top_field_first, 0);
+ put_symbol(c, state, f->cur_enc_frame->sample_aspect_ratio.num, 0);
+ put_symbol(c, state, f->cur_enc_frame->sample_aspect_ratio.den, 0);
if (f->version > 3) {
put_rac(c, state, fs->slice_coding_mode == 1);
if (fs->slice_coding_mode == 1)
@@ -1024,7 +1024,7 @@ static int encode_slice(AVCodecContext *c, void *arg)
int height = fs->slice_height;
int x = fs->slice_x;
int y = fs->slice_y;
- const AVFrame *const p = f->picture.f;
+ const AVFrame *const p = f->cur_enc_frame;
const int ps = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step;
int ret;
RangeCoder c_bak = fs->c;
@@ -1076,7 +1076,6 @@ retry:
} else {
ret = encode_rgb_frame(fs, planes, width, height, p->linesize);
}
- emms_c();
if (ret < 0) {
av_assert0(fs->slice_coding_mode == 0);
@@ -1098,7 +1097,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
{
FFV1Context *f = avctx->priv_data;
RangeCoder *const c = &f->slice_context[0]->c;
- AVFrame *const p = f->picture.f;
uint8_t keystate = 128;
uint8_t *buf_p;
int i, ret;
@@ -1165,9 +1163,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
ff_init_range_encoder(c, pkt->data, pkt->size);
ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
- av_frame_unref(p);
- if ((ret = av_frame_ref(p, pict)) < 0)
- return ret;
+ f->cur_enc_frame = pict;
if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
put_rac(c, &keystate, 1);
@@ -1235,20 +1231,12 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
f->picture_number++;
pkt->size = buf_p - pkt->data;
- pkt->pts =
- pkt->dts = pict->pts;
pkt->flags |= AV_PKT_FLAG_KEY * f->key_frame;
*got_packet = 1;
return 0;
}
-static av_cold int encode_close(AVCodecContext *avctx)
-{
- ff_ffv1_close(avctx);
- return 0;
-}
-
#define OFFSET(x) offsetof(FFV1Context, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
@@ -1278,14 +1266,16 @@ static const AVClass ffv1_class = {
const FFCodec ff_ffv1_encoder = {
.p.name = "ffv1",
- .p.long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
+ CODEC_LONG_NAME("FFmpeg video codec #1"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FFV1,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_SLICE_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(FFV1Context),
.init = encode_init,
FF_CODEC_ENCODE_CB(encode_frame),
- .close = encode_close,
- .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_DELAY,
+ .close = ff_ffv1_close,
.p.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV444P,
AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P,
@@ -1310,5 +1300,5 @@ const FFCodec ff_ffv1_encoder = {
},
.p.priv_class = &ffv1_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_EOF_FLUSH,
};
diff --git a/libavcodec/ffv1enc_template.c b/libavcodec/ffv1enc_template.c
index 8a4a38792..8953dbe07 100644
--- a/libavcodec/ffv1enc_template.c
+++ b/libavcodec/ffv1enc_template.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "ffv1_template.c"
+
static av_always_inline int RENAME(encode_line)(FFV1Context *s, int w,
TYPE *sample[3],
int plane_index, int bits)
diff --git a/libavcodec/ffwavesynth.c b/libavcodec/ffwavesynth.c
index 67e867b44..b932326fd 100644
--- a/libavcodec/ffwavesynth.c
+++ b/libavcodec/ffwavesynth.c
@@ -23,7 +23,7 @@
#include "libavutil/log.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#define SIN_BITS 14
@@ -461,7 +461,7 @@ static av_cold int wavesynth_close(AVCodecContext *avc)
const FFCodec ff_ffwavesynth_decoder = {
.p.name = "wavesynth",
- .p.long_name = NULL_IF_CONFIG_SMALL("Wave synthesis pseudo-codec"),
+ CODEC_LONG_NAME("Wave synthesis pseudo-codec"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_FFWAVESYNTH,
.priv_data_size = sizeof(struct wavesynth_context),
@@ -469,5 +469,5 @@ const FFCodec ff_ffwavesynth_decoder = {
.close = wavesynth_close,
FF_CODEC_DECODE_CB(wavesynth_decode),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/fic.c b/libavcodec/fic.c
index 491f63ea0..94cf42887 100644
--- a/libavcodec/fic.c
+++ b/libavcodec/fic.c
@@ -26,7 +26,7 @@
#include "libavutil/opt.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "get_bits.h"
#include "golomb.h"
@@ -486,7 +486,7 @@ static const AVClass fic_decoder_class = {
const FFCodec ff_fic_decoder = {
.p.name = "fic",
- .p.long_name = NULL_IF_CONFIG_SMALL("Mirillis FIC"),
+ CODEC_LONG_NAME("Mirillis FIC"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FIC,
.priv_data_size = sizeof(FICContext),
@@ -495,5 +495,4 @@ const FFCodec ff_fic_decoder = {
.close = fic_decode_close,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
.p.priv_class = &fic_decoder_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/fitsdec.c b/libavcodec/fitsdec.c
index b60c2bd44..b9c51e70c 100644
--- a/libavcodec/fitsdec.c
+++ b/libavcodec/fitsdec.c
@@ -32,7 +32,7 @@
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
@@ -326,7 +326,7 @@ const FFCodec ff_fits_decoder = {
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FITS,
.p.capabilities = AV_CODEC_CAP_DR1,
- .p.long_name = NULL_IF_CONFIG_SMALL("Flexible Image Transport System"),
+ CODEC_LONG_NAME("Flexible Image Transport System"),
.p.priv_class = &fits_decoder_class,
.priv_data_size = sizeof(FITSContext),
FF_CODEC_DECODE_CB(fits_decode_frame),
diff --git a/libavcodec/fitsenc.c b/libavcodec/fitsenc.c
index 5e9100be8..12952278a 100644
--- a/libavcodec/fitsenc.c
+++ b/libavcodec/fitsenc.c
@@ -36,10 +36,9 @@
#include "encode.h"
static int fits_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
- const AVFrame *pict, int *got_packet)
+ const AVFrame *p, int *got_packet)
{
- AVFrame * const p = (AVFrame *)pict;
- uint8_t *bytestream, *ptr;
+ uint8_t *bytestream;
const uint16_t flip = (1 << 15);
uint64_t data_size = 0, padded_data_size = 0;
int ret, bitpix, naxis3 = 1, i, j, k, bytes_left;
@@ -88,7 +87,7 @@ static int fits_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
for (k = 0; k < naxis3; k++) {
for (i = 0; i < avctx->height; i++) {
- ptr = p->data[map[k]] + (avctx->height - i - 1) * p->linesize[map[k]];
+ const uint8_t *ptr = p->data[map[k]] + (avctx->height - i - 1) * p->linesize[map[k]];
if (bitpix == 16) {
for (j = 0; j < avctx->width; j++) {
// subtracting bzero is equivalent to first bit flip
@@ -112,10 +111,10 @@ static int fits_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const FFCodec ff_fits_encoder = {
.p.name = "fits",
- .p.long_name = NULL_IF_CONFIG_SMALL("Flexible Image Transport System"),
+ CODEC_LONG_NAME("Flexible Image Transport System"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FITS,
- .p.capabilities = AV_CODEC_CAP_DR1,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
FF_CODEC_ENCODE_CB(fits_encode_frame),
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_GBRAP16BE,
AV_PIX_FMT_GBRP16BE,
diff --git a/libavcodec/flac.c b/libavcodec/flac.c
index dd6883062..174b4801b 100644
--- a/libavcodec/flac.c
+++ b/libavcodec/flac.c
@@ -26,8 +26,9 @@
#include "get_bits.h"
#include "flac.h"
#include "flacdata.h"
+#include "flac_parse.h"
-static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 };
+static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 32 };
static const AVChannelLayout flac_channel_layouts[8] = {
AV_CHANNEL_LAYOUT_MONO,
@@ -81,7 +82,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
/* bits per sample */
bps_code = get_bits(gb, 3);
- if (bps_code == 3 || bps_code == 7) {
+ if (bps_code == 3) {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"invalid sample size code (%d)\n",
bps_code);
@@ -145,29 +146,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
return 0;
}
-int ff_flac_get_max_frame_size(int blocksize, int ch, int bps)
-{
- /* Technically, there is no limit to FLAC frame size, but an encoder
- should not write a frame that is larger than if verbatim encoding mode
- were to be used. */
-
- int count;
-
- count = 16; /* frame header */
- count += ch * ((7+bps+7)/8); /* subframe headers */
- if (ch == 2) {
- /* for stereo, need to account for using decorrelation */
- count += (( 2*bps+1) * blocksize + 7) / 8;
- } else {
- count += ( ch*bps * blocksize + 7) / 8;
- }
- count += 2; /* frame footer */
-
- return count;
-}
-
int ff_flac_is_extradata_valid(AVCodecContext *avctx,
- enum FLACExtradataFormat *format,
uint8_t **streaminfo_start)
{
if (!avctx->extradata || avctx->extradata_size < FLAC_STREAMINFO_SIZE) {
@@ -180,14 +159,12 @@ int ff_flac_is_extradata_valid(AVCodecContext *avctx,
av_log(avctx, AV_LOG_WARNING, "extradata contains %d bytes too many.\n",
FLAC_STREAMINFO_SIZE-avctx->extradata_size);
}
- *format = FLAC_EXTRADATA_FORMAT_STREAMINFO;
*streaminfo_start = avctx->extradata;
} else {
if (avctx->extradata_size < 8+FLAC_STREAMINFO_SIZE) {
av_log(avctx, AV_LOG_ERROR, "extradata too small.\n");
return 0;
}
- *format = FLAC_EXTRADATA_FORMAT_FULL_HEADER;
*streaminfo_start = &avctx->extradata[8];
}
return 1;
diff --git a/libavcodec/flac.h b/libavcodec/flac.h
index cb220ab4c..00e631ed2 100644
--- a/libavcodec/flac.h
+++ b/libavcodec/flac.h
@@ -1,5 +1,5 @@
/*
- * FLAC (Free Lossless Audio Codec) decoder/demuxer common functions
+ * FLAC (Free Lossless Audio Codec) common stuff
* Copyright (c) 2008 Justin Ruggles
*
* This file is part of FFmpeg.
@@ -21,21 +21,19 @@
/**
* @file
- * FLAC (Free Lossless Audio Codec) decoder/demuxer common functions
+ * FLAC (Free Lossless Audio Codec) common stuff
*/
#ifndef AVCODEC_FLAC_H
#define AVCODEC_FLAC_H
-#include "avcodec.h"
-#include "bytestream.h"
-#include "get_bits.h"
+#include "libavutil/intreadwrite.h"
#define FLAC_STREAMINFO_SIZE 34
#define FLAC_MAX_CHANNELS 8
#define FLAC_MIN_BLOCKSIZE 16
#define FLAC_MAX_BLOCKSIZE 65535
-#define FLAC_MIN_FRAME_SIZE 11
+#define FLAC_MIN_FRAME_SIZE 10
enum {
FLAC_CHMODE_INDEPENDENT = 0,
@@ -55,84 +53,6 @@ enum {
FLAC_METADATA_TYPE_INVALID = 127
};
-enum FLACExtradataFormat {
- FLAC_EXTRADATA_FORMAT_STREAMINFO = 0,
- FLAC_EXTRADATA_FORMAT_FULL_HEADER = 1
-};
-
-#define FLACCOMMONINFO \
- int samplerate; /**< sample rate */\
- int channels; /**< number of channels */\
- int bps; /**< bits-per-sample */\
-
-/**
- * Data needed from the Streaminfo header for use by the raw FLAC demuxer
- * and/or the FLAC decoder.
- */
-#define FLACSTREAMINFO \
- FLACCOMMONINFO \
- int max_blocksize; /**< maximum block size, in samples */\
- int max_framesize; /**< maximum frame size, in bytes */\
- int64_t samples; /**< total number of samples */\
-
-typedef struct FLACStreaminfo {
- FLACSTREAMINFO
-} FLACStreaminfo;
-
-typedef struct FLACFrameInfo {
- FLACCOMMONINFO
- int blocksize; /**< block size of the frame */
- int ch_mode; /**< channel decorrelation mode */
- int64_t frame_or_sample_num; /**< frame number or sample number */
- int is_var_size; /**< specifies if the stream uses variable
- block sizes or a fixed block size;
- also determines the meaning of
- frame_or_sample_num */
-} FLACFrameInfo;
-
-/**
- * Parse the Streaminfo metadata block
- * @param[out] avctx codec context to set basic stream parameters
- * @param[out] s where parsed information is stored
- * @param[in] buffer pointer to start of 34-byte streaminfo data
- *
- * @return negative error code on faiure or >= 0 on success
- */
-int ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
- const uint8_t *buffer);
-
-/**
- * Validate the FLAC extradata.
- * @param[in] avctx codec context containing the extradata.
- * @param[out] format extradata format.
- * @param[out] streaminfo_start pointer to start of 34-byte STREAMINFO data.
- * @return 1 if valid, 0 if not valid.
- */
-int ff_flac_is_extradata_valid(AVCodecContext *avctx,
- enum FLACExtradataFormat *format,
- uint8_t **streaminfo_start);
-
-/**
- * Calculate an estimate for the maximum frame size based on verbatim mode.
- * @param blocksize block size, in samples
- * @param ch number of channels
- * @param bps bits-per-sample
- */
-int ff_flac_get_max_frame_size(int blocksize, int ch, int bps);
-
-/**
- * Validate and decode a frame header.
- * @param avctx AVCodecContext to use as av_log() context
- * @param gb GetBitContext from which to read frame header
- * @param[out] fi frame information
- * @param log_level_offset log level offset. can be used to silence error messages.
- * @return non-zero on error, 0 if ok
- */
-int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
- FLACFrameInfo *fi, int log_level_offset);
-
-void ff_flac_set_channel_layout(AVCodecContext *avctx, int channels);
-
/**
* Parse the metadata block parameters from the header.
* @param[in] block_header header data, at least 4 bytes
@@ -143,13 +63,13 @@ void ff_flac_set_channel_layout(AVCodecContext *avctx, int channels);
static av_always_inline void flac_parse_block_header(const uint8_t *block_header,
int *last, int *type, int *size)
{
- int tmp = bytestream_get_byte(&block_header);
+ int tmp = *block_header;
if (last)
*last = tmp & 0x80;
if (type)
*type = tmp & 0x7F;
if (size)
- *size = bytestream_get_be24(&block_header);
+ *size = AV_RB24(block_header + 1);
}
#endif /* AVCODEC_FLAC_H */
diff --git a/libavcodec/flac_parse.h b/libavcodec/flac_parse.h
new file mode 100644
index 000000000..67a7320be
--- /dev/null
+++ b/libavcodec/flac_parse.h
@@ -0,0 +1,89 @@
+/*
+ * FLAC (Free Lossless Audio Codec) decoder/parser common functions
+ * Copyright (c) 2008 Justin Ruggles
+ *
+ * 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
+ * FLAC (Free Lossless Audio Codec) decoder/parser common functions
+ */
+
+#ifndef AVCODEC_FLAC_PARSE_H
+#define AVCODEC_FLAC_PARSE_H
+
+#include "avcodec.h"
+#include "get_bits.h"
+
+typedef struct FLACStreaminfo {
+ int samplerate; /**< sample rate */
+ int channels; /**< number of channels */
+ int bps; /**< bits-per-sample */
+ int max_blocksize; /**< maximum block size, in samples */
+ int max_framesize; /**< maximum frame size, in bytes */
+ int64_t samples; /**< total number of samples */
+} FLACStreaminfo;
+
+typedef struct FLACFrameInfo {
+ int samplerate; /**< sample rate */
+ int channels; /**< number of channels */
+ int bps; /**< bits-per-sample */
+ int blocksize; /**< block size of the frame */
+ int ch_mode; /**< channel decorrelation mode */
+ int64_t frame_or_sample_num; /**< frame number or sample number */
+ int is_var_size; /**< specifies if the stream uses variable
+ block sizes or a fixed block size;
+ also determines the meaning of
+ frame_or_sample_num */
+} FLACFrameInfo;
+
+/**
+ * Parse the Streaminfo metadata block
+ * @param[out] avctx codec context to set basic stream parameters
+ * @param[out] s where parsed information is stored
+ * @param[in] buffer pointer to start of 34-byte streaminfo data
+ *
+ * @return negative error code on faiure or >= 0 on success
+ */
+int ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
+ const uint8_t *buffer);
+
+/**
+ * Validate the FLAC extradata.
+ * @param[in] avctx codec context containing the extradata.
+ * @param[out] format extradata format.
+ * @param[out] streaminfo_start pointer to start of 34-byte STREAMINFO data.
+ * @return 1 if valid, 0 if not valid.
+ */
+int ff_flac_is_extradata_valid(AVCodecContext *avctx,
+ uint8_t **streaminfo_start);
+
+/**
+ * Validate and decode a frame header.
+ * @param avctx AVCodecContext to use as av_log() context
+ * @param gb GetBitContext from which to read frame header
+ * @param[out] fi frame information
+ * @param log_level_offset log level offset. can be used to silence error messages.
+ * @return non-zero on error, 0 if ok
+ */
+int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
+ FLACFrameInfo *fi, int log_level_offset);
+
+void ff_flac_set_channel_layout(AVCodecContext *avctx, int channels);
+
+#endif /* AVCODEC_FLAC_PARSE_H */
diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c
index 81b6f12ab..bd91cc1a0 100644
--- a/libavcodec/flac_parser.c
+++ b/libavcodec/flac_parser.c
@@ -36,7 +36,7 @@
#include "libavutil/crc.h"
#include "bytestream.h"
#include "parser.h"
-#include "flac.h"
+#include "flac_parse.h"
/** maximum number of adjacent headers that compare CRCs against each other */
#define FLAC_MAX_SEQUENTIAL_HEADERS 4
@@ -455,7 +455,7 @@ static int check_header_mismatch(FLACParseContext *fpc,
int log_level_offset)
{
FLACFrameInfo *header_fi = &header->fi, *child_fi = &child->fi;
- int deduction, deduction_expected = 0, i;
+ int check_crc, deduction, deduction_expected = 0, i;
deduction = check_header_fi_mismatch(fpc, header_fi, child_fi,
log_level_offset);
/* Check sample and frame numbers. */
@@ -491,8 +491,22 @@ static int check_header_mismatch(FLACParseContext *fpc,
"sample/frame number mismatch in adjacent frames\n");
}
+ if (fpc->last_fi.is_var_size == header_fi->is_var_size) {
+ if (fpc->last_fi.is_var_size &&
+ fpc->last_fi.frame_or_sample_num + fpc->last_fi.blocksize == header_fi->frame_or_sample_num) {
+ check_crc = 0;
+ } else if (!fpc->last_fi.is_var_size &&
+ fpc->last_fi.frame_or_sample_num + 1 == header_fi->frame_or_sample_num) {
+ check_crc = 0;
+ } else {
+ check_crc = !deduction && !deduction_expected;
+ }
+ } else {
+ check_crc = !deduction && !deduction_expected;
+ }
+
/* If we have suspicious headers, check the CRC between them */
- if (deduction && !deduction_expected) {
+ if (check_crc || (deduction && !deduction_expected)) {
FLACHeaderMarker *curr;
int read_len;
uint8_t *buf;
@@ -600,7 +614,7 @@ static int score_header(FLACParseContext *fpc, FLACHeaderMarker *header)
static void score_sequences(FLACParseContext *fpc)
{
FLACHeaderMarker *curr;
- int best_score = 0;//FLAC_HEADER_NOT_SCORED_YET;
+ int best_score = FLAC_HEADER_NOT_SCORED_YET;
/* First pass to clear all old scores. */
for (curr = fpc->headers; curr; curr = curr->next)
curr->max_score = FLAC_HEADER_NOT_SCORED_YET;
@@ -649,8 +663,11 @@ static int get_best_header(FLACParseContext *fpc, const uint8_t **poutbuf,
/* Return the negative overread index so the client can compute pos.
This should be the amount overread to the beginning of the child */
- if (child)
- return child->offset - flac_fifo_size(&fpc->fifo_buf);
+ if (child) {
+ int64_t offset = child->offset - flac_fifo_size(&fpc->fifo_buf);
+ if (offset > -(1 << 28))
+ return offset;
+ }
return 0;
}
@@ -682,7 +699,7 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
}
fpc->avctx = avctx;
- if (fpc->best_header_valid)
+ if (fpc->best_header_valid && fpc->nb_headers_buffered >= FLAC_MIN_HEADERS)
return get_best_header(fpc, poutbuf, poutbuf_size);
/* If a best_header was found last call remove it with the buffer data. */
diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index 87f20c742..cc778a8df 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -44,13 +44,14 @@
#include "flac.h"
#include "flacdata.h"
#include "flacdsp.h"
+#include "flac_parse.h"
#include "thread.h"
#include "unary.h"
typedef struct FLACContext {
AVClass *class;
- struct FLACStreaminfo flac_stream_info;
+ FLACStreaminfo stream_info;
AVCodecContext *avctx; ///< parent AVCodecContext
GetBitContext gb; ///< GetBitContext initialized to start at the current frame
@@ -63,6 +64,9 @@ typedef struct FLACContext {
int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples
uint8_t *decoded_buffer;
unsigned int decoded_buffer_size;
+ int64_t *decoded_33bps; ///< decoded samples for a 33 bps subframe
+ uint8_t *decoded_buffer_33bps;
+ unsigned int decoded_buffer_size_33bps;
int buggy_lpc; ///< use workaround for old lavc encoded files
FLACDSPContext dsp;
@@ -73,7 +77,7 @@ static int allocate_buffers(FLACContext *s);
static void flac_set_bps(FLACContext *s)
{
enum AVSampleFormat req = s->avctx->request_sample_fmt;
- int need32 = s->flac_stream_info.bps > 16;
+ int need32 = s->stream_info.bps > 16;
int want32 = av_get_bytes_per_sample(req) > 2;
int planar = av_sample_fmt_is_planar(req);
@@ -82,19 +86,18 @@ static void flac_set_bps(FLACContext *s)
s->avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
else
s->avctx->sample_fmt = AV_SAMPLE_FMT_S32;
- s->sample_shift = 32 - s->flac_stream_info.bps;
+ s->sample_shift = 32 - s->stream_info.bps;
} else {
if (planar)
s->avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
else
s->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
- s->sample_shift = 16 - s->flac_stream_info.bps;
+ s->sample_shift = 16 - s->stream_info.bps;
}
}
static av_cold int flac_decode_init(AVCodecContext *avctx)
{
- enum FLACExtradataFormat format;
uint8_t *streaminfo;
int ret;
FLACContext *s = avctx->priv_data;
@@ -105,11 +108,11 @@ static av_cold int flac_decode_init(AVCodecContext *avctx)
if (!avctx->extradata)
return 0;
- if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo))
+ if (!ff_flac_is_extradata_valid(avctx, &streaminfo))
return AVERROR_INVALIDDATA;
/* initialize based on the demuxer-supplied streamdata header */
- ret = ff_flac_parse_streaminfo(avctx, &s->flac_stream_info, streaminfo);
+ ret = ff_flac_parse_streaminfo(avctx, &s->stream_info, streaminfo);
if (ret < 0)
return ret;
ret = allocate_buffers(s);
@@ -117,7 +120,7 @@ static av_cold int flac_decode_init(AVCodecContext *avctx)
return ret;
flac_set_bps(s);
ff_flacdsp_init(&s->dsp, avctx->sample_fmt,
- s->flac_stream_info.channels, s->flac_stream_info.bps);
+ s->stream_info.channels);
s->got_streaminfo = 1;
return 0;
@@ -137,10 +140,10 @@ static int allocate_buffers(FLACContext *s)
int buf_size;
int ret;
- av_assert0(s->flac_stream_info.max_blocksize);
+ av_assert0(s->stream_info.max_blocksize);
- buf_size = av_samples_get_buffer_size(NULL, s->flac_stream_info.channels,
- s->flac_stream_info.max_blocksize,
+ buf_size = av_samples_get_buffer_size(NULL, s->stream_info.channels,
+ s->stream_info.max_blocksize,
AV_SAMPLE_FMT_S32P, 0);
if (buf_size < 0)
return buf_size;
@@ -151,9 +154,27 @@ static int allocate_buffers(FLACContext *s)
ret = av_samples_fill_arrays((uint8_t **)s->decoded, NULL,
s->decoded_buffer,
- s->flac_stream_info.channels,
- s->flac_stream_info.max_blocksize,
+ s->stream_info.channels,
+ s->stream_info.max_blocksize,
AV_SAMPLE_FMT_S32P, 0);
+ if (ret >= 0 && s->stream_info.bps == 32 && s->stream_info.channels == 2) {
+ buf_size = av_samples_get_buffer_size(NULL, 1,
+ s->stream_info.max_blocksize,
+ AV_SAMPLE_FMT_S64P, 0);
+ if (buf_size < 0)
+ return buf_size;
+
+ av_fast_malloc(&s->decoded_buffer_33bps, &s->decoded_buffer_size_33bps, buf_size);
+ if (!s->decoded_buffer_33bps)
+ return AVERROR(ENOMEM);
+
+ ret = av_samples_fill_arrays((uint8_t **)&s->decoded_33bps, NULL,
+ s->decoded_buffer_33bps,
+ 1,
+ s->stream_info.max_blocksize,
+ AV_SAMPLE_FMT_S64P, 0);
+
+ }
return ret < 0 ? ret : 0;
}
@@ -177,7 +198,7 @@ static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size)
metadata_size != FLAC_STREAMINFO_SIZE) {
return AVERROR_INVALIDDATA;
}
- ret = ff_flac_parse_streaminfo(s->avctx, &s->flac_stream_info, &buf[8]);
+ ret = ff_flac_parse_streaminfo(s->avctx, &s->stream_info, &buf[8]);
if (ret < 0)
return ret;
ret = allocate_buffers(s);
@@ -185,7 +206,7 @@ static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size)
return ret;
flac_set_bps(s);
ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt,
- s->flac_stream_info.channels, s->flac_stream_info.bps);
+ s->stream_info.channels);
s->got_streaminfo = 1;
return 0;
@@ -331,6 +352,62 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded,
return 0;
}
+#define DECODER_SUBFRAME_FIXED_WIDE(residual) { \
+ const int blocksize = s->blocksize; \
+ int ret; \
+ \
+ if ((ret = decode_residuals(s, residual, pred_order)) < 0) \
+ return ret; \
+ \
+ switch (pred_order) { \
+ case 0: \
+ for (int i = pred_order; i < blocksize; i++) \
+ decoded[i] = residual[i]; \
+ break; \
+ case 1: \
+ for (int i = pred_order; i < blocksize; i++) \
+ decoded[i] = (int64_t)residual[i] + (int64_t)decoded[i-1];\
+ break; \
+ case 2: \
+ for (int i = pred_order; i < blocksize; i++) \
+ decoded[i] = (int64_t)residual[i] + 2*(int64_t)decoded[i-1] - (int64_t)decoded[i-2]; \
+ break; \
+ case 3: \
+ for (int i = pred_order; i < blocksize; i++) \
+ decoded[i] = (int64_t)residual[i] + 3*(int64_t)decoded[i-1] - 3*(int64_t)decoded[i-2] + (int64_t)decoded[i-3]; \
+ break; \
+ case 4: \
+ for (int i = pred_order; i < blocksize; i++) \
+ decoded[i] = (int64_t)residual[i] + 4*(int64_t)decoded[i-1] - 6*(int64_t)decoded[i-2] + 4*(int64_t)decoded[i-3] - (int64_t)decoded[i-4]; \
+ break; \
+ default: \
+ av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order); \
+ return AVERROR_INVALIDDATA; \
+ } \
+ return 0; \
+}
+
+static int decode_subframe_fixed_wide(FLACContext *s, int32_t *decoded,
+ int pred_order, int bps)
+{
+ /* warm up samples */
+ for (int i = 0; i < pred_order; i++) {
+ decoded[i] = get_sbits_long(&s->gb, bps);
+ }
+ DECODER_SUBFRAME_FIXED_WIDE(decoded);
+}
+
+
+static int decode_subframe_fixed_33bps(FLACContext *s, int64_t *decoded,
+ int32_t *residual, int pred_order)
+{
+ /* warm up samples */ \
+ for (int i = 0; i < pred_order; i++) { \
+ decoded[i] = get_sbits64(&s->gb, 33); \
+ } \
+ DECODER_SUBFRAME_FIXED_WIDE(residual);
+}
+
static void lpc_analyze_remodulate(SUINT32 *decoded, const int coeffs[32],
int order, int qlevel, int len, int bps)
{
@@ -389,25 +466,66 @@ static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order,
if ((ret = decode_residuals(s, decoded, pred_order)) < 0)
return ret;
- if ( ( s->buggy_lpc && s->flac_stream_info.bps <= 16)
+ if ( ( s->buggy_lpc && s->stream_info.bps <= 16)
|| ( !s->buggy_lpc && bps <= 16
&& bps + coeff_prec + av_log2(pred_order) <= 32)) {
s->dsp.lpc16(decoded, coeffs, pred_order, qlevel, s->blocksize);
} else {
s->dsp.lpc32(decoded, coeffs, pred_order, qlevel, s->blocksize);
- if (s->flac_stream_info.bps <= 16)
+ if (s->stream_info.bps <= 16)
lpc_analyze_remodulate(decoded, coeffs, pred_order, qlevel, s->blocksize, bps);
}
return 0;
}
+static int decode_subframe_lpc_33bps(FLACContext *s, int64_t *decoded,
+ int32_t *residual, int pred_order)
+{
+ int i, j, ret;
+ int coeff_prec, qlevel;
+ int coeffs[32];
+
+ /* warm up samples */
+ for (i = 0; i < pred_order; i++) {
+ decoded[i] = get_sbits64(&s->gb, 33);
+ }
+
+ coeff_prec = get_bits(&s->gb, 4) + 1;
+ if (coeff_prec == 16) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid coeff precision\n");
+ return AVERROR_INVALIDDATA;
+ }
+ qlevel = get_sbits(&s->gb, 5);
+ if (qlevel < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "qlevel %d not supported, maybe buggy stream\n",
+ qlevel);
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (i = 0; i < pred_order; i++) {
+ coeffs[pred_order - i - 1] = get_sbits(&s->gb, coeff_prec);
+ }
+
+ if ((ret = decode_residuals(s, residual, pred_order)) < 0)
+ return ret;
+
+ for (i = pred_order; i < s->blocksize; i++, decoded++) {
+ int64_t sum = 0;
+ for (j = 0; j < pred_order; j++)
+ sum += (int64_t)coeffs[j] * decoded[j];
+ decoded[j] = residual[i] + (sum >> qlevel);
+ }
+
+ return 0;
+}
+
static inline int decode_subframe(FLACContext *s, int channel)
{
int32_t *decoded = s->decoded[channel];
int type, wasted = 0;
- int bps = s->flac_stream_info.bps;
- int i, tmp, ret;
+ int bps = s->stream_info.bps;
+ int i, ret;
if (channel == 0) {
if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE)
@@ -427,7 +545,7 @@ static inline int decode_subframe(FLACContext *s, int channel)
int left = get_bits_left(&s->gb);
if ( left <= 0 ||
(left < bps && !show_bits_long(&s->gb, left)) ||
- !show_bits_long(&s->gb, bps)) {
+ !show_bits_long(&s->gb, bps-1)) {
av_log(s->avctx, AV_LOG_ERROR,
"Invalid number of wasted bits > available bits (%d) - left=%d\n",
bps, left);
@@ -436,34 +554,63 @@ static inline int decode_subframe(FLACContext *s, int channel)
wasted = 1 + get_unary(&s->gb, 1, get_bits_left(&s->gb));
bps -= wasted;
}
- if (bps > 32) {
- avpriv_report_missing_feature(s->avctx, "Decorrelated bit depth > 32");
- return AVERROR_PATCHWELCOME;
- }
//FIXME use av_log2 for types
if (type == 0) {
- tmp = get_sbits_long(&s->gb, bps);
- for (i = 0; i < s->blocksize; i++)
- decoded[i] = tmp;
+ if (bps < 33) {
+ int32_t tmp = get_sbits_long(&s->gb, bps);
+ for (i = 0; i < s->blocksize; i++)
+ decoded[i] = tmp;
+ } else {
+ int64_t tmp = get_sbits64(&s->gb, 33);
+ for (i = 0; i < s->blocksize; i++)
+ s->decoded_33bps[i] = tmp;
+ }
} else if (type == 1) {
- for (i = 0; i < s->blocksize; i++)
- decoded[i] = get_sbits_long(&s->gb, bps);
+ if (bps < 33) {
+ for (i = 0; i < s->blocksize; i++)
+ decoded[i] = get_sbits_long(&s->gb, bps);
+ } else {
+ for (i = 0; i < s->blocksize; i++)
+ s->decoded_33bps[i] = get_sbits64(&s->gb, 33);
+ }
} else if ((type >= 8) && (type <= 12)) {
- if ((ret = decode_subframe_fixed(s, decoded, type & ~0x8, bps)) < 0)
- return ret;
+ int order = type & ~0x8;
+ if (bps < 33) {
+ if (bps + order <= 32) {
+ if ((ret = decode_subframe_fixed(s, decoded, order, bps)) < 0)
+ return ret;
+ } else {
+ if ((ret = decode_subframe_fixed_wide(s, decoded, order, bps)) < 0)
+ return ret;
+ }
+ } else {
+ if ((ret = decode_subframe_fixed_33bps(s, s->decoded_33bps, decoded, order)) < 0)
+ return ret;
+ }
} else if (type >= 32) {
- if ((ret = decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps)) < 0)
- return ret;
+ if (bps < 33) {
+ if ((ret = decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps)) < 0)
+ return ret;
+ } else {
+ if ((ret = decode_subframe_lpc_33bps(s, s->decoded_33bps, decoded, (type & ~0x20)+1)) < 0)
+ return ret;
+ }
} else {
av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n");
return AVERROR_INVALIDDATA;
}
- if (wasted && wasted < 32) {
- int i;
- for (i = 0; i < s->blocksize; i++)
- decoded[i] = (unsigned)decoded[i] << wasted;
+ if (wasted) {
+ if (wasted+bps == 33) {
+ int i;
+ for (i = 0; i < s->blocksize; i++)
+ s->decoded_33bps[i] = (uint64_t)decoded[i] << wasted;
+ } else if (wasted < 32) {
+ int i;
+ for (i = 0; i < s->blocksize; i++)
+ decoded[i] = (unsigned)decoded[i] << wasted;
+ }
}
return 0;
@@ -480,68 +627,68 @@ static int decode_frame(FLACContext *s)
return ret;
}
- if ( s->flac_stream_info.channels
- && fi.channels != s->flac_stream_info.channels
+ if ( s->stream_info.channels
+ && fi.channels != s->stream_info.channels
&& s->got_streaminfo) {
- s->flac_stream_info.channels = fi.channels;
+ s->stream_info.channels = fi.channels;
ff_flac_set_channel_layout(s->avctx, fi.channels);
ret = allocate_buffers(s);
if (ret < 0)
return ret;
}
- s->flac_stream_info.channels = fi.channels;
+ s->stream_info.channels = fi.channels;
ff_flac_set_channel_layout(s->avctx, fi.channels);
s->ch_mode = fi.ch_mode;
- if (!s->flac_stream_info.bps && !fi.bps) {
+ if (!s->stream_info.bps && !fi.bps) {
av_log(s->avctx, AV_LOG_ERROR, "bps not found in STREAMINFO or frame header\n");
return AVERROR_INVALIDDATA;
}
if (!fi.bps) {
- fi.bps = s->flac_stream_info.bps;
- } else if (s->flac_stream_info.bps && fi.bps != s->flac_stream_info.bps) {
+ fi.bps = s->stream_info.bps;
+ } else if (s->stream_info.bps && fi.bps != s->stream_info.bps) {
av_log(s->avctx, AV_LOG_ERROR, "switching bps mid-stream is not "
"supported\n");
return AVERROR_INVALIDDATA;
}
- if (!s->flac_stream_info.bps) {
- s->flac_stream_info.bps = s->avctx->bits_per_raw_sample = fi.bps;
+ if (!s->stream_info.bps) {
+ s->stream_info.bps = s->avctx->bits_per_raw_sample = fi.bps;
flac_set_bps(s);
}
- if (!s->flac_stream_info.max_blocksize)
- s->flac_stream_info.max_blocksize = FLAC_MAX_BLOCKSIZE;
- if (fi.blocksize > s->flac_stream_info.max_blocksize) {
+ if (!s->stream_info.max_blocksize)
+ s->stream_info.max_blocksize = FLAC_MAX_BLOCKSIZE;
+ if (fi.blocksize > s->stream_info.max_blocksize) {
av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", fi.blocksize,
- s->flac_stream_info.max_blocksize);
+ s->stream_info.max_blocksize);
return AVERROR_INVALIDDATA;
}
s->blocksize = fi.blocksize;
- if (!s->flac_stream_info.samplerate && !fi.samplerate) {
+ if (!s->stream_info.samplerate && !fi.samplerate) {
av_log(s->avctx, AV_LOG_ERROR, "sample rate not found in STREAMINFO"
" or frame header\n");
return AVERROR_INVALIDDATA;
}
if (fi.samplerate == 0)
- fi.samplerate = s->flac_stream_info.samplerate;
- s->flac_stream_info.samplerate = s->avctx->sample_rate = fi.samplerate;
+ fi.samplerate = s->stream_info.samplerate;
+ s->stream_info.samplerate = s->avctx->sample_rate = fi.samplerate;
if (!s->got_streaminfo) {
ret = allocate_buffers(s);
if (ret < 0)
return ret;
s->got_streaminfo = 1;
- dump_headers(s->avctx, &s->flac_stream_info);
+ dump_headers(s->avctx, &s->stream_info);
}
ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt,
- s->flac_stream_info.channels, s->flac_stream_info.bps);
+ s->stream_info.channels);
-// dump_headers(s->avctx, &s->flac_stream_info);
+// dump_headers(s->avctx, &s->stream_info);
/* subframes */
- for (i = 0; i < s->flac_stream_info.channels; i++) {
+ for (i = 0; i < s->stream_info.channels; i++) {
if ((ret = decode_subframe(s, i)) < 0)
return ret;
}
@@ -554,6 +701,26 @@ static int decode_frame(FLACContext *s)
return 0;
}
+static void decorrelate_33bps(int ch_mode, int32_t **decoded, int64_t *decoded_33bps, int len)
+{
+ int i;
+ if (ch_mode == FLAC_CHMODE_LEFT_SIDE ) {
+ for (i = 0; i < len; i++)
+ decoded[1][i] = decoded[0][i] - decoded_33bps[i];
+ } else if (ch_mode == FLAC_CHMODE_RIGHT_SIDE ) {
+ for (i = 0; i < len; i++)
+ decoded[0][i] = decoded[1][i] + decoded_33bps[i];
+ } else if (ch_mode == FLAC_CHMODE_MID_SIDE ) {
+ for (i = 0; i < len; i++) {
+ uint64_t a = decoded[0][i];
+ int64_t b = decoded_33bps[i];
+ a -= b >> 1;
+ decoded[0][i] = (a + b);
+ decoded[1][i] = a;
+ }
+ }
+}
+
static int flac_decode_frame(AVCodecContext *avctx, AVFrame *frame,
int *got_frame_ptr, AVPacket *avpkt)
{
@@ -565,12 +732,6 @@ static int flac_decode_frame(AVCodecContext *avctx, AVFrame *frame,
*got_frame_ptr = 0;
- if (s->flac_stream_info.max_framesize == 0) {
- s->flac_stream_info.max_framesize =
- ff_flac_get_max_frame_size(s->flac_stream_info.max_blocksize ? s->flac_stream_info.max_blocksize : FLAC_MAX_BLOCKSIZE,
- FLAC_MAX_CHANNELS, 32);
- }
-
if (buf_size > 5 && !memcmp(buf, "\177FLAC", 5)) {
av_log(s->avctx, AV_LOG_DEBUG, "skipping flac header packet 1\n");
return buf_size;
@@ -583,7 +744,7 @@ static int flac_decode_frame(AVCodecContext *avctx, AVFrame *frame,
/* check that there is at least the smallest decodable amount of data.
this amount corresponds to the smallest valid FLAC frame possible.
- FF F8 69 02 00 00 9A 00 00 34 46 */
+ FF F8 69 02 00 00 9A 00 00 34 */
if (buf_size < FLAC_MIN_FRAME_SIZE)
return buf_size;
@@ -618,9 +779,15 @@ static int flac_decode_frame(AVCodecContext *avctx, AVFrame *frame,
if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
return ret;
- s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded,
- s->flac_stream_info.channels,
- s->blocksize, s->sample_shift);
+ if (s->stream_info.bps == 32 && s->ch_mode > 0) {
+ decorrelate_33bps(s->ch_mode, s->decoded, s->decoded_33bps, s->blocksize);
+ s->dsp.decorrelate[0](frame->data, s->decoded, s->stream_info.channels,
+ s->blocksize, s->sample_shift);
+ } else {
+ s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded,
+ s->stream_info.channels,
+ s->blocksize, s->sample_shift);
+ }
if (bytes_read > buf_size) {
av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size);
@@ -641,6 +808,7 @@ static av_cold int flac_decode_close(AVCodecContext *avctx)
FLACContext *s = avctx->priv_data;
av_freep(&s->decoded_buffer);
+ av_freep(&s->decoded_buffer_33bps);
return 0;
}
@@ -659,7 +827,7 @@ static const AVClass flac_decoder_class = {
const FFCodec ff_flac_decoder = {
.p.name = "flac",
- .p.long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
+ CODEC_LONG_NAME("FLAC (Free Lossless Audio Codec)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_FLAC,
.priv_data_size = sizeof(FLACContext),
@@ -675,5 +843,4 @@ const FFCodec ff_flac_decoder = {
AV_SAMPLE_FMT_S32P,
AV_SAMPLE_FMT_NONE },
.p.priv_class = &flac_decoder_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/flacdsp.c b/libavcodec/flacdsp.c
index 79002dcac..42e231db5 100644
--- a/libavcodec/flacdsp.c
+++ b/libavcodec/flacdsp.c
@@ -27,7 +27,6 @@
#define SAMPLE_SIZE 16
#define PLANAR 0
#include "flacdsp_template.c"
-#include "flacdsp_lpc_template.c"
#undef PLANAR
#define PLANAR 1
@@ -38,7 +37,6 @@
#define SAMPLE_SIZE 32
#define PLANAR 0
#include "flacdsp_template.c"
-#include "flacdsp_lpc_template.c"
#undef PLANAR
#define PLANAR 1
@@ -86,13 +84,10 @@ static void flac_lpc_32_c(int32_t *decoded, const int coeffs[32],
}
-av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int channels,
- int bps)
+av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int channels)
{
c->lpc16 = flac_lpc_16_c;
c->lpc32 = flac_lpc_32_c;
- c->lpc16_encode = flac_lpc_encode_c_16;
- c->lpc32_encode = flac_lpc_encode_c_32;
switch (fmt) {
case AV_SAMPLE_FMT_S32:
@@ -125,8 +120,8 @@ av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int cha
}
#if ARCH_ARM
- ff_flacdsp_init_arm(c, fmt, channels, bps);
+ ff_flacdsp_init_arm(c, fmt, channels);
#elif ARCH_X86
- ff_flacdsp_init_x86(c, fmt, channels, bps);
+ ff_flacdsp_init_x86(c, fmt, channels);
#endif
}
diff --git a/libavcodec/flacdsp.h b/libavcodec/flacdsp.h
index 4a7a36064..9f8ed38b6 100644
--- a/libavcodec/flacdsp.h
+++ b/libavcodec/flacdsp.h
@@ -36,8 +36,8 @@ typedef struct FLACDSPContext {
const int32_t coefs[32], int shift);
} FLACDSPContext;
-void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps);
-void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps);
-void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps);
+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_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int channels);
#endif /* AVCODEC_FLACDSP_H */
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index e9edd8476..a449b7323 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -31,12 +31,10 @@
#include "codec_internal.h"
#include "encode.h"
#include "put_bits.h"
-#include "put_golomb.h"
-#include "internal.h"
#include "lpc.h"
#include "flac.h"
#include "flacdata.h"
-#include "flacdsp.h"
+#include "flacencdsp.h"
#define FLAC_SUBFRAME_CONSTANT 0
#define FLAC_SUBFRAME_VERBATIM 1
@@ -96,6 +94,7 @@ typedef struct FlacSubframe {
typedef struct FlacFrame {
FlacSubframe subframes[FLAC_MAX_CHANNELS];
+ int64_t samples_33bps[FLAC_MAX_BLOCKSIZE];
int blocksize;
int bs_code[2];
uint8_t crc8;
@@ -125,7 +124,7 @@ typedef struct FlacEncodeContext {
uint8_t *md5_buffer;
unsigned int md5_buffer_size;
BswapDSPContext bdsp;
- FLACDSPContext flac_dsp;
+ FLACEncDSPContext flac_dsp;
int flushed;
int64_t next_pts;
@@ -158,6 +157,34 @@ static void write_streaminfo(FlacEncodeContext *s, uint8_t *header)
}
+/**
+ * Calculate an estimate for the maximum frame size based on verbatim mode.
+ * @param blocksize block size, in samples
+ * @param ch number of channels
+ * @param bps bits-per-sample
+ */
+static int flac_get_max_frame_size(int blocksize, int ch, int bps)
+{
+ /* Technically, there is no limit to FLAC frame size, but an encoder
+ should not write a frame that is larger than if verbatim encoding mode
+ were to be used. */
+
+ int count;
+
+ count = 16; /* frame header */
+ count += ch * ((7+bps+7)/8); /* subframe headers */
+ if (ch == 2) {
+ /* for stereo, need to account for using decorrelation */
+ count += (( 2*bps+1) * blocksize + 7) / 8;
+ } else {
+ count += ( ch*bps * blocksize + 7) / 8;
+ }
+ count += 2; /* frame footer */
+
+ return count;
+}
+
+
/**
* Set blocksize based on samplerate.
* Choose the closest predefined blocksize >= BLOCK_TIME_MS milliseconds.
@@ -255,10 +282,22 @@ static av_cold int flac_encode_init(AVCodecContext *avctx)
s->bps_code = 4;
break;
case AV_SAMPLE_FMT_S32:
- if (avctx->bits_per_raw_sample != 24)
- av_log(avctx, AV_LOG_WARNING, "encoding as 24 bits-per-sample\n");
- avctx->bits_per_raw_sample = 24;
- s->bps_code = 6;
+ if (avctx->bits_per_raw_sample <= 24) {
+ if (avctx->bits_per_raw_sample < 24)
+ av_log(avctx, AV_LOG_WARNING, "encoding as 24 bits-per-sample\n");
+ avctx->bits_per_raw_sample = 24;
+ s->bps_code = 6;
+ } else if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+ av_log(avctx, AV_LOG_WARNING,
+ "encoding as 24 bits-per-sample, more is considered "
+ "experimental. Add -strict experimental if you want "
+ "to encode more than 24 bits-per-sample\n");
+ avctx->bits_per_raw_sample = 24;
+ s->bps_code = 6;
+ } else {
+ avctx->bits_per_raw_sample = 32;
+ s->bps_code = 7;
+ }
break;
}
@@ -272,7 +311,7 @@ static av_cold int flac_encode_init(AVCodecContext *avctx)
/* find samplerate in table */
if (freq < 1)
return AVERROR(EINVAL);
- for (i = 4; i < 12; i++) {
+ for (i = 1; i < 12; i++) {
if (freq == ff_flac_sample_rate_table[i]) {
s->samplerate = ff_flac_sample_rate_table[i];
s->sr_code[0] = i;
@@ -291,6 +330,9 @@ static av_cold int flac_encode_init(AVCodecContext *avctx)
} else if (freq < 65535) {
s->sr_code[0] = 13;
s->sr_code[1] = freq;
+ } else if (freq < 1048576) {
+ s->sr_code[0] = 0;
+ s->sr_code[1] = 0;
} else {
av_log(avctx, AV_LOG_ERROR, "%d Hz not supported\n", freq);
return AVERROR(EINVAL);
@@ -379,9 +421,9 @@ static av_cold int flac_encode_init(AVCodecContext *avctx)
s->max_blocksize = s->avctx->frame_size;
/* set maximum encoded frame size in verbatim mode */
- s->max_framesize = ff_flac_get_max_frame_size(s->avctx->frame_size,
- s->channels,
- s->avctx->bits_per_raw_sample);
+ s->max_framesize = flac_get_max_frame_size(s->avctx->frame_size,
+ s->channels,
+ s->avctx->bits_per_raw_sample);
/* initialize MD5 context */
s->md5ctx = av_md5_alloc();
@@ -425,8 +467,7 @@ static av_cold int flac_encode_init(AVCodecContext *avctx)
s->options.max_prediction_order, FF_LPC_TYPE_LEVINSON);
ff_bswapdsp_init(&s->bdsp);
- ff_flacdsp_init(&s->flac_dsp, avctx->sample_fmt, channels,
- avctx->bits_per_raw_sample);
+ ff_flacencdsp_init(&s->flac_dsp);
dprint_compression_options(s);
@@ -507,8 +548,7 @@ static uint64_t rice_count_exact(const int32_t *res, int n, int k)
uint64_t count = 0;
for (i = 0; i < n; i++) {
- int32_t v = -2 * res[i] - 1;
- v ^= v >> 31;
+ unsigned v = ((unsigned)(res[i]) << 1) ^ (res[i] >> 31);
count += (v >> k) + 1 + k;
}
return count;
@@ -687,8 +727,8 @@ static uint64_t calc_rice_params(RiceContext *rc,
tmp_rc.coding_mode = rc->coding_mode;
- for (i = 0; i < n; i++)
- udata[i] = (2 * data[i]) ^ (data[i] >> 31);
+ for (i = pred_order; i < n; i++)
+ udata[i] = ((unsigned)(data[i]) << 1) ^ (data[i] >> 31);
calc_sum_top(pmax, exact ? kmax : 0, udata, n, pred_order, sums);
@@ -786,6 +826,130 @@ static void encode_residual_fixed(int32_t *res, const int32_t *smp, int n,
}
+/* These four functions check for every residual whether it can be
+ * contained in INT32_MAX) \
+ return 1; \
+ res[i] = res64; \
+ } \
+ } else if (order == 2) { \
+ for (int i = order; i < n; i++) { \
+ int64_t res64 = (int64_t)smp[i] - 2*(int64_t)smp[i-1] + smp[i-2]; \
+ if (res64 <= INT32_MIN || res64 > INT32_MAX) \
+ return 1; \
+ res[i] = res64; \
+ } \
+ } else if (order == 3) { \
+ for (int i = order; i < n; i++) { \
+ int64_t res64 = (int64_t)smp[i] - 3*(int64_t)smp[i-1] + 3*(int64_t)smp[i-2] - smp[i-3]; \
+ if (res64 <= INT32_MIN || res64 > INT32_MAX) \
+ return 1; \
+ res[i] = res64; \
+ } \
+ } else { \
+ for (int i = order; i < n; i++) { \
+ int64_t res64 = (int64_t)smp[i] - 4*(int64_t)smp[i-1] + 6*(int64_t)smp[i-2] - 4*(int64_t)smp[i-3] + smp[i-4]; \
+ if (res64 <= INT32_MIN || res64 > INT32_MAX) \
+ return 1; \
+ res[i] = res64; \
+ } \
+ } \
+ return 0; \
+}
+
+static int encode_residual_fixed_with_residual_limit(int32_t *res, const int32_t *smp,
+ int n, int order)
+{
+ ENCODE_RESIDUAL_FIXED_WITH_RESIDUAL_LIMIT();
+}
+
+
+static int encode_residual_fixed_with_residual_limit_33bps(int32_t *res, const int64_t *smp,
+ int n, int order)
+{
+ ENCODE_RESIDUAL_FIXED_WITH_RESIDUAL_LIMIT();
+}
+
+#define LPC_ENCODE_WITH_RESIDUAL_LIMIT() \
+{ \
+ for (int i = 0; i < order; i++) \
+ res[i] = smp[i]; \
+ for (int i = order; i < len; i++) { \
+ int64_t p = 0, tmp; \
+ for (int j = 0; j < order; j++) \
+ p += (int64_t)coefs[j]*smp[(i-1)-j]; \
+ p >>= shift; \
+ tmp = smp[i] - p; \
+ if (tmp <= INT32_MIN || tmp > INT32_MAX) \
+ return 1; \
+ res[i] = tmp; \
+ } \
+ return 0; \
+}
+
+static int lpc_encode_with_residual_limit(int32_t *res, const int32_t *smp, int len,
+ int order, int32_t *coefs, int shift)
+{
+ LPC_ENCODE_WITH_RESIDUAL_LIMIT();
+}
+
+static int lpc_encode_with_residual_limit_33bps(int32_t *res, const int64_t *smp, int len,
+ int order, int32_t *coefs, int shift)
+{
+ LPC_ENCODE_WITH_RESIDUAL_LIMIT();
+}
+
+static int lpc_encode_choose_datapath(FlacEncodeContext *s, int32_t bps,
+ int32_t *res, const int32_t *smp,
+ const int64_t *smp_33bps, int len,
+ int order, int32_t *coefs, int shift)
+{
+ uint64_t max_residual_value = 0;
+ int64_t max_sample_value = ((int64_t)(1) << (bps-1));
+ /* This calculates the max size of any residual with the current
+ * predictor, so we know whether we need to check the residual */
+ for (int i = 0; i < order; i++)
+ max_residual_value += FFABS(max_sample_value * coefs[i]);
+ max_residual_value >>= shift;
+ max_residual_value += max_sample_value;
+ if (bps > 32) {
+ if (lpc_encode_with_residual_limit_33bps(res, smp_33bps, len, order, coefs, shift))
+ return 1;
+ } else if (max_residual_value > INT32_MAX) {
+ if (lpc_encode_with_residual_limit(res, smp, len, order, coefs, shift))
+ return 1;
+ } else if (bps + s->options.lpc_coeff_precision + av_log2(order) <= 32) {
+ s->flac_dsp.lpc16_encode(res, smp, len, order, coefs, shift);
+ } else {
+ s->flac_dsp.lpc32_encode(res, smp, len, order, coefs, shift);
+ }
+ return 0;
+}
+
+#define DEFAULT_TO_VERBATIM() \
+{ \
+ sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM; \
+ if (sub->obits <= 32) \
+ memcpy(res, smp, n * sizeof(int32_t)); \
+ return subframe_count_exact(s, sub, 0); \
+}
+
static int encode_residual_ch(FlacEncodeContext *s, int ch)
{
int i, n;
@@ -795,28 +959,38 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
int32_t coefs[MAX_LPC_ORDER][MAX_LPC_ORDER];
int shift[MAX_LPC_ORDER];
int32_t *res, *smp;
+ int64_t *smp_33bps;
- frame = &s->frame;
- sub = &frame->subframes[ch];
- res = sub->residual;
- smp = sub->samples;
- n = frame->blocksize;
+ frame = &s->frame;
+ sub = &frame->subframes[ch];
+ res = sub->residual;
+ smp = sub->samples;
+ smp_33bps = frame->samples_33bps;
+ n = frame->blocksize;
/* CONSTANT */
- for (i = 1; i < n; i++)
- if(smp[i] != smp[0])
- break;
- if (i == n) {
- sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT;
- res[0] = smp[0];
- return subframe_count_exact(s, sub, 0);
+ if (sub->obits > 32) {
+ for (i = 1; i < n; i++)
+ if(smp_33bps[i] != smp_33bps[0])
+ break;
+ if (i == n) {
+ sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT;
+ return subframe_count_exact(s, sub, 0);
+ }
+ } else {
+ for (i = 1; i < n; i++)
+ if(smp[i] != smp[0])
+ break;
+ if (i == n) {
+ sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT;
+ res[0] = smp[0];
+ return subframe_count_exact(s, sub, 0);
+ }
}
/* VERBATIM */
if (frame->verbatim_only || n < 5) {
- sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM;
- memcpy(res, smp, n * sizeof(int32_t));
- return subframe_count_exact(s, sub, 0);
+ DEFAULT_TO_VERBATIM();
}
min_order = s->options.min_prediction_order;
@@ -833,15 +1007,32 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
opt_order = 0;
bits[0] = UINT32_MAX;
for (i = min_order; i <= max_order; i++) {
- encode_residual_fixed(res, smp, n, i);
+ if (sub->obits == 33) {
+ if (encode_residual_fixed_with_residual_limit_33bps(res, smp_33bps, n, i))
+ continue;
+ } else if (sub->obits + i >= 32) {
+ if (encode_residual_fixed_with_residual_limit(res, smp, n, i))
+ continue;
+ } else
+ encode_residual_fixed(res, smp, n, i);
bits[i] = find_subframe_rice_params(s, sub, i);
if (bits[i] < bits[opt_order])
opt_order = i;
}
+ if (opt_order == 0 && bits[0] == UINT32_MAX) {
+ /* No predictor found with residuals within order = opt_order;
sub->type_code = sub->type | sub->order;
if (sub->order != max_order) {
- encode_residual_fixed(res, smp, n, sub->order);
+ if (sub->obits == 33)
+ encode_residual_fixed_with_residual_limit_33bps(res, smp_33bps, n, sub->order);
+ else if (sub->obits + i >= 32)
+ encode_residual_fixed_with_residual_limit(res, smp, n, sub->order);
+ else
+ encode_residual_fixed(res, smp, n, sub->order);
find_subframe_rice_params(s, sub, sub->order);
}
return subframe_count_exact(s, sub, sub->order);
@@ -849,6 +1040,14 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
/* LPC */
sub->type = FLAC_SUBFRAME_LPC;
+ if (sub->obits == 33)
+ /* As ff_lpc_calc_coefs is shared with other codecs and the LSB
+ * probably isn't predictable anyway, throw away LSB for analysis
+ * so it fits 32 bit int and existing function can be used
+ * unmodified */
+ for (i = 0; i < n; i++)
+ smp[i] = smp_33bps[i] >> 1;
+
opt_order = ff_lpc_calc_coefs(&s->lpc_ctx, smp, n, min_order, max_order,
s->options.lpc_coeff_precision, coefs, shift, s->options.lpc_type,
s->options.lpc_passes, omethod,
@@ -869,13 +1068,8 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
order = av_clip(order, min_order - 1, max_order - 1);
if (order == last_order)
continue;
- if (s->bps_code * 4 + s->options.lpc_coeff_precision + av_log2(order) <= 32) {
- s->flac_dsp.lpc16_encode(res, smp, n, order+1, coefs[order],
- shift[order]);
- } else {
- s->flac_dsp.lpc32_encode(res, smp, n, order+1, coefs[order],
- shift[order]);
- }
+ if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, order+1, coefs[order], shift[order]))
+ continue;
bits[i] = find_subframe_rice_params(s, sub, order+1);
if (bits[i] < bits[opt_index]) {
opt_index = i;
@@ -889,11 +1083,8 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
opt_order = 0;
bits[0] = UINT32_MAX;
for (i = min_order-1; i < max_order; i++) {
- if (s->bps_code * 4 + s->options.lpc_coeff_precision + av_log2(i) <= 32) {
- s->flac_dsp.lpc16_encode(res, smp, n, i+1, coefs[i], shift[i]);
- } else {
- s->flac_dsp.lpc32_encode(res, smp, n, i+1, coefs[i], shift[i]);
- }
+ if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, i+1, coefs[i], shift[i]))
+ continue;
bits[i] = find_subframe_rice_params(s, sub, i+1);
if (bits[i] < bits[opt_order])
opt_order = i;
@@ -911,11 +1102,8 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
for (i = last-step; i <= last+step; i += step) {
if (i < min_order-1 || i >= max_order || bits[i] < UINT32_MAX)
continue;
- if (s->bps_code * 4 + s->options.lpc_coeff_precision + av_log2(i) <= 32) {
- s->flac_dsp.lpc32_encode(res, smp, n, i+1, coefs[i], shift[i]);
- } else {
- s->flac_dsp.lpc16_encode(res, smp, n, i+1, coefs[i], shift[i]);
- }
+ if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, i+1, coefs[i], shift[i]))
+ continue;
bits[i] = find_subframe_rice_params(s, sub, i+1);
if (bits[i] < bits[opt_order])
opt_order = i;
@@ -952,11 +1140,8 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
if (diffsum >8)
continue;
- if (s->bps_code * 4 + s->options.lpc_coeff_precision + av_log2(opt_order - 1) <= 32) {
- s->flac_dsp.lpc16_encode(res, smp, n, opt_order, lpc_try, shift[opt_order-1]);
- } else {
- s->flac_dsp.lpc32_encode(res, smp, n, opt_order, lpc_try, shift[opt_order-1]);
- }
+ if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, opt_order, lpc_try, shift[opt_order-1]))
+ continue;
score = find_subframe_rice_params(s, sub, opt_order);
if (score < best_score) {
best_score = score;
@@ -973,10 +1158,10 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
for (i = 0; i < sub->order; i++)
sub->coefs[i] = coefs[sub->order-1][i];
- if (s->bps_code * 4 + s->options.lpc_coeff_precision + av_log2(opt_order) <= 32) {
- s->flac_dsp.lpc16_encode(res, smp, n, sub->order, sub->coefs, sub->shift);
- } else {
- s->flac_dsp.lpc32_encode(res, smp, n, sub->order, sub->coefs, sub->shift);
+ if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, sub->order, sub->coefs, sub->shift)) {
+ /* No predictor found with residuals within order);
@@ -1043,57 +1228,91 @@ static int encode_frame(FlacEncodeContext *s)
static void remove_wasted_bits(FlacEncodeContext *s)
{
- int ch, i;
+ int ch, i, wasted_bits;
for (ch = 0; ch < s->channels; ch++) {
FlacSubframe *sub = &s->frame.subframes[ch];
- int32_t v = 0;
- for (i = 0; i < s->frame.blocksize; i++) {
- v |= sub->samples[i];
- if (v & 1)
- break;
- }
+ if (sub->obits > 32) {
+ int64_t v = 0;
+ for (i = 0; i < s->frame.blocksize; i++) {
+ v |= s->frame.samples_33bps[i];
+ if (v & 1)
+ break;
+ }
+
+ if (!v || (v & 1))
+ return;
+
+ v = ff_ctzll(v);
+
+ /* If any wasted bits are found, samples are moved
+ * from frame.samples_33bps to frame.subframes[ch] */
+ for (i = 0; i < s->frame.blocksize; i++)
+ sub->samples[i] = s->frame.samples_33bps[i] >> v;
+ wasted_bits = v;
+ } else {
+ int32_t v = 0;
+ for (i = 0; i < s->frame.blocksize; i++) {
+ v |= sub->samples[i];
+ if (v & 1)
+ break;
+ }
+
+ if (!v || (v & 1))
+ return;
- if (v && !(v & 1)) {
v = ff_ctz(v);
for (i = 0; i < s->frame.blocksize; i++)
sub->samples[i] >>= v;
-
- sub->wasted = v;
- sub->obits -= v;
-
- /* for 24-bit, check if removing wasted bits makes the range better
- suited for using RICE instead of RICE2 for entropy coding */
- if (sub->obits <= 17)
- sub->rc.coding_mode = CODING_MODE_RICE;
+ wasted_bits = v;
}
+
+ sub->wasted = wasted_bits;
+ sub->obits -= wasted_bits;
+
+ /* for 24-bit, check if removing wasted bits makes the range better
+ * suited for using RICE instead of RICE2 for entropy coding */
+ if (sub->obits <= 17)
+ sub->rc.coding_mode = CODING_MODE_RICE;
}
}
static int estimate_stereo_mode(const int32_t *left_ch, const int32_t *right_ch, int n,
- int max_rice_param)
+ int max_rice_param, int bps)
{
- int i, best;
- int32_t lt, rt;
+ int best;
uint64_t sum[4];
uint64_t score[4];
int k;
/* calculate sum of 2nd order residual for each channel */
sum[0] = sum[1] = sum[2] = sum[3] = 0;
- for (i = 2; i < n; i++) {
- lt = left_ch[i] - 2*left_ch[i-1] + left_ch[i-2];
- rt = right_ch[i] - 2*right_ch[i-1] + right_ch[i-2];
- sum[2] += FFABS((lt + rt) >> 1);
- sum[3] += FFABS(lt - rt);
- sum[0] += FFABS(lt);
- sum[1] += FFABS(rt);
+ if(bps < 30) {
+ int32_t lt, rt;
+ for (int i = 2; i < n; i++) {
+ lt = left_ch[i] - 2*left_ch[i-1] + left_ch[i-2];
+ rt = right_ch[i] - 2*right_ch[i-1] + right_ch[i-2];
+ sum[2] += FFABS((lt + rt) >> 1);
+ sum[3] += FFABS(lt - rt);
+ sum[0] += FFABS(lt);
+ sum[1] += FFABS(rt);
+ }
+ } else {
+ int64_t lt, rt;
+ for (int i = 2; i < n; i++) {
+ lt = (int64_t)left_ch[i] - 2*(int64_t)left_ch[i-1] + left_ch[i-2];
+ rt = (int64_t)right_ch[i] - 2*(int64_t)right_ch[i-1] + right_ch[i-2];
+ sum[2] += FFABS((lt + rt) >> 1);
+ sum[3] += FFABS(lt - rt);
+ sum[0] += FFABS(lt);
+ sum[1] += FFABS(rt);
+ }
}
/* estimate bit counts */
- for (i = 0; i < 4; i++) {
+ for (int i = 0; i < 4; i++) {
k = find_optimal_param(2 * sum[i], n, max_rice_param);
sum[i] = rice_encode_count( 2 * sum[i], n, k);
}
@@ -1106,7 +1325,7 @@ static int estimate_stereo_mode(const int32_t *left_ch, const int32_t *right_ch,
/* return mode with lowest score */
best = 0;
- for (i = 1; i < 4; i++)
+ for (int i = 1; i < 4; i++)
if (score[i] < score[best])
best = i;
@@ -1121,12 +1340,14 @@ static void channel_decorrelation(FlacEncodeContext *s)
{
FlacFrame *frame;
int32_t *left, *right;
- int i, n;
+ int64_t *side_33bps;
+ int n;
- frame = &s->frame;
- n = frame->blocksize;
- left = frame->subframes[0].samples;
- right = frame->subframes[1].samples;
+ frame = &s->frame;
+ n = frame->blocksize;
+ left = frame->subframes[0].samples;
+ right = frame->subframes[1].samples;
+ side_33bps = frame->samples_33bps;
if (s->channels != 2) {
frame->ch_mode = FLAC_CHMODE_INDEPENDENT;
@@ -1135,29 +1356,49 @@ static void channel_decorrelation(FlacEncodeContext *s)
if (s->options.ch_mode < 0) {
int max_rice_param = (1 << frame->subframes[0].rc.coding_mode) - 2;
- frame->ch_mode = estimate_stereo_mode(left, right, n, max_rice_param);
+ frame->ch_mode = estimate_stereo_mode(left, right, n, max_rice_param, s->avctx->bits_per_raw_sample);
} else
frame->ch_mode = s->options.ch_mode;
/* perform decorrelation and adjust bits-per-sample */
if (frame->ch_mode == FLAC_CHMODE_INDEPENDENT)
return;
- if (frame->ch_mode == FLAC_CHMODE_MID_SIDE) {
- int32_t tmp;
- for (i = 0; i < n; i++) {
- tmp = left[i];
- left[i] = (tmp + right[i]) >> 1;
- right[i] = tmp - right[i];
+ if(s->avctx->bits_per_raw_sample == 32) {
+ if (frame->ch_mode == FLAC_CHMODE_MID_SIDE) {
+ int64_t tmp;
+ for (int i = 0; i < n; i++) {
+ tmp = left[i];
+ left[i] = (tmp + right[i]) >> 1;
+ side_33bps[i] = tmp - right[i];
+ }
+ frame->subframes[1].obits++;
+ } else if (frame->ch_mode == FLAC_CHMODE_LEFT_SIDE) {
+ for (int i = 0; i < n; i++)
+ side_33bps[i] = (int64_t)left[i] - right[i];
+ frame->subframes[1].obits++;
+ } else {
+ for (int i = 0; i < n; i++)
+ side_33bps[i] = (int64_t)left[i] - right[i];
+ frame->subframes[0].obits++;
}
- frame->subframes[1].obits++;
- } else if (frame->ch_mode == FLAC_CHMODE_LEFT_SIDE) {
- for (i = 0; i < n; i++)
- right[i] = left[i] - right[i];
- frame->subframes[1].obits++;
} else {
- for (i = 0; i < n; i++)
- left[i] -= right[i];
- frame->subframes[0].obits++;
+ if (frame->ch_mode == FLAC_CHMODE_MID_SIDE) {
+ int32_t tmp;
+ for (int i = 0; i < n; i++) {
+ tmp = left[i];
+ left[i] = (tmp + right[i]) >> 1;
+ right[i] = tmp - right[i];
+ }
+ frame->subframes[1].obits++;
+ } else if (frame->ch_mode == FLAC_CHMODE_LEFT_SIDE) {
+ for (int i = 0; i < n; i++)
+ right[i] = left[i] - right[i];
+ frame->subframes[1].obits++;
+ } else {
+ for (int i = 0; i < n; i++)
+ left[i] -= right[i];
+ frame->subframes[0].obits++;
+ }
}
}
@@ -1206,13 +1447,32 @@ static void write_frame_header(FlacEncodeContext *s)
}
+static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k)
+{
+ unsigned v, e;
+
+ v = ((unsigned)(i) << 1) ^ (i >> 31);
+
+ e = (v >> k) + 1;
+ while (e > 31) {
+ put_bits(pb, 31, 0);
+ e -= 31;
+ }
+ put_bits(pb, e, 1);
+ if (k) {
+ unsigned mask = UINT32_MAX >> (32-k);
+ put_bits(pb, k, v & mask);
+ }
+}
+
+
static void write_subframes(FlacEncodeContext *s)
{
int ch;
for (ch = 0; ch < s->channels; ch++) {
FlacSubframe *sub = &s->frame.subframes[ch];
- int i, p, porder, psize;
+ int p, porder, psize;
int32_t *part_end;
int32_t *res = sub->residual;
int32_t *frame_end = &sub->residual[s->frame.blocksize];
@@ -1226,21 +1486,45 @@ static void write_subframes(FlacEncodeContext *s)
/* subframe */
if (sub->type == FLAC_SUBFRAME_CONSTANT) {
- put_sbits(&s->pb, sub->obits, res[0]);
+ if(sub->obits == 33)
+ put_sbits63(&s->pb, 33, s->frame.samples_33bps[0]);
+ else if(sub->obits == 32)
+ put_bits32(&s->pb, res[0]);
+ else
+ put_sbits(&s->pb, sub->obits, res[0]);
} else if (sub->type == FLAC_SUBFRAME_VERBATIM) {
- while (res < frame_end)
- put_sbits(&s->pb, sub->obits, *res++);
+ if (sub->obits == 33) {
+ int64_t *res64 = s->frame.samples_33bps;
+ int64_t *frame_end64 = &s->frame.samples_33bps[s->frame.blocksize];
+ while (res64 < frame_end64)
+ put_sbits63(&s->pb, 33, (*res64++));
+ } else if (sub->obits == 32) {
+ while (res < frame_end)
+ put_bits32(&s->pb, *res++);
+ } else {
+ while (res < frame_end)
+ put_sbits(&s->pb, sub->obits, *res++);
+ }
} else {
/* warm-up samples */
- for (i = 0; i < sub->order; i++)
- put_sbits(&s->pb, sub->obits, *res++);
+ if (sub->obits == 33) {
+ for (int i = 0; i < sub->order; i++)
+ put_sbits63(&s->pb, 33, s->frame.samples_33bps[i]);
+ res += sub->order;
+ } else if (sub->obits == 32) {
+ for (int i = 0; i < sub->order; i++)
+ put_bits32(&s->pb, *res++);
+ } else {
+ for (int i = 0; i < sub->order; i++)
+ put_sbits(&s->pb, sub->obits, *res++);
+ }
/* LPC coefficients */
if (sub->type == FLAC_SUBFRAME_LPC) {
int cbits = s->options.lpc_coeff_precision;
put_bits( &s->pb, 4, cbits-1);
put_sbits(&s->pb, 5, sub->shift);
- for (i = 0; i < sub->order; i++)
+ for (int i = 0; i < sub->order; i++)
put_sbits(&s->pb, cbits, sub->coefs[i]);
}
@@ -1258,7 +1542,7 @@ static void write_subframes(FlacEncodeContext *s)
int k = sub->rc.params[p];
put_bits(&s->pb, sub->rc.coding_mode, k);
while (res < part_end)
- set_sr_golomb_flac(&s->pb, *res++, k, INT32_MAX, 0);
+ set_sr_golomb_flac(&s->pb, *res++, k);
part_end = FFMIN(frame_end, part_end + psize);
}
}
@@ -1306,7 +1590,7 @@ static int update_md5_sum(FlacEncodeContext *s, const void *samples)
(const uint16_t *) samples, buf_size / 2);
buf = s->md5_buffer;
#endif
- } else {
+ } else if (s->avctx->bits_per_raw_sample <= 24) {
int i;
const int32_t *samples0 = samples;
uint8_t *tmp = s->md5_buffer;
@@ -1316,6 +1600,15 @@ static int update_md5_sum(FlacEncodeContext *s, const void *samples)
AV_WL24(tmp + 3*i, v);
}
buf = s->md5_buffer;
+ } else {
+ /* s->avctx->bits_per_raw_sample <= 32 */
+ int i;
+ const int32_t *samples0 = samples;
+ uint8_t *tmp = s->md5_buffer;
+
+ for (i = 0; i < s->frame.blocksize * s->channels; i++)
+ AV_WL32(tmp + 4*i, samples0[i]);
+ buf = s->md5_buffer;
}
av_md5_update(s->md5ctx, buf, buf_size);
@@ -1355,9 +1648,9 @@ static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
/* change max_framesize for small final frame */
if (frame->nb_samples < s->frame.blocksize) {
- s->max_framesize = ff_flac_get_max_frame_size(frame->nb_samples,
- s->channels,
- avctx->bits_per_raw_sample);
+ s->max_framesize = flac_get_max_frame_size(frame->nb_samples,
+ s->channels,
+ avctx->bits_per_raw_sample);
}
init_frame(s, frame->nb_samples);
@@ -1397,10 +1690,7 @@ static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
if (out_bytes < s->min_framesize)
s->min_framesize = out_bytes;
- avpkt->pts = frame->pts;
- avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
-
- s->next_pts = avpkt->pts + avpkt->duration;
+ s->next_pts = frame->pts + ff_samples_to_time_base(avctx, frame->nb_samples);
av_shrink_packet(avpkt, out_bytes);
@@ -1460,11 +1750,12 @@ static const AVClass flac_encoder_class = {
const FFCodec ff_flac_encoder = {
.p.name = "flac",
- .p.long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
+ CODEC_LONG_NAME("FLAC (Free Lossless Audio Codec)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_FLAC,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
- AV_CODEC_CAP_SMALL_LAST_FRAME,
+ AV_CODEC_CAP_SMALL_LAST_FRAME |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(FlacEncodeContext),
.init = flac_encode_init,
FF_CODEC_ENCODE_CB(flac_encode_frame),
@@ -1473,5 +1764,5 @@ const FFCodec ff_flac_encoder = {
AV_SAMPLE_FMT_S32,
AV_SAMPLE_FMT_NONE },
.p.priv_class = &flac_encoder_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_EOF_FLUSH,
};
diff --git a/libavcodec/flv.h b/libavcodec/flacencdsp.c
similarity index 64%
rename from libavcodec/flv.h
rename to libavcodec/flacencdsp.c
index 561cfe0ba..46e5a0352 100644
--- a/libavcodec/flv.h
+++ b/libavcodec/flacencdsp.c
@@ -1,5 +1,5 @@
/*
- * FLV specific private header.
+ * Copyright (c) 2012 Mans Rullgard
*
* This file is part of FFmpeg.
*
@@ -18,17 +18,23 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef AVCODEC_FLV_H
-#define AVCODEC_FLV_H
+#include "config.h"
+#include "flacencdsp.h"
-#include "get_bits.h"
-#include "mpegvideo.h"
-#include "put_bits.h"
+#define SAMPLE_SIZE 16
+#include "flacdsp_lpc_template.c"
-void ff_flv_encode_picture_header(MpegEncContext *s, int picture_number);
-void ff_flv2_encode_ac_esc(PutBitContext *pb, int slevel, int level, int run,
- int last);
+#undef SAMPLE_SIZE
+#define SAMPLE_SIZE 32
+#include "flacdsp_lpc_template.c"
-int ff_flv_decode_picture_header(MpegEncContext *s);
-#endif /* AVCODEC_FLV_H */
+av_cold void ff_flacencdsp_init(FLACEncDSPContext *c)
+{
+ c->lpc16_encode = flac_lpc_encode_c_16;
+ c->lpc32_encode = flac_lpc_encode_c_32;
+
+#if ARCH_X86
+ ff_flacencdsp_init_x86(c);
+#endif
+}
diff --git a/libavcodec/flacencdsp.h b/libavcodec/flacencdsp.h
new file mode 100644
index 000000000..39811e235
--- /dev/null
+++ b/libavcodec/flacencdsp.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_FLACENCDSP_H
+#define AVCODEC_FLACENCDSP_H
+
+#include
+
+typedef struct FLACEncDSPContext {
+ void (*lpc16_encode)(int32_t *res, const int32_t *smp, int len, int order,
+ const int32_t coefs[32], int shift);
+ void (*lpc32_encode)(int32_t *res, const int32_t *smp, int len, int order,
+ const int32_t coefs[32], int shift);
+} FLACEncDSPContext;
+
+void ff_flacencdsp_init(FLACEncDSPContext *c);
+void ff_flacencdsp_init_x86(FLACEncDSPContext *c);
+
+#endif /* AVCODEC_FLACDSP_H */
diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c
index 4357b25d0..8a01e3a4b 100644
--- a/libavcodec/flashsv.c
+++ b/libavcodec/flashsv.c
@@ -35,16 +35,15 @@
#include "config_components.h"
-#include
-#include
+#include
#include
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
#include "zlib_wrapper.h"
typedef struct BlockInfo {
@@ -503,7 +502,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
#if CONFIG_FLASHSV_DECODER
const FFCodec ff_flashsv_decoder = {
.p.name = "flashsv",
- .p.long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
+ CODEC_LONG_NAME("Flash Screen Video v1"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FLASHSV,
.priv_data_size = sizeof(FlashSVContext),
@@ -511,7 +510,7 @@ const FFCodec ff_flashsv_decoder = {
.close = flashsv_decode_end,
FF_CODEC_DECODE_CB(flashsv_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
};
#endif /* CONFIG_FLASHSV_DECODER */
@@ -571,7 +570,7 @@ static av_cold int flashsv2_decode_end(AVCodecContext *avctx)
const FFCodec ff_flashsv2_decoder = {
.p.name = "flashsv2",
- .p.long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"),
+ CODEC_LONG_NAME("Flash Screen Video v2"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FLASHSV2,
.priv_data_size = sizeof(FlashSVContext),
@@ -579,7 +578,7 @@ const FFCodec ff_flashsv2_decoder = {
.close = flashsv2_decode_end,
FF_CODEC_DECODE_CB(flashsv_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
};
#endif /* CONFIG_FLASHSV2_DECODER */
diff --git a/libavcodec/flashsv2enc.c b/libavcodec/flashsv2enc.c
index 07fa9945f..75b48eb1f 100644
--- a/libavcodec/flashsv2enc.c
+++ b/libavcodec/flashsv2enc.c
@@ -105,7 +105,7 @@ typedef struct FlashSV2Context {
int rows, cols;
- int last_key_frame;
+ int64_t last_key_frame;
int image_width, image_height;
int block_width, block_height;
@@ -787,7 +787,7 @@ static int optimum_use15_7(FlashSV2Context * s)
{
#ifndef FLASHSV2_DUMB
double ideal = ((double)(s->avctx->bit_rate * s->avctx->time_base.den * s->avctx->ticks_per_frame)) /
- ((double) s->avctx->time_base.num) * s->avctx->frame_number;
+ ((double) s->avctx->time_base.num) * s->avctx->frame_num;
if (ideal + use15_7_threshold < s->total_bits) {
return 1;
} else {
@@ -861,20 +861,20 @@ static int flashsv2_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
return res;
/* First frame needs to be a keyframe */
- if (avctx->frame_number == 0)
+ if (avctx->frame_num == 0)
keyframe = 1;
/* Check the placement of keyframes */
if (avctx->gop_size > 0) {
- if (avctx->frame_number >= s->last_key_frame + avctx->gop_size)
+ if (avctx->frame_num >= s->last_key_frame + avctx->gop_size)
keyframe = 1;
}
if (!keyframe
- && avctx->frame_number > s->last_key_frame + avctx->keyint_min) {
+ && avctx->frame_num > s->last_key_frame + avctx->keyint_min) {
recommend_keyframe(s, &keyframe);
if (keyframe)
- av_log(avctx, AV_LOG_DEBUG, "Recommending key frame at frame %d\n", avctx->frame_number);
+ av_log(avctx, AV_LOG_DEBUG, "Recommending key frame at frame %"PRId64"\n", avctx->frame_num);
}
if (keyframe) {
@@ -890,9 +890,9 @@ static int flashsv2_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
if (keyframe) {
new_key_frame(s);
- s->last_key_frame = avctx->frame_number;
+ s->last_key_frame = avctx->frame_num;
pkt->flags |= AV_PKT_FLAG_KEY;
- av_log(avctx, AV_LOG_DEBUG, "Inserting key frame at frame %d\n", avctx->frame_number);
+ av_log(avctx, AV_LOG_DEBUG, "Inserting key frame at frame %"PRId64"\n", avctx->frame_num);
}
pkt->size = res;
@@ -912,13 +912,14 @@ static av_cold int flashsv2_encode_end(AVCodecContext * avctx)
const FFCodec ff_flashsv2_encoder = {
.p.name = "flashsv2",
- .p.long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video Version 2"),
+ CODEC_LONG_NAME("Flash Screen Video Version 2"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FLASHSV2,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(FlashSV2Context),
.init = flashsv2_encode_init,
FF_CODEC_ENCODE_CB(flashsv2_encode_frame),
.close = flashsv2_encode_end,
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/flashsvenc.c b/libavcodec/flashsvenc.c
index 592bb061c..5cf0602f5 100644
--- a/libavcodec/flashsvenc.c
+++ b/libavcodec/flashsvenc.c
@@ -44,39 +44,40 @@
* Speed up. Make the difference check faster.
*/
-#include
-#include
+#include
#include
+#include "libavutil/buffer.h"
+
#include "avcodec.h"
#include "codec_internal.h"
#include "encode.h"
#include "put_bits.h"
#include "bytestream.h"
+/* These values are hardcoded for now. */
+#define BLOCK_WIDTH (4 * 16U)
+#define BLOCK_HEIGHT (4 * 16U)
typedef struct FlashSVContext {
AVCodecContext *avctx;
- uint8_t *previous_frame;
+ const uint8_t *previous_frame;
+ AVBufferRef *prev_frame_buf;
int image_width, image_height;
- int block_width, block_height;
- uint8_t *encbuffer;
- int block_size;
- int last_key_frame;
+ unsigned packet_size;
+ int64_t last_key_frame;
uint8_t tmpblock[3 * 256 * 256];
} FlashSVContext;
-static int copy_region_enc(uint8_t *sptr, uint8_t *dptr, int dx, int dy,
- int h, int w, int stride, uint8_t *pfptr)
+static int copy_region_enc(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
+ int h, int w, int stride, const uint8_t *pfptr)
{
int i, j;
- uint8_t *nsptr;
- uint8_t *npfptr;
int diff = 0;
for (i = dx + h; i > dx; i--) {
- nsptr = sptr + i * stride + dy * 3;
- npfptr = pfptr + i * stride + dy * 3;
+ const uint8_t *nsptr = sptr + i * stride + dy * 3;
+ const uint8_t *npfptr = pfptr + i * stride + dy * 3;
for (j = 0; j < w * 3; j++) {
diff |= npfptr[j] ^ nsptr[j];
dptr[j] = nsptr[j];
@@ -92,8 +93,7 @@ static av_cold int flashsv_encode_end(AVCodecContext *avctx)
{
FlashSVContext *s = avctx->priv_data;
- av_freep(&s->encbuffer);
- av_freep(&s->previous_frame);
+ av_buffer_unref(&s->prev_frame_buf);
return 0;
}
@@ -101,6 +101,7 @@ static av_cold int flashsv_encode_end(AVCodecContext *avctx)
static av_cold int flashsv_encode_init(AVCodecContext *avctx)
{
FlashSVContext *s = avctx->priv_data;
+ int h_blocks, v_blocks, nb_blocks;
s->avctx = avctx;
@@ -115,12 +116,10 @@ static av_cold int flashsv_encode_init(AVCodecContext *avctx)
s->image_width = avctx->width;
s->image_height = avctx->height;
- s->encbuffer = av_mallocz(s->image_width * s->image_height * 3);
-
- if (!s->encbuffer) {
- av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n");
- return AVERROR(ENOMEM);
- }
+ h_blocks = (s->image_width + BLOCK_WIDTH - 1) / BLOCK_WIDTH;
+ v_blocks = (s->image_height + BLOCK_WIDTH - 1) / BLOCK_WIDTH;
+ nb_blocks = h_blocks * v_blocks;
+ s->packet_size = 4 + nb_blocks * (2 + 3 * BLOCK_WIDTH * BLOCK_HEIGHT);
return 0;
}
@@ -128,7 +127,7 @@ static av_cold int flashsv_encode_init(AVCodecContext *avctx)
static int encode_bitstream(FlashSVContext *s, const AVFrame *p, uint8_t *buf,
int buf_size, int block_width, int block_height,
- uint8_t *previous_frame, int *I_frame)
+ const uint8_t *previous_frame, int *I_frame)
{
PutBitContext pb;
@@ -203,69 +202,59 @@ static int flashsv_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *pict, int *got_packet)
{
FlashSVContext * const s = avctx->priv_data;
- const AVFrame * const p = pict;
- uint8_t *pfptr;
+ const uint8_t *prev_frame = s->previous_frame;
int res;
int I_frame = 0;
int opt_w = 4, opt_h = 4;
/* First frame needs to be a keyframe */
- if (avctx->frame_number == 0) {
- s->previous_frame = av_mallocz(FFABS(p->linesize[0]) * s->image_height);
- if (!s->previous_frame) {
- av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n");
- return AVERROR(ENOMEM);
- }
+ if (!s->previous_frame) {
+ prev_frame = pict->data[0];
I_frame = 1;
}
- if (p->linesize[0] < 0)
- pfptr = s->previous_frame - (s->image_height - 1) * p->linesize[0];
- else
- pfptr = s->previous_frame;
-
/* Check the placement of keyframes */
if (avctx->gop_size > 0 &&
- avctx->frame_number >= s->last_key_frame + avctx->gop_size) {
+ avctx->frame_num >= s->last_key_frame + avctx->gop_size) {
I_frame = 1;
}
- if ((res = ff_alloc_packet(avctx, pkt, s->image_width * s->image_height * 3)) < 0)
+ res = ff_alloc_packet(avctx, pkt, s->packet_size);
+ if (res < 0)
return res;
- pkt->size = encode_bitstream(s, p, pkt->data, pkt->size, opt_w * 16, opt_h * 16,
- pfptr, &I_frame);
-
- //save the current frame
- if (p->linesize[0] > 0)
- memcpy(s->previous_frame, p->data[0], s->image_height * p->linesize[0]);
- else
- memcpy(s->previous_frame,
- p->data[0] + p->linesize[0] * (s->image_height - 1),
- s->image_height * FFABS(p->linesize[0]));
+ pkt->size = encode_bitstream(s, pict, pkt->data, pkt->size,
+ opt_w * 16, opt_h * 16,
+ prev_frame, &I_frame);
//mark the frame type so the muxer can mux it correctly
if (I_frame) {
- s->last_key_frame = avctx->frame_number;
- ff_dlog(avctx, "Inserting keyframe at frame %d\n", avctx->frame_number);
+ s->last_key_frame = avctx->frame_num;
+ ff_dlog(avctx, "Inserting keyframe at frame %"PRId64"\n", avctx->frame_num);
}
if (I_frame)
pkt->flags |= AV_PKT_FLAG_KEY;
*got_packet = 1;
+ //save the current frame
+ res = av_buffer_replace(&s->prev_frame_buf, pict->buf[0]);
+ if (res < 0)
+ return res;
+ s->previous_frame = pict->data[0];
+
return 0;
}
const FFCodec ff_flashsv_encoder = {
.p.name = "flashsv",
- .p.long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video"),
+ CODEC_LONG_NAME("Flash Screen Video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FLASHSV,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(FlashSVContext),
.init = flashsv_encode_init,
FF_CODEC_ENCODE_CB(flashsv_encode_frame),
.close = flashsv_encode_end,
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c
index b841050a8..228f65277 100644
--- a/libavcodec/flicvideo.c
+++ b/libavcodec/flicvideo.c
@@ -34,15 +34,13 @@
* in which the header is only 12 bytes.
*/
-#include
-#include
#include
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "mathops.h"
#define FLI_256_COLOR 4
@@ -1106,7 +1104,7 @@ static av_cold int flic_decode_end(AVCodecContext *avctx)
const FFCodec ff_flic_decoder = {
.p.name = "flic",
- .p.long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
+ CODEC_LONG_NAME("Autodesk Animator Flic video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FLIC,
.priv_data_size = sizeof(FlicDecodeContext),
@@ -1114,5 +1112,4 @@ const FFCodec ff_flic_decoder = {
.close = flic_decode_end,
FF_CODEC_DECODE_CB(flic_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/tests/fft-fixed.c b/libavcodec/float2half.c
similarity index 93%
rename from libavcodec/tests/fft-fixed.c
rename to libavcodec/float2half.c
index 3c50bf1dc..90a6f63fa 100644
--- a/libavcodec/tests/fft-fixed.c
+++ b/libavcodec/float2half.c
@@ -16,6 +16,4 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define FFT_FLOAT 0
-#define AVFFT 0
-#include "fft.c"
+#include "libavutil/float2half.c"
diff --git a/libavcodec/float2half.h b/libavcodec/float2half.h
deleted file mode 100644
index e05125088..000000000
--- a/libavcodec/float2half.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVCODEC_FLOAT2HALF_H
-#define AVCODEC_FLOAT2HALF_H
-
-#include
-
-static void float2half_tables(uint16_t *basetable, uint8_t *shifttable)
-{
- for (int i = 0; i < 256; i++) {
- int e = i - 127;
-
- if (e < -24) { // Very small numbers map to zero
- basetable[i|0x000] = 0x0000;
- basetable[i|0x100] = 0x8000;
- shifttable[i|0x000] = 24;
- shifttable[i|0x100] = 24;
- } else if (e < -14) { // Small numbers map to denorms
- basetable[i|0x000] = (0x0400>>(-e-14));
- basetable[i|0x100] = (0x0400>>(-e-14)) | 0x8000;
- shifttable[i|0x000] = -e-1;
- shifttable[i|0x100] = -e-1;
- } else if (e <= 15) { // Normal numbers just lose precision
- basetable[i|0x000] = ((e + 15) << 10);
- basetable[i|0x100] = ((e + 15) << 10) | 0x8000;
- shifttable[i|0x000] = 13;
- shifttable[i|0x100] = 13;
- } else if (e < 128) { // Large numbers map to Infinity
- basetable[i|0x000] = 0x7C00;
- basetable[i|0x100] = 0xFC00;
- shifttable[i|0x000] = 24;
- shifttable[i|0x100] = 24;
- } else { // Infinity and NaN's stay Infinity and NaN's
- basetable[i|0x000] = 0x7C00;
- basetable[i|0x100] = 0xFC00;
- shifttable[i|0x000] = 13;
- shifttable[i|0x100] = 13;
- }
- }
-}
-
-static uint16_t float2half(uint32_t f, uint16_t *basetable, uint8_t *shifttable)
-{
- uint16_t h;
-
- h = basetable[(f >> 23) & 0x1ff] + ((f & 0x007fffff) >> shifttable[(f >> 23) & 0x1ff]);
-
- return h;
-}
-
-#endif /* AVCODEC_FLOAT2HALF_H */
diff --git a/libavcodec/flvdec.c b/libavcodec/flvdec.c
index cc016d129..09fefd3d1 100644
--- a/libavcodec/flvdec.c
+++ b/libavcodec/flvdec.c
@@ -108,14 +108,12 @@ int ff_flv_decode_picture_header(MpegEncContext *s)
s->h263_flv - 1, s->qscale, s->picture_number);
}
- s->y_dc_scale_table = s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
-
return 0;
}
const FFCodec ff_flv_decoder = {
.p.name = "flv",
- .p.long_name = NULL_IF_CONFIG_SMALL("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"),
+ CODEC_LONG_NAME("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FLV1,
.priv_data_size = sizeof(MpegEncContext),
@@ -123,8 +121,7 @@ const FFCodec ff_flv_decoder = {
.close = ff_h263_decode_end,
FF_CODEC_DECODE_CB(ff_h263_decode_frame),
.p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
+ .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.p.max_lowres = 3,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE },
diff --git a/libavcodec/flvenc.c b/libavcodec/flvenc.c
index 74ed321e2..6a96cb0f2 100644
--- a/libavcodec/flvenc.c
+++ b/libavcodec/flvenc.c
@@ -25,7 +25,7 @@
#include "mpegvideodata.h"
#include "mpegvideoenc.h"
-void ff_flv_encode_picture_header(MpegEncContext *s, int picture_number)
+void ff_flv_encode_picture_header(MpegEncContext *s)
{
int format;
@@ -94,7 +94,7 @@ void ff_flv2_encode_ac_esc(PutBitContext *pb, int slevel, int level,
const FFCodec ff_flv_encoder = {
.p.name = "flv",
- .p.long_name = NULL_IF_CONFIG_SMALL("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"),
+ CODEC_LONG_NAME("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FLV1,
.p.priv_class = &ff_mpv_enc_class,
@@ -102,7 +102,8 @@ const FFCodec ff_flv_encoder = {
.init = ff_mpv_encode_init,
FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
.close = ff_mpv_encode_end,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE},
+ .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
};
diff --git a/libavcodec/flvenc.h b/libavcodec/flvenc.h
index aaa0fcffa..1ecbb46b1 100644
--- a/libavcodec/flvenc.h
+++ b/libavcodec/flvenc.h
@@ -24,7 +24,7 @@
#include "mpegvideo.h"
#include "put_bits.h"
-void ff_flv_encode_picture_header(MpegEncContext *s, int picture_number);
+void ff_flv_encode_picture_header(MpegEncContext *s);
void ff_flv2_encode_ac_esc(PutBitContext *pb, int slevel, int level, int run,
int last);
diff --git a/libavcodec/fmtconvert.c b/libavcodec/fmtconvert.c
index fd56a63c7..d889e61ac 100644
--- a/libavcodec/fmtconvert.c
+++ b/libavcodec/fmtconvert.c
@@ -22,7 +22,6 @@
#include "config.h"
#include "libavutil/attributes.h"
-#include "avcodec.h"
#include "fmtconvert.h"
static void int32_to_float_fmul_scalar_c(float *dst, const int32_t *src,
@@ -33,14 +32,6 @@ static void int32_to_float_fmul_scalar_c(float *dst, const int32_t *src,
dst[i] = src[i] * mul;
}
-static void int32_to_float_c(float *dst, const int32_t *src, intptr_t len)
-{
- int i;
-
- for (i = 0; i < len; i++)
- dst[i] = (float)src[i];
-}
-
static void int32_to_float_fmul_array8_c(FmtConvertContext *c, float *dst,
const int32_t *src, const float *mul,
int len)
@@ -50,20 +41,21 @@ static void int32_to_float_fmul_array8_c(FmtConvertContext *c, float *dst,
c->int32_to_float_fmul_scalar(&dst[i], &src[i], *mul++, 8);
}
-av_cold void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx)
+av_cold void ff_fmt_convert_init(FmtConvertContext *c)
{
- c->int32_to_float = int32_to_float_c;
c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_c;
c->int32_to_float_fmul_array8 = int32_to_float_fmul_array8_c;
#if ARCH_AARCH64
- ff_fmt_convert_init_aarch64(c, avctx);
+ ff_fmt_convert_init_aarch64(c);
#elif ARCH_ARM
- ff_fmt_convert_init_arm(c, avctx);
+ ff_fmt_convert_init_arm(c);
#elif ARCH_PPC
- ff_fmt_convert_init_ppc(c, avctx);
+ ff_fmt_convert_init_ppc(c);
+#elif ARCH_RISCV
+ ff_fmt_convert_init_riscv(c);
#elif ARCH_X86
- ff_fmt_convert_init_x86(c, avctx);
+ ff_fmt_convert_init_x86(c);
#endif
#if HAVE_MIPSFPU
ff_fmt_convert_init_mips(c);
diff --git a/libavcodec/fmtconvert.h b/libavcodec/fmtconvert.h
index a1b17e4f0..1cb4628a6 100644
--- a/libavcodec/fmtconvert.h
+++ b/libavcodec/fmtconvert.h
@@ -23,7 +23,7 @@
#ifndef AVCODEC_FMTCONVERT_H
#define AVCODEC_FMTCONVERT_H
-#include "avcodec.h"
+#include
typedef struct FmtConvertContext {
/**
@@ -37,16 +37,6 @@ typedef struct FmtConvertContext {
*/
void (*int32_to_float_fmul_scalar)(float *dst, const int32_t *src,
float mul, int len);
- /**
- * Convert an array of int32_t to float.
- * @param dst destination array of float.
- * constraints: 32-byte aligned
- * @param src source array of int32_t.
- * constraints: 32-byte aligned
- * @param len number of elements to convert.
- * constraints: multiple of 8
- */
- void (*int32_to_float)(float *dst, const int32_t *src, intptr_t len);
/**
* Convert an array of int32_t to float and multiply by a float value from another array,
@@ -66,12 +56,13 @@ typedef struct FmtConvertContext {
} FmtConvertContext;
-void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx);
+void ff_fmt_convert_init(FmtConvertContext *c);
-void ff_fmt_convert_init_aarch64(FmtConvertContext *c, AVCodecContext *avctx);
-void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx);
-void ff_fmt_convert_init_ppc(FmtConvertContext *c, AVCodecContext *avctx);
-void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx);
+void ff_fmt_convert_init_aarch64(FmtConvertContext *c);
+void ff_fmt_convert_init_arm(FmtConvertContext *c);
+void ff_fmt_convert_init_ppc(FmtConvertContext *c);
+void ff_fmt_convert_init_riscv(FmtConvertContext *c);
+void ff_fmt_convert_init_x86(FmtConvertContext *c);
void ff_fmt_convert_init_mips(FmtConvertContext *c);
#endif /* AVCODEC_FMTCONVERT_H */
diff --git a/libavcodec/fmvc.c b/libavcodec/fmvc.c
index 912ad8fc8..3ee915cc4 100644
--- a/libavcodec/fmvc.c
+++ b/libavcodec/fmvc.c
@@ -21,13 +21,12 @@
*/
#include
-#include
#include
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#define BLOCK_HEIGHT 112u
#define BLOCK_WIDTH 84u
@@ -637,7 +636,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
const FFCodec ff_fmvc_decoder = {
.p.name = "fmvc",
- .p.long_name = NULL_IF_CONFIG_SMALL("FM Screen Capture Codec"),
+ CODEC_LONG_NAME("FM Screen Capture Codec"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FMVC,
.priv_data_size = sizeof(FMVCContext),
@@ -645,6 +644,5 @@ const FFCodec ff_fmvc_decoder = {
.close = decode_close,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c
index 07d310a98..62d9580ad 100644
--- a/libavcodec/frame_thread_encoder.c
+++ b/libavcodec/frame_thread_encoder.c
@@ -24,14 +24,12 @@
#include "libavutil/avassert.h"
#include "libavutil/cpu.h"
-#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavutil/thread.h"
#include "avcodec.h"
-#include "codec_internal.h"
+#include "encode.h"
#include "internal.h"
#include "pthread_internal.h"
-#include "thread.h"
#define MAX_THREADS 64
/* There can be as many as MAX_THREADS + 1 outstanding tasks.
@@ -45,11 +43,11 @@ typedef struct{
AVPacket *outdata;
int return_code;
int finished;
+ int got_packet;
} Task;
typedef struct{
AVCodecContext *parent_avctx;
- pthread_mutex_t buffer_mutex;
pthread_mutex_t task_fifo_mutex; /* Used to guard (next_)task_index */
pthread_cond_t task_fifo_cond;
@@ -70,8 +68,8 @@ typedef struct{
#define OFF(member) offsetof(ThreadContext, member)
DEFINE_OFFSET_ARRAY(ThreadContext, thread_ctx, pthread_init_cnt,
- (OFF(buffer_mutex), OFF(task_fifo_mutex), OFF(finished_task_mutex)),
- (OFF(task_fifo_cond), OFF(finished_task_cond)));
+ (OFF(task_fifo_mutex), OFF(finished_task_mutex)),
+ (OFF(task_fifo_cond), OFF(finished_task_cond)));
#undef OFF
static void * attribute_align_arg worker(void *v){
@@ -79,7 +77,7 @@ static void * attribute_align_arg worker(void *v){
ThreadContext *c = avctx->internal->frame_thread_encoder;
while (!atomic_load(&c->exit)) {
- int got_packet = 0, ret;
+ int ret;
AVPacket *pkt;
AVFrame *frame;
Task *task;
@@ -104,19 +102,7 @@ static void * attribute_align_arg worker(void *v){
frame = task->indata;
pkt = task->outdata;
- ret = ffcodec(avctx->codec)->cb.encode(avctx, pkt, frame, &got_packet);
- if(got_packet) {
- int ret2 = av_packet_make_refcounted(pkt);
- if (ret >= 0 && ret2 < 0)
- ret = ret2;
- pkt->pts = pkt->dts = frame->pts;
- } else {
- pkt->data = NULL;
- pkt->size = 0;
- }
- pthread_mutex_lock(&c->buffer_mutex);
- av_frame_unref(frame);
- pthread_mutex_unlock(&c->buffer_mutex);
+ ret = ff_encode_encode_cb(avctx, pkt, frame, &task->got_packet);
pthread_mutex_lock(&c->finished_task_mutex);
task->return_code = ret;
task->finished = 1;
@@ -124,9 +110,7 @@ static void * attribute_align_arg worker(void *v){
pthread_mutex_unlock(&c->finished_task_mutex);
}
end:
- pthread_mutex_lock(&c->buffer_mutex);
avcodec_close(avctx);
- pthread_mutex_unlock(&c->buffer_mutex);
av_freep(&avctx);
return NULL;
}
@@ -315,8 +299,7 @@ int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
* because there is no outstanding task with this index. */
outtask->finished = 0;
av_packet_move_ref(pkt, outtask->outdata);
- if(pkt->data)
- *got_packet_ptr = 1;
+ *got_packet_ptr = outtask->got_packet;
c->finished_task_index = (c->finished_task_index + 1) % c->max_tasks;
return outtask->return_code;
diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c
index 7f695305f..4c4c46b60 100644
--- a/libavcodec/fraps.c
+++ b/libavcodec/fraps.c
@@ -141,7 +141,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *f,
int buf_size = avpkt->size;
uint32_t header;
unsigned int version,header_size;
- unsigned int x, y;
const uint32_t *buf32;
uint32_t *luma1,*luma2,*cb,*cr;
uint32_t offs[4];
@@ -238,12 +237,12 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *f,
}
buf32 = (const uint32_t*)buf;
- for (y = 0; y < avctx->height / 2; y++) {
+ for (ptrdiff_t y = 0; y < avctx->height / 2; y++) {
luma1 = (uint32_t*)&f->data[0][ y * 2 * f->linesize[0] ];
luma2 = (uint32_t*)&f->data[0][ (y * 2 + 1) * f->linesize[0] ];
cr = (uint32_t*)&f->data[1][ y * f->linesize[1] ];
cb = (uint32_t*)&f->data[2][ y * f->linesize[2] ];
- for (x = 0; x < avctx->width; x += 8) {
+ for (ptrdiff_t x = 0; x < avctx->width; x += 8) {
*luma1++ = *buf32++;
*luma1++ = *buf32++;
*luma2++ = *buf32++;
@@ -258,18 +257,18 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *f,
if (is_pal) {
uint32_t *pal = (uint32_t *)f->data[1];
- for (y = 0; y < 256; y++) {
+ for (unsigned y = 0; y < 256; y++) {
pal[y] = AV_RL32(buf) | 0xFF000000;
buf += 4;
}
- for (y = 0; y height; y++)
+ for (ptrdiff_t y = 0; y < avctx->height; y++)
memcpy(&f->data[0][y * f->linesize[0]],
&buf[y * avctx->width],
avctx->width);
} else {
/* Fraps v1 is an upside-down BGR24 */
- for (y = 0; yheight; y++)
+ for (ptrdiff_t y = 0; y < avctx->height; y++)
memcpy(&f->data[0][(avctx->height - y - 1) * f->linesize[0]],
&buf[y * avctx->width * 3],
3 * avctx->width);
@@ -341,7 +340,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
const FFCodec ff_fraps_decoder = {
.p.name = "fraps",
- .p.long_name = NULL_IF_CONFIG_SMALL("Fraps"),
+ CODEC_LONG_NAME("Fraps"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FRAPS,
.priv_data_size = sizeof(FrapsContext),
@@ -349,5 +348,4 @@ const FFCodec ff_fraps_decoder = {
.close = decode_end,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/frwu.c b/libavcodec/frwu.c
index 766fda745..cf183f841 100644
--- a/libavcodec/frwu.c
+++ b/libavcodec/frwu.c
@@ -23,7 +23,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "libavutil/opt.h"
typedef struct {
@@ -117,7 +117,7 @@ static const AVClass frwu_class = {
const FFCodec ff_frwu_decoder = {
.p.name = "frwu",
- .p.long_name = NULL_IF_CONFIG_SMALL("Forward Uncompressed"),
+ CODEC_LONG_NAME("Forward Uncompressed"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FRWU,
.priv_data_size = sizeof(FRWUContext),
@@ -125,5 +125,4 @@ const FFCodec ff_frwu_decoder = {
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
.p.priv_class = &frwu_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/ftr.c b/libavcodec/ftr.c
new file mode 100644
index 000000000..74a2c10b5
--- /dev/null
+++ b/libavcodec/ftr.c
@@ -0,0 +1,208 @@
+/*
+ * 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 "adts_header.h"
+#include "avcodec.h"
+#include "codec_internal.h"
+#include "get_bits.h"
+#include "decode.h"
+
+typedef struct FTRContext {
+ AVCodecContext *aac_avctx[64]; // wrapper context for AAC
+ int nb_context;
+ AVPacket *packet;
+ AVFrame *frame;
+} FTRContext;
+
+static av_cold int ftr_init(AVCodecContext *avctx)
+{
+ FTRContext *s = avctx->priv_data;
+ const AVCodec *codec;
+ int ret;
+
+ if (avctx->ch_layout.nb_channels > 64 ||
+ avctx->ch_layout.nb_channels <= 0)
+ return AVERROR(EINVAL);
+
+ s->packet = av_packet_alloc();
+ if (!s->packet)
+ return AVERROR(ENOMEM);
+
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
+
+ s->nb_context = avctx->ch_layout.nb_channels;
+
+ codec = avcodec_find_decoder(AV_CODEC_ID_AAC);
+ if (!codec)
+ return AVERROR_BUG;
+
+ for (int i = 0; i < s->nb_context; i++) {
+ s->aac_avctx[i] = avcodec_alloc_context3(codec);
+ if (!s->aac_avctx[i])
+ return AVERROR(ENOMEM);
+ ret = avcodec_open2(s->aac_avctx[i], codec, NULL);
+ if (ret < 0)
+ return ret;
+ }
+
+ avctx->sample_fmt = s->aac_avctx[0]->sample_fmt;
+ if (!av_sample_fmt_is_planar(avctx->sample_fmt))
+ return AVERROR(EINVAL);
+
+ return 0;
+}
+
+static int ftr_decode_frame(AVCodecContext *avctx, AVFrame *frame,
+ int *got_frame, AVPacket *avpkt)
+{
+ FTRContext *s = avctx->priv_data;
+ GetBitContext gb;
+ int ret, ch_offset = 0;
+
+ ret = init_get_bits8(&gb, avpkt->data, avpkt->size);
+ if (ret < 0)
+ return ret;
+
+ frame->nb_samples = 0;
+
+ for (int i = 0; i < s->nb_context; i++) {
+ AVCodecContext *codec_avctx = s->aac_avctx[i];
+ GetBitContext gb2 = gb;
+ AACADTSHeaderInfo hdr_info;
+ int size;
+
+ if (get_bits_left(&gb) < 64)
+ return AVERROR_INVALIDDATA;
+
+ memset(&hdr_info, 0, sizeof(hdr_info));
+
+ size = ff_adts_header_parse(&gb2, &hdr_info);
+ if (size <= 0 || size * 8 > get_bits_left(&gb))
+ return AVERROR_INVALIDDATA;
+
+ if (size > s->packet->size) {
+ ret = av_grow_packet(s->packet, size - s->packet->size);
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = av_packet_make_writable(s->packet);
+ if (ret < 0)
+ return ret;
+
+ memcpy(s->packet->data, avpkt->data + (get_bits_count(&gb) >> 3), size);
+ s->packet->size = size;
+
+ if (size > 12) {
+ uint8_t *buf = s->packet->data;
+
+ if (buf[3] & 0x20) {
+ int tmp = buf[8];
+ buf[ 9] = ~buf[9];
+ buf[11] = ~buf[11];
+ buf[12] = ~buf[12];
+ buf[ 8] = ~buf[10];
+ buf[10] = ~tmp;
+ }
+ }
+
+ ret = avcodec_send_packet(codec_avctx, s->packet);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n");
+ return ret;
+ }
+
+ ret = avcodec_receive_frame(codec_avctx, s->frame);
+ if (ret < 0)
+ return ret;
+
+ if (!avctx->sample_rate) {
+ avctx->sample_rate = codec_avctx->sample_rate;
+ } else {
+ if (avctx->sample_rate != codec_avctx->sample_rate)
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!frame->nb_samples) {
+ frame->nb_samples = s->frame->nb_samples;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+ } else {
+ if (frame->nb_samples != s->frame->nb_samples)
+ return AVERROR_INVALIDDATA;
+ }
+
+ skip_bits_long(&gb, size * 8);
+
+ if (ch_offset + s->frame->ch_layout.nb_channels > avctx->ch_layout.nb_channels)
+ return AVERROR_INVALIDDATA;
+
+ if (avctx->sample_fmt != codec_avctx->sample_fmt)
+ return AVERROR_INVALIDDATA;
+
+ for (int ch = 0; ch < s->frame->ch_layout.nb_channels; ch++)
+ memcpy(frame->extended_data[ch_offset + ch],
+ s->frame->extended_data[ch],
+ av_get_bytes_per_sample(codec_avctx->sample_fmt) * s->frame->nb_samples);
+
+ ch_offset += s->frame->ch_layout.nb_channels;
+
+ if (ch_offset >= avctx->ch_layout.nb_channels)
+ break;
+ }
+
+ *got_frame = 1;
+
+ return get_bits_count(&gb) >> 3;
+}
+
+static void ftr_flush(AVCodecContext *avctx)
+{
+ FTRContext *s = avctx->priv_data;
+
+ for (int i = 0; i < s->nb_context; i++)
+ avcodec_flush_buffers(s->aac_avctx[i]);
+}
+
+static av_cold int ftr_close(AVCodecContext *avctx)
+{
+ FTRContext *s = avctx->priv_data;
+
+ for (int i = 0; i < s->nb_context; i++)
+ avcodec_free_context(&s->aac_avctx[i]);
+ av_packet_free(&s->packet);
+ av_frame_free(&s->frame);
+
+ return 0;
+}
+
+const FFCodec ff_ftr_decoder = {
+ .p.name = "ftr",
+ .p.long_name = NULL_IF_CONFIG_SMALL("FTR Voice"),
+ .p.type = AVMEDIA_TYPE_AUDIO,
+ .p.id = AV_CODEC_ID_FTR,
+ .init = ftr_init,
+ FF_CODEC_DECODE_CB(ftr_decode_frame),
+ .close = ftr_close,
+ .flush = ftr_flush,
+ .priv_data_size = sizeof(FTRContext),
+ .p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
+};
diff --git a/libavcodec/ftr_parser.c b/libavcodec/ftr_parser.c
new file mode 100644
index 000000000..05e6cfed9
--- /dev/null
+++ b/libavcodec/ftr_parser.c
@@ -0,0 +1,107 @@
+/*
+ * FTR parser
+ * Copyright (c) 2022 Paul B Mahol
+ *
+ * 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
+ * FTR parser
+ */
+
+#include "parser.h"
+#include "get_bits.h"
+#include "adts_header.h"
+#include "adts_parser.h"
+#include "mpeg4audio.h"
+
+typedef struct FTRParseContext {
+ ParseContext pc;
+ int skip;
+ int split;
+ int frame_index;
+} FTRParseContext;
+
+static int ftr_parse(AVCodecParserContext *s, AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ uint8_t tmp[8 + AV_INPUT_BUFFER_PADDING_SIZE];
+ FTRParseContext *ftr = s->priv_data;
+ uint64_t state = ftr->pc.state64;
+ int next = END_NOT_FOUND;
+ GetBitContext bits;
+ AACADTSHeaderInfo hdr;
+ int size;
+
+ *poutbuf_size = 0;
+ *poutbuf = NULL;
+
+ if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
+ next = buf_size;
+ } else {
+ for (int i = 0; i < buf_size; i++) {
+ if (ftr->skip > 0) {
+ ftr->skip--;
+ if (ftr->skip == 0 && ftr->split) {
+ ftr->split = 0;
+ next = i;
+ s->duration = 1024;
+ s->key_frame = 1;
+ break;
+ } else if (ftr->skip > 0) {
+ continue;
+ }
+ }
+
+ state = (state << 8) | buf[i];
+ AV_WB64(tmp, state);
+ init_get_bits(&bits, tmp + 8 - AV_AAC_ADTS_HEADER_SIZE,
+ AV_AAC_ADTS_HEADER_SIZE * 8);
+
+ if ((size = ff_adts_header_parse(&bits, &hdr)) > 0) {
+ ftr->skip = size - 6;
+ ftr->frame_index += ff_mpeg4audio_channels[hdr.chan_config];
+ if (ftr->frame_index >= avctx->ch_layout.nb_channels) {
+ ftr->frame_index = 0;
+ ftr->split = 1;
+ }
+ }
+ }
+
+ ftr->pc.state64 = state;
+
+ if (ff_combine_frame(&ftr->pc, next, &buf, &buf_size) < 0) {
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
+ }
+
+ *poutbuf = buf;
+ *poutbuf_size = buf_size;
+
+ return next;
+}
+
+const AVCodecParser ff_ftr_parser = {
+ .codec_ids = { AV_CODEC_ID_FTR },
+ .priv_data_size = sizeof(FTRParseContext),
+ .parser_parse = ftr_parse,
+ .parser_close = ff_parse_close,
+};
diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c
index 00964369c..32b966e8e 100644
--- a/libavcodec/g2meet.c
+++ b/libavcodec/g2meet.c
@@ -29,19 +29,17 @@
#include
#include "libavutil/imgutils.h"
-#include "libavutil/intreadwrite.h"
#include "libavutil/mem_internal.h"
#include "avcodec.h"
#include "blockdsp.h"
#include "bytestream.h"
#include "codec_internal.h"
+#include "decode.h"
#include "elsdec.h"
#include "get_bits.h"
#include "idctdsp.h"
-#include "internal.h"
#include "jpegtables.h"
-#include "mjpeg.h"
#include "mjpegdec.h"
#define EPIC_PIX_STACK_SIZE 1024
@@ -61,22 +59,23 @@ enum Compression {
COMPR_KEMPF_J_B,
};
+/* These tables are already permuted according to ff_zigzag_direct */
static const uint8_t luma_quant[64] = {
- 8, 6, 5, 8, 12, 20, 26, 31,
- 6, 6, 7, 10, 13, 29, 30, 28,
- 7, 7, 8, 12, 20, 29, 35, 28,
- 7, 9, 11, 15, 26, 44, 40, 31,
- 9, 11, 19, 28, 34, 55, 52, 39,
- 12, 18, 28, 32, 41, 52, 57, 46,
- 25, 32, 39, 44, 52, 61, 60, 51,
- 36, 46, 48, 49, 56, 50, 52, 50
+ 8, 6, 6, 7, 6, 5, 8, 7,
+ 7, 7, 9, 9, 8, 10, 12, 20,
+ 13, 12, 11, 11, 12, 25, 18, 19,
+ 15, 20, 29, 26, 31, 30, 29, 26,
+ 28, 28, 32, 36, 46, 39, 32, 34,
+ 44, 35, 28, 28, 40, 55, 41, 44,
+ 48, 49, 52, 52, 52, 31, 39, 57,
+ 61, 56, 50, 60, 46, 51, 52, 50,
};
static const uint8_t chroma_quant[64] = {
- 9, 9, 12, 24, 50, 50, 50, 50,
- 9, 11, 13, 33, 50, 50, 50, 50,
- 12, 13, 28, 50, 50, 50, 50, 50,
- 24, 33, 50, 50, 50, 50, 50, 50,
+ 9, 9, 9, 12, 11, 12, 24, 13,
+ 13, 24, 50, 33, 28, 33, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50,
@@ -122,7 +121,7 @@ typedef struct ePICContext {
typedef struct JPGContext {
BlockDSPContext bdsp;
IDCTDSPContext idsp;
- ScanTable scantable;
+ uint8_t permutated_scantable[64];
VLC dc_vlc[2], ac_vlc[2];
int prev_dc[3];
@@ -182,10 +181,10 @@ static av_cold int jpg_init(AVCodecContext *avctx, JPGContext *c)
if (ret)
return ret;
- ff_blockdsp_init(&c->bdsp, avctx);
+ ff_blockdsp_init(&c->bdsp);
ff_idctdsp_init(&c->idsp, avctx);
- ff_init_scantable(c->idsp.idct_permutation, &c->scantable,
- ff_zigzag_direct);
+ ff_permute_scantable(c->permutated_scantable, ff_zigzag_direct,
+ c->idsp.idct_permutation);
return 0;
}
@@ -252,8 +251,8 @@ static int jpg_decode_block(JPGContext *c, GetBitContext *gb,
int nbits = val;
val = get_xbits(gb, nbits);
- val *= qmat[ff_zigzag_direct[pos]];
- block[c->scantable.permutated[pos]] = val;
+ val *= qmat[pos];
+ block[c->permutated_scantable[pos]] = val;
}
}
return 0;
@@ -932,8 +931,8 @@ static int epic_jb_decode_tile(G2MContext *c, int tile_x, int tile_y,
if (ret) {
av_log(avctx, AV_LOG_ERROR,
- "ePIC: tile decoding failed, frame=%d, tile_x=%d, tile_y=%d\n",
- avctx->frame_number, tile_x, tile_y);
+ "ePIC: tile decoding failed, frame=%"PRId64", tile_x=%d, tile_y=%d\n",
+ avctx->frame_num, tile_x, tile_y);
return AVERROR_INVALIDDATA;
}
@@ -1624,7 +1623,7 @@ static av_cold int g2m_decode_end(AVCodecContext *avctx)
const FFCodec ff_g2m_decoder = {
.p.name = "g2m",
- .p.long_name = NULL_IF_CONFIG_SMALL("Go2Meeting"),
+ CODEC_LONG_NAME("Go2Meeting"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_G2M,
.priv_data_size = sizeof(G2MContext),
@@ -1632,5 +1631,5 @@ const FFCodec ff_g2m_decoder = {
.close = g2m_decode_end,
FF_CODEC_DECODE_CB(g2m_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c
index 8a02ec523..231f1d32e 100644
--- a/libavcodec/g722dec.c
+++ b/libavcodec/g722dec.c
@@ -38,9 +38,9 @@
#include "libavutil/opt.h"
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
#include "g722.h"
-#include "internal.h"
#define OFFSET(x) offsetof(G722Context, x)
#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
@@ -141,7 +141,7 @@ static int g722_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_adpcm_g722_decoder = {
.p.name = "g722",
- .p.long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"),
+ CODEC_LONG_NAME("G.722 ADPCM"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ADPCM_G722,
.priv_data_size = sizeof(G722Context),
@@ -149,5 +149,4 @@ const FFCodec ff_adpcm_g722_decoder = {
FF_CODEC_DECODE_CB(g722_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
.p.priv_class = &g722_decoder_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/g722enc.c b/libavcodec/g722enc.c
index 325c3927d..47811cee4 100644
--- a/libavcodec/g722enc.c
+++ b/libavcodec/g722enc.c
@@ -32,7 +32,6 @@
#include "avcodec.h"
#include "codec_internal.h"
#include "encode.h"
-#include "internal.h"
#include "g722.h"
#include "libavutil/common.h"
@@ -373,20 +372,19 @@ static int g722_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
const FFCodec ff_adpcm_g722_encoder = {
.p.name = "g722",
- .p.long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"),
+ CODEC_LONG_NAME("G.722 ADPCM"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ADPCM_G722,
- .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(G722Context),
.init = g722_encode_init,
.close = g722_encode_close,
FF_CODEC_ENCODE_CB(g722_encode_frame),
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = (const uint64_t[]){ AV_CH_LAYOUT_MONO, 0 },
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS(AV_CH_LAYOUT_MONO)
.p.ch_layouts = (const AVChannelLayout[]){
AV_CHANNEL_LAYOUT_MONO, { 0 }
},
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/g723_1dec.c b/libavcodec/g723_1dec.c
index d095f09fe..55e20de5b 100644
--- a/libavcodec/g723_1dec.c
+++ b/libavcodec/g723_1dec.c
@@ -33,10 +33,9 @@
#include "acelp_vectors.h"
#include "avcodec.h"
#include "celp_filters.h"
-#include "celp_math.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
#include "g723_1.h"
#define CNG_RANDOM_SEED 12345
@@ -1113,7 +1112,7 @@ static const AVClass g723_1dec_class = {
const FFCodec ff_g723_1_decoder = {
.p.name = "g723_1",
- .p.long_name = NULL_IF_CONFIG_SMALL("G.723.1"),
+ CODEC_LONG_NAME("G.723.1"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_G723_1,
.priv_data_size = sizeof(G723_1_Context),
@@ -1121,5 +1120,4 @@ const FFCodec ff_g723_1_decoder = {
FF_CODEC_DECODE_CB(g723_1_decode_frame),
.p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
.p.priv_class = &g723_1dec_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/g723_1enc.c b/libavcodec/g723_1enc.c
index e8fb8429c..be8015313 100644
--- a/libavcodec/g723_1enc.c
+++ b/libavcodec/g723_1enc.c
@@ -126,7 +126,7 @@ static void highpass_filter(int16_t *buf, int16_t *fir, int *iir)
{
int i;
for (i = 0; i < FRAME_LEN; i++) {
- *iir = (buf[i] << 15) + ((-*fir) << 15) + MULL2(*iir, 0x7f00);
+ *iir = (buf[i] - *fir) * (1 << 15) + MULL2(*iir, 0x7f00);
*fir = buf[i];
buf[i] = av_clipl_int32((int64_t)*iir + (1 << 15)) >> 16;
}
@@ -166,7 +166,7 @@ static void comp_autocorr(int16_t *buf, int16_t *autocorr)
} else {
for (i = 1; i <= LPC_ORDER; i++) {
temp = ff_dot_product(vector, vector + i, LPC_FRAME - i);
- temp = MULL2((temp << scale), binomial_window[i - 1]);
+ temp = MULL2(temp * (1 << scale), binomial_window[i - 1]);
autocorr[i] = av_clipl_int32((int64_t) temp + (1 << 15)) >> 16;
}
}
@@ -193,15 +193,14 @@ static void levinson_durbin(int16_t *lpc, int16_t *autocorr, int16_t error)
temp = 0;
for (j = 0; j < i; j++)
temp -= lpc[j] * autocorr[i - j - 1];
- temp = ((autocorr[i] << 13) + temp) << 3;
+ temp = (autocorr[i] * (1 << 13) + temp) * (1 << 3);
if (FFABS(temp) >= (error << 16))
break;
partial_corr = temp / (error << 1);
- lpc[i] = av_clipl_int32((int64_t) (partial_corr << 14) +
- (1 << 15)) >> 16;
+ lpc[i] = (partial_corr + (1 << 1)) >> 2;
/* Update the prediction error */
temp = MULL2(temp, partial_corr);
@@ -210,8 +209,8 @@ static void levinson_durbin(int16_t *lpc, int16_t *autocorr, int16_t error)
memcpy(vector, lpc, i * sizeof(int16_t));
for (j = 0; j < i; j++) {
- temp = partial_corr * vector[i - j - 1] << 1;
- lpc[j] = av_clipl_int32((int64_t) (lpc[j] << 16) - temp +
+ temp = partial_corr * vector[i - j - 1] * 2;
+ lpc[j] = av_clipl_int32((int64_t) (lpc[j] * (1 << 16)) - temp +
(1 << 15)) >> 16;
}
}
@@ -260,9 +259,9 @@ static void lpc2lsp(int16_t *lpc, int16_t *prev_lsp, int16_t *lsp)
/* Compute the remaining coefficients */
for (i = 0; i < LPC_ORDER / 2; i++) {
/* f1 */
- f[2 * i + 2] = -f[2 * i] - ((lsp[i] + lsp[LPC_ORDER - 1 - i]) << 12);
+ f[2 * i + 2] = -f[2 * i] - (lsp[i] + lsp[LPC_ORDER - 1 - i]) * (1 << 12);
/* f2 */
- f[2 * i + 3] = f[2 * i + 1] - ((lsp[i] - lsp[LPC_ORDER - 1 - i]) << 12);
+ f[2 * i + 3] = f[2 * i + 1] - (lsp[i] - lsp[LPC_ORDER - 1 - i]) * (1 << 12);
}
/* Divide f1[5] and f2[5] by 2 for use in polynomial evaluation */
@@ -277,7 +276,7 @@ static void lpc2lsp(int16_t *lpc, int16_t *prev_lsp, int16_t *lsp)
shift = ff_g723_1_normalize_bits(max, 31);
for (i = 0; i < LPC_ORDER + 2; i++)
- f[i] = av_clipl_int32((int64_t) (f[i] << shift) + (1 << 15)) >> 16;
+ f[i] = av_clipl_int32((int64_t) (f[i] * (1 << shift)) + (1 << 15)) >> 16;
/**
* Evaluate F1 and F2 at uniform intervals of pi/256 along the
@@ -294,7 +293,7 @@ static void lpc2lsp(int16_t *lpc, int16_t *prev_lsp, int16_t *lsp)
temp = 0;
for (j = 0; j <= LPC_ORDER / 2; j++)
temp += f[LPC_ORDER - 2 * j + p] * ff_g723_1_cos_tab[i * j % COS_TBL_SIZE];
- cur_val = av_clipl_int32(temp << 1);
+ cur_val = av_clipl_int32(temp * 2);
/* Check for sign change, indicating a zero crossing */
if ((cur_val ^ prev_val) < 0) {
@@ -318,7 +317,7 @@ static void lpc2lsp(int16_t *lpc, int16_t *prev_lsp, int16_t *lsp)
for (j = 0; j <= LPC_ORDER / 2; j++)
temp += f[LPC_ORDER - 2 * j + p] *
ff_g723_1_cos_tab[i * j % COS_TBL_SIZE];
- cur_val = av_clipl_int32(temp << 1);
+ cur_val = av_clipl_int32(temp * 2);
}
prev_val = cur_val;
}
@@ -345,7 +344,7 @@ static void lpc2lsp(int16_t *lpc, int16_t *prev_lsp, int16_t *lsp)
temp[j] = (weight[j + (offset)] * ff_g723_1_lsp_band##num[i][j] + \
(1 << 14)) >> 15; \
} \
- error = ff_g723_1_dot_product(lsp + (offset), temp, size) << 1; \
+ error = ff_g723_1_dot_product(lsp + (offset), temp, size) * 2; \
error -= ff_g723_1_dot_product(ff_g723_1_lsp_band##num[i], temp, size); \
if (error > max) { \
max = error; \
@@ -420,7 +419,7 @@ static void iir_filter(int16_t *fir_coef, int16_t *iir_coef,
iir_coef[n - 1] * dest[m - n];
}
- dest[m] = av_clipl_int32((src[m] << 16) + (filter << 3) +
+ dest[m] = av_clipl_int32(src[m] * (1 << 16) + filter * (1 << 3) +
(1 << 15)) >> 16;
}
}
@@ -560,7 +559,7 @@ static void comp_harmonic_coeff(int16_t *buf, int16_t pitch_lag, HFParam *hf)
exp = ff_g723_1_normalize_bits(max, 31);
for (i = 0; i < 15; i++) {
- energy[i] = av_clipl_int32((int64_t)(energy[i] << exp) +
+ energy[i] = av_clipl_int32((int64_t)(energy[i] * (1 << exp)) +
(1 << 15)) >> 16;
}
@@ -614,8 +613,8 @@ static void harmonic_filter(HFParam *hf, const int16_t *src, int16_t *dest)
int i;
for (i = 0; i < SUBFRAME_LEN; i++) {
- int64_t temp = hf->gain * src[i - hf->index] << 1;
- dest[i] = av_clipl_int32((src[i] << 16) - temp + (1 << 15)) >> 16;
+ int64_t temp = hf->gain * src[i - hf->index] * 2;
+ dest[i] = av_clipl_int32(src[i] * (1 << 16) - temp + (1 << 15)) >> 16;
}
}
@@ -623,8 +622,8 @@ static void harmonic_noise_sub(HFParam *hf, const int16_t *src, int16_t *dest)
{
int i;
for (i = 0; i < SUBFRAME_LEN; i++) {
- int64_t temp = hf->gain * src[i - hf->index] << 1;
- dest[i] = av_clipl_int32(((dest[i] - src[i]) << 16) + temp +
+ int64_t temp = hf->gain * src[i - hf->index] * 2;
+ dest[i] = av_clipl_int32((dest[i] - src[i]) * (1 << 16) + temp +
(1 << 15)) >> 16;
}
}
@@ -656,7 +655,7 @@ static void synth_percept_filter(int16_t *qnt_lpc, int16_t *perf_lpc,
for (j = 1; j <= LPC_ORDER; j++)
temp -= qnt_lpc[j - 1] * bptr_16[i - j];
- buf[i] = (src[i] << 15) + (temp << 3);
+ buf[i] = src[i] * (1 << 15) + temp * (1 << 3);
bptr_16[i] = av_clipl_int32(buf[i] + (1 << 15)) >> 16;
}
@@ -666,7 +665,7 @@ static void synth_percept_filter(int16_t *qnt_lpc, int16_t *perf_lpc,
fir -= perf_lpc[j - 1] * bptr_16[i - j];
iir += perf_lpc[j + LPC_ORDER - 1] * dest[i - j];
}
- dest[i] = av_clipl_int32(((buf[i] + (fir << 3)) << scale) + (iir << 3) +
+ dest[i] = av_clipl_int32((buf[i] + fir * (1 << 3)) * (1 << scale) + iir * (1 << 3) +
(1 << 15)) >> 16;
}
memcpy(perf_fir, buf_16 + SUBFRAME_LEN, sizeof(int16_t) * LPC_ORDER);
@@ -715,23 +714,22 @@ static void acb_search(G723_1_ChannelContext *p, int16_t *residual,
temp = 0;
for (k = 0; k <= j; k++)
temp += residual[PITCH_ORDER - 1 + k] * impulse_resp[j - k];
- flt_buf[PITCH_ORDER - 1][j] = av_clipl_int32((temp << 1) +
- (1 << 15)) >> 16;
+ flt_buf[PITCH_ORDER - 1][j] = av_clipl_int32(temp * 2 + (1 << 15)) >> 16;
}
for (j = PITCH_ORDER - 2; j >= 0; j--) {
- flt_buf[j][0] = ((residual[j] << 13) + (1 << 14)) >> 15;
+ flt_buf[j][0] = (residual[j] + (1 << 1)) >> 2;
for (k = 1; k < SUBFRAME_LEN; k++) {
- temp = (flt_buf[j + 1][k - 1] << 15) +
+ temp = flt_buf[j + 1][k - 1] * (1 << 15) +
residual[j] * impulse_resp[k];
- flt_buf[j][k] = av_clipl_int32((temp << 1) + (1 << 15)) >> 16;
+ flt_buf[j][k] = av_clipl_int32(temp * 2 + (1 << 15)) >> 16;
}
}
/* Compute crosscorrelation with the signal */
for (j = 0; j < PITCH_ORDER; j++) {
temp = ff_dot_product(buf, flt_buf[j], SUBFRAME_LEN);
- ccr_buf[count++] = av_clipl_int32(temp << 1);
+ ccr_buf[count++] = av_clipl_int32(temp * 2);
}
/* Compute energies */
@@ -743,7 +741,7 @@ static void acb_search(G723_1_ChannelContext *p, int16_t *residual,
for (j = 1; j < PITCH_ORDER; j++) {
for (k = 0; k < j; k++) {
temp = ff_dot_product(flt_buf[j], flt_buf[k], SUBFRAME_LEN);
- ccr_buf[count++] = av_clipl_int32(temp << 2);
+ ccr_buf[count++] = av_clipl_int32(temp * (1 << 2));
}
}
}
@@ -756,7 +754,7 @@ static void acb_search(G723_1_ChannelContext *p, int16_t *residual,
temp = ff_g723_1_normalize_bits(max, 31);
for (i = 0; i < 20 * iter; i++)
- ccr_buf[i] = av_clipl_int32((int64_t) (ccr_buf[i] << temp) +
+ ccr_buf[i] = av_clipl_int32((int64_t) (ccr_buf[i] * (1 << temp)) +
(1 << 15)) >> 16;
max = 0;
@@ -804,11 +802,11 @@ static void sub_acb_contrib(const int16_t *residual, const int16_t *impulse_resp
int i, j;
/* Subtract adaptive CB contribution to obtain the residual */
for (i = 0; i < SUBFRAME_LEN; i++) {
- int64_t temp = buf[i] << 14;
+ int64_t temp = buf[i] * (1 << 14);
for (j = 0; j <= i; j++)
temp -= residual[j] * impulse_resp[i - j];
- buf[i] = av_clipl_int32((temp << 2) + (1 << 15)) >> 16;
+ buf[i] = av_clipl_int32(temp * (1 << 2) + (1 << 15)) >> 16;
}
}
@@ -852,7 +850,7 @@ static void get_fcb_param(FCBParam *optim, int16_t *impulse_resp,
for (i = 1; i < SUBFRAME_LEN; i++) {
temp = ff_g723_1_dot_product(temp_corr + i, temp_corr,
SUBFRAME_LEN - i);
- impulse_corr[i] = av_clipl_int32((temp << scale) + (1 << 15)) >> 16;
+ impulse_corr[i] = av_clipl_int32(temp * (1 << scale) + (1 << 15)) >> 16;
}
/* Compute crosscorrelation of impulse response with residual signal */
@@ -862,7 +860,7 @@ static void get_fcb_param(FCBParam *optim, int16_t *impulse_resp,
if (scale < 0)
ccr1[i] = temp >> -scale;
else
- ccr1[i] = av_clipl_int32(temp << scale);
+ ccr1[i] = av_clipl_int32(temp * (1 << scale));
}
/* Search loop */
@@ -911,7 +909,7 @@ static void get_fcb_param(FCBParam *optim, int16_t *impulse_resp,
continue;
temp = impulse_corr[FFABS(l - param.pulse_pos[k - 1])];
temp = av_clipl_int32((int64_t) temp *
- param.pulse_sign[k - 1] << 1);
+ param.pulse_sign[k - 1] * 2);
ccr2[l] -= temp;
temp = FFABS(ccr2[l]);
if (temp > max) {
@@ -935,17 +933,17 @@ static void get_fcb_param(FCBParam *optim, int16_t *impulse_resp,
temp = 0;
for (l = 0; l <= k; l++) {
int prod = av_clipl_int32((int64_t) temp_corr[l] *
- impulse_r[k - l] << 1);
+ impulse_r[k - l] * 2);
temp = av_clipl_int32(temp + prod);
}
- temp_corr[k] = temp << 2 >> 16;
+ temp_corr[k] = temp >> 14;
}
/* Compute square of error */
err = 0;
for (k = 0; k < SUBFRAME_LEN; k++) {
int64_t prod;
- prod = av_clipl_int32((int64_t) buf[k] * temp_corr[k] << 1);
+ prod = av_clipl_int32((int64_t) buf[k] * temp_corr[k] * 2);
err = av_clipl_int32(err - prod);
prod = av_clipl_int32((int64_t) temp_corr[k] * temp_corr[k]);
err = av_clipl_int32(err + prod);
@@ -1205,7 +1203,7 @@ static int g723_1_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
memmove(p->prev_excitation, p->prev_excitation + SUBFRAME_LEN,
sizeof(int16_t) * (PITCH_MAX - SUBFRAME_LEN));
for (j = 0; j < SUBFRAME_LEN; j++)
- in[j] = av_clip_int16((in[j] << 1) + impulse_resp[j]);
+ in[j] = av_clip_int16(in[j] * 2 + impulse_resp[j]);
memcpy(p->prev_excitation + PITCH_MAX - SUBFRAME_LEN, in,
sizeof(int16_t) * SUBFRAME_LEN);
@@ -1240,10 +1238,10 @@ static const FFCodecDefault defaults[] = {
const FFCodec ff_g723_1_encoder = {
.p.name = "g723_1",
- .p.long_name = NULL_IF_CONFIG_SMALL("G.723.1"),
+ CODEC_LONG_NAME("G.723.1"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_G723_1,
- .p.capabilities = AV_CODEC_CAP_DR1,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(G723_1_Context),
.init = g723_1_encode_init,
FF_CODEC_ENCODE_CB(g723_1_encode_frame),
@@ -1254,5 +1252,4 @@ const FFCodec ff_g723_1_encoder = {
.p.ch_layouts = (const AVChannelLayout[]){
AV_CHANNEL_LAYOUT_MONO, { 0 }
},
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/g726.c b/libavcodec/g726.c
index 3bf0da394..6c5638760 100644
--- a/libavcodec/g726.c
+++ b/libavcodec/g726.c
@@ -30,8 +30,8 @@
#include "libavutil/opt.h"
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "encode.h"
-#include "internal.h"
#include "get_bits.h"
#include "put_bits.h"
@@ -402,10 +402,11 @@ static const FFCodecDefault defaults[] = {
#if CONFIG_ADPCM_G726_ENCODER
const FFCodec ff_adpcm_g726_encoder = {
.p.name = "g726",
- .p.long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
+ CODEC_LONG_NAME("G.726 ADPCM"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ADPCM_G726,
- .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(G726Context),
.init = g726_encode_init,
FF_CODEC_ENCODE_CB(g726_encode_frame),
@@ -413,17 +414,17 @@ const FFCodec ff_adpcm_g726_encoder = {
AV_SAMPLE_FMT_NONE },
.p.priv_class = &g726_class,
.defaults = defaults,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
#if CONFIG_ADPCM_G726LE_ENCODER
const FFCodec ff_adpcm_g726le_encoder = {
.p.name = "g726le",
- .p.long_name = NULL_IF_CONFIG_SMALL("G.726 little endian ADPCM (\"right-justified\")"),
+ CODEC_LONG_NAME("G.726 little endian ADPCM (\"right-justified\")"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ADPCM_G726LE,
- .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(G726Context),
.init = g726_encode_init,
FF_CODEC_ENCODE_CB(g726_encode_frame),
@@ -431,7 +432,6 @@ const FFCodec ff_adpcm_g726le_encoder = {
AV_SAMPLE_FMT_NONE },
.p.priv_class = &g726_class,
.defaults = defaults,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
@@ -504,7 +504,7 @@ static void g726_decode_flush(AVCodecContext *avctx)
#if CONFIG_ADPCM_G726_DECODER
const FFCodec ff_adpcm_g726_decoder = {
.p.name = "g726",
- .p.long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
+ CODEC_LONG_NAME("G.726 ADPCM"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ADPCM_G726,
.priv_data_size = sizeof(G726Context),
@@ -512,7 +512,6 @@ const FFCodec ff_adpcm_g726_decoder = {
FF_CODEC_DECODE_CB(g726_decode_frame),
.flush = g726_decode_flush,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
@@ -526,7 +525,6 @@ const FFCodec ff_adpcm_g726le_decoder = {
FF_CODEC_DECODE_CB(g726_decode_frame),
.flush = g726_decode_flush,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
- .p.long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM little-endian"),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
+ CODEC_LONG_NAME("G.726 ADPCM little-endian"),
};
#endif
diff --git a/libavcodec/g729dec.c b/libavcodec/g729dec.c
index a306456f0..f783812cc 100644
--- a/libavcodec/g729dec.c
+++ b/libavcodec/g729dec.c
@@ -27,12 +27,11 @@
#include "get_bits.h"
#include "audiodsp.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "g729.h"
#include "lsp.h"
-#include "celp_math.h"
#include "celp_filters.h"
#include "acelp_filters.h"
#include "acelp_pitch_delay.h"
@@ -754,7 +753,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
const FFCodec ff_g729_decoder = {
.p.name = "g729",
- .p.long_name = NULL_IF_CONFIG_SMALL("G.729"),
+ CODEC_LONG_NAME("G.729"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_G729,
.priv_data_size = sizeof(G729Context),
@@ -762,12 +761,11 @@ const FFCodec ff_g729_decoder = {
FF_CODEC_DECODE_CB(decode_frame),
.close = decode_close,
.p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
const FFCodec ff_acelp_kelvin_decoder = {
.p.name = "acelp.kelvin",
- .p.long_name = NULL_IF_CONFIG_SMALL("Sipro ACELP.KELVIN"),
+ CODEC_LONG_NAME("Sipro ACELP.KELVIN"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ACELP_KELVIN,
.priv_data_size = sizeof(G729Context),
@@ -775,5 +773,4 @@ const FFCodec ff_acelp_kelvin_decoder = {
FF_CODEC_DECODE_CB(decode_frame),
.close = decode_close,
.p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/gdv.c b/libavcodec/gdv.c
index 70c2ad4bd..e114f3e80 100644
--- a/libavcodec/gdv.c
+++ b/libavcodec/gdv.c
@@ -25,7 +25,6 @@
#include "bytestream.h"
#include "codec_internal.h"
#include "decode.h"
-#include "internal.h"
typedef struct GDVContext {
AVCodecContext *avctx;
@@ -562,7 +561,7 @@ static av_cold int gdv_decode_close(AVCodecContext *avctx)
const FFCodec ff_gdv_decoder = {
.p.name = "gdv",
- .p.long_name = NULL_IF_CONFIG_SMALL("Gremlin Digital Video"),
+ CODEC_LONG_NAME("Gremlin Digital Video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_GDV,
.priv_data_size = sizeof(GDVContext),
@@ -570,5 +569,4 @@ const FFCodec ff_gdv_decoder = {
.close = gdv_decode_close,
FF_CODEC_DECODE_CB(gdv_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/gemdec.c b/libavcodec/gemdec.c
index 0d6acd530..c8fd8dcdc 100644
--- a/libavcodec/gemdec.c
+++ b/libavcodec/gemdec.c
@@ -27,7 +27,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
static const uint32_t gem_color_palette[16]={
0xFFFFFFFF, 0xFFFF0000, 0xFF00FF00, 0xFFFFFF00,
@@ -352,7 +352,7 @@ static av_cold int gem_close(AVCodecContext *avctx)
const FFCodec ff_gem_decoder = {
.p.name = "gem",
- .p.long_name = NULL_IF_CONFIG_SMALL("GEM Raster image"),
+ CODEC_LONG_NAME("GEM Raster image"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_GEM,
.p.capabilities = AV_CODEC_CAP_DR1,
diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h
index 992765dc9..65dc080dd 100644
--- a/libavcodec/get_bits.h
+++ b/libavcodec/get_bits.h
@@ -1,6 +1,5 @@
/*
* Copyright (c) 2004 Michael Niedermayer
- * Copyright (c) 2016 Alexandra Hájková
*
* This file is part of FFmpeg.
*
@@ -58,12 +57,55 @@
#define CACHED_BITSTREAM_READER 0
#endif
+#if CACHED_BITSTREAM_READER
+
+// we always want the LE implementation, to provide get_bits_le()
+#define BITSTREAM_LE
+
+#ifndef BITSTREAM_READER_LE
+# define BITSTREAM_BE
+# define BITSTREAM_DEFAULT_BE
+#endif
+
+#include "bitstream.h"
+
+#undef BITSTREAM_LE
+#undef BITSTREAM_BE
+#undef BITSTREAM_DEFAULT_BE
+
+typedef BitstreamContext GetBitContext;
+
+#define get_bits_count bits_tell
+#define get_bits_left bits_left
+#define skip_bits_long bits_skip
+#define skip_bits bits_skip
+#define get_bits bits_read_nz
+#define get_bitsz bits_read
+#define get_bits_long bits_read
+#define get_bits1 bits_read_bit
+#define get_bits64 bits_read_64
+#define get_xbits bits_read_xbits
+#define get_sbits bits_read_signed_nz
+#define get_sbits_long bits_read_signed
+#define show_bits bits_peek
+#define show_bits_long bits_peek
+#define init_get_bits bits_init
+#define init_get_bits8 bits_init8
+#define align_get_bits bits_align
+#define get_vlc2 bits_read_vlc
+
+#define init_get_bits8_le(s, buffer, byte_size) bits_init8_le((BitstreamContextLE*)s, buffer, byte_size)
+#define get_bits_le(s, n) bits_read_le((BitstreamContextLE*)s, n)
+
+#define show_bits1(s) bits_peek(s, 1)
+#define skip_bits1(s) bits_skip(s, 1)
+
+#define skip_1stop_8data_bits bits_skip_1stop_8data
+
+#else // CACHED_BITSTREAM_READER
+
typedef struct GetBitContext {
const uint8_t *buffer, *buffer_end;
-#if CACHED_BITSTREAM_READER
- uint64_t cache;
- unsigned bits_left;
-#endif
int index;
int size_in_bits;
int size_in_bits_plus8;
@@ -120,16 +162,12 @@ static inline unsigned int show_bits(GetBitContext *s, int n);
* For examples see get_bits, show_bits, skip_bits, get_vlc.
*/
-#if CACHED_BITSTREAM_READER
-# define MIN_CACHE_BITS 64
-#elif defined LONG_BITSTREAM_READER
+#if defined LONG_BITSTREAM_READER
# define MIN_CACHE_BITS 32
#else
# define MIN_CACHE_BITS 25
#endif
-#if !CACHED_BITSTREAM_READER
-
#define OPEN_READER_NOSIZE(name, gb) \
unsigned int name ## _index = (gb)->index; \
unsigned int av_unused name ## _cache
@@ -214,73 +252,12 @@ static inline unsigned int show_bits(GetBitContext *s, int n);
#define GET_CACHE(name, gb) ((uint32_t) name ## _cache)
-#endif
static inline int get_bits_count(const GetBitContext *s)
{
-#if CACHED_BITSTREAM_READER
- return s->index - s->bits_left;
-#else
return s->index;
-#endif
}
-#if CACHED_BITSTREAM_READER
-static inline void refill_32(GetBitContext *s, int is_le)
-{
-#if !UNCHECKED_BITSTREAM_READER
- if (s->index >> 3 >= s->buffer_end - s->buffer)
- return;
-#endif
-
- if (is_le)
- s->cache = (uint64_t)AV_RL32(s->buffer + (s->index >> 3)) << s->bits_left | s->cache;
- else
- s->cache = s->cache | (uint64_t)AV_RB32(s->buffer + (s->index >> 3)) << (32 - s->bits_left);
- s->index += 32;
- s->bits_left += 32;
-}
-
-static inline void refill_64(GetBitContext *s, int is_le)
-{
-#if !UNCHECKED_BITSTREAM_READER
- if (s->index >> 3 >= s->buffer_end - s->buffer)
- return;
-#endif
-
- if (is_le)
- s->cache = AV_RL64(s->buffer + (s->index >> 3));
- else
- s->cache = AV_RB64(s->buffer + (s->index >> 3));
- s->index += 64;
- s->bits_left = 64;
-}
-
-static inline uint64_t get_val(GetBitContext *s, unsigned n, int is_le)
-{
- uint64_t ret;
- av_assert2(n>0 && n<=63);
- if (is_le) {
- ret = s->cache & ((UINT64_C(1) << n) - 1);
- s->cache >>= n;
- } else {
- ret = s->cache >> (64 - n);
- s->cache <<= n;
- }
- s->bits_left -= n;
- return ret;
-}
-
-static inline unsigned show_val(const GetBitContext *s, unsigned n)
-{
-#ifdef BITSTREAM_READER_LE
- return s->cache & ((UINT64_C(1) << n) - 1);
-#else
- return s->cache >> (64 - n);
-#endif
-}
-#endif
-
/**
* Skips the specified number of bits.
* @param n the number of bits to skip,
@@ -290,29 +267,13 @@ static inline unsigned show_val(const GetBitContext *s, unsigned n)
*/
static inline void skip_bits_long(GetBitContext *s, int n)
{
-#if CACHED_BITSTREAM_READER
- skip_bits(s, n);
-#else
#if UNCHECKED_BITSTREAM_READER
s->index += n;
#else
s->index += av_clip(n, -s->index, s->size_in_bits_plus8 - s->index);
#endif
-#endif
}
-#if CACHED_BITSTREAM_READER
-static inline void skip_remaining(GetBitContext *s, unsigned n)
-{
-#ifdef BITSTREAM_READER_LE
- s->cache >>= n;
-#else
- s->cache <<= n;
-#endif
- s->bits_left -= n;
-}
-#endif
-
/**
* Read MPEG-1 dc-style VLC (sign bit + mantissa with no MSB).
* if MSB not set it is negative
@@ -320,13 +281,6 @@ static inline void skip_remaining(GetBitContext *s, unsigned n)
*/
static inline int get_xbits(GetBitContext *s, int n)
{
-#if CACHED_BITSTREAM_READER
- int32_t cache = show_bits(s, 32);
- int sign = ~cache >> 31;
- skip_remaining(s, n);
-
- return ((((uint32_t)(sign ^ cache)) >> (32 - n)) ^ sign) - sign;
-#else
register int sign;
register int32_t cache;
OPEN_READER(re, s);
@@ -337,10 +291,8 @@ static inline int get_xbits(GetBitContext *s, int n)
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return (NEG_USR32(sign ^ cache, n) ^ sign) - sign;
-#endif
}
-#if !CACHED_BITSTREAM_READER
static inline int get_xbits_le(GetBitContext *s, int n)
{
register int sign;
@@ -354,22 +306,16 @@ static inline int get_xbits_le(GetBitContext *s, int n)
CLOSE_READER(re, s);
return (zero_extend(sign ^ cache, n) ^ sign) - sign;
}
-#endif
static inline int get_sbits(GetBitContext *s, int n)
{
register int tmp;
-#if CACHED_BITSTREAM_READER
- av_assert2(n>0 && n<=25);
- tmp = sign_extend(get_bits(s, n), n);
-#else
OPEN_READER(re, s);
av_assert2(n>0 && n<=25);
UPDATE_CACHE(re, s);
tmp = SHOW_SBITS(re, s, n);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
-#endif
return tmp;
}
@@ -379,32 +325,12 @@ static inline int get_sbits(GetBitContext *s, int n)
static inline unsigned int get_bits(GetBitContext *s, int n)
{
register unsigned int tmp;
-#if CACHED_BITSTREAM_READER
-
- av_assert2(n>0 && n<=32);
- if (n > s->bits_left) {
-#ifdef BITSTREAM_READER_LE
- refill_32(s, 1);
-#else
- refill_32(s, 0);
-#endif
- if (s->bits_left < 32)
- s->bits_left = n;
- }
-
-#ifdef BITSTREAM_READER_LE
- tmp = get_val(s, n, 1);
-#else
- tmp = get_val(s, n, 0);
-#endif
-#else
OPEN_READER(re, s);
av_assert2(n>0 && n<=25);
UPDATE_CACHE(re, s);
tmp = SHOW_UBITS(re, s, n);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
-#endif
av_assert2(tmp < UINT64_C(1) << n);
return tmp;
}
@@ -419,16 +345,6 @@ static av_always_inline int get_bitsz(GetBitContext *s, int n)
static inline unsigned int get_bits_le(GetBitContext *s, int n)
{
-#if CACHED_BITSTREAM_READER
- av_assert2(n>0 && n<=32);
- if (n > s->bits_left) {
- refill_32(s, 1);
- if (s->bits_left < 32)
- s->bits_left = n;
- }
-
- return get_val(s, n, 1);
-#else
register int tmp;
OPEN_READER(re, s);
av_assert2(n>0 && n<=25);
@@ -437,7 +353,6 @@ static inline unsigned int get_bits_le(GetBitContext *s, int n)
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return tmp;
-#endif
}
/**
@@ -446,71 +361,22 @@ static inline unsigned int get_bits_le(GetBitContext *s, int n)
static inline unsigned int show_bits(GetBitContext *s, int n)
{
register unsigned int tmp;
-#if CACHED_BITSTREAM_READER
- if (n > s->bits_left)
-#ifdef BITSTREAM_READER_LE
- refill_32(s, 1);
-#else
- refill_32(s, 0);
-#endif
-
- tmp = show_val(s, n);
-#else
OPEN_READER_NOSIZE(re, s);
av_assert2(n>0 && n<=25);
UPDATE_CACHE(re, s);
tmp = SHOW_UBITS(re, s, n);
-#endif
return tmp;
}
static inline void skip_bits(GetBitContext *s, int n)
{
-#if CACHED_BITSTREAM_READER
- if (n < s->bits_left)
- skip_remaining(s, n);
- else {
- n -= s->bits_left;
- s->cache = 0;
- s->bits_left = 0;
-
- if (n >= 64) {
- unsigned skip = (n / 8) * 8;
-
- n -= skip;
- s->index += skip;
- }
-#ifdef BITSTREAM_READER_LE
- refill_64(s, 1);
-#else
- refill_64(s, 0);
-#endif
- if (n)
- skip_remaining(s, n);
- }
-#else
OPEN_READER(re, s);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
-#endif
}
static inline unsigned int get_bits1(GetBitContext *s)
{
-#if CACHED_BITSTREAM_READER
- if (!s->bits_left)
-#ifdef BITSTREAM_READER_LE
- refill_64(s, 1);
-#else
- refill_64(s, 0);
-#endif
-
-#ifdef BITSTREAM_READER_LE
- return get_val(s, 1, 1);
-#else
- return get_val(s, 1, 0);
-#endif
-#else
unsigned int index = s->index;
uint8_t result = s->buffer[index >> 3];
#ifdef BITSTREAM_READER_LE
@@ -527,7 +393,6 @@ static inline unsigned int get_bits1(GetBitContext *s)
s->index = index;
return result;
-#endif
}
static inline unsigned int show_bits1(GetBitContext *s)
@@ -548,10 +413,6 @@ static inline unsigned int get_bits_long(GetBitContext *s, int n)
av_assert2(n>=0 && n<=32);
if (!n) {
return 0;
-#if CACHED_BITSTREAM_READER
- }
- return get_bits(s, n);
-#else
} else if (n <= MIN_CACHE_BITS) {
return get_bits(s, n);
} else {
@@ -563,7 +424,6 @@ static inline unsigned int get_bits_long(GetBitContext *s, int n)
return ret | get_bits(s, n - 16);
#endif
}
-#endif
}
/**
@@ -596,6 +456,18 @@ static inline int get_sbits_long(GetBitContext *s, int n)
return sign_extend(get_bits_long(s, n), n);
}
+/**
+ * Read 0-64 bits as a signed integer.
+ */
+static inline int64_t get_sbits64(GetBitContext *s, int n)
+{
+ // sign_extend(x, 0) is undefined
+ if (!n)
+ return 0;
+
+ return sign_extend64(get_bits64(s, n), n);
+}
+
/**
* Show 0-32 bits.
*/
@@ -609,8 +481,17 @@ static inline unsigned int show_bits_long(GetBitContext *s, int n)
}
}
-static inline int init_get_bits_xe(GetBitContext *s, const uint8_t *buffer,
- int bit_size, int is_le)
+
+/**
+ * Initialize GetBitContext.
+ * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes
+ * larger than the actual read bits because some optimized bitstream
+ * readers read 32 or 64 bit at once and could read over the end
+ * @param bit_size the size of the buffer in bits
+ * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
+ */
+static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer,
+ int bit_size)
{
int buffer_size;
int ret = 0;
@@ -629,33 +510,9 @@ static inline int init_get_bits_xe(GetBitContext *s, const uint8_t *buffer,
s->buffer_end = buffer + buffer_size;
s->index = 0;
-#if CACHED_BITSTREAM_READER
- s->cache = 0;
- s->bits_left = 0;
- refill_64(s, is_le);
-#endif
-
return ret;
}
-/**
- * Initialize GetBitContext.
- * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes
- * larger than the actual read bits because some optimized bitstream
- * readers read 32 or 64 bit at once and could read over the end
- * @param bit_size the size of the buffer in bits
- * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
- */
-static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer,
- int bit_size)
-{
-#ifdef BITSTREAM_READER_LE
- return init_get_bits_xe(s, buffer, bit_size, 1);
-#else
- return init_get_bits_xe(s, buffer, bit_size, 0);
-#endif
-}
-
/**
* Initialize GetBitContext.
* @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes
@@ -677,7 +534,7 @@ static inline int init_get_bits8_le(GetBitContext *s, const uint8_t *buffer,
{
if (byte_size > INT_MAX / 8 || byte_size < 0)
byte_size = -1;
- return init_get_bits_xe(s, buffer, byte_size * 8, 1);
+ return init_get_bits(s, buffer, byte_size * 8);
}
static inline const uint8_t *align_get_bits(GetBitContext *s)
@@ -762,19 +619,6 @@ static inline const uint8_t *align_get_bits(GetBitContext *s)
SKIP_BITS(name, gb, n); \
} while (0)
-/* Return the LUT element for the given bitstream configuration. */
-static inline int set_idx(GetBitContext *s, int code, int *n, int *nb_bits,
- const VLCElem *table)
-{
- unsigned idx;
-
- *nb_bits = -*n;
- idx = show_bits(s, *nb_bits) + code;
- *n = table[idx].len;
-
- return table[idx].sym;
-}
-
/**
* Parse a vlc code.
* @param bits is the number of bits which will be read at once, must be
@@ -787,24 +631,6 @@ static inline int set_idx(GetBitContext *s, int code, int *n, int *nb_bits,
static av_always_inline int get_vlc2(GetBitContext *s, const VLCElem *table,
int bits, int max_depth)
{
-#if CACHED_BITSTREAM_READER
- int nb_bits;
- unsigned idx = show_bits(s, bits);
- int code = table[idx].sym;
- int n = table[idx].len;
-
- if (max_depth > 1 && n < 0) {
- skip_remaining(s, bits);
- code = set_idx(s, code, &n, &nb_bits, table);
- if (max_depth > 2 && n < 0) {
- skip_remaining(s, nb_bits);
- code = set_idx(s, code, &n, &nb_bits, table);
- }
- }
- skip_remaining(s, n);
-
- return code;
-#else
int code;
OPEN_READER(re, s);
@@ -815,7 +641,6 @@ static av_always_inline int get_vlc2(GetBitContext *s, const VLCElem *table,
CLOSE_READER(re, s);
return code;
-#endif
}
static inline int decode012(GetBitContext *gb)
@@ -855,4 +680,6 @@ static inline int skip_1stop_8data_bits(GetBitContext *gb)
return 0;
}
+#endif // CACHED_BITSTREAM_READER
+
#endif /* AVCODEC_GET_BITS_H */
diff --git a/libavcodec/get_buffer.c b/libavcodec/get_buffer.c
index 3e45a0479..a04fd878d 100644
--- a/libavcodec/get_buffer.c
+++ b/libavcodec/get_buffer.c
@@ -246,7 +246,6 @@ fail:
static int video_get_buffer(AVCodecContext *s, AVFrame *pic)
{
FramePool *pool = (FramePool*)s->internal->pool->data;
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format);
int i;
if (pic->data[0] || pic->data[1] || pic->data[2] || pic->data[3]) {
@@ -254,13 +253,6 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic)
return -1;
}
- if (!desc) {
- av_log(s, AV_LOG_ERROR,
- "Unable to get pixel format descriptor for format %s\n",
- av_get_pix_fmt_name(pic->format));
- return AVERROR(EINVAL);
- }
-
memset(pic->data, 0, sizeof(pic->data));
pic->extended_data = pic->data;
diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index 8c52c865a..131af6198 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -30,9 +30,7 @@
* @see http://www.w3.org/Graphics/GIF/spec-gif89a.txt
*/
-#define BITSTREAM_WRITER_LE
#include "libavutil/opt.h"
-#include "libavutil/imgutils.h"
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
@@ -40,8 +38,6 @@
#include "lzw.h"
#include "gif.h"
-#include "put_bits.h"
-
#define DEFAULT_TRANSPARENCY_INDEX 0x1f
typedef struct GIFContext {
@@ -322,7 +318,7 @@ static int gif_image_write_image(AVCodecContext *avctx,
disposal = GCE_DISPOSAL_INPLACE;
}
- if (s->image || !avctx->frame_number) { /* GIF header */
+ if (s->image || !avctx->frame_num) { /* GIF header */
const uint32_t *global_palette = palette ? palette : s->palette;
const AVRational sar = avctx->sample_aspect_ratio;
int64_t aspect = 0;
@@ -508,13 +504,13 @@ static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
if (!s->image) {
av_frame_unref(s->last_frame);
- ret = av_frame_ref(s->last_frame, (AVFrame*)pict);
+ ret = av_frame_ref(s->last_frame, pict);
if (ret < 0)
return ret;
}
pkt->size = outbuf_ptr - pkt->data;
- if (s->image || !avctx->frame_number)
+ if (s->image || !avctx->frame_num)
pkt->flags |= AV_PKT_FLAG_KEY;
*got_packet = 1;
@@ -554,9 +550,10 @@ static const AVClass gif_class = {
const FFCodec ff_gif_encoder = {
.p.name = "gif",
- .p.long_name = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"),
+ CODEC_LONG_NAME("GIF (Graphics Interchange Format)"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_GIF,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(GIFContext),
.init = gif_encode_init,
FF_CODEC_ENCODE_CB(gif_encode_frame),
@@ -566,5 +563,5 @@ const FFCodec ff_gif_encoder = {
AV_PIX_FMT_GRAY8, AV_PIX_FMT_PAL8, AV_PIX_FMT_NONE
},
.p.priv_class = &gif_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c
index 3936de1cd..f47390c3b 100644
--- a/libavcodec/gifdec.c
+++ b/libavcodec/gifdec.c
@@ -21,12 +21,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "lzw.h"
#include "gif.h"
@@ -475,7 +474,7 @@ static int gif_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
s->frame->pts = avpkt->pts;
s->frame->pkt_dts = avpkt->dts;
- s->frame->pkt_duration = avpkt->duration;
+ s->frame->duration = avpkt->duration;
if (avpkt->size >= 6) {
s->keyframe = memcmp(avpkt->data, gif87a_sig, 6) == 0 ||
@@ -558,7 +557,7 @@ static const AVClass decoder_class = {
const FFCodec ff_gif_decoder = {
.p.name = "gif",
- .p.long_name = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"),
+ CODEC_LONG_NAME("GIF (Graphics Interchange Format)"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_GIF,
.priv_data_size = sizeof(GifState),
@@ -566,7 +565,6 @@ const FFCodec ff_gif_decoder = {
.close = gif_decode_close,
FF_CODEC_DECODE_CB(gif_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.priv_class = &decoder_class,
};
diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c
index e5b8d6f41..14e236434 100644
--- a/libavcodec/gsmdec.c
+++ b/libavcodec/gsmdec.c
@@ -29,8 +29,8 @@
#include "libavutil/channel_layout.h"
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
#include "msgsmdec.h"
#include "gsmdec_template.c"
@@ -115,7 +115,7 @@ static void gsm_flush(AVCodecContext *avctx)
#if CONFIG_GSM_DECODER
const FFCodec ff_gsm_decoder = {
.p.name = "gsm",
- .p.long_name = NULL_IF_CONFIG_SMALL("GSM"),
+ CODEC_LONG_NAME("GSM"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_GSM,
.priv_data_size = sizeof(GSMContext),
@@ -123,13 +123,12 @@ const FFCodec ff_gsm_decoder = {
FF_CODEC_DECODE_CB(gsm_decode_frame),
.flush = gsm_flush,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
#if CONFIG_GSM_MS_DECODER
const FFCodec ff_gsm_ms_decoder = {
.p.name = "gsm_ms",
- .p.long_name = NULL_IF_CONFIG_SMALL("GSM Microsoft variant"),
+ CODEC_LONG_NAME("GSM Microsoft variant"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_GSM_MS,
.priv_data_size = sizeof(GSMContext),
@@ -137,6 +136,5 @@ const FFCodec ff_gsm_ms_decoder = {
FF_CODEC_DECODE_CB(gsm_decode_frame),
.flush = gsm_flush,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
diff --git a/libavcodec/h261.c b/libavcodec/h261.c
index 7dfaee7dc..8e0e13459 100644
--- a/libavcodec/h261.c
+++ b/libavcodec/h261.c
@@ -30,9 +30,9 @@
#define IS_FIL(a) ((a) & MB_TYPE_H261_FIL)
-static void h261_loop_filter(uint8_t *src, int stride)
+static void h261_loop_filter(uint8_t *src, ptrdiff_t stride)
{
- int x, y, xy, yz;
+ int x, y;
int temp[64];
for (x = 0; x < 8; x++) {
@@ -41,8 +41,8 @@ static void h261_loop_filter(uint8_t *src, int stride)
}
for (y = 1; y < 7; y++) {
for (x = 0; x < 8; x++) {
- xy = y * stride + x;
- yz = y * 8 + x;
+ ptrdiff_t xy = y * stride + x;
+ ptrdiff_t yz = y * 8 + x;
temp[yz] = src[xy - stride] + 2 * src[xy] + src[xy + stride];
}
}
@@ -51,8 +51,8 @@ static void h261_loop_filter(uint8_t *src, int stride)
src[y * stride] = (temp[y * 8] + 2) >> 2;
src[y * stride + 7] = (temp[y * 8 + 7] + 2) >> 2;
for (x = 1; x < 7; x++) {
- xy = y * stride + x;
- yz = y * 8 + x;
+ ptrdiff_t xy = y * stride + x;
+ ptrdiff_t yz = y * 8 + x;
src[xy] = (temp[yz - 1] + 2 * temp[yz] + temp[yz + 1] + 8) >> 4;
}
}
@@ -61,8 +61,8 @@ static void h261_loop_filter(uint8_t *src, int stride)
void ff_h261_loop_filter(MpegEncContext *s)
{
H261Context *const h = s->private_ctx;
- const int linesize = s->linesize;
- const int uvlinesize = s->uvlinesize;
+ const ptrdiff_t linesize = s->linesize;
+ const ptrdiff_t uvlinesize = s->uvlinesize;
uint8_t *dest_y = s->dest[0];
uint8_t *dest_cb = s->dest[1];
uint8_t *dest_cr = s->dest[2];
diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index 169917276..849629396 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -29,12 +29,12 @@
#include "libavutil/thread.h"
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "mpeg_er.h"
#include "mpegutils.h"
#include "mpegvideo.h"
#include "mpegvideodec.h"
#include "h261.h"
-#include "internal.h"
#define H261_MBA_VLC_BITS 8
#define H261_MTYPE_VLC_BITS 6
@@ -101,6 +101,15 @@ static av_cold int h261_decode_init(AVCodecContext *avctx)
return 0;
}
+static inline void h261_init_dest(MpegEncContext *s)
+{
+ const unsigned block_size = 8 >> s->avctx->lowres;
+ ff_init_block_index(s);
+ s->dest[0] += 2 * block_size;
+ s->dest[1] += block_size;
+ s->dest[2] += block_size;
+}
+
/**
* Decode the group of blocks header or slice header.
* @return <0 if an error occurred
@@ -213,8 +222,7 @@ static int h261_decode_mb_skipped(H261DecContext *h, int mba1, int mba2)
s->mb_x = ((h->gob_number - 1) % 2) * 11 + i % 11;
s->mb_y = ((h->gob_number - 1) / 2) * 3 + i / 11;
xy = s->mb_x + s->mb_y * s->mb_stride;
- ff_init_block_index(s);
- ff_update_block_index(s);
+ h261_init_dest(s);
for (j = 0; j < 6; j++)
s->block_last_index[j] = -1;
@@ -399,8 +407,7 @@ static int h261_decode_mb(H261DecContext *h)
s->mb_x = ((h->gob_number - 1) % 2) * 11 + ((h->current_mba - 1) % 11);
s->mb_y = ((h->gob_number - 1) / 2) * 3 + ((h->current_mba - 1) / 11);
xy = s->mb_x + s->mb_y * s->mb_stride;
- ff_init_block_index(s);
- ff_update_block_index(s);
+ h261_init_dest(s);
// Read mtype
com->mtype = get_vlc2(&s->gb, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2);
@@ -603,7 +610,7 @@ static int h261_decode_frame(AVCodecContext *avctx, AVFrame *pict,
MpegEncContext *s = &h->s;
int ret;
- ff_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size);
+ ff_dlog(avctx, "*****frame %"PRId64" size=%d\n", avctx->frame_num, buf_size);
ff_dlog(avctx, "bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);
h->gob_start_code_skipped = 0;
@@ -682,7 +689,7 @@ static av_cold int h261_decode_end(AVCodecContext *avctx)
const FFCodec ff_h261_decoder = {
.p.name = "h261",
- .p.long_name = NULL_IF_CONFIG_SMALL("H.261"),
+ CODEC_LONG_NAME("H.261"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_H261,
.priv_data_size = sizeof(H261DecContext),
@@ -690,6 +697,5 @@ const FFCodec ff_h261_decoder = {
.close = h261_decode_end,
FF_CODEC_DECODE_CB(h261_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
.p.max_lowres = 3,
};
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index 007bb4aa3..438ebb63d 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -46,25 +46,16 @@ typedef struct H261EncContext {
H261Context common;
int gob_number;
+ enum {
+ H261_QCIF = 0,
+ H261_CIF = 1,
+ } format;
} H261EncContext;
-int ff_h261_get_picture_format(int width, int height)
-{
- // QCIF
- if (width == 176 && height == 144)
- return 0;
- // CIF
- else if (width == 352 && height == 288)
- return 1;
- // ERROR
- else
- return AVERROR(EINVAL);
-}
-
-void ff_h261_encode_picture_header(MpegEncContext *s, int picture_number)
+void ff_h261_encode_picture_header(MpegEncContext *s)
{
H261EncContext *const h = (H261EncContext *)s;
- int format, temp_ref;
+ int temp_ref;
align_put_bits(&s->pb);
@@ -81,18 +72,13 @@ void ff_h261_encode_picture_header(MpegEncContext *s, int picture_number)
put_bits(&s->pb, 1, 0); /* camera off */
put_bits(&s->pb, 1, s->pict_type == AV_PICTURE_TYPE_I); /* freeze picture release on/off */
- format = ff_h261_get_picture_format(s->width, s->height);
-
- put_bits(&s->pb, 1, format); /* 0 == QCIF, 1 == CIF */
+ put_bits(&s->pb, 1, h->format); /* 0 == QCIF, 1 == CIF */
put_bits(&s->pb, 1, 1); /* still image mode */
put_bits(&s->pb, 1, 1); /* reserved */
put_bits(&s->pb, 1, 0); /* no PEI */
- if (format == 0)
- h->gob_number = -1;
- else
- h->gob_number = 0;
+ h->gob_number = h->format - 1;
s->mb_skip_run = 0;
}
@@ -102,7 +88,7 @@ void ff_h261_encode_picture_header(MpegEncContext *s, int picture_number)
static void h261_encode_gob_header(MpegEncContext *s, int mb_line)
{
H261EncContext *const h = (H261EncContext *)s;
- if (ff_h261_get_picture_format(s->width, s->height) == 0) {
+ if (h->format == H261_QCIF) {
h->gob_number += 2; // QCIF
} else {
h->gob_number++; // CIF
@@ -118,6 +104,7 @@ static void h261_encode_gob_header(MpegEncContext *s, int mb_line)
void ff_h261_reorder_mb_index(MpegEncContext *s)
{
+ const H261EncContext *const h = (H261EncContext*)s;
int index = s->mb_x + s->mb_y * s->mb_width;
if (index % 11 == 0) {
@@ -129,7 +116,7 @@ void ff_h261_reorder_mb_index(MpegEncContext *s)
/* for CIF the GOB's are fragmented in the middle of a scanline
* that's why we need to adjust the x and y index of the macroblocks */
- if (ff_h261_get_picture_format(s->width, s->height) == 1) { // CIF
+ if (h->format == H261_CIF) {
s->mb_x = index % 11;
index /= 11;
s->mb_y = index % 3;
@@ -139,7 +126,7 @@ void ff_h261_reorder_mb_index(MpegEncContext *s)
s->mb_y += 3 * index;
ff_init_block_index(s);
- ff_update_block_index(s);
+ ff_update_block_index(s, 8, 0, 1);
}
}
@@ -382,11 +369,22 @@ static av_cold void h261_encode_init_static(void)
init_uni_h261_rl_tab(&ff_h261_rl_tcoeff, uni_h261_rl_len);
}
-av_cold void ff_h261_encode_init(MpegEncContext *s)
+av_cold int ff_h261_encode_init(MpegEncContext *s)
{
H261EncContext *const h = (H261EncContext*)s;
static AVOnce init_static_once = AV_ONCE_INIT;
+ if (s->width == 176 && s->height == 144) {
+ h->format = H261_QCIF;
+ } else if (s->width == 352 && s->height == 288) {
+ h->format = H261_CIF;
+ } else {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "The specified picture size of %dx%d is not valid for the "
+ "H.261 codec.\nValid sizes are 176x144, 352x288\n",
+ s->width, s->height);
+ return AVERROR(EINVAL);
+ }
s->private_ctx = &h->common;
s->min_qcoeff = -127;
@@ -398,11 +396,13 @@ av_cold void ff_h261_encode_init(MpegEncContext *s)
s->intra_ac_vlc_length = s->inter_ac_vlc_length = uni_h261_rl_len;
s->intra_ac_vlc_last_length = s->inter_ac_vlc_last_length = uni_h261_rl_len + 128*64;
ff_thread_once(&init_static_once, h261_encode_init_static);
+
+ return 0;
}
const FFCodec ff_h261_encoder = {
.p.name = "h261",
- .p.long_name = NULL_IF_CONFIG_SMALL("H.261"),
+ CODEC_LONG_NAME("H.261"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_H261,
.p.priv_class = &ff_mpv_enc_class,
@@ -410,7 +410,8 @@ const FFCodec ff_h261_encoder = {
.init = ff_mpv_encode_init,
FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
.close = ff_mpv_encode_end,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE },
+ .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
};
diff --git a/libavcodec/h261enc.h b/libavcodec/h261enc.h
index 0a01858be..d8fdcad7a 100644
--- a/libavcodec/h261enc.h
+++ b/libavcodec/h261enc.h
@@ -30,11 +30,10 @@
#include "mpegvideo.h"
-int ff_h261_get_picture_format(int width, int height);
void ff_h261_reorder_mb_index(MpegEncContext *s);
void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64],
int motion_x, int motion_y);
-void ff_h261_encode_picture_header(MpegEncContext *s, int picture_number);
-void ff_h261_encode_init(MpegEncContext *s);
+void ff_h261_encode_picture_header(MpegEncContext *s);
+int ff_h261_encode_init(MpegEncContext *s);
#endif
diff --git a/libavcodec/h263_parser.c b/libavcodec/h263_parser.c
index 7a742caa8..f70a79117 100644
--- a/libavcodec/h263_parser.c
+++ b/libavcodec/h263_parser.c
@@ -25,16 +25,9 @@
*/
#include "parser.h"
-#if FF_API_FLAG_TRUNCATED
-/* Nuke this header when removing FF_API_FLAG_TRUNCATED */
-#include "h263_parser.h"
-
-int ff_h263_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
-#else
static int h263_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
{
-#endif
int vop_found, i;
uint32_t state;
@@ -80,11 +73,7 @@ static int h263_parse(AVCodecParserContext *s,
if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
next = buf_size;
} else {
-#if FF_API_FLAG_TRUNCATED
- next= ff_h263_find_frame_end(pc, buf, buf_size);
-#else
next = h263_find_frame_end(pc, buf, buf_size);
-#endif
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
*poutbuf = NULL;
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index d411bae22..f4e7048a5 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -31,26 +31,20 @@
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "error_resilience.h"
#include "flvdec.h"
#include "h263.h"
#include "h263dec.h"
-#if FF_API_FLAG_TRUNCATED
-#include "h263_parser.h"
-#endif
#include "hwconfig.h"
-#include "internal.h"
#include "mpeg_er.h"
#include "mpeg4video.h"
#include "mpeg4videodec.h"
-#if FF_API_FLAG_TRUNCATED
-#include "mpeg4video_parser.h"
-#endif
+#include "mpeg4videodefs.h"
#include "mpegutils.h"
#include "mpegvideo.h"
#include "mpegvideodec.h"
#include "msmpeg4dec.h"
-#include "qpeldsp.h"
#include "thread.h"
#include "wmv2dec.h"
@@ -62,9 +56,6 @@ static enum AVPixelFormat h263_get_format(AVCodecContext *avctx)
return avctx->pix_fmt;
}
- if (avctx->codec->id == AV_CODEC_ID_MSS2)
- return AV_PIX_FMT_YUV420P;
-
if (CONFIG_GRAY && (avctx->flags & AV_CODEC_FLAG_GRAY)) {
if (avctx->color_range == AVCOL_RANGE_UNSPECIFIED)
avctx->color_range = AVCOL_RANGE_MPEG;
@@ -116,15 +107,6 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx)
s->h263_pred = 1;
s->msmpeg4_version = 5;
break;
- case AV_CODEC_ID_VC1:
- case AV_CODEC_ID_WMV3:
- case AV_CODEC_ID_VC1IMAGE:
- case AV_CODEC_ID_WMV3IMAGE:
- case AV_CODEC_ID_MSS2:
- s->h263_pred = 1;
- s->msmpeg4_version = 6;
- avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
- break;
case AV_CODEC_ID_H263I:
break;
case AV_CODEC_ID_FLV1:
@@ -151,7 +133,6 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx)
}
ff_h263dsp_init(&s->h263dsp);
- ff_qpeldsp_init(&s->qdsp);
ff_h263_decode_init_vlc();
return 0;
@@ -176,14 +157,6 @@ static int get_consumed_bytes(MpegEncContext *s, int buf_size)
/* We would have to scan through the whole buf to handle the weird
* reordering ... */
return buf_size;
-#if FF_API_FLAG_TRUNCATED
- } else if (s->avctx->flags & AV_CODEC_FLAG_TRUNCATED) {
- pos -= s->parse_context.last_index;
- // padding is not really read so this might be -1
- if (pos < 0)
- pos = 0;
- return pos;
-#endif
} else {
// avoid infinite loops (maybe not needed...)
if (pos == 0)
@@ -258,7 +231,8 @@ static int decode_slice(MpegEncContext *s)
for (; s->mb_x < s->mb_width; s->mb_x++) {
int ret;
- ff_update_block_index(s);
+ ff_update_block_index(s, s->avctx->bits_per_raw_sample,
+ s->avctx->lowres, s->chroma_x_shift);
if (s->resync_mb_x == s->mb_x && s->resync_mb_y + 1 == s->mb_y)
s->first_slice_line = 0;
@@ -442,34 +416,24 @@ int ff_h263_decode_frame(AVCodecContext *avctx, AVFrame *pict,
return ret;
s->next_picture_ptr = NULL;
+ *got_frame = 1;
+ } else if (s->skipped_last_frame && s->current_picture_ptr) {
+ /* Output the last picture we decoded again if the stream ended with
+ * an NVOP */
+ if ((ret = av_frame_ref(pict, s->current_picture_ptr->f)) < 0)
+ return ret;
+ /* Copy props from the last input packet. Otherwise, props from the last
+ * returned picture would be reused */
+ if ((ret = ff_decode_frame_props(avctx, pict)) < 0)
+ return ret;
+ s->current_picture_ptr = NULL;
+
*got_frame = 1;
}
return 0;
}
-#if FF_API_FLAG_TRUNCATED
- if (s->avctx->flags & AV_CODEC_FLAG_TRUNCATED) {
- int next;
-
- if (CONFIG_MPEG4_DECODER && s->codec_id == AV_CODEC_ID_MPEG4) {
- next = ff_mpeg4_find_frame_end(&s->parse_context, buf, buf_size);
- } else if (CONFIG_H263_DECODER && s->codec_id == AV_CODEC_ID_H263) {
- next = ff_h263_find_frame_end(&s->parse_context, buf, buf_size);
- } else if (CONFIG_H263P_DECODER && s->codec_id == AV_CODEC_ID_H263P) {
- next = ff_h263_find_frame_end(&s->parse_context, buf, buf_size);
- } else {
- av_log(s->avctx, AV_LOG_ERROR,
- "this codec does not support truncated bitstreams\n");
- return AVERROR(ENOSYS);
- }
-
- if (ff_combine_frame(&s->parse_context, next, (const uint8_t **)&buf,
- &buf_size) < 0)
- return buf_size;
- }
-#endif
-
retry:
if (s->divx_packed && s->bitstream_buffer_size) {
int i;
@@ -501,16 +465,18 @@ retry:
/* let's go :-) */
if (CONFIG_WMV2_DECODER && s->msmpeg4_version == 5) {
ret = ff_wmv2_decode_picture_header(s);
- } else if (CONFIG_MSMPEG4_DECODER && s->msmpeg4_version) {
+ } else if (CONFIG_MSMPEG4DEC && s->msmpeg4_version) {
ret = ff_msmpeg4_decode_picture_header(s);
} else if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4) {
- if (s->avctx->extradata_size && s->picture_number == 0) {
+ if (s->avctx->extradata_size && !s->extradata_parsed) {
GetBitContext gb;
if (init_get_bits8(&gb, s->avctx->extradata, s->avctx->extradata_size) >= 0 )
ff_mpeg4_decode_picture_header(avctx->priv_data, &gb, 1, 0);
+ s->extradata_parsed = 1;
}
ret = ff_mpeg4_decode_picture_header(avctx->priv_data, &s->gb, 0, 0);
+ s->skipped_last_frame = (ret == FRAME_SKIPPED);
} else if (CONFIG_H263I_DECODER && s->codec_id == AV_CODEC_ID_H263I) {
ret = ff_intel_h263_decode_picture_header(s);
} else if (CONFIG_FLV_DECODER && s->h263_flv) {
@@ -542,13 +508,6 @@ retry:
return ret;
}
- if (!s->current_picture_ptr || s->current_picture_ptr->f->data[0]) {
- int i = ff_find_unused_picture(s->avctx, s->picture, 0);
- if (i < 0)
- return i;
- s->current_picture_ptr = &s->picture[i];
- }
-
avctx->has_b_frames = !s->low_delay;
if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4) {
@@ -591,10 +550,6 @@ retry:
s->codec_id == AV_CODEC_ID_H263I)
s->gob_index = H263_GOB_HEIGHT(s->height);
- // for skipping the frame
- s->current_picture.f->pict_type = s->pict_type;
- s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I;
-
/* skip B-frames if we don't have reference frames */
if (!s->last_picture_ptr &&
(s->pict_type == AV_PICTURE_TYPE_B || s->droppable))
@@ -606,14 +561,6 @@ retry:
avctx->skip_frame >= AVDISCARD_ALL)
return get_consumed_bytes(s, buf_size);
- if ((!s->no_rounding) || s->pict_type == AV_PICTURE_TYPE_B) {
- s->me.qpel_put = s->qdsp.put_qpel_pixels_tab;
- s->me.qpel_avg = s->qdsp.avg_qpel_pixels_tab;
- } else {
- s->me.qpel_put = s->qdsp.put_no_rnd_qpel_pixels_tab;
- s->me.qpel_avg = s->qdsp.avg_qpel_pixels_tab;
- }
-
if ((ret = ff_mpv_frame_start(s, avctx)) < 0)
return ret;
@@ -667,7 +614,7 @@ retry:
if (s->msmpeg4_version && s->msmpeg4_version < 4 &&
s->pict_type == AV_PICTURE_TYPE_I)
- if (!CONFIG_MSMPEG4_DECODER ||
+ if (!CONFIG_MSMPEG4DEC ||
ff_msmpeg4_decode_ext_header(s, buf_size) < 0)
s->er.error_status_table[s->mb_num - 1] = ER_MB_ERROR;
@@ -758,7 +705,7 @@ static const AVCodecHWConfigInternal *const h263_hw_config_list[] = {
const FFCodec ff_h263_decoder = {
.p.name = "h263",
- .p.long_name = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"),
+ CODEC_LONG_NAME("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_H263,
.priv_data_size = sizeof(MpegEncContext),
@@ -766,12 +713,8 @@ const FFCodec ff_h263_decoder = {
.close = ff_h263_decode_end,
FF_CODEC_DECODE_CB(ff_h263_decode_frame),
.p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
-#if FF_API_FLAG_TRUNCATED
- AV_CODEC_CAP_TRUNCATED |
-#endif
AV_CODEC_CAP_DELAY,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
+ .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.flush = ff_mpeg_flush,
.p.max_lowres = 3,
.p.pix_fmts = ff_h263_hwaccel_pixfmt_list_420,
@@ -780,7 +723,7 @@ const FFCodec ff_h263_decoder = {
const FFCodec ff_h263p_decoder = {
.p.name = "h263p",
- .p.long_name = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"),
+ CODEC_LONG_NAME("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_H263P,
.priv_data_size = sizeof(MpegEncContext),
@@ -788,12 +731,8 @@ const FFCodec ff_h263p_decoder = {
.close = ff_h263_decode_end,
FF_CODEC_DECODE_CB(ff_h263_decode_frame),
.p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
-#if FF_API_FLAG_TRUNCATED
- AV_CODEC_CAP_TRUNCATED |
-#endif
AV_CODEC_CAP_DELAY,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
+ .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.flush = ff_mpeg_flush,
.p.max_lowres = 3,
.p.pix_fmts = ff_h263_hwaccel_pixfmt_list_420,
diff --git a/libavcodec/h263enc.h b/libavcodec/h263enc.h
index fff85a18f..e45475686 100644
--- a/libavcodec/h263enc.h
+++ b/libavcodec/h263enc.h
@@ -25,7 +25,7 @@
#include "mpegvideoenc.h"
void ff_h263_encode_init(MpegEncContext *s);
-void ff_h263_encode_picture_header(MpegEncContext *s, int picture_number);
+void ff_h263_encode_picture_header(MpegEncContext *s);
void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line);
void ff_h263_encode_mb(MpegEncContext *s,
int16_t block[6][64],
diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c
new file mode 100644
index 000000000..6e4a9a1af
--- /dev/null
+++ b/libavcodec/h2645_sei.c
@@ -0,0 +1,670 @@
+/*
+ * Common H.264 and HEVC Supplementary Enhancement Information messages
+ *
+ * Copyright (c) 2003 Michael Niedermayer
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ * Copyright (C) 2013 Vittorio Giovara
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config_components.h"
+
+#include "libavutil/ambient_viewing_environment.h"
+#include "libavutil/display.h"
+#include "libavutil/film_grain_params.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/stereo3d.h"
+
+#include "atsc_a53.h"
+#include "avcodec.h"
+#include "dynamic_hdr10_plus.h"
+#include "dynamic_hdr_vivid.h"
+#include "get_bits.h"
+#include "golomb.h"
+#include "h2645_sei.h"
+
+#define IS_H264(codec_id) (CONFIG_H264_SEI && CONFIG_HEVC_SEI ? codec_id == AV_CODEC_ID_H264 : CONFIG_H264_SEI)
+#define IS_HEVC(codec_id) (CONFIG_H264_SEI && CONFIG_HEVC_SEI ? codec_id == AV_CODEC_ID_HEVC : CONFIG_HEVC_SEI)
+
+#if CONFIG_HEVC_SEI
+static int decode_registered_user_data_dynamic_hdr_plus(HEVCSEIDynamicHDRPlus *s,
+ GetByteContext *gb)
+{
+ size_t meta_size;
+ int err;
+ AVDynamicHDRPlus *metadata = av_dynamic_hdr_plus_alloc(&meta_size);
+ if (!metadata)
+ return AVERROR(ENOMEM);
+
+ err = ff_parse_itu_t_t35_to_dynamic_hdr10_plus(metadata, gb->buffer,
+ bytestream2_get_bytes_left(gb));
+ if (err < 0) {
+ av_free(metadata);
+ return err;
+ }
+
+ av_buffer_unref(&s->info);
+ s->info = av_buffer_create((uint8_t *)metadata, meta_size, NULL, NULL, 0);
+ if (!s->info) {
+ av_free(metadata);
+ return AVERROR(ENOMEM);
+ }
+
+ return 0;
+}
+
+static int decode_registered_user_data_dynamic_hdr_vivid(HEVCSEIDynamicHDRVivid *s,
+ GetByteContext *gb)
+{
+ size_t meta_size;
+ int err;
+ AVDynamicHDRVivid *metadata = av_dynamic_hdr_vivid_alloc(&meta_size);
+ if (!metadata)
+ return AVERROR(ENOMEM);
+
+ err = ff_parse_itu_t_t35_to_dynamic_hdr_vivid(metadata,
+ gb->buffer, bytestream2_get_bytes_left(gb));
+ if (err < 0) {
+ av_free(metadata);
+ return err;
+ }
+
+ av_buffer_unref(&s->info);
+ s->info = av_buffer_create((uint8_t *)metadata, meta_size, NULL, NULL, 0);
+ if (!s->info) {
+ av_free(metadata);
+ return AVERROR(ENOMEM);
+ }
+
+ return 0;
+}
+#endif
+
+static int decode_registered_user_data_afd(H2645SEIAFD *h, GetByteContext *gb)
+{
+ int flag;
+
+ if (bytestream2_get_bytes_left(gb) <= 0)
+ return AVERROR_INVALIDDATA;
+
+ flag = !!(bytestream2_get_byteu(gb) & 0x40); // active_format_flag
+
+ if (flag) {
+ if (bytestream2_get_bytes_left(gb) <= 0)
+ return AVERROR_INVALIDDATA;
+ h->active_format_description = bytestream2_get_byteu(gb) & 0xF;
+ h->present = 1;
+ }
+
+ return 0;
+}
+
+static int decode_registered_user_data_closed_caption(H2645SEIA53Caption *h,
+ GetByteContext *gb)
+{
+ return ff_parse_a53_cc(&h->buf_ref, gb->buffer,
+ bytestream2_get_bytes_left(gb));
+}
+
+static int decode_registered_user_data(H2645SEI *h, GetByteContext *gb,
+ enum AVCodecID codec_id, void *logctx)
+{
+ int country_code, provider_code;
+
+ if (bytestream2_get_bytes_left(gb) < 3)
+ return AVERROR_INVALIDDATA;
+
+ country_code = bytestream2_get_byteu(gb); // itu_t_t35_country_code
+ if (country_code == 0xFF) {
+ if (bytestream2_get_bytes_left(gb) < 3)
+ return AVERROR_INVALIDDATA;
+
+ bytestream2_skipu(gb, 1); // itu_t_t35_country_code_extension_byte
+ }
+
+ if (country_code != 0xB5 && country_code != 0x26) { // usa_country_code and cn_country_code
+ av_log(logctx, AV_LOG_VERBOSE,
+ "Unsupported User Data Registered ITU-T T35 SEI message (country_code = %d)\n",
+ country_code);
+ return 0;
+ }
+
+ /* itu_t_t35_payload_byte follows */
+ provider_code = bytestream2_get_be16u(gb);
+
+ switch (provider_code) {
+ case 0x31: { // atsc_provider_code
+ uint32_t user_identifier;
+
+ if (bytestream2_get_bytes_left(gb) < 4)
+ return AVERROR_INVALIDDATA;
+
+ user_identifier = bytestream2_get_be32u(gb);
+ switch (user_identifier) {
+ case MKBETAG('D', 'T', 'G', '1'): // afd_data
+ return decode_registered_user_data_afd(&h->afd, gb);
+ case MKBETAG('G', 'A', '9', '4'): // closed captions
+ return decode_registered_user_data_closed_caption(&h->a53_caption, gb);
+ default:
+ av_log(logctx, AV_LOG_VERBOSE,
+ "Unsupported User Data Registered ITU-T T35 SEI message (atsc user_identifier = 0x%04x)\n",
+ user_identifier);
+ break;
+ }
+ break;
+ }
+#if CONFIG_HEVC_SEI
+ case 0x04: { // cuva_provider_code
+ const uint16_t cuva_provider_oriented_code = 0x0005;
+ uint16_t provider_oriented_code;
+
+ if (!IS_HEVC(codec_id))
+ goto unsupported_provider_code;
+
+ if (bytestream2_get_bytes_left(gb) < 2)
+ return AVERROR_INVALIDDATA;
+
+ provider_oriented_code = bytestream2_get_be16u(gb);
+ if (provider_oriented_code == cuva_provider_oriented_code) {
+ return decode_registered_user_data_dynamic_hdr_vivid(&h->dynamic_hdr_vivid, gb);
+ }
+ break;
+ }
+ case 0x3C: { // smpte_provider_code
+ // A/341 Amendment - 2094-40
+ const uint16_t smpte2094_40_provider_oriented_code = 0x0001;
+ const uint8_t smpte2094_40_application_identifier = 0x04;
+ uint16_t provider_oriented_code;
+ uint8_t application_identifier;
+
+ if (!IS_HEVC(codec_id))
+ goto unsupported_provider_code;
+
+ if (bytestream2_get_bytes_left(gb) < 3)
+ return AVERROR_INVALIDDATA;
+
+ provider_oriented_code = bytestream2_get_be16u(gb);
+ application_identifier = bytestream2_get_byteu(gb);
+ if (provider_oriented_code == smpte2094_40_provider_oriented_code &&
+ application_identifier == smpte2094_40_application_identifier) {
+ return decode_registered_user_data_dynamic_hdr_plus(&h->dynamic_hdr_plus, gb);
+ }
+ break;
+ }
+ unsupported_provider_code:
+#endif
+ default:
+ av_log(logctx, AV_LOG_VERBOSE,
+ "Unsupported User Data Registered ITU-T T35 SEI message (provider_code = %d)\n",
+ provider_code);
+ break;
+ }
+
+ return 0;
+}
+
+static int decode_unregistered_user_data(H2645SEIUnregistered *h,
+ GetByteContext *gb,
+ enum AVCodecID codec_id)
+{
+ uint8_t *user_data;
+ int size = bytestream2_get_bytes_left(gb);
+ AVBufferRef *buf_ref, **tmp;
+
+ if (size < 16 || size >= INT_MAX - 1)
+ return AVERROR_INVALIDDATA;
+
+ tmp = av_realloc_array(h->buf_ref, h->nb_buf_ref + 1, sizeof(*h->buf_ref));
+ if (!tmp)
+ return AVERROR(ENOMEM);
+ h->buf_ref = tmp;
+
+ buf_ref = av_buffer_alloc(size + 1);
+ if (!buf_ref)
+ return AVERROR(ENOMEM);
+ user_data = buf_ref->data;
+
+ bytestream2_get_bufferu(gb, user_data, size);
+ user_data[size] = 0;
+ buf_ref->size = size;
+ h->buf_ref[h->nb_buf_ref++] = buf_ref;
+
+ if (IS_H264(codec_id)) {
+ int e, build;
+ e = sscanf(user_data + 16, "x264 - core %d", &build);
+ if (e == 1 && build > 0)
+ h->x264_build = build;
+ if (e == 1 && build == 1 && !strncmp(user_data+16, "x264 - core 0000", 16))
+ h->x264_build = 67;
+ }
+
+ return 0;
+}
+
+static int decode_display_orientation(H2645SEIDisplayOrientation *h,
+ GetBitContext *gb)
+{
+ h->present = !get_bits1(gb); // display_orientation_cancel_flag
+
+ if (h->present) {
+ h->hflip = get_bits1(gb); // hor_flip
+ h->vflip = get_bits1(gb); // ver_flip
+
+ h->anticlockwise_rotation = get_bits(gb, 16);
+ // This is followed by display_orientation_repetition_period
+ // and display_orientation_extension_flag for H.264
+ // and by display_orientation_persistence_flag for HEVC.
+ }
+
+ return 0;
+}
+
+static int decode_frame_packing_arrangement(H2645SEIFramePacking *h,
+ GetBitContext *gb,
+ enum AVCodecID codec_id)
+{
+ h->arrangement_id = get_ue_golomb_long(gb);
+ h->arrangement_cancel_flag = get_bits1(gb);
+ h->present = !h->arrangement_cancel_flag;
+
+ if (h->present) {
+ h->arrangement_type = get_bits(gb, 7);
+ h->quincunx_sampling_flag = get_bits1(gb);
+ h->content_interpretation_type = get_bits(gb, 6);
+
+ // spatial_flipping_flag, frame0_flipped_flag, field_views_flag
+ skip_bits(gb, 3);
+ h->current_frame_is_frame0_flag = get_bits1(gb);
+ // frame0_self_contained_flag, frame1_self_contained_flag
+ skip_bits(gb, 2);
+
+ if (!h->quincunx_sampling_flag && h->arrangement_type != 5)
+ skip_bits(gb, 16); // frame[01]_grid_position_[xy]
+ skip_bits(gb, 8); // frame_packing_arrangement_reserved_byte
+ if (IS_H264(codec_id))
+ h->arrangement_repetition_period = get_ue_golomb_long(gb);
+ else
+ skip_bits1(gb); // frame_packing_arrangement_persistence_flag
+ }
+ // H.264: frame_packing_arrangement_extension_flag,
+ // HEVC: upsampled_aspect_ratio_flag
+ skip_bits1(gb);
+
+ return 0;
+}
+
+static int decode_alternative_transfer(H2645SEIAlternativeTransfer *s,
+ GetByteContext *gb)
+{
+ if (bytestream2_get_bytes_left(gb) < 1)
+ return AVERROR_INVALIDDATA;
+
+ s->present = 1;
+ s->preferred_transfer_characteristics = bytestream2_get_byteu(gb);
+
+ return 0;
+}
+
+static int decode_ambient_viewing_environment(H2645SEIAmbientViewingEnvironment *s,
+ GetByteContext *gb)
+{
+ static const uint16_t max_ambient_light_value = 50000;
+
+ if (bytestream2_get_bytes_left(gb) < 8)
+ return AVERROR_INVALIDDATA;
+
+ s->ambient_illuminance = bytestream2_get_be32u(gb);
+ if (!s->ambient_illuminance)
+ return AVERROR_INVALIDDATA;
+
+ s->ambient_light_x = bytestream2_get_be16u(gb);
+ if (s->ambient_light_x > max_ambient_light_value)
+ return AVERROR_INVALIDDATA;
+
+ s->ambient_light_y = bytestream2_get_be16u(gb);
+ if (s->ambient_light_y > max_ambient_light_value)
+ return AVERROR_INVALIDDATA;
+
+ s->present = 1;
+
+ return 0;
+}
+
+static int decode_film_grain_characteristics(H2645SEIFilmGrainCharacteristics *h,
+ enum AVCodecID codec_id, GetBitContext *gb)
+{
+ h->present = !get_bits1(gb); // film_grain_characteristics_cancel_flag
+
+ if (h->present) {
+ memset(h, 0, sizeof(*h));
+ h->model_id = get_bits(gb, 2);
+ h->separate_colour_description_present_flag = get_bits1(gb);
+ if (h->separate_colour_description_present_flag) {
+ h->bit_depth_luma = get_bits(gb, 3) + 8;
+ h->bit_depth_chroma = get_bits(gb, 3) + 8;
+ h->full_range = get_bits1(gb);
+ h->color_primaries = get_bits(gb, 8);
+ h->transfer_characteristics = get_bits(gb, 8);
+ h->matrix_coeffs = get_bits(gb, 8);
+ }
+ h->blending_mode_id = get_bits(gb, 2);
+ h->log2_scale_factor = get_bits(gb, 4);
+ for (int c = 0; c < 3; c++)
+ h->comp_model_present_flag[c] = get_bits1(gb);
+ for (int c = 0; c < 3; c++) {
+ if (h->comp_model_present_flag[c]) {
+ h->num_intensity_intervals[c] = get_bits(gb, 8) + 1;
+ h->num_model_values[c] = get_bits(gb, 3) + 1;
+ if (h->num_model_values[c] > 6)
+ return AVERROR_INVALIDDATA;
+ for (int i = 0; i < h->num_intensity_intervals[c]; i++) {
+ h->intensity_interval_lower_bound[c][i] = get_bits(gb, 8);
+ h->intensity_interval_upper_bound[c][i] = get_bits(gb, 8);
+ for (int j = 0; j < h->num_model_values[c]; j++)
+ h->comp_model_value[c][i][j] = get_se_golomb_long(gb);
+ }
+ }
+ }
+ if (IS_HEVC(codec_id))
+ h->persistence_flag = get_bits1(gb);
+ else
+ h->repetition_period = get_ue_golomb_long(gb);
+
+ h->present = 1;
+ }
+
+ return 0;
+}
+
+int ff_h2645_sei_message_decode(H2645SEI *h, enum SEIType type,
+ enum AVCodecID codec_id, GetBitContext *gb,
+ GetByteContext *gbyte, void *logctx)
+{
+ switch (type) {
+ case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35:
+ return decode_registered_user_data(h, gbyte, codec_id, logctx);
+ case SEI_TYPE_USER_DATA_UNREGISTERED:
+ return decode_unregistered_user_data(&h->unregistered, gbyte, codec_id);
+ case SEI_TYPE_DISPLAY_ORIENTATION:
+ return decode_display_orientation(&h->display_orientation, gb);
+ case SEI_TYPE_FILM_GRAIN_CHARACTERISTICS:
+ return decode_film_grain_characteristics(&h->film_grain_characteristics, codec_id, gb);
+ case SEI_TYPE_FRAME_PACKING_ARRANGEMENT:
+ return decode_frame_packing_arrangement(&h->frame_packing, gb, codec_id);
+ case SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS:
+ return decode_alternative_transfer(&h->alternative_transfer, gbyte);
+ case SEI_TYPE_AMBIENT_VIEWING_ENVIRONMENT:
+ return decode_ambient_viewing_environment(&h->ambient_viewing_environment,
+ gbyte);
+ default:
+ return FF_H2645_SEI_MESSAGE_UNHANDLED;
+ }
+}
+
+int ff_h2645_sei_ctx_replace(H2645SEI *dst, const H2645SEI *src)
+{
+ int ret = av_buffer_replace(&dst->a53_caption.buf_ref,
+ src->a53_caption.buf_ref);
+ if (ret < 0)
+ return ret;
+
+ for (unsigned i = 0; i < dst->unregistered.nb_buf_ref; i++)
+ av_buffer_unref(&dst->unregistered.buf_ref[i]);
+ dst->unregistered.nb_buf_ref = 0;
+
+ if (src->unregistered.nb_buf_ref) {
+ ret = av_reallocp_array(&dst->unregistered.buf_ref,
+ src->unregistered.nb_buf_ref,
+ sizeof(*dst->unregistered.buf_ref));
+ if (ret < 0)
+ return ret;
+
+ for (unsigned i = 0; i < src->unregistered.nb_buf_ref; i++) {
+ dst->unregistered.buf_ref[i] = av_buffer_ref(src->unregistered.buf_ref[i]);
+ if (!dst->unregistered.buf_ref[i])
+ return AVERROR(ENOMEM);
+ dst->unregistered.nb_buf_ref++;
+ }
+ }
+
+ return 0;
+}
+
+static int is_frame_packing_type_valid(SEIFpaType type, enum AVCodecID codec_id)
+{
+ if (IS_H264(codec_id))
+ return type <= SEI_FPA_H264_TYPE_2D &&
+ type >= SEI_FPA_H264_TYPE_CHECKERBOARD;
+ else
+ return type <= SEI_FPA_TYPE_INTERLEAVE_TEMPORAL &&
+ type >= SEI_FPA_TYPE_SIDE_BY_SIDE;
+}
+
+int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei,
+ enum AVCodecID codec_id,
+ AVCodecContext *avctx, const H2645VUI *vui,
+ unsigned bit_depth_luma, unsigned bit_depth_chroma,
+ int seed)
+{
+ H2645SEIFramePacking *fp = &sei->frame_packing;
+
+ if (fp->present &&
+ is_frame_packing_type_valid(fp->arrangement_type, codec_id) &&
+ fp->content_interpretation_type > 0 &&
+ fp->content_interpretation_type < 3) {
+ AVStereo3D *stereo = av_stereo3d_create_side_data(frame);
+
+ if (!stereo)
+ return AVERROR(ENOMEM);
+
+ switch (fp->arrangement_type) {
+#if CONFIG_H264_SEI
+ case SEI_FPA_H264_TYPE_CHECKERBOARD:
+ stereo->type = AV_STEREO3D_CHECKERBOARD;
+ break;
+ case SEI_FPA_H264_TYPE_INTERLEAVE_COLUMN:
+ stereo->type = AV_STEREO3D_COLUMNS;
+ break;
+ case SEI_FPA_H264_TYPE_INTERLEAVE_ROW:
+ stereo->type = AV_STEREO3D_LINES;
+ break;
+#endif
+ case SEI_FPA_TYPE_SIDE_BY_SIDE:
+ if (fp->quincunx_sampling_flag)
+ stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
+ else
+ stereo->type = AV_STEREO3D_SIDEBYSIDE;
+ break;
+ case SEI_FPA_TYPE_TOP_BOTTOM:
+ stereo->type = AV_STEREO3D_TOPBOTTOM;
+ break;
+ case SEI_FPA_TYPE_INTERLEAVE_TEMPORAL:
+ stereo->type = AV_STEREO3D_FRAMESEQUENCE;
+ break;
+#if CONFIG_H264_SEI
+ case SEI_FPA_H264_TYPE_2D:
+ stereo->type = AV_STEREO3D_2D;
+ break;
+#endif
+ }
+
+ if (fp->content_interpretation_type == 2)
+ stereo->flags = AV_STEREO3D_FLAG_INVERT;
+
+ if (fp->arrangement_type == SEI_FPA_TYPE_INTERLEAVE_TEMPORAL) {
+ if (fp->current_frame_is_frame0_flag)
+ stereo->view = AV_STEREO3D_VIEW_LEFT;
+ else
+ stereo->view = AV_STEREO3D_VIEW_RIGHT;
+ }
+ }
+
+ if (sei->display_orientation.present &&
+ (sei->display_orientation.anticlockwise_rotation ||
+ sei->display_orientation.hflip ||
+ sei->display_orientation.vflip)) {
+ H2645SEIDisplayOrientation *o = &sei->display_orientation;
+ double angle = o->anticlockwise_rotation * 360 / (double) (1 << 16);
+ AVFrameSideData *rotation = av_frame_new_side_data(frame,
+ AV_FRAME_DATA_DISPLAYMATRIX,
+ sizeof(int32_t) * 9);
+ if (!rotation)
+ return AVERROR(ENOMEM);
+
+ /* av_display_rotation_set() expects the angle in the clockwise
+ * direction, hence the first minus.
+ * The below code applies the flips after the rotation, yet
+ * the H.2645 specs require flipping to be applied first.
+ * Because of R O(phi) = O(-phi) R (where R is flipping around
+ * an arbitatry axis and O(phi) is the proper rotation by phi)
+ * we can create display matrices as desired by negating
+ * the degree once for every flip applied. */
+ angle = -angle * (1 - 2 * !!o->hflip) * (1 - 2 * !!o->vflip);
+ av_display_rotation_set((int32_t *)rotation->data, angle);
+ av_display_matrix_flip((int32_t *)rotation->data,
+ o->hflip, o->vflip);
+ }
+
+ if (sei->a53_caption.buf_ref) {
+ H2645SEIA53Caption *a53 = &sei->a53_caption;
+ AVFrameSideData *sd = av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_A53_CC, a53->buf_ref);
+ if (!sd)
+ av_buffer_unref(&a53->buf_ref);
+ a53->buf_ref = NULL;
+ if (avctx)
+ avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
+ }
+
+ for (unsigned i = 0; i < sei->unregistered.nb_buf_ref; i++) {
+ H2645SEIUnregistered *unreg = &sei->unregistered;
+
+ if (unreg->buf_ref[i]) {
+ AVFrameSideData *sd = av_frame_new_side_data_from_buf(frame,
+ AV_FRAME_DATA_SEI_UNREGISTERED,
+ unreg->buf_ref[i]);
+ if (!sd)
+ av_buffer_unref(&unreg->buf_ref[i]);
+ unreg->buf_ref[i] = NULL;
+ }
+ }
+ sei->unregistered.nb_buf_ref = 0;
+
+ if (sei->afd.present) {
+ AVFrameSideData *sd = av_frame_new_side_data(frame, AV_FRAME_DATA_AFD,
+ sizeof(uint8_t));
+
+ if (sd) {
+ *sd->data = sei->afd.active_format_description;
+ sei->afd.present = 0;
+ }
+ }
+
+ if (sei->film_grain_characteristics.present) {
+ H2645SEIFilmGrainCharacteristics *fgc = &sei->film_grain_characteristics;
+ AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(frame);
+ AVFilmGrainH274Params *h274;
+
+ if (!fgp)
+ return AVERROR(ENOMEM);
+
+ fgp->type = AV_FILM_GRAIN_PARAMS_H274;
+ h274 = &fgp->codec.h274;
+
+ fgp->seed = seed;
+
+ h274->model_id = fgc->model_id;
+ if (fgc->separate_colour_description_present_flag) {
+ h274->bit_depth_luma = fgc->bit_depth_luma;
+ h274->bit_depth_chroma = fgc->bit_depth_chroma;
+ h274->color_range = fgc->full_range + 1;
+ h274->color_primaries = fgc->color_primaries;
+ h274->color_trc = fgc->transfer_characteristics;
+ h274->color_space = fgc->matrix_coeffs;
+ } else {
+ h274->bit_depth_luma = bit_depth_luma;
+ h274->bit_depth_chroma = bit_depth_chroma;
+ if (vui->video_signal_type_present_flag)
+ h274->color_range = vui->video_full_range_flag + 1;
+ else
+ h274->color_range = AVCOL_RANGE_UNSPECIFIED;
+ if (vui->colour_description_present_flag) {
+ h274->color_primaries = vui->colour_primaries;
+ h274->color_trc = vui->transfer_characteristics;
+ h274->color_space = vui->matrix_coeffs;
+ } else {
+ h274->color_primaries = AVCOL_PRI_UNSPECIFIED;
+ h274->color_trc = AVCOL_TRC_UNSPECIFIED;
+ h274->color_space = AVCOL_SPC_UNSPECIFIED;
+ }
+ }
+ h274->blending_mode_id = fgc->blending_mode_id;
+ h274->log2_scale_factor = fgc->log2_scale_factor;
+
+ memcpy(&h274->component_model_present, &fgc->comp_model_present_flag,
+ sizeof(h274->component_model_present));
+ memcpy(&h274->num_intensity_intervals, &fgc->num_intensity_intervals,
+ sizeof(h274->num_intensity_intervals));
+ memcpy(&h274->num_model_values, &fgc->num_model_values,
+ sizeof(h274->num_model_values));
+ memcpy(&h274->intensity_interval_lower_bound, &fgc->intensity_interval_lower_bound,
+ sizeof(h274->intensity_interval_lower_bound));
+ memcpy(&h274->intensity_interval_upper_bound, &fgc->intensity_interval_upper_bound,
+ sizeof(h274->intensity_interval_upper_bound));
+ memcpy(&h274->comp_model_value, &fgc->comp_model_value,
+ sizeof(h274->comp_model_value));
+
+ if (IS_H264(codec_id))
+ fgc->present = !!fgc->repetition_period;
+ else
+ fgc->present = fgc->persistence_flag;
+
+ if (avctx)
+ avctx->properties |= FF_CODEC_PROPERTY_FILM_GRAIN;
+ }
+
+ if (sei->ambient_viewing_environment.present) {
+ H2645SEIAmbientViewingEnvironment *env =
+ &sei->ambient_viewing_environment;
+
+ AVAmbientViewingEnvironment *dst_env =
+ av_ambient_viewing_environment_create_side_data(frame);
+ if (!dst_env)
+ return AVERROR(ENOMEM);
+
+ dst_env->ambient_illuminance = av_make_q(env->ambient_illuminance, 10000);
+ dst_env->ambient_light_x = av_make_q(env->ambient_light_x, 50000);
+ dst_env->ambient_light_y = av_make_q(env->ambient_light_y, 50000);
+ }
+
+ return 0;
+}
+
+void ff_h2645_sei_reset(H2645SEI *s)
+{
+ av_buffer_unref(&s->a53_caption.buf_ref);
+
+ for (unsigned i = 0; i < s->unregistered.nb_buf_ref; i++)
+ av_buffer_unref(&s->unregistered.buf_ref[i]);
+ s->unregistered.nb_buf_ref = 0;
+ av_freep(&s->unregistered.buf_ref);
+ av_buffer_unref(&s->dynamic_hdr_plus.info);
+ av_buffer_unref(&s->dynamic_hdr_vivid.info);
+
+ s->ambient_viewing_environment.present = 0;
+}
diff --git a/libavcodec/h2645_sei.h b/libavcodec/h2645_sei.h
new file mode 100644
index 000000000..e07ae1037
--- /dev/null
+++ b/libavcodec/h2645_sei.h
@@ -0,0 +1,152 @@
+/*
+ * 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_H2645_SEI_H
+#define AVCODEC_H2645_SEI_H
+
+#include
+
+#include "libavutil/buffer.h"
+#include "libavutil/frame.h"
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "codec_id.h"
+#include "get_bits.h"
+#include "h2645_vui.h"
+#include "sei.h"
+
+typedef struct H2645SEIA53Caption {
+ AVBufferRef *buf_ref;
+} H2645SEIA53Caption;
+
+typedef struct H2645SEIAFD {
+ int present;
+ uint8_t active_format_description;
+} H2645SEIAFD;
+
+typedef struct HEVCSEIDynamicHDRPlus {
+ AVBufferRef *info;
+} HEVCSEIDynamicHDRPlus;
+
+typedef struct HEVCSEIDynamicHDRVivid {
+ AVBufferRef *info;
+} HEVCSEIDynamicHDRVivid;
+
+typedef struct H2645SEIUnregistered {
+ AVBufferRef **buf_ref;
+ unsigned nb_buf_ref;
+ int x264_build; //< H.264 only
+} H2645SEIUnregistered;
+
+typedef struct H2645SEIFramePacking {
+ int present;
+ int arrangement_id;
+ int arrangement_cancel_flag; ///< is previous arrangement canceled, -1 if never received (currently H.264 only)
+ SEIFpaType arrangement_type;
+ int arrangement_repetition_period;
+ int content_interpretation_type;
+ int quincunx_sampling_flag;
+ int current_frame_is_frame0_flag;
+} H2645SEIFramePacking;
+
+typedef struct H2645SEIDisplayOrientation {
+ int present;
+ int anticlockwise_rotation;
+ int hflip, vflip;
+} H2645SEIDisplayOrientation;
+
+typedef struct H2645SEIAlternativeTransfer {
+ int present;
+ int preferred_transfer_characteristics;
+} H2645SEIAlternativeTransfer;
+
+typedef struct H2645SEIAmbientViewingEnvironment {
+ int present;
+ uint32_t ambient_illuminance;
+ uint16_t ambient_light_x;
+ uint16_t ambient_light_y;
+} H2645SEIAmbientViewingEnvironment;
+
+typedef struct H2645SEIFilmGrainCharacteristics {
+ int present;
+ int model_id;
+ int separate_colour_description_present_flag;
+ int bit_depth_luma;
+ int bit_depth_chroma;
+ int full_range;
+ int color_primaries;
+ int transfer_characteristics;
+ int matrix_coeffs;
+ int blending_mode_id;
+ int log2_scale_factor;
+ int comp_model_present_flag[3];
+ uint16_t num_intensity_intervals[3];
+ uint8_t num_model_values[3];
+ uint8_t intensity_interval_lower_bound[3][256];
+ uint8_t intensity_interval_upper_bound[3][256];
+ int16_t comp_model_value[3][256][6];
+ int repetition_period; //< H.264 only
+ int persistence_flag; //< HEVC only
+} H2645SEIFilmGrainCharacteristics;
+
+typedef struct H2645SEI {
+ H2645SEIA53Caption a53_caption;
+ H2645SEIAFD afd;
+ HEVCSEIDynamicHDRPlus dynamic_hdr_plus; //< HEVC only
+ HEVCSEIDynamicHDRVivid dynamic_hdr_vivid; //< HEVC only
+ H2645SEIUnregistered unregistered;
+ H2645SEIFramePacking frame_packing;
+ H2645SEIDisplayOrientation display_orientation;
+ H2645SEIAlternativeTransfer alternative_transfer;
+ H2645SEIFilmGrainCharacteristics film_grain_characteristics;
+ H2645SEIAmbientViewingEnvironment ambient_viewing_environment;
+} H2645SEI;
+
+enum {
+ FF_H2645_SEI_MESSAGE_HANDLED = 0,
+ FF_H2645_SEI_MESSAGE_UNHANDLED,
+};
+
+/**
+ * Decode a single SEI message.
+ *
+ * This function may either use gb or gbyte to decode the SEI message.
+ *
+ * @param[in, out] gb GetBitContext that needs to be at the start
+ * of the payload (i.e. after the payload_size bytes);
+ * it needs to be initially byte-aligned
+ * @param[in, out] gbyte a GetByteContext for the same data as gb
+ * @return < 0 on error, FF_H2645_SEI_MESSAGE_HANDLED if the SEI message
+ * has been handled or FF_H2645_SEI_MESSAGE_UNHANDLED if not.
+ */
+int ff_h2645_sei_message_decode(H2645SEI *h, enum SEIType type,
+ enum AVCodecID codec_id, GetBitContext *gb,
+ GetByteContext *gbyte, void *logctx);
+
+int ff_h2645_sei_ctx_replace(H2645SEI *dst, const H2645SEI *src);
+
+void ff_h2645_sei_reset(H2645SEI *s);
+
+int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei,
+ enum AVCodecID codec_id,
+ AVCodecContext *avctx, const H2645VUI *vui,
+ unsigned bit_depth_luma, unsigned bit_depth_chroma,
+ int seed);
+
+#endif /* AVCODEC_H2645_SEI_H */
diff --git a/libavcodec/h2645_vui.c b/libavcodec/h2645_vui.c
new file mode 100644
index 000000000..0633fcbdd
--- /dev/null
+++ b/libavcodec/h2645_vui.c
@@ -0,0 +1,91 @@
+/*
+ * Common H.264/HEVC VUI Parameter decoding
+ *
+ * Copyright (c) 2003 Michael Niedermayer
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2012 - 2013 Mickael Raulet
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ * Copyright (C) 2013 Vittorio Giovara
+ *
+ * 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/log.h"
+#include "libavutil/pixdesc.h"
+
+#include "get_bits.h"
+#include "golomb.h"
+#include "h2645data.h"
+#include "h2645_vui.h"
+
+#define EXTENDED_SAR 255
+
+void ff_h2645_decode_common_vui_params(GetBitContext *gb, H2645VUI *vui, void *logctx)
+{
+ int aspect_ratio_info_present_flag;
+
+ av_log(logctx, AV_LOG_DEBUG, "Decoding VUI\n");
+
+ aspect_ratio_info_present_flag = get_bits1(gb);
+ if (aspect_ratio_info_present_flag) {
+ uint8_t aspect_ratio_idc = get_bits(gb, 8);
+ if (aspect_ratio_idc < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect))
+ vui->sar = ff_h2645_pixel_aspect[aspect_ratio_idc];
+ else if (aspect_ratio_idc == EXTENDED_SAR) {
+ vui->sar.num = get_bits(gb, 16);
+ vui->sar.den = get_bits(gb, 16);
+ } else
+ av_log(logctx, AV_LOG_WARNING,
+ "Unknown SAR index: %u.\n", aspect_ratio_idc);
+ } else
+ vui->sar = (AVRational){ 0, 1 };
+
+ vui->overscan_info_present_flag = get_bits1(gb);
+ if (vui->overscan_info_present_flag)
+ vui->overscan_appropriate_flag = get_bits1(gb);
+
+ vui->video_signal_type_present_flag = get_bits1(gb);
+ if (vui->video_signal_type_present_flag) {
+ vui->video_format = get_bits(gb, 3);
+ vui->video_full_range_flag = get_bits1(gb);
+ vui->colour_description_present_flag = get_bits1(gb);
+ if (vui->colour_description_present_flag) {
+ vui->colour_primaries = get_bits(gb, 8);
+ vui->transfer_characteristics = get_bits(gb, 8);
+ vui->matrix_coeffs = get_bits(gb, 8);
+
+ // Set invalid values to "unspecified"
+ if (!av_color_primaries_name(vui->colour_primaries))
+ vui->colour_primaries = AVCOL_PRI_UNSPECIFIED;
+ if (!av_color_transfer_name(vui->transfer_characteristics))
+ vui->transfer_characteristics = AVCOL_TRC_UNSPECIFIED;
+ if (!av_color_space_name(vui->matrix_coeffs))
+ vui->matrix_coeffs = AVCOL_SPC_UNSPECIFIED;
+ }
+ }
+
+ vui->chroma_loc_info_present_flag = get_bits1(gb);
+ if (vui->chroma_loc_info_present_flag) {
+ vui->chroma_sample_loc_type_top_field = get_ue_golomb_31(gb);
+ vui->chroma_sample_loc_type_bottom_field = get_ue_golomb_31(gb);
+ if (vui->chroma_sample_loc_type_top_field <= 5U)
+ vui->chroma_location = vui->chroma_sample_loc_type_top_field + 1;
+ else
+ vui->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
+ } else
+ vui->chroma_location = AVCHROMA_LOC_LEFT;
+}
diff --git a/libavcodec/h2645_vui.h b/libavcodec/h2645_vui.h
new file mode 100644
index 000000000..638da7c36
--- /dev/null
+++ b/libavcodec/h2645_vui.h
@@ -0,0 +1,49 @@
+/*
+ * 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_H2645_VUI_H
+#define AVCODEC_H2645_VUI_H
+
+#include "libavutil/pixfmt.h"
+#include "libavutil/rational.h"
+
+#include "get_bits.h"
+
+typedef struct H2645VUI {
+ AVRational sar;
+
+ int overscan_info_present_flag;
+ int overscan_appropriate_flag;
+
+ int video_signal_type_present_flag;
+ int video_format;
+ int video_full_range_flag;
+ int colour_description_present_flag;
+ enum AVColorPrimaries colour_primaries;
+ enum AVColorTransferCharacteristic transfer_characteristics;
+ enum AVColorSpace matrix_coeffs;
+
+ int chroma_loc_info_present_flag;
+ int chroma_sample_loc_type_top_field;
+ int chroma_sample_loc_type_bottom_field;
+ enum AVChromaLocation chroma_location;
+} H2645VUI;
+
+void ff_h2645_decode_common_vui_params(GetBitContext *gb, H2645VUI *vui, void *logctx);
+
+#endif /* AVCODEC_H2645_VUI_H */
diff --git a/libavcodec/h263_parser.h b/libavcodec/h2645data.c
similarity index 68%
rename from libavcodec/h263_parser.h
rename to libavcodec/h2645data.c
index 565a222bc..9897ca318 100644
--- a/libavcodec/h263_parser.h
+++ b/libavcodec/h2645data.c
@@ -1,7 +1,4 @@
/*
- * H.263 parser
- * Copyright (c) 2002-2004 Michael Niedermayer
- *
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
@@ -19,11 +16,24 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef AVCODEC_H263_PARSER_H
-#define AVCODEC_H263_PARSER_H
+#include "h2645data.h"
-#include "parser.h"
-
-int ff_h263_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size);
-
-#endif /* AVCODEC_H263_PARSER_H */
+const AVRational ff_h2645_pixel_aspect[] = {
+ { 0, 1 },
+ { 1, 1 },
+ { 12, 11 },
+ { 10, 11 },
+ { 16, 11 },
+ { 40, 33 },
+ { 24, 11 },
+ { 20, 11 },
+ { 32, 11 },
+ { 80, 33 },
+ { 18, 11 },
+ { 15, 11 },
+ { 64, 33 },
+ { 160, 99 },
+ { 4, 3 },
+ { 3, 2 },
+ { 2, 1 },
+};
diff --git a/libavcodec/h2645data.h b/libavcodec/h2645data.h
new file mode 100644
index 000000000..bc56d7687
--- /dev/null
+++ b/libavcodec/h2645data.h
@@ -0,0 +1,26 @@
+/*
+ * 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_H2645DATA_H
+#define AVCODEC_H2645DATA_H
+
+#include "libavutil/rational.h"
+
+extern const AVRational ff_h2645_pixel_aspect[17];
+
+#endif /* AVCODEC_H2645DATA_H */
diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c
index 2440cfa83..c164a289b 100644
--- a/libavcodec/h264_loopfilter.c
+++ b/libavcodec/h264_loopfilter.c
@@ -143,7 +143,7 @@ static av_always_inline void filter_mb_edgecv(uint8_t *pix, int stride,
static av_always_inline void filter_mb_mbaff_edgev(const H264Context *h, uint8_t *pix,
int stride,
- const int16_t bS[7], int bsi,
+ const int16_t bS[ /* 1 + 2 * bsi */ ], int bsi,
int qp, int a, int b,
int intra)
{
@@ -166,7 +166,7 @@ static av_always_inline void filter_mb_mbaff_edgev(const H264Context *h, uint8_t
static av_always_inline void filter_mb_mbaff_edgecv(const H264Context *h,
uint8_t *pix, int stride,
- const int16_t bS[7],
+ const int16_t bS[ /* 1 + 2 * bsi */ ],
int bsi, int qp, int a,
int b, int intra)
{
diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
index 6efdc9247..b9cfeaba9 100644
--- a/libavcodec/h264_metadata_bsf.c
+++ b/libavcodec/h264_metadata_bsf.c
@@ -29,6 +29,7 @@
#include "h264.h"
#include "h264_levels.h"
#include "h264_sei.h"
+#include "h2645data.h"
enum {
FLIP_HORIZONTAL = 1,
@@ -144,25 +145,17 @@ static int h264_metadata_update_sps(AVBSFContext *bsf,
int crop_unit_x, crop_unit_y;
if (ctx->sample_aspect_ratio.num && ctx->sample_aspect_ratio.den) {
- // Table E-1.
- static const AVRational sar_idc[] = {
- { 0, 0 }, // Unspecified (never written here).
- { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 },
- { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 },
- { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 },
- { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 },
- };
int num, den, i;
av_reduce(&num, &den, ctx->sample_aspect_ratio.num,
ctx->sample_aspect_ratio.den, 65535);
- for (i = 1; i < FF_ARRAY_ELEMS(sar_idc); i++) {
- if (num == sar_idc[i].num &&
- den == sar_idc[i].den)
+ for (i = 1; i < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect); i++) {
+ if (num == ff_h2645_pixel_aspect[i].num &&
+ den == ff_h2645_pixel_aspect[i].den)
break;
}
- if (i == FF_ARRAY_ELEMS(sar_idc)) {
+ if (i == FF_ARRAY_ELEMS(ff_h2645_pixel_aspect)) {
sps->vui.aspect_ratio_idc = 255;
sps->vui.sar_width = num;
sps->vui.sar_height = den;
@@ -476,12 +469,13 @@ static int h264_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt,
H264MetadataContext *ctx = bsf->priv_data;
int err, i, has_sps, seek_point;
- // If an AUD is present, it must be the first NAL unit.
- if (au->nb_units && au->units[0].type == H264_NAL_AUD) {
- if (ctx->aud == BSF_ELEMENT_REMOVE)
- ff_cbs_delete_unit(au, 0);
- } else {
- if (pkt && ctx->aud == BSF_ELEMENT_INSERT) {
+ if (ctx->aud == BSF_ELEMENT_REMOVE) {
+ for (i = au->nb_units - 1; i >= 0; i--) {
+ if (au->units[i].type == H264_NAL_AUD)
+ ff_cbs_delete_unit(au, i);
+ }
+ } else if (ctx->aud == BSF_ELEMENT_INSERT) {
+ if (pkt) {
err = h264_metadata_insert_aud(bsf, au);
if (err < 0)
return err;
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index 50810f178..46134a1c4 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -274,8 +274,8 @@ static inline int parse_nal_units(AVCodecParserContext *s,
s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
ff_h264_sei_uninit(&p->sei);
- p->sei.frame_packing.arrangement_cancel_flag = -1;
- p->sei.unregistered.x264_build = -1;
+ p->sei.common.frame_packing.arrangement_cancel_flag = -1;
+ p->sei.common.unregistered.x264_build = -1;
if (!buf_size)
return 0;
@@ -565,7 +565,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
}
if (sps->timing_info_present_flag) {
int64_t den = sps->time_scale;
- if (p->sei.unregistered.x264_build < 44U)
+ if (p->sei.common.unregistered.x264_build < 44U)
den *= 2;
av_reduce(&avctx->framerate.den, &avctx->framerate.num,
sps->num_units_in_tick * avctx->ticks_per_frame, den, 1 << 30);
@@ -593,6 +593,7 @@ static int h264_parse(AVCodecParserContext *s,
{
H264ParseContext *p = s->priv_data;
ParseContext *pc = &p->pc;
+ AVRational time_base = { 0, 1 };
int next;
if (!p->got_first) {
@@ -624,7 +625,7 @@ static int h264_parse(AVCodecParserContext *s,
parse_nal_units(s, avctx, buf, buf_size);
if (avctx->framerate.num)
- avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));
+ time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));
if (p->sei.picture_timing.cpb_removal_delay >= 0) {
s->dts_sync_point = p->sei.buffering_period.present;
s->dts_ref_dts_delta = p->sei.picture_timing.cpb_removal_delay;
@@ -640,9 +641,9 @@ static int h264_parse(AVCodecParserContext *s,
}
if (s->dts_sync_point >= 0) {
- int64_t den = avctx->time_base.den * (int64_t)avctx->pkt_timebase.num;
+ int64_t den = time_base.den * (int64_t)avctx->pkt_timebase.num;
if (den > 0) {
- int64_t num = avctx->time_base.num * (int64_t)avctx->pkt_timebase.den;
+ int64_t num = time_base.num * (int64_t)avctx->pkt_timebase.den;
if (s->dts != AV_NOPTS_VALUE) {
// got DTS from the stream, update reference timestamp
p->reference_dts = s->dts - av_rescale(s->dts_ref_dts_delta, num, den);
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index e16da68de..d0d1e6590 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -31,13 +31,12 @@
#include "mathops.h"
#include "avcodec.h"
#include "h264data.h"
+#include "h2645_vui.h"
#include "h264_ps.h"
#include "golomb.h"
#define MIN_LOG2_MAX_FRAME_NUM 4
-#define EXTENDED_SAR 255
-
static const uint8_t default_scaling4[2][16] = {
{ 6, 13, 20, 28, 13, 20, 28, 32,
20, 28, 32, 37, 28, 32, 37, 42 },
@@ -132,58 +131,7 @@ static inline int decode_hrd_parameters(GetBitContext *gb, void *logctx,
static inline int decode_vui_parameters(GetBitContext *gb, void *logctx,
SPS *sps)
{
- int aspect_ratio_info_present_flag;
- unsigned int aspect_ratio_idc;
-
- aspect_ratio_info_present_flag = get_bits1(gb);
-
- if (aspect_ratio_info_present_flag) {
- aspect_ratio_idc = get_bits(gb, 8);
- if (aspect_ratio_idc == EXTENDED_SAR) {
- sps->sar.num = get_bits(gb, 16);
- sps->sar.den = get_bits(gb, 16);
- } else if (aspect_ratio_idc < FF_ARRAY_ELEMS(ff_h264_pixel_aspect)) {
- sps->sar = ff_h264_pixel_aspect[aspect_ratio_idc];
- } else {
- av_log(logctx, AV_LOG_ERROR, "illegal aspect ratio\n");
- return AVERROR_INVALIDDATA;
- }
- } else {
- sps->sar.num =
- sps->sar.den = 0;
- }
-
- if (get_bits1(gb)) /* overscan_info_present_flag */
- get_bits1(gb); /* overscan_appropriate_flag */
-
- sps->video_signal_type_present_flag = get_bits1(gb);
- if (sps->video_signal_type_present_flag) {
- get_bits(gb, 3); /* video_format */
- sps->full_range = get_bits1(gb); /* video_full_range_flag */
-
- sps->colour_description_present_flag = get_bits1(gb);
- if (sps->colour_description_present_flag) {
- sps->color_primaries = get_bits(gb, 8); /* colour_primaries */
- sps->color_trc = get_bits(gb, 8); /* transfer_characteristics */
- sps->colorspace = get_bits(gb, 8); /* matrix_coefficients */
-
- // Set invalid values to "unspecified"
- if (!av_color_primaries_name(sps->color_primaries))
- sps->color_primaries = AVCOL_PRI_UNSPECIFIED;
- if (!av_color_transfer_name(sps->color_trc))
- sps->color_trc = AVCOL_TRC_UNSPECIFIED;
- if (!av_color_space_name(sps->colorspace))
- sps->colorspace = AVCOL_SPC_UNSPECIFIED;
- }
- }
-
- /* chroma_location_info_present_flag */
- if (get_bits1(gb)) {
- /* chroma_sample_location_type_top_field */
- sps->chroma_location = get_ue_golomb_31(gb) + 1;
- get_ue_golomb_31(gb); /* chroma_sample_location_type_bottom_field */
- } else
- sps->chroma_location = AVCHROMA_LOC_LEFT;
+ ff_h2645_decode_common_vui_params(gb, &sps->vui, logctx);
if (show_bits1(gb) && get_bits_left(gb) < 10) {
av_log(logctx, AV_LOG_WARNING, "Truncated VUI (%d)\n", get_bits_left(gb));
@@ -376,12 +324,12 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
sps->profile_idc = profile_idc;
sps->constraint_set_flags = constraint_set_flags;
sps->level_idc = level_idc;
- sps->full_range = -1;
+ sps->vui.video_full_range_flag = -1;
memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4));
memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8));
sps->scaling_matrix_present = 0;
- sps->colorspace = 2; //AVCOL_SPC_UNSPECIFIED
+ sps->vui.matrix_coeffs = AVCOL_SPC_UNSPECIFIED;
if (sps->profile_idc == 100 || // High profile
sps->profile_idc == 110 || // High10 profile
@@ -598,8 +546,8 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
}
}
- if (!sps->sar.den)
- sps->sar.den = 1;
+ if (!sps->vui.sar.den)
+ sps->vui.sar.den = 1;
if (avctx->debug & FF_DEBUG_PICT_INFO) {
static const char csp[4][5] = { "Gray", "420", "422", "444" };
diff --git a/libavcodec/h264_ps.h b/libavcodec/h264_ps.h
index dc52835ed..5c35761fb 100644
--- a/libavcodec/h264_ps.h
+++ b/libavcodec/h264_ps.h
@@ -33,6 +33,7 @@
#include "avcodec.h"
#include "get_bits.h"
#include "h264.h"
+#include "h2645_vui.h"
#define MAX_SPS_COUNT 32
#define MAX_PPS_COUNT 256
@@ -70,14 +71,7 @@ typedef struct SPS {
unsigned int crop_top; ///< frame_cropping_rect_top_offset
unsigned int crop_bottom; ///< frame_cropping_rect_bottom_offset
int vui_parameters_present_flag;
- AVRational sar;
- int video_signal_type_present_flag;
- int full_range;
- int colour_description_present_flag;
- enum AVColorPrimaries color_primaries;
- enum AVColorTransferCharacteristic color_trc;
- enum AVColorSpace colorspace;
- enum AVChromaLocation chroma_location;
+ H2645VUI vui;
int timing_info_present_flag;
uint32_t num_units_in_tick;
diff --git a/libavcodec/h264_redundant_pps_bsf.c b/libavcodec/h264_redundant_pps_bsf.c
index f8bab1f10..df9a88a70 100644
--- a/libavcodec/h264_redundant_pps_bsf.c
+++ b/libavcodec/h264_redundant_pps_bsf.c
@@ -80,26 +80,15 @@ static int h264_redundant_pps_update_fragment(AVBSFContext *bsf,
CodedBitstreamFragment *au)
{
H264RedundantPPSContext *ctx = bsf->priv_data;
- int au_has_sps;
int err, i;
- au_has_sps = 0;
for (i = 0; i < au->nb_units; i++) {
CodedBitstreamUnit *nal = &au->units[i];
- if (nal->type == H264_NAL_SPS)
- au_has_sps = 1;
if (nal->type == H264_NAL_PPS) {
err = h264_redundant_pps_fixup_pps(ctx, nal);
if (err < 0)
return err;
- if (!au_has_sps) {
- av_log(bsf, AV_LOG_VERBOSE, "Deleting redundant PPS "
- "at %"PRId64".\n", pkt->pts);
- ff_cbs_delete_unit(au, i);
- i--;
- continue;
- }
}
if (nal->type == H264_NAL_SLICE ||
nal->type == H264_NAL_IDR_SLICE) {
diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
index 034ddb8f1..668204959 100644
--- a/libavcodec/h264_sei.c
+++ b/libavcodec/h264_sei.c
@@ -32,7 +32,7 @@
#include "libavutil/log.h"
#include "libavutil/macros.h"
#include "libavutil/mem.h"
-#include "atsc_a53.h"
+#include "bytestream.h"
#include "get_bits.h"
#include "golomb.h"
#include "h264_ps.h"
@@ -54,24 +54,22 @@ void ff_h264_sei_uninit(H264SEIContext *h)
h->picture_timing.present = 0;
h->buffering_period.present = 0;
- h->frame_packing.present = 0;
- h->film_grain_characteristics.present = 0;
- h->display_orientation.present = 0;
- h->afd.present = 0;
+ h->common.frame_packing.present = 0;
+ h->common.film_grain_characteristics.present = 0;
+ h->common.display_orientation.present = 0;
+ h->common.afd.present = 0;
- av_buffer_unref(&h->a53_caption.buf_ref);
- for (int i = 0; i < h->unregistered.nb_buf_ref; i++)
- av_buffer_unref(&h->unregistered.buf_ref[i]);
- h->unregistered.nb_buf_ref = 0;
- av_freep(&h->unregistered.buf_ref);
+ ff_h2645_sei_reset(&h->common);
}
int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS *sps,
void *logctx)
{
GetBitContext gb;
+ av_unused int ret;
- init_get_bits(&gb, h->payload, h->payload_size_bits);
+ ret = init_get_bits8(&gb, h->payload, h->payload_size_bytes);
+ av_assert1(ret >= 0);
if (sps->nal_hrd_parameters_present_flag ||
sps->vcl_hrd_parameters_present_flag) {
@@ -133,157 +131,23 @@ int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS *sps,
return 0;
}
-static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb,
+static int decode_picture_timing(H264SEIPictureTiming *h, GetByteContext *gb,
void *logctx)
{
- int index = get_bits_count(gb);
- int size_bits = get_bits_left(gb);
- int size = (size_bits + 7) / 8;
+ int size = bytestream2_get_bytes_left(gb);
- if (index & 7) {
- av_log(logctx, AV_LOG_ERROR, "Unaligned SEI payload\n");
- return AVERROR_INVALIDDATA;
- }
if (size > sizeof(h->payload)) {
av_log(logctx, AV_LOG_ERROR, "Picture timing SEI payload too large\n");
return AVERROR_INVALIDDATA;
}
- memcpy(h->payload, gb->buffer + index / 8, size);
+ bytestream2_get_bufferu(gb, h->payload, size);
- h->payload_size_bits = size_bits;
+ h->payload_size_bytes = size;
h->present = 1;
return 0;
}
-static int decode_registered_user_data_afd(H264SEIAFD *h, GetBitContext *gb, int size)
-{
- int flag;
-
- if (size-- < 1)
- return AVERROR_INVALIDDATA;
- skip_bits(gb, 1); // 0
- flag = get_bits(gb, 1); // active_format_flag
- skip_bits(gb, 6); // reserved
-
- if (flag) {
- if (size-- < 1)
- return AVERROR_INVALIDDATA;
- skip_bits(gb, 4); // reserved
- h->active_format_description = get_bits(gb, 4);
- h->present = 1;
- }
-
- return 0;
-}
-
-static int decode_registered_user_data_closed_caption(H264SEIA53Caption *h,
- GetBitContext *gb, void *logctx,
- int size)
-{
- if (size < 3)
- return AVERROR(EINVAL);
-
- return ff_parse_a53_cc(&h->buf_ref, gb->buffer + get_bits_count(gb) / 8, size);
-}
-
-static int decode_registered_user_data(H264SEIContext *h, GetBitContext *gb,
- void *logctx, int size)
-{
- int country_code, provider_code;
-
- if (size < 3)
- return AVERROR_INVALIDDATA;
- size -= 3;
-
- country_code = get_bits(gb, 8); // itu_t_t35_country_code
- if (country_code == 0xFF) {
- if (size < 1)
- return AVERROR_INVALIDDATA;
-
- skip_bits(gb, 8); // itu_t_t35_country_code_extension_byte
- size--;
- }
-
- if (country_code != 0xB5) { // usa_country_code
- av_log(logctx, AV_LOG_VERBOSE,
- "Unsupported User Data Registered ITU-T T35 SEI message (country_code = %d)\n",
- country_code);
- return 0;
- }
-
- /* itu_t_t35_payload_byte follows */
- provider_code = get_bits(gb, 16);
-
- switch (provider_code) {
- case 0x31: { // atsc_provider_code
- uint32_t user_identifier;
-
- if (size < 4)
- return AVERROR_INVALIDDATA;
- size -= 4;
-
- user_identifier = get_bits_long(gb, 32);
- switch (user_identifier) {
- case MKBETAG('D', 'T', 'G', '1'): // afd_data
- return decode_registered_user_data_afd(&h->afd, gb, size);
- case MKBETAG('G', 'A', '9', '4'): // closed captions
- return decode_registered_user_data_closed_caption(&h->a53_caption, gb,
- logctx, size);
- default:
- av_log(logctx, AV_LOG_VERBOSE,
- "Unsupported User Data Registered ITU-T T35 SEI message (atsc user_identifier = 0x%04x)\n",
- user_identifier);
- break;
- }
- break;
- }
- default:
- av_log(logctx, AV_LOG_VERBOSE,
- "Unsupported User Data Registered ITU-T T35 SEI message (provider_code = %d)\n",
- provider_code);
- break;
- }
-
- return 0;
-}
-
-static int decode_unregistered_user_data(H264SEIUnregistered *h, GetBitContext *gb,
- void *logctx, int size)
-{
- uint8_t *user_data;
- int e, build, i;
- AVBufferRef *buf_ref, **tmp;
-
- if (size < 16 || size >= INT_MAX - 1)
- return AVERROR_INVALIDDATA;
-
- tmp = av_realloc_array(h->buf_ref, h->nb_buf_ref + 1, sizeof(*h->buf_ref));
- if (!tmp)
- return AVERROR(ENOMEM);
- h->buf_ref = tmp;
-
- buf_ref = av_buffer_alloc(size + 1);
- if (!buf_ref)
- return AVERROR(ENOMEM);
- user_data = buf_ref->data;
-
- for (i = 0; i < size; i++)
- user_data[i] = get_bits(gb, 8);
-
- user_data[i] = 0;
- buf_ref->size = size;
- h->buf_ref[h->nb_buf_ref++] = buf_ref;
-
- e = sscanf(user_data + 16, "x264 - core %d", &build);
- if (e == 1 && build > 0)
- h->x264_build = build;
- if (e == 1 && build == 1 && !strncmp(user_data+16, "x264 - core 0000", 16))
- h->x264_build = 67;
-
- return 0;
-}
-
static int decode_recovery_point(H264SEIRecoveryPoint *h, GetBitContext *gb, void *logctx)
{
unsigned recovery_frame_cnt = get_ue_golomb_long(gb);
@@ -339,122 +203,26 @@ static int decode_buffering_period(H264SEIBufferingPeriod *h, GetBitContext *gb,
return 0;
}
-static int decode_frame_packing_arrangement(H264SEIFramePacking *h,
- GetBitContext *gb)
+static int decode_green_metadata(H264SEIGreenMetaData *h, GetByteContext *gb)
{
- h->arrangement_id = get_ue_golomb_long(gb);
- h->arrangement_cancel_flag = get_bits1(gb);
- h->present = !h->arrangement_cancel_flag;
-
- if (h->present) {
- h->arrangement_type = get_bits(gb, 7);
- h->quincunx_sampling_flag = get_bits1(gb);
- h->content_interpretation_type = get_bits(gb, 6);
-
- // spatial_flipping_flag, frame0_flipped_flag, field_views_flag
- skip_bits(gb, 3);
- h->current_frame_is_frame0_flag = get_bits1(gb);
- // frame0_self_contained_flag, frame1_self_contained_flag
- skip_bits(gb, 2);
-
- if (!h->quincunx_sampling_flag && h->arrangement_type != 5)
- skip_bits(gb, 16); // frame[01]_grid_position_[xy]
- skip_bits(gb, 8); // frame_packing_arrangement_reserved_byte
- h->arrangement_repetition_period = get_ue_golomb_long(gb);
- }
- skip_bits1(gb); // frame_packing_arrangement_extension_flag
-
- return 0;
-}
-
-static int decode_display_orientation(H264SEIDisplayOrientation *h,
- GetBitContext *gb)
-{
- h->present = !get_bits1(gb);
-
- if (h->present) {
- h->hflip = get_bits1(gb); // hor_flip
- h->vflip = get_bits1(gb); // ver_flip
-
- h->anticlockwise_rotation = get_bits(gb, 16);
- get_ue_golomb_long(gb); // display_orientation_repetition_period
- skip_bits1(gb); // display_orientation_extension_flag
- }
-
- return 0;
-}
-
-static int decode_green_metadata(H264SEIGreenMetaData *h, GetBitContext *gb)
-{
- h->green_metadata_type = get_bits(gb, 8);
+ h->green_metadata_type = bytestream2_get_byte(gb);
if (h->green_metadata_type == 0) {
- h->period_type = get_bits(gb, 8);
+ h->period_type = bytestream2_get_byte(gb);
if (h->period_type == 2)
- h->num_seconds = get_bits(gb, 16);
+ h->num_seconds = bytestream2_get_be16(gb);
else if (h->period_type == 3)
- h->num_pictures = get_bits(gb, 16);
+ h->num_pictures = bytestream2_get_be16(gb);
- h->percent_non_zero_macroblocks = get_bits(gb, 8);
- h->percent_intra_coded_macroblocks = get_bits(gb, 8);
- h->percent_six_tap_filtering = get_bits(gb, 8);
- h->percent_alpha_point_deblocking_instance = get_bits(gb, 8);
+ h->percent_non_zero_macroblocks = bytestream2_get_byte(gb);
+ h->percent_intra_coded_macroblocks = bytestream2_get_byte(gb);
+ h->percent_six_tap_filtering = bytestream2_get_byte(gb);
+ h->percent_alpha_point_deblocking_instance = bytestream2_get_byte(gb);
} else if (h->green_metadata_type == 1) {
- h->xsd_metric_type = get_bits(gb, 8);
- h->xsd_metric_value = get_bits(gb, 16);
- }
-
- return 0;
-}
-
-static int decode_alternative_transfer(H264SEIAlternativeTransfer *h,
- GetBitContext *gb)
-{
- h->present = 1;
- h->preferred_transfer_characteristics = get_bits(gb, 8);
- return 0;
-}
-
-static int decode_film_grain_characteristics(H264SEIFilmGrainCharacteristics *h,
- GetBitContext *gb)
-{
- h->present = !get_bits1(gb); // film_grain_characteristics_cancel_flag
-
- if (h->present) {
- memset(h, 0, sizeof(*h));
- h->model_id = get_bits(gb, 2);
- h->separate_colour_description_present_flag = get_bits1(gb);
- if (h->separate_colour_description_present_flag) {
- h->bit_depth_luma = get_bits(gb, 3) + 8;
- h->bit_depth_chroma = get_bits(gb, 3) + 8;
- h->full_range = get_bits1(gb);
- h->color_primaries = get_bits(gb, 8);
- h->transfer_characteristics = get_bits(gb, 8);
- h->matrix_coeffs = get_bits(gb, 8);
- }
- h->blending_mode_id = get_bits(gb, 2);
- h->log2_scale_factor = get_bits(gb, 4);
- for (int c = 0; c < 3; c++)
- h->comp_model_present_flag[c] = get_bits1(gb);
- for (int c = 0; c < 3; c++) {
- if (h->comp_model_present_flag[c]) {
- h->num_intensity_intervals[c] = get_bits(gb, 8) + 1;
- h->num_model_values[c] = get_bits(gb, 3) + 1;
- if (h->num_model_values[c] > 6)
- return AVERROR_INVALIDDATA;
- for (int i = 0; i < h->num_intensity_intervals[c]; i++) {
- h->intensity_interval_lower_bound[c][i] = get_bits(gb, 8);
- h->intensity_interval_upper_bound[c][i] = get_bits(gb, 8);
- for (int j = 0; j < h->num_model_values[c]; j++)
- h->comp_model_value[c][i][j] = get_se_golomb_long(gb);
- }
- }
- }
- h->repetition_period = get_ue_golomb_long(gb);
-
- h->present = 1;
+ h->xsd_metric_type = bytestream2_get_byte(gb);
+ h->xsd_metric_value = bytestream2_get_be16(gb);
}
return 0;
@@ -463,45 +231,46 @@ static int decode_film_grain_characteristics(H264SEIFilmGrainCharacteristics *h,
int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb,
const H264ParamSets *ps, void *logctx)
{
+ GetByteContext gbyte;
int master_ret = 0;
- while (get_bits_left(gb) > 16 && show_bits(gb, 16)) {
+ av_assert1((get_bits_count(gb) % 8) == 0);
+ bytestream2_init(&gbyte, gb->buffer + get_bits_count(gb) / 8,
+ get_bits_left(gb) / 8);
+
+ while (bytestream2_get_bytes_left(&gbyte) > 2 && bytestream2_peek_ne16(&gbyte)) {
+ GetByteContext gbyte_payload;
GetBitContext gb_payload;
int type = 0;
unsigned size = 0;
int ret = 0;
do {
- if (get_bits_left(gb) < 8)
+ if (bytestream2_get_bytes_left(&gbyte) <= 0)
return AVERROR_INVALIDDATA;
- type += show_bits(gb, 8);
- } while (get_bits(gb, 8) == 255);
+ type += bytestream2_peek_byteu(&gbyte);
+ } while (bytestream2_get_byteu(&gbyte) == 255);
do {
- if (get_bits_left(gb) < 8)
+ if (bytestream2_get_bytes_left(&gbyte) <= 0)
return AVERROR_INVALIDDATA;
- size += show_bits(gb, 8);
- } while (get_bits(gb, 8) == 255);
+ size += bytestream2_peek_byteu(&gbyte);
+ } while (bytestream2_get_byteu(&gbyte) == 255);
- if (size > get_bits_left(gb) / 8) {
+ if (size > bytestream2_get_bytes_left(&gbyte)) {
av_log(logctx, AV_LOG_ERROR, "SEI type %d size %d truncated at %d\n",
- type, 8*size, get_bits_left(gb));
+ type, size, bytestream2_get_bytes_left(&gbyte));
return AVERROR_INVALIDDATA;
}
- ret = init_get_bits8(&gb_payload, gb->buffer + get_bits_count(gb) / 8, size);
+ bytestream2_init (&gbyte_payload, gbyte.buffer, size);
+ ret = init_get_bits8(&gb_payload, gbyte.buffer, size);
if (ret < 0)
return ret;
switch (type) {
case SEI_TYPE_PIC_TIMING: // Picture timing SEI
- ret = decode_picture_timing(&h->picture_timing, &gb_payload, logctx);
- break;
- case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35:
- ret = decode_registered_user_data(h, &gb_payload, logctx, size);
- break;
- case SEI_TYPE_USER_DATA_UNREGISTERED:
- ret = decode_unregistered_user_data(&h->unregistered, &gb_payload, logctx, size);
+ ret = decode_picture_timing(&h->picture_timing, &gbyte_payload, logctx);
break;
case SEI_TYPE_RECOVERY_POINT:
ret = decode_recovery_point(&h->recovery_point, &gb_payload, logctx);
@@ -509,23 +278,14 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb,
case SEI_TYPE_BUFFERING_PERIOD:
ret = decode_buffering_period(&h->buffering_period, &gb_payload, ps, logctx);
break;
- case SEI_TYPE_FRAME_PACKING_ARRANGEMENT:
- ret = decode_frame_packing_arrangement(&h->frame_packing, &gb_payload);
- break;
- case SEI_TYPE_DISPLAY_ORIENTATION:
- ret = decode_display_orientation(&h->display_orientation, &gb_payload);
- break;
case SEI_TYPE_GREEN_METADATA:
- ret = decode_green_metadata(&h->green_metadata, &gb_payload);
- break;
- case SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS:
- ret = decode_alternative_transfer(&h->alternative_transfer, &gb_payload);
- break;
- case SEI_TYPE_FILM_GRAIN_CHARACTERISTICS:
- ret = decode_film_grain_characteristics(&h->film_grain_characteristics, &gb_payload);
+ ret = decode_green_metadata(&h->green_metadata, &gbyte_payload);
break;
default:
- av_log(logctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type);
+ ret = ff_h2645_sei_message_decode(&h->common, type, AV_CODEC_ID_H264,
+ &gb_payload, &gbyte_payload, logctx);
+ if (ret == FF_H2645_SEI_MESSAGE_UNHANDLED)
+ av_log(logctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type);
}
if (ret < 0 && ret != AVERROR_PS_NOT_FOUND)
return ret;
@@ -537,47 +297,47 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb,
type, -get_bits_left(&gb_payload));
}
- skip_bits_long(gb, 8 * size);
+ bytestream2_skipu(&gbyte, size);
}
return master_ret;
}
-const char *ff_h264_sei_stereo_mode(const H264SEIFramePacking *h)
+const char *ff_h264_sei_stereo_mode(const H2645SEIFramePacking *h)
{
if (h->arrangement_cancel_flag == 0) {
switch (h->arrangement_type) {
- case H264_SEI_FPA_TYPE_CHECKERBOARD:
+ case SEI_FPA_H264_TYPE_CHECKERBOARD:
if (h->content_interpretation_type == 2)
return "checkerboard_rl";
else
return "checkerboard_lr";
- case H264_SEI_FPA_TYPE_INTERLEAVE_COLUMN:
+ case SEI_FPA_H264_TYPE_INTERLEAVE_COLUMN:
if (h->content_interpretation_type == 2)
return "col_interleaved_rl";
else
return "col_interleaved_lr";
- case H264_SEI_FPA_TYPE_INTERLEAVE_ROW:
+ case SEI_FPA_H264_TYPE_INTERLEAVE_ROW:
if (h->content_interpretation_type == 2)
return "row_interleaved_rl";
else
return "row_interleaved_lr";
- case H264_SEI_FPA_TYPE_SIDE_BY_SIDE:
+ case SEI_FPA_TYPE_SIDE_BY_SIDE:
if (h->content_interpretation_type == 2)
return "right_left";
else
return "left_right";
- case H264_SEI_FPA_TYPE_TOP_BOTTOM:
+ case SEI_FPA_TYPE_TOP_BOTTOM:
if (h->content_interpretation_type == 2)
return "bottom_top";
else
return "top_bottom";
- case H264_SEI_FPA_TYPE_INTERLEAVE_TEMPORAL:
+ case SEI_FPA_TYPE_INTERLEAVE_TEMPORAL:
if (h->content_interpretation_type == 2)
return "block_rl";
else
return "block_lr";
- case H264_SEI_FPA_TYPE_2D:
+ case SEI_FPA_H264_TYPE_2D:
default:
return "mono";
}
diff --git a/libavcodec/h264_sei.h b/libavcodec/h264_sei.h
index f9166b45d..bb9275e56 100644
--- a/libavcodec/h264_sei.h
+++ b/libavcodec/h264_sei.h
@@ -20,6 +20,7 @@
#define AVCODEC_H264_SEI_H
#include "get_bits.h"
+#include "h2645_sei.h"
#include "h264_ps.h"
#include "sei.h"
@@ -39,19 +40,6 @@ typedef enum {
H264_SEI_PIC_STRUCT_FRAME_TRIPLING = 8 ///< 8: %frame tripling
} H264_SEI_PicStructType;
-/**
- * frame_packing_arrangement types
- */
-typedef enum {
- H264_SEI_FPA_TYPE_CHECKERBOARD = 0,
- H264_SEI_FPA_TYPE_INTERLEAVE_COLUMN = 1,
- H264_SEI_FPA_TYPE_INTERLEAVE_ROW = 2,
- H264_SEI_FPA_TYPE_SIDE_BY_SIDE = 3,
- H264_SEI_FPA_TYPE_TOP_BOTTOM = 4,
- H264_SEI_FPA_TYPE_INTERLEAVE_TEMPORAL = 5,
- H264_SEI_FPA_TYPE_2D = 6,
-} H264_SEI_FpaType;
-
typedef struct H264SEITimeCode {
/* When not continuously receiving full timecodes, we have to reference
the previous timecode received */
@@ -66,7 +54,7 @@ typedef struct H264SEITimeCode {
typedef struct H264SEIPictureTiming {
// maximum size of pic_timing according to the spec should be 274 bits
uint8_t payload[40];
- int payload_size_bits;
+ int payload_size_bytes;
int present;
H264_SEI_PicStructType pic_struct;
@@ -99,21 +87,6 @@ typedef struct H264SEIPictureTiming {
int timecode_cnt;
} H264SEIPictureTiming;
-typedef struct H264SEIAFD {
- int present;
- uint8_t active_format_description;
-} H264SEIAFD;
-
-typedef struct H264SEIA53Caption {
- AVBufferRef *buf_ref;
-} H264SEIA53Caption;
-
-typedef struct H264SEIUnregistered {
- int x264_build;
- AVBufferRef **buf_ref;
- int nb_buf_ref;
-} H264SEIUnregistered;
-
typedef struct H264SEIRecoveryPoint {
/**
* recovery_frame_cnt
@@ -130,23 +103,6 @@ typedef struct H264SEIBufferingPeriod {
int initial_cpb_removal_delay[32]; ///< Initial timestamps for CPBs
} H264SEIBufferingPeriod;
-typedef struct H264SEIFramePacking {
- int present;
- int arrangement_id;
- int arrangement_cancel_flag; ///< is previous arrangement canceled, -1 if never received
- H264_SEI_FpaType arrangement_type;
- int arrangement_repetition_period;
- int content_interpretation_type;
- int quincunx_sampling_flag;
- int current_frame_is_frame0_flag;
-} H264SEIFramePacking;
-
-typedef struct H264SEIDisplayOrientation {
- int present;
- int anticlockwise_rotation;
- int hflip, vflip;
-} H264SEIDisplayOrientation;
-
typedef struct H264SEIGreenMetaData {
uint8_t green_metadata_type;
uint8_t period_type;
@@ -160,44 +116,12 @@ typedef struct H264SEIGreenMetaData {
uint16_t xsd_metric_value;
} H264SEIGreenMetaData;
-typedef struct H264SEIAlternativeTransfer {
- int present;
- int preferred_transfer_characteristics;
-} H264SEIAlternativeTransfer;
-
-typedef struct H264SEIFilmGrainCharacteristics {
- int present;
- int model_id;
- int separate_colour_description_present_flag;
- int bit_depth_luma;
- int bit_depth_chroma;
- int full_range;
- int color_primaries;
- int transfer_characteristics;
- int matrix_coeffs;
- int blending_mode_id;
- int log2_scale_factor;
- int comp_model_present_flag[3];
- uint16_t num_intensity_intervals[3];
- uint8_t num_model_values[3];
- uint8_t intensity_interval_lower_bound[3][256];
- uint8_t intensity_interval_upper_bound[3][256];
- int16_t comp_model_value[3][256][6];
- int repetition_period;
-} H264SEIFilmGrainCharacteristics;
-
typedef struct H264SEIContext {
+ H2645SEI common;
H264SEIPictureTiming picture_timing;
- H264SEIAFD afd;
- H264SEIA53Caption a53_caption;
- H264SEIUnregistered unregistered;
H264SEIRecoveryPoint recovery_point;
H264SEIBufferingPeriod buffering_period;
- H264SEIFramePacking frame_packing;
- H264SEIDisplayOrientation display_orientation;
H264SEIGreenMetaData green_metadata;
- H264SEIAlternativeTransfer alternative_transfer;
- H264SEIFilmGrainCharacteristics film_grain_characteristics;
} H264SEIContext;
struct H264ParamSets;
@@ -205,6 +129,12 @@ struct H264ParamSets;
int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb,
const struct H264ParamSets *ps, void *logctx);
+static inline int ff_h264_sei_ctx_replace(H264SEIContext *dst,
+ const H264SEIContext *src)
+{
+ return ff_h2645_sei_ctx_replace(&dst->common, &src->common);
+}
+
/**
* Reset SEI values at the beginning of the frame.
*/
@@ -213,7 +143,7 @@ void ff_h264_sei_uninit(H264SEIContext *h);
/**
* Get stereo_mode string from the h264 frame_packing_arrangement
*/
-const char *ff_h264_sei_stereo_mode(const H264SEIFramePacking *h);
+const char *ff_h264_sei_stereo_mode(const H2645SEIFramePacking *h);
/**
* Parse the contents of a picture timing message given an active SPS.
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index d56722a5c..7767e16cf 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -31,11 +31,11 @@
#include "libavutil/display.h"
#include "libavutil/film_grain_params.h"
#include "libavutil/pixdesc.h"
-#include "libavutil/stereo3d.h"
#include "libavutil/timecode.h"
#include "internal.h"
#include "cabac.h"
#include "cabac_functions.h"
+#include "decode.h"
#include "error_resilience.h"
#include "avcodec.h"
#include "h264.h"
@@ -327,7 +327,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
!h->ps.sps ||
h->ps.sps->bit_depth_luma != h1->ps.sps->bit_depth_luma ||
h->ps.sps->chroma_format_idc != h1->ps.sps->chroma_format_idc ||
- h->ps.sps->colorspace != h1->ps.sps->colorspace)) {
+ h->ps.sps->vui.matrix_coeffs != h1->ps.sps->vui.matrix_coeffs)) {
need_reinit = 1;
}
@@ -433,29 +433,11 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
h->frame_recovered = h1->frame_recovered;
- ret = av_buffer_replace(&h->sei.a53_caption.buf_ref, h1->sei.a53_caption.buf_ref);
+ ret = ff_h264_sei_ctx_replace(&h->sei, &h1->sei);
if (ret < 0)
return ret;
- for (i = 0; i < h->sei.unregistered.nb_buf_ref; i++)
- av_buffer_unref(&h->sei.unregistered.buf_ref[i]);
- h->sei.unregistered.nb_buf_ref = 0;
-
- if (h1->sei.unregistered.nb_buf_ref) {
- ret = av_reallocp_array(&h->sei.unregistered.buf_ref,
- h1->sei.unregistered.nb_buf_ref,
- sizeof(*h->sei.unregistered.buf_ref));
- if (ret < 0)
- return ret;
-
- for (i = 0; i < h1->sei.unregistered.nb_buf_ref; i++) {
- h->sei.unregistered.buf_ref[i] = av_buffer_ref(h1->sei.unregistered.buf_ref[i]);
- if (!h->sei.unregistered.buf_ref[i])
- return AVERROR(ENOMEM);
- h->sei.unregistered.nb_buf_ref++;
- }
- }
- h->sei.unregistered.x264_build = h1->sei.unregistered.x264_build;
+ h->sei.common.unregistered.x264_build = h1->sei.common.unregistered.x264_build;
if (!h->cur_pic_ptr)
return 0;
@@ -507,7 +489,11 @@ static int h264_frame_start(H264Context *h)
pic = &h->DPB[i];
pic->reference = h->droppable ? 0 : h->picture_structure;
+#if FF_API_FRAME_PICTURE_NUMBER
+FF_DISABLE_DEPRECATION_WARNINGS
pic->f->coded_picture_number = h->coded_picture_number++;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
pic->field_picture = h->picture_structure != PICT_FRAME;
pic->frame_num = h->poc.frame_num;
/*
@@ -528,7 +514,7 @@ static int h264_frame_start(H264Context *h)
pic->f->crop_top = h->crop_top;
pic->f->crop_bottom = h->crop_bottom;
- pic->needs_fg = h->sei.film_grain_characteristics.present && !h->avctx->hwaccel &&
+ pic->needs_fg = h->sei.common.film_grain_characteristics.present && !h->avctx->hwaccel &&
!(h->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN);
if ((ret = alloc_picture(h, pic)) < 0)
@@ -579,8 +565,8 @@ static int h264_frame_start(H264Context *h)
h->mb_aff_frame = h->ps.sps->mb_aff && (h->picture_structure == PICT_FRAME);
- if (h->sei.unregistered.x264_build >= 0)
- h->x264_build = h->sei.unregistered.x264_build;
+ if (h->sei.common.unregistered.x264_build >= 0)
+ h->x264_build = h->sei.common.unregistered.x264_build;
assert(h->cur_pic_ptr->long_ref == 0);
@@ -955,7 +941,7 @@ static int h264_slice_header_init(H264Context *h)
goto fail;
}
- ff_set_sar(h->avctx, sps->sar);
+ ff_set_sar(h->avctx, sps->vui.sar);
av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt,
&h->chroma_x_shift, &h->chroma_y_shift);
@@ -1080,7 +1066,7 @@ static int h264_init_ps(H264Context *h, const H264SliceContext *sl, int first_sl
|| (non_j_pixfmt(h->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h, 0))))
must_reinit = 1;
- if (first_slice && av_cmp_q(sps->sar, h->avctx->sample_aspect_ratio))
+ if (first_slice && av_cmp_q(sps->vui.sar, h->avctx->sample_aspect_ratio))
must_reinit = 1;
if (!h->setup_finished) {
@@ -1102,25 +1088,25 @@ static int h264_init_ps(H264Context *h, const H264SliceContext *sl, int first_sl
init_dimensions(h);
- if (sps->video_signal_type_present_flag) {
- h->avctx->color_range = sps->full_range > 0 ? AVCOL_RANGE_JPEG
- : AVCOL_RANGE_MPEG;
- if (sps->colour_description_present_flag) {
- if (h->avctx->colorspace != sps->colorspace)
+ if (sps->vui.video_signal_type_present_flag) {
+ h->avctx->color_range = sps->vui.video_full_range_flag > 0 ? AVCOL_RANGE_JPEG
+ : AVCOL_RANGE_MPEG;
+ if (sps->vui.colour_description_present_flag) {
+ if (h->avctx->colorspace != sps->vui.matrix_coeffs)
needs_reinit = 1;
- h->avctx->color_primaries = sps->color_primaries;
- h->avctx->color_trc = sps->color_trc;
- h->avctx->colorspace = sps->colorspace;
+ h->avctx->color_primaries = sps->vui.colour_primaries;
+ h->avctx->color_trc = sps->vui.transfer_characteristics;
+ h->avctx->colorspace = sps->vui.matrix_coeffs;
}
}
- if (h->sei.alternative_transfer.present &&
- av_color_transfer_name(h->sei.alternative_transfer.preferred_transfer_characteristics) &&
- h->sei.alternative_transfer.preferred_transfer_characteristics != AVCOL_TRC_UNSPECIFIED) {
- h->avctx->color_trc = h->sei.alternative_transfer.preferred_transfer_characteristics;
+ if (h->sei.common.alternative_transfer.present &&
+ av_color_transfer_name(h->sei.common.alternative_transfer.preferred_transfer_characteristics) &&
+ h->sei.common.alternative_transfer.preferred_transfer_characteristics != AVCOL_TRC_UNSPECIFIED) {
+ h->avctx->color_trc = h->sei.common.alternative_transfer.preferred_transfer_characteristics;
}
}
- h->avctx->chroma_sample_location = sps->chroma_location;
+ h->avctx->chroma_sample_location = sps->vui.chroma_location;
if (!h->context_initialized || must_reinit || needs_reinit) {
int flush_changes = h->context_initialized;
@@ -1162,6 +1148,7 @@ static int h264_export_frame_props(H264Context *h)
const SPS *sps = h->ps.sps;
H264Picture *cur = h->cur_pic_ptr;
AVFrame *out = cur->f;
+ int ret;
out->interlaced_frame = 0;
out->repeat_pict = 0;
@@ -1243,166 +1230,11 @@ static int h264_export_frame_props(H264Context *h)
}
}
- if (h->sei.frame_packing.present &&
- h->sei.frame_packing.arrangement_type <= 6 &&
- h->sei.frame_packing.content_interpretation_type > 0 &&
- h->sei.frame_packing.content_interpretation_type < 3) {
- H264SEIFramePacking *fp = &h->sei.frame_packing;
- AVStereo3D *stereo = av_stereo3d_create_side_data(out);
- if (stereo) {
- switch (fp->arrangement_type) {
- case H264_SEI_FPA_TYPE_CHECKERBOARD:
- stereo->type = AV_STEREO3D_CHECKERBOARD;
- break;
- case H264_SEI_FPA_TYPE_INTERLEAVE_COLUMN:
- stereo->type = AV_STEREO3D_COLUMNS;
- break;
- case H264_SEI_FPA_TYPE_INTERLEAVE_ROW:
- stereo->type = AV_STEREO3D_LINES;
- break;
- case H264_SEI_FPA_TYPE_SIDE_BY_SIDE:
- if (fp->quincunx_sampling_flag)
- stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
- else
- stereo->type = AV_STEREO3D_SIDEBYSIDE;
- break;
- case H264_SEI_FPA_TYPE_TOP_BOTTOM:
- stereo->type = AV_STEREO3D_TOPBOTTOM;
- break;
- case H264_SEI_FPA_TYPE_INTERLEAVE_TEMPORAL:
- stereo->type = AV_STEREO3D_FRAMESEQUENCE;
- break;
- case H264_SEI_FPA_TYPE_2D:
- stereo->type = AV_STEREO3D_2D;
- break;
- }
-
- if (fp->content_interpretation_type == 2)
- stereo->flags = AV_STEREO3D_FLAG_INVERT;
-
- if (fp->arrangement_type == H264_SEI_FPA_TYPE_INTERLEAVE_TEMPORAL) {
- if (fp->current_frame_is_frame0_flag)
- stereo->view = AV_STEREO3D_VIEW_LEFT;
- else
- stereo->view = AV_STEREO3D_VIEW_RIGHT;
- }
- }
- }
-
- if (h->sei.display_orientation.present &&
- (h->sei.display_orientation.anticlockwise_rotation ||
- h->sei.display_orientation.hflip ||
- h->sei.display_orientation.vflip)) {
- H264SEIDisplayOrientation *o = &h->sei.display_orientation;
- double angle = o->anticlockwise_rotation * 360 / (double) (1 << 16);
- AVFrameSideData *rotation = av_frame_new_side_data(out,
- AV_FRAME_DATA_DISPLAYMATRIX,
- sizeof(int32_t) * 9);
- if (rotation) {
- /* av_display_rotation_set() expects the angle in the clockwise
- * direction, hence the first minus.
- * The below code applies the flips after the rotation, yet
- * the H.2645 specs require flipping to be applied first.
- * Because of R O(phi) = O(-phi) R (where R is flipping around
- * an arbitatry axis and O(phi) is the proper rotation by phi)
- * we can create display matrices as desired by negating
- * the degree once for every flip applied. */
- angle = -angle * (1 - 2 * !!o->hflip) * (1 - 2 * !!o->vflip);
- av_display_rotation_set((int32_t *)rotation->data, angle);
- av_display_matrix_flip((int32_t *)rotation->data,
- o->hflip, o->vflip);
- }
- }
-
- if (h->sei.afd.present) {
- AVFrameSideData *sd = av_frame_new_side_data(out, AV_FRAME_DATA_AFD,
- sizeof(uint8_t));
-
- if (sd) {
- *sd->data = h->sei.afd.active_format_description;
- h->sei.afd.present = 0;
- }
- }
-
- if (h->sei.a53_caption.buf_ref) {
- H264SEIA53Caption *a53 = &h->sei.a53_caption;
-
- AVFrameSideData *sd = av_frame_new_side_data_from_buf(out, AV_FRAME_DATA_A53_CC, a53->buf_ref);
- if (!sd)
- av_buffer_unref(&a53->buf_ref);
- a53->buf_ref = NULL;
-
- h->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
- }
-
- for (int i = 0; i < h->sei.unregistered.nb_buf_ref; i++) {
- H264SEIUnregistered *unreg = &h->sei.unregistered;
-
- if (unreg->buf_ref[i]) {
- AVFrameSideData *sd = av_frame_new_side_data_from_buf(out,
- AV_FRAME_DATA_SEI_UNREGISTERED,
- unreg->buf_ref[i]);
- if (!sd)
- av_buffer_unref(&unreg->buf_ref[i]);
- unreg->buf_ref[i] = NULL;
- }
- }
- h->sei.unregistered.nb_buf_ref = 0;
-
- if (h->sei.film_grain_characteristics.present) {
- H264SEIFilmGrainCharacteristics *fgc = &h->sei.film_grain_characteristics;
- AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(out);
- if (!fgp)
- return AVERROR(ENOMEM);
-
- fgp->type = AV_FILM_GRAIN_PARAMS_H274;
- fgp->seed = cur->poc + (h->poc_offset << 5);
-
- fgp->codec.h274.model_id = fgc->model_id;
- if (fgc->separate_colour_description_present_flag) {
- fgp->codec.h274.bit_depth_luma = fgc->bit_depth_luma;
- fgp->codec.h274.bit_depth_chroma = fgc->bit_depth_chroma;
- fgp->codec.h274.color_range = fgc->full_range + 1;
- fgp->codec.h274.color_primaries = fgc->color_primaries;
- fgp->codec.h274.color_trc = fgc->transfer_characteristics;
- fgp->codec.h274.color_space = fgc->matrix_coeffs;
- } else {
- fgp->codec.h274.bit_depth_luma = sps->bit_depth_luma;
- fgp->codec.h274.bit_depth_chroma = sps->bit_depth_chroma;
- if (sps->video_signal_type_present_flag)
- fgp->codec.h274.color_range = sps->full_range + 1;
- else
- fgp->codec.h274.color_range = AVCOL_RANGE_UNSPECIFIED;
- if (sps->colour_description_present_flag) {
- fgp->codec.h274.color_primaries = sps->color_primaries;
- fgp->codec.h274.color_trc = sps->color_trc;
- fgp->codec.h274.color_space = sps->colorspace;
- } else {
- fgp->codec.h274.color_primaries = AVCOL_PRI_UNSPECIFIED;
- fgp->codec.h274.color_trc = AVCOL_TRC_UNSPECIFIED;
- fgp->codec.h274.color_space = AVCOL_SPC_UNSPECIFIED;
- }
- }
- fgp->codec.h274.blending_mode_id = fgc->blending_mode_id;
- fgp->codec.h274.log2_scale_factor = fgc->log2_scale_factor;
-
- memcpy(&fgp->codec.h274.component_model_present, &fgc->comp_model_present_flag,
- sizeof(fgp->codec.h274.component_model_present));
- memcpy(&fgp->codec.h274.num_intensity_intervals, &fgc->num_intensity_intervals,
- sizeof(fgp->codec.h274.num_intensity_intervals));
- memcpy(&fgp->codec.h274.num_model_values, &fgc->num_model_values,
- sizeof(fgp->codec.h274.num_model_values));
- memcpy(&fgp->codec.h274.intensity_interval_lower_bound, &fgc->intensity_interval_lower_bound,
- sizeof(fgp->codec.h274.intensity_interval_lower_bound));
- memcpy(&fgp->codec.h274.intensity_interval_upper_bound, &fgc->intensity_interval_upper_bound,
- sizeof(fgp->codec.h274.intensity_interval_upper_bound));
- memcpy(&fgp->codec.h274.comp_model_value, &fgc->comp_model_value,
- sizeof(fgp->codec.h274.comp_model_value));
-
- fgc->present = !!fgc->repetition_period;
-
- h->avctx->properties |= FF_CODEC_PROPERTY_FILM_GRAIN;
- }
+ ret = ff_h2645_sei_to_frame(out, &h->sei.common, AV_CODEC_ID_H264, h->avctx,
+ &sps->vui, sps->bit_depth_luma, sps->bit_depth_chroma,
+ cur->poc + (unsigned)(h->poc_offset << 5));
+ if (ret < 0)
+ return ret;
if (h->sei.picture_timing.timecode_cnt > 0) {
uint32_t *tc_sd;
@@ -1469,7 +1301,7 @@ static int h264_select_output_frame(H264Context *h)
h->last_pocs[0] = cur->poc;
cur->mmco_reset = 1;
} else if(h->avctx->has_b_frames < out_of_order && !sps->bitstream_restriction_flag){
- int loglevel = h->avctx->frame_number > 1 ? AV_LOG_WARNING : AV_LOG_VERBOSE;
+ int loglevel = h->avctx->frame_num > 1 ? AV_LOG_WARNING : AV_LOG_VERBOSE;
av_log(h->avctx, loglevel, "Increasing reorder buffer to %d\n", out_of_order);
h->avctx->has_b_frames = out_of_order;
}
@@ -1649,7 +1481,7 @@ static int h264_field_start(H264Context *h, const H264SliceContext *sl,
while (h->poc.frame_num != h->poc.prev_frame_num && !h->first_field &&
h->poc.frame_num != (h->poc.prev_frame_num + 1) % (1 << sps->log2_max_frame_num)) {
- H264Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;
+ const H264Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;
av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",
h->poc.frame_num, h->poc.prev_frame_num);
if (!sps->gaps_in_frame_num_allowed_flag)
diff --git a/libavcodec/h264chroma.h b/libavcodec/h264chroma.h
index 3259b4935..b8f9c8f4f 100644
--- a/libavcodec/h264chroma.h
+++ b/libavcodec/h264chroma.h
@@ -22,7 +22,7 @@
#include
#include
-typedef void (*h264_chroma_mc_func)(uint8_t *dst /*align 8*/, uint8_t *src /*align 1*/, ptrdiff_t srcStride, int h, int x, int y);
+typedef void (*h264_chroma_mc_func)(uint8_t *dst /*align 8*/, const uint8_t *src /*align 1*/, ptrdiff_t srcStride, int h, int x, int y);
typedef struct H264ChromaContext {
h264_chroma_mc_func put_h264_chroma_pixels_tab[4];
diff --git a/libavcodec/h264chroma_template.c b/libavcodec/h264chroma_template.c
index a3ca07b51..b9d24f5a0 100644
--- a/libavcodec/h264chroma_template.c
+++ b/libavcodec/h264chroma_template.c
@@ -26,9 +26,9 @@
#include "bit_depth_template.c"
#define H264_CHROMA_MC(OPNAME, OP)\
-static void FUNCC(OPNAME ## h264_chroma_mc1)(uint8_t *_dst /*align 8*/, uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y){\
+static void FUNCC(OPNAME ## h264_chroma_mc1)(uint8_t *_dst /*align 8*/, const uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y){\
pixel *dst = (pixel*)_dst;\
- pixel *src = (pixel*)_src;\
+ const pixel *src = (const pixel*)_src;\
const int A=(8-x)*(8-y);\
const int B=( x)*(8-y);\
const int C=(8-x)*( y);\
@@ -60,10 +60,10 @@ static void FUNCC(OPNAME ## h264_chroma_mc1)(uint8_t *_dst /*align 8*/, uint8_t
}\
}\
}\
-static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *_dst /*align 8*/, uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\
+static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *_dst /*align 8*/, const uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\
{\
pixel *dst = (pixel*)_dst;\
- pixel *src = (pixel*)_src;\
+ const pixel *src = (const pixel*)_src;\
const int A=(8-x)*(8-y);\
const int B=( x)*(8-y);\
const int C=(8-x)*( y);\
@@ -99,10 +99,10 @@ static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *_dst /*align 8*/, uint8_t
}\
}\
\
-static void FUNCC(OPNAME ## h264_chroma_mc4)(uint8_t *_dst /*align 8*/, uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\
+static void FUNCC(OPNAME ## h264_chroma_mc4)(uint8_t *_dst /*align 8*/, const uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\
{\
pixel *dst = (pixel*)_dst;\
- pixel *src = (pixel*)_src;\
+ const pixel *src = (const pixel*)_src;\
const int A=(8-x)*(8-y);\
const int B=( x)*(8-y);\
const int C=(8-x)*( y);\
@@ -144,10 +144,10 @@ static void FUNCC(OPNAME ## h264_chroma_mc4)(uint8_t *_dst /*align 8*/, uint8_t
}\
}\
\
-static void FUNCC(OPNAME ## h264_chroma_mc8)(uint8_t *_dst /*align 8*/, uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\
+static void FUNCC(OPNAME ## h264_chroma_mc8)(uint8_t *_dst /*align 8*/, const uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\
{\
pixel *dst = (pixel*)_dst;\
- pixel *src = (pixel*)_src;\
+ const pixel *src = (const pixel*)_src;\
const int A=(8-x)*(8-y);\
const int B=( x)*(8-y);\
const int C=(8-x)*( y);\
diff --git a/libavcodec/h264data.h b/libavcodec/h264data.h
index 4efe76a34..f809886ae 100644
--- a/libavcodec/h264data.h
+++ b/libavcodec/h264data.h
@@ -49,26 +49,6 @@ extern const PMbInfo ff_h264_p_sub_mb_type_info[4];
extern const PMbInfo ff_h264_b_mb_type_info[23];
extern const PMbInfo ff_h264_b_sub_mb_type_info[13];
-static const AVRational ff_h264_pixel_aspect[17] = {
- { 0, 1 },
- { 1, 1 },
- { 12, 11 },
- { 10, 11 },
- { 16, 11 },
- { 40, 33 },
- { 24, 11 },
- { 20, 11 },
- { 32, 11 },
- { 80, 33 },
- { 18, 11 },
- { 15, 11 },
- { 64, 33 },
- { 160, 99 },
- { 4, 3 },
- { 3, 2 },
- { 2, 1 },
-};
-
extern const uint8_t ff_h264_dequant4_coeff_init[6][3];
extern const uint8_t ff_h264_dequant8_coeff_init_scan[16];
extern const uint8_t ff_h264_dequant8_coeff_init[6][6];
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index 2a5b53ea5..2d691731c 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -296,8 +296,8 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h)
h->recovery_frame = -1;
h->frame_recovered = 0;
h->poc.prev_frame_num = -1;
- h->sei.frame_packing.arrangement_cancel_flag = -1;
- h->sei.unregistered.x264_build = -1;
+ h->sei.common.frame_packing.arrangement_cancel_flag = -1;
+ h->sei.common.unregistered.x264_build = -1;
h->next_outputed_poc = INT_MIN;
for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++)
@@ -382,12 +382,6 @@ static av_cold int h264_decode_init(AVCodecContext *avctx)
return AVERROR_UNKNOWN;
}
- if (avctx->ticks_per_frame == 1) {
- if(h->avctx->time_base.den < INT_MAX/2) {
- h->avctx->time_base.den *= 2;
- } else
- h->avctx->time_base.num /= 2;
- }
avctx->ticks_per_frame = 2;
if (!avctx->internal->is_copy) {
@@ -852,7 +846,7 @@ static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
if (srcp->needs_fg && (ret = av_frame_copy_props(dst, srcp->f)) < 0)
return ret;
- av_dict_set(&dst->metadata, "stereo_mode", ff_h264_sei_stereo_mode(&h->sei.frame_packing), 0);
+ av_dict_set(&dst->metadata, "stereo_mode", ff_h264_sei_stereo_mode(&h->sei.common.frame_packing), 0);
if (srcp->sei_recovery_frame_cnt == 0)
dst->key_frame = 1;
@@ -1068,14 +1062,14 @@ static const AVClass h264_class = {
const FFCodec ff_h264_decoder = {
.p.name = "h264",
- .p.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
+ CODEC_LONG_NAME("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_H264,
.priv_data_size = sizeof(H264Context),
.init = h264_decode_init,
.close = h264_decode_end,
FF_CODEC_DECODE_CB(h264_decode_frame),
- .p.capabilities = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ AV_CODEC_CAP_DR1 |
+ .p.capabilities = AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS |
AV_CODEC_CAP_FRAME_THREADS,
.hw_configs = (const AVCodecHWConfigInternal *const []) {
@@ -1102,11 +1096,11 @@ const FFCodec ff_h264_decoder = {
#endif
NULL
},
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING |
+ .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING |
FF_CODEC_CAP_ALLOCATE_PROGRESS | FF_CODEC_CAP_INIT_CLEANUP,
.flush = h264_decode_flush,
- .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context),
- .update_thread_context_for_user = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context_for_user),
+ UPDATE_THREAD_CONTEXT(ff_h264_update_thread_context),
+ UPDATE_THREAD_CONTEXT_FOR_USER(ff_h264_update_thread_context_for_user),
.p.profiles = NULL_IF_CONFIG_SMALL(ff_h264_profiles),
.p.priv_class = &h264_class,
};
diff --git a/libavcodec/h265_metadata_bsf.c b/libavcodec/h265_metadata_bsf.c
index ffcbbf012..6787bd14a 100644
--- a/libavcodec/h265_metadata_bsf.c
+++ b/libavcodec/h265_metadata_bsf.c
@@ -24,6 +24,7 @@
#include "cbs.h"
#include "cbs_bsf.h"
#include "cbs_h265.h"
+#include "h2645data.h"
#include "hevc.h"
#include "h265_profile_level.h"
@@ -194,25 +195,17 @@ static int h265_metadata_update_sps(AVBSFContext *bsf,
int crop_unit_x, crop_unit_y;
if (ctx->sample_aspect_ratio.num && ctx->sample_aspect_ratio.den) {
- // Table E-1.
- static const AVRational sar_idc[] = {
- { 0, 0 }, // Unspecified (never written here).
- { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 },
- { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 },
- { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 },
- { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 },
- };
int num, den, i;
av_reduce(&num, &den, ctx->sample_aspect_ratio.num,
ctx->sample_aspect_ratio.den, 65535);
- for (i = 1; i < FF_ARRAY_ELEMS(sar_idc); i++) {
- if (num == sar_idc[i].num &&
- den == sar_idc[i].den)
+ for (i = 1; i < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect); i++) {
+ if (num == ff_h2645_pixel_aspect[i].num &&
+ den == ff_h2645_pixel_aspect[i].den)
break;
}
- if (i == FF_ARRAY_ELEMS(sar_idc)) {
+ if (i == FF_ARRAY_ELEMS(ff_h2645_pixel_aspect)) {
sps->vui.aspect_ratio_idc = 255;
sps->vui.sar_width = num;
sps->vui.sar_height = den;
diff --git a/libavcodec/h274.h b/libavcodec/h274.h
index 807b3a016..920f6991f 100644
--- a/libavcodec/h274.h
+++ b/libavcodec/h274.h
@@ -28,7 +28,7 @@
#ifndef AVCODEC_H274_H
#define AVCODEC_H274_H
-#include
+#include "libavutil/film_grain_params.h"
// Must be initialized to {0} prior to first usage
typedef struct H274FilmGrainDatabase {
diff --git a/libavcodec/fft_fixed.c b/libavcodec/half2float.c
similarity index 91%
rename from libavcodec/fft_fixed.c
rename to libavcodec/half2float.c
index 3d3bd2fca..1b023f96a 100644
--- a/libavcodec/fft_fixed.c
+++ b/libavcodec/half2float.c
@@ -16,6 +16,4 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define FFT_FLOAT 0
-#define FFT_FIXED_32 0
-#include "fft_template.c"
+#include "libavutil/half2float.c"
diff --git a/libavcodec/hapdec.c b/libavcodec/hapdec.c
index 0aab1ab87..3df69e633 100644
--- a/libavcodec/hapdec.c
+++ b/libavcodec/hapdec.c
@@ -414,7 +414,7 @@ static av_cold int hap_close(AVCodecContext *avctx)
const FFCodec ff_hap_decoder = {
.p.name = "hap",
- .p.long_name = NULL_IF_CONFIG_SMALL("Vidvox Hap"),
+ CODEC_LONG_NAME("Vidvox Hap"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_HAP,
.init = hap_init,
@@ -423,8 +423,7 @@ const FFCodec ff_hap_decoder = {
.priv_data_size = sizeof(HapContext),
.p.capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS |
AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.codec_tags = (const uint32_t []){
MKTAG('H','a','p','1'),
MKTAG('H','a','p','5'),
diff --git a/libavcodec/hapenc.c b/libavcodec/hapenc.c
index 6a9d4e06c..7de7358e3 100644
--- a/libavcodec/hapenc.c
+++ b/libavcodec/hapenc.c
@@ -348,18 +348,18 @@ static const AVClass hapenc_class = {
const FFCodec ff_hap_encoder = {
.p.name = "hap",
- .p.long_name = NULL_IF_CONFIG_SMALL("Vidvox Hap"),
+ CODEC_LONG_NAME("Vidvox Hap"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_HAP,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(HapContext),
.p.priv_class = &hapenc_class,
- .p.capabilities = AV_CODEC_CAP_SLICE_THREADS,
.init = hap_init,
FF_CODEC_ENCODE_CB(hap_encode),
.close = hap_close,
.p.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_RGBA, AV_PIX_FMT_NONE,
},
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/hcadec.c b/libavcodec/hcadec.c
index 705457587..2f019a821 100644
--- a/libavcodec/hcadec.c
+++ b/libavcodec/hcadec.c
@@ -18,15 +18,14 @@
#include "libavutil/crc.h"
#include "libavutil/float_dsp.h"
-#include "libavutil/intreadwrite.h"
#include "libavutil/mem_internal.h"
#include "libavutil/tx.h"
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
#include "hca_data.h"
typedef struct ChannelContext {
@@ -442,7 +441,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
const FFCodec ff_hca_decoder = {
.p.name = "hca",
- .p.long_name = NULL_IF_CONFIG_SMALL("CRI HCA"),
+ CODEC_LONG_NAME("CRI HCA"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_HCA,
.priv_data_size = sizeof(HCAContext),
@@ -450,7 +449,7 @@ const FFCodec ff_hca_decoder = {
FF_CODEC_DECODE_CB(decode_frame),
.close = decode_close,
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
};
diff --git a/libavcodec/hcom.c b/libavcodec/hcom.c
index 74a13e004..9284cd11c 100644
--- a/libavcodec/hcom.c
+++ b/libavcodec/hcom.c
@@ -22,8 +22,8 @@
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
typedef struct HEntry {
int16_t l, r;
@@ -136,7 +136,7 @@ static av_cold int hcom_close(AVCodecContext *avctx)
const FFCodec ff_hcom_decoder = {
.p.name = "hcom",
- .p.long_name = NULL_IF_CONFIG_SMALL("HCOM Audio"),
+ CODEC_LONG_NAME("HCOM Audio"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_HCOM,
.priv_data_size = sizeof(HCOMContext),
@@ -144,5 +144,5 @@ const FFCodec ff_hcom_decoder = {
.close = hcom_close,
FF_CODEC_DECODE_CB(hcom_decode),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/hdr_parser.c b/libavcodec/hdr_parser.c
new file mode 100644
index 000000000..915fd3822
--- /dev/null
+++ b/libavcodec/hdr_parser.c
@@ -0,0 +1,79 @@
+/*
+ * Radiance HDR parser
+ * Copyright (c) 2022 Paul B Mahol
+ *
+ * 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
+ * Radiance HDR parser
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "parser.h"
+
+typedef struct HDRParseContext {
+ ParseContext pc;
+} HDRParseContext;
+
+static int hdr_parse(AVCodecParserContext *s, AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ HDRParseContext *ipc = s->priv_data;
+ uint64_t state = ipc->pc.state64;
+ int next = END_NOT_FOUND, i = 0;
+
+ *poutbuf_size = 0;
+ *poutbuf = NULL;
+
+ if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
+ next = buf_size;
+ } else {
+ for (; i < buf_size; i++) {
+ state = (state << 8) | buf[i];
+ if (state == AV_RB64("ADIANCE\n") && (i > 10 || ipc->pc.index > 10)) {
+ next = i - 10;
+ break;
+ }
+ }
+
+ ipc->pc.state64 = state;
+ if (ff_combine_frame(&ipc->pc, next, &buf, &buf_size) < 0) {
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
+ }
+
+ *poutbuf = buf;
+ *poutbuf_size = buf_size;
+
+ s->pict_type = AV_PICTURE_TYPE_I;
+ s->key_frame = 1;
+ s->duration = 1;
+
+ return next;
+}
+
+const AVCodecParser ff_hdr_parser = {
+ .codec_ids = { AV_CODEC_ID_RADIANCE_HDR },
+ .priv_data_size = sizeof(HDRParseContext),
+ .parser_parse = hdr_parse,
+ .parser_close = ff_parse_close,
+};
diff --git a/libavcodec/hdrdec.c b/libavcodec/hdrdec.c
new file mode 100644
index 000000000..998227744
--- /dev/null
+++ b/libavcodec/hdrdec.c
@@ -0,0 +1,231 @@
+/*
+ * Radiance HDR image format
+ *
+ * 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 "bytestream.h"
+#include "codec_internal.h"
+#include "decode.h"
+#include "thread.h"
+
+#define MINELEN 8
+#define MAXELEN 0x7fff
+
+static int hdr_get_line(GetByteContext *gb, uint8_t *buffer, int size)
+{
+ int n = 0, c;
+
+ memset(buffer, 0, size);
+
+ do {
+ c = bytestream2_get_byte(gb);
+ if (n < size - 1)
+ buffer[n++] = c;
+ } while (bytestream2_get_bytes_left(gb) > 0 && c != '\n');
+
+ return 0;
+}
+
+static float convert(int expo, int val)
+{
+ if (expo == -128) {
+ return 0.f;
+ } else {
+ const float v = val / 256.f;
+
+ return ldexpf(v, expo);
+ }
+}
+
+static int decompress(uint8_t *scanline, int w, GetByteContext *gb, const uint8_t *start)
+{
+ int rshift = 0;
+
+ while (w > 0) {
+ if (bytestream2_get_bytes_left(gb) < 4)
+ return AVERROR_INVALIDDATA;
+ scanline[0] = bytestream2_get_byte(gb);
+ scanline[1] = bytestream2_get_byte(gb);
+ scanline[2] = bytestream2_get_byte(gb);
+ scanline[3] = bytestream2_get_byte(gb);
+
+ if (scanline[0] == 1 &&
+ scanline[1] == 1 &&
+ scanline[2] == 1) {
+ int run = scanline[3];
+ for (int i = run << rshift; i > 0 && w > 0 && scanline >= start + 4; i--) {
+ memcpy(scanline, scanline - 4, 4);
+ scanline += 4;
+ w -= 4;
+ }
+ rshift += 8;
+ if (rshift > 16)
+ break;
+ } else {
+ scanline += 4;
+ w--;
+ rshift = 0;
+ }
+ }
+
+ return 1;
+}
+
+static int hdr_decode_frame(AVCodecContext *avctx, AVFrame *p,
+ int *got_frame, AVPacket *avpkt)
+{
+ int width = 0, height = 0;
+ GetByteContext gb;
+ uint8_t line[512];
+ float sar;
+ int ret;
+
+ bytestream2_init(&gb, avpkt->data, avpkt->size);
+ hdr_get_line(&gb, line, sizeof(line));
+ if (memcmp("#?RADIANCE\n", line, 11))
+ return AVERROR_INVALIDDATA;
+
+ do {
+ hdr_get_line(&gb, line, sizeof(line));
+ if (sscanf(line, "PIXASPECT=%f\n", &sar) == 1)
+ avctx->sample_aspect_ratio = p->sample_aspect_ratio = av_inv_q(av_d2q(sar, 4096));
+ } while (line[0] != '\n' && line[0]);
+
+ hdr_get_line(&gb, line, sizeof(line));
+ if (sscanf(line, "-Y %d +X %d\n", &height, &width) == 2) {
+ ;
+ } else if (sscanf(line, "+Y %d +X %d\n", &height, &width) == 2) {
+ ;
+ } else if (sscanf(line, "-Y %d -X %d\n", &height, &width) == 2) {
+ ;
+ } else if (sscanf(line, "+Y %d -X %d\n", &height, &width) == 2) {
+ ;
+ } else if (sscanf(line, "-X %d +Y %d\n", &width, &height) == 2) {
+ ;
+ } else if (sscanf(line, "+X %d +Y %d\n", &width, &height) == 2) {
+ ;
+ } else if (sscanf(line, "-X %d -Y %d\n", &width, &height) == 2) {
+ ;
+ } else if (sscanf(line, "+X %d -Y %d\n", &width, &height) == 2) {
+ ;
+ }
+
+ if ((ret = ff_set_dimensions(avctx, width, height)) < 0)
+ return ret;
+
+ avctx->pix_fmt = AV_PIX_FMT_GBRPF32;
+
+ if (avctx->skip_frame >= AVDISCARD_ALL)
+ return avpkt->size;
+
+ if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
+ return ret;
+
+ for (int y = 0; y < height; y++) {
+ float *dst_r = (float *)(p->data[2] + y * p->linesize[2]);
+ float *dst_g = (float *)(p->data[0] + y * p->linesize[0]);
+ float *dst_b = (float *)(p->data[1] + y * p->linesize[1]);
+ uint8_t *scanline = p->data[0] + y * p->linesize[0];
+ int i;
+
+ if (width < MINELEN || width > MAXELEN) {
+ ret = decompress(scanline, width, &gb, scanline);
+ if (ret < 0)
+ return ret;
+ goto convert;
+ }
+
+ i = bytestream2_peek_byte(&gb);
+ if (i != 2) {
+ ret = decompress(scanline, width, &gb, scanline);
+ if (ret < 0)
+ return ret;
+ goto convert;
+ }
+ bytestream2_skip(&gb, 1);
+
+ scanline[1] = bytestream2_get_byte(&gb);
+ scanline[2] = bytestream2_get_byte(&gb);
+ i = bytestream2_get_byte(&gb);
+
+ if (scanline[1] != 2 || scanline[2] & 128) {
+ scanline[0] = 2;
+ scanline[3] = i;
+ ret = decompress(scanline + 4, width - 1, &gb, scanline);
+ if (ret < 0)
+ return ret;
+ goto convert;
+ }
+
+ for (int i = 0; i < 4; i++) {
+ uint8_t *scanline = p->data[0] + y * p->linesize[0] + i;
+
+ for (int j = 0; j < width * 4 && bytestream2_get_bytes_left(&gb) > 0;) {
+ int run = bytestream2_get_byte(&gb);
+ if (run > 128) {
+ uint8_t val = bytestream2_get_byte(&gb);
+ run &= 127;
+ while (run--) {
+ if (j >= width * 4)
+ break;
+ scanline[j] = val;
+ j += 4;
+ }
+ } else if (run > 0) {
+ while (run--) {
+ if (j >= width * 4)
+ break;
+ scanline[j] = bytestream2_get_byte(&gb);
+ j += 4;
+ }
+ }
+ }
+ }
+
+convert:
+ for (int x = 0; x < width; x++) {
+ uint8_t rgbe[4];
+ int expo;
+
+ memcpy(rgbe, p->data[0] + y * p->linesize[0] + x * 4, 4);
+ expo = rgbe[3] - 128;
+
+ dst_r[x] = convert(expo, rgbe[0]);
+ dst_b[x] = convert(expo, rgbe[2]);
+ dst_g[x] = convert(expo, rgbe[1]);
+ }
+ }
+
+ p->key_frame = 1;
+ p->pict_type = AV_PICTURE_TYPE_I;
+
+ *got_frame = 1;
+
+ return avpkt->size;
+}
+
+const FFCodec ff_hdr_decoder = {
+ .p.name = "hdr",
+ CODEC_LONG_NAME("HDR (Radiance RGBE format) image"),
+ .p.type = AVMEDIA_TYPE_VIDEO,
+ .p.id = AV_CODEC_ID_RADIANCE_HDR,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+ .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
+ FF_CODEC_DECODE_CB(hdr_decode_frame),
+};
diff --git a/libavcodec/hdrenc.c b/libavcodec/hdrenc.c
new file mode 100644
index 000000000..40d283ee6
--- /dev/null
+++ b/libavcodec/hdrenc.c
@@ -0,0 +1,190 @@
+/*
+ * Radiance HDR image format
+ *
+ * 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/imgutils.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "codec_internal.h"
+#include "encode.h"
+
+typedef struct HDREncContext {
+ uint8_t *scanline;
+} HDREncContext;
+
+static av_cold int hdr_encode_init(AVCodecContext *avctx)
+{
+ HDREncContext *s = avctx->priv_data;
+
+ s->scanline = av_calloc(avctx->width * 4, sizeof(*s->scanline));
+ if (!s->scanline)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static av_cold int hdr_encode_close(AVCodecContext *avctx)
+{
+ HDREncContext *s = avctx->priv_data;
+
+ av_freep(&s->scanline);
+
+ return 0;
+}
+
+static void bytestream_put_str(uint8_t **buf, const char *const line)
+{
+ bytestream_put_buffer(buf, line, strlen(line));
+}
+
+static void float2rgbe(uint8_t *rgbe, float red, float green, float blue)
+{
+ float v;
+ int e;
+
+ v = FFMAX3(red, green, blue);
+
+ if (v < 1e-32f) {
+ rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
+ } else {
+ v = frexpf(v, &e) * 256.f / v;
+
+ rgbe[0] = av_clip_uint8(red * v);
+ rgbe[1] = av_clip_uint8(green * v);
+ rgbe[2] = av_clip_uint8(blue * v);
+ rgbe[3] = av_clip_uint8(e + 128);
+ }
+}
+
+static void rle(uint8_t **buffer, const uint8_t *data, int width)
+{
+#define MIN_RLE 4
+ int cur = 0;
+
+ while (cur < width) {
+ int run_count = 0, old_run_count = 0;
+ int beg_run = cur;
+ uint8_t buf[2];
+
+ while (run_count < MIN_RLE && beg_run < width) {
+ beg_run += run_count;
+ old_run_count = run_count;
+ run_count = 1;
+ while ((beg_run + run_count < width) && (run_count < 127) &&
+ (data[beg_run * 4] == data[(beg_run + run_count) * 4]))
+ run_count++;
+ }
+
+ if ((old_run_count > 1) && (old_run_count == beg_run - cur)) {
+ buf[0] = 128 + old_run_count;
+ buf[1] = data[cur * 4];
+ bytestream_put_buffer(buffer, buf, sizeof(buf));
+ cur = beg_run;
+ }
+
+ while (cur < beg_run) {
+ int nonrun_count = FFMIN(128, beg_run - cur);
+ buf[0] = nonrun_count;
+ bytestream_put_byte(buffer, buf[0]);
+ for (int n = 0; n < nonrun_count; n++)
+ bytestream_put_byte(buffer, data[(cur + n) * 4]);
+ cur += nonrun_count;
+ }
+
+ if (run_count >= MIN_RLE) {
+ buf[0] = 128 + run_count;
+ buf[1] = data[beg_run * 4];
+ bytestream_put_buffer(buffer, buf, sizeof(buf));
+ cur += run_count;
+ }
+ }
+}
+
+static int hdr_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+ const AVFrame *frame, int *got_packet)
+{
+ HDREncContext *s = avctx->priv_data;
+ int64_t packet_size;
+ uint8_t *buf;
+ int ret;
+
+ packet_size = avctx->width * avctx->height * 4LL + 1024LL;
+ if ((ret = ff_get_encode_buffer(avctx, pkt, packet_size, 0)) < 0)
+ return ret;
+
+ buf = pkt->data;
+ bytestream_put_str(&buf, "#?RADIANCE\n");
+ bytestream_put_str(&buf, "SOFTWARE=lavc\n");
+ ret = snprintf(buf, 32, "PIXASPECT=%f\n", av_q2d(av_inv_q(avctx->sample_aspect_ratio)));
+ if (ret > 0)
+ buf += ret;
+ bytestream_put_str(&buf, "FORMAT=32-bit_rle_rgbe\n\n");
+ ret = snprintf(buf, 32, "-Y %d +X %d\n", avctx->height, avctx->width);
+ if (ret > 0)
+ buf += ret;
+
+ for (int y = 0; y < avctx->height; y++) {
+ const float *red = (const float *)(frame->data[2] + y * frame->linesize[2]);
+ const float *green = (const float *)(frame->data[0] + y * frame->linesize[0]);
+ const float *blue = (const float *)(frame->data[1] + y * frame->linesize[1]);
+
+ if (avctx->width < 8 || avctx->width > 0x7fff) {
+ for (int x = 0; x < avctx->width; x++) {
+ float2rgbe(buf, red[x], green[x], blue[x]);
+ buf += 4;
+ }
+ } else {
+ bytestream_put_byte(&buf, 2);
+ bytestream_put_byte(&buf, 2);
+ bytestream_put_byte(&buf, avctx->width >> 8);
+ bytestream_put_byte(&buf, avctx->width & 0xFF);
+
+ for (int x = 0; x < avctx->width; x++)
+ float2rgbe(s->scanline + 4 * x, red[x], green[x], blue[x]);
+ for (int p = 0; p < 4; p++)
+ rle(&buf, s->scanline + p, avctx->width);
+ }
+ }
+
+ pkt->flags |= AV_PKT_FLAG_KEY;
+
+ av_shrink_packet(pkt, buf - pkt->data);
+
+ *got_packet = 1;
+
+ return 0;
+}
+
+const FFCodec ff_hdr_encoder = {
+ .p.name = "hdr",
+ CODEC_LONG_NAME("HDR (Radiance RGBE format) image"),
+ .priv_data_size = sizeof(HDREncContext),
+ .p.type = AVMEDIA_TYPE_VIDEO,
+ .p.id = AV_CODEC_ID_RADIANCE_HDR,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ .init = hdr_encode_init,
+ FF_CODEC_ENCODE_CB(hdr_encode_frame),
+ .close = hdr_encode_close,
+ .p.pix_fmts = (const enum AVPixelFormat[]){
+ AV_PIX_FMT_GBRPF32,
+ AV_PIX_FMT_NONE
+ },
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
+};
diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c
index a194f8a02..6b38da84b 100644
--- a/libavcodec/hevc_cabac.c
+++ b/libavcodec/hevc_cabac.c
@@ -447,25 +447,26 @@ static const uint8_t diag_scan8x8_inv[8][8] = {
{ 28, 36, 43, 49, 54, 58, 61, 63, },
};
-void ff_hevc_save_states(HEVCContext *s, int ctb_addr_ts)
+void ff_hevc_save_states(HEVCLocalContext *lc, int ctb_addr_ts)
{
+ const HEVCContext *const s = lc->parent;
+
if (s->ps.pps->entropy_coding_sync_enabled_flag &&
(ctb_addr_ts % s->ps.sps->ctb_width == 2 ||
(s->ps.sps->ctb_width == 2 &&
ctb_addr_ts % s->ps.sps->ctb_width == 0))) {
- memcpy(s->cabac_state, s->HEVClc->cabac_state, HEVC_CONTEXTS);
+ memcpy(lc->common_cabac_state->state, lc->cabac_state, HEVC_CONTEXTS);
if (s->ps.sps->persistent_rice_adaptation_enabled_flag) {
- memcpy(s->stat_coeff, s->HEVClc->stat_coeff, HEVC_STAT_COEFFS);
+ memcpy(lc->common_cabac_state->stat_coeff, lc->stat_coeff, HEVC_STAT_COEFFS);
}
}
}
-static void load_states(HEVCContext *s, int thread)
+static void load_states(HEVCLocalContext *lc, const HEVCContext *s)
{
- memcpy(s->HEVClc->cabac_state, s->cabac_state, HEVC_CONTEXTS);
+ memcpy(lc->cabac_state, lc->common_cabac_state->state, HEVC_CONTEXTS);
if (s->ps.sps->persistent_rice_adaptation_enabled_flag) {
- const HEVCContext *prev = s->sList[(thread + s->threads_number - 1) % s->threads_number];
- memcpy(s->HEVClc->stat_coeff, prev->stat_coeff, HEVC_STAT_COEFFS);
+ memcpy(lc->stat_coeff, lc->common_cabac_state->stat_coeff, HEVC_STAT_COEFFS);
}
}
@@ -474,17 +475,17 @@ static int cabac_reinit(HEVCLocalContext *lc)
return skip_bytes(&lc->cc, 0) == NULL ? AVERROR_INVALIDDATA : 0;
}
-static int cabac_init_decoder(HEVCContext *s)
+static int cabac_init_decoder(HEVCLocalContext *lc)
{
- GetBitContext *gb = &s->HEVClc->gb;
+ GetBitContext *gb = &lc->gb;
skip_bits(gb, 1);
align_get_bits(gb);
- return ff_init_cabac_decoder(&s->HEVClc->cc,
+ return ff_init_cabac_decoder(&lc->cc,
gb->buffer + get_bits_count(gb) / 8,
(get_bits_left(gb) + 7) / 8);
}
-static void cabac_init_state(HEVCContext *s)
+static void cabac_init_state(HEVCLocalContext *lc, const HEVCContext *s)
{
int init_type = 2 - s->sh.slice_type;
int i;
@@ -501,31 +502,33 @@ static void cabac_init_state(HEVCContext *s)
pre ^= pre >> 31;
if (pre > 124)
pre = 124 + (pre & 1);
- s->HEVClc->cabac_state[i] = pre;
+ lc->cabac_state[i] = pre;
}
for (i = 0; i < 4; i++)
- s->HEVClc->stat_coeff[i] = 0;
+ lc->stat_coeff[i] = 0;
}
-int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts, int thread)
+int ff_hevc_cabac_init(HEVCLocalContext *lc, int ctb_addr_ts)
{
+ const HEVCContext *const s = lc->parent;
+
if (ctb_addr_ts == s->ps.pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs]) {
- int ret = cabac_init_decoder(s);
+ int ret = cabac_init_decoder(lc);
if (ret < 0)
return ret;
if (s->sh.dependent_slice_segment_flag == 0 ||
(s->ps.pps->tiles_enabled_flag &&
s->ps.pps->tile_id[ctb_addr_ts] != s->ps.pps->tile_id[ctb_addr_ts - 1]))
- cabac_init_state(s);
+ cabac_init_state(lc, s);
if (!s->sh.first_slice_in_pic_flag &&
s->ps.pps->entropy_coding_sync_enabled_flag) {
if (ctb_addr_ts % s->ps.sps->ctb_width == 0) {
if (s->ps.sps->ctb_width == 1)
- cabac_init_state(s);
+ cabac_init_state(lc, s);
else if (s->sh.dependent_slice_segment_flag == 1)
- load_states(s, thread);
+ load_states(lc, s);
}
}
} else {
@@ -533,111 +536,112 @@ int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts, int thread)
s->ps.pps->tile_id[ctb_addr_ts] != s->ps.pps->tile_id[ctb_addr_ts - 1]) {
int ret;
if (s->threads_number == 1)
- ret = cabac_reinit(s->HEVClc);
+ ret = cabac_reinit(lc);
else {
- ret = cabac_init_decoder(s);
+ ret = cabac_init_decoder(lc);
}
if (ret < 0)
return ret;
- cabac_init_state(s);
+ cabac_init_state(lc, s);
}
if (s->ps.pps->entropy_coding_sync_enabled_flag) {
if (ctb_addr_ts % s->ps.sps->ctb_width == 0) {
int ret;
- get_cabac_terminate(&s->HEVClc->cc);
+ get_cabac_terminate(&lc->cc);
if (s->threads_number == 1)
- ret = cabac_reinit(s->HEVClc);
+ ret = cabac_reinit(lc);
else {
- ret = cabac_init_decoder(s);
+ ret = cabac_init_decoder(lc);
}
if (ret < 0)
return ret;
if (s->ps.sps->ctb_width == 1)
- cabac_init_state(s);
+ cabac_init_state(lc, s);
else
- load_states(s, thread);
+ load_states(lc, s);
}
}
}
return 0;
}
-#define GET_CABAC(ctx) get_cabac(&s->HEVClc->cc, &s->HEVClc->cabac_state[ctx])
+#define GET_CABAC(ctx) get_cabac(&lc->cc, &lc->cabac_state[ctx])
-int ff_hevc_sao_merge_flag_decode(HEVCContext *s)
+int ff_hevc_sao_merge_flag_decode(HEVCLocalContext *lc)
{
return GET_CABAC(elem_offset[SAO_MERGE_FLAG]);
}
-int ff_hevc_sao_type_idx_decode(HEVCContext *s)
+int ff_hevc_sao_type_idx_decode(HEVCLocalContext *lc)
{
if (!GET_CABAC(elem_offset[SAO_TYPE_IDX]))
return 0;
- if (!get_cabac_bypass(&s->HEVClc->cc))
+ if (!get_cabac_bypass(&lc->cc))
return SAO_BAND;
return SAO_EDGE;
}
-int ff_hevc_sao_band_position_decode(HEVCContext *s)
+int ff_hevc_sao_band_position_decode(HEVCLocalContext *lc)
{
int i;
- int value = get_cabac_bypass(&s->HEVClc->cc);
+ int value = get_cabac_bypass(&lc->cc);
for (i = 0; i < 4; i++)
- value = (value << 1) | get_cabac_bypass(&s->HEVClc->cc);
+ value = (value << 1) | get_cabac_bypass(&lc->cc);
return value;
}
-int ff_hevc_sao_offset_abs_decode(HEVCContext *s)
+int ff_hevc_sao_offset_abs_decode(HEVCLocalContext *lc)
{
int i = 0;
- int length = (1 << (FFMIN(s->ps.sps->bit_depth, 10) - 5)) - 1;
+ int length = (1 << (FFMIN(lc->parent->ps.sps->bit_depth, 10) - 5)) - 1;
- while (i < length && get_cabac_bypass(&s->HEVClc->cc))
+ while (i < length && get_cabac_bypass(&lc->cc))
i++;
return i;
}
-int ff_hevc_sao_offset_sign_decode(HEVCContext *s)
+int ff_hevc_sao_offset_sign_decode(HEVCLocalContext *lc)
{
- return get_cabac_bypass(&s->HEVClc->cc);
+ return get_cabac_bypass(&lc->cc);
}
-int ff_hevc_sao_eo_class_decode(HEVCContext *s)
+int ff_hevc_sao_eo_class_decode(HEVCLocalContext *lc)
{
- int ret = get_cabac_bypass(&s->HEVClc->cc) << 1;
- ret |= get_cabac_bypass(&s->HEVClc->cc);
+ int ret = get_cabac_bypass(&lc->cc) << 1;
+ ret |= get_cabac_bypass(&lc->cc);
return ret;
}
-int ff_hevc_end_of_slice_flag_decode(HEVCContext *s)
+int ff_hevc_end_of_slice_flag_decode(HEVCLocalContext *lc)
{
- return get_cabac_terminate(&s->HEVClc->cc);
+ return get_cabac_terminate(&lc->cc);
}
-int ff_hevc_cu_transquant_bypass_flag_decode(HEVCContext *s)
+int ff_hevc_cu_transquant_bypass_flag_decode(HEVCLocalContext *lc)
{
return GET_CABAC(elem_offset[CU_TRANSQUANT_BYPASS_FLAG]);
}
-int ff_hevc_skip_flag_decode(HEVCContext *s, int x0, int y0, int x_cb, int y_cb)
+int ff_hevc_skip_flag_decode(HEVCLocalContext *lc, int x0, int y0, int x_cb, int y_cb)
{
+ const HEVCContext *const s = lc->parent;
int min_cb_width = s->ps.sps->min_cb_width;
int inc = 0;
int x0b = av_mod_uintp2(x0, s->ps.sps->log2_ctb_size);
int y0b = av_mod_uintp2(y0, s->ps.sps->log2_ctb_size);
- if (s->HEVClc->ctb_left_flag || x0b)
+ if (lc->ctb_left_flag || x0b)
inc = !!SAMPLE_CTB(s->skip_flag, x_cb - 1, y_cb);
- if (s->HEVClc->ctb_up_flag || y0b)
+ if (lc->ctb_up_flag || y0b)
inc += !!SAMPLE_CTB(s->skip_flag, x_cb, y_cb - 1);
return GET_CABAC(elem_offset[SKIP_FLAG] + inc);
}
-int ff_hevc_cu_qp_delta_abs(HEVCContext *s)
+int ff_hevc_cu_qp_delta_abs(HEVCLocalContext *lc)
{
int prefix_val = 0;
int suffix_val = 0;
@@ -649,34 +653,34 @@ int ff_hevc_cu_qp_delta_abs(HEVCContext *s)
}
if (prefix_val >= 5) {
int k = 0;
- while (k < 7 && get_cabac_bypass(&s->HEVClc->cc)) {
+ while (k < 7 && get_cabac_bypass(&lc->cc)) {
suffix_val += 1 << k;
k++;
}
if (k == 7) {
- av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", k);
+ av_log(lc->logctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", k);
return AVERROR_INVALIDDATA;
}
while (k--)
- suffix_val += get_cabac_bypass(&s->HEVClc->cc) << k;
+ suffix_val += get_cabac_bypass(&lc->cc) << k;
}
return prefix_val + suffix_val;
}
-int ff_hevc_cu_qp_delta_sign_flag(HEVCContext *s)
+int ff_hevc_cu_qp_delta_sign_flag(HEVCLocalContext *lc)
{
- return get_cabac_bypass(&s->HEVClc->cc);
+ return get_cabac_bypass(&lc->cc);
}
-int ff_hevc_cu_chroma_qp_offset_flag(HEVCContext *s)
+int ff_hevc_cu_chroma_qp_offset_flag(HEVCLocalContext *lc)
{
return GET_CABAC(elem_offset[CU_CHROMA_QP_OFFSET_FLAG]);
}
-int ff_hevc_cu_chroma_qp_offset_idx(HEVCContext *s)
+int ff_hevc_cu_chroma_qp_offset_idx(HEVCLocalContext *lc)
{
- int c_max= FFMAX(5, s->ps.pps->chroma_qp_offset_list_len_minus1);
+ int c_max= FFMAX(5, lc->parent->ps.pps->chroma_qp_offset_list_len_minus1);
int i = 0;
while (i < c_max && GET_CABAC(elem_offset[CU_CHROMA_QP_OFFSET_IDX]))
@@ -685,23 +689,25 @@ int ff_hevc_cu_chroma_qp_offset_idx(HEVCContext *s)
return i;
}
-int ff_hevc_pred_mode_decode(HEVCContext *s)
+int ff_hevc_pred_mode_decode(HEVCLocalContext *lc)
{
return GET_CABAC(elem_offset[PRED_MODE_FLAG]);
}
-int ff_hevc_split_coding_unit_flag_decode(HEVCContext *s, int ct_depth, int x0, int y0)
+int ff_hevc_split_coding_unit_flag_decode(HEVCLocalContext *lc, int ct_depth, int x0, int y0)
{
+ const HEVCContext *const s = lc->parent;
+ const HEVCSPS *const sps = s->ps.sps;
int inc = 0, depth_left = 0, depth_top = 0;
- int x0b = av_mod_uintp2(x0, s->ps.sps->log2_ctb_size);
- int y0b = av_mod_uintp2(y0, s->ps.sps->log2_ctb_size);
- int x_cb = x0 >> s->ps.sps->log2_min_cb_size;
- int y_cb = y0 >> s->ps.sps->log2_min_cb_size;
+ int x0b = av_mod_uintp2(x0, sps->log2_ctb_size);
+ int y0b = av_mod_uintp2(y0, sps->log2_ctb_size);
+ int x_cb = x0 >> sps->log2_min_cb_size;
+ int y_cb = y0 >> sps->log2_min_cb_size;
- if (s->HEVClc->ctb_left_flag || x0b)
- depth_left = s->tab_ct_depth[(y_cb) * s->ps.sps->min_cb_width + x_cb - 1];
- if (s->HEVClc->ctb_up_flag || y0b)
- depth_top = s->tab_ct_depth[(y_cb - 1) * s->ps.sps->min_cb_width + x_cb];
+ if (lc->ctb_left_flag || x0b)
+ depth_left = s->tab_ct_depth[(y_cb) * sps->min_cb_width + x_cb - 1];
+ if (lc->ctb_up_flag || y0b)
+ depth_top = s->tab_ct_depth[(y_cb - 1) * sps->min_cb_width + x_cb];
inc += (depth_left > ct_depth);
inc += (depth_top > ct_depth);
@@ -709,12 +715,12 @@ int ff_hevc_split_coding_unit_flag_decode(HEVCContext *s, int ct_depth, int x0,
return GET_CABAC(elem_offset[SPLIT_CODING_UNIT_FLAG] + inc);
}
-int ff_hevc_part_mode_decode(HEVCContext *s, int log2_cb_size)
+int ff_hevc_part_mode_decode(HEVCLocalContext *lc, int log2_cb_size)
{
if (GET_CABAC(elem_offset[PART_MODE])) // 1
return PART_2Nx2N;
- if (log2_cb_size == s->ps.sps->log2_min_cb_size) {
- if (s->HEVClc->cu.pred_mode == MODE_INTRA) // 0
+ if (log2_cb_size == lc->parent->ps.sps->log2_min_cb_size) {
+ if (lc->cu.pred_mode == MODE_INTRA) // 0
return PART_NxN;
if (GET_CABAC(elem_offset[PART_MODE] + 1)) // 01
return PART_2NxN;
@@ -725,7 +731,7 @@ int ff_hevc_part_mode_decode(HEVCContext *s, int log2_cb_size)
return PART_NxN; // 000
}
- if (!s->ps.sps->amp_enabled_flag) {
+ if (!lc->parent->ps.sps->amp_enabled_flag) {
if (GET_CABAC(elem_offset[PART_MODE] + 1)) // 01
return PART_2NxN;
return PART_Nx2N;
@@ -734,84 +740,84 @@ int ff_hevc_part_mode_decode(HEVCContext *s, int log2_cb_size)
if (GET_CABAC(elem_offset[PART_MODE] + 1)) { // 01X, 01XX
if (GET_CABAC(elem_offset[PART_MODE] + 3)) // 011
return PART_2NxN;
- if (get_cabac_bypass(&s->HEVClc->cc)) // 0101
+ if (get_cabac_bypass(&lc->cc)) // 0101
return PART_2NxnD;
return PART_2NxnU; // 0100
}
if (GET_CABAC(elem_offset[PART_MODE] + 3)) // 001
return PART_Nx2N;
- if (get_cabac_bypass(&s->HEVClc->cc)) // 0001
+ if (get_cabac_bypass(&lc->cc)) // 0001
return PART_nRx2N;
return PART_nLx2N; // 0000
}
-int ff_hevc_pcm_flag_decode(HEVCContext *s)
+int ff_hevc_pcm_flag_decode(HEVCLocalContext *lc)
{
- return get_cabac_terminate(&s->HEVClc->cc);
+ return get_cabac_terminate(&lc->cc);
}
-int ff_hevc_prev_intra_luma_pred_flag_decode(HEVCContext *s)
+int ff_hevc_prev_intra_luma_pred_flag_decode(HEVCLocalContext *lc)
{
return GET_CABAC(elem_offset[PREV_INTRA_LUMA_PRED_FLAG]);
}
-int ff_hevc_mpm_idx_decode(HEVCContext *s)
+int ff_hevc_mpm_idx_decode(HEVCLocalContext *lc)
{
int i = 0;
- while (i < 2 && get_cabac_bypass(&s->HEVClc->cc))
+ while (i < 2 && get_cabac_bypass(&lc->cc))
i++;
return i;
}
-int ff_hevc_rem_intra_luma_pred_mode_decode(HEVCContext *s)
+int ff_hevc_rem_intra_luma_pred_mode_decode(HEVCLocalContext *lc)
{
int i;
- int value = get_cabac_bypass(&s->HEVClc->cc);
+ int value = get_cabac_bypass(&lc->cc);
for (i = 0; i < 4; i++)
- value = (value << 1) | get_cabac_bypass(&s->HEVClc->cc);
+ value = (value << 1) | get_cabac_bypass(&lc->cc);
return value;
}
-int ff_hevc_intra_chroma_pred_mode_decode(HEVCContext *s)
+int ff_hevc_intra_chroma_pred_mode_decode(HEVCLocalContext *lc)
{
int ret;
if (!GET_CABAC(elem_offset[INTRA_CHROMA_PRED_MODE]))
return 4;
- ret = get_cabac_bypass(&s->HEVClc->cc) << 1;
- ret |= get_cabac_bypass(&s->HEVClc->cc);
+ ret = get_cabac_bypass(&lc->cc) << 1;
+ ret |= get_cabac_bypass(&lc->cc);
return ret;
}
-int ff_hevc_merge_idx_decode(HEVCContext *s)
+int ff_hevc_merge_idx_decode(HEVCLocalContext *lc)
{
int i = GET_CABAC(elem_offset[MERGE_IDX]);
if (i != 0) {
- while (i < s->sh.max_num_merge_cand-1 && get_cabac_bypass(&s->HEVClc->cc))
+ while (i < lc->parent->sh.max_num_merge_cand-1 && get_cabac_bypass(&lc->cc))
i++;
}
return i;
}
-int ff_hevc_merge_flag_decode(HEVCContext *s)
+int ff_hevc_merge_flag_decode(HEVCLocalContext *lc)
{
return GET_CABAC(elem_offset[MERGE_FLAG]);
}
-int ff_hevc_inter_pred_idc_decode(HEVCContext *s, int nPbW, int nPbH)
+int ff_hevc_inter_pred_idc_decode(HEVCLocalContext *lc, int nPbW, int nPbH)
{
if (nPbW + nPbH == 12)
return GET_CABAC(elem_offset[INTER_PRED_IDC] + 4);
- if (GET_CABAC(elem_offset[INTER_PRED_IDC] + s->HEVClc->ct_depth))
+ if (GET_CABAC(elem_offset[INTER_PRED_IDC] + lc->ct_depth))
return PRED_BI;
return GET_CABAC(elem_offset[INTER_PRED_IDC] + 4);
}
-int ff_hevc_ref_idx_lx_decode(HEVCContext *s, int num_ref_idx_lx)
+int ff_hevc_ref_idx_lx_decode(HEVCLocalContext *lc, int num_ref_idx_lx)
{
int i = 0;
int max = num_ref_idx_lx - 1;
@@ -820,87 +826,88 @@ int ff_hevc_ref_idx_lx_decode(HEVCContext *s, int num_ref_idx_lx)
while (i < max_ctx && GET_CABAC(elem_offset[REF_IDX_L0] + i))
i++;
if (i == 2) {
- while (i < max && get_cabac_bypass(&s->HEVClc->cc))
+ while (i < max && get_cabac_bypass(&lc->cc))
i++;
}
return i;
}
-int ff_hevc_mvp_lx_flag_decode(HEVCContext *s)
+int ff_hevc_mvp_lx_flag_decode(HEVCLocalContext *lc)
{
return GET_CABAC(elem_offset[MVP_LX_FLAG]);
}
-int ff_hevc_no_residual_syntax_flag_decode(HEVCContext *s)
+int ff_hevc_no_residual_syntax_flag_decode(HEVCLocalContext *lc)
{
return GET_CABAC(elem_offset[NO_RESIDUAL_DATA_FLAG]);
}
-static av_always_inline int abs_mvd_greater0_flag_decode(HEVCContext *s)
+static av_always_inline int abs_mvd_greater0_flag_decode(HEVCLocalContext *lc)
{
return GET_CABAC(elem_offset[ABS_MVD_GREATER0_FLAG]);
}
-static av_always_inline int abs_mvd_greater1_flag_decode(HEVCContext *s)
+static av_always_inline int abs_mvd_greater1_flag_decode(HEVCLocalContext *lc)
{
return GET_CABAC(elem_offset[ABS_MVD_GREATER1_FLAG] + 1);
}
-static av_always_inline int mvd_decode(HEVCContext *s)
+static av_always_inline int mvd_decode(HEVCLocalContext *lc)
{
int ret = 2;
int k = 1;
- while (k < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc->cc)) {
+ while (k < CABAC_MAX_BIN && get_cabac_bypass(&lc->cc)) {
ret += 1U << k;
k++;
}
if (k == CABAC_MAX_BIN) {
- av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", k);
+ av_log(lc->logctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", k);
return 0;
}
while (k--)
- ret += get_cabac_bypass(&s->HEVClc->cc) << k;
- return get_cabac_bypass_sign(&s->HEVClc->cc, -ret);
+ ret += get_cabac_bypass(&lc->cc) << k;
+ return get_cabac_bypass_sign(&lc->cc, -ret);
}
-static av_always_inline int mvd_sign_flag_decode(HEVCContext *s)
+static av_always_inline int mvd_sign_flag_decode(HEVCLocalContext *lc)
{
- return get_cabac_bypass_sign(&s->HEVClc->cc, -1);
+ return get_cabac_bypass_sign(&lc->cc, -1);
}
-int ff_hevc_split_transform_flag_decode(HEVCContext *s, int log2_trafo_size)
+int ff_hevc_split_transform_flag_decode(HEVCLocalContext *lc, int log2_trafo_size)
{
return GET_CABAC(elem_offset[SPLIT_TRANSFORM_FLAG] + 5 - log2_trafo_size);
}
-int ff_hevc_cbf_cb_cr_decode(HEVCContext *s, int trafo_depth)
+int ff_hevc_cbf_cb_cr_decode(HEVCLocalContext *lc, int trafo_depth)
{
return GET_CABAC(elem_offset[CBF_CB_CR] + trafo_depth);
}
-int ff_hevc_cbf_luma_decode(HEVCContext *s, int trafo_depth)
+int ff_hevc_cbf_luma_decode(HEVCLocalContext *lc, int trafo_depth)
{
return GET_CABAC(elem_offset[CBF_LUMA] + !trafo_depth);
}
-static int hevc_transform_skip_flag_decode(HEVCContext *s, int c_idx)
+static int hevc_transform_skip_flag_decode(HEVCLocalContext *lc, int c_idx)
{
return GET_CABAC(elem_offset[TRANSFORM_SKIP_FLAG] + !!c_idx);
}
-static int explicit_rdpcm_flag_decode(HEVCContext *s, int c_idx)
+static int explicit_rdpcm_flag_decode(HEVCLocalContext *lc, int c_idx)
{
return GET_CABAC(elem_offset[EXPLICIT_RDPCM_FLAG] + !!c_idx);
}
-static int explicit_rdpcm_dir_flag_decode(HEVCContext *s, int c_idx)
+static int explicit_rdpcm_dir_flag_decode(HEVCLocalContext *lc, int c_idx)
{
return GET_CABAC(elem_offset[EXPLICIT_RDPCM_DIR_FLAG] + !!c_idx);
}
-int ff_hevc_log2_res_scale_abs(HEVCContext *s, int idx) {
+int ff_hevc_log2_res_scale_abs(HEVCLocalContext *lc, int idx)
+{
int i =0;
while (i < 4 && GET_CABAC(elem_offset[LOG2_RES_SCALE_ABS] + 4 * idx + i))
@@ -909,11 +916,12 @@ int ff_hevc_log2_res_scale_abs(HEVCContext *s, int idx) {
return i;
}
-int ff_hevc_res_scale_sign_flag(HEVCContext *s, int idx) {
+int ff_hevc_res_scale_sign_flag(HEVCLocalContext *lc, int idx)
+{
return GET_CABAC(elem_offset[RES_SCALE_SIGN_FLAG] + idx);
}
-static av_always_inline void last_significant_coeff_xy_prefix_decode(HEVCContext *s, int c_idx,
+static av_always_inline void last_significant_coeff_xy_prefix_decode(HEVCLocalContext *lc, int c_idx,
int log2_size, int *last_scx_prefix, int *last_scy_prefix)
{
int i = 0;
@@ -939,19 +947,19 @@ static av_always_inline void last_significant_coeff_xy_prefix_decode(HEVCContext
*last_scy_prefix = i;
}
-static av_always_inline int last_significant_coeff_suffix_decode(HEVCContext *s,
+static av_always_inline int last_significant_coeff_suffix_decode(HEVCLocalContext *lc,
int last_significant_coeff_prefix)
{
int i;
int length = (last_significant_coeff_prefix >> 1) - 1;
- int value = get_cabac_bypass(&s->HEVClc->cc);
+ int value = get_cabac_bypass(&lc->cc);
for (i = 1; i < length; i++)
- value = (value << 1) | get_cabac_bypass(&s->HEVClc->cc);
+ value = (value << 1) | get_cabac_bypass(&lc->cc);
return value;
}
-static av_always_inline int significant_coeff_group_flag_decode(HEVCContext *s, int c_idx, int ctx_cg)
+static av_always_inline int significant_coeff_group_flag_decode(HEVCLocalContext *lc, int c_idx, int ctx_cg)
{
int inc;
@@ -959,19 +967,19 @@ static av_always_inline int significant_coeff_group_flag_decode(HEVCContext *s,
return GET_CABAC(elem_offset[SIGNIFICANT_COEFF_GROUP_FLAG] + inc);
}
-static av_always_inline int significant_coeff_flag_decode(HEVCContext *s, int x_c, int y_c,
+static av_always_inline int significant_coeff_flag_decode(HEVCLocalContext *lc, int x_c, int y_c,
int offset, const uint8_t *ctx_idx_map)
{
int inc = ctx_idx_map[(y_c << 2) + x_c] + offset;
return GET_CABAC(elem_offset[SIGNIFICANT_COEFF_FLAG] + inc);
}
-static av_always_inline int significant_coeff_flag_decode_0(HEVCContext *s, int c_idx, int offset)
+static av_always_inline int significant_coeff_flag_decode_0(HEVCLocalContext *lc, int c_idx, int offset)
{
return GET_CABAC(elem_offset[SIGNIFICANT_COEFF_FLAG] + offset);
}
-static av_always_inline int coeff_abs_level_greater1_flag_decode(HEVCContext *s, int c_idx, int inc)
+static av_always_inline int coeff_abs_level_greater1_flag_decode(HEVCLocalContext *lc, int c_idx, int inc)
{
if (c_idx > 0)
@@ -980,7 +988,7 @@ static av_always_inline int coeff_abs_level_greater1_flag_decode(HEVCContext *s,
return GET_CABAC(elem_offset[COEFF_ABS_LEVEL_GREATER1_FLAG] + inc);
}
-static av_always_inline int coeff_abs_level_greater2_flag_decode(HEVCContext *s, int c_idx, int inc)
+static av_always_inline int coeff_abs_level_greater2_flag_decode(HEVCLocalContext *lc, int c_idx, int inc)
{
if (c_idx > 0)
inc += 4;
@@ -988,47 +996,47 @@ static av_always_inline int coeff_abs_level_greater2_flag_decode(HEVCContext *s,
return GET_CABAC(elem_offset[COEFF_ABS_LEVEL_GREATER2_FLAG] + inc);
}
-static av_always_inline int coeff_abs_level_remaining_decode(HEVCContext *s, int rc_rice_param)
+static av_always_inline int coeff_abs_level_remaining_decode(HEVCLocalContext *lc, int rc_rice_param)
{
int prefix = 0;
int suffix = 0;
int last_coeff_abs_level_remaining;
int i;
- while (prefix < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc->cc))
+ while (prefix < CABAC_MAX_BIN && get_cabac_bypass(&lc->cc))
prefix++;
if (prefix < 3) {
for (i = 0; i < rc_rice_param; i++)
- suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc->cc);
+ suffix = (suffix << 1) | get_cabac_bypass(&lc->cc);
last_coeff_abs_level_remaining = (prefix << rc_rice_param) + suffix;
} else {
int prefix_minus3 = prefix - 3;
if (prefix == CABAC_MAX_BIN || prefix_minus3 + rc_rice_param > 16 + 6) {
- av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", prefix);
+ av_log(lc->logctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", prefix);
return 0;
}
for (i = 0; i < prefix_minus3 + rc_rice_param; i++)
- suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc->cc);
+ suffix = (suffix << 1) | get_cabac_bypass(&lc->cc);
last_coeff_abs_level_remaining = (((1 << prefix_minus3) + 3 - 1)
<< rc_rice_param) + suffix;
}
return last_coeff_abs_level_remaining;
}
-static av_always_inline int coeff_sign_flag_decode(HEVCContext *s, uint8_t nb)
+static av_always_inline int coeff_sign_flag_decode(HEVCLocalContext *lc, uint8_t nb)
{
int i;
int ret = 0;
for (i = 0; i < nb; i++)
- ret = (ret << 1) | get_cabac_bypass(&s->HEVClc->cc);
+ ret = (ret << 1) | get_cabac_bypass(&lc->cc);
return ret;
}
-void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
+void ff_hevc_hls_residual_coding(HEVCLocalContext *lc, int x0, int y0,
int log2_trafo_size, enum ScanType scan_idx,
int c_idx)
{
@@ -1037,7 +1045,7 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
x_c = (x_cg << 2) + scan_x_off[n]; \
y_c = (y_cg << 2) + scan_y_off[n]; \
} while (0)
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
int transform_skip_flag = 0;
int last_significant_coeff_x, last_significant_coeff_y;
@@ -1092,7 +1100,7 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
if (s->ps.pps->transform_skip_enabled_flag &&
log2_trafo_size <= s->ps.pps->log2_max_transform_skip_block_size) {
- transform_skip_flag = hevc_transform_skip_flag_decode(s, c_idx);
+ transform_skip_flag = hevc_transform_skip_flag_decode(lc, c_idx);
}
if (c_idx == 0) {
@@ -1151,24 +1159,24 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
if (lc->cu.pred_mode == MODE_INTER && s->ps.sps->explicit_rdpcm_enabled_flag &&
(transform_skip_flag || lc->cu.cu_transquant_bypass_flag)) {
- explicit_rdpcm_flag = explicit_rdpcm_flag_decode(s, c_idx);
+ explicit_rdpcm_flag = explicit_rdpcm_flag_decode(lc, c_idx);
if (explicit_rdpcm_flag) {
- explicit_rdpcm_dir_flag = explicit_rdpcm_dir_flag_decode(s, c_idx);
+ explicit_rdpcm_dir_flag = explicit_rdpcm_dir_flag_decode(lc, c_idx);
}
}
- last_significant_coeff_xy_prefix_decode(s, c_idx, log2_trafo_size,
+ last_significant_coeff_xy_prefix_decode(lc, c_idx, log2_trafo_size,
&last_significant_coeff_x, &last_significant_coeff_y);
if (last_significant_coeff_x > 3) {
- int suffix = last_significant_coeff_suffix_decode(s, last_significant_coeff_x);
+ int suffix = last_significant_coeff_suffix_decode(lc, last_significant_coeff_x);
last_significant_coeff_x = (1 << ((last_significant_coeff_x >> 1) - 1)) *
(2 + (last_significant_coeff_x & 1)) +
suffix;
}
if (last_significant_coeff_y > 3) {
- int suffix = last_significant_coeff_suffix_decode(s, last_significant_coeff_y);
+ int suffix = last_significant_coeff_suffix_decode(lc, last_significant_coeff_y);
last_significant_coeff_y = (1 << ((last_significant_coeff_y >> 1) - 1)) *
(2 + (last_significant_coeff_y & 1)) +
suffix;
@@ -1247,7 +1255,7 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
ctx_cg += significant_coeff_group_flag[x_cg][y_cg + 1];
significant_coeff_group_flag[x_cg][y_cg] =
- significant_coeff_group_flag_decode(s, c_idx, ctx_cg);
+ significant_coeff_group_flag_decode(lc, c_idx, ctx_cg);
implicit_non_zero_coeff = 1;
} else {
significant_coeff_group_flag[x_cg][y_cg] =
@@ -1314,7 +1322,7 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
for (n = n_end; n > 0; n--) {
x_c = scan_x_off[n];
y_c = scan_y_off[n];
- if (significant_coeff_flag_decode(s, x_c, y_c, scf_offset, ctx_idx_map_p)) {
+ if (significant_coeff_flag_decode(lc, x_c, y_c, scf_offset, ctx_idx_map_p)) {
significant_coeff_flag_idx[nb_significant_coeff_flag] = n;
nb_significant_coeff_flag++;
implicit_non_zero_coeff = 0;
@@ -1338,7 +1346,7 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
scf_offset = 2 + scf_offset;
}
}
- if (significant_coeff_flag_decode_0(s, c_idx, scf_offset) == 1) {
+ if (significant_coeff_flag_decode_0(lc, c_idx, scf_offset) == 1) {
significant_coeff_flag_idx[nb_significant_coeff_flag] = 0;
nb_significant_coeff_flag++;
}
@@ -1382,7 +1390,7 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
for (m = 0; m < (n_end > 8 ? 8 : n_end); m++) {
int inc = (ctx_set << 2) + greater1_ctx;
coeff_abs_level_greater1_flag[m] =
- coeff_abs_level_greater1_flag_decode(s, c_idx, inc);
+ coeff_abs_level_greater1_flag_decode(lc, c_idx, inc);
if (coeff_abs_level_greater1_flag[m]) {
greater1_ctx = 0;
if (first_greater1_coeff_idx == -1)
@@ -1403,12 +1411,12 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
sign_hidden = (last_nz_pos_in_cg - first_nz_pos_in_cg >= 4);
if (first_greater1_coeff_idx != -1) {
- coeff_abs_level_greater1_flag[first_greater1_coeff_idx] += coeff_abs_level_greater2_flag_decode(s, c_idx, ctx_set);
+ coeff_abs_level_greater1_flag[first_greater1_coeff_idx] += coeff_abs_level_greater2_flag_decode(lc, c_idx, ctx_set);
}
if (!s->ps.pps->sign_data_hiding_flag || !sign_hidden ) {
- coeff_sign_flag = coeff_sign_flag_decode(s, nb_significant_coeff_flag) << (16 - nb_significant_coeff_flag);
+ coeff_sign_flag = coeff_sign_flag_decode(lc, nb_significant_coeff_flag) << (16 - nb_significant_coeff_flag);
} else {
- coeff_sign_flag = coeff_sign_flag_decode(s, nb_significant_coeff_flag - 1) << (16 - (nb_significant_coeff_flag - 1));
+ coeff_sign_flag = coeff_sign_flag_decode(lc, nb_significant_coeff_flag - 1) << (16 - (nb_significant_coeff_flag - 1));
}
for (m = 0; m < n_end; m++) {
@@ -1417,7 +1425,7 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
if (m < 8) {
trans_coeff_level = 1 + coeff_abs_level_greater1_flag[m];
if (trans_coeff_level == ((m == first_greater1_coeff_idx) ? 3 : 2)) {
- int last_coeff_abs_level_remaining = coeff_abs_level_remaining_decode(s, c_rice_param);
+ int last_coeff_abs_level_remaining = coeff_abs_level_remaining_decode(lc, c_rice_param);
trans_coeff_level += last_coeff_abs_level_remaining;
if (trans_coeff_level > (3 << c_rice_param))
@@ -1433,7 +1441,7 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
}
}
} else {
- int last_coeff_abs_level_remaining = coeff_abs_level_remaining_decode(s, c_rice_param);
+ int last_coeff_abs_level_remaining = coeff_abs_level_remaining_decode(lc, c_rice_param);
trans_coeff_level = 1 + last_coeff_abs_level_remaining;
if (trans_coeff_level > (3 << c_rice_param))
@@ -1538,26 +1546,25 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
s->hevcdsp.add_residual[log2_trafo_size-2](dst, coeffs, stride);
}
-void ff_hevc_hls_mvd_coding(HEVCContext *s, int x0, int y0, int log2_cb_size)
+void ff_hevc_hls_mvd_coding(HEVCLocalContext *lc, int x0, int y0, int log2_cb_size)
{
- HEVCLocalContext *lc = s->HEVClc;
- int x = abs_mvd_greater0_flag_decode(s);
- int y = abs_mvd_greater0_flag_decode(s);
+ int x = abs_mvd_greater0_flag_decode(lc);
+ int y = abs_mvd_greater0_flag_decode(lc);
if (x)
- x += abs_mvd_greater1_flag_decode(s);
+ x += abs_mvd_greater1_flag_decode(lc);
if (y)
- y += abs_mvd_greater1_flag_decode(s);
+ y += abs_mvd_greater1_flag_decode(lc);
switch (x) {
- case 2: lc->pu.mvd.x = mvd_decode(s); break;
- case 1: lc->pu.mvd.x = mvd_sign_flag_decode(s); break;
+ case 2: lc->pu.mvd.x = mvd_decode(lc); break;
+ case 1: lc->pu.mvd.x = mvd_sign_flag_decode(lc); break;
case 0: lc->pu.mvd.x = 0; break;
}
switch (y) {
- case 2: lc->pu.mvd.y = mvd_decode(s); break;
- case 1: lc->pu.mvd.y = mvd_sign_flag_decode(s); break;
+ case 2: lc->pu.mvd.y = mvd_decode(lc); break;
+ case 1: lc->pu.mvd.y = mvd_sign_flag_decode(lc); break;
case 0: lc->pu.mvd.y = 0; break;
}
}
diff --git a/libavcodec/hevc_filter.c b/libavcodec/hevc_filter.c
index 1ae561db9..0c45310ea 100644
--- a/libavcodec/hevc_filter.c
+++ b/libavcodec/hevc_filter.c
@@ -44,7 +44,7 @@ static const uint8_t betatable[52] = {
38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64 // QP 38...51
};
-static int chroma_tc(HEVCContext *s, int qp_y, int c_idx, int tc_offset)
+static int chroma_tc(const HEVCContext *s, int qp_y, int c_idx, int tc_offset)
{
static const int qp_c[] = {
29, 30, 31, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37
@@ -73,9 +73,9 @@ static int chroma_tc(HEVCContext *s, int qp_y, int c_idx, int tc_offset)
return tctable[idxt];
}
-static int get_qPy_pred(HEVCContext *s, int xBase, int yBase, int log2_cb_size)
+static int get_qPy_pred(HEVCLocalContext *lc, const HEVCContext *s,
+ int xBase, int yBase, int log2_cb_size)
{
- HEVCLocalContext *lc = s->HEVClc;
int ctb_size_mask = (1 << s->ps.sps->log2_ctb_size) - 1;
int MinCuQpDeltaSizeMask = (1 << (s->ps.sps->log2_ctb_size -
s->ps.pps->diff_cu_qp_delta_depth)) - 1;
@@ -116,19 +116,20 @@ static int get_qPy_pred(HEVCContext *s, int xBase, int yBase, int log2_cb_size)
return (qPy_a + qPy_b + 1) >> 1;
}
-void ff_hevc_set_qPy(HEVCContext *s, int xBase, int yBase, int log2_cb_size)
+void ff_hevc_set_qPy(HEVCLocalContext *lc, int xBase, int yBase, int log2_cb_size)
{
- int qp_y = get_qPy_pred(s, xBase, yBase, log2_cb_size);
+ const HEVCContext *const s = lc->parent;
+ int qp_y = get_qPy_pred(lc, s, xBase, yBase, log2_cb_size);
- if (s->HEVClc->tu.cu_qp_delta != 0) {
+ if (lc->tu.cu_qp_delta != 0) {
int off = s->ps.sps->qp_bd_offset;
- s->HEVClc->qp_y = FFUMOD(qp_y + s->HEVClc->tu.cu_qp_delta + 52 + 2 * off,
+ lc->qp_y = FFUMOD(qp_y + lc->tu.cu_qp_delta + 52 + 2 * off,
52 + off) - off;
} else
- s->HEVClc->qp_y = qp_y;
+ lc->qp_y = qp_y;
}
-static int get_qPy(HEVCContext *s, int xC, int yC)
+static int get_qPy(const HEVCContext *s, int xC, int yC)
{
int log2_min_cb_size = s->ps.sps->log2_min_cb_size;
int x = xC >> log2_min_cb_size;
@@ -197,7 +198,7 @@ static void copy_vert(uint8_t *dst, const uint8_t *src,
}
}
-static void copy_CTB_to_hv(HEVCContext *s, const uint8_t *src,
+static void copy_CTB_to_hv(const HEVCContext *s, const uint8_t *src,
ptrdiff_t stride_src, int x, int y, int width, int height,
int c_idx, int x_ctb, int y_ctb)
{
@@ -217,7 +218,7 @@ static void copy_CTB_to_hv(HEVCContext *s, const uint8_t *src,
copy_vert(s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb + 1) * h + y) << sh), src + ((width - 1) << sh), sh, height, 1 << sh, stride_src);
}
-static void restore_tqb_pixels(HEVCContext *s,
+static void restore_tqb_pixels(const HEVCContext *s,
uint8_t *src1, const uint8_t *dst1,
ptrdiff_t stride_src, ptrdiff_t stride_dst,
int x0, int y0, int width, int height, int c_idx)
@@ -252,10 +253,9 @@ static void restore_tqb_pixels(HEVCContext *s,
#define CTB(tab, x, y) ((tab)[(y) * s->ps.sps->ctb_width + (x)])
-static void sao_filter_CTB(HEVCContext *s, int x, int y)
+static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCContext *s, int x, int y)
{
static const uint8_t sao_tab[8] = { 0, 1, 2, 2, 3, 3, 4, 4 };
- HEVCLocalContext *lc = s->HEVClc;
int c_idx;
int edges[4]; // 0 left 1 top 2 right 3 bottom
int x_ctb = x >> s->ps.sps->log2_ctb_size;
@@ -461,7 +461,7 @@ static void sao_filter_CTB(HEVCContext *s, int x, int y)
}
}
-static int get_pcm(HEVCContext *s, int x, int y)
+static int get_pcm(const HEVCContext *s, int x, int y)
{
int log2_min_pu_size = s->ps.sps->log2_min_pu_size;
int x_pu, y_pu;
@@ -482,7 +482,7 @@ static int get_pcm(HEVCContext *s, int x, int y)
(tc_offset & -2), \
0, MAX_QP + DEFAULT_INTRA_TC_OFFSET)]
-static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0)
+static void deblocking_filter_CTB(const HEVCContext *s, int x0, int y0)
{
uint8_t *src;
int x, y;
@@ -720,11 +720,11 @@ static int boundary_strength(const HEVCContext *s, const MvField *curr, const Mv
return 1;
}
-void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0,
+void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, int x0, int y0,
int log2_trafo_size)
{
- HEVCLocalContext *lc = s->HEVClc;
- MvField *tab_mvf = s->ref->tab_mvf;
+ const HEVCContext *s = lc->parent;
+ const MvField *tab_mvf = s->ref->tab_mvf;
int log2_min_pu_size = s->ps.sps->log2_min_pu_size;
int log2_min_tu_size = s->ps.sps->log2_min_tb_size;
int min_pu_width = s->ps.sps->min_pu_width;
@@ -756,8 +756,8 @@ void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0,
for (i = 0; i < (1 << log2_trafo_size); i += 4) {
int x_pu = (x0 + i) >> log2_min_pu_size;
int x_tu = (x0 + i) >> log2_min_tu_size;
- MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
- MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
+ const MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
+ const MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
uint8_t top_cbf_luma = s->cbf_luma[yp_tu * min_tu_width + x_tu];
uint8_t curr_cbf_luma = s->cbf_luma[yq_tu * min_tu_width + x_tu];
@@ -794,8 +794,8 @@ void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0,
for (i = 0; i < (1 << log2_trafo_size); i += 4) {
int y_pu = (y0 + i) >> log2_min_pu_size;
int y_tu = (y0 + i) >> log2_min_tu_size;
- MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
- MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
+ const MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
+ const MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
uint8_t left_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xp_tu];
uint8_t curr_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xq_tu];
@@ -810,7 +810,7 @@ void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0,
}
if (log2_trafo_size > log2_min_pu_size && !is_intra) {
- RefPicList *rpl = s->ref->refPicList;
+ const RefPicList *rpl = s->ref->refPicList;
// bs for TU internal horizontal PU boundaries
for (j = 8; j < (1 << log2_trafo_size); j += 8) {
@@ -819,8 +819,8 @@ void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0,
for (i = 0; i < (1 << log2_trafo_size); i += 4) {
int x_pu = (x0 + i) >> log2_min_pu_size;
- MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
- MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
+ const MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
+ const MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
bs = boundary_strength(s, curr, top, rpl);
s->horizontal_bs[((x0 + i) + (y0 + j) * s->bs_width) >> 2] = bs;
@@ -834,8 +834,8 @@ void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0,
for (i = 8; i < (1 << log2_trafo_size); i += 8) {
int xp_pu = (x0 + i - 1) >> log2_min_pu_size;
int xq_pu = (x0 + i) >> log2_min_pu_size;
- MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
- MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
+ const MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
+ const MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
bs = boundary_strength(s, curr, left, rpl);
s->vertical_bs[((x0 + i) + (y0 + j) * s->bs_width) >> 2] = bs;
@@ -848,8 +848,9 @@ void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0,
#undef CB
#undef CR
-void ff_hevc_hls_filter(HEVCContext *s, int x, int y, int ctb_size)
+void ff_hevc_hls_filter(HEVCLocalContext *lc, int x, int y, int ctb_size)
{
+ const HEVCContext *const s = lc->parent;
int x_end = x >= s->ps.sps->width - ctb_size;
int skip = 0;
if (s->avctx->skip_loop_filter >= AVDISCARD_ALL ||
@@ -867,16 +868,16 @@ void ff_hevc_hls_filter(HEVCContext *s, int x, int y, int ctb_size)
if (s->ps.sps->sao_enabled && !skip) {
int y_end = y >= s->ps.sps->height - ctb_size;
if (y && x)
- sao_filter_CTB(s, x - ctb_size, y - ctb_size);
+ sao_filter_CTB(lc, s, x - ctb_size, y - ctb_size);
if (x && y_end)
- sao_filter_CTB(s, x - ctb_size, y);
+ sao_filter_CTB(lc, s, x - ctb_size, y);
if (y && x_end) {
- sao_filter_CTB(s, x, y - ctb_size);
+ sao_filter_CTB(lc, s, x, y - ctb_size);
if (s->threads_type & FF_THREAD_FRAME )
ff_thread_report_progress(&s->ref->tf, y, 0);
}
if (x_end && y_end) {
- sao_filter_CTB(s, x , y);
+ sao_filter_CTB(lc, s, x , y);
if (s->threads_type & FF_THREAD_FRAME )
ff_thread_report_progress(&s->ref->tf, y + ctb_size, 0);
}
@@ -884,14 +885,14 @@ void ff_hevc_hls_filter(HEVCContext *s, int x, int y, int ctb_size)
ff_thread_report_progress(&s->ref->tf, y + ctb_size - 4, 0);
}
-void ff_hevc_hls_filters(HEVCContext *s, int x_ctb, int y_ctb, int ctb_size)
+void ff_hevc_hls_filters(HEVCLocalContext *lc, int x_ctb, int y_ctb, int ctb_size)
{
- int x_end = x_ctb >= s->ps.sps->width - ctb_size;
- int y_end = y_ctb >= s->ps.sps->height - ctb_size;
+ int x_end = x_ctb >= lc->parent->ps.sps->width - ctb_size;
+ int y_end = y_ctb >= lc->parent->ps.sps->height - ctb_size;
if (y_ctb && x_ctb)
- ff_hevc_hls_filter(s, x_ctb - ctb_size, y_ctb - ctb_size, ctb_size);
+ ff_hevc_hls_filter(lc, x_ctb - ctb_size, y_ctb - ctb_size, ctb_size);
if (y_ctb && x_end)
- ff_hevc_hls_filter(s, x_ctb, y_ctb - ctb_size, ctb_size);
+ ff_hevc_hls_filter(lc, x_ctb, y_ctb - ctb_size, ctb_size);
if (x_ctb && y_end)
- ff_hevc_hls_filter(s, x_ctb - ctb_size, y_ctb, ctb_size);
+ ff_hevc_hls_filter(lc, x_ctb - ctb_size, y_ctb, ctb_size);
}
diff --git a/libavcodec/hevc_mvs.c b/libavcodec/hevc_mvs.c
index 516e4a6b7..c231797a5 100644
--- a/libavcodec/hevc_mvs.c
+++ b/libavcodec/hevc_mvs.c
@@ -40,10 +40,10 @@ static const uint8_t l0_l1_cand_idx[12][2] = {
{ 3, 2, },
};
-void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0,
+void ff_hevc_set_neighbour_available(HEVCLocalContext *lc, int x0, int y0,
int nPbW, int nPbH)
{
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
int x0b = av_mod_uintp2(x0, s->ps.sps->log2_ctb_size);
int y0b = av_mod_uintp2(y0, s->ps.sps->log2_ctb_size);
@@ -62,7 +62,7 @@ void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0,
/*
* 6.4.1 Derivation process for z-scan order block availability
*/
-static av_always_inline int z_scan_block_avail(HEVCContext *s, int xCurr, int yCurr,
+static av_always_inline int z_scan_block_avail(const HEVCContext *s, int xCurr, int yCurr,
int xN, int yN)
{
#define MIN_TB_ADDR_ZS(x, y) \
@@ -84,7 +84,7 @@ static av_always_inline int z_scan_block_avail(HEVCContext *s, int xCurr, int yC
}
//check if the two luma locations belong to the same motion estimation region
-static av_always_inline int is_diff_mer(HEVCContext *s, int xN, int yN, int xP, int yP)
+static av_always_inline int is_diff_mer(const HEVCContext *s, int xN, int yN, int xP, int yP)
{
uint8_t plevel = s->ps.pps->log2_parallel_merge_level;
@@ -161,11 +161,11 @@ static int check_mvset(Mv *mvLXCol, const Mv *mvCol,
refPicList_col, L ## l, temp_col.ref_idx[l])
// derive the motion vectors section 8.5.3.1.8
-static int derive_temporal_colocated_mvs(HEVCContext *s, MvField temp_col,
+static int derive_temporal_colocated_mvs(const HEVCContext *s, MvField temp_col,
int refIdxLx, Mv *mvLXCol, int X,
int colPic, const RefPicList *refPicList_col)
{
- RefPicList *refPicList = s->ref->refPicList;
+ const RefPicList *refPicList = s->ref->refPicList;
if (temp_col.pred_flag == PF_INTRA)
return 0;
@@ -216,18 +216,18 @@ static int derive_temporal_colocated_mvs(HEVCContext *s, MvField temp_col,
/*
* 8.5.3.1.7 temporal luma motion vector prediction
*/
-static int temporal_luma_motion_vector(HEVCContext *s, int x0, int y0,
+static int temporal_luma_motion_vector(const HEVCContext *s, int x0, int y0,
int nPbW, int nPbH, int refIdxLx,
Mv *mvLXCol, int X)
{
- MvField *tab_mvf;
+ const MvField *tab_mvf;
MvField temp_col;
int x, y, x_pu, y_pu;
int min_pu_width = s->ps.sps->min_pu_width;
int availableFlagLXCol = 0;
int colPic;
- HEVCFrame *ref = s->ref->collocated_ref;
+ const HEVCFrame *ref = s->ref->collocated_ref;
if (!ref) {
memset(mvLXCol, 0, sizeof(*mvLXCol));
@@ -283,16 +283,16 @@ static int temporal_luma_motion_vector(HEVCContext *s, int x0, int y0,
/*
* 8.5.3.1.2 Derivation process for spatial merging candidates
*/
-static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0,
+static void derive_spatial_merge_candidates(HEVCLocalContext *lc, const HEVCContext *s,
+ int x0, int y0,
int nPbW, int nPbH,
int log2_cb_size,
int singleMCLFlag, int part_idx,
int merge_idx,
struct MvField mergecandlist[])
{
- HEVCLocalContext *lc = s->HEVClc;
- RefPicList *refPicList = s->ref->refPicList;
- MvField *tab_mvf = s->ref->tab_mvf;
+ const RefPicList *refPicList = s->ref->refPicList;
+ const MvField *tab_mvf = s->ref->tab_mvf;
const int min_pu_width = s->ps.sps->min_pu_width;
@@ -477,16 +477,16 @@ static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0,
/*
* 8.5.3.1.1 Derivation process of luma Mvs for merge mode
*/
-void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW,
+void ff_hevc_luma_mv_merge_mode(HEVCLocalContext *lc, int x0, int y0, int nPbW,
int nPbH, int log2_cb_size, int part_idx,
int merge_idx, MvField *mv)
{
+ const HEVCContext *const s = lc->parent;
int singleMCLFlag = 0;
int nCS = 1 << log2_cb_size;
MvField mergecand_list[MRG_MAX_NUM_CANDS];
int nPbW2 = nPbW;
int nPbH2 = nPbH;
- HEVCLocalContext *lc = s->HEVClc;
if (s->ps.pps->log2_parallel_merge_level > 2 && nCS == 8) {
singleMCLFlag = 1;
@@ -497,8 +497,8 @@ void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW,
part_idx = 0;
}
- ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH);
- derive_spatial_merge_candidates(s, x0, y0, nPbW, nPbH, log2_cb_size,
+ ff_hevc_set_neighbour_available(lc, x0, y0, nPbW, nPbH);
+ derive_spatial_merge_candidates(lc, s, x0, y0, nPbW, nPbH, log2_cb_size,
singleMCLFlag, part_idx,
merge_idx, mergecand_list);
@@ -510,12 +510,12 @@ void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW,
*mv = mergecand_list[merge_idx];
}
-static av_always_inline void dist_scale(HEVCContext *s, Mv *mv,
+static av_always_inline void dist_scale(const HEVCContext *s, Mv *mv,
int min_pu_width, int x, int y,
int elist, int ref_idx_curr, int ref_idx)
{
- RefPicList *refPicList = s->ref->refPicList;
- MvField *tab_mvf = s->ref->tab_mvf;
+ const RefPicList *refPicList = s->ref->refPicList;
+ const MvField *tab_mvf = s->ref->tab_mvf;
int ref_pic_elist = refPicList[elist].list[TAB_MVF(x, y).ref_idx[elist]];
int ref_pic_curr = refPicList[ref_idx_curr].list[ref_idx];
@@ -527,13 +527,13 @@ static av_always_inline void dist_scale(HEVCContext *s, Mv *mv,
}
}
-static int mv_mp_mode_mx(HEVCContext *s, int x, int y, int pred_flag_index,
+static int mv_mp_mode_mx(const HEVCContext *s, int x, int y, int pred_flag_index,
Mv *mv, int ref_idx_curr, int ref_idx)
{
- MvField *tab_mvf = s->ref->tab_mvf;
+ const MvField *tab_mvf = s->ref->tab_mvf;
int min_pu_width = s->ps.sps->min_pu_width;
- RefPicList *refPicList = s->ref->refPicList;
+ const RefPicList *refPicList = s->ref->refPicList;
if (((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) &&
refPicList[pred_flag_index].list[TAB_MVF(x, y).ref_idx[pred_flag_index]] == refPicList[ref_idx_curr].list[ref_idx]) {
@@ -543,13 +543,13 @@ static int mv_mp_mode_mx(HEVCContext *s, int x, int y, int pred_flag_index,
return 0;
}
-static int mv_mp_mode_mx_lt(HEVCContext *s, int x, int y, int pred_flag_index,
+static int mv_mp_mode_mx_lt(const HEVCContext *s, int x, int y, int pred_flag_index,
Mv *mv, int ref_idx_curr, int ref_idx)
{
- MvField *tab_mvf = s->ref->tab_mvf;
+ const MvField *tab_mvf = s->ref->tab_mvf;
int min_pu_width = s->ps.sps->min_pu_width;
- RefPicList *refPicList = s->ref->refPicList;
+ const RefPicList *refPicList = s->ref->refPicList;
if ((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) {
int currIsLongTerm = refPicList[ref_idx_curr].isLongTerm[ref_idx];
@@ -580,13 +580,13 @@ static int mv_mp_mode_mx_lt(HEVCContext *s, int x, int y, int pred_flag_index,
(y ## v) >> s->ps.sps->log2_min_pu_size, \
pred, &mx, ref_idx_curr, ref_idx)
-void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW,
+void ff_hevc_luma_mv_mvp_mode(HEVCLocalContext *lc, int x0, int y0, int nPbW,
int nPbH, int log2_cb_size, int part_idx,
int merge_idx, MvField *mv,
int mvp_lx_flag, int LX)
{
- HEVCLocalContext *lc = s->HEVClc;
- MvField *tab_mvf = s->ref->tab_mvf;
+ const HEVCContext *const s = lc->parent;
+ const MvField *const tab_mvf = s->ref->tab_mvf;
int isScaledFlag_L0 = 0;
int availableFlagLXA0 = 1;
int availableFlagLXB0 = 1;
diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c
index f665d8053..5fe62ec35 100644
--- a/libavcodec/hevc_ps.c
+++ b/libavcodec/hevc_ps.c
@@ -25,6 +25,7 @@
#include "libavutil/imgutils.h"
#include "golomb.h"
+#include "h2645_vui.h"
#include "hevc_data.h"
#include "hevc_ps.h"
@@ -50,26 +51,6 @@ static const uint8_t default_scaling_list_inter[] = {
24, 25, 28, 33, 41, 54, 71, 91
};
-static const AVRational vui_sar[] = {
- { 0, 1 },
- { 1, 1 },
- { 12, 11 },
- { 10, 11 },
- { 16, 11 },
- { 40, 33 },
- { 24, 11 },
- { 20, 11 },
- { 32, 11 },
- { 80, 33 },
- { 18, 11 },
- { 15, 11 },
- { 64, 33 },
- { 160, 99 },
- { 4, 3 },
- { 3, 2 },
- { 2, 1 },
-};
-
static const uint8_t hevc_sub_width_c[] = {
1, 2, 2, 1
};
@@ -587,47 +568,15 @@ static void decode_vui(GetBitContext *gb, AVCodecContext *avctx,
{
VUI backup_vui, *vui = &sps->vui;
GetBitContext backup;
- int sar_present, alt = 0;
+ int alt = 0;
- av_log(avctx, AV_LOG_DEBUG, "Decoding VUI\n");
+ ff_h2645_decode_common_vui_params(gb, &sps->vui.common, avctx);
- sar_present = get_bits1(gb);
- if (sar_present) {
- uint8_t sar_idx = get_bits(gb, 8);
- if (sar_idx < FF_ARRAY_ELEMS(vui_sar))
- vui->sar = vui_sar[sar_idx];
- else if (sar_idx == 255) {
- vui->sar.num = get_bits(gb, 16);
- vui->sar.den = get_bits(gb, 16);
- } else
- av_log(avctx, AV_LOG_WARNING,
- "Unknown SAR index: %u.\n", sar_idx);
- }
-
- vui->overscan_info_present_flag = get_bits1(gb);
- if (vui->overscan_info_present_flag)
- vui->overscan_appropriate_flag = get_bits1(gb);
-
- vui->video_signal_type_present_flag = get_bits1(gb);
- if (vui->video_signal_type_present_flag) {
- vui->video_format = get_bits(gb, 3);
- vui->video_full_range_flag = get_bits1(gb);
- vui->colour_description_present_flag = get_bits1(gb);
- if (vui->video_full_range_flag && sps->pix_fmt == AV_PIX_FMT_YUV420P)
+ if (vui->common.video_signal_type_present_flag) {
+ if (vui->common.video_full_range_flag && sps->pix_fmt == AV_PIX_FMT_YUV420P)
sps->pix_fmt = AV_PIX_FMT_YUVJ420P;
- if (vui->colour_description_present_flag) {
- vui->colour_primaries = get_bits(gb, 8);
- vui->transfer_characteristic = get_bits(gb, 8);
- vui->matrix_coeffs = get_bits(gb, 8);
-
- // Set invalid values to "unspecified"
- if (!av_color_primaries_name(vui->colour_primaries))
- vui->colour_primaries = AVCOL_PRI_UNSPECIFIED;
- if (!av_color_transfer_name(vui->transfer_characteristic))
- vui->transfer_characteristic = AVCOL_TRC_UNSPECIFIED;
- if (!av_color_space_name(vui->matrix_coeffs))
- vui->matrix_coeffs = AVCOL_SPC_UNSPECIFIED;
- if (vui->matrix_coeffs == AVCOL_SPC_RGB) {
+ if (vui->common.colour_description_present_flag) {
+ if (vui->common.matrix_coeffs == AVCOL_SPC_RGB) {
switch (sps->pix_fmt) {
case AV_PIX_FMT_YUV444P:
sps->pix_fmt = AV_PIX_FMT_GBRP;
@@ -643,12 +592,6 @@ static void decode_vui(GetBitContext *gb, AVCodecContext *avctx,
}
}
- vui->chroma_loc_info_present_flag = get_bits1(gb);
- if (vui->chroma_loc_info_present_flag) {
- vui->chroma_sample_loc_type_top_field = get_ue_golomb_long(gb);
- vui->chroma_sample_loc_type_bottom_field = get_ue_golomb_long(gb);
- }
-
vui->neutra_chroma_indication_flag = get_bits1(gb);
vui->field_seq_flag = get_bits1(gb);
vui->frame_field_info_present_flag = get_bits1(gb);
@@ -1123,7 +1066,7 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
sps->sps_temporal_mvp_enabled_flag = get_bits1(gb);
sps->sps_strong_intra_smoothing_enable_flag = get_bits1(gb);
- sps->vui.sar = (AVRational){0, 1};
+ sps->vui.common.sar = (AVRational){0, 1};
vui_present = get_bits1(gb);
if (vui_present)
decode_vui(gb, avctx, apply_defdispwin, sps);
diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h
index 2a1bbf648..18894cfed 100644
--- a/libavcodec/hevc_ps.h
+++ b/libavcodec/hevc_ps.h
@@ -29,6 +29,7 @@
#include "avcodec.h"
#include "get_bits.h"
+#include "h2645_vui.h"
#include "hevc.h"
typedef struct ShortTermRPS {
@@ -47,22 +48,8 @@ typedef struct HEVCWindow {
} HEVCWindow;
typedef struct VUI {
- AVRational sar;
+ H2645VUI common;
- int overscan_info_present_flag;
- int overscan_appropriate_flag;
-
- int video_signal_type_present_flag;
- int video_format;
- int video_full_range_flag;
- int colour_description_present_flag;
- uint8_t colour_primaries;
- uint8_t transfer_characteristic;
- uint8_t matrix_coeffs;
-
- int chroma_loc_info_present_flag;
- int chroma_sample_loc_type_top_field;
- int chroma_sample_loc_type_bottom_field;
int neutra_chroma_indication_flag;
int field_seq_flag;
diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
index 6a70c817b..811e8feff 100644
--- a/libavcodec/hevc_refs.c
+++ b/libavcodec/hevc_refs.c
@@ -173,23 +173,36 @@ int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, int poc)
return 0;
}
+static void unref_missing_refs(HEVCContext *s)
+{
+ for (int i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+ HEVCFrame *frame = &s->DPB[i];
+ if (frame->sequence == HEVC_SEQUENCE_COUNTER_INVALID) {
+ ff_hevc_unref_frame(s, frame, ~0);
+ }
+ }
+}
+
int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush)
{
+ if (IS_IRAP(s) && s->no_rasl_output_flag == 1) {
+ const static int mask = HEVC_FRAME_FLAG_BUMPING | HEVC_FRAME_FLAG_OUTPUT;
+ for (int i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+ HEVCFrame *frame = &s->DPB[i];
+ if ((frame->flags & mask) == HEVC_FRAME_FLAG_OUTPUT &&
+ frame->sequence != s->seq_decode) {
+ if (s->sh.no_output_of_prior_pics_flag == 1)
+ ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT);
+ else
+ frame->flags |= HEVC_FRAME_FLAG_BUMPING;
+ }
+ }
+ }
do {
int nb_output = 0;
int min_poc = INT_MAX;
int i, min_idx, ret;
- if (s->sh.no_output_of_prior_pics_flag == 1 && s->no_rasl_output_flag == 1) {
- for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
- HEVCFrame *frame = &s->DPB[i];
- if (!(frame->flags & HEVC_FRAME_FLAG_BUMPING) && frame->poc != s->poc &&
- frame->sequence == s->seq_output) {
- ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT);
- }
- }
- }
-
for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
HEVCFrame *frame = &s->DPB[i];
if ((frame->flags & HEVC_FRAME_FLAG_OUTPUT) &&
@@ -230,7 +243,7 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush)
}
if (s->seq_output != s->seq_decode)
- s->seq_output = (s->seq_output + 1) & 0xff;
+ s->seq_output = (s->seq_output + 1) & HEVC_SEQUENCE_COUNTER_MASK;
else
break;
} while (1);
@@ -374,7 +387,7 @@ static HEVCFrame *find_ref_idx(HEVCContext *s, int poc, uint8_t use_msb)
for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
HEVCFrame *ref = &s->DPB[i];
if (ref->frame->buf[0] && ref->sequence == s->seq_decode) {
- if ((ref->poc & mask) == poc)
+ if ((ref->poc & mask) == poc && (use_msb || ref->poc != s->poc))
return ref;
}
}
@@ -416,7 +429,7 @@ static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc)
}
frame->poc = poc;
- frame->sequence = s->seq_decode;
+ frame->sequence = HEVC_SEQUENCE_COUNTER_INVALID;
frame->flags = 0;
if (s->threads_type == FF_THREAD_FRAME)
@@ -460,6 +473,8 @@ int ff_hevc_frame_rps(HEVCContext *s)
return 0;
}
+ unref_missing_refs(s);
+
/* clear the reference flags on all frames except the current one */
for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
HEVCFrame *frame = &s->DPB[i];
diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
index 631373e06..3c6bde1b6 100644
--- a/libavcodec/hevc_sei.c
+++ b/libavcodec/hevc_sei.c
@@ -22,10 +22,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "atsc_a53.h"
#include "bytestream.h"
-#include "dynamic_hdr10_plus.h"
-#include "dynamic_hdr_vivid.h"
#include "golomb.h"
#include "hevc_ps.h"
#include "hevc_sei.h"
@@ -98,38 +95,6 @@ static int decode_nal_sei_content_light_info(HEVCSEIContentLight *s,
return 0;
}
-static int decode_nal_sei_frame_packing_arrangement(HEVCSEIFramePacking *s, GetBitContext *gb)
-{
- get_ue_golomb_long(gb); // frame_packing_arrangement_id
- s->present = !get_bits1(gb);
-
- if (s->present) {
- s->arrangement_type = get_bits(gb, 7);
- s->quincunx_subsampling = get_bits1(gb);
- s->content_interpretation_type = get_bits(gb, 6);
-
- // spatial_flipping_flag, frame0_flipped_flag, field_views_flag
- skip_bits(gb, 3);
- s->current_frame_is_frame0_flag = get_bits1(gb);
- }
- return 0;
-}
-
-static int decode_nal_sei_display_orientation(HEVCSEIDisplayOrientation *s, GetBitContext *gb)
-{
- s->present = !get_bits1(gb);
-
- if (s->present) {
- s->hflip = get_bits1(gb); // hor_flip
- s->vflip = get_bits1(gb); // ver_flip
-
- s->anticlockwise_rotation = get_bits(gb, 16);
- // skip_bits1(gb); // display_orientation_persistence_flag
- }
-
- return 0;
-}
-
static int decode_nal_sei_pic_timing(HEVCSEI *s, GetBitContext *gb,
const HEVCParamSets *ps, void *logctx)
{
@@ -161,182 +126,6 @@ static int decode_nal_sei_pic_timing(HEVCSEI *s, GetBitContext *gb,
return 0;
}
-static int decode_registered_user_data_closed_caption(HEVCSEIA53Caption *s,
- GetByteContext *gb)
-{
- int ret;
-
- ret = ff_parse_a53_cc(&s->buf_ref, gb->buffer,
- bytestream2_get_bytes_left(gb));
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int decode_nal_sei_user_data_unregistered(HEVCSEIUnregistered *s,
- GetByteContext *gb)
-{
- AVBufferRef *buf_ref, **tmp;
- int size = bytestream2_get_bytes_left(gb);
-
- if (size < 16 || size >= INT_MAX - 1)
- return AVERROR_INVALIDDATA;
-
- tmp = av_realloc_array(s->buf_ref, s->nb_buf_ref + 1, sizeof(*s->buf_ref));
- if (!tmp)
- return AVERROR(ENOMEM);
- s->buf_ref = tmp;
-
- buf_ref = av_buffer_alloc(size + 1);
- if (!buf_ref)
- return AVERROR(ENOMEM);
-
- bytestream2_get_bufferu(gb, buf_ref->data, size);
- buf_ref->data[size] = 0;
- buf_ref->size = size;
- s->buf_ref[s->nb_buf_ref++] = buf_ref;
-
- return 0;
-}
-
-static int decode_registered_user_data_dynamic_hdr_plus(HEVCSEIDynamicHDRPlus *s,
- GetByteContext *gb)
-{
- size_t meta_size;
- int err;
- AVDynamicHDRPlus *metadata = av_dynamic_hdr_plus_alloc(&meta_size);
- if (!metadata)
- return AVERROR(ENOMEM);
-
- err = ff_parse_itu_t_t35_to_dynamic_hdr10_plus(metadata, gb->buffer,
- bytestream2_get_bytes_left(gb));
- if (err < 0) {
- av_free(metadata);
- return err;
- }
-
- av_buffer_unref(&s->info);
- s->info = av_buffer_create((uint8_t *)metadata, meta_size, NULL, NULL, 0);
- if (!s->info) {
- av_free(metadata);
- return AVERROR(ENOMEM);
- }
-
- return 0;
-}
-
-static int decode_registered_user_data_dynamic_hdr_vivid(HEVCSEIDynamicHDRVivid *s,
- GetByteContext *gb)
-{
- size_t meta_size;
- int err;
- AVDynamicHDRVivid *metadata = av_dynamic_hdr_vivid_alloc(&meta_size);
- if (!metadata)
- return AVERROR(ENOMEM);
-
- err = ff_parse_itu_t_t35_to_dynamic_hdr_vivid(metadata,
- gb->buffer, bytestream2_get_bytes_left(gb));
- if (err < 0) {
- av_free(metadata);
- return err;
- }
-
- av_buffer_unref(&s->info);
- s->info = av_buffer_create((uint8_t *)metadata, meta_size, NULL, NULL, 0);
- if (!s->info) {
- av_free(metadata);
- return AVERROR(ENOMEM);
- }
-
- return 0;
-}
-
-static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCSEI *s, GetByteContext *gb,
- void *logctx)
-{
- int country_code, provider_code;
-
- if (bytestream2_get_bytes_left(gb) < 3)
- return AVERROR_INVALIDDATA;
-
- country_code = bytestream2_get_byteu(gb);
- if (country_code == 0xFF) {
- if (bytestream2_get_bytes_left(gb) < 3)
- return AVERROR_INVALIDDATA;
-
- bytestream2_skipu(gb, 1);
- }
-
- if (country_code != 0xB5 && country_code != 0x26) { // usa_country_code and cn_country_code
- av_log(logctx, AV_LOG_VERBOSE,
- "Unsupported User Data Registered ITU-T T35 SEI message (country_code = 0x%x)\n",
- country_code);
- return 0;
- }
-
- provider_code = bytestream2_get_be16u(gb);
-
- switch (provider_code) {
- case 0x04: { // cuva_provider_code
- const uint16_t cuva_provider_oriented_code = 0x0005;
- uint16_t provider_oriented_code;
-
- if (bytestream2_get_bytes_left(gb) < 2)
- return AVERROR_INVALIDDATA;
-
- provider_oriented_code = bytestream2_get_be16u(gb);
- if (provider_oriented_code == cuva_provider_oriented_code) {
- return decode_registered_user_data_dynamic_hdr_vivid(&s->dynamic_hdr_vivid, gb);
- }
- break;
- }
- case 0x3C: { // smpte_provider_code
- // A/341 Amendment - 2094-40
- const uint16_t smpte2094_40_provider_oriented_code = 0x0001;
- const uint8_t smpte2094_40_application_identifier = 0x04;
- uint16_t provider_oriented_code;
- uint8_t application_identifier;
-
- if (bytestream2_get_bytes_left(gb) < 3)
- return AVERROR_INVALIDDATA;
-
- provider_oriented_code = bytestream2_get_be16u(gb);
- application_identifier = bytestream2_get_byteu(gb);
- if (provider_oriented_code == smpte2094_40_provider_oriented_code &&
- application_identifier == smpte2094_40_application_identifier) {
- return decode_registered_user_data_dynamic_hdr_plus(&s->dynamic_hdr_plus, gb);
- }
- break;
- }
- case 0x31: { // atsc_provider_code
- uint32_t user_identifier;
-
- if (bytestream2_get_bytes_left(gb) < 4)
- return AVERROR_INVALIDDATA;
-
- user_identifier = bytestream2_get_be32u(gb);
- switch (user_identifier) {
- case MKBETAG('G', 'A', '9', '4'):
- return decode_registered_user_data_closed_caption(&s->a53_caption, gb);
- default:
- av_log(logctx, AV_LOG_VERBOSE,
- "Unsupported User Data Registered ITU-T T35 SEI message (atsc user_identifier = 0x%04x)\n",
- user_identifier);
- break;
- }
- break;
- }
- default:
- av_log(logctx, AV_LOG_VERBOSE,
- "Unsupported User Data Registered ITU-T T35 SEI message (provider_code = %d)\n",
- provider_code);
- break;
- }
-
- return 0;
-}
-
static int decode_nal_sei_active_parameter_sets(HEVCSEI *s, GetBitContext *gb, void *logctx)
{
int num_sps_ids_minus1;
@@ -362,18 +151,6 @@ static int decode_nal_sei_active_parameter_sets(HEVCSEI *s, GetBitContext *gb, v
return 0;
}
-static int decode_nal_sei_alternative_transfer(HEVCSEIAlternativeTransfer *s,
- GetByteContext *gb)
-{
- if (bytestream2_get_bytes_left(gb) < 1)
- return AVERROR_INVALIDDATA;
-
- s->present = 1;
- s->preferred_transfer_characteristics = bytestream2_get_byteu(gb);
-
- return 0;
-}
-
static int decode_nal_sei_timecode(HEVCSEITimeCode *s, GetBitContext *gb)
{
s->num_clock_ts = get_bits(gb, 2);
@@ -420,49 +197,6 @@ static int decode_nal_sei_timecode(HEVCSEITimeCode *s, GetBitContext *gb)
return 0;
}
-static int decode_film_grain_characteristics(HEVCSEIFilmGrainCharacteristics *h,
- GetBitContext *gb)
-{
- h->present = !get_bits1(gb); // film_grain_characteristics_cancel_flag
-
- if (h->present) {
- memset(h, 0, sizeof(*h));
- h->model_id = get_bits(gb, 2);
- h->separate_colour_description_present_flag = get_bits1(gb);
- if (h->separate_colour_description_present_flag) {
- h->bit_depth_luma = get_bits(gb, 3) + 8;
- h->bit_depth_chroma = get_bits(gb, 3) + 8;
- h->full_range = get_bits1(gb);
- h->color_primaries = get_bits(gb, 8);
- h->transfer_characteristics = get_bits(gb, 8);
- h->matrix_coeffs = get_bits(gb, 8);
- }
- h->blending_mode_id = get_bits(gb, 2);
- h->log2_scale_factor = get_bits(gb, 4);
- for (int c = 0; c < 3; c++)
- h->comp_model_present_flag[c] = get_bits1(gb);
- for (int c = 0; c < 3; c++) {
- if (h->comp_model_present_flag[c]) {
- h->num_intensity_intervals[c] = get_bits(gb, 8) + 1;
- h->num_model_values[c] = get_bits(gb, 3) + 1;
- if (h->num_model_values[c] > 6)
- return AVERROR_INVALIDDATA;
- for (int i = 0; i < h->num_intensity_intervals[c]; i++) {
- h->intensity_interval_lower_bound[c][i] = get_bits(gb, 8);
- h->intensity_interval_upper_bound[c][i] = get_bits(gb, 8);
- for (int j = 0; j < h->num_model_values[c]; j++)
- h->comp_model_value[c][i][j] = get_se_golomb_long(gb);
- }
- }
- }
- h->persistence_flag = get_bits1(gb);
-
- h->present = 1;
- }
-
- return 0;
-}
-
static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte,
void *logctx, HEVCSEI *s,
const HEVCParamSets *ps, int type)
@@ -470,10 +204,6 @@ static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte,
switch (type) {
case 256: // Mismatched value from HM 8.1
return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gbyte);
- case SEI_TYPE_FRAME_PACKING_ARRANGEMENT:
- return decode_nal_sei_frame_packing_arrangement(&s->frame_packing, gb);
- case SEI_TYPE_DISPLAY_ORIENTATION:
- return decode_nal_sei_display_orientation(&s->display_orientation, gb);
case SEI_TYPE_PIC_TIMING:
return decode_nal_sei_pic_timing(s, gb, ps, logctx);
case SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME:
@@ -482,19 +212,15 @@ static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte,
return decode_nal_sei_content_light_info(&s->content_light, gbyte);
case SEI_TYPE_ACTIVE_PARAMETER_SETS:
return decode_nal_sei_active_parameter_sets(s, gb, logctx);
- case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35:
- return decode_nal_sei_user_data_registered_itu_t_t35(s, gbyte, logctx);
- case SEI_TYPE_USER_DATA_UNREGISTERED:
- return decode_nal_sei_user_data_unregistered(&s->unregistered, gbyte);
- case SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS:
- return decode_nal_sei_alternative_transfer(&s->alternative_transfer, gbyte);
case SEI_TYPE_TIME_CODE:
return decode_nal_sei_timecode(&s->timecode, gb);
- case SEI_TYPE_FILM_GRAIN_CHARACTERISTICS:
- return decode_film_grain_characteristics(&s->film_grain_characteristics, gb);
- default:
- av_log(logctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
- return 0;
+ default: {
+ int ret = ff_h2645_sei_message_decode(&s->common, type, AV_CODEC_ID_HEVC,
+ gb, gbyte, logctx);
+ if (ret == FF_H2645_SEI_MESSAGE_UNHANDLED)
+ av_log(logctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
+ return ret;
+ }
}
}
@@ -566,15 +292,3 @@ int ff_hevc_decode_nal_sei(GetBitContext *gb, void *logctx, HEVCSEI *s,
} while (bytestream2_get_bytes_left(&gbyte) > 0);
return 1;
}
-
-void ff_hevc_reset_sei(HEVCSEI *s)
-{
- av_buffer_unref(&s->a53_caption.buf_ref);
-
- for (int i = 0; i < s->unregistered.nb_buf_ref; i++)
- av_buffer_unref(&s->unregistered.buf_ref[i]);
- s->unregistered.nb_buf_ref = 0;
- av_freep(&s->unregistered.buf_ref);
- av_buffer_unref(&s->dynamic_hdr_plus.info);
- av_buffer_unref(&s->dynamic_hdr_vivid.info);
-}
diff --git a/libavcodec/hevc_sei.h b/libavcodec/hevc_sei.h
index ef987f678..4189f5e6f 100644
--- a/libavcodec/hevc_sei.h
+++ b/libavcodec/hevc_sei.h
@@ -27,6 +27,7 @@
#include "get_bits.h"
#include "hevc.h"
+#include "h2645_sei.h"
#include "sei.h"
@@ -48,25 +49,10 @@ typedef struct HEVCSEIFramePacking {
int current_frame_is_frame0_flag;
} HEVCSEIFramePacking;
-typedef struct HEVCSEIDisplayOrientation {
- int present;
- int anticlockwise_rotation;
- int hflip, vflip;
-} HEVCSEIDisplayOrientation;
-
typedef struct HEVCSEIPictureTiming {
int picture_struct;
} HEVCSEIPictureTiming;
-typedef struct HEVCSEIA53Caption {
- AVBufferRef *buf_ref;
-} HEVCSEIA53Caption;
-
-typedef struct HEVCSEIUnregistered {
- AVBufferRef **buf_ref;
- int nb_buf_ref;
-} HEVCSEIUnregistered;
-
typedef struct HEVCSEIMasteringDisplay {
int present;
uint16_t display_primaries[3][2];
@@ -75,14 +61,6 @@ typedef struct HEVCSEIMasteringDisplay {
uint32_t min_luminance;
} HEVCSEIMasteringDisplay;
-typedef struct HEVCSEIDynamicHDRPlus {
- AVBufferRef *info;
-} HEVCSEIDynamicHDRPlus;
-
-typedef struct HEVCSEIDynamicHDRVivid {
- AVBufferRef *info;
-} HEVCSEIDynamicHDRVivid;
-
typedef struct HEVCSEIContentLight {
int present;
uint16_t max_content_light_level;
@@ -114,42 +92,14 @@ typedef struct HEVCSEITimeCode {
int32_t time_offset_value[3];
} HEVCSEITimeCode;
-typedef struct HEVCSEIFilmGrainCharacteristics {
- int present;
- int model_id;
- int separate_colour_description_present_flag;
- int bit_depth_luma;
- int bit_depth_chroma;
- int full_range;
- int color_primaries;
- int transfer_characteristics;
- int matrix_coeffs;
- int blending_mode_id;
- int log2_scale_factor;
- int comp_model_present_flag[3];
- uint16_t num_intensity_intervals[3];
- uint8_t num_model_values[3];
- uint8_t intensity_interval_lower_bound[3][256];
- uint8_t intensity_interval_upper_bound[3][256];
- int16_t comp_model_value[3][256][6];
- int persistence_flag;
-} HEVCSEIFilmGrainCharacteristics;
-
typedef struct HEVCSEI {
+ H2645SEI common;
HEVCSEIPictureHash picture_hash;
- HEVCSEIFramePacking frame_packing;
- HEVCSEIDisplayOrientation display_orientation;
HEVCSEIPictureTiming picture_timing;
- HEVCSEIA53Caption a53_caption;
- HEVCSEIUnregistered unregistered;
HEVCSEIMasteringDisplay mastering_display;
- HEVCSEIDynamicHDRPlus dynamic_hdr_plus;
- HEVCSEIDynamicHDRVivid dynamic_hdr_vivid;
HEVCSEIContentLight content_light;
int active_seq_parameter_set_id;
- HEVCSEIAlternativeTransfer alternative_transfer;
HEVCSEITimeCode timecode;
- HEVCSEIFilmGrainCharacteristics film_grain_characteristics;
} HEVCSEI;
struct HEVCParamSets;
@@ -157,13 +107,21 @@ struct HEVCParamSets;
int ff_hevc_decode_nal_sei(GetBitContext *gb, void *logctx, HEVCSEI *s,
const struct HEVCParamSets *ps, enum HEVCNALUnitType type);
+static inline int ff_hevc_sei_ctx_replace(HEVCSEI *dst, const HEVCSEI *src)
+{
+ return ff_h2645_sei_ctx_replace(&dst->common, &src->common);
+}
+
/**
* Reset SEI values that are stored on the Context.
* e.g. Caption data that was extracted during NAL
* parsing.
*
- * @param s HEVCContext.
+ * @param sei HEVCSEI.
*/
-void ff_hevc_reset_sei(HEVCSEI *s);
+static inline void ff_hevc_reset_sei(HEVCSEI *sei)
+{
+ ff_h2645_sei_reset(&sei->common);
+}
#endif /* AVCODEC_HEVC_SEI_H */
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index f8f981e83..567e8d81d 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -26,6 +26,7 @@
#include "config_components.h"
#include "libavutil/attributes.h"
+#include "libavutil/avstring.h"
#include "libavutil/common.h"
#include "libavutil/display.h"
#include "libavutil/film_grain_params.h"
@@ -34,13 +35,13 @@
#include "libavutil/md5.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
-#include "libavutil/stereo3d.h"
#include "libavutil/timecode.h"
#include "bswapdsp.h"
#include "bytestream.h"
#include "cabac_functions.h"
#include "codec_internal.h"
+#include "decode.h"
#include "golomb.h"
#include "hevc.h"
#include "hevc_data.h"
@@ -338,18 +339,18 @@ static void export_stream_params(HEVCContext *s, const HEVCSPS *sps)
avctx->profile = sps->ptl.general_ptl.profile_idc;
avctx->level = sps->ptl.general_ptl.level_idc;
- ff_set_sar(avctx, sps->vui.sar);
+ ff_set_sar(avctx, sps->vui.common.sar);
- if (sps->vui.video_signal_type_present_flag)
- avctx->color_range = sps->vui.video_full_range_flag ? AVCOL_RANGE_JPEG
- : AVCOL_RANGE_MPEG;
+ if (sps->vui.common.video_signal_type_present_flag)
+ avctx->color_range = sps->vui.common.video_full_range_flag ? AVCOL_RANGE_JPEG
+ : AVCOL_RANGE_MPEG;
else
avctx->color_range = AVCOL_RANGE_MPEG;
- if (sps->vui.colour_description_present_flag) {
- avctx->color_primaries = sps->vui.colour_primaries;
- avctx->color_trc = sps->vui.transfer_characteristic;
- avctx->colorspace = sps->vui.matrix_coeffs;
+ if (sps->vui.common.colour_description_present_flag) {
+ avctx->color_primaries = sps->vui.common.colour_primaries;
+ avctx->color_trc = sps->vui.common.transfer_characteristics;
+ avctx->colorspace = sps->vui.common.matrix_coeffs;
} else {
avctx->color_primaries = AVCOL_PRI_UNSPECIFIED;
avctx->color_trc = AVCOL_TRC_UNSPECIFIED;
@@ -358,9 +359,9 @@ static void export_stream_params(HEVCContext *s, const HEVCSPS *sps)
avctx->chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED;
if (sps->chroma_format_idc == 1) {
- if (sps->vui.chroma_loc_info_present_flag) {
- if (sps->vui.chroma_sample_loc_type_top_field <= 5)
- avctx->chroma_sample_location = sps->vui.chroma_sample_loc_type_top_field + 1;
+ if (sps->vui.common.chroma_loc_info_present_flag) {
+ if (sps->vui.common.chroma_sample_loc_type_top_field <= 5)
+ avctx->chroma_sample_location = sps->vui.common.chroma_sample_loc_type_top_field + 1;
} else
avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
}
@@ -382,16 +383,16 @@ static int export_stream_params_from_sei(HEVCContext *s)
{
AVCodecContext *avctx = s->avctx;
- if (s->sei.a53_caption.buf_ref)
+ if (s->sei.common.a53_caption.buf_ref)
s->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
- if (s->sei.alternative_transfer.present &&
- av_color_transfer_name(s->sei.alternative_transfer.preferred_transfer_characteristics) &&
- s->sei.alternative_transfer.preferred_transfer_characteristics != AVCOL_TRC_UNSPECIFIED) {
- avctx->color_trc = s->sei.alternative_transfer.preferred_transfer_characteristics;
+ if (s->sei.common.alternative_transfer.present &&
+ av_color_transfer_name(s->sei.common.alternative_transfer.preferred_transfer_characteristics) &&
+ s->sei.common.alternative_transfer.preferred_transfer_characteristics != AVCOL_TRC_UNSPECIFIED) {
+ avctx->color_trc = s->sei.common.alternative_transfer.preferred_transfer_characteristics;
}
- if (s->sei.film_grain_characteristics.present)
+ if (s->sei.common.film_grain_characteristics.present)
avctx->properties |= FF_CODEC_PROPERTY_FILM_GRAIN;
return 0;
@@ -452,6 +453,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
#endif
break;
case AV_PIX_FMT_YUV444P:
+#if CONFIG_HEVC_VAAPI_HWACCEL
+ *fmt++ = AV_PIX_FMT_VAAPI;
+#endif
#if CONFIG_HEVC_VDPAU_HWACCEL
*fmt++ = AV_PIX_FMT_VDPAU;
#endif
@@ -477,11 +481,19 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
#endif
case AV_PIX_FMT_YUV420P12:
case AV_PIX_FMT_YUV444P12:
+#if CONFIG_HEVC_VAAPI_HWACCEL
+ *fmt++ = AV_PIX_FMT_VAAPI;
+#endif
#if CONFIG_HEVC_VDPAU_HWACCEL
*fmt++ = AV_PIX_FMT_VDPAU;
#endif
#if CONFIG_HEVC_NVDEC_HWACCEL
*fmt++ = AV_PIX_FMT_CUDA;
+#endif
+ break;
+ case AV_PIX_FMT_YUV422P12:
+#if CONFIG_HEVC_VAAPI_HWACCEL
+ *fmt++ = AV_PIX_FMT_VAAPI;
#endif
break;
}
@@ -569,7 +581,7 @@ static int hls_slice_header(HEVCContext *s)
}
if ((IS_IDR(s) || IS_BLA(s)) && sh->first_slice_in_pic_flag) {
- s->seq_decode = (s->seq_decode + 1) & 0xff;
+ s->seq_decode = (s->seq_decode + 1) & HEVC_SEQUENCE_COUNTER_MASK;
s->max_ra = INT_MAX;
if (IS_IDR(s))
ff_hevc_clear_refs(s);
@@ -594,15 +606,8 @@ static int hls_slice_header(HEVCContext *s)
if (s->ps.sps != (HEVCSPS*)s->ps.sps_list[s->ps.pps->sps_id]->data) {
const HEVCSPS *sps = (HEVCSPS*)s->ps.sps_list[s->ps.pps->sps_id]->data;
- const HEVCSPS *last_sps = s->ps.sps;
enum AVPixelFormat pix_fmt;
- if (last_sps && IS_IRAP(s) && s->nal_unit_type != HEVC_NAL_CRA_NUT) {
- if (sps->width != last_sps->width || sps->height != last_sps->height ||
- sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering !=
- last_sps->temporal_layer[last_sps->max_sub_layers - 1].max_dec_pic_buffering)
- sh->no_output_of_prior_pics_flag = 0;
- }
ff_hevc_clear_refs(s);
ret = set_sps(s, sps, sps->pix_fmt);
@@ -614,7 +619,7 @@ static int hls_slice_header(HEVCContext *s)
return pix_fmt;
s->avctx->pix_fmt = pix_fmt;
- s->seq_decode = (s->seq_decode + 1) & 0xff;
+ s->seq_decode = (s->seq_decode + 1) & HEVC_SEQUENCE_COUNTER_MASK;
s->max_ra = INT_MAX;
}
@@ -1005,9 +1010,9 @@ do { \
sao->elem = 0; \
} while (0)
-static void hls_sao_param(HEVCContext *s, int rx, int ry)
+static void hls_sao_param(HEVCLocalContext *lc, int rx, int ry)
{
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
int sao_merge_left_flag = 0;
int sao_merge_up_flag = 0;
SAOParams *sao = &CTB(s->sao, rx, ry);
@@ -1017,11 +1022,11 @@ static void hls_sao_param(HEVCContext *s, int rx, int ry)
s->sh.slice_sample_adaptive_offset_flag[1]) {
if (rx > 0) {
if (lc->ctb_left_flag)
- sao_merge_left_flag = ff_hevc_sao_merge_flag_decode(s);
+ sao_merge_left_flag = ff_hevc_sao_merge_flag_decode(lc);
}
if (ry > 0 && !sao_merge_left_flag) {
if (lc->ctb_up_flag)
- sao_merge_up_flag = ff_hevc_sao_merge_flag_decode(s);
+ sao_merge_up_flag = ff_hevc_sao_merge_flag_decode(lc);
}
}
@@ -1038,27 +1043,27 @@ static void hls_sao_param(HEVCContext *s, int rx, int ry)
sao->type_idx[2] = sao->type_idx[1];
sao->eo_class[2] = sao->eo_class[1];
} else {
- SET_SAO(type_idx[c_idx], ff_hevc_sao_type_idx_decode(s));
+ SET_SAO(type_idx[c_idx], ff_hevc_sao_type_idx_decode(lc));
}
if (sao->type_idx[c_idx] == SAO_NOT_APPLIED)
continue;
for (i = 0; i < 4; i++)
- SET_SAO(offset_abs[c_idx][i], ff_hevc_sao_offset_abs_decode(s));
+ SET_SAO(offset_abs[c_idx][i], ff_hevc_sao_offset_abs_decode(lc));
if (sao->type_idx[c_idx] == SAO_BAND) {
for (i = 0; i < 4; i++) {
if (sao->offset_abs[c_idx][i]) {
SET_SAO(offset_sign[c_idx][i],
- ff_hevc_sao_offset_sign_decode(s));
+ ff_hevc_sao_offset_sign_decode(lc));
} else {
sao->offset_sign[c_idx][i] = 0;
}
}
- SET_SAO(band_position[c_idx], ff_hevc_sao_band_position_decode(s));
+ SET_SAO(band_position[c_idx], ff_hevc_sao_band_position_decode(lc));
} else if (c_idx != 2) {
- SET_SAO(eo_class[c_idx], ff_hevc_sao_eo_class_decode(s));
+ SET_SAO(eo_class[c_idx], ff_hevc_sao_eo_class_decode(lc));
}
// Inferred parameters
@@ -1079,12 +1084,12 @@ static void hls_sao_param(HEVCContext *s, int rx, int ry)
#undef SET_SAO
#undef CTB
-static int hls_cross_component_pred(HEVCContext *s, int idx) {
- HEVCLocalContext *lc = s->HEVClc;
- int log2_res_scale_abs_plus1 = ff_hevc_log2_res_scale_abs(s, idx);
+static int hls_cross_component_pred(HEVCLocalContext *lc, int idx)
+{
+ int log2_res_scale_abs_plus1 = ff_hevc_log2_res_scale_abs(lc, idx);
if (log2_res_scale_abs_plus1 != 0) {
- int res_scale_sign_flag = ff_hevc_res_scale_sign_flag(s, idx);
+ int res_scale_sign_flag = ff_hevc_res_scale_sign_flag(lc, idx);
lc->tu.res_scale_val = (1 << (log2_res_scale_abs_plus1 - 1)) *
(1 - 2 * res_scale_sign_flag);
} else {
@@ -1095,20 +1100,20 @@ static int hls_cross_component_pred(HEVCContext *s, int idx) {
return 0;
}
-static int hls_transform_unit(HEVCContext *s, int x0, int y0,
+static int hls_transform_unit(HEVCLocalContext *lc, int x0, int y0,
int xBase, int yBase, int cb_xBase, int cb_yBase,
int log2_cb_size, int log2_trafo_size,
int blk_idx, int cbf_luma, int *cbf_cb, int *cbf_cr)
{
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
const int log2_trafo_size_c = log2_trafo_size - s->ps.sps->hshift[1];
int i;
if (lc->cu.pred_mode == MODE_INTRA) {
int trafo_size = 1 << log2_trafo_size;
- ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size);
+ ff_hevc_set_neighbour_available(lc, x0, y0, trafo_size, trafo_size);
- s->hpc.intra_pred[log2_trafo_size - 2](s, x0, y0, 0);
+ s->hpc.intra_pred[log2_trafo_size - 2](lc, x0, y0, 0);
}
if (cbf_luma || cbf_cb[0] || cbf_cr[0] ||
@@ -1120,9 +1125,9 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
(cbf_cb[1] || cbf_cr[1]));
if (s->ps.pps->cu_qp_delta_enabled_flag && !lc->tu.is_cu_qp_delta_coded) {
- lc->tu.cu_qp_delta = ff_hevc_cu_qp_delta_abs(s);
+ lc->tu.cu_qp_delta = ff_hevc_cu_qp_delta_abs(lc);
if (lc->tu.cu_qp_delta != 0)
- if (ff_hevc_cu_qp_delta_sign_flag(s) == 1)
+ if (ff_hevc_cu_qp_delta_sign_flag(lc) == 1)
lc->tu.cu_qp_delta = -lc->tu.cu_qp_delta;
lc->tu.is_cu_qp_delta_coded = 1;
@@ -1137,16 +1142,16 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
return AVERROR_INVALIDDATA;
}
- ff_hevc_set_qPy(s, cb_xBase, cb_yBase, log2_cb_size);
+ ff_hevc_set_qPy(lc, cb_xBase, cb_yBase, log2_cb_size);
}
if (s->sh.cu_chroma_qp_offset_enabled_flag && cbf_chroma &&
!lc->cu.cu_transquant_bypass_flag && !lc->tu.is_cu_chroma_qp_offset_coded) {
- int cu_chroma_qp_offset_flag = ff_hevc_cu_chroma_qp_offset_flag(s);
+ int cu_chroma_qp_offset_flag = ff_hevc_cu_chroma_qp_offset_flag(lc);
if (cu_chroma_qp_offset_flag) {
int cu_chroma_qp_offset_idx = 0;
if (s->ps.pps->chroma_qp_offset_list_len_minus1 > 0) {
- cu_chroma_qp_offset_idx = ff_hevc_cu_chroma_qp_offset_idx(s);
+ cu_chroma_qp_offset_idx = ff_hevc_cu_chroma_qp_offset_idx(lc);
av_log(s->avctx, AV_LOG_ERROR,
"cu_chroma_qp_offset_idx not yet tested.\n");
}
@@ -1180,7 +1185,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
lc->tu.cross_pf = 0;
if (cbf_luma)
- ff_hevc_hls_residual_coding(s, x0, y0, log2_trafo_size, scan_idx, 0);
+ ff_hevc_hls_residual_coding(lc, x0, y0, log2_trafo_size, scan_idx, 0);
if (s->ps.sps->chroma_format_idc && (log2_trafo_size > 2 || s->ps.sps->chroma_format_idc == 3)) {
int trafo_size_h = 1 << (log2_trafo_size_c + s->ps.sps->hshift[1]);
int trafo_size_v = 1 << (log2_trafo_size_c + s->ps.sps->vshift[1]);
@@ -1189,22 +1194,22 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
(lc->tu.chroma_mode_c == 4)));
if (lc->tu.cross_pf) {
- hls_cross_component_pred(s, 0);
+ hls_cross_component_pred(lc, 0);
}
for (i = 0; i < (s->ps.sps->chroma_format_idc == 2 ? 2 : 1); i++) {
if (lc->cu.pred_mode == MODE_INTRA) {
- ff_hevc_set_neighbour_available(s, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v);
- s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (i << log2_trafo_size_c), 1);
+ ff_hevc_set_neighbour_available(lc, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v);
+ s->hpc.intra_pred[log2_trafo_size_c - 2](lc, x0, y0 + (i << log2_trafo_size_c), 1);
}
if (cbf_cb[i])
- ff_hevc_hls_residual_coding(s, x0, y0 + (i << log2_trafo_size_c),
+ ff_hevc_hls_residual_coding(lc, x0, y0 + (i << log2_trafo_size_c),
log2_trafo_size_c, scan_idx_c, 1);
else
if (lc->tu.cross_pf) {
ptrdiff_t stride = s->frame->linesize[1];
int hshift = s->ps.sps->hshift[1];
int vshift = s->ps.sps->vshift[1];
- int16_t *coeffs_y = (int16_t*)lc->edge_emu_buffer;
+ const int16_t *coeffs_y = (int16_t*)lc->edge_emu_buffer;
int16_t *coeffs = (int16_t*)lc->edge_emu_buffer2;
int size = 1 << log2_trafo_size_c;
@@ -1218,22 +1223,23 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
}
if (lc->tu.cross_pf) {
- hls_cross_component_pred(s, 1);
+ hls_cross_component_pred(lc, 1);
}
for (i = 0; i < (s->ps.sps->chroma_format_idc == 2 ? 2 : 1); i++) {
if (lc->cu.pred_mode == MODE_INTRA) {
- ff_hevc_set_neighbour_available(s, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v);
- s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (i << log2_trafo_size_c), 2);
+ ff_hevc_set_neighbour_available(lc, x0, y0 + (i << log2_trafo_size_c),
+ trafo_size_h, trafo_size_v);
+ s->hpc.intra_pred[log2_trafo_size_c - 2](lc, x0, y0 + (i << log2_trafo_size_c), 2);
}
if (cbf_cr[i])
- ff_hevc_hls_residual_coding(s, x0, y0 + (i << log2_trafo_size_c),
+ ff_hevc_hls_residual_coding(lc, x0, y0 + (i << log2_trafo_size_c),
log2_trafo_size_c, scan_idx_c, 2);
else
if (lc->tu.cross_pf) {
ptrdiff_t stride = s->frame->linesize[2];
int hshift = s->ps.sps->hshift[2];
int vshift = s->ps.sps->vshift[2];
- int16_t *coeffs_y = (int16_t*)lc->edge_emu_buffer;
+ const int16_t *coeffs_y = (int16_t*)lc->edge_emu_buffer;
int16_t *coeffs = (int16_t*)lc->edge_emu_buffer2;
int size = 1 << log2_trafo_size_c;
@@ -1250,22 +1256,22 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
int trafo_size_v = 1 << (log2_trafo_size + s->ps.sps->vshift[1]);
for (i = 0; i < (s->ps.sps->chroma_format_idc == 2 ? 2 : 1); i++) {
if (lc->cu.pred_mode == MODE_INTRA) {
- ff_hevc_set_neighbour_available(s, xBase, yBase + (i << log2_trafo_size),
+ ff_hevc_set_neighbour_available(lc, xBase, yBase + (i << log2_trafo_size),
trafo_size_h, trafo_size_v);
- s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (i << log2_trafo_size), 1);
+ s->hpc.intra_pred[log2_trafo_size - 2](lc, xBase, yBase + (i << log2_trafo_size), 1);
}
if (cbf_cb[i])
- ff_hevc_hls_residual_coding(s, xBase, yBase + (i << log2_trafo_size),
+ ff_hevc_hls_residual_coding(lc, xBase, yBase + (i << log2_trafo_size),
log2_trafo_size, scan_idx_c, 1);
}
for (i = 0; i < (s->ps.sps->chroma_format_idc == 2 ? 2 : 1); i++) {
if (lc->cu.pred_mode == MODE_INTRA) {
- ff_hevc_set_neighbour_available(s, xBase, yBase + (i << log2_trafo_size),
+ ff_hevc_set_neighbour_available(lc, xBase, yBase + (i << log2_trafo_size),
trafo_size_h, trafo_size_v);
- s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (i << log2_trafo_size), 2);
+ s->hpc.intra_pred[log2_trafo_size - 2](lc, xBase, yBase + (i << log2_trafo_size), 2);
}
if (cbf_cr[i])
- ff_hevc_hls_residual_coding(s, xBase, yBase + (i << log2_trafo_size),
+ ff_hevc_hls_residual_coding(lc, xBase, yBase + (i << log2_trafo_size),
log2_trafo_size, scan_idx_c, 2);
}
}
@@ -1273,27 +1279,27 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
if (log2_trafo_size > 2 || s->ps.sps->chroma_format_idc == 3) {
int trafo_size_h = 1 << (log2_trafo_size_c + s->ps.sps->hshift[1]);
int trafo_size_v = 1 << (log2_trafo_size_c + s->ps.sps->vshift[1]);
- ff_hevc_set_neighbour_available(s, x0, y0, trafo_size_h, trafo_size_v);
- s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0, 1);
- s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0, 2);
+ ff_hevc_set_neighbour_available(lc, x0, y0, trafo_size_h, trafo_size_v);
+ s->hpc.intra_pred[log2_trafo_size_c - 2](lc, x0, y0, 1);
+ s->hpc.intra_pred[log2_trafo_size_c - 2](lc, x0, y0, 2);
if (s->ps.sps->chroma_format_idc == 2) {
- ff_hevc_set_neighbour_available(s, x0, y0 + (1 << log2_trafo_size_c),
+ ff_hevc_set_neighbour_available(lc, x0, y0 + (1 << log2_trafo_size_c),
trafo_size_h, trafo_size_v);
- s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (1 << log2_trafo_size_c), 1);
- s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (1 << log2_trafo_size_c), 2);
+ s->hpc.intra_pred[log2_trafo_size_c - 2](lc, x0, y0 + (1 << log2_trafo_size_c), 1);
+ s->hpc.intra_pred[log2_trafo_size_c - 2](lc, x0, y0 + (1 << log2_trafo_size_c), 2);
}
} else if (blk_idx == 3) {
int trafo_size_h = 1 << (log2_trafo_size + 1);
int trafo_size_v = 1 << (log2_trafo_size + s->ps.sps->vshift[1]);
- ff_hevc_set_neighbour_available(s, xBase, yBase,
+ ff_hevc_set_neighbour_available(lc, xBase, yBase,
trafo_size_h, trafo_size_v);
- s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase, 1);
- s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase, 2);
+ s->hpc.intra_pred[log2_trafo_size - 2](lc, xBase, yBase, 1);
+ s->hpc.intra_pred[log2_trafo_size - 2](lc, xBase, yBase, 2);
if (s->ps.sps->chroma_format_idc == 2) {
- ff_hevc_set_neighbour_available(s, xBase, yBase + (1 << (log2_trafo_size)),
+ ff_hevc_set_neighbour_available(lc, xBase, yBase + (1 << log2_trafo_size),
trafo_size_h, trafo_size_v);
- s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (1 << (log2_trafo_size)), 1);
- s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (1 << (log2_trafo_size)), 2);
+ s->hpc.intra_pred[log2_trafo_size - 2](lc, xBase, yBase + (1 << log2_trafo_size), 1);
+ s->hpc.intra_pred[log2_trafo_size - 2](lc, xBase, yBase + (1 << log2_trafo_size), 2);
}
}
}
@@ -1301,7 +1307,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
return 0;
}
-static void set_deblocking_bypass(HEVCContext *s, int x0, int y0, int log2_cb_size)
+static void set_deblocking_bypass(const HEVCContext *s, int x0, int y0, int log2_cb_size)
{
int cb_size = 1 << log2_cb_size;
int log2_min_pu_size = s->ps.sps->log2_min_pu_size;
@@ -1316,13 +1322,13 @@ static void set_deblocking_bypass(HEVCContext *s, int x0, int y0, int log2_cb_si
s->is_pcm[i + j * min_pu_width] = 2;
}
-static int hls_transform_tree(HEVCContext *s, int x0, int y0,
+static int hls_transform_tree(HEVCLocalContext *lc, int x0, int y0,
int xBase, int yBase, int cb_xBase, int cb_yBase,
int log2_cb_size, int log2_trafo_size,
int trafo_depth, int blk_idx,
const int *base_cbf_cb, const int *base_cbf_cr)
{
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
uint8_t split_transform_flag;
int cbf_cb[2];
int cbf_cr[2];
@@ -1354,7 +1360,7 @@ static int hls_transform_tree(HEVCContext *s, int x0, int y0,
log2_trafo_size > s->ps.sps->log2_min_tb_size &&
trafo_depth < lc->cu.max_trafo_depth &&
!(lc->cu.intra_split_flag && trafo_depth == 0)) {
- split_transform_flag = ff_hevc_split_transform_flag_decode(s, log2_trafo_size);
+ split_transform_flag = ff_hevc_split_transform_flag_decode(lc, log2_trafo_size);
} else {
int inter_split = s->ps.sps->max_transform_hierarchy_depth_inter == 0 &&
lc->cu.pred_mode == MODE_INTER &&
@@ -1368,16 +1374,16 @@ static int hls_transform_tree(HEVCContext *s, int x0, int y0,
if (s->ps.sps->chroma_format_idc && (log2_trafo_size > 2 || s->ps.sps->chroma_format_idc == 3)) {
if (trafo_depth == 0 || cbf_cb[0]) {
- cbf_cb[0] = ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
+ cbf_cb[0] = ff_hevc_cbf_cb_cr_decode(lc, trafo_depth);
if (s->ps.sps->chroma_format_idc == 2 && (!split_transform_flag || log2_trafo_size == 3)) {
- cbf_cb[1] = ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
+ cbf_cb[1] = ff_hevc_cbf_cb_cr_decode(lc, trafo_depth);
}
}
if (trafo_depth == 0 || cbf_cr[0]) {
- cbf_cr[0] = ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
+ cbf_cr[0] = ff_hevc_cbf_cb_cr_decode(lc, trafo_depth);
if (s->ps.sps->chroma_format_idc == 2 && (!split_transform_flag || log2_trafo_size == 3)) {
- cbf_cr[1] = ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
+ cbf_cr[1] = ff_hevc_cbf_cb_cr_decode(lc, trafo_depth);
}
}
}
@@ -1389,7 +1395,7 @@ static int hls_transform_tree(HEVCContext *s, int x0, int y0,
#define SUBDIVIDE(x, y, idx) \
do { \
- ret = hls_transform_tree(s, x, y, x0, y0, cb_xBase, cb_yBase, log2_cb_size, \
+ ret = hls_transform_tree(lc, x, y, x0, y0, cb_xBase, cb_yBase, log2_cb_size,\
log2_trafo_size - 1, trafo_depth + 1, idx, \
cbf_cb, cbf_cr); \
if (ret < 0) \
@@ -1411,10 +1417,10 @@ do {
if (lc->cu.pred_mode == MODE_INTRA || trafo_depth != 0 ||
cbf_cb[0] || cbf_cr[0] ||
(s->ps.sps->chroma_format_idc == 2 && (cbf_cb[1] || cbf_cr[1]))) {
- cbf_luma = ff_hevc_cbf_luma_decode(s, trafo_depth);
+ cbf_luma = ff_hevc_cbf_luma_decode(lc, trafo_depth);
}
- ret = hls_transform_unit(s, x0, y0, xBase, yBase, cb_xBase, cb_yBase,
+ ret = hls_transform_unit(lc, x0, y0, xBase, yBase, cb_xBase, cb_yBase,
log2_cb_size, log2_trafo_size,
blk_idx, cbf_luma, cbf_cb, cbf_cr);
if (ret < 0)
@@ -1430,7 +1436,7 @@ do {
}
}
if (!s->sh.disable_deblocking_filter_flag) {
- ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_trafo_size);
+ ff_hevc_deblocking_boundary_strengths(lc, x0, y0, log2_trafo_size);
if (s->ps.pps->transquant_bypass_enable_flag &&
lc->cu.cu_transquant_bypass_flag)
set_deblocking_bypass(s, x0, y0, log2_trafo_size);
@@ -1439,9 +1445,9 @@ do {
return 0;
}
-static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size)
+static int hls_pcm_sample(HEVCLocalContext *lc, int x0, int y0, int log2_cb_size)
{
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
GetBitContext gb;
int cb_size = 1 << log2_cb_size;
ptrdiff_t stride0 = s->frame->linesize[0];
@@ -1459,7 +1465,7 @@ static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size)
int ret;
if (!s->sh.disable_deblocking_filter_flag)
- ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size);
+ ff_hevc_deblocking_boundary_strengths(lc, x0, y0, log2_cb_size);
ret = init_get_bits(&gb, pcm, length);
if (ret < 0)
@@ -1496,12 +1502,12 @@ static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size)
* @param luma_offset additive offset applied to the luma prediction value
*/
-static void luma_mc_uni(HEVCContext *s, uint8_t *dst, ptrdiff_t dststride,
- AVFrame *ref, const Mv *mv, int x_off, int y_off,
+static void luma_mc_uni(HEVCLocalContext *lc, uint8_t *dst, ptrdiff_t dststride,
+ const AVFrame *ref, const Mv *mv, int x_off, int y_off,
int block_w, int block_h, int luma_weight, int luma_offset)
{
- HEVCLocalContext *lc = s->HEVClc;
- uint8_t *src = ref->data[0];
+ const HEVCContext *const s = lc->parent;
+ const uint8_t *src = ref->data[0];
ptrdiff_t srcstride = ref->linesize[0];
int pic_width = s->ps.sps->width;
int pic_height = s->ps.sps->height;
@@ -1557,11 +1563,12 @@ static void luma_mc_uni(HEVCContext *s, uint8_t *dst, ptrdiff_t dststride,
* @param mv1 motion vector1 (relative to block position) to get pixel data from
* @param current_mv current motion vector structure
*/
- static void luma_mc_bi(HEVCContext *s, uint8_t *dst, ptrdiff_t dststride,
- AVFrame *ref0, const Mv *mv0, int x_off, int y_off,
- int block_w, int block_h, AVFrame *ref1, const Mv *mv1, struct MvField *current_mv)
+ static void luma_mc_bi(HEVCLocalContext *lc, uint8_t *dst, ptrdiff_t dststride,
+ const AVFrame *ref0, const Mv *mv0, int x_off, int y_off,
+ int block_w, int block_h, const AVFrame *ref1,
+ const Mv *mv1, struct MvField *current_mv)
{
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
ptrdiff_t src0stride = ref0->linesize[0];
ptrdiff_t src1stride = ref1->linesize[0];
int pic_width = s->ps.sps->width;
@@ -1578,8 +1585,8 @@ static void luma_mc_uni(HEVCContext *s, uint8_t *dst, ptrdiff_t dststride,
int y_off1 = y_off + (mv1->y >> 2);
int idx = hevc_pel_weight[block_w];
- uint8_t *src0 = ref0->data[0] + y_off0 * src0stride + (int)((unsigned)x_off0 << s->ps.sps->pixel_shift);
- uint8_t *src1 = ref1->data[0] + y_off1 * src1stride + (int)((unsigned)x_off1 << s->ps.sps->pixel_shift);
+ const uint8_t *src0 = ref0->data[0] + y_off0 * src0stride + (int)((unsigned)x_off0 << s->ps.sps->pixel_shift);
+ const uint8_t *src1 = ref1->data[0] + y_off1 * src1stride + (int)((unsigned)x_off1 << s->ps.sps->pixel_shift);
if (x_off0 < QPEL_EXTRA_BEFORE || y_off0 < QPEL_EXTRA_AFTER ||
x_off0 >= pic_width - block_w - QPEL_EXTRA_AFTER ||
@@ -1648,11 +1655,12 @@ static void luma_mc_uni(HEVCContext *s, uint8_t *dst, ptrdiff_t dststride,
* @param chroma_offset additive offset applied to the chroma prediction value
*/
-static void chroma_mc_uni(HEVCContext *s, uint8_t *dst0,
- ptrdiff_t dststride, uint8_t *src0, ptrdiff_t srcstride, int reflist,
- int x_off, int y_off, int block_w, int block_h, struct MvField *current_mv, int chroma_weight, int chroma_offset)
+static void chroma_mc_uni(HEVCLocalContext *lc, uint8_t *dst0,
+ ptrdiff_t dststride, const uint8_t *src0, ptrdiff_t srcstride, int reflist,
+ int x_off, int y_off, int block_w, int block_h,
+ const struct MvField *current_mv, int chroma_weight, int chroma_offset)
{
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
int pic_width = s->ps.sps->width >> s->ps.sps->hshift[1];
int pic_height = s->ps.sps->height >> s->ps.sps->vshift[1];
const Mv *mv = ¤t_mv->mv[reflist];
@@ -1713,20 +1721,21 @@ static void chroma_mc_uni(HEVCContext *s, uint8_t *dst0,
* @param current_mv current motion vector structure
* @param cidx chroma component(cb, cr)
*/
-static void chroma_mc_bi(HEVCContext *s, uint8_t *dst0, ptrdiff_t dststride, AVFrame *ref0, AVFrame *ref1,
- int x_off, int y_off, int block_w, int block_h, struct MvField *current_mv, int cidx)
+static void chroma_mc_bi(HEVCLocalContext *lc, uint8_t *dst0, ptrdiff_t dststride,
+ const AVFrame *ref0, const AVFrame *ref1,
+ int x_off, int y_off, int block_w, int block_h, const MvField *current_mv, int cidx)
{
- HEVCLocalContext *lc = s->HEVClc;
- uint8_t *src1 = ref0->data[cidx+1];
- uint8_t *src2 = ref1->data[cidx+1];
+ const HEVCContext *const s = lc->parent;
+ const uint8_t *src1 = ref0->data[cidx+1];
+ const uint8_t *src2 = ref1->data[cidx+1];
ptrdiff_t src1stride = ref0->linesize[cidx+1];
ptrdiff_t src2stride = ref1->linesize[cidx+1];
int weight_flag = (s->sh.slice_type == HEVC_SLICE_P && s->ps.pps->weighted_pred_flag) ||
(s->sh.slice_type == HEVC_SLICE_B && s->ps.pps->weighted_bipred_flag);
int pic_width = s->ps.sps->width >> s->ps.sps->hshift[1];
int pic_height = s->ps.sps->height >> s->ps.sps->vshift[1];
- Mv *mv0 = ¤t_mv->mv[0];
- Mv *mv1 = ¤t_mv->mv[1];
+ const Mv *const mv0 = ¤t_mv->mv[0];
+ const Mv *const mv1 = ¤t_mv->mv[1];
int hshift = s->ps.sps->hshift[1];
int vshift = s->ps.sps->vshift[1];
@@ -1803,7 +1812,7 @@ static void chroma_mc_bi(HEVCContext *s, uint8_t *dst0, ptrdiff_t dststride, AVF
_mx1, _my1, block_w);
}
-static void hevc_await_progress(HEVCContext *s, HEVCFrame *ref,
+static void hevc_await_progress(const HEVCContext *s, const HEVCFrame *ref,
const Mv *mv, int y0, int height)
{
if (s->threads_type == FF_THREAD_FRAME ) {
@@ -1813,27 +1822,27 @@ static void hevc_await_progress(HEVCContext *s, HEVCFrame *ref,
}
}
-static void hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW,
+static void hevc_luma_mv_mvp_mode(HEVCLocalContext *lc, int x0, int y0, int nPbW,
int nPbH, int log2_cb_size, int part_idx,
int merge_idx, MvField *mv)
{
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
enum InterPredIdc inter_pred_idc = PRED_L0;
int mvp_flag;
- ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH);
+ ff_hevc_set_neighbour_available(lc, x0, y0, nPbW, nPbH);
mv->pred_flag = 0;
if (s->sh.slice_type == HEVC_SLICE_B)
- inter_pred_idc = ff_hevc_inter_pred_idc_decode(s, nPbW, nPbH);
+ inter_pred_idc = ff_hevc_inter_pred_idc_decode(lc, nPbW, nPbH);
if (inter_pred_idc != PRED_L1) {
if (s->sh.nb_refs[L0])
- mv->ref_idx[0]= ff_hevc_ref_idx_lx_decode(s, s->sh.nb_refs[L0]);
+ mv->ref_idx[0]= ff_hevc_ref_idx_lx_decode(lc, s->sh.nb_refs[L0]);
mv->pred_flag = PF_L0;
- ff_hevc_hls_mvd_coding(s, x0, y0, 0);
- mvp_flag = ff_hevc_mvp_lx_flag_decode(s);
- ff_hevc_luma_mv_mvp_mode(s, x0, y0, nPbW, nPbH, log2_cb_size,
+ ff_hevc_hls_mvd_coding(lc, x0, y0, 0);
+ mvp_flag = ff_hevc_mvp_lx_flag_decode(lc);
+ ff_hevc_luma_mv_mvp_mode(lc, x0, y0, nPbW, nPbH, log2_cb_size,
part_idx, merge_idx, mv, mvp_flag, 0);
mv->mv[0].x += lc->pu.mvd.x;
mv->mv[0].y += lc->pu.mvd.y;
@@ -1841,39 +1850,39 @@ static void hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW,
if (inter_pred_idc != PRED_L0) {
if (s->sh.nb_refs[L1])
- mv->ref_idx[1]= ff_hevc_ref_idx_lx_decode(s, s->sh.nb_refs[L1]);
+ mv->ref_idx[1]= ff_hevc_ref_idx_lx_decode(lc, s->sh.nb_refs[L1]);
if (s->sh.mvd_l1_zero_flag == 1 && inter_pred_idc == PRED_BI) {
AV_ZERO32(&lc->pu.mvd);
} else {
- ff_hevc_hls_mvd_coding(s, x0, y0, 1);
+ ff_hevc_hls_mvd_coding(lc, x0, y0, 1);
}
mv->pred_flag += PF_L1;
- mvp_flag = ff_hevc_mvp_lx_flag_decode(s);
- ff_hevc_luma_mv_mvp_mode(s, x0, y0, nPbW, nPbH, log2_cb_size,
+ mvp_flag = ff_hevc_mvp_lx_flag_decode(lc);
+ ff_hevc_luma_mv_mvp_mode(lc, x0, y0, nPbW, nPbH, log2_cb_size,
part_idx, merge_idx, mv, mvp_flag, 1);
mv->mv[1].x += lc->pu.mvd.x;
mv->mv[1].y += lc->pu.mvd.y;
}
}
-static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
+static void hls_prediction_unit(HEVCLocalContext *lc, int x0, int y0,
int nPbW, int nPbH,
int log2_cb_size, int partIdx, int idx)
{
#define POS(c_idx, x, y) \
&s->frame->data[c_idx][((y) >> s->ps.sps->vshift[c_idx]) * s->frame->linesize[c_idx] + \
(((x) >> s->ps.sps->hshift[c_idx]) << s->ps.sps->pixel_shift)]
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
int merge_idx = 0;
struct MvField current_mv = {{{ 0 }}};
int min_pu_width = s->ps.sps->min_pu_width;
MvField *tab_mvf = s->ref->tab_mvf;
- RefPicList *refPicList = s->ref->refPicList;
- HEVCFrame *ref0 = NULL, *ref1 = NULL;
+ const RefPicList *refPicList = s->ref->refPicList;
+ const HEVCFrame *ref0 = NULL, *ref1 = NULL;
uint8_t *dst0 = POS(0, x0, y0);
uint8_t *dst1 = POS(1, x0, y0);
uint8_t *dst2 = POS(2, x0, y0);
@@ -1887,18 +1896,18 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
int skip_flag = SAMPLE_CTB(s->skip_flag, x_cb, y_cb);
if (!skip_flag)
- lc->pu.merge_flag = ff_hevc_merge_flag_decode(s);
+ lc->pu.merge_flag = ff_hevc_merge_flag_decode(lc);
if (skip_flag || lc->pu.merge_flag) {
if (s->sh.max_num_merge_cand > 1)
- merge_idx = ff_hevc_merge_idx_decode(s);
+ merge_idx = ff_hevc_merge_idx_decode(lc);
else
merge_idx = 0;
- ff_hevc_luma_mv_merge_mode(s, x0, y0, nPbW, nPbH, log2_cb_size,
+ ff_hevc_luma_mv_merge_mode(lc, x0, y0, nPbW, nPbH, log2_cb_size,
partIdx, merge_idx, ¤t_mv);
} else {
- hevc_luma_mv_mvp_mode(s, x0, y0, nPbW, nPbH, log2_cb_size,
+ hevc_luma_mv_mvp_mode(lc, x0, y0, nPbW, nPbH, log2_cb_size,
partIdx, merge_idx, ¤t_mv);
}
@@ -1928,16 +1937,16 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
int nPbW_c = nPbW >> s->ps.sps->hshift[1];
int nPbH_c = nPbH >> s->ps.sps->vshift[1];
- luma_mc_uni(s, dst0, s->frame->linesize[0], ref0->frame,
+ luma_mc_uni(lc, dst0, s->frame->linesize[0], ref0->frame,
¤t_mv.mv[0], x0, y0, nPbW, nPbH,
s->sh.luma_weight_l0[current_mv.ref_idx[0]],
s->sh.luma_offset_l0[current_mv.ref_idx[0]]);
if (s->ps.sps->chroma_format_idc) {
- chroma_mc_uni(s, dst1, s->frame->linesize[1], ref0->frame->data[1], ref0->frame->linesize[1],
+ chroma_mc_uni(lc, dst1, s->frame->linesize[1], ref0->frame->data[1], ref0->frame->linesize[1],
0, x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv,
s->sh.chroma_weight_l0[current_mv.ref_idx[0]][0], s->sh.chroma_offset_l0[current_mv.ref_idx[0]][0]);
- chroma_mc_uni(s, dst2, s->frame->linesize[2], ref0->frame->data[2], ref0->frame->linesize[2],
+ chroma_mc_uni(lc, dst2, s->frame->linesize[2], ref0->frame->data[2], ref0->frame->linesize[2],
0, x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv,
s->sh.chroma_weight_l0[current_mv.ref_idx[0]][1], s->sh.chroma_offset_l0[current_mv.ref_idx[0]][1]);
}
@@ -1947,17 +1956,17 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
int nPbW_c = nPbW >> s->ps.sps->hshift[1];
int nPbH_c = nPbH >> s->ps.sps->vshift[1];
- luma_mc_uni(s, dst0, s->frame->linesize[0], ref1->frame,
+ luma_mc_uni(lc, dst0, s->frame->linesize[0], ref1->frame,
¤t_mv.mv[1], x0, y0, nPbW, nPbH,
s->sh.luma_weight_l1[current_mv.ref_idx[1]],
s->sh.luma_offset_l1[current_mv.ref_idx[1]]);
if (s->ps.sps->chroma_format_idc) {
- chroma_mc_uni(s, dst1, s->frame->linesize[1], ref1->frame->data[1], ref1->frame->linesize[1],
+ chroma_mc_uni(lc, dst1, s->frame->linesize[1], ref1->frame->data[1], ref1->frame->linesize[1],
1, x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv,
s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][0]);
- chroma_mc_uni(s, dst2, s->frame->linesize[2], ref1->frame->data[2], ref1->frame->linesize[2],
+ chroma_mc_uni(lc, dst2, s->frame->linesize[2], ref1->frame->data[2], ref1->frame->linesize[2],
1, x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv,
s->sh.chroma_weight_l1[current_mv.ref_idx[1]][1], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][1]);
}
@@ -1967,15 +1976,15 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
int nPbW_c = nPbW >> s->ps.sps->hshift[1];
int nPbH_c = nPbH >> s->ps.sps->vshift[1];
- luma_mc_bi(s, dst0, s->frame->linesize[0], ref0->frame,
+ luma_mc_bi(lc, dst0, s->frame->linesize[0], ref0->frame,
¤t_mv.mv[0], x0, y0, nPbW, nPbH,
ref1->frame, ¤t_mv.mv[1], ¤t_mv);
if (s->ps.sps->chroma_format_idc) {
- chroma_mc_bi(s, dst1, s->frame->linesize[1], ref0->frame, ref1->frame,
+ chroma_mc_bi(lc, dst1, s->frame->linesize[1], ref0->frame, ref1->frame,
x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv, 0);
- chroma_mc_bi(s, dst2, s->frame->linesize[2], ref0->frame, ref1->frame,
+ chroma_mc_bi(lc, dst2, s->frame->linesize[2], ref0->frame, ref1->frame,
x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv, 1);
}
}
@@ -1984,10 +1993,10 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
/**
* 8.4.1
*/
-static int luma_intra_pred_mode(HEVCContext *s, int x0, int y0, int pu_size,
+static int luma_intra_pred_mode(HEVCLocalContext *lc, int x0, int y0, int pu_size,
int prev_intra_luma_pred_flag)
{
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
int x_pu = x0 >> s->ps.sps->log2_min_pu_size;
int y_pu = y0 >> s->ps.sps->log2_min_pu_size;
int min_pu_width = s->ps.sps->min_pu_width;
@@ -2064,7 +2073,7 @@ static int luma_intra_pred_mode(HEVCContext *s, int x0, int y0, int pu_size,
return intra_pred_mode;
}
-static av_always_inline void set_ct_depth(HEVCContext *s, int x0, int y0,
+static av_always_inline void set_ct_depth(const HEVCContext *s, int x0, int y0,
int log2_cb_size, int ct_depth)
{
int length = (1 << log2_cb_size) >> s->ps.sps->log2_min_cb_size;
@@ -2081,10 +2090,10 @@ static const uint8_t tab_mode_idx[] = {
0, 1, 2, 2, 2, 2, 3, 5, 7, 8, 10, 12, 13, 15, 17, 18, 19, 20,
21, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28, 29, 29, 30, 31};
-static void intra_prediction_unit(HEVCContext *s, int x0, int y0,
+static void intra_prediction_unit(HEVCLocalContext *lc, int x0, int y0,
int log2_cb_size)
{
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
static const uint8_t intra_chroma_table[4] = { 0, 26, 10, 1 };
uint8_t prev_intra_luma_pred_flag[4];
int split = lc->cu.part_mode == PART_NxN;
@@ -2095,17 +2104,17 @@ static void intra_prediction_unit(HEVCContext *s, int x0, int y0,
for (i = 0; i < side; i++)
for (j = 0; j < side; j++)
- prev_intra_luma_pred_flag[2 * i + j] = ff_hevc_prev_intra_luma_pred_flag_decode(s);
+ prev_intra_luma_pred_flag[2 * i + j] = ff_hevc_prev_intra_luma_pred_flag_decode(lc);
for (i = 0; i < side; i++) {
for (j = 0; j < side; j++) {
if (prev_intra_luma_pred_flag[2 * i + j])
- lc->pu.mpm_idx = ff_hevc_mpm_idx_decode(s);
+ lc->pu.mpm_idx = ff_hevc_mpm_idx_decode(lc);
else
- lc->pu.rem_intra_luma_pred_mode = ff_hevc_rem_intra_luma_pred_mode_decode(s);
+ lc->pu.rem_intra_luma_pred_mode = ff_hevc_rem_intra_luma_pred_mode_decode(lc);
lc->pu.intra_pred_mode[2 * i + j] =
- luma_intra_pred_mode(s, x0 + pb_size * j, y0 + pb_size * i, pb_size,
+ luma_intra_pred_mode(lc, x0 + pb_size * j, y0 + pb_size * i, pb_size,
prev_intra_luma_pred_flag[2 * i + j]);
}
}
@@ -2113,7 +2122,7 @@ static void intra_prediction_unit(HEVCContext *s, int x0, int y0,
if (s->ps.sps->chroma_format_idc == 3) {
for (i = 0; i < side; i++) {
for (j = 0; j < side; j++) {
- lc->pu.chroma_mode_c[2 * i + j] = chroma_mode = ff_hevc_intra_chroma_pred_mode_decode(s);
+ lc->pu.chroma_mode_c[2 * i + j] = chroma_mode = ff_hevc_intra_chroma_pred_mode_decode(lc);
if (chroma_mode != 4) {
if (lc->pu.intra_pred_mode[2 * i + j] == intra_chroma_table[chroma_mode])
lc->pu.intra_pred_mode_c[2 * i + j] = 34;
@@ -2126,7 +2135,7 @@ static void intra_prediction_unit(HEVCContext *s, int x0, int y0,
}
} else if (s->ps.sps->chroma_format_idc == 2) {
int mode_idx;
- lc->pu.chroma_mode_c[0] = chroma_mode = ff_hevc_intra_chroma_pred_mode_decode(s);
+ lc->pu.chroma_mode_c[0] = chroma_mode = ff_hevc_intra_chroma_pred_mode_decode(lc);
if (chroma_mode != 4) {
if (lc->pu.intra_pred_mode[0] == intra_chroma_table[chroma_mode])
mode_idx = 34;
@@ -2137,7 +2146,7 @@ static void intra_prediction_unit(HEVCContext *s, int x0, int y0,
}
lc->pu.intra_pred_mode_c[0] = tab_mode_idx[mode_idx];
} else if (s->ps.sps->chroma_format_idc != 0) {
- chroma_mode = ff_hevc_intra_chroma_pred_mode_decode(s);
+ chroma_mode = ff_hevc_intra_chroma_pred_mode_decode(lc);
if (chroma_mode != 4) {
if (lc->pu.intra_pred_mode[0] == intra_chroma_table[chroma_mode])
lc->pu.intra_pred_mode_c[0] = 34;
@@ -2149,11 +2158,11 @@ static void intra_prediction_unit(HEVCContext *s, int x0, int y0,
}
}
-static void intra_prediction_unit_default_value(HEVCContext *s,
+static void intra_prediction_unit_default_value(HEVCLocalContext *lc,
int x0, int y0,
int log2_cb_size)
{
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
int pb_size = 1 << log2_cb_size;
int size_in_pus = pb_size >> s->ps.sps->log2_min_pu_size;
int min_pu_width = s->ps.sps->min_pu_width;
@@ -2172,10 +2181,9 @@ static void intra_prediction_unit_default_value(HEVCContext *s,
tab_mvf[(y_pu + j) * min_pu_width + x_pu + k].pred_flag = PF_INTRA;
}
-static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size)
+static int hls_coding_unit(HEVCLocalContext *lc, const HEVCContext *s, int x0, int y0, int log2_cb_size)
{
int cb_size = 1 << log2_cb_size;
- HEVCLocalContext *lc = s->HEVClc;
int log2_min_cb_size = s->ps.sps->log2_min_cb_size;
int length = cb_size >> log2_min_cb_size;
int min_cb_width = s->ps.sps->min_cb_width;
@@ -2195,14 +2203,14 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size)
for (x = 0; x < 4; x++)
lc->pu.intra_pred_mode[x] = 1;
if (s->ps.pps->transquant_bypass_enable_flag) {
- lc->cu.cu_transquant_bypass_flag = ff_hevc_cu_transquant_bypass_flag_decode(s);
+ lc->cu.cu_transquant_bypass_flag = ff_hevc_cu_transquant_bypass_flag_decode(lc);
if (lc->cu.cu_transquant_bypass_flag)
set_deblocking_bypass(s, x0, y0, log2_cb_size);
} else
lc->cu.cu_transquant_bypass_flag = 0;
if (s->sh.slice_type != HEVC_SLICE_I) {
- uint8_t skip_flag = ff_hevc_skip_flag_decode(s, x0, y0, x_cb, y_cb);
+ uint8_t skip_flag = ff_hevc_skip_flag_decode(lc, x0, y0, x_cb, y_cb);
x = y_cb * min_cb_width + x_cb;
for (y = 0; y < length; y++) {
@@ -2219,19 +2227,19 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size)
}
if (SAMPLE_CTB(s->skip_flag, x_cb, y_cb)) {
- hls_prediction_unit(s, x0, y0, cb_size, cb_size, log2_cb_size, 0, idx);
- intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);
+ hls_prediction_unit(lc, x0, y0, cb_size, cb_size, log2_cb_size, 0, idx);
+ intra_prediction_unit_default_value(lc, x0, y0, log2_cb_size);
if (!s->sh.disable_deblocking_filter_flag)
- ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size);
+ ff_hevc_deblocking_boundary_strengths(lc, x0, y0, log2_cb_size);
} else {
int pcm_flag = 0;
if (s->sh.slice_type != HEVC_SLICE_I)
- lc->cu.pred_mode = ff_hevc_pred_mode_decode(s);
+ lc->cu.pred_mode = ff_hevc_pred_mode_decode(lc);
if (lc->cu.pred_mode != MODE_INTRA ||
log2_cb_size == s->ps.sps->log2_min_cb_size) {
- lc->cu.part_mode = ff_hevc_part_mode_decode(s, log2_cb_size);
+ lc->cu.part_mode = ff_hevc_part_mode_decode(lc, log2_cb_size);
lc->cu.intra_split_flag = lc->cu.part_mode == PART_NxN &&
lc->cu.pred_mode == MODE_INTRA;
}
@@ -2240,54 +2248,54 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size)
if (lc->cu.part_mode == PART_2Nx2N && s->ps.sps->pcm_enabled_flag &&
log2_cb_size >= s->ps.sps->pcm.log2_min_pcm_cb_size &&
log2_cb_size <= s->ps.sps->pcm.log2_max_pcm_cb_size) {
- pcm_flag = ff_hevc_pcm_flag_decode(s);
+ pcm_flag = ff_hevc_pcm_flag_decode(lc);
}
if (pcm_flag) {
- intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);
- ret = hls_pcm_sample(s, x0, y0, log2_cb_size);
+ intra_prediction_unit_default_value(lc, x0, y0, log2_cb_size);
+ ret = hls_pcm_sample(lc, x0, y0, log2_cb_size);
if (s->ps.sps->pcm.loop_filter_disable_flag)
set_deblocking_bypass(s, x0, y0, log2_cb_size);
if (ret < 0)
return ret;
} else {
- intra_prediction_unit(s, x0, y0, log2_cb_size);
+ intra_prediction_unit(lc, x0, y0, log2_cb_size);
}
} else {
- intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);
+ intra_prediction_unit_default_value(lc, x0, y0, log2_cb_size);
switch (lc->cu.part_mode) {
case PART_2Nx2N:
- hls_prediction_unit(s, x0, y0, cb_size, cb_size, log2_cb_size, 0, idx);
+ hls_prediction_unit(lc, x0, y0, cb_size, cb_size, log2_cb_size, 0, idx);
break;
case PART_2NxN:
- hls_prediction_unit(s, x0, y0, cb_size, cb_size / 2, log2_cb_size, 0, idx);
- hls_prediction_unit(s, x0, y0 + cb_size / 2, cb_size, cb_size / 2, log2_cb_size, 1, idx);
+ hls_prediction_unit(lc, x0, y0, cb_size, cb_size / 2, log2_cb_size, 0, idx);
+ hls_prediction_unit(lc, x0, y0 + cb_size / 2, cb_size, cb_size / 2, log2_cb_size, 1, idx);
break;
case PART_Nx2N:
- hls_prediction_unit(s, x0, y0, cb_size / 2, cb_size, log2_cb_size, 0, idx - 1);
- hls_prediction_unit(s, x0 + cb_size / 2, y0, cb_size / 2, cb_size, log2_cb_size, 1, idx - 1);
+ hls_prediction_unit(lc, x0, y0, cb_size / 2, cb_size, log2_cb_size, 0, idx - 1);
+ hls_prediction_unit(lc, x0 + cb_size / 2, y0, cb_size / 2, cb_size, log2_cb_size, 1, idx - 1);
break;
case PART_2NxnU:
- hls_prediction_unit(s, x0, y0, cb_size, cb_size / 4, log2_cb_size, 0, idx);
- hls_prediction_unit(s, x0, y0 + cb_size / 4, cb_size, cb_size * 3 / 4, log2_cb_size, 1, idx);
+ hls_prediction_unit(lc, x0, y0, cb_size, cb_size / 4, log2_cb_size, 0, idx);
+ hls_prediction_unit(lc, x0, y0 + cb_size / 4, cb_size, cb_size * 3 / 4, log2_cb_size, 1, idx);
break;
case PART_2NxnD:
- hls_prediction_unit(s, x0, y0, cb_size, cb_size * 3 / 4, log2_cb_size, 0, idx);
- hls_prediction_unit(s, x0, y0 + cb_size * 3 / 4, cb_size, cb_size / 4, log2_cb_size, 1, idx);
+ hls_prediction_unit(lc, x0, y0, cb_size, cb_size * 3 / 4, log2_cb_size, 0, idx);
+ hls_prediction_unit(lc, x0, y0 + cb_size * 3 / 4, cb_size, cb_size / 4, log2_cb_size, 1, idx);
break;
case PART_nLx2N:
- hls_prediction_unit(s, x0, y0, cb_size / 4, cb_size, log2_cb_size, 0, idx - 2);
- hls_prediction_unit(s, x0 + cb_size / 4, y0, cb_size * 3 / 4, cb_size, log2_cb_size, 1, idx - 2);
+ hls_prediction_unit(lc, x0, y0, cb_size / 4, cb_size, log2_cb_size, 0, idx - 2);
+ hls_prediction_unit(lc, x0 + cb_size / 4, y0, cb_size * 3 / 4, cb_size, log2_cb_size, 1, idx - 2);
break;
case PART_nRx2N:
- hls_prediction_unit(s, x0, y0, cb_size * 3 / 4, cb_size, log2_cb_size, 0, idx - 2);
- hls_prediction_unit(s, x0 + cb_size * 3 / 4, y0, cb_size / 4, cb_size, log2_cb_size, 1, idx - 2);
+ hls_prediction_unit(lc, x0, y0, cb_size * 3 / 4, cb_size, log2_cb_size, 0, idx - 2);
+ hls_prediction_unit(lc, x0 + cb_size * 3 / 4, y0, cb_size / 4, cb_size, log2_cb_size, 1, idx - 2);
break;
case PART_NxN:
- hls_prediction_unit(s, x0, y0, cb_size / 2, cb_size / 2, log2_cb_size, 0, idx - 1);
- hls_prediction_unit(s, x0 + cb_size / 2, y0, cb_size / 2, cb_size / 2, log2_cb_size, 1, idx - 1);
- hls_prediction_unit(s, x0, y0 + cb_size / 2, cb_size / 2, cb_size / 2, log2_cb_size, 2, idx - 1);
- hls_prediction_unit(s, x0 + cb_size / 2, y0 + cb_size / 2, cb_size / 2, cb_size / 2, log2_cb_size, 3, idx - 1);
+ hls_prediction_unit(lc, x0, y0, cb_size / 2, cb_size / 2, log2_cb_size, 0, idx - 1);
+ hls_prediction_unit(lc, x0 + cb_size / 2, y0, cb_size / 2, cb_size / 2, log2_cb_size, 1, idx - 1);
+ hls_prediction_unit(lc, x0, y0 + cb_size / 2, cb_size / 2, cb_size / 2, log2_cb_size, 2, idx - 1);
+ hls_prediction_unit(lc, x0 + cb_size / 2, y0 + cb_size / 2, cb_size / 2, cb_size / 2, log2_cb_size, 3, idx - 1);
break;
}
}
@@ -2297,27 +2305,27 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size)
if (lc->cu.pred_mode != MODE_INTRA &&
!(lc->cu.part_mode == PART_2Nx2N && lc->pu.merge_flag)) {
- rqt_root_cbf = ff_hevc_no_residual_syntax_flag_decode(s);
+ rqt_root_cbf = ff_hevc_no_residual_syntax_flag_decode(lc);
}
if (rqt_root_cbf) {
const static int cbf[2] = { 0 };
lc->cu.max_trafo_depth = lc->cu.pred_mode == MODE_INTRA ?
s->ps.sps->max_transform_hierarchy_depth_intra + lc->cu.intra_split_flag :
s->ps.sps->max_transform_hierarchy_depth_inter;
- ret = hls_transform_tree(s, x0, y0, x0, y0, x0, y0,
+ ret = hls_transform_tree(lc, x0, y0, x0, y0, x0, y0,
log2_cb_size,
log2_cb_size, 0, 0, cbf, cbf);
if (ret < 0)
return ret;
} else {
if (!s->sh.disable_deblocking_filter_flag)
- ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size);
+ ff_hevc_deblocking_boundary_strengths(lc, x0, y0, log2_cb_size);
}
}
}
if (s->ps.pps->cu_qp_delta_enabled_flag && lc->tu.is_cu_qp_delta_coded == 0)
- ff_hevc_set_qPy(s, x0, y0, log2_cb_size);
+ ff_hevc_set_qPy(lc, x0, y0, log2_cb_size);
x = y_cb * min_cb_width + x_cb;
for (y = 0; y < length; y++) {
@@ -2335,10 +2343,10 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size)
return 0;
}
-static int hls_coding_quadtree(HEVCContext *s, int x0, int y0,
+static int hls_coding_quadtree(HEVCLocalContext *lc, int x0, int y0,
int log2_cb_size, int cb_depth)
{
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
const int cb_size = 1 << log2_cb_size;
int ret;
int split_cu;
@@ -2347,7 +2355,7 @@ static int hls_coding_quadtree(HEVCContext *s, int x0, int y0,
if (x0 + cb_size <= s->ps.sps->width &&
y0 + cb_size <= s->ps.sps->height &&
log2_cb_size > s->ps.sps->log2_min_cb_size) {
- split_cu = ff_hevc_split_coding_unit_flag_decode(s, cb_depth, x0, y0);
+ split_cu = ff_hevc_split_coding_unit_flag_decode(lc, cb_depth, x0, y0);
} else {
split_cu = (log2_cb_size > s->ps.sps->log2_min_cb_size);
}
@@ -2370,23 +2378,23 @@ static int hls_coding_quadtree(HEVCContext *s, int x0, int y0,
int more_data = 0;
- more_data = hls_coding_quadtree(s, x0, y0, log2_cb_size - 1, cb_depth + 1);
+ more_data = hls_coding_quadtree(lc, x0, y0, log2_cb_size - 1, cb_depth + 1);
if (more_data < 0)
return more_data;
if (more_data && x1 < s->ps.sps->width) {
- more_data = hls_coding_quadtree(s, x1, y0, log2_cb_size - 1, cb_depth + 1);
+ more_data = hls_coding_quadtree(lc, x1, y0, log2_cb_size - 1, cb_depth + 1);
if (more_data < 0)
return more_data;
}
if (more_data && y1 < s->ps.sps->height) {
- more_data = hls_coding_quadtree(s, x0, y1, log2_cb_size - 1, cb_depth + 1);
+ more_data = hls_coding_quadtree(lc, x0, y1, log2_cb_size - 1, cb_depth + 1);
if (more_data < 0)
return more_data;
}
if (more_data && x1 < s->ps.sps->width &&
y1 < s->ps.sps->height) {
- more_data = hls_coding_quadtree(s, x1, y1, log2_cb_size - 1, cb_depth + 1);
+ more_data = hls_coding_quadtree(lc, x1, y1, log2_cb_size - 1, cb_depth + 1);
if (more_data < 0)
return more_data;
}
@@ -2401,7 +2409,7 @@ static int hls_coding_quadtree(HEVCContext *s, int x0, int y0,
else
return 0;
} else {
- ret = hls_coding_unit(s, x0, y0, log2_cb_size);
+ ret = hls_coding_unit(lc, s, x0, y0, log2_cb_size);
if (ret < 0)
return ret;
if ((!((x0 + cb_size) %
@@ -2410,7 +2418,7 @@ static int hls_coding_quadtree(HEVCContext *s, int x0, int y0,
(!((y0 + cb_size) %
(1 << (s->ps.sps->log2_ctb_size))) ||
(y0 + cb_size >= s->ps.sps->height))) {
- int end_of_slice_flag = ff_hevc_end_of_slice_flag_decode(s);
+ int end_of_slice_flag = ff_hevc_end_of_slice_flag_decode(lc);
return !end_of_slice_flag;
} else {
return 1;
@@ -2420,10 +2428,10 @@ static int hls_coding_quadtree(HEVCContext *s, int x0, int y0,
return 0;
}
-static void hls_decode_neighbour(HEVCContext *s, int x_ctb, int y_ctb,
+static void hls_decode_neighbour(HEVCLocalContext *lc, int x_ctb, int y_ctb,
int ctb_addr_ts)
{
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
int ctb_size = 1 << s->ps.sps->log2_ctb_size;
int ctb_addr_rs = s->ps.pps->ctb_addr_ts_to_rs[ctb_addr_ts];
int ctb_addr_in_slice = ctb_addr_rs - s->sh.slice_addr;
@@ -2472,6 +2480,7 @@ static void hls_decode_neighbour(HEVCContext *s, int x_ctb, int y_ctb,
static int hls_decode_entry(AVCodecContext *avctxt, void *isFilterThread)
{
HEVCContext *s = avctxt->priv_data;
+ HEVCLocalContext *const lc = s->HEVClc;
int ctb_size = 1 << s->ps.sps->log2_ctb_size;
int more_data = 1;
int x_ctb = 0;
@@ -2497,21 +2506,21 @@ static int hls_decode_entry(AVCodecContext *avctxt, void *isFilterThread)
x_ctb = (ctb_addr_rs % ((s->ps.sps->width + ctb_size - 1) >> s->ps.sps->log2_ctb_size)) << s->ps.sps->log2_ctb_size;
y_ctb = (ctb_addr_rs / ((s->ps.sps->width + ctb_size - 1) >> s->ps.sps->log2_ctb_size)) << s->ps.sps->log2_ctb_size;
- hls_decode_neighbour(s, x_ctb, y_ctb, ctb_addr_ts);
+ hls_decode_neighbour(lc, x_ctb, y_ctb, ctb_addr_ts);
- ret = ff_hevc_cabac_init(s, ctb_addr_ts, 0);
+ ret = ff_hevc_cabac_init(lc, ctb_addr_ts);
if (ret < 0) {
s->tab_slice_address[ctb_addr_rs] = -1;
return ret;
}
- hls_sao_param(s, x_ctb >> s->ps.sps->log2_ctb_size, y_ctb >> s->ps.sps->log2_ctb_size);
+ hls_sao_param(lc, x_ctb >> s->ps.sps->log2_ctb_size, y_ctb >> s->ps.sps->log2_ctb_size);
s->deblock[ctb_addr_rs].beta_offset = s->sh.beta_offset;
s->deblock[ctb_addr_rs].tc_offset = s->sh.tc_offset;
s->filter_slice_edges[ctb_addr_rs] = s->sh.slice_loop_filter_across_slices_enabled_flag;
- more_data = hls_coding_quadtree(s, x_ctb, y_ctb, s->ps.sps->log2_ctb_size, 0);
+ more_data = hls_coding_quadtree(lc, x_ctb, y_ctb, s->ps.sps->log2_ctb_size, 0);
if (more_data < 0) {
s->tab_slice_address[ctb_addr_rs] = -1;
return more_data;
@@ -2519,13 +2528,13 @@ static int hls_decode_entry(AVCodecContext *avctxt, void *isFilterThread)
ctb_addr_ts++;
- ff_hevc_save_states(s, ctb_addr_ts);
- ff_hevc_hls_filters(s, x_ctb, y_ctb, ctb_size);
+ ff_hevc_save_states(lc, ctb_addr_ts);
+ ff_hevc_hls_filters(lc, x_ctb, y_ctb, ctb_size);
}
if (x_ctb + ctb_size >= s->ps.sps->width &&
y_ctb + ctb_size >= s->ps.sps->height)
- ff_hevc_hls_filter(s, x_ctb, y_ctb, ctb_size);
+ ff_hevc_hls_filter(lc, x_ctb, y_ctb, ctb_size);
return ctb_addr_ts;
}
@@ -2541,22 +2550,19 @@ static int hls_slice_data(HEVCContext *s)
s->avctx->execute(s->avctx, hls_decode_entry, arg, ret , 1, sizeof(int));
return ret[0];
}
-static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int job, int self_id)
+static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *hevc_lclist,
+ int job, int self_id)
{
- HEVCContext *s1 = avctxt->priv_data, *s;
- HEVCLocalContext *lc;
- int ctb_size = 1<< s1->ps.sps->log2_ctb_size;
+ HEVCLocalContext *lc = ((HEVCLocalContext**)hevc_lclist)[self_id];
+ const HEVCContext *const s = lc->parent;
+ int ctb_size = 1 << s->ps.sps->log2_ctb_size;
int more_data = 1;
- int *ctb_row_p = input_ctb_row;
- int ctb_row = ctb_row_p[job];
- int ctb_addr_rs = s1->sh.slice_ctb_addr_rs + ctb_row * ((s1->ps.sps->width + ctb_size - 1) >> s1->ps.sps->log2_ctb_size);
- int ctb_addr_ts = s1->ps.pps->ctb_addr_rs_to_ts[ctb_addr_rs];
- int thread = ctb_row % s1->threads_number;
+ int ctb_row = job;
+ int ctb_addr_rs = s->sh.slice_ctb_addr_rs + ctb_row * ((s->ps.sps->width + ctb_size - 1) >> s->ps.sps->log2_ctb_size);
+ int ctb_addr_ts = s->ps.pps->ctb_addr_rs_to_ts[ctb_addr_rs];
+ int thread = ctb_row % s->threads_number;
int ret;
- s = s1->sList[self_id];
- lc = s->HEVClc;
-
if(ctb_row) {
ret = init_get_bits8(&lc->gb, s->data + s->sh.offset[ctb_row - 1], s->sh.size[ctb_row - 1]);
if (ret < 0)
@@ -2568,20 +2574,23 @@ static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int
int x_ctb = (ctb_addr_rs % s->ps.sps->ctb_width) << s->ps.sps->log2_ctb_size;
int y_ctb = (ctb_addr_rs / s->ps.sps->ctb_width) << s->ps.sps->log2_ctb_size;
- hls_decode_neighbour(s, x_ctb, y_ctb, ctb_addr_ts);
+ hls_decode_neighbour(lc, x_ctb, y_ctb, ctb_addr_ts);
ff_thread_await_progress2(s->avctx, ctb_row, thread, SHIFT_CTB_WPP);
- if (atomic_load(&s1->wpp_err)) {
+ /* atomic_load's prototype requires a pointer to non-const atomic variable
+ * (due to implementations via mutexes, where reads involve writes).
+ * Of course, casting const away here is nevertheless safe. */
+ if (atomic_load((atomic_int*)&s->wpp_err)) {
ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP);
return 0;
}
- ret = ff_hevc_cabac_init(s, ctb_addr_ts, thread);
+ ret = ff_hevc_cabac_init(lc, ctb_addr_ts);
if (ret < 0)
goto error;
- hls_sao_param(s, x_ctb >> s->ps.sps->log2_ctb_size, y_ctb >> s->ps.sps->log2_ctb_size);
- more_data = hls_coding_quadtree(s, x_ctb, y_ctb, s->ps.sps->log2_ctb_size, 0);
+ hls_sao_param(lc, x_ctb >> s->ps.sps->log2_ctb_size, y_ctb >> s->ps.sps->log2_ctb_size);
+ more_data = hls_coding_quadtree(lc, x_ctb, y_ctb, s->ps.sps->log2_ctb_size, 0);
if (more_data < 0) {
ret = more_data;
@@ -2590,18 +2599,19 @@ static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int
ctb_addr_ts++;
- ff_hevc_save_states(s, ctb_addr_ts);
+ ff_hevc_save_states(lc, ctb_addr_ts);
ff_thread_report_progress2(s->avctx, ctb_row, thread, 1);
- ff_hevc_hls_filters(s, x_ctb, y_ctb, ctb_size);
+ ff_hevc_hls_filters(lc, x_ctb, y_ctb, ctb_size);
if (!more_data && (x_ctb+ctb_size) < s->ps.sps->width && ctb_row != s->sh.num_entry_point_offsets) {
- atomic_store(&s1->wpp_err, 1);
+ /* Casting const away here is safe, because it is an atomic operation. */
+ atomic_store((atomic_int*)&s->wpp_err, 1);
ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP);
return 0;
}
if ((x_ctb+ctb_size) >= s->ps.sps->width && (y_ctb+ctb_size) >= s->ps.sps->height ) {
- ff_hevc_hls_filter(s, x_ctb, y_ctb, ctb_size);
+ ff_hevc_hls_filter(lc, x_ctb, y_ctb, ctb_size);
ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP);
return ctb_addr_ts;
}
@@ -2617,7 +2627,8 @@ static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int
return 0;
error:
s->tab_slice_address[ctb_addr_rs] = -1;
- atomic_store(&s1->wpp_err, 1);
+ /* Casting const away here is safe, because it is an atomic operation. */
+ atomic_store((atomic_int*)&s->wpp_err, 1);
ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP);
return ret;
}
@@ -2627,42 +2638,28 @@ static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal)
const uint8_t *data = nal->data;
int length = nal->size;
HEVCLocalContext *lc = s->HEVClc;
- int *ret = av_malloc_array(s->sh.num_entry_point_offsets + 1, sizeof(int));
- int *arg = av_malloc_array(s->sh.num_entry_point_offsets + 1, sizeof(int));
+ int *ret;
int64_t offset;
int64_t startheader, cmpt = 0;
int i, j, res = 0;
- if (!ret || !arg) {
- av_free(ret);
- av_free(arg);
- return AVERROR(ENOMEM);
- }
-
if (s->sh.slice_ctb_addr_rs + s->sh.num_entry_point_offsets * s->ps.sps->ctb_width >= s->ps.sps->ctb_width * s->ps.sps->ctb_height) {
av_log(s->avctx, AV_LOG_ERROR, "WPP ctb addresses are wrong (%d %d %d %d)\n",
s->sh.slice_ctb_addr_rs, s->sh.num_entry_point_offsets,
s->ps.sps->ctb_width, s->ps.sps->ctb_height
);
- res = AVERROR_INVALIDDATA;
- goto error;
+ return AVERROR_INVALIDDATA;
}
- ff_alloc_entries(s->avctx, s->sh.num_entry_point_offsets + 1);
-
for (i = 1; i < s->threads_number; i++) {
- if (s->sList[i] && s->HEVClcList[i])
+ if (s->HEVClcList[i])
continue;
- av_freep(&s->sList[i]);
- av_freep(&s->HEVClcList[i]);
- s->sList[i] = av_malloc(sizeof(HEVCContext));
s->HEVClcList[i] = av_mallocz(sizeof(HEVCLocalContext));
- if (!s->sList[i] || !s->HEVClcList[i]) {
- res = AVERROR(ENOMEM);
- goto error;
- }
- memcpy(s->sList[i], s, sizeof(HEVCContext));
- s->sList[i]->HEVClc = s->HEVClcList[i];
+ if (!s->HEVClcList[i])
+ return AVERROR(ENOMEM);
+ s->HEVClcList[i]->logctx = s->avctx;
+ s->HEVClcList[i]->parent = s;
+ s->HEVClcList[i]->common_cabac_state = &s->cabac;
}
offset = (lc->gb.index >> 3);
@@ -2691,8 +2688,7 @@ static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal)
offset += s->sh.entry_point_offset[s->sh.num_entry_point_offsets - 1] - cmpt;
if (length < offset) {
av_log(s->avctx, AV_LOG_ERROR, "entry_point_offset table is corrupted\n");
- res = AVERROR_INVALIDDATA;
- goto error;
+ return AVERROR_INVALIDDATA;
}
s->sh.size[s->sh.num_entry_point_offsets - 1] = length - offset;
s->sh.offset[s->sh.num_entry_point_offsets - 1] = offset;
@@ -2701,28 +2697,26 @@ static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal)
s->data = data;
for (i = 1; i < s->threads_number; i++) {
- s->sList[i]->HEVClc->first_qp_group = 1;
- s->sList[i]->HEVClc->qp_y = s->sList[0]->HEVClc->qp_y;
- memcpy(s->sList[i], s, sizeof(HEVCContext));
- s->sList[i]->HEVClc = s->HEVClcList[i];
+ s->HEVClcList[i]->first_qp_group = 1;
+ s->HEVClcList[i]->qp_y = s->HEVClc->qp_y;
}
atomic_store(&s->wpp_err, 0);
- ff_reset_entries(s->avctx);
+ res = ff_slice_thread_allocz_entries(s->avctx, s->sh.num_entry_point_offsets + 1);
+ if (res < 0)
+ return res;
- for (i = 0; i <= s->sh.num_entry_point_offsets; i++) {
- arg[i] = i;
- ret[i] = 0;
- }
+ ret = av_calloc(s->sh.num_entry_point_offsets + 1, sizeof(*ret));
+ if (!ret)
+ return AVERROR(ENOMEM);
if (s->ps.pps->entropy_coding_sync_enabled_flag)
- s->avctx->execute2(s->avctx, hls_decode_entry_wpp, arg, ret, s->sh.num_entry_point_offsets + 1);
+ s->avctx->execute2(s->avctx, hls_decode_entry_wpp, s->HEVClcList, ret, s->sh.num_entry_point_offsets + 1);
for (i = 0; i <= s->sh.num_entry_point_offsets; i++)
res += ret[i];
-error:
+
av_free(ret);
- av_free(arg);
return res;
}
@@ -2731,67 +2725,6 @@ static int set_side_data(HEVCContext *s)
AVFrame *out = s->ref->frame;
int ret;
- if (s->sei.frame_packing.present &&
- s->sei.frame_packing.arrangement_type >= 3 &&
- s->sei.frame_packing.arrangement_type <= 5 &&
- s->sei.frame_packing.content_interpretation_type > 0 &&
- s->sei.frame_packing.content_interpretation_type < 3) {
- AVStereo3D *stereo = av_stereo3d_create_side_data(out);
- if (!stereo)
- return AVERROR(ENOMEM);
-
- switch (s->sei.frame_packing.arrangement_type) {
- case 3:
- if (s->sei.frame_packing.quincunx_subsampling)
- stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
- else
- stereo->type = AV_STEREO3D_SIDEBYSIDE;
- break;
- case 4:
- stereo->type = AV_STEREO3D_TOPBOTTOM;
- break;
- case 5:
- stereo->type = AV_STEREO3D_FRAMESEQUENCE;
- break;
- }
-
- if (s->sei.frame_packing.content_interpretation_type == 2)
- stereo->flags = AV_STEREO3D_FLAG_INVERT;
-
- if (s->sei.frame_packing.arrangement_type == 5) {
- if (s->sei.frame_packing.current_frame_is_frame0_flag)
- stereo->view = AV_STEREO3D_VIEW_LEFT;
- else
- stereo->view = AV_STEREO3D_VIEW_RIGHT;
- }
- }
-
- if (s->sei.display_orientation.present &&
- (s->sei.display_orientation.anticlockwise_rotation ||
- s->sei.display_orientation.hflip || s->sei.display_orientation.vflip)) {
- double angle = s->sei.display_orientation.anticlockwise_rotation * 360 / (double) (1 << 16);
- AVFrameSideData *rotation = av_frame_new_side_data(out,
- AV_FRAME_DATA_DISPLAYMATRIX,
- sizeof(int32_t) * 9);
- if (!rotation)
- return AVERROR(ENOMEM);
-
- /* av_display_rotation_set() expects the angle in the clockwise
- * direction, hence the first minus.
- * The below code applies the flips after the rotation, yet
- * the H.2645 specs require flipping to be applied first.
- * Because of R O(phi) = O(-phi) R (where R is flipping around
- * an arbitatry axis and O(phi) is the proper rotation by phi)
- * we can create display matrices as desired by negating
- * the degree once for every flip applied. */
- angle = -angle * (1 - 2 * !!s->sei.display_orientation.hflip)
- * (1 - 2 * !!s->sei.display_orientation.vflip);
- av_display_rotation_set((int32_t *)rotation->data, angle);
- av_display_matrix_flip((int32_t *)rotation->data,
- s->sei.display_orientation.hflip,
- s->sei.display_orientation.vflip);
- }
-
// Decrement the mastering display flag when IRAP frame has no_rasl_output_flag=1
// so the side data persists for the entire coded video sequence.
if (s->sei.mastering_display.present > 0 &&
@@ -2861,28 +2794,12 @@ static int set_side_data(HEVCContext *s)
metadata->MaxCLL, metadata->MaxFALL);
}
- if (s->sei.a53_caption.buf_ref) {
- HEVCSEIA53Caption *a53 = &s->sei.a53_caption;
-
- AVFrameSideData *sd = av_frame_new_side_data_from_buf(out, AV_FRAME_DATA_A53_CC, a53->buf_ref);
- if (!sd)
- av_buffer_unref(&a53->buf_ref);
- a53->buf_ref = NULL;
- }
-
- for (int i = 0; i < s->sei.unregistered.nb_buf_ref; i++) {
- HEVCSEIUnregistered *unreg = &s->sei.unregistered;
-
- if (unreg->buf_ref[i]) {
- AVFrameSideData *sd = av_frame_new_side_data_from_buf(out,
- AV_FRAME_DATA_SEI_UNREGISTERED,
- unreg->buf_ref[i]);
- if (!sd)
- av_buffer_unref(&unreg->buf_ref[i]);
- unreg->buf_ref[i] = NULL;
- }
- }
- s->sei.unregistered.nb_buf_ref = 0;
+ ret = ff_h2645_sei_to_frame(out, &s->sei.common, AV_CODEC_ID_HEVC, NULL,
+ &s->ps.sps->vui.common,
+ s->ps.sps->bit_depth, s->ps.sps->bit_depth_chroma,
+ s->ref->poc /* no poc_offset in HEVC */);
+ if (ret < 0)
+ return ret;
if (s->sei.timecode.present) {
uint32_t *tc_sd;
@@ -2910,63 +2827,8 @@ static int set_side_data(HEVCContext *s)
s->sei.timecode.num_clock_ts = 0;
}
- if (s->sei.film_grain_characteristics.present) {
- HEVCSEIFilmGrainCharacteristics *fgc = &s->sei.film_grain_characteristics;
- AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(out);
- if (!fgp)
- return AVERROR(ENOMEM);
-
- fgp->type = AV_FILM_GRAIN_PARAMS_H274;
- fgp->seed = s->ref->poc; /* no poc_offset in HEVC */
-
- fgp->codec.h274.model_id = fgc->model_id;
- if (fgc->separate_colour_description_present_flag) {
- fgp->codec.h274.bit_depth_luma = fgc->bit_depth_luma;
- fgp->codec.h274.bit_depth_chroma = fgc->bit_depth_chroma;
- fgp->codec.h274.color_range = fgc->full_range + 1;
- fgp->codec.h274.color_primaries = fgc->color_primaries;
- fgp->codec.h274.color_trc = fgc->transfer_characteristics;
- fgp->codec.h274.color_space = fgc->matrix_coeffs;
- } else {
- const HEVCSPS *sps = s->ps.sps;
- const VUI *vui = &sps->vui;
- fgp->codec.h274.bit_depth_luma = sps->bit_depth;
- fgp->codec.h274.bit_depth_chroma = sps->bit_depth_chroma;
- if (vui->video_signal_type_present_flag)
- fgp->codec.h274.color_range = vui->video_full_range_flag + 1;
- else
- fgp->codec.h274.color_range = AVCOL_RANGE_UNSPECIFIED;
- if (vui->colour_description_present_flag) {
- fgp->codec.h274.color_primaries = vui->colour_primaries;
- fgp->codec.h274.color_trc = vui->transfer_characteristic;
- fgp->codec.h274.color_space = vui->matrix_coeffs;
- } else {
- fgp->codec.h274.color_primaries = AVCOL_PRI_UNSPECIFIED;
- fgp->codec.h274.color_trc = AVCOL_TRC_UNSPECIFIED;
- fgp->codec.h274.color_space = AVCOL_SPC_UNSPECIFIED;
- }
- }
- fgp->codec.h274.blending_mode_id = fgc->blending_mode_id;
- fgp->codec.h274.log2_scale_factor = fgc->log2_scale_factor;
-
- memcpy(&fgp->codec.h274.component_model_present, &fgc->comp_model_present_flag,
- sizeof(fgp->codec.h274.component_model_present));
- memcpy(&fgp->codec.h274.num_intensity_intervals, &fgc->num_intensity_intervals,
- sizeof(fgp->codec.h274.num_intensity_intervals));
- memcpy(&fgp->codec.h274.num_model_values, &fgc->num_model_values,
- sizeof(fgp->codec.h274.num_model_values));
- memcpy(&fgp->codec.h274.intensity_interval_lower_bound, &fgc->intensity_interval_lower_bound,
- sizeof(fgp->codec.h274.intensity_interval_lower_bound));
- memcpy(&fgp->codec.h274.intensity_interval_upper_bound, &fgc->intensity_interval_upper_bound,
- sizeof(fgp->codec.h274.intensity_interval_upper_bound));
- memcpy(&fgp->codec.h274.comp_model_value, &fgc->comp_model_value,
- sizeof(fgp->codec.h274.comp_model_value));
-
- fgc->present = fgc->persistence_flag;
- }
-
- if (s->sei.dynamic_hdr_plus.info) {
- AVBufferRef *info_ref = av_buffer_ref(s->sei.dynamic_hdr_plus.info);
+ if (s->sei.common.dynamic_hdr_plus.info) {
+ AVBufferRef *info_ref = av_buffer_ref(s->sei.common.dynamic_hdr_plus.info);
if (!info_ref)
return AVERROR(ENOMEM);
@@ -2987,8 +2849,8 @@ static int set_side_data(HEVCContext *s)
if ((ret = ff_dovi_attach_side_data(&s->dovi_ctx, out)) < 0)
return ret;
- if (s->sei.dynamic_hdr_vivid.info) {
- AVBufferRef *info_ref = av_buffer_ref(s->sei.dynamic_hdr_vivid.info);
+ if (s->sei.common.dynamic_hdr_vivid.info) {
+ AVBufferRef *info_ref = av_buffer_ref(s->sei.common.dynamic_hdr_vivid.info);
if (!info_ref)
return AVERROR(ENOMEM);
@@ -3034,7 +2896,7 @@ static int hevc_frame_start(HEVCContext *s)
s->ref->frame->key_frame = IS_IRAP(s);
- s->ref->needs_fg = s->sei.film_grain_characteristics.present &&
+ s->ref->needs_fg = s->sei.common.film_grain_characteristics.present &&
!(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) &&
!s->avctx->hwaccel;
@@ -3266,7 +3128,7 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal)
break;
case HEVC_NAL_EOS_NUT:
case HEVC_NAL_EOB_NUT:
- s->seq_decode = (s->seq_decode + 1) & 0xff;
+ s->seq_decode = (s->seq_decode + 1) & HEVC_SEQUENCE_COUNTER_MASK;
s->max_ra = INT_MAX;
break;
case HEVC_NAL_AUD:
@@ -3374,17 +3236,12 @@ fail:
return ret;
}
-static void print_md5(void *log_ctx, int level, uint8_t md5[16])
-{
- int i;
- for (i = 0; i < 16; i++)
- av_log(log_ctx, level, "%02"PRIx8, md5[i]);
-}
-
static int verify_md5(HEVCContext *s, AVFrame *frame)
{
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
+ char msg_buf[4 * (50 + 2 * 2 * 16 /* MD5-size */)];
int pixel_shift;
+ int err = 0;
int i, j;
if (!desc)
@@ -3392,9 +3249,6 @@ static int verify_md5(HEVCContext *s, AVFrame *frame)
pixel_shift = desc->comp[0].depth > 8;
- av_log(s->avctx, AV_LOG_DEBUG, "Verifying checksum for frame with POC %d: ",
- s->poc);
-
/* the checksums are LE, so we have to byteswap for >8bpp formats
* on BE arches */
#if HAVE_BIGENDIAN
@@ -3407,6 +3261,7 @@ static int verify_md5(HEVCContext *s, AVFrame *frame)
}
#endif
+ msg_buf[0] = '\0';
for (i = 0; frame->data[i]; i++) {
int width = s->avctx->coded_width;
int height = s->avctx->coded_height;
@@ -3428,23 +3283,26 @@ static int verify_md5(HEVCContext *s, AVFrame *frame)
}
av_md5_final(s->md5_ctx, md5);
+#define MD5_PRI "%016" PRIx64 "%016" PRIx64
+#define MD5_PRI_ARG(buf) AV_RB64(buf), AV_RB64((const uint8_t*)(buf) + 8)
+
if (!memcmp(md5, s->sei.picture_hash.md5[i], 16)) {
- av_log (s->avctx, AV_LOG_DEBUG, "plane %d - correct ", i);
- print_md5(s->avctx, AV_LOG_DEBUG, md5);
- av_log (s->avctx, AV_LOG_DEBUG, "; ");
+ av_strlcatf(msg_buf, sizeof(msg_buf),
+ "plane %d - correct " MD5_PRI "; ",
+ i, MD5_PRI_ARG(md5));
} else {
- av_log (s->avctx, AV_LOG_ERROR, "mismatching checksum of plane %d - ", i);
- print_md5(s->avctx, AV_LOG_ERROR, md5);
- av_log (s->avctx, AV_LOG_ERROR, " != ");
- print_md5(s->avctx, AV_LOG_ERROR, s->sei.picture_hash.md5[i]);
- av_log (s->avctx, AV_LOG_ERROR, "\n");
- return AVERROR_INVALIDDATA;
+ av_strlcatf(msg_buf, sizeof(msg_buf),
+ "mismatching checksum of plane %d - " MD5_PRI " != " MD5_PRI "; ",
+ i, MD5_PRI_ARG(md5), MD5_PRI_ARG(s->sei.picture_hash.md5[i]));
+ err = AVERROR_INVALIDDATA;
}
}
- av_log(s->avctx, AV_LOG_DEBUG, "\n");
+ av_log(s->avctx, err < 0 ? AV_LOG_ERROR : AV_LOG_DEBUG,
+ "Verifying checksum for frame with POC %d: %s\n",
+ s->poc, msg_buf);
- return 0;
+ return err;
}
static int hevc_decode_extradata(HEVCContext *s, uint8_t *buf, int length, int first)
@@ -3599,8 +3457,6 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx)
av_freep(&s->md5_ctx);
- av_freep(&s->cabac_state);
-
for (i = 0; i < 3; i++) {
av_freep(&s->sao_pixel_buffer_h[i]);
av_freep(&s->sao_pixel_buffer_v[i]);
@@ -3619,15 +3475,13 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx)
av_freep(&s->sh.offset);
av_freep(&s->sh.size);
- if (s->HEVClcList && s->sList) {
+ if (s->HEVClcList) {
for (i = 1; i < s->threads_number; i++) {
av_freep(&s->HEVClcList[i]);
- av_freep(&s->sList[i]);
}
}
av_freep(&s->HEVClc);
av_freep(&s->HEVClcList);
- av_freep(&s->sList);
ff_h2645_packet_uninit(&s->pkt);
@@ -3645,15 +3499,12 @@ static av_cold int hevc_init_context(AVCodecContext *avctx)
s->HEVClc = av_mallocz(sizeof(HEVCLocalContext));
s->HEVClcList = av_mallocz(sizeof(HEVCLocalContext*) * s->threads_number);
- s->sList = av_mallocz(sizeof(HEVCContext*) * s->threads_number);
- if (!s->HEVClc || !s->HEVClcList || !s->sList)
+ if (!s->HEVClc || !s->HEVClcList)
return AVERROR(ENOMEM);
+ s->HEVClc->parent = s;
+ s->HEVClc->logctx = avctx;
+ s->HEVClc->common_cabac_state = &s->cabac;
s->HEVClcList[0] = s->HEVClc;
- s->sList[0] = s;
-
- s->cabac_state = av_malloc(HEVC_CONTEXTS);
- if (!s->cabac_state)
- return AVERROR(ENOMEM);
s->output_frame = av_frame_alloc();
if (!s->output_frame)
@@ -3741,34 +3592,16 @@ static int hevc_update_thread_context(AVCodecContext *dst,
s->threads_type = s0->threads_type;
if (s0->eos) {
- s->seq_decode = (s->seq_decode + 1) & 0xff;
+ s->seq_decode = (s->seq_decode + 1) & HEVC_SEQUENCE_COUNTER_MASK;
s->max_ra = INT_MAX;
}
- ret = av_buffer_replace(&s->sei.a53_caption.buf_ref, s0->sei.a53_caption.buf_ref);
+ ret = ff_h2645_sei_ctx_replace(&s->sei.common, &s0->sei.common);
if (ret < 0)
return ret;
- for (i = 0; i < s->sei.unregistered.nb_buf_ref; i++)
- av_buffer_unref(&s->sei.unregistered.buf_ref[i]);
- s->sei.unregistered.nb_buf_ref = 0;
-
- if (s0->sei.unregistered.nb_buf_ref) {
- ret = av_reallocp_array(&s->sei.unregistered.buf_ref,
- s0->sei.unregistered.nb_buf_ref,
- sizeof(*s->sei.unregistered.buf_ref));
- if (ret < 0)
- return ret;
-
- for (i = 0; i < s0->sei.unregistered.nb_buf_ref; i++) {
- s->sei.unregistered.buf_ref[i] = av_buffer_ref(s0->sei.unregistered.buf_ref[i]);
- if (!s->sei.unregistered.buf_ref[i])
- return AVERROR(ENOMEM);
- s->sei.unregistered.nb_buf_ref++;
- }
- }
-
- ret = av_buffer_replace(&s->sei.dynamic_hdr_plus.info, s0->sei.dynamic_hdr_plus.info);
+ ret = av_buffer_replace(&s->sei.common.dynamic_hdr_plus.info,
+ s0->sei.common.dynamic_hdr_plus.info);
if (ret < 0)
return ret;
@@ -3780,15 +3613,16 @@ static int hevc_update_thread_context(AVCodecContext *dst,
if (ret < 0)
return ret;
- ret = av_buffer_replace(&s->sei.dynamic_hdr_vivid.info, s0->sei.dynamic_hdr_vivid.info);
+ ret = av_buffer_replace(&s->sei.common.dynamic_hdr_vivid.info,
+ s0->sei.common.dynamic_hdr_vivid.info);
if (ret < 0)
return ret;
- s->sei.frame_packing = s0->sei.frame_packing;
- s->sei.display_orientation = s0->sei.display_orientation;
+ s->sei.common.frame_packing = s0->sei.common.frame_packing;
+ s->sei.common.display_orientation = s0->sei.common.display_orientation;
+ s->sei.common.alternative_transfer = s0->sei.common.alternative_transfer;
s->sei.mastering_display = s0->sei.mastering_display;
s->sei.content_light = s0->sei.content_light;
- s->sei.alternative_transfer = s0->sei.alternative_transfer;
ret = export_stream_params_from_sei(s);
if (ret < 0)
@@ -3869,7 +3703,7 @@ static const AVClass hevc_decoder_class = {
const FFCodec ff_hevc_decoder = {
.p.name = "hevc",
- .p.long_name = NULL_IF_CONFIG_SMALL("HEVC (High Efficiency Video Coding)"),
+ CODEC_LONG_NAME("HEVC (High Efficiency Video Coding)"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_HEVC,
.priv_data_size = sizeof(HEVCContext),
@@ -3878,10 +3712,10 @@ const FFCodec ff_hevc_decoder = {
.close = hevc_decode_free,
FF_CODEC_DECODE_CB(hevc_decode_frame),
.flush = hevc_decode_flush,
- .update_thread_context = ONLY_IF_THREADS_ENABLED(hevc_update_thread_context),
+ UPDATE_THREAD_CONTEXT(hevc_update_thread_context),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING |
+ .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING |
FF_CODEC_CAP_ALLOCATE_PROGRESS | FF_CODEC_CAP_INIT_CLEANUP,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles),
.hw_configs = (const AVCodecHWConfigInternal *const []) {
diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h
index f6acf845a..9d3f4adbb 100644
--- a/libavcodec/hevcdec.h
+++ b/libavcodec/hevcdec.h
@@ -226,6 +226,11 @@ enum ScanType {
SCAN_VERT,
};
+typedef struct HEVCCABACState {
+ uint8_t state[HEVC_CONTEXTS];
+ uint8_t stat_coeff[HEVC_STAT_COEFFS];
+} HEVCCABACState;
+
typedef struct LongTermRPS {
int poc[32];
uint8_t poc_msb_present[32];
@@ -390,6 +395,9 @@ typedef struct DBParams {
#define HEVC_FRAME_FLAG_LONG_REF (1 << 2)
#define HEVC_FRAME_FLAG_BUMPING (1 << 3)
+#define HEVC_SEQUENCE_COUNTER_MASK 0xff
+#define HEVC_SEQUENCE_COUNTER_INVALID (HEVC_SEQUENCE_COUNTER_MASK + 1)
+
typedef struct HEVCFrame {
AVFrame *frame;
AVFrame *frame_grain;
@@ -428,9 +436,24 @@ typedef struct HEVCLocalContext {
uint8_t first_qp_group;
+ void *logctx;
+ const struct HEVCContext *parent;
+
GetBitContext gb;
CABACContext cc;
+ /**
+ * This is a pointer to the common CABAC state.
+ * In case entropy_coding_sync_enabled_flag is set,
+ * the CABAC state after decoding the second CTU in a row is
+ * stored here and used to initialize the CABAC state before
+ * decoding the first CTU in the next row.
+ * This is the basis for WPP and in case slice-threading is used,
+ * the next row is decoded by another thread making this state
+ * shared between threads.
+ */
+ HEVCCABACState *common_cabac_state;
+
int8_t qp_y;
int8_t curr_qp_y;
@@ -468,8 +491,6 @@ typedef struct HEVCContext {
const AVClass *c; // needed by private avoptions
AVCodecContext *avctx;
- struct HEVCContext **sList;
-
HEVCLocalContext **HEVClcList;
HEVCLocalContext *HEVClc;
@@ -479,9 +500,6 @@ typedef struct HEVCContext {
int width;
int height;
- uint8_t *cabac_state;
- uint8_t stat_coeff[HEVC_STAT_COEFFS];
-
/** 1 if the independent slice segment header was successfully parsed */
uint8_t slice_initialized;
@@ -554,6 +572,9 @@ typedef struct HEVCContext {
uint16_t seq_decode;
uint16_t seq_output;
+ /** The target for the common_cabac_state of the local contexts. */
+ HEVCCABACState cabac;
+
int enable_parallel_tiles;
atomic_int wpp_err;
@@ -597,38 +618,38 @@ int ff_hevc_frame_rps(HEVCContext *s);
*/
int ff_hevc_slice_rpl(HEVCContext *s);
-void ff_hevc_save_states(HEVCContext *s, int ctb_addr_ts);
-int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts, int thread);
-int ff_hevc_sao_merge_flag_decode(HEVCContext *s);
-int ff_hevc_sao_type_idx_decode(HEVCContext *s);
-int ff_hevc_sao_band_position_decode(HEVCContext *s);
-int ff_hevc_sao_offset_abs_decode(HEVCContext *s);
-int ff_hevc_sao_offset_sign_decode(HEVCContext *s);
-int ff_hevc_sao_eo_class_decode(HEVCContext *s);
-int ff_hevc_end_of_slice_flag_decode(HEVCContext *s);
-int ff_hevc_cu_transquant_bypass_flag_decode(HEVCContext *s);
-int ff_hevc_skip_flag_decode(HEVCContext *s, int x0, int y0,
+void ff_hevc_save_states(HEVCLocalContext *lc, int ctb_addr_ts);
+int ff_hevc_cabac_init(HEVCLocalContext *lc, int ctb_addr_ts);
+int ff_hevc_sao_merge_flag_decode(HEVCLocalContext *lc);
+int ff_hevc_sao_type_idx_decode(HEVCLocalContext *lc);
+int ff_hevc_sao_band_position_decode(HEVCLocalContext *lc);
+int ff_hevc_sao_offset_abs_decode(HEVCLocalContext *lc);
+int ff_hevc_sao_offset_sign_decode(HEVCLocalContext *lc);
+int ff_hevc_sao_eo_class_decode(HEVCLocalContext *lc);
+int ff_hevc_end_of_slice_flag_decode(HEVCLocalContext *lc);
+int ff_hevc_cu_transquant_bypass_flag_decode(HEVCLocalContext *lc);
+int ff_hevc_skip_flag_decode(HEVCLocalContext *lc, int x0, int y0,
int x_cb, int y_cb);
-int ff_hevc_pred_mode_decode(HEVCContext *s);
-int ff_hevc_split_coding_unit_flag_decode(HEVCContext *s, int ct_depth,
+int ff_hevc_pred_mode_decode(HEVCLocalContext *lc);
+int ff_hevc_split_coding_unit_flag_decode(HEVCLocalContext *lc, int ct_depth,
int x0, int y0);
-int ff_hevc_part_mode_decode(HEVCContext *s, int log2_cb_size);
-int ff_hevc_pcm_flag_decode(HEVCContext *s);
-int ff_hevc_prev_intra_luma_pred_flag_decode(HEVCContext *s);
-int ff_hevc_mpm_idx_decode(HEVCContext *s);
-int ff_hevc_rem_intra_luma_pred_mode_decode(HEVCContext *s);
-int ff_hevc_intra_chroma_pred_mode_decode(HEVCContext *s);
-int ff_hevc_merge_idx_decode(HEVCContext *s);
-int ff_hevc_merge_flag_decode(HEVCContext *s);
-int ff_hevc_inter_pred_idc_decode(HEVCContext *s, int nPbW, int nPbH);
-int ff_hevc_ref_idx_lx_decode(HEVCContext *s, int num_ref_idx_lx);
-int ff_hevc_mvp_lx_flag_decode(HEVCContext *s);
-int ff_hevc_no_residual_syntax_flag_decode(HEVCContext *s);
-int ff_hevc_split_transform_flag_decode(HEVCContext *s, int log2_trafo_size);
-int ff_hevc_cbf_cb_cr_decode(HEVCContext *s, int trafo_depth);
-int ff_hevc_cbf_luma_decode(HEVCContext *s, int trafo_depth);
-int ff_hevc_log2_res_scale_abs(HEVCContext *s, int idx);
-int ff_hevc_res_scale_sign_flag(HEVCContext *s, int idx);
+int ff_hevc_part_mode_decode(HEVCLocalContext *lc, int log2_cb_size);
+int ff_hevc_pcm_flag_decode(HEVCLocalContext *lc);
+int ff_hevc_prev_intra_luma_pred_flag_decode(HEVCLocalContext *lc);
+int ff_hevc_mpm_idx_decode(HEVCLocalContext *lc);
+int ff_hevc_rem_intra_luma_pred_mode_decode(HEVCLocalContext *lc);
+int ff_hevc_intra_chroma_pred_mode_decode(HEVCLocalContext *lc);
+int ff_hevc_merge_idx_decode(HEVCLocalContext *lc);
+int ff_hevc_merge_flag_decode(HEVCLocalContext *lc);
+int ff_hevc_inter_pred_idc_decode(HEVCLocalContext *lc, int nPbW, int nPbH);
+int ff_hevc_ref_idx_lx_decode(HEVCLocalContext *lc, int num_ref_idx_lx);
+int ff_hevc_mvp_lx_flag_decode(HEVCLocalContext *lc);
+int ff_hevc_no_residual_syntax_flag_decode(HEVCLocalContext *lc);
+int ff_hevc_split_transform_flag_decode(HEVCLocalContext *lc, int log2_trafo_size);
+int ff_hevc_cbf_cb_cr_decode(HEVCLocalContext *lc, int trafo_depth);
+int ff_hevc_cbf_luma_decode(HEVCLocalContext *lc, int trafo_depth);
+int ff_hevc_log2_res_scale_abs(HEVCLocalContext *lc, int idx);
+int ff_hevc_res_scale_sign_flag(HEVCLocalContext *lc, int idx);
/**
* Get the number of candidate references for the current frame.
@@ -664,30 +685,30 @@ void ff_hevc_bump_frame(HEVCContext *s);
void ff_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags);
-void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0,
+void ff_hevc_set_neighbour_available(HEVCLocalContext *lc, int x0, int y0,
int nPbW, int nPbH);
-void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0,
+void ff_hevc_luma_mv_merge_mode(HEVCLocalContext *lc, int x0, int y0,
int nPbW, int nPbH, int log2_cb_size,
int part_idx, int merge_idx, MvField *mv);
-void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0,
+void ff_hevc_luma_mv_mvp_mode(HEVCLocalContext *lc, int x0, int y0,
int nPbW, int nPbH, int log2_cb_size,
int part_idx, int merge_idx,
MvField *mv, int mvp_lx_flag, int LX);
-void ff_hevc_set_qPy(HEVCContext *s, int xBase, int yBase,
+void ff_hevc_hls_filter(HEVCLocalContext *lc, int x, int y, int ctb_size);
+void ff_hevc_hls_filters(HEVCLocalContext *lc, int x_ctb, int y_ctb, int ctb_size);
+void ff_hevc_set_qPy(HEVCLocalContext *lc, int xBase, int yBase,
int log2_cb_size);
-void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0,
+void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, int x0, int y0,
int log2_trafo_size);
-int ff_hevc_cu_qp_delta_sign_flag(HEVCContext *s);
-int ff_hevc_cu_qp_delta_abs(HEVCContext *s);
-int ff_hevc_cu_chroma_qp_offset_flag(HEVCContext *s);
-int ff_hevc_cu_chroma_qp_offset_idx(HEVCContext *s);
-void ff_hevc_hls_filter(HEVCContext *s, int x, int y, int ctb_size);
-void ff_hevc_hls_filters(HEVCContext *s, int x_ctb, int y_ctb, int ctb_size);
-void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
+int ff_hevc_cu_qp_delta_sign_flag(HEVCLocalContext *lc);
+int ff_hevc_cu_qp_delta_abs(HEVCLocalContext *lc);
+int ff_hevc_cu_chroma_qp_offset_flag(HEVCLocalContext *lc);
+int ff_hevc_cu_chroma_qp_offset_idx(HEVCLocalContext *lc);
+void ff_hevc_hls_residual_coding(HEVCLocalContext *lc, int x0, int y0,
int log2_trafo_size, enum ScanType scan_idx,
int c_idx);
-void ff_hevc_hls_mvd_coding(HEVCContext *s, int x0, int y0, int log2_cb_size);
+void ff_hevc_hls_mvd_coding(HEVCLocalContext *lc, int x0, int y0, int log2_cb_size);
extern const uint8_t ff_hevc_qpel_extra_before[4];
extern const uint8_t ff_hevc_qpel_extra_after[4];
diff --git a/libavcodec/hevcdsp.h b/libavcodec/hevcdsp.h
index d642ecf9c..1b9c5bb6b 100644
--- a/libavcodec/hevcdsp.h
+++ b/libavcodec/hevcdsp.h
@@ -48,7 +48,7 @@ typedef struct HEVCDSPContext {
void (*put_pcm)(uint8_t *_dst, ptrdiff_t _stride, int width, int height,
struct GetBitContext *gb, int pcm_bit_depth);
- void (*add_residual[4])(uint8_t *dst, int16_t *res, ptrdiff_t stride);
+ void (*add_residual[4])(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
void (*dequant)(int16_t *coeffs, int16_t log2_size);
@@ -60,68 +60,68 @@ typedef struct HEVCDSPContext {
void (*idct_dc[4])(int16_t *coeffs);
- void (*sao_band_filter[5])(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src,
- int16_t *sao_offset_val, int sao_left_class, int width, int height);
+ void (*sao_band_filter[5])(uint8_t *_dst, const uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src,
+ const int16_t *sao_offset_val, int sao_left_class, int width, int height);
/* implicit stride_src parameter has value of 2 * MAX_PB_SIZE + AV_INPUT_BUFFER_PADDING_SIZE */
- void (*sao_edge_filter[5])(uint8_t *_dst /* align 16 */, uint8_t *_src /* align 32 */, ptrdiff_t stride_dst,
- int16_t *sao_offset_val, int sao_eo_class, int width, int height);
+ void (*sao_edge_filter[5])(uint8_t *_dst /* align 16 */, const uint8_t *_src /* align 32 */, ptrdiff_t stride_dst,
+ const int16_t *sao_offset_val, int sao_eo_class, int width, int height);
- void (*sao_edge_restore[2])(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src,
- struct SAOParams *sao, int *borders, int _width, int _height, int c_idx,
- uint8_t *vert_edge, uint8_t *horiz_edge, uint8_t *diag_edge);
+ void (*sao_edge_restore[2])(uint8_t *_dst, const uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src,
+ const struct SAOParams *sao, const int *borders, int _width, int _height, int c_idx,
+ const uint8_t *vert_edge, const uint8_t *horiz_edge, const uint8_t *diag_edge);
- void (*put_hevc_qpel[10][2][2])(int16_t *dst, uint8_t *src, ptrdiff_t srcstride,
+ void (*put_hevc_qpel[10][2][2])(int16_t *dst, const uint8_t *src, ptrdiff_t srcstride,
int height, intptr_t mx, intptr_t my, int width);
- void (*put_hevc_qpel_uni[10][2][2])(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
+ void (*put_hevc_qpel_uni[10][2][2])(uint8_t *dst, ptrdiff_t dststride, const uint8_t *src, ptrdiff_t srcstride,
int height, intptr_t mx, intptr_t my, int width);
- void (*put_hevc_qpel_uni_w[10][2][2])(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
+ void (*put_hevc_qpel_uni_w[10][2][2])(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src, ptrdiff_t _srcstride,
int height, int denom, int wx, int ox, intptr_t mx, intptr_t my, int width);
- void (*put_hevc_qpel_bi[10][2][2])(uint8_t *dst, ptrdiff_t dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+ void (*put_hevc_qpel_bi[10][2][2])(uint8_t *dst, ptrdiff_t dststride,
+ const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
int height, intptr_t mx, intptr_t my, int width);
- void (*put_hevc_qpel_bi_w[10][2][2])(uint8_t *dst, ptrdiff_t dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+ void (*put_hevc_qpel_bi_w[10][2][2])(uint8_t *dst, ptrdiff_t dststride,
+ const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
int height, int denom, int wx0, int wx1,
int ox0, int ox1, intptr_t mx, intptr_t my, int width);
- void (*put_hevc_epel[10][2][2])(int16_t *dst, uint8_t *src, ptrdiff_t srcstride,
+ void (*put_hevc_epel[10][2][2])(int16_t *dst, const uint8_t *src, ptrdiff_t srcstride,
int height, intptr_t mx, intptr_t my, int width);
- void (*put_hevc_epel_uni[10][2][2])(uint8_t *dst, ptrdiff_t dststride, uint8_t *_src, ptrdiff_t _srcstride,
+ void (*put_hevc_epel_uni[10][2][2])(uint8_t *dst, ptrdiff_t dststride, const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width);
- void (*put_hevc_epel_uni_w[10][2][2])(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
+ void (*put_hevc_epel_uni_w[10][2][2])(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src, ptrdiff_t _srcstride,
int height, int denom, int wx, int ox, intptr_t mx, intptr_t my, int width);
- void (*put_hevc_epel_bi[10][2][2])(uint8_t *dst, ptrdiff_t dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+ void (*put_hevc_epel_bi[10][2][2])(uint8_t *dst, ptrdiff_t dststride, const uint8_t *_src, ptrdiff_t _srcstride,
+ const int16_t *src2,
int height, intptr_t mx, intptr_t my, int width);
- void (*put_hevc_epel_bi_w[10][2][2])(uint8_t *dst, ptrdiff_t dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+ void (*put_hevc_epel_bi_w[10][2][2])(uint8_t *dst, ptrdiff_t dststride,
+ const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
int height, int denom, int wx0, int ox0, int wx1,
int ox1, intptr_t mx, intptr_t my, int width);
void (*hevc_h_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,
- int beta, int32_t *tc,
- uint8_t *no_p, uint8_t *no_q);
+ int beta, const int32_t *tc,
+ const uint8_t *no_p, const uint8_t *no_q);
void (*hevc_v_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,
- int beta, int32_t *tc,
- uint8_t *no_p, uint8_t *no_q);
+ int beta, const int32_t *tc,
+ const uint8_t *no_p, const uint8_t *no_q);
void (*hevc_h_loop_filter_chroma)(uint8_t *pix, ptrdiff_t stride,
- int32_t *tc, uint8_t *no_p, uint8_t *no_q);
+ const int32_t *tc, const uint8_t *no_p, const uint8_t *no_q);
void (*hevc_v_loop_filter_chroma)(uint8_t *pix, ptrdiff_t stride,
- int32_t *tc, uint8_t *no_p, uint8_t *no_q);
+ const int32_t *tc, const uint8_t *no_p, const uint8_t *no_q);
void (*hevc_h_loop_filter_luma_c)(uint8_t *pix, ptrdiff_t stride,
- int beta, int32_t *tc,
- uint8_t *no_p, uint8_t *no_q);
+ int beta, const int32_t *tc,
+ const uint8_t *no_p, const uint8_t *no_q);
void (*hevc_v_loop_filter_luma_c)(uint8_t *pix, ptrdiff_t stride,
- int beta, int32_t *tc,
- uint8_t *no_p, uint8_t *no_q);
+ int beta, const int32_t *tc,
+ const uint8_t *no_p, const uint8_t *no_q);
void (*hevc_h_loop_filter_chroma_c)(uint8_t *pix, ptrdiff_t stride,
- int32_t *tc, uint8_t *no_p,
- uint8_t *no_q);
+ const int32_t *tc, const uint8_t *no_p,
+ const uint8_t *no_q);
void (*hevc_v_loop_filter_chroma_c)(uint8_t *pix, ptrdiff_t stride,
- int32_t *tc, uint8_t *no_p,
- uint8_t *no_q);
+ const int32_t *tc, const uint8_t *no_p,
+ const uint8_t *no_q);
} HEVCDSPContext;
void ff_hevc_dsp_init(HEVCDSPContext *hpc, int bit_depth);
diff --git a/libavcodec/hevcdsp_template.c b/libavcodec/hevcdsp_template.c
index 61425975c..725fab99e 100644
--- a/libavcodec/hevcdsp_template.c
+++ b/libavcodec/hevcdsp_template.c
@@ -41,7 +41,7 @@ static void FUNC(put_pcm)(uint8_t *_dst, ptrdiff_t stride, int width, int height
}
}
-static av_always_inline void FUNC(add_residual)(uint8_t *_dst, int16_t *res,
+static av_always_inline void FUNC(add_residual)(uint8_t *_dst, const int16_t *res,
ptrdiff_t stride, int size)
{
int x, y;
@@ -58,25 +58,25 @@ static av_always_inline void FUNC(add_residual)(uint8_t *_dst, int16_t *res,
}
}
-static void FUNC(add_residual4x4)(uint8_t *_dst, int16_t *res,
+static void FUNC(add_residual4x4)(uint8_t *_dst, const int16_t *res,
ptrdiff_t stride)
{
FUNC(add_residual)(_dst, res, stride, 4);
}
-static void FUNC(add_residual8x8)(uint8_t *_dst, int16_t *res,
+static void FUNC(add_residual8x8)(uint8_t *_dst, const int16_t *res,
ptrdiff_t stride)
{
FUNC(add_residual)(_dst, res, stride, 8);
}
-static void FUNC(add_residual16x16)(uint8_t *_dst, int16_t *res,
+static void FUNC(add_residual16x16)(uint8_t *_dst, const int16_t *res,
ptrdiff_t stride)
{
FUNC(add_residual)(_dst, res, stride, 16);
}
-static void FUNC(add_residual32x32)(uint8_t *_dst, int16_t *res,
+static void FUNC(add_residual32x32)(uint8_t *_dst, const int16_t *res,
ptrdiff_t stride)
{
FUNC(add_residual)(_dst, res, stride, 32);
@@ -295,13 +295,13 @@ IDCT_DC(32)
#undef SET
#undef SCALE
-static void FUNC(sao_band_filter)(uint8_t *_dst, uint8_t *_src,
+static void FUNC(sao_band_filter)(uint8_t *_dst, const uint8_t *_src,
ptrdiff_t stride_dst, ptrdiff_t stride_src,
- int16_t *sao_offset_val, int sao_left_class,
+ const int16_t *sao_offset_val, int sao_left_class,
int width, int height)
{
pixel *dst = (pixel *)_dst;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
int offset_table[32] = { 0 };
int k, y, x;
int shift = BIT_DEPTH - 5;
@@ -321,7 +321,7 @@ static void FUNC(sao_band_filter)(uint8_t *_dst, uint8_t *_src,
#define CMP(a, b) (((a) > (b)) - ((a) < (b)))
-static void FUNC(sao_edge_filter)(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val,
+static void FUNC(sao_edge_filter)(uint8_t *_dst, const uint8_t *_src, ptrdiff_t stride_dst, const int16_t *sao_offset_val,
int eo, int width, int height) {
static const uint8_t edge_idx[] = { 1, 2, 0, 3, 4 };
@@ -332,7 +332,7 @@ static void FUNC(sao_edge_filter)(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride
{ { 1, -1 }, { -1, 1 } }, // 135 degree
};
pixel *dst = (pixel *)_dst;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
int a_stride, b_stride;
int x, y;
ptrdiff_t stride_src = (2*MAX_PB_SIZE + AV_INPUT_BUFFER_PADDING_SIZE) / sizeof(pixel);
@@ -352,16 +352,16 @@ static void FUNC(sao_edge_filter)(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride
}
}
-static void FUNC(sao_edge_restore_0)(uint8_t *_dst, uint8_t *_src,
- ptrdiff_t stride_dst, ptrdiff_t stride_src, SAOParams *sao,
- int *borders, int _width, int _height,
- int c_idx, uint8_t *vert_edge,
- uint8_t *horiz_edge, uint8_t *diag_edge)
+static void FUNC(sao_edge_restore_0)(uint8_t *_dst, const uint8_t *_src,
+ ptrdiff_t stride_dst, ptrdiff_t stride_src, const SAOParams *sao,
+ const int *borders, int _width, int _height,
+ int c_idx, const uint8_t *vert_edge,
+ const uint8_t *horiz_edge, const uint8_t *diag_edge)
{
int x, y;
pixel *dst = (pixel *)_dst;
- pixel *src = (pixel *)_src;
- int16_t *sao_offset_val = sao->offset_val[c_idx];
+ const pixel *src = (const pixel *)_src;
+ const int16_t *sao_offset_val = sao->offset_val[c_idx];
int sao_eo_class = sao->eo_class[c_idx];
int init_x = 0, width = _width, height = _height;
@@ -402,16 +402,16 @@ static void FUNC(sao_edge_restore_0)(uint8_t *_dst, uint8_t *_src,
}
}
-static void FUNC(sao_edge_restore_1)(uint8_t *_dst, uint8_t *_src,
- ptrdiff_t stride_dst, ptrdiff_t stride_src, SAOParams *sao,
- int *borders, int _width, int _height,
- int c_idx, uint8_t *vert_edge,
- uint8_t *horiz_edge, uint8_t *diag_edge)
+static void FUNC(sao_edge_restore_1)(uint8_t *_dst, const uint8_t *_src,
+ ptrdiff_t stride_dst, ptrdiff_t stride_src, const SAOParams *sao,
+ const int *borders, int _width, int _height,
+ int c_idx, const uint8_t *vert_edge,
+ const uint8_t *horiz_edge, const uint8_t *diag_edge)
{
int x, y;
pixel *dst = (pixel *)_dst;
- pixel *src = (pixel *)_src;
- int16_t *sao_offset_val = sao->offset_val[c_idx];
+ const pixel *src = (const pixel *)_src;
+ const int16_t *sao_offset_val = sao->offset_val[c_idx];
int sao_eo_class = sao->eo_class[c_idx];
int init_x = 0, init_y = 0, width = _width, height = _height;
@@ -494,11 +494,11 @@ static void FUNC(sao_edge_restore_1)(uint8_t *_dst, uint8_t *_src,
//
////////////////////////////////////////////////////////////////////////////////
static void FUNC(put_hevc_pel_pixels)(int16_t *dst,
- uint8_t *_src, ptrdiff_t _srcstride,
+ const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
for (y = 0; y < height; y++) {
@@ -509,11 +509,11 @@ static void FUNC(put_hevc_pel_pixels)(int16_t *dst,
}
}
-static void FUNC(put_hevc_pel_uni_pixels)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
+static void FUNC(put_hevc_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)
{
int y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -525,12 +525,12 @@ static void FUNC(put_hevc_pel_uni_pixels)(uint8_t *_dst, ptrdiff_t _dststride, u
}
}
-static void FUNC(put_hevc_pel_bi_pixels)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+static void FUNC(put_hevc_pel_bi_pixels)(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src, ptrdiff_t _srcstride,
+ const int16_t *src2,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -551,11 +551,11 @@ static void FUNC(put_hevc_pel_bi_pixels)(uint8_t *_dst, ptrdiff_t _dststride, ui
}
}
-static void FUNC(put_hevc_pel_uni_w_pixels)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
+static void FUNC(put_hevc_pel_uni_w_pixels)(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src, ptrdiff_t _srcstride,
int height, int denom, int wx, int ox, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -575,13 +575,13 @@ static void FUNC(put_hevc_pel_uni_w_pixels)(uint8_t *_dst, ptrdiff_t _dststride,
}
}
-static void FUNC(put_hevc_pel_bi_w_pixels)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+static void FUNC(put_hevc_pel_bi_w_pixels)(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src, ptrdiff_t _srcstride,
+ const int16_t *src2,
int height, int denom, int wx0, int wx1,
int ox0, int ox1, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -615,11 +615,11 @@ static void FUNC(put_hevc_pel_bi_w_pixels)(uint8_t *_dst, ptrdiff_t _dststride,
filter[7] * src[x + 4 * stride])
static void FUNC(put_hevc_qpel_h)(int16_t *dst,
- uint8_t *_src, ptrdiff_t _srcstride,
+ const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
const int8_t *filter = ff_hevc_qpel_filters[mx - 1];
for (y = 0; y < height; y++) {
@@ -631,11 +631,11 @@ static void FUNC(put_hevc_qpel_h)(int16_t *dst,
}
static void FUNC(put_hevc_qpel_v)(int16_t *dst,
- uint8_t *_src, ptrdiff_t _srcstride,
+ const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
const int8_t *filter = ff_hevc_qpel_filters[my - 1];
for (y = 0; y < height; y++) {
@@ -647,14 +647,14 @@ static void FUNC(put_hevc_qpel_v)(int16_t *dst,
}
static void FUNC(put_hevc_qpel_hv)(int16_t *dst,
- uint8_t *_src,
+ const uint8_t *_src,
ptrdiff_t _srcstride,
int height, intptr_t mx,
intptr_t my, int width)
{
int x, y;
const int8_t *filter;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
int16_t tmp_array[(MAX_PB_SIZE + QPEL_EXTRA) * MAX_PB_SIZE];
int16_t *tmp = tmp_array;
@@ -679,11 +679,11 @@ static void FUNC(put_hevc_qpel_hv)(int16_t *dst,
}
static void FUNC(put_hevc_qpel_uni_h)(uint8_t *_dst, ptrdiff_t _dststride,
- uint8_t *_src, ptrdiff_t _srcstride,
+ const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -704,12 +704,12 @@ static void FUNC(put_hevc_qpel_uni_h)(uint8_t *_dst, ptrdiff_t _dststride,
}
}
-static void FUNC(put_hevc_qpel_bi_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+static void FUNC(put_hevc_qpel_bi_h)(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src, ptrdiff_t _srcstride,
+ const int16_t *src2,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -733,11 +733,11 @@ static void FUNC(put_hevc_qpel_bi_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_
}
static void FUNC(put_hevc_qpel_uni_v)(uint8_t *_dst, ptrdiff_t _dststride,
- uint8_t *_src, ptrdiff_t _srcstride,
+ const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -759,12 +759,12 @@ static void FUNC(put_hevc_qpel_uni_v)(uint8_t *_dst, ptrdiff_t _dststride,
}
-static void FUNC(put_hevc_qpel_bi_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+static void FUNC(put_hevc_qpel_bi_v)(uint8_t *_dst, ptrdiff_t _dststride,
+ const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -788,12 +788,12 @@ static void FUNC(put_hevc_qpel_bi_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8_
}
static void FUNC(put_hevc_qpel_uni_hv)(uint8_t *_dst, ptrdiff_t _dststride,
- uint8_t *_src, ptrdiff_t _srcstride,
+ const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
const int8_t *filter;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -827,13 +827,13 @@ static void FUNC(put_hevc_qpel_uni_hv)(uint8_t *_dst, ptrdiff_t _dststride,
}
}
-static void FUNC(put_hevc_qpel_bi_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+static void FUNC(put_hevc_qpel_bi_hv)(uint8_t *_dst, ptrdiff_t _dststride,
+ const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
const int8_t *filter;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -868,12 +868,12 @@ static void FUNC(put_hevc_qpel_bi_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8
}
static void FUNC(put_hevc_qpel_uni_w_h)(uint8_t *_dst, ptrdiff_t _dststride,
- uint8_t *_src, ptrdiff_t _srcstride,
+ const uint8_t *_src, ptrdiff_t _srcstride,
int height, int denom, int wx, int ox,
intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -894,13 +894,13 @@ static void FUNC(put_hevc_qpel_uni_w_h)(uint8_t *_dst, ptrdiff_t _dststride,
}
}
-static void FUNC(put_hevc_qpel_bi_w_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+static void FUNC(put_hevc_qpel_bi_w_h)(uint8_t *_dst, ptrdiff_t _dststride,
+ const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
int height, int denom, int wx0, int wx1,
int ox0, int ox1, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -923,12 +923,12 @@ static void FUNC(put_hevc_qpel_bi_w_h)(uint8_t *_dst, ptrdiff_t _dststride, uint
}
static void FUNC(put_hevc_qpel_uni_w_v)(uint8_t *_dst, ptrdiff_t _dststride,
- uint8_t *_src, ptrdiff_t _srcstride,
+ const uint8_t *_src, ptrdiff_t _srcstride,
int height, int denom, int wx, int ox,
intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -949,13 +949,13 @@ static void FUNC(put_hevc_qpel_uni_w_v)(uint8_t *_dst, ptrdiff_t _dststride,
}
}
-static void FUNC(put_hevc_qpel_bi_w_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+static void FUNC(put_hevc_qpel_bi_w_v)(uint8_t *_dst, ptrdiff_t _dststride,
+ const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
int height, int denom, int wx0, int wx1,
int ox0, int ox1, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -978,13 +978,13 @@ static void FUNC(put_hevc_qpel_bi_w_v)(uint8_t *_dst, ptrdiff_t _dststride, uint
}
static void FUNC(put_hevc_qpel_uni_w_hv)(uint8_t *_dst, ptrdiff_t _dststride,
- uint8_t *_src, ptrdiff_t _srcstride,
+ const uint8_t *_src, ptrdiff_t _srcstride,
int height, int denom, int wx, int ox,
intptr_t mx, intptr_t my, int width)
{
int x, y;
const int8_t *filter;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -1018,14 +1018,14 @@ static void FUNC(put_hevc_qpel_uni_w_hv)(uint8_t *_dst, ptrdiff_t _dststride,
}
}
-static void FUNC(put_hevc_qpel_bi_w_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+static void FUNC(put_hevc_qpel_bi_w_hv)(uint8_t *_dst, ptrdiff_t _dststride,
+ const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
int height, int denom, int wx0, int wx1,
int ox0, int ox1, intptr_t mx, intptr_t my, int width)
{
int x, y;
const int8_t *filter;
- pixel *src = (pixel*)_src;
+ const pixel *src = (const pixel*)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -1068,11 +1068,11 @@ static void FUNC(put_hevc_qpel_bi_w_hv)(uint8_t *_dst, ptrdiff_t _dststride, uin
filter[3] * src[x + 2 * stride])
static void FUNC(put_hevc_epel_h)(int16_t *dst,
- uint8_t *_src, ptrdiff_t _srcstride,
+ const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
const int8_t *filter = ff_hevc_epel_filters[mx - 1];
for (y = 0; y < height; y++) {
@@ -1084,11 +1084,11 @@ static void FUNC(put_hevc_epel_h)(int16_t *dst,
}
static void FUNC(put_hevc_epel_v)(int16_t *dst,
- uint8_t *_src, ptrdiff_t _srcstride,
+ const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
const int8_t *filter = ff_hevc_epel_filters[my - 1];
@@ -1101,11 +1101,11 @@ static void FUNC(put_hevc_epel_v)(int16_t *dst,
}
static void FUNC(put_hevc_epel_hv)(int16_t *dst,
- uint8_t *_src, ptrdiff_t _srcstride,
+ const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
const int8_t *filter = ff_hevc_epel_filters[mx - 1];
int16_t tmp_array[(MAX_PB_SIZE + EPEL_EXTRA) * MAX_PB_SIZE];
@@ -1131,11 +1131,11 @@ static void FUNC(put_hevc_epel_hv)(int16_t *dst,
}
}
-static void FUNC(put_hevc_epel_uni_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
+static void FUNC(put_hevc_epel_uni_h)(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -1155,12 +1155,12 @@ static void FUNC(put_hevc_epel_uni_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8
}
}
-static void FUNC(put_hevc_epel_bi_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+static void FUNC(put_hevc_epel_bi_h)(uint8_t *_dst, ptrdiff_t _dststride,
+ const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -1182,11 +1182,11 @@ static void FUNC(put_hevc_epel_bi_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_
}
}
-static void FUNC(put_hevc_epel_uni_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
+static void FUNC(put_hevc_epel_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)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -1206,12 +1206,12 @@ static void FUNC(put_hevc_epel_uni_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8
}
}
-static void FUNC(put_hevc_epel_bi_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+static void FUNC(put_hevc_epel_bi_v)(uint8_t *_dst, ptrdiff_t _dststride,
+ const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
const int8_t *filter = ff_hevc_epel_filters[my - 1];
pixel *dst = (pixel *)_dst;
@@ -1232,11 +1232,11 @@ static void FUNC(put_hevc_epel_bi_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8_
}
}
-static void FUNC(put_hevc_epel_uni_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
+static void FUNC(put_hevc_epel_uni_hv)(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src, ptrdiff_t _srcstride,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -1270,12 +1270,12 @@ static void FUNC(put_hevc_epel_uni_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint
}
}
-static void FUNC(put_hevc_epel_bi_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+static void FUNC(put_hevc_epel_bi_hv)(uint8_t *_dst, ptrdiff_t _dststride,
+ const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
int height, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -1310,11 +1310,11 @@ static void FUNC(put_hevc_epel_bi_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8
}
}
-static void FUNC(put_hevc_epel_uni_w_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
+static void FUNC(put_hevc_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, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -1336,13 +1336,13 @@ static void FUNC(put_hevc_epel_uni_w_h)(uint8_t *_dst, ptrdiff_t _dststride, uin
}
}
-static void FUNC(put_hevc_epel_bi_w_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+static void FUNC(put_hevc_epel_bi_w_h)(uint8_t *_dst, ptrdiff_t _dststride,
+ const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
int height, int denom, int wx0, int wx1,
int ox0, int ox1, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -1362,11 +1362,11 @@ static void FUNC(put_hevc_epel_bi_w_h)(uint8_t *_dst, ptrdiff_t _dststride, uint
}
}
-static void FUNC(put_hevc_epel_uni_w_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
+static void FUNC(put_hevc_epel_uni_w_v)(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src, ptrdiff_t _srcstride,
int height, int denom, int wx, int ox, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -1388,13 +1388,13 @@ static void FUNC(put_hevc_epel_uni_w_v)(uint8_t *_dst, ptrdiff_t _dststride, uin
}
}
-static void FUNC(put_hevc_epel_bi_w_v)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+static void FUNC(put_hevc_epel_bi_w_v)(uint8_t *_dst, ptrdiff_t _dststride,
+ const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
int height, int denom, int wx0, int wx1,
int ox0, int ox1, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
const int8_t *filter = ff_hevc_epel_filters[my - 1];
pixel *dst = (pixel *)_dst;
@@ -1414,11 +1414,11 @@ static void FUNC(put_hevc_epel_bi_w_v)(uint8_t *_dst, ptrdiff_t _dststride, uint
}
}
-static void FUNC(put_hevc_epel_uni_w_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
+static void FUNC(put_hevc_epel_uni_w_hv)(uint8_t *_dst, ptrdiff_t _dststride, const uint8_t *_src, ptrdiff_t _srcstride,
int height, int denom, int wx, int ox, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -1453,13 +1453,13 @@ static void FUNC(put_hevc_epel_uni_w_hv)(uint8_t *_dst, ptrdiff_t _dststride, ui
}
}
-static void FUNC(put_hevc_epel_bi_w_hv)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
- int16_t *src2,
+static void FUNC(put_hevc_epel_bi_w_hv)(uint8_t *_dst, ptrdiff_t _dststride,
+ const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
int height, int denom, int wx0, int wx1,
int ox0, int ox1, intptr_t mx, intptr_t my, int width)
{
int x, y;
- pixel *src = (pixel *)_src;
+ const pixel *src = (const pixel *)_src;
ptrdiff_t srcstride = _srcstride / sizeof(pixel);
pixel *dst = (pixel *)_dst;
ptrdiff_t dststride = _dststride / sizeof(pixel);
@@ -1515,8 +1515,8 @@ static void FUNC(put_hevc_epel_bi_w_hv)(uint8_t *_dst, ptrdiff_t _dststride, uin
static void FUNC(hevc_loop_filter_luma)(uint8_t *_pix,
ptrdiff_t _xstride, ptrdiff_t _ystride,
- int beta, int *_tc,
- uint8_t *_no_p, uint8_t *_no_q)
+ int beta, const int *_tc,
+ const uint8_t *_no_p, const uint8_t *_no_q)
{
int d, j;
pixel *pix = (pixel *)_pix;
@@ -1610,8 +1610,8 @@ static void FUNC(hevc_loop_filter_luma)(uint8_t *_pix,
}
static void FUNC(hevc_loop_filter_chroma)(uint8_t *_pix, ptrdiff_t _xstride,
- ptrdiff_t _ystride, int *_tc,
- uint8_t *_no_p, uint8_t *_no_q)
+ ptrdiff_t _ystride, const int *_tc,
+ const uint8_t *_no_p, const uint8_t *_no_q)
{
int d, j, no_p, no_q;
pixel *pix = (pixel *)_pix;
@@ -1644,30 +1644,30 @@ static void FUNC(hevc_loop_filter_chroma)(uint8_t *_pix, ptrdiff_t _xstride,
}
static void FUNC(hevc_h_loop_filter_chroma)(uint8_t *pix, ptrdiff_t stride,
- int32_t *tc, uint8_t *no_p,
- uint8_t *no_q)
+ const int32_t *tc, const uint8_t *no_p,
+ const uint8_t *no_q)
{
FUNC(hevc_loop_filter_chroma)(pix, stride, sizeof(pixel), tc, no_p, no_q);
}
static void FUNC(hevc_v_loop_filter_chroma)(uint8_t *pix, ptrdiff_t stride,
- int32_t *tc, uint8_t *no_p,
- uint8_t *no_q)
+ const int32_t *tc, const uint8_t *no_p,
+ const uint8_t *no_q)
{
FUNC(hevc_loop_filter_chroma)(pix, sizeof(pixel), stride, tc, no_p, no_q);
}
static void FUNC(hevc_h_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,
- int beta, int32_t *tc, uint8_t *no_p,
- uint8_t *no_q)
+ int beta, const int32_t *tc, const uint8_t *no_p,
+ const uint8_t *no_q)
{
FUNC(hevc_loop_filter_luma)(pix, stride, sizeof(pixel),
beta, tc, no_p, no_q);
}
static void FUNC(hevc_v_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,
- int beta, int32_t *tc, uint8_t *no_p,
- uint8_t *no_q)
+ int beta, const int32_t *tc, const uint8_t *no_p,
+ const uint8_t *no_q)
{
FUNC(hevc_loop_filter_luma)(pix, sizeof(pixel), stride,
beta, tc, no_p, no_q);
diff --git a/libavcodec/hevcpred.h b/libavcodec/hevcpred.h
index eb1766368..b1b1dc4f3 100644
--- a/libavcodec/hevcpred.h
+++ b/libavcodec/hevcpred.h
@@ -26,10 +26,10 @@
#include
#include
-struct HEVCContext;
+struct HEVCLocalContext;
typedef struct HEVCPredContext {
- void (*intra_pred[4])(struct HEVCContext *s, int x0, int y0, int c_idx);
+ void (*intra_pred[4])(struct HEVCLocalContext *lc, int x0, int y0, int c_idx);
void (*pred_planar[4])(uint8_t *src, const uint8_t *top,
const uint8_t *left, ptrdiff_t stride);
diff --git a/libavcodec/hevcpred_template.c b/libavcodec/hevcpred_template.c
index ca75ec112..16d1c7f35 100644
--- a/libavcodec/hevcpred_template.c
+++ b/libavcodec/hevcpred_template.c
@@ -27,7 +27,7 @@
#define POS(x, y) src[(x) + stride * (y)]
-static av_always_inline void FUNC(intra_pred)(HEVCContext *s, int x0, int y0,
+static av_always_inline void FUNC(intra_pred)(HEVCLocalContext *lc, int x0, int y0,
int log2_size, int c_idx)
{
#define PU(x) \
@@ -70,7 +70,7 @@ do { \
else \
a = PIXEL_SPLAT_X4(ptr[i + 3])
- HEVCLocalContext *lc = s->HEVClc;
+ const HEVCContext *const s = lc->parent;
int i;
int hshift = s->ps.sps->hshift[c_idx];
int vshift = s->ps.sps->vshift[c_idx];
@@ -346,9 +346,9 @@ do { \
}
#define INTRA_PRED(size) \
-static void FUNC(intra_pred_ ## size)(HEVCContext *s, int x0, int y0, int c_idx) \
+static void FUNC(intra_pred_ ## size)(HEVCLocalContext *lc, int x0, int y0, int c_idx) \
{ \
- FUNC(intra_pred)(s, x0, y0, size, c_idx); \
+ FUNC(intra_pred)(lc, x0, y0, size, c_idx); \
}
INTRA_PRED(2)
diff --git a/libavcodec/hnm4video.c b/libavcodec/hnm4video.c
index 1326d5f87..f223bb82f 100644
--- a/libavcodec/hnm4video.c
+++ b/libavcodec/hnm4video.c
@@ -29,7 +29,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#define HNM4_CHUNK_ID_PL 19536
#define HNM4_CHUNK_ID_IZ 23113
@@ -499,7 +499,7 @@ static av_cold int hnm_decode_end(AVCodecContext *avctx)
const FFCodec ff_hnm4_video_decoder = {
.p.name = "hnm4video",
- .p.long_name = NULL_IF_CONFIG_SMALL("HNM 4 video"),
+ CODEC_LONG_NAME("HNM 4 video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_HNM4_VIDEO,
.priv_data_size = sizeof(Hnm4VideoContext),
@@ -507,5 +507,5 @@ const FFCodec ff_hnm4_video_decoder = {
.close = hnm_decode_end,
FF_CODEC_DECODE_CB(hnm_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/hq_hqa.c b/libavcodec/hq_hqa.c
index cea2475bb..6ce73b7ae 100644
--- a/libavcodec/hq_hqa.c
+++ b/libavcodec/hq_hqa.c
@@ -21,13 +21,13 @@
#include
#include "libavutil/attributes.h"
-#include "libavutil/intreadwrite.h"
#include "avcodec.h"
+#include "bytestream.h"
#include "canopus.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
#include "hq_hqa.h"
#include "hq_hqadsp.h"
@@ -114,12 +114,12 @@ static int hq_decode_mb(HQContext *c, AVFrame *pic,
return 0;
}
-static int hq_decode_frame(HQContext *ctx, AVFrame *pic,
+static int hq_decode_frame(HQContext *ctx, AVFrame *pic, GetByteContext *gbc,
int prof_num, size_t data_size)
{
const HQProfile *profile;
GetBitContext gb;
- const uint8_t *perm, *src = ctx->gbc.buffer;
+ const uint8_t *perm, *src = gbc->buffer;
uint32_t slice_off[21];
int slice, start_off, next_off, i, ret;
@@ -144,7 +144,7 @@ static int hq_decode_frame(HQContext *ctx, AVFrame *pic,
/* Offsets are stored from CUV position, so adjust them accordingly. */
for (i = 0; i < profile->num_slices + 1; i++)
- slice_off[i] = bytestream2_get_be24(&ctx->gbc) - 4;
+ slice_off[i] = bytestream2_get_be24(gbc) - 4;
next_off = 0;
for (slice = 0; slice < profile->num_slices; slice++) {
@@ -240,20 +240,20 @@ static int hqa_decode_slice(HQContext *ctx, AVFrame *pic, GetBitContext *gb,
return 0;
}
-static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, size_t data_size)
+static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, GetByteContext *gbc, size_t data_size)
{
GetBitContext gb;
const int num_slices = 8;
uint32_t slice_off[9];
int i, slice, ret;
int width, height, quant;
- const uint8_t *src = ctx->gbc.buffer;
+ const uint8_t *src = gbc->buffer;
- if (bytestream2_get_bytes_left(&ctx->gbc) < 8 + 4*(num_slices + 1))
+ if (bytestream2_get_bytes_left(gbc) < 8 + 4*(num_slices + 1))
return AVERROR_INVALIDDATA;
- width = bytestream2_get_be16(&ctx->gbc);
- height = bytestream2_get_be16(&ctx->gbc);
+ width = bytestream2_get_be16(gbc);
+ height = bytestream2_get_be16(gbc);
ret = ff_set_dimensions(ctx->avctx, width, height);
if (ret < 0)
@@ -266,8 +266,8 @@ static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, size_t data_size)
av_log(ctx->avctx, AV_LOG_VERBOSE, "HQA Profile\n");
- quant = bytestream2_get_byte(&ctx->gbc);
- bytestream2_skip(&ctx->gbc, 3);
+ quant = bytestream2_get_byte(gbc);
+ bytestream2_skip(gbc, 3);
if (quant >= NUM_HQ_QUANTS) {
av_log(ctx->avctx, AV_LOG_ERROR,
"Invalid quantization matrix %d.\n", quant);
@@ -280,7 +280,7 @@ static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, size_t data_size)
/* Offsets are stored from HQA1 position, so adjust them accordingly. */
for (i = 0; i < num_slices + 1; i++)
- slice_off[i] = bytestream2_get_be32(&ctx->gbc) - 4;
+ slice_off[i] = bytestream2_get_be32(gbc) - 4;
for (slice = 0; slice < num_slices; slice++) {
if (slice_off[slice] < (num_slices + 1) * 3 ||
@@ -305,32 +305,33 @@ static int hq_hqa_decode_frame(AVCodecContext *avctx, AVFrame *pic,
int *got_frame, AVPacket *avpkt)
{
HQContext *ctx = avctx->priv_data;
+ GetByteContext gbc0, *const gbc = &gbc0;
uint32_t info_tag;
unsigned int data_size;
int ret;
unsigned tag;
- bytestream2_init(&ctx->gbc, avpkt->data, avpkt->size);
- if (bytestream2_get_bytes_left(&ctx->gbc) < 4 + 4) {
+ bytestream2_init(gbc, avpkt->data, avpkt->size);
+ if (bytestream2_get_bytes_left(gbc) < 4 + 4) {
av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", avpkt->size);
return AVERROR_INVALIDDATA;
}
- info_tag = bytestream2_peek_le32(&ctx->gbc);
+ info_tag = bytestream2_peek_le32(gbc);
if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
int info_size;
- bytestream2_skip(&ctx->gbc, 4);
- info_size = bytestream2_get_le32(&ctx->gbc);
- if (info_size < 0 || bytestream2_get_bytes_left(&ctx->gbc) < info_size) {
+ bytestream2_skip(gbc, 4);
+ info_size = bytestream2_get_le32(gbc);
+ if (info_size < 0 || bytestream2_get_bytes_left(gbc) < info_size) {
av_log(avctx, AV_LOG_ERROR, "Invalid INFO size (%d).\n", info_size);
return AVERROR_INVALIDDATA;
}
- ff_canopus_parse_info_tag(avctx, ctx->gbc.buffer, info_size);
+ ff_canopus_parse_info_tag(avctx, gbc->buffer, info_size);
- bytestream2_skip(&ctx->gbc, info_size);
+ bytestream2_skip(gbc, info_size);
}
- data_size = bytestream2_get_bytes_left(&ctx->gbc);
+ data_size = bytestream2_get_bytes_left(gbc);
if (data_size < 4) {
av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", data_size);
return AVERROR_INVALIDDATA;
@@ -339,11 +340,11 @@ static int hq_hqa_decode_frame(AVCodecContext *avctx, AVFrame *pic,
/* HQ defines dimensions and number of slices, and thus slice traversal
* order. HQA has no size constraint and a fixed number of slices, so it
* needs a separate scheme for it. */
- tag = bytestream2_get_le32(&ctx->gbc);
+ tag = bytestream2_get_le32(gbc);
if ((tag & 0x00FFFFFF) == (MKTAG('U', 'V', 'C', ' ') & 0x00FFFFFF)) {
- ret = hq_decode_frame(ctx, pic, tag >> 24, data_size);
+ ret = hq_decode_frame(ctx, pic, gbc, tag >> 24, data_size);
} else if (tag == MKTAG('H', 'Q', 'A', '1')) {
- ret = hqa_decode_frame(ctx, pic, data_size);
+ ret = hqa_decode_frame(ctx, pic, gbc, data_size);
} else {
av_log(avctx, AV_LOG_ERROR, "Not a HQ/HQA frame.\n");
return AVERROR_INVALIDDATA;
@@ -383,7 +384,7 @@ static av_cold int hq_hqa_decode_close(AVCodecContext *avctx)
const FFCodec ff_hq_hqa_decoder = {
.p.name = "hq_hqa",
- .p.long_name = NULL_IF_CONFIG_SMALL("Canopus HQ/HQA"),
+ CODEC_LONG_NAME("Canopus HQ/HQA"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_HQ_HQA,
.priv_data_size = sizeof(HQContext),
@@ -391,6 +392,5 @@ const FFCodec ff_hq_hqa_decoder = {
FF_CODEC_DECODE_CB(hq_hqa_decode_frame),
.close = hq_hqa_decode_close,
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/hq_hqa.h b/libavcodec/hq_hqa.h
index 08d79e745..71aa36706 100644
--- a/libavcodec/hq_hqa.h
+++ b/libavcodec/hq_hqa.h
@@ -26,7 +26,6 @@
#include "libavutil/mem_internal.h"
#include "avcodec.h"
-#include "bytestream.h"
#include "hq_hqadsp.h"
#include "vlc.h"
@@ -37,7 +36,6 @@
typedef struct HQContext {
AVCodecContext *avctx;
HQDSPContext hqhqadsp;
- GetByteContext gbc;
VLC hq_ac_vlc;
VLC hqa_cbp_vlc;
diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c
index 596b8a7ed..608394655 100644
--- a/libavcodec/hqx.c
+++ b/libavcodec/hqx.c
@@ -536,7 +536,7 @@ static av_cold int hqx_decode_init(AVCodecContext *avctx)
const FFCodec ff_hqx_decoder = {
.p.name = "hqx",
- .p.long_name = NULL_IF_CONFIG_SMALL("Canopus HQX"),
+ CODEC_LONG_NAME("Canopus HQX"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_HQX,
.priv_data_size = sizeof(HQXContext),
@@ -545,6 +545,5 @@ const FFCodec ff_hqx_decoder = {
.close = hqx_decode_close,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS |
AV_CODEC_CAP_FRAME_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c
index e582060cc..aaba313bf 100644
--- a/libavcodec/huffyuv.c
+++ b/libavcodec/huffyuv.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002-2014 Michael Niedermayer
*
- * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
+ * see https://multimedia.cx/huffyuv.txt for a description of
* the algorithm used
*
* This file is part of FFmpeg.
@@ -30,65 +30,55 @@
#include
+#include "libavutil/attributes.h"
+#include "libavutil/error.h"
+#include "libavutil/log.h"
#include "libavutil/mem.h"
-#include "avcodec.h"
-#include "bswapdsp.h"
#include "huffyuv.h"
int ff_huffyuv_generate_bits_table(uint32_t *dst, const uint8_t *len_table, int n)
{
- int len, index;
- uint32_t bits = 0;
+ int lens[33] = { 0 };
+ uint32_t codes[33];
- for (len = 32; len > 0; len--) {
- for (index = 0; index < n; index++) {
- if (len_table[index] == len)
- dst[index] = bits++;
- }
- if (bits & 1) {
+ for (int i = 0; i < n; i++)
+ lens[len_table[i]]++;
+
+ codes[32] = 0;
+ for (int i = FF_ARRAY_ELEMS(lens) - 1; i > 0; i--) {
+ if ((lens[i] + codes[i]) & 1) {
av_log(NULL, AV_LOG_ERROR, "Error generating huffman table\n");
return -1;
}
- bits >>= 1;
+ codes[i - 1] = (lens[i] + codes[i]) >> 1;
+ }
+ for (int i = 0; i < n; i++) {
+ if (len_table[i])
+ dst[i] = codes[len_table[i]]++;
}
return 0;
}
-av_cold int ff_huffyuv_alloc_temp(HYuvContext *s)
+av_cold int ff_huffyuv_alloc_temp(uint8_t *temp[3], uint16_t *temp16[3], int width)
{
int i;
for (i=0; i<3; i++) {
- s->temp[i]= av_malloc(4*s->width + 16);
- if (!s->temp[i])
+ temp[i] = av_malloc(4 * width + 16);
+ if (!temp[i])
return AVERROR(ENOMEM);
- s->temp16[i] = (uint16_t*)s->temp[i];
+ temp16[i] = (uint16_t*)temp[i];
}
return 0;
}
-av_cold void ff_huffyuv_common_init(AVCodecContext *avctx)
-{
- HYuvContext *s = avctx->priv_data;
-
- s->avctx = avctx;
- s->flags = avctx->flags;
-
- ff_bswapdsp_init(&s->bdsp);
-
- s->width = avctx->width;
- s->height = avctx->height;
-
- av_assert1(s->width > 0 && s->height > 0);
-}
-
-av_cold void ff_huffyuv_common_end(HYuvContext *s)
+av_cold void ff_huffyuv_common_end(uint8_t *temp[3], uint16_t *temp16[3])
{
int i;
for(i = 0; i < 3; i++) {
- av_freep(&s->temp[i]);
- s->temp16[i] = NULL;
+ av_freep(&temp[i]);
+ temp16[i] = NULL;
}
}
diff --git a/libavcodec/huffyuv.h b/libavcodec/huffyuv.h
index 83309d4b1..22a766611 100644
--- a/libavcodec/huffyuv.h
+++ b/libavcodec/huffyuv.h
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2002-2014 Michael Niedermayer
*
- * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
+ * see https://multimedia.cx/huffyuv.txt for a description of
* the algorithm used
*
* This file is part of FFmpeg.
@@ -31,16 +31,19 @@
#include
-#include "avcodec.h"
-#include "bswapdsp.h"
-#include "get_bits.h"
-#include "huffyuvdsp.h"
-#include "huffyuvencdsp.h"
-#include "put_bits.h"
-#include "lossless_videodsp.h"
-#include "lossless_videoencdsp.h"
+#include "config.h"
-#define VLC_BITS 12
+#if HAVE_BIGENDIAN
+#define B 3
+#define G 2
+#define R 1
+#define A 0
+#else
+#define B 0
+#define G 1
+#define R 2
+#define A 3
+#endif
#define MAX_BITS 16
#define MAX_N (1<
*
- * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
+ * see https://multimedia.cx/huffyuv.txt for a description of
* the algorithm used
*
* This file is part of FFmpeg.
@@ -35,6 +35,7 @@
#include "config_components.h"
#include "avcodec.h"
+#include "bswapdsp.h"
#include "codec_internal.h"
#include "get_bits.h"
#include "huffyuv.h"
@@ -44,6 +45,43 @@
#include "libavutil/imgutils.h"
#include "libavutil/pixdesc.h"
+#define VLC_BITS 12
+
+typedef struct HYuvDecContext {
+ GetBitContext gb;
+ Predictor predictor;
+ int interlaced;
+ int decorrelate;
+ int bitstream_bpp;
+ int version;
+ int yuy2; //use yuy2 instead of 422P
+ int bgr32; //use bgr32 instead of bgr24
+ int bps;
+ int n; // 1<priv_data;
+ HYuvDecContext *s = avctx->priv_data;
int i;
- ff_huffyuv_common_end(s);
+ ff_huffyuv_common_end(s->temp, s->temp16);
av_freep(&s->bitstream_buffer);
for (i = 0; i < 8; i++)
@@ -293,13 +331,16 @@ static av_cold int decode_end(AVCodecContext *avctx)
static av_cold int decode_init(AVCodecContext *avctx)
{
- HYuvContext *s = avctx->priv_data;
+ HYuvDecContext *s = avctx->priv_data;
int ret;
ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
if (ret < 0)
return ret;
+ s->flags = avctx->flags;
+
+ ff_bswapdsp_init(&s->bdsp);
ff_huffyuvdsp_init(&s->hdsp, avctx->pix_fmt);
ff_llviddsp_init(&s->llviddsp);
memset(s->vlc, 0, 4 * sizeof(VLC));
@@ -545,8 +586,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
}
}
- ff_huffyuv_common_init(avctx);
-
if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P || avctx->pix_fmt == AV_PIX_FMT_YUV420P) && avctx->width & 1) {
av_log(avctx, AV_LOG_ERROR, "width must be even for this colorspace\n");
return AVERROR_INVALIDDATA;
@@ -558,7 +597,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
return AVERROR_INVALIDDATA;
}
- if ((ret = ff_huffyuv_alloc_temp(s)) < 0)
+ if ((ret = ff_huffyuv_alloc_temp(s->temp, s->temp16, avctx->width)) < 0)
return ret;
return 0;
@@ -617,7 +656,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
GET_VLC_DUAL(dst0, dst1, re, &s->gb, s->vlc[4+plane1].table, \
s->vlc[0].table, s->vlc[plane1].table, VLC_BITS, 3, OP8bits)
-static void decode_422_bitstream(HYuvContext *s, int count)
+static void decode_422_bitstream(HYuvDecContext *s, int count)
{
int i, icount;
OPEN_READER(re, &s->gb);
@@ -661,7 +700,7 @@ static void decode_422_bitstream(HYuvContext *s, int count)
dst1 = get_vlc2(&s->gb, s->vlc[plane].table, VLC_BITS, 3)<<2;\
dst1 += get_bits(&s->gb, 2);\
}
-static void decode_plane_bitstream(HYuvContext *s, int width, int plane)
+static void decode_plane_bitstream(HYuvDecContext *s, int width, int plane)
{
int i, count = width/2;
@@ -722,7 +761,7 @@ static void decode_plane_bitstream(HYuvContext *s, int width, int plane)
}
}
-static void decode_gray_bitstream(HYuvContext *s, int count)
+static void decode_gray_bitstream(HYuvDecContext *s, int count)
{
int i;
OPEN_READER(re, &s->gb);
@@ -740,7 +779,7 @@ static void decode_gray_bitstream(HYuvContext *s, int count)
CLOSE_READER(re, &s->gb);
}
-static av_always_inline void decode_bgr_1(HYuvContext *s, int count,
+static av_always_inline void decode_bgr_1(HYuvDecContext *s, int count,
int decorrelate, int alpha)
{
int i;
@@ -798,7 +837,7 @@ static av_always_inline void decode_bgr_1(HYuvContext *s, int count,
CLOSE_READER(re, &s->gb);
}
-static void decode_bgr_bitstream(HYuvContext *s, int count)
+static void decode_bgr_bitstream(HYuvDecContext *s, int count)
{
if (s->decorrelate) {
if (s->bitstream_bpp == 24)
@@ -813,12 +852,12 @@ static void decode_bgr_bitstream(HYuvContext *s, int count)
}
}
-static void draw_slice(HYuvContext *s, AVFrame *frame, int y)
+static void draw_slice(HYuvDecContext *s, AVCodecContext *avctx, AVFrame *frame, int y)
{
int h, cy, i;
int offset[AV_NUM_DATA_POINTERS];
- if (!s->avctx->draw_horiz_band)
+ if (!avctx->draw_horiz_band)
return;
h = y - s->last_slice_end;
@@ -836,12 +875,12 @@ static void draw_slice(HYuvContext *s, AVFrame *frame, int y)
offset[i] = 0;
emms_c();
- s->avctx->draw_horiz_band(s->avctx, frame, offset, y, 3, h);
+ avctx->draw_horiz_band(avctx, frame, offset, y, 3, h);
s->last_slice_end = y + h;
}
-static int left_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src, int w, int acc)
+static int left_prediction(HYuvDecContext *s, uint8_t *dst, const uint8_t *src, int w, int acc)
{
if (s->bps <= 8) {
return s->llviddsp.add_left_pred(dst, src, w, acc);
@@ -850,7 +889,7 @@ static int left_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src, int
}
}
-static void add_bytes(HYuvContext *s, uint8_t *dst, uint8_t *src, int w)
+static void add_bytes(HYuvDecContext *s, uint8_t *dst, uint8_t *src, int w)
{
if (s->bps <= 8) {
s->llviddsp.add_bytes(dst, src, w);
@@ -859,7 +898,7 @@ static void add_bytes(HYuvContext *s, uint8_t *dst, uint8_t *src, int w)
}
}
-static void add_median_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src, const uint8_t *diff, int w, int *left, int *left_top)
+static void add_median_prediction(HYuvDecContext *s, uint8_t *dst, const uint8_t *src, const uint8_t *diff, int w, int *left, int *left_top)
{
if (s->bps <= 8) {
s->llviddsp.add_median_pred(dst, src, diff, w, left, left_top);
@@ -871,10 +910,10 @@ static void add_median_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *s
static int decode_slice(AVCodecContext *avctx, AVFrame *p, int height,
int buf_size, int y_offset, int table_size)
{
- HYuvContext *s = avctx->priv_data;
+ HYuvDecContext *s = avctx->priv_data;
int fake_ystride, fake_ustride, fake_vstride;
- const int width = s->width;
- const int width2 = s->width >> 1;
+ const int width = avctx->width;
+ const int width2 = avctx->width >> 1;
int ret;
if ((ret = init_get_bits8(&s->gb, s->bitstream_buffer + table_size, buf_size - table_size)) < 0)
@@ -952,7 +991,7 @@ static int decode_slice(AVCodecContext *avctx, AVFrame *p, int height,
break;
}
}
- draw_slice(s, p, height);
+ draw_slice(s, avctx, p, height);
} else if (s->bitstream_bpp < 24) {
int y, cy;
int lefty, leftu, leftv;
@@ -1006,7 +1045,7 @@ static int decode_slice(AVCodecContext *avctx, AVFrame *p, int height,
break;
}
- draw_slice(s, p, y);
+ draw_slice(s, avctx, p, y);
ydst = p->data[0] + p->linesize[0] * (y + y_offset);
udst = p->data[1] + p->linesize[1] * (cy + y_offset);
@@ -1029,7 +1068,7 @@ static int decode_slice(AVCodecContext *avctx, AVFrame *p, int height,
}
}
}
- draw_slice(s, p, height);
+ draw_slice(s, avctx, p, height);
break;
case MEDIAN:
@@ -1100,7 +1139,7 @@ static int decode_slice(AVCodecContext *avctx, AVFrame *p, int height,
if (y >= height)
break;
}
- draw_slice(s, p, y);
+ draw_slice(s, avctx, p, y);
decode_422_bitstream(s, width);
@@ -1117,7 +1156,7 @@ static int decode_slice(AVCodecContext *avctx, AVFrame *p, int height,
}
}
- draw_slice(s, p, height);
+ draw_slice(s, avctx, p, height);
break;
}
}
@@ -1163,7 +1202,7 @@ static int decode_slice(AVCodecContext *avctx, AVFrame *p, int height,
}
}
// just 1 large slice as this is not possible in reverse order
- draw_slice(s, p, height);
+ draw_slice(s, avctx, p, height);
break;
default:
av_log(avctx, AV_LOG_ERROR,
@@ -1184,9 +1223,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- HYuvContext *s = avctx->priv_data;
- const int width = s->width;
- const int height = s->height;
+ HYuvDecContext *s = avctx->priv_data;
+ const int width = avctx->width;
+ const int height = avctx->height;
int slice, table_size = 0, ret, nb_slices;
unsigned slices_info_offset;
int slice_height;
@@ -1264,46 +1303,46 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
const FFCodec ff_huffyuv_decoder = {
.p.name = "huffyuv",
- .p.long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
+ CODEC_LONG_NAME("Huffyuv / HuffYUV"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_HUFFYUV,
- .priv_data_size = sizeof(HYuvContext),
+ .priv_data_size = sizeof(HYuvDecContext),
.init = decode_init,
.close = decode_end,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
AV_CODEC_CAP_FRAME_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
#if CONFIG_FFVHUFF_DECODER
const FFCodec ff_ffvhuff_decoder = {
.p.name = "ffvhuff",
- .p.long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
+ CODEC_LONG_NAME("Huffyuv FFmpeg variant"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FFVHUFF,
- .priv_data_size = sizeof(HYuvContext),
+ .priv_data_size = sizeof(HYuvDecContext),
.init = decode_init,
.close = decode_end,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
AV_CODEC_CAP_FRAME_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
#endif /* CONFIG_FFVHUFF_DECODER */
#if CONFIG_HYMT_DECODER
const FFCodec ff_hymt_decoder = {
.p.name = "hymt",
- .p.long_name = NULL_IF_CONFIG_SMALL("HuffYUV MT"),
+ CODEC_LONG_NAME("HuffYUV MT"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_HYMT,
- .priv_data_size = sizeof(HYuvContext),
+ .priv_data_size = sizeof(HYuvDecContext),
.init = decode_init,
.close = decode_end,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
AV_CODEC_CAP_FRAME_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
#endif /* CONFIG_HYMT_DECODER */
diff --git a/libavcodec/huffyuvdsp.c b/libavcodec/huffyuvdsp.c
index 10723b2fc..fb98836cc 100644
--- a/libavcodec/huffyuvdsp.c
+++ b/libavcodec/huffyuvdsp.c
@@ -21,6 +21,7 @@
#include "config.h"
#include "libavutil/attributes.h"
#include "mathops.h"
+#include "huffyuv.h"
#include "huffyuvdsp.h"
// 0x00010001 or 0x0001000100010001 or whatever, depending on the cpu's native arithmetic size
diff --git a/libavcodec/huffyuvdsp.h b/libavcodec/huffyuvdsp.h
index e5f5b0546..90e50b542 100644
--- a/libavcodec/huffyuvdsp.h
+++ b/libavcodec/huffyuvdsp.h
@@ -21,19 +21,6 @@
#include
#include "libavutil/pixfmt.h"
-#include "config.h"
-
-#if HAVE_BIGENDIAN
-#define B 3
-#define G 2
-#define R 1
-#define A 0
-#else
-#define B 0
-#define G 1
-#define R 2
-#define A 3
-#endif
typedef struct HuffYUVDSPContext {
void (*add_int16)(uint16_t *dst/*align 16*/, const uint16_t *src/*align 16*/,
diff --git a/libavcodec/huffyuvenc.c b/libavcodec/huffyuvenc.c
index 195d45c91..72d6246eb 100644
--- a/libavcodec/huffyuvenc.c
+++ b/libavcodec/huffyuvenc.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2002-2014 Michael Niedermayer
*
- * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
+ * see https://multimedia.cx/huffyuv.txt for a description of
* the algorithm used
*
* This file is part of FFmpeg.
@@ -31,6 +31,7 @@
#include "config_components.h"
#include "avcodec.h"
+#include "bswapdsp.h"
#include "codec_internal.h"
#include "encode.h"
#include "huffyuv.h"
@@ -41,7 +42,39 @@
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
-static inline void diff_bytes(HYuvContext *s, uint8_t *dst,
+typedef struct HYuvEncContext {
+ AVClass *class;
+ AVCodecContext *avctx;
+ PutBitContext pb;
+ Predictor predictor;
+ int interlaced;
+ int decorrelate;
+ int bitstream_bpp;
+ int version;
+ int bps;
+ int n; // 1<bps <= 8) {
@@ -51,7 +84,7 @@ static inline void diff_bytes(HYuvContext *s, uint8_t *dst,
}
}
-static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst,
+static inline int sub_left_prediction(HYuvEncContext *s, uint8_t *dst,
const uint8_t *src, int w, int left)
{
int i;
@@ -82,7 +115,7 @@ static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst,
}
}
-static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst,
+static inline void sub_left_prediction_bgr32(HYuvEncContext *s, uint8_t *dst,
const uint8_t *src, int w,
int *red, int *green, int *blue,
int *alpha)
@@ -118,8 +151,8 @@ static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst,
*alpha = src[(w - 1) * 4 + A];
}
-static inline void sub_left_prediction_rgb24(HYuvContext *s, uint8_t *dst,
- uint8_t *src, int w,
+static inline void sub_left_prediction_rgb24(HYuvEncContext *s, uint8_t *dst,
+ const uint8_t *src, int w,
int *red, int *green, int *blue)
{
int i;
@@ -146,7 +179,9 @@ static inline void sub_left_prediction_rgb24(HYuvContext *s, uint8_t *dst,
*blue = src[(w - 1) * 3 + 2];
}
-static void sub_median_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int w, int *left, int *left_top)
+static void sub_median_prediction(HYuvEncContext *s, uint8_t *dst,
+ const uint8_t *src1, const uint8_t *src2,
+ int w, int *left, int *left_top)
{
if (s->bps <= 8) {
s->llvidencdsp.sub_median_pred(dst, src1, src2, w , left, left_top);
@@ -155,7 +190,7 @@ static void sub_median_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *s
}
}
-static int store_table(HYuvContext *s, const uint8_t *len, uint8_t *buf)
+static int store_table(HYuvEncContext *s, const uint8_t *len, uint8_t *buf)
{
int i;
int index = 0;
@@ -180,7 +215,7 @@ static int store_table(HYuvContext *s, const uint8_t *len, uint8_t *buf)
return index;
}
-static int store_huffman_tables(HYuvContext *s, uint8_t *buf)
+static int store_huffman_tables(HYuvEncContext *s, uint8_t *buf)
{
int i, ret;
int size = 0;
@@ -204,16 +239,21 @@ static int store_huffman_tables(HYuvContext *s, uint8_t *buf)
static av_cold int encode_init(AVCodecContext *avctx)
{
- HYuvContext *s = avctx->priv_data;
+ HYuvEncContext *s = avctx->priv_data;
int i, j;
int ret;
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+ const AVPixFmtDescriptor *desc;
- ff_huffyuv_common_init(avctx);
- ff_huffyuvencdsp_init(&s->hencdsp, avctx);
+ s->avctx = avctx;
+ s->flags = avctx->flags;
+
+ ff_bswapdsp_init(&s->bdsp);
+ ff_huffyuvencdsp_init(&s->hencdsp, avctx->pix_fmt);
ff_llvidencdsp_init(&s->llvidencdsp);
avctx->extradata = av_mallocz(3*MAX_N + 4);
+ if (!avctx->extradata)
+ return AVERROR(ENOMEM);
if (s->flags&AV_CODEC_FLAG_PASS1) {
#define STATS_OUT_SIZE 21*MAX_N*3 + 4
avctx->stats_out = av_mallocz(STATS_OUT_SIZE); // 21*256*3(%llu ) + 3(\n) + 1(0) = 16132
@@ -222,21 +262,18 @@ static av_cold int encode_init(AVCodecContext *avctx)
}
s->version = 2;
- if (!avctx->extradata)
- return AVERROR(ENOMEM);
-
+ desc = av_pix_fmt_desc_get(avctx->pix_fmt);
s->bps = desc->comp[0].depth;
s->yuv = !(desc->flags & AV_PIX_FMT_FLAG_RGB) && desc->nb_components >= 2;
s->chroma = desc->nb_components > 2;
s->alpha = !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA);
- av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt,
- &s->chroma_h_shift,
- &s->chroma_v_shift);
+ s->chroma_h_shift = desc->log2_chroma_w;
+ s->chroma_v_shift = desc->log2_chroma_h;
switch (avctx->pix_fmt) {
case AV_PIX_FMT_YUV420P:
case AV_PIX_FMT_YUV422P:
- if (s->width & 1) {
+ if (avctx->width & 1) {
av_log(avctx, AV_LOG_ERROR, "Width must be even for this colorspace.\n");
return AVERROR(EINVAL);
}
@@ -310,13 +347,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
}
if (avctx->codec->id == AV_CODEC_ID_HUFFYUV) {
- if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
- av_log(avctx, AV_LOG_ERROR,
- "Error: YV12 is not supported by huffyuv; use "
- "vcodec=ffvhuff or format=422p\n");
- return AVERROR(EINVAL);
- }
- if (s->interlaced != ( s->height > 288 ))
+ if (s->interlaced != ( avctx->height > 288 ))
av_log(avctx, AV_LOG_INFO,
"using huffyuv 2.2.0 or newer interlacing flag\n");
}
@@ -333,22 +364,22 @@ static av_cold int encode_init(AVCodecContext *avctx)
return AVERROR(EINVAL);
}
- ((uint8_t*)avctx->extradata)[0] = s->predictor | (s->decorrelate << 6);
- ((uint8_t*)avctx->extradata)[2] = s->interlaced ? 0x10 : 0x20;
+ avctx->extradata[0] = s->predictor | (s->decorrelate << 6);
+ avctx->extradata[2] = s->interlaced ? 0x10 : 0x20;
if (s->context)
- ((uint8_t*)avctx->extradata)[2] |= 0x40;
+ avctx->extradata[2] |= 0x40;
if (s->version < 3) {
- ((uint8_t*)avctx->extradata)[1] = s->bitstream_bpp;
- ((uint8_t*)avctx->extradata)[3] = 0;
+ avctx->extradata[1] = s->bitstream_bpp;
+ avctx->extradata[3] = 0;
} else {
- ((uint8_t*)avctx->extradata)[1] = ((s->bps-1)<<4) | s->chroma_h_shift | (s->chroma_v_shift<<2);
+ avctx->extradata[1] = ((s->bps-1)<<4) | s->chroma_h_shift | (s->chroma_v_shift<<2);
if (s->chroma)
- ((uint8_t*)avctx->extradata)[2] |= s->yuv ? 1 : 2;
+ avctx->extradata[2] |= s->yuv ? 1 : 2;
if (s->alpha)
- ((uint8_t*)avctx->extradata)[2] |= 4;
- ((uint8_t*)avctx->extradata)[3] = 1;
+ avctx->extradata[2] |= 4;
+ avctx->extradata[3] = 1;
}
- s->avctx->extradata_size = 4;
+ avctx->extradata_size = 4;
if (avctx->stats_in) {
char *p = avctx->stats_in;
@@ -378,14 +409,14 @@ static av_cold int encode_init(AVCodecContext *avctx)
}
}
- ret = store_huffman_tables(s, s->avctx->extradata + s->avctx->extradata_size);
+ ret = store_huffman_tables(s, avctx->extradata + avctx->extradata_size);
if (ret < 0)
return ret;
- s->avctx->extradata_size += ret;
+ avctx->extradata_size += ret;
if (s->context) {
for (i = 0; i < 4; i++) {
- int pels = s->width * s->height / (i ? 40 : 10);
+ int pels = avctx->width * avctx->height / (i ? 40 : 10);
for (j = 0; j < s->vlc_n; j++) {
int d = FFMIN(j, s->vlc_n - j);
s->stats[i][j] = pels/(d*d + 1);
@@ -397,16 +428,15 @@ static av_cold int encode_init(AVCodecContext *avctx)
s->stats[i][j]= 0;
}
- if (ff_huffyuv_alloc_temp(s)) {
- ff_huffyuv_common_end(s);
- return AVERROR(ENOMEM);
- }
+ ret = ff_huffyuv_alloc_temp(s->temp, s->temp16, avctx->width);
+ if (ret < 0)
+ return ret;
s->picture_number=0;
return 0;
}
-static int encode_422_bitstream(HYuvContext *s, int offset, int count)
+static int encode_422_bitstream(HYuvEncContext *s, int offset, int count)
{
int i;
const uint8_t *y = s->temp[0] + offset;
@@ -461,7 +491,7 @@ static int encode_422_bitstream(HYuvContext *s, int offset, int count)
return 0;
}
-static int encode_plane_bitstream(HYuvContext *s, int width, int plane)
+static int encode_plane_bitstream(HYuvEncContext *s, int width, int plane)
{
int i, count = width/2;
@@ -623,7 +653,7 @@ static int encode_plane_bitstream(HYuvContext *s, int width, int plane)
return 0;
}
-static int encode_gray_bitstream(HYuvContext *s, int count)
+static int encode_gray_bitstream(HYuvEncContext *s, int count)
{
int i;
@@ -668,7 +698,7 @@ static int encode_gray_bitstream(HYuvContext *s, int count)
return 0;
}
-static inline int encode_bgra_bitstream(HYuvContext *s, int count, int planes)
+static inline int encode_bgra_bitstream(HYuvEncContext *s, int count, int planes)
{
int i;
@@ -721,10 +751,10 @@ static inline int encode_bgra_bitstream(HYuvContext *s, int count, int planes)
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *pict, int *got_packet)
{
- HYuvContext *s = avctx->priv_data;
- const int width = s->width;
- const int width2 = s->width>>1;
- const int height = s->height;
+ HYuvEncContext *s = avctx->priv_data;
+ const int width = avctx->width;
+ const int width2 = avctx->width >> 1;
+ const int height = avctx->height;
const int fake_ystride = s->interlaced ? pict->linesize[0]*2 : pict->linesize[0];
const int fake_ustride = s->interlaced ? pict->linesize[1]*2 : pict->linesize[1];
const int fake_vstride = s->interlaced ? pict->linesize[2]*2 : pict->linesize[2];
@@ -789,7 +819,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
y++; cy++;
for (; y < height; y++,cy++) {
- uint8_t *ydst, *udst, *vdst;
+ const uint8_t *ydst, *udst, *vdst;
if (s->bitstream_bpp == 12) {
while (2 * cy > y) {
@@ -812,7 +842,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
}
} else {
for (cy = y = 1; y < height; y++, cy++) {
- uint8_t *ydst, *udst, *vdst;
+ const uint8_t *ydst, *udst, *vdst;
/* encode a luma only line & y++ */
if (s->bitstream_bpp == 12) {
@@ -852,10 +882,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
}
}
} else if(avctx->pix_fmt == AV_PIX_FMT_RGB32) {
- uint8_t *data = p->data[0] + (height - 1) * p->linesize[0];
+ const uint8_t *data = p->data[0] + (height - 1) * p->linesize[0];
const int stride = -p->linesize[0];
const int fake_stride = -fake_ystride;
- int y;
int leftr, leftg, leftb, lefta;
put_bits(&s->pb, 8, lefta = data[A]);
@@ -867,8 +896,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
&leftr, &leftg, &leftb, &lefta);
encode_bgra_bitstream(s, width - 1, 4);
- for (y = 1; y < s->height; y++) {
- uint8_t *dst = data + y*stride;
+ for (int y = 1; y < height; y++) {
+ const uint8_t *dst = data + y*stride;
if (s->predictor == PLANE && s->interlaced < y) {
s->llvidencdsp.diff_bytes(s->temp[1], dst, dst - fake_stride, width * 4);
sub_left_prediction_bgr32(s, s->temp[0], s->temp[1], width,
@@ -880,10 +909,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
encode_bgra_bitstream(s, width, 4);
}
} else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {
- uint8_t *data = p->data[0] + (height - 1) * p->linesize[0];
+ const uint8_t *data = p->data[0] + (height - 1) * p->linesize[0];
const int stride = -p->linesize[0];
const int fake_stride = -fake_ystride;
- int y;
int leftr, leftg, leftb;
put_bits(&s->pb, 8, leftr = data[0]);
@@ -895,8 +923,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
&leftr, &leftg, &leftb);
encode_bgra_bitstream(s, width-1, 3);
- for (y = 1; y < s->height; y++) {
- uint8_t *dst = data + y * stride;
+ for (int y = 1; y < height; y++) {
+ const uint8_t *dst = data + y * stride;
if (s->predictor == PLANE && s->interlaced < y) {
s->llvidencdsp.diff_bytes(s->temp[1], dst, dst - fake_stride,
width * 3);
@@ -939,7 +967,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
lefttop = p->data[plane][0];
for (; y < h; y++) {
- uint8_t *dst = p->data[plane] + p->linesize[plane] * y;
+ const uint8_t *dst = p->data[plane] + p->linesize[plane] * y;
sub_median_prediction(s, s->temp[0], dst - fake_stride, dst, w , &left, &lefttop);
@@ -947,7 +975,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
}
} else {
for (y = 1; y < h; y++) {
- uint8_t *dst = p->data[plane] + p->linesize[plane] * y;
+ const uint8_t *dst = p->data[plane] + p->linesize[plane] * y;
if (s->predictor == PLANE && s->interlaced < y) {
diff_bytes(s, s->temp[1], dst, dst - fake_stride, w);
@@ -1003,16 +1031,16 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
static av_cold int encode_end(AVCodecContext *avctx)
{
- HYuvContext *s = avctx->priv_data;
+ HYuvEncContext *s = avctx->priv_data;
- ff_huffyuv_common_end(s);
+ ff_huffyuv_common_end(s->temp, s->temp16);
av_freep(&avctx->stats_out);
return 0;
}
-#define OFFSET(x) offsetof(HYuvContext, x)
+#define OFFSET(x) offsetof(HYuvEncContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
#define COMMON_OPTIONS \
@@ -1051,34 +1079,35 @@ static const AVClass ff_class = {
const FFCodec ff_huffyuv_encoder = {
.p.name = "huffyuv",
- .p.long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
+ CODEC_LONG_NAME("Huffyuv / HuffYUV"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_HUFFYUV,
- .priv_data_size = sizeof(HYuvContext),
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ .priv_data_size = sizeof(HYuvEncContext),
.init = encode_init,
FF_CODEC_ENCODE_CB(encode_frame),
.close = encode_end,
- .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
.p.priv_class = &normal_class,
.p.pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24,
AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
},
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
#if CONFIG_FFVHUFF_ENCODER
const FFCodec ff_ffvhuff_encoder = {
.p.name = "ffvhuff",
- .p.long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
+ CODEC_LONG_NAME("Huffyuv FFmpeg variant"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_FFVHUFF,
- .priv_data_size = sizeof(HYuvContext),
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ .priv_data_size = sizeof(HYuvEncContext),
.init = encode_init,
FF_CODEC_ENCODE_CB(encode_frame),
.close = encode_end,
- .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
.p.priv_class = &ff_class,
.p.pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV411P,
@@ -1097,7 +1126,6 @@ const FFCodec ff_ffvhuff_encoder = {
AV_PIX_FMT_RGB24,
AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
},
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
#endif
diff --git a/libavcodec/huffyuvencdsp.c b/libavcodec/huffyuvencdsp.c
index ea1ef911b..36e8f6130 100644
--- a/libavcodec/huffyuvencdsp.c
+++ b/libavcodec/huffyuvencdsp.c
@@ -68,12 +68,12 @@ static void sub_hfyu_median_pred_int16_c(uint16_t *dst, const uint16_t *src1, co
*left_top = lt;
}
-av_cold void ff_huffyuvencdsp_init(HuffYUVEncDSPContext *c, AVCodecContext *avctx)
+av_cold void ff_huffyuvencdsp_init(HuffYUVEncDSPContext *c, enum AVPixelFormat pix_fmt)
{
c->diff_int16 = diff_int16_c;
c->sub_hfyu_median_pred_int16 = sub_hfyu_median_pred_int16_c;
#if ARCH_X86
- ff_huffyuvencdsp_init_x86(c, avctx);
+ ff_huffyuvencdsp_init_x86(c, pix_fmt);
#endif
}
diff --git a/libavcodec/huffyuvencdsp.h b/libavcodec/huffyuvencdsp.h
index 603f9c8c2..779a51ac7 100644
--- a/libavcodec/huffyuvencdsp.h
+++ b/libavcodec/huffyuvencdsp.h
@@ -21,7 +21,7 @@
#include
-#include "avcodec.h"
+#include "libavutil/pixfmt.h"
typedef struct HuffYUVEncDSPContext {
void (*diff_int16)(uint16_t *dst /* align 16 */,
@@ -34,7 +34,7 @@ typedef struct HuffYUVEncDSPContext {
int w, int *left, int *left_top);
} HuffYUVEncDSPContext;
-void ff_huffyuvencdsp_init(HuffYUVEncDSPContext *c, AVCodecContext *avctx);
-void ff_huffyuvencdsp_init_x86(HuffYUVEncDSPContext *c, AVCodecContext *avctx);
+void ff_huffyuvencdsp_init(HuffYUVEncDSPContext *c, enum AVPixelFormat pix_fmt);
+void ff_huffyuvencdsp_init_x86(HuffYUVEncDSPContext *c, enum AVPixelFormat pix_fmt);
#endif /* AVCODEC_HUFFYUVENCDSP_H */
diff --git a/libavcodec/idcinvideo.c b/libavcodec/idcinvideo.c
index ecd4ab2fe..f6b8b3cd6 100644
--- a/libavcodec/idcinvideo.c
+++ b/libavcodec/idcinvideo.c
@@ -44,14 +44,12 @@
* decoding algorithm and it worked fine on much lower spec machines.
*/
-#include
-#include
+#include
#include
#include "avcodec.h"
#include "codec_internal.h"
#include "decode.h"
-#include "internal.h"
#include "libavutil/internal.h"
#define HUFFMAN_TABLE_SIZE 64 * 1024
@@ -243,7 +241,7 @@ static const FFCodecDefault idcin_defaults[] = {
const FFCodec ff_idcin_decoder = {
.p.name = "idcinvideo",
- .p.long_name = NULL_IF_CONFIG_SMALL("id Quake II CIN video"),
+ CODEC_LONG_NAME("id Quake II CIN video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_IDCIN,
.priv_data_size = sizeof(IdcinContext),
@@ -251,5 +249,4 @@ const FFCodec ff_idcin_decoder = {
FF_CODEC_DECODE_CB(idcin_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
.defaults = idcin_defaults,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/idctdsp.c b/libavcodec/idctdsp.c
index 9035003b7..7216afb09 100644
--- a/libavcodec/idctdsp.c
+++ b/libavcodec/idctdsp.c
@@ -27,24 +27,12 @@
#include "simple_idct.h"
#include "xvididct.h"
-av_cold void ff_init_scantable(const uint8_t *permutation, ScanTable *st,
- const uint8_t *src_scantable)
+av_cold void ff_permute_scantable(uint8_t dst[64], const uint8_t src[64],
+ const uint8_t permutation[64])
{
- int i, end;
-
- st->scantable = src_scantable;
-
- for (i = 0; i < 64; i++) {
- int j = src_scantable[i];
- st->permutated[i] = permutation[j];
- }
-
- end = -1;
- for (i = 0; i < 64; i++) {
- int j = st->permutated[i];
- if (j > end)
- end = j;
- st->raster_end[i] = end;
+ for (int i = 0; i < 64; i++) {
+ int j = src[i];
+ dst[i] = permutation[j];
}
}
@@ -312,6 +300,8 @@ av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx)
ff_idctdsp_init_arm(c, avctx, high_bit_depth);
#elif ARCH_PPC
ff_idctdsp_init_ppc(c, avctx, high_bit_depth);
+#elif ARCH_RISCV
+ ff_idctdsp_init_riscv(c, avctx, high_bit_depth);
#elif ARCH_X86
ff_idctdsp_init_x86(c, avctx, high_bit_depth);
#elif ARCH_MIPS
diff --git a/libavcodec/idctdsp.h b/libavcodec/idctdsp.h
index e8f20acaf..722446334 100644
--- a/libavcodec/idctdsp.h
+++ b/libavcodec/idctdsp.h
@@ -25,15 +25,6 @@
#include "avcodec.h"
-/**
- * Scantable.
- */
-typedef struct ScanTable {
- const uint8_t *scantable;
- uint8_t permutated[64];
- uint8_t raster_end[64];
-} ScanTable;
-
enum idct_permutation_type {
FF_IDCT_PERM_NONE,
FF_IDCT_PERM_LIBMPEG2,
@@ -43,8 +34,8 @@ enum idct_permutation_type {
FF_IDCT_PERM_SSE2,
};
-void ff_init_scantable(const uint8_t *permutation, ScanTable *st,
- const uint8_t *src_scantable);
+void ff_permute_scantable(uint8_t dst[64], const uint8_t src[64],
+ const uint8_t permutation[64]);
void ff_init_scantable_permutation(uint8_t *idct_permutation,
enum idct_permutation_type perm_type);
int ff_init_scantable_permutation_x86(uint8_t *idct_permutation,
@@ -114,6 +105,8 @@ void ff_idctdsp_init_arm(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
void ff_idctdsp_init_ppc(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
+void ff_idctdsp_init_riscv(IDCTDSPContext *c, AVCodecContext *avctx,
+ unsigned high_bit_depth);
void ff_idctdsp_init_x86(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
void ff_idctdsp_init_mips(IDCTDSPContext *c, AVCodecContext *avctx,
diff --git a/libavcodec/iff.c b/libavcodec/iff.c
index 74ebddc62..e02d2e77e 100644
--- a/libavcodec/iff.c
+++ b/libavcodec/iff.c
@@ -33,8 +33,7 @@
#include "bytestream.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
-#include "mathops.h"
+#include "decode.h"
// TODO: masking bits
typedef enum {
@@ -45,7 +44,6 @@ typedef enum {
} mask_type;
typedef struct IffContext {
- AVFrame *frame;
int planesize;
uint8_t * planebuf;
uint8_t * ham_buf; ///< temporary buffer for planar to chunky conversation
@@ -63,7 +61,6 @@ typedef struct IffContext {
unsigned masking; ///< TODO: masking method used
int init; // 1 if buffer and palette data already initialized, 0 otherwise
int16_t tvdc[16]; ///< TVDC lookup table
- GetByteContext gb;
uint8_t *video[2];
unsigned video_size;
uint32_t *pal;
@@ -154,9 +151,10 @@ static av_always_inline uint32_t gray2rgb(const uint32_t x) {
static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
{
IffContext *s = avctx->priv_data;
- int count, i;
+ unsigned count, i;
const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
- int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
+ /* extract_header() already checked that the RHS is >= 0. */
+ unsigned palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
if (avctx->bits_per_coded_sample > 8) {
av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
@@ -199,183 +197,123 @@ static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
* decoder structures.
*
* @param avctx the AVCodecContext where to extract extra context to
- * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
* @return >= 0 in case of success, a negative error code otherwise
*/
static int extract_header(AVCodecContext *const avctx,
- const AVPacket *const avpkt)
+ const uint8_t *const extradata, int extradata_size)
{
IffContext *s = avctx->priv_data;
- const uint8_t *buf;
+ const uint8_t *buf = extradata;
unsigned buf_size = 0;
- int i, palette_size;
+ int palette_size;
- if (avctx->extradata_size < 2) {
+ if (extradata_size < 2) {
av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
return AVERROR_INVALIDDATA;
}
- palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
+ palette_size = extradata_size - AV_RB16(extradata);
- if (avpkt && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
- uint32_t chunk_id;
- uint64_t data_size;
- GetByteContext *gb = &s->gb;
+ buf_size = bytestream_get_be16(&buf);
+ if (buf_size <= 1 || palette_size < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid palette size received: %u -> palette data offset: %d\n",
+ buf_size, palette_size);
+ return AVERROR_INVALIDDATA;
+ }
- bytestream2_skip(gb, 4);
- while (bytestream2_get_bytes_left(gb) >= 1) {
- chunk_id = bytestream2_get_le32(gb);
- data_size = bytestream2_get_be32(gb);
+ if (buf_size < 41)
+ return 0;
- if (chunk_id == MKTAG('B', 'M', 'H', 'D')) {
- bytestream2_skip(gb, data_size + (data_size & 1));
- } else if (chunk_id == MKTAG('A', 'N', 'H', 'D')) {
- unsigned extra;
- if (data_size < 40)
- return AVERROR_INVALIDDATA;
+ s->compression = bytestream_get_byte(&buf);
+ s->bpp = bytestream_get_byte(&buf);
+ s->ham = bytestream_get_byte(&buf);
+ s->flags = bytestream_get_byte(&buf);
+ s->transparency = bytestream_get_be16(&buf);
+ s->masking = bytestream_get_byte(&buf);
+ for (int i = 0; i < 16; i++)
+ s->tvdc[i] = bytestream_get_be16(&buf);
- s->compression = (bytestream2_get_byte(gb) << 8) | (s->compression & 0xFF);
- bytestream2_skip(gb, 19);
- extra = bytestream2_get_be32(gb);
- s->is_short = !(extra & 1);
- s->is_brush = extra == 2;
- s->is_interlaced = !!(extra & 0x40);
- data_size -= 24;
- bytestream2_skip(gb, data_size + (data_size & 1));
- } else if (chunk_id == MKTAG('D', 'L', 'T', 'A') ||
- chunk_id == MKTAG('B', 'O', 'D', 'Y')) {
- if (chunk_id == MKTAG('B','O','D','Y'))
- s->compression &= 0xFF;
- break;
- } else if (chunk_id == MKTAG('C', 'M', 'A', 'P')) {
- int count = data_size / 3;
- uint32_t *pal = s->pal;
-
- if (count > 256)
- return AVERROR_INVALIDDATA;
- if (s->ham) {
- for (i = 0; i < count; i++)
- pal[i] = 0xFF000000 | bytestream2_get_le24(gb);
- } else {
- for (i = 0; i < count; i++)
- pal[i] = 0xFF000000 | bytestream2_get_be24(gb);
- }
- bytestream2_skip(gb, data_size & 1);
- } else {
- bytestream2_skip(gb, data_size + (data_size&1));
- }
- }
- } else if (!avpkt) {
- buf = avctx->extradata;
- buf_size = bytestream_get_be16(&buf);
- if (buf_size <= 1 || palette_size < 0) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid palette size received: %u -> palette data offset: %d\n",
- buf_size, palette_size);
+ if (s->ham) {
+ if (s->bpp > 8) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
+ return AVERROR_INVALIDDATA;
+ } else if (s->ham != (s->bpp > 6 ? 6 : 4)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u, BPP: %u\n", s->ham, s->bpp);
return AVERROR_INVALIDDATA;
}
}
- if (buf_size >= 41) {
- s->compression = bytestream_get_byte(&buf);
- s->bpp = bytestream_get_byte(&buf);
- s->ham = bytestream_get_byte(&buf);
- s->flags = bytestream_get_byte(&buf);
- s->transparency = bytestream_get_be16(&buf);
- s->masking = bytestream_get_byte(&buf);
- for (i = 0; i < 16; i++)
- s->tvdc[i] = bytestream_get_be16(&buf);
+ if (s->masking == MASK_HAS_MASK) {
+ if (s->bpp >= 8 && !s->ham) {
+ avctx->pix_fmt = AV_PIX_FMT_RGB32;
+ if (s->bpp > 16) {
+ av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
+ return AVERROR(ENOMEM);
+ }
+ s->mask_buf = av_malloc((s->planesize * 32) + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!s->mask_buf)
+ return AVERROR(ENOMEM);
+ s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!s->mask_palbuf)
+ return AVERROR(ENOMEM);
+ }
+ s->bpp++;
+ } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
+ av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
+ return AVERROR_PATCHWELCOME;
+ }
+ if (!s->bpp || s->bpp > 32) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->video_size && s->planesize * s->bpp * avctx->height > s->video_size)
+ return AVERROR_INVALIDDATA;
- if (s->ham) {
- if (s->bpp > 8) {
- av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
- return AVERROR_INVALIDDATA;
- } else if (s->ham != (s->bpp > 6 ? 6 : 4)) {
- av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u, BPP: %u\n", s->ham, s->bpp);
- return AVERROR_INVALIDDATA;
+ if (s->ham) {
+ int count = FFMIN(palette_size / 3, 1 << s->ham);
+ int ham_count;
+ const uint8_t *const palette = extradata + AV_RB16(extradata);
+ int extra_space = 1;
+
+ if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ') && s->ham == 4)
+ extra_space = 4;
+
+ s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!s->ham_buf)
+ return AVERROR(ENOMEM);
+
+ ham_count = 8 * (1 << s->ham);
+ s->ham_palbuf = av_malloc(extra_space * (ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!s->ham_palbuf)
+ return AVERROR(ENOMEM);
+
+ if (count) { // HAM with color palette attached
+ // prefill with black and palette and set HAM take direct value mask to zero
+ memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
+ for (int i = 0; i < count; i++) {
+ s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
+ }
+ count = 1 << s->ham;
+ } else { // HAM with grayscale color palette
+ count = 1 << s->ham;
+ for (int i = 0; i < count; i++) {
+ s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
+ s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
}
}
-
+ for (int i = 0; i < count; i++) {
+ uint32_t tmp = i << (8 - s->ham);
+ tmp |= tmp >> s->ham;
+ s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
+ s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
+ s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
+ s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
+ s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
+ s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
+ }
if (s->masking == MASK_HAS_MASK) {
- if (s->bpp >= 8 && !s->ham) {
- avctx->pix_fmt = AV_PIX_FMT_RGB32;
- av_freep(&s->mask_buf);
- av_freep(&s->mask_palbuf);
- if (s->bpp > 16) {
- av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
- return AVERROR(ENOMEM);
- }
- s->mask_buf = av_malloc((s->planesize * 32) + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!s->mask_buf)
- return AVERROR(ENOMEM);
- s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!s->mask_palbuf) {
- av_freep(&s->mask_buf);
- return AVERROR(ENOMEM);
- }
- }
- s->bpp++;
- } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
- av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
- return AVERROR_PATCHWELCOME;
- }
- if (!s->bpp || s->bpp > 32) {
- av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
- return AVERROR_INVALIDDATA;
- }
- if (s->video_size && s->planesize * s->bpp * avctx->height > s->video_size)
- return AVERROR_INVALIDDATA;
-
- av_freep(&s->ham_buf);
- av_freep(&s->ham_palbuf);
-
- if (s->ham) {
- int i, count = FFMIN(palette_size / 3, 1 << s->ham);
- int ham_count;
- const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
- int extra_space = 1;
-
- if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ') && s->ham == 4)
- extra_space = 4;
-
- s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!s->ham_buf)
- return AVERROR(ENOMEM);
-
- ham_count = 8 * (1 << s->ham);
- s->ham_palbuf = av_malloc(extra_space * (ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!s->ham_palbuf) {
- av_freep(&s->ham_buf);
- return AVERROR(ENOMEM);
- }
-
- if (count) { // HAM with color palette attached
- // prefill with black and palette and set HAM take direct value mask to zero
- memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
- for (i=0; i < count; i++) {
- s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
- }
- count = 1 << s->ham;
- } else { // HAM with grayscale color palette
- count = 1 << s->ham;
- for (i=0; i < count; i++) {
- s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
- s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
- }
- }
- for (i=0; i < count; i++) {
- uint32_t tmp = i << (8 - s->ham);
- tmp |= tmp >> s->ham;
- s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
- s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
- s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
- s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
- s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
- s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
- }
- if (s->masking == MASK_HAS_MASK) {
- for (i = 0; i < ham_count; i++)
- s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
- }
+ for (int i = 0; i < ham_count; i++)
+ s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
}
}
@@ -449,7 +387,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
return AVERROR(ENOMEM);
}
- if ((err = extract_header(avctx, NULL)) < 0)
+ err = extract_header(avctx, avctx->extradata, avctx->extradata_size);
+ if (err < 0)
return err;
return 0;
@@ -1525,6 +1464,61 @@ static int unsupported(AVCodecContext *avctx)
return AVERROR_INVALIDDATA;
}
+static int parse_packet_header(AVCodecContext *const avctx,
+ GetByteContext *gb)
+{
+ IffContext *s = avctx->priv_data;
+
+ if (avctx->codec_tag != MKTAG('A', 'N', 'I', 'M'))
+ return 0;
+
+ bytestream2_skip(gb, 4);
+ while (bytestream2_get_bytes_left(gb) >= 1) {
+ uint32_t chunk_id = bytestream2_get_le32(gb);
+ uint64_t data_size = bytestream2_get_be32(gb);
+
+ if (chunk_id == MKTAG('B', 'M', 'H', 'D')) {
+ bytestream2_skip(gb, data_size + (data_size & 1));
+ } else if (chunk_id == MKTAG('A', 'N', 'H', 'D')) {
+ unsigned extra;
+ if (data_size < 40)
+ return AVERROR_INVALIDDATA;
+
+ s->compression = (bytestream2_get_byte(gb) << 8) | (s->compression & 0xFF);
+ bytestream2_skip(gb, 19);
+ extra = bytestream2_get_be32(gb);
+ s->is_short = !(extra & 1);
+ s->is_brush = extra == 2;
+ s->is_interlaced = !!(extra & 0x40);
+ data_size -= 24;
+ bytestream2_skip(gb, data_size + (data_size & 1));
+ } else if (chunk_id == MKTAG('D', 'L', 'T', 'A') ||
+ chunk_id == MKTAG('B', 'O', 'D', 'Y')) {
+ if (chunk_id == MKTAG('B','O','D','Y'))
+ s->compression &= 0xFF;
+ break;
+ } else if (chunk_id == MKTAG('C', 'M', 'A', 'P')) {
+ int count = data_size / 3;
+ uint32_t *pal = s->pal;
+
+ if (count > 256)
+ return AVERROR_INVALIDDATA;
+ if (s->ham) {
+ for (int i = 0; i < count; i++)
+ pal[i] = 0xFF000000 | bytestream2_get_le24(gb);
+ } else {
+ for (int i = 0; i < count; i++)
+ pal[i] = 0xFF000000 | bytestream2_get_be24(gb);
+ }
+ bytestream2_skip(gb, data_size & 1);
+ } else {
+ bytestream2_skip(gb, data_size + (data_size&1));
+ }
+ }
+
+ return 0;
+}
+
static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
int *got_frame, AVPacket *avpkt)
{
@@ -1533,17 +1527,16 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
int buf_size = avpkt->size;
const uint8_t *buf_end = buf + buf_size;
int y, plane, res;
- GetByteContext *gb = &s->gb;
+ GetByteContext gb0, *const gb = &gb0;
const AVPixFmtDescriptor *desc;
bytestream2_init(gb, avpkt->data, avpkt->size);
- if ((res = extract_header(avctx, avpkt)) < 0)
+ if ((res = parse_packet_header(avctx, gb)) < 0)
return res;
if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
return res;
- s->frame = frame;
buf += bytestream2_tell(gb);
buf_size -= bytestream2_tell(gb);
@@ -1562,7 +1555,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
- memcpy(s->pal, s->frame->data[1], 256 * 4);
+ memcpy(s->pal, frame->data[1], 256 * 4);
}
switch (s->compression) {
@@ -1908,7 +1901,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_iff_ilbm_decoder = {
.p.name = "iff",
- .p.long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
+ CODEC_LONG_NAME("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_IFF_ILBM,
.priv_data_size = sizeof(IffContext),
@@ -1916,5 +1909,5 @@ const FFCodec ff_iff_ilbm_decoder = {
.close = decode_end,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/ilbcdec.c b/libavcodec/ilbcdec.c
index 62a9ad19b..4ecdff418 100644
--- a/libavcodec/ilbcdec.c
+++ b/libavcodec/ilbcdec.c
@@ -33,7 +33,7 @@
#include "libavutil/channel_layout.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "get_bits.h"
#include "ilbcdata.h"
@@ -91,7 +91,6 @@ typedef struct ILBCContext {
int enhancer;
int mode;
- GetBitContext gb;
ILBCFrame frame;
int prev_enh_pl;
@@ -127,11 +126,14 @@ typedef struct ILBCContext {
int16_t hpimemy[4];
} ILBCContext;
-static int unpack_frame(ILBCContext *s)
+static int unpack_frame(ILBCContext *s, const uint8_t *buf, int size)
{
ILBCFrame *frame = &s->frame;
- GetBitContext *gb = &s->gb;
- int j;
+ GetBitContext gb0, *const gb = &gb0;
+ int j, ret;
+
+ if ((ret = init_get_bits8(gb, buf, size)) < 0)
+ return ret;
frame->lsf[0] = get_bits(gb, 6);
frame->lsf[1] = get_bits(gb, 7);
@@ -331,8 +333,8 @@ static void lsf_check_stability(int16_t *lsf, int dim, int nb_vectors)
}
}
-static void lsf_interpolate(int16_t *out, int16_t *in1,
- int16_t *in2, int16_t coef,
+static void lsf_interpolate(int16_t *out, const int16_t *in1,
+ const int16_t *in2, int16_t coef,
int size)
{
int invcoef = 16384 - coef, i;
@@ -341,7 +343,7 @@ static void lsf_interpolate(int16_t *out, int16_t *in1,
out[i] = (coef * in1[i] + invcoef * in2[i] + 8192) >> 14;
}
-static void lsf2lsp(int16_t *lsf, int16_t *lsp, int order)
+static void lsf2lsp(const int16_t *lsf, int16_t *lsp, int order)
{
int16_t diff, freq;
int32_t tmp;
@@ -364,7 +366,7 @@ static void lsf2lsp(int16_t *lsf, int16_t *lsp, int order)
}
}
-static void get_lsp_poly(int16_t *lsp, int32_t *f)
+static void get_lsp_poly(const int16_t *lsp, int32_t *f)
{
int16_t high, low;
int i, j, k, l;
@@ -391,7 +393,7 @@ static void get_lsp_poly(int16_t *lsp, int32_t *f)
}
}
-static void lsf2poly(int16_t *a, int16_t *lsf)
+static void lsf2poly(int16_t *a, const int16_t *lsf)
{
int32_t f[2][6];
int16_t lsp[10];
@@ -418,8 +420,8 @@ static void lsf2poly(int16_t *a, int16_t *lsf)
}
}
-static void lsp_interpolate2polydec(int16_t *a, int16_t *lsf1,
- int16_t *lsf2, int coef, int length)
+static void lsp_interpolate2polydec(int16_t *a, const int16_t *lsf1,
+ const int16_t *lsf2, int coef, int length)
{
int16_t lsftmp[LPC_FILTERORDER];
@@ -437,13 +439,13 @@ static void bw_expand(int16_t *out, const int16_t *in, const int16_t *coef, int
}
static void lsp_interpolate(int16_t *syntdenum, int16_t *weightdenum,
- int16_t *lsfdeq, int16_t length,
+ const int16_t *lsfdeq, int16_t length,
ILBCContext *s)
{
- int16_t lp[LPC_FILTERORDER + 1], *lsfdeq2;
+ int16_t lp[LPC_FILTERORDER + 1];
+ const int16_t *const lsfdeq2 = lsfdeq + length;
int i, pos, lp_length;
- lsfdeq2 = lsfdeq + length;
lp_length = length + 1;
if (s->mode == 30) {
@@ -478,8 +480,8 @@ static void lsp_interpolate(int16_t *syntdenum, int16_t *weightdenum,
}
}
-static void filter_mafq12(int16_t *in_ptr, int16_t *out_ptr,
- int16_t *B, int16_t B_length,
+static void filter_mafq12(const int16_t *in_ptr, int16_t *out_ptr,
+ const int16_t *B, int16_t B_length,
int16_t length)
{
int o, i, j;
@@ -520,13 +522,14 @@ static void filter_arfq12(const int16_t *data_in,
}
}
-static void state_construct(int16_t ifm, int16_t *idx,
- int16_t *synt_denum, int16_t *Out_fix,
+static void state_construct(int16_t ifm, const int16_t *idx,
+ const int16_t *synt_denum, int16_t *Out_fix,
int16_t len)
{
int k;
int16_t maxVal;
- int16_t *tmp1, *tmp2, *tmp3;
+ int16_t *tmp1, *tmp3;
+ const int16_t *tmp2;
/* Stack based */
int16_t numerator[1 + LPC_FILTERORDER];
int16_t sampleValVec[2 * STATE_SHORT_LEN_30MS + LPC_FILTERORDER];
@@ -630,7 +633,7 @@ static void add_vector_and_shift(int16_t *out, const int16_t *in1,
out[i] = (in1[i] + in2[i]) >> shift;
}
-static void create_augmented_vector(int index, int16_t *buffer, int16_t *cbVec)
+static void create_augmented_vector(int index, const int16_t *buffer, int16_t *cbVec)
{
int16_t cbVecTmp[4];
int interpolation_length = FFMIN(4, index);
@@ -696,7 +699,7 @@ static void get_codebook(int16_t * cbvec, /* (o) Constructed codebook vector *
/* do filtering to get the codebook vector */
- filter_mafq12(&mem[memIndTest + 4], cbvec, (int16_t *) kCbFiltersRev, CB_FILTERLEN, cbveclen);
+ filter_mafq12(&mem[memIndTest + 4], cbvec, kCbFiltersRev, CB_FILTERLEN, cbveclen);
} else {
/* interpolated vectors */
/* Stuff zeros outside memory buffer */
@@ -704,7 +707,7 @@ static void get_codebook(int16_t * cbvec, /* (o) Constructed codebook vector *
memset(mem + lMem, 0, CB_HALFFILTERLEN * 2);
/* do filtering */
- filter_mafq12(&mem[memIndTest + 7], tempbuff2, (int16_t *) kCbFiltersRev, CB_FILTERLEN, (int16_t) (cbveclen + 5));
+ filter_mafq12(&mem[memIndTest + 7], tempbuff2, kCbFiltersRev, CB_FILTERLEN, (int16_t) (cbveclen + 5));
/* Calculate lag index */
lag = (cbveclen << 1) - 20 + index - base_size - lMem - 1;
@@ -716,8 +719,8 @@ static void get_codebook(int16_t * cbvec, /* (o) Constructed codebook vector *
static void construct_vector (
int16_t *decvector, /* (o) Decoded vector */
- int16_t *index, /* (i) Codebook indices */
- int16_t *gain_index, /* (i) Gain quantization indices */
+ const int16_t *index, /* (i) Codebook indices */
+ const int16_t *gain_index, /* (i) Gain quantization indices */
int16_t *mem, /* (i) Buffer for codevector construction */
int16_t lMem, /* (i) Length of buffer */
int16_t veclen)
@@ -753,10 +756,10 @@ static void construct_vector (
}
}
-static void reverse_memcpy(int16_t *dest, int16_t *source, int length)
+static void reverse_memcpy(int16_t *dest, const int16_t *source, int length)
{
int16_t* destPtr = dest;
- int16_t* sourcePtr = source;
+ const int16_t *sourcePtr = source;
int j;
for (j = 0; j < length; j++)
@@ -766,7 +769,7 @@ static void reverse_memcpy(int16_t *dest, int16_t *source, int length)
static void decode_residual(ILBCContext *s,
ILBCFrame *encbits,
int16_t *decresidual,
- int16_t *syntdenum)
+ const int16_t *syntdenum)
{
int16_t meml_gotten, Nfor, Nback, diff, start_pos;
int16_t subcount, subframe;
@@ -911,12 +914,10 @@ static int32_t scale_dot_product(const int16_t *v1, const int16_t *v2, int lengt
return av_clipl_int32(sum);
}
-static void correlation(int32_t *corr, int32_t *ener, int16_t *buffer,
+static void correlation(int32_t *corr, int32_t *ener, const int16_t *buffer,
int16_t lag, int16_t blen, int16_t srange, int16_t scale)
{
- int16_t *w16ptr;
-
- w16ptr = &buffer[blen - srange - lag];
+ const int16_t *w16ptr = &buffer[blen - srange - lag];
*corr = scale_dot_product(&buffer[blen - srange], w16ptr, srange, scale);
*ener = scale_dot_product(w16ptr, w16ptr, srange, scale);
@@ -952,8 +953,8 @@ static void do_plc(int16_t *plc_residual, /* (o) concealed residual */
int16_t *plc_lpc, /* (o) concealed LP parameters */
int16_t PLI, /* (i) packet loss indicator
0 - no PL, 1 = PL */
- int16_t *decresidual, /* (i) decoded residual */
- int16_t *lpc, /* (i) decoded LPC (only used for no PL) */
+ const int16_t *decresidual, /* (i) decoded residual */
+ const int16_t *lpc, /* (i) decoded LPC (only used for no PL) */
int16_t inlag, /* (i) pitch lag */
ILBCContext *s) /* (i/o) decoder instance */
{
@@ -1202,7 +1203,7 @@ static void do_plc(int16_t *plc_residual, /* (o) concealed residual */
return;
}
-static int xcorr_coeff(int16_t *target, int16_t *regressor,
+static int xcorr_coeff(const int16_t *target, const int16_t *regressor,
int16_t subl, int16_t searchLen,
int16_t offset, int16_t step)
{
@@ -1213,8 +1214,8 @@ static int xcorr_coeff(int16_t *target, int16_t *regressor,
int16_t cross_corr_sg_mod, cross_corr_sg_mod_max;
int32_t cross_corr, energy;
int16_t cross_corr_mod, energy_mod, enery_mod_max;
- int16_t *tp, *rp;
- int16_t *rp_beg, *rp_end;
+ const int16_t *rp;
+ const int16_t *rp_beg, *rp_end;
int16_t totscale, totscale_max;
int16_t scalediff;
int32_t new_crit, max_crit;
@@ -1253,10 +1254,9 @@ static int xcorr_coeff(int16_t *target, int16_t *regressor,
energy = scale_dot_product(regressor, regressor, subl, shifts);
for (k = 0; k < searchLen; k++) {
- tp = target;
rp = ®ressor[pos];
- cross_corr = scale_dot_product(tp, rp, subl, shifts);
+ cross_corr = scale_dot_product(target, rp, subl, shifts);
if ((energy > 0) && (cross_corr > 0)) {
/* Put cross correlation and energy on 16 bit word */
@@ -1359,21 +1359,21 @@ static void hp_output(int16_t *signal, const int16_t *ba, int16_t *y,
static int ilbc_decode_frame(AVCodecContext *avctx, AVFrame *frame,
int *got_frame_ptr, AVPacket *avpkt)
{
- const uint8_t *buf = avpkt->data;
ILBCContext *s = avctx->priv_data;
int mode = s->mode, ret;
int16_t *plc_data = &s->plc_residual[LPC_FILTERORDER];
- if ((ret = init_get_bits8(&s->gb, buf, avpkt->size)) < 0)
- return ret;
memset(&s->frame, 0, sizeof(ILBCFrame));
+ ret = unpack_frame(s, avpkt->data, avpkt->size);
+ if (ret < 0)
+ return ret;
+ if (ret)
+ mode = 0;
frame->nb_samples = s->block_samples;
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret;
- if (unpack_frame(s))
- mode = 0;
if (s->frame.start < 1 || s->frame.start > 5)
mode = 0;
@@ -1480,12 +1480,11 @@ static av_cold int ilbc_decode_init(AVCodecContext *avctx)
const FFCodec ff_ilbc_decoder = {
.p.name = "ilbc",
- .p.long_name = NULL_IF_CONFIG_SMALL("iLBC (Internet Low Bitrate Codec)"),
+ CODEC_LONG_NAME("iLBC (Internet Low Bitrate Codec)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ILBC,
.init = ilbc_decode_init,
FF_CODEC_DECODE_CB(ilbc_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
.priv_data_size = sizeof(ILBCContext),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/imc.c b/libavcodec/imc.c
index 978ea74b7..174332de4 100644
--- a/libavcodec/imc.c
+++ b/libavcodec/imc.c
@@ -33,7 +33,6 @@
#include
#include
-#include
#include "libavutil/channel_layout.h"
#include "libavutil/ffmath.h"
@@ -41,13 +40,13 @@
#include "libavutil/internal.h"
#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"
+#include "libavutil/tx.h"
#include "avcodec.h"
#include "bswapdsp.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "fft.h"
-#include "internal.h"
#include "sinewin.h"
#include "imcdata.h"
@@ -65,7 +64,7 @@ typedef struct IMCChannel {
float flcoeffs4[BANDS];
float flcoeffs5[BANDS];
float flcoeffs6[BANDS];
- float CWdecoded[COEFFS];
+ DECLARE_ALIGNED(32, float, CWdecoded)[COEFFS];
int bandWidthT[BANDS]; ///< codewords per band
int bitsBandT[BANDS]; ///< how many bits per codeword in band
@@ -79,31 +78,25 @@ typedef struct IMCChannel {
int skipFlags[COEFFS]; ///< skip coefficient decoding or not
int codewords[COEFFS]; ///< raw codewords read from bitstream
- float last_fft_im[COEFFS];
-
int decoder_reset;
+ DECLARE_ALIGNED(32, float, prev_win)[128];
} IMCChannel;
typedef struct IMCContext {
IMCChannel chctx[2];
/** MDCT tables */
- //@{
- float mdct_sine_window[COEFFS];
- float post_cos[COEFFS];
- float post_sin[COEFFS];
- float pre_coef1[COEFFS];
- float pre_coef2[COEFFS];
- //@}
+ DECLARE_ALIGNED(32, float, mdct_sine_window)[COEFFS];
float sqrt_tab[30];
GetBitContext gb;
+ AVFloatDSPContext *fdsp;
BswapDSPContext bdsp;
- void (*butterflies_float)(float *av_restrict v1, float *av_restrict v2, int len);
- FFTContext fft;
- DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2];
+ AVTXContext *mdct;
+ av_tx_fn mdct_fn;
float *out_samples;
+ DECLARE_ALIGNED(32, float, temp)[256];
int coef0_pos;
@@ -197,8 +190,7 @@ static av_cold int imc_decode_init(AVCodecContext *avctx)
int i, j, ret;
IMCContext *q = avctx->priv_data;
static AVOnce init_static_once = AV_ONCE_INIT;
- AVFloatDSPContext *fdsp;
- double r1, r2;
+ float scale = 1.0f / (16384);
if (avctx->codec_id == AV_CODEC_ID_IAC && avctx->sample_rate > 96000) {
av_log(avctx, AV_LOG_ERROR,
@@ -223,33 +215,14 @@ static av_cold int imc_decode_init(AVCodecContext *avctx)
for (i = 0; i < BANDS; i++)
q->chctx[j].old_floor[i] = 1.0;
-
- for (i = 0; i < COEFFS / 2; i++)
- q->chctx[j].last_fft_im[i] = 0;
}
/* Build mdct window, a simple sine window normalized with sqrt(2) */
ff_sine_window_init(q->mdct_sine_window, COEFFS);
for (i = 0; i < COEFFS; i++)
q->mdct_sine_window[i] *= sqrt(2.0);
- for (i = 0; i < COEFFS / 2; i++) {
- q->post_cos[i] = (1.0f / 32768) * cos(i / 256.0 * M_PI);
- q->post_sin[i] = (1.0f / 32768) * sin(i / 256.0 * M_PI);
-
- r1 = sin((i * 4.0 + 1.0) / 1024.0 * M_PI);
- r2 = cos((i * 4.0 + 1.0) / 1024.0 * M_PI);
-
- if (i & 0x1) {
- q->pre_coef1[i] = (r1 + r2) * sqrt(2.0);
- q->pre_coef2[i] = -(r1 - r2) * sqrt(2.0);
- } else {
- q->pre_coef1[i] = -(r1 + r2) * sqrt(2.0);
- q->pre_coef2[i] = (r1 - r2) * sqrt(2.0);
- }
- }
/* Generate a square root table */
-
for (i = 0; i < 30; i++)
q->sqrt_tab[i] = sqrt(i);
@@ -262,15 +235,14 @@ static av_cold int imc_decode_init(AVCodecContext *avctx)
memcpy(q->weights2, imc_weights2, sizeof(imc_weights2));
}
- fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
- if (!fdsp)
+ q->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
+ if (!q->fdsp)
return AVERROR(ENOMEM);
- q->butterflies_float = fdsp->butterflies_float;
- av_free(fdsp);
- if ((ret = ff_fft_init(&q->fft, 7, 1))) {
- av_log(avctx, AV_LOG_INFO, "FFT init failed\n");
+
+ ret = av_tx_init(&q->mdct, &q->mdct_fn, AV_TX_FLOAT_MDCT, 1, COEFFS, &scale, 0);
+ if (ret < 0)
return ret;
- }
+
ff_bswapdsp_init(&q->bdsp);
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
@@ -727,39 +699,6 @@ static void imc_adjust_bit_allocation(IMCContext *q, IMCChannel *chctx,
}
}
-static void imc_imdct256(IMCContext *q, IMCChannel *chctx, int channels)
-{
- int i;
- float re, im;
- float *dst1 = q->out_samples;
- float *dst2 = q->out_samples + (COEFFS - 1);
-
- /* prerotation */
- for (i = 0; i < COEFFS / 2; i++) {
- q->samples[i].re = -(q->pre_coef1[i] * chctx->CWdecoded[COEFFS - 1 - i * 2]) -
- (q->pre_coef2[i] * chctx->CWdecoded[i * 2]);
- q->samples[i].im = (q->pre_coef2[i] * chctx->CWdecoded[COEFFS - 1 - i * 2]) -
- (q->pre_coef1[i] * chctx->CWdecoded[i * 2]);
- }
-
- /* FFT */
- q->fft.fft_permute(&q->fft, q->samples);
- q->fft.fft_calc(&q->fft, q->samples);
-
- /* postrotation, window and reorder */
- for (i = 0; i < COEFFS / 2; i++) {
- re = ( q->samples[i].re * q->post_cos[i]) + (-q->samples[i].im * q->post_sin[i]);
- im = (-q->samples[i].im * q->post_cos[i]) - ( q->samples[i].re * q->post_sin[i]);
- *dst1 = (q->mdct_sine_window[COEFFS - 1 - i * 2] * chctx->last_fft_im[i])
- + (q->mdct_sine_window[i * 2] * re);
- *dst2 = (q->mdct_sine_window[i * 2] * chctx->last_fft_im[i])
- - (q->mdct_sine_window[COEFFS - 1 - i * 2] * re);
- dst1 += 2;
- dst2 -= 2;
- chctx->last_fft_im[i] = im;
- }
-}
-
static int inverse_quant_coeff(IMCContext *q, IMCChannel *chctx,
int stream_format_code)
{
@@ -1013,7 +952,10 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
memset(chctx->skipFlags, 0, sizeof(chctx->skipFlags));
- imc_imdct256(q, chctx, avctx->ch_layout.nb_channels);
+ q->mdct_fn(q->mdct, q->temp, chctx->CWdecoded, sizeof(float));
+ q->fdsp->vector_fmul_window(q->out_samples, chctx->prev_win, q->temp,
+ q->mdct_sine_window, 128);
+ memcpy(chctx->prev_win, q->temp + 128, sizeof(float)*128);
return 0;
}
@@ -1055,8 +997,8 @@ static int imc_decode_frame(AVCodecContext *avctx, AVFrame *frame,
}
if (avctx->ch_layout.nb_channels == 2) {
- q->butterflies_float((float *)frame->extended_data[0],
- (float *)frame->extended_data[1], COEFFS);
+ q->fdsp->butterflies_float((float *)frame->extended_data[0],
+ (float *)frame->extended_data[1], COEFFS);
}
*got_frame_ptr = 1;
@@ -1068,7 +1010,8 @@ static av_cold int imc_decode_close(AVCodecContext * avctx)
{
IMCContext *q = avctx->priv_data;
- ff_fft_end(&q->fft);
+ av_free(q->fdsp);
+ av_tx_uninit(&q->mdct);
return 0;
}
@@ -1084,7 +1027,7 @@ static av_cold void flush(AVCodecContext *avctx)
#if CONFIG_IMC_DECODER
const FFCodec ff_imc_decoder = {
.p.name = "imc",
- .p.long_name = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"),
+ CODEC_LONG_NAME("IMC (Intel Music Coder)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_IMC,
.priv_data_size = sizeof(IMCContext),
@@ -1095,13 +1038,12 @@ const FFCodec ff_imc_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
#if CONFIG_IAC_DECODER
const FFCodec ff_iac_decoder = {
.p.name = "iac",
- .p.long_name = NULL_IF_CONFIG_SMALL("IAC (Indeo Audio Coder)"),
+ CODEC_LONG_NAME("IAC (Indeo Audio Coder)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_IAC,
.priv_data_size = sizeof(IMCContext),
@@ -1112,6 +1054,5 @@ const FFCodec ff_iac_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
#endif
diff --git a/libavcodec/imm4.c b/libavcodec/imm4.c
index d82681886..ccec5dff4 100644
--- a/libavcodec/imm4.c
+++ b/libavcodec/imm4.c
@@ -20,8 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include
-#include
+#include
#include
#include "libavutil/mem_internal.h"
@@ -30,10 +29,10 @@
#include "avcodec.h"
#include "bswapdsp.h"
#include "codec_internal.h"
+#include "decode.h"
#include "copy_block.h"
#include "get_bits.h"
#include "idctdsp.h"
-#include "internal.h"
#define CBPLO_VLC_BITS 6
#define CBPHI_VLC_BITS 6
@@ -52,9 +51,8 @@ typedef struct IMM4Context {
unsigned lo;
unsigned hi;
- ScanTable intra_scantable;
- DECLARE_ALIGNED(32, int16_t, block)[6][64];
IDCTDSPContext idsp;
+ DECLARE_ALIGNED(32, int16_t, block)[6][64];
} IMM4Context;
static const uint8_t intra_cb[] = {
@@ -130,7 +128,7 @@ static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
int block, int factor, int flag, int offset, int flag2)
{
IMM4Context *s = avctx->priv_data;
- const uint8_t *scantable = s->intra_scantable.permutated;
+ const uint8_t *idct_permutation = s->idsp.idct_permutation;
int i, last, len, factor2;
for (i = !flag; i < 64; i++) {
@@ -153,17 +151,17 @@ static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
i += len;
if (i >= 64)
break;
- s->block[block][scantable[i]] = offset * (factor2 < 0 ? -1 : 1) + factor * factor2;
+ s->block[block][idct_permutation[i]] = offset * (factor2 < 0 ? -1 : 1) + factor * factor2;
if (last)
break;
}
if (s->hi == 2 && flag2 && block < 4) {
if (flag)
- s->block[block][scantable[0]] *= 2;
- s->block[block][scantable[1]] *= 2;
- s->block[block][scantable[8]] *= 2;
- s->block[block][scantable[16]] *= 2;
+ s->block[block][idct_permutation[0]] *= 2;
+ s->block[block][idct_permutation[1]] *= 2;
+ s->block[block][idct_permutation[8]] *= 2;
+ s->block[block][idct_permutation[16]] *= 2;
}
return 0;
@@ -173,7 +171,7 @@ static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
unsigned cbp, int flag, int offset, unsigned flag2)
{
IMM4Context *s = avctx->priv_data;
- const uint8_t *scantable = s->intra_scantable.permutated;
+ const uint8_t *idct_permutation = s->idsp.idct_permutation;
int ret, i;
memset(s->block, 0, sizeof(s->block));
@@ -186,7 +184,7 @@ static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
x = 128;
x *= 8;
- s->block[i][scantable[0]] = x;
+ s->block[i][idct_permutation[0]] = x;
}
if (cbp & (1 << (5 - i))) {
@@ -496,14 +494,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
{
static AVOnce init_static_once = AV_ONCE_INIT;
IMM4Context *s = avctx->priv_data;
- uint8_t table[64];
-
- for (int i = 0; i < 64; i++)
- table[i] = i;
ff_bswapdsp_init(&s->bdsp);
ff_idctdsp_init(&s->idsp, avctx);
- ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, table);
s->prev_frame = av_frame_alloc();
if (!s->prev_frame)
@@ -534,7 +527,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
const FFCodec ff_imm4_decoder = {
.p.name = "imm4",
- .p.long_name = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
+ CODEC_LONG_NAME("Infinity IMM4"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_IMM4,
.priv_data_size = sizeof(IMM4Context),
@@ -543,6 +536,5 @@ const FFCodec ff_imm4_decoder = {
FF_CODEC_DECODE_CB(decode_frame),
.flush = decode_flush,
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/imm5.c b/libavcodec/imm5.c
index 9b7ac17aa..2535e7726 100644
--- a/libavcodec/imm5.c
+++ b/libavcodec/imm5.c
@@ -179,7 +179,7 @@ static av_cold int imm5_close(AVCodecContext *avctx)
const FFCodec ff_imm5_decoder = {
.p.name = "imm5",
- .p.long_name = NULL_IF_CONFIG_SMALL("Infinity IMM5"),
+ CODEC_LONG_NAME("Infinity IMM5"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_IMM5,
.init = imm5_init,
@@ -187,6 +187,5 @@ const FFCodec ff_imm5_decoder = {
.close = imm5_close,
.flush = imm5_flush,
.priv_data_size = sizeof(IMM5Context),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/imx.c b/libavcodec/imx.c
index 4ee600686..44bab23c2 100644
--- a/libavcodec/imx.c
+++ b/libavcodec/imx.c
@@ -23,7 +23,6 @@
#include "bytestream.h"
#include "codec_internal.h"
#include "decode.h"
-#include "internal.h"
typedef struct SimbiosisIMXContext {
AVFrame *frame;
@@ -182,7 +181,7 @@ static int imx_decode_close(AVCodecContext *avctx)
const FFCodec ff_simbiosis_imx_decoder = {
.p.name = "simbiosis_imx",
- .p.long_name = NULL_IF_CONFIG_SMALL("Simbiosis Interactive IMX Video"),
+ CODEC_LONG_NAME("Simbiosis Interactive IMX Video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_SIMBIOSIS_IMX,
.priv_data_size = sizeof(SimbiosisIMXContext),
@@ -191,6 +190,5 @@ const FFCodec ff_simbiosis_imx_decoder = {
.close = imx_decode_close,
.flush = imx_decode_flush,
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c
index 79028975e..dd88ebf7c 100644
--- a/libavcodec/indeo2.c
+++ b/libavcodec/indeo2.c
@@ -30,10 +30,9 @@
#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
#include "indeo2data.h"
-#include "internal.h"
-#include "mathops.h"
typedef struct Ir2Context{
AVCodecContext *avctx;
@@ -261,7 +260,7 @@ static av_cold int ir2_decode_end(AVCodecContext *avctx)
const FFCodec ff_indeo2_decoder = {
.p.name = "indeo2",
- .p.long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"),
+ CODEC_LONG_NAME("Intel Indeo 2"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_INDEO2,
.priv_data_size = sizeof(Ir2Context),
@@ -269,5 +268,4 @@ const FFCodec ff_indeo2_decoder = {
.close = ir2_decode_end,
FF_CODEC_DECODE_CB(ir2_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index 43669f46b..5f1014f0d 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -34,11 +34,11 @@
#include "libavutil/thread.h"
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "copy_block.h"
#include "bytestream.h"
#include "get_bits.h"
#include "hpeldsp.h"
-#include "internal.h"
#include "indeo3data.h"
@@ -1135,7 +1135,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
const FFCodec ff_indeo3_decoder = {
.p.name = "indeo3",
- .p.long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 3"),
+ CODEC_LONG_NAME("Intel Indeo 3"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_INDEO3,
.priv_data_size = sizeof(Indeo3DecodeContext),
@@ -1143,5 +1143,5 @@ const FFCodec ff_indeo3_decoder = {
.close = decode_close,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c
index f0cdff0e2..64dfc7cce 100644
--- a/libavcodec/indeo4.c
+++ b/libavcodec/indeo4.c
@@ -705,7 +705,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
const FFCodec ff_indeo4_decoder = {
.p.name = "indeo4",
- .p.long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"),
+ CODEC_LONG_NAME("Intel Indeo Video Interactive 4"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_INDEO4,
.priv_data_size = sizeof(IVI45DecContext),
@@ -713,5 +713,4 @@ const FFCodec ff_indeo4_decoder = {
.close = ff_ivi_decode_close,
FF_CODEC_DECODE_CB(ff_ivi_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c
index aff110221..df95064e3 100644
--- a/libavcodec/indeo5.c
+++ b/libavcodec/indeo5.c
@@ -685,7 +685,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
const FFCodec ff_indeo5_decoder = {
.p.name = "indeo5",
- .p.long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 5"),
+ CODEC_LONG_NAME("Intel Indeo Video Interactive 5"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_INDEO5,
.priv_data_size = sizeof(IVI45DecContext),
@@ -693,5 +693,5 @@ const FFCodec ff_indeo5_decoder = {
.close = ff_ivi_decode_close,
FF_CODEC_DECODE_CB(ff_ivi_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/intelh263dec.c b/libavcodec/intelh263dec.c
index ded0a7f61..2c216b00a 100644
--- a/libavcodec/intelh263dec.c
+++ b/libavcodec/intelh263dec.c
@@ -122,9 +122,6 @@ int ff_intel_h263_decode_picture_header(MpegEncContext *s)
return AVERROR_INVALIDDATA;
s->f_code = 1;
- s->y_dc_scale_table=
- s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
-
ff_h263_show_pict_info(s);
return 0;
@@ -132,7 +129,7 @@ int ff_intel_h263_decode_picture_header(MpegEncContext *s)
const FFCodec ff_h263i_decoder = {
.p.name = "h263i",
- .p.long_name = NULL_IF_CONFIG_SMALL("Intel H.263"),
+ CODEC_LONG_NAME("Intel H.263"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_H263I,
.priv_data_size = sizeof(MpegEncContext),
@@ -140,8 +137,7 @@ const FFCodec ff_h263i_decoder = {
.close = ff_h263_decode_end,
FF_CODEC_DECODE_CB(ff_h263_decode_frame),
.p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
+ .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.p.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 17e1de812..a283c52e0 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -33,6 +33,10 @@
#include "avcodec.h"
#include "config.h"
+#if CONFIG_LCMS2
+# include "fflcms2.h"
+#endif
+
#define FF_SANE_NB_CHANNELS 512U
#if HAVE_SIMD_ALIGN_64
@@ -53,11 +57,17 @@ typedef struct AVCodecInternal {
int is_copy;
/**
- * An audio frame with less than required samples has been submitted and
- * padded with silence. Reject all subsequent frames.
+ * An audio frame with less than required samples has been submitted (and
+ * potentially padded with silence). Reject all subsequent frames.
*/
int last_audio_frame;
+ /**
+ * Audio encoders can set this flag during init to indicate that they
+ * want the small last frame to be padded to a multiple of pad_samples.
+ */
+ int pad_samples;
+
AVBufferRef *pool;
void *thread_ctx;
@@ -78,7 +88,6 @@ typedef struct AVCodecInternal {
* for decoding.
*/
AVPacket *last_pkt_props;
- struct AVFifo *pkt_props;
/**
* temporary buffer used for encoders to store their bitstream
@@ -103,6 +112,14 @@ typedef struct AVCodecInternal {
*/
AVFrame *in_frame;
+ /**
+ * When the AV_CODEC_FLAG_RECON_FRAME flag is used. the encoder should store
+ * here the reconstructed frame corresponding to the last returned packet.
+ *
+ * Not allocated in other cases.
+ */
+ AVFrame *recon_frame;
+
/**
* If this is set, then FFCodec->close (if existing) needs to be called
* for the parent AVCodecContext.
@@ -125,7 +142,7 @@ typedef struct AVCodecInternal {
int draining;
/**
- * buffers for using new encode/decode API through legacy API
+ * Temporary buffers for newly received or not yet output packets/frames.
*/
AVPacket *buffer_pkt;
AVFrame *buffer_frame;
@@ -133,8 +150,6 @@ typedef struct AVCodecInternal {
int showed_multi_packet_warning;
- int skip_samples_multiplier;
-
/* to prevent infinite loop on errors when draining */
int nb_draining_errors;
@@ -143,11 +158,11 @@ typedef struct AVCodecInternal {
int initial_format;
int initial_width, initial_height;
int initial_sample_rate;
-#if FF_API_OLD_CHANNEL_LAYOUT
- int initial_channels;
- uint64_t initial_channel_layout;
-#endif
AVChannelLayout initial_ch_layout;
+
+#if CONFIG_LCMS2
+ FFIccContext icc; /* used to read and write embedded ICC profiles */
+#endif
} AVCodecInternal;
/**
@@ -167,18 +182,6 @@ void ff_color_frame(AVFrame *frame, const int color[4]);
*/
#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - AV_INPUT_BUFFER_PADDING_SIZE)
-/**
- * Rescale from sample rate to AVCodecContext.time_base.
- */
-static av_always_inline int64_t ff_samples_to_time_base(AVCodecContext *avctx,
- int64_t samples)
-{
- if(samples == AV_NOPTS_VALUE)
- return AV_NOPTS_VALUE;
- return av_rescale_q(samples, (AVRational){ 1, avctx->sample_rate },
- avctx->time_base);
-}
-
/**
* 2^(x) for integer x
* @return correctly rounded float
@@ -198,57 +201,10 @@ static av_always_inline float ff_exp2fi(int x) {
return 0;
}
-/**
- * Get a buffer for a frame. This is a wrapper around
- * AVCodecContext.get_buffer() and should be used instead calling get_buffer()
- * directly.
- */
-int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags);
-
-#define FF_REGET_BUFFER_FLAG_READONLY 1 ///< the returned buffer does not need to be writable
-/**
- * Identical in function to ff_get_buffer(), except it reuses the existing buffer
- * if available.
- */
-int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags);
-
-int ff_thread_can_start_frame(AVCodecContext *avctx);
-
int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx);
int avpriv_codec_get_cap_skip_frame_fill_param(const AVCodec *codec);
-/**
- * Check that the provided frame dimensions are valid and set them on the codec
- * context.
- */
-int ff_set_dimensions(AVCodecContext *s, int width, int height);
-
-/**
- * Check that the provided sample aspect ratio is valid and set it on the codec
- * context.
- */
-int ff_set_sar(AVCodecContext *avctx, AVRational sar);
-
-/**
- * Add or update AV_FRAME_DATA_MATRIXENCODING side data.
- */
-int ff_side_data_update_matrix_encoding(AVFrame *frame,
- enum AVMatrixEncoding matrix_encoding);
-
-/**
- * Select the (possibly hardware accelerated) pixel format.
- * This is a wrapper around AVCodecContext.get_format() and should be used
- * instead of calling get_format() directly.
- *
- * The list of pixel formats must contain at least one valid entry, and is
- * terminated with AV_PIX_FMT_NONE. If it is possible to decode to software,
- * the last entry in the list must be the most accurate software format.
- * If it is not possible to decode to software, AVCodecContext.sw_pix_fmt
- * must be set before calling this function.
- */
-int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt);
-
/**
* Add a CPB properties side data to an encoding context.
*/
@@ -288,6 +244,4 @@ int64_t ff_guess_coded_bitrate(AVCodecContext *avctx);
int ff_int_from_list_or_default(void *ctx, const char * val_name, int val,
const int * array_valid_values, int default_value);
-void ff_dvdsub_parse_palette(uint32_t *palette, const char *p);
-
#endif /* AVCODEC_INTERNAL_H */
diff --git a/libavcodec/interplayacm.c b/libavcodec/interplayacm.c
index 3c482e4c8..a0b9655e7 100644
--- a/libavcodec/interplayacm.c
+++ b/libavcodec/interplayacm.c
@@ -24,8 +24,8 @@
#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
static const int8_t map_1bit[] = { -1, +1 };
static const int8_t map_2bit_near[] = { -2, -1, +1, +2 };
@@ -634,13 +634,13 @@ static av_cold int decode_close(AVCodecContext *avctx)
const FFCodec ff_interplay_acm_decoder = {
.p.name = "interplayacm",
- .p.long_name = NULL_IF_CONFIG_SMALL("Interplay ACM"),
+ CODEC_LONG_NAME("Interplay ACM"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_INTERPLAY_ACM,
.init = decode_init,
.close = decode_close,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.priv_data_size = sizeof(InterplayACMContext),
};
diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c
index fe2a9e1e6..1a3461bf1 100644
--- a/libavcodec/interplayvideo.c
+++ b/libavcodec/interplayvideo.c
@@ -35,7 +35,6 @@
*/
#include
-#include
#include
#include "libavutil/intreadwrite.h"
@@ -47,7 +46,6 @@
#include "decode.h"
#include "get_bits.h"
#include "hpeldsp.h"
-#include "internal.h"
#define PALETTE_COUNT 256
@@ -928,7 +926,7 @@ static void ipvideo_format_06_firstpass(IpvideoContext *s, AVFrame *frame, int16
}
} else {
/* Don't try to copy second_last_frame data on the first frames */
- if (s->avctx->frame_number > 2)
+ if (s->avctx->frame_num > 2)
copy_from(s, s->second_last_frame, frame, 0, 0);
}
}
@@ -1087,7 +1085,7 @@ static void ipvideo_decode_format_10_opcodes(IpvideoContext *s, AVFrame *frame)
copy_from(s, s->cur_decode_frame, frame, 0, 0);
} else {
/* Don't try to copy last_frame data on the first frame */
- if (s->avctx->frame_number)
+ if (s->avctx->frame_num)
copy_from(s, s->last_frame, frame, 0, 0);
}
skip *= 2;
@@ -1146,8 +1144,8 @@ static void ipvideo_decode_format_11_opcodes(IpvideoContext *s, AVFrame *frame)
ret = ipvideo_decode_block16[opcode](s, frame);
}
if (ret != 0) {
- av_log(s->avctx, AV_LOG_ERROR, "decode problem on frame %d, @ block (%d, %d)\n",
- s->avctx->frame_number, x, y);
+ av_log(s->avctx, AV_LOG_ERROR, "decode problem on frame %"PRId64", @ block (%d, %d)\n",
+ s->avctx->frame_num, x, y);
return;
}
}
@@ -1358,7 +1356,7 @@ static av_cold int ipvideo_decode_end(AVCodecContext *avctx)
const FFCodec ff_interplay_video_decoder = {
.p.name = "interplayvideo",
- .p.long_name = NULL_IF_CONFIG_SMALL("Interplay MVE video"),
+ CODEC_LONG_NAME("Interplay MVE video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_INTERPLAY_VIDEO,
.priv_data_size = sizeof(IpvideoContext),
@@ -1366,5 +1364,5 @@ const FFCodec ff_interplay_video_decoder = {
.close = ipvideo_decode_end,
FF_CODEC_DECODE_CB(ipvideo_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_PARAM_CHANGE,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/intrax8.c b/libavcodec/intrax8.c
index 73b8aeea7..e4c8b96c9 100644
--- a/libavcodec/intrax8.c
+++ b/libavcodec/intrax8.c
@@ -26,7 +26,7 @@
#include "avcodec.h"
#include "get_bits.h"
#include "idctdsp.h"
-#include "msmpeg4data.h"
+#include "msmpeg4_vc1_data.h"
#include "intrax8huf.h"
#include "intrax8.h"
#include "intrax8dsp.h"
@@ -92,9 +92,9 @@ static av_cold void x8_vlc_init(void)
static void x8_reset_vlc_tables(IntraX8Context *w)
{
- memset(w->j_dc_vlc, 0, sizeof(w->j_dc_vlc));
- memset(w->j_ac_vlc, 0, sizeof(w->j_ac_vlc));
- w->j_orient_vlc = NULL;
+ memset(w->j_dc_vlc_table, 0, sizeof(w->j_dc_vlc_table));
+ memset(w->j_ac_vlc_table, 0, sizeof(w->j_ac_vlc_table));
+ w->j_orient_vlc_table = NULL;
}
static inline void x8_select_ac_table(IntraX8Context *const w, int mode)
@@ -103,23 +103,23 @@ static inline void x8_select_ac_table(IntraX8Context *const w, int mode)
av_assert2(mode < 4);
- if (w->j_ac_vlc[mode])
+ if (w->j_ac_vlc_table[mode])
return;
table_index = get_bits(w->gb, 3);
// 2 modes use same tables
- w->j_ac_vlc[mode] = &j_ac_vlc[w->quant < 13][mode >> 1][table_index];
+ w->j_ac_vlc_table[mode] = j_ac_vlc[w->quant < 13][mode >> 1][table_index].table;
av_assert2(w->j_ac_vlc[mode]);
}
static inline int x8_get_orient_vlc(IntraX8Context *w)
{
- if (!w->j_orient_vlc) {
+ if (!w->j_orient_vlc_table) {
int table_index = get_bits(w->gb, 1 + (w->quant < 13));
- w->j_orient_vlc = &j_orient_vlc[w->quant < 13][table_index];
+ w->j_orient_vlc_table = j_orient_vlc[w->quant < 13][table_index].table;
}
- return get_vlc2(w->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD);
+ return get_vlc2(w->gb, w->j_orient_vlc_table, OR_VLC_BITS, OR_VLC_MTD);
}
#define extra_bits(eb) (eb) // 3 bits
@@ -175,7 +175,7 @@ static void x8_get_ac_rlf(IntraX8Context *const w, const int mode,
int i, e;
// x8_select_ac_table(w, mode);
- i = get_vlc2(w->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD);
+ i = get_vlc2(w->gb, w->j_ac_vlc_table[mode], AC_VLC_BITS, AC_VLC_MTD);
if (i < 46) { // [0-45]
int t, l;
@@ -255,13 +255,13 @@ static int x8_get_dc_rlf(IntraX8Context *const w, const int mode,
int i, e, c;
av_assert2(mode < 3);
- if (!w->j_dc_vlc[mode]) {
+ if (!w->j_dc_vlc_table[mode]) {
int table_index = get_bits(w->gb, 3);
// 4 modes, same table
- w->j_dc_vlc[mode] = &j_dc_vlc[w->quant < 13][table_index];
+ w->j_dc_vlc_table[mode] = j_dc_vlc[w->quant < 13][table_index].table;
}
- i = get_vlc2(w->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD);
+ i = get_vlc2(w->gb, w->j_dc_vlc_table[mode], DC_VLC_BITS, DC_VLC_MTD);
/* (i >= 17) { i -= 17; final =1; } */
c = i > 16;
@@ -577,7 +577,7 @@ static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma)
x8_select_ac_table(w, ac_mode);
/* scantable_selector[12] = { 0, 2, 0, 1, 1, 1, 0, 2, 2, 0, 1, 2 }; <-
* -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 => 0x928548 */
- scantable = w->scantable[(0x928548 >> (2 * w->orient)) & 3].permutated;
+ scantable = w->permutated_scantable[(0x928548 >> (2 * w->orient)) & 3];
pos = 0;
do {
n++;
@@ -692,7 +692,7 @@ static void x8_init_block_index(IntraX8Context *w, AVFrame *frame)
}
av_cold int ff_intrax8_common_init(AVCodecContext *avctx,
- IntraX8Context *w, IDCTDSPContext *idsp,
+ IntraX8Context *w,
int16_t (*block)[64],
int block_last_index[12],
int mb_width, int mb_height)
@@ -700,7 +700,6 @@ av_cold int ff_intrax8_common_init(AVCodecContext *avctx,
static AVOnce init_static_once = AV_ONCE_INIT;
w->avctx = avctx;
- w->idsp = *idsp;
w->mb_width = mb_width;
w->mb_height = mb_height;
w->block = block;
@@ -716,15 +715,15 @@ av_cold int ff_intrax8_common_init(AVCodecContext *avctx,
ff_init_scantable_permutation(w->idct_permutation,
w->wdsp.idct_perm);
- ff_init_scantable(w->idct_permutation, &w->scantable[0],
- ff_wmv1_scantable[0]);
- ff_init_scantable(w->idct_permutation, &w->scantable[1],
- ff_wmv1_scantable[2]);
- ff_init_scantable(w->idct_permutation, &w->scantable[2],
- ff_wmv1_scantable[3]);
+ ff_permute_scantable(w->permutated_scantable[0], ff_wmv1_scantable[0],
+ w->idct_permutation);
+ ff_permute_scantable(w->permutated_scantable[1], ff_wmv1_scantable[2],
+ w->idct_permutation);
+ ff_permute_scantable(w->permutated_scantable[2], ff_wmv1_scantable[3],
+ w->idct_permutation);
ff_intrax8dsp_init(&w->dsp);
- ff_blockdsp_init(&w->bdsp, avctx);
+ ff_blockdsp_init(&w->bdsp);
ff_thread_once(&init_static_once, x8_vlc_init);
diff --git a/libavcodec/intrax8.h b/libavcodec/intrax8.h
index 5b8946ea2..8e22361f1 100644
--- a/libavcodec/intrax8.h
+++ b/libavcodec/intrax8.h
@@ -21,21 +21,20 @@
#include "blockdsp.h"
#include "get_bits.h"
-#include "idctdsp.h"
#include "intrax8dsp.h"
#include "wmv2dsp.h"
#include "mpegpicture.h"
typedef struct IntraX8Context {
- VLC *j_ac_vlc[4]; // they point to the static j_mb_vlc
- VLC *j_orient_vlc;
- VLC *j_dc_vlc[3];
+ const VLCElem *j_ac_vlc_table[4]; // they point to the static j_mb_vlc.table
+ const VLCElem *j_orient_vlc_table;
+ const VLCElem *j_dc_vlc_table[3];
int use_quant_matrix;
// set by ff_intrax8_common_init
uint8_t *prediction_table; // 2 * (mb_w * 2)
- ScanTable scantable[3];
+ uint8_t permutated_scantable[3][64];
WMV2DSPContext wdsp;
uint8_t idct_permutation[64];
AVCodecContext *avctx;
@@ -44,7 +43,6 @@ typedef struct IntraX8Context {
// set by the caller codec
IntraX8DSPContext dsp;
- IDCTDSPContext idsp;
BlockDSPContext bdsp;
int quant;
int dquant;
@@ -78,7 +76,6 @@ typedef struct IntraX8Context {
* Initialize IntraX8 frame decoder.
* @param avctx pointer to AVCodecContext
* @param w pointer to IntraX8Context
- * @param idsp pointer to IDCTDSPContext
* @param block pointer to block array
* @param block_last_index pointer to index array
* @param mb_width macroblock width
@@ -86,7 +83,7 @@ typedef struct IntraX8Context {
* @return 0 on success, a negative AVERROR value on error
*/
int ff_intrax8_common_init(AVCodecContext *avctx,
- IntraX8Context *w, IDCTDSPContext *idsp,
+ IntraX8Context *w,
int16_t (*block)[64],
int block_last_index[12],
int mb_width, int mb_height);
diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index af054360d..d4a07071e 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -50,6 +50,7 @@
#include "mpegvideodata.h"
#include "mpegvideodec.h"
#include "mpeg4videodec.h"
+#include "mpeg4videodefs.h"
// The defines below define the number of bits that are read at once for
// reading vlc values. Changing these may improve speed and data cache needs
@@ -543,9 +544,9 @@ static int h263_decode_block(MpegEncContext * s, int16_t * block,
i = 0;
if (s->ac_pred) {
if (s->h263_aic_dir)
- scan_table = s->intra_v_scantable.permutated; /* left */
+ scan_table = s->permutated_intra_v_scantable; /* left */
else
- scan_table = s->intra_h_scantable.permutated; /* top */
+ scan_table = s->permutated_intra_h_scantable; /* top */
}
} else if (s->mb_intra) {
/* DC coef */
@@ -1092,7 +1093,7 @@ int ff_h263_decode_picture_header(MpegEncContext *s)
align_get_bits(&s->gb);
- if (show_bits(&s->gb, 2) == 2 && s->avctx->frame_number == 0) {
+ if (show_bits(&s->gb, 2) == 2 && s->avctx->frame_num == 0) {
av_log(s->avctx, AV_LOG_WARNING, "Header looks like RTP instead of H.263\n");
}
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 2fcd001db..c30ecad43 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -105,7 +105,7 @@ av_const int ff_h263_aspect_to_info(AVRational aspect){
return FF_ASPECT_EXTENDED;
}
-void ff_h263_encode_picture_header(MpegEncContext * s, int picture_number)
+void ff_h263_encode_picture_header(MpegEncContext * s)
{
int format, coded_frame_rate, coded_frame_rate_base, i, temp_ref;
int best_clock_code=1;
@@ -898,12 +898,13 @@ static const AVClass h263_class = {
const FFCodec ff_h263_encoder = {
.p.name = "h263",
- .p.long_name = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996"),
+ CODEC_LONG_NAME("H.263 / H.263-1996"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_H263,
.p.pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE},
.p.priv_class = &h263_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.priv_data_size = sizeof(MpegEncContext),
.init = ff_mpv_encode_init,
FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
@@ -928,13 +929,13 @@ static const AVClass h263p_class = {
const FFCodec ff_h263p_encoder = {
.p.name = "h263p",
- .p.long_name = NULL_IF_CONFIG_SMALL("H.263+ / H.263-1998 / H.263 version 2"),
+ CODEC_LONG_NAME("H.263+ / H.263-1998 / H.263 version 2"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_H263P,
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
.p.priv_class = &h263p_class,
- .p.capabilities = AV_CODEC_CAP_SLICE_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.priv_data_size = sizeof(MpegEncContext),
.init = ff_mpv_encode_init,
FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
diff --git a/libavcodec/ivi.c b/libavcodec/ivi.c
index 6577fa335..43f3cb1da 100644
--- a/libavcodec/ivi.c
+++ b/libavcodec/ivi.c
@@ -34,8 +34,8 @@
#define BITSTREAM_READER_LE
#include "avcodec.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
#include "ivi.h"
#include "ivi_dsp.h"
diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c
index ce77a6d96..6406f90ac 100644
--- a/libavcodec/j2kenc.c
+++ b/libavcodec/j2kenc.c
@@ -507,7 +507,7 @@ static int init_tiles(Jpeg2000EncoderContext *s)
static void copy_frame_ ##D(Jpeg2000EncoderContext *s) \
{ \
int tileno, compno, i, y, x; \
- PIXEL *line; \
+ const PIXEL *line; \
for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ \
Jpeg2000Tile *tile = s->tile + tileno; \
if (s->planar){ \
@@ -515,23 +515,23 @@ static int init_tiles(Jpeg2000EncoderContext *s)
Jpeg2000Component *comp = tile->comp + compno; \
int *dst = comp->i_data; \
int cbps = s->cbps[compno]; \
- line = (PIXEL*)s->picture->data[compno] \
+ line = (const PIXEL*)s->picture->data[compno] \
+ comp->coord[1][0] * (s->picture->linesize[compno] / sizeof(PIXEL)) \
+ comp->coord[0][0]; \
for (y = comp->coord[1][0]; y < comp->coord[1][1]; y++){ \
- PIXEL *ptr = line; \
+ const PIXEL *ptr = line; \
for (x = comp->coord[0][0]; x < comp->coord[0][1]; x++) \
*dst++ = *ptr++ - (1 << (cbps - 1)); \
line += s->picture->linesize[compno] / sizeof(PIXEL); \
} \
} \
} else{ \
- line = (PIXEL*)s->picture->data[0] + tile->comp[0].coord[1][0] * (s->picture->linesize[0] / sizeof(PIXEL)) \
+ line = (const PIXEL*)(s->picture->data[0] + tile->comp[0].coord[1][0] * s->picture->linesize[0]) \
+ tile->comp[0].coord[0][0] * s->ncomponents; \
\
i = 0; \
for (y = tile->comp[0].coord[1][0]; y < tile->comp[0].coord[1][1]; y++){ \
- PIXEL *ptr = line; \
+ const PIXEL *ptr = line; \
for (x = tile->comp[0].coord[0][0]; x < tile->comp[0].coord[0][1]; x++, i++){ \
for (compno = 0; compno < s->ncomponents; compno++){ \
int cbps = s->cbps[compno]; \
@@ -1597,7 +1597,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
update_size(chunkstart, s->buf);
if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
int i;
- uint8_t *palette = pict->data[1];
+ const uint8_t *palette = pict->data[1];
chunkstart = s->buf;
bytestream_put_be32(&s->buf, 0);
bytestream_put_buffer(&s->buf, "pclr", 4);
@@ -1832,9 +1832,10 @@ static const AVClass j2k_class = {
const FFCodec ff_jpeg2000_encoder = {
.p.name = "jpeg2000",
- .p.long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"),
+ CODEC_LONG_NAME("JPEG 2000"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_JPEG2000,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(Jpeg2000EncoderContext),
.init = j2kenc_init,
FF_CODEC_ENCODE_CB(encode_frame),
@@ -1848,5 +1849,5 @@ const FFCodec ff_jpeg2000_encoder = {
AV_PIX_FMT_NONE
},
.p.priv_class = &j2k_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/jacosubdec.c b/libavcodec/jacosubdec.c
index e3bf9f422..08349a9ec 100644
--- a/libavcodec/jacosubdec.c
+++ b/libavcodec/jacosubdec.c
@@ -195,12 +195,11 @@ end:
const FFCodec ff_jacosub_decoder = {
.p.name = "jacosub",
- .p.long_name = NULL_IF_CONFIG_SMALL("JACOsub subtitle"),
+ CODEC_LONG_NAME("JACOsub subtitle"),
.p.type = AVMEDIA_TYPE_SUBTITLE,
.p.id = AV_CODEC_ID_JACOSUB,
.init = ff_ass_subtitle_header_default,
FF_CODEC_DECODE_SUB_CB(jacosub_decode_frame),
.flush = ff_ass_decoder_flush,
.priv_data_size = sizeof(FFASSDecoderContext),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h
index d06313425..e5ecb4cbf 100644
--- a/libavcodec/jpeg2000.h
+++ b/libavcodec/jpeg2000.h
@@ -110,6 +110,8 @@ enum Jpeg2000Quantsty { // quantization style
#define JPEG2000_CSTY_PREC 0x01 // Precincts defined in coding style
#define JPEG2000_CSTY_SOP 0x02 // SOP marker present
#define JPEG2000_CSTY_EPH 0x04 // EPH marker present
+#define JPEG2000_CTSY_HTJ2K_F 0x40 // Only HT code-blocks (Rec. ITU-T T.814 | ISO/IEC 15444-15) are present
+#define JPEG2000_CTSY_HTJ2K_M 0xC0 // HT code blocks (Rec. ITU-T T.814 | ISO/IEC 15444-15) can be present
// Progression orders
#define JPEG2000_PGOD_LRCP 0x00 // Layer-resolution level-component-position progression
diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
index 92966b11f..c2b81ec10 100644
--- a/libavcodec/jpeg2000dec.c
+++ b/libavcodec/jpeg2000dec.c
@@ -37,7 +37,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "thread.h"
#include "jpeg2000.h"
#include "jpeg2000dsp.h"
@@ -521,6 +521,10 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c)
c->cblk_style = bytestream2_get_byteu(&s->g);
if (c->cblk_style != 0) { // cblk style
+ if (c->cblk_style & JPEG2000_CTSY_HTJ2K_M || c->cblk_style & JPEG2000_CTSY_HTJ2K_F) {
+ av_log(s->avctx, AV_LOG_ERROR, "Support for High throughput JPEG 2000 is not yet available\n");
+ return AVERROR_PATCHWELCOME;
+ }
av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style);
if (c->cblk_style & JPEG2000_CBLK_BYPASS)
av_log(s->avctx, AV_LOG_WARNING, "Selective arithmetic coding bypass\n");
@@ -1679,7 +1683,7 @@ static void decode_refpass(Jpeg2000T1Context *t1, int width, int height,
}
}
-static void decode_clnpass(Jpeg2000DecoderContext *s, Jpeg2000T1Context *t1,
+static void decode_clnpass(const Jpeg2000DecoderContext *s, Jpeg2000T1Context *t1,
int width, int height, int bpno, int bandno,
int seg_symbols, int vert_causal_ctx_csty_symbol)
{
@@ -1745,7 +1749,7 @@ static void decode_clnpass(Jpeg2000DecoderContext *s, Jpeg2000T1Context *t1,
}
}
-static int decode_cblk(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty,
+static int decode_cblk(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty,
Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk,
int width, int height, int bandpos, uint8_t roi_shift)
{
@@ -1896,7 +1900,7 @@ static void dequantization_int_97(int x, int y, Jpeg2000Cblk *cblk,
}
}
-static inline void mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
+static inline void mct_decode(const Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
{
int i, csize = 1;
void *src[3];
@@ -1937,7 +1941,7 @@ static inline void roi_scale_cblk(Jpeg2000Cblk *cblk,
}
}
-static inline void tile_codeblocks(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
+static inline void tile_codeblocks(const Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
{
Jpeg2000T1Context t1;
@@ -2009,7 +2013,7 @@ static inline void tile_codeblocks(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile
}
#define WRITE_FRAME(D, PIXEL) \
- static inline void write_frame_ ## D(Jpeg2000DecoderContext * s, Jpeg2000Tile * tile, \
+ static inline void write_frame_ ## D(const Jpeg2000DecoderContext * s, Jpeg2000Tile * tile, \
AVFrame * picture, int precision) \
{ \
const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(s->avctx->pix_fmt); \
@@ -2078,7 +2082,7 @@ WRITE_FRAME(16, uint16_t)
static int jpeg2000_decode_tile(AVCodecContext *avctx, void *td,
int jobnr, int threadnr)
{
- Jpeg2000DecoderContext *s = avctx->priv_data;
+ const Jpeg2000DecoderContext *s = avctx->priv_data;
AVFrame *picture = td;
Jpeg2000Tile *tile = s->tile + jobnr;
@@ -2515,6 +2519,15 @@ static int jpeg2000_decode_frame(AVCodecContext *avctx, AVFrame *picture,
if (ret = jpeg2000_read_main_headers(s))
goto end;
+ if (s->sar.num && s->sar.den)
+ avctx->sample_aspect_ratio = s->sar;
+ s->sar.num = s->sar.den = 0;
+
+ if (avctx->skip_frame >= AVDISCARD_ALL) {
+ jpeg2000_dec_cleanup(s);
+ return avpkt->size;
+ }
+
/* get picture buffer */
if ((ret = ff_thread_get_buffer(avctx, picture, 0)) < 0)
goto end;
@@ -2543,9 +2556,6 @@ static int jpeg2000_decode_frame(AVCodecContext *avctx, AVFrame *picture,
if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
memcpy(picture->data[1], s->palette, 256 * sizeof(uint32_t));
- if (s->sar.num && s->sar.den)
- avctx->sample_aspect_ratio = s->sar;
- s->sar.num = s->sar.den = 0;
return bytestream2_tell(&s->g);
@@ -2572,7 +2582,7 @@ static const AVClass jpeg2000_class = {
const FFCodec ff_jpeg2000_decoder = {
.p.name = "jpeg2000",
- .p.long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"),
+ CODEC_LONG_NAME("JPEG 2000"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_JPEG2000,
.p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_DR1,
@@ -2582,5 +2592,5 @@ const FFCodec ff_jpeg2000_decoder = {
.p.priv_class = &jpeg2000_class,
.p.max_lowres = 5,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_jpeg2000_profiles),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
+ .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
};
diff --git a/libavcodec/jpeg2000dsp.c b/libavcodec/jpeg2000dsp.c
index b61be3b72..b1bff6d5b 100644
--- a/libavcodec/jpeg2000dsp.c
+++ b/libavcodec/jpeg2000dsp.c
@@ -76,14 +76,13 @@ static void ict_int(void *_src0, void *_src1, void *_src2, int csize)
static void rct_int(void *_src0, void *_src1, void *_src2, int csize)
{
- int32_t *src0 = _src0, *src1 = _src1, *src2 = _src2;
- int32_t i0, i1, i2;
+ uint32_t *src0 = _src0, *src1 = _src1, *src2 = _src2;
int i;
for (i = 0; i < csize; i++) {
- i1 = *src0 - (*src2 + *src1 >> 2);
- i0 = i1 + *src2;
- i2 = i1 + *src1;
+ uint32_t i1 = *src0 - ((int32_t)(*src2 + *src1) >> 2);
+ int32_t i0 = i1 + *src2;
+ int32_t i2 = i1 + *src1;
*src0++ = i0;
*src1++ = i1;
*src2++ = i2;
diff --git a/libavcodec/jpeg2000dwt.c b/libavcodec/jpeg2000dwt.c
index f2da7307c..34e33553f 100644
--- a/libavcodec/jpeg2000dwt.c
+++ b/libavcodec/jpeg2000dwt.c
@@ -81,7 +81,7 @@ static void sd_1d53(int *p, int i0, int i1)
if (i1 <= i0 + 1) {
if (i0 == 1)
- p[1] <<= 1;
+ p[1] *= 2;
return;
}
diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c
index ab663dc1f..ec163b896 100644
--- a/libavcodec/jpeglsdec.c
+++ b/libavcodec/jpeglsdec.c
@@ -552,14 +552,13 @@ end:
const FFCodec ff_jpegls_decoder = {
.p.name = "jpegls",
- .p.long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"),
+ CODEC_LONG_NAME("JPEG-LS"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_JPEGLS,
.priv_data_size = sizeof(MJpegDecodeContext),
.init = ff_mjpeg_decode_init,
.close = ff_mjpeg_decode_end,
- FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame),
+ FF_CODEC_DECODE_CB(ff_mjpeg_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
- FF_CODEC_CAP_SETS_PKT_DTS,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c
index 577e8a19d..53394102d 100644
--- a/libavcodec/jpeglsenc.c
+++ b/libavcodec/jpeglsenc.c
@@ -413,8 +413,6 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt,
/* End of image */
put_marker_byteu(&pb, EOI);
- emms_c();
-
av_shrink_packet(pkt, bytestream2_tell_p(&pb));
*got_packet = 1;
return 0;
@@ -475,10 +473,11 @@ static const AVClass jpegls_class = {
const FFCodec ff_jpegls_encoder = {
.p.name = "jpegls",
- .p.long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"),
+ CODEC_LONG_NAME("JPEG-LS"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_JPEGLS,
- .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(JPEGLSContext),
.p.priv_class = &jpegls_class,
.init = encode_jpegls_init,
@@ -489,6 +488,5 @@ const FFCodec ff_jpegls_encoder = {
AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16,
AV_PIX_FMT_NONE
},
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/jpegquanttables.c b/libavcodec/jpegquanttables.c
new file mode 100644
index 000000000..2ab50016c
--- /dev/null
+++ b/libavcodec/jpegquanttables.c
@@ -0,0 +1,54 @@
+/*
+ * MJPEG encoder and decoder
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2003 Alex Beregszaszi
+ * Copyright (c) 2003-2004 Michael Niedermayer
+ *
+ * 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
+ * MJPEG quantization tables
+ */
+
+#include "jpegquanttables.h"
+
+/* These are the sample quantization tables given in JPEG spec section K.1.
+ * The spec says that the values given produce "good" quality, and
+ * when divided by 2, "very good" quality.
+ */
+const uint8_t ff_mjpeg_std_luminance_quant_tbl[64] = {
+ 16, 11, 10, 16, 24, 40, 51, 61,
+ 12, 12, 14, 19, 26, 58, 60, 55,
+ 14, 13, 16, 24, 40, 57, 69, 56,
+ 14, 17, 22, 29, 51, 87, 80, 62,
+ 18, 22, 37, 56, 68, 109, 103, 77,
+ 24, 35, 55, 64, 81, 104, 113, 92,
+ 49, 64, 78, 87, 103, 121, 120, 101,
+ 72, 92, 95, 98, 112, 100, 103, 99
+};
+const uint8_t ff_mjpeg_std_chrominance_quant_tbl[64] = {
+ 17, 18, 24, 47, 99, 99, 99, 99,
+ 18, 21, 26, 66, 99, 99, 99, 99,
+ 24, 26, 56, 99, 99, 99, 99, 99,
+ 47, 66, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99
+};
diff --git a/libavcodec/rv10.h b/libavcodec/jpegquanttables.h
similarity index 69%
rename from libavcodec/rv10.h
rename to libavcodec/jpegquanttables.h
index 364270e76..48a342987 100644
--- a/libavcodec/rv10.h
+++ b/libavcodec/jpegquanttables.h
@@ -1,5 +1,5 @@
/*
- * RV10/RV20 decoder
+ * MJPEG quantization tables
*
* This file is part of FFmpeg.
*
@@ -18,16 +18,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef AVCODEC_RV10_H
-#define AVCODEC_RV10_H
+#ifndef AVCODEC_JPEGQUANTTABLES_H
+#define AVCODEC_JPEGQUANTTABLES_H
#include
+#include "libavutil/attributes_internal.h"
-#include "mpegvideo.h"
+FF_VISIBILITY_PUSH_HIDDEN
+extern const uint8_t ff_mjpeg_std_luminance_quant_tbl[64];
+extern const uint8_t ff_mjpeg_std_chrominance_quant_tbl[64];
+FF_VISIBILITY_POP_HIDDEN
-int ff_rv_decode_dc(MpegEncContext *s, int n);
-
-int ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number);
-void ff_rv20_encode_picture_header(MpegEncContext *s, int picture_number);
-
-#endif /* AVCODEC_RV10_H */
+#endif /* AVCODEC_JPEGQUANTTABLES_H */
diff --git a/libavcodec/jpegtables.c b/libavcodec/jpegtables.c
index e453fcf90..9a15975a9 100644
--- a/libavcodec/jpegtables.c
+++ b/libavcodec/jpegtables.c
@@ -31,30 +31,3 @@
*/
#include "jpegtabs.h"
-
-#if 0
-/* These are the sample quantization tables given in JPEG spec section K.1.
- * The spec says that the values given produce "good" quality, and
- * when divided by 2, "very good" quality.
- */
-static const unsigned char std_luminance_quant_tbl[64] = {
- 16, 11, 10, 16, 24, 40, 51, 61,
- 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 56, 68, 109, 103, 77,
- 24, 35, 55, 64, 81, 104, 113, 92,
- 49, 64, 78, 87, 103, 121, 120, 101,
- 72, 92, 95, 98, 112, 100, 103, 99
-};
-static const unsigned char std_chrominance_quant_tbl[64] = {
- 17, 18, 24, 47, 99, 99, 99, 99,
- 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 66, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99
-};
-#endif
diff --git a/libavcodec/jpegtables.h b/libavcodec/jpegtables.h
index 49b5ecdeb..39baec3ef 100644
--- a/libavcodec/jpegtables.h
+++ b/libavcodec/jpegtables.h
@@ -23,6 +23,9 @@
#include
+#include "libavutil/attributes_internal.h"
+
+FF_VISIBILITY_PUSH_HIDDEN
extern const uint8_t ff_mjpeg_bits_dc_luminance[];
extern const uint8_t ff_mjpeg_val_dc[];
@@ -33,5 +36,6 @@ extern const uint8_t ff_mjpeg_val_ac_luminance[];
extern const uint8_t ff_mjpeg_bits_ac_chrominance[];
extern const uint8_t ff_mjpeg_val_ac_chrominance[];
+FF_VISIBILITY_POP_HIDDEN
#endif /* AVCODEC_JPEGTABLES_H */
diff --git a/libavcodec/jrevdct.c b/libavcodec/jrevdct.c
index 36160cb66..7f1863515 100644
--- a/libavcodec/jrevdct.c
+++ b/libavcodec/jrevdct.c
@@ -255,7 +255,7 @@ void ff_j_rev_dct(DCTBLOCK data)
if (d0) {
/* Compute a 32 bit value to assign. */
int16_t dcval = (int16_t) (d0 * (1 << PASS1_BITS));
- register int v = (dcval & 0xffff) | ((dcval * (1 << 16)) & 0xffff0000);
+ register unsigned v = (dcval & 0xffff) | ((uint32_t)dcval << 16);
AV_WN32A(&idataptr[ 0], v);
AV_WN32A(&idataptr[ 4], v);
@@ -988,8 +988,8 @@ void ff_j_rev_dct4(DCTBLOCK data)
/* AC terms all zero */
if (d0) {
/* Compute a 32 bit value to assign. */
- int16_t dcval = (int16_t) (d0 << PASS1_BITS);
- register int v = (dcval & 0xffff) | ((dcval << 16) & 0xffff0000);
+ int16_t dcval = (int16_t) (d0 * (1 << PASS1_BITS));
+ register unsigned v = (dcval & 0xffff) | ((uint32_t)dcval << 16);
AV_WN32A(&idataptr[0], v);
AV_WN32A(&idataptr[4], v);
@@ -1008,8 +1008,8 @@ void ff_j_rev_dct4(DCTBLOCK data)
tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065);
tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865);
- tmp0 = (d0 + d4) << CONST_BITS;
- tmp1 = (d0 - d4) << CONST_BITS;
+ tmp0 = (d0 + d4) * (1 << CONST_BITS);
+ tmp1 = (d0 - d4) * (1 << CONST_BITS);
tmp10 = tmp0 + tmp3;
tmp13 = tmp0 - tmp3;
@@ -1020,8 +1020,8 @@ void ff_j_rev_dct4(DCTBLOCK data)
tmp2 = MULTIPLY(-d6, FIX_1_306562965);
tmp3 = MULTIPLY(d6, FIX_0_541196100);
- tmp0 = (d0 + d4) << CONST_BITS;
- tmp1 = (d0 - d4) << CONST_BITS;
+ tmp0 = (d0 + d4) * (1 << CONST_BITS);
+ tmp1 = (d0 - d4) * (1 << CONST_BITS);
tmp10 = tmp0 + tmp3;
tmp13 = tmp0 - tmp3;
@@ -1034,8 +1034,8 @@ void ff_j_rev_dct4(DCTBLOCK data)
tmp2 = MULTIPLY(d2, FIX_0_541196100);
tmp3 = MULTIPLY(d2, FIX_1_306562965);
- tmp0 = (d0 + d4) << CONST_BITS;
- tmp1 = (d0 - d4) << CONST_BITS;
+ tmp0 = (d0 + d4) * (1 << CONST_BITS);
+ tmp1 = (d0 - d4) * (1 << CONST_BITS);
tmp10 = tmp0 + tmp3;
tmp13 = tmp0 - tmp3;
@@ -1043,8 +1043,8 @@ void ff_j_rev_dct4(DCTBLOCK data)
tmp12 = tmp1 - tmp2;
} else {
/* d0 != 0, d2 == 0, d4 != 0, d6 == 0 */
- tmp10 = tmp13 = (d0 + d4) << CONST_BITS;
- tmp11 = tmp12 = (d0 - d4) << CONST_BITS;
+ tmp10 = tmp13 = (d0 + d4) * (1 << CONST_BITS);
+ tmp11 = tmp12 = (d0 - d4) * (1 << CONST_BITS);
}
}
@@ -1086,8 +1086,8 @@ void ff_j_rev_dct4(DCTBLOCK data)
tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065);
tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865);
- tmp0 = (d0 + d4) << CONST_BITS;
- tmp1 = (d0 - d4) << CONST_BITS;
+ tmp0 = (d0 + d4) * (1 << CONST_BITS);
+ tmp1 = (d0 - d4) * (1 << CONST_BITS);
tmp10 = tmp0 + tmp3;
tmp13 = tmp0 - tmp3;
@@ -1098,8 +1098,8 @@ void ff_j_rev_dct4(DCTBLOCK data)
tmp2 = MULTIPLY(-d6, FIX_1_306562965);
tmp3 = MULTIPLY(d6, FIX_0_541196100);
- tmp0 = (d0 + d4) << CONST_BITS;
- tmp1 = (d0 - d4) << CONST_BITS;
+ tmp0 = (d0 + d4) * (1 << CONST_BITS);
+ tmp1 = (d0 - d4) * (1 << CONST_BITS);
tmp10 = tmp0 + tmp3;
tmp13 = tmp0 - tmp3;
@@ -1112,8 +1112,8 @@ void ff_j_rev_dct4(DCTBLOCK data)
tmp2 = MULTIPLY(d2, FIX_0_541196100);
tmp3 = MULTIPLY(d2, FIX_1_306562965);
- tmp0 = (d0 + d4) << CONST_BITS;
- tmp1 = (d0 - d4) << CONST_BITS;
+ tmp0 = (d0 + d4) * (1 << CONST_BITS);
+ tmp1 = (d0 - d4) * (1 << CONST_BITS);
tmp10 = tmp0 + tmp3;
tmp13 = tmp0 - tmp3;
@@ -1121,8 +1121,8 @@ void ff_j_rev_dct4(DCTBLOCK data)
tmp12 = tmp1 - tmp2;
} else {
/* d0 != 0, d2 == 0, d4 != 0, d6 == 0 */
- tmp10 = tmp13 = (d0 + d4) << CONST_BITS;
- tmp11 = tmp12 = (d0 - d4) << CONST_BITS;
+ tmp10 = tmp13 = (d0 + d4) * (1 << CONST_BITS);
+ tmp11 = tmp12 = (d0 - d4) * (1 << CONST_BITS);
}
}
diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c
index 06015ba59..e0287a9cb 100644
--- a/libavcodec/jvdec.c
+++ b/libavcodec/jvdec.c
@@ -30,8 +30,8 @@
#include "avcodec.h"
#include "blockdsp.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "internal.h"
typedef struct JvContext {
BlockDSPContext bdsp;
@@ -56,7 +56,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
return AVERROR(ENOMEM);
avctx->pix_fmt = AV_PIX_FMT_PAL8;
- ff_blockdsp_init(&s->bdsp, avctx);
+ ff_blockdsp_init(&s->bdsp);
return 0;
}
@@ -236,7 +236,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
const FFCodec ff_jv_decoder = {
.p.name = "jv",
- .p.long_name = NULL_IF_CONFIG_SMALL("Bitmap Brothers JV video"),
+ CODEC_LONG_NAME("Bitmap Brothers JV video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_JV,
.priv_data_size = sizeof(JvContext),
@@ -244,5 +244,4 @@ const FFCodec ff_jv_decoder = {
.close = decode_close,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c
index 08e92c710..139ec9b05 100644
--- a/libavcodec/kgv1dec.c
+++ b/libavcodec/kgv1dec.c
@@ -29,7 +29,7 @@
#include "libavutil/imgutils.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
typedef struct KgvContext {
uint16_t *frame_buffer;
@@ -178,7 +178,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
const FFCodec ff_kgv1_decoder = {
.p.name = "kgv1",
- .p.long_name = NULL_IF_CONFIG_SMALL("Kega Game Video"),
+ CODEC_LONG_NAME("Kega Game Video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_KGV1,
.priv_data_size = sizeof(KgvContext),
@@ -187,5 +187,4 @@ const FFCodec ff_kgv1_decoder = {
FF_CODEC_DECODE_CB(decode_frame),
.flush = decode_flush,
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c
index a009ba0ce..153cea03b 100644
--- a/libavcodec/kmvc.c
+++ b/libavcodec/kmvc.c
@@ -25,13 +25,11 @@
*/
#include
-#include
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
#include "decode.h"
-#include "internal.h"
#include "libavutil/common.h"
#define KMVC_KEYFRAME 0x80
@@ -406,12 +404,11 @@ static av_cold int decode_init(AVCodecContext * avctx)
const FFCodec ff_kmvc_decoder = {
.p.name = "kmvc",
- .p.long_name = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"),
+ CODEC_LONG_NAME("Karl Morton's video codec"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_KMVC,
.priv_data_size = sizeof(KmvcContext),
.init = decode_init,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c
index 00e800522..78ccbc15b 100644
--- a/libavcodec/lagarith.c
+++ b/libavcodec/lagarith.c
@@ -730,12 +730,11 @@ static av_cold int lag_decode_init(AVCodecContext *avctx)
const FFCodec ff_lagarith_decoder = {
.p.name = "lagarith",
- .p.long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"),
+ CODEC_LONG_NAME("Lagarith lossless"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_LAGARITH,
.priv_data_size = sizeof(LagarithContext),
.init = lag_decode_init,
FF_CODEC_DECODE_CB(lag_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c
index ffa2fe5a6..5cc0a29bc 100644
--- a/libavcodec/lcldec.c
+++ b/libavcodec/lcldec.c
@@ -632,7 +632,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
#if CONFIG_MSZH_DECODER
const FFCodec ff_mszh_decoder = {
.p.name = "mszh",
- .p.long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"),
+ CODEC_LONG_NAME("LCL (LossLess Codec Library) MSZH"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_MSZH,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
@@ -640,14 +640,14 @@ const FFCodec ff_mszh_decoder = {
.init = decode_init,
.close = decode_end,
FF_CODEC_DECODE_CB(decode_frame),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
#endif
#if CONFIG_ZLIB_DECODER
const FFCodec ff_zlib_decoder = {
.p.name = "zlib",
- .p.long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
+ CODEC_LONG_NAME("LCL (LossLess Codec Library) ZLIB"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_ZLIB,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
@@ -655,6 +655,6 @@ const FFCodec ff_zlib_decoder = {
.init = decode_init,
.close = decode_end,
FF_CODEC_DECODE_CB(decode_frame),
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
#endif
diff --git a/libavcodec/lclenc.c b/libavcodec/lclenc.c
index bd42c155a..dd5eed9d6 100644
--- a/libavcodec/lclenc.c
+++ b/libavcodec/lclenc.c
@@ -153,15 +153,15 @@ static av_cold int encode_end(AVCodecContext *avctx)
const FFCodec ff_zlib_encoder = {
.p.name = "zlib",
- .p.long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
+ CODEC_LONG_NAME("LCL (LossLess Codec Library) ZLIB"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_ZLIB,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(LclEncContext),
.init = encode_init,
FF_CODEC_ENCODE_CB(encode_frame),
.close = encode_end,
- .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/tests/imgconvert.c b/libavcodec/libaom.c
similarity index 51%
rename from libavcodec/tests/imgconvert.c
rename to libavcodec/libaom.c
index aefc324bf..0befaaa53 100644
--- a/libavcodec/tests/imgconvert.c
+++ b/libavcodec/libaom.c
@@ -1,7 +1,4 @@
/*
- * Misc image conversion routines
- * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
- *
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
@@ -19,28 +16,34 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "libavcodec/imgconvert.c"
+/**
+ * @file
+ * AOM common functions
+ */
-#if FF_API_AVPICTURE
-FF_DISABLE_DEPRECATION_WARNINGS
-int main(void){
+#include "libavutil/pixdesc.h"
+#include "libaom.h"
+
+void ff_aom_image_copy_16_to_8(AVFrame *pic, struct aom_image *img)
+{
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format);
int i;
- int err=0;
- int skip = 0;
- for (i=0; iname) {
- skip ++;
- continue;
+ for (i = 0; i < desc->nb_components; i++) {
+ int w = img->d_w;
+ int h = img->d_h;
+ int x, y;
+
+ if (i) {
+ w = (w + img->x_chroma_shift) >> img->x_chroma_shift;
+ h = (h + img->y_chroma_shift) >> img->y_chroma_shift;
}
- if (skip) {
- av_log(NULL, AV_LOG_INFO, "%3d unused pixel format values\n", skip);
- skip = 0;
+
+ for (y = 0; y < h; y++) {
+ uint16_t *src = (uint16_t *)(img->planes[i] + y * img->stride[i]);
+ uint8_t *dst = pic->data[i] + y * pic->linesize[i];
+ for (x = 0; x < w; x++)
+ *dst++ = *src++;
}
- av_log(NULL, AV_LOG_INFO, "pix fmt %s yuv_plan:%d avg_bpp:%d\n", desc->name, is_yuv_planar(desc), av_get_padded_bits_per_pixel(desc));
}
- return err;
}
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif /* FF_API_AVPICTURE */
diff --git a/libavcodec/libaom.h b/libavcodec/libaom.h
new file mode 100644
index 000000000..bb495af98
--- /dev/null
+++ b/libavcodec/libaom.h
@@ -0,0 +1,33 @@
+/*
+ * 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
+ * AOM common functions
+ */
+
+#ifndef AVCODEC_LIBAOM_H
+#define AVCODEC_LIBAOM_H
+
+#include
+
+#include "libavutil/frame.h"
+
+void ff_aom_image_copy_16_to_8(AVFrame *pic, struct aom_image *img);
+
+#endif /* AVCODEC_LIBAOM_H */
diff --git a/libavcodec/libaomdec.c b/libavcodec/libaomdec.c
index 52a8bf19e..53982559d 100644
--- a/libavcodec/libaomdec.c
+++ b/libavcodec/libaomdec.c
@@ -32,7 +32,8 @@
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
+#include "libaom.h"
#include "profiles.h"
typedef struct AV1DecodeContext {
@@ -60,30 +61,6 @@ static av_cold int aom_init(AVCodecContext *avctx,
return 0;
}
-static void image_copy_16_to_8(AVFrame *pic, struct aom_image *img)
-{
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format);
- int i;
-
- for (i = 0; i < desc->nb_components; i++) {
- int w = img->d_w;
- int h = img->d_h;
- int x, y;
-
- if (i) {
- w = (w + img->x_chroma_shift) >> img->x_chroma_shift;
- h = (h + img->y_chroma_shift) >> img->y_chroma_shift;
- }
-
- for (y = 0; y < h; y++) {
- uint16_t *src = (uint16_t *)(img->planes[i] + y * img->stride[i]);
- uint8_t *dst = pic->data[i] + y * pic->linesize[i];
- for (x = 0; x < w; x++)
- *dst++ = *src++;
- }
- }
-}
-
// returns 0 on success, AVERROR_INVALIDDATA otherwise
static int set_pix_fmt(AVCodecContext *avctx, struct aom_image *img)
{
@@ -136,15 +113,19 @@ static int set_pix_fmt(AVCodecContext *avctx, struct aom_image *img)
case AOM_IMG_FMT_I444:
case AOM_IMG_FMT_I44416:
if (img->bit_depth == 8) {
- avctx->pix_fmt = AV_PIX_FMT_YUV444P;
+ avctx->pix_fmt = avctx->colorspace == AVCOL_SPC_RGB ?
+ AV_PIX_FMT_GBRP : AV_PIX_FMT_YUV444P;
avctx->profile = FF_PROFILE_AV1_HIGH;
return 0;
} else if (img->bit_depth == 10) {
avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
+ avctx->pix_fmt = avctx->colorspace == AVCOL_SPC_RGB ?
+ AV_PIX_FMT_GBRP10 : AV_PIX_FMT_YUV444P10;
avctx->profile = FF_PROFILE_AV1_HIGH;
return 0;
} else if (img->bit_depth == 12) {
- avctx->pix_fmt = AV_PIX_FMT_YUV444P12;
+ avctx->pix_fmt = avctx->colorspace == AVCOL_SPC_RGB ?
+ AV_PIX_FMT_GBRP12 : AV_PIX_FMT_YUV444P12;
avctx->profile = FF_PROFILE_AV1_PROFESSIONAL;
return 0;
} else {
@@ -223,7 +204,7 @@ static int aom_decode(AVCodecContext *avctx, AVFrame *picture,
ff_set_sar(avctx, picture->sample_aspect_ratio);
if ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) && img->bit_depth == 8)
- image_copy_16_to_8(picture, img);
+ ff_aom_image_copy_16_to_8(picture, img);
else {
const uint8_t *planes[4] = { img->planes[0], img->planes[1], img->planes[2] };
const int stride[4] = { img->stride[0], img->stride[1], img->stride[2] };
@@ -250,7 +231,7 @@ static av_cold int av1_init(AVCodecContext *avctx)
const FFCodec ff_libaom_av1_decoder = {
.p.name = "libaom-av1",
- .p.long_name = NULL_IF_CONFIG_SMALL("libaom AV1"),
+ CODEC_LONG_NAME("libaom AV1"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AV1,
.priv_data_size = sizeof(AV1DecodeContext),
@@ -258,7 +239,8 @@ const FFCodec ff_libaom_av1_decoder = {
.close = aom_free,
FF_CODEC_DECODE_CB(aom_decode),
.p.capabilities = AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_AUTO_THREADS,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_AUTO_THREADS,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles),
.p.wrapper_name = "libaom",
};
diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
index 6b7e426bf..0b88102c7 100644
--- a/libavcodec/libaomenc.c
+++ b/libavcodec/libaomenc.c
@@ -23,6 +23,8 @@
* AV1 encoder support via libaom
*/
+#include
+
#define AOM_DISABLE_CTRL_TYPECHECKS 1
#include
#include
@@ -31,6 +33,7 @@
#include "libavutil/base64.h"
#include "libavutil/common.h"
#include "libavutil/cpu.h"
+#include "libavutil/imgutils.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
@@ -41,6 +44,7 @@
#include "codec_internal.h"
#include "encode.h"
#include "internal.h"
+#include "libaom.h"
#include "packet_internal.h"
#include "profiles.h"
@@ -68,6 +72,7 @@ typedef struct AOMEncoderContext {
struct aom_codec_ctx encoder;
struct aom_image rawimg;
struct aom_fixed_buf twopass_stats;
+ unsigned twopass_stats_size;
struct FrameListData *coded_frame_list;
int cpu_used;
int auto_alt_ref;
@@ -208,6 +213,7 @@ static const char *const ctlidstr[] = {
#ifdef AOM_CTRL_AV1E_GET_TARGET_SEQ_LEVEL_IDX
[AV1E_GET_TARGET_SEQ_LEVEL_IDX] = "AV1E_GET_TARGET_SEQ_LEVEL_IDX",
#endif
+ [AV1_GET_NEW_FRAME_IMAGE] = "AV1_GET_NEW_FRAME_IMAGE",
};
static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc)
@@ -364,6 +370,31 @@ static av_cold int codecctl_intp(AVCodecContext *avctx,
}
#endif
+static av_cold int codecctl_imgp(AVCodecContext *avctx,
+#ifdef UENUM1BYTE
+ aome_enc_control_id id,
+#else
+ enum aome_enc_control_id id,
+#endif
+ struct aom_image *img)
+{
+ AOMContext *ctx = avctx->priv_data;
+ char buf[80];
+ int res;
+
+ snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]);
+
+ res = aom_codec_control(&ctx->encoder, id, img);
+ if (res != AOM_CODEC_OK) {
+ snprintf(buf, sizeof(buf), "Failed to get %s codec control",
+ ctlidstr[id]);
+ log_encoder_error(avctx, buf);
+ return AVERROR(EINVAL);
+ }
+
+ return 0;
+}
+
static av_cold int aom_free(AVCodecContext *avctx)
{
AOMContext *ctx = avctx->priv_data;
@@ -371,7 +402,7 @@ static av_cold int aom_free(AVCodecContext *avctx)
#if defined(AOM_CTRL_AV1E_GET_NUM_OPERATING_POINTS) && \
defined(AOM_CTRL_AV1E_GET_SEQ_LEVEL_IDX) && \
defined(AOM_CTRL_AV1E_GET_TARGET_SEQ_LEVEL_IDX)
- if (!(avctx->flags & AV_CODEC_FLAG_PASS1)) {
+ if (ctx->encoder.iface && !(avctx->flags & AV_CODEC_FLAG_PASS1)) {
int num_operating_points;
int levels[32];
int target_levels[32];
@@ -1065,6 +1096,7 @@ static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame,
}
memcpy(pkt->data, cx_frame->buf, pkt->size);
pkt->pts = pkt->dts = cx_frame->pts;
+ pkt->duration = cx_frame->duration;
if (!!(cx_frame->flags & AOM_FRAME_IS_KEY)) {
pkt->flags |= AV_PKT_FLAG_KEY;
@@ -1172,14 +1204,17 @@ static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out)
case AOM_CODEC_STATS_PKT:
{
struct aom_fixed_buf *stats = &ctx->twopass_stats;
- int err;
- if ((err = av_reallocp(&stats->buf,
- stats->sz +
- pkt->data.twopass_stats.sz)) < 0) {
+ uint8_t *tmp = av_fast_realloc(stats->buf,
+ &ctx->twopass_stats_size,
+ stats->sz +
+ pkt->data.twopass_stats.sz);
+ if (!tmp) {
+ av_freep(&stats->buf);
stats->sz = 0;
av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n");
- return err;
+ return AVERROR(ENOMEM);
}
+ stats->buf = tmp;
memcpy((uint8_t *)stats->buf + stats->sz,
pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz);
stats->sz += pkt->data.twopass_stats.sz;
@@ -1206,12 +1241,44 @@ static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out)
return size;
}
+static enum AVPixelFormat aomfmt_to_pixfmt(struct aom_image *img)
+{
+ switch (img->fmt) {
+ case AOM_IMG_FMT_I420:
+ case AOM_IMG_FMT_I42016:
+ if (img->bit_depth == 8)
+ return img->monochrome ? AV_PIX_FMT_GRAY8 : AV_PIX_FMT_YUV420P;
+ else if (img->bit_depth == 10)
+ return img->monochrome ? AV_PIX_FMT_GRAY10 : AV_PIX_FMT_YUV420P10;
+ else
+ return img->monochrome ? AV_PIX_FMT_GRAY12 : AV_PIX_FMT_YUV420P12;
+ case AOM_IMG_FMT_I422:
+ case AOM_IMG_FMT_I42216:
+ if (img->bit_depth == 8)
+ return AV_PIX_FMT_YUV422P;
+ else if (img->bit_depth == 10)
+ return AV_PIX_FMT_YUV422P10;
+ else
+ return AV_PIX_FMT_YUV422P12;
+ case AOM_IMG_FMT_I444:
+ case AOM_IMG_FMT_I44416:
+ if (img->bit_depth == 8)
+ return AV_PIX_FMT_YUV444P;
+ else if (img->bit_depth == 10)
+ return AV_PIX_FMT_YUV444P10;
+ else
+ return AV_PIX_FMT_YUV444P12;
+ };
+ return AV_PIX_FMT_NONE;
+}
+
static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *frame, int *got_packet)
{
AOMContext *ctx = avctx->priv_data;
struct aom_image *rawimg = NULL;
int64_t timestamp = 0;
+ unsigned long duration = 0;
int res, coded_size;
aom_enc_frame_flags_t flags = 0;
@@ -1224,6 +1291,13 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
rawimg->stride[AOM_PLANE_U] = frame->linesize[1];
rawimg->stride[AOM_PLANE_V] = frame->linesize[2];
timestamp = frame->pts;
+
+ if (frame->duration > ULONG_MAX) {
+ av_log(avctx, AV_LOG_WARNING,
+ "Frame duration too large: %"PRId64"\n", frame->duration);
+ } else
+ duration = frame->duration ? frame->duration : avctx->ticks_per_frame;
+
switch (frame->color_range) {
case AVCOL_RANGE_MPEG:
rawimg->range = AOM_CR_STUDIO_RANGE;
@@ -1237,13 +1311,14 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
flags |= AOM_EFLAG_FORCE_KF;
}
- res = aom_codec_encode(&ctx->encoder, rawimg, timestamp,
- avctx->ticks_per_frame, flags);
+ res = aom_codec_encode(&ctx->encoder, rawimg, timestamp, duration, flags);
if (res != AOM_CODEC_OK) {
log_encoder_error(avctx, "Error encoding frame");
return AVERROR_INVALIDDATA;
}
coded_size = queue_frames(avctx, pkt);
+ if (coded_size < 0)
+ return coded_size;
if (!frame && avctx->flags & AV_CODEC_FLAG_PASS1) {
size_t b64_size = AV_BASE64_SIZE(ctx->twopass_stats.sz);
@@ -1259,6 +1334,43 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
}
*got_packet = !!coded_size;
+
+ if (*got_packet && avctx->flags & AV_CODEC_FLAG_RECON_FRAME) {
+ AVCodecInternal *avci = avctx->internal;
+ struct aom_image img;
+
+ av_frame_unref(avci->recon_frame);
+
+ res = codecctl_imgp(avctx, AV1_GET_NEW_FRAME_IMAGE, &img);
+ if (res < 0)
+ return res;
+
+ avci->recon_frame->format = aomfmt_to_pixfmt(&img);
+ if (avci->recon_frame->format == AV_PIX_FMT_NONE) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Unhandled reconstructed frame colorspace: %d\n",
+ img.fmt);
+ return AVERROR(ENOSYS);
+ }
+
+ avci->recon_frame->width = img.d_w;
+ avci->recon_frame->height = img.d_h;
+
+ res = av_frame_get_buffer(avci->recon_frame, 0);
+ if (res < 0)
+ return res;
+
+ if ((img.fmt & AOM_IMG_FMT_HIGHBITDEPTH) && img.bit_depth == 8)
+ ff_aom_image_copy_16_to_8(avci->recon_frame, &img);
+ else {
+ const uint8_t *planes[4] = { img.planes[0], img.planes[1], img.planes[2] };
+ const int stride[4] = { img.stride[0], img.stride[1], img.stride[2] };
+
+ av_image_copy(avci->recon_frame->data, avci->recon_frame->linesize, planes,
+ stride, avci->recon_frame->format, img.d_w, img.d_h);
+ }
+ }
+
return 0;
}
@@ -1430,10 +1542,11 @@ static const AVClass class_aom = {
FFCodec ff_libaom_av1_encoder = {
.p.name = "libaom-av1",
- .p.long_name = NULL_IF_CONFIG_SMALL("libaom AV1"),
+ CODEC_LONG_NAME("libaom AV1"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AV1,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_ENCODER_RECON_FRAME |
AV_CODEC_CAP_OTHER_THREADS,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles),
.p.priv_class = &class_aom,
@@ -1442,7 +1555,9 @@ FFCodec ff_libaom_av1_encoder = {
.init = av1_init,
FF_CODEC_ENCODE_CB(aom_encode),
.close = aom_free,
- .caps_internal = FF_CODEC_CAP_AUTO_THREADS,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_INIT_CLEANUP |
+ FF_CODEC_CAP_AUTO_THREADS,
.defaults = defaults,
.init_static_data = av1_init_static,
};
diff --git a/libavcodec/libaribb24.c b/libavcodec/libaribb24.c
index 9658e1d5a..8ccf3c4b5 100644
--- a/libavcodec/libaribb24.c
+++ b/libavcodec/libaribb24.c
@@ -40,10 +40,18 @@ typedef struct Libaribb24Context {
char *aribb24_base_path;
unsigned int aribb24_skip_ruby;
+
+ int default_profile;
} Libaribb24Context;
-static unsigned int get_profile_font_size(int profile)
+static unsigned int get_profile_font_size(AVCodecContext *avctx)
{
+ Libaribb24Context *b24 = avctx->priv_data;
+ int profile = avctx->profile;
+
+ if (profile == FF_PROFILE_UNKNOWN)
+ profile = b24->default_profile;
+
switch (profile) {
case FF_PROFILE_ARIB_PROFILE_A:
return 36;
@@ -61,26 +69,31 @@ static void libaribb24_log(void *p, const char *msg)
static int libaribb24_generate_ass_header(AVCodecContext *avctx)
{
+ Libaribb24Context *b24 = avctx->priv_data;
unsigned int plane_width = 0;
unsigned int plane_height = 0;
unsigned int font_size = 0;
+ int profile = avctx->profile;
- switch (avctx->profile) {
+ if (profile == FF_PROFILE_UNKNOWN)
+ profile = b24->default_profile;
+
+ switch (profile) {
case FF_PROFILE_ARIB_PROFILE_A:
plane_width = 960;
plane_height = 540;
- font_size = get_profile_font_size(avctx->profile);
break;
case FF_PROFILE_ARIB_PROFILE_C:
plane_width = 320;
plane_height = 180;
- font_size = get_profile_font_size(avctx->profile);
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unknown or unsupported profile set!\n");
return AVERROR(EINVAL);
}
+ font_size = get_profile_font_size(avctx);
+
avctx->subtitle_header = av_asprintf(
"[Script Info]\r\n"
"; Script generated by FFmpeg/Lavc%s\r\n"
@@ -135,6 +148,7 @@ static int libaribb24_init(AVCodecContext *avctx)
Libaribb24Context *b24 = avctx->priv_data;
void(* arib_dec_init)(arib_decoder_t* decoder) = NULL;
int ret_code = AVERROR_EXTERNAL;
+ int profile = avctx->profile;
if (!(b24->lib_instance = arib_instance_new(avctx))) {
av_log(avctx, AV_LOG_ERROR, "Failed to initialize libaribb24!\n");
@@ -158,7 +172,10 @@ static int libaribb24_init(AVCodecContext *avctx)
goto init_fail;
}
- switch (avctx->profile) {
+ if (profile == FF_PROFILE_UNKNOWN)
+ profile = b24->default_profile;
+
+ switch (profile) {
case FF_PROFILE_ARIB_PROFILE_A:
arib_dec_init = arib_initialize_decoder_a_profile;
break;
@@ -209,7 +226,7 @@ static int libaribb24_handle_regions(AVCodecContext *avctx, AVSubtitle *sub)
{
Libaribb24Context *b24 = avctx->priv_data;
const arib_buf_region_t *region = arib_decoder_get_regions(b24->decoder);
- unsigned int profile_font_size = get_profile_font_size(avctx->profile);
+ unsigned int profile_font_size = get_profile_font_size(avctx);
AVBPrint buf = { 0 };
int ret = 0;
@@ -371,6 +388,10 @@ static const AVOption options[] = {
OFFSET(aribb24_base_path), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD },
{ "aribb24-skip-ruby-text", "skip ruby text blocks during decoding",
OFFSET(aribb24_skip_ruby), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, SD },
+ { "default_profile", "default profile to use if not specified in the stream parameters",
+ OFFSET(default_profile), AV_OPT_TYPE_INT, { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, FF_PROFILE_ARIB_PROFILE_C, SD, "profile" },
+ {"a", "Profile A", 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_ARIB_PROFILE_A}, INT_MIN, INT_MAX, SD, "profile"},
+ {"c", "Profile C", 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_ARIB_PROFILE_C}, INT_MIN, INT_MAX, SD, "profile"},
{ NULL }
};
@@ -383,11 +404,12 @@ static const AVClass aribb24_class = {
const FFCodec ff_libaribb24_decoder = {
.p.name = "libaribb24",
- .p.long_name = NULL_IF_CONFIG_SMALL("libaribb24 ARIB STD-B24 caption decoder"),
+ CODEC_LONG_NAME("libaribb24 ARIB STD-B24 caption decoder"),
.p.type = AVMEDIA_TYPE_SUBTITLE,
.p.id = AV_CODEC_ID_ARIB_CAPTION,
.p.priv_class = &aribb24_class,
.p.wrapper_name = "libaribb24",
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(Libaribb24Context),
.init = libaribb24_init,
.close = libaribb24_close,
diff --git a/libavcodec/libcelt_dec.c b/libavcodec/libcelt_dec.c
index d659d80ed..fcd4fc773 100644
--- a/libavcodec/libcelt_dec.c
+++ b/libavcodec/libcelt_dec.c
@@ -23,7 +23,7 @@
#include
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "libavutil/intreadwrite.h"
struct libcelt_context {
@@ -129,11 +129,12 @@ static int libcelt_dec_decode(AVCodecContext *c, AVFrame *frame,
const FFCodec ff_libcelt_decoder = {
.p.name = "libcelt",
- .p.long_name = NULL_IF_CONFIG_SMALL("Xiph CELT decoder using libcelt"),
+ CODEC_LONG_NAME("Xiph CELT decoder using libcelt"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_CELT,
.p.capabilities = AV_CODEC_CAP_DR1,
.p.wrapper_name = "libcelt",
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(struct libcelt_context),
.init = libcelt_dec_init,
.close = libcelt_dec_close,
diff --git a/libavcodec/libcodec2.c b/libavcodec/libcodec2.c
index abb1130e8..83f68e85c 100644
--- a/libavcodec/libcodec2.c
+++ b/libavcodec/libcodec2.c
@@ -24,8 +24,8 @@
#include "avcodec.h"
#include "libavutil/opt.h"
#include "codec_internal.h"
+#include "decode.h"
#include "encode.h"
-#include "internal.h"
#include "codec2utils.h"
typedef struct {
@@ -105,7 +105,6 @@ static av_cold int libcodec2_init_encoder(AVCodecContext *avctx)
//will need to be smarter once we get wideband support
if (avctx->sample_rate != 8000 ||
- avctx->ch_layout.nb_channels != 1 ||
avctx->sample_fmt != AV_SAMPLE_FMT_S16) {
av_log(avctx, AV_LOG_ERROR, "only 8 kHz 16-bit mono allowed\n");
return AVERROR(EINVAL);
@@ -178,37 +177,36 @@ static int libcodec2_encode(AVCodecContext *avctx, AVPacket *avpkt,
const FFCodec ff_libcodec2_decoder = {
.p.name = "libcodec2",
- .p.long_name = NULL_IF_CONFIG_SMALL("codec2 decoder using libcodec2"),
+ CODEC_LONG_NAME("codec2 decoder using libcodec2"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_CODEC2,
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF,
.p.supported_samplerates = (const int[]){ 8000, 0 },
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },
.p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_MONO, { 0 } },
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(LibCodec2Context),
.init = libcodec2_init_decoder,
.close = libcodec2_close,
FF_CODEC_DECODE_CB(libcodec2_decode),
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, 0 },
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS(AV_CH_LAYOUT_MONO)
};
const FFCodec ff_libcodec2_encoder = {
.p.name = "libcodec2",
- .p.long_name = NULL_IF_CONFIG_SMALL("codec2 encoder using libcodec2"),
+ CODEC_LONG_NAME("codec2 encoder using libcodec2"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_CODEC2,
- .p.capabilities = AV_CODEC_CAP_DR1,
+ .p.capabilities = AV_CODEC_CAP_DR1 |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.p.supported_samplerates = (const int[]){ 8000, 0 },
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },
.p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_MONO, { 0 } },
.p.priv_class = &libcodec2_enc_class,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(LibCodec2Context),
.init = libcodec2_init_encoder,
.close = libcodec2_close,
FF_CODEC_ENCODE_CB(libcodec2_encode),
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, 0 },
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS(AV_CH_LAYOUT_MONO)
};
diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
index 0a46cf226..2488a709c 100644
--- a/libavcodec/libdav1d.c
+++ b/libavcodec/libdav1d.c
@@ -41,15 +41,13 @@
typedef struct Libdav1dContext {
AVClass *class;
Dav1dContext *c;
- /* This packet coincides with AVCodecInternal.in_pkt
- * and is not owned by us. */
- AVPacket *pkt;
AVBufferPool *pool;
int pool_size;
Dav1dData data;
int tile_threads;
int frame_threads;
+ int max_frame_delay;
int apply_grain;
int operating_point;
int all_layers;
@@ -218,8 +216,6 @@ static av_cold int libdav1d_init(AVCodecContext *c)
#endif
int res;
- dav1d->pkt = c->internal->in_pkt;
-
av_log(c, AV_LOG_INFO, "libdav1d %s\n", dav1d_version());
dav1d_default_settings(&s);
@@ -246,7 +242,9 @@ static av_cold int libdav1d_init(AVCodecContext *c)
s.n_threads = FFMAX(dav1d->frame_threads, dav1d->tile_threads);
else
s.n_threads = FFMIN(threads, DAV1D_MAX_THREADS);
- s.max_frame_delay = (c->flags & AV_CODEC_FLAG_LOW_DELAY) ? 1 : 0;
+ if (dav1d->max_frame_delay > 0 && (c->flags & AV_CODEC_FLAG_LOW_DELAY))
+ av_log(c, AV_LOG_WARNING, "Low delay mode requested, forcing max_frame_delay 1\n");
+ s.max_frame_delay = (c->flags & AV_CODEC_FLAG_LOW_DELAY) ? 1 : dav1d->max_frame_delay;
av_log(c, AV_LOG_DEBUG, "Using %d threads, %d max_frame_delay\n",
s.n_threads, s.max_frame_delay);
#else
@@ -256,10 +254,21 @@ static av_cold int libdav1d_init(AVCodecContext *c)
s.n_frame_threads = dav1d->frame_threads
? dav1d->frame_threads
: FFMIN(ceil(threads / s.n_tile_threads), DAV1D_MAX_FRAME_THREADS);
+ if (dav1d->max_frame_delay > 0)
+ s.n_frame_threads = FFMIN(s.n_frame_threads, dav1d->max_frame_delay);
av_log(c, AV_LOG_DEBUG, "Using %d frame threads, %d tile threads\n",
s.n_frame_threads, s.n_tile_threads);
#endif
+#if FF_DAV1D_VERSION_AT_LEAST(6,8)
+ if (c->skip_frame >= AVDISCARD_NONKEY)
+ s.decode_frame_type = DAV1D_DECODEFRAMETYPE_KEY;
+ else if (c->skip_frame >= AVDISCARD_NONINTRA)
+ s.decode_frame_type = DAV1D_DECODEFRAMETYPE_INTRA;
+ else if (c->skip_frame >= AVDISCARD_NONREF)
+ s.decode_frame_type = DAV1D_DECODEFRAMETYPE_REFERENCE;
+#endif
+
res = libdav1d_parse_extradata(c);
if (res < 0)
return res;
@@ -279,6 +288,13 @@ static void libdav1d_flush(AVCodecContext *c)
dav1d_flush(dav1d->c);
}
+typedef struct OpaqueData {
+ void *pkt_orig_opaque;
+#if FF_API_REORDERED_OPAQUE
+ int64_t reordered_opaque;
+#endif
+} OpaqueData;
+
static void libdav1d_data_free(const uint8_t *data, void *opaque) {
AVBufferRef *buf = opaque;
@@ -286,8 +302,10 @@ static void libdav1d_data_free(const uint8_t *data, void *opaque) {
}
static void libdav1d_user_data_free(const uint8_t *data, void *opaque) {
+ AVPacket *pkt = opaque;
av_assert0(data == opaque);
- av_free(opaque);
+ av_free(pkt->opaque);
+ av_packet_free(&pkt);
}
static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
@@ -295,52 +313,68 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
Libdav1dContext *dav1d = c->priv_data;
Dav1dData *data = &dav1d->data;
Dav1dPicture pic = { 0 }, *p = &pic;
+ AVPacket *pkt;
+ OpaqueData *od = NULL;
#if FF_DAV1D_VERSION_AT_LEAST(5,1)
enum Dav1dEventFlags event_flags = 0;
#endif
int res;
if (!data->sz) {
- AVPacket *const pkt = dav1d->pkt;
+ pkt = av_packet_alloc();
+
+ if (!pkt)
+ return AVERROR(ENOMEM);
res = ff_decode_get_packet(c, pkt);
- if (res < 0 && res != AVERROR_EOF)
+ if (res < 0 && res != AVERROR_EOF) {
+ av_packet_free(&pkt);
return res;
+ }
if (pkt->size) {
res = dav1d_data_wrap(data, pkt->data, pkt->size,
libdav1d_data_free, pkt->buf);
if (res < 0) {
- av_packet_unref(pkt);
+ av_packet_free(&pkt);
return res;
}
- data->m.timestamp = pkt->pts;
- data->m.offset = pkt->pos;
- data->m.duration = pkt->duration;
-
pkt->buf = NULL;
- av_packet_unref(pkt);
- if (c->reordered_opaque != AV_NOPTS_VALUE) {
- uint8_t *reordered_opaque = av_memdup(&c->reordered_opaque,
- sizeof(c->reordered_opaque));
- if (!reordered_opaque) {
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (
+#if FF_API_REORDERED_OPAQUE
+ c->reordered_opaque != AV_NOPTS_VALUE ||
+#endif
+ (pkt->opaque && (c->flags & AV_CODEC_FLAG_COPY_OPAQUE))) {
+ od = av_mallocz(sizeof(*od));
+ if (!od) {
+ av_packet_free(&pkt);
dav1d_data_unref(data);
return AVERROR(ENOMEM);
}
-
- res = dav1d_data_wrap_user_data(data, reordered_opaque,
- libdav1d_user_data_free, reordered_opaque);
- if (res < 0) {
- av_free(reordered_opaque);
- dav1d_data_unref(data);
- return res;
- }
+ od->pkt_orig_opaque = pkt->opaque;
+#if FF_API_REORDERED_OPAQUE
+ od->reordered_opaque = c->reordered_opaque;
+#endif
+FF_ENABLE_DEPRECATION_WARNINGS
}
- } else if (res >= 0) {
- av_packet_unref(pkt);
- return AVERROR(EAGAIN);
+ pkt->opaque = od;
+
+ res = dav1d_data_wrap_user_data(data, (const uint8_t *)pkt,
+ libdav1d_user_data_free, pkt);
+ if (res < 0) {
+ av_free(pkt->opaque);
+ av_packet_free(&pkt);
+ dav1d_data_unref(data);
+ return res;
+ }
+ pkt = NULL;
+ } else {
+ av_packet_free(&pkt);
+ if (res >= 0)
+ return AVERROR(EAGAIN);
}
}
@@ -405,17 +439,29 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
INT_MAX);
ff_set_sar(c, frame->sample_aspect_ratio);
- if (p->m.user_data.data)
- memcpy(&frame->reordered_opaque, p->m.user_data.data, sizeof(frame->reordered_opaque));
+ pkt = (AVPacket *)p->m.user_data.data;
+ od = pkt->opaque;
+#if FF_API_REORDERED_OPAQUE
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (od && od->reordered_opaque != AV_NOPTS_VALUE)
+ frame->reordered_opaque = od->reordered_opaque;
else
frame->reordered_opaque = AV_NOPTS_VALUE;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ // restore the original user opaque value for
+ // ff_decode_frame_props_from_pkt()
+ pkt->opaque = od ? od->pkt_orig_opaque : NULL;
+ av_freep(&od);
// match timestamps and packet size
- frame->pts = p->m.timestamp;
- frame->pkt_dts = p->m.timestamp;
- frame->pkt_pos = p->m.offset;
- frame->pkt_size = p->m.size;
- frame->pkt_duration = p->m.duration;
+ res = ff_decode_frame_props_from_pkt(c, frame, pkt);
+ pkt->opaque = NULL;
+ if (res < 0)
+ goto fail;
+
+ frame->pkt_dts = pkt->pts;
frame->key_frame = p->frame_hdr->frame_type == DAV1D_FRAME_TYPE_KEY;
switch (p->frame_hdr->frame_type) {
@@ -555,12 +601,16 @@ static av_cold int libdav1d_close(AVCodecContext *c)
#ifndef DAV1D_MAX_TILE_THREADS
#define DAV1D_MAX_TILE_THREADS DAV1D_MAX_THREADS
#endif
+#ifndef DAV1D_MAX_FRAME_DELAY
+#define DAV1D_MAX_FRAME_DELAY DAV1D_MAX_FRAME_THREADS
+#endif
#define OFFSET(x) offsetof(Libdav1dContext, x)
#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption libdav1d_options[] = {
{ "tilethreads", "Tile threads", OFFSET(tile_threads), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, DAV1D_MAX_TILE_THREADS, VD | AV_OPT_FLAG_DEPRECATED },
{ "framethreads", "Frame threads", OFFSET(frame_threads), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, DAV1D_MAX_FRAME_THREADS, VD | AV_OPT_FLAG_DEPRECATED },
+ { "max_frame_delay", "Max frame delay", OFFSET(max_frame_delay), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, DAV1D_MAX_FRAME_DELAY, VD },
{ "filmgrain", "Apply Film Grain", OFFSET(apply_grain), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VD | AV_OPT_FLAG_DEPRECATED },
{ "oppoint", "Select an operating point of the scalable bitstream", OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 31, VD },
{ "alllayers", "Output all spatial layers", OFFSET(all_layers), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
@@ -576,7 +626,7 @@ static const AVClass libdav1d_class = {
const FFCodec ff_libdav1d_decoder = {
.p.name = "libdav1d",
- .p.long_name = NULL_IF_CONFIG_SMALL("dav1d AV1 decoder by VideoLAN"),
+ CODEC_LONG_NAME("dav1d AV1 decoder by VideoLAN"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AV1,
.priv_data_size = sizeof(Libdav1dContext),
@@ -585,7 +635,7 @@ const FFCodec ff_libdav1d_decoder = {
.flush = libdav1d_flush,
FF_CODEC_RECEIVE_FRAME_CB(libdav1d_receive_frame),
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_SETS_PKT_DTS |
+ .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS | FF_CODEC_CAP_SETS_FRAME_PROPS |
FF_CODEC_CAP_AUTO_THREADS,
.p.priv_class = &libdav1d_class,
.p.wrapper_name = "libdav1d",
diff --git a/libavcodec/libdavs2.c b/libavcodec/libdavs2.c
index 918e48502..179d2f4e4 100644
--- a/libavcodec/libdavs2.c
+++ b/libavcodec/libdavs2.c
@@ -223,7 +223,7 @@ static int davs2_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_libdavs2_decoder = {
.p.name = "libdavs2",
- .p.long_name = NULL_IF_CONFIG_SMALL("libdavs2 AVS2-P2/IEEE1857.4"),
+ CODEC_LONG_NAME("libdavs2 AVS2-P2/IEEE1857.4"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AVS2,
.priv_data_size = sizeof(DAVS2Context),
@@ -232,7 +232,8 @@ const FFCodec ff_libdavs2_decoder = {
FF_CODEC_DECODE_CB(davs2_decode_frame),
.flush = davs2_flush,
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
- .caps_internal = FF_CODEC_CAP_AUTO_THREADS,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_AUTO_THREADS,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE },
.p.wrapper_name = "libdavs2",
diff --git a/libavcodec/libfdk-aacdec.c b/libavcodec/libfdk-aacdec.c
index 11eee51a9..8c1586e25 100644
--- a/libavcodec/libfdk-aacdec.c
+++ b/libavcodec/libfdk-aacdec.c
@@ -24,7 +24,7 @@
#include "libavutil/opt.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#ifdef AACDECODER_LIB_VL0
#define FDKDEC_VER_AT_LEAST(vl0, vl1) \
@@ -478,7 +478,7 @@ static av_cold void fdk_aac_decode_flush(AVCodecContext *avctx)
const FFCodec ff_libfdk_aac_decoder = {
.p.name = "libfdk_aac",
- .p.long_name = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"),
+ CODEC_LONG_NAME("Fraunhofer FDK AAC"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AAC,
.priv_data_size = sizeof(FDKAACDecContext),
@@ -492,7 +492,6 @@ const FFCodec ff_libfdk_aac_decoder = {
#endif
,
.p.priv_class = &fdk_aac_dec_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.wrapper_name = "libfdk",
};
diff --git a/libavcodec/libfdk-aacenc.c b/libavcodec/libfdk-aacenc.c
index a5697bde5..54549de47 100644
--- a/libavcodec/libfdk-aacenc.c
+++ b/libavcodec/libfdk-aacenc.c
@@ -187,6 +187,9 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
case 4: mode = MODE_1_2_1; sce = 2; cpe = 1; break;
case 5: mode = MODE_1_2_2; sce = 1; cpe = 2; break;
case 6: mode = MODE_1_2_2_1; sce = 2; cpe = 2; break;
+#if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
+ case 7: mode = MODE_6_1; sce = 3; cpe = 2; break;
+#endif
/* The version macro is introduced the same time as the 7.1 support, so this
should suffice. */
#if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12
@@ -195,6 +198,10 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
cpe = 3;
if (!av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1)) {
mode = MODE_7_1_REAR_SURROUND;
+#if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
+ } else if (!av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK)) {
+ mode = MODE_7_1_TOP_FRONT;
+#endif
} else {
// MODE_1_2_2_2_1 and MODE_7_1_FRONT_CENTER use the same channel layout
mode = MODE_7_1_FRONT_CENTER;
@@ -448,9 +455,15 @@ static const uint64_t aac_channel_layout[] = {
AV_CH_LAYOUT_4POINT0,
AV_CH_LAYOUT_5POINT0_BACK,
AV_CH_LAYOUT_5POINT1_BACK,
+#if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
+ AV_CH_LAYOUT_6POINT1_BACK,
+#endif
#if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12
AV_CH_LAYOUT_7POINT1_WIDE_BACK,
AV_CH_LAYOUT_7POINT1,
+#endif
+#if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
+ AV_CH_LAYOUT_7POINT1_TOP_BACK,
#endif
0,
};
@@ -463,9 +476,15 @@ static const AVChannelLayout aac_ch_layouts[16] = {
AV_CHANNEL_LAYOUT_4POINT0,
AV_CHANNEL_LAYOUT_5POINT0_BACK,
AV_CHANNEL_LAYOUT_5POINT1_BACK,
-#ifdef AACENCODER_LIB_VL0
+#if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
+ AV_CHANNEL_LAYOUT_6POINT1_BACK,
+#endif
+#if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12
AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK,
AV_CHANNEL_LAYOUT_7POINT1,
+#endif
+#if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
+ AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK,
#endif
{ 0 },
};
@@ -477,14 +496,16 @@ static const int aac_sample_rates[] = {
const FFCodec ff_libfdk_aac_encoder = {
.p.name = "libfdk_aac",
- .p.long_name = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"),
+ CODEC_LONG_NAME("Fraunhofer FDK AAC"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AAC,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_SMALL_LAST_FRAME,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(AACContext),
.init = aac_encode_init,
FF_CODEC_ENCODE_CB(aac_encode_frame),
.close = aac_encode_close,
- .p.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_NONE },
.p.priv_class = &aac_enc_class,
@@ -492,8 +513,6 @@ const FFCodec ff_libfdk_aac_encoder = {
.p.profiles = profiles,
.p.supported_samplerates = aac_sample_rates,
.p.wrapper_name = "libfdk",
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = aac_channel_layout,
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(aac_channel_layout)
.p.ch_layouts = aac_ch_layouts,
};
diff --git a/libavcodec/libgsmdec.c b/libavcodec/libgsmdec.c
index 9c2304f7a..a86e9deac 100644
--- a/libavcodec/libgsmdec.c
+++ b/libavcodec/libgsmdec.c
@@ -40,7 +40,7 @@
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "gsm.h"
typedef struct LibGSMDecodeContext {
@@ -127,11 +127,12 @@ static void libgsm_flush(AVCodecContext *avctx) {
#if CONFIG_LIBGSM_DECODER
const FFCodec ff_libgsm_decoder = {
.p.name = "libgsm",
- .p.long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"),
+ CODEC_LONG_NAME("libgsm GSM"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_GSM,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
.p.wrapper_name = "libgsm",
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(LibGSMDecodeContext),
.init = libgsm_decode_init,
.close = libgsm_decode_close,
@@ -142,11 +143,12 @@ const FFCodec ff_libgsm_decoder = {
#if CONFIG_LIBGSM_MS_DECODER
const FFCodec ff_libgsm_ms_decoder = {
.p.name = "libgsm_ms",
- .p.long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"),
+ CODEC_LONG_NAME("libgsm GSM Microsoft variant"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_GSM_MS,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
.p.wrapper_name = "libgsm",
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(LibGSMDecodeContext),
.init = libgsm_decode_init,
.close = libgsm_decode_close,
diff --git a/libavcodec/libgsmenc.c b/libavcodec/libgsmenc.c
index a45b77be9..640954491 100644
--- a/libavcodec/libgsmenc.c
+++ b/libavcodec/libgsmenc.c
@@ -119,40 +119,38 @@ static const FFCodecDefault libgsm_defaults[] = {
#if CONFIG_LIBGSM_ENCODER
const FFCodec ff_libgsm_encoder = {
.p.name = "libgsm",
- .p.long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"),
+ CODEC_LONG_NAME("libgsm GSM"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_GSM,
- .p.capabilities = AV_CODEC_CAP_DR1,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.init = libgsm_encode_init,
FF_CODEC_ENCODE_CB(libgsm_encode_frame),
.close = libgsm_encode_close,
.defaults = libgsm_defaults,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, 0 },
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS(AV_CH_LAYOUT_MONO)
.p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_MONO, { 0 } },
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_NONE },
.p.wrapper_name = "libgsm",
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
};
#endif
#if CONFIG_LIBGSM_MS_ENCODER
const FFCodec ff_libgsm_ms_encoder = {
.p.name = "libgsm_ms",
- .p.long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"),
+ CODEC_LONG_NAME("libgsm GSM Microsoft variant"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_GSM_MS,
- .p.capabilities = AV_CODEC_CAP_DR1,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.init = libgsm_encode_init,
FF_CODEC_ENCODE_CB(libgsm_encode_frame),
.close = libgsm_encode_close,
.defaults = libgsm_defaults,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, 0 },
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS(AV_CH_LAYOUT_MONO)
.p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_MONO, { 0 } },
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_NONE },
.p.wrapper_name = "libgsm",
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
};
#endif
diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c
index a7b1eaf28..9ca90bf0c 100644
--- a/libavcodec/libilbc.c
+++ b/libavcodec/libilbc.c
@@ -26,8 +26,8 @@
#include "libavutil/opt.h"
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "encode.h"
-#include "internal.h"
#ifndef LIBILBC_VERSION_MAJOR
#define LIBILBC_VERSION_MAJOR 2
@@ -119,9 +119,10 @@ static int ilbc_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_libilbc_decoder = {
.p.name = "libilbc",
- .p.long_name = NULL_IF_CONFIG_SMALL("iLBC (Internet Low Bitrate Codec)"),
+ CODEC_LONG_NAME("iLBC (Internet Low Bitrate Codec)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ILBC,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(ILBCDecContext),
.init = ilbc_decode_init,
FF_CODEC_DECODE_CB(ilbc_decode_frame),
@@ -201,9 +202,11 @@ static const FFCodecDefault ilbc_encode_defaults[] = {
const FFCodec ff_libilbc_encoder = {
.p.name = "libilbc",
- .p.long_name = NULL_IF_CONFIG_SMALL("iLBC (Internet Low Bitrate Codec)"),
+ CODEC_LONG_NAME("iLBC (Internet Low Bitrate Codec)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_ILBC,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(ILBCEncContext),
.init = ilbc_encode_init,
FF_CODEC_ENCODE_CB(ilbc_encode_frame),
diff --git a/libavcodec/libjxl.h b/libavcodec/libjxl.h
index 5387c438f..e305b6e75 100644
--- a/libavcodec/libjxl.h
+++ b/libavcodec/libjxl.h
@@ -27,8 +27,20 @@
#ifndef AVCODEC_LIBJXL_H
#define AVCODEC_LIBJXL_H
+#include
#include
+/*
+ * libjxl version 0.7.0 and earlier doesn't contain these macros at all
+ * so to detect version 0.7.0 versus 0.8.0 we need to define them ourselves
+ */
+#ifndef JPEGXL_COMPUTE_NUMERIC_VERSION
+ #define JPEGXL_COMPUTE_NUMERIC_VERSION(major,minor,patch) ((major<<24) | (minor<<16) | (patch<<8) | 0)
+#endif
+#ifndef JPEGXL_NUMERIC_VERSION
+ #define JPEGXL_NUMERIC_VERSION JPEGXL_COMPUTE_NUMERIC_VERSION(0, 7, 0)
+#endif
+
/**
* Transform threadcount in ffmpeg to one used by libjxl.
*
diff --git a/libavcodec/libjxldec.c b/libavcodec/libjxldec.c
index 829478bbd..045a1535f 100644
--- a/libavcodec/libjxldec.c
+++ b/libavcodec/libjxldec.c
@@ -36,7 +36,7 @@
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include
#include
@@ -47,6 +47,9 @@ typedef struct LibJxlDecodeContext {
JxlDecoder *decoder;
JxlBasicInfo basic_info;
JxlPixelFormat jxl_pixfmt;
+#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
+ JxlBitDepth jxl_bit_depth;
+#endif
JxlDecoderStatus events;
AVBufferRef *iccp;
} LibJxlDecodeContext;
@@ -93,10 +96,17 @@ static av_cold int libjxl_decode_init(AVCodecContext *avctx)
return libjxl_init_jxl_decoder(avctx);
}
-static enum AVPixelFormat libjxl_get_pix_fmt(void *avctx, const JxlBasicInfo *basic_info, JxlPixelFormat *format)
+static enum AVPixelFormat libjxl_get_pix_fmt(AVCodecContext *avctx, LibJxlDecodeContext *ctx)
{
+ const JxlBasicInfo *basic_info = &ctx->basic_info;
+ JxlPixelFormat *format = &ctx->jxl_pixfmt;
format->endianness = JXL_NATIVE_ENDIAN;
format->num_channels = basic_info->num_color_channels + (basic_info->alpha_bits > 0);
+#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
+ ctx->jxl_bit_depth.bits_per_sample = avctx->bits_per_raw_sample = basic_info->bits_per_sample;
+ ctx->jxl_bit_depth.type = JXL_BIT_DEPTH_FROM_PIXEL_FORMAT;
+ ctx->jxl_bit_depth.exponent_bits_per_sample = basic_info->exponent_bits_per_sample;
+#endif
/* Gray */
if (basic_info->num_color_channels == 1) {
if (basic_info->bits_per_sample <= 8) {
@@ -119,10 +129,10 @@ static enum AVPixelFormat libjxl_get_pix_fmt(void *avctx, const JxlBasicInfo *ba
format->data_type = JXL_TYPE_UINT8;
return basic_info->alpha_bits ? AV_PIX_FMT_RGBA : AV_PIX_FMT_RGB24;
}
- if (basic_info->bits_per_sample > 16)
- av_log(avctx, AV_LOG_WARNING, "Downsampling larger integer to 16-bit via libjxl\n");
if (basic_info->exponent_bits_per_sample)
av_log(avctx, AV_LOG_WARNING, "Downsampling float to 16-bit integer via libjxl\n");
+ else if (basic_info->bits_per_sample > 16)
+ av_log(avctx, AV_LOG_WARNING, "Downsampling larger integer to 16-bit via libjxl\n");
format->data_type = JXL_TYPE_UINT16;
return basic_info->alpha_bits ? AV_PIX_FMT_RGBA64 : AV_PIX_FMT_RGB48;
}
@@ -167,9 +177,9 @@ static enum AVColorTransferCharacteristic libjxl_get_trc(void *avctx, const JxlC
case JXL_TRANSFER_FUNCTION_DCI: return AVCOL_TRC_SMPTE428;
case JXL_TRANSFER_FUNCTION_HLG: return AVCOL_TRC_ARIB_STD_B67;
case JXL_TRANSFER_FUNCTION_GAMMA:
- if (jxl_color->gamma > 2.199 && jxl_color->gamma < 2.201)
+ if (jxl_color->gamma > 0.45355 && jxl_color->gamma < 0.45555)
return AVCOL_TRC_GAMMA22;
- else if (jxl_color->gamma > 2.799 && jxl_color->gamma < 2.801)
+ else if (jxl_color->gamma > 0.35614 && jxl_color->gamma < 0.35814)
return AVCOL_TRC_GAMMA28;
else
av_log(avctx, AV_LOG_WARNING, "Unsupported gamma transfer: %f\n", jxl_color->gamma);
@@ -367,7 +377,7 @@ static int libjxl_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_f
av_log(avctx, AV_LOG_ERROR, "Bad libjxl basic info event\n");
return AVERROR_EXTERNAL;
}
- avctx->pix_fmt = libjxl_get_pix_fmt(avctx, &ctx->basic_info, &ctx->jxl_pixfmt);
+ avctx->pix_fmt = libjxl_get_pix_fmt(avctx, ctx);
if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
av_log(avctx, AV_LOG_ERROR, "Bad libjxl pixel format\n");
return AVERROR_EXTERNAL;
@@ -390,6 +400,12 @@ static int libjxl_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_f
av_log(avctx, AV_LOG_ERROR, "Bad libjxl dec need image out buffer event\n");
return AVERROR_EXTERNAL;
}
+#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
+ if (JxlDecoderSetImageOutBitDepth(ctx->decoder, &ctx->jxl_bit_depth) != JXL_DEC_SUCCESS) {
+ av_log(avctx, AV_LOG_ERROR, "Error setting output bit depth\n");
+ return AVERROR_EXTERNAL;
+ }
+#endif
continue;
case JXL_DEC_FULL_IMAGE:
/* full image is one frame, even if animated */
@@ -447,7 +463,7 @@ static av_cold int libjxl_decode_close(AVCodecContext *avctx)
const FFCodec ff_libjxl_decoder = {
.p.name = "libjxl",
- .p.long_name = NULL_IF_CONFIG_SMALL("libjxl JPEG XL"),
+ CODEC_LONG_NAME("libjxl JPEG XL"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_JPEGXL,
.priv_data_size = sizeof(LibJxlDecodeContext),
@@ -455,6 +471,8 @@ const FFCodec ff_libjxl_decoder = {
FF_CODEC_DECODE_CB(libjxl_decode_frame),
.close = libjxl_decode_close,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_OTHER_THREADS,
- .caps_internal = FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP |
+ FF_CODEC_CAP_ICC_PROFILES,
.p.wrapper_name = "libjxl",
};
diff --git a/libavcodec/libjxlenc.c b/libavcodec/libjxlenc.c
index 6a948cc3a..897452f57 100644
--- a/libavcodec/libjxlenc.c
+++ b/libavcodec/libjxlenc.c
@@ -190,7 +190,7 @@ static av_cold int libjxl_encode_init(AVCodecContext *avctx)
* Populate a JxlColorEncoding with the given enum AVColorPrimaries.
* @return < 0 upon failure, >= 0 upon success
*/
-static int libjxl_populate_primaries(JxlColorEncoding *jxl_color, enum AVColorPrimaries prm)
+static int libjxl_populate_primaries(void *avctx, JxlColorEncoding *jxl_color, enum AVColorPrimaries prm)
{
const AVColorPrimariesDesc *desc;
@@ -211,6 +211,11 @@ static int libjxl_populate_primaries(JxlColorEncoding *jxl_color, enum AVColorPr
jxl_color->primaries = JXL_PRIMARIES_P3;
jxl_color->white_point = JXL_WHITE_POINT_D65;
return 0;
+ case AVCOL_PRI_UNSPECIFIED:
+ av_log(avctx, AV_LOG_WARNING, "Unknown primaries, assuming BT.709/sRGB. Colors may be wrong.\n");
+ jxl_color->primaries = JXL_PRIMARIES_SRGB;
+ jxl_color->white_point = JXL_WHITE_POINT_D65;
+ return 0;
}
desc = av_csp_primaries_desc_from_id(prm);
@@ -245,6 +250,10 @@ static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFra
JxlBasicInfo info;
JxlColorEncoding jxl_color;
JxlPixelFormat jxl_fmt;
+ int bits_per_sample;
+#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
+ JxlBitDepth jxl_bit_depth;
+#endif
JxlEncoderStatus jret;
int ret;
size_t available = ctx->buffer_size;
@@ -264,7 +273,9 @@ static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFra
info.ysize = frame->height;
info.num_extra_channels = (jxl_fmt.num_channels + 1) % 2;
info.num_color_channels = jxl_fmt.num_channels - info.num_extra_channels;
- info.bits_per_sample = av_get_bits_per_pixel(pix_desc) / jxl_fmt.num_channels;
+ bits_per_sample = av_get_bits_per_pixel(pix_desc) / jxl_fmt.num_channels;
+ info.bits_per_sample = avctx->bits_per_raw_sample > 0 && !(pix_desc->flags & AV_PIX_FMT_FLAG_FLOAT)
+ ? avctx->bits_per_raw_sample : bits_per_sample;
info.alpha_bits = (info.num_extra_channels > 0) * info.bits_per_sample;
if (pix_desc->flags & AV_PIX_FMT_FLAG_FLOAT) {
info.exponent_bits_per_sample = info.bits_per_sample > 16 ? 8 : 5;
@@ -276,6 +287,13 @@ static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFra
jxl_fmt.data_type = info.bits_per_sample <= 8 ? JXL_TYPE_UINT8 : JXL_TYPE_UINT16;
}
+#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
+ jxl_bit_depth.bits_per_sample = bits_per_sample;
+ jxl_bit_depth.type = JXL_BIT_DEPTH_FROM_PIXEL_FORMAT;
+ jxl_bit_depth.exponent_bits_per_sample = pix_desc->flags & AV_PIX_FMT_FLAG_FLOAT ?
+ info.exponent_bits_per_sample : 0;
+#endif
+
/* JPEG XL format itself does not support limited range */
if (avctx->color_range == AVCOL_RANGE_MPEG ||
avctx->color_range == AVCOL_RANGE_UNSPECIFIED && frame->color_range == AVCOL_RANGE_MPEG)
@@ -340,7 +358,7 @@ static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFra
else
jxl_color.color_space = JXL_COLOR_SPACE_RGB;
- ret = libjxl_populate_primaries(&jxl_color,
+ ret = libjxl_populate_primaries(avctx, &jxl_color,
frame->color_primaries && frame->color_primaries != AVCOL_PRI_UNSPECIFIED
? frame->color_primaries : avctx->color_primaries);
if (ret < 0)
@@ -352,6 +370,11 @@ static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFra
if (JxlEncoderSetColorEncoding(ctx->encoder, &jxl_color) != JXL_ENC_SUCCESS)
av_log(avctx, AV_LOG_WARNING, "Failed to set JxlColorEncoding\n");
+#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
+ if (JxlEncoderSetFrameBitDepth(ctx->options, &jxl_bit_depth) != JXL_ENC_SUCCESS)
+ av_log(avctx, AV_LOG_WARNING, "Failed to set JxlBitDepth\n");
+#endif
+
/* depending on basic info, level 10 might
* be required instead of level 5 */
if (JxlEncoderGetRequiredCodestreamLevel(ctx->encoder) > 5) {
@@ -455,15 +478,18 @@ static const AVClass libjxl_encode_class = {
const FFCodec ff_libjxl_encoder = {
.p.name = "libjxl",
- .p.long_name = NULL_IF_CONFIG_SMALL("libjxl JPEG XL"),
+ CODEC_LONG_NAME("libjxl JPEG XL"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_JPEGXL,
.priv_data_size = sizeof(LibJxlEncodeContext),
.init = libjxl_encode_init,
FF_CODEC_ENCODE_CB(libjxl_encode_frame),
.close = libjxl_encode_close,
- .p.capabilities = AV_CODEC_CAP_OTHER_THREADS,
- .caps_internal = FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP,
+ .p.capabilities = AV_CODEC_CAP_OTHER_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP |
+ FF_CODEC_CAP_ICC_PROFILES,
.p.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA,
AV_PIX_FMT_RGB48, AV_PIX_FMT_RGBA64,
diff --git a/libavcodec/libkvazaar.c b/libavcodec/libkvazaar.c
index 7fd0e9523..168486f4e 100644
--- a/libavcodec/libkvazaar.c
+++ b/libavcodec/libkvazaar.c
@@ -320,7 +320,7 @@ static const FFCodecDefault defaults[] = {
const FFCodec ff_libkvazaar_encoder = {
.p.name = "libkvazaar",
- .p.long_name = NULL_IF_CONFIG_SMALL("libkvazaar H.265 / HEVC"),
+ CODEC_LONG_NAME("libkvazaar H.265 / HEVC"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_HEVC,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
@@ -335,7 +335,7 @@ const FFCodec ff_libkvazaar_encoder = {
FF_CODEC_ENCODE_CB(libkvazaar_encode),
.close = libkvazaar_close,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP |
FF_CODEC_CAP_AUTO_THREADS,
.p.wrapper_name = "libkvazaar",
diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c
index 02a256c76..26e58baa3 100644
--- a/libavcodec/libmp3lame.c
+++ b/libavcodec/libmp3lame.c
@@ -330,11 +330,12 @@ static const int libmp3lame_sample_rates[] = {
const FFCodec ff_libmp3lame_encoder = {
.p.name = "libmp3lame",
- .p.long_name = NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"),
+ CODEC_LONG_NAME("libmp3lame MP3 (MPEG audio layer 3)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_MP3,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SMALL_LAST_FRAME,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(LAMEContext),
.init = mp3lame_encode_init,
FF_CODEC_ENCODE_CB(mp3lame_encode_frame),
@@ -344,11 +345,7 @@ const FFCodec ff_libmp3lame_encoder = {
AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_NONE },
.p.supported_samplerates = libmp3lame_sample_rates,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
- AV_CH_LAYOUT_STEREO,
- 0 },
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS(AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO)
.p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_MONO,
AV_CHANNEL_LAYOUT_STEREO,
{ 0 },
diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c
index 539f0ded3..fd9e6e634 100644
--- a/libavcodec/libopencore-amr.c
+++ b/libavcodec/libopencore-amr.c
@@ -30,8 +30,8 @@
#include "avcodec.h"
#include "audio_frame_queue.h"
#include "codec_internal.h"
+#include "decode.h"
#include "encode.h"
-#include "internal.h"
#if CONFIG_LIBOPENCORE_AMRNB_DECODER || CONFIG_LIBOPENCORE_AMRWB_DECODER
static int amr_decode_fix_avctx(AVCodecContext *avctx)
@@ -135,9 +135,10 @@ static int amr_nb_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_libopencore_amrnb_decoder = {
.p.name = "libopencore_amrnb",
- .p.long_name = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"),
+ CODEC_LONG_NAME("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AMR_NB,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(AMRContext),
.init = amr_nb_decode_init,
.close = amr_nb_decode_close,
@@ -290,14 +291,16 @@ static int amr_nb_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
const FFCodec ff_libopencore_amrnb_encoder = {
.p.name = "libopencore_amrnb",
- .p.long_name = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"),
+ CODEC_LONG_NAME("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AMR_NB,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_SMALL_LAST_FRAME,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(AMRContext),
.init = amr_nb_encode_init,
FF_CODEC_ENCODE_CB(amr_nb_encode_frame),
.close = amr_nb_encode_close,
- .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SMALL_LAST_FRAME,
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_NONE },
.p.priv_class = &amrnb_class,
@@ -374,11 +377,12 @@ static int amr_wb_decode_close(AVCodecContext *avctx)
const FFCodec ff_libopencore_amrwb_decoder = {
.p.name = "libopencore_amrwb",
- .p.long_name = NULL_IF_CONFIG_SMALL("OpenCORE AMR-WB (Adaptive Multi-Rate Wide-Band)"),
+ CODEC_LONG_NAME("OpenCORE AMR-WB (Adaptive Multi-Rate Wide-Band)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AMR_WB,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
.p.wrapper_name = "libopencore_amrwb",
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(AMRWBContext),
.init = amr_wb_decode_init,
.close = amr_wb_decode_close,
diff --git a/libavcodec/libopenh264dec.c b/libavcodec/libopenh264dec.c
index 007f86b61..af53219b4 100644
--- a/libavcodec/libopenh264dec.c
+++ b/libavcodec/libopenh264dec.c
@@ -31,7 +31,7 @@
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "libopenh264.h"
typedef struct SVCContext {
@@ -158,7 +158,7 @@ static int svc_decode_frame(AVCodecContext *avctx, AVFrame *avframe,
const FFCodec ff_libopenh264_decoder = {
.p.name = "libopenh264",
- .p.long_name = NULL_IF_CONFIG_SMALL("OpenH264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
+ CODEC_LONG_NAME("OpenH264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_H264,
.priv_data_size = sizeof(SVCContext),
@@ -166,7 +166,7 @@ const FFCodec ff_libopenh264_decoder = {
FF_CODEC_DECODE_CB(svc_decode_frame),
.close = svc_decode_close,
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS | FF_CODEC_CAP_INIT_THREADSAFE |
+ .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS |
FF_CODEC_CAP_INIT_CLEANUP,
.bsfs = "h264_mp4toannexb",
.p.wrapper_name = "libopenh264",
diff --git a/libavcodec/libopenh264enc.c b/libavcodec/libopenh264enc.c
index db252aace..8b4755f5b 100644
--- a/libavcodec/libopenh264enc.c
+++ b/libavcodec/libopenh264enc.c
@@ -50,9 +50,6 @@ typedef struct SVCContext {
int max_nal_size;
int skip_frames;
int skipped;
-#if FF_API_OPENH264_CABAC
- int cabac; // deprecated
-#endif
int coder;
// rate control mode
@@ -63,22 +60,6 @@ typedef struct SVCContext {
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
#define DEPRECATED AV_OPT_FLAG_DEPRECATED
static const AVOption options[] = {
-#if FF_API_OPENH264_SLICE_MODE
-#if OPENH264_VER_AT_LEAST(1, 6)
- { "slice_mode", "set slice mode, use slices/max_nal_size", OFFSET(slice_mode), AV_OPT_TYPE_INT, { .i64 = SM_FIXEDSLCNUM_SLICE }, SM_SINGLE_SLICE, SM_RESERVED, VE|DEPRECATED, "slice_mode" },
-#else
- { "slice_mode", "set slice mode, use slices/max_nal_size", OFFSET(slice_mode), AV_OPT_TYPE_INT, { .i64 = SM_AUTO_SLICE }, SM_SINGLE_SLICE, SM_RESERVED, VE|DEPRECATED, "slice_mode" },
-#endif
- { "fixed", "a fixed number of slices", 0, AV_OPT_TYPE_CONST, { .i64 = SM_FIXEDSLCNUM_SLICE }, 0, 0, VE, "slice_mode" },
-#if OPENH264_VER_AT_LEAST(1, 6)
- { "dyn", "Size limited (compatibility name)", 0, AV_OPT_TYPE_CONST, { .i64 = SM_SIZELIMITED_SLICE }, 0, 0, VE, "slice_mode" },
- { "sizelimited", "Size limited", 0, AV_OPT_TYPE_CONST, { .i64 = SM_SIZELIMITED_SLICE }, 0, 0, VE, "slice_mode" },
-#else
- { "rowmb", "one slice per row of macroblocks", 0, AV_OPT_TYPE_CONST, { .i64 = SM_ROWMB_SLICE }, 0, 0, VE, "slice_mode" },
- { "auto", "automatic number of slices according to number of threads", 0, AV_OPT_TYPE_CONST, { .i64 = SM_AUTO_SLICE }, 0, 0, VE, "slice_mode" },
- { "dyn", "Dynamic slicing", 0, AV_OPT_TYPE_CONST, { .i64 = SM_DYN_SLICE }, 0, 0, VE, "slice_mode" },
-#endif
-#endif
{ "loopfilter", "enable loop filter", OFFSET(loopfilter), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE },
{ "profile", "set profile restrictions", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, 0xffff, VE, "profile" },
#define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, { .i64 = value }, 0, 0, VE, "profile"
@@ -88,9 +69,6 @@ static const AVOption options[] = {
#undef PROFILE
{ "max_nal_size", "set maximum NAL size in bytes", OFFSET(max_nal_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
{ "allow_skip_frames", "allow skipping frames to hit the target bitrate", OFFSET(skip_frames), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
-#if FF_API_OPENH264_CABAC
- { "cabac", "Enable cabac(deprecated, use coder)", OFFSET(cabac), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE|DEPRECATED },
-#endif
{ "coder", "Coder type", OFFSET(coder), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE, "coder" },
{ "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, INT_MIN, INT_MAX, VE, "coder" },
{ "cavlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "coder" },
@@ -453,15 +431,16 @@ static const FFCodecDefault svc_enc_defaults[] = {
const FFCodec ff_libopenh264_encoder = {
.p.name = "libopenh264",
- .p.long_name = NULL_IF_CONFIG_SMALL("OpenH264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
+ CODEC_LONG_NAME("OpenH264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_H264,
- .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_OTHER_THREADS,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_OTHER_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(SVCContext),
.init = svc_encode_init,
FF_CODEC_ENCODE_CB(svc_encode_frame),
.close = svc_encode_close,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP |
FF_CODEC_CAP_AUTO_THREADS,
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE },
diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c
index 58ac6c413..206db07ec 100644
--- a/libavcodec/libopenjpegdec.c
+++ b/libavcodec/libopenjpegdec.c
@@ -32,7 +32,7 @@
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "thread.h"
#include
@@ -502,13 +502,14 @@ static const AVClass openjpeg_class = {
const FFCodec ff_libopenjpeg_decoder = {
.p.name = "libopenjpeg",
- .p.long_name = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
+ CODEC_LONG_NAME("OpenJPEG JPEG 2000"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_JPEG2000,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
.p.max_lowres = 31,
.p.priv_class = &openjpeg_class,
.p.wrapper_name = "libopenjpeg",
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(LibOpenJPEGContext),
.init = libopenjpeg_decode_init,
FF_CODEC_DECODE_CB(libopenjpeg_decode_frame),
diff --git a/libavcodec/libopenjpegenc.c b/libavcodec/libopenjpegenc.c
index 06338e882..009c7a437 100644
--- a/libavcodec/libopenjpegenc.c
+++ b/libavcodec/libopenjpegenc.c
@@ -756,13 +756,15 @@ static const AVClass openjpeg_class = {
const FFCodec ff_libopenjpeg_encoder = {
.p.name = "libopenjpeg",
- .p.long_name = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
+ CODEC_LONG_NAME("OpenJPEG JPEG 2000"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_JPEG2000,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(LibOpenJPEGContext),
.init = libopenjpeg_encode_init,
FF_CODEC_ENCODE_CB(libopenjpeg_encode_frame),
- .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
+ .p.capabilities = AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.p.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48,
AV_PIX_FMT_RGBA64, AV_PIX_FMT_GBR24P,
diff --git a/libavcodec/libopusdec.c b/libavcodec/libopusdec.c
index 316ab0f2a..9b9a61034 100644
--- a/libavcodec/libopusdec.c
+++ b/libavcodec/libopusdec.c
@@ -29,10 +29,11 @@
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "internal.h"
-#include "vorbis.h"
#include "mathops.h"
#include "libopus.h"
+#include "vorbis_data.h"
struct libopus_context {
AVClass *class;
@@ -232,7 +233,7 @@ static const AVClass libopusdec_class = {
const FFCodec ff_libopus_decoder = {
.p.name = "libopus",
- .p.long_name = NULL_IF_CONFIG_SMALL("libopus Opus"),
+ CODEC_LONG_NAME("libopus Opus"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_OPUS,
.priv_data_size = sizeof(struct libopus_context),
@@ -241,7 +242,8 @@ const FFCodec ff_libopus_decoder = {
FF_CODEC_DECODE_CB(libopus_decode),
.flush = libopus_flush,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
- .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_INIT_CLEANUP,
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c
index c884075ff..75bc491c9 100644
--- a/libavcodec/libopusenc.c
+++ b/libavcodec/libopusenc.c
@@ -29,8 +29,8 @@
#include "codec_internal.h"
#include "encode.h"
#include "libopus.h"
-#include "vorbis.h"
#include "audio_frame_queue.h"
+#include "vorbis_data.h"
typedef struct LibopusEncOpts {
int vbr;
@@ -459,7 +459,7 @@ static int libopus_encode(AVCodecContext *avctx, AVPacket *avpkt,
const int bytes_per_sample = av_get_bytes_per_sample(avctx->sample_fmt);
const int channels = avctx->ch_layout.nb_channels;
const int sample_size = channels * bytes_per_sample;
- uint8_t *audio;
+ const uint8_t *audio;
int ret;
int discard_padding;
@@ -470,18 +470,18 @@ static int libopus_encode(AVCodecContext *avctx, AVPacket *avpkt,
if (opus->encoder_channel_map != NULL) {
audio = opus->samples;
libopus_copy_samples_with_channel_map(
- audio, frame->data[0], opus->encoder_channel_map,
+ opus->samples, frame->data[0], opus->encoder_channel_map,
channels, frame->nb_samples, bytes_per_sample);
} else if (frame->nb_samples < opus->opts.packet_size) {
audio = opus->samples;
- memcpy(audio, frame->data[0], frame->nb_samples * sample_size);
+ memcpy(opus->samples, frame->data[0], frame->nb_samples * sample_size);
} else
audio = frame->data[0];
} else {
if (!opus->afq.remaining_samples || (!opus->afq.frame_alloc && !opus->afq.frame_count))
return 0;
audio = opus->samples;
- memset(audio, 0, opus->opts.packet_size * sample_size);
+ memset(opus->samples, 0, opus->opts.packet_size * sample_size);
}
/* Maximum packet size taken from opusenc in opus-tools. 120ms packets
@@ -491,11 +491,11 @@ static int libopus_encode(AVCodecContext *avctx, AVPacket *avpkt,
return ret;
if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT)
- ret = opus_multistream_encode_float(opus->enc, (float *)audio,
+ ret = opus_multistream_encode_float(opus->enc, (const float *)audio,
opus->opts.packet_size,
avpkt->data, avpkt->size);
else
- ret = opus_multistream_encode(opus->enc, (opus_int16 *)audio,
+ ret = opus_multistream_encode(opus->enc, (const opus_int16 *)audio,
opus->opts.packet_size,
avpkt->data, avpkt->size);
@@ -585,14 +585,16 @@ static const int libopus_sample_rates[] = {
const FFCodec ff_libopus_encoder = {
.p.name = "libopus",
- .p.long_name = NULL_IF_CONFIG_SMALL("libopus Opus"),
+ CODEC_LONG_NAME("libopus Opus"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_OPUS,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_SMALL_LAST_FRAME,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(LibopusEncContext),
.init = libopus_encode_init,
FF_CODEC_ENCODE_CB(libopus_encode),
.close = libopus_encode_close,
- .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SMALL_LAST_FRAME,
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_FLT,
AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/librav1e.c b/libavcodec/librav1e.c
index 9d811ba81..08affabe3 100644
--- a/libavcodec/librav1e.c
+++ b/libavcodec/librav1e.c
@@ -22,6 +22,7 @@
#include
+#include "libavutil/buffer.h"
#include "libavutil/internal.h"
#include "libavutil/avassert.h"
#include "libavutil/base64.h"
@@ -30,7 +31,6 @@
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "avcodec.h"
-#include "bsf.h"
#include "codec_internal.h"
#include "encode.h"
#include "internal.h"
@@ -41,7 +41,6 @@ typedef struct librav1eContext {
RaContext *ctx;
AVFrame *frame;
RaFrame *rframe;
- AVBSFContext *bsf;
uint8_t *pass_data;
size_t pass_pos;
@@ -55,6 +54,17 @@ typedef struct librav1eContext {
int tile_cols;
} librav1eContext;
+typedef struct FrameData {
+ int64_t pts;
+ int64_t duration;
+#if FF_API_REORDERED_OPAQUE
+ int64_t reordered_opaque;
+#endif
+
+ void *frame_opaque;
+ AVBufferRef *frame_opaque_ref;
+} FrameData;
+
static inline RaPixelRange range_map(enum AVPixelFormat pix_fmt, enum AVColorRange range)
{
switch (pix_fmt) {
@@ -176,7 +186,6 @@ static av_cold int librav1e_encode_close(AVCodecContext *avctx)
}
av_frame_free(&ctx->frame);
- av_bsf_free(&ctx->bsf);
av_freep(&ctx->pass_data);
return 0;
@@ -245,41 +254,10 @@ static av_cold int librav1e_encode_init(AVCodecContext *avctx)
}
}
- if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
- const AVBitStreamFilter *filter = av_bsf_get_by_name("extract_extradata");
- int bret;
-
- if (!filter) {
- av_log(avctx, AV_LOG_ERROR, "extract_extradata bitstream filter "
- "not found. This is a bug, please report it.\n");
- ret = AVERROR_BUG;
- goto end;
- }
-
- bret = av_bsf_alloc(filter, &ctx->bsf);
- if (bret < 0) {
- ret = bret;
- goto end;
- }
-
- bret = avcodec_parameters_from_context(ctx->bsf->par_in, avctx);
- if (bret < 0) {
- ret = bret;
- goto end;
- }
-
- bret = av_bsf_init(ctx->bsf);
- if (bret < 0) {
- ret = bret;
- goto end;
- }
- }
-
{
- AVDictionaryEntry *en = NULL;
- while ((en = av_dict_get(ctx->rav1e_opts, "", en, AV_DICT_IGNORE_SUFFIX))) {
- int parse_ret = rav1e_config_parse(cfg, en->key, en->value);
- if (parse_ret < 0)
+ const AVDictionaryEntry *en = NULL;
+ while ((en = av_dict_iterate(ctx->rav1e_opts, en))) {
+ if (rav1e_config_parse(cfg, en->key, en->value) < 0)
av_log(avctx, AV_LOG_WARNING, "Invalid value for %s: %s.\n", en->key, en->value);
}
}
@@ -298,6 +276,12 @@ static av_cold int librav1e_encode_init(AVCodecContext *avctx)
goto end;
}
+ if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0)
+ rav1e_config_set_sample_aspect_ratio(cfg, (RaRational) {
+ avctx->sample_aspect_ratio.num,
+ avctx->sample_aspect_ratio.den
+ });
+
rret = rav1e_config_parse_int(cfg, "threads", avctx->thread_count);
if (rret < 0)
av_log(avctx, AV_LOG_WARNING, "Invalid number of threads, defaulting to auto.\n");
@@ -421,6 +405,23 @@ static av_cold int librav1e_encode_init(AVCodecContext *avctx)
goto end;
}
+ if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
+ RaData *seq_hdr = rav1e_container_sequence_header(ctx->ctx);
+
+ if (seq_hdr)
+ avctx->extradata = av_mallocz(seq_hdr->len + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!seq_hdr || !avctx->extradata) {
+ rav1e_data_unref(seq_hdr);
+ av_log(avctx, AV_LOG_ERROR, "Failed to get extradata.\n");
+ ret = seq_hdr ? AVERROR(ENOMEM) : AVERROR_EXTERNAL;
+ goto end;
+ }
+
+ memcpy(avctx->extradata, seq_hdr->data, seq_hdr->len);
+ avctx->extradata_size = seq_hdr->len;
+ rav1e_data_unref(seq_hdr);
+ }
+
ret = 0;
end:
@@ -430,11 +431,23 @@ end:
return ret;
}
+static void frame_data_free(void *data)
+{
+ FrameData *fd = data;
+
+ if (!fd)
+ return;
+
+ av_buffer_unref(&fd->frame_opaque_ref);
+ av_free(data);
+}
+
static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
{
librav1eContext *ctx = avctx->priv_data;
RaFrame *rframe = ctx->rframe;
RaPacket *rpkt = NULL;
+ FrameData *fd;
int ret;
if (!rframe) {
@@ -447,18 +460,34 @@ static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
if (frame->buf[0]) {
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
- int64_t *pts = av_malloc(sizeof(int64_t));
- if (!pts) {
+ fd = av_mallocz(sizeof(*fd));
+ if (!fd) {
av_log(avctx, AV_LOG_ERROR, "Could not allocate PTS buffer.\n");
return AVERROR(ENOMEM);
}
- *pts = frame->pts;
+ fd->pts = frame->pts;
+ fd->duration = frame->duration;
+#if FF_API_REORDERED_OPAQUE
+FF_DISABLE_DEPRECATION_WARNINGS
+ fd->reordered_opaque = frame->reordered_opaque;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+ fd->frame_opaque = frame->opaque;
+ ret = av_buffer_replace(&fd->frame_opaque_ref, frame->opaque_ref);
+ if (ret < 0) {
+ frame_data_free(fd);
+ av_frame_unref(frame);
+ return ret;
+ }
+ }
rframe = rav1e_frame_new(ctx->ctx);
if (!rframe) {
av_log(avctx, AV_LOG_ERROR, "Could not allocate new rav1e frame.\n");
av_frame_unref(frame);
- av_freep(&pts);
+ frame_data_free(fd);
return AVERROR(ENOMEM);
}
@@ -470,7 +499,7 @@ static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
frame->linesize[i], bytes);
}
av_frame_unref(frame);
- rav1e_frame_set_opaque(rframe, pts, av_free);
+ rav1e_frame_set_opaque(rframe, fd, frame_data_free);
}
}
@@ -546,26 +575,50 @@ retry:
if (rpkt->frame_type == RA_FRAME_TYPE_KEY)
pkt->flags |= AV_PKT_FLAG_KEY;
- pkt->pts = pkt->dts = *((int64_t *) rpkt->opaque);
- av_free(rpkt->opaque);
- rav1e_packet_unref(rpkt);
+ fd = rpkt->opaque;
+ pkt->pts = pkt->dts = fd->pts;
+ pkt->duration = fd->duration;
+#if FF_API_REORDERED_OPAQUE
+FF_DISABLE_DEPRECATION_WARNINGS
+ avctx->reordered_opaque = fd->reordered_opaque;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
- if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
- int ret = av_bsf_send_packet(ctx->bsf, pkt);
+ if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+ pkt->opaque = fd->frame_opaque;
+ pkt->opaque_ref = fd->frame_opaque_ref;
+ fd->frame_opaque_ref = NULL;
+ }
+
+ frame_data_free(fd);
+
+ if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME) {
+ AVCodecInternal *avci = avctx->internal;
+ AVFrame *frame = avci->recon_frame;
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+
+ av_frame_unref(frame);
+
+ frame->format = avctx->pix_fmt;
+ frame->width = avctx->width;
+ frame->height = avctx->height;
+
+ ret = ff_encode_alloc_frame(avctx, frame);
if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "extradata extraction send failed.\n");
- av_packet_unref(pkt);
+ rav1e_packet_unref(rpkt);
return ret;
}
- ret = av_bsf_receive_packet(ctx->bsf, pkt);
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "extradata extraction receive failed.\n");
- av_packet_unref(pkt);
- return ret;
+ for (int i = 0; i < desc->nb_components; i++) {
+ int shift = i ? desc->log2_chroma_h : 0;
+ rav1e_frame_extract_plane(rpkt->rec, i, frame->data[i],
+ (frame->height >> shift) * frame->linesize[i],
+ frame->linesize[i], desc->comp[i].step);
}
}
+ rav1e_packet_unref(rpkt);
+
return 0;
}
@@ -616,7 +669,7 @@ static const AVClass class = {
const FFCodec ff_librav1e_encoder = {
.p.name = "librav1e",
- .p.long_name = NULL_IF_CONFIG_SMALL("librav1e AV1"),
+ CODEC_LONG_NAME("librav1e AV1"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AV1,
.init = librav1e_encode_init,
@@ -627,7 +680,9 @@ const FFCodec ff_librav1e_encoder = {
.defaults = librav1e_defaults,
.p.pix_fmts = librav1e_pix_fmts,
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS |
- AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS,
+ AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_RECON_FRAME |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS,
.p.wrapper_name = "librav1e",
};
diff --git a/libavcodec/librsvgdec.c b/libavcodec/librsvgdec.c
index 6e949fe3d..9c8aa2ded 100644
--- a/libavcodec/librsvgdec.c
+++ b/libavcodec/librsvgdec.c
@@ -21,7 +21,7 @@
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "libavutil/opt.h"
#include "librsvg-2.0/librsvg/rsvg.h"
@@ -120,7 +120,7 @@ static const AVClass librsvg_decoder_class = {
const FFCodec ff_librsvg_decoder = {
.p.name = "librsvg",
- .p.long_name = NULL_IF_CONFIG_SMALL("Librsvg rasterizer"),
+ CODEC_LONG_NAME("Librsvg rasterizer"),
.p.priv_class = &librsvg_decoder_class,
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_SVG,
diff --git a/libavcodec/libshine.c b/libavcodec/libshine.c
index 9bc545689..2f6a9233e 100644
--- a/libavcodec/libshine.c
+++ b/libavcodec/libshine.c
@@ -44,11 +44,6 @@ static av_cold int libshine_encode_init(AVCodecContext *avctx)
{
SHINEContext *s = avctx->priv_data;
- if (avctx->ch_layout.nb_channels <= 0 || avctx->ch_layout.nb_channels > 2){
- av_log(avctx, AV_LOG_ERROR, "only mono or stereo is supported\n");
- return AVERROR(EINVAL);
- }
-
shine_set_config_mpeg_defaults(&s->config.mpeg);
if (avctx->bit_rate)
s->config.mpeg.bitr = avctx->bit_rate / 1000;
@@ -133,10 +128,11 @@ static const int libshine_sample_rates[] = {
const FFCodec ff_libshine_encoder = {
.p.name = "libshine",
- .p.long_name = NULL_IF_CONFIG_SMALL("libshine MP3 (MPEG audio layer 3)"),
+ CODEC_LONG_NAME("libshine MP3 (MPEG audio layer 3)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_MP3,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(SHINEContext),
.init = libshine_encode_init,
FF_CODEC_ENCODE_CB(libshine_encode_frame),
@@ -144,11 +140,7 @@ const FFCodec ff_libshine_encoder = {
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_NONE },
.p.supported_samplerates = libshine_sample_rates,
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
- AV_CH_LAYOUT_STEREO,
- 0 },
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS(AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO)
.p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_MONO,
AV_CHANNEL_LAYOUT_STEREO,
{ 0 },
diff --git a/libavcodec/libspeexdec.c b/libavcodec/libspeexdec.c
index bb8e1a7db..47fc5d6a4 100644
--- a/libavcodec/libspeexdec.c
+++ b/libavcodec/libspeexdec.c
@@ -27,7 +27,7 @@
#include "libavutil/common.h"
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
typedef struct LibSpeexContext {
SpeexBits bits;
@@ -192,11 +192,12 @@ static av_cold void libspeex_decode_flush(AVCodecContext *avctx)
const FFCodec ff_libspeex_decoder = {
.p.name = "libspeex",
- .p.long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"),
+ CODEC_LONG_NAME("libspeex Speex"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_SPEEX,
.p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
.p.wrapper_name = "libspeex",
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(LibSpeexContext),
.init = libspeex_decode_init,
.close = libspeex_decode_close,
diff --git a/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c
index ec4b3c6a8..9fdb24786 100644
--- a/libavcodec/libspeexenc.c
+++ b/libavcodec/libspeexenc.c
@@ -152,13 +152,6 @@ static av_cold int encode_init(AVCodecContext *avctx)
int header_size;
int32_t complexity;
- /* channels */
- if (channels < 1 || channels > 2) {
- av_log(avctx, AV_LOG_ERROR, "Invalid channels (%d). Only stereo and "
- "mono are supported\n", channels);
- return AVERROR(EINVAL);
- }
-
/* sample rate and encoding mode */
switch (avctx->sample_rate) {
case 8000: mode = speex_lib_get_mode(SPEEX_MODEID_NB); break;
@@ -350,21 +343,18 @@ static const FFCodecDefault defaults[] = {
const FFCodec ff_libspeex_encoder = {
.p.name = "libspeex",
- .p.long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"),
+ CODEC_LONG_NAME("libspeex Speex"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_SPEEX,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(LibSpeexEncContext),
.init = encode_init,
FF_CODEC_ENCODE_CB(encode_frame),
.close = encode_close,
- .p.capabilities = AV_CODEC_CAP_DELAY,
.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_NONE },
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = (const uint64_t[]){ AV_CH_LAYOUT_MONO,
- AV_CH_LAYOUT_STEREO,
- 0 },
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS(AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO)
.p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_MONO,
AV_CHANNEL_LAYOUT_STEREO,
{ 0 },
diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c
index 4001cf7f0..56e1e22b5 100644
--- a/libavcodec/libsvtav1.c
+++ b/libavcodec/libsvtav1.c
@@ -124,16 +124,12 @@ static int svt_print_error(void *log_ctx, EbErrorType err,
static int alloc_buffer(EbSvtAv1EncConfiguration *config, SvtContext *svt_enc)
{
- const int pack_mode_10bit =
- (config->encoder_bit_depth > 8) && (config->compressed_ten_bit_format == 0) ? 1 : 0;
- const size_t luma_size_8bit =
- config->source_width * config->source_height * (1 << pack_mode_10bit);
- const size_t luma_size_10bit =
- (config->encoder_bit_depth > 8 && pack_mode_10bit == 0) ? luma_size_8bit : 0;
+ const size_t luma_size = config->source_width * config->source_height *
+ (config->encoder_bit_depth > 8 ? 2 : 1);
EbSvtIOFormat *in_data;
- svt_enc->raw_size = (luma_size_8bit + luma_size_10bit) * 3 / 2;
+ svt_enc->raw_size = luma_size * 3 / 2;
// allocate buffer for in and out
svt_enc->in_buf = av_mallocz(sizeof(*svt_enc->in_buf));
@@ -159,14 +155,19 @@ static int config_enc_params(EbSvtAv1EncConfiguration *param,
// Update param from options
#if FF_API_SVTAV1_OPTS
- param->hierarchical_levels = svt_enc->hierarchical_level;
- param->tier = svt_enc->tier;
- param->scene_change_detection = svt_enc->scd;
- param->tile_columns = svt_enc->tile_columns;
- param->tile_rows = svt_enc->tile_rows;
+ if (svt_enc->hierarchical_level >= 0)
+ param->hierarchical_levels = svt_enc->hierarchical_level;
+ if (svt_enc->tier >= 0)
+ param->tier = svt_enc->tier;
+ if (svt_enc->scd >= 0)
+ param->scene_change_detection = svt_enc->scd;
+ if (svt_enc->tile_columns >= 0)
+ param->tile_columns = svt_enc->tile_columns;
+ if (svt_enc->tile_rows >= 0)
+ param->tile_rows = svt_enc->tile_rows;
if (svt_enc->la_depth >= 0)
- param->look_ahead_distance = svt_enc->la_depth;
+ param->look_ahead_distance = svt_enc->la_depth;
#endif
if (svt_enc->enc_mode >= 0)
@@ -183,7 +184,8 @@ static int config_enc_params(EbSvtAv1EncConfiguration *param,
param->min_qp_allowed = avctx->qmin;
}
param->max_bit_rate = avctx->rc_max_rate;
- param->vbv_bufsize = avctx->rc_buffer_size;
+ if (avctx->bit_rate && avctx->rc_buffer_size)
+ param->maximum_buffer_size_ms = avctx->rc_buffer_size * 1000LL / avctx->bit_rate;
if (svt_enc->crf > 0) {
param->qp = svt_enc->crf;
@@ -300,7 +302,7 @@ static int config_enc_params(EbSvtAv1EncConfiguration *param,
avctx->bit_rate = param->rate_control_mode > 0 ?
param->target_bit_rate : 0;
avctx->rc_max_rate = param->max_bit_rate;
- avctx->rc_buffer_size = param->vbv_bufsize;
+ avctx->rc_buffer_size = param->maximum_buffer_size_ms * avctx->bit_rate / 1000LL;
if (avctx->bit_rate || avctx->rc_max_rate || avctx->rc_buffer_size) {
AVCPBProperties *cpb_props = ff_add_cpb_side_data(avctx);
@@ -575,7 +577,7 @@ static av_cold int eb_enc_close(AVCodecContext *avctx)
static const AVOption options[] = {
#if FF_API_SVTAV1_OPTS
{ "hielevel", "Hierarchical prediction levels setting (Deprecated, use svtav1-params)", OFFSET(hierarchical_level),
- AV_OPT_TYPE_INT, { .i64 = 4 }, 3, 4, VE | AV_OPT_FLAG_DEPRECATED , "hielevel"},
+ AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 4, VE | AV_OPT_FLAG_DEPRECATED , "hielevel"},
{ "3level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, INT_MIN, INT_MAX, VE, "hielevel" },
{ "4level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 4 }, INT_MIN, INT_MAX, VE, "hielevel" },
@@ -583,7 +585,7 @@ static const AVOption options[] = {
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 120, VE | AV_OPT_FLAG_DEPRECATED },
{ "tier", "Set operating point tier (Deprecated, use svtav1-params)", OFFSET(tier),
- AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE | AV_OPT_FLAG_DEPRECATED, "tier" },
+ AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE | AV_OPT_FLAG_DEPRECATED, "tier" },
{ "main", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, VE, "tier" },
{ "high", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, VE, "tier" },
#endif
@@ -626,10 +628,10 @@ static const AVOption options[] = {
AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 63, VE },
#if FF_API_SVTAV1_OPTS
{ "sc_detection", "Scene change detection (Deprecated, use svtav1-params)", OFFSET(scd),
- AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE | AV_OPT_FLAG_DEPRECATED },
+ AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE | AV_OPT_FLAG_DEPRECATED },
- { "tile_columns", "Log2 of number of tile columns to use (Deprecated, use svtav1-params)", OFFSET(tile_columns), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 4, VE | AV_OPT_FLAG_DEPRECATED },
- { "tile_rows", "Log2 of number of tile rows to use (Deprecated, use svtav1-params)", OFFSET(tile_rows), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 6, VE | AV_OPT_FLAG_DEPRECATED },
+ { "tile_columns", "Log2 of number of tile columns to use (Deprecated, use svtav1-params)", OFFSET(tile_columns), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 4, VE | AV_OPT_FLAG_DEPRECATED },
+ { "tile_rows", "Log2 of number of tile rows to use (Deprecated, use svtav1-params)", OFFSET(tile_rows), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 6, VE | AV_OPT_FLAG_DEPRECATED },
#endif
{ "svtav1-params", "Set the SVT-AV1 configuration using a :-separated list of key=value parameters", OFFSET(svtav1_opts), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },
@@ -655,7 +657,7 @@ static const FFCodecDefault eb_enc_defaults[] = {
const FFCodec ff_libsvtav1_encoder = {
.p.name = "libsvtav1",
- .p.long_name = NULL_IF_CONFIG_SMALL("SVT-AV1(Scalable Video Technology for AV1) encoder"),
+ CODEC_LONG_NAME("SVT-AV1(Scalable Video Technology for AV1) encoder"),
.priv_data_size = sizeof(SvtContext),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AV1,
@@ -663,7 +665,8 @@ const FFCodec ff_libsvtav1_encoder = {
FF_CODEC_RECEIVE_PACKET_CB(eb_receive_packet),
.close = eb_enc_close,
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
- .caps_internal = FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP,
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P,
AV_PIX_FMT_YUV420P10,
AV_PIX_FMT_NONE },
diff --git a/libavcodec/libtheoraenc.c b/libavcodec/libtheoraenc.c
index 162d170b0..06eeaae00 100644
--- a/libavcodec/libtheoraenc.c
+++ b/libavcodec/libtheoraenc.c
@@ -119,7 +119,7 @@ static int get_stats(AVCodecContext *avctx, int eos)
return 0;
#else
av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n");
- return AVERROR(ENOSUP);
+ return AVERROR(ENOTSUP);
#endif
}
@@ -158,7 +158,7 @@ static int submit_stats(AVCodecContext *avctx)
return 0;
#else
av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n");
- return AVERROR(ENOSUP);
+ return AVERROR(ENOTSUP);
#endif
}
@@ -346,7 +346,13 @@ static int encode_frame(AVCodecContext* avc_context, AVPacket *pkt,
// HACK: assumes no encoder delay, this is true until libtheora becomes
// multithreaded (which will be disabled unless explicitly requested)
- pkt->pts = pkt->dts = frame->pts;
+ pkt->pts = frame->pts;
+ pkt->duration = frame->duration;
+
+ ret = ff_encode_reordered_opaque(avc_context, pkt, frame);
+ if (ret < 0)
+ return ret;
+
if (!(o_packet.granulepos & h->keyframe_mask))
pkt->flags |= AV_PKT_FLAG_KEY;
*got_packet = 1;
@@ -369,11 +375,14 @@ static av_cold int encode_close(AVCodecContext* avc_context)
/** AVCodec struct exposed to libavcodec */
const FFCodec ff_libtheora_encoder = {
.p.name = "libtheora",
- .p.long_name = NULL_IF_CONFIG_SMALL("libtheora Theora"),
+ CODEC_LONG_NAME("libtheora Theora"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_THEORA,
.p.capabilities = AV_CODEC_CAP_DR1 |
- AV_CODEC_CAP_DELAY /* for statsfile summary */,
+ /* for statsfile summary */
+ AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(TheoraContext),
.init = encode_init,
.close = encode_close,
diff --git a/libavcodec/libtwolame.c b/libavcodec/libtwolame.c
index 1e53cf225..9c0156aa2 100644
--- a/libavcodec/libtwolame.c
+++ b/libavcodec/libtwolame.c
@@ -33,7 +33,6 @@
#include "avcodec.h"
#include "codec_internal.h"
#include "encode.h"
-#include "internal.h"
#include "mpegaudio.h"
typedef struct TWOLAMEContext {
@@ -211,14 +210,15 @@ static const int twolame_samplerates[] = {
const FFCodec ff_libtwolame_encoder = {
.p.name = "libtwolame",
- .p.long_name = NULL_IF_CONFIG_SMALL("libtwolame MP2 (MPEG audio layer 2)"),
+ CODEC_LONG_NAME("libtwolame MP2 (MPEG audio layer 2)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_MP2,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(TWOLAMEContext),
.init = twolame_encode_init,
FF_CODEC_ENCODE_CB(twolame_encode_frame),
.close = twolame_encode_close,
- .p.capabilities = AV_CODEC_CAP_DELAY,
.defaults = twolame_defaults,
.p.priv_class = &twolame_class,
.p.sample_fmts = (const enum AVSampleFormat[]) {
@@ -228,12 +228,7 @@ const FFCodec ff_libtwolame_encoder = {
AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_NONE
},
-#if FF_API_OLD_CHANNEL_LAYOUT
- .p.channel_layouts = (const uint64_t[]) {
- AV_CH_LAYOUT_MONO,
- AV_CH_LAYOUT_STEREO,
- 0 },
-#endif
+ CODEC_OLD_CHANNEL_LAYOUTS(AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO)
.p.ch_layouts = (const AVChannelLayout[]) {
AV_CHANNEL_LAYOUT_MONO,
AV_CHANNEL_LAYOUT_STEREO,
diff --git a/libavcodec/libuavs3d.c b/libavcodec/libuavs3d.c
index 7c6c3f044..b1ccb151e 100644
--- a/libavcodec/libuavs3d.c
+++ b/libavcodec/libuavs3d.c
@@ -30,7 +30,7 @@
#include "avcodec.h"
#include "avs3.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "uavs3d.h"
typedef struct uavs3d_context {
@@ -81,8 +81,12 @@ static void uavs3d_output_callback(uavs3d_io_frm_t *dec_frame) {
frm->pkt_dts = dec_frame->dts;
frm->pkt_pos = dec_frame->pkt_pos;
frm->pkt_size = dec_frame->pkt_size;
+#if FF_API_FRAME_PICTURE_NUMBER
+FF_DISABLE_DEPRECATION_WARNINGS
frm->coded_picture_number = dec_frame->dtr;
frm->display_picture_number = dec_frame->ptr;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
if (dec_frame->type < 0 || dec_frame->type >= FF_ARRAY_ELEMS(ff_avs3_image_type)) {
av_log(NULL, AV_LOG_WARNING, "Error frame type in uavs3d: %d.\n", dec_frame->type);
@@ -248,7 +252,7 @@ static int libuavs3d_decode_frame(AVCodecContext *avctx, AVFrame *frm,
const FFCodec ff_libuavs3d_decoder = {
.p.name = "libuavs3d",
- .p.long_name = NULL_IF_CONFIG_SMALL("libuavs3d AVS3-P2/IEEE1857.10"),
+ CODEC_LONG_NAME("libuavs3d AVS3-P2/IEEE1857.10"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AVS3,
.priv_data_size = sizeof(uavs3d_context),
@@ -256,7 +260,8 @@ const FFCodec ff_libuavs3d_decoder = {
.close = libuavs3d_end,
FF_CODEC_DECODE_CB(libuavs3d_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
- .caps_internal = FF_CODEC_CAP_AUTO_THREADS,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_AUTO_THREADS,
.flush = libuavs3d_flush,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_YUV420P10LE,
diff --git a/libavcodec/libvo-amrwbenc.c b/libavcodec/libvo-amrwbenc.c
index 12ef6d7fe..02b8941a6 100644
--- a/libavcodec/libvo-amrwbenc.c
+++ b/libavcodec/libvo-amrwbenc.c
@@ -29,7 +29,6 @@
#include "avcodec.h"
#include "codec_internal.h"
#include "encode.h"
-#include "internal.h"
#define MAX_PACKET_SIZE (1 + (477 + 7) / 8)
@@ -142,12 +141,14 @@ static int amr_wb_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
const FFCodec ff_libvo_amrwbenc_encoder = {
.p.name = "libvo_amrwbenc",
- .p.long_name = NULL_IF_CONFIG_SMALL("Android VisualOn AMR-WB "
- "(Adaptive Multi-Rate Wide-Band)"),
+ CODEC_LONG_NAME("Android VisualOn AMR-WB (Adaptive Multi-Rate Wide-Band)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AMR_WB,
+ .p.capabilities = AV_CODEC_CAP_DR1 |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.p.priv_class = &amrwb_class,
.p.wrapper_name = "libvo_amrwbenc",
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(AMRWBContext),
.init = amr_wb_encode_init,
FF_CODEC_ENCODE_CB(amr_wb_encode_frame),
diff --git a/libavcodec/libvorbisdec.c b/libavcodec/libvorbisdec.c
index 81c4ac1c0..a5e7a691d 100644
--- a/libavcodec/libvorbisdec.c
+++ b/libavcodec/libvorbisdec.c
@@ -23,7 +23,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
typedef struct OggVorbisDecContext {
vorbis_info vi; /**< vorbis_info used during init */
@@ -212,10 +212,11 @@ static int oggvorbis_decode_close(AVCodecContext *avccontext) {
const FFCodec ff_libvorbis_decoder = {
.p.name = "libvorbis",
- .p.long_name = NULL_IF_CONFIG_SMALL("libvorbis"),
+ CODEC_LONG_NAME("libvorbis"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_VORBIS,
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_CHANNEL_CONF,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(OggVorbisDecContext),
.init = oggvorbis_decode_init,
FF_CODEC_DECODE_CB(oggvorbis_decode_frame),
diff --git a/libavcodec/libvorbisenc.c b/libavcodec/libvorbisenc.c
index 9460d3267..6331cf0d7 100644
--- a/libavcodec/libvorbisenc.c
+++ b/libavcodec/libvorbisenc.c
@@ -28,9 +28,7 @@
#include "audio_frame_queue.h"
#include "codec_internal.h"
#include "encode.h"
-#include "internal.h"
#include "version.h"
-#include "vorbis.h"
#include "vorbis_parser.h"
@@ -377,11 +375,12 @@ static int libvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
const FFCodec ff_libvorbis_encoder = {
.p.name = "libvorbis",
- .p.long_name = NULL_IF_CONFIG_SMALL("libvorbis"),
+ CODEC_LONG_NAME("libvorbis"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_VORBIS,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SMALL_LAST_FRAME,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(LibvorbisEncContext),
.init = libvorbis_encode_init,
FF_CODEC_ENCODE_CB(libvorbis_encode_frame),
diff --git a/libavcodec/libvpx.h b/libavcodec/libvpx.h
index 0caed8cdc..331feb874 100644
--- a/libavcodec/libvpx.h
+++ b/libavcodec/libvpx.h
@@ -25,6 +25,8 @@
#include "codec_internal.h"
+#define MAX_VPX_THREADS 64
+
void ff_vp9_init_static(FFCodec *codec);
#if 0
enum AVPixelFormat ff_vpx_imgfmt_to_pixfmt(vpx_img_fmt_t img);
diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c
index 0b279e7ed..0ae19c3f7 100644
--- a/libavcodec/libvpxdec.c
+++ b/libavcodec/libvpxdec.c
@@ -37,7 +37,6 @@
#include "avcodec.h"
#include "codec_internal.h"
#include "decode.h"
-#include "internal.h"
#include "libvpx.h"
#include "profiles.h"
@@ -89,7 +88,7 @@ static av_cold int vpx_init(AVCodecContext *avctx,
const struct vpx_codec_iface *iface)
{
struct vpx_codec_dec_cfg deccfg = {
- .threads = FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), 16)
+ .threads = FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), MAX_VPX_THREADS)
};
av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str());
@@ -357,7 +356,7 @@ static av_cold int vp8_init(AVCodecContext *avctx)
const FFCodec ff_libvpx_vp8_decoder = {
.p.name = "libvpx",
- .p.long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"),
+ CODEC_LONG_NAME("libvpx VP8"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_VP8,
.p.capabilities = AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_CAP_DR1,
@@ -366,7 +365,8 @@ const FFCodec ff_libvpx_vp8_decoder = {
.init = vp8_init,
.close = vpx_free,
FF_CODEC_DECODE_CB(vpx_decode),
- .caps_internal = FF_CODEC_CAP_AUTO_THREADS,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_AUTO_THREADS,
};
#endif /* CONFIG_LIBVPX_VP8_DECODER */
@@ -379,7 +379,7 @@ static av_cold int vp9_init(AVCodecContext *avctx)
FFCodec ff_libvpx_vp9_decoder = {
.p.name = "libvpx-vp9",
- .p.long_name = NULL_IF_CONFIG_SMALL("libvpx VP9"),
+ CODEC_LONG_NAME("libvpx VP9"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_VP9,
.p.capabilities = AV_CODEC_CAP_OTHER_THREADS,
@@ -389,7 +389,8 @@ FFCodec ff_libvpx_vp9_decoder = {
.init = vp9_init,
.close = vpx_free,
FF_CODEC_DECODE_CB(vpx_decode),
- .caps_internal = FF_CODEC_CAP_AUTO_THREADS,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_AUTO_THREADS,
.init_static_data = ff_vp9_init_static,
};
#endif /* CONFIG_LIBVPX_VP9_DECODER */
diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index 5e5247ac7..339d4d814 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -80,6 +80,7 @@ typedef struct VPxEncoderContext {
struct vpx_image rawimg_alpha;
uint8_t is_alpha;
struct vpx_fixed_buf twopass_stats;
+ unsigned twopass_stats_size;
int deadline; //i.e., RT/GOOD/BEST
uint64_t sse[4];
int have_sse; /**< true if we have pending sse[] */
@@ -130,6 +131,7 @@ typedef struct VPxEncoderContext {
int tune_content;
int corpus_complexity;
int tpl_model;
+ int min_gf_interval;
AVFifo *hdr10_plus_fifo;
/**
* If the driver does not support ROI then warn the first time we
@@ -185,6 +187,9 @@ static const char *const ctlidstr[] = {
#ifdef VPX_CTRL_VP9E_SET_TPL
[VP9E_SET_TPL] = "VP9E_SET_TPL",
#endif
+#ifdef VPX_CTRL_VP9E_SET_MIN_GF_INTERVAL
+ [VP9E_SET_MIN_GF_INTERVAL] = "VP9E_SET_MIN_GF_INTERVAL",
+#endif
#endif
};
@@ -895,7 +900,7 @@ static av_cold int vpx_init(AVCodecContext *avctx,
vpx_codec_caps_t codec_caps = vpx_codec_get_caps(iface);
vpx_svc_extra_cfg_t svc_params;
#endif
- AVDictionaryEntry* en = NULL;
+ const AVDictionaryEntry* en = NULL;
av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str());
av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config());
@@ -937,7 +942,7 @@ static av_cold int vpx_init(AVCodecContext *avctx,
enccfg.g_timebase.num = avctx->time_base.num;
enccfg.g_timebase.den = avctx->time_base.den;
enccfg.g_threads =
- FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), 16);
+ FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), MAX_VPX_THREADS);
enccfg.g_lag_in_frames= ctx->lag_in_frames;
if (avctx->flags & AV_CODEC_FLAG_PASS1)
@@ -1067,7 +1072,7 @@ static av_cold int vpx_init(AVCodecContext *avctx,
enccfg.g_error_resilient = ctx->error_resilient || ctx->flags & VP8F_ERROR_RESILIENT;
- while ((en = av_dict_get(ctx->vpx_ts_parameters, "", en, AV_DICT_IGNORE_SUFFIX))) {
+ while ((en = av_dict_iterate(ctx->vpx_ts_parameters, en))) {
if (vpx_ts_param_parse(ctx, &enccfg, en->key, en->value, avctx->codec_id) < 0)
av_log(avctx, AV_LOG_WARNING,
"Error parsing option '%s = %s'.\n",
@@ -1172,6 +1177,10 @@ static av_cold int vpx_init(AVCodecContext *avctx,
#ifdef VPX_CTRL_VP9E_SET_TPL
if (ctx->tpl_model >= 0)
codecctl_int(avctx, VP9E_SET_TPL, ctx->tpl_model);
+#endif
+#ifdef VPX_CTRL_VP9E_SET_MIN_GF_INTERVAL
+ if (ctx->min_gf_interval >= 0)
+ codecctl_int(avctx, VP9E_SET_MIN_GF_INTERVAL, ctx->min_gf_interval);
#endif
}
#endif
@@ -1356,16 +1365,20 @@ static int queue_frames(AVCodecContext *avctx, struct vpx_codec_ctx *encoder,
break;
case VPX_CODEC_STATS_PKT: {
struct vpx_fixed_buf *stats = &ctx->twopass_stats;
- int err;
+ uint8_t *tmp;
if (!pkt_out)
break;
- if ((err = av_reallocp(&stats->buf,
- stats->sz +
- pkt->data.twopass_stats.sz)) < 0) {
+ tmp = av_fast_realloc(stats->buf,
+ &ctx->twopass_stats_size,
+ stats->sz +
+ pkt->data.twopass_stats.sz);
+ if (!tmp) {
+ av_freep(&stats->buf);
stats->sz = 0;
av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n");
- return err;
+ return AVERROR(ENOMEM);
}
+ stats->buf = tmp;
memcpy((uint8_t*)stats->buf + stats->sz,
pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz);
stats->sz += pkt->data.twopass_stats.sz;
@@ -1906,6 +1919,9 @@ static const AVOption vp9_options[] = {
#endif
#ifdef VPX_CTRL_VP9E_SET_TPL
{ "enable-tpl", "Enable temporal dependency model", OFFSET(tpl_model), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE },
+#endif
+#ifdef VPX_CTRL_VP9E_SET_MIN_GF_INTERVAL
+ { "min-gf-interval", "Minimum golden/alternate reference frame interval", OFFSET(min_gf_interval), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE },
#endif
LEGACY_OPTIONS
{ NULL }
@@ -1939,7 +1955,7 @@ static const AVClass class_vp8 = {
const FFCodec ff_libvpx_vp8_encoder = {
.p.name = "libvpx",
- .p.long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"),
+ CODEC_LONG_NAME("libvpx VP8"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_VP8,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
@@ -1948,7 +1964,8 @@ const FFCodec ff_libvpx_vp8_encoder = {
.init = vp8_init,
FF_CODEC_ENCODE_CB(vpx_encode),
.close = vpx_free,
- .caps_internal = FF_CODEC_CAP_AUTO_THREADS,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_AUTO_THREADS,
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE },
.p.priv_class = &class_vp8,
.defaults = defaults,
@@ -1971,7 +1988,7 @@ static const AVClass class_vp9 = {
FFCodec ff_libvpx_vp9_encoder = {
.p.name = "libvpx-vp9",
- .p.long_name = NULL_IF_CONFIG_SMALL("libvpx VP9"),
+ CODEC_LONG_NAME("libvpx VP9"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_VP9,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
@@ -1983,7 +2000,8 @@ FFCodec ff_libvpx_vp9_encoder = {
.init = vp9_init,
FF_CODEC_ENCODE_CB(vpx_encode),
.close = vpx_free,
- .caps_internal = FF_CODEC_CAP_AUTO_THREADS,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_AUTO_THREADS,
.defaults = defaults,
.init_static_data = ff_vp9_init_static,
};
diff --git a/libavcodec/libwavpackenc.c b/libavcodec/libwavpackenc.c
deleted file mode 100644
index e84b07489..000000000
--- a/libavcodec/libwavpackenc.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include
-#include
-
-#include "libavutil/attributes.h"
-#include "libavutil/opt.h"
-#include "libavutil/samplefmt.h"
-
-#include "audio_frame_queue.h"
-#include "avcodec.h"
-#include "internal.h"
-
-#define WV_DEFAULT_BLOCK_SIZE 32768
-
-typedef struct LibWavpackContext {
- const AVClass *class;
- WavpackContext *wv;
- AudioFrameQueue afq;
-
- AVPacket *pkt;
- int user_size;
-
- int got_output;
-} LibWavpackContext;
-
-static int wavpack_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
- const AVFrame *frame, int *got_output)
-{
- LibWavpackContext *s = avctx->priv_data;
- int ret;
-
- s->got_output = 0;
- s->pkt = pkt;
- s->user_size = pkt->size;
-
- if (frame) {
- ret = ff_af_queue_add(&s->afq, frame);
- if (ret < 0)
- return ret;
-
- ret = WavpackPackSamples(s->wv, (int32_t*)frame->data[0], frame->nb_samples);
- if (!ret) {
- av_log(avctx, AV_LOG_ERROR, "Error encoding a frame: %s\n",
- WavpackGetErrorMessage(s->wv));
- return AVERROR_UNKNOWN;
- }
- }
-
- if (!s->got_output &&
- (!frame || frame->nb_samples < avctx->frame_size)) {
- ret = WavpackFlushSamples(s->wv);
- if (!ret) {
- av_log(avctx, AV_LOG_ERROR, "Error flushing the encoder: %s\n",
- WavpackGetErrorMessage(s->wv));
- return AVERROR_UNKNOWN;
- }
- }
-
- if (s->got_output) {
- ff_af_queue_remove(&s->afq, avctx->frame_size, &pkt->pts, &pkt->duration);
- *got_output = 1;
- }
-
- return 0;
-}
-
-static int encode_callback(void *id, void *data, int32_t count)
-{
- AVCodecContext *avctx = id;
- LibWavpackContext *s = avctx->priv_data;
- int ret, offset = s->pkt->size;
-
- if (s->user_size) {
- if (s->user_size - count < s->pkt->size) {
- av_log(avctx, AV_LOG_ERROR, "Provided packet too small.\n");
- return 0;
- }
- s->pkt->size += count;
- } else {
- ret = av_grow_packet(s->pkt, count);
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "Error allocating output packet.\n");
- return 0;
- }
- }
-
- memcpy(s->pkt->data + offset, data, count);
-
- s->got_output = 1;
-
- return 1;
-}
-
-static av_cold int wavpack_encode_init(AVCodecContext *avctx)
-{
- LibWavpackContext *s = avctx->priv_data;
- WavpackConfig config = { 0 };
- int ret;
-
- s->wv = WavpackOpenFileOutput(encode_callback, avctx, NULL);
- if (!s->wv) {
- av_log(avctx, AV_LOG_ERROR, "Error allocating the encoder.\n");
- return AVERROR(ENOMEM);
- }
-
- if (!avctx->frame_size)
- avctx->frame_size = WV_DEFAULT_BLOCK_SIZE;
-
- config.bytes_per_sample = 4;
- config.bits_per_sample = 32;
- config.block_samples = avctx->frame_size;
- config.channel_mask = avctx->channel_layout;
- config.num_channels = avctx->channels;
- config.sample_rate = avctx->sample_rate;
-
- if (avctx->compression_level != FF_COMPRESSION_DEFAULT) {
- if (avctx->compression_level >= 3) {
- config.flags |= CONFIG_VERY_HIGH_FLAG;
-
- if (avctx->compression_level >= 8)
- config.xmode = 6;
- else if (avctx->compression_level >= 7)
- config.xmode = 5;
- else if (avctx->compression_level >= 6)
- config.xmode = 4;
- else if (avctx->compression_level >= 5)
- config.xmode = 3;
- else if (avctx->compression_level >= 4)
- config.xmode = 2;
- } else if (avctx->compression_level >= 2)
- config.flags |= CONFIG_HIGH_FLAG;
- else if (avctx->compression_level < 1)
- config.flags |= CONFIG_FAST_FLAG;
- }
-
- ret = WavpackSetConfiguration(s->wv, &config, -1);
- if (!ret)
- goto fail;
-
- ret = WavpackPackInit(s->wv);
- if (!ret)
- goto fail;
-
- ff_af_queue_init(avctx, &s->afq);
-
- return 0;
-
-fail:
- av_log(avctx, AV_LOG_ERROR, "Error configuring the encoder: %s.\n",
- WavpackGetErrorMessage(s->wv));
- WavpackCloseFile(s->wv);
- return AVERROR_UNKNOWN;
-}
-
-static av_cold int wavpack_encode_close(AVCodecContext *avctx)
-{
- LibWavpackContext *s = avctx->priv_data;
-
- WavpackCloseFile(s->wv);
-
- ff_af_queue_close(&s->afq);
-
- return 0;
-}
-
-AVCodec ff_libwavpack_encoder = {
- .name = "libwavpack",
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_WAVPACK,
- .priv_data_size = sizeof(LibWavpackContext),
- .init = wavpack_encode_init,
- .encode2 = wavpack_encode_frame,
- .close = wavpack_encode_close,
- .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SMALL_LAST_FRAME,
- .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32,
- AV_SAMPLE_FMT_NONE },
- .wrapper_name = "libwavpack",
-};
diff --git a/libavcodec/libwebpenc.c b/libavcodec/libwebpenc.c
index c5dc1b160..d6edd8660 100644
--- a/libavcodec/libwebpenc.c
+++ b/libavcodec/libwebpenc.c
@@ -89,13 +89,14 @@ static int libwebp_encode_close(AVCodecContext *avctx)
const FFCodec ff_libwebp_encoder = {
.p.name = "libwebp",
- .p.long_name = NULL_IF_CONFIG_SMALL("libwebp WebP image"),
+ CODEC_LONG_NAME("libwebp WebP image"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_WEBP,
- .p.capabilities = AV_CODEC_CAP_DR1,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.p.pix_fmts = ff_libwebpenc_pix_fmts,
.p.priv_class = &ff_libwebpenc_class,
.p.wrapper_name = "libwebp",
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(LibWebPContext),
.defaults = ff_libwebp_defaults,
.init = libwebp_encode_init,
diff --git a/libavcodec/libwebpenc_animencoder.c b/libavcodec/libwebpenc_animencoder.c
index 765fcf70d..8756231f2 100644
--- a/libavcodec/libwebpenc_animencoder.c
+++ b/libavcodec/libwebpenc_animencoder.c
@@ -24,6 +24,8 @@
* WebP encoder using libwebp (WebPAnimEncoder API)
*/
+#include "libavutil/buffer.h"
+
#include "config.h"
#include "codec_internal.h"
#include "encode.h"
@@ -35,6 +37,14 @@ typedef struct LibWebPAnimContext {
LibWebPContextCommon cc;
WebPAnimEncoder *enc; // the main AnimEncoder object
int64_t first_frame_pts; // pts of the first encoded frame.
+ int64_t end_pts; // pts + duration of the last frame
+
+#if FF_API_REORDERED_OPAQUE
+ int64_t reordered_opaque;
+#endif
+ void *first_frame_opaque;
+ AVBufferRef *first_frame_opaque_ref;
+
int done; // If true, we have assembled the bitstream already
} LibWebPAnimContext;
@@ -77,7 +87,22 @@ static int libwebp_anim_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
memcpy(pkt->data, assembled_data.bytes, assembled_data.size);
WebPDataClear(&assembled_data);
s->done = 1;
- pkt->pts = pkt->dts = s->first_frame_pts;
+ pkt->pts = s->first_frame_pts;
+
+ if (pkt->pts != AV_NOPTS_VALUE && s->end_pts > pkt->pts)
+ pkt->duration = s->end_pts - pkt->pts;
+
+#if FF_API_REORDERED_OPAQUE
+FF_DISABLE_DEPRECATION_WARNINGS
+ avctx->reordered_opaque = s->reordered_opaque;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+ pkt->opaque = s->first_frame_opaque;
+ pkt->opaque_ref = s->first_frame_opaque_ref;
+ s->first_frame_opaque_ref = NULL;
+ }
+
*got_packet = 1;
return 0;
} else {
@@ -107,8 +132,25 @@ static int libwebp_anim_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
goto end;
}
- if (!avctx->frame_number)
+ if (!avctx->frame_num) {
s->first_frame_pts = frame->pts;
+#if FF_API_REORDERED_OPAQUE
+FF_DISABLE_DEPRECATION_WARNINGS
+ s->reordered_opaque = frame->reordered_opaque;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+ s->first_frame_opaque = frame->opaque;
+ ret = av_buffer_replace(&s->first_frame_opaque_ref, frame->opaque_ref);
+ if (ret < 0)
+ goto end;
+ }
+ }
+
+ if (frame->pts != AV_NOPTS_VALUE)
+ s->end_pts = frame->pts + frame->duration;
+
ret = 0;
*got_packet = 0;
@@ -126,18 +168,22 @@ static int libwebp_anim_encode_close(AVCodecContext *avctx)
av_frame_free(&s->cc.ref);
WebPAnimEncoderDelete(s->enc);
+ av_buffer_unref(&s->first_frame_opaque_ref);
+
return 0;
}
const FFCodec ff_libwebp_anim_encoder = {
.p.name = "libwebp_anim",
- .p.long_name = NULL_IF_CONFIG_SMALL("libwebp WebP image"),
+ CODEC_LONG_NAME("libwebp WebP image"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_WEBP,
- .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.p.pix_fmts = ff_libwebpenc_pix_fmts,
.p.priv_class = &ff_libwebpenc_class,
.p.wrapper_name = "libwebp",
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(LibWebPAnimContext),
.defaults = ff_libwebp_defaults,
.init = libwebp_anim_encode_init,
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 98ec03086..f65ac5dac 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -21,6 +21,7 @@
#include "config_components.h"
+#include "libavutil/buffer.h"
#include "libavutil/eval.h"
#include "libavutil/internal.h"
#include "libavutil/opt.h"
@@ -49,8 +50,14 @@
#define MB_SIZE 16
typedef struct X264Opaque {
+#if FF_API_REORDERED_OPAQUE
int64_t reordered_opaque;
+#endif
int64_t wallclock;
+ int64_t duration;
+
+ void *frame_opaque;
+ AVBufferRef *frame_opaque_ref;
} X264Opaque;
typedef struct X264Context {
@@ -133,6 +140,11 @@ static void X264_log(void *p, int level, const char *fmt, va_list args)
av_vlog(p, level_map[level], fmt, args);
}
+static void opaque_uninit(X264Opaque *o)
+{
+ av_buffer_unref(&o->frame_opaque_ref);
+ memset(o, 0, sizeof(*o));
+}
static int encode_nals(AVCodecContext *ctx, AVPacket *pkt,
const x264_nal_t *nals, int nnal)
@@ -311,191 +323,287 @@ static void free_picture(AVCodecContext *ctx)
pic->extra_sei.num_payloads = 0;
}
-static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
- int *got_packet)
+static enum AVPixelFormat csp_to_pixfmt(int csp)
+{
+ switch (csp) {
+#ifdef X264_CSP_I400
+ case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
+ case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
+#endif
+ case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
+ case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
+ case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
+ case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
+ case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
+ case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
+ case X264_CSP_NV12: return AV_PIX_FMT_NV12;
+#ifdef X264_CSP_NV21
+ case X264_CSP_NV21: return AV_PIX_FMT_NV21;
+#endif
+ case X264_CSP_NV16: return AV_PIX_FMT_NV16;
+ };
+ return AV_PIX_FMT_NONE;
+}
+
+static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic, int bit_depth,
+ const AVFrame *frame, const uint8_t *data, size_t size)
{
X264Context *x4 = ctx->priv_data;
- x264_nal_t *nal;
- int nnal, i, ret;
- x264_picture_t pic_out = {0};
- int pict_type;
- int bit_depth;
+
+ int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE;
+ int mby = (frame->height + MB_SIZE - 1) / MB_SIZE;
+ int qp_range = 51 + 6 * (bit_depth - 8);
+ int nb_rois;
+ const AVRegionOfInterest *roi;
+ uint32_t roi_size;
+ float *qoffsets;
+
+ if (x4->params.rc.i_aq_mode == X264_AQ_NONE) {
+ if (!x4->roi_warned) {
+ x4->roi_warned = 1;
+ av_log(ctx, AV_LOG_WARNING, "Adaptive quantization must be enabled to use ROI encoding, skipping ROI.\n");
+ }
+ return 0;
+ } else if (frame->interlaced_frame) {
+ if (!x4->roi_warned) {
+ x4->roi_warned = 1;
+ av_log(ctx, AV_LOG_WARNING, "interlaced_frame not supported for ROI encoding yet, skipping ROI.\n");
+ }
+ return 0;
+ }
+
+ roi = (const AVRegionOfInterest*)data;
+ roi_size = roi->self_size;
+ if (!roi_size || size % roi_size != 0) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n");
+ return AVERROR(EINVAL);
+ }
+ nb_rois = size / roi_size;
+
+ qoffsets = av_calloc(mbx * mby, sizeof(*qoffsets));
+ if (!qoffsets)
+ return AVERROR(ENOMEM);
+
+ // This list must be iterated in reverse because the first
+ // region in the list applies when regions overlap.
+ for (int i = nb_rois - 1; i >= 0; i--) {
+ int startx, endx, starty, endy;
+ float qoffset;
+
+ roi = (const AVRegionOfInterest*)(data + roi_size * i);
+
+ starty = FFMIN(mby, roi->top / MB_SIZE);
+ endy = FFMIN(mby, (roi->bottom + MB_SIZE - 1)/ MB_SIZE);
+ startx = FFMIN(mbx, roi->left / MB_SIZE);
+ endx = FFMIN(mbx, (roi->right + MB_SIZE - 1)/ MB_SIZE);
+
+ if (roi->qoffset.den == 0) {
+ av_free(qoffsets);
+ av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den must not be zero.\n");
+ return AVERROR(EINVAL);
+ }
+ qoffset = roi->qoffset.num * 1.0f / roi->qoffset.den;
+ qoffset = av_clipf(qoffset * qp_range, -qp_range, +qp_range);
+
+ for (int y = starty; y < endy; y++) {
+ for (int x = startx; x < endx; x++) {
+ qoffsets[x + y*mbx] = qoffset;
+ }
+ }
+ }
+
+ pic->prop.quant_offsets = qoffsets;
+ pic->prop.quant_offsets_free = av_free;
+
+ return 0;
+}
+
+static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
+ x264_picture_t **ppic)
+{
+ X264Context *x4 = ctx->priv_data;
+ X264Opaque *opaque = &x4->reordered_opaque[x4->next_reordered_opaque];
+ x264_picture_t *pic = &x4->pic;
+ x264_sei_t *sei = &pic->extra_sei;
+ unsigned int sei_data_size = 0;
int64_t wallclock = 0;
- X264Opaque *out_opaque;
+ int bit_depth, ret;
AVFrameSideData *sd;
- x264_picture_init( &x4->pic );
- x4->pic.img.i_csp = x4->params.i_csp;
+ *ppic = NULL;
+ if (!frame)
+ return 0;
+
+ x264_picture_init(pic);
+ pic->img.i_csp = x4->params.i_csp;
#if X264_BUILD >= 153
bit_depth = x4->params.i_bitdepth;
#else
bit_depth = x264_bit_depth;
#endif
if (bit_depth > 8)
- x4->pic.img.i_csp |= X264_CSP_HIGH_DEPTH;
- x4->pic.img.i_plane = avfmt2_num_planes(ctx->pix_fmt);
+ pic->img.i_csp |= X264_CSP_HIGH_DEPTH;
+ pic->img.i_plane = avfmt2_num_planes(ctx->pix_fmt);
- if (frame) {
- x264_sei_t *sei = &x4->pic.extra_sei;
- unsigned int sei_data_size = 0;
+ for (int i = 0; i < pic->img.i_plane; i++) {
+ pic->img.plane[i] = frame->data[i];
+ pic->img.i_stride[i] = frame->linesize[i];
+ }
- for (i = 0; i < x4->pic.img.i_plane; i++) {
- x4->pic.img.plane[i] = frame->data[i];
- x4->pic.img.i_stride[i] = frame->linesize[i];
- }
+ pic->i_pts = frame->pts;
- x4->pic.i_pts = frame->pts;
+ opaque_uninit(opaque);
- x4->reordered_opaque[x4->next_reordered_opaque].reordered_opaque = frame->reordered_opaque;
- x4->reordered_opaque[x4->next_reordered_opaque].wallclock = wallclock;
- if (ctx->export_side_data & AV_CODEC_EXPORT_DATA_PRFT)
- x4->reordered_opaque[x4->next_reordered_opaque].wallclock = av_gettime();
- x4->pic.opaque = &x4->reordered_opaque[x4->next_reordered_opaque];
- x4->next_reordered_opaque++;
- x4->next_reordered_opaque %= x4->nb_reordered_opaque;
+ if (ctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+ opaque->frame_opaque = frame->opaque;
+ ret = av_buffer_replace(&opaque->frame_opaque_ref, frame->opaque_ref);
+ if (ret < 0)
+ goto fail;
+ }
- switch (frame->pict_type) {
- case AV_PICTURE_TYPE_I:
- x4->pic.i_type = x4->forced_idr > 0 ? X264_TYPE_IDR
- : X264_TYPE_KEYFRAME;
- break;
- case AV_PICTURE_TYPE_P:
- x4->pic.i_type = X264_TYPE_P;
- break;
- case AV_PICTURE_TYPE_B:
- x4->pic.i_type = X264_TYPE_B;
- break;
- default:
- x4->pic.i_type = X264_TYPE_AUTO;
- break;
- }
- reconfig_encoder(ctx, frame);
+#if FF_API_REORDERED_OPAQUE
+FF_DISABLE_DEPRECATION_WARNINGS
+ opaque->reordered_opaque = frame->reordered_opaque;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ opaque->duration = frame->duration;
+ opaque->wallclock = wallclock;
+ if (ctx->export_side_data & AV_CODEC_EXPORT_DATA_PRFT)
+ opaque->wallclock = av_gettime();
- if (x4->a53_cc) {
- void *sei_data;
- size_t sei_size;
+ pic->opaque = opaque;
- ret = ff_alloc_a53_sei(frame, 0, &sei_data, &sei_size);
- if (ret < 0) {
- av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
- } else if (sei_data) {
- x4->pic.extra_sei.payloads = av_mallocz(sizeof(x4->pic.extra_sei.payloads[0]));
- if (x4->pic.extra_sei.payloads == NULL) {
- av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
- av_free(sei_data);
- } else {
- x4->pic.extra_sei.sei_free = av_free;
+ x4->next_reordered_opaque++;
+ x4->next_reordered_opaque %= x4->nb_reordered_opaque;
- x4->pic.extra_sei.payloads[0].payload_size = sei_size;
- x4->pic.extra_sei.payloads[0].payload = sei_data;
- x4->pic.extra_sei.num_payloads = 1;
- x4->pic.extra_sei.payloads[0].payload_type = 4;
- }
+ switch (frame->pict_type) {
+ case AV_PICTURE_TYPE_I:
+ pic->i_type = x4->forced_idr > 0 ? X264_TYPE_IDR : X264_TYPE_KEYFRAME;
+ break;
+ case AV_PICTURE_TYPE_P:
+ pic->i_type = X264_TYPE_P;
+ break;
+ case AV_PICTURE_TYPE_B:
+ pic->i_type = X264_TYPE_B;
+ break;
+ default:
+ pic->i_type = X264_TYPE_AUTO;
+ break;
+ }
+ reconfig_encoder(ctx, frame);
+
+ if (x4->a53_cc) {
+ void *sei_data;
+ size_t sei_size;
+
+ ret = ff_alloc_a53_sei(frame, 0, &sei_data, &sei_size);
+ if (ret < 0)
+ goto fail;
+
+ if (sei_data) {
+ pic->extra_sei.payloads = av_mallocz(sizeof(pic->extra_sei.payloads[0]));
+ if (pic->extra_sei.payloads == NULL) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
}
- }
- sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
- if (sd) {
- if (x4->params.rc.i_aq_mode == X264_AQ_NONE) {
- if (!x4->roi_warned) {
- x4->roi_warned = 1;
- av_log(ctx, AV_LOG_WARNING, "Adaptive quantization must be enabled to use ROI encoding, skipping ROI.\n");
- }
- } else {
- if (frame->interlaced_frame == 0) {
- int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE;
- int mby = (frame->height + MB_SIZE - 1) / MB_SIZE;
- int qp_range = 51 + 6 * (bit_depth - 8);
- int nb_rois;
- const AVRegionOfInterest *roi;
- uint32_t roi_size;
- float *qoffsets;
+ pic->extra_sei.sei_free = av_free;
- roi = (const AVRegionOfInterest*)sd->data;
- roi_size = roi->self_size;
- if (!roi_size || sd->size % roi_size != 0) {
- free_picture(ctx);
- av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n");
- return AVERROR(EINVAL);
- }
- nb_rois = sd->size / roi_size;
-
- qoffsets = av_calloc(mbx * mby, sizeof(*qoffsets));
- if (!qoffsets) {
- free_picture(ctx);
- return AVERROR(ENOMEM);
- }
- // This list must be iterated in reverse because the first
- // region in the list applies when regions overlap.
- for (int i = nb_rois - 1; i >= 0; i--) {
- int startx, endx, starty, endy;
- float qoffset;
-
- roi = (const AVRegionOfInterest*)(sd->data + roi_size * i);
-
- starty = FFMIN(mby, roi->top / MB_SIZE);
- endy = FFMIN(mby, (roi->bottom + MB_SIZE - 1)/ MB_SIZE);
- startx = FFMIN(mbx, roi->left / MB_SIZE);
- endx = FFMIN(mbx, (roi->right + MB_SIZE - 1)/ MB_SIZE);
-
- if (roi->qoffset.den == 0) {
- av_free(qoffsets);
- free_picture(ctx);
- av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den must not be zero.\n");
- return AVERROR(EINVAL);
- }
- qoffset = roi->qoffset.num * 1.0f / roi->qoffset.den;
- qoffset = av_clipf(qoffset * qp_range, -qp_range, +qp_range);
-
- for (int y = starty; y < endy; y++) {
- for (int x = startx; x < endx; x++) {
- qoffsets[x + y*mbx] = qoffset;
- }
- }
- }
-
- x4->pic.prop.quant_offsets = qoffsets;
- x4->pic.prop.quant_offsets_free = av_free;
- } else {
- if (!x4->roi_warned) {
- x4->roi_warned = 1;
- av_log(ctx, AV_LOG_WARNING, "interlaced_frame not supported for ROI encoding yet, skipping ROI.\n");
- }
- }
- }
- }
-
- if (x4->udu_sei) {
- for (int j = 0; j < frame->nb_side_data; j++) {
- AVFrameSideData *side_data = frame->side_data[j];
- void *tmp;
- x264_sei_payload_t *sei_payload;
- if (side_data->type != AV_FRAME_DATA_SEI_UNREGISTERED)
- continue;
- tmp = av_fast_realloc(sei->payloads, &sei_data_size, (sei->num_payloads + 1) * sizeof(*sei_payload));
- if (!tmp) {
- free_picture(ctx);
- return AVERROR(ENOMEM);
- }
- sei->payloads = tmp;
- sei->sei_free = av_free;
- sei_payload = &sei->payloads[sei->num_payloads];
- sei_payload->payload = av_memdup(side_data->data, side_data->size);
- if (!sei_payload->payload) {
- free_picture(ctx);
- return AVERROR(ENOMEM);
- }
- sei_payload->payload_size = side_data->size;
- sei_payload->payload_type = SEI_TYPE_USER_DATA_UNREGISTERED;
- sei->num_payloads++;
- }
+ pic->extra_sei.payloads[0].payload_size = sei_size;
+ pic->extra_sei.payloads[0].payload = sei_data;
+ pic->extra_sei.num_payloads = 1;
+ pic->extra_sei.payloads[0].payload_type = 4;
}
}
+ sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
+ if (sd) {
+ ret = setup_roi(ctx, pic, bit_depth, frame, sd->data, sd->size);
+ if (ret < 0)
+ goto fail;
+ }
+
+ if (x4->udu_sei) {
+ for (int j = 0; j < frame->nb_side_data; j++) {
+ AVFrameSideData *side_data = frame->side_data[j];
+ void *tmp;
+ x264_sei_payload_t *sei_payload;
+ if (side_data->type != AV_FRAME_DATA_SEI_UNREGISTERED)
+ continue;
+ tmp = av_fast_realloc(sei->payloads, &sei_data_size, (sei->num_payloads + 1) * sizeof(*sei_payload));
+ if (!tmp) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ sei->payloads = tmp;
+ sei->sei_free = av_free;
+ sei_payload = &sei->payloads[sei->num_payloads];
+ sei_payload->payload = av_memdup(side_data->data, side_data->size);
+ if (!sei_payload->payload) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ sei_payload->payload_size = side_data->size;
+ sei_payload->payload_type = SEI_TYPE_USER_DATA_UNREGISTERED;
+ sei->num_payloads++;
+ }
+ }
+
+ *ppic = pic;
+ return 0;
+
+fail:
+ free_picture(ctx);
+ *ppic = NULL;
+ return ret;
+}
+
+static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
+ int *got_packet)
+{
+ X264Context *x4 = ctx->priv_data;
+ x264_nal_t *nal;
+ int nnal, ret;
+ x264_picture_t pic_out = {0}, *pic_in;
+ int pict_type;
+ int64_t wallclock = 0;
+ X264Opaque *out_opaque;
+
+ ret = setup_frame(ctx, frame, &pic_in);
+ if (ret < 0)
+ return ret;
+
do {
- if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0)
+ if (x264_encoder_encode(x4->enc, &nal, &nnal, pic_in, &pic_out) < 0)
return AVERROR_EXTERNAL;
+ if (nnal && (ctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
+ AVCodecInternal *avci = ctx->internal;
+
+ av_frame_unref(avci->recon_frame);
+
+ avci->recon_frame->format = csp_to_pixfmt(pic_out.img.i_csp);
+ if (avci->recon_frame->format == AV_PIX_FMT_NONE) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Unhandled reconstructed frame colorspace: %d\n",
+ pic_out.img.i_csp);
+ return AVERROR(ENOSYS);
+ }
+
+ avci->recon_frame->width = ctx->width;
+ avci->recon_frame->height = ctx->height;
+ for (int i = 0; i < pic_out.img.i_plane; i++) {
+ avci->recon_frame->data[i] = pic_out.img.plane[i];
+ avci->recon_frame->linesize[i] = pic_out.img.i_stride[i];
+ }
+
+ ret = av_frame_make_writable(avci->recon_frame);
+ if (ret < 0) {
+ av_frame_unref(avci->recon_frame);
+ return ret;
+ }
+ }
+
ret = encode_nals(ctx, pkt, nal, nnal);
if (ret < 0)
return ret;
@@ -510,11 +618,30 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
out_opaque = pic_out.opaque;
if (out_opaque >= x4->reordered_opaque &&
out_opaque < &x4->reordered_opaque[x4->nb_reordered_opaque]) {
+#if FF_API_REORDERED_OPAQUE
+FF_DISABLE_DEPRECATION_WARNINGS
ctx->reordered_opaque = out_opaque->reordered_opaque;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
wallclock = out_opaque->wallclock;
+ pkt->duration = out_opaque->duration;
+
+ if (ctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+ pkt->opaque = out_opaque->frame_opaque;
+ pkt->opaque_ref = out_opaque->frame_opaque_ref;
+ out_opaque->frame_opaque_ref = NULL;
+ }
+
+ opaque_uninit(out_opaque);
} else {
// Unexpected opaque pointer on picture output
+ av_log(ctx, AV_LOG_ERROR, "Unexpected opaque pointer; "
+ "this is a bug, please report it.\n");
+#if FF_API_REORDERED_OPAQUE
+FF_DISABLE_DEPRECATION_WARNINGS
ctx->reordered_opaque = 0;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
}
switch (pic_out.i_type) {
@@ -550,6 +677,9 @@ static av_cold int X264_close(AVCodecContext *avctx)
X264Context *x4 = avctx->priv_data;
av_freep(&x4->sei);
+
+ for (int i = 0; i < x4->nb_reordered_opaque; i++)
+ opaque_uninit(&x4->reordered_opaque[i]);
av_freep(&x4->reordered_opaque);
#if X264_BUILD >= 161
@@ -928,6 +1058,9 @@ static av_cold int X264_init(AVCodecContext *avctx)
if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
x4->params.b_repeat_headers = 0;
+ if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME)
+ x4->params.b_full_recon = 1;
+
if(x4->x264opts){
const char *p= x4->x264opts;
while(p){
@@ -1018,10 +1151,12 @@ static av_cold int X264_init(AVCodecContext *avctx)
// Overestimate the reordered opaque buffer size, in case a runtime
// reconfigure would increase the delay (which it shouldn't).
x4->nb_reordered_opaque = x264_encoder_maximum_delayed_frames(x4->enc) + 17;
- x4->reordered_opaque = av_malloc_array(x4->nb_reordered_opaque,
- sizeof(*x4->reordered_opaque));
- if (!x4->reordered_opaque)
+ x4->reordered_opaque = av_calloc(x4->nb_reordered_opaque,
+ sizeof(*x4->reordered_opaque));
+ if (!x4->reordered_opaque) {
+ x4->nb_reordered_opaque = 0;
return AVERROR(ENOMEM);
+ }
return 0;
}
@@ -1218,12 +1353,13 @@ const
#endif
FFCodec ff_libx264_encoder = {
.p.name = "libx264",
- .p.long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
+ CODEC_LONG_NAME("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_H264,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_OTHER_THREADS |
- AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE |
+ AV_CODEC_CAP_ENCODER_RECON_FRAME,
.p.priv_class = &x264_class,
.p.wrapper_name = "libx264",
.priv_data_size = sizeof(X264Context),
@@ -1237,8 +1373,8 @@ FFCodec ff_libx264_encoder = {
.p.pix_fmts = pix_fmts_all,
#endif
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS
-#if X264_BUILD >= 158
- | FF_CODEC_CAP_INIT_THREADSAFE
+#if X264_BUILD < 158
+ | FF_CODEC_CAP_NOT_INIT_THREADSAFE
#endif
,
};
@@ -1254,7 +1390,7 @@ static const AVClass rgbclass = {
const FFCodec ff_libx264rgb_encoder = {
.p.name = "libx264rgb",
- .p.long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB"),
+ CODEC_LONG_NAME("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_H264,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
@@ -1269,8 +1405,8 @@ const FFCodec ff_libx264rgb_encoder = {
.close = X264_close,
.defaults = x264_defaults,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS
-#if X264_BUILD >= 158
- | FF_CODEC_CAP_INIT_THREADSAFE
+#if X264_BUILD < 158
+ | FF_CODEC_CAP_NOT_INIT_THREADSAFE
#endif
,
};
@@ -1286,7 +1422,7 @@ static const AVClass X262_class = {
const FFCodec ff_libx262_encoder = {
.p.name = "libx262",
- .p.long_name = NULL_IF_CONFIG_SMALL("libx262 MPEG2VIDEO"),
+ CODEC_LONG_NAME("libx262 MPEG2VIDEO"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_MPEG2VIDEO,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
@@ -1300,6 +1436,7 @@ const FFCodec ff_libx262_encoder = {
FF_CODEC_ENCODE_CB(X264_frame),
.close = X264_close,
.defaults = x264_defaults,
- .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS,
};
#endif
diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c
index f68ecb309..420d0953a 100644
--- a/libavcodec/libx265.c
+++ b/libavcodec/libx265.c
@@ -27,6 +27,8 @@
#include
#include
+#include "libavutil/avassert.h"
+#include "libavutil/buffer.h"
#include "libavutil/internal.h"
#include "libavutil/common.h"
#include "libavutil/opt.h"
@@ -36,8 +38,21 @@
#include "encode.h"
#include "internal.h"
#include "packet_internal.h"
+#include "atsc_a53.h"
#include "sei.h"
+typedef struct ReorderedData {
+#if FF_API_REORDERED_OPAQUE
+ int64_t reordered_opaque;
+#endif
+ int64_t duration;
+
+ void *frame_opaque;
+ AVBufferRef *frame_opaque_ref;
+
+ int in_use;
+} ReorderedData;
+
typedef struct libx265Context {
const AVClass *class;
@@ -56,6 +71,10 @@ typedef struct libx265Context {
void *sei_data;
int sei_data_size;
int udu_sei;
+ int a53_cc;
+
+ ReorderedData *rd;
+ int nb_rd;
/**
* If the encoder does not support ROI then warn the first time we
@@ -79,6 +98,40 @@ static int is_keyframe(NalUnitType naltype)
}
}
+static int rd_get(libx265Context *ctx)
+{
+ const int add = 16;
+
+ ReorderedData *tmp;
+ int idx;
+
+ for (int i = 0; i < ctx->nb_rd; i++)
+ if (!ctx->rd[i].in_use) {
+ ctx->rd[i].in_use = 1;
+ return i;
+ }
+
+ tmp = av_realloc_array(ctx->rd, ctx->nb_rd + add, sizeof(*ctx->rd));
+ if (!tmp)
+ return AVERROR(ENOMEM);
+ memset(tmp + ctx->nb_rd, 0, sizeof(*tmp) * add);
+
+ ctx->rd = tmp;
+ ctx->nb_rd += add;
+
+ idx = ctx->nb_rd - add;
+ ctx->rd[idx].in_use = 1;
+
+ return idx;
+}
+
+static void rd_release(libx265Context *ctx, int idx)
+{
+ av_assert0(idx >= 0 && idx < ctx->nb_rd);
+ av_buffer_unref(&ctx->rd[idx].frame_opaque_ref);
+ memset(&ctx->rd[idx], 0, sizeof(ctx->rd[idx]));
+}
+
static av_cold int libx265_encode_close(AVCodecContext *avctx)
{
libx265Context *ctx = avctx->priv_data;
@@ -86,6 +139,10 @@ static av_cold int libx265_encode_close(AVCodecContext *avctx)
ctx->api->param_free(ctx->params);
av_freep(&ctx->sei_data);
+ for (int i = 0; i < ctx->nb_rd; i++)
+ rd_release(ctx, i);
+ av_freep(&ctx->rd);
+
if (ctx->encoder)
ctx->api->encoder_close(ctx->encoder);
@@ -293,7 +350,6 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
return ret;
}
-#if X265_BUILD >= 89
if (avctx->qmin >= 0) {
ret = libx265_param_parse_int(avctx, "qpmin", avctx->qmin);
if (ret < 0)
@@ -304,7 +360,6 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
if (ret < 0)
return ret;
}
-#endif
if (avctx->max_qdiff >= 0) {
ret = libx265_param_parse_int(avctx, "qpstep", avctx->max_qdiff);
if (ret < 0)
@@ -499,6 +554,22 @@ static av_cold int libx265_encode_set_roi(libx265Context *ctx, const AVFrame *fr
return 0;
}
+static void free_picture(libx265Context *ctx, x265_picture *pic)
+{
+ x265_sei *sei = &pic->userSEI;
+ for (int i = 0; i < sei->numPayloads; i++)
+ av_free(sei->payloads[i].payload);
+
+ if (pic->userData) {
+ int idx = (int)(intptr_t)pic->userData - 1;
+ rd_release(ctx, idx);
+ pic->userData = NULL;
+ }
+
+ av_freep(&pic->quantOffsets);
+ sei->numPayloads = 0;
+}
+
static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *pic, int *got_packet)
{
@@ -506,6 +577,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
x265_picture x265pic;
x265_picture x265pic_out = { 0 };
x265_nal *nal;
+ x265_sei *sei;
uint8_t *dst;
int pict_type;
int payload = 0;
@@ -515,9 +587,13 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
ctx->api->picture_init(ctx->params, &x265pic);
+ sei = &x265pic.userSEI;
+ sei->numPayloads = 0;
+
if (pic) {
- x265_sei *sei = &x265pic.userSEI;
- sei->numPayloads = 0;
+ ReorderedData *rd;
+ int rd_idx;
+
for (i = 0; i < 3; i++) {
x265pic.planes[i] = pic->data[i];
x265pic.stride[i] = pic->linesize[i];
@@ -536,14 +612,58 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
if (ret < 0)
return ret;
- if (pic->reordered_opaque) {
- x265pic.userData = av_malloc(sizeof(pic->reordered_opaque));
- if (!x265pic.userData) {
- av_freep(&x265pic.quantOffsets);
- return AVERROR(ENOMEM);
- }
+ rd_idx = rd_get(ctx);
+ if (rd_idx < 0) {
+ free_picture(ctx, &x265pic);
+ return rd_idx;
+ }
+ rd = &ctx->rd[rd_idx];
- memcpy(x265pic.userData, &pic->reordered_opaque, sizeof(pic->reordered_opaque));
+ rd->duration = pic->duration;
+#if FF_API_REORDERED_OPAQUE
+FF_DISABLE_DEPRECATION_WARNINGS
+ rd->reordered_opaque = pic->reordered_opaque;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+ rd->frame_opaque = pic->opaque;
+ ret = av_buffer_replace(&rd->frame_opaque_ref, pic->opaque_ref);
+ if (ret < 0) {
+ rd_release(ctx, rd_idx);
+ free_picture(ctx, &x265pic);
+ return ret;
+ }
+ }
+
+ x265pic.userData = (void*)(intptr_t)(rd_idx + 1);
+
+ if (ctx->a53_cc) {
+ void *sei_data;
+ size_t sei_size;
+
+ ret = ff_alloc_a53_sei(pic, 0, &sei_data, &sei_size);
+ if (ret < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
+ } else if (sei_data) {
+ void *tmp;
+ x265_sei_payload *sei_payload;
+
+ tmp = av_fast_realloc(ctx->sei_data,
+ &ctx->sei_data_size,
+ (sei->numPayloads + 1) * sizeof(*sei_payload));
+ if (!tmp) {
+ av_free(sei_data);
+ free_picture(ctx, &x265pic);
+ return AVERROR(ENOMEM);
+ }
+ ctx->sei_data = tmp;
+ sei->payloads = ctx->sei_data;
+ sei_payload = &sei->payloads[sei->numPayloads];
+ sei_payload->payload = sei_data;
+ sei_payload->payloadSize = sei_size;
+ sei_payload->payloadType = SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35;
+ sei->numPayloads++;
+ }
}
if (ctx->udu_sei) {
@@ -559,14 +679,17 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
&ctx->sei_data_size,
(sei->numPayloads + 1) * sizeof(*sei_payload));
if (!tmp) {
- av_freep(&x265pic.userData);
- av_freep(&x265pic.quantOffsets);
+ free_picture(ctx, &x265pic);
return AVERROR(ENOMEM);
}
ctx->sei_data = tmp;
sei->payloads = ctx->sei_data;
sei_payload = &sei->payloads[sei->numPayloads];
- sei_payload->payload = side_data->data;
+ sei_payload->payload = av_memdup(side_data->data, side_data->size);
+ if (!sei_payload->payload) {
+ free_picture(ctx, &x265pic);
+ return AVERROR(ENOMEM);
+ }
sei_payload->payloadSize = side_data->size;
/* Equal to libx265 USER_DATA_UNREGISTERED */
sei_payload->payloadType = SEI_TYPE_USER_DATA_UNREGISTERED;
@@ -578,6 +701,8 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
ret = ctx->api->encoder_encode(ctx->encoder, &nal, &nnal,
pic ? &x265pic : NULL, &x265pic_out);
+ for (i = 0; i < sei->numPayloads; i++)
+ av_free(sei->payloads[i].payload);
av_freep(&x265pic.quantOffsets);
if (ret < 0)
@@ -634,10 +759,31 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
ff_side_data_set_encoder_stats(pkt, x265pic_out.frameData.qp * FF_QP2LAMBDA, NULL, 0, pict_type);
if (x265pic_out.userData) {
- memcpy(&avctx->reordered_opaque, x265pic_out.userData, sizeof(avctx->reordered_opaque));
- av_freep(&x265pic_out.userData);
- } else
+ int idx = (int)(intptr_t)x265pic_out.userData - 1;
+ ReorderedData *rd = &ctx->rd[idx];
+
+#if FF_API_REORDERED_OPAQUE
+FF_DISABLE_DEPRECATION_WARNINGS
+ avctx->reordered_opaque = rd->reordered_opaque;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ pkt->duration = rd->duration;
+
+ if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+ pkt->opaque = rd->frame_opaque;
+ pkt->opaque_ref = rd->frame_opaque_ref;
+ rd->frame_opaque_ref = NULL;
+ }
+
+ rd_release(ctx, idx);
+ }
+#if FF_API_REORDERED_OPAQUE
+ else {
+FF_DISABLE_DEPRECATION_WARNINGS
avctx->reordered_opaque = 0;
+FF_ENABLE_DEPRECATION_WARNINGS
+ }
+#endif
*got_packet = 1;
return 0;
@@ -713,7 +859,8 @@ static const AVOption options[] = {
{ "preset", "set the x265 preset", OFFSET(preset), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
{ "tune", "set the x265 tune parameter", OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
{ "profile", "set the x265 profile", OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
- { "udu_sei", "Use user data unregistered SEI if available", OFFSET(udu_sei), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+ { "udu_sei", "Use user data unregistered SEI if available", OFFSET(udu_sei), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+ { "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
{ "x265-params", "set the x265 configuration using a :-separated list of key=value parameters", OFFSET(x265_opts), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },
{ NULL }
};
@@ -743,7 +890,7 @@ static const FFCodecDefault x265_defaults[] = {
FFCodec ff_libx265_encoder = {
.p.name = "libx265",
- .p.long_name = NULL_IF_CONFIG_SMALL("libx265 H.265 / HEVC"),
+ CODEC_LONG_NAME("libx265 H.265 / HEVC"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_HEVC,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
@@ -757,5 +904,6 @@ FFCodec ff_libx265_encoder = {
.close = libx265_encode_close,
.priv_data_size = sizeof(libx265Context),
.defaults = x265_defaults,
- .caps_internal = FF_CODEC_CAP_AUTO_THREADS,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_AUTO_THREADS,
};
diff --git a/libavcodec/libxavs.c b/libavcodec/libxavs.c
index a3efbcb4a..9ed73d104 100644
--- a/libavcodec/libxavs.c
+++ b/libavcodec/libxavs.c
@@ -423,7 +423,7 @@ static const FFCodecDefault xavs_defaults[] = {
const FFCodec ff_libxavs_encoder = {
.p.name = "libxavs",
- .p.long_name = NULL_IF_CONFIG_SMALL("libxavs Chinese AVS (Audio Video Standard)"),
+ CODEC_LONG_NAME("libxavs Chinese AVS (Audio Video Standard)"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_CAVS,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
@@ -432,7 +432,8 @@ const FFCodec ff_libxavs_encoder = {
.init = XAVS_init,
FF_CODEC_ENCODE_CB(XAVS_frame),
.close = XAVS_close,
- .caps_internal = FF_CODEC_CAP_AUTO_THREADS,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_AUTO_THREADS,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
.p.priv_class = &xavs_class,
.defaults = xavs_defaults,
diff --git a/libavcodec/libxavs2.c b/libavcodec/libxavs2.c
index bf34b7acb..c493ddc32 100644
--- a/libavcodec/libxavs2.c
+++ b/libavcodec/libxavs2.c
@@ -96,8 +96,8 @@ static av_cold int xavs2_init(AVCodecContext *avctx)
xavs2_opt_set2("OpenGOP", "%d", !(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP));
{
- AVDictionaryEntry *en = NULL;
- while ((en = av_dict_get(cae->xavs2_opts, "", en, AV_DICT_IGNORE_SUFFIX)))
+ const AVDictionaryEntry *en = NULL;
+ while ((en = av_dict_iterate(cae->xavs2_opts, en)))
xavs2_opt_set2(en->key, "%s", en->value);
}
@@ -288,7 +288,7 @@ static const FFCodecDefault xavs2_defaults[] = {
const FFCodec ff_libxavs2_encoder = {
.p.name = "libxavs2",
- .p.long_name = NULL_IF_CONFIG_SMALL("libxavs2 AVS2-P2/IEEE1857.4"),
+ CODEC_LONG_NAME("libxavs2 AVS2-P2/IEEE1857.4"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_AVS2,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
@@ -297,7 +297,8 @@ const FFCodec ff_libxavs2_encoder = {
.init = xavs2_init,
FF_CODEC_ENCODE_CB(xavs2_encode_frame),
.close = xavs2_close,
- .caps_internal = FF_CODEC_CAP_AUTO_THREADS,
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
+ FF_CODEC_CAP_AUTO_THREADS,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE },
.p.priv_class = &libxavs2,
diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c
index 4b3dd71bc..aba875b6b 100644
--- a/libavcodec/libxvid.c
+++ b/libavcodec/libxvid.c
@@ -30,7 +30,7 @@
#include
#include "libavutil/avassert.h"
-#include "libavutil/file.h"
+#include "libavutil/file_open.h"
#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
@@ -899,16 +899,16 @@ static const AVClass xvid_class = {
const FFCodec ff_libxvid_encoder = {
.p.name = "libxvid",
- .p.long_name = NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"),
+ CODEC_LONG_NAME("libxvidcore MPEG-4 part 2"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_MPEG4,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(struct xvid_context),
.init = xvid_encode_init,
FF_CODEC_ENCODE_CB(xvid_encode_frame),
.close = xvid_encode_close,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
.p.priv_class = &xvid_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.wrapper_name = "libxvid",
};
diff --git a/libavcodec/libzvbi-teletextdec.c b/libavcodec/libzvbi-teletextdec.c
index 514e76f1b..45e30eb01 100644
--- a/libavcodec/libzvbi-teletextdec.c
+++ b/libavcodec/libzvbi-teletextdec.c
@@ -813,12 +813,13 @@ static const AVClass teletext_class = {
const FFCodec ff_libzvbi_teletext_decoder = {
.p.name = "libzvbi_teletextdec",
- .p.long_name = NULL_IF_CONFIG_SMALL("Libzvbi DVB teletext decoder"),
+ CODEC_LONG_NAME("Libzvbi DVB teletext decoder"),
.p.type = AVMEDIA_TYPE_SUBTITLE,
.p.id = AV_CODEC_ID_DVB_TELETEXT,
.p.capabilities = AV_CODEC_CAP_DELAY,
.p.priv_class = &teletext_class,
.p.wrapper_name = "libzvbi",
+ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
.priv_data_size = sizeof(TeletextContext),
.init = teletext_init_decoder,
.close = teletext_close_decoder,
diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c
index fc7a46273..aa62beac7 100644
--- a/libavcodec/ljpegenc.c
+++ b/libavcodec/ljpegenc.c
@@ -33,22 +33,16 @@
#include "libavutil/frame.h"
#include "libavutil/mem.h"
#include "libavutil/opt.h"
-#include "libavutil/pixdesc.h"
#include "avcodec.h"
#include "codec_internal.h"
#include "encode.h"
-#include "idctdsp.h"
#include "jpegtables.h"
-#include "mathops.h"
#include "mjpegenc_common.h"
#include "mjpeg.h"
typedef struct LJpegEncContext {
AVClass *class;
- IDCTDSPContext idsp;
- ScanTable scantable;
- uint16_t matrix[64];
int vsample[4];
int hsample[4];
@@ -78,7 +72,7 @@ static int ljpeg_encode_bgr(AVCodecContext *avctx, PutBitContext *pb,
for (y = 0; y < height; y++) {
const int modified_predictor = y ? s->pred : 1;
- uint8_t *ptr = frame->data[0] + (linesize * y);
+ const uint8_t *ptr = frame->data[0] + (linesize * y);
if (put_bytes_left(pb, 0) < width * 4 * 4) {
av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
@@ -132,7 +126,7 @@ static inline void ljpeg_encode_yuv_mb(LJpegEncContext *s, PutBitContext *pb,
if (mb_x == 0 || mb_y == 0) {
for (i = 0; i < 3; i++) {
- uint8_t *ptr;
+ const uint8_t *ptr;
int x, y, h, v, linesize;
h = s->hsample[i];
v = s->vsample[i];
@@ -166,7 +160,7 @@ static inline void ljpeg_encode_yuv_mb(LJpegEncContext *s, PutBitContext *pb,
}
} else {
for (i = 0; i < 3; i++) {
- uint8_t *ptr;
+ const uint8_t *ptr;
int x, y, h, v, linesize;
h = s->hsample[i];
v = s->vsample[i];
@@ -240,8 +234,8 @@ static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
init_put_bits(&pb, pkt->data, pkt->size);
- ff_mjpeg_encode_picture_header(avctx, &pb, pict, NULL, &s->scantable,
- s->pred, s->matrix, s->matrix, 0);
+ ff_mjpeg_encode_picture_header(avctx, &pb, pict, NULL, NULL,
+ s->pred, NULL, NULL, 0);
header_bits = put_bits_count(&pb);
@@ -254,8 +248,6 @@ static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
if (ret < 0)
return ret;
- emms_c();
-
ff_mjpeg_escape_FF(&pb, header_bits >> 3);
ff_mjpeg_encode_picture_trailer(&pb, header_bits);
@@ -287,10 +279,6 @@ static av_cold int ljpeg_encode_init(AVCodecContext *avctx)
if (!s->scratch)
return AVERROR(ENOMEM);
- ff_idctdsp_init(&s->idsp, avctx);
- ff_init_scantable(s->idsp.idct_permutation, &s->scantable,
- ff_zigzag_direct);
-
ff_mjpeg_init_hvsample(avctx, s->hsample, s->vsample);
ff_mjpeg_build_huffman_codes(s->huff_size_dc_luminance,
@@ -325,19 +313,19 @@ static const AVClass ljpeg_class = {
const FFCodec ff_ljpeg_encoder = {
.p.name = "ljpeg",
- .p.long_name = NULL_IF_CONFIG_SMALL("Lossless JPEG"),
+ CODEC_LONG_NAME("Lossless JPEG"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_LJPEG,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(LJpegEncContext),
.p.priv_class = &ljpeg_class,
.init = ljpeg_encode_init,
FF_CODEC_ENCODE_CB(ljpeg_encode_frame),
.close = ljpeg_encode_close,
- .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
.p.pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_BGR24 , AV_PIX_FMT_BGRA , AV_PIX_FMT_BGR0,
AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P,
AV_PIX_FMT_YUV420P , AV_PIX_FMT_YUV444P , AV_PIX_FMT_YUV422P,
AV_PIX_FMT_NONE},
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/loco.c b/libavcodec/loco.c
index 9cadc9d00..d57a67317 100644
--- a/libavcodec/loco.c
+++ b/libavcodec/loco.c
@@ -26,9 +26,9 @@
#include "avcodec.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
#include "golomb.h"
-#include "internal.h"
#include "mathops.h"
enum LOCO_MODE {
@@ -338,12 +338,11 @@ static av_cold int decode_init(AVCodecContext *avctx)
const FFCodec ff_loco_decoder = {
.p.name = "loco",
- .p.long_name = NULL_IF_CONFIG_SMALL("LOCO"),
+ CODEC_LONG_NAME("LOCO"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_LOCO,
.priv_data_size = sizeof(LOCOContext),
.init = decode_init,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/loongarch/cabac.h b/libavcodec/loongarch/cabac.h
index e1c946fe1..f896ccf13 100644
--- a/libavcodec/loongarch/cabac.h
+++ b/libavcodec/loongarch/cabac.h
@@ -25,6 +25,7 @@
#ifndef AVCODEC_LOONGARCH_CABAC_H
#define AVCODEC_LOONGARCH_CABAC_H
+#include "libavutil/attributes.h"
#include "libavcodec/cabac.h"
#include "config.h"
diff --git a/libavcodec/loongarch/h264chroma_lasx.c b/libavcodec/loongarch/h264chroma_lasx.c
index 824a78dfc..1c0e002bd 100644
--- a/libavcodec/loongarch/h264chroma_lasx.c
+++ b/libavcodec/loongarch/h264chroma_lasx.c
@@ -33,7 +33,7 @@ static const uint8_t chroma_mask_arr[64] = {
0, 1, 1, 2, 2, 3, 3, 4, 16, 17, 17, 18, 18, 19, 19, 20
};
-static av_always_inline void avc_chroma_hv_8x4_lasx(uint8_t *src, uint8_t *dst,
+static av_always_inline void avc_chroma_hv_8x4_lasx(const uint8_t *src, uint8_t *dst,
ptrdiff_t stride, uint32_t coef_hor0,
uint32_t coef_hor1, uint32_t coef_ver0,
uint32_t coef_ver1)
@@ -71,7 +71,7 @@ static av_always_inline void avc_chroma_hv_8x4_lasx(uint8_t *src, uint8_t *dst,
__lasx_xvstelm_d(out, dst + stride_3x, 0, 3);
}
-static av_always_inline void avc_chroma_hv_8x8_lasx(uint8_t *src, uint8_t *dst,
+static av_always_inline void avc_chroma_hv_8x8_lasx(const uint8_t *src, uint8_t *dst,
ptrdiff_t stride, uint32_t coef_hor0,
uint32_t coef_hor1, uint32_t coef_ver0,
uint32_t coef_ver1)
@@ -127,7 +127,7 @@ static av_always_inline void avc_chroma_hv_8x8_lasx(uint8_t *src, uint8_t *dst,
__lasx_xvstelm_d(out1, dst + stride_3x, 0, 3);
}
-static av_always_inline void avc_chroma_hz_8x4_lasx(uint8_t *src, uint8_t *dst,
+static av_always_inline void avc_chroma_hz_8x4_lasx(const uint8_t *src, uint8_t *dst,
ptrdiff_t stride, uint32_t coeff0, uint32_t coeff1)
{
ptrdiff_t stride_2x = stride << 1;
@@ -154,7 +154,7 @@ static av_always_inline void avc_chroma_hz_8x4_lasx(uint8_t *src, uint8_t *dst,
}
-static av_always_inline void avc_chroma_hz_8x8_lasx(uint8_t *src, uint8_t *dst,
+static av_always_inline void avc_chroma_hz_8x8_lasx(const uint8_t *src, uint8_t *dst,
ptrdiff_t stride, uint32_t coeff0, uint32_t coeff1)
{
ptrdiff_t stride_2x = stride << 1;
@@ -193,7 +193,7 @@ static av_always_inline void avc_chroma_hz_8x8_lasx(uint8_t *src, uint8_t *dst,
__lasx_xvstelm_d(out1, dst + stride_3x, 0, 3);
}
-static av_always_inline void avc_chroma_hz_nonmult_lasx(uint8_t *src,
+static av_always_inline void avc_chroma_hz_nonmult_lasx(const uint8_t *src,
uint8_t *dst, ptrdiff_t stride, uint32_t coeff0,
uint32_t coeff1, int32_t height)
{
@@ -239,7 +239,7 @@ static av_always_inline void avc_chroma_hz_nonmult_lasx(uint8_t *src,
}
}
-static av_always_inline void avc_chroma_vt_8x4_lasx(uint8_t *src, uint8_t *dst,
+static av_always_inline void avc_chroma_vt_8x4_lasx(const uint8_t *src, uint8_t *dst,
ptrdiff_t stride, uint32_t coeff0, uint32_t coeff1)
{
ptrdiff_t stride_2x = stride << 1;
@@ -266,7 +266,7 @@ static av_always_inline void avc_chroma_vt_8x4_lasx(uint8_t *src, uint8_t *dst,
__lasx_xvstelm_d(out, dst + stride_3x, 0, 3);
}
-static av_always_inline void avc_chroma_vt_8x8_lasx(uint8_t *src, uint8_t *dst,
+static av_always_inline void avc_chroma_vt_8x8_lasx(const uint8_t *src, uint8_t *dst,
ptrdiff_t stride, uint32_t coeff0, uint32_t coeff1)
{
ptrdiff_t stride_2x = stride << 1;
@@ -307,7 +307,7 @@ static av_always_inline void avc_chroma_vt_8x8_lasx(uint8_t *src, uint8_t *dst,
__lasx_xvstelm_d(out1, dst + stride_3x, 0, 3);
}
-static av_always_inline void copy_width8x8_lasx(uint8_t *src, uint8_t *dst,
+static av_always_inline void copy_width8x8_lasx(const uint8_t *src, uint8_t *dst,
ptrdiff_t stride)
{
uint64_t tmp[8];
@@ -347,7 +347,7 @@ static av_always_inline void copy_width8x8_lasx(uint8_t *src, uint8_t *dst,
);
}
-static av_always_inline void copy_width8x4_lasx(uint8_t *src, uint8_t *dst,
+static av_always_inline void copy_width8x4_lasx(const uint8_t *src, uint8_t *dst,
ptrdiff_t stride)
{
uint64_t tmp[4];
@@ -372,7 +372,7 @@ static av_always_inline void copy_width8x4_lasx(uint8_t *src, uint8_t *dst,
);
}
-static void avc_chroma_hv_8w_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avc_chroma_hv_8w_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
uint32_t coef_hor0, uint32_t coef_hor1,
uint32_t coef_ver0, uint32_t coef_ver1,
int32_t height)
@@ -386,7 +386,7 @@ static void avc_chroma_hv_8w_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
}
}
-static void avc_chroma_hv_4x2_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avc_chroma_hv_4x2_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
uint32_t coef_hor0, uint32_t coef_hor1,
uint32_t coef_ver0, uint32_t coef_ver1)
{
@@ -414,7 +414,7 @@ static void avc_chroma_hv_4x2_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
__lasx_xvstelm_w(res_vt, dst + stride, 0, 1);
}
-static void avc_chroma_hv_4x4_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avc_chroma_hv_4x4_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
uint32_t coef_hor0, uint32_t coef_hor1,
uint32_t coef_ver0, uint32_t coef_ver1)
{
@@ -446,7 +446,7 @@ static void avc_chroma_hv_4x4_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
__lasx_xvstelm_w(res_hz0, dst + stride_3, 0, 5);
}
-static void avc_chroma_hv_4x8_lasx(uint8_t *src, uint8_t * dst, ptrdiff_t stride,
+static void avc_chroma_hv_4x8_lasx(const uint8_t *src, uint8_t * dst, ptrdiff_t stride,
uint32_t coef_hor0, uint32_t coef_hor1,
uint32_t coef_ver0, uint32_t coef_ver1)
{
@@ -492,7 +492,7 @@ static void avc_chroma_hv_4x8_lasx(uint8_t *src, uint8_t * dst, ptrdiff_t stride
__lasx_xvstelm_w(res_hz0, dst + stride_3, 0, 7);
}
-static void avc_chroma_hv_4w_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avc_chroma_hv_4w_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
uint32_t coef_hor0, uint32_t coef_hor1,
uint32_t coef_ver0, uint32_t coef_ver1,
int32_t height)
@@ -509,7 +509,7 @@ static void avc_chroma_hv_4w_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
}
}
-static void avc_chroma_hz_4x2_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avc_chroma_hz_4x2_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
uint32_t coeff0, uint32_t coeff1)
{
__m256i src0, src1;
@@ -528,7 +528,7 @@ static void avc_chroma_hz_4x2_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
__lasx_xvstelm_w(res, dst + stride, 0, 1);
}
-static void avc_chroma_hz_4x4_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avc_chroma_hz_4x4_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
uint32_t coeff0, uint32_t coeff1)
{
ptrdiff_t stride_2 = stride << 1;
@@ -553,7 +553,7 @@ static void avc_chroma_hz_4x4_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
__lasx_xvstelm_w(res, dst + stride_3, 0, 5);
}
-static void avc_chroma_hz_4x8_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avc_chroma_hz_4x8_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
uint32_t coeff0, uint32_t coeff1)
{
ptrdiff_t stride_2 = stride << 1;
@@ -588,7 +588,7 @@ static void avc_chroma_hz_4x8_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
__lasx_xvstelm_w(res0, dst + stride_3, 0, 7);
}
-static void avc_chroma_hz_4w_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avc_chroma_hz_4w_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
uint32_t coeff0, uint32_t coeff1,
int32_t height)
{
@@ -601,7 +601,7 @@ static void avc_chroma_hz_4w_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
}
}
-static void avc_chroma_hz_8w_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avc_chroma_hz_8w_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
uint32_t coeff0, uint32_t coeff1,
int32_t height)
{
@@ -614,7 +614,7 @@ static void avc_chroma_hz_8w_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
}
}
-static void avc_chroma_vt_4x2_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avc_chroma_vt_4x2_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
uint32_t coeff0, uint32_t coeff1)
{
__m256i src0, src1, src2;
@@ -635,7 +635,7 @@ static void avc_chroma_vt_4x2_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
__lasx_xvstelm_w(res, dst + stride, 0, 1);
}
-static void avc_chroma_vt_4x4_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avc_chroma_vt_4x4_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
uint32_t coeff0, uint32_t coeff1)
{
ptrdiff_t stride_2 = stride << 1;
@@ -664,7 +664,7 @@ static void avc_chroma_vt_4x4_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
__lasx_xvstelm_w(res, dst + stride_3, 0, 5);
}
-static void avc_chroma_vt_4x8_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avc_chroma_vt_4x8_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
uint32_t coeff0, uint32_t coeff1)
{
ptrdiff_t stride_2 = stride << 1;
@@ -705,7 +705,7 @@ static void avc_chroma_vt_4x8_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
__lasx_xvstelm_w(res0, dst + stride_3, 0, 7);
}
-static void avc_chroma_vt_4w_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avc_chroma_vt_4w_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
uint32_t coeff0, uint32_t coeff1,
int32_t height)
{
@@ -718,7 +718,7 @@ static void avc_chroma_vt_4w_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
}
}
-static void avc_chroma_vt_8w_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avc_chroma_vt_8w_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
uint32_t coeff0, uint32_t coeff1,
int32_t height)
{
@@ -729,7 +729,7 @@ static void avc_chroma_vt_8w_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
}
}
-static void copy_width4_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void copy_width4_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
int32_t height)
{
uint32_t tp0, tp1, tp2, tp3, tp4, tp5, tp6, tp7;
@@ -799,7 +799,7 @@ static void copy_width4_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
}
}
-static void copy_width8_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void copy_width8_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
int32_t height)
{
if (8 == height) {
@@ -809,7 +809,7 @@ static void copy_width8_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
}
}
-void ff_put_h264_chroma_mc4_lasx(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_h264_chroma_mc4_lasx(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int height, int x, int y)
{
av_assert2(x < 8 && y < 8 && x >= 0 && y >= 0);
@@ -825,7 +825,7 @@ void ff_put_h264_chroma_mc4_lasx(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
}
}
-void ff_put_h264_chroma_mc8_lasx(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_h264_chroma_mc8_lasx(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int height, int x, int y)
{
av_assert2(x < 8 && y < 8 && x >= 0 && y >= 0);
@@ -841,7 +841,7 @@ void ff_put_h264_chroma_mc8_lasx(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
}
}
-static av_always_inline void avc_chroma_hv_and_aver_dst_8x4_lasx(uint8_t *src,
+static av_always_inline void avc_chroma_hv_and_aver_dst_8x4_lasx(const uint8_t *src,
uint8_t *dst, ptrdiff_t stride, uint32_t coef_hor0,
uint32_t coef_hor1, uint32_t coef_ver0,
uint32_t coef_ver1)
@@ -885,7 +885,7 @@ static av_always_inline void avc_chroma_hv_and_aver_dst_8x4_lasx(uint8_t *src,
__lasx_xvstelm_d(out, dst + stride_3x, 0, 3);
}
-static av_always_inline void avc_chroma_hv_and_aver_dst_8x8_lasx(uint8_t *src,
+static av_always_inline void avc_chroma_hv_and_aver_dst_8x8_lasx(const uint8_t *src,
uint8_t *dst, ptrdiff_t stride, uint32_t coef_hor0,
uint32_t coef_hor1, uint32_t coef_ver0,
uint32_t coef_ver1)
@@ -957,7 +957,7 @@ static av_always_inline void avc_chroma_hv_and_aver_dst_8x8_lasx(uint8_t *src,
__lasx_xvstelm_d(out1, dst + stride_3x, 0, 3);
}
-static av_always_inline void avc_chroma_hz_and_aver_dst_8x4_lasx(uint8_t *src,
+static av_always_inline void avc_chroma_hz_and_aver_dst_8x4_lasx(const uint8_t *src,
uint8_t *dst, ptrdiff_t stride, uint32_t coeff0,
uint32_t coeff1)
{
@@ -990,7 +990,7 @@ static av_always_inline void avc_chroma_hz_and_aver_dst_8x4_lasx(uint8_t *src,
__lasx_xvstelm_d(out, dst + stride_3x, 0, 3);
}
-static av_always_inline void avc_chroma_hz_and_aver_dst_8x8_lasx(uint8_t *src,
+static av_always_inline void avc_chroma_hz_and_aver_dst_8x8_lasx(const uint8_t *src,
uint8_t *dst, ptrdiff_t stride, uint32_t coeff0,
uint32_t coeff1)
{
@@ -1043,7 +1043,7 @@ static av_always_inline void avc_chroma_hz_and_aver_dst_8x8_lasx(uint8_t *src,
__lasx_xvstelm_d(out1, dst + stride_3x, 0, 3);
}
-static av_always_inline void avc_chroma_vt_and_aver_dst_8x4_lasx(uint8_t *src,
+static av_always_inline void avc_chroma_vt_and_aver_dst_8x4_lasx(const uint8_t *src,
uint8_t *dst, ptrdiff_t stride, uint32_t coeff0,
uint32_t coeff1)
{
@@ -1077,7 +1077,7 @@ static av_always_inline void avc_chroma_vt_and_aver_dst_8x4_lasx(uint8_t *src,
__lasx_xvstelm_d(out, dst + stride_3x, 0, 3);
}
-static av_always_inline void avc_chroma_vt_and_aver_dst_8x8_lasx(uint8_t *src,
+static av_always_inline void avc_chroma_vt_and_aver_dst_8x8_lasx(const uint8_t *src,
uint8_t *dst, ptrdiff_t stride, uint32_t coeff0,
uint32_t coeff1)
{
@@ -1132,7 +1132,7 @@ static av_always_inline void avc_chroma_vt_and_aver_dst_8x8_lasx(uint8_t *src,
__lasx_xvstelm_d(out1, dst + stride_3x, 0, 3);
}
-static av_always_inline void avg_width8x8_lasx(uint8_t *src, uint8_t *dst,
+static av_always_inline void avg_width8x8_lasx(const uint8_t *src, uint8_t *dst,
ptrdiff_t stride)
{
__m256i src0, src1, src2, src3;
@@ -1184,7 +1184,7 @@ static av_always_inline void avg_width8x8_lasx(uint8_t *src, uint8_t *dst,
__lasx_xvstelm_d(dst0, dst + stride_3x, 0, 3);
}
-static av_always_inline void avg_width8x4_lasx(uint8_t *src, uint8_t *dst,
+static av_always_inline void avg_width8x4_lasx(const uint8_t *src, uint8_t *dst,
ptrdiff_t stride)
{
__m256i src0, src1, src2, src3;
@@ -1213,7 +1213,7 @@ static av_always_inline void avg_width8x4_lasx(uint8_t *src, uint8_t *dst,
__lasx_xvstelm_d(dst0, dst + stride_3x, 0, 3);
}
-static void avc_chroma_hv_and_aver_dst_8w_lasx(uint8_t *src, uint8_t *dst,
+static void avc_chroma_hv_and_aver_dst_8w_lasx(const uint8_t *src, uint8_t *dst,
ptrdiff_t stride,
uint32_t coef_hor0,
uint32_t coef_hor1,
@@ -1230,7 +1230,7 @@ static void avc_chroma_hv_and_aver_dst_8w_lasx(uint8_t *src, uint8_t *dst,
}
}
-static void avc_chroma_hz_and_aver_dst_8w_lasx(uint8_t *src, uint8_t *dst,
+static void avc_chroma_hz_and_aver_dst_8w_lasx(const uint8_t *src, uint8_t *dst,
ptrdiff_t stride, uint32_t coeff0,
uint32_t coeff1, int32_t height)
{
@@ -1241,7 +1241,7 @@ static void avc_chroma_hz_and_aver_dst_8w_lasx(uint8_t *src, uint8_t *dst,
}
}
-static void avc_chroma_vt_and_aver_dst_8w_lasx(uint8_t *src, uint8_t *dst,
+static void avc_chroma_vt_and_aver_dst_8w_lasx(const uint8_t *src, uint8_t *dst,
ptrdiff_t stride, uint32_t coeff0,
uint32_t coeff1, int32_t height)
{
@@ -1252,7 +1252,7 @@ static void avc_chroma_vt_and_aver_dst_8w_lasx(uint8_t *src, uint8_t *dst,
}
}
-static void avg_width8_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
+static void avg_width8_lasx(const uint8_t *src, uint8_t *dst, ptrdiff_t stride,
int32_t height)
{
if (8 == height) {
@@ -1262,7 +1262,7 @@ static void avg_width8_lasx(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
}
}
-void ff_avg_h264_chroma_mc8_lasx(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_avg_h264_chroma_mc8_lasx(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int height, int x, int y)
{
av_assert2(x < 8 && y < 8 && x >= 0 && y >= 0);
diff --git a/libavcodec/loongarch/h264chroma_lasx.h b/libavcodec/loongarch/h264chroma_lasx.h
index 4aac8db8c..633752035 100644
--- a/libavcodec/loongarch/h264chroma_lasx.h
+++ b/libavcodec/loongarch/h264chroma_lasx.h
@@ -26,11 +26,11 @@
#include
#include "libavcodec/h264.h"
-void ff_put_h264_chroma_mc4_lasx(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_h264_chroma_mc4_lasx(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_put_h264_chroma_mc8_lasx(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_put_h264_chroma_mc8_lasx(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
-void ff_avg_h264_chroma_mc8_lasx(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+void ff_avg_h264_chroma_mc8_lasx(uint8_t *dst, const uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
#endif /* AVCODEC_LOONGARCH_H264CHROMA_LASX_H */
diff --git a/libavcodec/loongarch/hevc_lpf_sao_lsx.c b/libavcodec/loongarch/hevc_lpf_sao_lsx.c
index fc10e8eda..b5822afd9 100644
--- a/libavcodec/loongarch/hevc_lpf_sao_lsx.c
+++ b/libavcodec/loongarch/hevc_lpf_sao_lsx.c
@@ -24,8 +24,8 @@
#include "hevcdsp_lsx.h"
void ff_hevc_loop_filter_luma_h_8_lsx(uint8_t *src, ptrdiff_t stride,
- int32_t beta, int32_t *tc,
- uint8_t *p_is_pcm, uint8_t *q_is_pcm)
+ int32_t beta, const int32_t *tc,
+ const uint8_t *p_is_pcm, const uint8_t *q_is_pcm)
{
ptrdiff_t stride_2x = (stride << 1);
ptrdiff_t stride_4x = (stride << 2);
@@ -436,8 +436,8 @@ void ff_hevc_loop_filter_luma_h_8_lsx(uint8_t *src, ptrdiff_t stride,
}
void ff_hevc_loop_filter_luma_v_8_lsx(uint8_t *src, ptrdiff_t stride,
- int32_t beta, int32_t *tc,
- uint8_t *p_is_pcm, uint8_t *q_is_pcm)
+ int32_t beta, const int32_t *tc,
+ const uint8_t *p_is_pcm, const uint8_t *q_is_pcm)
{
ptrdiff_t stride_2x = (stride << 1);
ptrdiff_t stride_4x = (stride << 2);
@@ -861,8 +861,8 @@ void ff_hevc_loop_filter_luma_v_8_lsx(uint8_t *src, ptrdiff_t stride,
}
void ff_hevc_loop_filter_chroma_h_8_lsx(uint8_t *src, ptrdiff_t stride,
- int32_t *tc, uint8_t *p_is_pcm,
- uint8_t *q_is_pcm)
+ const int32_t *tc, const uint8_t *p_is_pcm,
+ const uint8_t *q_is_pcm)
{
uint8_t *p1_ptr = src - (stride << 1);
uint8_t *p0_ptr = src - stride;
@@ -915,8 +915,8 @@ void ff_hevc_loop_filter_chroma_h_8_lsx(uint8_t *src, ptrdiff_t stride,
}
void ff_hevc_loop_filter_chroma_v_8_lsx(uint8_t *src, ptrdiff_t stride,
- int32_t *tc, uint8_t *p_is_pcm,
- uint8_t *q_is_pcm)
+ const int32_t *tc, const uint8_t *p_is_pcm,
+ const uint8_t *q_is_pcm)
{
ptrdiff_t stride_2x = (stride << 1);
ptrdiff_t stride_4x = (stride << 2);
@@ -987,9 +987,9 @@ void ff_hevc_loop_filter_chroma_v_8_lsx(uint8_t *src, ptrdiff_t stride,
static void hevc_sao_edge_filter_0degree_4width_lsx(uint8_t *dst,
int32_t dst_stride,
- uint8_t *src,
+ const uint8_t *src,
int32_t src_stride,
- int16_t *sao_offset_val,
+ const int16_t *sao_offset_val,
int32_t height)
{
const int32_t src_stride_2x = (src_stride << 1);
@@ -1072,9 +1072,9 @@ static void hevc_sao_edge_filter_0degree_4width_lsx(uint8_t *dst,
static void hevc_sao_edge_filter_0degree_8width_lsx(uint8_t *dst,
int32_t dst_stride,
- uint8_t *src,
+ const uint8_t *src,
int32_t src_stride,
- int16_t *sao_offset_val,
+ const int16_t *sao_offset_val,
int32_t height)
{
const int32_t src_stride_2x = (src_stride << 1);
@@ -1165,13 +1165,14 @@ static void hevc_sao_edge_filter_0degree_8width_lsx(uint8_t *dst,
static void hevc_sao_edge_filter_0degree_16multiple_lsx(uint8_t *dst,
int32_t dst_stride,
- uint8_t *src,
+ const uint8_t *src,
int32_t src_stride,
- int16_t *sao_offset_val,
+ const int16_t *sao_offset_val,
int32_t width,
int32_t height)
{
- uint8_t *dst_ptr, *src_minus1;
+ uint8_t *dst_ptr;
+ const uint8_t *src_minus1;
int32_t v_cnt;
const int32_t src_stride_2x = (src_stride << 1);
const int32_t dst_stride_2x = (dst_stride << 1);
@@ -1303,9 +1304,9 @@ static void hevc_sao_edge_filter_0degree_16multiple_lsx(uint8_t *dst,
static void hevc_sao_edge_filter_90degree_4width_lsx(uint8_t *dst,
int32_t dst_stride,
- uint8_t *src,
+ const uint8_t *src,
int32_t src_stride,
- int16_t *sao_offset_val,
+ const int16_t *sao_offset_val,
int32_t height)
{
const int32_t src_stride_2x = (src_stride << 1);
@@ -1398,9 +1399,9 @@ static void hevc_sao_edge_filter_90degree_4width_lsx(uint8_t *dst,
static void hevc_sao_edge_filter_90degree_8width_lsx(uint8_t *dst,
int32_t dst_stride,
- uint8_t *src,
+ const uint8_t *src,
int32_t src_stride,
- int16_t *sao_offset_val,
+ const int16_t *sao_offset_val,
int32_t height)
{
const int32_t src_stride_2x = (src_stride << 1);
@@ -1491,14 +1492,14 @@ static void hevc_sao_edge_filter_90degree_8width_lsx(uint8_t *dst,
static void hevc_sao_edge_filter_90degree_16multiple_lsx(uint8_t *dst,
int32_t dst_stride,
- uint8_t *src,
+ const uint8_t *src,
int32_t src_stride,
- int16_t *
+ const int16_t *
sao_offset_val,
int32_t width,
int32_t height)
{
- uint8_t *src_orig = src;
+ const uint8_t *src_orig = src;
uint8_t *dst_orig = dst;
int32_t h_cnt, v_cnt;
const int32_t src_stride_2x = (src_stride << 1);
@@ -1610,12 +1611,12 @@ static void hevc_sao_edge_filter_90degree_16multiple_lsx(uint8_t *dst,
static void hevc_sao_edge_filter_45degree_4width_lsx(uint8_t *dst,
int32_t dst_stride,
- uint8_t *src,
+ const uint8_t *src,
int32_t src_stride,
- int16_t *sao_offset_val,
+ const int16_t *sao_offset_val,
int32_t height)
{
- uint8_t *src_orig;
+ const uint8_t *src_orig;
const int32_t src_stride_2x = (src_stride << 1);
const int32_t dst_stride_2x = (dst_stride << 1);
__m128i shuf1 = {0x807060504030201, 0x100F0E0D0C0B0A09};
@@ -1723,12 +1724,12 @@ static void hevc_sao_edge_filter_45degree_4width_lsx(uint8_t *dst,
static void hevc_sao_edge_filter_45degree_8width_lsx(uint8_t *dst,
int32_t dst_stride,
- uint8_t *src,
+ const uint8_t *src,
int32_t src_stride,
- int16_t *sao_offset_val,
+ const int16_t *sao_offset_val,
int32_t height)
{
- uint8_t *src_orig;
+ const uint8_t *src_orig;
const int32_t src_stride_2x = (src_stride << 1);
const int32_t dst_stride_2x = (dst_stride << 1);
__m128i shuf1 = {0x807060504030201, 0x100F0E0D0C0B0A09};
@@ -1842,14 +1843,14 @@ static void hevc_sao_edge_filter_45degree_8width_lsx(uint8_t *dst,
static void hevc_sao_edge_filter_45degree_16multiple_lsx(uint8_t *dst,
int32_t dst_stride,
- uint8_t *src,
+ const uint8_t *src,
int32_t src_stride,
- int16_t *
+ const int16_t *
sao_offset_val,
int32_t width,
int32_t height)
{
- uint8_t *src_orig = src;
+ const uint8_t *src_orig = src;
uint8_t *dst_orig = dst;
int32_t v_cnt;
const int32_t src_stride_2x = (src_stride << 1);
@@ -1990,12 +1991,12 @@ static void hevc_sao_edge_filter_45degree_16multiple_lsx(uint8_t *dst,
static void hevc_sao_edge_filter_135degree_4width_lsx(uint8_t *dst,
int32_t dst_stride,
- uint8_t *src,
+ const uint8_t *src,
int32_t src_stride,
- int16_t *sao_offset_val,
+ const int16_t *sao_offset_val,
int32_t height)
{
- uint8_t *src_orig;
+ const uint8_t *src_orig;
const int32_t src_stride_2x = (src_stride << 1);
const int32_t dst_stride_2x = (dst_stride << 1);
@@ -2105,12 +2106,12 @@ static void hevc_sao_edge_filter_135degree_4width_lsx(uint8_t *dst,
static void hevc_sao_edge_filter_135degree_8width_lsx(uint8_t *dst,
int32_t dst_stride,
- uint8_t *src,
+ const uint8_t *src,
int32_t src_stride,
- int16_t *sao_offset_val,
+ const int16_t *sao_offset_val,
int32_t height)
{
- uint8_t *src_orig;
+ const uint8_t *src_orig;
const int32_t src_stride_2x = (src_stride << 1);
const int32_t dst_stride_2x = (dst_stride << 1);
@@ -2219,13 +2220,14 @@ static void hevc_sao_edge_filter_135degree_8width_lsx(uint8_t *dst,
static void hevc_sao_edge_filter_135degree_16multiple_lsx(uint8_t *dst,
int32_t dst_stride,
- uint8_t *src,
+ const uint8_t *src,
int32_t src_stride,
- int16_t *sao_offset_val,
+ const int16_t *sao_offset_val,
int32_t width,
int32_t height)
{
- uint8_t *src_orig, *dst_orig;
+ const uint8_t *src_orig;
+ uint8_t *dst_orig;
int32_t v_cnt;
const int32_t src_stride_2x = (src_stride << 1);
const int32_t dst_stride_2x = (dst_stride << 1);
@@ -2362,9 +2364,9 @@ static void hevc_sao_edge_filter_135degree_16multiple_lsx(uint8_t *dst,
}
}
-void ff_hevc_sao_edge_filter_8_lsx(uint8_t *dst, uint8_t *src,
+void ff_hevc_sao_edge_filter_8_lsx(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride_dst,
- int16_t *sao_offset_val,
+ const int16_t *sao_offset_val,
int eo, int width, int height)
{
ptrdiff_t stride_src = (2 * MAX_PB_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
diff --git a/libavcodec/loongarch/hevc_mc_bi_lsx.c b/libavcodec/loongarch/hevc_mc_bi_lsx.c
index 9092fdccb..48441c107 100644
--- a/libavcodec/loongarch/hevc_mc_bi_lsx.c
+++ b/libavcodec/loongarch/hevc_mc_bi_lsx.c
@@ -42,8 +42,8 @@ hevc_bi_rnd_clip(__m128i in0, __m128i vec0, __m128i in1, __m128i vec1)
/* hevc_bi_copy: dst = av_clip_uint8((src0 << 6 + src1) >> 7) */
static
-void hevc_bi_copy_4w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+void hevc_bi_copy_4w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride, int32_t height)
{
int32_t loop_cnt = height >> 3;
@@ -127,8 +127,8 @@ void hevc_bi_copy_4w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
static
-void hevc_bi_copy_6w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+void hevc_bi_copy_6w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride, int32_t height)
{
int32_t loop_cnt;
@@ -223,8 +223,8 @@ void hevc_bi_copy_6w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
static
-void hevc_bi_copy_8w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+void hevc_bi_copy_8w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride, int32_t height)
{
int32_t loop_cnt = height >> 3;
@@ -308,8 +308,8 @@ void hevc_bi_copy_8w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
static
-void hevc_bi_copy_12w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+void hevc_bi_copy_12w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride, int32_t height)
{
uint32_t loop_cnt;
@@ -322,7 +322,7 @@ void hevc_bi_copy_12w_lsx(uint8_t *src0_ptr, int32_t src_stride,
int32_t src_stride_3x = src_stride_2x + src_stride;
int32_t dst_stride_3x = dst_stride_2x + dst_stride;
int32_t src2_stride_3x = src2_stride_2x + src2_stride_x;
- int16_t* _src1 = src1_ptr + 8;
+ const int16_t *_src1 = src1_ptr + 8;
__m128i out0, out1, out2;
__m128i src0, src1, src2, src3;
__m128i in0, in1, in2, in3, in4, in5, in6, in7;
@@ -366,8 +366,8 @@ void hevc_bi_copy_12w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
static
-void hevc_bi_copy_16w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+void hevc_bi_copy_16w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride, int32_t height)
{
uint32_t loop_cnt;
@@ -380,7 +380,7 @@ void hevc_bi_copy_16w_lsx(uint8_t *src0_ptr, int32_t src_stride,
int32_t src_stride_3x = src_stride_2x + src_stride;
int32_t dst_stride_3x = dst_stride_2x + dst_stride;
int32_t src2_stride_3x = src2_stride_2x + src2_stride_x;
- int16_t *_src1 = src1_ptr + 8;
+ const int16_t *_src1 = src1_ptr + 8;
__m128i out0, out1, out2, out3;
__m128i src0, src1, src2, src3;
__m128i in0, in1, in2, in3, in4, in5, in6, in7;
@@ -423,8 +423,8 @@ void hevc_bi_copy_16w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
static
-void hevc_bi_copy_24w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+void hevc_bi_copy_24w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride, int32_t height)
{
hevc_bi_copy_16w_lsx(src0_ptr, src_stride, src1_ptr, src2_stride,
@@ -434,8 +434,8 @@ void hevc_bi_copy_24w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
static
-void hevc_bi_copy_32w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+void hevc_bi_copy_32w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride, int32_t height)
{
hevc_bi_copy_16w_lsx(src0_ptr, src_stride, src1_ptr, src2_stride,
@@ -445,8 +445,8 @@ void hevc_bi_copy_32w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
static
-void hevc_bi_copy_48w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+void hevc_bi_copy_48w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride, int32_t height)
{
hevc_bi_copy_16w_lsx(src0_ptr, src_stride, src1_ptr, src2_stride,
@@ -456,8 +456,8 @@ void hevc_bi_copy_48w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
static
-void hevc_bi_copy_64w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+void hevc_bi_copy_64w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride, int32_t height)
{
hevc_bi_copy_32w_lsx(src0_ptr, src_stride, src1_ptr, src2_stride,
@@ -466,8 +466,8 @@ void hevc_bi_copy_64w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst + 32, dst_stride, height);
}
-static void hevc_hz_8t_16w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hz_8t_16w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -531,8 +531,8 @@ static void hevc_hz_8t_16w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
}
-static void hevc_hz_8t_24w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hz_8t_24w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -585,8 +585,8 @@ static void hevc_hz_8t_24w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
}
-static void hevc_hz_8t_32w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hz_8t_32w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -596,8 +596,8 @@ static void hevc_hz_8t_32w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst + 16, dst_stride, filter, height);
}
-static void hevc_hz_8t_48w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hz_8t_48w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -607,8 +607,8 @@ static void hevc_hz_8t_48w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst + 16, dst_stride, filter, height);
}
-static void hevc_hz_8t_64w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hz_8t_64w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -619,7 +619,7 @@ static void hevc_hz_8t_64w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
static av_always_inline
-void hevc_vt_8t_8w_lsx(uint8_t *src0_ptr, int32_t src_stride, int16_t *src1_ptr,
+void hevc_vt_8t_8w_lsx(const uint8_t *src0_ptr, int32_t src_stride, const int16_t *src1_ptr,
int32_t src2_stride, uint8_t *dst, int32_t dst_stride,\
const int8_t *filter, int32_t height)
{
@@ -705,14 +705,14 @@ void hevc_vt_8t_8w_lsx(uint8_t *src0_ptr, int32_t src_stride, int16_t *src1_ptr,
}
static av_always_inline
-void hevc_vt_8t_16multx2mult_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+void hevc_vt_8t_16multx2mult_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height,
int32_t width)
{
- uint8_t *src0_ptr_tmp;
- int16_t *src1_ptr_tmp;
+ const uint8_t *src0_ptr_tmp;
+ const int16_t *src1_ptr_tmp;
uint8_t *dst_tmp;
uint32_t loop_cnt;
uint32_t cnt;
@@ -808,8 +808,8 @@ void hevc_vt_8t_16multx2mult_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
}
-static void hevc_vt_8t_16w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_vt_8t_16w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -817,8 +817,8 @@ static void hevc_vt_8t_16w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst, dst_stride, filter, height, 16);
}
-static void hevc_vt_8t_24w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_vt_8t_24w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -828,8 +828,8 @@ static void hevc_vt_8t_24w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst + 16, dst_stride, filter, height);
}
-static void hevc_vt_8t_32w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_vt_8t_32w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -837,8 +837,8 @@ static void hevc_vt_8t_32w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst, dst_stride, filter, height, 32);
}
-static void hevc_vt_8t_48w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_vt_8t_48w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -846,8 +846,8 @@ static void hevc_vt_8t_48w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst, dst_stride, filter, height, 48);
}
-static void hevc_vt_8t_64w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_vt_8t_64w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -856,16 +856,16 @@ static void hevc_vt_8t_64w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
static av_always_inline
-void hevc_hv_8t_8multx1mult_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+void hevc_hv_8t_8multx1mult_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height, int32_t width)
{
uint32_t loop_cnt;
uint32_t cnt;
- uint8_t *src0_ptr_tmp;
- int16_t *src1_ptr_tmp;
+ const uint8_t *src0_ptr_tmp;
+ const int16_t *src1_ptr_tmp;
uint8_t *dst_tmp;
int32_t src_stride_2x = (src_stride << 1);
int32_t src_stride_4x = (src_stride << 2);
@@ -994,8 +994,8 @@ void hevc_hv_8t_8multx1mult_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
}
-static void hevc_hv_8t_8w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hv_8t_8w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -1004,8 +1004,8 @@ static void hevc_hv_8t_8w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst, dst_stride, filter_x, filter_y, height, 8);
}
-static void hevc_hv_8t_16w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hv_8t_16w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -1014,8 +1014,8 @@ static void hevc_hv_8t_16w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst, dst_stride, filter_x, filter_y, height, 16);
}
-static void hevc_hv_8t_24w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hv_8t_24w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -1024,8 +1024,8 @@ static void hevc_hv_8t_24w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst, dst_stride, filter_x, filter_y, height, 24);
}
-static void hevc_hv_8t_32w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hv_8t_32w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -1034,8 +1034,8 @@ static void hevc_hv_8t_32w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst, dst_stride, filter_x, filter_y, height, 32);
}
-static void hevc_hv_8t_48w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hv_8t_48w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -1044,8 +1044,8 @@ static void hevc_hv_8t_48w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst, dst_stride, filter_x, filter_y, height, 48);
}
-static void hevc_hv_8t_64w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hv_8t_64w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -1054,12 +1054,12 @@ static void hevc_hv_8t_64w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst, dst_stride, filter_x, filter_y, height, 64);
}
-static void hevc_hz_4t_24w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hz_4t_24w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
- int16_t *src1_ptr_tmp;
+ const int16_t *src1_ptr_tmp;
uint8_t *dst_tmp;
uint32_t loop_cnt;
int32_t dst_stride_2x = (dst_stride << 1);
@@ -1157,8 +1157,8 @@ static void hevc_hz_4t_24w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
}
-static void hevc_hz_4t_32w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hz_4t_32w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1201,8 +1201,8 @@ static void hevc_hz_4t_32w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
}
-static void hevc_vt_4t_12w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_vt_4t_12w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1216,7 +1216,7 @@ static void hevc_vt_4t_12w_lsx(uint8_t *src0_ptr, int32_t src_stride,
int32_t src_stride_3x = src_stride_2x + src_stride;
int32_t dst_stride_3x = dst_stride_2x + dst_stride;
int32_t src2_stride_3x = src2_stride_2x + src2_stride_x;
- int16_t *_src1 = src1_ptr + 8;
+ const int16_t *_src1 = src1_ptr + 8;
__m128i src0, src1, src2, src3, src4, src5, src6;
__m128i in0, in1, in2, in3, in4, in5, in6, in7;
__m128i src10_r, src32_r, src21_r, src43_r, src54_r, src65_r;
@@ -1290,8 +1290,8 @@ static void hevc_vt_4t_12w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
}
-static void hevc_vt_4t_16w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_vt_4t_16w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1362,8 +1362,8 @@ static void hevc_vt_4t_16w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
}
-static void hevc_vt_4t_24w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_vt_4t_24w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1469,8 +1469,8 @@ static void hevc_vt_4t_24w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
}
-static void hevc_vt_4t_32w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_vt_4t_32w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1480,8 +1480,8 @@ static void hevc_vt_4t_32w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst + 16, dst_stride, filter, height);
}
-static void hevc_hv_4t_6w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hv_4t_6w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -1668,7 +1668,7 @@ static void hevc_hv_4t_6w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
static av_always_inline
-void hevc_hv_4t_8x2_lsx(uint8_t *src0_ptr, int32_t src_stride, int16_t *src1_ptr,
+void hevc_hv_4t_8x2_lsx(const uint8_t *src0_ptr, int32_t src_stride, const int16_t *src1_ptr,
int32_t src2_stride, uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y)
{
@@ -1739,8 +1739,8 @@ void hevc_hv_4t_8x2_lsx(uint8_t *src0_ptr, int32_t src_stride, int16_t *src1_ptr
}
static av_always_inline
-void hevc_hv_4t_8multx4_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+void hevc_hv_4t_8multx4_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t width8mult)
@@ -1858,7 +1858,7 @@ void hevc_hv_4t_8multx4_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
static av_always_inline
-void hevc_hv_4t_8x6_lsx(uint8_t *src0_ptr, int32_t src_stride, int16_t *src1_ptr,
+void hevc_hv_4t_8x6_lsx(const uint8_t *src0_ptr, int32_t src_stride, const int16_t *src1_ptr,
int32_t src2_stride, uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y)
{
@@ -1990,15 +1990,15 @@ void hevc_hv_4t_8x6_lsx(uint8_t *src0_ptr, int32_t src_stride, int16_t *src1_ptr
}
static av_always_inline
-void hevc_hv_4t_8multx4mult_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+void hevc_hv_4t_8multx4mult_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height, int32_t width)
{
uint32_t loop_cnt, cnt;
- uint8_t *src0_ptr_tmp;
- int16_t *src1_ptr_tmp;
+ const uint8_t *src0_ptr_tmp;
+ const int16_t *src1_ptr_tmp;
uint8_t *dst_tmp;
const int32_t src_stride_2x = (src_stride << 1);
const int32_t dst_stride_2x = (dst_stride << 1);
@@ -2130,8 +2130,8 @@ void hevc_hv_4t_8multx4mult_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
}
-static void hevc_hv_4t_8w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hv_4t_8w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -2151,8 +2151,8 @@ static void hevc_hv_4t_8w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
}
-static void hevc_hv_4t_16w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hv_4t_16w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -2166,8 +2166,8 @@ static void hevc_hv_4t_16w_lsx(uint8_t *src0_ptr, int32_t src_stride,
}
}
-static void hevc_hv_4t_24w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hv_4t_24w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -2176,8 +2176,8 @@ static void hevc_hv_4t_24w_lsx(uint8_t *src0_ptr, int32_t src_stride,
dst, dst_stride, filter_x, filter_y, height, 24);
}
-static void hevc_hv_4t_32w_lsx(uint8_t *src0_ptr, int32_t src_stride,
- int16_t *src1_ptr, int32_t src2_stride,
+static void hevc_hv_4t_32w_lsx(const uint8_t *src0_ptr, int32_t src_stride,
+ const int16_t *src1_ptr, int32_t src2_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -2189,9 +2189,9 @@ static void hevc_hv_4t_32w_lsx(uint8_t *src0_ptr, int32_t src_stride,
#define BI_MC_COPY(WIDTH) \
void ff_hevc_put_hevc_bi_pel_pixels##WIDTH##_8_lsx(uint8_t *dst, \
ptrdiff_t dst_stride, \
- uint8_t *src, \
+ const uint8_t *src, \
ptrdiff_t src_stride, \
- int16_t *src_16bit, \
+ const int16_t *src_16bit, \
int height, \
intptr_t mx, \
intptr_t my, \
@@ -2216,9 +2216,9 @@ BI_MC_COPY(64);
#define BI_MC(PEL, DIR, WIDTH, TAP, DIR1, FILT_DIR) \
void ff_hevc_put_hevc_bi_##PEL##_##DIR##WIDTH##_8_lsx(uint8_t *dst, \
ptrdiff_t dst_stride, \
- uint8_t *src, \
+ const uint8_t *src, \
ptrdiff_t src_stride, \
- int16_t *src_16bit, \
+ const int16_t *src_16bit, \
int height, \
intptr_t mx, \
intptr_t my, \
@@ -2257,9 +2257,9 @@ BI_MC(epel, v, 32, 4, vt, my);
#define BI_MC_HV(PEL, WIDTH, TAP) \
void ff_hevc_put_hevc_bi_##PEL##_hv##WIDTH##_8_lsx(uint8_t *dst, \
ptrdiff_t dst_stride, \
- uint8_t *src, \
+ const uint8_t *src, \
ptrdiff_t src_stride, \
- int16_t *src_16bit, \
+ const int16_t *src_16bit, \
int height, \
intptr_t mx, \
intptr_t my, \
diff --git a/libavcodec/loongarch/hevc_mc_uni_lsx.c b/libavcodec/loongarch/hevc_mc_uni_lsx.c
index a15c86268..5437dce0e 100644
--- a/libavcodec/loongarch/hevc_mc_uni_lsx.c
+++ b/libavcodec/loongarch/hevc_mc_uni_lsx.c
@@ -33,7 +33,7 @@ static const uint8_t ff_hevc_mask_arr[16 * 3] __attribute__((aligned(0x40))) = {
};
static av_always_inline
-void common_hz_8t_64w_lsx(uint8_t *src, int32_t src_stride,
+void common_hz_8t_64w_lsx(const uint8_t *src, int32_t src_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -125,7 +125,7 @@ void common_hz_8t_64w_lsx(uint8_t *src, int32_t src_stride,
}
static av_always_inline
-void common_vt_8t_8w_lsx(uint8_t *src, int32_t src_stride,
+void common_vt_8t_8w_lsx(const uint8_t *src, int32_t src_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -197,11 +197,11 @@ void common_vt_8t_8w_lsx(uint8_t *src, int32_t src_stride,
}
static av_always_inline
-void common_vt_8t_16w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void common_vt_8t_16w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter,
int32_t height, int32_t width)
{
- uint8_t *src_tmp;
+ const uint8_t *src_tmp;
uint8_t *dst_tmp;
uint32_t loop_cnt, cnt;
const int32_t src_stride_2x = (src_stride << 1);
@@ -304,7 +304,7 @@ void common_vt_8t_16w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
}
-static void common_vt_8t_24w_lsx(uint8_t *src, int32_t src_stride,
+static void common_vt_8t_24w_lsx(const uint8_t *src, int32_t src_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -313,21 +313,21 @@ static void common_vt_8t_24w_lsx(uint8_t *src, int32_t src_stride,
height);
}
-static void common_vt_8t_32w_lsx(uint8_t *src, int32_t src_stride,
+static void common_vt_8t_32w_lsx(const uint8_t *src, int32_t src_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
common_vt_8t_16w_lsx(src, src_stride, dst, dst_stride, filter, height, 32);
}
-static void common_vt_8t_48w_lsx(uint8_t *src, int32_t src_stride,
+static void common_vt_8t_48w_lsx(const uint8_t *src, int32_t src_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
common_vt_8t_16w_lsx(src, src_stride, dst, dst_stride, filter, height, 48);
}
-static void common_vt_8t_64w_lsx(uint8_t *src, int32_t src_stride,
+static void common_vt_8t_64w_lsx(const uint8_t *src, int32_t src_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -335,12 +335,12 @@ static void common_vt_8t_64w_lsx(uint8_t *src, int32_t src_stride,
}
static av_always_inline
-void hevc_hv_8t_8x2_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void hevc_hv_8t_8x2_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height, int32_t width)
{
uint32_t loop_cnt, cnt;
- uint8_t *src_tmp;
+ const uint8_t *src_tmp;
uint8_t *dst_tmp;
const int32_t src_stride_2x = (src_stride << 1);
const int32_t dst_stride_2x = (dst_stride << 1);
@@ -496,7 +496,7 @@ void hevc_hv_8t_8x2_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
}
-static void hevc_hv_8t_8w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+static void hevc_hv_8t_8w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height)
{
@@ -504,7 +504,7 @@ static void hevc_hv_8t_8w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
filter_x, filter_y, height, 8);
}
-static void hevc_hv_8t_16w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+static void hevc_hv_8t_16w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height)
{
@@ -512,7 +512,7 @@ static void hevc_hv_8t_16w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
filter_x, filter_y, height, 16);
}
-static void hevc_hv_8t_24w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+static void hevc_hv_8t_24w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height)
{
@@ -520,7 +520,7 @@ static void hevc_hv_8t_24w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
filter_x, filter_y, height, 24);
}
-static void hevc_hv_8t_32w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+static void hevc_hv_8t_32w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height)
{
@@ -528,7 +528,7 @@ static void hevc_hv_8t_32w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
filter_x, filter_y, height, 32);
}
-static void hevc_hv_8t_48w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+static void hevc_hv_8t_48w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height)
{
@@ -536,7 +536,7 @@ static void hevc_hv_8t_48w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
filter_x, filter_y, height, 48);
}
-static void hevc_hv_8t_64w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+static void hevc_hv_8t_64w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height)
{
@@ -545,14 +545,14 @@ static void hevc_hv_8t_64w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
static av_always_inline
-void common_vt_4t_24w_lsx(uint8_t *src, int32_t src_stride,
+void common_vt_4t_24w_lsx(const uint8_t *src, int32_t src_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
uint32_t loop_cnt;
int32_t src_stride_2x = (src_stride << 1);
int32_t src_stride_3x = src_stride_2x + src_stride;
- uint8_t *_src;
+ const uint8_t *_src;
__m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10;
__m128i src11, filt0, filt1;
@@ -651,7 +651,7 @@ void common_vt_4t_24w_lsx(uint8_t *src, int32_t src_stride,
}
static av_always_inline
-void common_vt_4t_32w_lsx(uint8_t *src, int32_t src_stride,
+void common_vt_4t_32w_lsx(const uint8_t *src, int32_t src_stride,
uint8_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -659,7 +659,7 @@ void common_vt_4t_32w_lsx(uint8_t *src, int32_t src_stride,
int32_t src_stride_2x = (src_stride << 1);
int32_t dst_stride_2x = (dst_stride << 1);
int32_t src_stride_3x = src_stride_2x + src_stride;
- uint8_t *_src;
+ const uint8_t *_src;
__m128i src0, src1, src2, src3, src4, src6, src7, src8, src9, src10;
__m128i src10_r, src32_r, src76_r, src98_r;
@@ -745,7 +745,7 @@ void common_vt_4t_32w_lsx(uint8_t *src, int32_t src_stride,
}
static av_always_inline
-void hevc_hv_4t_8x2_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void hevc_hv_4t_8x2_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y)
{
@@ -806,7 +806,7 @@ void hevc_hv_4t_8x2_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
static av_always_inline
-void hevc_hv_4t_8multx4_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void hevc_hv_4t_8multx4_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t width8mult)
{
@@ -902,7 +902,7 @@ void hevc_hv_4t_8multx4_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
static av_always_inline
-void hevc_hv_4t_8x6_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void hevc_hv_4t_8x6_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y)
{
@@ -1009,13 +1009,13 @@ void hevc_hv_4t_8x6_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
static av_always_inline
-void hevc_hv_4t_8multx4mult_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void hevc_hv_4t_8multx4mult_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height,
int32_t width8mult)
{
uint32_t loop_cnt, cnt;
- uint8_t *src_tmp;
+ const uint8_t *src_tmp;
uint8_t *dst_tmp;
const int32_t src_stride_2x = (src_stride << 1);
const int32_t dst_stride_2x = (dst_stride << 1);
@@ -1128,7 +1128,7 @@ void hevc_hv_4t_8multx4mult_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
static
-void hevc_hv_4t_8w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void hevc_hv_4t_8w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height)
{
@@ -1146,12 +1146,13 @@ void hevc_hv_4t_8w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
static av_always_inline
-void hevc_hv_4t_12w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void hevc_hv_4t_12w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height)
{
uint32_t loop_cnt;
- uint8_t *src_tmp, *dst_tmp;
+ const uint8_t *src_tmp;
+ uint8_t *dst_tmp;
const int32_t src_stride_2x = (src_stride << 1);
const int32_t dst_stride_2x = (dst_stride << 1);
const int32_t src_stride_4x = (src_stride << 2);
@@ -1333,7 +1334,7 @@ void hevc_hv_4t_12w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
}
-static void hevc_hv_4t_16w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+static void hevc_hv_4t_16w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height)
{
@@ -1346,7 +1347,7 @@ static void hevc_hv_4t_16w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
}
-static void hevc_hv_4t_24w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+static void hevc_hv_4t_24w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height)
{
@@ -1354,7 +1355,7 @@ static void hevc_hv_4t_24w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
filter_x, filter_y, height, 3);
}
-static void hevc_hv_4t_32w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+static void hevc_hv_4t_32w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height)
{
@@ -1365,7 +1366,7 @@ static void hevc_hv_4t_32w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
#define UNI_MC(PEL, DIR, WIDTH, TAP, DIR1, FILT_DIR) \
void ff_hevc_put_hevc_uni_##PEL##_##DIR##WIDTH##_8_lsx(uint8_t *dst, \
ptrdiff_t dst_stride, \
- uint8_t *src, \
+ const uint8_t *src, \
ptrdiff_t src_stride, \
int height, \
intptr_t mx, \
@@ -1393,7 +1394,7 @@ UNI_MC(epel, v, 32, 4, vt, my);
#define UNI_MC_HV(PEL, WIDTH, TAP) \
void ff_hevc_put_hevc_uni_##PEL##_hv##WIDTH##_8_lsx(uint8_t *dst, \
ptrdiff_t dst_stride, \
- uint8_t *src, \
+ const uint8_t *src, \
ptrdiff_t src_stride, \
int height, \
intptr_t mx, \
diff --git a/libavcodec/loongarch/hevc_mc_uniw_lsx.c b/libavcodec/loongarch/hevc_mc_uniw_lsx.c
index 118f5b820..c4e79225d 100644
--- a/libavcodec/loongarch/hevc_mc_uniw_lsx.c
+++ b/libavcodec/loongarch/hevc_mc_uniw_lsx.c
@@ -31,13 +31,13 @@ static const uint8_t ff_hevc_mask_arr[16 * 2] __attribute__((aligned(0x40))) = {
};
static av_always_inline
-void hevc_hv_8t_8x2_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void hevc_hv_8t_8x2_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height, int32_t weight,
int32_t offset, int32_t rnd_val, int32_t width)
{
uint32_t loop_cnt, cnt;
- uint8_t *src_tmp;
+ const uint8_t *src_tmp;
uint8_t *dst_tmp;
const int32_t src_stride_2x = (src_stride << 1);
const int32_t dst_stride_2x = (dst_stride << 1);
@@ -207,7 +207,7 @@ void hevc_hv_8t_8x2_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
static
-void hevc_hv_8t_8w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void hevc_hv_8t_8w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height, int32_t weight,
int32_t offset, int32_t rnd_val)
@@ -217,7 +217,7 @@ void hevc_hv_8t_8w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
static
-void hevc_hv_8t_16w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void hevc_hv_8t_16w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height, int32_t weight,
int32_t offset, int32_t rnd_val)
@@ -227,7 +227,7 @@ void hevc_hv_8t_16w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
static
-void hevc_hv_8t_24w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void hevc_hv_8t_24w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height, int32_t weight,
int32_t offset, int32_t rnd_val)
@@ -237,7 +237,7 @@ void hevc_hv_8t_24w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
static
-void hevc_hv_8t_32w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void hevc_hv_8t_32w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height, int32_t weight,
int32_t offset, int32_t rnd_val)
@@ -247,7 +247,7 @@ void hevc_hv_8t_32w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
static
-void hevc_hv_8t_48w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void hevc_hv_8t_48w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height, int32_t weight,
int32_t offset, int32_t rnd_val)
@@ -257,7 +257,7 @@ void hevc_hv_8t_48w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
}
static
-void hevc_hv_8t_64w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
+void hevc_hv_8t_64w_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
int32_t dst_stride, const int8_t *filter_x,
const int8_t *filter_y, int32_t height, int32_t weight,
int32_t offset, int32_t rnd_val)
@@ -270,7 +270,7 @@ void hevc_hv_8t_64w_lsx(uint8_t *src, int32_t src_stride, uint8_t *dst,
#define UNI_W_MC_HV(PEL, WIDTH, TAP) \
void ff_hevc_put_hevc_uni_w_##PEL##_hv##WIDTH##_8_lsx(uint8_t *dst, \
ptrdiff_t dst_stride, \
- uint8_t *src, \
+ const uint8_t *src, \
ptrdiff_t src_stride, \
int height, \
int denom, \
diff --git a/libavcodec/loongarch/hevcdsp_lsx.c b/libavcodec/loongarch/hevcdsp_lsx.c
index a520f02bd..85843dd11 100644
--- a/libavcodec/loongarch/hevcdsp_lsx.c
+++ b/libavcodec/loongarch/hevcdsp_lsx.c
@@ -31,7 +31,7 @@ static const uint8_t ff_hevc_mask_arr[16 * 2] __attribute__((aligned(0x40))) = {
};
/* hevc_copy: dst = src << 6 */
-static void hevc_copy_4w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_copy_4w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
int32_t height)
{
@@ -83,7 +83,7 @@ static void hevc_copy_4w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_copy_6w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_copy_6w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
int32_t height)
{
@@ -146,7 +146,7 @@ static void hevc_copy_6w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_copy_8w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_copy_8w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
int32_t height)
{
@@ -197,7 +197,7 @@ static void hevc_copy_8w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_copy_12w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_copy_12w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
int32_t height)
{
@@ -269,7 +269,7 @@ static void hevc_copy_12w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_copy_16w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_copy_16w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
int32_t height)
{
@@ -354,7 +354,7 @@ static void hevc_copy_16w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_copy_24w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_copy_24w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
int32_t height)
{
@@ -365,7 +365,7 @@ static void hevc_copy_24w_lsx(uint8_t *src, int32_t src_stride,
int32_t dst_stride_2x = (dst_stride << 2);
int32_t src_stride_3x = src_stride_2x + src_stride;
int32_t dst_stride_3x = dst_stride_2x + dst_stride_x;
- uint8_t *_src = src + 16;
+ const uint8_t *_src = src + 16;
int16_t *dst1 = dst;
__m128i zero = __lsx_vldi(0);
__m128i src0, src1, src2, src3, src4, src5, src6, src7;
@@ -408,7 +408,7 @@ static void hevc_copy_24w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_copy_32w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_copy_32w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
int32_t height)
{
@@ -416,7 +416,7 @@ static void hevc_copy_32w_lsx(uint8_t *src, int32_t src_stride,
int32_t src_stride_2x = (src_stride << 1);
int32_t src_stride_4x = (src_stride << 2);
int32_t src_stride_3x = src_stride_2x + src_stride;
- uint8_t *_src = src + 16;
+ const uint8_t *_src = src + 16;
__m128i zero = {0};
__m128i src0, src1, src2, src3, src4, src5, src6, src7;
__m128i in0_r, in1_r, in2_r, in3_r, in0_l, in1_l, in2_l, in3_l;
@@ -468,7 +468,7 @@ static void hevc_copy_32w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_copy_48w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_copy_48w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
int32_t height)
{
@@ -543,7 +543,7 @@ static void hevc_copy_48w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_copy_64w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_copy_64w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
int32_t height)
{
@@ -595,7 +595,7 @@ static void hevc_copy_64w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_hz_8t_4w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hz_8t_4w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -682,7 +682,7 @@ static void hevc_hz_8t_4w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_hz_8t_8w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hz_8t_8w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -746,7 +746,7 @@ static void hevc_hz_8t_8w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_hz_8t_12w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hz_8t_12w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -754,7 +754,7 @@ static void hevc_hz_8t_12w_lsx(uint8_t *src, int32_t src_stride,
int32_t src_stride_2x = (src_stride << 1);
int32_t src_stride_4x = (src_stride << 2);
int32_t src_stride_3x = src_stride_2x + src_stride;
- uint8_t *_src;
+ const uint8_t *_src;
__m128i src0, src1, src2, src3, src4, src5, src6, src7;
__m128i mask0, mask1, mask2, mask3, mask4, mask5, mask6, mask7;
__m128i vec0, vec1, vec2, vec3, vec4, vec5;
@@ -838,7 +838,7 @@ static void hevc_hz_8t_12w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_hz_8t_16w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hz_8t_16w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -898,7 +898,7 @@ static void hevc_hz_8t_16w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_hz_8t_24w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hz_8t_24w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -968,7 +968,7 @@ static void hevc_hz_8t_24w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_hz_8t_32w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hz_8t_32w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1028,7 +1028,7 @@ static void hevc_hz_8t_32w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_hz_8t_48w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hz_8t_48w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1097,7 +1097,7 @@ static void hevc_hz_8t_48w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_hz_8t_64w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hz_8t_64w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1191,7 +1191,7 @@ static void hevc_hz_8t_64w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_vt_8t_4w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_vt_8t_4w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1311,7 +1311,7 @@ static void hevc_vt_8t_4w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_vt_8t_8w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_vt_8t_8w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1385,7 +1385,7 @@ static void hevc_vt_8t_8w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_vt_8t_12w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_vt_8t_12w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1487,7 +1487,7 @@ static void hevc_vt_8t_12w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_vt_8t_16multx4mult_lsx(uint8_t *src,
+static void hevc_vt_8t_16multx4mult_lsx(const uint8_t *src,
int32_t src_stride,
int16_t *dst,
int32_t dst_stride,
@@ -1495,7 +1495,7 @@ static void hevc_vt_8t_16multx4mult_lsx(uint8_t *src,
int32_t height,
int32_t width)
{
- uint8_t *src_tmp;
+ const uint8_t *src_tmp;
int16_t *dst_tmp;
int32_t loop_cnt, cnt;
int32_t src_stride_2x = (src_stride << 1);
@@ -1611,7 +1611,7 @@ static void hevc_vt_8t_16multx4mult_lsx(uint8_t *src,
}
}
-static void hevc_vt_8t_16w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_vt_8t_16w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1619,7 +1619,7 @@ static void hevc_vt_8t_16w_lsx(uint8_t *src, int32_t src_stride,
filter, height, 16);
}
-static void hevc_vt_8t_24w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_vt_8t_24w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1629,7 +1629,7 @@ static void hevc_vt_8t_24w_lsx(uint8_t *src, int32_t src_stride,
filter, height);
}
-static void hevc_vt_8t_32w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_vt_8t_32w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1637,7 +1637,7 @@ static void hevc_vt_8t_32w_lsx(uint8_t *src, int32_t src_stride,
filter, height, 32);
}
-static void hevc_vt_8t_48w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_vt_8t_48w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1645,7 +1645,7 @@ static void hevc_vt_8t_48w_lsx(uint8_t *src, int32_t src_stride,
filter, height, 48);
}
-static void hevc_vt_8t_64w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_vt_8t_64w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter, int32_t height)
{
@@ -1653,7 +1653,7 @@ static void hevc_vt_8t_64w_lsx(uint8_t *src, int32_t src_stride,
filter, height, 64);
}
-static void hevc_hv_8t_4w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hv_8t_4w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -1785,7 +1785,7 @@ static void hevc_hv_8t_4w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_hv_8t_8multx1mult_lsx(uint8_t *src,
+static void hevc_hv_8t_8multx1mult_lsx(const uint8_t *src,
int32_t src_stride,
int16_t *dst,
int32_t dst_stride,
@@ -1795,7 +1795,7 @@ static void hevc_hv_8t_8multx1mult_lsx(uint8_t *src,
int32_t width)
{
uint32_t loop_cnt, cnt;
- uint8_t *src_tmp;
+ const uint8_t *src_tmp;
int16_t *dst_tmp;
int32_t src_stride_2x = (src_stride << 1);
int32_t src_stride_4x = (src_stride << 2);
@@ -1928,7 +1928,7 @@ static void hevc_hv_8t_8multx1mult_lsx(uint8_t *src,
}
}
-static void hevc_hv_8t_8w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hv_8t_8w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -1937,13 +1937,13 @@ static void hevc_hv_8t_8w_lsx(uint8_t *src, int32_t src_stride,
filter_x, filter_y, height, 8);
}
-static void hevc_hv_8t_12w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hv_8t_12w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
{
uint32_t loop_cnt;
- uint8_t *src_tmp;
+ const uint8_t *src_tmp;
int16_t *dst_tmp;
int32_t src_stride_2x = (src_stride << 1);
int32_t src_stride_4x = (src_stride << 2);
@@ -2174,7 +2174,7 @@ static void hevc_hv_8t_12w_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_hv_8t_16w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hv_8t_16w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -2183,7 +2183,7 @@ static void hevc_hv_8t_16w_lsx(uint8_t *src, int32_t src_stride,
filter_x, filter_y, height, 16);
}
-static void hevc_hv_8t_24w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hv_8t_24w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -2192,7 +2192,7 @@ static void hevc_hv_8t_24w_lsx(uint8_t *src, int32_t src_stride,
filter_x, filter_y, height, 24);
}
-static void hevc_hv_8t_32w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hv_8t_32w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -2201,7 +2201,7 @@ static void hevc_hv_8t_32w_lsx(uint8_t *src, int32_t src_stride,
filter_x, filter_y, height, 32);
}
-static void hevc_hv_8t_48w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hv_8t_48w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -2210,7 +2210,7 @@ static void hevc_hv_8t_48w_lsx(uint8_t *src, int32_t src_stride,
filter_x, filter_y, height, 48);
}
-static void hevc_hv_8t_64w_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hv_8t_64w_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter_x, const int8_t *filter_y,
int32_t height)
@@ -2219,7 +2219,7 @@ static void hevc_hv_8t_64w_lsx(uint8_t *src, int32_t src_stride,
filter_x, filter_y, height, 64);
}
-static void hevc_hz_4t_32w_lsx(uint8_t *src,
+static void hevc_hz_4t_32w_lsx(const uint8_t *src,
int32_t src_stride,
int16_t *dst,
int32_t dst_stride,
@@ -2265,7 +2265,7 @@ static void hevc_hz_4t_32w_lsx(uint8_t *src,
}
}
-static void hevc_vt_4t_16w_lsx(uint8_t *src,
+static void hevc_vt_4t_16w_lsx(const uint8_t *src,
int32_t src_stride,
int16_t *dst,
int32_t dst_stride,
@@ -2327,7 +2327,7 @@ static void hevc_vt_4t_16w_lsx(uint8_t *src,
}
}
-static void hevc_vt_4t_24w_lsx(uint8_t *src,
+static void hevc_vt_4t_24w_lsx(const uint8_t *src,
int32_t src_stride,
int16_t *dst,
int32_t dst_stride,
@@ -2337,7 +2337,7 @@ static void hevc_vt_4t_24w_lsx(uint8_t *src,
int32_t loop_cnt;
int32_t src_stride_2x = (src_stride << 1);
int32_t src_stride_3x = src_stride_2x + src_stride;
- uint8_t *_src;
+ const uint8_t *_src;
__m128i src0, src1, src2, src3, src4, src5;
__m128i src6, src7, src8, src9, src10, src11;
@@ -2421,7 +2421,7 @@ static void hevc_vt_4t_24w_lsx(uint8_t *src,
}
}
-static void hevc_vt_4t_32w_lsx(uint8_t *src,
+static void hevc_vt_4t_32w_lsx(const uint8_t *src,
int32_t src_stride,
int16_t *dst,
int32_t dst_stride,
@@ -2431,7 +2431,7 @@ static void hevc_vt_4t_32w_lsx(uint8_t *src,
int32_t loop_cnt;
int32_t src_stride_2x = (src_stride << 1);
int32_t src_stride_3x = src_stride_2x + src_stride;
- uint8_t *_src;
+ const uint8_t *_src;
__m128i src0, src1, src2, src3, src4, src5;
__m128i src6, src7, src8, src9, src10, src11;
@@ -2527,7 +2527,7 @@ static void hevc_vt_4t_32w_lsx(uint8_t *src,
}
}
-static void hevc_hv_4t_8x2_lsx(uint8_t *src,
+static void hevc_hv_4t_8x2_lsx(const uint8_t *src,
int32_t src_stride,
int16_t *dst,
int32_t dst_stride,
@@ -2594,7 +2594,7 @@ static void hevc_hv_4t_8x2_lsx(uint8_t *src,
__lsx_vst(dst1_r, dst + dst_stride, 0);
}
-static void hevc_hv_4t_8multx4_lsx(uint8_t *src, int32_t src_stride,
+static void hevc_hv_4t_8multx4_lsx(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
const int8_t *filter_x,
const int8_t *filter_y, int32_t width8mult)
@@ -2694,7 +2694,7 @@ static void hevc_hv_4t_8multx4_lsx(uint8_t *src, int32_t src_stride,
}
}
-static void hevc_hv_4t_8x6_lsx(uint8_t *src,
+static void hevc_hv_4t_8x6_lsx(const uint8_t *src,
int32_t src_stride,
int16_t *dst,
int32_t dst_stride,
@@ -2803,7 +2803,7 @@ static void hevc_hv_4t_8x6_lsx(uint8_t *src,
__lsx_vstx(dst5_r, dst, dst_stride_2x);
}
-static void hevc_hv_4t_8multx4mult_lsx(uint8_t *src,
+static void hevc_hv_4t_8multx4mult_lsx(const uint8_t *src,
int32_t src_stride,
int16_t *dst,
int32_t dst_stride,
@@ -2813,7 +2813,7 @@ static void hevc_hv_4t_8multx4mult_lsx(uint8_t *src,
int32_t width8mult)
{
uint32_t loop_cnt, cnt;
- uint8_t *src_tmp;
+ const uint8_t *src_tmp;
int16_t *dst_tmp;
int32_t src_stride_2x = (src_stride << 1);
int32_t dst_stride_x = (dst_stride << 1);
@@ -2930,7 +2930,7 @@ static void hevc_hv_4t_8multx4mult_lsx(uint8_t *src,
}
}
-static void hevc_hv_4t_8w_lsx(uint8_t *src,
+static void hevc_hv_4t_8w_lsx(const uint8_t *src,
int32_t src_stride,
int16_t *dst,
int32_t dst_stride,
@@ -2954,7 +2954,7 @@ static void hevc_hv_4t_8w_lsx(uint8_t *src,
}
}
-static void hevc_hv_4t_12w_lsx(uint8_t *src,
+static void hevc_hv_4t_12w_lsx(const uint8_t *src,
int32_t src_stride,
int16_t *dst,
int32_t dst_stride,
@@ -2963,7 +2963,7 @@ static void hevc_hv_4t_12w_lsx(uint8_t *src,
int32_t height)
{
uint32_t loop_cnt;
- uint8_t *src_tmp;
+ const uint8_t *src_tmp;
int16_t *dst_tmp;
int32_t src_stride_2x = (src_stride << 1);
int32_t dst_stride_x = (dst_stride << 1);
@@ -3159,7 +3159,7 @@ static void hevc_hv_4t_12w_lsx(uint8_t *src,
}
}
-static void hevc_hv_4t_16w_lsx(uint8_t *src,
+static void hevc_hv_4t_16w_lsx(const uint8_t *src,
int32_t src_stride,
int16_t *dst,
int32_t dst_stride,
@@ -3176,7 +3176,7 @@ static void hevc_hv_4t_16w_lsx(uint8_t *src,
}
}
-static void hevc_hv_4t_24w_lsx(uint8_t *src,
+static void hevc_hv_4t_24w_lsx(const uint8_t *src,
int32_t src_stride,
int16_t *dst,
int32_t dst_stride,
@@ -3188,7 +3188,7 @@ static void hevc_hv_4t_24w_lsx(uint8_t *src,
filter_x, filter_y, height, 3);
}
-static void hevc_hv_4t_32w_lsx(uint8_t *src,
+static void hevc_hv_4t_32w_lsx(const uint8_t *src,
int32_t src_stride,
int16_t *dst,
int32_t dst_stride,
@@ -3202,7 +3202,7 @@ static void hevc_hv_4t_32w_lsx(uint8_t *src,
#define MC_COPY(WIDTH) \
void ff_hevc_put_hevc_pel_pixels##WIDTH##_8_lsx(int16_t *dst, \
- uint8_t *src, \
+ const uint8_t *src, \
ptrdiff_t src_stride, \
int height, \
intptr_t mx, \
@@ -3226,7 +3226,7 @@ MC_COPY(64);
#define MC(PEL, DIR, WIDTH, TAP, DIR1, FILT_DIR) \
void ff_hevc_put_hevc_##PEL##_##DIR##WIDTH##_8_lsx(int16_t *dst, \
- uint8_t *src, \
+ const uint8_t *src, \
ptrdiff_t src_stride, \
int height, \
intptr_t mx, \
@@ -3267,7 +3267,7 @@ MC(epel, v, 32, 4, vt, my);
#define MC_HV(PEL, WIDTH, TAP) \
void ff_hevc_put_hevc_##PEL##_hv##WIDTH##_8_lsx(int16_t *dst, \
- uint8_t *src, \
+ const uint8_t *src, \
ptrdiff_t src_stride, \
int height, \
intptr_t mx, \
diff --git a/libavcodec/loongarch/hevcdsp_lsx.h b/libavcodec/loongarch/hevcdsp_lsx.h
index 0c517af88..0d54196ca 100644
--- a/libavcodec/loongarch/hevcdsp_lsx.h
+++ b/libavcodec/loongarch/hevcdsp_lsx.h
@@ -27,7 +27,7 @@
#define MC(PEL, DIR, WIDTH) \
void ff_hevc_put_hevc_##PEL##_##DIR##WIDTH##_8_lsx(int16_t *dst, \
- uint8_t *src, \
+ const uint8_t *src, \
ptrdiff_t src_stride, \
int height, \
intptr_t mx, \
@@ -88,9 +88,9 @@ MC(epel, hv, 32);
#define BI_MC(PEL, DIR, WIDTH) \
void ff_hevc_put_hevc_bi_##PEL##_##DIR##WIDTH##_8_lsx(uint8_t *dst, \
ptrdiff_t dst_stride, \
- uint8_t *src, \
+ const uint8_t *src, \
ptrdiff_t src_stride, \
- int16_t *src_16bit, \
+ const int16_t *src_16bit, \
int height, \
intptr_t mx, \
intptr_t my, \
@@ -145,7 +145,7 @@ BI_MC(epel, hv, 32);
#define UNI_MC(PEL, DIR, WIDTH) \
void ff_hevc_put_hevc_uni_##PEL##_##DIR##WIDTH##_8_lsx(uint8_t *dst, \
ptrdiff_t dst_stride, \
- uint8_t *src, \
+ const uint8_t *src, \
ptrdiff_t src_stride, \
int height, \
intptr_t mx, \
@@ -181,7 +181,7 @@ UNI_MC(epel, hv, 32);
void ff_hevc_put_hevc_uni_w_##PEL##_##DIR##WIDTH##_8_lsx(uint8_t *dst, \
ptrdiff_t \
dst_stride, \
- uint8_t *src, \
+ const uint8_t *src, \
ptrdiff_t \
src_stride, \
int height, \
@@ -202,24 +202,24 @@ UNI_W_MC(qpel, hv, 64);
#undef UNI_W_MC
void ff_hevc_loop_filter_luma_h_8_lsx(uint8_t *src, ptrdiff_t stride,
- int32_t beta, int32_t *tc,
- uint8_t *p_is_pcm, uint8_t *q_is_pcm);
+ int32_t beta, const int32_t *tc,
+ const uint8_t *p_is_pcm, const uint8_t *q_is_pcm);
void ff_hevc_loop_filter_luma_v_8_lsx(uint8_t *src, ptrdiff_t stride,
- int32_t beta, int32_t *tc,
- uint8_t *p_is_pcm, uint8_t *q_is_pcm);
+ int32_t beta, const int32_t *tc,
+ const uint8_t *p_is_pcm, const uint8_t *q_is_pcm);
void ff_hevc_loop_filter_chroma_h_8_lsx(uint8_t *src, ptrdiff_t stride,
- int32_t *tc, uint8_t *p_is_pcm,
- uint8_t *q_is_pcm);
+ const int32_t *tc, const uint8_t *p_is_pcm,
+ const uint8_t *q_is_pcm);
void ff_hevc_loop_filter_chroma_v_8_lsx(uint8_t *src, ptrdiff_t stride,
- int32_t *tc, uint8_t *p_is_pcm,
- uint8_t *q_is_pcm);
+ const int32_t *tc, const uint8_t *p_is_pcm,
+ const uint8_t *q_is_pcm);
-void ff_hevc_sao_edge_filter_8_lsx(uint8_t *dst, uint8_t *src,
+void ff_hevc_sao_edge_filter_8_lsx(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride_dst,
- int16_t *sao_offset_val,
+ const int16_t *sao_offset_val,
int eo, int width, int height);
void ff_hevc_idct_4x4_lsx(int16_t *coeffs, int col_limit);
diff --git a/libavcodec/loongarch/vc1dsp_lasx.c b/libavcodec/loongarch/vc1dsp_lasx.c
index 40b8668f2..848fe4afb 100644
--- a/libavcodec/loongarch/vc1dsp_lasx.c
+++ b/libavcodec/loongarch/vc1dsp_lasx.c
@@ -698,7 +698,7 @@ PUT_VC1_MSPEL_MC_LASX(3, 2);
PUT_VC1_MSPEL_MC_LASX(3, 3);
void ff_put_no_rnd_vc1_chroma_mc8_lasx(uint8_t *dst /* align 8 */,
- uint8_t *src /* align 1 */,
+ const uint8_t *src /* align 1 */,
ptrdiff_t stride, int h, int x, int y)
{
const int intA = (8 - x) * (8 - y);
diff --git a/libavcodec/loongarch/vc1dsp_loongarch.h b/libavcodec/loongarch/vc1dsp_loongarch.h
index 398631aec..e5ccbcb76 100644
--- a/libavcodec/loongarch/vc1dsp_loongarch.h
+++ b/libavcodec/loongarch/vc1dsp_loongarch.h
@@ -73,7 +73,7 @@ FF_PUT_VC1_MSPEL_MC_H_LASX(2);
FF_PUT_VC1_MSPEL_MC_H_LASX(3);
void ff_put_no_rnd_vc1_chroma_mc8_lasx(uint8_t *dst /* align 8 */,
- uint8_t *src /* align 1 */,
+ const uint8_t *src /* align 1 */,
ptrdiff_t stride, int h, int x, int y);
#endif /* AVCODEC_LOONGARCH_VC1DSP_LOONGARCH_H */
diff --git a/libavcodec/loongarch/videodsp_init.c b/libavcodec/loongarch/videodsp_init.c
index 6cbb7763f..92ade4f84 100644
--- a/libavcodec/loongarch/videodsp_init.c
+++ b/libavcodec/loongarch/videodsp_init.c
@@ -22,7 +22,7 @@
#include "libavcodec/videodsp.h"
#include "libavutil/attributes.h"
-static void prefetch_loongarch(uint8_t *mem, ptrdiff_t stride, int h)
+static void prefetch_loongarch(const uint8_t *mem, ptrdiff_t stride, int h)
{
register const uint8_t *p = mem;
diff --git a/libavcodec/loongarch/vp8_mc_lsx.c b/libavcodec/loongarch/vp8_mc_lsx.c
index 80c4f87e8..034d84cc5 100644
--- a/libavcodec/loongarch/vp8_mc_lsx.c
+++ b/libavcodec/loongarch/vp8_mc_lsx.c
@@ -122,7 +122,7 @@ static const int8_t subpel_filters_lsx[7][8] = {
} )
void ff_put_vp8_epel8_h6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int height, int mx, int my)
{
uint32_t loop_cnt;
@@ -187,7 +187,7 @@ void ff_put_vp8_epel8_h6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
}
void ff_put_vp8_epel16_h6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int height, int mx, int my)
{
uint32_t loop_cnt;
@@ -241,7 +241,7 @@ void ff_put_vp8_epel16_h6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
}
void ff_put_vp8_epel8_v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int height, int mx, int my)
{
uint32_t loop_cnt;
@@ -308,7 +308,7 @@ void ff_put_vp8_epel8_v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
}
void ff_put_vp8_epel16_v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int height, int mx, int my)
{
uint32_t loop_cnt;
@@ -389,7 +389,7 @@ void ff_put_vp8_epel16_v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
}
void ff_put_vp8_epel8_h6v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int height, int mx, int my)
{
uint32_t loop_cnt;
@@ -491,7 +491,7 @@ void ff_put_vp8_epel8_h6v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
}
void ff_put_vp8_epel16_h6v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int height, int mx, int my)
{
int32_t multiple8_cnt;
@@ -504,7 +504,7 @@ void ff_put_vp8_epel16_h6v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
}
void ff_put_vp8_epel8_v4_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int height, int mx, int my)
{
uint32_t loop_cnt;
@@ -561,7 +561,7 @@ void ff_put_vp8_epel8_v4_lsx(uint8_t *dst, ptrdiff_t dst_stride,
}
void ff_put_vp8_epel16_v4_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int height, int mx, int my)
{
uint32_t loop_cnt;
@@ -631,7 +631,7 @@ void ff_put_vp8_epel16_v4_lsx(uint8_t *dst, ptrdiff_t dst_stride,
}
void ff_put_vp8_epel8_h6v4_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int height, int mx, int my)
{
uint32_t loop_cnt;
@@ -714,7 +714,7 @@ void ff_put_vp8_epel8_h6v4_lsx(uint8_t *dst, ptrdiff_t dst_stride,
}
void ff_put_vp8_epel16_h6v4_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int height, int mx, int my)
{
int32_t multiple8_cnt;
@@ -728,7 +728,7 @@ void ff_put_vp8_epel16_h6v4_lsx(uint8_t *dst, ptrdiff_t dst_stride,
}
void ff_put_vp8_epel8_h4v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int height, int mx, int my)
{
uint32_t loop_cnt;
@@ -818,7 +818,7 @@ void ff_put_vp8_epel8_h4v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
}
void ff_put_vp8_epel16_h4v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int height, int mx, int my)
{
int32_t multiple8_cnt;
@@ -832,7 +832,7 @@ void ff_put_vp8_epel16_h4v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
}
void ff_put_vp8_pixels8_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int height, int mx, int my)
{
int32_t cnt;
@@ -889,12 +889,13 @@ void ff_put_vp8_pixels8_lsx(uint8_t *dst, ptrdiff_t dst_stride,
}
void ff_put_vp8_pixels16_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int height, int mx, int my)
{
int32_t width = 16;
int32_t cnt, loop_cnt;
- uint8_t *src_tmp, *dst_tmp;
+ const uint8_t *src_tmp;
+ uint8_t *dst_tmp;
__m128i src0, src1, src2, src3, src4, src5, src6, src7;
ptrdiff_t src_stride2 = src_stride << 1;
diff --git a/libavcodec/loongarch/vp8dsp_loongarch.h b/libavcodec/loongarch/vp8dsp_loongarch.h
index 87e9509db..09c7e1f91 100644
--- a/libavcodec/loongarch/vp8dsp_loongarch.h
+++ b/libavcodec/loongarch/vp8dsp_loongarch.h
@@ -25,49 +25,49 @@
#include "libavcodec/vp8dsp.h"
void ff_put_vp8_pixels8_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int h, int x, int y);
void ff_put_vp8_pixels16_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int h, int x, int y);
void ff_put_vp8_epel16_h6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int h, int mx, int my);
void ff_put_vp8_epel16_v4_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int h, int mx, int my);
void ff_put_vp8_epel16_v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int h, int mx, int my);
void ff_put_vp8_epel16_h6v4_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int h, int mx, int my);
void ff_put_vp8_epel16_h4v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int h, int mx, int my);
void ff_put_vp8_epel16_h6v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int h, int mx, int my);
void ff_put_vp8_epel8_v4_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int h, int mx, int my);
void ff_put_vp8_epel8_v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int h, int mx, int my);
void ff_put_vp8_epel8_h6v4_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int h, int mx, int my);
void ff_put_vp8_epel8_h4v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int h, int mx, int my);
void ff_put_vp8_epel8_h6v6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int h, int mx, int my);
void ff_put_vp8_epel8_h6_lsx(uint8_t *dst, ptrdiff_t dst_stride,
- uint8_t *src, ptrdiff_t src_stride,
+ const uint8_t *src, ptrdiff_t src_stride,
int h, int mx, int my);
/* loop filter */
diff --git a/libavcodec/loongarch/vp9dsp_loongarch.h b/libavcodec/loongarch/vp9dsp_loongarch.h
index 3cc918a18..9fe4294d5 100644
--- a/libavcodec/loongarch/vp9dsp_loongarch.h
+++ b/libavcodec/loongarch/vp9dsp_loongarch.h
@@ -22,6 +22,9 @@
#ifndef AVCODEC_LOONGARCH_VP9DSP_LOONGARCH_H
#define AVCODEC_LOONGARCH_VP9DSP_LOONGARCH_H
+#include
+#include
+
#define VP9_8TAP_LOONGARCH_LSX_FUNC(SIZE, type, type_idx) \
void ff_put_8tap_##type##_##SIZE##h_lsx(uint8_t *dst, ptrdiff_t dststride, \
const uint8_t *src, \
diff --git a/libavcodec/lossless_videoencdsp.c b/libavcodec/lossless_videoencdsp.c
index e0b78bb3d..b4130ebc7 100644
--- a/libavcodec/lossless_videoencdsp.c
+++ b/libavcodec/lossless_videoencdsp.c
@@ -74,7 +74,7 @@ static void sub_median_pred_c(uint8_t *dst, const uint8_t *src1,
*left_top = lt;
}
-static void sub_left_predict_c(uint8_t *dst, uint8_t *src,
+static void sub_left_predict_c(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, ptrdiff_t width, int height)
{
int i, j;
diff --git a/libavcodec/lossless_videoencdsp.h b/libavcodec/lossless_videoencdsp.h
index 7794f03e3..f2c287848 100644
--- a/libavcodec/lossless_videoencdsp.h
+++ b/libavcodec/lossless_videoencdsp.h
@@ -35,7 +35,7 @@ typedef struct LLVidEncDSPContext {
const uint8_t *src2, intptr_t w,
int *left, int *left_top);
- void (*sub_left_predict)(uint8_t *dst, uint8_t *src,
+ void (*sub_left_predict)(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, ptrdiff_t width, int height);
} LLVidEncDSPContext;
diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c
index 3238ad5fc..dc6a3060c 100644
--- a/libavcodec/lpc.c
+++ b/libavcodec/lpc.c
@@ -31,13 +31,18 @@
/**
* Apply Welch window function to audio block
*/
-static void lpc_apply_welch_window_c(const int32_t *data, int len,
+static void lpc_apply_welch_window_c(const int32_t *data, ptrdiff_t len,
double *w_data)
{
int i, n2;
double w;
double c;
+ if (len == 1) {
+ w_data[0] = 0.0;
+ return;
+ }
+
n2 = (len >> 1);
c = 2.0 / (len - 1.0);
@@ -48,6 +53,7 @@ static void lpc_apply_welch_window_c(const int32_t *data, int len,
w_data[i] = data[i] * w;
w_data[len-1-i] = data[len-1-i] * w;
}
+ w_data[n2] = 0.0;
return;
}
@@ -65,7 +71,7 @@ static void lpc_apply_welch_window_c(const int32_t *data, int len,
* Calculate autocorrelation data from audio samples
* A Welch window function is applied before calculation.
*/
-static void lpc_compute_autocorr_c(const double *data, int len, int lag,
+static void lpc_compute_autocorr_c(const double *data, ptrdiff_t len, int lag,
double *autoc)
{
int i, j;
diff --git a/libavcodec/lpc.h b/libavcodec/lpc.h
index e1b41bfd9..467d0b283 100644
--- a/libavcodec/lpc.h
+++ b/libavcodec/lpc.h
@@ -23,6 +23,7 @@
#define AVCODEC_LPC_H
#include
+#include
#include "libavutil/avassert.h"
#include "libavutil/lls.h"
#include "aac_defines.h"
@@ -64,7 +65,7 @@ typedef struct LPCContext {
* @param len number of input samples
* @param w_data output samples
*/
- void (*lpc_apply_welch_window)(const int32_t *data, int len,
+ void (*lpc_apply_welch_window)(const int32_t *data, ptrdiff_t len,
double *w_data);
/**
* Perform autocorrelation on input samples with delay of 0 to lag.
@@ -79,7 +80,7 @@ typedef struct LPCContext {
* @param autoc output autocorrelation coefficients.
* constraints: array size must be at least lag+1.
*/
- void (*lpc_compute_autocorr)(const double *data, int len, int lag,
+ void (*lpc_compute_autocorr)(const double *data, ptrdiff_t len, int lag,
double *autoc);
// TODO: these should be allocated to reduce ABI compatibility issues
diff --git a/libavcodec/lscrdec.c b/libavcodec/lscrdec.c
index 9e7010c28..76a46751f 100644
--- a/libavcodec/lscrdec.c
+++ b/libavcodec/lscrdec.c
@@ -29,7 +29,7 @@
#include "bytestream.h"
#include "codec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "packet.h"
#include "png.h"
#include "pngdsp.h"
@@ -246,7 +246,7 @@ static void lscr_decode_flush(AVCodecContext *avctx)
const FFCodec ff_lscr_decoder = {
.p.name = "lscr",
- .p.long_name = NULL_IF_CONFIG_SMALL("LEAD Screen Capture"),
+ CODEC_LONG_NAME("LEAD Screen Capture"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_LSCR,
.p.capabilities = AV_CODEC_CAP_DR1,
@@ -255,5 +255,5 @@ const FFCodec ff_lscr_decoder = {
.close = lscr_decode_close,
FF_CODEC_DECODE_CB(decode_frame_lscr),
.flush = lscr_decode_flush,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/lsp.c b/libavcodec/lsp.c
index 90f2efaaf..275984097 100644
--- a/libavcodec/lsp.c
+++ b/libavcodec/lsp.c
@@ -23,11 +23,15 @@
#include
+#include "config.h"
+
#define FRAC_BITS 14
#include "libavutil/macros.h"
#include "mathops.h"
#include "lsp.h"
+#if ARCH_MIPS
#include "libavcodec/mips/lsp_mips.h"
+#endif /* ARCH_MIPS */
#include "libavutil/avassert.h"
void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, int lsfq_max, int lp_order)
@@ -120,6 +124,32 @@ static void lsp2poly(int* f, const int16_t* lsp, int lp_half_order)
}
}
+#ifndef lsp2polyf
+/**
+ * Compute the Pa / (1 + z(-1)) or Qa / (1 - z(-1)) coefficients
+ * needed for LSP to LPC conversion.
+ * We only need to calculate the 6 first elements of the polynomial.
+ *
+ * @param lsp line spectral pairs in cosine domain
+ * @param[out] f polynomial input/output as a vector
+ *
+ * TIA/EIA/IS-733 2.4.3.3.5-1/2
+ */
+static void lsp2polyf(const double *lsp, double *f, int lp_half_order)
+{
+ f[0] = 1.0;
+ f[1] = -2 * lsp[0];
+ lsp -= 2;
+ for (int i = 2; i <= lp_half_order; i++) {
+ double val = -2 * lsp[2*i];
+ f[i] = val * f[i-1] + 2*f[i-2];
+ for (int j = i-1; j > 1; j--)
+ f[j] += f[j-1] * val + f[j-2];
+ f[1] += val;
+ }
+}
+#endif /* lsp2polyf */
+
void ff_acelp_lsp2lpc(int16_t* lp, const int16_t* lsp, int lp_half_order)
{
int i;
@@ -152,8 +182,8 @@ void ff_amrwb_lsp2lpc(const double *lsp, float *lp, int lp_order)
qa[-1] = 0.0;
- ff_lsp2polyf(lsp , pa, lp_half_order );
- ff_lsp2polyf(lsp + 1, qa, lp_half_order - 1);
+ lsp2polyf(lsp , pa, lp_half_order );
+ lsp2polyf(lsp + 1, qa, lp_half_order - 1);
for (i = 1, j = lp_order - 1; i < lp_half_order; i++, j--) {
double paf = pa[i] * (1 + lsp[lp_order - 1]);
@@ -187,25 +217,6 @@ void ff_acelp_lp_decode(int16_t* lp_1st, int16_t* lp_2nd, const int16_t* lsp_2nd
ff_acelp_lsp2lpc(lp_2nd, lsp_2nd, lp_order >> 1);
}
-#ifndef ff_lsp2polyf
-void ff_lsp2polyf(const double *lsp, double *f, int lp_half_order)
-{
- int i, j;
-
- f[0] = 1.0;
- f[1] = -2 * lsp[0];
- lsp -= 2;
- for(i=2; i<=lp_half_order; i++)
- {
- double val = -2 * lsp[2*i];
- f[i] = val * f[i-1] + 2*f[i-2];
- for(j=i-1; j>1; j--)
- f[j] += f[j-1] * val + f[j-2];
- f[1] += val;
- }
-}
-#endif /* ff_lsp2polyf */
-
void ff_acelp_lspd2lpc(const double *lsp, float *lpc, int lp_half_order)
{
double pa[MAX_LP_HALF_ORDER+1], qa[MAX_LP_HALF_ORDER+1];
@@ -213,8 +224,8 @@ void ff_acelp_lspd2lpc(const double *lsp, float *lpc, int lp_half_order)
av_assert2(lp_half_order <= MAX_LP_HALF_ORDER);
- ff_lsp2polyf(lsp, pa, lp_half_order);
- ff_lsp2polyf(lsp + 1, qa, lp_half_order);
+ lsp2polyf(lsp, pa, lp_half_order);
+ lsp2polyf(lsp + 1, qa, lp_half_order);
while (lp_half_order--) {
double paf = pa[lp_half_order+1] + pa[lp_half_order];
diff --git a/libavcodec/lsp.h b/libavcodec/lsp.h
index 621ebeaeb..26b1382ed 100644
--- a/libavcodec/lsp.h
+++ b/libavcodec/lsp.h
@@ -115,16 +115,4 @@ void ff_acelp_lspd2lpc(const double *lsp, float *lpc, int lp_half_order);
*/
void ff_sort_nearly_sorted_floats(float *vals, int len);
-/**
- * Compute the Pa / (1 + z(-1)) or Qa / (1 - z(-1)) coefficients
- * needed for LSP to LPC conversion.
- * We only need to calculate the 6 first elements of the polynomial.
- *
- * @param lsp line spectral pairs in cosine domain
- * @param[out] f polynomial input/output as a vector
- *
- * TIA/EIA/IS-733 2.4.3.3.5-1/2
- */
-void ff_lsp2polyf(const double *lsp, double *f, int lp_half_order);
-
#endif /* AVCODEC_LSP_H */
diff --git a/libavcodec/m101.c b/libavcodec/m101.c
index fce31956c..3def577b7 100644
--- a/libavcodec/m101.c
+++ b/libavcodec/m101.c
@@ -22,7 +22,7 @@
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
static av_cold int m101_decode_init(AVCodecContext *avctx)
@@ -53,11 +53,6 @@ static int m101_decode_frame(AVCodecContext *avctx, AVFrame *frame,
int min_stride = 2 * avctx->width;
int bits = avctx->extradata[2*4];
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
- frame->pict_type = AV_PICTURE_TYPE_I;
- frame->key_frame = 1;
-
stride = AV_RL32(avctx->extradata + 5*4);
if (avctx->pix_fmt == AV_PIX_FMT_YUV422P10)
@@ -69,6 +64,10 @@ static int m101_decode_frame(AVCodecContext *avctx, AVFrame *frame,
return AVERROR_INVALIDDATA;
}
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+ frame->pict_type = AV_PICTURE_TYPE_I;
+ frame->key_frame = 1;
frame->interlaced_frame = ((avctx->extradata[3*4] & 3) != 3);
if (frame->interlaced_frame)
frame->top_field_first = avctx->extradata[3*4] & 1;
@@ -107,11 +106,10 @@ static int m101_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_m101_decoder = {
.p.name = "m101",
- .p.long_name = NULL_IF_CONFIG_SMALL("Matrox Uncompressed SD"),
+ CODEC_LONG_NAME("Matrox Uncompressed SD"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_M101,
.init = m101_decode_init,
FF_CODEC_DECODE_CB(m101_decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/mace.c b/libavcodec/mace.c
index 110b32003..a35291330 100644
--- a/libavcodec/mace.c
+++ b/libavcodec/mace.c
@@ -26,7 +26,7 @@
#include "avcodec.h"
#include "codec_internal.h"
-#include "internal.h"
+#include "decode.h"
#include "libavutil/common.h"
/*
@@ -286,7 +286,7 @@ static int mace_decode_frame(AVCodecContext *avctx, AVFrame *frame,
const FFCodec ff_mace3_decoder = {
.p.name = "mace3",
- .p.long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 3:1"),
+ CODEC_LONG_NAME("MACE (Macintosh Audio Compression/Expansion) 3:1"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_MACE3,
.priv_data_size = sizeof(MACEContext),
@@ -295,12 +295,11 @@ const FFCodec ff_mace3_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
const FFCodec ff_mace6_decoder = {
.p.name = "mace6",
- .p.long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 6:1"),
+ CODEC_LONG_NAME("MACE (Macintosh Audio Compression/Expansion) 6:1"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_MACE6,
.priv_data_size = sizeof(MACEContext),
@@ -309,5 +308,4 @@ const FFCodec ff_mace6_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_NONE },
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/magicyuv.c b/libavcodec/magicyuv.c
index 634d45ca4..62263409b 100644
--- a/libavcodec/magicyuv.c
+++ b/libavcodec/magicyuv.c
@@ -29,9 +29,8 @@
#include "avcodec.h"
#include "bytestream.h"
#include "codec_internal.h"
+#include "decode.h"
#include "get_bits.h"
-#include "huffyuvdsp.h"
-#include "internal.h"
#include "lossless_videodsp.h"
#include "thread.h"
@@ -115,7 +114,7 @@ static void magicyuv_median_pred16(uint16_t *dst, const uint16_t *src1,
static int magy_decode_slice10(AVCodecContext *avctx, void *tdata,
int j, int threadnr)
{
- MagicYUVContext *s = avctx->priv_data;
+ const MagicYUVContext *s = avctx->priv_data;
int interlaced = s->interlaced;
const int bps = s->bps;
const int max = s->max - 1;
@@ -247,7 +246,7 @@ static int magy_decode_slice10(AVCodecContext *avctx, void *tdata,
static int magy_decode_slice(AVCodecContext *avctx, void *tdata,
int j, int threadnr)
{
- MagicYUVContext *s = avctx->priv_data;
+ const MagicYUVContext *s = avctx->priv_data;
int interlaced = s->interlaced;
AVFrame *p = s->p;
int i, k, x, min_width;
@@ -695,7 +694,7 @@ static av_cold int magy_decode_end(AVCodecContext *avctx)
const FFCodec ff_magicyuv_decoder = {
.p.name = "magicyuv",
- .p.long_name = NULL_IF_CONFIG_SMALL("MagicYUV video"),
+ CODEC_LONG_NAME("MagicYUV video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_MAGICYUV,
.priv_data_size = sizeof(MagicYUVContext),
@@ -705,5 +704,4 @@ const FFCodec ff_magicyuv_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_FRAME_THREADS |
AV_CODEC_CAP_SLICE_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};
diff --git a/libavcodec/magicyuvenc.c b/libavcodec/magicyuvenc.c
index ce492368e..9e41c1b0f 100644
--- a/libavcodec/magicyuvenc.c
+++ b/libavcodec/magicyuvenc.c
@@ -458,11 +458,12 @@ static int magy_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
}
if (s->correlate) {
- uint8_t *r, *g, *b, *decorrelated[2] = { s->decorrelate_buf[0],
+ uint8_t *decorrelated[2] = { s->decorrelate_buf[0],
s->decorrelate_buf[1] };
const int decorrelate_linesize = FFALIGN(width, 16);
const uint8_t *const data[4] = { decorrelated[0], frame->data[0],
decorrelated[1], frame->data[3] };
+ const uint8_t *r, *g, *b;
const int linesize[4] = { decorrelate_linesize, frame->linesize[0],
decorrelate_linesize, frame->linesize[3] };
@@ -565,19 +566,20 @@ static const AVClass magicyuv_class = {
const FFCodec ff_magicyuv_encoder = {
.p.name = "magicyuv",
- .p.long_name = NULL_IF_CONFIG_SMALL("MagicYUV video"),
+ CODEC_LONG_NAME("MagicYUV video"),
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_MAGICYUV,
+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_data_size = sizeof(MagicYUVContext),
.p.priv_class = &magicyuv_class,
.init = magy_encode_init,
.close = magy_encode_close,
FF_CODEC_ENCODE_CB(magy_encode_frame),
- .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
.p.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_YUV422P,
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_GRAY8,
AV_PIX_FMT_NONE
},
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
diff --git a/libavcodec/mathops.h b/libavcodec/mathops.h
index f81d21f9c..a1dc32330 100644
--- a/libavcodec/mathops.h
+++ b/libavcodec/mathops.h
@@ -24,6 +24,7 @@
#include
+#include "libavutil/attributes_internal.h"
#include "libavutil/common.h"
#include "config.h"
@@ -32,7 +33,7 @@
extern const uint32_t ff_inverse[257];
extern const uint8_t ff_log2_run[41];
extern const uint8_t ff_sqrt_tab[256];
-extern const uint8_t ff_crop_tab[256 + 2 * MAX_NEG_CROP];
+extern const uint8_t attribute_visibility_hidden ff_crop_tab[256 + 2 * MAX_NEG_CROP];
extern const uint8_t ff_zigzag_direct[64];
extern const uint8_t ff_zigzag_scan[16+1];
@@ -137,6 +138,15 @@ static inline av_const int sign_extend(int val, unsigned bits)
}
#endif
+#ifndef sign_extend64
+static inline av_const int64_t sign_extend64(int64_t val, unsigned bits)
+{
+ unsigned shift = 8 * sizeof(int64_t) - bits;
+ union { uint64_t u; int64_t s; } v = { (uint64_t) val << shift };
+ return v.s >> shift;
+}
+#endif
+
#ifndef zero_extend
static inline av_const unsigned zero_extend(unsigned val, unsigned bits)
{
diff --git a/libavcodec/mdct15.c b/libavcodec/mdct15.c
deleted file mode 100644
index f8ed74d15..000000000
--- a/libavcodec/mdct15.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (c) 2013-2014 Mozilla Corporation
- * Copyright (c) 2017 Rostislav Pehlivanov
- *
- * 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
- * Celt non-power of 2 iMDCT
- */
-
-#include
-#include
-#include
-#include