1
0
This repository has been archived on 2024-11-10. You can view files and clone it, but cannot push or open issues or pull requests.
Lakka-rk322x/packages/multimedia/ffmpeg/patches/L4T/ffmpeg-4.3.2-add-nvv4l-encoder-decoder.patch
GavinDarkglider c4f65eb837 Lakka L4T/Switch Changes for v4.1 (#1644)
* Switch: Use versions of these firmwares supplied by kernel install

* Switch: Update kernel to latest

* Backup old uenv.txt on update.

* Update L4T ffmpeg patches
2022-03-24 16:14:15 +01:00

18073 lines
629 KiB
Diff

diff -Naur ffmpeg-4.3.2-Matrix-19.1/configure ffmpeg-4.3.2-Matrix-19.1-2/configure
--- ffmpeg-4.3.2-Matrix-19.1/configure 2022-03-07 22:55:07.872422837 +0100
+++ ffmpeg-4.3.2-Matrix-19.1-2/configure 2022-03-20 03:34:12.674191538 +0100
@@ -330,6 +330,7 @@
--enable-cuda-nvcc enable Nvidia CUDA compiler [no]
--disable-cuda-llvm disable CUDA compilation using clang [autodetect]
--disable-cuvid disable Nvidia CUVID support [autodetect]
+ --enable-nvv4l2 enable Nvidia Tegra NVV4L2 support [no]
--disable-d3d11va disable Microsoft Direct3D 11 video acceleration code [autodetect]
--disable-dxva2 disable Microsoft DirectX 9 video acceleration code [autodetect]
--disable-ffnvcodec disable dynamically linked Nvidia code [autodetect]
@@ -1839,6 +1840,7 @@
ffnvcodec
nvdec
nvenc
+ nvv4l2
vaapi
vdpau
videotoolbox
@@ -3039,7 +3041,8 @@
qsvvpp_select="qsv"
vaapi_encode_deps="vaapi"
v4l2_m2m_deps="linux_videodev2_h sem_timedwait"
-
+nvv4l2_deps="pthreads"
+nvv4l2_extralibs="-lnvbuf_utils -lv4l2"
hwupload_cuda_filter_deps="ffnvcodec"
scale_npp_filter_deps="ffnvcodec libnpp"
scale_cuda_filter_deps="ffnvcodec"
@@ -3054,6 +3057,9 @@
nvenc_deps="ffnvcodec"
nvenc_deps_any="libdl LoadLibrary"
nvenc_encoder_deps="nvenc"
+h264_nvv4l2_encoder_deps="nvv4l2"
+h264_nvv4l2_decoder_deps="nvv4l2"
+h264_nvv4l2_decoder_select="h264_mp4toannexb_bsf"
aac_mf_encoder_deps="mediafoundation"
ac3_mf_encoder_deps="mediafoundation"
@@ -3084,6 +3090,9 @@
hevc_mediacodec_decoder_select="hevc_mp4toannexb_bsf hevc_parser"
hevc_mf_encoder_deps="mediafoundation"
hevc_nvenc_encoder_deps="nvenc"
+hevc_nvv4l2_encoder_deps="nvv4l2"
+hevc_nvv4l2_decoder_deps="nvv4l2"
+hevc_nvv4l2_decoder_select="hevc_mp4toannexb_bsf"
hevc_qsv_decoder_select="hevc_mp4toannexb_bsf qsvdec"
hevc_qsv_encoder_select="hevcparse qsvenc"
hevc_rkmpp_decoder_deps="rkmpp"
@@ -3106,6 +3115,7 @@
mpeg2_cuvid_decoder_deps="cuvid"
mpeg2_mmal_decoder_deps="mmal"
mpeg2_mediacodec_decoder_deps="mediacodec"
+mpeg2_nvv4l2_decoder_deps="nvv4l2"
mpeg2_qsv_decoder_select="qsvdec"
mpeg2_qsv_encoder_select="qsvenc"
mpeg2_vaapi_encoder_select="cbs_mpeg2 vaapi_encode"
@@ -3114,6 +3124,7 @@
mpeg4_cuvid_decoder_deps="cuvid"
mpeg4_mediacodec_decoder_deps="mediacodec"
mpeg4_mmal_decoder_deps="mmal"
+mpeg4_nvv4l2_decoder_deps="nvv4l2"
mpeg4_omx_encoder_deps="omx"
mpeg4_v4l2m2m_decoder_deps="v4l2_m2m mpeg4_v4l2_m2m"
mpeg4_v4l2m2m_encoder_deps="v4l2_m2m mpeg4_v4l2_m2m"
@@ -3127,6 +3138,7 @@
vc1_v4l2m2m_decoder_deps="v4l2_m2m vc1_v4l2_m2m"
vp8_cuvid_decoder_deps="cuvid"
vp8_mediacodec_decoder_deps="mediacodec"
+vp8_nvv4l2_decoder_deps="nvv4l2"
vp8_qsv_decoder_select="qsvdec"
vp8_rkmpp_decoder_deps="rkmpp"
vp8_vaapi_encoder_deps="VAEncPictureParameterBufferVP8"
@@ -3135,6 +3147,7 @@
vp8_v4l2m2m_encoder_deps="v4l2_m2m vp8_v4l2_m2m"
vp9_cuvid_decoder_deps="cuvid"
vp9_mediacodec_decoder_deps="mediacodec"
+vp9_nvv4l2_decoder_deps="nvv4l2"
vp9_qsv_decoder_select="qsvdec"
vp9_rkmpp_decoder_deps="rkmpp"
vp9_vaapi_encoder_deps="VAEncPictureParameterBufferVP9"
@@ -3404,6 +3417,7 @@
lavfi_indev_deps="avfilter"
libcdio_indev_deps="libcdio"
libdc1394_indev_deps="libdc1394"
+nvv4l2_indev_deps="v4l2"
openal_indev_deps="openal"
opengl_outdev_deps="opengl"
opengl_outdev_suggest="sdl2"
@@ -6741,6 +6755,8 @@
int main(void) { return 0; }
EOF
+enabled nvv4l2 && add_ldflags "-L/usr/lib/aarch64-linux-gnu/tegra"
+
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"
diff -Naur ffmpeg-4.3.2-Matrix-19.1/configure.orig ffmpeg-4.3.2-Matrix-19.1-2/configure.orig
--- ffmpeg-4.3.2-Matrix-19.1/configure.orig 2022-03-07 22:55:02.276300867 +0100
+++ ffmpeg-4.3.2-Matrix-19.1-2/configure.orig 1970-01-01 01:00:00.000000000 +0100
@@ -1,7680 +0,0 @@
-#!/bin/sh
-#
-# FFmpeg configure script
-#
-# Copyright (c) 2000-2002 Fabrice Bellard
-# Copyright (c) 2005-2008 Diego Biurrun
-# Copyright (c) 2005-2008 Mans Rullgard
-#
-
-# Prevent locale nonsense from breaking basic text processing.
-LC_ALL=C
-export LC_ALL
-
-# make sure we are running under a compatible shell
-# try to make this part work with most shells
-
-try_exec(){
- echo "Trying shell $1"
- type "$1" > /dev/null 2>&1 && exec "$@"
-}
-
-unset foo
-(: ${foo%%bar}) 2> /dev/null
-E1="$?"
-
-(: ${foo?}) 2> /dev/null
-E2="$?"
-
-if test "$E1" != 0 || test "$E2" = 0; then
- echo "Broken shell detected. Trying alternatives."
- export FF_CONF_EXEC
- if test "0$FF_CONF_EXEC" -lt 1; then
- FF_CONF_EXEC=1
- try_exec bash "$0" "$@"
- fi
- if test "0$FF_CONF_EXEC" -lt 2; then
- FF_CONF_EXEC=2
- try_exec ksh "$0" "$@"
- fi
- if test "0$FF_CONF_EXEC" -lt 3; then
- FF_CONF_EXEC=3
- try_exec /usr/xpg4/bin/sh "$0" "$@"
- fi
- echo "No compatible shell script interpreter found."
- echo "This configure script requires a POSIX-compatible shell"
- echo "such as bash or ksh."
- echo "THIS IS NOT A BUG IN FFMPEG, DO NOT REPORT IT AS SUCH."
- echo "Instead, install a working POSIX-compatible shell."
- echo "Disabling this configure test will create a broken FFmpeg."
- if test "$BASH_VERSION" = '2.04.0(1)-release'; then
- echo "This bash version ($BASH_VERSION) is broken on your platform."
- echo "Upgrade to a later version if available."
- fi
- exit 1
-fi
-
-test -d /usr/xpg4/bin && PATH=/usr/xpg4/bin:$PATH
-
-show_help(){
- cat <<EOF
-Usage: configure [options]
-Options: [defaults in brackets after descriptions]
-
-Help options:
- --help print this message
- --quiet Suppress showing informative output
- --list-decoders show all available decoders
- --list-encoders show all available encoders
- --list-hwaccels show all available hardware accelerators
- --list-demuxers show all available demuxers
- --list-muxers show all available muxers
- --list-parsers show all available parsers
- --list-protocols show all available protocols
- --list-bsfs show all available bitstream filters
- --list-indevs show all available input devices
- --list-outdevs show all available output devices
- --list-filters show all available filters
-
-Standard options:
- --logfile=FILE log tests and output to FILE [ffbuild/config.log]
- --disable-logging do not log configure debug information
- --fatal-warnings fail if any configure warning is generated
- --prefix=PREFIX install in PREFIX [$prefix_default]
- --bindir=DIR install binaries in DIR [PREFIX/bin]
- --datadir=DIR install data files in DIR [PREFIX/share/ffmpeg]
- --docdir=DIR install documentation in DIR [PREFIX/share/doc/ffmpeg]
- --libdir=DIR install libs in DIR [PREFIX/lib]
- --shlibdir=DIR install shared libs in DIR [LIBDIR]
- --incdir=DIR install includes in DIR [PREFIX/include]
- --mandir=DIR install man page in DIR [PREFIX/share/man]
- --pkgconfigdir=DIR install pkg-config files in DIR [LIBDIR/pkgconfig]
- --enable-rpath use rpath to allow installing libraries in paths
- not part of the dynamic linker search path
- use rpath when linking programs (USE WITH CARE)
- --install-name-dir=DIR Darwin directory name for installed targets
-
-Licensing options:
- --enable-gpl allow use of GPL code, the resulting libs
- and binaries will be under GPL [no]
- --enable-version3 upgrade (L)GPL to version 3 [no]
- --enable-nonfree allow use of nonfree code, the resulting libs
- and binaries will be unredistributable [no]
-
-Configuration options:
- --disable-static do not build static libraries [no]
- --enable-shared build shared libraries [no]
- --enable-small optimize for size instead of speed
- --disable-runtime-cpudetect disable detecting CPU capabilities at runtime (smaller binary)
- --enable-gray enable full grayscale support (slower color)
- --disable-swscale-alpha disable alpha channel support in swscale
- --disable-all disable building components, libraries and programs
- --disable-autodetect disable automatically detected external libraries [no]
-
-Program options:
- --disable-programs do not build command line programs
- --disable-ffmpeg disable ffmpeg build
- --disable-ffplay disable ffplay build
- --disable-ffprobe disable ffprobe build
-
-Documentation options:
- --disable-doc do not build documentation
- --disable-htmlpages do not build HTML documentation pages
- --disable-manpages do not build man documentation pages
- --disable-podpages do not build POD documentation pages
- --disable-txtpages do not build text documentation pages
-
-Component options:
- --disable-avdevice disable libavdevice build
- --disable-avcodec disable libavcodec build
- --disable-avformat disable libavformat build
- --disable-swresample disable libswresample build
- --disable-swscale disable libswscale build
- --disable-postproc disable libpostproc build
- --disable-avfilter disable libavfilter build
- --enable-avresample enable libavresample build (deprecated) [no]
- --disable-pthreads disable pthreads [autodetect]
- --disable-w32threads disable Win32 threads [autodetect]
- --disable-os2threads disable OS/2 threads [autodetect]
- --disable-network disable network support [no]
- --disable-dct disable DCT code
- --disable-dwt disable DWT code
- --disable-error-resilience disable error resilience code
- --disable-lsp disable LSP code
- --disable-lzo disable LZO decoder code
- --disable-mdct disable MDCT code
- --disable-rdft disable RDFT code
- --disable-fft disable FFT code
- --disable-faan disable floating point AAN (I)DCT code
- --disable-pixelutils disable pixel utils in libavutil
-
-Individual component options:
- --disable-everything disable all components listed below
- --disable-encoder=NAME disable encoder NAME
- --enable-encoder=NAME enable encoder NAME
- --disable-encoders disable all encoders
- --disable-decoder=NAME disable decoder NAME
- --enable-decoder=NAME enable decoder NAME
- --disable-decoders disable all decoders
- --disable-hwaccel=NAME disable hwaccel NAME
- --enable-hwaccel=NAME enable hwaccel NAME
- --disable-hwaccels disable all hwaccels
- --disable-muxer=NAME disable muxer NAME
- --enable-muxer=NAME enable muxer NAME
- --disable-muxers disable all muxers
- --disable-demuxer=NAME disable demuxer NAME
- --enable-demuxer=NAME enable demuxer NAME
- --disable-demuxers disable all demuxers
- --enable-parser=NAME enable parser NAME
- --disable-parser=NAME disable parser NAME
- --disable-parsers disable all parsers
- --enable-bsf=NAME enable bitstream filter NAME
- --disable-bsf=NAME disable bitstream filter NAME
- --disable-bsfs disable all bitstream filters
- --enable-protocol=NAME enable protocol NAME
- --disable-protocol=NAME disable protocol NAME
- --disable-protocols disable all protocols
- --enable-indev=NAME enable input device NAME
- --disable-indev=NAME disable input device NAME
- --disable-indevs disable input devices
- --enable-outdev=NAME enable output device NAME
- --disable-outdev=NAME disable output device NAME
- --disable-outdevs disable output devices
- --disable-devices disable all devices
- --enable-filter=NAME enable filter NAME
- --disable-filter=NAME disable filter NAME
- --disable-filters disable all filters
-
-External library support:
-
- Using any of the following switches will allow FFmpeg to link to the
- corresponding external library. All the components depending on that library
- will become enabled, if all their other dependencies are met and they are not
- explicitly disabled. E.g. --enable-libwavpack will enable linking to
- libwavpack and allow the libwavpack encoder to be built, unless it is
- specifically disabled with --disable-encoder=libwavpack.
-
- Note that only the system libraries are auto-detected. All the other external
- libraries must be explicitly enabled.
-
- Also note that the following help text describes the purpose of the libraries
- themselves, not all their features will necessarily be usable by FFmpeg.
-
- --disable-alsa disable ALSA support [autodetect]
- --disable-appkit disable Apple AppKit framework [autodetect]
- --disable-avfoundation disable Apple AVFoundation framework [autodetect]
- --enable-avisynth enable reading of AviSynth script files [no]
- --disable-bzlib disable bzlib [autodetect]
- --disable-coreimage disable Apple CoreImage framework [autodetect]
- --enable-chromaprint enable audio fingerprinting with chromaprint [no]
- --enable-frei0r enable frei0r video filtering [no]
- --enable-gcrypt enable gcrypt, needed for rtmp(t)e support
- if openssl, librtmp or gmp is not used [no]
- --enable-gmp enable gmp, needed for rtmp(t)e support
- if openssl or librtmp is not used [no]
- --enable-gnutls enable gnutls, needed for https support
- if openssl, libtls or mbedtls is not used [no]
- --disable-iconv disable iconv [autodetect]
- --enable-jni enable JNI support [no]
- --enable-ladspa enable LADSPA audio filtering [no]
- --enable-libaom enable AV1 video encoding/decoding via libaom [no]
- --enable-libaribb24 enable ARIB text and caption decoding via libaribb24 [no]
- --enable-libass enable libass subtitles rendering,
- needed for subtitles and ass filter [no]
- --enable-libbluray enable BluRay reading using libbluray [no]
- --enable-libbs2b enable bs2b DSP library [no]
- --enable-libcaca enable textual display using libcaca [no]
- --enable-libcelt enable CELT decoding via libcelt [no]
- --enable-libcdio enable audio CD grabbing with libcdio [no]
- --enable-libcodec2 enable codec2 en/decoding using libcodec2 [no]
- --enable-libdav1d enable AV1 decoding via libdav1d [no]
- --enable-libdavs2 enable AVS2 decoding via libdavs2 [no]
- --enable-libdc1394 enable IIDC-1394 grabbing using libdc1394
- and libraw1394 [no]
- --enable-libfdk-aac enable AAC de/encoding via libfdk-aac [no]
- --enable-libflite enable flite (voice synthesis) support via libflite [no]
- --enable-libfontconfig enable libfontconfig, useful for drawtext filter [no]
- --enable-libfreetype enable libfreetype, needed for drawtext filter [no]
- --enable-libfribidi enable libfribidi, improves drawtext filter [no]
- --enable-libglslang enable GLSL->SPIRV compilation via libglslang [no]
- --enable-libgme enable Game Music Emu via libgme [no]
- --enable-libgsm enable GSM de/encoding via libgsm [no]
- --enable-libiec61883 enable iec61883 via libiec61883 [no]
- --enable-libilbc enable iLBC de/encoding via libilbc [no]
- --enable-libjack enable JACK audio sound server [no]
- --enable-libklvanc enable Kernel Labs VANC processing [no]
- --enable-libkvazaar enable HEVC encoding via libkvazaar [no]
- --enable-liblensfun enable lensfun lens correction [no]
- --enable-libmodplug enable ModPlug via libmodplug [no]
- --enable-libmp3lame enable MP3 encoding via libmp3lame [no]
- --enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no]
- --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
- --enable-libopencv enable video filtering via libopencv [no]
- --enable-libopenh264 enable H.264 encoding via OpenH264 [no]
- --enable-libopenjpeg enable JPEG 2000 de/encoding via OpenJPEG [no]
- --enable-libopenmpt enable decoding tracked files via libopenmpt [no]
- --enable-libopus enable Opus de/encoding via libopus [no]
- --enable-libpulse enable Pulseaudio input via libpulse [no]
- --enable-librabbitmq enable RabbitMQ library [no]
- --enable-librav1e enable AV1 encoding via rav1e [no]
- --enable-librsvg enable SVG rasterization via librsvg [no]
- --enable-librubberband enable rubberband needed for rubberband filter [no]
- --enable-librtmp enable RTMP[E] support via librtmp [no]
- --enable-libshine enable fixed-point MP3 encoding via libshine [no]
- --enable-libsmbclient enable Samba protocol via libsmbclient [no]
- --enable-libsnappy enable Snappy compression, needed for hap encoding [no]
- --enable-libsoxr enable Include libsoxr resampling [no]
- --enable-libspeex enable Speex de/encoding via libspeex [no]
- --enable-libsrt enable Haivision SRT protocol via libsrt [no]
- --enable-libssh enable SFTP protocol via libssh [no]
- --enable-libtensorflow enable TensorFlow as a DNN module backend
- for DNN based filters like sr [no]
- --enable-libtesseract enable Tesseract, needed for ocr filter [no]
- --enable-libtheora enable Theora encoding via libtheora [no]
- --enable-libtls enable LibreSSL (via libtls), needed for https support
- if openssl, gnutls or mbedtls is not used [no]
- --enable-libtwolame enable MP2 encoding via libtwolame [no]
- --enable-libudev enable libudev [no]
- --enable-libv4l2 enable libv4l2/v4l-utils [no]
- --enable-libvidstab enable video stabilization using vid.stab [no]
- --enable-libvmaf enable vmaf filter via libvmaf [no]
- --enable-libvo-amrwbenc enable AMR-WB encoding via libvo-amrwbenc [no]
- --enable-libvorbis enable Vorbis en/decoding via libvorbis,
- native implementation exists [no]
- --enable-libvpx enable VP8 and VP9 de/encoding via libvpx [no]
- --enable-libwavpack enable wavpack encoding via libwavpack [no]
- --enable-libwebp enable WebP encoding via libwebp [no]
- --enable-libx264 enable H.264 encoding via x264 [no]
- --enable-libx265 enable HEVC encoding via x265 [no]
- --enable-libxavs enable AVS encoding via xavs [no]
- --enable-libxavs2 enable AVS2 encoding via xavs2 [no]
- --enable-libxcb enable X11 grabbing using XCB [autodetect]
- --enable-libxcb-shm enable X11 grabbing shm communication [autodetect]
- --enable-libxcb-xfixes enable X11 grabbing mouse rendering [autodetect]
- --enable-libxcb-shape enable X11 grabbing shape rendering [autodetect]
- --enable-libxvid enable Xvid encoding via xvidcore,
- native MPEG-4/Xvid encoder exists [no]
- --enable-libxml2 enable XML parsing using the C library libxml2, needed
- for dash demuxing support [no]
- --enable-libzimg enable z.lib, needed for zscale filter [no]
- --enable-libzmq enable message passing via libzmq [no]
- --enable-libzvbi enable teletext support via libzvbi [no]
- --enable-lv2 enable LV2 audio filtering [no]
- --disable-lzma disable lzma [autodetect]
- --enable-decklink enable Blackmagic DeckLink I/O support [no]
- --enable-mbedtls enable mbedTLS, needed for https support
- if openssl, gnutls or libtls is not used [no]
- --enable-mediacodec enable Android MediaCodec support [no]
- --enable-mediafoundation enable encoding via MediaFoundation [auto]
- --enable-libmysofa enable libmysofa, needed for sofalizer filter [no]
- --enable-openal enable OpenAL 1.1 capture support [no]
- --enable-opencl enable OpenCL processing [no]
- --enable-opengl enable OpenGL rendering [no]
- --enable-openssl enable openssl, needed for https support
- if gnutls, libtls or mbedtls is not used [no]
- --enable-pocketsphinx enable PocketSphinx, needed for asr filter [no]
- --disable-sndio disable sndio support [autodetect]
- --disable-schannel disable SChannel SSP, needed for TLS support on
- Windows if openssl and gnutls are not used [autodetect]
- --disable-sdl2 disable sdl2 [autodetect]
- --disable-securetransport disable Secure Transport, needed for TLS support
- on OSX if openssl and gnutls are not used [autodetect]
- --enable-vapoursynth enable VapourSynth demuxer [no]
- --enable-vulkan enable Vulkan code [no]
- --disable-xlib disable xlib [autodetect]
- --disable-zlib disable zlib [autodetect]
-
- The following libraries provide various hardware acceleration features:
- --disable-amf disable AMF video encoding code [autodetect]
- --disable-audiotoolbox disable Apple AudioToolbox code [autodetect]
- --enable-cuda-nvcc enable Nvidia CUDA compiler [no]
- --disable-cuda-llvm disable CUDA compilation using clang [autodetect]
- --disable-cuvid disable Nvidia CUVID support [autodetect]
- --disable-d3d11va disable Microsoft Direct3D 11 video acceleration code [autodetect]
- --disable-dxva2 disable Microsoft DirectX 9 video acceleration code [autodetect]
- --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-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]
- --disable-nvenc disable Nvidia video encoding code [autodetect]
- --enable-omx enable OpenMAX IL code [no]
- --enable-omx-rpi enable OpenMAX IL code for Raspberry Pi [no]
- --enable-rkmpp enable Rockchip Media Process Platform code [no]
- --disable-v4l2-m2m disable V4L2 mem2mem code [autodetect]
- --enable-v4l2-request enable V4L2 request API code [no]
- --disable-vaapi disable Video Acceleration API (mainly Unix/Intel) code [autodetect]
- --disable-vdpau disable Nvidia Video Decode and Presentation API for Unix code [autodetect]
- --disable-videotoolbox disable VideoToolbox code [autodetect]
-
-Toolchain options:
- --arch=ARCH select architecture [$arch]
- --cpu=CPU select the minimum required CPU (affects
- instruction selection, may crash on older CPUs)
- --cross-prefix=PREFIX use PREFIX for compilation tools [$cross_prefix]
- --progs-suffix=SUFFIX program name suffix []
- --enable-cross-compile assume a cross-compiler is used
- --sysroot=PATH root of cross-build tree
- --sysinclude=PATH location of cross-build system headers
- --target-os=OS compiler targets OS [$target_os]
- --target-exec=CMD command to run executables on target
- --target-path=DIR path to view of build directory on target
- --target-samples=DIR path to samples directory on target
- --tempprefix=PATH force fixed dir/prefix instead of mktemp for checks
- --toolchain=NAME set tool defaults according to NAME
- (gcc-asan, clang-asan, gcc-msan, clang-msan,
- gcc-tsan, clang-tsan, gcc-usan, clang-usan,
- valgrind-massif, valgrind-memcheck,
- msvc, icl, gcov, llvm-cov, hardened)
- --nm=NM use nm tool NM [$nm_default]
- --ar=AR use archive tool AR [$ar_default]
- --as=AS use assembler AS [$as_default]
- --ln_s=LN_S use symbolic link tool LN_S [$ln_s_default]
- --strip=STRIP use strip tool STRIP [$strip_default]
- --windres=WINDRES use windows resource compiler WINDRES [$windres_default]
- --x86asmexe=EXE use nasm-compatible assembler EXE [$x86asmexe_default]
- --cc=CC use C compiler CC [$cc_default]
- --cxx=CXX use C compiler CXX [$cxx_default]
- --objcc=OCC use ObjC compiler OCC [$cc_default]
- --dep-cc=DEPCC use dependency generator DEPCC [$cc_default]
- --nvcc=NVCC use Nvidia CUDA compiler NVCC or clang [$nvcc_default]
- --ld=LD use linker LD [$ld_default]
- --pkg-config=PKGCONFIG use pkg-config tool PKGCONFIG [$pkg_config_default]
- --pkg-config-flags=FLAGS pass additional flags to pkgconf []
- --ranlib=RANLIB use ranlib RANLIB [$ranlib_default]
- --doxygen=DOXYGEN use DOXYGEN to generate API doc [$doxygen_default]
- --host-cc=HOSTCC use host C compiler HOSTCC
- --host-cflags=HCFLAGS use HCFLAGS when compiling for host
- --host-cppflags=HCPPFLAGS use HCPPFLAGS when compiling for host
- --host-ld=HOSTLD use host linker HOSTLD
- --host-ldflags=HLDFLAGS use HLDFLAGS when linking for host
- --host-extralibs=HLIBS use libs HLIBS when linking for host
- --host-os=OS compiler host OS [$target_os]
- --extra-cflags=ECFLAGS add ECFLAGS to CFLAGS [$CFLAGS]
- --extra-cxxflags=ECFLAGS add ECFLAGS to CXXFLAGS [$CXXFLAGS]
- --extra-objcflags=FLAGS add FLAGS to OBJCFLAGS [$CFLAGS]
- --extra-ldflags=ELDFLAGS add ELDFLAGS to LDFLAGS [$LDFLAGS]
- --extra-ldexeflags=ELDFLAGS add ELDFLAGS to LDEXEFLAGS [$LDEXEFLAGS]
- --extra-ldsoflags=ELDFLAGS add ELDFLAGS to LDSOFLAGS [$LDSOFLAGS]
- --extra-libs=ELIBS add ELIBS [$ELIBS]
- --extra-version=STRING version string suffix []
- --optflags=OPTFLAGS override optimization-related compiler flags
- --nvccflags=NVCCFLAGS override nvcc flags [$nvccflags_default]
- --build-suffix=SUFFIX library name suffix []
- --enable-pic build position-independent code
- --enable-thumb compile for Thumb instruction set
- --enable-lto use link-time optimization
- --env="ENV=override" override the environment variables
-
-Advanced options (experts only):
- --malloc-prefix=PREFIX prefix malloc and related names with PREFIX
- --custom-allocator=NAME use a supported custom allocator
- --disable-symver disable symbol versioning
- --enable-hardcoded-tables use hardcoded tables instead of runtime generation
- --disable-safe-bitstream-reader
- disable buffer boundary checking in bitreaders
- (faster, but may crash)
- --sws-max-filter-size=N the max filter size swscale uses [$sws_max_filter_size_default]
-
-Optimization options (experts only):
- --disable-asm disable all assembly optimizations
- --disable-altivec disable AltiVec optimizations
- --disable-vsx disable VSX optimizations
- --disable-power8 disable POWER8 optimizations
- --disable-amd3dnow disable 3DNow! optimizations
- --disable-amd3dnowext disable 3DNow! extended optimizations
- --disable-mmx disable MMX optimizations
- --disable-mmxext disable MMXEXT optimizations
- --disable-sse disable SSE optimizations
- --disable-sse2 disable SSE2 optimizations
- --disable-sse3 disable SSE3 optimizations
- --disable-ssse3 disable SSSE3 optimizations
- --disable-sse4 disable SSE4 optimizations
- --disable-sse42 disable SSE4.2 optimizations
- --disable-avx disable AVX optimizations
- --disable-xop disable XOP optimizations
- --disable-fma3 disable FMA3 optimizations
- --disable-fma4 disable FMA4 optimizations
- --disable-avx2 disable AVX2 optimizations
- --disable-avx512 disable AVX-512 optimizations
- --disable-aesni disable AESNI optimizations
- --disable-armv5te disable armv5te optimizations
- --disable-armv6 disable armv6 optimizations
- --disable-armv6t2 disable armv6t2 optimizations
- --disable-vfp disable VFP optimizations
- --disable-neon disable NEON optimizations
- --disable-inline-asm disable use of inline assembly
- --disable-x86asm disable use of standalone x86 assembly
- --disable-mipsdsp disable MIPS DSP ASE R1 optimizations
- --disable-mipsdspr2 disable MIPS DSP ASE R2 optimizations
- --disable-msa disable MSA optimizations
- --disable-msa2 disable MSA2 optimizations
- --disable-mipsfpu disable floating point MIPS optimizations
- --disable-mmi disable Loongson SIMD optimizations
- --disable-fast-unaligned consider unaligned accesses slow
-
-Developer options (useful when working on FFmpeg itself):
- --disable-debug disable debugging symbols
- --enable-debug=LEVEL set the debug level [$debuglevel]
- --disable-optimizations disable compiler optimizations
- --enable-extra-warnings enable more compiler warnings
- --disable-stripping disable stripping of executables and shared libraries
- --assert-level=level 0(default), 1 or 2, amount of assertion testing,
- 2 causes a slowdown at runtime.
- --enable-memory-poisoning fill heap uninitialized allocated space with arbitrary data
- --valgrind=VALGRIND run "make fate" tests through valgrind to detect memory
- leaks and errors, using the specified valgrind binary.
- Cannot be combined with --target-exec
- --enable-ftrapv Trap arithmetic overflows
- --samples=PATH location of test samples for FATE, if not set use
- \$FATE_SAMPLES at make invocation time.
- --enable-neon-clobber-test check NEON registers for clobbering (should be
- used only for debugging purposes)
- --enable-xmm-clobber-test check XMM registers for clobbering (Win64-only;
- should be used only for debugging purposes)
- --enable-random randomly enable/disable components
- --disable-random
- --enable-random=LIST randomly enable/disable specific components or
- --disable-random=LIST component groups. LIST is a comma-separated list
- of NAME[:PROB] entries where NAME is a component
- (group) and PROB the probability associated with
- NAME (default 0.5).
- --random-seed=VALUE seed value for --enable/disable-random
- --disable-valgrind-backtrace do not print a backtrace under Valgrind
- (only applies to --disable-optimizations builds)
- --enable-ossfuzz Enable building fuzzer tool
- --libfuzzer=PATH path to libfuzzer
- --ignore-tests=TESTS comma-separated list (without "fate-" prefix
- in the name) of tests whose result is ignored
- --enable-linux-perf enable Linux Performance Monitor API
- --disable-large-tests disable tests that use a large amount of memory
-
-NOTE: Object files are built at the place where configure is launched.
-EOF
- exit 0
-}
-
-if test -t 1 && which tput >/dev/null 2>&1; then
- ncolors=$(tput colors)
- if test -n "$ncolors" && test $ncolors -ge 8; then
- bold_color=$(tput bold)
- warn_color=$(tput setaf 3)
- error_color=$(tput setaf 1)
- reset_color=$(tput sgr0)
- fi
- # 72 used instead of 80 since that's the default of pr
- ncols=$(tput cols)
-fi
-: ${ncols:=72}
-
-log(){
- echo "$@" >> $logfile
-}
-
-log_file(){
- log BEGIN "$1"
- log_file_i=1
- while IFS= read -r log_file_line; do
- printf '%5d\t%s\n' "$log_file_i" "$log_file_line"
- log_file_i=$(($log_file_i+1))
- done < "$1" >> "$logfile"
- log END "$1"
-}
-
-warn(){
- log "WARNING: $*"
- WARNINGS="${WARNINGS}WARNING: $*\n"
-}
-
-die(){
- log "$@"
- echo "$error_color$bold_color$@$reset_color"
- cat <<EOF
-
-If you think configure made a mistake, make sure you are using the latest
-version from Git. If the latest version fails, report the problem to the
-ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net.
-EOF
- if disabled logging; then
- cat <<EOF
-Rerun configure with logging enabled (do not use --disable-logging), and
-include the log this produces with your report.
-EOF
- else
- cat <<EOF
-Include the log file "$logfile" produced by configure as this will help
-solve the problem.
-EOF
- fi
- exit 1
-}
-
-# Avoid locale weirdness, besides we really just want to translate ASCII.
-toupper(){
- echo "$@" | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
-}
-
-tolower(){
- echo "$@" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz
-}
-
-c_escape(){
- echo "$*" | sed 's/["\\]/\\\0/g'
-}
-
-sh_quote(){
- v=$(echo "$1" | sed "s/'/'\\\\''/g")
- test "x$v" = "x${v#*[!A-Za-z0-9_/.+-]}" || v="'$v'"
- echo "$v"
-}
-
-cleanws(){
- echo "$@" | sed 's/^ *//;s/[[:space:]][[:space:]]*/ /g;s/ *$//'
-}
-
-filter(){
- pat=$1
- shift
- for v; do
- eval "case '$v' in $pat) printf '%s ' '$v' ;; esac"
- done
-}
-
-filter_out(){
- pat=$1
- shift
- for v; do
- eval "case '$v' in $pat) ;; *) printf '%s ' '$v' ;; esac"
- done
-}
-
-map(){
- m=$1
- shift
- for v; do eval $m; done
-}
-
-add_suffix(){
- suffix=$1
- shift
- for v; do echo ${v}${suffix}; done
-}
-
-remove_suffix(){
- suffix=$1
- shift
- for v; do echo ${v%$suffix}; done
-}
-
-set_all(){
- value=$1
- shift
- for var in $*; do
- eval $var=$value
- done
-}
-
-set_weak(){
- value=$1
- shift
- for var; do
- eval : \${$var:=$value}
- done
-}
-
-sanitize_var_name(){
- echo $@ | sed 's/[^A-Za-z0-9_]/_/g'
-}
-
-set_sanitized(){
- var=$1
- shift
- eval $(sanitize_var_name "$var")='$*'
-}
-
-get_sanitized(){
- eval echo \$$(sanitize_var_name "$1")
-}
-
-pushvar(){
- for pvar in $*; do
- eval level=\${${pvar}_level:=0}
- eval ${pvar}_${level}="\$$pvar"
- eval ${pvar}_level=$(($level+1))
- done
-}
-
-popvar(){
- for pvar in $*; do
- eval level=\${${pvar}_level:-0}
- test $level = 0 && continue
- eval level=$(($level-1))
- eval $pvar="\${${pvar}_${level}}"
- eval ${pvar}_level=$level
- eval unset ${pvar}_${level}
- done
-}
-
-request(){
- for var in $*; do
- eval ${var}_requested=yes
- eval $var=
- done
-}
-
-warn_if_gets_disabled(){
- for var in $*; do
- WARN_IF_GETS_DISABLED_LIST="$WARN_IF_GETS_DISABLED_LIST $var"
- done
-}
-
-enable(){
- set_all yes $*
-}
-
-disable(){
- set_all no $*
-}
-
-disable_with_reason(){
- disable $1
- eval "${1}_disable_reason=\"$2\""
- if requested $1; then
- die "ERROR: $1 requested, but $2"
- fi
-}
-
-enable_weak(){
- set_weak yes $*
-}
-
-disable_weak(){
- set_weak no $*
-}
-
-enable_sanitized(){
- for var; do
- enable $(sanitize_var_name $var)
- done
-}
-
-disable_sanitized(){
- for var; do
- disable $(sanitize_var_name $var)
- done
-}
-
-do_enable_deep(){
- for var; do
- enabled $var && continue
- set -- $var
- eval enable_deep \$${var}_select
- var=$1
- eval enable_deep_weak \$${var}_suggest
- done
-}
-
-enable_deep(){
- do_enable_deep $*
- enable $*
-}
-
-enable_deep_weak(){
- for var; do
- disabled $var && continue
- set -- $var
- do_enable_deep $var
- var=$1
- enable_weak $var
- done
-}
-
-requested(){
- test "${1#!}" = "$1" && op="=" || op="!="
- eval test "x\$${1#!}_requested" $op "xyes"
-}
-
-enabled(){
- test "${1#!}" = "$1" && op="=" || op="!="
- eval test "x\$${1#!}" $op "xyes"
-}
-
-disabled(){
- test "${1#!}" = "$1" && op="=" || op="!="
- eval test "x\$${1#!}" $op "xno"
-}
-
-enabled_all(){
- for opt; do
- enabled $opt || return 1
- done
-}
-
-disabled_all(){
- for opt; do
- disabled $opt || return 1
- done
-}
-
-enabled_any(){
- for opt; do
- enabled $opt && return 0
- done
-}
-
-disabled_any(){
- for opt; do
- disabled $opt && return 0
- done
- return 1
-}
-
-set_default(){
- for opt; do
- eval : \${$opt:=\$${opt}_default}
- done
-}
-
-is_in(){
- value=$1
- shift
- for var in $*; do
- [ $var = $value ] && return 0
- done
- return 1
-}
-
-# The cfg loop is very hot (several thousands iterations), and in bash also
-# potentialy quite slow. Try to abort the iterations early, preferably without
-# calling functions. 70%+ of the time cfg is already done or without deps.
-check_deps(){
- for cfg; do
- eval [ x\$${cfg}_checking = xdone ] && continue
- eval [ x\$${cfg}_checking = xinprogress ] && die "Circular dependency for $cfg."
-
- eval "
- dep_all=\$${cfg}_deps
- dep_any=\$${cfg}_deps_any
- dep_con=\$${cfg}_conflict
- dep_sel=\$${cfg}_select
- dep_sgs=\$${cfg}_suggest
- dep_ifa=\$${cfg}_if
- dep_ifn=\$${cfg}_if_any
- "
-
- # most of the time here $cfg has no deps - avoid costly no-op work
- if [ "$dep_all$dep_any$dep_con$dep_sel$dep_sgs$dep_ifa$dep_ifn" ]; then
- eval ${cfg}_checking=inprogress
-
- set -- $cfg "$dep_all" "$dep_any" "$dep_con" "$dep_sel" "$dep_sgs" "$dep_ifa" "$dep_ifn"
- check_deps $dep_all $dep_any $dep_con $dep_sel $dep_sgs $dep_ifa $dep_ifn
- cfg=$1; dep_all=$2; dep_any=$3; dep_con=$4; dep_sel=$5 dep_sgs=$6; dep_ifa=$7; dep_ifn=$8
-
- [ -n "$dep_ifa" ] && { enabled_all $dep_ifa && enable_weak $cfg; }
- [ -n "$dep_ifn" ] && { enabled_any $dep_ifn && enable_weak $cfg; }
- enabled_all $dep_all || { disable_with_reason $cfg "not all dependencies are satisfied: $dep_all"; }
- enabled_any $dep_any || { disable_with_reason $cfg "not any dependency is satisfied: $dep_any"; }
- disabled_all $dep_con || { disable_with_reason $cfg "some conflicting dependencies are unsatisfied: $dep_con"; }
- disabled_any $dep_sel && { disable_with_reason $cfg "some selected dependency is unsatisfied: $dep_sel"; }
-
- enabled $cfg && enable_deep_weak $dep_sel $dep_sgs
-
- for dep in $dep_all $dep_any $dep_sel $dep_sgs; do
- # filter out library deps, these do not belong in extralibs
- is_in $dep $LIBRARY_LIST && continue
- enabled $dep && eval append ${cfg}_extralibs ${dep}_extralibs
- done
- fi
-
- eval ${cfg}_checking=done
- done
-}
-
-print_config(){
- pfx=$1
- files=$2
- shift 2
- map 'eval echo "$v \${$v:-no}"' "$@" |
- awk "BEGIN { split(\"$files\", files) }
- {
- c = \"$pfx\" toupper(\$1);
- v = \$2;
- sub(/yes/, 1, v);
- sub(/no/, 0, v);
- for (f in files) {
- file = files[f];
- if (file ~ /\\.h\$/) {
- printf(\"#define %s %d\\n\", c, v) >>file;
- } else if (file ~ /\\.asm\$/) {
- printf(\"%%define %s %d\\n\", c, v) >>file;
- } else if (file ~ /\\.mak\$/) {
- n = -v ? \"\" : \"!\";
- printf(\"%s%s=yes\\n\", n, c) >>file;
- } else if (file ~ /\\.texi\$/) {
- pre = -v ? \"\" : \"@c \";
- yesno = \$2;
- c2 = tolower(c);
- gsub(/_/, \"-\", c2);
- printf(\"%s@set %s %s\\n\", pre, c2, yesno) >>file;
- }
- }
- }"
-}
-
-print_enabled(){
- suf=$1
- shift
- for v; do
- enabled $v && printf "%s\n" ${v%$suf}
- done
-}
-
-append(){
- var=$1
- shift
- eval "$var=\"\$$var $*\""
-}
-
-prepend(){
- var=$1
- shift
- eval "$var=\"$* \$$var\""
-}
-
-reverse () {
- eval '
- reverse_out=
- for v in $'$1'; do
- reverse_out="$v $reverse_out"
- done
- '$1'=$reverse_out
- '
-}
-
-# keeps the last occurence of each non-unique item
-unique(){
- unique_out=
- eval unique_in=\$$1
- reverse unique_in
- for v in $unique_in; do
- # " $unique_out" +space such that every item is surrounded with spaces
- case " $unique_out" in *" $v "*) continue; esac # already in list
- unique_out="$unique_out$v "
- done
- reverse unique_out
- eval $1=\$unique_out
-}
-
-resolve(){
- resolve_out=
- eval resolve_in=\$$1
- for v in $resolve_in; do
- eval 'resolve_out="$resolve_out$'$v' "'
- done
- eval $1=\$resolve_out
-}
-
-add_cppflags(){
- append CPPFLAGS "$@"
-}
-
-add_cflags(){
- append CFLAGS $($cflags_filter "$@")
-}
-
-add_cflags_headers(){
- append CFLAGS_HEADERS $($cflags_filter "$@")
-}
-
-add_cxxflags(){
- append CXXFLAGS $($cflags_filter "$@")
-}
-
-add_objcflags(){
- append OBJCFLAGS $($objcflags_filter "$@")
-}
-
-add_asflags(){
- append ASFLAGS $($asflags_filter "$@")
-}
-
-add_ldflags(){
- append LDFLAGS $($ldflags_filter "$@")
-}
-
-add_ldexeflags(){
- append LDEXEFLAGS $($ldflags_filter "$@")
-}
-
-add_ldsoflags(){
- append LDSOFLAGS $($ldflags_filter "$@")
-}
-
-add_extralibs(){
- prepend extralibs $($ldflags_filter "$@")
-}
-
-add_stripflags(){
- append ASMSTRIPFLAGS "$@"
-}
-
-add_host_cppflags(){
- append host_cppflags "$@"
-}
-
-add_host_cflags(){
- append host_cflags $($host_cflags_filter "$@")
-}
-
-add_host_ldflags(){
- append host_ldflags $($host_ldflags_filter "$@")
-}
-
-add_compat(){
- append compat_objs $1
- shift
- map 'add_cppflags -D$v' "$@"
-}
-
-test_cmd(){
- log "$@"
- "$@" >> $logfile 2>&1
-}
-
-test_stat(){
- log test_stat "$@"
- stat "$1" >> $logfile 2>&1
-}
-
-cc_e(){
- eval printf '%s\\n' $CC_E
-}
-
-cc_o(){
- eval printf '%s\\n' $CC_O
-}
-
-as_o(){
- eval printf '%s\\n' $AS_O
-}
-
-x86asm_o(){
- eval printf '%s\\n' $X86ASM_O
-}
-
-ld_o(){
- eval printf '%s\\n' $LD_O
-}
-
-hostcc_e(){
- eval printf '%s\\n' $HOSTCC_E
-}
-
-hostcc_o(){
- eval printf '%s\\n' $HOSTCC_O
-}
-
-nvcc_o(){
- eval printf '%s\\n' $NVCC_O
-}
-
-test_cc(){
- log test_cc "$@"
- cat > $TMPC
- log_file $TMPC
- test_cmd $cc $CPPFLAGS $CFLAGS "$@" $CC_C $(cc_o $TMPO) $TMPC
-}
-
-test_cxx(){
- log test_cxx "$@"
- cat > $TMPCPP
- log_file $TMPCPP
- test_cmd $cxx $CPPFLAGS $CFLAGS $CXXFLAGS "$@" $CXX_C -o $TMPO $TMPCPP
-}
-
-test_objcc(){
- log test_objcc "$@"
- cat > $TMPM
- log_file $TMPM
- test_cmd $objcc -Werror=missing-prototypes $CPPFLAGS $CFLAGS $OBJCFLAGS "$@" $OBJCC_C $(cc_o $TMPO) $TMPM
-}
-
-test_nvcc(){
- log test_nvcc "$@"
- cat > $TMPCU
- log_file $TMPCU
- tmpcu_=$TMPCU
- tmpo_=$TMPO
- [ -x "$(command -v cygpath)" ] && tmpcu_=$(cygpath -m $tmpcu_) && tmpo_=$(cygpath -m $tmpo_)
- test_cmd $nvcc $nvccflags "$@" $NVCC_C $(nvcc_o $tmpo_) $tmpcu_
-}
-
-check_nvcc() {
- log check_nvcc "$@"
- name=$1
- shift 1
- disabled $name && return
- disable $name
- test_nvcc "$@" <<EOF && enable $name
-extern "C" {
- __global__ void hello(unsigned char *data) {}
-}
-EOF
-}
-
-test_cpp(){
- log test_cpp "$@"
- cat > $TMPC
- log_file $TMPC
- test_cmd $cc $CPPFLAGS $CFLAGS "$@" $(cc_e $TMPO) $TMPC
-}
-
-test_as(){
- log test_as "$@"
- cat > $TMPS
- log_file $TMPS
- test_cmd $as $CPPFLAGS $ASFLAGS "$@" $AS_C $(as_o $TMPO) $TMPS
-}
-
-test_x86asm(){
- log test_x86asm "$@"
- echo "$1" > $TMPASM
- log_file $TMPASM
- shift
- test_cmd $x86asmexe $X86ASMFLAGS -Werror "$@" $(x86asm_o $TMPO) $TMPASM
-}
-
-check_cmd(){
- log check_cmd "$@"
- cmd=$1
- disabled $cmd && return
- disable $cmd
- test_cmd $@ && enable $cmd
-}
-
-check_as(){
- log check_as "$@"
- name=$1
- code=$2
- shift 2
- disable $name
- test_as $@ <<EOF && enable $name
-$code
-EOF
-}
-
-check_inline_asm(){
- log check_inline_asm "$@"
- name="$1"
- code="$2"
- shift 2
- disable $name
- test_cc "$@" <<EOF && enable $name
-void foo(void){ __asm__ volatile($code); }
-EOF
-}
-
-check_inline_asm_flags(){
- log check_inline_asm_flags "$@"
- name="$1"
- code="$2"
- flags=''
- shift 2
- while [ "$1" != "" ]; do
- append flags $1
- shift
- done;
- disable $name
- cat > $TMPC <<EOF
-void foo(void){ __asm__ volatile($code); }
-EOF
- log_file $TMPC
- test_cmd $cc $CPPFLAGS $CFLAGS $flags "$@" $CC_C $(cc_o $TMPO) $TMPC &&
- enable $name && add_cflags $flags && add_asflags $flags && add_ldflags $flags
-}
-
-check_insn(){
- log check_insn "$@"
- check_inline_asm ${1}_inline "\"$2\""
- check_as ${1}_external "$2"
-}
-
-check_x86asm(){
- log check_x86asm "$@"
- name=$1
- shift
- disable $name
- test_x86asm "$@" && enable $name
-}
-
-test_ld(){
- log test_ld "$@"
- type=$1
- shift 1
- flags=$(filter_out '-l*|*.so' $@)
- libs=$(filter '-l*|*.so' $@)
- test_$type $($cflags_filter $flags) || return
- flags=$($ldflags_filter $flags)
- libs=$($ldflags_filter $libs)
- test_cmd $ld $LDFLAGS $LDEXEFLAGS $flags $(ld_o $TMPE) $TMPO $libs $extralibs
-}
-
-check_ld(){
- log check_ld "$@"
- type=$1
- name=$2
- shift 2
- disable $name
- test_ld $type $@ && enable $name
-}
-
-print_include(){
- hdr=$1
- test "${hdr%.h}" = "${hdr}" &&
- echo "#include $hdr" ||
- echo "#include <$hdr>"
-}
-
-test_code(){
- log test_code "$@"
- check=$1
- headers=$2
- code=$3
- shift 3
- {
- for hdr in $headers; do
- print_include $hdr
- done
- echo "int main(void) { $code; return 0; }"
- } | test_$check "$@"
-}
-
-check_cppflags(){
- log check_cppflags "$@"
- test_cpp "$@" <<EOF && append CPPFLAGS "$@"
-#include <stdlib.h>
-EOF
-}
-
-test_cflags(){
- log test_cflags "$@"
- set -- $($cflags_filter "$@")
- test_cc "$@" <<EOF
-int x;
-EOF
-}
-
-check_cflags(){
- log check_cflags "$@"
- test_cflags "$@" && add_cflags "$@"
-}
-
-check_cxxflags(){
- log check_cxxflags "$@"
- set -- $($cflags_filter "$@")
- test_cxx "$@" <<EOF && append CXXFLAGS "$@"
-int x;
-EOF
-}
-
-test_objcflags(){
- log test_objcflags "$@"
- set -- $($objcflags_filter "$@")
- test_objcc "$@" <<EOF
-int x;
-EOF
-}
-
-check_objcflags(){
- log check_objcflags "$@"
- test_objcflags "$@" && add_objcflags "$@"
-}
-
-test_ldflags(){
- log test_ldflags "$@"
- set -- $($ldflags_filter "$@")
- test_ld "cc" "$@" <<EOF
-int main(void){ return 0; }
-EOF
-}
-
-check_ldflags(){
- log check_ldflags "$@"
- test_ldflags "$@" && add_ldflags "$@"
-}
-
-test_stripflags(){
- log test_stripflags "$@"
- # call test_cc to get a fresh TMPO
- test_cc <<EOF
-int main(void) { return 0; }
-EOF
- test_cmd $strip $ASMSTRIPFLAGS "$@" $TMPO
-}
-
-check_stripflags(){
- log check_stripflags "$@"
- test_stripflags "$@" && add_stripflags "$@"
-}
-
-check_headers(){
- log check_headers "$@"
- headers=$1
- shift
- disable_sanitized $headers
- {
- for hdr in $headers; do
- print_include $hdr
- done
- echo "int x;"
- } | test_cpp "$@" && enable_sanitized $headers
-}
-
-check_header_objcc(){
- log check_header_objcc "$@"
- rm -f -- "$TMPO"
- header=$1
- shift
- disable_sanitized $header
- {
- echo "#include <$header>"
- echo "int main(void) { return 0; }"
- } | test_objcc && test_stat "$TMPO" && enable_sanitized $header
-}
-
-check_apple_framework(){
- log check_apple_framework "$@"
- framework="$1"
- name="$(tolower $framework)"
- header="${framework}/${framework}.h"
- disable $name
- check_header_objcc $header &&
- enable $name && eval ${name}_extralibs='"-framework $framework"'
-}
-
-check_func(){
- log check_func "$@"
- func=$1
- shift
- disable $func
- test_ld "cc" "$@" <<EOF && enable $func
-extern int $func();
-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" "$@" <<EOF && enable $func
-#include <complex.h>
-#include <math.h>
-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
- narg=$2
- shift 2
- test $narg = 2 && args="f, g" || args="f"
- disable $func
- test_ld "cc" "$@" <<EOF && enable $func
-#include <math.h>
-float foo(float f, float g) { return $func($args); }
-int main(void){ return (int) foo; }
-EOF
-}
-
-check_func_headers(){
- log check_func_headers "$@"
- headers=$1
- funcs=$2
- shift 2
- {
- for hdr in $headers; do
- print_include $hdr
- done
- echo "#include <stdint.h>"
- for func in $funcs; do
- echo "long check_$func(void) { return (long) $func; }"
- done
- echo "int main(void) { int ret = 0;"
- # LTO could optimize out the test functions without this
- for func in $funcs; do
- echo " ret |= ((intptr_t)check_$func) & 0xFFFF;"
- done
- echo "return ret; }"
- } | test_ld "cc" "$@" && enable $funcs && enable_sanitized $headers
-}
-
-check_class_headers_cpp(){
- log check_class_headers_cpp "$@"
- headers=$1
- classes=$2
- shift 2
- {
- for hdr in $headers; do
- echo "#include <$hdr>"
- done
- echo "int main(void) { "
- i=1
- for class in $classes; do
- echo "$class obj$i;"
- i=$(expr $i + 1)
- done
- echo "return 0; }"
- } | test_ld "cxx" "$@" && enable $funcs && enable_sanitized $headers
-}
-
-test_cpp_condition(){
- log test_cpp_condition "$@"
- header=$1
- condition=$2
- shift 2
- test_cpp "$@" <<EOF
-#include <$header>
-#if !($condition)
-#error "unsatisfied condition: $condition"
-#endif
-EOF
-}
-
-check_cpp_condition(){
- log check_cpp_condition "$@"
- name=$1
- shift 1
- disable $name
- test_cpp_condition "$@" && enable $name
-}
-
-test_cflags_cc(){
- log test_cflags_cc "$@"
- flags=$1
- header=$2
- condition=$3
- shift 3
- set -- $($cflags_filter "$flags")
- test_cc "$@" <<EOF
-#include <$header>
-#if !($condition)
-#error "unsatisfied condition: $condition"
-#endif
-EOF
-}
-
-check_lib(){
- log check_lib "$@"
- name="$1"
- headers="$2"
- funcs="$3"
- shift 3
- disable $name
- check_func_headers "$headers" "$funcs" "$@" &&
- enable $name && eval ${name}_extralibs="\$@"
-}
-
-check_lib_cpp(){
- log check_lib_cpp "$@"
- name="$1"
- headers="$2"
- classes="$3"
- shift 3
- disable $name
- check_class_headers_cpp "$headers" "$classes" "$@" &&
- enable $name && eval ${name}_extralibs="\$@"
-}
-
-test_pkg_config(){
- log test_pkg_config "$@"
- name="$1"
- pkg_version="$2"
- pkg="${2%% *}"
- headers="$3"
- funcs="$4"
- shift 4
- disable $name
- test_cmd $pkg_config --exists --print-errors $pkg_version || return
- pkg_cflags=$($pkg_config --cflags $pkg_config_flags $pkg)
- pkg_libs=$($pkg_config --libs $pkg_config_flags $pkg)
- check_func_headers "$headers" "$funcs" $pkg_cflags $pkg_libs "$@" &&
- enable $name &&
- set_sanitized "${name}_cflags" $pkg_cflags &&
- set_sanitized "${name}_extralibs" $pkg_libs
-}
-
-check_pkg_config(){
- log check_pkg_config "$@"
- name="$1"
- test_pkg_config "$@" &&
- eval add_cflags \$${name}_cflags
-}
-
-test_exec(){
- test_ld "cc" "$@" && { enabled cross_compile || $TMPE >> $logfile 2>&1; }
-}
-
-check_exec_crash(){
- log check_exec_crash "$@"
- code=$(cat)
-
- # exit() is not async signal safe. _Exit (C99) and _exit (POSIX)
- # are safe but may not be available everywhere. Thus we use
- # raise(SIGTERM) instead. The check is run in a subshell so we
- # can redirect the "Terminated" message from the shell. SIGBUS
- # is not defined by standard C so it is used conditionally.
-
- (test_exec "$@") >> $logfile 2>&1 <<EOF
-#include <signal.h>
-static void sighandler(int sig){
- raise(SIGTERM);
-}
-int foo(void){
- $code
-}
-int (*func_ptr)(void) = foo;
-int main(void){
- signal(SIGILL, sighandler);
- signal(SIGFPE, sighandler);
- signal(SIGSEGV, sighandler);
-#ifdef SIGBUS
- signal(SIGBUS, sighandler);
-#endif
- return func_ptr();
-}
-EOF
-}
-
-check_type(){
- log check_type "$@"
- headers=$1
- type=$2
- shift 2
- disable_sanitized "$type"
- test_code cc "$headers" "$type v" "$@" && enable_sanitized "$type"
-}
-
-check_struct(){
- log check_struct "$@"
- headers=$1
- struct=$2
- member=$3
- shift 3
- disable_sanitized "${struct}_${member}"
- test_code cc "$headers" "const void *p = &(($struct *)0)->$member" "$@" &&
- enable_sanitized "${struct}_${member}"
-}
-
-check_builtin(){
- log check_builtin "$@"
- name=$1
- headers=$2
- builtin=$3
- shift 3
- disable "$name"
- test_code ld "$headers" "$builtin" "cc" "$@" && enable "$name"
-}
-
-check_compile_assert(){
- log check_compile_assert "$@"
- name=$1
- headers=$2
- condition=$3
- shift 3
- disable "$name"
- test_code cc "$headers" "char c[2 * !!($condition) - 1]" "$@" && enable "$name"
-}
-
-check_cc(){
- log check_cc "$@"
- name=$1
- shift
- disable "$name"
- test_code cc "$@" && enable "$name"
-}
-
-require(){
- log require "$@"
- name_version="$1"
- name="${1%% *}"
- shift
- check_lib $name "$@" || die "ERROR: $name_version not found"
-}
-
-require_cc(){
- log require_cc "$@"
- name="$1"
- check_cc "$@" || die "ERROR: $name failed"
-}
-
-require_cpp(){
- log require_cpp "$@"
- name_version="$1"
- name="${1%% *}"
- shift
- check_lib_cpp "$name" "$@" || die "ERROR: $name_version not found"
-}
-
-require_headers(){
- log require_headers "$@"
- headers="$1"
- check_headers "$@" || die "ERROR: $headers not found"
-}
-
-require_cpp_condition(){
- log require_cpp_condition "$@"
- condition="$3"
- check_cpp_condition "$@" || die "ERROR: $condition not satisfied"
-}
-
-require_pkg_config(){
- log require_pkg_config "$@"
- pkg_version="$2"
- check_pkg_config "$@" || die "ERROR: $pkg_version not found using pkg-config$pkg_config_fail_message"
-}
-
-test_host_cc(){
- log test_host_cc "$@"
- cat > $TMPC
- log_file $TMPC
- test_cmd $host_cc $host_cflags "$@" $HOSTCC_C $(hostcc_o $TMPO) $TMPC
-}
-
-test_host_cpp(){
- log test_host_cpp "$@"
- cat > $TMPC
- log_file $TMPC
- test_cmd $host_cc $host_cppflags $host_cflags "$@" $(hostcc_e $TMPO) $TMPC
-}
-
-check_host_cppflags(){
- log check_host_cppflags "$@"
- test_host_cpp "$@" <<EOF && append host_cppflags "$@"
-#include <stdlib.h>
-EOF
-}
-
-check_host_cflags(){
- log check_host_cflags "$@"
- set -- $($host_cflags_filter "$@")
- test_host_cc "$@" <<EOF && append host_cflags "$@"
-int x;
-EOF
-}
-
-test_host_cpp_condition(){
- log test_host_cpp_condition "$@"
- header=$1
- condition=$2
- shift 2
- test_host_cpp "$@" <<EOF
-#include <$header>
-#if !($condition)
-#error "unsatisfied condition: $condition"
-#endif
-EOF
-}
-
-check_host_cpp_condition(){
- log check_host_cpp_condition "$@"
- name=$1
- shift 1
- disable $name
- test_host_cpp_condition "$@" && enable $name
-}
-
-cp_if_changed(){
- cmp -s "$1" "$2" && { test "$quiet" != "yes" && echo "$2 is unchanged"; } && return
- mkdir -p "$(dirname $2)"
- cp -f "$1" "$2"
-}
-
-# CONFIG_LIST contains configurable options, while HAVE_LIST is for
-# system-dependent things.
-
-AVCODEC_COMPONENTS="
- bsfs
- decoders
- encoders
- hwaccels
- parsers
-"
-
-AVDEVICE_COMPONENTS="
- indevs
- outdevs
-"
-
-AVFILTER_COMPONENTS="
- filters
-"
-
-AVFORMAT_COMPONENTS="
- demuxers
- muxers
- protocols
-"
-
-COMPONENT_LIST="
- $AVCODEC_COMPONENTS
- $AVDEVICE_COMPONENTS
- $AVFILTER_COMPONENTS
- $AVFORMAT_COMPONENTS
-"
-
-EXAMPLE_LIST="
- avio_list_dir_example
- avio_reading_example
- decode_audio_example
- decode_video_example
- demuxing_decoding_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
- transcode_aac_example
- transcoding_example
- vaapi_encode_example
- vaapi_transcode_example
-"
-
-EXTERNAL_AUTODETECT_LIBRARY_LIST="
- alsa
- appkit
- avfoundation
- bzlib
- coreimage
- iconv
- libxcb
- libxcb_shm
- libxcb_shape
- libxcb_xfixes
- lzma
- mediafoundation
- schannel
- sdl2
- securetransport
- sndio
- xlib
- zlib
-"
-
-EXTERNAL_LIBRARY_GPL_LIST="
- avisynth
- frei0r
- libcdio
- libdavs2
- librubberband
- libvidstab
- libx264
- libx265
- libxavs
- libxavs2
- libxvid
-"
-
-EXTERNAL_LIBRARY_NONFREE_LIST="
- decklink
- libfdk_aac
- openssl
- libtls
-"
-
-EXTERNAL_LIBRARY_VERSION3_LIST="
- gmp
- libaribb24
- liblensfun
- libopencore_amrnb
- libopencore_amrwb
- libvmaf
- libvo_amrwbenc
- mbedtls
- rkmpp
-"
-
-EXTERNAL_LIBRARY_GPLV3_LIST="
- libsmbclient
-"
-
-EXTERNAL_LIBRARY_LIST="
- $EXTERNAL_LIBRARY_GPL_LIST
- $EXTERNAL_LIBRARY_NONFREE_LIST
- $EXTERNAL_LIBRARY_VERSION3_LIST
- $EXTERNAL_LIBRARY_GPLV3_LIST
- chromaprint
- gcrypt
- gnutls
- jni
- ladspa
- libaom
- libass
- libbluray
- libbs2b
- libcaca
- libcelt
- libcodec2
- libdav1d
- libdc1394
- libdrm
- libflite
- libfontconfig
- libfreetype
- libfribidi
- libglslang
- libgme
- libgsm
- libiec61883
- libilbc
- libjack
- libklvanc
- libkvazaar
- libmodplug
- libmp3lame
- libmysofa
- libopencv
- libopenh264
- libopenjpeg
- libopenmpt
- libopus
- libpulse
- librabbitmq
- librav1e
- librsvg
- librtmp
- libshine
- libsmbclient
- libsnappy
- libsoxr
- libspeex
- libsrt
- libssh
- libtensorflow
- libtesseract
- libtheora
- libtwolame
- libudev
- libv4l2
- libvorbis
- libvpx
- libwavpack
- libwebp
- libxml2
- libzimg
- libzmq
- libzvbi
- lv2
- mediacodec
- openal
- opengl
- pocketsphinx
- vapoursynth
-"
-
-HWACCEL_AUTODETECT_LIBRARY_LIST="
- amf
- audiotoolbox
- crystalhd
- cuda
- cuda_llvm
- cuvid
- d3d11va
- dxva2
- ffnvcodec
- nvdec
- nvenc
- vaapi
- vdpau
- videotoolbox
- v4l2_m2m
- xvmc
-"
-
-# catchall list of things that require external libs to link
-EXTRALIBS_LIST="
- cpu_init
- cws2fws
-"
-
-HWACCEL_LIBRARY_NONFREE_LIST="
- cuda_nvcc
- cuda_sdk
- libnpp
-"
-
-HWACCEL_LIBRARY_LIST="
- $HWACCEL_LIBRARY_NONFREE_LIST
- libmfx
- mmal
- omx
- opencl
- v4l2_request
- vulkan
-"
-
-DOCUMENT_LIST="
- doc
- htmlpages
- manpages
- podpages
- txtpages
-"
-
-FEATURE_LIST="
- ftrapv
- gray
- hardcoded_tables
- omx_rpi
- runtime_cpudetect
- safe_bitstream_reader
- shared
- small
- static
- swscale_alpha
-"
-
-# this list should be kept in linking order
-LIBRARY_LIST="
- avdevice
- avfilter
- swscale
- postproc
- avformat
- avcodec
- swresample
- avresample
- avutil
-"
-
-LICENSE_LIST="
- gpl
- nonfree
- version3
-"
-
-PROGRAM_LIST="
- ffplay
- ffprobe
- ffmpeg
-"
-
-SUBSYSTEM_LIST="
- dct
- dwt
- error_resilience
- faan
- fast_unaligned
- fft
- lsp
- lzo
- mdct
- pixelutils
- network
- rdft
-"
-
-# COMPONENT_LIST needs to come last to ensure correct dependency checking
-CONFIG_LIST="
- $DOCUMENT_LIST
- $EXAMPLE_LIST
- $EXTERNAL_LIBRARY_LIST
- $EXTERNAL_AUTODETECT_LIBRARY_LIST
- $HWACCEL_LIBRARY_LIST
- $HWACCEL_AUTODETECT_LIBRARY_LIST
- $FEATURE_LIST
- $LICENSE_LIST
- $LIBRARY_LIST
- $PROGRAM_LIST
- $SUBSYSTEM_LIST
- autodetect
- fontconfig
- large_tests
- linux_perf
- memory_poisoning
- neon_clobber_test
- ossfuzz
- pic
- thumb
- valgrind_backtrace
- xmm_clobber_test
- $COMPONENT_LIST
-"
-
-THREADS_LIST="
- pthreads
- os2threads
- w32threads
-"
-
-ATOMICS_LIST="
- atomics_gcc
- atomics_suncc
- atomics_win32
-"
-
-AUTODETECT_LIBS="
- $EXTERNAL_AUTODETECT_LIBRARY_LIST
- $HWACCEL_AUTODETECT_LIBRARY_LIST
- $THREADS_LIST
-"
-
-ARCH_LIST="
- aarch64
- alpha
- arm
- avr32
- avr32_ap
- avr32_uc
- bfin
- ia64
- m68k
- mips
- mips64
- parisc
- ppc
- ppc64
- s390
- sh4
- sparc
- sparc64
- tilegx
- tilepro
- tomi
- x86
- x86_32
- x86_64
-"
-
-ARCH_EXT_LIST_ARM="
- armv5te
- armv6
- armv6t2
- armv8
- neon
- vfp
- vfpv3
- setend
-"
-
-ARCH_EXT_LIST_MIPS="
- mipsfpu
- mips32r2
- mips32r5
- mips64r2
- mips32r6
- mips64r6
- mipsdsp
- mipsdspr2
- msa
- msa2
-"
-
-ARCH_EXT_LIST_LOONGSON="
- loongson2
- loongson3
- mmi
-"
-
-ARCH_EXT_LIST_X86_SIMD="
- aesni
- amd3dnow
- amd3dnowext
- avx
- avx2
- avx512
- fma3
- fma4
- mmx
- mmxext
- sse
- sse2
- sse3
- sse4
- sse42
- ssse3
- xop
-"
-
-ARCH_EXT_LIST_PPC="
- altivec
- dcbzl
- ldbrx
- power8
- ppc4xx
- vsx
-"
-
-ARCH_EXT_LIST_X86="
- $ARCH_EXT_LIST_X86_SIMD
- cpunop
- i686
-"
-
-ARCH_EXT_LIST="
- $ARCH_EXT_LIST_ARM
- $ARCH_EXT_LIST_PPC
- $ARCH_EXT_LIST_X86
- $ARCH_EXT_LIST_MIPS
- $ARCH_EXT_LIST_LOONGSON
-"
-
-ARCH_FEATURES="
- aligned_stack
- fast_64bit
- fast_clz
- fast_cmov
- local_aligned
- simd_align_16
- simd_align_32
- simd_align_64
-"
-
-BUILTIN_LIST="
- atomic_cas_ptr
- machine_rw_barrier
- MemoryBarrier
- mm_empty
- rdtsc
- sem_timedwait
- sync_val_compare_and_swap
-"
-HAVE_LIST_CMDLINE="
- inline_asm
- symver
- x86asm
-"
-
-HAVE_LIST_PUB="
- bigendian
- fast_unaligned
-"
-
-HEADERS_LIST="
- arpa_inet_h
- asm_types_h
- cdio_paranoia_h
- cdio_paranoia_paranoia_h
- cuda_h
- dispatch_dispatch_h
- dev_bktr_ioctl_bt848_h
- dev_bktr_ioctl_meteor_h
- dev_ic_bt8xx_h
- dev_video_bktr_ioctl_bt848_h
- dev_video_meteor_ioctl_meteor_h
- direct_h
- dirent_h
- dxgidebug_h
- dxva_h
- ES2_gl_h
- gsm_h
- io_h
- linux_perf_event_h
- machine_ioctl_bt848_h
- machine_ioctl_meteor_h
- malloc_h
- opencv2_core_core_c_h
- OpenGL_gl3_h
- poll_h
- sys_param_h
- sys_resource_h
- sys_select_h
- sys_soundcard_h
- sys_time_h
- sys_un_h
- sys_videoio_h
- termios_h
- udplite_h
- unistd_h
- valgrind_valgrind_h
- windows_h
- winsock2_h
-"
-
-INTRINSICS_LIST="
- intrinsics_neon
-"
-
-COMPLEX_FUNCS="
- cabs
- cexp
-"
-
-MATH_FUNCS="
- atanf
- atan2f
- cbrt
- cbrtf
- copysign
- cosf
- erf
- exp2
- exp2f
- expf
- hypot
- isfinite
- isinf
- isnan
- ldexpf
- llrint
- llrintf
- log2
- log2f
- log10f
- lrint
- lrintf
- powf
- rint
- round
- roundf
- sinf
- trunc
- truncf
-"
-
-SYSTEM_FEATURES="
- dos_paths
- libc_msvcrt
- MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS
- section_data_rel_ro
- threads
- uwp
- winrt
-"
-
-SYSTEM_FUNCS="
- access
- aligned_malloc
- arc4random
- clock_gettime
- closesocket
- CommandLineToArgvW
- fcntl
- getaddrinfo
- gethrtime
- getopt
- GetModuleHandle
- GetProcessAffinityMask
- GetProcessMemoryInfo
- GetProcessTimes
- getrusage
- GetStdHandle
- GetSystemTimeAsFileTime
- gettimeofday
- glob
- glXGetProcAddress
- gmtime_r
- inet_aton
- isatty
- kbhit
- localtime_r
- lstat
- lzo1x_999_compress
- mach_absolute_time
- MapViewOfFile
- memalign
- mkstemp
- mmap
- mprotect
- nanosleep
- PeekNamedPipe
- posix_memalign
- pthread_cancel
- sched_getaffinity
- SecItemImport
- SetConsoleTextAttribute
- SetConsoleCtrlHandler
- SetDllDirectory
- setmode
- setrlimit
- Sleep
- strerror_r
- sysconf
- sysctl
- usleep
- UTGetOSTypeFromString
- VirtualAlloc
- wglGetProcAddress
-"
-
-SYSTEM_LIBRARIES="
- bcrypt
- vaapi_drm
- vaapi_x11
- vdpau_x11
-"
-
-TOOLCHAIN_FEATURES="
- as_arch_directive
- as_dn_directive
- as_fpu_directive
- as_func
- as_object_arch
- asm_mod_q
- blocks_extension
- ebp_available
- ebx_available
- gnu_as
- gnu_windres
- ibm_asm
- inline_asm_direct_symbol_refs
- inline_asm_labels
- inline_asm_nonlocal_labels
- pragma_deprecated
- rsync_contimeout
- symver_asm_label
- symver_gnu_asm
- vfp_args
- xform_asm
- xmm_clobbers
-"
-
-TYPES_LIST="
- kCMVideoCodecType_HEVC
- kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange
- kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ
- kCVImageBufferTransferFunction_ITU_R_2100_HLG
- kCVImageBufferTransferFunction_Linear
- socklen_t
- struct_addrinfo
- struct_group_source_req
- struct_ip_mreq_source
- struct_ipv6_mreq
- struct_msghdr_msg_flags
- struct_pollfd
- struct_rusage_ru_maxrss
- struct_sctp_event_subscribe
- struct_sockaddr_in6
- struct_sockaddr_sa_len
- struct_sockaddr_storage
- struct_stat_st_mtim_tv_nsec
- struct_v4l2_frmivalenum_discrete
-"
-
-HAVE_LIST="
- $ARCH_EXT_LIST
- $(add_suffix _external $ARCH_EXT_LIST)
- $(add_suffix _inline $ARCH_EXT_LIST)
- $ARCH_FEATURES
- $BUILTIN_LIST
- $COMPLEX_FUNCS
- $HAVE_LIST_CMDLINE
- $HAVE_LIST_PUB
- $HEADERS_LIST
- $INTRINSICS_LIST
- $MATH_FUNCS
- $SYSTEM_FEATURES
- $SYSTEM_FUNCS
- $SYSTEM_LIBRARIES
- $THREADS_LIST
- $TOOLCHAIN_FEATURES
- $TYPES_LIST
- makeinfo
- makeinfo_html
- opencl_d3d11
- opencl_drm_arm
- opencl_drm_beignet
- opencl_dxva2
- opencl_vaapi_beignet
- opencl_vaapi_intel_media
- perl
- pod2man
- texi2html
-"
-
-# options emitted with CONFIG_ prefix but not available on the command line
-CONFIG_EXTRA="
- aandcttables
- ac3dsp
- adts_header
- audio_frame_queue
- audiodsp
- blockdsp
- bswapdsp
- cabac
- cbs
- cbs_av1
- cbs_h264
- cbs_h265
- cbs_jpeg
- cbs_mpeg2
- cbs_vp9
- dirac_parse
- dnn
- dvprofile
- exif
- faandct
- faanidct
- fdctdsp
- flacdsp
- fmtconvert
- frame_thread_encoder
- g722dsp
- golomb
- gplv3
- h263dsp
- h264chroma
- h264dsp
- h264parse
- h264pred
- h264qpel
- hevcparse
- hpeldsp
- huffman
- huffyuvdsp
- huffyuvencdsp
- idctdsp
- iirfilter
- mdct15
- intrax8
- iso_media
- ividsp
- jpegtables
- lgplv3
- libx262
- llauddsp
- llviddsp
- llvidencdsp
- lpc
- lzf
- me_cmp
- mpeg_er
- mpegaudio
- mpegaudiodsp
- mpegaudioheader
- mpegvideo
- mpegvideoenc
- mss34dsp
- pixblockdsp
- qpeldsp
- qsv
- qsvdec
- qsvenc
- qsvvpp
- rangecoder
- riffdec
- riffenc
- rtpdec
- rtpenc_chain
- rv34dsp
- scene_sad
- sinewin
- snappy
- srtp
- startcode
- texturedsp
- texturedspenc
- tpeldsp
- vaapi_1
- vaapi_encode
- vc1dsp
- videodsp
- vp3dsp
- vp56dsp
- vp8dsp
- wma_freqs
- wmv2dsp
-"
-
-CMDLINE_SELECT="
- $ARCH_EXT_LIST
- $CONFIG_LIST
- $HAVE_LIST_CMDLINE
- $THREADS_LIST
- asm
- cross_compile
- debug
- extra_warnings
- logging
- lto
- optimizations
- rpath
- stripping
-"
-
-PATHS_LIST="
- bindir
- datadir
- docdir
- incdir
- libdir
- mandir
- pkgconfigdir
- prefix
- shlibdir
- install_name_dir
-"
-
-CMDLINE_SET="
- $PATHS_LIST
- ar
- arch
- as
- assert_level
- build_suffix
- cc
- objcc
- cpu
- cross_prefix
- custom_allocator
- cxx
- dep_cc
- doxygen
- env
- extra_version
- gas
- host_cc
- host_cflags
- host_extralibs
- host_ld
- host_ldflags
- host_os
- ignore_tests
- install
- ld
- ln_s
- logfile
- malloc_prefix
- nm
- optflags
- nvcc
- nvccflags
- pkg_config
- pkg_config_flags
- progs_suffix
- random_seed
- ranlib
- samples
- strip
- sws_max_filter_size
- sysinclude
- sysroot
- target_exec
- target_os
- target_path
- target_samples
- tempprefix
- toolchain
- valgrind
- windres
- x86asmexe
-"
-
-CMDLINE_APPEND="
- extra_cflags
- extra_cxxflags
- extra_objcflags
- host_cppflags
-"
-
-# code dependency declarations
-
-# architecture extensions
-
-armv5te_deps="arm"
-armv6_deps="arm"
-armv6t2_deps="arm"
-armv8_deps="aarch64"
-neon_deps_any="aarch64 arm"
-intrinsics_neon_deps="neon"
-vfp_deps_any="aarch64 arm"
-vfpv3_deps="vfp"
-setend_deps="arm"
-
-map 'eval ${v}_inline_deps=inline_asm' $ARCH_EXT_LIST_ARM
-
-altivec_deps="ppc"
-dcbzl_deps="ppc"
-ldbrx_deps="ppc"
-ppc4xx_deps="ppc"
-vsx_deps="altivec"
-power8_deps="vsx"
-
-loongson2_deps="mips"
-loongson3_deps="mips"
-mips32r2_deps="mips"
-mips32r5_deps="mips"
-mips32r6_deps="mips"
-mips64r2_deps="mips"
-mips64r6_deps="mips"
-mipsfpu_deps="mips"
-mipsdsp_deps="mips"
-mipsdspr2_deps="mips"
-mmi_deps="mips"
-msa_deps="mipsfpu"
-msa2_deps="msa"
-
-cpunop_deps="i686"
-x86_64_select="i686"
-x86_64_suggest="fast_cmov"
-
-amd3dnow_deps="mmx"
-amd3dnowext_deps="amd3dnow"
-i686_deps="x86"
-mmx_deps="x86"
-mmxext_deps="mmx"
-sse_deps="mmxext"
-sse2_deps="sse"
-sse3_deps="sse2"
-ssse3_deps="sse3"
-sse4_deps="ssse3"
-sse42_deps="sse4"
-aesni_deps="sse42"
-avx_deps="sse42"
-xop_deps="avx"
-fma3_deps="avx"
-fma4_deps="avx"
-avx2_deps="avx"
-avx512_deps="avx2"
-
-mmx_external_deps="x86asm"
-mmx_inline_deps="inline_asm x86"
-mmx_suggest="mmx_external mmx_inline"
-
-for ext in $(filter_out mmx $ARCH_EXT_LIST_X86_SIMD); do
- eval dep=\$${ext}_deps
- eval ${ext}_external_deps='"${dep}_external"'
- eval ${ext}_inline_deps='"${dep}_inline"'
- eval ${ext}_suggest='"${ext}_external ${ext}_inline"'
-done
-
-aligned_stack_if_any="aarch64 ppc x86"
-fast_64bit_if_any="aarch64 alpha ia64 mips64 parisc64 ppc64 sparc64 x86_64"
-fast_clz_if_any="aarch64 alpha avr32 mips ppc x86"
-fast_unaligned_if_any="aarch64 ppc x86"
-simd_align_16_if_any="altivec neon sse"
-simd_align_32_if_any="avx"
-simd_align_64_if_any="avx512"
-
-# system capabilities
-linux_perf_deps="linux_perf_event_h"
-symver_if_any="symver_asm_label symver_gnu_asm"
-valgrind_backtrace_conflict="optimizations"
-valgrind_backtrace_deps="valgrind_valgrind_h"
-
-# threading support
-atomics_gcc_if="sync_val_compare_and_swap"
-atomics_suncc_if="atomic_cas_ptr machine_rw_barrier"
-atomics_win32_if="MemoryBarrier"
-atomics_native_if_any="$ATOMICS_LIST"
-w32threads_deps="atomics_native"
-threads_if_any="$THREADS_LIST"
-
-# subsystems
-cbs_av1_select="cbs"
-cbs_h264_select="cbs"
-cbs_h265_select="cbs"
-cbs_jpeg_select="cbs"
-cbs_mpeg2_select="cbs"
-cbs_vp9_select="cbs"
-dct_select="rdft"
-dirac_parse_select="golomb"
-dnn_suggest="libtensorflow"
-error_resilience_select="me_cmp"
-faandct_deps="faan"
-faandct_select="fdctdsp"
-faanidct_deps="faan"
-faanidct_select="idctdsp"
-h264dsp_select="startcode"
-hevcparse_select="golomb"
-frame_thread_encoder_deps="encoders threads"
-intrax8_select="blockdsp idctdsp"
-mdct_select="fft"
-mdct15_select="fft"
-me_cmp_select="fdctdsp idctdsp pixblockdsp"
-mpeg_er_select="error_resilience"
-mpegaudio_select="mpegaudiodsp mpegaudioheader"
-mpegaudiodsp_select="dct"
-mpegvideo_select="blockdsp h264chroma hpeldsp idctdsp me_cmp mpeg_er videodsp"
-mpegvideoenc_select="aandcttables me_cmp mpegvideo pixblockdsp qpeldsp"
-vc1dsp_select="h264chroma qpeldsp startcode"
-rdft_select="fft"
-
-# decoders / encoders
-aac_decoder_select="adts_header mdct15 mdct sinewin"
-aac_fixed_decoder_select="adts_header mdct sinewin"
-aac_encoder_select="audio_frame_queue iirfilter lpc mdct 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"
-acelp_kelvin_decoder_select="audiodsp"
-adpcm_g722_decoder_select="g722dsp"
-adpcm_g722_encoder_select="g722dsp"
-aic_decoder_select="golomb idctdsp"
-alac_encoder_select="lpc"
-als_decoder_select="bswapdsp"
-amrnb_decoder_select="lsp"
-amrwb_decoder_select="lsp"
-amv_decoder_select="sp5x_decoder exif"
-amv_encoder_select="jpegtables mpegvideoenc"
-ape_decoder_select="bswapdsp llauddsp"
-apng_decoder_deps="zlib"
-apng_encoder_deps="zlib"
-apng_encoder_select="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"
-avrn_decoder_select="exif jpegtables"
-bink_decoder_select="blockdsp hpeldsp"
-binkaudio_dct_decoder_select="mdct rdft dct sinewin wma_freqs"
-binkaudio_rdft_decoder_select="mdct rdft sinewin 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"
-cscd_decoder_select="lzo"
-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"
-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"
-eatgq_decoder_select="aandcttables"
-eatqi_decoder_select="aandcttables blockdsp bswapdsp idctdsp"
-exr_decoder_deps="zlib"
-ffv1_decoder_select="rangecoder"
-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"
-flashsv2_decoder_deps="zlib"
-flashsv2_encoder_deps="zlib"
-flashsv_decoder_deps="zlib"
-flashsv_encoder_deps="zlib"
-flv_decoder_select="h263_decoder"
-flv_encoder_select="h263_encoder"
-fourxm_decoder_select="blockdsp bswapdsp"
-fraps_decoder_select="bswapdsp huffman"
-g2m_decoder_deps="zlib"
-g2m_decoder_select="blockdsp idctdsp jpegtables"
-g729_decoder_select="audiodsp"
-h261_decoder_select="mpegvideo"
-h261_encoder_select="mpegvideoenc"
-h263_decoder_select="h263_parser h263dsp mpegvideo qpeldsp"
-h263_encoder_select="h263dsp mpegvideoenc"
-h263i_decoder_select="h263_decoder"
-h263p_decoder_select="h263_decoder"
-h263p_encoder_select="h263_encoder"
-h264_decoder_select="cabac golomb h264chroma h264dsp h264parse h264pred h264qpel videodsp"
-h264_decoder_suggest="error_resilience"
-hap_decoder_select="snappy texturedsp"
-hap_encoder_deps="libsnappy"
-hap_encoder_select="texturedspenc"
-hevc_decoder_select="bswapdsp cabac golomb hevcparse 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"
-imm5_decoder_select="h264_decoder hevc_decoder"
-indeo3_decoder_select="hpeldsp"
-indeo4_decoder_select="ividsp"
-indeo5_decoder_select="ividsp"
-interplay_video_decoder_select="hpeldsp"
-jpegls_decoder_select="mjpeg_decoder"
-jv_decoder_select="blockdsp"
-lagarith_decoder_select="llviddsp"
-ljpeg_encoder_select="idctdsp jpegtables mpegvideoenc"
-lscr_decoder_deps="zlib"
-magicyuv_decoder_select="llviddsp"
-magicyuv_encoder_select="llvidencdsp"
-mdec_decoder_select="blockdsp bswapdsp idctdsp mpegvideo"
-metasound_decoder_select="lsp mdct sinewin"
-mimic_decoder_select="blockdsp bswapdsp hpeldsp idctdsp"
-mjpeg_decoder_select="blockdsp hpeldsp exif idctdsp jpegtables"
-mjpeg_encoder_select="jpegtables mpegvideoenc"
-mjpegb_decoder_select="mjpeg_decoder"
-mlp_decoder_select="mlp_parser"
-mlp_encoder_select="lpc audio_frame_queue"
-motionpixels_decoder_select="bswapdsp"
-mp1_decoder_select="mpegaudio"
-mp1float_decoder_select="mpegaudio"
-mp2_decoder_select="mpegaudio"
-mp2float_decoder_select="mpegaudio"
-mp3_decoder_select="mpegaudio"
-mp3adu_decoder_select="mpegaudio"
-mp3adufloat_decoder_select="mpegaudio"
-mp3float_decoder_select="mpegaudio"
-mp3on4_decoder_select="mpegaudio"
-mp3on4float_decoder_select="mpegaudio"
-mpc7_decoder_select="bswapdsp mpegaudiodsp"
-mpc8_decoder_select="mpegaudiodsp"
-mpegvideo_decoder_select="mpegvideo"
-mpeg1video_decoder_select="mpegvideo"
-mpeg1video_encoder_select="mpegvideoenc h263dsp"
-mpeg2video_decoder_select="mpegvideo"
-mpeg2video_encoder_select="mpegvideoenc h263dsp"
-mpeg4_decoder_select="h263_decoder mpeg4video_parser"
-mpeg4_encoder_select="h263_encoder"
-msa1_decoder_select="mss34dsp"
-mscc_decoder_deps="zlib"
-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"
-mss2_decoder_select="mpegvideo qpeldsp vc1_decoder"
-mts2_decoder_select="mss34dsp"
-mv30_decoder_select="aandcttables blockdsp"
-mvha_decoder_deps="zlib"
-mvha_decoder_select="llviddsp"
-mwsc_decoder_deps="zlib"
-mxpeg_decoder_select="mjpeg_decoder"
-nellymoser_decoder_select="mdct sinewin"
-nellymoser_encoder_select="audio_frame_queue mdct sinewin"
-notchlc_decoder_select="lzf"
-nuv_decoder_select="idctdsp lzo"
-on2avc_decoder_select="mdct"
-opus_decoder_deps="swresample"
-opus_decoder_select="mdct15"
-opus_encoder_select="audio_frame_queue mdct15"
-png_decoder_deps="zlib"
-png_encoder_deps="zlib"
-png_encoder_select="llvidencdsp"
-prores_decoder_select="blockdsp idctdsp"
-prores_encoder_select="fdctdsp"
-qcelp_decoder_select="lsp"
-qdm2_decoder_select="mdct rdft mpegaudiodsp"
-ra_144_decoder_select="audiodsp"
-ra_144_encoder_select="audio_frame_queue lpc audiodsp"
-ralf_decoder_select="golomb"
-rasc_decoder_deps="zlib"
-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"
-rv20_encoder_select="h263_encoder"
-rv30_decoder_select="golomb h264pred h264qpel mpegvideo rv34dsp"
-rv40_decoder_select="golomb h264pred h264qpel mpegvideo rv34dsp"
-screenpresso_decoder_deps="zlib"
-shorten_decoder_select="bswapdsp"
-sipr_decoder_select="lsp"
-snow_decoder_select="dwt h264qpel hpeldsp me_cmp rangecoder videodsp"
-snow_encoder_select="dwt h264qpel hpeldsp me_cmp mpegvideoenc rangecoder"
-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"
-srgc_decoder_deps="zlib"
-svq1_decoder_select="hpeldsp"
-svq1_encoder_select="hpeldsp me_cmp mpegvideoenc"
-svq3_decoder_select="golomb h264dsp h264parse h264pred hpeldsp tpeldsp videodsp"
-svq3_decoder_suggest="zlib"
-tak_decoder_select="audiodsp"
-tdsc_decoder_deps="zlib"
-tdsc_decoder_select="mjpeg_decoder"
-theora_decoder_select="vp3_decoder"
-thp_decoder_select="mjpeg_decoder"
-tiff_decoder_select="mjpeg_decoder"
-tiff_decoder_suggest="zlib lzma"
-tiff_encoder_suggest="zlib"
-truehd_decoder_select="mlp_parser"
-truehd_encoder_select="lpc audio_frame_queue"
-truemotion2_decoder_select="bswapdsp"
-truespeech_decoder_select="bswapdsp"
-tscc_decoder_deps="zlib"
-twinvq_decoder_select="mdct lsp sinewin"
-txd_decoder_select="texturedsp"
-utvideo_decoder_select="bswapdsp llviddsp"
-utvideo_encoder_select="bswapdsp huffman llvidencdsp"
-vble_decoder_select="llviddsp"
-vc1_decoder_select="blockdsp h263_decoder h264qpel intrax8 mpegvideo vc1dsp"
-vc1image_decoder_select="vc1_decoder"
-vorbis_decoder_select="mdct"
-vorbis_encoder_select="audio_frame_queue mdct"
-vp3_decoder_select="hpeldsp vp3dsp videodsp"
-vp4_decoder_select="vp3_decoder"
-vp5_decoder_select="h264chroma hpeldsp videodsp vp3dsp vp56dsp"
-vp6_decoder_select="h264chroma hpeldsp huffman videodsp vp3dsp vp56dsp"
-vp6a_decoder_select="vp6_decoder"
-vp6f_decoder_select="vp6_decoder"
-vp7_decoder_select="h264pred videodsp vp8dsp"
-vp8_decoder_select="h264pred videodsp vp8dsp"
-vp9_decoder_select="videodsp vp9_parser vp9_superframe_split_bsf"
-wcmv_decoder_deps="zlib"
-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"
-wmv3_decoder_select="vc1_decoder"
-wmv3image_decoder_select="wmv3_decoder"
-xma1_decoder_select="wmapro_decoder"
-xma2_decoder_select="wmapro_decoder"
-ylc_decoder_select="bswapdsp"
-zerocodec_decoder_deps="zlib"
-zlib_decoder_deps="zlib"
-zlib_encoder_deps="zlib"
-zmbv_decoder_deps="zlib"
-zmbv_encoder_deps="zlib"
-
-# hardware accelerators
-crystalhd_deps="libcrystalhd_libcrystalhd_if_h"
-cuda_deps="ffnvcodec"
-cuvid_deps="ffnvcodec"
-d3d11va_deps="dxva_h ID3D11VideoDecoder ID3D11VideoContext"
-dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode ole32 user32"
-ffnvcodec_deps_any="libdl LoadLibrary"
-nvdec_deps="ffnvcodec"
-v4l2_request_deps="linux_videodev2_h linux_media_h v4l2_timeval_to_ns libdrm libudev"
-vaapi_x11_deps="xlib"
-videotoolbox_hwaccel_deps="videotoolbox pthreads"
-videotoolbox_hwaccel_extralibs="-framework QuartzCore"
-xvmc_deps="X11_extensions_XvMClib_h"
-
-h263_vaapi_hwaccel_deps="vaapi"
-h263_vaapi_hwaccel_select="h263_decoder"
-h263_videotoolbox_hwaccel_deps="videotoolbox"
-h263_videotoolbox_hwaccel_select="h263_decoder"
-h264_d3d11va_hwaccel_deps="d3d11va"
-h264_d3d11va_hwaccel_select="h264_decoder"
-h264_d3d11va2_hwaccel_deps="d3d11va"
-h264_d3d11va2_hwaccel_select="h264_decoder"
-h264_dxva2_hwaccel_deps="dxva2"
-h264_dxva2_hwaccel_select="h264_decoder"
-h264_nvdec_hwaccel_deps="nvdec"
-h264_nvdec_hwaccel_select="h264_decoder"
-h264_v4l2request_hwaccel_deps="v4l2_request"
-h264_v4l2request_hwaccel_select="h264_decoder"
-h264_vaapi_hwaccel_deps="vaapi"
-h264_vaapi_hwaccel_select="h264_decoder"
-h264_vdpau_hwaccel_deps="vdpau"
-h264_vdpau_hwaccel_select="h264_decoder"
-h264_videotoolbox_hwaccel_deps="videotoolbox"
-h264_videotoolbox_hwaccel_select="h264_decoder"
-hevc_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_HEVC"
-hevc_d3d11va_hwaccel_select="hevc_decoder"
-hevc_d3d11va2_hwaccel_deps="d3d11va DXVA_PicParams_HEVC"
-hevc_d3d11va2_hwaccel_select="hevc_decoder"
-hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC"
-hevc_dxva2_hwaccel_select="hevc_decoder"
-hevc_nvdec_hwaccel_deps="nvdec"
-hevc_nvdec_hwaccel_select="hevc_decoder"
-hevc_v4l2request_hwaccel_deps="v4l2_request"
-hevc_v4l2request_hwaccel_select="hevc_decoder"
-hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC"
-hevc_vaapi_hwaccel_select="hevc_decoder"
-hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC"
-hevc_vdpau_hwaccel_select="hevc_decoder"
-hevc_videotoolbox_hwaccel_deps="videotoolbox"
-hevc_videotoolbox_hwaccel_select="hevc_decoder"
-mjpeg_nvdec_hwaccel_deps="nvdec"
-mjpeg_nvdec_hwaccel_select="mjpeg_decoder"
-mjpeg_vaapi_hwaccel_deps="vaapi"
-mjpeg_vaapi_hwaccel_select="mjpeg_decoder"
-mpeg_xvmc_hwaccel_deps="xvmc"
-mpeg_xvmc_hwaccel_select="mpeg2video_decoder"
-mpeg1_nvdec_hwaccel_deps="nvdec"
-mpeg1_nvdec_hwaccel_select="mpeg1video_decoder"
-mpeg1_vdpau_hwaccel_deps="vdpau"
-mpeg1_vdpau_hwaccel_select="mpeg1video_decoder"
-mpeg1_videotoolbox_hwaccel_deps="videotoolbox"
-mpeg1_videotoolbox_hwaccel_select="mpeg1video_decoder"
-mpeg1_xvmc_hwaccel_deps="xvmc"
-mpeg1_xvmc_hwaccel_select="mpeg1video_decoder"
-mpeg2_d3d11va_hwaccel_deps="d3d11va"
-mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder"
-mpeg2_d3d11va2_hwaccel_deps="d3d11va"
-mpeg2_d3d11va2_hwaccel_select="mpeg2video_decoder"
-mpeg2_dxva2_hwaccel_deps="dxva2"
-mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
-mpeg2_nvdec_hwaccel_deps="nvdec"
-mpeg2_nvdec_hwaccel_select="mpeg2video_decoder"
-mpeg2_v4l2request_hwaccel_deps="v4l2_request mpeg2_v4l2_request"
-mpeg2_v4l2request_hwaccel_select="mpeg2video_decoder"
-mpeg2_vaapi_hwaccel_deps="vaapi"
-mpeg2_vaapi_hwaccel_select="mpeg2video_decoder"
-mpeg2_vdpau_hwaccel_deps="vdpau"
-mpeg2_vdpau_hwaccel_select="mpeg2video_decoder"
-mpeg2_videotoolbox_hwaccel_deps="videotoolbox"
-mpeg2_videotoolbox_hwaccel_select="mpeg2video_decoder"
-mpeg2_xvmc_hwaccel_deps="xvmc"
-mpeg2_xvmc_hwaccel_select="mpeg2video_decoder"
-mpeg4_nvdec_hwaccel_deps="nvdec"
-mpeg4_nvdec_hwaccel_select="mpeg4_decoder"
-mpeg4_vaapi_hwaccel_deps="vaapi"
-mpeg4_vaapi_hwaccel_select="mpeg4_decoder"
-mpeg4_vdpau_hwaccel_deps="vdpau"
-mpeg4_vdpau_hwaccel_select="mpeg4_decoder"
-mpeg4_videotoolbox_hwaccel_deps="videotoolbox"
-mpeg4_videotoolbox_hwaccel_select="mpeg4_decoder"
-vc1_d3d11va_hwaccel_deps="d3d11va"
-vc1_d3d11va_hwaccel_select="vc1_decoder"
-vc1_d3d11va2_hwaccel_deps="d3d11va"
-vc1_d3d11va2_hwaccel_select="vc1_decoder"
-vc1_dxva2_hwaccel_deps="dxva2"
-vc1_dxva2_hwaccel_select="vc1_decoder"
-vc1_nvdec_hwaccel_deps="nvdec"
-vc1_nvdec_hwaccel_select="vc1_decoder"
-vc1_vaapi_hwaccel_deps="vaapi"
-vc1_vaapi_hwaccel_select="vc1_decoder"
-vc1_vdpau_hwaccel_deps="vdpau"
-vc1_vdpau_hwaccel_select="vc1_decoder"
-vp8_nvdec_hwaccel_deps="nvdec"
-vp8_nvdec_hwaccel_select="vp8_decoder"
-vp8_v4l2request_hwaccel_deps="v4l2_request"
-vp8_v4l2request_hwaccel_select="vp8_decoder"
-vp8_vaapi_hwaccel_deps="vaapi"
-vp8_vaapi_hwaccel_select="vp8_decoder"
-vp9_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_VP9"
-vp9_d3d11va_hwaccel_select="vp9_decoder"
-vp9_d3d11va2_hwaccel_deps="d3d11va DXVA_PicParams_VP9"
-vp9_d3d11va2_hwaccel_select="vp9_decoder"
-vp9_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_VP9"
-vp9_dxva2_hwaccel_select="vp9_decoder"
-vp9_nvdec_hwaccel_deps="nvdec"
-vp9_nvdec_hwaccel_select="vp9_decoder"
-vp9_v4l2request_hwaccel_deps="v4l2_request"
-vp9_v4l2request_hwaccel_select="vp9_decoder"
-vp9_vaapi_hwaccel_deps="vaapi VADecPictureParameterBufferVP9_bit_depth"
-vp9_vaapi_hwaccel_select="vp9_decoder"
-vp9_vdpau_hwaccel_deps="vdpau VdpPictureInfoVP9"
-vp9_vdpau_hwaccel_select="vp9_decoder"
-wmv3_d3d11va_hwaccel_select="vc1_d3d11va_hwaccel"
-wmv3_d3d11va2_hwaccel_select="vc1_d3d11va2_hwaccel"
-wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
-wmv3_nvdec_hwaccel_select="vc1_nvdec_hwaccel"
-wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
-wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
-
-# hardware-accelerated codecs
-mediafoundation_deps="mftransform_h MFCreateAlignedMemoryBuffer"
-mediafoundation_extralibs="-lmfplat -lmfuuid -lole32 -lstrmiids"
-omx_deps="libdl pthreads"
-omx_rpi_select="omx"
-qsv_deps="libmfx"
-qsvdec_select="qsv"
-qsvenc_select="qsv"
-qsvvpp_select="qsv"
-vaapi_encode_deps="vaapi"
-v4l2_m2m_deps="linux_videodev2_h sem_timedwait"
-
-hwupload_cuda_filter_deps="ffnvcodec"
-scale_npp_filter_deps="ffnvcodec libnpp"
-scale_cuda_filter_deps="ffnvcodec"
-scale_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
-thumbnail_cuda_filter_deps="ffnvcodec"
-thumbnail_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
-transpose_npp_filter_deps="ffnvcodec libnpp"
-overlay_cuda_filter_deps="ffnvcodec"
-overlay_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
-
-amf_deps_any="libdl LoadLibrary"
-nvenc_deps="ffnvcodec"
-nvenc_deps_any="libdl LoadLibrary"
-nvenc_encoder_deps="nvenc"
-
-aac_mf_encoder_deps="mediafoundation"
-ac3_mf_encoder_deps="mediafoundation"
-h263_v4l2m2m_decoder_deps="v4l2_m2m h263_v4l2_m2m"
-h263_v4l2m2m_encoder_deps="v4l2_m2m h263_v4l2_m2m"
-h264_amf_encoder_deps="amf"
-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_select="h264_mp4toannexb_bsf h264_parser"
-h264_mf_encoder_deps="mediafoundation"
-h264_mmal_decoder_deps="mmal"
-h264_nvenc_encoder_deps="nvenc"
-h264_omx_encoder_deps="omx"
-h264_qsv_decoder_select="h264_mp4toannexb_bsf qsvdec"
-h264_qsv_encoder_select="qsvenc"
-h264_rkmpp_decoder_deps="rkmpp"
-h264_rkmpp_decoder_select="h264_mp4toannexb_bsf"
-h264_vaapi_encoder_select="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"
-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_select="hevc_mp4toannexb_bsf hevc_parser"
-hevc_mf_encoder_deps="mediafoundation"
-hevc_nvenc_encoder_deps="nvenc"
-hevc_qsv_decoder_select="hevc_mp4toannexb_bsf qsvdec"
-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_v4l2m2m_decoder_deps="v4l2_m2m hevc_v4l2_m2m"
-hevc_v4l2m2m_decoder_select="hevc_mp4toannexb_bsf"
-hevc_v4l2m2m_encoder_deps="v4l2_m2m hevc_v4l2_m2m"
-mjpeg_cuvid_decoder_deps="cuvid"
-mjpeg_qsv_decoder_select="qsvdec"
-mjpeg_qsv_encoder_deps="libmfx"
-mjpeg_qsv_encoder_select="qsvenc"
-mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG"
-mjpeg_vaapi_encoder_select="cbs_jpeg jpegtables vaapi_encode"
-mp3_mf_encoder_deps="mediafoundation"
-mpeg1_cuvid_decoder_deps="cuvid"
-mpeg1_v4l2m2m_decoder_deps="v4l2_m2m mpeg1_v4l2_m2m"
-mpeg2_crystalhd_decoder_select="crystalhd"
-mpeg2_cuvid_decoder_deps="cuvid"
-mpeg2_mmal_decoder_deps="mmal"
-mpeg2_mediacodec_decoder_deps="mediacodec"
-mpeg2_qsv_decoder_select="qsvdec"
-mpeg2_qsv_encoder_select="qsvenc"
-mpeg2_vaapi_encoder_select="cbs_mpeg2 vaapi_encode"
-mpeg2_v4l2m2m_decoder_deps="v4l2_m2m mpeg2_v4l2_m2m"
-mpeg4_crystalhd_decoder_select="crystalhd"
-mpeg4_cuvid_decoder_deps="cuvid"
-mpeg4_mediacodec_decoder_deps="mediacodec"
-mpeg4_mmal_decoder_deps="mmal"
-mpeg4_omx_encoder_deps="omx"
-mpeg4_v4l2m2m_decoder_deps="v4l2_m2m mpeg4_v4l2_m2m"
-mpeg4_v4l2m2m_encoder_deps="v4l2_m2m mpeg4_v4l2_m2m"
-msmpeg4_crystalhd_decoder_select="crystalhd"
-nvenc_h264_encoder_select="h264_nvenc_encoder"
-nvenc_hevc_encoder_select="hevc_nvenc_encoder"
-vc1_crystalhd_decoder_select="crystalhd"
-vc1_cuvid_decoder_deps="cuvid"
-vc1_mmal_decoder_deps="mmal"
-vc1_qsv_decoder_select="qsvdec"
-vc1_v4l2m2m_decoder_deps="v4l2_m2m vc1_v4l2_m2m"
-vp8_cuvid_decoder_deps="cuvid"
-vp8_mediacodec_decoder_deps="mediacodec"
-vp8_qsv_decoder_select="qsvdec"
-vp8_rkmpp_decoder_deps="rkmpp"
-vp8_vaapi_encoder_deps="VAEncPictureParameterBufferVP8"
-vp8_vaapi_encoder_select="vaapi_encode"
-vp8_v4l2m2m_decoder_deps="v4l2_m2m vp8_v4l2_m2m"
-vp8_v4l2m2m_encoder_deps="v4l2_m2m vp8_v4l2_m2m"
-vp9_cuvid_decoder_deps="cuvid"
-vp9_mediacodec_decoder_deps="mediacodec"
-vp9_qsv_decoder_select="qsvdec"
-vp9_rkmpp_decoder_deps="rkmpp"
-vp9_vaapi_encoder_deps="VAEncPictureParameterBufferVP9"
-vp9_vaapi_encoder_select="vaapi_encode"
-vp9_qsv_encoder_deps="libmfx MFX_CODEC_VP9"
-vp9_qsv_encoder_select="qsvenc"
-vp9_v4l2m2m_decoder_deps="v4l2_m2m vp9_v4l2_m2m"
-wmv3_crystalhd_decoder_select="crystalhd"
-
-# parsers
-aac_parser_select="adts_header"
-av1_parser_select="cbs_av1"
-h264_parser_select="golomb h264dsp h264parse"
-hevc_parser_select="hevcparse"
-mpegaudio_parser_select="mpegaudioheader"
-mpegvideo_parser_select="mpegvideo"
-mpeg4video_parser_select="h263dsp mpegvideo qpeldsp"
-vc1_parser_select="vc1dsp"
-
-# bitstream_filters
-aac_adtstoasc_bsf_select="adts_header"
-av1_frame_merge_bsf_select="cbs_av1"
-av1_frame_split_bsf_select="cbs_av1"
-av1_metadata_bsf_select="cbs_av1"
-eac3_core_bsf_select="ac3_parser"
-filter_units_bsf_select="cbs"
-h264_metadata_bsf_deps="const_nan"
-h264_metadata_bsf_select="cbs_h264"
-h264_redundant_pps_bsf_select="cbs_h264"
-hevc_metadata_bsf_select="cbs_h265"
-mjpeg2jpeg_bsf_select="jpegtables"
-mpeg2_metadata_bsf_select="cbs_mpeg2"
-trace_headers_bsf_select="cbs"
-vp9_metadata_bsf_select="cbs_vp9"
-
-# external libraries
-aac_at_decoder_deps="audiotoolbox"
-aac_at_decoder_select="aac_adtstoasc_bsf"
-ac3_at_decoder_deps="audiotoolbox"
-ac3_at_decoder_select="ac3_parser"
-adpcm_ima_qt_at_decoder_deps="audiotoolbox"
-alac_at_decoder_deps="audiotoolbox"
-amr_nb_at_decoder_deps="audiotoolbox"
-avisynth_deps_any="libdl LoadLibrary"
-avisynth_demuxer_deps="avisynth"
-avisynth_demuxer_select="riffdec"
-eac3_at_decoder_deps="audiotoolbox"
-eac3_at_decoder_select="ac3_parser"
-gsm_ms_at_decoder_deps="audiotoolbox"
-ilbc_at_decoder_deps="audiotoolbox"
-mp1_at_decoder_deps="audiotoolbox"
-mp2_at_decoder_deps="audiotoolbox"
-mp3_at_decoder_deps="audiotoolbox"
-mp1_at_decoder_select="mpegaudioheader"
-mp2_at_decoder_select="mpegaudioheader"
-mp3_at_decoder_select="mpegaudioheader"
-pcm_alaw_at_decoder_deps="audiotoolbox"
-pcm_mulaw_at_decoder_deps="audiotoolbox"
-qdmc_decoder_select="fft"
-qdmc_at_decoder_deps="audiotoolbox"
-qdm2_at_decoder_deps="audiotoolbox"
-aac_at_encoder_deps="audiotoolbox"
-aac_at_encoder_select="audio_frame_queue"
-alac_at_encoder_deps="audiotoolbox"
-alac_at_encoder_select="audio_frame_queue"
-ilbc_at_encoder_deps="audiotoolbox"
-ilbc_at_encoder_select="audio_frame_queue"
-pcm_alaw_at_encoder_deps="audiotoolbox"
-pcm_alaw_at_encoder_select="audio_frame_queue"
-pcm_mulaw_at_encoder_deps="audiotoolbox"
-pcm_mulaw_at_encoder_select="audio_frame_queue"
-chromaprint_muxer_deps="chromaprint"
-h264_videotoolbox_encoder_deps="pthreads"
-h264_videotoolbox_encoder_select="videotoolbox_encoder"
-hevc_videotoolbox_encoder_deps="pthreads"
-hevc_videotoolbox_encoder_select="videotoolbox_encoder"
-libaom_av1_decoder_deps="libaom"
-libaom_av1_encoder_deps="libaom"
-libaom_av1_encoder_select="extract_extradata_bsf"
-libaribb24_decoder_deps="libaribb24"
-libcelt_decoder_deps="libcelt"
-libcodec2_decoder_deps="libcodec2"
-libcodec2_encoder_deps="libcodec2"
-libdav1d_decoder_deps="libdav1d"
-libdavs2_decoder_deps="libdavs2"
-libfdk_aac_decoder_deps="libfdk_aac"
-libfdk_aac_encoder_deps="libfdk_aac"
-libfdk_aac_encoder_select="audio_frame_queue"
-libgme_demuxer_deps="libgme"
-libgsm_decoder_deps="libgsm"
-libgsm_encoder_deps="libgsm"
-libgsm_ms_decoder_deps="libgsm"
-libgsm_ms_encoder_deps="libgsm"
-libilbc_decoder_deps="libilbc"
-libilbc_encoder_deps="libilbc"
-libkvazaar_encoder_deps="libkvazaar"
-libmodplug_demuxer_deps="libmodplug"
-libmp3lame_encoder_deps="libmp3lame"
-libmp3lame_encoder_select="audio_frame_queue mpegaudioheader"
-libopencore_amrnb_decoder_deps="libopencore_amrnb"
-libopencore_amrnb_encoder_deps="libopencore_amrnb"
-libopencore_amrnb_encoder_select="audio_frame_queue"
-libopencore_amrwb_decoder_deps="libopencore_amrwb"
-libopenh264_decoder_deps="libopenh264"
-libopenh264_decoder_select="h264_mp4toannexb_bsf"
-libopenh264_encoder_deps="libopenh264"
-libopenjpeg_decoder_deps="libopenjpeg"
-libopenjpeg_encoder_deps="libopenjpeg"
-libopenmpt_demuxer_deps="libopenmpt"
-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"
-libspeex_decoder_deps="libspeex"
-libspeex_encoder_deps="libspeex"
-libspeex_encoder_select="audio_frame_queue"
-libtheora_encoder_deps="libtheora"
-libtwolame_encoder_deps="libtwolame"
-libvo_amrwbenc_encoder_deps="libvo_amrwbenc"
-libvorbis_decoder_deps="libvorbis"
-libvorbis_encoder_deps="libvorbis libvorbisenc"
-libvorbis_encoder_select="audio_frame_queue"
-libvpx_vp8_decoder_deps="libvpx"
-libvpx_vp8_encoder_deps="libvpx"
-libvpx_vp9_decoder_deps="libvpx"
-libvpx_vp9_encoder_deps="libvpx"
-libwavpack_encoder_deps="libwavpack"
-libwavpack_encoder_select="audio_frame_queue"
-libwebp_encoder_deps="libwebp"
-libwebp_anim_encoder_deps="libwebp"
-libx262_encoder_deps="libx262"
-libx264_encoder_deps="libx264"
-libx264rgb_encoder_deps="libx264 x264_csp_bgr"
-libx264rgb_encoder_select="libx264_encoder"
-libx265_encoder_deps="libx265"
-libxavs_encoder_deps="libxavs"
-libxavs2_encoder_deps="libxavs2"
-libxvid_encoder_deps="libxvid"
-libzvbi_teletext_decoder_deps="libzvbi"
-vapoursynth_demuxer_deps="vapoursynth"
-videotoolbox_suggest="coreservices"
-videotoolbox_deps="corefoundation coremedia corevideo"
-videotoolbox_encoder_deps="videotoolbox VTCompressionSessionPrepareToEncodeFrames"
-
-# demuxers / muxers
-ac3_demuxer_select="ac3_parser"
-act_demuxer_select="riffdec"
-aiff_muxer_select="iso_media"
-asf_demuxer_select="riffdec"
-asf_o_demuxer_select="riffdec"
-asf_muxer_select="riffenc"
-asf_stream_muxer_select="asf_muxer"
-av1_demuxer_select="av1_frame_merge_bsf av1_parser"
-avi_demuxer_select="iso_media riffdec exif"
-avi_muxer_select="riffenc"
-caf_demuxer_select="iso_media riffdec"
-caf_muxer_select="iso_media"
-dash_muxer_select="mp4_muxer"
-dash_demuxer_deps="libxml2"
-dirac_demuxer_select="dirac_parser"
-dts_demuxer_select="dca_parser"
-dtshd_demuxer_select="dca_parser"
-dv_demuxer_select="dvprofile"
-dv_muxer_select="dvprofile"
-dxa_demuxer_select="riffdec"
-eac3_demuxer_select="ac3_parser"
-f4v_muxer_select="mov_muxer"
-fifo_muxer_deps="threads"
-flac_demuxer_select="flac_parser"
-flv_muxer_select="aac_adtstoasc_bsf"
-gxf_muxer_select="pcm_rechunk_bsf"
-hds_muxer_select="flv_muxer"
-hls_muxer_select="mpegts_muxer"
-hls_muxer_suggest="gcrypt openssl"
-image2_alias_pix_demuxer_select="image2_demuxer"
-image2_brender_pix_demuxer_select="image2_demuxer"
-ipod_muxer_select="mov_muxer"
-ismv_muxer_select="mov_muxer"
-ivf_muxer_select="av1_metadata_bsf vp9_superframe_bsf"
-latm_muxer_select="aac_adtstoasc_bsf"
-matroska_audio_muxer_select="matroska_muxer"
-matroska_demuxer_select="iso_media riffdec"
-matroska_demuxer_suggest="bzlib lzo zlib"
-matroska_muxer_select="iso_media riffenc vp9_superframe_bsf aac_adtstoasc_bsf"
-mlp_demuxer_select="mlp_parser"
-mmf_muxer_select="riffenc"
-mov_demuxer_select="iso_media riffdec"
-mov_demuxer_suggest="zlib"
-mov_muxer_select="iso_media riffenc rtpenc_chain vp9_superframe_bsf aac_adtstoasc_bsf"
-mp3_demuxer_select="mpegaudio_parser"
-mp3_muxer_select="mpegaudioheader"
-mp4_muxer_select="mov_muxer"
-mpegts_demuxer_select="iso_media"
-mpegts_muxer_select="adts_muxer latm_muxer h264_mp4toannexb_bsf hevc_mp4toannexb_bsf"
-mpegtsraw_demuxer_select="mpegts_demuxer"
-mxf_muxer_select="golomb pcm_rechunk_bsf"
-mxf_d10_muxer_select="mxf_muxer"
-mxf_opatom_muxer_select="mxf_muxer"
-nut_muxer_select="riffenc"
-nuv_demuxer_select="riffdec"
-oga_muxer_select="ogg_muxer"
-ogg_demuxer_select="dirac_parse"
-ogv_muxer_select="ogg_muxer"
-opus_muxer_select="ogg_muxer"
-psp_muxer_select="mov_muxer"
-rtp_demuxer_select="sdp_demuxer"
-rtp_muxer_select="golomb jpegtables"
-rtpdec_select="asf_demuxer jpegtables mov_demuxer mpegts_demuxer rm_demuxer rtp_protocol srtp"
-rtsp_demuxer_select="http_protocol rtpdec"
-rtsp_muxer_select="rtp_muxer http_protocol rtp_protocol rtpenc_chain"
-sap_demuxer_select="sdp_demuxer"
-sap_muxer_select="rtp_muxer rtp_protocol rtpenc_chain"
-sdp_demuxer_select="rtpdec"
-smoothstreaming_muxer_select="ismv_muxer"
-spdif_demuxer_select="adts_header"
-spdif_muxer_select="adts_header"
-spx_muxer_select="ogg_muxer"
-swf_demuxer_suggest="zlib"
-tak_demuxer_select="tak_parser"
-truehd_demuxer_select="mlp_parser"
-tg2_muxer_select="mov_muxer"
-tgp_muxer_select="mov_muxer"
-vobsub_demuxer_select="mpegps_demuxer"
-w64_demuxer_select="wav_demuxer"
-w64_muxer_select="wav_muxer"
-wav_demuxer_select="riffdec"
-wav_muxer_select="riffenc"
-webm_chunk_muxer_select="webm_muxer"
-webm_muxer_select="iso_media riffenc"
-webm_dash_manifest_demuxer_select="matroska_demuxer"
-wtv_demuxer_select="mpegts_demuxer riffdec"
-wtv_muxer_select="mpegts_muxer riffenc"
-xmv_demuxer_select="riffdec"
-xwma_demuxer_select="riffdec"
-
-# indevs / outdevs
-android_camera_indev_deps="android camera2ndk mediandk pthreads"
-android_camera_indev_extralibs="-landroid -lcamera2ndk -lmediandk"
-alsa_indev_deps="alsa"
-alsa_outdev_deps="alsa"
-avfoundation_indev_deps="avfoundation corevideo coremedia pthreads"
-avfoundation_indev_suggest="coregraphics applicationservices"
-avfoundation_indev_extralibs="-framework Foundation"
-bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h"
-caca_outdev_deps="libcaca"
-decklink_deps_any="libdl LoadLibrary"
-decklink_indev_deps="decklink threads"
-decklink_indev_extralibs="-lstdc++"
-decklink_outdev_deps="decklink threads"
-decklink_outdev_suggest="libklvanc"
-decklink_outdev_extralibs="-lstdc++"
-dshow_indev_deps="IBaseFilter"
-dshow_indev_extralibs="-lpsapi -lole32 -lstrmiids -luuid -loleaut32 -lshlwapi"
-fbdev_indev_deps="linux_fb_h"
-fbdev_outdev_deps="linux_fb_h"
-gdigrab_indev_deps="CreateDIBSection"
-gdigrab_indev_extralibs="-lgdi32"
-gdigrab_indev_select="bmp_decoder"
-iec61883_indev_deps="libiec61883"
-jack_indev_deps="libjack"
-jack_indev_deps_any="sem_timedwait dispatch_dispatch_h"
-kmsgrab_indev_deps="libdrm"
-lavfi_indev_deps="avfilter"
-libcdio_indev_deps="libcdio"
-libdc1394_indev_deps="libdc1394"
-openal_indev_deps="openal"
-opengl_outdev_deps="opengl"
-opengl_outdev_suggest="sdl2"
-oss_indev_deps_any="sys_soundcard_h"
-oss_outdev_deps_any="sys_soundcard_h"
-pulse_indev_deps="libpulse"
-pulse_outdev_deps="libpulse"
-sdl2_outdev_deps="sdl2"
-sndio_indev_deps="sndio"
-sndio_outdev_deps="sndio"
-v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h"
-v4l2_indev_suggest="libv4l2"
-v4l2_outdev_deps_any="linux_videodev2_h sys_videoio_h"
-v4l2_outdev_suggest="libv4l2"
-vfwcap_indev_deps="vfw32 vfwcap_defines"
-xcbgrab_indev_deps="libxcb"
-xcbgrab_indev_suggest="libxcb_shm libxcb_shape libxcb_xfixes"
-xv_outdev_deps="xlib"
-
-# protocols
-async_protocol_deps="threads"
-bluray_protocol_deps="libbluray"
-ffrtmpcrypt_protocol_conflict="librtmp_protocol"
-ffrtmpcrypt_protocol_deps_any="gcrypt gmp openssl mbedtls"
-ffrtmpcrypt_protocol_select="tcp_protocol"
-ffrtmphttp_protocol_conflict="librtmp_protocol"
-ffrtmphttp_protocol_select="http_protocol"
-ftp_protocol_select="tcp_protocol"
-gopher_protocol_select="network"
-http_protocol_select="tcp_protocol"
-http_protocol_suggest="zlib"
-httpproxy_protocol_select="tcp_protocol"
-httpproxy_protocol_suggest="zlib"
-https_protocol_select="tls_protocol"
-https_protocol_suggest="zlib"
-icecast_protocol_select="http_protocol"
-mmsh_protocol_select="http_protocol"
-mmst_protocol_select="network"
-rtmp_protocol_conflict="librtmp_protocol"
-rtmp_protocol_select="tcp_protocol"
-rtmp_protocol_suggest="zlib"
-rtmpe_protocol_select="ffrtmpcrypt_protocol"
-rtmpe_protocol_suggest="zlib"
-rtmps_protocol_conflict="librtmp_protocol"
-rtmps_protocol_select="tls_protocol"
-rtmps_protocol_suggest="zlib"
-rtmpt_protocol_select="ffrtmphttp_protocol"
-rtmpt_protocol_suggest="zlib"
-rtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
-rtmpte_protocol_suggest="zlib"
-rtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
-rtmpts_protocol_suggest="zlib"
-rtp_protocol_select="udp_protocol"
-schannel_conflict="openssl gnutls libtls mbedtls"
-sctp_protocol_deps="struct_sctp_event_subscribe struct_msghdr_msg_flags"
-sctp_protocol_select="network"
-securetransport_conflict="openssl gnutls libtls mbedtls"
-srtp_protocol_select="rtp_protocol srtp"
-tcp_protocol_select="network"
-tls_protocol_deps_any="gnutls openssl schannel securetransport libtls mbedtls"
-tls_protocol_select="tcp_protocol"
-udp_protocol_select="network"
-udplite_protocol_select="network"
-unix_protocol_deps="sys_un_h"
-unix_protocol_select="network"
-
-# external library protocols
-libamqp_protocol_deps="librabbitmq"
-libamqp_protocol_select="network"
-librtmp_protocol_deps="librtmp"
-librtmpe_protocol_deps="librtmp"
-librtmps_protocol_deps="librtmp"
-librtmpt_protocol_deps="librtmp"
-librtmpte_protocol_deps="librtmp"
-libsmbclient_protocol_deps="libsmbclient gplv3"
-libsrt_protocol_deps="libsrt"
-libsrt_protocol_select="network"
-libssh_protocol_deps="libssh"
-libtls_conflict="openssl gnutls mbedtls"
-libzmq_protocol_deps="libzmq"
-libzmq_protocol_select="network"
-
-# filters
-afftdn_filter_deps="avcodec"
-afftdn_filter_select="fft"
-afftfilt_filter_deps="avcodec"
-afftfilt_filter_select="fft"
-afir_filter_deps="avcodec"
-afir_filter_select="rdft"
-amovie_filter_deps="avcodec avformat"
-aresample_filter_deps="swresample"
-asr_filter_deps="pocketsphinx"
-ass_filter_deps="libass"
-atempo_filter_deps="avcodec"
-atempo_filter_select="rdft"
-avgblur_opencl_filter_deps="opencl"
-avgblur_vulkan_filter_deps="vulkan libglslang"
-azmq_filter_deps="libzmq"
-blackframe_filter_deps="gpl"
-bm3d_filter_deps="avcodec"
-bm3d_filter_select="dct"
-boxblur_filter_deps="gpl"
-boxblur_opencl_filter_deps="opencl gpl"
-bs2b_filter_deps="libbs2b"
-chromaber_vulkan_filter_deps="vulkan libglslang"
-colorkey_opencl_filter_deps="opencl"
-colormatrix_filter_deps="gpl"
-convolution_opencl_filter_deps="opencl"
-convolve_filter_deps="avcodec"
-convolve_filter_select="fft"
-coreimage_filter_deps="coreimage appkit"
-coreimage_filter_extralibs="-framework OpenGL"
-coreimagesrc_filter_deps="coreimage appkit"
-coreimagesrc_filter_extralibs="-framework OpenGL"
-cover_rect_filter_deps="avcodec avformat gpl"
-cropdetect_filter_deps="gpl"
-deconvolve_filter_deps="avcodec"
-deconvolve_filter_select="fft"
-deinterlace_qsv_filter_deps="libmfx"
-deinterlace_vaapi_filter_deps="vaapi"
-delogo_filter_deps="gpl"
-denoise_vaapi_filter_deps="vaapi"
-derain_filter_select="dnn"
-deshake_filter_select="pixelutils"
-deshake_opencl_filter_deps="opencl"
-dilation_opencl_filter_deps="opencl"
-dnn_processing_filter_deps="swscale"
-dnn_processing_filter_select="dnn"
-drawtext_filter_deps="libfreetype"
-drawtext_filter_suggest="libfontconfig libfribidi"
-elbg_filter_deps="avcodec"
-eq_filter_deps="gpl"
-erosion_opencl_filter_deps="opencl"
-fftfilt_filter_deps="avcodec"
-fftfilt_filter_select="rdft"
-fftdnoiz_filter_deps="avcodec"
-fftdnoiz_filter_select="fft"
-find_rect_filter_deps="avcodec avformat gpl"
-firequalizer_filter_deps="avcodec"
-firequalizer_filter_select="rdft"
-flite_filter_deps="libflite"
-framerate_filter_select="scene_sad"
-freezedetect_filter_select="scene_sad"
-frei0r_filter_deps="frei0r libdl"
-frei0r_src_filter_deps="frei0r libdl"
-fspp_filter_deps="gpl"
-headphone_filter_select="fft"
-histeq_filter_deps="gpl"
-hqdn3d_filter_deps="gpl"
-interlace_filter_deps="gpl"
-kerndeint_filter_deps="gpl"
-ladspa_filter_deps="ladspa libdl"
-lensfun_filter_deps="liblensfun version3"
-lv2_filter_deps="lv2"
-mcdeint_filter_deps="avcodec gpl"
-movie_filter_deps="avcodec avformat"
-mpdecimate_filter_deps="gpl"
-mpdecimate_filter_select="pixelutils"
-minterpolate_filter_select="scene_sad"
-mptestsrc_filter_deps="gpl"
-negate_filter_deps="lut_filter"
-nlmeans_opencl_filter_deps="opencl"
-nnedi_filter_deps="gpl"
-ocr_filter_deps="libtesseract"
-ocv_filter_deps="libopencv"
-openclsrc_filter_deps="opencl"
-overlay_opencl_filter_deps="opencl"
-overlay_qsv_filter_deps="libmfx"
-overlay_qsv_filter_select="qsvvpp"
-overlay_vulkan_filter_deps="vulkan libglslang"
-owdenoise_filter_deps="gpl"
-pad_opencl_filter_deps="opencl"
-pan_filter_deps="swresample"
-perspective_filter_deps="gpl"
-phase_filter_deps="gpl"
-pp7_filter_deps="gpl"
-pp_filter_deps="gpl postproc"
-prewitt_opencl_filter_deps="opencl"
-procamp_vaapi_filter_deps="vaapi"
-program_opencl_filter_deps="opencl"
-pullup_filter_deps="gpl"
-removelogo_filter_deps="avcodec avformat swscale"
-repeatfields_filter_deps="gpl"
-resample_filter_deps="avresample"
-roberts_opencl_filter_deps="opencl"
-rubberband_filter_deps="librubberband"
-sab_filter_deps="gpl swscale"
-scale2ref_filter_deps="swscale"
-scale_filter_deps="swscale"
-scale_qsv_filter_deps="libmfx"
-scdet_filter_select="scene_sad"
-select_filter_select="scene_sad"
-sharpness_vaapi_filter_deps="vaapi"
-showcqt_filter_deps="avcodec avformat swscale"
-showcqt_filter_suggest="libfontconfig libfreetype"
-showcqt_filter_select="fft"
-showfreqs_filter_deps="avcodec"
-showfreqs_filter_select="fft"
-showspatial_filter_select="fft"
-showspectrum_filter_deps="avcodec"
-showspectrum_filter_select="fft"
-showspectrumpic_filter_deps="avcodec"
-showspectrumpic_filter_select="fft"
-signature_filter_deps="gpl avcodec avformat"
-sinc_filter_select="rdft"
-smartblur_filter_deps="gpl swscale"
-sobel_opencl_filter_deps="opencl"
-sofalizer_filter_deps="libmysofa avcodec"
-sofalizer_filter_select="fft"
-spectrumsynth_filter_deps="avcodec"
-spectrumsynth_filter_select="fft"
-spp_filter_deps="gpl avcodec"
-spp_filter_select="fft idctdsp fdctdsp me_cmp pixblockdsp"
-sr_filter_deps="avformat swscale"
-sr_filter_select="dnn"
-stereo3d_filter_deps="gpl"
-subtitles_filter_deps="avformat avcodec libass"
-super2xsai_filter_deps="gpl"
-pixfmts_super2xsai_test_deps="super2xsai_filter"
-superequalizer_filter_select="rdft"
-surround_filter_select="rdft"
-tinterlace_filter_deps="gpl"
-tinterlace_merge_test_deps="tinterlace_filter"
-tinterlace_pad_test_deps="tinterlace_filter"
-tonemap_filter_deps="const_nan"
-tonemap_vaapi_filter_deps="vaapi VAProcFilterParameterBufferHDRToneMapping"
-tonemap_opencl_filter_deps="opencl const_nan"
-transpose_opencl_filter_deps="opencl"
-transpose_vaapi_filter_deps="vaapi VAProcPipelineCaps_rotation_flags"
-unsharp_opencl_filter_deps="opencl"
-uspp_filter_deps="gpl avcodec"
-vaguedenoiser_filter_deps="gpl"
-vidstabdetect_filter_deps="libvidstab"
-vidstabtransform_filter_deps="libvidstab"
-libvmaf_filter_deps="libvmaf pthreads"
-zmq_filter_deps="libzmq"
-zoompan_filter_deps="swscale"
-zscale_filter_deps="libzimg const_nan"
-scale_vaapi_filter_deps="vaapi"
-scale_vulkan_filter_deps="vulkan libglslang"
-vpp_qsv_filter_deps="libmfx"
-vpp_qsv_filter_select="qsvvpp"
-xfade_opencl_filter_deps="opencl"
-yadif_cuda_filter_deps="ffnvcodec"
-yadif_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
-
-# examples
-avio_list_dir_deps="avformat avutil"
-avio_reading_deps="avformat avcodec avutil"
-decode_audio_example_deps="avcodec avutil"
-decode_video_example_deps="avcodec avutil"
-demuxing_decoding_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"
-transcode_aac_example_deps="avcodec avformat swresample"
-transcoding_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"
-
-# EXTRALIBS_LIST
-cpu_init_extralibs="pthreads_extralibs"
-cws2fws_extralibs="zlib_extralibs"
-
-# libraries, in any order
-avcodec_deps="avutil"
-avcodec_suggest="libm"
-avcodec_select="null_bsf"
-avdevice_deps="avformat avcodec avutil"
-avdevice_suggest="libm"
-avfilter_deps="avutil"
-avfilter_suggest="libm"
-avformat_deps="avcodec avutil"
-avformat_suggest="libm network zlib"
-avresample_deps="avutil"
-avresample_suggest="libm"
-avutil_suggest="clock_gettime ffnvcodec libm libdrm libmfx opencl user32 vaapi vulkan videotoolbox corefoundation corevideo coremedia bcrypt"
-postproc_deps="avutil gpl"
-postproc_suggest="libm"
-swresample_deps="avutil"
-swresample_suggest="libm libsoxr"
-swscale_deps="avutil"
-swscale_suggest="libm"
-
-avcodec_extralibs="pthreads_extralibs iconv_extralibs dxva2_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_select="aformat_filter anull_filter atrim_filter format_filter
- hflip_filter null_filter
- transpose_filter trim_filter vflip_filter"
-ffmpeg_suggest="ole32 psapi shell32"
-ffplay_deps="avcodec avformat swscale swresample sdl2"
-ffplay_select="rdft crop_filter transpose_filter hflip_filter vflip_filter rotate_filter"
-ffplay_suggest="shell32"
-ffprobe_deps="avcodec avformat"
-ffprobe_suggest="shell32"
-
-# documentation
-podpages_deps="perl"
-manpages_deps="perl pod2man"
-htmlpages_deps="perl"
-htmlpages_deps_any="makeinfo_html texi2html"
-txtpages_deps="perl makeinfo"
-doc_deps_any="manpages htmlpages podpages txtpages"
-
-# default parameters
-
-logfile="ffbuild/config.log"
-
-# installation paths
-prefix_default="/usr/local"
-bindir_default='${prefix}/bin'
-datadir_default='${prefix}/share/ffmpeg'
-docdir_default='${prefix}/share/doc/ffmpeg'
-incdir_default='${prefix}/include'
-libdir_default='${prefix}/lib'
-mandir_default='${prefix}/share/man'
-
-# toolchain
-ar_default="ar"
-cc_default="gcc"
-cxx_default="g++"
-host_cc_default="gcc"
-doxygen_default="doxygen"
-install="install"
-ln_s_default="ln -s -f"
-nm_default="nm -g"
-pkg_config_default=pkg-config
-ranlib_default="ranlib"
-strip_default="strip"
-version_script='--version-script'
-objformat="elf32"
-x86asmexe_default="nasm"
-windres_default="windres"
-striptype="direct"
-
-# OS
-target_os_default=$(tolower $(uname -s))
-host_os=$target_os_default
-
-# machine
-if test "$target_os_default" = aix; then
- arch_default=$(uname -p)
- strip_default="strip -X32_64"
- nm_default="nm -g -X32_64"
-else
- arch_default=$(uname -m)
-fi
-cpu="generic"
-intrinsics="none"
-
-# configurable options
-enable $PROGRAM_LIST
-enable $DOCUMENT_LIST
-enable $EXAMPLE_LIST
-enable $(filter_out avresample $LIBRARY_LIST)
-enable stripping
-
-enable asm
-enable debug
-enable doc
-enable faan faandct faanidct
-enable large_tests
-enable optimizations
-enable runtime_cpudetect
-enable safe_bitstream_reader
-enable static
-enable swscale_alpha
-enable valgrind_backtrace
-
-sws_max_filter_size_default=256
-set_default sws_max_filter_size
-
-# internal components are enabled by default
-enable $EXTRALIBS_LIST
-
-# Avoid external, non-system, libraries getting enabled by dependency resolution
-disable $EXTERNAL_LIBRARY_LIST $HWACCEL_LIBRARY_LIST
-
-# build settings
-SHFLAGS='-shared -Wl,-soname,$$(@F)'
-LIBPREF="lib"
-LIBSUF=".a"
-FULLNAME='$(NAME)$(BUILDSUF)'
-LIBNAME='$(LIBPREF)$(FULLNAME)$(LIBSUF)'
-SLIBPREF="lib"
-SLIBSUF=".so"
-SLIBNAME='$(SLIBPREF)$(FULLNAME)$(SLIBSUF)'
-SLIBNAME_WITH_VERSION='$(SLIBNAME).$(LIBVERSION)'
-SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
-LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
-SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
-SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'
-VERSION_SCRIPT_POSTPROCESS_CMD="cat"
-
-asflags_filter=echo
-cflags_filter=echo
-ldflags_filter=echo
-
-AS_C='-c'
-AS_O='-o $@'
-CC_C='-c'
-CC_E='-E -o $@'
-CC_O='-o $@'
-CXX_C='-c'
-CXX_O='-o $@'
-OBJCC_C='-c'
-OBJCC_E='-E -o $@'
-OBJCC_O='-o $@'
-X86ASM_O='-o $@'
-LD_O='-o $@'
-LD_LIB='-l%'
-LD_PATH='-L'
-HOSTCC_C='-c'
-HOSTCC_E='-E -o $@'
-HOSTCC_O='-o $@'
-HOSTLD_O='-o $@'
-NVCC_C='-c'
-NVCC_O='-o $@'
-
-host_extralibs='-lm'
-host_cflags_filter=echo
-host_ldflags_filter=echo
-
-target_path='$(CURDIR)'
-
-# since the object filename is not given with the -MM flag, the compiler
-# is only able to print the basename, and we must add the path ourselves
-DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< 2>/dev/null | sed -e "/^\#.*/d" -e "s,^[[:space:]]*$(@F),$(@D)/$(@F)," > $(@:.o=.d)'
-DEPFLAGS='-MM'
-
-mkdir -p ffbuild
-
-# find source path
-if test -f configure; then
- source_path=.
-elif test -f src/configure; then
- source_path=src
-else
- source_path=$(cd $(dirname "$0"); pwd)
- case "$source_path" in
- *[[:blank:]]*) die "Out of tree builds are impossible with whitespace in source path." ;;
- esac
- test -e "$source_path/config.h" &&
- die "Out of tree builds are impossible with config.h in source dir."
-fi
-
-for v in "$@"; do
- r=${v#*=}
- l=${v%"$r"}
- r=$(sh_quote "$r")
- FFMPEG_CONFIGURATION="${FFMPEG_CONFIGURATION# } ${l}${r}"
-done
-
-find_things_extern(){
- thing=$1
- pattern=$2
- file=$source_path/$3
- out=${4:-$thing}
- sed -n "s/^[^#]*extern.*$pattern *ff_\([^ ]*\)_$thing;/\1_$out/p" "$file"
-}
-
-find_filters_extern(){
- file=$source_path/$1
- sed -n 's/^extern AVFilter ff_[avfsinkrc]\{2,5\}_\([[:alnum:]_]\{1,\}\);/\1_filter/p' $file
-}
-
-FILTER_LIST=$(find_filters_extern libavfilter/allfilters.c)
-OUTDEV_LIST=$(find_things_extern muxer AVOutputFormat 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)
-DEMUXER_LIST=$(find_things_extern demuxer AVInputFormat libavformat/allformats.c)
-ENCODER_LIST=$(find_things_extern encoder AVCodec libavcodec/allcodecs.c)
-DECODER_LIST=$(find_things_extern decoder AVCodec libavcodec/allcodecs.c)
-CODEC_LIST="
- $ENCODER_LIST
- $DECODER_LIST
-"
-PARSER_LIST=$(find_things_extern parser AVCodecParser libavcodec/parsers.c)
-BSF_LIST=$(find_things_extern bsf AVBitStreamFilter libavcodec/bitstream_filters.c)
-HWACCEL_LIST=$(find_things_extern hwaccel AVHWAccel libavcodec/hwaccels.h)
-PROTOCOL_LIST=$(find_things_extern protocol URLProtocol libavformat/protocols.c)
-
-AVCODEC_COMPONENTS_LIST="
- $BSF_LIST
- $DECODER_LIST
- $ENCODER_LIST
- $HWACCEL_LIST
- $PARSER_LIST
-"
-
-AVDEVICE_COMPONENTS_LIST="
- $INDEV_LIST
- $OUTDEV_LIST
-"
-
-AVFILTER_COMPONENTS_LIST="
- $FILTER_LIST
-"
-
-AVFORMAT_COMPONENTS_LIST="
- $DEMUXER_LIST
- $MUXER_LIST
- $PROTOCOL_LIST
-"
-
-ALL_COMPONENTS="
- $AVCODEC_COMPONENTS_LIST
- $AVDEVICE_COMPONENTS_LIST
- $AVFILTER_COMPONENTS_LIST
- $AVFORMAT_COMPONENTS_LIST
-"
-
-for n in $COMPONENT_LIST; do
- v=$(toupper ${n%s})_LIST
- eval enable \$$v
- eval ${n}_if_any="\$$v"
-done
-
-enable $ARCH_EXT_LIST
-
-die_unknown(){
- echo "Unknown option \"$1\"."
- echo "See $0 --help for available options."
- exit 1
-}
-
-print_in_columns() {
- tr ' ' '\n' | sort | tr '\r\n' ' ' | awk -v col_width=24 -v width="$ncols" '
- {
- num_cols = width > col_width ? int(width / col_width) : 1;
- num_rows = int((NF + num_cols-1) / num_cols);
- y = x = 1;
- for (y = 1; y <= num_rows; y++) {
- i = y;
- for (x = 1; x <= num_cols; x++) {
- if (i <= NF) {
- line = sprintf("%s%-" col_width "s", line, $i);
- }
- i = i + num_rows;
- }
- print line; line = "";
- }
- }' | sed 's/ *$//'
-}
-
-show_list() {
- suffix=_$1
- shift
- echo $* | sed s/$suffix//g | print_in_columns
- exit 0
-}
-
-rand_list(){
- IFS=', '
- set -- $*
- unset IFS
- for thing; do
- comp=${thing%:*}
- prob=${thing#$comp}
- prob=${prob#:}
- is_in ${comp} $COMPONENT_LIST && eval comp=\$$(toupper ${comp%s})_LIST
- echo "prob ${prob:-0.5}"
- printf '%s\n' $comp
- done
-}
-
-do_random(){
- action=$1
- shift
- random_seed=$(awk "BEGIN { srand($random_seed); print srand() }")
- $action $(rand_list "$@" | awk "BEGIN { srand($random_seed) } \$1 == \"prob\" { prob = \$2; next } rand() < prob { print }")
-}
-
-for opt do
- optval="${opt#*=}"
- case "$opt" in
- --extra-ldflags=*)
- add_ldflags $optval
- ;;
- --extra-ldexeflags=*)
- add_ldexeflags $optval
- ;;
- --extra-ldsoflags=*)
- add_ldsoflags $optval
- ;;
- --extra-ldlibflags=*)
- warn "The --extra-ldlibflags option is only provided for compatibility and will be\n"\
- "removed in the future. Use --extra-ldsoflags instead."
- add_ldsoflags $optval
- ;;
- --extra-libs=*)
- add_extralibs $optval
- ;;
- --disable-devices)
- disable $INDEV_LIST $OUTDEV_LIST
- ;;
- --enable-debug=*)
- debuglevel="$optval"
- ;;
- --disable-programs)
- disable $PROGRAM_LIST
- ;;
- --disable-everything)
- map 'eval unset \${$(toupper ${v%s})_LIST}' $COMPONENT_LIST
- ;;
- --disable-all)
- map 'eval unset \${$(toupper ${v%s})_LIST}' $COMPONENT_LIST
- disable $LIBRARY_LIST $PROGRAM_LIST doc
- enable avutil
- ;;
- --enable-random|--disable-random)
- action=${opt%%-random}
- do_random ${action#--} $COMPONENT_LIST
- ;;
- --enable-random=*|--disable-random=*)
- action=${opt%%-random=*}
- do_random ${action#--} $optval
- ;;
- --enable-sdl)
- enable sdl2
- ;;
- --enable-*=*|--disable-*=*)
- eval $(echo "${opt%%=*}" | sed 's/--/action=/;s/-/ thing=/')
- is_in "${thing}s" $COMPONENT_LIST || die_unknown "$opt"
- eval list=\$$(toupper $thing)_LIST
- name=$(echo "${optval}" | sed "s/,/_${thing}|/g")_${thing}
- list=$(filter "$name" $list)
- [ "$list" = "" ] && warn "Option $opt did not match anything"
- test $action = enable && warn_if_gets_disabled $list
- $action $list
- ;;
- --enable-yasm|--disable-yasm)
- warn "The ${opt} option is only provided for compatibility and will be\n"\
- "removed in the future. Use --enable-x86asm / --disable-x86asm instead."
- test $opt = --enable-yasm && x86asm=yes || x86asm=no
- ;;
- --yasmexe=*)
- warn "The --yasmexe option is only provided for compatibility and will be\n"\
- "removed in the future. Use --x86asmexe instead."
- x86asmexe="$optval"
- ;;
- --enable-?*|--disable-?*)
- eval $(echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g')
- if is_in $option $COMPONENT_LIST; then
- test $action = disable && action=unset
- eval $action \$$(toupper ${option%s})_LIST
- elif is_in $option $CMDLINE_SELECT; then
- $action $option
- else
- die_unknown $opt
- fi
- ;;
- --list-*)
- NAME="${opt#--list-}"
- is_in $NAME $COMPONENT_LIST || die_unknown $opt
- NAME=${NAME%s}
- eval show_list $NAME \$$(toupper $NAME)_LIST
- ;;
- --help|-h) show_help
- ;;
- --quiet|-q) quiet=yes
- ;;
- --fatal-warnings) enable fatal_warnings
- ;;
- --libfuzzer=*)
- libfuzzer_path="$optval"
- ;;
- *)
- optname="${opt%%=*}"
- optname="${optname#--}"
- optname=$(echo "$optname" | sed 's/-/_/g')
- if is_in $optname $CMDLINE_SET; then
- eval $optname='$optval'
- elif is_in $optname $CMDLINE_APPEND; then
- append $optname "$optval"
- else
- die_unknown $opt
- fi
- ;;
- esac
-done
-
-for e in $env; do
- eval "export $e"
-done
-
-if disabled autodetect; then
-
- # Unless iconv is explicitely disabled by the user, we still want to probe
- # for the iconv from the libc.
- disabled iconv || enable libc_iconv
-
- disable_weak $EXTERNAL_AUTODETECT_LIBRARY_LIST
- disable_weak $HWACCEL_AUTODETECT_LIBRARY_LIST
-fi
-# Mark specifically enabled, but normally autodetected libraries as requested.
-for lib in $AUTODETECT_LIBS; do
- enabled $lib && request $lib
-done
-#TODO: switch to $AUTODETECT_LIBS when $THREADS_LIST is supported the same way
-enable_weak $EXTERNAL_AUTODETECT_LIBRARY_LIST
-enable_weak $HWACCEL_AUTODETECT_LIBRARY_LIST
-
-disabled logging && logfile=/dev/null
-
-# command line configuration sanity checks
-
-# we need to build at least one lib type
-if ! enabled_any static shared; then
- cat <<EOF
-At least one library type must be built.
-Specify --enable-static to build the static libraries or --enable-shared to
-build the shared libraries as well. To only build the shared libraries specify
---disable-static in addition to --enable-shared.
-EOF
- exit 1
-fi
-
-die_license_disabled() {
- enabled $1 || { enabled $v && die "$v is $1 and --enable-$1 is not specified."; }
-}
-
-die_license_disabled_gpl() {
- enabled $1 || { enabled $v && die "$v is incompatible with the gpl and --enable-$1 is not specified."; }
-}
-
-map "die_license_disabled gpl" $EXTERNAL_LIBRARY_GPL_LIST $EXTERNAL_LIBRARY_GPLV3_LIST
-map "die_license_disabled version3" $EXTERNAL_LIBRARY_VERSION3_LIST $EXTERNAL_LIBRARY_GPLV3_LIST
-
-enabled gpl && map "die_license_disabled_gpl nonfree" $EXTERNAL_LIBRARY_NONFREE_LIST
-map "die_license_disabled nonfree" $HWACCEL_LIBRARY_NONFREE_LIST
-
-enabled version3 && { enabled gpl && enable gplv3 || enable lgplv3; }
-
-if enabled nonfree; then
- license="nonfree and unredistributable"
-elif enabled gplv3; then
- license="GPL version 3 or later"
-elif enabled lgplv3; then
- license="LGPL version 3 or later"
-elif enabled gpl; then
- license="GPL version 2 or later"
-else
- license="LGPL version 2.1 or later"
-fi
-
-enabled_all gnutls openssl &&
- die "GnuTLS and OpenSSL must not be enabled at the same time."
-
-enabled_all gnutls mbedtls &&
- die "GnuTLS and mbedTLS must not be enabled at the same time."
-
-enabled_all openssl mbedtls &&
- die "OpenSSL and mbedTLS must not be enabled at the same time."
-
-# Disable all the library-specific components if the library itself
-# is disabled, see AVCODEC_LIST and following _LIST variables.
-
-disable_components(){
- disabled ${1} && disable $(
- eval components="\$$(toupper ${1})_COMPONENTS"
- map 'eval echo \${$(toupper ${v%s})_LIST}' $components
- )
-}
-
-map 'disable_components $v' $LIBRARY_LIST
-
-echo "# $0 $FFMPEG_CONFIGURATION" > $logfile
-set >> $logfile
-
-test -n "$valgrind" && toolchain="valgrind-memcheck"
-
-enabled ossfuzz && ! echo $CFLAGS | grep -q -- "-fsanitize=" && ! echo $CFLAGS | grep -q -- "-fcoverage-mapping" &&{
- add_cflags -fsanitize=address,undefined -fsanitize-coverage=trace-pc-guard,trace-cmp -fno-omit-frame-pointer
- add_ldflags -fsanitize=address,undefined -fsanitize-coverage=trace-pc-guard,trace-cmp
-}
-
-case "$toolchain" in
- *-asan)
- cc_default="${toolchain%-asan}"
- add_cflags -fsanitize=address
- add_ldflags -fsanitize=address
- ;;
- *-msan)
- cc_default="${toolchain%-msan}"
- add_cflags -fsanitize=memory -fsanitize-memory-track-origins
- add_ldflags -fsanitize=memory
- ;;
- *-tsan)
- cc_default="${toolchain%-tsan}"
- add_cflags -fsanitize=thread
- add_ldflags -fsanitize=thread
- case "$toolchain" in
- gcc-tsan)
- add_cflags -fPIC
- add_ldflags -fPIC
- ;;
- esac
- ;;
- *-usan)
- cc_default="${toolchain%-usan}"
- add_cflags -fsanitize=undefined
- add_ldflags -fsanitize=undefined
- ;;
- valgrind-*)
- target_exec_default="valgrind"
- case "$toolchain" in
- valgrind-massif)
- target_exec_args="--tool=massif --alloc-fn=av_malloc --alloc-fn=av_mallocz --alloc-fn=av_calloc --alloc-fn=av_fast_padded_malloc --alloc-fn=av_fast_malloc --alloc-fn=av_realloc_f --alloc-fn=av_fast_realloc --alloc-fn=av_realloc"
- ;;
- valgrind-memcheck)
- target_exec_args="--error-exitcode=1 --malloc-fill=0x2a --track-origins=yes --leak-check=full --gen-suppressions=all --suppressions=$source_path/tests/fate-valgrind.supp"
- ;;
- 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"
- cxx_default="cl.exe"
- else
- die "Unsupported MSVC version (2013 or newer required)"
- fi
- ld_default="$source_path/compat/windows/mslink"
- nm_default="dumpbin.exe -symbols"
- ar_default="lib.exe"
- case "$arch" in
- aarch64|arm64)
- as_default="armasm64.exe"
- ;;
- arm*)
- as_default="armasm.exe"
- ;;
- esac
- target_os_default="win32"
- # Use a relative path for TMPDIR. This makes sure all the
- # ffconf temp files are written with a relative path, avoiding
- # issues with msys/win32 path conversion for MSVC parameters
- # such as -Fo<file> or -out:<file>.
- TMPDIR=.
- ;;
- icl)
- cc_default="icl"
- ld_default="xilink"
- nm_default="dumpbin -symbols"
- ar_default="xilib"
- target_os_default="win32"
- TMPDIR=.
- ;;
- gcov)
- add_cflags -fprofile-arcs -ftest-coverage
- add_ldflags -fprofile-arcs -ftest-coverage
- ;;
- llvm-cov)
- add_cflags -fprofile-arcs -ftest-coverage
- add_ldflags --coverage
- ;;
- hardened)
- add_cppflags -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2
- add_cflags -fno-strict-overflow -fstack-protector-all
- add_ldflags -Wl,-z,relro -Wl,-z,now
- add_cflags -fPIE
- add_ldexeflags -fPIE -pie
- ;;
- ?*)
- die "Unknown toolchain $toolchain"
- ;;
-esac
-
-if test -n "$cross_prefix"; then
- test -n "$arch" && test -n "$target_os" ||
- die "Must specify target arch (--arch) and OS (--target-os) when cross-compiling"
- enable cross_compile
-fi
-
-set_default target_os
-if test "$target_os" = android; then
- cc_default="clang"
-fi
-
-ar_default="${cross_prefix}${ar_default}"
-cc_default="${cross_prefix}${cc_default}"
-cxx_default="${cross_prefix}${cxx_default}"
-nm_default="${cross_prefix}${nm_default}"
-pkg_config_default="${cross_prefix}${pkg_config_default}"
-if ${cross_prefix}${ranlib_default} 2>&1 | grep -q "\-D "; then
- ranlib_default="${cross_prefix}${ranlib_default} -D"
-else
- ranlib_default="${cross_prefix}${ranlib_default}"
-fi
-strip_default="${cross_prefix}${strip_default}"
-windres_default="${cross_prefix}${windres_default}"
-
-sysinclude_default="${sysroot}/usr/include"
-
-if enabled cuda_sdk; then
- warn "Option --enable-cuda-sdk is deprecated. Use --enable-cuda-nvcc instead."
- enable cuda_nvcc
-fi
-
-if enabled cuda_nvcc; then
- nvcc_default="nvcc"
- nvccflags_default="-gencode arch=compute_30,code=sm_30 -O2"
-else
- nvcc_default="clang"
- nvccflags_default="--cuda-gpu-arch=sm_30 -O2"
- NVCC_C=""
-fi
-
-set_default arch cc cxx doxygen pkg_config ranlib strip sysinclude \
- target_exec x86asmexe nvcc
-enabled cross_compile || host_cc_default=$cc
-set_default host_cc
-
-pkg_config_fail_message=""
-if ! $pkg_config --version >/dev/null 2>&1; then
- warn "$pkg_config not found, library detection may fail."
- pkg_config=false
-elif is_in -static $cc $LDFLAGS && ! is_in --static $pkg_config $pkg_config_flags; then
- pkg_config_fail_message="
-Note: When building a static binary, add --pkg-config-flags=\"--static\"."
-fi
-
-if test $doxygen != $doxygen_default && \
- ! $doxygen --version >/dev/null 2>&1; then
- warn "Specified doxygen \"$doxygen\" not found, API documentation will fail to build."
-fi
-
-exesuf() {
- case $1 in
- mingw32*|mingw64*|win32|win64|cygwin*|*-dos|freedos|opendos|os/2*|symbian) echo .exe ;;
- esac
-}
-
-EXESUF=$(exesuf $target_os)
-HOSTEXESUF=$(exesuf $host_os)
-
-# set temporary file name
-: ${TMPDIR:=$TEMPDIR}
-: ${TMPDIR:=$TMP}
-: ${TMPDIR:=/tmp}
-
-if [ -n "$tempprefix" ] ; then
- mktemp(){
- tmpname="$tempprefix.${HOSTNAME}.${UID}"
- echo "$tmpname"
- mkdir "$tmpname"
- }
-elif ! test_cmd mktemp -u XXXXXX; then
- # simple replacement for missing mktemp
- # NOT SAFE FOR GENERAL USE
- mktemp(){
- tmpname="${2%%XXX*}.${HOSTNAME}.${UID}.$$"
- echo "$tmpname"
- mkdir "$tmpname"
- }
-fi
-
-FFTMPDIR=$(mktemp -d "${TMPDIR}/ffconf.XXXXXXXX" 2> /dev/null) ||
- die "Unable to create temporary directory in $TMPDIR."
-
-tmpfile(){
- tmp="${FFTMPDIR}/test"$2
- (set -C; exec > $tmp) 2> /dev/null ||
- die "Unable to create temporary file in $FFTMPDIR."
- eval $1=$tmp
-}
-
-trap 'rm -rf -- "$FFTMPDIR"' EXIT
-trap 'exit 2' INT
-
-tmpfile TMPASM .asm
-tmpfile TMPC .c
-tmpfile TMPCPP .cpp
-tmpfile TMPE $EXESUF
-tmpfile TMPH .h
-tmpfile TMPM .m
-tmpfile TMPCU .cu
-tmpfile TMPO .o
-tmpfile TMPS .S
-tmpfile TMPSH .sh
-tmpfile TMPV .ver
-
-unset -f mktemp
-
-chmod +x $TMPE
-
-# make sure we can execute files in $TMPDIR
-cat > $TMPSH 2>> $logfile <<EOF
-#! /bin/sh
-EOF
-chmod +x $TMPSH >> $logfile 2>&1
-if ! $TMPSH >> $logfile 2>&1; then
- cat <<EOF
-Unable to create and execute files in $TMPDIR. Set the TMPDIR environment
-variable to another directory and make sure that it is not mounted noexec.
-EOF
- die "Sanity test failed."
-fi
-
-armasm_flags(){
- for flag; do
- case $flag in
- # Filter out MSVC cl.exe options from cflags that shouldn't
- # be passed to gas-preprocessor
- -M[TD]*) ;;
- *) echo $flag ;;
- esac
- done
-}
-
-cparser_flags(){
- for flag; do
- case $flag in
- -Wno-switch) echo -Wno-switch-enum ;;
- -Wno-format-zero-length) ;;
- -Wdisabled-optimization) ;;
- -Wno-pointer-sign) echo -Wno-other ;;
- *) echo $flag ;;
- esac
- done
-}
-
-msvc_common_flags(){
- for flag; do
- case $flag in
- # In addition to specifying certain flags under the compiler
- # specific filters, they must be specified here as well or else the
- # generic catch all at the bottom will print the original flag.
- -Wall) ;;
- -Wextra) ;;
- -std=c*) ;;
- # Common flags
- -fomit-frame-pointer) ;;
- -g) echo -Z7 ;;
- -fno-math-errno) ;;
- -fno-common) ;;
- -fno-signed-zeros) ;;
- -fPIC) ;;
- -mthumb) ;;
- -march=*) ;;
- -lz) echo zlib.lib ;;
- -lx264) echo libx264.lib ;;
- -lstdc++) ;;
- -l*) echo ${flag#-l}.lib ;;
- -LARGEADDRESSAWARE) echo $flag ;;
- -L*) echo -libpath:${flag#-L} ;;
- -Wl,*) ;;
- *) echo $flag ;;
- esac
- done
-}
-
-msvc_flags(){
- msvc_common_flags "$@"
- for flag; do
- case $flag in
- -Wall) echo -W3 -wd4018 -wd4146 -wd4244 -wd4305 \
- -wd4554 ;;
- -Wextra) echo -W4 -wd4244 -wd4127 -wd4018 -wd4389 \
- -wd4146 -wd4057 -wd4204 -wd4706 -wd4305 \
- -wd4152 -wd4324 -we4013 -wd4100 -wd4214 \
- -wd4307 \
- -wd4273 -wd4554 -wd4701 -wd4703 ;;
- esac
- done
-}
-
-icl_flags(){
- msvc_common_flags "$@"
- for flag; do
- case $flag in
- # Despite what Intel's documentation says -Wall, which is supported
- # on Windows, does enable remarks so disable them here.
- -Wall) echo $flag -Qdiag-disable:remark ;;
- -std=c99) echo -Qstd=c99 ;;
- -flto) echo -ipo ;;
- esac
- done
-}
-
-icc_flags(){
- for flag; do
- case $flag in
- -flto) echo -ipo ;;
- *) echo $flag ;;
- esac
- done
-}
-
-suncc_flags(){
- for flag; do
- case $flag in
- -march=*|-mcpu=*)
- case "${flag#*=}" in
- native) echo -xtarget=native ;;
- v9|niagara) echo -xarch=sparc ;;
- ultrasparc) echo -xarch=sparcvis ;;
- ultrasparc3|niagara2) echo -xarch=sparcvis2 ;;
- i586|pentium) echo -xchip=pentium ;;
- i686|pentiumpro|pentium2) echo -xtarget=pentium_pro ;;
- pentium3*|c3-2) echo -xtarget=pentium3 ;;
- pentium-m) echo -xarch=sse2 -xchip=pentium3 ;;
- pentium4*) echo -xtarget=pentium4 ;;
- prescott|nocona) echo -xarch=sse3 -xchip=pentium4 ;;
- *-sse3) echo -xarch=sse3 ;;
- core2) echo -xarch=ssse3 -xchip=core2 ;;
- bonnell) echo -xarch=ssse3 ;;
- corei7|nehalem) echo -xtarget=nehalem ;;
- westmere) echo -xtarget=westmere ;;
- silvermont) echo -xarch=sse4_2 ;;
- corei7-avx|sandybridge) echo -xtarget=sandybridge ;;
- core-avx*|ivybridge|haswell|broadwell|skylake*|knl)
- echo -xarch=avx ;;
- amdfam10|barcelona) echo -xtarget=barcelona ;;
- btver1) echo -xarch=amdsse4a ;;
- btver2|bdver*|znver*) echo -xarch=avx ;;
- athlon-4|athlon-[mx]p) echo -xarch=ssea ;;
- k8|opteron|athlon64|athlon-fx)
- echo -xarch=sse2a ;;
- athlon*) echo -xarch=pentium_proa ;;
- esac
- ;;
- -std=c99) echo -xc99 ;;
- -fomit-frame-pointer) echo -xregs=frameptr ;;
- -fPIC) echo -KPIC -xcode=pic32 ;;
- -W*,*) echo $flag ;;
- -f*-*|-W*|-mimpure-text) ;;
- -shared) echo -G ;;
- *) echo $flag ;;
- esac
- done
-}
-
-probe_cc(){
- pfx=$1
- _cc=$2
- first=$3
-
- unset _type _ident _cc_c _cc_e _cc_o _flags _cflags
- unset _ld_o _ldflags _ld_lib _ld_path
- unset _depflags _DEPCMD _DEPFLAGS
- _flags_filter=echo
-
- if $_cc --version 2>&1 | grep -q '^GNU assembler'; then
- true # no-op to avoid reading stdin in following checks
- elif $_cc -v 2>&1 | grep -q '^gcc.*LLVM'; then
- _type=llvm_gcc
- gcc_extra_ver=$(expr "$($_cc --version 2>/dev/null | head -n1)" : '.*\((.*)\)')
- _ident="llvm-gcc $($_cc -dumpversion 2>/dev/null) $gcc_extra_ver"
- _depflags='-MMD -MF $(@:.o=.d) -MT $@'
- _cflags_speed='-O3'
- _cflags_size='-Os'
- elif $_cc -v 2>&1 | grep -qi ^gcc; then
- _type=gcc
- gcc_version=$($_cc --version | head -n1)
- gcc_basever=$($_cc -dumpversion)
- gcc_pkg_ver=$(expr "$gcc_version" : '[^ ]* \(([^)]*)\)')
- gcc_ext_ver=$(expr "$gcc_version" : ".*$gcc_pkg_ver $gcc_basever \\(.*\\)")
- _ident=$(cleanws "gcc $gcc_basever $gcc_pkg_ver $gcc_ext_ver")
- case $gcc_basever in
- 2) ;;
- 2.*) ;;
- *) _depflags='-MMD -MF $(@:.o=.d) -MT $@' ;;
- esac
- if [ "$first" = true ]; then
- case $gcc_basever in
- 4.2*)
- warn "gcc 4.2 is outdated and may miscompile FFmpeg. Please use a newer compiler." ;;
- esac
- fi
- _cflags_speed='-O3'
- _cflags_size='-Os'
- elif $_cc --version 2>/dev/null | grep -q ^icc; then
- _type=icc
- _ident=$($_cc --version | head -n1)
- _depflags='-MMD'
- _cflags_speed='-O3'
- _cflags_size='-Os'
- _cflags_noopt='-O1'
- _flags_filter=icc_flags
- elif $_cc -v 2>&1 | grep -q xlc; then
- _type=xlc
- _ident=$($_cc -qversion 2>/dev/null | head -n1)
- _cflags_speed='-O5'
- _cflags_size='-O5 -qcompact'
- elif $_cc --vsn 2>/dev/null | grep -Eq "ARM (C/C\+\+ )?Compiler"; then
- test -d "$sysroot" || die "No valid sysroot specified."
- _type=armcc
- _ident=$($_cc --vsn | grep -i build | head -n1 | sed 's/.*: //')
- armcc_conf="$PWD/armcc.conf"
- $_cc --arm_linux_configure \
- --arm_linux_config_file="$armcc_conf" \
- --configure_sysroot="$sysroot" \
- --configure_cpp_headers="$sysinclude" >>$logfile 2>&1 ||
- die "Error creating armcc configuration file."
- $_cc --vsn | grep -q RVCT && armcc_opt=rvct || armcc_opt=armcc
- _flags="--arm_linux_config_file=$armcc_conf --translate_gcc"
- as_default="${cross_prefix}gcc"
- _depflags='-MMD'
- _cflags_speed='-O3'
- _cflags_size='-Os'
- elif $_cc -v 2>&1 | grep -q clang && ! $_cc -? > /dev/null 2>&1; then
- _type=clang
- _ident=$($_cc --version 2>/dev/null | head -n1)
- _depflags='-MMD -MF $(@:.o=.d) -MT $@'
- _cflags_speed='-O3'
- _cflags_size='-Oz'
- elif $_cc -V 2>&1 | grep -q Sun; then
- _type=suncc
- _ident=$($_cc -V 2>&1 | head -n1 | cut -d' ' -f 2-)
- _DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< | sed -e "1s,^.*: ,$@: ," -e "\$$!s,\$$, \\\," -e "1!s,^.*: , ," > $(@:.o=.d)'
- _DEPFLAGS='-xM1 -xc99'
- _ldflags='-std=c99'
- _cflags_speed='-O5'
- _cflags_size='-O5 -xspace'
- _flags_filter=suncc_flags
- elif $_cc -v 2>&1 | grep -q 'PathScale\|Path64'; then
- _type=pathscale
- _ident=$($_cc -v 2>&1 | head -n1 | tr -d :)
- _depflags='-MMD -MF $(@:.o=.d) -MT $@'
- _cflags_speed='-O2'
- _cflags_size='-Os'
- _flags_filter='filter_out -Wdisabled-optimization'
- elif $_cc -v 2>&1 | grep -q Open64; then
- _type=open64
- _ident=$($_cc -v 2>&1 | head -n1 | tr -d :)
- _depflags='-MMD -MF $(@:.o=.d) -MT $@'
- _cflags_speed='-O2'
- _cflags_size='-Os'
- _flags_filter='filter_out -Wdisabled-optimization|-Wtype-limits|-fno-signed-zeros'
- elif $_cc 2>&1 | grep -q 'Microsoft.*ARM.*Assembler'; then
- _type=armasm
- _ident=$($_cc | head -n1)
- # 4509: "This form of conditional instruction is deprecated"
- _flags="-nologo -ignore 4509"
- _flags_filter=armasm_flags
- elif $_cc 2>&1 | grep -q Intel; then
- _type=icl
- _ident=$($_cc 2>&1 | head -n1)
- _depflags='-QMMD -QMF$(@:.o=.d) -QMT$@'
- # Not only is O3 broken on 13.x+ but it is slower on all previous
- # versions (tested) as well.
- _cflags_speed="-O2"
- _cflags_size="-O1 -Oi" # -O1 without -Oi miscompiles stuff
- if $_cc 2>&1 | grep -q Linker; then
- _ld_o='-out:$@'
- else
- _ld_o='-Fe$@'
- fi
- _cc_o='-Fo$@'
- _cc_e='-P'
- _flags_filter=icl_flags
- _ld_lib='lib%.a'
- _ld_path='-libpath:'
- # -Qdiag-error to make icl error when seeing certain unknown arguments
- _flags='-nologo -Qdiag-error:4044,10157'
- # -Qvec- -Qsimd- to prevent miscompilation, -GS, fp:precise for consistency
- # with MSVC which enables it by default.
- _cflags='-Qms0 -Qvec- -Qsimd- -GS -fp:precise'
- disable stripping
- elif $_cc -? 2>/dev/null | grep -q 'LLVM.*Linker'; then
- # lld can emulate multiple different linkers; in ms link.exe mode,
- # the -? parameter gives the help output which contains an identifyable
- # string, while it gives an error in other modes.
- _type=lld-link
- # The link.exe mode doesn't have a switch for getting the version,
- # but we can force it back to gnu mode and get the version from there.
- _ident=$($_cc -flavor gnu --version 2>/dev/null)
- _ld_o='-out:$@'
- _flags_filter=msvc_flags
- _ld_lib='lib%.a'
- _ld_path='-libpath:'
- elif $_cc -nologo- 2>&1 | grep -q Microsoft || { $_cc -v 2>&1 | grep -q clang && $_cc -? > /dev/null 2>&1; }; then
- _type=msvc
- if $_cc -nologo- 2>&1 | grep -q Microsoft; then
- _ident=$($_cc 2>&1 | head -n1 | tr -d '\r')
- else
- _ident=$($_cc --version 2>/dev/null | head -n1 | tr -d '\r')
- fi
- _DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< 2>&1 | awk '\''/including/ { sub(/^.*file: */, ""); gsub(/\\/, "/"); if (!match($$0, / /)) print "$@:", $$0 }'\'' > $(@:.o=.d)'
- _DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -showIncludes -Zs'
- _cflags_speed="-O2"
- _cflags_size="-O1"
- _cflags_noopt="-O1"
- if $_cc -nologo- 2>&1 | grep -q Linker; then
- _ld_o='-out:$@'
- else
- _ld_o='-Fe$@'
- fi
- _cc_o='-Fo$@'
- _cc_e='-P -Fi$@'
- _flags_filter=msvc_flags
- _ld_lib='lib%.a'
- _ld_path='-libpath:'
- _flags='-nologo'
- disable stripping
- elif $_cc --version 2>/dev/null | grep -q ^cparser; then
- _type=cparser
- _ident=$($_cc --version | head -n1)
- _depflags='-MMD'
- _cflags_speed='-O4'
- _cflags_size='-O2'
- _flags_filter=cparser_flags
- fi
-
- eval ${pfx}_type=\$_type
- eval ${pfx}_ident=\$_ident
-}
-
-set_ccvars(){
- eval ${1}_C=\${_cc_c-\${${1}_C}}
- eval ${1}_E=\${_cc_e-\${${1}_E}}
- eval ${1}_O=\${_cc_o-\${${1}_O}}
-
- if [ -n "$_depflags" ]; then
- eval ${1}_DEPFLAGS=\$_depflags
- else
- eval ${1}DEP=\${_DEPCMD:-\$DEPCMD}
- eval ${1}DEP_FLAGS=\${_DEPFLAGS:-\$DEPFLAGS}
- eval DEP${1}FLAGS=\$_flags
- fi
-}
-
-probe_cc cc "$cc" "true"
-cflags_filter=$_flags_filter
-cflags_speed=$_cflags_speed
-cflags_size=$_cflags_size
-cflags_noopt=$_cflags_noopt
-add_cflags $_flags $_cflags
-cc_ldflags=$_ldflags
-set_ccvars CC
-set_ccvars CXX
-
-probe_cc hostcc "$host_cc"
-host_cflags_filter=$_flags_filter
-host_cflags_speed=$_cflags_speed
-add_host_cflags $_flags $_cflags
-set_ccvars HOSTCC
-
-test -n "$cc_type" && enable $cc_type ||
- warn "Unknown C compiler $cc, unable to select optimal CFLAGS"
-
-: ${as_default:=$cc}
-: ${objcc_default:=$cc}
-: ${dep_cc_default:=$cc}
-: ${ld_default:=$cc}
-: ${host_ld_default:=$host_cc}
-set_default ar as objcc dep_cc ld ln_s host_ld windres
-
-probe_cc as "$as"
-asflags_filter=$_flags_filter
-add_asflags $_flags $_cflags
-set_ccvars AS
-
-probe_cc objcc "$objcc"
-objcflags_filter=$_flags_filter
-add_objcflags $_flags $_cflags
-set_ccvars OBJC
-
-probe_cc ld "$ld"
-ldflags_filter=$_flags_filter
-add_ldflags $_flags $_ldflags
-test "$cc_type" != "$ld_type" && add_ldflags $cc_ldflags
-LD_O=${_ld_o-$LD_O}
-LD_LIB=${_ld_lib-$LD_LIB}
-LD_PATH=${_ld_path-$LD_PATH}
-
-probe_cc hostld "$host_ld"
-host_ldflags_filter=$_flags_filter
-add_host_ldflags $_flags $_ldflags
-HOSTLD_O=${_ld_o-$HOSTLD_O}
-
-if [ -z "$CC_DEPFLAGS" ] && [ "$dep_cc" != "$cc" ]; then
- probe_cc depcc "$dep_cc"
- CCDEP=${_DEPCMD:-$DEPCMD}
- CCDEP_FLAGS=${_DEPFLAGS:=$DEPFLAGS}
- DEPCCFLAGS=$_flags
-fi
-
-if $ar 2>&1 | grep -q Microsoft; then
- arflags="-nologo"
- ar_o='-out:$@'
-elif $ar 2>&1 | grep -q "\[D\] "; then
- arflags="rcD"
- ar_o='$@'
-else
- arflags="rc"
- ar_o='$@'
-fi
-
-add_cflags $extra_cflags
-add_cxxflags $extra_cxxflags
-add_objcflags $extra_objcflags
-add_asflags $extra_cflags
-
-if test -n "$sysroot"; then
- case "$cc_type" in
- gcc|llvm_gcc|clang)
- add_cppflags --sysroot="$sysroot"
- add_ldflags --sysroot="$sysroot"
- ;;
- esac
-fi
-
-if test "$cpu" = host; then
- enabled cross_compile &&
- warn "--cpu=host makes no sense when cross-compiling."
-
- case "$cc_type" in
- gcc|llvm_gcc)
- check_native(){
- $cc $1=native -v -c -o $TMPO $TMPC >$TMPE 2>&1 || return
- sed -n "/cc1.*$1=/{
- s/.*$1=\\([^ ]*\\).*/\\1/
- p
- q
- }" $TMPE
- }
- cpu=$(check_native -march || check_native -mcpu)
- ;;
- clang)
- check_native(){
- $cc $1=native -v -c -o $TMPO $TMPC >$TMPE 2>&1 || return
- sed -n "/cc1.*-target-cpu /{
- s/.*-target-cpu \\([^ ]*\\).*/\\1/
- p
- q
- }" $TMPE
- }
- cpu=$(check_native -march)
- ;;
- esac
-
- test "${cpu:-host}" = host &&
- die "--cpu=host not supported with compiler $cc"
-fi
-
-# Deal with common $arch aliases
-case "$arch" in
- aarch64|arm64)
- arch="aarch64"
- ;;
- arm*|iPad*|iPhone*)
- arch="arm"
- ;;
- mips*|IP*)
- case "$arch" in
- *el)
- add_cppflags -EL
- add_ldflags -EL
- ;;
- *eb)
- add_cppflags -EB
- add_ldflags -EB
- ;;
- esac
- arch="mips"
- ;;
- parisc*|hppa*)
- arch="parisc"
- ;;
- "Power Macintosh"|ppc*|powerpc*)
- arch="ppc"
- ;;
- s390|s390x)
- arch="s390"
- ;;
- sh4|sh)
- arch="sh4"
- ;;
- sun4*|sparc*)
- arch="sparc"
- ;;
- tilegx|tile-gx)
- arch="tilegx"
- ;;
- i[3-6]86*|i86pc|BePC|x86pc|x86_64|x86_32|amd64)
- arch="x86"
- ;;
-esac
-
-is_in $arch $ARCH_LIST || warn "unknown architecture $arch"
-enable $arch
-
-# Add processor-specific flags
-if enabled aarch64; then
-
- case $cpu in
- armv*)
- cpuflags="-march=$cpu"
- ;;
- *)
- cpuflags="-mcpu=$cpu"
- ;;
- esac
-
-elif enabled alpha; then
-
- cpuflags="-mcpu=$cpu"
-
-elif enabled arm; then
-
- check_arm_arch() {
- test_cpp_condition stddef.h \
- "defined __ARM_ARCH_${1}__ || defined __TARGET_ARCH_${2:-$1}" \
- $cpuflags
- }
-
- probe_arm_arch() {
- if check_arm_arch 4; then echo armv4
- elif check_arm_arch 4T; then echo armv4t
- elif check_arm_arch 5; then echo armv5
- elif check_arm_arch 5E; then echo armv5e
- elif check_arm_arch 5T; then echo armv5t
- elif check_arm_arch 5TE; then echo armv5te
- elif check_arm_arch 5TEJ; then echo armv5te
- elif check_arm_arch 6; then echo armv6
- elif check_arm_arch 6J; then echo armv6j
- elif check_arm_arch 6K; then echo armv6k
- elif check_arm_arch 6Z; then echo armv6z
- elif check_arm_arch 6KZ; then echo armv6zk
- elif check_arm_arch 6ZK; then echo armv6zk
- elif check_arm_arch 6T2; then echo armv6t2
- elif check_arm_arch 7; then echo armv7
- elif check_arm_arch 7A 7_A; then echo armv7-a
- elif check_arm_arch 7S; then echo armv7-a
- elif check_arm_arch 7R 7_R; then echo armv7-r
- elif check_arm_arch 7M 7_M; then echo armv7-m
- elif check_arm_arch 7EM 7E_M; then echo armv7-m
- elif check_arm_arch 8A 8_A; then echo armv8-a
- fi
- }
-
- [ "$cpu" = generic ] && cpu=$(probe_arm_arch)
-
- case $cpu in
- armv*)
- cpuflags="-march=$cpu"
- subarch=$(echo $cpu | sed 's/[^a-z0-9]//g')
- ;;
- *)
- cpuflags="-mcpu=$cpu"
- case $cpu in
- cortex-a*) subarch=armv7a ;;
- cortex-r*) subarch=armv7r ;;
- cortex-m*) enable thumb; subarch=armv7m ;;
- arm11*) subarch=armv6 ;;
- arm[79]*e*|arm9[24]6*|arm96*|arm102[26]) subarch=armv5te ;;
- armv4*|arm7*|arm9[24]*) subarch=armv4 ;;
- *) subarch=$(probe_arm_arch) ;;
- esac
- ;;
- esac
-
- case "$subarch" in
- armv5t*) enable fast_clz ;;
- armv[6-8]*)
- enable fast_clz
- disabled fast_unaligned || enable fast_unaligned
- ;;
- esac
-
-elif enabled avr32; then
-
- case $cpu in
- ap7[02]0[0-2])
- subarch="avr32_ap"
- cpuflags="-mpart=$cpu"
- ;;
- ap)
- subarch="avr32_ap"
- cpuflags="-march=$cpu"
- ;;
- uc3[ab]*)
- subarch="avr32_uc"
- cpuflags="-mcpu=$cpu"
- ;;
- uc)
- subarch="avr32_uc"
- cpuflags="-march=$cpu"
- ;;
- esac
-
-elif enabled bfin; then
-
- cpuflags="-mcpu=$cpu"
-
-elif enabled mips; then
-
- cpuflags="-march=$cpu"
-
- if [ "$cpu" != "generic" ]; then
- disable mips32r2
- disable mips32r5
- disable mips64r2
- disable mips32r6
- disable mips64r6
- disable loongson2
- disable loongson3
-
- case $cpu in
- 24kc|24kf*|24kec|34kc|1004kc|24kef*|34kf*|1004kf*|74kc|74kf)
- enable mips32r2
- disable msa
- ;;
- p5600|i6400|p6600)
- disable mipsdsp
- disable mipsdspr2
- ;;
- loongson*)
- enable loongson2
- enable loongson3
- enable local_aligned
- enable simd_align_16
- enable fast_64bit
- enable fast_clz
- enable fast_cmov
- enable fast_unaligned
- disable aligned_stack
- disable mipsdsp
- disable mipsdspr2
- # When gcc version less than 5.3.0, add -fno-expensive-optimizations flag.
- if [ $cc == gcc ]; then
- gcc_version=$(gcc -dumpversion)
- if [ "$(echo "$gcc_version 5.3.0" | tr " " "\n" | sort -rV | head -n 1)" == "$gcc_version" ]; then
- expensive_optimization_flag=""
- else
- expensive_optimization_flag="-fno-expensive-optimizations"
- fi
- fi
- case $cpu in
- loongson3*)
- cpuflags="-march=loongson3a -mhard-float $expensive_optimization_flag"
- ;;
- loongson2e)
- cpuflags="-march=loongson2e -mhard-float $expensive_optimization_flag"
- ;;
- loongson2f)
- cpuflags="-march=loongson2f -mhard-float $expensive_optimization_flag"
- ;;
- esac
- ;;
- *)
- # Unknown CPU. Disable everything.
- warn "unknown CPU. Disabling all MIPS optimizations."
- disable mipsfpu
- disable mipsdsp
- disable mipsdspr2
- disable msa
- disable mmi
- ;;
- esac
-
- case $cpu in
- 24kc)
- disable mipsfpu
- disable mipsdsp
- disable mipsdspr2
- ;;
- 24kf*)
- disable mipsdsp
- disable mipsdspr2
- ;;
- 24kec|34kc|1004kc)
- disable mipsfpu
- disable mipsdspr2
- ;;
- 24kef*|34kf*|1004kf*)
- disable mipsdspr2
- ;;
- 74kc)
- disable mipsfpu
- ;;
- p5600)
- enable mips32r5
- check_cflags "-mtune=p5600" && check_cflags "-msched-weight -mload-store-pairs -funroll-loops"
- ;;
- i6400)
- enable mips64r6
- check_cflags "-mtune=i6400 -mabi=64" && check_cflags "-msched-weight -mload-store-pairs -funroll-loops" && check_ldflags "-mabi=64"
- ;;
- p6600)
- enable mips64r6
- check_cflags "-mtune=p6600 -mabi=64" && check_cflags "-msched-weight -mload-store-pairs -funroll-loops" && check_ldflags "-mabi=64"
- ;;
- esac
- else
- # We do not disable anything. Is up to the user to disable the unwanted features.
- warn 'generic cpu selected'
- fi
-
-elif enabled ppc; then
-
- disable ldbrx
-
- case $(tolower $cpu) in
- 601|ppc601|powerpc601)
- cpuflags="-mcpu=601"
- disable altivec
- ;;
- 603*|ppc603*|powerpc603*)
- cpuflags="-mcpu=603"
- disable altivec
- ;;
- 604*|ppc604*|powerpc604*)
- cpuflags="-mcpu=604"
- disable altivec
- ;;
- g3|75*|ppc75*|powerpc75*)
- cpuflags="-mcpu=750"
- disable altivec
- ;;
- g4|745*|ppc745*|powerpc745*)
- cpuflags="-mcpu=7450"
- disable vsx
- ;;
- 74*|ppc74*|powerpc74*)
- cpuflags="-mcpu=7400"
- disable vsx
- ;;
- g5|970|ppc970|powerpc970)
- cpuflags="-mcpu=970"
- disable vsx
- ;;
- power[3-6]*)
- cpuflags="-mcpu=$cpu"
- disable vsx
- ;;
- power[7-8]*)
- cpuflags="-mcpu=$cpu"
- ;;
- cell)
- cpuflags="-mcpu=cell"
- enable ldbrx
- disable vsx
- ;;
- e500mc)
- cpuflags="-mcpu=e500mc"
- disable altivec
- ;;
- e500v2)
- cpuflags="-mcpu=8548 -mhard-float -mfloat-gprs=double"
- disable altivec
- disable dcbzl
- ;;
- e500)
- cpuflags="-mcpu=8540 -mhard-float"
- disable altivec
- disable dcbzl
- ;;
- esac
-
-elif enabled sparc; then
-
- case $cpu in
- cypress|f93[04]|tsc701|sparcl*|supersparc|hypersparc|niagara|v[789])
- cpuflags="-mcpu=$cpu"
- ;;
- ultrasparc*|niagara[234])
- cpuflags="-mcpu=$cpu"
- ;;
- esac
-
-elif enabled x86; then
-
- case $cpu in
- i[345]86|pentium)
- cpuflags="-march=$cpu"
- disable i686
- disable mmx
- ;;
- # targets that do NOT support nopl and conditional mov (cmov)
- pentium-mmx|k6|k6-[23]|winchip-c6|winchip2|c3)
- cpuflags="-march=$cpu"
- disable i686
- ;;
- # targets that do support nopl and conditional mov (cmov)
- i686|pentiumpro|pentium[23]|pentium-m|athlon|athlon-tbird|athlon-4|athlon-[mx]p|athlon64*|k8*|opteron*|athlon-fx\
- |core*|atom|bonnell|nehalem|westmere|silvermont|sandybridge|ivybridge|haswell|broadwell|skylake*|knl\
- |amdfam10|barcelona|b[dt]ver*|znver*)
- cpuflags="-march=$cpu"
- enable i686
- enable fast_cmov
- ;;
- # targets that do support conditional mov but on which it's slow
- pentium4|pentium4m|prescott|nocona)
- cpuflags="-march=$cpu"
- enable i686
- disable fast_cmov
- ;;
- esac
-
-fi
-
-if [ "$cpu" != generic ]; then
- add_cflags $cpuflags
- add_asflags $cpuflags
- test "$cc_type" = "$ld_type" && add_ldflags $cpuflags
-fi
-
-# compiler sanity check
-test_exec <<EOF
-int main(void){ return 0; }
-EOF
-if test "$?" != 0; then
- echo "$cc is unable to create an executable file."
- if test -z "$cross_prefix" && ! enabled cross_compile ; then
- echo "If $cc is a cross-compiler, use the --enable-cross-compile option."
- echo "Only do this if you know what cross compiling means."
- fi
- die "C compiler test failed."
-fi
-
-add_cppflags -D_ISOC99_SOURCE
-add_cxxflags -D__STDC_CONSTANT_MACROS
-check_cxxflags -std=c++11 || check_cxxflags -std=c++0x
-
-# some compilers silently accept -std=c11, so we also need to check that the
-# version macro is defined properly
-test_cflags_cc -std=c11 ctype.h "__STDC_VERSION__ >= 201112L" &&
- add_cflags -std=c11 ||
- check_cflags -std=c99
-
-check_cppflags -D_FILE_OFFSET_BITS=64
-check_cppflags -D_LARGEFILE_SOURCE
-
-add_host_cppflags -D_ISOC99_SOURCE
-check_host_cflags -std=c99
-check_host_cflags -Wall
-check_host_cflags $host_cflags_speed
-
-check_64bit(){
- arch32=$1
- arch64=$2
- expr=${3:-'sizeof(void *) > 4'}
- test_code cc "" "int test[2*($expr) - 1]" &&
- subarch=$arch64 || subarch=$arch32
- enable $subarch
-}
-
-case "$arch" in
- aarch64|alpha|ia64)
- enabled shared && enable_weak pic
- ;;
- mips)
- check_64bit mips mips64 '_MIPS_SIM > 1'
- enabled shared && enable_weak pic
- ;;
- parisc)
- check_64bit parisc parisc64
- enabled shared && enable_weak pic
- ;;
- ppc)
- check_64bit ppc ppc64
- enabled shared && enable_weak pic
- ;;
- s390)
- check_64bit s390 s390x
- enabled shared && enable_weak pic
- ;;
- sparc)
- check_64bit sparc sparc64
- enabled shared && enable_weak pic
- ;;
- x86)
- check_64bit x86_32 x86_64
- # Treat x32 as x64 for now. Note it also needs pic if shared
- test "$subarch" = "x86_32" && test_cpp_condition stddef.h 'defined(__x86_64__)' &&
- subarch=x86_64 && enable x86_64 && disable x86_32
- if enabled x86_64; then
- enabled shared && enable_weak pic
- objformat=elf64
- fi
- ;;
-esac
-
-# OS specific
-case $target_os in
- aix)
- SHFLAGS=-shared
- add_cppflags '-I\$(SRC_PATH)/compat/aix'
- enabled shared && add_ldflags -Wl,-brtl
- arflags='-Xany -r -c'
- striptype=""
- ;;
- android)
- disable symver
- enable section_data_rel_ro
- add_cflags -fPIE
- add_ldexeflags -fPIE -pie
- SLIB_INSTALL_NAME='$(SLIBNAME)'
- SLIB_INSTALL_LINKS=
- SHFLAGS='-shared -Wl,-soname,$(SLIBNAME)'
- ;;
- haiku)
- prefix_default="/boot/common"
- network_extralibs="-lnetwork"
- host_extralibs=
- ;;
- sunos)
- SHFLAGS='-shared -Wl,-h,$$(@F)'
- enabled x86 && append SHFLAGS -mimpure-text
- network_extralibs="-lsocket -lnsl"
- add_cppflags -D__EXTENSIONS__
- # When using suncc to build, the Solaris linker will mark
- # an executable with each instruction set encountered by
- # the Solaris assembler. As our libraries contain their own
- # guards for processor-specific code, instead suppress
- # generation of the HWCAPS ELF section on Solaris x86 only.
- enabled_all suncc x86 &&
- echo "hwcap_1 = OVERRIDE;" > mapfile &&
- add_ldflags -Wl,-M,mapfile
- nm_default='nm -P -g'
- striptype=""
- version_script='-M'
- VERSION_SCRIPT_POSTPROCESS_CMD='perl $(SRC_PATH)/compat/solaris/make_sunver.pl - $(OBJS)'
- ;;
- netbsd)
- disable symver
- oss_indev_extralibs="-lossaudio"
- oss_outdev_extralibs="-lossaudio"
- enabled gcc || check_ldflags -Wl,-zmuldefs
- ;;
- openbsd|bitrig)
- disable symver
- enable section_data_rel_ro
- striptype=""
- SHFLAGS='-shared'
- SLIB_INSTALL_NAME='$(SLIBNAME).$(LIBMAJOR).$(LIBMINOR)'
- SLIB_INSTALL_LINKS=
- oss_indev_extralibs="-lossaudio"
- oss_outdev_extralibs="-lossaudio"
- ;;
- dragonfly)
- disable symver
- ;;
- freebsd)
- ;;
- bsd/os)
- add_extralibs -lpoll -lgnugetopt
- strip="strip -d"
- ;;
- darwin)
- enabled ppc && add_asflags -force_cpusubtype_ALL
- install_name_dir_default='$(SHLIBDIR)'
- SHFLAGS='-dynamiclib -Wl,-single_module -Wl,-install_name,$(INSTALL_NAME_DIR)/$(SLIBNAME_WITH_MAJOR),-current_version,$(LIBVERSION),-compatibility_version,$(LIBMAJOR)'
- enabled x86_32 && append SHFLAGS -Wl,-read_only_relocs,suppress
- strip="${strip} -x"
- add_ldflags -Wl,-dynamic,-search_paths_first
- check_cflags -Werror=partial-availability
- SLIBSUF=".dylib"
- SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME).$(LIBVERSION)$(SLIBSUF)'
- SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME).$(LIBMAJOR)$(SLIBSUF)'
- enabled x86_64 && objformat="macho64" || objformat="macho32"
- enabled_any pic shared x86_64 ||
- { check_cflags -mdynamic-no-pic && add_asflags -mdynamic-no-pic; }
- check_headers dispatch/dispatch.h &&
- add_cppflags '-I\$(SRC_PATH)/compat/dispatch_semaphore'
- if test -n "$sysroot"; then
- is_in -isysroot $cc $CPPFLAGS $CFLAGS || check_cppflags -isysroot $sysroot
- is_in -isysroot $ld $LDFLAGS || check_ldflags -isysroot $sysroot
- fi
- version_script='-exported_symbols_list'
- VERSION_SCRIPT_POSTPROCESS_CMD='tr " " "\n" | sed -n /global:/,/local:/p | grep ";" | tr ";" "\n" | sed -E "s/(.+)/_\1/g" | sed -E "s/(.+[^*])$$$$/\1*/"'
- # Workaround for Xcode 11 -fstack-check bug
- if enabled clang; then
- clang_version=$($cc -dumpversion)
- test ${clang_version%%.*} -eq 11 && add_cflags -fno-stack-check
- fi
- ;;
- msys*)
- die "Native MSYS builds are discouraged, please use the MINGW environment."
- ;;
- mingw32*|mingw64*)
- target_os=mingw32
- LIBTARGET=i386
- if enabled x86_64; then
- LIBTARGET="i386:x86-64"
- elif enabled arm; then
- LIBTARGET="arm"
- elif enabled aarch64; then
- LIBTARGET="arm64"
- fi
- if enabled shared; then
- # 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 x86_32 && check_ldflags -Wl,--large-address-aware
- shlibdir_default="$bindir_default"
- SLIBPREF=""
- SLIBSUF=".dll"
- SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)'
- SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
- if test_cmd lib.exe -list; then
- SLIB_EXTRA_CMD=-'lib.exe -nologo -machine:$(LIBTARGET) -def:$$(@:$(SLIBSUF)=.def) -out:$(SUBDIR)$(SLIBNAME:$(SLIBSUF)=.lib)'
- if enabled x86_64; then
- LIBTARGET=x64
- fi
- else
- SLIB_EXTRA_CMD=-'$(DLLTOOL) -m $(LIBTARGET) -d $$(@:$(SLIBSUF)=.def) -l $(SUBDIR)$(SLIBNAME:$(SLIBSUF)=.lib) -D $(SLIBNAME_WITH_MAJOR)'
- fi
- SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
- SLIB_INSTALL_LINKS=
- SLIB_INSTALL_EXTRA_SHLIB='$(SLIBNAME:$(SLIBSUF)=.lib)'
- SLIB_INSTALL_EXTRA_LIB='lib$(SLIBNAME:$(SLIBSUF)=.dll.a) $(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.def)'
- SLIB_CREATE_DEF_CMD='EXTERN_PREFIX="$(EXTERN_PREFIX)" AR="$(AR_CMD)" NM="$(NM_CMD)" $(SRC_PATH)/compat/windows/makedef $(SUBDIR)lib$(NAME).ver $(OBJS) > $$(@:$(SLIBSUF)=.def)'
- SHFLAGS='-shared -Wl,--out-implib,$(SUBDIR)lib$(SLIBNAME:$(SLIBSUF)=.dll.a) -Wl,--disable-auto-image-base $$(@:$(SLIBSUF)=.def)'
- enabled x86_64 && objformat="win64" || objformat="win32"
- dlltool="${cross_prefix}dlltool"
- ranlib=:
- enable dos_paths
- check_ldflags -Wl,--nxcompat,--dynamicbase
- # Lets work around some stupidity in binutils.
- # ld will strip relocations from executables even though we need them
- # for dynamicbase (ASLR). Using -pie does retain the reloc section
- # however ld then forgets what the entry point should be (oops) so we
- # have to manually (re)set it.
- if enabled x86_32; then
- disabled debug && add_ldexeflags -Wl,--pic-executable,-e,_mainCRTStartup
- elif enabled x86_64; then
- disabled debug && add_ldexeflags -Wl,--pic-executable,-e,mainCRTStartup
- check_ldflags -Wl,--high-entropy-va # binutils 2.25
- # Set image base >4GB for extra entropy with HEASLR
- add_ldexeflags -Wl,--image-base,0x140000000
- append SHFLAGS -Wl,--image-base,0x180000000
- fi
- ;;
- win32|win64)
- disable symver
- if enabled shared; then
- # Link to the import library instead of the normal static library
- # for shared libs.
- LD_LIB='%.lib'
- # Cannot build both shared and static libs with MSVC or icl.
- disable static
- fi
- enabled x86_32 && check_ldflags -LARGEADDRESSAWARE
- shlibdir_default="$bindir_default"
- SLIBPREF=""
- SLIBSUF=".dll"
- SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)'
- SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
- SLIB_CREATE_DEF_CMD='EXTERN_PREFIX="$(EXTERN_PREFIX)" $(SRC_PATH)/compat/windows/makedef $(SUBDIR)lib$(NAME).ver $(OBJS) > $$(@:$(SLIBSUF)=.def)'
- SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
- SLIB_INSTALL_LINKS=
- SLIB_INSTALL_EXTRA_SHLIB='$(SLIBNAME:$(SLIBSUF)=.lib)'
- SLIB_INSTALL_EXTRA_LIB='$(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.def)'
- SHFLAGS='-dll -def:$$(@:$(SLIBSUF)=.def) -implib:$(SUBDIR)$(SLIBNAME:$(SLIBSUF)=.lib)'
- enabled x86_64 && objformat="win64" || objformat="win32"
- ranlib=:
- enable dos_paths
- ;;
- cygwin*)
- target_os=cygwin
- shlibdir_default="$bindir_default"
- SLIBPREF="cyg"
- SLIBSUF=".dll"
- SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)'
- SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
- SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
- SLIB_INSTALL_LINKS=
- SLIB_INSTALL_EXTRA_LIB='lib$(FULLNAME).dll.a'
- 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
- add_cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600
- ;;
- *-dos|freedos|opendos)
- network_extralibs="-lsocket"
- objformat="coff"
- enable dos_paths
- ;;
- linux)
- enable section_data_rel_ro
- enabled_any arm aarch64 && enable_weak linux_perf
- ;;
- irix*)
- target_os=irix
- ranlib="echo ignoring ranlib"
- ;;
- os/2*)
- strip="lxlite -CS"
- striptype=""
- objformat="aout"
- add_cppflags -D_GNU_SOURCE
- add_ldflags -Zomf -Zbin-files -Zargs-wild -Zhigh-mem -Zmap
- SHFLAGS='$(SUBDIR)$(NAME).def -Zdll -Zomf'
- LIBSUF="_s.a"
- SLIBPREF=""
- SLIBSUF=".dll"
- SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)'
- SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(shell echo $(FULLNAME) | cut -c1-6)$(LIBMAJOR)$(SLIBSUF)'
- SLIB_CREATE_DEF_CMD='echo LIBRARY $(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=) INITINSTANCE TERMINSTANCE > $(SUBDIR)$(FULLNAME).def; \
- echo CODE PRELOAD MOVEABLE DISCARDABLE >> $(SUBDIR)$(FULLNAME).def; \
- echo DATA PRELOAD MOVEABLE MULTIPLE NONSHARED >> $(SUBDIR)$(FULLNAME).def; \
- echo EXPORTS >> $(SUBDIR)$(FULLNAME).def; \
- emxexp $(OBJS) >> $(SUBDIR)$(FULLNAME).def'
- SLIB_EXTRA_CMD='emximp -o $(SUBDIR)$(LIBPREF)$(FULLNAME)_dll.a $(SUBDIR)$(FULLNAME).def; \
- emximp -o $(SUBDIR)$(LIBPREF)$(FULLNAME)_dll.lib $(SUBDIR)$(FULLNAME).def;'
- SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
- SLIB_INSTALL_LINKS=
- SLIB_INSTALL_EXTRA_LIB='$(LIBPREF)$(FULLNAME)_dll.a $(LIBPREF)$(FULLNAME)_dll.lib'
- enable dos_paths
- enable_weak os2threads
- ;;
- gnu/kfreebsd)
- add_cppflags -D_BSD_SOURCE
- ;;
- gnu)
- ;;
- qnx)
- add_cppflags -D_QNX_SOURCE
- network_extralibs="-lsocket"
- ;;
- symbian)
- SLIBSUF=".dll"
- enable dos_paths
- add_cflags --include=$sysinclude/gcce/gcce.h -fvisibility=default
- add_cppflags -D__GCCE__ -D__SYMBIAN32__ -DSYMBIAN_OE_POSIX_SIGNALS
- add_ldflags -Wl,--target1-abs,--no-undefined \
- -Wl,-Ttext,0x80000,-Tdata,0x1000000 -shared \
- -Wl,--entry=_E32Startup -Wl,-u,_E32Startup
- add_extralibs -l:eexe.lib -l:usrt2_2.lib -l:dfpaeabi.dso \
- -l:drtaeabi.dso -l:scppnwdl.dso -lsupc++ -lgcc \
- -l:libc.dso -l:libm.dso -l:euser.dso -l:libcrt0.lib
- ;;
- minix)
- ;;
- none)
- ;;
- *)
- die "Unknown OS '$target_os'."
- ;;
-esac
-
-# test if creating links works
-link_dest=$(mktemp -u $TMPDIR/dest_XXXXXXXX)
-link_name=$(mktemp -u $TMPDIR/name_XXXXXXXX)
-mkdir "$link_dest"
-$ln_s "$link_dest" "$link_name"
-touch "$link_dest/test_file"
-if [ "$source_path" != "." ] && [ "$source_path" != "src" ] && ([ ! -d src ] || [ -L src ]) && [ -e "$link_name/test_file" ]; then
- # create link to source path
- [ -e src ] && rm src
- $ln_s "$source_path" src
- source_link=src
-else
- # creating directory links doesn't work
- # fall back to using the full source path
- source_link="$source_path"
-fi
-# cleanup
-rm -r "$link_dest"
-rm -r "$link_name"
-
-# determine libc flavour
-
-probe_libc(){
- pfx=$1
- pfx_no_=${pfx%_}
- # uclibc defines __GLIBC__, so it needs to be checked before glibc.
- if test_${pfx}cpp_condition features.h "defined __UCLIBC__"; then
- eval ${pfx}libc_type=uclibc
- add_${pfx}cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600
- elif test_${pfx}cpp_condition features.h "defined __GLIBC__"; then
- eval ${pfx}libc_type=glibc
- add_${pfx}cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600
- # MinGW headers can be installed on Cygwin, so check for newlib first.
- elif test_${pfx}cpp_condition newlib.h "defined _NEWLIB_VERSION"; then
- eval ${pfx}libc_type=newlib
- add_${pfx}cppflags -U__STRICT_ANSI__ -D_XOPEN_SOURCE=600
- # MinGW64 is backwards compatible with MinGW32, so check for it first.
- elif test_${pfx}cpp_condition _mingw.h "defined __MINGW64_VERSION_MAJOR"; then
- eval ${pfx}libc_type=mingw64
- if test_${pfx}cpp_condition _mingw.h "__MINGW64_VERSION_MAJOR < 3"; then
- add_compat msvcrt/snprintf.o
- add_cflags "-include $source_path/compat/msvcrt/snprintf.h"
- fi
- add_${pfx}cppflags -U__STRICT_ANSI__ -D__USE_MINGW_ANSI_STDIO=1
- eval test \$${pfx_no_}cc_type = "gcc" &&
- add_${pfx}cppflags -D__printf__=__gnu_printf__
- test_${pfx}cpp_condition windows.h "!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600" &&
- add_${pfx}cppflags -D_WIN32_WINNT=0x0600
- add_${pfx}cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600
- elif test_${pfx}cpp_condition _mingw.h "defined __MINGW_VERSION" ||
- test_${pfx}cpp_condition _mingw.h "defined __MINGW32_VERSION"; then
- eval ${pfx}libc_type=mingw32
- test_${pfx}cpp_condition _mingw.h "__MINGW32_MAJOR_VERSION > 3 || \
- (__MINGW32_MAJOR_VERSION == 3 && __MINGW32_MINOR_VERSION >= 15)" ||
- die "ERROR: MinGW32 runtime version must be >= 3.15."
- add_${pfx}cppflags -U__STRICT_ANSI__ -D__USE_MINGW_ANSI_STDIO=1
- test_${pfx}cpp_condition _mingw.h "__MSVCRT_VERSION__ < 0x0700" &&
- add_${pfx}cppflags -D__MSVCRT_VERSION__=0x0700
- test_${pfx}cpp_condition windows.h "!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600" &&
- add_${pfx}cppflags -D_WIN32_WINNT=0x0600
- eval test \$${pfx_no_}cc_type = "gcc" &&
- add_${pfx}cppflags -D__printf__=__gnu_printf__
- add_${pfx}cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600
- elif test_${pfx}cpp_condition crtversion.h "defined _VC_CRT_MAJOR_VERSION"; then
- eval ${pfx}libc_type=msvcrt
- if test_${pfx}cpp_condition crtversion.h "_VC_CRT_MAJOR_VERSION < 14"; then
- if [ "$pfx" = host_ ]; then
- add_host_cppflags -Dsnprintf=_snprintf
- else
- add_compat strtod.o strtod=avpriv_strtod
- add_compat msvcrt/snprintf.o snprintf=avpriv_snprintf \
- _snprintf=avpriv_snprintf \
- vsnprintf=avpriv_vsnprintf
- fi
- fi
- add_${pfx}cppflags -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS
- # The MSVC 2010 headers (Win 7.0 SDK) set _WIN32_WINNT to
- # 0x601 by default unless something else is set by the user.
- # This can easily lead to us detecting functions only present
- # in such new versions and producing binaries requiring windows 7.0.
- # Therefore explicitly set the default to Vista unless the user has
- # set something else on the command line.
- # Don't do this if WINAPI_FAMILY is set and is set to a non-desktop
- # family. For these cases, configure is free to use any functions
- # found in the SDK headers by default. (Alternatively, we could force
- # _WIN32_WINNT to 0x0602 in that case.)
- test_${pfx}cpp_condition stdlib.h "defined(_WIN32_WINNT)" ||
- { test_${pfx}cpp <<EOF && add_${pfx}cppflags -D_WIN32_WINNT=0x0600; }
-#ifdef WINAPI_FAMILY
-#include <winapifamily.h>
-#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-#error not desktop
-#endif
-#endif
-EOF
- if [ "$pfx" = "" ]; then
- check_func strtoll || add_cflags -Dstrtoll=_strtoi64
- check_func strtoull || add_cflags -Dstrtoull=_strtoui64
- fi
- elif test_${pfx}cpp_condition stddef.h "defined __KLIBC__"; then
- eval ${pfx}libc_type=klibc
- elif test_${pfx}cpp_condition sys/cdefs.h "defined __BIONIC__"; then
- eval ${pfx}libc_type=bionic
- elif test_${pfx}cpp_condition sys/brand.h "defined LABELED_BRAND_NAME"; then
- eval ${pfx}libc_type=solaris
- add_${pfx}cppflags -D__EXTENSIONS__ -D_XOPEN_SOURCE=600
- elif test_${pfx}cpp_condition sys/version.h "defined __DJGPP__"; then
- eval ${pfx}libc_type=djgpp
- add_cppflags -U__STRICT_ANSI__
- add_cflags "-include $source_path/compat/djgpp/math.h"
- add_compat djgpp/math.o
- fi
- test_${pfx}cc <<EOF
-#include <time.h>
-void *v = localtime_r;
-EOF
-test "$?" != 0 && test_${pfx}cc -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 <<EOF && add_${pfx}cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600
-#include <time.h>
-void *v = localtime_r;
-EOF
-
- eval test -n "\${${pfx}libc_type}" && enable ${pfx}libc_${libc_type}
-}
-
-probe_libc
-probe_libc host_
-
-# hacks for compiler/libc/os combinations
-
-case $libc_type in
- bionic)
- add_compat strtod.o strtod=avpriv_strtod
- ;;
-esac
-
-check_compile_assert flt_lim "float.h limits.h" "DBL_MAX == (double)DBL_MAX" ||
- add_cppflags '-I\$(SRC_PATH)/compat/float'
-
-test_cpp_condition stdlib.h "defined(__PIC__) || defined(__pic__) || defined(PIC)" && enable_weak pic
-
-set_default libdir
-: ${shlibdir_default:="$libdir"}
-: ${pkgconfigdir_default:="$libdir/pkgconfig"}
-
-set_default $PATHS_LIST
-set_default nm
-
-disabled optimizations || enabled ossfuzz || check_cflags -fomit-frame-pointer
-
-enable_weak_pic() {
- disabled pic && return
- enable pic
- add_cppflags -DPIC
- case "$target_os" in
- mingw*|cygwin*|win*)
- ;;
- *)
- add_cflags -fPIC
- add_asflags -fPIC
- ;;
- esac
-}
-
-enabled pic && enable_weak_pic
-
-test_cc <<EOF || die "Symbol mangling check failed."
-int ff_extern;
-EOF
-sym=$($nm $TMPO | awk '/ff_extern/{ print substr($0, match($0, /[^ \t]*ff_extern/)) }')
-extern_prefix=${sym%%ff_extern*}
-
-! disabled inline_asm && check_inline_asm inline_asm '"" ::'
-
-for restrict_keyword in restrict __restrict__ __restrict ""; do
- test_code cc "" "char * $restrict_keyword p" && break
-done
-
-check_cc pragma_deprecated "" '_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")'
-
-# The global variable ensures the bits appear unchanged in the object file.
-test_cc <<EOF || die "endian test failed"
-unsigned int endian = 'B' << 24 | 'I' << 16 | 'G' << 8 | 'E';
-EOF
-od -t x1 $TMPO | grep -q '42 *49 *47 *45' && enable bigendian
-
-check_cc const_nan math.h "struct { double d; } static const bar[] = { { NAN } }"
-
-if ! enabled ppc64 || enabled bigendian; then
- disable vsx
-fi
-
-check_gas() {
- log "check_gas using '$as' as AS"
- # :vararg is used on aarch64, arm and ppc altivec
- check_as vararg "
-.macro m n, y:vararg=0
-\n: .int \y
-.endm
-m x" || return 1
- # .altmacro is only used in arm asm
- ! enabled arm || check_as gnu_as ".altmacro"
-}
-
-if enabled_any arm aarch64 || enabled_all ppc altivec && enabled asm; then
- nogas=:
- enabled_any arm aarch64 && nogas=die
- enabled_all ppc altivec && [ $target_os_default != aix ] && nogas=warn
- as_noop=-v
-
- case $as_type in
- arm*) gaspp_as_type=armasm; as_noop=-h ;;
- gcc) gaspp_as_type=gas ;;
- *) gaspp_as_type=$as_type ;;
- esac
-
- [ $target_os = "darwin" ] && gaspp_as_type="apple-$gaspp_as_type"
-
- test "${as#*gas-preprocessor.pl}" != "$as" ||
- test_cmd gas-preprocessor.pl -arch $arch -as-type $gaspp_as_type -- ${as:=$cc} $as_noop &&
- gas="${gas:=gas-preprocessor.pl} -arch $arch -as-type $gaspp_as_type -- ${as:=$cc}"
-
- if ! check_gas ; then
- as=${gas:=$as}
- check_gas || \
- $nogas "GNU assembler not found, install/update gas-preprocessor"
- fi
-
- check_as as_func ".func test
- .endfunc"
-fi
-
-check_inline_asm inline_asm_labels '"1:\n"'
-
-check_inline_asm inline_asm_nonlocal_labels '"Label:\n"'
-
-if enabled aarch64; then
- enabled armv8 && check_insn armv8 'prfm pldl1strm, [x0]'
- # internal assembler in clang 3.3 does not support this instruction
- enabled neon && check_insn neon 'ext v0.8B, v0.8B, v1.8B, #1'
- enabled vfp && check_insn vfp 'fmadd d0, d0, d1, d2'
-
- map 'enabled_any ${v}_external ${v}_inline || disable $v' $ARCH_EXT_LIST_ARM
-
-elif enabled alpha; then
-
- check_cflags -mieee
-
-elif enabled arm; then
-
- enabled msvc && check_cpp_condition thumb stddef.h "defined _M_ARMT"
- test_cpp_condition stddef.h "defined __thumb__" && test_cc <<EOF && enable_weak thumb
-float func(float a, float b){ return a+b; }
-EOF
- enabled thumb && check_cflags -mthumb || check_cflags -marm
-
- if check_cpp_condition vfp_args stddef.h "defined __ARM_PCS_VFP"; then
- :
- elif check_cpp_condition vfp_args stddef.h "defined _M_ARM_FP && _M_ARM_FP >= 30"; then
- :
- elif ! test_cpp_condition stddef.h "defined __ARM_PCS || defined __SOFTFP__" && [ $target_os != darwin ]; then
- case "${cross_prefix:-$cc}" in
- *hardfloat*) enable vfp_args; fpabi=vfp ;;
- *) check_ld "cc" vfp_args <<EOF && fpabi=vfp || fpabi=soft ;;
-__asm__ (".eabi_attribute 28, 1");
-int main(void) { return 0; }
-EOF
- esac
- warn "Compiler does not indicate floating-point ABI, guessing $fpabi."
- fi
-
- enabled armv5te && check_insn armv5te 'qadd r0, r0, r0'
- enabled armv6 && check_insn armv6 'sadd16 r0, r0, r0'
- enabled armv6t2 && check_insn armv6t2 'movt r0, #0'
- enabled neon && check_insn neon 'vadd.i16 q0, q0, q0'
- enabled vfp && check_insn vfp 'fadds s0, s0, s0'
- enabled vfpv3 && check_insn vfpv3 'vmov.f32 s0, #1.0'
- enabled setend && check_insn setend 'setend be'
-
- [ $target_os = linux ] || [ $target_os = android ] ||
- map 'enabled_any ${v}_external ${v}_inline || disable $v' \
- $ARCH_EXT_LIST_ARM
-
- check_inline_asm asm_mod_q '"add r0, %Q0, %R0" :: "r"((long long)0)'
-
- check_as as_arch_directive ".arch armv7-a"
- check_as as_dn_directive "ra .dn d0.i16"
- check_as as_fpu_directive ".fpu neon"
-
- # llvm's integrated assembler supports .object_arch from llvm 3.5
- [ "$objformat" = elf32 ] || [ "$objformat" = elf64 ] &&
- check_as as_object_arch ".object_arch armv4"
-
- # MS armasm fails to assemble our PIC constructs
- [ $target_os != win32 ] && enabled_all armv6t2 shared !pic && enable_weak_pic
-
-elif enabled mips; then
-
- enabled loongson2 && check_inline_asm loongson2 '"dmult.g $8, $9, $10"'
- enabled loongson3 && check_inline_asm loongson3 '"gsldxc1 $f0, 0($2, $3)"'
- enabled mmi && check_inline_asm mmi '"punpcklhw $f0, $f0, $f0"'
-
- # Enable minimum ISA based on selected options
- if enabled mips64; then
- enabled mips64r6 && check_inline_asm_flags mips64r6 '"dlsa $0, $0, $0, 1"' '-mips64r6'
- enabled mips64r2 && check_inline_asm_flags mips64r2 '"dext $0, $0, 0, 1"' '-mips64r2'
- disabled mips64r6 && disabled mips64r2 && check_inline_asm_flags mips64r1 '"daddi $0, $0, 0"' '-mips64'
- else
- enabled mips32r6 && check_inline_asm_flags mips32r6 '"aui $0, $0, 0"' '-mips32r6'
- enabled mips32r5 && check_inline_asm_flags mips32r5 '"eretnc"' '-mips32r5'
- enabled mips32r2 && check_inline_asm_flags mips32r2 '"ext $0, $0, 0, 1"' '-mips32r2'
- disabled mips32r6 && disabled mips32r5 && disabled mips32r2 && check_inline_asm_flags mips32r1 '"addi $0, $0, 0"' '-mips32'
- fi
-
- enabled mipsfpu && check_inline_asm_flags mipsfpu '"cvt.d.l $f0, $f2"' '-mhard-float'
- enabled mipsfpu && (enabled mips32r5 || enabled mips32r6 || enabled mips64r6) && check_inline_asm_flags mipsfpu '"cvt.d.l $f0, $f1"' '-mfp64'
- enabled mipsfpu && enabled msa && check_inline_asm_flags msa '"addvi.b $w0, $w1, 1"' '-mmsa' && check_headers msa.h || disable msa
- enabled mipsdsp && check_inline_asm_flags mipsdsp '"addu.qb $t0, $t1, $t2"' '-mdsp'
- enabled mipsdspr2 && check_inline_asm_flags mipsdspr2 '"absq_s.qb $t0, $t1"' '-mdspr2'
- enabled msa && enabled msa2 && check_inline_asm_flags msa2 '"nxbits.any.b $w0, $w0"' '-mmsa2' && check_headers msa2.h || disable msa2
-
- if enabled bigendian && enabled msa; then
- disable msa
- fi
-
-elif enabled parisc; then
-
- if enabled gcc; then
- case $($cc -dumpversion) in
- 4.[3-9].*) check_cflags -fno-optimize-sibling-calls ;;
- esac
- fi
-
-elif enabled ppc; then
-
- enable local_aligned
-
- check_inline_asm dcbzl '"dcbzl 0, %0" :: "r"(0)'
- check_inline_asm ibm_asm '"add 0, 0, 0"'
- check_inline_asm ppc4xx '"maclhw r10, r11, r12"'
- check_inline_asm xform_asm '"lwzx %1, %y0" :: "Z"(*(int*)0), "r"(0)'
-
- if enabled altivec; then
- check_cflags -maltivec -mabi=altivec
-
- # check if our compiler supports Motorola AltiVec C API
- check_cc altivec altivec.h "vector signed int v1 = (vector signed int) { 0 };
- vector signed int v2 = (vector signed int) { 1 };
- v1 = vec_add(v1, v2);"
-
- enabled altivec || warn "Altivec disabled, possibly missing --cpu flag"
- fi
-
- if enabled vsx; then
- check_cflags -mvsx &&
- check_cc vsx altivec.h "int v[4] = { 0 };
- vector signed int v1 = vec_vsx_ld(0, v);"
- fi
-
- if enabled power8; then
- check_cpp_condition power8 "altivec.h" "defined(_ARCH_PWR8)"
- fi
-
-elif enabled x86; then
-
- check_builtin rdtsc intrin.h "__rdtsc()"
- check_builtin mm_empty mmintrin.h "_mm_empty()"
-
- enable local_aligned
-
- # check whether EBP is available on x86
- # As 'i' is stored on the stack, this program will crash
- # if the base pointer is used to access it because the
- # base pointer is cleared in the inline assembly code.
- check_exec_crash <<EOF && enable ebp_available
-volatile int i=0;
-__asm__ volatile ("xorl %%ebp, %%ebp" ::: "%ebp");
-return i;
-EOF
-
- # check whether EBX is available on x86
- check_inline_asm ebx_available '""::"b"(0)' &&
- check_inline_asm ebx_available '"":::"%ebx"'
-
- # check whether xmm clobbers are supported
- check_inline_asm xmm_clobbers '"":::"%xmm0"'
-
- check_inline_asm inline_asm_direct_symbol_refs '"movl '$extern_prefix'test, %eax"' ||
- check_inline_asm inline_asm_direct_symbol_refs '"movl '$extern_prefix'test(%rip), %eax"'
-
- # check whether binutils is new enough to compile SSSE3/MMXEXT
- enabled ssse3 && check_inline_asm ssse3_inline '"pabsw %xmm0, %xmm0"'
- enabled mmxext && check_inline_asm mmxext_inline '"pmaxub %mm0, %mm1"'
-
- probe_x86asm(){
- x86asmexe_probe=$1
- if test_cmd $x86asmexe_probe -v; then
- x86asmexe=$x86asmexe_probe
- x86asm_type=nasm
- x86asm_debug="-g -F dwarf"
- X86ASMDEP=
- X86ASM_DEPFLAGS='-MD $(@:.o=.d)'
- elif test_cmd $x86asmexe_probe --version; then
- x86asmexe=$x86asmexe_probe
- x86asm_type=yasm
- x86asm_debug="-g dwarf2"
- X86ASMDEP='$(DEPX86ASM) $(X86ASMFLAGS) -M $(X86ASM_O) $< > $(@:.o=.d)'
- X86ASM_DEPFLAGS=
- fi
- check_x86asm x86asm "movbe ecx, [5]"
- }
-
- if ! disabled_any asm mmx x86asm; then
- disable x86asm
- for program in $x86asmexe nasm yasm; do
- probe_x86asm $program && break
- done
- disabled x86asm && die "nasm/yasm not found or too old. Use --disable-x86asm for a crippled build."
- X86ASMFLAGS="-f $objformat"
- enabled pic && append X86ASMFLAGS "-DPIC"
- test -n "$extern_prefix" && append X86ASMFLAGS "-DPREFIX"
- case "$objformat" in
- elf*) enabled debug && append X86ASMFLAGS $x86asm_debug ;;
- esac
-
- enabled avx512 && check_x86asm avx512_external "vmovdqa32 [eax]{k1}{z}, zmm0"
- enabled avx2 && check_x86asm avx2_external "vextracti128 xmm0, ymm0, 0"
- enabled xop && check_x86asm xop_external "vpmacsdd xmm0, xmm1, xmm2, xmm3"
- enabled fma4 && check_x86asm fma4_external "vfmaddps ymm0, ymm1, ymm2, ymm3"
- check_x86asm cpunop "CPU amdnop"
- fi
-
- case "$cpu" in
- athlon*|opteron*|k8*|pentium|pentium-mmx|prescott|nocona|atom|geode)
- disable fast_clz
- ;;
- esac
-
-fi
-
-check_cc intrinsics_neon arm_neon.h "int16x8_t test = vdupq_n_s16(0)"
-
-check_ldflags -Wl,--as-needed
-check_ldflags -Wl,-z,noexecstack
-
-if ! disabled network; then
- check_func getaddrinfo $network_extralibs
- check_func inet_aton $network_extralibs
-
- check_type netdb.h "struct addrinfo"
- check_type netinet/in.h "struct group_source_req" -D_BSD_SOURCE
- check_type netinet/in.h "struct ip_mreq_source" -D_BSD_SOURCE
- check_type netinet/in.h "struct ipv6_mreq" -D_DARWIN_C_SOURCE
- check_type poll.h "struct pollfd"
- check_type netinet/sctp.h "struct sctp_event_subscribe"
- check_struct "sys/socket.h" "struct msghdr" msg_flags
- check_struct "sys/types.h sys/socket.h" "struct sockaddr" sa_len
- check_type netinet/in.h "struct sockaddr_in6"
- check_type "sys/types.h sys/socket.h" "struct sockaddr_storage"
- check_type "sys/types.h sys/socket.h" socklen_t
-
- # Prefer arpa/inet.h over winsock2
- if check_headers arpa/inet.h ; then
- check_func closesocket
- elif check_headers winsock2.h ; then
- check_func_headers winsock2.h closesocket -lws2 &&
- network_extralibs="-lws2" ||
- { check_func_headers winsock2.h closesocket -lws2_32 &&
- network_extralibs="-lws2_32"; } || disable winsock2_h network
- check_func_headers ws2tcpip.h getaddrinfo $network_extralibs
-
- check_type ws2tcpip.h socklen_t
- check_type ws2tcpip.h "struct addrinfo"
- check_type ws2tcpip.h "struct group_source_req"
- check_type ws2tcpip.h "struct ip_mreq_source"
- check_type ws2tcpip.h "struct ipv6_mreq"
- check_type winsock2.h "struct pollfd"
- check_struct winsock2.h "struct sockaddr" sa_len
- check_type ws2tcpip.h "struct sockaddr_in6"
- check_type ws2tcpip.h "struct sockaddr_storage"
- else
- disable network
- fi
-fi
-
-check_builtin atomic_cas_ptr atomic.h "void **ptr; void *oldval, *newval; atomic_cas_ptr(ptr, oldval, newval)"
-check_builtin machine_rw_barrier mbarrier.h "__machine_rw_barrier()"
-check_builtin MemoryBarrier windows.h "MemoryBarrier()"
-check_builtin sync_val_compare_and_swap "" "int *ptr; int oldval, newval; __sync_val_compare_and_swap(ptr, oldval, newval)"
-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 x264_csp_bgr "stdint.h x264.h" "X264_CSP_BGR"
-
-case "$custom_allocator" in
- jemalloc)
- # jemalloc by default does not use a prefix
- require libjemalloc jemalloc/jemalloc.h malloc -ljemalloc
- ;;
- tcmalloc)
- require_pkg_config libtcmalloc libtcmalloc gperftools/tcmalloc.h tc_malloc
- malloc_prefix=tc_
- ;;
-esac
-
-check_func_headers malloc.h _aligned_malloc && enable aligned_malloc
-check_func ${malloc_prefix}memalign && enable memalign
-check_func ${malloc_prefix}posix_memalign && enable posix_memalign
-
-check_func access
-check_func_headers stdlib.h arc4random
-check_lib clock_gettime time.h clock_gettime || check_lib clock_gettime time.h clock_gettime -lrt
-check_func fcntl
-check_func fork
-check_func gethrtime
-check_func getopt
-check_func getrusage
-check_func gettimeofday
-check_func isatty
-check_func mkstemp
-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 sched_getaffinity
-check_func setrlimit
-check_struct "sys/stat.h" "struct stat" st_mtim.tv_nsec -D_BSD_SOURCE
-check_func strerror_r
-check_func sysconf
-check_func sysctl
-check_func usleep
-
-check_func_headers conio.h kbhit
-check_func_headers io.h setmode
-check_func_headers lzo/lzo1x.h lzo1x_999_compress
-check_func_headers mach/mach_time.h mach_absolute_time
-check_func_headers stdlib.h getenv
-check_func_headers sys/stat.h lstat
-
-check_func_headers windows.h GetModuleHandle
-check_func_headers windows.h GetProcessAffinityMask
-check_func_headers windows.h GetProcessTimes
-check_func_headers windows.h GetStdHandle
-check_func_headers windows.h GetSystemTimeAsFileTime
-check_func_headers windows.h LoadLibrary
-check_func_headers windows.h MapViewOfFile
-check_func_headers windows.h PeekNamedPipe
-check_func_headers windows.h SetConsoleTextAttribute
-check_func_headers windows.h SetConsoleCtrlHandler
-check_func_headers windows.h SetDllDirectory
-check_func_headers windows.h Sleep
-check_func_headers windows.h VirtualAlloc
-check_func_headers glob.h glob
-enabled xlib &&
- check_lib xlib "X11/Xlib.h X11/extensions/Xvlib.h" XvGetPortAttribute -lXv -lX11 -lXext
-
-check_headers direct.h
-check_headers dirent.h
-check_headers dxgidebug.h
-check_headers dxva.h
-check_headers dxva2api.h -D_WIN32_WINNT=0x0600
-check_headers io.h
-check_headers linux/perf_event.h
-check_headers libcrystalhd/libcrystalhd_if.h
-check_headers malloc.h
-check_headers mftransform.h
-check_headers net/udplite.h
-check_headers poll.h
-check_headers sys/param.h
-check_headers sys/resource.h
-check_headers sys/select.h
-check_headers sys/time.h
-check_headers sys/un.h
-check_headers termios.h
-check_headers unistd.h
-check_headers valgrind/valgrind.h
-check_func_headers VideoToolbox/VTCompressionSession.h VTCompressionSessionPrepareToEncodeFrames -framework VideoToolbox
-check_headers windows.h
-check_headers X11/extensions/XvMClib.h
-check_headers asm/types.h
-
-# it seems there are versions of clang in some distros that try to use the
-# gcc headers, which explodes for stdatomic
-# so we also check that atomics actually work here
-check_builtin stdatomic stdatomic.h "atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += bar"
-
-check_lib advapi32 "windows.h" RegCloseKey -ladvapi32
-check_lib bcrypt "windows.h bcrypt.h" BCryptGenRandom -lbcrypt &&
- check_cpp_condition bcrypt bcrypt.h "defined BCRYPT_RNG_ALGORITHM"
-check_lib ole32 "windows.h" CoTaskMemFree -lole32
-check_lib shell32 "windows.h shellapi.h" CommandLineToArgvW -lshell32
-check_lib psapi "windows.h psapi.h" GetProcessMemoryInfo -lpsapi
-
-check_lib android android/native_window.h ANativeWindow_acquire -landroid
-check_lib mediandk "stdint.h media/NdkImage.h" AImage_delete -lmediandk
-check_lib camera2ndk "stdbool.h stdint.h camera/NdkCameraManager.h" ACameraManager_create -lcamera2ndk
-
-enabled appkit && check_apple_framework AppKit
-enabled audiotoolbox && check_apple_framework AudioToolbox
-enabled avfoundation && check_apple_framework AVFoundation
-enabled coreimage && check_apple_framework CoreImage
-enabled videotoolbox && check_apple_framework VideoToolbox
-
-check_apple_framework CoreFoundation
-check_apple_framework CoreMedia
-check_apple_framework CoreVideo
-
-enabled avfoundation && {
- disable coregraphics applicationservices
- check_lib coregraphics CoreGraphics/CoreGraphics.h CGGetActiveDisplayList "-framework CoreGraphics" ||
- check_lib applicationservices ApplicationServices/ApplicationServices.h CGGetActiveDisplayList "-framework ApplicationServices"; }
-
-enabled videotoolbox && {
- check_lib coreservices CoreServices/CoreServices.h UTGetOSTypeFromString "-framework CoreServices"
- check_func_headers CoreMedia/CMFormatDescription.h kCMVideoCodecType_HEVC "-framework CoreMedia"
- check_func_headers CoreVideo/CVPixelBuffer.h kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange "-framework CoreVideo"
- check_func_headers CoreVideo/CVImageBuffer.h kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ "-framework CoreVideo"
- check_func_headers CoreVideo/CVImageBuffer.h kCVImageBufferTransferFunction_ITU_R_2100_HLG "-framework CoreVideo"
- check_func_headers CoreVideo/CVImageBuffer.h kCVImageBufferTransferFunction_Linear "-framework CoreVideo"
-}
-
-check_struct "sys/time.h sys/resource.h" "struct rusage" ru_maxrss
-
-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 d3d11.h" "ID3D11VideoDecoder"
-check_type "windows.h d3d11.h" "ID3D11VideoContext"
-check_type "d3d9.h dxva2api.h" DXVA2_ConfigPictureDecode -D_WIN32_WINNT=0x0602
-check_func_headers mfapi.h MFCreateAlignedMemoryBuffer -lmfplat
-
-check_type "vdpau/vdpau.h" "VdpPictureInfoHEVC"
-check_type "vdpau/vdpau.h" "VdpPictureInfoVP9"
-
-if [ -z "$nvccflags" ]; then
- nvccflags=$nvccflags_default
-fi
-
-if enabled x86_64 || enabled ppc64 || enabled aarch64; then
- nvccflags="$nvccflags -m64"
-else
- nvccflags="$nvccflags -m32"
-fi
-
-if enabled cuda_nvcc; then
- nvccflags="$nvccflags -ptx"
-else
- nvccflags="$nvccflags -S -nocudalib -nocudainc --cuda-device-only -include ${source_link}/compat/cuda/cuda_runtime.h"
- check_nvcc cuda_llvm
-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" ""
-fi
-
-check_cpp_condition winrt windows.h "!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)"
-
-if ! disabled w32threads && ! enabled pthreads; then
- check_func_headers "windows.h process.h" _beginthreadex &&
- check_type "windows.h" CONDITION_VARIABLE &&
- check_type "windows.h" INIT_ONCE &&
- enable w32threads || disable w32threads
- if ! enabled w32threads && enabled winrt; then
- check_func_headers "windows.h" CreateThread &&
- enable w32threads || disable w32threads
- fi
-fi
-
-# check for some common methods of building with pthread support
-# do this before the optional library checks as some of them require pthreads
-if ! disabled pthreads && ! enabled w32threads && ! enabled os2threads; then
- if check_lib pthreads pthread.h pthread_join -pthread &&
- check_lib pthreads pthread.h pthread_create -pthread; then
- add_cflags -pthread
- elif check_lib pthreads pthread.h pthread_join -pthreads &&
- check_lib pthreads pthread.h pthread_create -pthreads; then
- add_cflags -pthreads
- elif check_lib pthreads pthread.h pthread_join -ldl -pthread &&
- check_lib pthreads pthread.h pthread_create -ldl -pthread; then
- add_cflags -ldl -pthread
- elif check_lib pthreads pthread.h pthread_join -lpthreadGC2 &&
- check_lib pthreads pthread.h pthread_create -lpthreadGC2; then
- :
- elif check_lib pthreads pthread.h pthread_join -lpthread &&
- check_lib pthreads pthread.h pthread_create -lpthread; then
- :
- elif check_func pthread_join && check_func pthread_create; then
- enable pthreads
- fi
- check_cc pthreads "pthread.h" "static pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER"
-
- if enabled pthreads; then
- check_builtin sem_timedwait semaphore.h "sem_t *s; sem_init(s,0,0); sem_timedwait(s,0); sem_destroy(s)" $pthreads_extralibs
- check_func pthread_cancel $pthreads_extralibs
- fi
-fi
-
-enabled zlib && { check_pkg_config zlib zlib "zlib.h" zlibVersion ||
- check_lib zlib zlib.h zlibVersion -lz; }
-enabled bzlib && check_lib bzlib bzlib.h BZ2_bzlibVersion -lbz2
-enabled lzma && check_lib lzma lzma.h lzma_version_number -llzma
-
-# On some systems dynamic loading requires no extra linker flags
-check_lib libdl dlfcn.h "dlopen dlsym" || check_lib libdl dlfcn.h "dlopen dlsym" -ldl
-
-check_lib libm math.h sin -lm
-
-atan2f_args=2
-copysign_args=2
-hypot_args=2
-ldexpf_args=2
-powf_args=2
-
-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"
-enabled cuda_nvcc && { check_nvcc cuda_nvcc || die "ERROR: failed checking for nvcc."; }
-enabled chromaprint && require chromaprint chromaprint.h chromaprint_get_version -lchromaprint
-enabled decklink && { require_headers DeckLinkAPI.h &&
- { test_cpp_condition DeckLinkAPIVersion.h "BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a090500" || die "ERROR: Decklink API version must be >= 10.9.5."; } }
-enabled frei0r && require_headers "frei0r.h dlfcn.h"
-enabled gmp && require gmp gmp.h mpz_export -lgmp
-enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gnutls_global_init
-enabled jni && { [ $target_os = "android" ] && check_headers jni.h && enabled pthreads || die "ERROR: jni not found"; }
-enabled ladspa && require_headers "ladspa.h dlfcn.h"
-enabled libaom && require_pkg_config libaom "aom >= 1.0.0" aom/aom_codec.h aom_codec_version
-enabled libaribb24 && { check_pkg_config libaribb24 "aribb24 > 1.0.3" "aribb24/aribb24.h" arib_instance_new ||
- { enabled gpl && require_pkg_config libaribb24 aribb24 "aribb24/aribb24.h" arib_instance_new; } ||
- die "ERROR: libaribb24 requires version higher than 1.0.3 or --enable-gpl."; }
-enabled lv2 && require_pkg_config lv2 lilv-0 "lilv/lilv.h" lilv_world_new
-enabled libiec61883 && require libiec61883 libiec61883/iec61883.h iec61883_cmp_connect -lraw1394 -lavc1394 -lrom1394 -liec61883
-enabled libass && require_pkg_config libass libass ass/ass.h ass_library_init
-enabled libbluray && require_pkg_config libbluray libbluray libbluray/bluray.h bd_open
-enabled libbs2b && require_pkg_config libbs2b libbs2b bs2b.h bs2b_open
-enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 &&
- { check_lib libcelt celt/celt.h celt_decoder_create_custom -lcelt0 ||
- die "ERROR: libcelt must be installed and version must be >= 0.11.0."; }
-enabled libcaca && require_pkg_config libcaca caca caca.h caca_create_canvas
-enabled libcodec2 && require libcodec2 codec2/codec2.h codec2_create -lcodec2
-enabled libdav1d && require_pkg_config libdav1d "dav1d >= 0.4.0" "dav1d/dav1d.h" dav1d_version
-enabled libdavs2 && require_pkg_config libdavs2 "davs2 >= 1.6.0" davs2.h davs2_decoder_open
-enabled libdc1394 && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new
-enabled libdrm && require_pkg_config libdrm libdrm xf86drm.h drmGetVersion
-enabled libfdk_aac && { check_pkg_config libfdk_aac fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen ||
- { require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac &&
- warn "using libfdk without pkg-config"; } }
-flite_extralibs="-lflite_cmu_time_awb -lflite_cmu_us_awb -lflite_cmu_us_kal -lflite_cmu_us_kal16 -lflite_cmu_us_rms -lflite_cmu_us_slt -lflite_usenglish -lflite_cmulex -lflite"
-enabled libflite && require libflite "flite/flite.h" flite_init $flite_extralibs
-enabled fontconfig && enable libfontconfig
-enabled libfontconfig && require_pkg_config libfontconfig fontconfig "fontconfig/fontconfig.h" FcInit
-enabled libfreetype && require_pkg_config libfreetype freetype2 "ft2build.h FT_FREETYPE_H" FT_Init_FreeType
-enabled libfribidi && require_pkg_config libfribidi fribidi fribidi.h fribidi_version_info
-enabled libglslang && require_cpp libglslang glslang/SPIRV/GlslangToSpv.h "glslang::TIntermediate*" -lglslang -lOSDependent -lHLSL -lOGLCompiler -lSPVRemapper -lSPIRV -lSPIRV-Tools-opt -lSPIRV-Tools -lpthread -lstdc++
-enabled libgme && { check_pkg_config libgme libgme gme/gme.h gme_new_emu ||
- require libgme gme/gme.h gme_new_emu -lgme -lstdc++; }
-enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do
- check_lib libgsm "${gsm_hdr}" gsm_create -lgsm && break;
- done || die "ERROR: libgsm not found"; }
-enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc $pthreads_extralibs
-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
-# 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 "mfx/mfxvideo.h" MFXInit ||
- { require libmfx "mfx/mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } }
-if enabled libmfx; then
- check_cc MFX_CODEC_VP9 "mfx/mfxvp9.h mfx/mfxstructures.h" "MFX_CODEC_VP9"
-fi
-
-enabled libmodplug && require_pkg_config libmodplug libmodplug libmodplug/modplug.h ModPlug_Load
-enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame $libm_extralibs
-enabled libmysofa && { check_pkg_config libmysofa libmysofa mysofa.h mysofa_neighborhood_init_withstepdefine ||
- require libmysofa mysofa.h mysofa_neighborhood_init_withstepdefine -lmysofa $zlib_extralibs; }
-enabled libnpp && { check_lib libnpp npp.h nppGetLibVersion -lnppig -lnppicc -lnppc -lnppidei ||
- check_lib libnpp npp.h nppGetLibVersion -lnppi -lnppc -lnppidei ||
- die "ERROR: libnpp not found"; }
-enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb
-enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb
-enabled libopencv && { check_headers opencv2/core/core_c.h &&
- { check_pkg_config libopencv opencv opencv2/core/core_c.h cvCreateImageHeader ||
- require libopencv opencv2/core/core_c.h cvCreateImageHeader -lopencv_core -lopencv_imgproc; } ||
- require_pkg_config libopencv opencv opencv/cxcore.h cvCreateImageHeader; }
-enabled libopenh264 && require_pkg_config libopenh264 openh264 wels/codec_api.h WelsGetCodecVersion
-enabled libopenjpeg && { check_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version ||
- { require_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version -DOPJ_STATIC && add_cppflags -DOPJ_STATIC; } }
-enabled libopenmpt && require_pkg_config libopenmpt "libopenmpt >= 0.2.6557" libopenmpt/libopenmpt.h openmpt_module_create -lstdc++ && append libopenmpt_extralibs "-lstdc++"
-enabled libopus && {
- enabled libopus_decoder && {
- require_pkg_config libopus opus opus_multistream.h opus_multistream_decoder_create
- }
- enabled libopus_encoder && {
- require_pkg_config libopus opus opus_multistream.h opus_multistream_surround_encoder_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.1.0" rav1e.h rav1e_context_new
-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
-enabled librubberband && require_pkg_config librubberband "rubberband >= 1.8.1" rubberband/rubberband-c.h rubberband_new -lstdc++ && append librubberband_extralibs "-lstdc++"
-enabled libshine && require_pkg_config libshine shine shine/layer3.h shine_encode_buffer
-enabled libsmbclient && { check_pkg_config libsmbclient smbclient libsmbclient.h smbc_init ||
- require libsmbclient libsmbclient.h smbc_init -lsmbclient; }
-enabled libsnappy && require libsnappy snappy-c.h snappy_compress -lsnappy -lstdc++
-enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr
-enabled libssh && require_pkg_config libssh libssh libssh/sftp.h sftp_init
-enabled libspeex && require_pkg_config libspeex speex speex/speex.h speex_decoder_init
-enabled libsrt && require_pkg_config libsrt "srt >= 1.3.0" srt/srt.h srt_socket
-enabled libtensorflow && require libtensorflow tensorflow/c/c_api.h TF_Version -ltensorflow
-enabled libtesseract && require_pkg_config libtesseract tesseract tesseract/capi.h TessBaseAPICreate
-enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
-enabled libtls && require_pkg_config libtls libtls tls.h tls_configure
-enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame &&
- { check_lib libtwolame twolame.h twolame_encode_buffer_float32_interleaved -ltwolame ||
- die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; }
-enabled libudev && require_pkg_config libudev libudev libudev.h udev_new
-enabled libv4l2 && require_pkg_config libv4l2 libv4l2 libv4l2.h v4l2_ioctl
-enabled libvidstab && require_pkg_config libvidstab "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit
-enabled libvmaf && require_pkg_config libvmaf "libvmaf >= 1.3.9" libvmaf.h compute_vmaf
-enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
-enabled libvorbis && require_pkg_config libvorbis vorbis vorbis/codec.h vorbis_info_init &&
- require_pkg_config libvorbisenc vorbisenc vorbis/vorbisenc.h vorbis_encode_init
-
-enabled libvpx && {
- enabled libvpx_vp8_decoder && {
- check_pkg_config libvpx_vp8_decoder "vpx >= 1.4.0" "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp8_dx ||
- check_lib libvpx_vp8_decoder "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_vp8_dx VPX_IMG_FMT_HIGHBITDEPTH" "-lvpx $libm_extralibs $pthreads_extralibs"
- }
- enabled libvpx_vp8_encoder && {
- check_pkg_config libvpx_vp8_encoder "vpx >= 1.4.0" "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp8_cx ||
- check_lib libvpx_vp8_encoder "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_vp8_cx VPX_IMG_FMT_HIGHBITDEPTH" "-lvpx $libm_extralibs $pthreads_extralibs"
- }
- enabled libvpx_vp9_decoder && {
- check_pkg_config libvpx_vp9_decoder "vpx >= 1.4.0" "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp9_dx ||
- check_lib libvpx_vp9_decoder "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_vp9_dx VPX_IMG_FMT_HIGHBITDEPTH" "-lvpx $libm_extralibs $pthreads_extralibs"
- }
- enabled libvpx_vp9_encoder && {
- check_pkg_config libvpx_vp9_encoder "vpx >= 1.4.0" "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp9_cx ||
- check_lib libvpx_vp9_encoder "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_vp9_cx VPX_IMG_FMT_HIGHBITDEPTH" "-lvpx $libm_extralibs $pthreads_extralibs"
- }
- if disabled_all libvpx_vp8_decoder libvpx_vp9_decoder libvpx_vp8_encoder libvpx_vp9_encoder; then
- die "libvpx enabled but no supported decoders found"
- fi
-}
-
-enabled libwavpack && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput -lwavpack
-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 && { check_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode ||
- { require libx264 "stdint.h x264.h" x264_encoder_encode "-lx264 $pthreads_extralibs $libm_extralibs" &&
- warn "using libx264 without pkg-config"; } } &&
- require_cpp_condition libx264 x264.h "X264_BUILD >= 118" &&
- 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"
-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
-enabled libzimg && require_pkg_config libzimg "zimg >= 2.7.0" zimg.h zimg_get_api_version
-enabled libzmq && require_pkg_config libzmq "libzmq >= 4.2.1" zmq.h zmq_ctx_new
-enabled libzvbi && require_pkg_config libzvbi zvbi-0.2 libzvbi.h vbi_decoder_new &&
- { test_cpp_condition libzvbi.h "VBI_VERSION_MAJOR > 0 || VBI_VERSION_MINOR > 2 || VBI_VERSION_MINOR == 2 && VBI_VERSION_MICRO >= 28" ||
- enabled gpl || die "ERROR: libzvbi requires version 0.2.28 or --enable-gpl."; }
-enabled libxml2 && require_pkg_config libxml2 libxml-2.0 libxml2/libxml/xmlversion.h xmlCheckVersion
-enabled mbedtls && { check_pkg_config mbedtls mbedtls mbedtls/x509_crt.h mbedtls_x509_crt_init ||
- check_pkg_config mbedtls mbedtls mbedtls/ssl.h mbedtls_ssl_init ||
- check_lib mbedtls mbedtls/ssl.h mbedtls_ssl_init -lmbedtls -lmbedx509 -lmbedcrypto ||
- die "ERROR: mbedTLS not found"; }
-enabled mediacodec && { enabled jni || die "ERROR: mediacodec requires --enable-jni"; }
-enabled mmal && { check_lib mmal interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host ||
- { ! enabled cross_compile &&
- add_cflags -isystem/opt/vc/include/ -isystem/opt/vc/include/interface/vmcs_host/linux -isystem/opt/vc/include/interface/vcos/pthreads -fgnu89-inline &&
- add_ldflags -L/opt/vc/lib/ &&
- 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
- 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)" ||
- die "ERROR: openal must be installed and version must be 1.1 or compatible"; }
-enabled opencl && { check_pkg_config opencl OpenCL CL/cl.h clEnqueueNDRangeKernel ||
- check_lib opencl OpenCL/cl.h clEnqueueNDRangeKernel -Wl,-framework,OpenCL ||
- check_lib opencl CL/cl.h clEnqueueNDRangeKernel -lOpenCL ||
- die "ERROR: opencl not found"; } &&
- { test_cpp_condition "OpenCL/cl.h" "defined(CL_VERSION_1_2)" ||
- test_cpp_condition "CL/cl.h" "defined(CL_VERSION_1_2)" ||
- die "ERROR: opencl must be installed and version must be 1.2 or compatible"; }
-enabled opengl && { check_lib opengl GL/glx.h glXGetProcAddress "-lGL" ||
- check_lib opengl windows.h wglGetProcAddress "-lopengl32 -lgdi32" ||
- check_lib opengl OpenGL/gl3.h glGetError "-Wl,-framework,OpenGL" ||
- check_lib opengl ES2/gl.h glGetError "-isysroot=${sysroot} -Wl,-framework,OpenGLES" ||
- die "ERROR: opengl not found."
- }
-enabled omx_rpi && { test_code cc OMX_Core.h OMX_IndexConfigBrcmVideoRequestIFrame ||
- { ! enabled cross_compile &&
- add_cflags -isystem/opt/vc/include/IL &&
- test_code cc OMX_Core.h OMX_IndexConfigBrcmVideoRequestIFrame; } ||
- die "ERROR: OpenMAX IL headers from raspberrypi/firmware not found"; } &&
- enable omx
-enabled omx && require_headers OMX_Core.h
-enabled openssl && { check_pkg_config openssl openssl openssl/ssl.h OPENSSL_init_ssl ||
- check_pkg_config openssl openssl openssl/ssl.h SSL_library_init ||
- check_lib openssl openssl/ssl.h OPENSSL_init_ssl -lssl -lcrypto ||
- check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto ||
- check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 ||
- check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 ||
- die "ERROR: openssl not found"; }
-enabled pocketsphinx && require_pkg_config pocketsphinx pocketsphinx pocketsphinx/pocketsphinx.h ps_init
-enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/rk_mpi.h mpp_create &&
- require_pkg_config rockchip_mpp "rockchip_mpp >= 1.3.7" rockchip/rk_mpi.h mpp_create &&
- { enabled libdrm ||
- die "ERROR: rkmpp requires --enable-libdrm"; }
- }
-enabled v4l2_request && { enabled libdrm ||
- die "ERROR: v4l2-request requires --enable-libdrm"; } &&
- { enabled libudev ||
- die "ERROR: v4l2-request requires --enable-libudev"; }
-enabled vapoursynth && require_pkg_config vapoursynth "vapoursynth-script >= 42" VSScript.h vsscript_init
-
-
-if enabled gcrypt; then
- GCRYPT_CONFIG="${cross_prefix}libgcrypt-config"
- if "${GCRYPT_CONFIG}" --version > /dev/null 2>&1; then
- gcrypt_cflags=$("${GCRYPT_CONFIG}" --cflags)
- gcrypt_extralibs=$("${GCRYPT_CONFIG}" --libs)
- check_func_headers gcrypt.h gcry_mpi_new $gcrypt_cflags $gcrypt_extralibs ||
- die "ERROR: gcrypt not found"
- add_cflags $gcrypt_cflags
- else
- require gcrypt gcrypt.h gcry_mpi_new -lgcrypt
- fi
-fi
-
-if enabled sdl2; then
- SDL2_CONFIG="${cross_prefix}sdl2-config"
- test_pkg_config sdl2 "sdl2 >= 2.0.1 sdl2 < 2.1.0" SDL_events.h SDL_PollEvent
- if disabled sdl2 && "${SDL2_CONFIG}" --version > /dev/null 2>&1; then
- sdl2_cflags=$("${SDL2_CONFIG}" --cflags)
- sdl2_extralibs=$("${SDL2_CONFIG}" --libs)
- test_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x020001" $sdl2_cflags &&
- test_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x020100" $sdl2_cflags &&
- check_func_headers SDL_events.h SDL_PollEvent $sdl2_extralibs $sdl2_cflags &&
- enable sdl2
- fi
- if test $target_os = "mingw32"; then
- sdl2_extralibs=$(filter_out '-mwindows' $sdl2_extralibs)
- fi
-fi
-
-if enabled decklink; then
- case $target_os in
- mingw32*|mingw64*|win32|win64)
- decklink_outdev_extralibs="$decklink_outdev_extralibs -lole32 -loleaut32"
- decklink_indev_extralibs="$decklink_indev_extralibs -lole32 -loleaut32"
- ;;
- esac
-fi
-
-enabled securetransport &&
- check_func SecIdentityCreate "-Wl,-framework,CoreFoundation -Wl,-framework,Security" &&
- check_lib securetransport "Security/SecureTransport.h Security/Security.h" "SSLCreateContext" "-Wl,-framework,CoreFoundation -Wl,-framework,Security" ||
- disable securetransport
-
-enabled securetransport &&
- check_func SecItemImport "-Wl,-framework,CoreFoundation -Wl,-framework,Security"
-
-enabled schannel &&
- check_func_headers "windows.h security.h" InitializeSecurityContext -DSECURITY_WIN32 -lsecur32 &&
- test_cpp_condition winerror.h "defined(SEC_I_CONTEXT_EXPIRED)" &&
- schannel_extralibs="-lsecur32" ||
- disable schannel
-
-makeinfo --version > /dev/null 2>&1 && enable makeinfo || disable makeinfo
-enabled makeinfo \
- && [ 0$(makeinfo --version | grep "texinfo" | sed 's/.*texinfo[^0-9]*\([0-9]*\)\..*/\1/') -ge 5 ] \
- && enable makeinfo_html || disable makeinfo_html
-disabled makeinfo_html && texi2html --help 2> /dev/null | grep -q 'init-file' && enable texi2html || disable texi2html
-perl -v > /dev/null 2>&1 && enable perl || disable perl
-pod2man --help > /dev/null 2>&1 && enable pod2man || disable pod2man
-rsync --help 2> /dev/null | grep -q 'contimeout' && enable rsync_contimeout || disable rsync_contimeout
-
-# check V4L2 codecs available in the API
-if enabled v4l2_m2m; then
- check_headers linux/fb.h
- check_headers linux/videodev2.h
- test_code cc linux/videodev2.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete
- check_cc v4l2_m2m linux/videodev2.h "int i = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_VIDEO_M2M | V4L2_BUF_FLAG_LAST;"
- check_cc vc1_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VC1_ANNEX_G;"
- check_cc mpeg1_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG1;"
- check_cc mpeg2_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2;"
- check_cc mpeg4_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG4;"
- check_cc hevc_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_HEVC;"
- check_cc h263_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_H263;"
- check_cc h264_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_H264;"
- check_cc vp8_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP8;"
- check_cc vp9_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP9;"
-fi
-
-check_func_headers "linux/media.h linux/videodev2.h" v4l2_timeval_to_ns
-check_cc h264_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_H264_SLICE;"
-check_cc hevc_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_HEVC_SLICE;"
-check_cc mpeg2_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2_SLICE;"
-check_cc vp8_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_VP8_FRAME;"
-check_cc vp9_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_VP9_FRAME;"
-
-check_headers sys/videoio.h
-test_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete
-
-check_lib user32 "windows.h winuser.h" GetShellWindow -luser32
-check_lib vfw32 "windows.h vfw.h" capCreateCaptureWindow -lvfw32
-# check that WM_CAP_DRIVER_CONNECT is defined to the proper value
-# w32api 3.12 had it defined wrong
-check_cpp_condition vfwcap_defines vfw.h "WM_CAP_DRIVER_CONNECT > WM_USER"
-
-check_type "dshow.h" IBaseFilter
-
-# check for ioctl_meteor.h, ioctl_bt848.h and alternatives
-check_headers "dev/bktr/ioctl_meteor.h dev/bktr/ioctl_bt848.h" ||
- check_headers "machine/ioctl_meteor.h machine/ioctl_bt848.h" ||
- check_headers "dev/video/meteor/ioctl_meteor.h dev/video/bktr/ioctl_bt848.h" ||
- check_headers "dev/ic/bt8xx.h"
-
-if check_struct sys/soundcard.h audio_buf_info bytes; then
- enable_sanitized sys/soundcard.h
-else
- test_cc -D__BSD_VISIBLE -D__XSI_VISIBLE <<EOF && add_cppflags -D__BSD_VISIBLE -D__XSI_VISIBLE && enable_sanitized sys/soundcard.h
- #include <sys/soundcard.h>
- audio_buf_info abc;
-EOF
-fi
-
-enabled alsa && { check_pkg_config alsa alsa "alsa/asoundlib.h" snd_pcm_htimestamp ||
- check_lib alsa alsa/asoundlib.h snd_pcm_htimestamp -lasound; }
-
-enabled libjack &&
- require_pkg_config libjack jack jack/jack.h jack_port_get_latency_range
-
-enabled sndio && check_lib sndio sndio.h sio_open -lsndio
-
-if enabled libcdio; then
- check_pkg_config libcdio libcdio_paranoia "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open ||
- check_pkg_config libcdio libcdio_paranoia "cdio/paranoia/cdda.h cdio/paranoia/paranoia.h" cdio_cddap_open ||
- check_lib libcdio "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio ||
- check_lib libcdio "cdio/paranoia/cdda.h cdio/paranoia/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio ||
- die "ERROR: No usable libcdio/cdparanoia found"
-fi
-
-enabled libxcb && check_pkg_config libxcb "xcb >= 1.4" xcb/xcb.h xcb_connect ||
- disable libxcb_shm libxcb_shape libxcb_xfixes
-
-if enabled libxcb; then
- enabled libxcb_shm && check_pkg_config libxcb_shm xcb-shm xcb/shm.h xcb_shm_attach
- enabled libxcb_shape && check_pkg_config libxcb_shape xcb-shape xcb/shape.h xcb_shape_get_rectangles
- enabled libxcb_xfixes && check_pkg_config libxcb_xfixes xcb-xfixes xcb/xfixes.h xcb_xfixes_get_cursor_image
-fi
-
-check_func_headers "windows.h" CreateDIBSection "$gdigrab_indev_extralibs"
-
-# d3d11va requires linking directly to dxgi and d3d11 if not building for
-# the desktop api partition
-test_cpp <<EOF && enable uwp && d3d11va_extralibs="-ldxgi -ld3d11"
-#ifdef WINAPI_FAMILY
-#include <winapifamily.h>
-#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-#error desktop, not uwp
-#else
-// WINAPI_FAMILY_APP, WINAPI_FAMILY_PHONE_APP => UWP
-#endif
-#else
-#error no family set
-#endif
-EOF
-
-enabled vaapi &&
- check_pkg_config vaapi "libva >= 0.35.0" "va/va.h" vaInitialize
-
-if enabled vaapi; then
- check_pkg_config vaapi_drm "libva-drm" "va/va_drm.h" vaGetDisplayDRM
-
- if enabled xlib; then
- check_pkg_config vaapi_x11 "libva-x11" "va/va_x11.h" vaGetDisplay
- fi
-
- check_cpp_condition vaapi_1 "va/va.h" "VA_CHECK_VERSION(1, 0, 0)"
-
- check_type "va/va.h va/va_dec_hevc.h" "VAPictureParameterBufferHEVC"
- check_struct "va/va.h" "VADecPictureParameterBufferVP9" bit_depth
- check_type "va/va.h va/va_vpp.h" "VAProcFilterParameterBufferHDRToneMapping"
- check_struct "va/va.h va/va_vpp.h" "VAProcPipelineCaps" rotation_flags
- check_type "va/va.h va/va_enc_hevc.h" "VAEncPictureParameterBufferHEVC"
- check_type "va/va.h va/va_enc_jpeg.h" "VAEncPictureParameterBufferJPEG"
- check_type "va/va.h va/va_enc_vp8.h" "VAEncPictureParameterBufferVP8"
- check_type "va/va.h va/va_enc_vp9.h" "VAEncPictureParameterBufferVP9"
-fi
-
-if enabled_all opencl libdrm ; then
- check_type "CL/cl_intel.h" "clCreateImageFromFdINTEL_fn" &&
- enable opencl_drm_beignet
- check_func_headers "CL/cl_ext.h" clImportMemoryARM &&
- enable opencl_drm_arm
-fi
-
-if enabled_all opencl vaapi ; then
- if enabled opencl_drm_beignet ; then
- enable opencl_vaapi_beignet
- else
- check_type "CL/cl.h CL/cl_va_api_media_sharing_intel.h" "clCreateFromVA_APIMediaSurfaceINTEL_fn" &&
- enable opencl_vaapi_intel_media
- fi
-fi
-
-if enabled_all opencl dxva2 ; then
- check_type "CL/cl_dx9_media_sharing.h" cl_dx9_surface_info_khr &&
- enable opencl_dxva2
-fi
-
-if enabled_all opencl d3d11va ; then
- check_type "CL/cl_d3d11.h" clGetDeviceIDsFromD3D11KHR_fn &&
- enable opencl_d3d11
-fi
-
-enabled vdpau &&
- check_cpp_condition vdpau vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP"
-
-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 vulkan &&
- require_pkg_config vulkan "vulkan >= 1.1.97" "vulkan/vulkan.h" vkCreateInstance
-
-if enabled x86; then
- case $target_os in
- mingw32*|mingw64*|win32|win64|linux|cygwin*)
- ;;
- *)
- disable ffnvcodec cuvid nvdec nvenc
- ;;
- esac
-elif enabled_any aarch64 ppc64 && ! enabled bigendian; then
- case $target_os in
- linux)
- ;;
- *)
- disable ffnvcodec cuvid nvdec nvenc
- ;;
- esac
-else
- disable ffnvcodec cuvid nvdec nvenc
-fi
-
-enabled ffnvcodec && enable cuda
-
-enabled nvenc &&
- test_cc -I$source_path <<EOF || disable nvenc
-#include <ffnvcodec/nvEncodeAPI.h>
-NV_ENCODE_API_FUNCTION_LIST flist;
-void f(void) { struct { const GUID guid; } s[] = { { NV_ENC_PRESET_HQ_GUID } }; }
-int main(void) { return 0; }
-EOF
-
-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"
-
-# Funny iconv installations are not unusual, so check it after all flags have been set
-if enabled libc_iconv; then
- check_func_headers iconv.h iconv
-elif enabled iconv; then
- check_func_headers iconv.h iconv || check_lib iconv iconv.h iconv -liconv
-fi
-
-enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel"
-
-# add some useful compiler flags if supported
-check_cflags -Wdeclaration-after-statement
-check_cflags -Wall
-check_cflags -Wdisabled-optimization
-check_cflags -Wpointer-arith
-check_cflags -Wredundant-decls
-check_cflags -Wwrite-strings
-check_cflags -Wtype-limits
-check_cflags -Wundef
-check_cflags -Wmissing-prototypes
-check_cflags -Wno-pointer-to-int-cast
-check_cflags -Wstrict-prototypes
-check_cflags -Wempty-body
-
-if enabled extra_warnings; then
- check_cflags -Wcast-qual
- check_cflags -Wextra
- check_cflags -Wpedantic
-fi
-
-check_disable_warning(){
- warning_flag=-W${1#-Wno-}
- test_cflags $unknown_warning_flags $warning_flag && add_cflags $1
-}
-
-test_cflags -Werror=unused-command-line-argument &&
- append unknown_warning_flags "-Werror=unused-command-line-argument"
-test_cflags -Werror=unknown-warning-option &&
- append unknown_warning_flags "-Werror=unknown-warning-option"
-
-check_disable_warning -Wno-parentheses
-check_disable_warning -Wno-switch
-check_disable_warning -Wno-format-zero-length
-check_disable_warning -Wno-pointer-sign
-check_disable_warning -Wno-unused-const-variable
-check_disable_warning -Wno-bool-operation
-check_disable_warning -Wno-char-subscripts
-
-check_disable_warning_headers(){
- warning_flag=-W${1#-Wno-}
- test_cflags $warning_flag && add_cflags_headers $1
-}
-
-check_disable_warning_headers -Wno-deprecated-declarations
-check_disable_warning_headers -Wno-unused-variable
-
-test_cc <<EOF && enable blocks_extension
-void (^block)(void);
-EOF
-
-# add some linker flags
-check_ldflags -Wl,--warn-common
-check_ldflags -Wl,-rpath-link=:libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample
-enabled rpath && add_ldexeflags -Wl,-rpath,$libdir && add_ldsoflags -Wl,-rpath,$libdir
-test_ldflags -Wl,-Bsymbolic && append SHFLAGS -Wl,-Bsymbolic
-
-# add some strip flags
-check_stripflags -x
-
-enabled neon_clobber_test &&
- check_ldflags -Wl,--wrap,avcodec_open2 \
- -Wl,--wrap,avcodec_decode_audio4 \
- -Wl,--wrap,avcodec_decode_video2 \
- -Wl,--wrap,avcodec_decode_subtitle2 \
- -Wl,--wrap,avcodec_encode_audio2 \
- -Wl,--wrap,avcodec_encode_video2 \
- -Wl,--wrap,avcodec_encode_subtitle \
- -Wl,--wrap,avcodec_send_packet \
- -Wl,--wrap,avcodec_receive_packet \
- -Wl,--wrap,avcodec_send_frame \
- -Wl,--wrap,avcodec_receive_frame \
- -Wl,--wrap,swr_convert \
- -Wl,--wrap,avresample_convert ||
- disable neon_clobber_test
-
-enabled xmm_clobber_test &&
- check_ldflags -Wl,--wrap,avcodec_open2 \
- -Wl,--wrap,avcodec_decode_audio4 \
- -Wl,--wrap,avcodec_decode_video2 \
- -Wl,--wrap,avcodec_decode_subtitle2 \
- -Wl,--wrap,avcodec_encode_audio2 \
- -Wl,--wrap,avcodec_encode_video2 \
- -Wl,--wrap,avcodec_encode_subtitle \
- -Wl,--wrap,avcodec_send_packet \
- -Wl,--wrap,avcodec_receive_packet \
- -Wl,--wrap,avcodec_send_frame \
- -Wl,--wrap,avcodec_receive_frame \
- -Wl,--wrap,swr_convert \
- -Wl,--wrap,avresample_convert \
- -Wl,--wrap,sws_scale ||
- disable xmm_clobber_test
-
-check_ld "cc" proper_dce <<EOF
-extern const int array[512];
-static inline int func(void) { return array[0]; }
-int main(void) { return 0; }
-EOF
-
-if enabled proper_dce; then
- echo "X { local: *; };" > $TMPV
- if test_ldflags -Wl,${version_script},$TMPV; then
- append SHFLAGS '-Wl,${version_script},\$(SUBDIR)lib\$(NAME).ver'
- quotes='""'
- test_cc <<EOF && enable symver_asm_label
-void ff_foo(void) __asm__ ("av_foo@VERSION");
-void ff_foo(void) { ${inline_asm+__asm__($quotes);} }
-EOF
- test_cc <<EOF && enable symver_gnu_asm
-__asm__(".symver ff_foo,av_foo@VERSION");
-void ff_foo(void) {}
-EOF
- fi
-fi
-
-if [ -z "$optflags" ]; then
- if enabled small; then
- optflags=$cflags_size
- elif enabled optimizations; then
- optflags=$cflags_speed
- else
- optflags=$cflags_noopt
- fi
-fi
-
-check_optflags(){
- check_cflags "$@"
- enabled lto && check_ldflags "$@"
-}
-
-check_optflags $optflags
-check_optflags -fno-math-errno
-check_optflags -fno-signed-zeros
-
-if enabled lto; then
- test "$cc_type" != "$ld_type" && die "LTO requires same compiler and linker"
- check_cflags -flto
- check_ldflags -flto $cpuflags
- disable inline_asm_direct_symbol_refs
-fi
-
-enabled ftrapv && check_cflags -ftrapv
-
-test_cc -mno-red-zone <<EOF && noredzone_flags="-mno-red-zone"
-int x;
-EOF
-
-
-if enabled icc; then
- # Just warnings, no remarks
- check_cflags -w1
- # -wd: Disable following warnings
- # 144, 167, 556: -Wno-pointer-sign
- # 188: enumerated type mixed with another type
- # 1292: attribute "foo" ignored
- # 1419: external declaration in primary source file
- # 10006: ignoring unknown option -fno-signed-zeros
- # 10148: ignoring unknown option -Wno-parentheses
- # 10156: ignoring option '-W'; no argument required
- # 13200: No EMMS instruction before call to function
- # 13203: No EMMS instruction before return from function
- check_cflags -wd144,167,188,556,1292,1419,10006,10148,10156,13200,13203
- # 11030: Warning unknown option --as-needed
- # 10156: ignoring option '-export'; no argument required
- check_ldflags -wd10156,11030
- # icc 11.0 and 11.1 work with ebp_available, but don't pass the test
- enable ebp_available
- # The test above does not test linking
- enabled lto && disable symver_asm_label
- if enabled x86_32; then
- icc_version=$($cc -dumpversion)
- test ${icc_version%%.*} -ge 11 &&
- check_cflags -falign-stack=maintain-16-byte ||
- disable aligned_stack
- fi
-elif enabled gcc; then
- check_optflags -fno-tree-vectorize
- check_cflags -Werror=format-security
- check_cflags -Werror=implicit-function-declaration
- check_cflags -Werror=missing-prototypes
- check_cflags -Werror=return-type
- check_cflags -Werror=vla
- check_cflags -Wformat
- check_cflags -fdiagnostics-color=auto
- enabled extra_warnings || check_disable_warning -Wno-maybe-uninitialized
- if enabled x86_32; then
- case $target_os in
- *bsd*)
- # BSDs don't guarantee a 16 byte aligned stack, but we can
- # request GCC to try to maintain 16 byte alignment throughout
- # function calls. Library entry points that might call assembly
- # functions align the stack. (The parameter means 2^4 bytes.)
- check_cflags -mpreferred-stack-boundary=4
- ;;
- esac
- fi
-elif enabled llvm_gcc; then
- check_cflags -mllvm -stack-alignment=16
-elif enabled clang; then
- if enabled x86_32; then
- # Clang doesn't support maintaining alignment without assuming the
- # same alignment in every function. If 16 byte alignment would be
- # enabled, one would also have to either add attribute_align_arg on
- # every single entry point into the libraries or enable -mstackrealign
- # (doing stack realignment in every single function).
- case $target_os in
- mingw32|win32|*bsd*)
- disable aligned_stack
- ;;
- *)
- check_cflags -mllvm -stack-alignment=16
- check_cflags -mstack-alignment=16
- ;;
- esac
- else
- check_cflags -mllvm -stack-alignment=16
- check_cflags -mstack-alignment=16
- fi
- check_cflags -Qunused-arguments
- check_cflags -Werror=implicit-function-declaration
- check_cflags -Werror=missing-prototypes
- check_cflags -Werror=return-type
-elif enabled cparser; then
- add_cflags -Wno-missing-variable-declarations
- add_cflags -Wno-empty-statement
-elif enabled armcc; then
- add_cflags -W${armcc_opt},--diag_suppress=4343 # hardfp compat
- add_cflags -W${armcc_opt},--diag_suppress=3036 # using . as system include dir
- # 2523: use of inline assembly is deprecated
- add_cflags -W${armcc_opt},--diag_suppress=2523
- add_cflags -W${armcc_opt},--diag_suppress=1207
- add_cflags -W${armcc_opt},--diag_suppress=1293 # assignment in condition
- add_cflags -W${armcc_opt},--diag_suppress=3343 # hardfp compat
- add_cflags -W${armcc_opt},--diag_suppress=167 # pointer sign
- add_cflags -W${armcc_opt},--diag_suppress=513 # pointer sign
-elif enabled pathscale; then
- add_cflags -fstrict-overflow -OPT:wrap_around_unsafe_opt=OFF
- disable inline_asm
-elif enabled_any msvc icl; then
- enabled x86_32 && disable aligned_stack
- enabled_all x86_32 debug && add_cflags -Oy-
- enabled debug && add_ldflags -debug
- enable pragma_deprecated
- if enabled icl; then
- # -Qansi-alias is basically -fstrict-aliasing, but does not work
- # (correctly) on icl 13.x.
- test_cpp_condition "windows.h" "__ICL < 1300 || __ICL >= 1400" &&
- add_cflags -Qansi-alias
- # Some inline asm is not compilable in debug
- if enabled debug; then
- disable ebp_available
- disable ebx_available
- fi
- fi
- # msvcrt10 x64 incorrectly enables log2, only msvcrt12 (MSVC 2013) onwards actually has log2.
- check_cpp_condition log2 crtversion.h "_VC_CRT_MAJOR_VERSION >= 12"
- # The CRT headers contain __declspec(restrict) in a few places, but if redefining
- # restrict, this might break. MSVC 2010 and 2012 fail with __declspec(__restrict)
- # (as it ends up if the restrict redefine is done before including stdlib.h), while
- # MSVC 2013 and newer can handle it fine.
- # If this declspec fails, force including stdlib.h before the restrict redefinition
- # happens in config.h.
- if [ $restrict_keyword != restrict ]; then
- test_cc <<EOF || add_cflags -FIstdlib.h
-__declspec($restrict_keyword) void *foo(int);
-EOF
- fi
- # the new SSA optimzer in VS2015 U3 is mis-optimizing some parts of the code
- # Issue has been fixed in MSVC v19.00.24218.
- test_cpp_condition windows.h "_MSC_FULL_VER >= 190024218" ||
- check_cflags -d2SSAOptimizer-
- # enable utf-8 source processing on VS2015 U2 and newer
- test_cpp_condition windows.h "_MSC_FULL_VER >= 190023918" &&
- add_cflags -utf-8
-fi
-
-for pfx in "" host_; do
- varname=${pfx%_}cc_type
- eval "type=\$$varname"
- if [ "$type" = "msvc" ]; then
- test_${pfx}cc <<EOF || add_${pfx}cflags -Dinline=__inline
-static inline int foo(int a) { return a; }
-EOF
- fi
-done
-
-case $as_type in
- clang)
- add_asflags -Qunused-arguments
- ;;
-esac
-
-case $ld_type in
- clang)
- check_ldflags -Qunused-arguments
- ;;
-esac
-
-enable frame_thread_encoder
-
-enabled asm || { arch=c; disable $ARCH_LIST $ARCH_EXT_LIST; }
-
-check_deps $CONFIG_LIST \
- $CONFIG_EXTRA \
- $HAVE_LIST \
- $ALL_COMPONENTS \
-
-enabled threads && ! enabled pthreads && ! enabled atomics_native && die "non pthread threading without atomics not supported, try adding --enable-pthreads or --cpu=i486 or higher if you are on x86"
-enabled avresample && warn "Building with deprecated library libavresample"
-
-case $target_os in
-haiku)
- disable memalign
- disable posix_memalign
- ;;
-*-dos|freedos|opendos)
- if test_cpp_condition sys/version.h "defined(__DJGPP__) && __DJGPP__ == 2 && __DJGPP_MINOR__ == 5"; then
- disable memalign
- fi
- ;;
-esac
-
-flatten_extralibs(){
- nested_entries=
- list_name=$1
- eval list=\$${1}
- for entry in $list; do
- entry_copy=$entry
- resolve entry_copy
- flat_entries=
- for e in $entry_copy; do
- case $e in
- *_extralibs) nested_entries="$nested_entries$e ";;
- *) flat_entries="$flat_entries$e ";;
- esac
- done
- eval $entry="\$flat_entries"
- done
- append $list_name "$nested_entries"
-
- resolve nested_entries
- if test -n "$(filter '*_extralibs' $nested_entries)"; then
- flatten_extralibs $list_name
- fi
-}
-
-flatten_extralibs_wrapper(){
- list_name=$1
- flatten_extralibs $list_name
- unique $list_name
- resolve $list_name
- eval $list_name=\$\(\$ldflags_filter \$$list_name\)
- eval printf \''%s'\' \""\$$list_name"\"
-}
-
-for linkunit in $LIBRARY_LIST; do
- unset current_extralibs
- eval components=\$$(toupper ${linkunit})_COMPONENTS_LIST
- for comp in ${components}; do
- enabled $comp || continue
- comp_extralibs="${comp}_extralibs"
- append current_extralibs $comp_extralibs
- done
- eval prepend ${linkunit}_extralibs $current_extralibs
-done
-
-for linkunit in $LIBRARY_LIST $PROGRAM_LIST $EXTRALIBS_LIST; do
- eval ${linkunit}_extralibs=\$\(flatten_extralibs_wrapper ${linkunit}_extralibs\)
-done
-
-map 'enabled $v && intrinsics=${v#intrinsics_}' $INTRINSICS_LIST
-
-for thread in $THREADS_LIST; do
- if enabled $thread; then
- test -n "$thread_type" &&
- die "ERROR: Only one thread type must be selected." ||
- thread_type="$thread"
- fi
-done
-
-if disabled stdatomic; then
- if enabled atomics_gcc; then
- add_cppflags '-I\$(SRC_PATH)/compat/atomics/gcc'
- elif enabled atomics_win32; then
- add_cppflags '-I\$(SRC_PATH)/compat/atomics/win32'
- elif enabled atomics_suncc; then
- add_cppflags '-I\$(SRC_PATH)/compat/atomics/suncc'
- elif enabled pthreads; then
- add_compat atomics/pthread/stdatomic.o
- add_cppflags '-I\$(SRC_PATH)/compat/atomics/pthread'
- else
- enabled threads && die "Threading is enabled, but no atomics are available"
- add_cppflags '-I\$(SRC_PATH)/compat/atomics/dummy'
- fi
-fi
-
-# Check if requested libraries were found.
-for lib in $AUTODETECT_LIBS; do
- requested $lib && ! enabled $lib && die "ERROR: $lib requested but not found";
-done
-
-enabled zlib && add_cppflags -DZLIB_CONST
-
-# conditional library dependencies, in any order
-enabled afftdn_filter && prepend avfilter_deps "avcodec"
-enabled afftfilt_filter && prepend avfilter_deps "avcodec"
-enabled afir_filter && prepend avfilter_deps "avcodec"
-enabled amovie_filter && prepend avfilter_deps "avformat avcodec"
-enabled aresample_filter && prepend avfilter_deps "swresample"
-enabled atempo_filter && prepend avfilter_deps "avcodec"
-enabled bm3d_filter && prepend avfilter_deps "avcodec"
-enabled cover_rect_filter && prepend avfilter_deps "avformat avcodec"
-enabled convolve_filter && prepend avfilter_deps "avcodec"
-enabled deconvolve_filter && prepend avfilter_deps "avcodec"
-enabled ebur128_filter && enabled swresample && prepend avfilter_deps "swresample"
-enabled elbg_filter && prepend avfilter_deps "avcodec"
-enabled fftfilt_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"
-enabled pp_filter && prepend avfilter_deps "postproc"
-enabled removelogo_filter && prepend avfilter_deps "avformat avcodec swscale"
-enabled resample_filter && prepend avfilter_deps "avresample"
-enabled sab_filter && prepend avfilter_deps "swscale"
-enabled scale_filter && prepend avfilter_deps "swscale"
-enabled scale2ref_filter && prepend avfilter_deps "swscale"
-enabled sofalizer_filter && prepend avfilter_deps "avcodec"
-enabled showcqt_filter && prepend avfilter_deps "avformat avcodec swscale"
-enabled showfreqs_filter && prepend avfilter_deps "avcodec"
-enabled showspectrum_filter && prepend avfilter_deps "avcodec"
-enabled signature_filter && prepend avfilter_deps "avcodec avformat"
-enabled smartblur_filter && prepend avfilter_deps "swscale"
-enabled spectrumsynth_filter && prepend avfilter_deps "avcodec"
-enabled spp_filter && prepend avfilter_deps "avcodec"
-enabled sr_filter && prepend avfilter_deps "avformat swscale"
-enabled subtitles_filter && prepend avfilter_deps "avformat avcodec"
-enabled uspp_filter && prepend avfilter_deps "avcodec"
-enabled zoompan_filter && prepend avfilter_deps "swscale"
-
-enabled lavfi_indev && prepend avdevice_deps "avfilter"
-
-#FIXME
-enabled_any sdl2_outdev opengl_outdev && enabled sdl2 &&
- add_cflags $(filter_out '-Dmain=SDL_main' $sdl2_cflags)
-
-enabled opus_decoder && prepend avcodec_deps "swresample"
-
-# reorder the items at var $1 to align with the items order at var $2 .
-# die if an item at $1 is not at $2 .
-reorder_by(){
- eval rb_in=\$$1
- eval rb_ordered=\$$2
-
- for rb in $rb_in; do
- is_in $rb $rb_ordered || die "$rb at \$$1 is not at \$$2"
- done
-
- rb_out=
- for rb in $rb_ordered; do
- is_in $rb $rb_in && rb_out="$rb_out$rb "
- done
- eval $1=\$rb_out
-}
-
-# deps-expand fflib $1: N x {append all expanded deps; unique}
-# within a set of N items, N expansions are enough to expose a cycle.
-expand_deps(){
- unique ${1}_deps # required for the early break test.
- for dummy in $LIBRARY_LIST; do # N iteratios
- eval deps=\$${1}_deps
- append ${1}_deps $(map 'eval echo \$${v}_deps' $deps)
- unique ${1}_deps
- eval '[ ${#deps} = ${#'${1}_deps'} ]' && break # doesn't expand anymore
- done
-
- eval is_in $1 \$${1}_deps && die "Dependency cycle at ${1}_deps"
- reorder_by ${1}_deps LIBRARY_LIST # linking order is expected later
-}
-
-#we have to remove gpl from the deps here as some code assumes all lib deps are libs
-postproc_deps="$(filter_out 'gpl' $postproc_deps)"
-
-map 'expand_deps $v' $LIBRARY_LIST
-
-if test "$quiet" != "yes"; then
-
-echo "install prefix $prefix"
-echo "source path $source_path"
-echo "C compiler $cc"
-echo "C library $libc_type"
-if test "$host_cc" != "$cc"; then
- echo "host C compiler $host_cc"
- echo "host C library $host_libc_type"
-fi
-echo "ARCH $arch ($cpu)"
-if test "$build_suffix" != ""; then
- echo "build suffix $build_suffix"
-fi
-if test "$progs_suffix" != ""; then
- echo "progs suffix $progs_suffix"
-fi
-if test "$extra_version" != ""; then
- echo "version string suffix $extra_version"
-fi
-echo "big-endian ${bigendian-no}"
-echo "runtime cpu detection ${runtime_cpudetect-no}"
-if enabled x86; then
- echo "standalone assembly ${x86asm-no}"
- echo "x86 assembler ${x86asmexe}"
- echo "MMX enabled ${mmx-no}"
- echo "MMXEXT enabled ${mmxext-no}"
- echo "3DNow! enabled ${amd3dnow-no}"
- echo "3DNow! extended enabled ${amd3dnowext-no}"
- echo "SSE enabled ${sse-no}"
- echo "SSSE3 enabled ${ssse3-no}"
- echo "AESNI enabled ${aesni-no}"
- echo "AVX enabled ${avx-no}"
- echo "AVX2 enabled ${avx2-no}"
- echo "AVX-512 enabled ${avx512-no}"
- echo "XOP enabled ${xop-no}"
- echo "FMA3 enabled ${fma3-no}"
- echo "FMA4 enabled ${fma4-no}"
- echo "i686 features enabled ${i686-no}"
- echo "CMOV is fast ${fast_cmov-no}"
- echo "EBX available ${ebx_available-no}"
- echo "EBP available ${ebp_available-no}"
-fi
-if enabled aarch64; then
- echo "NEON enabled ${neon-no}"
- echo "VFP enabled ${vfp-no}"
-fi
-if enabled arm; then
- echo "ARMv5TE enabled ${armv5te-no}"
- echo "ARMv6 enabled ${armv6-no}"
- echo "ARMv6T2 enabled ${armv6t2-no}"
- echo "VFP enabled ${vfp-no}"
- echo "NEON enabled ${neon-no}"
- echo "THUMB enabled ${thumb-no}"
-fi
-if enabled mips; then
- echo "MIPS FPU enabled ${mipsfpu-no}"
- echo "MIPS DSP R1 enabled ${mipsdsp-no}"
- echo "MIPS DSP R2 enabled ${mipsdspr2-no}"
- echo "MIPS MSA enabled ${msa-no}"
- echo "MIPS MSA2 enabled ${msa2-no}"
- echo "LOONGSON MMI enabled ${mmi-no}"
-fi
-if enabled ppc; then
- echo "AltiVec enabled ${altivec-no}"
- echo "VSX enabled ${vsx-no}"
- echo "POWER8 enabled ${power8-no}"
- echo "PPC 4xx optimizations ${ppc4xx-no}"
- echo "dcbzl available ${dcbzl-no}"
-fi
-echo "debug symbols ${debug-no}"
-echo "strip symbols ${stripping-no}"
-echo "optimize for size ${small-no}"
-echo "optimizations ${optimizations-no}"
-echo "static ${static-no}"
-echo "shared ${shared-no}"
-echo "postprocessing support ${postproc-no}"
-echo "network support ${network-no}"
-echo "threading support ${thread_type-no}"
-echo "safe bitstream reader ${safe_bitstream_reader-no}"
-echo "texi2html enabled ${texi2html-no}"
-echo "perl enabled ${perl-no}"
-echo "pod2man enabled ${pod2man-no}"
-echo "makeinfo enabled ${makeinfo-no}"
-echo "makeinfo supports HTML ${makeinfo_html-no}"
-test -n "$random_seed" &&
- echo "random seed ${random_seed}"
-echo
-
-echo "External libraries:"
-print_enabled '' $EXTERNAL_LIBRARY_LIST $EXTERNAL_AUTODETECT_LIBRARY_LIST | print_in_columns
-echo
-
-echo "External libraries providing hardware acceleration:"
-print_enabled '' $HWACCEL_LIBRARY_LIST $HWACCEL_AUTODETECT_LIBRARY_LIST | print_in_columns
-echo
-
-echo "Libraries:"
-print_enabled '' $LIBRARY_LIST | print_in_columns
-echo
-
-echo "Programs:"
-print_enabled '' $PROGRAM_LIST | print_in_columns
-echo
-
-for type in decoder encoder hwaccel parser demuxer muxer protocol filter bsf indev outdev; do
- echo "Enabled ${type}s:"
- eval list=\$$(toupper $type)_LIST
- print_enabled '_*' $list | print_in_columns
- echo
-done
-
-if test -n "$ignore_tests"; then
- ignore_tests=$(echo $ignore_tests | tr ',' ' ')
- echo "Ignored FATE tests:"
- echo $ignore_tests | print_in_columns
- echo
-fi
-
-echo "License: $license"
-
-fi # test "$quiet" != "yes"
-
-if test -n "$WARN_IF_GETS_DISABLED_LIST"; then
- for cfg in $WARN_IF_GETS_DISABLED_LIST; do
- if disabled $cfg; then
- varname=${cfg}_disable_reason
- eval "warn \"Disabled $cfg because \$$varname\""
- fi
- done
-fi
-
-if test -n "$WARNINGS"; then
- printf "\n%s%s$WARNINGS%s" "$warn_color" "$bold_color" "$reset_color"
- enabled fatal_warnings && exit 1
-fi
-
-test -e Makefile || echo "include $source_path/Makefile" > Makefile
-
-esc(){
- echo "$*" | sed 's/%/%25/g;s/:/%3a/g'
-}
-
-echo "config:$arch:$subarch:$cpu:$target_os:$(esc $cc_ident):$(esc $FFMPEG_CONFIGURATION)" > ffbuild/config.fate
-
-enabled stripping || strip="echo skipping strip"
-enabled stripping || striptype=""
-
-config_files="$TMPH ffbuild/config.mak doc/config.texi"
-
-cat > ffbuild/config.mak <<EOF
-# Automatically generated by configure - do not modify!
-ifndef FFMPEG_CONFIG_MAK
-FFMPEG_CONFIG_MAK=1
-FFMPEG_CONFIGURATION=$FFMPEG_CONFIGURATION
-prefix=$prefix
-LIBDIR=\$(DESTDIR)$libdir
-SHLIBDIR=\$(DESTDIR)$shlibdir
-INCDIR=\$(DESTDIR)$incdir
-BINDIR=\$(DESTDIR)$bindir
-DATADIR=\$(DESTDIR)$datadir
-DOCDIR=\$(DESTDIR)$docdir
-MANDIR=\$(DESTDIR)$mandir
-PKGCONFIGDIR=\$(DESTDIR)$pkgconfigdir
-INSTALL_NAME_DIR=$install_name_dir
-SRC_PATH=$source_path
-SRC_LINK=$source_link
-ifndef MAIN_MAKEFILE
-SRC_PATH:=\$(SRC_PATH:.%=..%)
-endif
-CC_IDENT=$cc_ident
-ARCH=$arch
-INTRINSICS=$intrinsics
-EXTERN_PREFIX=$extern_prefix
-CC=$cc
-CXX=$cxx
-AS=$as
-OBJCC=$objcc
-LD=$ld
-DEPCC=$dep_cc
-DEPCCFLAGS=$DEPCCFLAGS \$(CPPFLAGS)
-DEPAS=$as
-DEPASFLAGS=$DEPASFLAGS \$(CPPFLAGS)
-X86ASM=$x86asmexe
-DEPX86ASM=$x86asmexe
-DEPX86ASMFLAGS=\$(X86ASMFLAGS)
-AR=$ar
-ARFLAGS=$arflags
-AR_O=$ar_o
-AR_CMD=$ar
-NM_CMD=$nm
-RANLIB=$ranlib
-STRIP=$strip
-STRIPTYPE=$striptype
-NVCC=$nvcc
-CP=cp -p
-LN_S=$ln_s
-CPPFLAGS=$CPPFLAGS
-CFLAGS=$CFLAGS
-CXXFLAGS=$CXXFLAGS
-OBJCFLAGS=$OBJCFLAGS
-ASFLAGS=$ASFLAGS
-NVCCFLAGS=$nvccflags
-AS_C=$AS_C
-AS_O=$AS_O
-OBJCC_C=$OBJCC_C
-OBJCC_E=$OBJCC_E
-OBJCC_O=$OBJCC_O
-CC_C=$CC_C
-CC_E=$CC_E
-CC_O=$CC_O
-CXX_C=$CXX_C
-CXX_O=$CXX_O
-NVCC_C=$NVCC_C
-NVCC_O=$NVCC_O
-LD_O=$LD_O
-X86ASM_O=$X86ASM_O
-LD_LIB=$LD_LIB
-LD_PATH=$LD_PATH
-DLLTOOL=$dlltool
-WINDRES=$windres
-DEPWINDRES=$dep_cc
-DOXYGEN=$doxygen
-LDFLAGS=$LDFLAGS
-LDEXEFLAGS=$LDEXEFLAGS
-LDSOFLAGS=$LDSOFLAGS
-SHFLAGS=$(echo $($ldflags_filter $SHFLAGS))
-ASMSTRIPFLAGS=$ASMSTRIPFLAGS
-X86ASMFLAGS=$X86ASMFLAGS
-BUILDSUF=$build_suffix
-PROGSSUF=$progs_suffix
-FULLNAME=$FULLNAME
-LIBPREF=$LIBPREF
-LIBSUF=$LIBSUF
-LIBNAME=$LIBNAME
-SLIBPREF=$SLIBPREF
-SLIBSUF=$SLIBSUF
-EXESUF=$EXESUF
-EXTRA_VERSION=$extra_version
-CCDEP=$CCDEP
-CXXDEP=$CXXDEP
-CCDEP_FLAGS=$CCDEP_FLAGS
-ASDEP=$ASDEP
-ASDEP_FLAGS=$ASDEP_FLAGS
-X86ASMDEP=$X86ASMDEP
-X86ASMDEP_FLAGS=$X86ASMDEP_FLAGS
-CC_DEPFLAGS=$CC_DEPFLAGS
-AS_DEPFLAGS=$AS_DEPFLAGS
-X86ASM_DEPFLAGS=$X86ASM_DEPFLAGS
-HOSTCC=$host_cc
-HOSTLD=$host_ld
-HOSTCFLAGS=$host_cflags
-HOSTCPPFLAGS=$host_cppflags
-HOSTEXESUF=$HOSTEXESUF
-HOSTLDFLAGS=$host_ldflags
-HOSTEXTRALIBS=$host_extralibs
-DEPHOSTCC=$host_cc
-DEPHOSTCCFLAGS=$DEPHOSTCCFLAGS \$(HOSTCCFLAGS)
-HOSTCCDEP=$HOSTCCDEP
-HOSTCCDEP_FLAGS=$HOSTCCDEP_FLAGS
-HOSTCC_DEPFLAGS=$HOSTCC_DEPFLAGS
-HOSTCC_C=$HOSTCC_C
-HOSTCC_O=$HOSTCC_O
-HOSTLD_O=$HOSTLD_O
-TARGET_EXEC=$target_exec $target_exec_args
-TARGET_PATH=$target_path
-TARGET_SAMPLES=${target_samples:-\$(SAMPLES)}
-CFLAGS-ffplay=${sdl2_cflags}
-CFLAGS_HEADERS=$CFLAGS_HEADERS
-LIB_INSTALL_EXTRA_CMD=$LIB_INSTALL_EXTRA_CMD
-EXTRALIBS=$extralibs
-COMPAT_OBJS=$compat_objs
-INSTALL=$install
-LIBTARGET=${LIBTARGET}
-SLIBNAME=${SLIBNAME}
-SLIBNAME_WITH_VERSION=${SLIBNAME_WITH_VERSION}
-SLIBNAME_WITH_MAJOR=${SLIBNAME_WITH_MAJOR}
-SLIB_CREATE_DEF_CMD=${SLIB_CREATE_DEF_CMD}
-SLIB_EXTRA_CMD=${SLIB_EXTRA_CMD}
-SLIB_INSTALL_NAME=${SLIB_INSTALL_NAME}
-SLIB_INSTALL_LINKS=${SLIB_INSTALL_LINKS}
-SLIB_INSTALL_EXTRA_LIB=${SLIB_INSTALL_EXTRA_LIB}
-SLIB_INSTALL_EXTRA_SHLIB=${SLIB_INSTALL_EXTRA_SHLIB}
-VERSION_SCRIPT_POSTPROCESS_CMD=${VERSION_SCRIPT_POSTPROCESS_CMD}
-SAMPLES:=${samples:-\$(FATE_SAMPLES)}
-NOREDZONE_FLAGS=$noredzone_flags
-LIBFUZZER_PATH=$libfuzzer_path
-IGNORE_TESTS=$ignore_tests
-EOF
-
-map 'eval echo "${v}_FFLIBS=\$${v}_deps" >> ffbuild/config.mak' $LIBRARY_LIST
-
-for entry in $LIBRARY_LIST $PROGRAM_LIST $EXTRALIBS_LIST; do
- eval echo "EXTRALIBS-${entry}=\$${entry}_extralibs" >> ffbuild/config.mak
-done
-
-cat > $TMPH <<EOF
-/* Automatically generated by configure - do not modify! */
-#ifndef FFMPEG_CONFIG_H
-#define FFMPEG_CONFIG_H
-#define FFMPEG_CONFIGURATION "$(c_escape $FFMPEG_CONFIGURATION)"
-#define FFMPEG_LICENSE "$(c_escape $license)"
-#define CONFIG_THIS_YEAR 2021
-#define FFMPEG_DATADIR "$(eval c_escape $datadir)"
-#define AVCONV_DATADIR "$(eval c_escape $datadir)"
-#define CC_IDENT "$(c_escape ${cc_ident:-Unknown compiler})"
-#define av_restrict $restrict_keyword
-#define EXTERN_PREFIX "${extern_prefix}"
-#define EXTERN_ASM ${extern_prefix}
-#define BUILDSUF "$build_suffix"
-#define SLIBSUF "$SLIBSUF"
-#define HAVE_MMX2 HAVE_MMXEXT
-#define SWS_MAX_FILTER_SIZE $sws_max_filter_size
-EOF
-
-test -n "$assert_level" &&
- echo "#define ASSERT_LEVEL $assert_level" >>$TMPH
-
-test -n "$malloc_prefix" &&
- echo "#define MALLOC_PREFIX $malloc_prefix" >>$TMPH
-
-if enabled x86asm; then
- append config_files $TMPASM
- cat > $TMPASM <<EOF
-; Automatically generated by configure - do not modify!
-EOF
-fi
-
-enabled getenv || echo "#define getenv(x) NULL" >> $TMPH
-
-
-mkdir -p doc
-mkdir -p tests
-mkdir -p tests/api
-echo "@c auto-generated by configure - do not modify! " > doc/config.texi
-
-print_config ARCH_ "$config_files" $ARCH_LIST
-print_config HAVE_ "$config_files" $HAVE_LIST
-print_config CONFIG_ "$config_files" $CONFIG_LIST \
- $CONFIG_EXTRA \
- $ALL_COMPONENTS \
-
-echo "#endif /* FFMPEG_CONFIG_H */" >> $TMPH
-echo "endif # FFMPEG_CONFIG_MAK" >> ffbuild/config.mak
-
-# Do not overwrite an unchanged config.h to avoid superfluous rebuilds.
-cp_if_changed $TMPH config.h
-touch ffbuild/.config
-
-enabled x86asm && cp_if_changed $TMPASM config.asm
-
-cat > $TMPH <<EOF
-/* Generated by ffmpeg configure */
-#ifndef AVUTIL_AVCONFIG_H
-#define AVUTIL_AVCONFIG_H
-EOF
-
-print_config AV_HAVE_ $TMPH $HAVE_LIST_PUB
-
-echo "#endif /* AVUTIL_AVCONFIG_H */" >> $TMPH
-
-cp_if_changed $TMPH libavutil/avconfig.h
-
-# full_filter_name_foo=vf_foo
-# full_filter_name_bar=asrc_bar
-# ...
-eval "$(sed -n "s/^extern AVFilter ff_\([avfsinkrc]\{2,5\}\)_\(.*\);/full_filter_name_\2=\1_\2/p" $source_path/libavfilter/allfilters.c)"
-
-# generate the lists of enabled components
-print_enabled_components(){
- file=$1
- struct_name=$2
- name=$3
- shift 3
- echo "static const $struct_name * const $name[] = {" > $TMPH
- for c in $*; do
- if enabled $c; then
- case $name in
- filter_list)
- eval c=\$full_filter_name_${c%_filter}
- ;;
- indev_list)
- c=${c%_indev}_demuxer
- ;;
- outdev_list)
- c=${c%_outdev}_muxer
- ;;
- esac
- printf " &ff_%s,\n" $c >> $TMPH
- fi
- done
- if [ "$name" = "filter_list" ]; then
- for c in asrc_abuffer vsrc_buffer asink_abuffer vsink_buffer; do
- printf " &ff_%s,\n" $c >> $TMPH
- done
- fi
- echo " NULL };" >> $TMPH
- cp_if_changed $TMPH $file
-}
-
-print_enabled_components libavfilter/filter_list.c AVFilter filter_list $FILTER_LIST
-print_enabled_components libavcodec/codec_list.c AVCodec codec_list $CODEC_LIST
-print_enabled_components libavcodec/parser_list.c AVCodecParser parser_list $PARSER_LIST
-print_enabled_components libavcodec/bsf_list.c AVBitStreamFilter bitstream_filters $BSF_LIST
-print_enabled_components libavformat/demuxer_list.c AVInputFormat demuxer_list $DEMUXER_LIST
-print_enabled_components libavformat/muxer_list.c AVOutputFormat muxer_list $MUXER_LIST
-print_enabled_components libavdevice/indev_list.c AVInputFormat indev_list $INDEV_LIST
-print_enabled_components libavdevice/outdev_list.c AVOutputFormat outdev_list $OUTDEV_LIST
-print_enabled_components libavformat/protocol_list.c URLProtocol url_protocols $PROTOCOL_LIST
-
-# Settings for pkg-config files
-
-cat > $TMPH <<EOF
-# Automatically generated by configure - do not modify!
-shared=$shared
-build_suffix=$build_suffix
-prefix=$prefix
-libdir=$libdir
-incdir=$incdir
-rpath=$(enabled rpath && echo "-Wl,-rpath,\${libdir}")
-source_path=${source_path}
-LIBPREF=${LIBPREF}
-LIBSUF=${LIBSUF}
-extralibs_avutil="$avutil_extralibs"
-extralibs_avcodec="$avcodec_extralibs"
-extralibs_avformat="$avformat_extralibs"
-extralibs_avdevice="$avdevice_extralibs"
-extralibs_avfilter="$avfilter_extralibs"
-extralibs_avresample="$avresample_extralibs"
-extralibs_postproc="$postproc_extralibs"
-extralibs_swscale="$swscale_extralibs"
-extralibs_swresample="$swresample_extralibs"
-EOF
-
-for lib in $LIBRARY_LIST; do
- lib_deps="$(eval echo \$${lib}_deps)"
- echo ${lib}_deps=\"$lib_deps\" >> $TMPH
-done
-
-cp_if_changed $TMPH ffbuild/config.sh
diff -Naur ffmpeg-4.3.2-Matrix-19.1/fftools/ffmpeg_opt.c ffmpeg-4.3.2-Matrix-19.1-2/fftools/ffmpeg_opt.c
--- ffmpeg-4.3.2-Matrix-19.1/fftools/ffmpeg_opt.c 2022-03-07 22:55:03.088318565 +0100
+++ ffmpeg-4.3.2-Matrix-19.1-2/fftools/ffmpeg_opt.c 2022-03-20 03:19:12.723688233 +0100
@@ -750,6 +750,25 @@
char *codec_name = NULL;
MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
+
+#if CONFIG_NVV4L2
+ /* Reset requested decoder in order to enforce NVV4L2 if possible. */
+ if (codec_name) {
+ if (strcmp(codec_name, "h264") == 0)
+ return avcodec_find_decoder(st->codecpar->codec_id);
+ else if (strcmp(codec_name, "hevc") == 0)
+ return avcodec_find_decoder(st->codecpar->codec_id);
+ else if (strcmp(codec_name, "mpeg2video") == 0)
+ return avcodec_find_decoder(st->codecpar->codec_id);
+ else if (strcmp(codec_name, "mpeg4") == 0)
+ return avcodec_find_decoder(st->codecpar->codec_id);
+ else if (strcmp(codec_name, "vp8") == 0)
+ return avcodec_find_decoder(st->codecpar->codec_id);
+ else if (strcmp(codec_name, "vp9") == 0 && st->codecpar->format != AV_PIX_FMT_YUV420P10)
+ return avcodec_find_decoder(st->codecpar->codec_id);
+ }
+#endif
+
if (codec_name) {
AVCodec *codec = find_codec_or_die(codec_name, st->codecpar->codec_type, 0);
st->codecpar->codec_id = codec->id;
diff -Naur ffmpeg-4.3.2-Matrix-19.1/fftools/ffplay.c ffmpeg-4.3.2-Matrix-19.1-2/fftools/ffplay.c
--- ffmpeg-4.3.2-Matrix-19.1/fftools/ffplay.c 2022-03-07 22:55:03.136319611 +0100
+++ ffmpeg-4.3.2-Matrix-19.1-2/fftools/ffplay.c 2022-03-20 03:19:12.727688297 +0100
@@ -2604,6 +2604,31 @@
case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
}
+
+#if CONFIG_NVV4L2
+ /* Reset requested decoder in order to enforce NVV4L2 if possible. */
+ if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && forced_codec_name) {
+ if (strcmp(forced_codec_name, "h264") == 0)
+ forced_codec_name = NULL;
+ else if (strcmp(forced_codec_name, "hevc") == 0)
+ forced_codec_name = NULL;
+ else if (strcmp(forced_codec_name, "mpeg2video") == 0)
+ forced_codec_name = NULL;
+ else if (strcmp(forced_codec_name, "mpeg4") == 0)
+ forced_codec_name = NULL;
+ else if (strcmp(forced_codec_name, "vp8") == 0)
+ forced_codec_name = NULL;
+ else if (strcmp(forced_codec_name, "vp9") == 0 &&
+ avctx->pix_fmt != AV_PIX_FMT_YUV420P10) {
+ forced_codec_name = NULL;
+ }
+ }
+
+ /* NVV4L2 does not support VP9 with YUV420P10. */
+ if (!forced_codec_name && avctx->pix_fmt == AV_PIX_FMT_YUV420P10)
+ forced_codec_name = "vp9";
+#endif
+
if (forced_codec_name)
codec = avcodec_find_decoder_by_name(forced_codec_name);
if (!codec) {
diff -Naur ffmpeg-4.3.2-Matrix-19.1/fftools/ffplay.c.orig ffmpeg-4.3.2-Matrix-19.1-2/fftools/ffplay.c.orig
--- ffmpeg-4.3.2-Matrix-19.1/fftools/ffplay.c.orig 1970-01-01 01:00:00.000000000 +0100
+++ ffmpeg-4.3.2-Matrix-19.1-2/fftools/ffplay.c.orig 2022-03-20 03:19:12.727688297 +0100
@@ -0,0 +1,3782 @@
+/*
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * simple media player based on the FFmpeg libraries
+ */
+
+#include "config.h"
+#include <inttypes.h>
+#include <math.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdint.h>
+
+#include "libavutil/avstring.h"
+#include "libavutil/eval.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/dict.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/samplefmt.h"
+#include "libavutil/avassert.h"
+#include "libavutil/time.h"
+#include "libavutil/bprint.h"
+#include "libavformat/avformat.h"
+#include "libavdevice/avdevice.h"
+#include "libswscale/swscale.h"
+#include "libavutil/opt.h"
+#include "libavcodec/avfft.h"
+#include "libswresample/swresample.h"
+
+#if CONFIG_AVFILTER
+# include "libavfilter/avfilter.h"
+# include "libavfilter/buffersink.h"
+# include "libavfilter/buffersrc.h"
+#endif
+
+#include <SDL.h>
+#include <SDL_thread.h>
+
+#include "cmdutils.h"
+
+#include <assert.h>
+
+const char program_name[] = "ffplay";
+const int program_birth_year = 2003;
+
+#define MAX_QUEUE_SIZE (15 * 1024 * 1024)
+#define MIN_FRAMES 25
+#define EXTERNAL_CLOCK_MIN_FRAMES 2
+#define EXTERNAL_CLOCK_MAX_FRAMES 10
+
+/* Minimum SDL audio buffer size, in samples. */
+#define SDL_AUDIO_MIN_BUFFER_SIZE 512
+/* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
+#define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
+
+/* Step size for volume control in dB */
+#define SDL_VOLUME_STEP (0.75)
+
+/* no AV sync correction is done if below the minimum AV sync threshold */
+#define AV_SYNC_THRESHOLD_MIN 0.04
+/* AV sync correction is done if above the maximum AV sync threshold */
+#define AV_SYNC_THRESHOLD_MAX 0.1
+/* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
+#define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
+/* no AV correction is done if too big error */
+#define AV_NOSYNC_THRESHOLD 10.0
+
+/* maximum audio speed change to get correct sync */
+#define SAMPLE_CORRECTION_PERCENT_MAX 10
+
+/* external clock speed adjustment constants for realtime sources based on buffer fullness */
+#define EXTERNAL_CLOCK_SPEED_MIN 0.900
+#define EXTERNAL_CLOCK_SPEED_MAX 1.010
+#define EXTERNAL_CLOCK_SPEED_STEP 0.001
+
+/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
+#define AUDIO_DIFF_AVG_NB 20
+
+/* polls for possible required screen refresh at least this often, should be less than 1/fps */
+#define REFRESH_RATE 0.01
+
+/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
+/* TODO: We assume that a decoded and resampled frame fits into this buffer */
+#define SAMPLE_ARRAY_SIZE (8 * 65536)
+
+#define CURSOR_HIDE_DELAY 1000000
+
+#define USE_ONEPASS_SUBTITLE_RENDER 1
+
+static unsigned sws_flags = SWS_BICUBIC;
+
+typedef struct MyAVPacketList {
+ AVPacket pkt;
+ struct MyAVPacketList *next;
+ int serial;
+} MyAVPacketList;
+
+typedef struct PacketQueue {
+ MyAVPacketList *first_pkt, *last_pkt;
+ int nb_packets;
+ int size;
+ int64_t duration;
+ int abort_request;
+ int serial;
+ SDL_mutex *mutex;
+ SDL_cond *cond;
+} PacketQueue;
+
+#define VIDEO_PICTURE_QUEUE_SIZE 3
+#define SUBPICTURE_QUEUE_SIZE 16
+#define SAMPLE_QUEUE_SIZE 9
+#define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
+
+typedef struct AudioParams {
+ int freq;
+ int channels;
+ int64_t channel_layout;
+ enum AVSampleFormat fmt;
+ int frame_size;
+ int bytes_per_sec;
+} AudioParams;
+
+typedef struct Clock {
+ double pts; /* clock base */
+ double pts_drift; /* clock base minus time at which we updated the clock */
+ double last_updated;
+ double speed;
+ int serial; /* clock is based on a packet with this serial */
+ int paused;
+ int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
+} Clock;
+
+/* Common struct for handling all types of decoded data and allocated render buffers. */
+typedef struct Frame {
+ AVFrame *frame;
+ AVSubtitle sub;
+ int serial;
+ double pts; /* presentation timestamp for the frame */
+ double duration; /* estimated duration of the frame */
+ int64_t pos; /* byte position of the frame in the input file */
+ int width;
+ int height;
+ int format;
+ AVRational sar;
+ int uploaded;
+ int flip_v;
+} Frame;
+
+typedef struct FrameQueue {
+ Frame queue[FRAME_QUEUE_SIZE];
+ int rindex;
+ int windex;
+ int size;
+ int max_size;
+ int keep_last;
+ int rindex_shown;
+ SDL_mutex *mutex;
+ SDL_cond *cond;
+ PacketQueue *pktq;
+} FrameQueue;
+
+enum {
+ AV_SYNC_AUDIO_MASTER, /* default choice */
+ AV_SYNC_VIDEO_MASTER,
+ AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
+};
+
+typedef struct Decoder {
+ AVPacket pkt;
+ PacketQueue *queue;
+ AVCodecContext *avctx;
+ int pkt_serial;
+ int finished;
+ int packet_pending;
+ SDL_cond *empty_queue_cond;
+ int64_t start_pts;
+ AVRational start_pts_tb;
+ int64_t next_pts;
+ AVRational next_pts_tb;
+ SDL_Thread *decoder_tid;
+} Decoder;
+
+typedef struct VideoState {
+ SDL_Thread *read_tid;
+ AVInputFormat *iformat;
+ int abort_request;
+ int force_refresh;
+ int paused;
+ int last_paused;
+ int queue_attachments_req;
+ int seek_req;
+ int seek_flags;
+ int64_t seek_pos;
+ int64_t seek_rel;
+ int read_pause_return;
+ AVFormatContext *ic;
+ int realtime;
+
+ Clock audclk;
+ Clock vidclk;
+ Clock extclk;
+
+ FrameQueue pictq;
+ FrameQueue subpq;
+ FrameQueue sampq;
+
+ Decoder auddec;
+ Decoder viddec;
+ Decoder subdec;
+
+ int audio_stream;
+
+ int av_sync_type;
+
+ double audio_clock;
+ int audio_clock_serial;
+ double audio_diff_cum; /* used for AV difference average computation */
+ double audio_diff_avg_coef;
+ double audio_diff_threshold;
+ int audio_diff_avg_count;
+ AVStream *audio_st;
+ PacketQueue audioq;
+ int audio_hw_buf_size;
+ uint8_t *audio_buf;
+ uint8_t *audio_buf1;
+ unsigned int audio_buf_size; /* in bytes */
+ unsigned int audio_buf1_size;
+ int audio_buf_index; /* in bytes */
+ int audio_write_buf_size;
+ int audio_volume;
+ int muted;
+ struct AudioParams audio_src;
+#if CONFIG_AVFILTER
+ struct AudioParams audio_filter_src;
+#endif
+ struct AudioParams audio_tgt;
+ struct SwrContext *swr_ctx;
+ int frame_drops_early;
+ int frame_drops_late;
+
+ enum ShowMode {
+ SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
+ } show_mode;
+ int16_t sample_array[SAMPLE_ARRAY_SIZE];
+ int sample_array_index;
+ int last_i_start;
+ RDFTContext *rdft;
+ int rdft_bits;
+ FFTSample *rdft_data;
+ int xpos;
+ double last_vis_time;
+ SDL_Texture *vis_texture;
+ SDL_Texture *sub_texture;
+ SDL_Texture *vid_texture;
+
+ int subtitle_stream;
+ AVStream *subtitle_st;
+ PacketQueue subtitleq;
+
+ double frame_timer;
+ double frame_last_returned_time;
+ double frame_last_filter_delay;
+ int video_stream;
+ AVStream *video_st;
+ PacketQueue videoq;
+ double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
+ struct SwsContext *img_convert_ctx;
+ struct SwsContext *sub_convert_ctx;
+ int eof;
+
+ char *filename;
+ int width, height, xleft, ytop;
+ int step;
+
+#if CONFIG_AVFILTER
+ int vfilter_idx;
+ AVFilterContext *in_video_filter; // the first filter in the video chain
+ AVFilterContext *out_video_filter; // the last filter in the video chain
+ AVFilterContext *in_audio_filter; // the first filter in the audio chain
+ AVFilterContext *out_audio_filter; // the last filter in the audio chain
+ AVFilterGraph *agraph; // audio filter graph
+#endif
+
+ int last_video_stream, last_audio_stream, last_subtitle_stream;
+
+ SDL_cond *continue_read_thread;
+} VideoState;
+
+/* options specified by the user */
+static AVInputFormat *file_iformat;
+static const char *input_filename;
+static const char *window_title;
+static int default_width = 640;
+static int default_height = 480;
+static int screen_width = 0;
+static int screen_height = 0;
+static int screen_left = SDL_WINDOWPOS_CENTERED;
+static int screen_top = SDL_WINDOWPOS_CENTERED;
+static int audio_disable;
+static int video_disable;
+static int subtitle_disable;
+static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
+static int seek_by_bytes = -1;
+static float seek_interval = 10;
+static int display_disable;
+static int borderless;
+static int alwaysontop;
+static int startup_volume = 100;
+static int show_status = -1;
+static int av_sync_type = AV_SYNC_AUDIO_MASTER;
+static int64_t start_time = AV_NOPTS_VALUE;
+static int64_t duration = AV_NOPTS_VALUE;
+static int fast = 0;
+static int genpts = 0;
+static int lowres = 0;
+static int decoder_reorder_pts = -1;
+static int autoexit;
+static int exit_on_keydown;
+static int exit_on_mousedown;
+static int loop = 1;
+static int framedrop = -1;
+static int infinite_buffer = -1;
+static enum ShowMode show_mode = SHOW_MODE_NONE;
+static const char *audio_codec_name;
+static const char *subtitle_codec_name;
+static const char *video_codec_name;
+double rdftspeed = 0.02;
+static int64_t cursor_last_shown;
+static int cursor_hidden = 0;
+#if CONFIG_AVFILTER
+static const char **vfilters_list = NULL;
+static int nb_vfilters = 0;
+static char *afilters = NULL;
+#endif
+static int autorotate = 1;
+static int find_stream_info = 1;
+static int filter_nbthreads = 0;
+
+/* current context */
+static int is_full_screen;
+static int64_t audio_callback_time;
+
+static AVPacket flush_pkt;
+
+#define FF_QUIT_EVENT (SDL_USEREVENT + 2)
+
+static SDL_Window *window;
+static SDL_Renderer *renderer;
+static SDL_RendererInfo renderer_info = {0};
+static SDL_AudioDeviceID audio_dev;
+
+static const struct TextureFormatEntry {
+ enum AVPixelFormat format;
+ int texture_fmt;
+} sdl_texture_format_map[] = {
+ { AV_PIX_FMT_RGB8, SDL_PIXELFORMAT_RGB332 },
+ { AV_PIX_FMT_RGB444, SDL_PIXELFORMAT_RGB444 },
+ { AV_PIX_FMT_RGB555, SDL_PIXELFORMAT_RGB555 },
+ { AV_PIX_FMT_BGR555, SDL_PIXELFORMAT_BGR555 },
+ { AV_PIX_FMT_RGB565, SDL_PIXELFORMAT_RGB565 },
+ { AV_PIX_FMT_BGR565, SDL_PIXELFORMAT_BGR565 },
+ { AV_PIX_FMT_RGB24, SDL_PIXELFORMAT_RGB24 },
+ { AV_PIX_FMT_BGR24, SDL_PIXELFORMAT_BGR24 },
+ { AV_PIX_FMT_0RGB32, SDL_PIXELFORMAT_RGB888 },
+ { AV_PIX_FMT_0BGR32, SDL_PIXELFORMAT_BGR888 },
+ { AV_PIX_FMT_NE(RGB0, 0BGR), SDL_PIXELFORMAT_RGBX8888 },
+ { AV_PIX_FMT_NE(BGR0, 0RGB), SDL_PIXELFORMAT_BGRX8888 },
+ { AV_PIX_FMT_RGB32, SDL_PIXELFORMAT_ARGB8888 },
+ { AV_PIX_FMT_RGB32_1, SDL_PIXELFORMAT_RGBA8888 },
+ { AV_PIX_FMT_BGR32, SDL_PIXELFORMAT_ABGR8888 },
+ { AV_PIX_FMT_BGR32_1, SDL_PIXELFORMAT_BGRA8888 },
+ { AV_PIX_FMT_YUV420P, SDL_PIXELFORMAT_IYUV },
+ { AV_PIX_FMT_YUYV422, SDL_PIXELFORMAT_YUY2 },
+ { AV_PIX_FMT_UYVY422, SDL_PIXELFORMAT_UYVY },
+ { AV_PIX_FMT_NONE, SDL_PIXELFORMAT_UNKNOWN },
+};
+
+#if CONFIG_AVFILTER
+static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
+{
+ GROW_ARRAY(vfilters_list, nb_vfilters);
+ vfilters_list[nb_vfilters - 1] = arg;
+ return 0;
+}
+#endif
+
+static inline
+int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
+ enum AVSampleFormat fmt2, int64_t channel_count2)
+{
+ /* If channel count == 1, planar and non-planar formats are the same */
+ if (channel_count1 == 1 && channel_count2 == 1)
+ return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
+ else
+ return channel_count1 != channel_count2 || fmt1 != fmt2;
+}
+
+static inline
+int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
+{
+ if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
+ return channel_layout;
+ else
+ return 0;
+}
+
+static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
+{
+ MyAVPacketList *pkt1;
+
+ if (q->abort_request)
+ return -1;
+
+ pkt1 = av_malloc(sizeof(MyAVPacketList));
+ if (!pkt1)
+ return -1;
+ pkt1->pkt = *pkt;
+ pkt1->next = NULL;
+ if (pkt == &flush_pkt)
+ q->serial++;
+ pkt1->serial = q->serial;
+
+ if (!q->last_pkt)
+ q->first_pkt = pkt1;
+ else
+ q->last_pkt->next = pkt1;
+ q->last_pkt = pkt1;
+ q->nb_packets++;
+ q->size += pkt1->pkt.size + sizeof(*pkt1);
+ q->duration += pkt1->pkt.duration;
+ /* XXX: should duplicate packet data in DV case */
+ SDL_CondSignal(q->cond);
+ return 0;
+}
+
+static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
+{
+ int ret;
+
+ SDL_LockMutex(q->mutex);
+ ret = packet_queue_put_private(q, pkt);
+ SDL_UnlockMutex(q->mutex);
+
+ if (pkt != &flush_pkt && ret < 0)
+ av_packet_unref(pkt);
+
+ return ret;
+}
+
+static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
+{
+ AVPacket pkt1, *pkt = &pkt1;
+ av_init_packet(pkt);
+ pkt->data = NULL;
+ pkt->size = 0;
+ pkt->stream_index = stream_index;
+ return packet_queue_put(q, pkt);
+}
+
+/* packet queue handling */
+static int packet_queue_init(PacketQueue *q)
+{
+ memset(q, 0, sizeof(PacketQueue));
+ q->mutex = SDL_CreateMutex();
+ if (!q->mutex) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
+ return AVERROR(ENOMEM);
+ }
+ q->cond = SDL_CreateCond();
+ if (!q->cond) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
+ return AVERROR(ENOMEM);
+ }
+ q->abort_request = 1;
+ return 0;
+}
+
+static void packet_queue_flush(PacketQueue *q)
+{
+ MyAVPacketList *pkt, *pkt1;
+
+ SDL_LockMutex(q->mutex);
+ for (pkt = q->first_pkt; pkt; pkt = pkt1) {
+ pkt1 = pkt->next;
+ av_packet_unref(&pkt->pkt);
+ av_freep(&pkt);
+ }
+ q->last_pkt = NULL;
+ q->first_pkt = NULL;
+ q->nb_packets = 0;
+ q->size = 0;
+ q->duration = 0;
+ SDL_UnlockMutex(q->mutex);
+}
+
+static void packet_queue_destroy(PacketQueue *q)
+{
+ packet_queue_flush(q);
+ SDL_DestroyMutex(q->mutex);
+ SDL_DestroyCond(q->cond);
+}
+
+static void packet_queue_abort(PacketQueue *q)
+{
+ SDL_LockMutex(q->mutex);
+
+ q->abort_request = 1;
+
+ SDL_CondSignal(q->cond);
+
+ SDL_UnlockMutex(q->mutex);
+}
+
+static void packet_queue_start(PacketQueue *q)
+{
+ SDL_LockMutex(q->mutex);
+ q->abort_request = 0;
+ packet_queue_put_private(q, &flush_pkt);
+ SDL_UnlockMutex(q->mutex);
+}
+
+/* return < 0 if aborted, 0 if no packet and > 0 if packet. */
+static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
+{
+ MyAVPacketList *pkt1;
+ int ret;
+
+ SDL_LockMutex(q->mutex);
+
+ for (;;) {
+ if (q->abort_request) {
+ ret = -1;
+ break;
+ }
+
+ pkt1 = q->first_pkt;
+ if (pkt1) {
+ q->first_pkt = pkt1->next;
+ if (!q->first_pkt)
+ q->last_pkt = NULL;
+ q->nb_packets--;
+ q->size -= pkt1->pkt.size + sizeof(*pkt1);
+ q->duration -= pkt1->pkt.duration;
+ *pkt = pkt1->pkt;
+ if (serial)
+ *serial = pkt1->serial;
+ av_free(pkt1);
+ ret = 1;
+ break;
+ } else if (!block) {
+ ret = 0;
+ break;
+ } else {
+ SDL_CondWait(q->cond, q->mutex);
+ }
+ }
+ SDL_UnlockMutex(q->mutex);
+ return ret;
+}
+
+static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
+ memset(d, 0, sizeof(Decoder));
+ d->avctx = avctx;
+ d->queue = queue;
+ d->empty_queue_cond = empty_queue_cond;
+ d->start_pts = AV_NOPTS_VALUE;
+ d->pkt_serial = -1;
+}
+
+static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
+ int ret = AVERROR(EAGAIN);
+
+ for (;;) {
+ AVPacket pkt;
+
+ if (d->queue->serial == d->pkt_serial) {
+ do {
+ if (d->queue->abort_request)
+ return -1;
+
+ switch (d->avctx->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ ret = avcodec_receive_frame(d->avctx, frame);
+ if (ret >= 0) {
+ if (decoder_reorder_pts == -1) {
+ frame->pts = frame->best_effort_timestamp;
+ } else if (!decoder_reorder_pts) {
+ frame->pts = frame->pkt_dts;
+ }
+ }
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ ret = avcodec_receive_frame(d->avctx, frame);
+ if (ret >= 0) {
+ AVRational tb = (AVRational){1, frame->sample_rate};
+ if (frame->pts != AV_NOPTS_VALUE)
+ frame->pts = av_rescale_q(frame->pts, d->avctx->pkt_timebase, tb);
+ else if (d->next_pts != AV_NOPTS_VALUE)
+ frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
+ if (frame->pts != AV_NOPTS_VALUE) {
+ d->next_pts = frame->pts + frame->nb_samples;
+ d->next_pts_tb = tb;
+ }
+ }
+ break;
+ }
+ if (ret == AVERROR_EOF) {
+ d->finished = d->pkt_serial;
+ avcodec_flush_buffers(d->avctx);
+ return 0;
+ }
+ if (ret >= 0)
+ return 1;
+ } while (ret != AVERROR(EAGAIN));
+ }
+
+ do {
+ if (d->queue->nb_packets == 0)
+ SDL_CondSignal(d->empty_queue_cond);
+ if (d->packet_pending) {
+ av_packet_move_ref(&pkt, &d->pkt);
+ d->packet_pending = 0;
+ } else {
+ if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
+ return -1;
+ }
+ if (d->queue->serial == d->pkt_serial)
+ break;
+ av_packet_unref(&pkt);
+ } while (1);
+
+ if (pkt.data == flush_pkt.data) {
+ avcodec_flush_buffers(d->avctx);
+ d->finished = 0;
+ d->next_pts = d->start_pts;
+ d->next_pts_tb = d->start_pts_tb;
+ } else {
+ if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+ int got_frame = 0;
+ ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &pkt);
+ if (ret < 0) {
+ ret = AVERROR(EAGAIN);
+ } else {
+ if (got_frame && !pkt.data) {
+ d->packet_pending = 1;
+ av_packet_move_ref(&d->pkt, &pkt);
+ }
+ ret = got_frame ? 0 : (pkt.data ? AVERROR(EAGAIN) : AVERROR_EOF);
+ }
+ } else {
+ if (avcodec_send_packet(d->avctx, &pkt) == AVERROR(EAGAIN)) {
+ av_log(d->avctx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");
+ d->packet_pending = 1;
+ av_packet_move_ref(&d->pkt, &pkt);
+ }
+ }
+ av_packet_unref(&pkt);
+ }
+ }
+}
+
+static void decoder_destroy(Decoder *d) {
+ av_packet_unref(&d->pkt);
+ avcodec_free_context(&d->avctx);
+}
+
+static void frame_queue_unref_item(Frame *vp)
+{
+ av_frame_unref(vp->frame);
+ avsubtitle_free(&vp->sub);
+}
+
+static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
+{
+ int i;
+ memset(f, 0, sizeof(FrameQueue));
+ if (!(f->mutex = SDL_CreateMutex())) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
+ return AVERROR(ENOMEM);
+ }
+ if (!(f->cond = SDL_CreateCond())) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
+ return AVERROR(ENOMEM);
+ }
+ f->pktq = pktq;
+ f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
+ f->keep_last = !!keep_last;
+ for (i = 0; i < f->max_size; i++)
+ if (!(f->queue[i].frame = av_frame_alloc()))
+ return AVERROR(ENOMEM);
+ return 0;
+}
+
+static void frame_queue_destory(FrameQueue *f)
+{
+ int i;
+ for (i = 0; i < f->max_size; i++) {
+ Frame *vp = &f->queue[i];
+ frame_queue_unref_item(vp);
+ av_frame_free(&vp->frame);
+ }
+ SDL_DestroyMutex(f->mutex);
+ SDL_DestroyCond(f->cond);
+}
+
+static void frame_queue_signal(FrameQueue *f)
+{
+ SDL_LockMutex(f->mutex);
+ SDL_CondSignal(f->cond);
+ SDL_UnlockMutex(f->mutex);
+}
+
+static Frame *frame_queue_peek(FrameQueue *f)
+{
+ return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
+}
+
+static Frame *frame_queue_peek_next(FrameQueue *f)
+{
+ return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
+}
+
+static Frame *frame_queue_peek_last(FrameQueue *f)
+{
+ return &f->queue[f->rindex];
+}
+
+static Frame *frame_queue_peek_writable(FrameQueue *f)
+{
+ /* wait until we have space to put a new frame */
+ SDL_LockMutex(f->mutex);
+ while (f->size >= f->max_size &&
+ !f->pktq->abort_request) {
+ SDL_CondWait(f->cond, f->mutex);
+ }
+ SDL_UnlockMutex(f->mutex);
+
+ if (f->pktq->abort_request)
+ return NULL;
+
+ return &f->queue[f->windex];
+}
+
+static Frame *frame_queue_peek_readable(FrameQueue *f)
+{
+ /* wait until we have a readable a new frame */
+ SDL_LockMutex(f->mutex);
+ while (f->size - f->rindex_shown <= 0 &&
+ !f->pktq->abort_request) {
+ SDL_CondWait(f->cond, f->mutex);
+ }
+ SDL_UnlockMutex(f->mutex);
+
+ if (f->pktq->abort_request)
+ return NULL;
+
+ return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
+}
+
+static void frame_queue_push(FrameQueue *f)
+{
+ if (++f->windex == f->max_size)
+ f->windex = 0;
+ SDL_LockMutex(f->mutex);
+ f->size++;
+ SDL_CondSignal(f->cond);
+ SDL_UnlockMutex(f->mutex);
+}
+
+static void frame_queue_next(FrameQueue *f)
+{
+ if (f->keep_last && !f->rindex_shown) {
+ f->rindex_shown = 1;
+ return;
+ }
+ frame_queue_unref_item(&f->queue[f->rindex]);
+ if (++f->rindex == f->max_size)
+ f->rindex = 0;
+ SDL_LockMutex(f->mutex);
+ f->size--;
+ SDL_CondSignal(f->cond);
+ SDL_UnlockMutex(f->mutex);
+}
+
+/* return the number of undisplayed frames in the queue */
+static int frame_queue_nb_remaining(FrameQueue *f)
+{
+ return f->size - f->rindex_shown;
+}
+
+/* return last shown position */
+static int64_t frame_queue_last_pos(FrameQueue *f)
+{
+ Frame *fp = &f->queue[f->rindex];
+ if (f->rindex_shown && fp->serial == f->pktq->serial)
+ return fp->pos;
+ else
+ return -1;
+}
+
+static void decoder_abort(Decoder *d, FrameQueue *fq)
+{
+ packet_queue_abort(d->queue);
+ frame_queue_signal(fq);
+ SDL_WaitThread(d->decoder_tid, NULL);
+ d->decoder_tid = NULL;
+ packet_queue_flush(d->queue);
+}
+
+static inline void fill_rectangle(int x, int y, int w, int h)
+{
+ SDL_Rect rect;
+ rect.x = x;
+ rect.y = y;
+ rect.w = w;
+ rect.h = h;
+ if (w && h)
+ SDL_RenderFillRect(renderer, &rect);
+}
+
+static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
+{
+ Uint32 format;
+ int access, w, h;
+ if (!*texture || SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
+ void *pixels;
+ int pitch;
+ if (*texture)
+ SDL_DestroyTexture(*texture);
+ if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
+ return -1;
+ if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
+ return -1;
+ if (init_texture) {
+ if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
+ return -1;
+ memset(pixels, 0, pitch * new_height);
+ SDL_UnlockTexture(*texture);
+ }
+ av_log(NULL, AV_LOG_VERBOSE, "Created %dx%d texture with %s.\n", new_width, new_height, SDL_GetPixelFormatName(new_format));
+ }
+ return 0;
+}
+
+static void calculate_display_rect(SDL_Rect *rect,
+ int scr_xleft, int scr_ytop, int scr_width, int scr_height,
+ int pic_width, int pic_height, AVRational pic_sar)
+{
+ AVRational aspect_ratio = pic_sar;
+ int64_t width, height, x, y;
+
+ if (av_cmp_q(aspect_ratio, av_make_q(0, 1)) <= 0)
+ aspect_ratio = av_make_q(1, 1);
+
+ aspect_ratio = av_mul_q(aspect_ratio, av_make_q(pic_width, pic_height));
+
+ /* XXX: we suppose the screen has a 1.0 pixel ratio */
+ height = scr_height;
+ width = av_rescale(height, aspect_ratio.num, aspect_ratio.den) & ~1;
+ if (width > scr_width) {
+ width = scr_width;
+ height = av_rescale(width, aspect_ratio.den, aspect_ratio.num) & ~1;
+ }
+ x = (scr_width - width) / 2;
+ y = (scr_height - height) / 2;
+ rect->x = scr_xleft + x;
+ rect->y = scr_ytop + y;
+ rect->w = FFMAX((int)width, 1);
+ rect->h = FFMAX((int)height, 1);
+}
+
+static void get_sdl_pix_fmt_and_blendmode(int format, Uint32 *sdl_pix_fmt, SDL_BlendMode *sdl_blendmode)
+{
+ int i;
+ *sdl_blendmode = SDL_BLENDMODE_NONE;
+ *sdl_pix_fmt = SDL_PIXELFORMAT_UNKNOWN;
+ if (format == AV_PIX_FMT_RGB32 ||
+ format == AV_PIX_FMT_RGB32_1 ||
+ format == AV_PIX_FMT_BGR32 ||
+ format == AV_PIX_FMT_BGR32_1)
+ *sdl_blendmode = SDL_BLENDMODE_BLEND;
+ for (i = 0; i < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; i++) {
+ if (format == sdl_texture_format_map[i].format) {
+ *sdl_pix_fmt = sdl_texture_format_map[i].texture_fmt;
+ return;
+ }
+ }
+}
+
+static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
+ int ret = 0;
+ Uint32 sdl_pix_fmt;
+ SDL_BlendMode sdl_blendmode;
+ get_sdl_pix_fmt_and_blendmode(frame->format, &sdl_pix_fmt, &sdl_blendmode);
+ if (realloc_texture(tex, sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_ARGB8888 : sdl_pix_fmt, frame->width, frame->height, sdl_blendmode, 0) < 0)
+ return -1;
+ switch (sdl_pix_fmt) {
+ case SDL_PIXELFORMAT_UNKNOWN:
+ /* This should only happen if we are not using avfilter... */
+ *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
+ frame->width, frame->height, frame->format, frame->width, frame->height,
+ AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
+ if (*img_convert_ctx != NULL) {
+ uint8_t *pixels[4];
+ int pitch[4];
+ if (!SDL_LockTexture(*tex, NULL, (void **)pixels, pitch)) {
+ sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
+ 0, frame->height, pixels, pitch);
+ SDL_UnlockTexture(*tex);
+ }
+ } else {
+ av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
+ ret = -1;
+ }
+ break;
+ case SDL_PIXELFORMAT_IYUV:
+ if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) {
+ ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0], frame->linesize[0],
+ frame->data[1], frame->linesize[1],
+ frame->data[2], frame->linesize[2]);
+ } else if (frame->linesize[0] < 0 && frame->linesize[1] < 0 && frame->linesize[2] < 0) {
+ ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0],
+ frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1],
+ frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]);
+ } else {
+ av_log(NULL, AV_LOG_ERROR, "Mixed negative and positive linesizes are not supported.\n");
+ return -1;
+ }
+ break;
+ default:
+ if (frame->linesize[0] < 0) {
+ ret = SDL_UpdateTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
+ } else {
+ ret = SDL_UpdateTexture(*tex, NULL, frame->data[0], frame->linesize[0]);
+ }
+ break;
+ }
+ return ret;
+}
+
+static void set_sdl_yuv_conversion_mode(AVFrame *frame)
+{
+#if SDL_VERSION_ATLEAST(2,0,8)
+ SDL_YUV_CONVERSION_MODE mode = SDL_YUV_CONVERSION_AUTOMATIC;
+ if (frame && (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUYV422 || frame->format == AV_PIX_FMT_UYVY422)) {
+ if (frame->color_range == AVCOL_RANGE_JPEG)
+ mode = SDL_YUV_CONVERSION_JPEG;
+ else if (frame->colorspace == AVCOL_SPC_BT709)
+ mode = SDL_YUV_CONVERSION_BT709;
+ else if (frame->colorspace == AVCOL_SPC_BT470BG || frame->colorspace == AVCOL_SPC_SMPTE170M || frame->colorspace == AVCOL_SPC_SMPTE240M)
+ mode = SDL_YUV_CONVERSION_BT601;
+ }
+ SDL_SetYUVConversionMode(mode);
+#endif
+}
+
+static void video_image_display(VideoState *is)
+{
+ Frame *vp;
+ Frame *sp = NULL;
+ SDL_Rect rect;
+
+ vp = frame_queue_peek_last(&is->pictq);
+ if (is->subtitle_st) {
+ if (frame_queue_nb_remaining(&is->subpq) > 0) {
+ sp = frame_queue_peek(&is->subpq);
+
+ if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
+ if (!sp->uploaded) {
+ uint8_t* pixels[4];
+ int pitch[4];
+ int i;
+ if (!sp->width || !sp->height) {
+ sp->width = vp->width;
+ sp->height = vp->height;
+ }
+ if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
+ return;
+
+ for (i = 0; i < sp->sub.num_rects; i++) {
+ AVSubtitleRect *sub_rect = sp->sub.rects[i];
+
+ sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
+ sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
+ sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
+ sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
+
+ is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
+ sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
+ sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
+ 0, NULL, NULL, NULL);
+ if (!is->sub_convert_ctx) {
+ av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
+ return;
+ }
+ if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
+ sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
+ 0, sub_rect->h, pixels, pitch);
+ SDL_UnlockTexture(is->sub_texture);
+ }
+ }
+ sp->uploaded = 1;
+ }
+ } else
+ sp = NULL;
+ }
+ }
+
+ calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
+
+ if (!vp->uploaded) {
+ if (upload_texture(&is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
+ return;
+ vp->uploaded = 1;
+ vp->flip_v = vp->frame->linesize[0] < 0;
+ }
+
+ set_sdl_yuv_conversion_mode(vp->frame);
+ SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
+ set_sdl_yuv_conversion_mode(NULL);
+ if (sp) {
+#if USE_ONEPASS_SUBTITLE_RENDER
+ SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
+#else
+ int i;
+ double xratio = (double)rect.w / (double)sp->width;
+ double yratio = (double)rect.h / (double)sp->height;
+ for (i = 0; i < sp->sub.num_rects; i++) {
+ SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
+ SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
+ .y = rect.y + sub_rect->y * yratio,
+ .w = sub_rect->w * xratio,
+ .h = sub_rect->h * yratio};
+ SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
+ }
+#endif
+ }
+}
+
+static inline int compute_mod(int a, int b)
+{
+ return a < 0 ? a%b + b : a%b;
+}
+
+static void video_audio_display(VideoState *s)
+{
+ int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
+ int ch, channels, h, h2;
+ int64_t time_diff;
+ int rdft_bits, nb_freq;
+
+ for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
+ ;
+ nb_freq = 1 << (rdft_bits - 1);
+
+ /* compute display index : center on currently output samples */
+ channels = s->audio_tgt.channels;
+ nb_display_channels = channels;
+ if (!s->paused) {
+ int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
+ n = 2 * channels;
+ delay = s->audio_write_buf_size;
+ delay /= n;
+
+ /* to be more precise, we take into account the time spent since
+ the last buffer computation */
+ if (audio_callback_time) {
+ time_diff = av_gettime_relative() - audio_callback_time;
+ delay -= (time_diff * s->audio_tgt.freq) / 1000000;
+ }
+
+ delay += 2 * data_used;
+ if (delay < data_used)
+ delay = data_used;
+
+ i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
+ if (s->show_mode == SHOW_MODE_WAVES) {
+ h = INT_MIN;
+ for (i = 0; i < 1000; i += channels) {
+ int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
+ int a = s->sample_array[idx];
+ int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
+ int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
+ int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
+ int score = a - d;
+ if (h < score && (b ^ c) < 0) {
+ h = score;
+ i_start = idx;
+ }
+ }
+ }
+
+ s->last_i_start = i_start;
+ } else {
+ i_start = s->last_i_start;
+ }
+
+ if (s->show_mode == SHOW_MODE_WAVES) {
+ SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
+
+ /* total height for one channel */
+ h = s->height / nb_display_channels;
+ /* graph height / 2 */
+ h2 = (h * 9) / 20;
+ for (ch = 0; ch < nb_display_channels; ch++) {
+ i = i_start + ch;
+ y1 = s->ytop + ch * h + (h / 2); /* position of center line */
+ for (x = 0; x < s->width; x++) {
+ y = (s->sample_array[i] * h2) >> 15;
+ if (y < 0) {
+ y = -y;
+ ys = y1 - y;
+ } else {
+ ys = y1;
+ }
+ fill_rectangle(s->xleft + x, ys, 1, y);
+ i += channels;
+ if (i >= SAMPLE_ARRAY_SIZE)
+ i -= SAMPLE_ARRAY_SIZE;
+ }
+ }
+
+ SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
+
+ for (ch = 1; ch < nb_display_channels; ch++) {
+ y = s->ytop + ch * h;
+ fill_rectangle(s->xleft, y, s->width, 1);
+ }
+ } else {
+ if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
+ return;
+
+ nb_display_channels= FFMIN(nb_display_channels, 2);
+ if (rdft_bits != s->rdft_bits) {
+ av_rdft_end(s->rdft);
+ av_free(s->rdft_data);
+ s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
+ s->rdft_bits = rdft_bits;
+ s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
+ }
+ if (!s->rdft || !s->rdft_data){
+ av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
+ s->show_mode = SHOW_MODE_WAVES;
+ } else {
+ FFTSample *data[2];
+ SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
+ uint32_t *pixels;
+ int pitch;
+ for (ch = 0; ch < nb_display_channels; ch++) {
+ data[ch] = s->rdft_data + 2 * nb_freq * ch;
+ i = i_start + ch;
+ for (x = 0; x < 2 * nb_freq; x++) {
+ double w = (x-nb_freq) * (1.0 / nb_freq);
+ data[ch][x] = s->sample_array[i] * (1.0 - w * w);
+ i += channels;
+ if (i >= SAMPLE_ARRAY_SIZE)
+ i -= SAMPLE_ARRAY_SIZE;
+ }
+ av_rdft_calc(s->rdft, data[ch]);
+ }
+ /* Least efficient way to do this, we should of course
+ * directly access it but it is more than fast enough. */
+ if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
+ pitch >>= 2;
+ pixels += pitch * s->height;
+ for (y = 0; y < s->height; y++) {
+ double w = 1 / sqrt(nb_freq);
+ int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
+ int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
+ : a;
+ a = FFMIN(a, 255);
+ b = FFMIN(b, 255);
+ pixels -= pitch;
+ *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
+ }
+ SDL_UnlockTexture(s->vis_texture);
+ }
+ SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
+ }
+ if (!s->paused)
+ s->xpos++;
+ if (s->xpos >= s->width)
+ s->xpos= s->xleft;
+ }
+}
+
+static void stream_component_close(VideoState *is, int stream_index)
+{
+ AVFormatContext *ic = is->ic;
+ AVCodecParameters *codecpar;
+
+ if (stream_index < 0 || stream_index >= ic->nb_streams)
+ return;
+ codecpar = ic->streams[stream_index]->codecpar;
+
+ switch (codecpar->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ decoder_abort(&is->auddec, &is->sampq);
+ SDL_CloseAudioDevice(audio_dev);
+ decoder_destroy(&is->auddec);
+ swr_free(&is->swr_ctx);
+ av_freep(&is->audio_buf1);
+ is->audio_buf1_size = 0;
+ is->audio_buf = NULL;
+
+ if (is->rdft) {
+ av_rdft_end(is->rdft);
+ av_freep(&is->rdft_data);
+ is->rdft = NULL;
+ is->rdft_bits = 0;
+ }
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ decoder_abort(&is->viddec, &is->pictq);
+ decoder_destroy(&is->viddec);
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ decoder_abort(&is->subdec, &is->subpq);
+ decoder_destroy(&is->subdec);
+ break;
+ default:
+ break;
+ }
+
+ ic->streams[stream_index]->discard = AVDISCARD_ALL;
+ switch (codecpar->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ is->audio_st = NULL;
+ is->audio_stream = -1;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ is->video_st = NULL;
+ is->video_stream = -1;
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ is->subtitle_st = NULL;
+ is->subtitle_stream = -1;
+ break;
+ default:
+ break;
+ }
+}
+
+static void stream_close(VideoState *is)
+{
+ /* XXX: use a special url_shutdown call to abort parse cleanly */
+ is->abort_request = 1;
+ SDL_WaitThread(is->read_tid, NULL);
+
+ /* close each stream */
+ if (is->audio_stream >= 0)
+ stream_component_close(is, is->audio_stream);
+ if (is->video_stream >= 0)
+ stream_component_close(is, is->video_stream);
+ if (is->subtitle_stream >= 0)
+ stream_component_close(is, is->subtitle_stream);
+
+ avformat_close_input(&is->ic);
+
+ packet_queue_destroy(&is->videoq);
+ packet_queue_destroy(&is->audioq);
+ packet_queue_destroy(&is->subtitleq);
+
+ /* free all pictures */
+ frame_queue_destory(&is->pictq);
+ frame_queue_destory(&is->sampq);
+ frame_queue_destory(&is->subpq);
+ SDL_DestroyCond(is->continue_read_thread);
+ sws_freeContext(is->img_convert_ctx);
+ sws_freeContext(is->sub_convert_ctx);
+ av_free(is->filename);
+ if (is->vis_texture)
+ SDL_DestroyTexture(is->vis_texture);
+ if (is->vid_texture)
+ SDL_DestroyTexture(is->vid_texture);
+ if (is->sub_texture)
+ SDL_DestroyTexture(is->sub_texture);
+ av_free(is);
+}
+
+static void do_exit(VideoState *is)
+{
+ if (is) {
+ stream_close(is);
+ }
+ if (renderer)
+ SDL_DestroyRenderer(renderer);
+ if (window)
+ SDL_DestroyWindow(window);
+ uninit_opts();
+#if CONFIG_AVFILTER
+ av_freep(&vfilters_list);
+#endif
+ avformat_network_deinit();
+ if (show_status)
+ printf("\n");
+ SDL_Quit();
+ av_log(NULL, AV_LOG_QUIET, "%s", "");
+ exit(0);
+}
+
+static void sigterm_handler(int sig)
+{
+ exit(123);
+}
+
+static void set_default_window_size(int width, int height, AVRational sar)
+{
+ SDL_Rect rect;
+ int max_width = screen_width ? screen_width : INT_MAX;
+ int max_height = screen_height ? screen_height : INT_MAX;
+ if (max_width == INT_MAX && max_height == INT_MAX)
+ max_height = height;
+ calculate_display_rect(&rect, 0, 0, max_width, max_height, width, height, sar);
+ default_width = rect.w;
+ default_height = rect.h;
+}
+
+static int video_open(VideoState *is)
+{
+ int w,h;
+
+ w = screen_width ? screen_width : default_width;
+ h = screen_height ? screen_height : default_height;
+
+ if (!window_title)
+ window_title = input_filename;
+ SDL_SetWindowTitle(window, window_title);
+
+ SDL_SetWindowSize(window, w, h);
+ SDL_SetWindowPosition(window, screen_left, screen_top);
+ if (is_full_screen)
+ SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
+ SDL_ShowWindow(window);
+
+ is->width = w;
+ is->height = h;
+
+ return 0;
+}
+
+/* display the current picture, if any */
+static void video_display(VideoState *is)
+{
+ if (!is->width)
+ video_open(is);
+
+ SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
+ SDL_RenderClear(renderer);
+ if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
+ video_audio_display(is);
+ else if (is->video_st)
+ video_image_display(is);
+ SDL_RenderPresent(renderer);
+}
+
+static double get_clock(Clock *c)
+{
+ if (*c->queue_serial != c->serial)
+ return NAN;
+ if (c->paused) {
+ return c->pts;
+ } else {
+ double time = av_gettime_relative() / 1000000.0;
+ return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
+ }
+}
+
+static void set_clock_at(Clock *c, double pts, int serial, double time)
+{
+ c->pts = pts;
+ c->last_updated = time;
+ c->pts_drift = c->pts - time;
+ c->serial = serial;
+}
+
+static void set_clock(Clock *c, double pts, int serial)
+{
+ double time = av_gettime_relative() / 1000000.0;
+ set_clock_at(c, pts, serial, time);
+}
+
+static void set_clock_speed(Clock *c, double speed)
+{
+ set_clock(c, get_clock(c), c->serial);
+ c->speed = speed;
+}
+
+static void init_clock(Clock *c, int *queue_serial)
+{
+ c->speed = 1.0;
+ c->paused = 0;
+ c->queue_serial = queue_serial;
+ set_clock(c, NAN, -1);
+}
+
+static void sync_clock_to_slave(Clock *c, Clock *slave)
+{
+ double clock = get_clock(c);
+ double slave_clock = get_clock(slave);
+ if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
+ set_clock(c, slave_clock, slave->serial);
+}
+
+static int get_master_sync_type(VideoState *is) {
+ if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
+ if (is->video_st)
+ return AV_SYNC_VIDEO_MASTER;
+ else
+ return AV_SYNC_AUDIO_MASTER;
+ } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
+ if (is->audio_st)
+ return AV_SYNC_AUDIO_MASTER;
+ else
+ return AV_SYNC_EXTERNAL_CLOCK;
+ } else {
+ return AV_SYNC_EXTERNAL_CLOCK;
+ }
+}
+
+/* get the current master clock value */
+static double get_master_clock(VideoState *is)
+{
+ double val;
+
+ switch (get_master_sync_type(is)) {
+ case AV_SYNC_VIDEO_MASTER:
+ val = get_clock(&is->vidclk);
+ break;
+ case AV_SYNC_AUDIO_MASTER:
+ val = get_clock(&is->audclk);
+ break;
+ default:
+ val = get_clock(&is->extclk);
+ break;
+ }
+ return val;
+}
+
+static void check_external_clock_speed(VideoState *is) {
+ if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
+ is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
+ set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
+ } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
+ (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
+ set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
+ } else {
+ double speed = is->extclk.speed;
+ if (speed != 1.0)
+ set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
+ }
+}
+
+/* seek in the stream */
+static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
+{
+ if (!is->seek_req) {
+ is->seek_pos = pos;
+ is->seek_rel = rel;
+ is->seek_flags &= ~AVSEEK_FLAG_BYTE;
+ if (seek_by_bytes)
+ is->seek_flags |= AVSEEK_FLAG_BYTE;
+ is->seek_req = 1;
+ SDL_CondSignal(is->continue_read_thread);
+ }
+}
+
+/* pause or resume the video */
+static void stream_toggle_pause(VideoState *is)
+{
+ if (is->paused) {
+ is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
+ if (is->read_pause_return != AVERROR(ENOSYS)) {
+ is->vidclk.paused = 0;
+ }
+ set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
+ }
+ set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
+ is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
+}
+
+static void toggle_pause(VideoState *is)
+{
+ stream_toggle_pause(is);
+ is->step = 0;
+}
+
+static void toggle_mute(VideoState *is)
+{
+ is->muted = !is->muted;
+}
+
+static void update_volume(VideoState *is, int sign, double step)
+{
+ double volume_level = is->audio_volume ? (20 * log(is->audio_volume / (double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
+ int new_volume = lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign * step) / 20.0));
+ is->audio_volume = av_clip(is->audio_volume == new_volume ? (is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
+}
+
+static void step_to_next_frame(VideoState *is)
+{
+ /* if the stream is paused unpause it, then step */
+ if (is->paused)
+ stream_toggle_pause(is);
+ is->step = 1;
+}
+
+static double compute_target_delay(double delay, VideoState *is)
+{
+ double sync_threshold, diff = 0;
+
+ /* update delay to follow master synchronisation source */
+ if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
+ /* if video is slave, we try to correct big delays by
+ duplicating or deleting a frame */
+ diff = get_clock(&is->vidclk) - get_master_clock(is);
+
+ /* skip or repeat frame. We take into account the
+ delay to compute the threshold. I still don't know
+ if it is the best guess */
+ sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
+ if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
+ if (diff <= -sync_threshold)
+ delay = FFMAX(0, delay + diff);
+ else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
+ delay = delay + diff;
+ else if (diff >= sync_threshold)
+ delay = 2 * delay;
+ }
+ }
+
+ av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
+ delay, -diff);
+
+ return delay;
+}
+
+static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
+ if (vp->serial == nextvp->serial) {
+ double duration = nextvp->pts - vp->pts;
+ if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
+ return vp->duration;
+ else
+ return duration;
+ } else {
+ return 0.0;
+ }
+}
+
+static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
+ /* update current video pts */
+ set_clock(&is->vidclk, pts, serial);
+ sync_clock_to_slave(&is->extclk, &is->vidclk);
+}
+
+/* called to display each frame */
+static void video_refresh(void *opaque, double *remaining_time)
+{
+ VideoState *is = opaque;
+ double time;
+
+ Frame *sp, *sp2;
+
+ if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
+ check_external_clock_speed(is);
+
+ if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
+ time = av_gettime_relative() / 1000000.0;
+ if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
+ video_display(is);
+ is->last_vis_time = time;
+ }
+ *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
+ }
+
+ if (is->video_st) {
+retry:
+ if (frame_queue_nb_remaining(&is->pictq) == 0) {
+ // nothing to do, no picture to display in the queue
+ } else {
+ double last_duration, duration, delay;
+ Frame *vp, *lastvp;
+
+ /* dequeue the picture */
+ lastvp = frame_queue_peek_last(&is->pictq);
+ vp = frame_queue_peek(&is->pictq);
+
+ if (vp->serial != is->videoq.serial) {
+ frame_queue_next(&is->pictq);
+ goto retry;
+ }
+
+ if (lastvp->serial != vp->serial)
+ is->frame_timer = av_gettime_relative() / 1000000.0;
+
+ if (is->paused)
+ goto display;
+
+ /* compute nominal last_duration */
+ last_duration = vp_duration(is, lastvp, vp);
+ delay = compute_target_delay(last_duration, is);
+
+ time= av_gettime_relative()/1000000.0;
+ if (time < is->frame_timer + delay) {
+ *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
+ goto display;
+ }
+
+ is->frame_timer += delay;
+ if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
+ is->frame_timer = time;
+
+ SDL_LockMutex(is->pictq.mutex);
+ if (!isnan(vp->pts))
+ update_video_pts(is, vp->pts, vp->pos, vp->serial);
+ SDL_UnlockMutex(is->pictq.mutex);
+
+ if (frame_queue_nb_remaining(&is->pictq) > 1) {
+ Frame *nextvp = frame_queue_peek_next(&is->pictq);
+ duration = vp_duration(is, vp, nextvp);
+ if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
+ is->frame_drops_late++;
+ frame_queue_next(&is->pictq);
+ goto retry;
+ }
+ }
+
+ if (is->subtitle_st) {
+ while (frame_queue_nb_remaining(&is->subpq) > 0) {
+ sp = frame_queue_peek(&is->subpq);
+
+ if (frame_queue_nb_remaining(&is->subpq) > 1)
+ sp2 = frame_queue_peek_next(&is->subpq);
+ else
+ sp2 = NULL;
+
+ if (sp->serial != is->subtitleq.serial
+ || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
+ || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
+ {
+ if (sp->uploaded) {
+ int i;
+ for (i = 0; i < sp->sub.num_rects; i++) {
+ AVSubtitleRect *sub_rect = sp->sub.rects[i];
+ uint8_t *pixels;
+ int pitch, j;
+
+ if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
+ for (j = 0; j < sub_rect->h; j++, pixels += pitch)
+ memset(pixels, 0, sub_rect->w << 2);
+ SDL_UnlockTexture(is->sub_texture);
+ }
+ }
+ }
+ frame_queue_next(&is->subpq);
+ } else {
+ break;
+ }
+ }
+ }
+
+ frame_queue_next(&is->pictq);
+ is->force_refresh = 1;
+
+ if (is->step && !is->paused)
+ stream_toggle_pause(is);
+ }
+display:
+ /* display picture */
+ if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
+ video_display(is);
+ }
+ is->force_refresh = 0;
+ if (show_status) {
+ AVBPrint buf;
+ static int64_t last_time;
+ int64_t cur_time;
+ int aqsize, vqsize, sqsize;
+ double av_diff;
+
+ cur_time = av_gettime_relative();
+ if (!last_time || (cur_time - last_time) >= 30000) {
+ aqsize = 0;
+ vqsize = 0;
+ sqsize = 0;
+ if (is->audio_st)
+ aqsize = is->audioq.size;
+ if (is->video_st)
+ vqsize = is->videoq.size;
+ if (is->subtitle_st)
+ sqsize = is->subtitleq.size;
+ av_diff = 0;
+ if (is->audio_st && is->video_st)
+ av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
+ else if (is->video_st)
+ av_diff = get_master_clock(is) - get_clock(&is->vidclk);
+ else if (is->audio_st)
+ av_diff = get_master_clock(is) - get_clock(&is->audclk);
+
+ av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
+ av_bprintf(&buf,
+ "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
+ get_master_clock(is),
+ (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
+ av_diff,
+ is->frame_drops_early + is->frame_drops_late,
+ aqsize / 1024,
+ vqsize / 1024,
+ sqsize,
+ is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
+ is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
+
+ if (show_status == 1 && AV_LOG_INFO > av_log_get_level())
+ fprintf(stderr, "%s", buf.str);
+ else
+ av_log(NULL, AV_LOG_INFO, "%s", buf.str);
+
+ fflush(stderr);
+ av_bprint_finalize(&buf, NULL);
+
+ last_time = cur_time;
+ }
+ }
+}
+
+static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
+{
+ Frame *vp;
+
+#if defined(DEBUG_SYNC)
+ printf("frame_type=%c pts=%0.3f\n",
+ av_get_picture_type_char(src_frame->pict_type), pts);
+#endif
+
+ if (!(vp = frame_queue_peek_writable(&is->pictq)))
+ return -1;
+
+ vp->sar = src_frame->sample_aspect_ratio;
+ vp->uploaded = 0;
+
+ vp->width = src_frame->width;
+ vp->height = src_frame->height;
+ vp->format = src_frame->format;
+
+ vp->pts = pts;
+ vp->duration = duration;
+ vp->pos = pos;
+ vp->serial = serial;
+
+ set_default_window_size(vp->width, vp->height, vp->sar);
+
+ av_frame_move_ref(vp->frame, src_frame);
+ frame_queue_push(&is->pictq);
+ return 0;
+}
+
+static int get_video_frame(VideoState *is, AVFrame *frame)
+{
+ int got_picture;
+
+ if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
+ return -1;
+
+ if (got_picture) {
+ double dpts = NAN;
+
+ if (frame->pts != AV_NOPTS_VALUE)
+ dpts = av_q2d(is->video_st->time_base) * frame->pts;
+
+ frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
+
+ if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
+ if (frame->pts != AV_NOPTS_VALUE) {
+ double diff = dpts - get_master_clock(is);
+ if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
+ diff - is->frame_last_filter_delay < 0 &&
+ is->viddec.pkt_serial == is->vidclk.serial &&
+ is->videoq.nb_packets) {
+ is->frame_drops_early++;
+ av_frame_unref(frame);
+ got_picture = 0;
+ }
+ }
+ }
+ }
+
+ return got_picture;
+}
+
+#if CONFIG_AVFILTER
+static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
+ AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
+{
+ int ret, i;
+ int nb_filters = graph->nb_filters;
+ AVFilterInOut *outputs = NULL, *inputs = NULL;
+
+ if (filtergraph) {
+ outputs = avfilter_inout_alloc();
+ inputs = avfilter_inout_alloc();
+ if (!outputs || !inputs) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ outputs->name = av_strdup("in");
+ outputs->filter_ctx = source_ctx;
+ outputs->pad_idx = 0;
+ outputs->next = NULL;
+
+ inputs->name = av_strdup("out");
+ inputs->filter_ctx = sink_ctx;
+ inputs->pad_idx = 0;
+ inputs->next = NULL;
+
+ if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
+ goto fail;
+ } else {
+ if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
+ goto fail;
+ }
+
+ /* Reorder the filters to ensure that inputs of the custom filters are merged first */
+ for (i = 0; i < graph->nb_filters - nb_filters; i++)
+ FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
+
+ ret = avfilter_graph_config(graph, NULL);
+fail:
+ avfilter_inout_free(&outputs);
+ avfilter_inout_free(&inputs);
+ return ret;
+}
+
+static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
+{
+ enum AVPixelFormat pix_fmts[FF_ARRAY_ELEMS(sdl_texture_format_map)];
+ char sws_flags_str[512] = "";
+ char buffersrc_args[256];
+ int ret;
+ AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
+ AVCodecParameters *codecpar = is->video_st->codecpar;
+ AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
+ AVDictionaryEntry *e = NULL;
+ int nb_pix_fmts = 0;
+ int i, j;
+
+ for (i = 0; i < renderer_info.num_texture_formats; i++) {
+ for (j = 0; j < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; j++) {
+ if (renderer_info.texture_formats[i] == sdl_texture_format_map[j].texture_fmt) {
+ pix_fmts[nb_pix_fmts++] = sdl_texture_format_map[j].format;
+ break;
+ }
+ }
+ }
+ pix_fmts[nb_pix_fmts] = AV_PIX_FMT_NONE;
+
+ while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
+ if (!strcmp(e->key, "sws_flags")) {
+ av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
+ } else
+ av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
+ }
+ if (strlen(sws_flags_str))
+ sws_flags_str[strlen(sws_flags_str)-1] = '\0';
+
+ graph->scale_sws_opts = av_strdup(sws_flags_str);
+
+ snprintf(buffersrc_args, sizeof(buffersrc_args),
+ "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
+ frame->width, frame->height, frame->format,
+ is->video_st->time_base.num, is->video_st->time_base.den,
+ codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
+ if (fr.num && fr.den)
+ av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
+
+ if ((ret = avfilter_graph_create_filter(&filt_src,
+ avfilter_get_by_name("buffer"),
+ "ffplay_buffer", buffersrc_args, NULL,
+ graph)) < 0)
+ goto fail;
+
+ ret = avfilter_graph_create_filter(&filt_out,
+ avfilter_get_by_name("buffersink"),
+ "ffplay_buffersink", NULL, NULL, graph);
+ if (ret < 0)
+ goto fail;
+
+ if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
+ goto fail;
+
+ last_filter = filt_out;
+
+/* Note: this macro adds a filter before the lastly added filter, so the
+ * processing order of the filters is in reverse */
+#define INSERT_FILT(name, arg) do { \
+ AVFilterContext *filt_ctx; \
+ \
+ ret = avfilter_graph_create_filter(&filt_ctx, \
+ avfilter_get_by_name(name), \
+ "ffplay_" name, arg, NULL, graph); \
+ if (ret < 0) \
+ goto fail; \
+ \
+ ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
+ if (ret < 0) \
+ goto fail; \
+ \
+ last_filter = filt_ctx; \
+} while (0)
+
+ if (autorotate) {
+ double theta = get_rotation(is->video_st);
+
+ if (fabs(theta - 90) < 1.0) {
+ INSERT_FILT("transpose", "clock");
+ } else if (fabs(theta - 180) < 1.0) {
+ INSERT_FILT("hflip", NULL);
+ INSERT_FILT("vflip", NULL);
+ } else if (fabs(theta - 270) < 1.0) {
+ INSERT_FILT("transpose", "cclock");
+ } else if (fabs(theta) > 1.0) {
+ char rotate_buf[64];
+ snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
+ INSERT_FILT("rotate", rotate_buf);
+ }
+ }
+
+ if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
+ goto fail;
+
+ is->in_video_filter = filt_src;
+ is->out_video_filter = filt_out;
+
+fail:
+ return ret;
+}
+
+static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
+{
+ static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
+ int sample_rates[2] = { 0, -1 };
+ int64_t channel_layouts[2] = { 0, -1 };
+ int channels[2] = { 0, -1 };
+ AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
+ char aresample_swr_opts[512] = "";
+ AVDictionaryEntry *e = NULL;
+ char asrc_args[256];
+ int ret;
+
+ avfilter_graph_free(&is->agraph);
+ if (!(is->agraph = avfilter_graph_alloc()))
+ return AVERROR(ENOMEM);
+ is->agraph->nb_threads = filter_nbthreads;
+
+ while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
+ 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';
+ av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
+
+ ret = snprintf(asrc_args, sizeof(asrc_args),
+ "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
+ is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
+ is->audio_filter_src.channels,
+ 1, is->audio_filter_src.freq);
+ if (is->audio_filter_src.channel_layout)
+ snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
+ ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
+
+ ret = avfilter_graph_create_filter(&filt_asrc,
+ avfilter_get_by_name("abuffer"), "ffplay_abuffer",
+ asrc_args, NULL, is->agraph);
+ if (ret < 0)
+ goto end;
+
+
+ ret = avfilter_graph_create_filter(&filt_asink,
+ avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
+ NULL, NULL, is->agraph);
+ if (ret < 0)
+ goto end;
+
+ if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
+ goto end;
+ if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
+ goto end;
+
+ if (force_output_format) {
+ channel_layouts[0] = is->audio_tgt.channel_layout;
+ channels [0] = is->audio_tgt.channels;
+ sample_rates [0] = is->audio_tgt.freq;
+ if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
+ goto end;
+ if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
+ goto end;
+ if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
+ goto end;
+ if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
+ goto end;
+ }
+
+
+ if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
+ goto end;
+
+ is->in_audio_filter = filt_asrc;
+ is->out_audio_filter = filt_asink;
+
+end:
+ if (ret < 0)
+ avfilter_graph_free(&is->agraph);
+ return ret;
+}
+#endif /* CONFIG_AVFILTER */
+
+static int audio_thread(void *arg)
+{
+ VideoState *is = arg;
+ AVFrame *frame = av_frame_alloc();
+ Frame *af;
+#if CONFIG_AVFILTER
+ int last_serial = -1;
+ int64_t dec_channel_layout;
+ int reconfigure;
+#endif
+ int got_frame = 0;
+ AVRational tb;
+ int ret = 0;
+
+ if (!frame)
+ return AVERROR(ENOMEM);
+
+ do {
+ if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
+ goto the_end;
+
+ if (got_frame) {
+ tb = (AVRational){1, frame->sample_rate};
+
+#if CONFIG_AVFILTER
+ dec_channel_layout = get_valid_channel_layout(frame->channel_layout, frame->channels);
+
+ reconfigure =
+ cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
+ frame->format, frame->channels) ||
+ is->audio_filter_src.channel_layout != dec_channel_layout ||
+ is->audio_filter_src.freq != frame->sample_rate ||
+ is->auddec.pkt_serial != last_serial;
+
+ if (reconfigure) {
+ char buf1[1024], buf2[1024];
+ av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
+ av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
+ av_log(NULL, AV_LOG_DEBUG,
+ "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
+ is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
+ frame->sample_rate, frame->channels, av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
+
+ is->audio_filter_src.fmt = frame->format;
+ is->audio_filter_src.channels = frame->channels;
+ is->audio_filter_src.channel_layout = dec_channel_layout;
+ is->audio_filter_src.freq = frame->sample_rate;
+ last_serial = is->auddec.pkt_serial;
+
+ if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
+ goto the_end;
+ }
+
+ if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
+ goto the_end;
+
+ while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
+ tb = av_buffersink_get_time_base(is->out_audio_filter);
+#endif
+ if (!(af = frame_queue_peek_writable(&is->sampq)))
+ goto the_end;
+
+ af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
+ af->pos = frame->pkt_pos;
+ af->serial = is->auddec.pkt_serial;
+ af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
+
+ av_frame_move_ref(af->frame, frame);
+ frame_queue_push(&is->sampq);
+
+#if CONFIG_AVFILTER
+ if (is->audioq.serial != is->auddec.pkt_serial)
+ break;
+ }
+ if (ret == AVERROR_EOF)
+ is->auddec.finished = is->auddec.pkt_serial;
+#endif
+ }
+ } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
+ the_end:
+#if CONFIG_AVFILTER
+ avfilter_graph_free(&is->agraph);
+#endif
+ av_frame_free(&frame);
+ return ret;
+}
+
+static int decoder_start(Decoder *d, int (*fn)(void *), const char *thread_name, void* arg)
+{
+ packet_queue_start(d->queue);
+ d->decoder_tid = SDL_CreateThread(fn, thread_name, arg);
+ if (!d->decoder_tid) {
+ av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
+ return AVERROR(ENOMEM);
+ }
+ return 0;
+}
+
+static int video_thread(void *arg)
+{
+ VideoState *is = arg;
+ AVFrame *frame = av_frame_alloc();
+ double pts;
+ double duration;
+ int ret;
+ AVRational tb = is->video_st->time_base;
+ AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
+
+#if CONFIG_AVFILTER
+ AVFilterGraph *graph = NULL;
+ AVFilterContext *filt_out = NULL, *filt_in = NULL;
+ int last_w = 0;
+ int last_h = 0;
+ enum AVPixelFormat last_format = -2;
+ int last_serial = -1;
+ int last_vfilter_idx = 0;
+#endif
+
+ if (!frame)
+ return AVERROR(ENOMEM);
+
+ for (;;) {
+ ret = get_video_frame(is, frame);
+ if (ret < 0)
+ goto the_end;
+ if (!ret)
+ continue;
+
+#if CONFIG_AVFILTER
+ if ( last_w != frame->width
+ || last_h != frame->height
+ || last_format != frame->format
+ || last_serial != is->viddec.pkt_serial
+ || last_vfilter_idx != is->vfilter_idx) {
+ av_log(NULL, AV_LOG_DEBUG,
+ "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
+ last_w, last_h,
+ (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
+ frame->width, frame->height,
+ (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
+ avfilter_graph_free(&graph);
+ graph = avfilter_graph_alloc();
+ if (!graph) {
+ ret = AVERROR(ENOMEM);
+ goto the_end;
+ }
+ graph->nb_threads = filter_nbthreads;
+ if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
+ SDL_Event event;
+ event.type = FF_QUIT_EVENT;
+ event.user.data1 = is;
+ SDL_PushEvent(&event);
+ goto the_end;
+ }
+ filt_in = is->in_video_filter;
+ filt_out = is->out_video_filter;
+ last_w = frame->width;
+ last_h = frame->height;
+ last_format = frame->format;
+ last_serial = is->viddec.pkt_serial;
+ last_vfilter_idx = is->vfilter_idx;
+ frame_rate = av_buffersink_get_frame_rate(filt_out);
+ }
+
+ ret = av_buffersrc_add_frame(filt_in, frame);
+ if (ret < 0)
+ goto the_end;
+
+ while (ret >= 0) {
+ is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
+
+ ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
+ if (ret < 0) {
+ if (ret == AVERROR_EOF)
+ is->viddec.finished = is->viddec.pkt_serial;
+ ret = 0;
+ break;
+ }
+
+ is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
+ if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
+ is->frame_last_filter_delay = 0;
+ tb = av_buffersink_get_time_base(filt_out);
+#endif
+ duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
+ pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
+ ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
+ av_frame_unref(frame);
+#if CONFIG_AVFILTER
+ if (is->videoq.serial != is->viddec.pkt_serial)
+ break;
+ }
+#endif
+
+ if (ret < 0)
+ goto the_end;
+ }
+ the_end:
+#if CONFIG_AVFILTER
+ avfilter_graph_free(&graph);
+#endif
+ av_frame_free(&frame);
+ return 0;
+}
+
+static int subtitle_thread(void *arg)
+{
+ VideoState *is = arg;
+ Frame *sp;
+ int got_subtitle;
+ double pts;
+
+ for (;;) {
+ if (!(sp = frame_queue_peek_writable(&is->subpq)))
+ return 0;
+
+ if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
+ break;
+
+ pts = 0;
+
+ if (got_subtitle && sp->sub.format == 0) {
+ if (sp->sub.pts != AV_NOPTS_VALUE)
+ pts = sp->sub.pts / (double)AV_TIME_BASE;
+ sp->pts = pts;
+ sp->serial = is->subdec.pkt_serial;
+ sp->width = is->subdec.avctx->width;
+ sp->height = is->subdec.avctx->height;
+ sp->uploaded = 0;
+
+ /* now we can update the picture count */
+ frame_queue_push(&is->subpq);
+ } else if (got_subtitle) {
+ avsubtitle_free(&sp->sub);
+ }
+ }
+ return 0;
+}
+
+/* copy samples for viewing in editor window */
+static void update_sample_display(VideoState *is, short *samples, int samples_size)
+{
+ int size, len;
+
+ size = samples_size / sizeof(short);
+ while (size > 0) {
+ len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
+ if (len > size)
+ len = size;
+ memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
+ samples += len;
+ is->sample_array_index += len;
+ if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
+ is->sample_array_index = 0;
+ size -= len;
+ }
+}
+
+/* return the wanted number of samples to get better sync if sync_type is video
+ * or external master clock */
+static int synchronize_audio(VideoState *is, int nb_samples)
+{
+ int wanted_nb_samples = nb_samples;
+
+ /* if not master, then we try to remove or add samples to correct the clock */
+ if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
+ double diff, avg_diff;
+ int min_nb_samples, max_nb_samples;
+
+ diff = get_clock(&is->audclk) - get_master_clock(is);
+
+ if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
+ is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
+ if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
+ /* not enough measures to have a correct estimate */
+ is->audio_diff_avg_count++;
+ } else {
+ /* estimate the A-V difference */
+ avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
+
+ if (fabs(avg_diff) >= is->audio_diff_threshold) {
+ wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
+ min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
+ max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
+ wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
+ }
+ av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
+ diff, avg_diff, wanted_nb_samples - nb_samples,
+ is->audio_clock, is->audio_diff_threshold);
+ }
+ } else {
+ /* too big difference : may be initial PTS errors, so
+ reset A-V filter */
+ is->audio_diff_avg_count = 0;
+ is->audio_diff_cum = 0;
+ }
+ }
+
+ return wanted_nb_samples;
+}
+
+/**
+ * Decode one audio frame and return its uncompressed size.
+ *
+ * The processed audio frame is decoded, converted if required, and
+ * stored in is->audio_buf, with size in bytes given by the return
+ * value.
+ */
+static int audio_decode_frame(VideoState *is)
+{
+ int data_size, resampled_data_size;
+ int64_t dec_channel_layout;
+ av_unused double audio_clock0;
+ int wanted_nb_samples;
+ Frame *af;
+
+ if (is->paused)
+ return -1;
+
+ do {
+#if defined(_WIN32)
+ while (frame_queue_nb_remaining(&is->sampq) == 0) {
+ if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
+ return -1;
+ av_usleep (1000);
+ }
+#endif
+ if (!(af = frame_queue_peek_readable(&is->sampq)))
+ return -1;
+ frame_queue_next(&is->sampq);
+ } while (af->serial != is->audioq.serial);
+
+ data_size = av_samples_get_buffer_size(NULL, af->frame->channels,
+ af->frame->nb_samples,
+ af->frame->format, 1);
+
+ dec_channel_layout =
+ (af->frame->channel_layout && af->frame->channels == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
+ af->frame->channel_layout : av_get_default_channel_layout(af->frame->channels);
+ wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
+
+ if (af->frame->format != is->audio_src.fmt ||
+ dec_channel_layout != is->audio_src.channel_layout ||
+ af->frame->sample_rate != is->audio_src.freq ||
+ (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
+ swr_free(&is->swr_ctx);
+ is->swr_ctx = swr_alloc_set_opts(NULL,
+ is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
+ dec_channel_layout, af->frame->format, af->frame->sample_rate,
+ 0, NULL);
+ if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
+ af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->channels,
+ is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
+ swr_free(&is->swr_ctx);
+ return -1;
+ }
+ is->audio_src.channel_layout = dec_channel_layout;
+ is->audio_src.channels = af->frame->channels;
+ is->audio_src.freq = af->frame->sample_rate;
+ is->audio_src.fmt = af->frame->format;
+ }
+
+ if (is->swr_ctx) {
+ const uint8_t **in = (const uint8_t **)af->frame->extended_data;
+ uint8_t **out = &is->audio_buf1;
+ int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
+ int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
+ int len2;
+ if (out_size < 0) {
+ av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
+ return -1;
+ }
+ if (wanted_nb_samples != af->frame->nb_samples) {
+ if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
+ wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
+ av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
+ return -1;
+ }
+ }
+ av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
+ if (!is->audio_buf1)
+ return AVERROR(ENOMEM);
+ len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
+ if (len2 < 0) {
+ av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
+ return -1;
+ }
+ if (len2 == out_count) {
+ av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
+ if (swr_init(is->swr_ctx) < 0)
+ swr_free(&is->swr_ctx);
+ }
+ is->audio_buf = is->audio_buf1;
+ resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
+ } else {
+ is->audio_buf = af->frame->data[0];
+ resampled_data_size = data_size;
+ }
+
+ audio_clock0 = is->audio_clock;
+ /* update the audio clock with the pts */
+ if (!isnan(af->pts))
+ is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
+ else
+ is->audio_clock = NAN;
+ is->audio_clock_serial = af->serial;
+#ifdef DEBUG
+ {
+ static double last_clock;
+ printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
+ is->audio_clock - last_clock,
+ is->audio_clock, audio_clock0);
+ last_clock = is->audio_clock;
+ }
+#endif
+ return resampled_data_size;
+}
+
+/* prepare a new audio buffer */
+static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
+{
+ VideoState *is = opaque;
+ int audio_size, len1;
+
+ audio_callback_time = av_gettime_relative();
+
+ while (len > 0) {
+ if (is->audio_buf_index >= is->audio_buf_size) {
+ audio_size = audio_decode_frame(is);
+ if (audio_size < 0) {
+ /* if error, just output silence */
+ is->audio_buf = NULL;
+ is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
+ } else {
+ if (is->show_mode != SHOW_MODE_VIDEO)
+ update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
+ is->audio_buf_size = audio_size;
+ }
+ is->audio_buf_index = 0;
+ }
+ len1 = is->audio_buf_size - is->audio_buf_index;
+ if (len1 > len)
+ len1 = len;
+ if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
+ memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
+ else {
+ memset(stream, 0, len1);
+ if (!is->muted && is->audio_buf)
+ SDL_MixAudioFormat(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, AUDIO_S16SYS, len1, is->audio_volume);
+ }
+ len -= len1;
+ stream += len1;
+ is->audio_buf_index += len1;
+ }
+ is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
+ /* Let's assume the audio driver that is used by SDL has two periods. */
+ if (!isnan(is->audio_clock)) {
+ set_clock_at(&is->audclk, is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / is->audio_tgt.bytes_per_sec, is->audio_clock_serial, audio_callback_time / 1000000.0);
+ sync_clock_to_slave(&is->extclk, &is->audclk);
+ }
+}
+
+static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
+{
+ SDL_AudioSpec wanted_spec, spec;
+ const char *env;
+ static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
+ static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
+ int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
+
+ env = SDL_getenv("SDL_AUDIO_CHANNELS");
+ if (env) {
+ wanted_nb_channels = atoi(env);
+ wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
+ }
+ if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
+ wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
+ wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
+ }
+ wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
+ wanted_spec.channels = wanted_nb_channels;
+ wanted_spec.freq = wanted_sample_rate;
+ if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
+ av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
+ return -1;
+ }
+ while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
+ next_sample_rate_idx--;
+ wanted_spec.format = AUDIO_S16SYS;
+ wanted_spec.silence = 0;
+ wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
+ wanted_spec.callback = sdl_audio_callback;
+ wanted_spec.userdata = opaque;
+ while (!(audio_dev = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE))) {
+ av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
+ wanted_spec.channels, wanted_spec.freq, SDL_GetError());
+ wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
+ if (!wanted_spec.channels) {
+ wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
+ wanted_spec.channels = wanted_nb_channels;
+ if (!wanted_spec.freq) {
+ av_log(NULL, AV_LOG_ERROR,
+ "No more combinations to try, audio open failed\n");
+ return -1;
+ }
+ }
+ wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
+ }
+ if (spec.format != AUDIO_S16SYS) {
+ av_log(NULL, AV_LOG_ERROR,
+ "SDL advised audio format %d is not supported!\n", spec.format);
+ return -1;
+ }
+ if (spec.channels != wanted_spec.channels) {
+ wanted_channel_layout = av_get_default_channel_layout(spec.channels);
+ if (!wanted_channel_layout) {
+ av_log(NULL, AV_LOG_ERROR,
+ "SDL advised channel count %d is not supported!\n", spec.channels);
+ return -1;
+ }
+ }
+
+ audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
+ audio_hw_params->freq = spec.freq;
+ audio_hw_params->channel_layout = wanted_channel_layout;
+ audio_hw_params->channels = spec.channels;
+ audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
+ audio_hw_params->bytes_per_sec = av_samples_get_buffer_size(NULL, audio_hw_params->channels, audio_hw_params->freq, audio_hw_params->fmt, 1);
+ if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
+ av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
+ return -1;
+ }
+ return spec.size;
+}
+
+/* open a given stream. Return 0 if OK */
+static int stream_component_open(VideoState *is, int stream_index)
+{
+ AVFormatContext *ic = is->ic;
+ AVCodecContext *avctx;
+ AVCodec *codec;
+ const char *forced_codec_name = NULL;
+ AVDictionary *opts = NULL;
+ AVDictionaryEntry *t = NULL;
+ int sample_rate, nb_channels;
+ int64_t channel_layout;
+ int ret = 0;
+ int stream_lowres = lowres;
+
+ if (stream_index < 0 || stream_index >= ic->nb_streams)
+ return -1;
+
+ avctx = avcodec_alloc_context3(NULL);
+ if (!avctx)
+ return AVERROR(ENOMEM);
+
+ ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
+ if (ret < 0)
+ goto fail;
+ avctx->pkt_timebase = ic->streams[stream_index]->time_base;
+
+ codec = avcodec_find_decoder(avctx->codec_id);
+
+ switch(avctx->codec_type){
+ case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
+ case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
+ case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
+ }
+ if (forced_codec_name)
+ codec = avcodec_find_decoder_by_name(forced_codec_name);
+ if (!codec) {
+ if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
+ "No codec could be found with name '%s'\n", forced_codec_name);
+ else av_log(NULL, AV_LOG_WARNING,
+ "No decoder could be found for codec %s\n", avcodec_get_name(avctx->codec_id));
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ avctx->codec_id = codec->id;
+ if (stream_lowres > codec->max_lowres) {
+ av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
+ codec->max_lowres);
+ stream_lowres = codec->max_lowres;
+ }
+ avctx->lowres = stream_lowres;
+
+ if (fast)
+ avctx->flags2 |= AV_CODEC_FLAG2_FAST;
+
+ opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
+ if (!av_dict_get(opts, "threads", NULL, 0))
+ av_dict_set(&opts, "threads", "auto", 0);
+ if (stream_lowres)
+ av_dict_set_int(&opts, "lowres", stream_lowres, 0);
+ if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
+ av_dict_set(&opts, "refcounted_frames", "1", 0);
+ if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
+ goto fail;
+ }
+ if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
+ av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
+ ret = AVERROR_OPTION_NOT_FOUND;
+ goto fail;
+ }
+
+ is->eof = 0;
+ ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
+ switch (avctx->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+#if CONFIG_AVFILTER
+ {
+ AVFilterContext *sink;
+
+ is->audio_filter_src.freq = avctx->sample_rate;
+ is->audio_filter_src.channels = avctx->channels;
+ is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
+ is->audio_filter_src.fmt = avctx->sample_fmt;
+ if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
+ goto fail;
+ sink = is->out_audio_filter;
+ sample_rate = av_buffersink_get_sample_rate(sink);
+ nb_channels = av_buffersink_get_channels(sink);
+ channel_layout = av_buffersink_get_channel_layout(sink);
+ }
+#else
+ sample_rate = avctx->sample_rate;
+ nb_channels = avctx->channels;
+ channel_layout = avctx->channel_layout;
+#endif
+
+ /* prepare audio output */
+ if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
+ goto fail;
+ is->audio_hw_buf_size = ret;
+ is->audio_src = is->audio_tgt;
+ is->audio_buf_size = 0;
+ is->audio_buf_index = 0;
+
+ /* init averaging filter */
+ is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
+ is->audio_diff_avg_count = 0;
+ /* since we do not have a precise anough audio FIFO fullness,
+ we correct audio sync only if larger than this threshold */
+ is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
+
+ is->audio_stream = stream_index;
+ is->audio_st = ic->streams[stream_index];
+
+ decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
+ if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
+ is->auddec.start_pts = is->audio_st->start_time;
+ is->auddec.start_pts_tb = is->audio_st->time_base;
+ }
+ if ((ret = decoder_start(&is->auddec, audio_thread, "audio_decoder", is)) < 0)
+ goto out;
+ SDL_PauseAudioDevice(audio_dev, 0);
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ is->video_stream = stream_index;
+ is->video_st = ic->streams[stream_index];
+
+ decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
+ if ((ret = decoder_start(&is->viddec, video_thread, "video_decoder", is)) < 0)
+ goto out;
+ is->queue_attachments_req = 1;
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ is->subtitle_stream = stream_index;
+ is->subtitle_st = ic->streams[stream_index];
+
+ decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
+ if ((ret = decoder_start(&is->subdec, subtitle_thread, "subtitle_decoder", is)) < 0)
+ goto out;
+ break;
+ default:
+ break;
+ }
+ goto out;
+
+fail:
+ avcodec_free_context(&avctx);
+out:
+ av_dict_free(&opts);
+
+ return ret;
+}
+
+static int decode_interrupt_cb(void *ctx)
+{
+ VideoState *is = ctx;
+ return is->abort_request;
+}
+
+static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
+ return stream_id < 0 ||
+ queue->abort_request ||
+ (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
+ queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
+}
+
+static int is_realtime(AVFormatContext *s)
+{
+ if( !strcmp(s->iformat->name, "rtp")
+ || !strcmp(s->iformat->name, "rtsp")
+ || !strcmp(s->iformat->name, "sdp")
+ )
+ return 1;
+
+ if(s->pb && ( !strncmp(s->url, "rtp:", 4)
+ || !strncmp(s->url, "udp:", 4)
+ )
+ )
+ return 1;
+ return 0;
+}
+
+/* this thread gets the stream from the disk or the network */
+static int read_thread(void *arg)
+{
+ VideoState *is = arg;
+ AVFormatContext *ic = NULL;
+ int err, i, ret;
+ int st_index[AVMEDIA_TYPE_NB];
+ AVPacket pkt1, *pkt = &pkt1;
+ int64_t stream_start_time;
+ int pkt_in_play_range = 0;
+ AVDictionaryEntry *t;
+ SDL_mutex *wait_mutex = SDL_CreateMutex();
+ int scan_all_pmts_set = 0;
+ int64_t pkt_ts;
+
+ if (!wait_mutex) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ memset(st_index, -1, sizeof(st_index));
+ is->eof = 0;
+
+ ic = avformat_alloc_context();
+ if (!ic) {
+ av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ ic->interrupt_callback.callback = decode_interrupt_cb;
+ ic->interrupt_callback.opaque = is;
+ 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);
+ scan_all_pmts_set = 1;
+ }
+ err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
+ if (err < 0) {
+ print_error(is->filename, err);
+ ret = -1;
+ goto fail;
+ }
+ if (scan_all_pmts_set)
+ av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
+
+ if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
+ av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
+ ret = AVERROR_OPTION_NOT_FOUND;
+ goto fail;
+ }
+ is->ic = ic;
+
+ if (genpts)
+ ic->flags |= AVFMT_FLAG_GENPTS;
+
+ av_format_inject_global_side_data(ic);
+
+ if (find_stream_info) {
+ AVDictionary **opts = setup_find_stream_info_opts(ic, codec_opts);
+ int orig_nb_streams = ic->nb_streams;
+
+ err = avformat_find_stream_info(ic, opts);
+
+ for (i = 0; i < orig_nb_streams; i++)
+ av_dict_free(&opts[i]);
+ av_freep(&opts);
+
+ if (err < 0) {
+ av_log(NULL, AV_LOG_WARNING,
+ "%s: could not find codec parameters\n", is->filename);
+ ret = -1;
+ goto fail;
+ }
+ }
+
+ if (ic->pb)
+ ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
+
+ if (seek_by_bytes < 0)
+ seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
+
+ is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
+
+ if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
+ window_title = av_asprintf("%s - %s", t->value, input_filename);
+
+ /* if seeking requested, we execute it */
+ if (start_time != AV_NOPTS_VALUE) {
+ int64_t timestamp;
+
+ timestamp = start_time;
+ /* add the stream start time */
+ if (ic->start_time != AV_NOPTS_VALUE)
+ timestamp += ic->start_time;
+ ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
+ is->filename, (double)timestamp / AV_TIME_BASE);
+ }
+ }
+
+ is->realtime = is_realtime(ic);
+
+ if (show_status)
+ av_dump_format(ic, 0, is->filename, 0);
+
+ for (i = 0; i < ic->nb_streams; i++) {
+ AVStream *st = ic->streams[i];
+ enum AVMediaType type = st->codecpar->codec_type;
+ st->discard = AVDISCARD_ALL;
+ if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
+ if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
+ st_index[type] = i;
+ }
+ for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
+ if (wanted_stream_spec[i] && st_index[i] == -1) {
+ av_log(NULL, AV_LOG_ERROR, "Stream specifier %s does not match any %s stream\n", wanted_stream_spec[i], av_get_media_type_string(i));
+ st_index[i] = INT_MAX;
+ }
+ }
+
+ if (!video_disable)
+ st_index[AVMEDIA_TYPE_VIDEO] =
+ av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
+ st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
+ if (!audio_disable)
+ st_index[AVMEDIA_TYPE_AUDIO] =
+ av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
+ st_index[AVMEDIA_TYPE_AUDIO],
+ st_index[AVMEDIA_TYPE_VIDEO],
+ NULL, 0);
+ if (!video_disable && !subtitle_disable)
+ st_index[AVMEDIA_TYPE_SUBTITLE] =
+ av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
+ st_index[AVMEDIA_TYPE_SUBTITLE],
+ (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
+ st_index[AVMEDIA_TYPE_AUDIO] :
+ st_index[AVMEDIA_TYPE_VIDEO]),
+ NULL, 0);
+
+ is->show_mode = show_mode;
+ if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
+ AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
+ AVCodecParameters *codecpar = st->codecpar;
+ AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
+ if (codecpar->width)
+ set_default_window_size(codecpar->width, codecpar->height, sar);
+ }
+
+ /* open the streams */
+ if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
+ stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
+ }
+
+ ret = -1;
+ if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
+ ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
+ }
+ if (is->show_mode == SHOW_MODE_NONE)
+ is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
+
+ if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
+ stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
+ }
+
+ if (is->video_stream < 0 && is->audio_stream < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
+ is->filename);
+ ret = -1;
+ goto fail;
+ }
+
+ if (infinite_buffer < 0 && is->realtime)
+ infinite_buffer = 1;
+
+ for (;;) {
+ if (is->abort_request)
+ break;
+ if (is->paused != is->last_paused) {
+ is->last_paused = is->paused;
+ if (is->paused)
+ is->read_pause_return = av_read_pause(ic);
+ else
+ av_read_play(ic);
+ }
+#if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
+ if (is->paused &&
+ (!strcmp(ic->iformat->name, "rtsp") ||
+ (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
+ /* wait 10 ms to avoid trying to get another packet */
+ /* XXX: horrible */
+ SDL_Delay(10);
+ continue;
+ }
+#endif
+ if (is->seek_req) {
+ int64_t seek_target = is->seek_pos;
+ int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
+ int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
+// FIXME the +-2 is due to rounding being not done in the correct direction in generation
+// of the seek_pos/seek_rel variables
+
+ ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR,
+ "%s: error while seeking\n", is->ic->url);
+ } else {
+ if (is->audio_stream >= 0) {
+ packet_queue_flush(&is->audioq);
+ packet_queue_put(&is->audioq, &flush_pkt);
+ }
+ if (is->subtitle_stream >= 0) {
+ packet_queue_flush(&is->subtitleq);
+ packet_queue_put(&is->subtitleq, &flush_pkt);
+ }
+ if (is->video_stream >= 0) {
+ packet_queue_flush(&is->videoq);
+ packet_queue_put(&is->videoq, &flush_pkt);
+ }
+ if (is->seek_flags & AVSEEK_FLAG_BYTE) {
+ set_clock(&is->extclk, NAN, 0);
+ } else {
+ set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
+ }
+ }
+ is->seek_req = 0;
+ is->queue_attachments_req = 1;
+ is->eof = 0;
+ if (is->paused)
+ step_to_next_frame(is);
+ }
+ if (is->queue_attachments_req) {
+ if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
+ AVPacket copy;
+ if ((ret = av_packet_ref(&copy, &is->video_st->attached_pic)) < 0)
+ goto fail;
+ packet_queue_put(&is->videoq, &copy);
+ packet_queue_put_nullpacket(&is->videoq, is->video_stream);
+ }
+ is->queue_attachments_req = 0;
+ }
+
+ /* if the queue are full, no need to read more */
+ if (infinite_buffer<1 &&
+ (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
+ || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
+ stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
+ stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
+ /* wait 10 ms */
+ SDL_LockMutex(wait_mutex);
+ SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
+ SDL_UnlockMutex(wait_mutex);
+ continue;
+ }
+ if (!is->paused &&
+ (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
+ (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
+ if (loop != 1 && (!loop || --loop)) {
+ stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
+ } else if (autoexit) {
+ ret = AVERROR_EOF;
+ goto fail;
+ }
+ }
+ ret = av_read_frame(ic, pkt);
+ if (ret < 0) {
+ if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
+ if (is->video_stream >= 0)
+ packet_queue_put_nullpacket(&is->videoq, is->video_stream);
+ if (is->audio_stream >= 0)
+ packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
+ if (is->subtitle_stream >= 0)
+ packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
+ is->eof = 1;
+ }
+ if (ic->pb && ic->pb->error)
+ break;
+ SDL_LockMutex(wait_mutex);
+ SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
+ SDL_UnlockMutex(wait_mutex);
+ continue;
+ } else {
+ is->eof = 0;
+ }
+ /* check if packet is in play range specified by user, then queue, otherwise discard */
+ stream_start_time = ic->streams[pkt->stream_index]->start_time;
+ pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
+ pkt_in_play_range = duration == AV_NOPTS_VALUE ||
+ (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
+ av_q2d(ic->streams[pkt->stream_index]->time_base) -
+ (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
+ <= ((double)duration / 1000000);
+ if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
+ packet_queue_put(&is->audioq, pkt);
+ } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
+ && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
+ packet_queue_put(&is->videoq, pkt);
+ } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
+ packet_queue_put(&is->subtitleq, pkt);
+ } else {
+ av_packet_unref(pkt);
+ }
+ }
+
+ ret = 0;
+ fail:
+ if (ic && !is->ic)
+ avformat_close_input(&ic);
+
+ if (ret != 0) {
+ SDL_Event event;
+
+ event.type = FF_QUIT_EVENT;
+ event.user.data1 = is;
+ SDL_PushEvent(&event);
+ }
+ SDL_DestroyMutex(wait_mutex);
+ return 0;
+}
+
+static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
+{
+ VideoState *is;
+
+ is = av_mallocz(sizeof(VideoState));
+ if (!is)
+ return NULL;
+ is->last_video_stream = is->video_stream = -1;
+ is->last_audio_stream = is->audio_stream = -1;
+ is->last_subtitle_stream = is->subtitle_stream = -1;
+ is->filename = av_strdup(filename);
+ if (!is->filename)
+ goto fail;
+ is->iformat = iformat;
+ is->ytop = 0;
+ is->xleft = 0;
+
+ /* start video display */
+ if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
+ goto fail;
+ if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
+ goto fail;
+ if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
+ goto fail;
+
+ if (packet_queue_init(&is->videoq) < 0 ||
+ packet_queue_init(&is->audioq) < 0 ||
+ packet_queue_init(&is->subtitleq) < 0)
+ goto fail;
+
+ if (!(is->continue_read_thread = SDL_CreateCond())) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
+ goto fail;
+ }
+
+ init_clock(&is->vidclk, &is->videoq.serial);
+ init_clock(&is->audclk, &is->audioq.serial);
+ init_clock(&is->extclk, &is->extclk.serial);
+ is->audio_clock_serial = -1;
+ if (startup_volume < 0)
+ av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
+ if (startup_volume > 100)
+ av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
+ startup_volume = av_clip(startup_volume, 0, 100);
+ startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
+ is->audio_volume = startup_volume;
+ is->muted = 0;
+ is->av_sync_type = av_sync_type;
+ is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
+ if (!is->read_tid) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
+fail:
+ stream_close(is);
+ return NULL;
+ }
+ return is;
+}
+
+static void stream_cycle_channel(VideoState *is, int codec_type)
+{
+ AVFormatContext *ic = is->ic;
+ int start_index, stream_index;
+ int old_index;
+ AVStream *st;
+ AVProgram *p = NULL;
+ int nb_streams = is->ic->nb_streams;
+
+ if (codec_type == AVMEDIA_TYPE_VIDEO) {
+ start_index = is->last_video_stream;
+ old_index = is->video_stream;
+ } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
+ start_index = is->last_audio_stream;
+ old_index = is->audio_stream;
+ } else {
+ start_index = is->last_subtitle_stream;
+ old_index = is->subtitle_stream;
+ }
+ stream_index = start_index;
+
+ if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
+ p = av_find_program_from_stream(ic, NULL, is->video_stream);
+ if (p) {
+ nb_streams = p->nb_stream_indexes;
+ for (start_index = 0; start_index < nb_streams; start_index++)
+ if (p->stream_index[start_index] == stream_index)
+ break;
+ if (start_index == nb_streams)
+ start_index = -1;
+ stream_index = start_index;
+ }
+ }
+
+ for (;;) {
+ if (++stream_index >= nb_streams)
+ {
+ if (codec_type == AVMEDIA_TYPE_SUBTITLE)
+ {
+ stream_index = -1;
+ is->last_subtitle_stream = -1;
+ goto the_end;
+ }
+ if (start_index == -1)
+ return;
+ stream_index = 0;
+ }
+ if (stream_index == start_index)
+ return;
+ st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
+ if (st->codecpar->codec_type == codec_type) {
+ /* check that parameters are OK */
+ switch (codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ if (st->codecpar->sample_rate != 0 &&
+ st->codecpar->channels != 0)
+ goto the_end;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ case AVMEDIA_TYPE_SUBTITLE:
+ goto the_end;
+ default:
+ break;
+ }
+ }
+ }
+ the_end:
+ if (p && stream_index != -1)
+ stream_index = p->stream_index[stream_index];
+ av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
+ av_get_media_type_string(codec_type),
+ old_index,
+ stream_index);
+
+ stream_component_close(is, old_index);
+ stream_component_open(is, stream_index);
+}
+
+
+static void toggle_full_screen(VideoState *is)
+{
+ is_full_screen = !is_full_screen;
+ SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
+}
+
+static void toggle_audio_display(VideoState *is)
+{
+ int next = is->show_mode;
+ do {
+ next = (next + 1) % SHOW_MODE_NB;
+ } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
+ if (is->show_mode != next) {
+ is->force_refresh = 1;
+ is->show_mode = next;
+ }
+}
+
+static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
+ double remaining_time = 0.0;
+ SDL_PumpEvents();
+ while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
+ if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
+ SDL_ShowCursor(0);
+ cursor_hidden = 1;
+ }
+ if (remaining_time > 0.0)
+ av_usleep((int64_t)(remaining_time * 1000000.0));
+ remaining_time = REFRESH_RATE;
+ if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
+ video_refresh(is, &remaining_time);
+ SDL_PumpEvents();
+ }
+}
+
+static void seek_chapter(VideoState *is, int incr)
+{
+ int64_t pos = get_master_clock(is) * AV_TIME_BASE;
+ int i;
+
+ if (!is->ic->nb_chapters)
+ return;
+
+ /* find the current chapter */
+ for (i = 0; i < is->ic->nb_chapters; i++) {
+ AVChapter *ch = is->ic->chapters[i];
+ if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
+ i--;
+ break;
+ }
+ }
+
+ i += incr;
+ i = FFMAX(i, 0);
+ if (i >= is->ic->nb_chapters)
+ return;
+
+ av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
+ stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
+ AV_TIME_BASE_Q), 0, 0);
+}
+
+/* handle an event sent by the GUI */
+static void event_loop(VideoState *cur_stream)
+{
+ SDL_Event event;
+ double incr, pos, frac;
+
+ for (;;) {
+ double x;
+ refresh_loop_wait_event(cur_stream, &event);
+ switch (event.type) {
+ case SDL_KEYDOWN:
+ if (exit_on_keydown || event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q) {
+ do_exit(cur_stream);
+ break;
+ }
+ // If we don't yet have a window, skip all key events, because read_thread might still be initializing...
+ if (!cur_stream->width)
+ continue;
+ switch (event.key.keysym.sym) {
+ case SDLK_f:
+ toggle_full_screen(cur_stream);
+ cur_stream->force_refresh = 1;
+ break;
+ case SDLK_p:
+ case SDLK_SPACE:
+ toggle_pause(cur_stream);
+ break;
+ case SDLK_m:
+ toggle_mute(cur_stream);
+ break;
+ case SDLK_KP_MULTIPLY:
+ case SDLK_0:
+ update_volume(cur_stream, 1, SDL_VOLUME_STEP);
+ break;
+ case SDLK_KP_DIVIDE:
+ case SDLK_9:
+ update_volume(cur_stream, -1, SDL_VOLUME_STEP);
+ break;
+ case SDLK_s: // S: Step to next frame
+ step_to_next_frame(cur_stream);
+ break;
+ case SDLK_a:
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
+ break;
+ case SDLK_v:
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
+ break;
+ case SDLK_c:
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
+ break;
+ case SDLK_t:
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
+ break;
+ case SDLK_w:
+#if CONFIG_AVFILTER
+ if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
+ if (++cur_stream->vfilter_idx >= nb_vfilters)
+ cur_stream->vfilter_idx = 0;
+ } else {
+ cur_stream->vfilter_idx = 0;
+ toggle_audio_display(cur_stream);
+ }
+#else
+ toggle_audio_display(cur_stream);
+#endif
+ break;
+ case SDLK_PAGEUP:
+ if (cur_stream->ic->nb_chapters <= 1) {
+ incr = 600.0;
+ goto do_seek;
+ }
+ seek_chapter(cur_stream, 1);
+ break;
+ case SDLK_PAGEDOWN:
+ if (cur_stream->ic->nb_chapters <= 1) {
+ incr = -600.0;
+ goto do_seek;
+ }
+ seek_chapter(cur_stream, -1);
+ break;
+ case SDLK_LEFT:
+ incr = seek_interval ? -seek_interval : -10.0;
+ goto do_seek;
+ case SDLK_RIGHT:
+ incr = seek_interval ? seek_interval : 10.0;
+ goto do_seek;
+ case SDLK_UP:
+ incr = 60.0;
+ goto do_seek;
+ case SDLK_DOWN:
+ incr = -60.0;
+ do_seek:
+ if (seek_by_bytes) {
+ pos = -1;
+ if (pos < 0 && cur_stream->video_stream >= 0)
+ pos = frame_queue_last_pos(&cur_stream->pictq);
+ if (pos < 0 && cur_stream->audio_stream >= 0)
+ pos = frame_queue_last_pos(&cur_stream->sampq);
+ if (pos < 0)
+ pos = avio_tell(cur_stream->ic->pb);
+ if (cur_stream->ic->bit_rate)
+ incr *= cur_stream->ic->bit_rate / 8.0;
+ else
+ incr *= 180000.0;
+ pos += incr;
+ stream_seek(cur_stream, pos, incr, 1);
+ } else {
+ pos = get_master_clock(cur_stream);
+ if (isnan(pos))
+ pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
+ pos += incr;
+ if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
+ pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
+ stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ if (exit_on_mousedown) {
+ do_exit(cur_stream);
+ break;
+ }
+ if (event.button.button == SDL_BUTTON_LEFT) {
+ static int64_t last_mouse_left_click = 0;
+ if (av_gettime_relative() - last_mouse_left_click <= 500000) {
+ toggle_full_screen(cur_stream);
+ cur_stream->force_refresh = 1;
+ last_mouse_left_click = 0;
+ } else {
+ last_mouse_left_click = av_gettime_relative();
+ }
+ }
+ case SDL_MOUSEMOTION:
+ if (cursor_hidden) {
+ SDL_ShowCursor(1);
+ cursor_hidden = 0;
+ }
+ cursor_last_shown = av_gettime_relative();
+ if (event.type == SDL_MOUSEBUTTONDOWN) {
+ if (event.button.button != SDL_BUTTON_RIGHT)
+ break;
+ x = event.button.x;
+ } else {
+ if (!(event.motion.state & SDL_BUTTON_RMASK))
+ break;
+ x = event.motion.x;
+ }
+ if (seek_by_bytes || cur_stream->ic->duration <= 0) {
+ uint64_t size = avio_size(cur_stream->ic->pb);
+ stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
+ } else {
+ int64_t ts;
+ int ns, hh, mm, ss;
+ int tns, thh, tmm, tss;
+ tns = cur_stream->ic->duration / 1000000LL;
+ thh = tns / 3600;
+ tmm = (tns % 3600) / 60;
+ tss = (tns % 60);
+ frac = x / cur_stream->width;
+ ns = frac * tns;
+ hh = ns / 3600;
+ mm = (ns % 3600) / 60;
+ ss = (ns % 60);
+ av_log(NULL, AV_LOG_INFO,
+ "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
+ hh, mm, ss, thh, tmm, tss);
+ ts = frac * cur_stream->ic->duration;
+ if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
+ ts += cur_stream->ic->start_time;
+ stream_seek(cur_stream, ts, 0, 0);
+ }
+ break;
+ case SDL_WINDOWEVENT:
+ switch (event.window.event) {
+ case SDL_WINDOWEVENT_SIZE_CHANGED:
+ screen_width = cur_stream->width = event.window.data1;
+ screen_height = cur_stream->height = event.window.data2;
+ if (cur_stream->vis_texture) {
+ SDL_DestroyTexture(cur_stream->vis_texture);
+ cur_stream->vis_texture = NULL;
+ }
+ case SDL_WINDOWEVENT_EXPOSED:
+ cur_stream->force_refresh = 1;
+ }
+ break;
+ case SDL_QUIT:
+ case FF_QUIT_EVENT:
+ do_exit(cur_stream);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static int opt_frame_size(void *optctx, const char *opt, const char *arg)
+{
+ av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
+ return opt_default(NULL, "video_size", arg);
+}
+
+static int opt_width(void *optctx, const char *opt, const char *arg)
+{
+ screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
+ return 0;
+}
+
+static int opt_height(void *optctx, const char *opt, const char *arg)
+{
+ screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
+ return 0;
+}
+
+static int opt_format(void *optctx, const char *opt, const char *arg)
+{
+ file_iformat = av_find_input_format(arg);
+ if (!file_iformat) {
+ av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
+ return AVERROR(EINVAL);
+ }
+ return 0;
+}
+
+static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
+{
+ av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
+ return opt_default(NULL, "pixel_format", arg);
+}
+
+static int opt_sync(void *optctx, const char *opt, const char *arg)
+{
+ if (!strcmp(arg, "audio"))
+ av_sync_type = AV_SYNC_AUDIO_MASTER;
+ else if (!strcmp(arg, "video"))
+ av_sync_type = AV_SYNC_VIDEO_MASTER;
+ else if (!strcmp(arg, "ext"))
+ av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
+ else {
+ av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
+ exit(1);
+ }
+ return 0;
+}
+
+static int opt_seek(void *optctx, const char *opt, const char *arg)
+{
+ start_time = parse_time_or_die(opt, arg, 1);
+ return 0;
+}
+
+static int opt_duration(void *optctx, const char *opt, const char *arg)
+{
+ duration = parse_time_or_die(opt, arg, 1);
+ return 0;
+}
+
+static int opt_show_mode(void *optctx, const char *opt, const char *arg)
+{
+ show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
+ !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
+ !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
+ parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
+ return 0;
+}
+
+static void opt_input_file(void *optctx, const char *filename)
+{
+ if (input_filename) {
+ av_log(NULL, AV_LOG_FATAL,
+ "Argument '%s' provided as input filename, but '%s' was already specified.\n",
+ filename, input_filename);
+ exit(1);
+ }
+ if (!strcmp(filename, "-"))
+ filename = "pipe:";
+ input_filename = filename;
+}
+
+static int opt_codec(void *optctx, const char *opt, const char *arg)
+{
+ const char *spec = strchr(opt, ':');
+ if (!spec) {
+ av_log(NULL, AV_LOG_ERROR,
+ "No media specifier was specified in '%s' in option '%s'\n",
+ arg, opt);
+ return AVERROR(EINVAL);
+ }
+ spec++;
+ switch (spec[0]) {
+ case 'a' : audio_codec_name = arg; break;
+ case 's' : subtitle_codec_name = arg; break;
+ case 'v' : video_codec_name = arg; break;
+ default:
+ av_log(NULL, AV_LOG_ERROR,
+ "Invalid media specifier '%s' in option '%s'\n", spec, opt);
+ return AVERROR(EINVAL);
+ }
+ return 0;
+}
+
+static int dummy;
+
+static const OptionDef options[] = {
+ CMDUTILS_COMMON_OPTIONS
+ { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
+ { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
+ { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
+ { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
+ { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
+ { "vn", OPT_BOOL, { &video_disable }, "disable video" },
+ { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
+ { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
+ { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
+ { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
+ { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
+ { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
+ { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
+ { "seek_interval", OPT_FLOAT | HAS_ARG, { &seek_interval }, "set seek interval for left/right keys, in seconds", "seconds" },
+ { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
+ { "noborder", OPT_BOOL, { &borderless }, "borderless window" },
+ { "alwaysontop", OPT_BOOL, { &alwaysontop }, "window always on top" },
+ { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
+ { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
+ { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
+ { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
+ { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
+ { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
+ { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
+ { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
+ { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
+ { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
+ { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
+ { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
+ { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
+ { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
+ { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
+ { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
+ { "left", OPT_INT | HAS_ARG | OPT_EXPERT, { &screen_left }, "set the x position for the left of the window", "x pos" },
+ { "top", OPT_INT | HAS_ARG | OPT_EXPERT, { &screen_top }, "set the y position for the top of the window", "y pos" },
+#if CONFIG_AVFILTER
+ { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
+ { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
+#endif
+ { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
+ { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
+ { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
+ { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
+ { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
+ { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
+ { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
+ { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
+ { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
+ { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
+ "read and decode the streams to fill missing information with heuristics" },
+ { "filter_threads", HAS_ARG | OPT_INT | OPT_EXPERT, { &filter_nbthreads }, "number of filter threads per graph" },
+ { NULL, },
+};
+
+static void show_usage(void)
+{
+ av_log(NULL, AV_LOG_INFO, "Simple media player\n");
+ av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
+ av_log(NULL, AV_LOG_INFO, "\n");
+}
+
+void show_help_default(const char *opt, const char *arg)
+{
+ av_log_set_callback(log_callback_help);
+ show_usage();
+ show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
+ show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
+ printf("\n");
+ show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
+ show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
+#if !CONFIG_AVFILTER
+ show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
+#else
+ show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
+#endif
+ printf("\nWhile playing:\n"
+ "q, ESC quit\n"
+ "f toggle full screen\n"
+ "p, SPC pause\n"
+ "m toggle mute\n"
+ "9, 0 decrease and increase volume respectively\n"
+ "/, * decrease and increase volume respectively\n"
+ "a cycle audio channel in the current program\n"
+ "v cycle video channel\n"
+ "t cycle subtitle channel in the current program\n"
+ "c cycle program\n"
+ "w cycle video filters or show modes\n"
+ "s activate frame-step mode\n"
+ "left/right seek backward/forward 10 seconds or to custom interval if -seek_interval is set\n"
+ "down/up seek backward/forward 1 minute\n"
+ "page down/page up seek backward/forward 10 minutes\n"
+ "right mouse click seek to percentage in file corresponding to fraction of width\n"
+ "left double-click toggle full screen\n"
+ );
+}
+
+/* Called from the main */
+int main(int argc, char **argv)
+{
+ int flags;
+ VideoState *is;
+
+ init_dynload();
+
+ av_log_set_flags(AV_LOG_SKIP_REPEATED);
+ parse_loglevel(argc, argv, options);
+
+ /* register all codecs, demux and protocols */
+#if CONFIG_AVDEVICE
+ avdevice_register_all();
+#endif
+ avformat_network_init();
+
+ init_opts();
+
+ signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
+ signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
+
+ show_banner(argc, argv, options);
+
+ parse_options(NULL, argc, argv, options, opt_input_file);
+
+ if (!input_filename) {
+ show_usage();
+ av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
+ av_log(NULL, AV_LOG_FATAL,
+ "Use -h to get full help or, even better, run 'man %s'\n", program_name);
+ exit(1);
+ }
+
+ if (display_disable) {
+ video_disable = 1;
+ }
+ flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
+ if (audio_disable)
+ flags &= ~SDL_INIT_AUDIO;
+ else {
+ /* Try to work around an occasional ALSA buffer underflow issue when the
+ * period size is NPOT due to ALSA resampling by forcing the buffer size. */
+ if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
+ SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
+ }
+ if (display_disable)
+ flags &= ~SDL_INIT_VIDEO;
+ if (SDL_Init (flags)) {
+ av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
+ av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
+ exit(1);
+ }
+
+ SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
+ SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
+
+ av_init_packet(&flush_pkt);
+ flush_pkt.data = (uint8_t *)&flush_pkt;
+
+ if (!display_disable) {
+ int flags = SDL_WINDOW_HIDDEN;
+ if (alwaysontop)
+#if SDL_VERSION_ATLEAST(2,0,5)
+ flags |= SDL_WINDOW_ALWAYS_ON_TOP;
+#else
+ av_log(NULL, AV_LOG_WARNING, "Your SDL version doesn't support SDL_WINDOW_ALWAYS_ON_TOP. Feature will be inactive.\n");
+#endif
+ if (borderless)
+ flags |= SDL_WINDOW_BORDERLESS;
+ else
+ flags |= SDL_WINDOW_RESIZABLE;
+ window = SDL_CreateWindow(program_name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, default_width, default_height, flags);
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
+ if (window) {
+ renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+ if (!renderer) {
+ av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
+ renderer = SDL_CreateRenderer(window, -1, 0);
+ }
+ if (renderer) {
+ if (!SDL_GetRendererInfo(renderer, &renderer_info))
+ av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", renderer_info.name);
+ }
+ }
+ if (!window || !renderer || !renderer_info.num_texture_formats) {
+ av_log(NULL, AV_LOG_FATAL, "Failed to create window or renderer: %s", SDL_GetError());
+ do_exit(NULL);
+ }
+ }
+
+ is = stream_open(input_filename, file_iformat);
+ if (!is) {
+ av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");
+ do_exit(NULL);
+ }
+
+ event_loop(is);
+
+ /* never returns */
+
+ return 0;
+}
diff -Naur ffmpeg-4.3.2-Matrix-19.1/libavcodec/allcodecs.c ffmpeg-4.3.2-Matrix-19.1-2/libavcodec/allcodecs.c
--- ffmpeg-4.3.2-Matrix-19.1/libavcodec/allcodecs.c 2022-03-07 22:55:03.188320745 +0100
+++ ffmpeg-4.3.2-Matrix-19.1-2/libavcodec/allcodecs.c 2022-03-20 03:19:12.727688297 +0100
@@ -137,6 +137,8 @@
extern AVCodec ff_h263p_encoder;
extern AVCodec ff_h263p_decoder;
extern AVCodec ff_h263_v4l2m2m_decoder;
+extern AVCodec ff_h264_nvv4l2_encoder;
+extern AVCodec ff_h264_nvv4l2_decoder;
extern AVCodec ff_h264_decoder;
extern AVCodec ff_h264_crystalhd_decoder;
extern AVCodec ff_h264_v4l2m2m_decoder;
@@ -146,6 +148,8 @@
extern AVCodec ff_h264_rkmpp_decoder;
extern AVCodec ff_hap_encoder;
extern AVCodec ff_hap_decoder;
+extern AVCodec ff_hevc_nvv4l2_encoder;
+extern AVCodec ff_hevc_nvv4l2_decoder;
extern AVCodec ff_hevc_decoder;
extern AVCodec ff_hevc_qsv_decoder;
extern AVCodec ff_hevc_rkmpp_decoder;
@@ -188,8 +192,10 @@
extern AVCodec ff_motionpixels_decoder;
extern AVCodec ff_mpeg1video_encoder;
extern AVCodec ff_mpeg1video_decoder;
+extern AVCodec ff_mpeg2_nvv4l2_decoder;
extern AVCodec ff_mpeg2video_encoder;
extern AVCodec ff_mpeg2video_decoder;
+extern AVCodec ff_mpeg4_nvv4l2_decoder;
extern AVCodec ff_mpeg4_encoder;
extern AVCodec ff_mpeg4_decoder;
extern AVCodec ff_mpeg4_crystalhd_decoder;
@@ -342,9 +348,11 @@
extern AVCodec ff_vp6a_decoder;
extern AVCodec ff_vp6f_decoder;
extern AVCodec ff_vp7_decoder;
+extern AVCodec ff_vp8_nvv4l2_decoder;
extern AVCodec ff_vp8_decoder;
extern AVCodec ff_vp8_rkmpp_decoder;
extern AVCodec ff_vp8_v4l2m2m_decoder;
+extern AVCodec ff_vp9_nvv4l2_decoder;
extern AVCodec ff_vp9_decoder;
extern AVCodec ff_vp9_rkmpp_decoder;
extern AVCodec ff_vp9_v4l2m2m_decoder;
diff -Naur ffmpeg-4.3.2-Matrix-19.1/libavcodec/Makefile ffmpeg-4.3.2-Matrix-19.1-2/libavcodec/Makefile
--- ffmpeg-4.3.2-Matrix-19.1/libavcodec/Makefile 2022-03-07 22:55:03.356324406 +0100
+++ ffmpeg-4.3.2-Matrix-19.1-2/libavcodec/Makefile 2022-03-20 03:19:12.727688297 +0100
@@ -131,6 +131,7 @@
mpegvideoencdsp.o
OBJS-$(CONFIG_MSS34DSP) += mss34dsp.o
OBJS-$(CONFIG_NVENC) += nvenc.o
+OBJS-$(CONFIG_NVV4L2) += nvv4l2.o
OBJS-$(CONFIG_PIXBLOCKDSP) += pixblockdsp.o
OBJS-$(CONFIG_QPELDSP) += qpeldsp.o
OBJS-$(CONFIG_QSV) += qsv.o
@@ -361,12 +362,14 @@
h264_slice.o h264data.o
OBJS-$(CONFIG_H264_AMF_ENCODER) += amfenc_h264.o
OBJS-$(CONFIG_H264_CUVID_DECODER) += cuviddec.o
+OBJS-$(CONFIG_H264_NVV4L2_DECODER) += nvv4l2_dec.o
OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec.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
OBJS-$(CONFIG_NVENC_ENCODER) += nvenc_h264.o
OBJS-$(CONFIG_NVENC_H264_ENCODER) += nvenc_h264.o
+OBJS-$(CONFIG_H264_NVV4L2_ENCODER) += nvv4l2_enc.o
OBJS-$(CONFIG_H264_OMX_ENCODER) += omx.o
OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec_h2645.o
OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o
@@ -384,6 +387,7 @@
hevcdsp.o hevc_filter.o hevc_data.o
OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o
OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o
+OBJS-$(CONFIG_HEVC_NVV4L2_DECODER) += nvv4l2_dec.o
OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o
OBJS-$(CONFIG_HEVC_MF_ENCODER) += mfenc.o mf_utils.o
OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o
@@ -394,6 +398,7 @@
OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o
OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level.o
OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o
+OBJS-$(CONFIG_HEVC_NVV4L2_ENCODER) += nvv4l2_enc.o
OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o
OBJS-$(CONFIG_HQ_HQA_DECODER) += hq_hqa.o hq_hqadata.o hq_hqadsp.o \
@@ -482,11 +487,13 @@
OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o
OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o
OBJS-$(CONFIG_MPEG2_CUVID_DECODER) += cuviddec.o
+OBJS-$(CONFIG_MPEG2_NVV4L2_DECODER) += nvv4l2_dec.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_CUVID_DECODER) += cuviddec.o
+OBJS-$(CONFIG_MPEG4_NVV4L2_DECODER) += nvv4l2_dec.o
OBJS-$(CONFIG_MPEG4_MEDIACODEC_DECODER) += mediacodecdec.o
OBJS-$(CONFIG_MPEG4_OMX_ENCODER) += omx.o
OBJS-$(CONFIG_MPEG4_V4L2M2M_DECODER) += v4l2_m2m_dec.o
@@ -693,6 +700,7 @@
OBJS-$(CONFIG_VP7_DECODER) += vp8.o vp56rac.o
OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp56rac.o
OBJS-$(CONFIG_VP8_CUVID_DECODER) += cuviddec.o
+OBJS-$(CONFIG_VP8_NVV4L2_DECODER) += nvv4l2_dec.o
OBJS-$(CONFIG_VP8_MEDIACODEC_DECODER) += mediacodecdec.o
OBJS-$(CONFIG_VP8_QSV_DECODER) += qsvdec_other.o
OBJS-$(CONFIG_VP8_RKMPP_DECODER) += rkmppdec.o
@@ -703,6 +711,7 @@
vp9block.o vp9prob.o vp9mvs.o vp56rac.o \
vp9dsp_8bpp.o vp9dsp_10bpp.o vp9dsp_12bpp.o
OBJS-$(CONFIG_VP9_CUVID_DECODER) += cuviddec.o
+OBJS-$(CONFIG_VP9_NVV4L2_DECODER) += nvv4l2_dec.o
OBJS-$(CONFIG_VP9_MEDIACODEC_DECODER) += mediacodecdec.o
OBJS-$(CONFIG_VP9_RKMPP_DECODER) += rkmppdec.o
OBJS-$(CONFIG_VP9_VAAPI_ENCODER) += vaapi_encode_vp9.o
diff -Naur ffmpeg-4.3.2-Matrix-19.1/libavcodec/nvv4l2.c ffmpeg-4.3.2-Matrix-19.1-2/libavcodec/nvv4l2.c
--- ffmpeg-4.3.2-Matrix-19.1/libavcodec/nvv4l2.c 1970-01-01 01:00:00.000000000 +0100
+++ ffmpeg-4.3.2-Matrix-19.1-2/libavcodec/nvv4l2.c 2022-03-20 03:24:58.293242052 +0100
@@ -0,0 +1,866 @@
+/*
+ * Copyright (c) 2021-2022, CTCaer <ctcaer@gmail.com>
+ *
+ * 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.
+ */
+
+#include <stdatomic.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include "internal.h"
+#include "libavutil/log.h"
+
+#include "nvv4l2.h"
+
+uint32_t nvv4l2_map_nvcodec_type(NvCodingType nv_codec_type)
+{
+ uint32_t v4l2_pix_fmt;
+ switch (nv_codec_type) {
+ case NvVideoCodec_H264:
+ v4l2_pix_fmt = V4L2_PIX_FMT_H264;
+ break;
+ case NvVideoCodec_HEVC:
+ v4l2_pix_fmt = V4L2_PIX_FMT_H265;
+ break;
+ case NvVideoCodec_MPEG2:
+ v4l2_pix_fmt = V4L2_PIX_FMT_MPEG2;
+ break;
+ case NvVideoCodec_MPEG4:
+ v4l2_pix_fmt = V4L2_PIX_FMT_MPEG4;
+ break;
+ case NvVideoCodec_VP8:
+ v4l2_pix_fmt = V4L2_PIX_FMT_VP8;
+ break;
+ case NvVideoCodec_VP9:
+ v4l2_pix_fmt = V4L2_PIX_FMT_VP9;
+ break;
+ default:
+ v4l2_pix_fmt = V4L2_PIX_FMT_H264;
+ break;
+ }
+
+ return v4l2_pix_fmt;
+}
+
+int nvv4l2_pool_idx_next(nvv4l2_ctx_t *ctx, NvQueues *q)
+{
+ int index;
+ if (q->capacity < NV_MAX_BUFFERS) {
+ index = q->back;
+ } else {
+ index = -1;
+ }
+ return index;
+}
+
+void nvv4l2_pool_push(nvv4l2_ctx_t *ctx, NvQueues *q)
+{
+ if (q->capacity < NV_MAX_BUFFERS) {
+ q->back = (q->back + 1) % NV_MAX_BUFFERS;
+ atomic_fetch_add(&q->capacity, 1);
+ } else {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Queue already full!\n");
+ }
+}
+
+int nvv4l2_pool_pop(nvv4l2_ctx_t *ctx, NvQueues *q)
+{
+ int index = q->front;
+ if (q->capacity != 0) {
+ q->front = (q->front + 1) % NV_MAX_BUFFERS;
+ atomic_fetch_sub(&q->capacity, 1);
+ } else {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Queue already empty!");
+ }
+ return index;
+}
+
+int
+nvv4l2_create_bufferfmt(NvBuffer *buffer, enum v4l2_buf_type buf_type,
+ enum v4l2_memory memory_type, uint32_t n_planes,
+ NvBufferPlaneFormat *fmt, uint32_t index)
+{
+ buffer->mapped = false;
+ buffer->buf_type = buf_type;
+ buffer->memory_type = memory_type;
+ buffer->index = index;
+ buffer->n_planes = n_planes;
+
+ memset(buffer->planes, 0, sizeof(NvBufferPlane));
+ for (uint32_t i = 0; i < buffer->n_planes; i++) {
+ buffer->planes[i].fd = -1;
+ buffer->planes[i].fmt = fmt[i];
+ }
+ return 0;
+}
+
+int
+nvv4l2_map_out(nvv4l2_ctx_t *ctx, struct v4l2_buffer *v4l2_buf,
+ enum v4l2_buf_type buf_type, enum v4l2_memory mem_type,
+ int dma_fd)
+{
+ int ret;
+ NvBuffer *buffer;
+ NvBufferParams params;
+ unsigned char *data;
+ pthread_mutex_lock(&ctx->queue_lock);
+
+ if (buf_type == ctx->op_buf_type)
+ buffer = ctx->op_buffers[v4l2_buf->index];
+ else if (buf_type == ctx->cp_buf_type)
+ buffer = ctx->cp_buffers[v4l2_buf->index];
+
+ switch (mem_type) {
+ case V4L2_MEMORY_DMABUF:
+ ret = NvBufferGetParams(dma_fd, &params);
+ if(ret) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "GetParams failed!\n");
+ pthread_mutex_unlock(&ctx->queue_lock);
+ return ret;
+ }
+ for (uint32_t i = 0; i < buffer->n_planes; i++) {
+ buffer->planes[i].fd = dma_fd;
+ v4l2_buf->m.planes[i].m.fd = dma_fd;
+ buffer->planes[i].mem_offset = params.offset[i];
+ ret = NvBufferMemMap(dma_fd, i, NvBufferMem_Read_Write,
+ (void **)&data);
+ if (ret) {
+ ctx->in_error = true;
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Error while Mapping buffer!\n");
+ pthread_mutex_unlock(&ctx->queue_lock);
+ return ret;
+ }
+ buffer->planes[i].data = data;
+ }
+ break;
+ default:
+ pthread_mutex_unlock(&ctx->queue_lock);
+ return -1;
+ }
+ pthread_mutex_unlock(&ctx->queue_lock);
+
+ return ret;
+}
+
+int
+nvv4l2_unmap_out(nvv4l2_ctx_t *ctx, int index, enum v4l2_buf_type buf_type,
+ enum v4l2_memory mem_type, int dma_fd)
+{
+ int ret = 0;
+ NvBuffer *buffer;
+ pthread_mutex_lock(&ctx->queue_lock);
+
+ if (buf_type == ctx->op_buf_type)
+ buffer = ctx->op_buffers[index];
+ else if (buf_type == ctx->cp_buf_type)
+ buffer = ctx->cp_buffers[index];
+
+ switch (mem_type) {
+ case V4L2_MEMORY_DMABUF:
+ for (uint32_t i = 0; i < buffer->n_planes; i++) {
+ ret = NvBufferMemUnMap(dma_fd, i, (void **)&buffer->planes[i].data);
+ if (ret) {
+ ctx->in_error = true;
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Error while Unmapping buffer!\n");
+ pthread_mutex_unlock(&ctx->queue_lock);
+ return ret;
+ }
+ }
+ break;
+ default:
+ pthread_mutex_unlock(&ctx->queue_lock);
+ return -1;
+ }
+ pthread_mutex_unlock(&ctx->queue_lock);
+
+ return ret;
+}
+
+int nvv4l2_allocate_memory(nvv4l2_ctx_t *ctx, NvBuffer *buffer)
+{
+ for (uint32_t i = 0; i < buffer->n_planes; i++) {
+ buffer->planes[i].length = NVMAX(buffer->planes[i].fmt.sizeimage,
+ buffer->planes[i].fmt.width *
+ buffer->planes[i].fmt.bytesperpixel *
+ buffer->planes[i].fmt.height);
+ buffer->planes[i].data =
+ (unsigned char *)NVMALLOC(sizeof(unsigned char) *
+ buffer->planes[i].length);
+ if (buffer->planes[i].data == NULL) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Could not allocate buffer %d plane %d!\n",
+ buffer->index, i);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int nvv4l2_map(nvv4l2_ctx_t *ctx, NvBuffer *buffer)
+{
+ if (buffer->memory_type != V4L2_MEMORY_MMAP) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Buffer type %d can't be mapped!\n", buffer->memory_type);
+ return -1;
+ }
+
+ if (buffer->mapped) {
+ av_log(ctx->avctx, AV_LOG_VERBOSE, "Buffer %d already mapped!\n",
+ buffer->index);
+ return 0;
+ }
+
+ for (uint32_t i = 0; i < buffer->n_planes; i++) {
+ if (buffer->planes[i].fd == -1) {
+ return -1;
+ }
+
+ buffer->planes[i].data =
+ (unsigned char *)mmap(NULL, buffer-> planes[i].length,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ buffer->planes[i].fd,
+ buffer->planes
+ [i].mem_offset);
+ if (buffer->planes[i].data == MAP_FAILED) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Could not map buffer %d plane %d!\n", buffer->index, i);
+ return -1;
+ }
+ }
+ buffer->mapped = true;
+ return 0;
+}
+
+void nvv4l2_unmap(nvv4l2_ctx_t *ctx, NvBuffer *buffer)
+{
+ if (buffer->memory_type != V4L2_MEMORY_MMAP || !buffer->mapped) {
+ av_log(ctx->avctx, AV_LOG_VERBOSE,
+ "Cannot unmap Buffer %d Only mapped MMAP buffer can be unmapped\n",
+ buffer->index);
+ return;
+ }
+
+ for (uint32_t i = 0; i < buffer->n_planes; i++) {
+ if (buffer->planes[i].data) {
+ munmap(buffer->planes[i].data, buffer->planes[i].length);
+ }
+ buffer->planes[i].data = NULL;
+ }
+ buffer->mapped = false;
+}
+
+void nvv4l2_destroyBuffer(nvv4l2_ctx_t *ctx, NvBuffer *buffer)
+{
+ if (buffer->mapped) {
+ nvv4l2_unmap(ctx, buffer);
+ }
+}
+
+int
+nvv4l2_query_buffer(nvv4l2_ctx_t *ctx, enum v4l2_buf_type buf_type,
+ enum v4l2_memory memory_type, uint32_t num_planes,
+ uint32_t index)
+{
+ struct v4l2_buffer v4l2_buf;
+ struct v4l2_plane planes[NV_MAX_PLANES];
+ NvBuffer *buffer;
+ int ret;
+ uint32_t j;
+
+ memset(&v4l2_buf, 0, sizeof(struct v4l2_buffer));
+ memset(planes, 0, sizeof(planes));
+ v4l2_buf.index = index;
+ v4l2_buf.type = buf_type;
+ v4l2_buf.memory = memory_type;
+ v4l2_buf.m.planes = planes;
+ v4l2_buf.length = num_planes;
+
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_QUERYBUF, &v4l2_buf);
+ if (ret) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Error in QueryBuf!\n");
+ } else {
+ if (buf_type == ctx->op_buf_type) {
+ buffer = ctx->op_buffers[index];
+ } else if (buf_type == ctx->cp_buf_type) {
+ buffer = ctx->cp_buffers[index];
+ }
+
+ for (j = 0; j < v4l2_buf.length; j++) {
+ buffer->planes[j].length = v4l2_buf.m.planes[j].length;
+ buffer->planes[j].mem_offset =
+ v4l2_buf.m.planes[j].m.mem_offset;
+ }
+ }
+
+ return ret;
+}
+
+int
+nvv4l2_export_buffer(nvv4l2_ctx_t *ctx, enum v4l2_buf_type buf_type,
+ uint32_t num_planes, uint32_t index)
+{
+ struct v4l2_exportbuffer expbuf;
+ NvBuffer *buffer;
+ int ret;
+
+ memset(&expbuf, 0, sizeof(expbuf));
+ expbuf.type = buf_type;
+ expbuf.index = index;
+
+ for (uint32_t i = 0; i < num_planes; i++) {
+ expbuf.plane = i;
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_EXPBUF, &expbuf);
+ if (ret) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Error in ExportBuf!\n");
+ }
+ else {
+ if (buf_type == ctx->op_buf_type) {
+ buffer = ctx->op_buffers[index];
+ } else if (buf_type == ctx->cp_buf_type) {
+ buffer = ctx->cp_buffers[index];
+ }
+ buffer->planes[i].fd = expbuf.fd;
+ }
+ }
+ return 0;
+}
+
+int
+nvv4l2_fill_buffer_plane_format(nvv4l2_ctx_t *ctx,
+ uint32_t *num_planes,
+ NvBufferPlaneFormat *planefmts,
+ uint32_t width, uint32_t height,
+ uint32_t pixfmt)
+{
+ switch (pixfmt) {
+ case V4L2_PIX_FMT_YUV444M:
+ *num_planes = 3;
+
+ planefmts[0].width = width;
+ planefmts[1].width = width;
+ planefmts[2].width = width;
+
+ planefmts[0].height = height;
+ planefmts[1].height = height;
+ planefmts[2].height = height;
+
+ planefmts[0].bytesperpixel = 1;
+ planefmts[1].bytesperpixel = 1;
+ planefmts[2].bytesperpixel = 1;
+ break;
+ case V4L2_PIX_FMT_YUV420M:
+ *num_planes = 3;
+
+ planefmts[0].width = width;
+ planefmts[1].width = width / 2;
+ planefmts[2].width = width / 2;
+
+ planefmts[0].height = height;
+ planefmts[1].height = height / 2;
+ planefmts[2].height = height / 2;
+
+ planefmts[0].bytesperpixel = 1;
+ planefmts[1].bytesperpixel = 1;
+ planefmts[2].bytesperpixel = 1;
+ break;
+ case V4L2_PIX_FMT_NV12M:
+ *num_planes = 2;
+
+ planefmts[0].width = width;
+ planefmts[1].width = width / 2;
+
+ planefmts[0].height = height;
+ planefmts[1].height = height / 2;
+
+ planefmts[0].bytesperpixel = 1;
+ planefmts[1].bytesperpixel = 2;
+ break;
+ case V4L2_PIX_FMT_P010M:
+ *num_planes = 2;
+
+ planefmts[0].width = width;
+ planefmts[1].width = width / 2;
+
+ planefmts[0].height = height;
+ planefmts[1].height = height / 2;
+
+ planefmts[0].bytesperpixel = 2;
+ planefmts[1].bytesperpixel = 4;
+ break;
+ default:
+ av_log(ctx->avctx, AV_LOG_ERROR, "Unsupported pixel format!");
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+nvv4l2_dq_event(nvv4l2_ctx_t *ctx, struct v4l2_event *event,
+ uint32_t max_wait_ms)
+{
+ int ret;
+ do {
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_DQEVENT, event);
+
+ if (errno != EAGAIN) {
+ break;
+ } else if (max_wait_ms-- == 0) {
+ break;
+ } else {
+ usleep(1000);
+ }
+ }
+ while (ret && (ctx->op_streamon || ctx->cp_streamon));
+
+ return ret;
+}
+
+int
+nvv4l2_dq_buffer(nvv4l2_ctx_t *ctx, struct v4l2_buffer *v4l2_buf,
+ NvBuffer **buffer, enum v4l2_buf_type buf_type,
+ enum v4l2_memory memory_type, uint32_t num_retries)
+{
+ int ret;
+ bool is_in_error = false;
+ v4l2_buf->type = buf_type;
+ v4l2_buf->memory = memory_type;
+ do {
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_DQBUF, v4l2_buf);
+ if (ret == 0) {
+ pthread_mutex_lock(&ctx->queue_lock);
+ switch (v4l2_buf->type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ if (buffer)
+ *buffer = ctx->op_buffers[v4l2_buf->index];
+ for (uint32_t i = 0;
+ i < ctx->op_buffers[v4l2_buf->index]->n_planes; i++) {
+ ctx->op_buffers[v4l2_buf->index]->planes[i].bytesused =
+ v4l2_buf->m.planes[i].bytesused;
+ }
+ ctx->num_queued_op_buffers--;
+ break;
+
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ if (buffer)
+ *buffer = ctx->cp_buffers[v4l2_buf->index];
+ for (uint32_t i = 0;
+ i < ctx->cp_buffers[v4l2_buf->index]->n_planes; i++) {
+ ctx->cp_buffers[v4l2_buf->index]->planes[i].bytesused =
+ v4l2_buf->m.planes[i].bytesused;
+ }
+ ctx->num_queued_cp_buffers--;
+ break;
+
+ default:
+ av_log(ctx->avctx, AV_LOG_ERROR, "Invalid buffer type!\n");
+ }
+ pthread_cond_broadcast(&ctx->queue_cond);
+ pthread_mutex_unlock(&ctx->queue_lock);
+ } else if (errno == EAGAIN) {
+ pthread_mutex_lock(&ctx->queue_lock);
+ if (v4l2_buf->flags & V4L2_BUF_FLAG_LAST) {
+ pthread_mutex_unlock(&ctx->queue_lock);
+ break;
+ }
+ pthread_mutex_unlock(&ctx->queue_lock);
+
+ if (num_retries-- == 0) {
+ av_log(ctx->avctx, AV_LOG_VERBOSE, "Resource unavailable!\n");
+ break;
+ }
+ } else {
+ is_in_error = true;
+ break;
+ }
+ }
+ while (ret && !is_in_error);
+
+ return ret;
+}
+
+int
+nvv4l2_q_buffer(nvv4l2_ctx_t *ctx, struct v4l2_buffer *v4l2_buf,
+ NvBuffer *buffer, enum v4l2_buf_type buf_type,
+ enum v4l2_memory memory_type, int num_planes)
+{
+ int ret;
+
+ pthread_mutex_lock(&ctx->queue_lock);
+
+ if (!buffer && buf_type == ctx->op_buf_type)
+ buffer = ctx->op_buffers[v4l2_buf->index];
+ else if (!buffer && buf_type == ctx->cp_buf_type)
+ buffer = ctx->cp_buffers[v4l2_buf->index];
+
+ v4l2_buf->type = buf_type;
+ v4l2_buf->memory = memory_type;
+ v4l2_buf->length = num_planes;
+
+ switch (memory_type) {
+ case V4L2_MEMORY_USERPTR:
+ for (uint32_t i = 0; i < buffer->n_planes; i++) {
+ v4l2_buf->m.planes[i].m.userptr =
+ (unsigned long) buffer->planes[i].data;
+ v4l2_buf->m.planes[i].bytesused = buffer->planes[i].bytesused;
+ }
+ break;
+ case V4L2_MEMORY_MMAP:
+ for (uint32_t i = 0; i < buffer->n_planes; i++) {
+ v4l2_buf->m.planes[i].bytesused = buffer->planes[i].bytesused;
+ }
+ break;
+
+ case V4L2_MEMORY_DMABUF:
+ break;
+
+ default:
+ pthread_cond_broadcast(&ctx->queue_cond);
+ pthread_mutex_unlock(&ctx->queue_lock);
+ return -1;
+ }
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_QBUF, v4l2_buf);
+
+ if (ret == 0) {
+ if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ ctx->num_queued_op_buffers++;
+ } else {
+ ctx->num_queued_cp_buffers++;
+ }
+ pthread_cond_broadcast(&ctx->queue_cond);
+ }
+ pthread_mutex_unlock(&ctx->queue_lock);
+
+ return ret;
+}
+
+int
+nvv4l2_req_buffers_on_capture_plane(nvv4l2_ctx_t *ctx,
+ enum v4l2_buf_type buf_type,
+ enum v4l2_memory mem_type,
+ int num_buffers)
+{
+ struct v4l2_requestbuffers reqbufs;
+ int ret;
+ memset(&reqbufs, 0, sizeof(struct v4l2_requestbuffers));
+
+ reqbufs.count = num_buffers;
+ reqbufs.memory = mem_type;
+ reqbufs.type = buf_type;
+
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_REQBUFS, &reqbufs);
+ if (ret)
+ return ret;
+
+ if (reqbufs.count) {
+ ctx->cp_buffers =
+ (NvBuffer **)NVMALLOC(reqbufs.count * sizeof(NvBuffer *));
+ for (uint32_t i = 0; i < reqbufs.count; ++i) {
+ ctx->cp_buffers[i] = (NvBuffer *)NVMALLOC(sizeof(NvBuffer));
+ nvv4l2_create_bufferfmt(ctx->cp_buffers[i], buf_type, mem_type,
+ ctx->cp_num_planes, ctx->cp_planefmts, i);
+ }
+ } else if (ctx->cp_buffers) {
+ for (uint32_t i = 0; i < ctx->cp_num_buffers; ++i) {
+ for (uint32_t j = 0; j < ctx->cp_buffers[i]->n_planes &&
+ mem_type == V4L2_MEMORY_USERPTR; j++) {
+ NVFREE(ctx->cp_buffers[i]->planes[j].data);
+ }
+ NVFREE(ctx->cp_buffers[i]);
+ }
+ NVFREE(ctx->cp_buffers);
+ ctx->cp_buffers = NULL;
+ }
+ ctx->cp_num_buffers = reqbufs.count;
+
+ return ret;
+}
+
+int
+nvv4l2_req_buffers_on_output_plane(nvv4l2_ctx_t *ctx,
+ enum v4l2_buf_type buf_type,
+ enum v4l2_memory mem_type,
+ int num_buffers)
+{
+ struct v4l2_requestbuffers reqbufs;
+ int ret;
+ memset(&reqbufs, 0, sizeof(struct v4l2_requestbuffers));
+
+ reqbufs.count = num_buffers;
+ reqbufs.memory = mem_type;
+ reqbufs.type = buf_type;
+
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_REQBUFS, &reqbufs);
+ if (ret)
+ return ret;
+
+ if (reqbufs.count) {
+ ctx->op_buffers =
+ (NvBuffer **)NVMALLOC(reqbufs.count * sizeof(NvBuffer *));
+ for (uint32_t i = 0; i < reqbufs.count; ++i) {
+ ctx->op_buffers[i] = (NvBuffer *)NVMALLOC(sizeof(NvBuffer));
+ nvv4l2_create_bufferfmt(ctx->op_buffers[i], buf_type, mem_type,
+ ctx->op_num_planes, ctx->op_planefmts, i);
+ }
+ } else if (ctx->op_buffers) {
+ for (uint32_t i = 0; i < ctx->op_num_buffers; ++i) {
+ for (uint32_t j = 0; j < ctx->op_buffers[i]->n_planes &&
+ mem_type == V4L2_MEMORY_USERPTR; j++) {
+ NVFREE(ctx->op_buffers[i]->planes[j].data);
+ }
+ NVFREE(ctx->op_buffers[i]);
+ }
+ NVFREE(ctx->op_buffers);
+ ctx->op_buffers = NULL;
+ }
+ ctx->op_num_buffers = reqbufs.count;
+
+ return ret;
+}
+
+int
+nvv4l2_set_ext_controls(int fd, uint32_t id,
+ uint32_t class, uint32_t value)
+{
+ int ret;
+ struct v4l2_ext_control ctl;
+ struct v4l2_ext_controls ctrls;
+
+ memset(&ctl, 0, sizeof(struct v4l2_ext_control));
+ memset(&ctrls, 0, sizeof(struct v4l2_ext_controls));
+ ctl.id = id;
+ ctl.value = value;
+ ctrls.count = 1;
+ ctrls.controls = &ctl;
+ ctrls.ctrl_class = class;
+
+ ret = v4l2_ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls);
+
+ return ret;
+}
+
+int
+nvv4l2_set_ext_control_qp_range(int fd, uint32_t qpmin,
+ uint32_t qpmax)
+{
+ int ret;
+ struct v4l2_ext_control ctl;
+ struct v4l2_ext_controls ctrls;
+ v4l2_ctrl_video_qp_range qprange;
+
+ memset(&ctl, 0, sizeof(struct v4l2_ext_control));
+ memset(&ctrls, 0, sizeof(struct v4l2_ext_controls));
+
+ qprange.MinQpI = qpmin;
+ qprange.MaxQpI = qpmax;
+ qprange.MinQpP = qpmin;
+ qprange.MaxQpP = qpmax;
+ qprange.MinQpB = qpmin;
+ qprange.MaxQpB = qpmax;
+
+ ctl.id = V4L2_CID_MPEG_VIDEOENC_QP_RANGE;
+ ctl.string = (char *)&qprange;
+
+ ctrls.count = 1;
+ ctrls.controls = &ctl;
+ ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+
+ ret = v4l2_ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls);
+
+ return ret;
+}
+
+int
+nvv4l2_set_ext_control_constant_qp(int fd, uint32_t qpval)
+{
+ int ret;
+ struct v4l2_ext_control ctl[3];
+ struct v4l2_ext_controls ctrls;
+
+ memset(&ctl, 0, sizeof(ctl));
+ memset(&ctrls, 0, sizeof(ctrls));
+
+ ctl[0].id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
+ ctl[0].value = 0; // disable rate control
+
+ ctl[1].id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
+ ctl[1].value = qpval;
+
+ ctl[2].id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
+ ctl[2].value = qpval;
+
+ ctrls.count = 3;
+ ctrls.controls = &ctl[0];
+ ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+
+ ret = v4l2_ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls);
+
+ return ret;
+}
+
+int
+nvv4l2_get_ext_control_metadata(int fd, uint32_t buffer_index,
+ v4l2_ctrl_videoenc_outputbuf_metadata *enc_metadata)
+{
+ int ret;
+ struct v4l2_ext_control ctl;
+ struct v4l2_ext_controls ctrls;
+ v4l2_ctrl_video_metadata metadata;
+
+ memset(&ctl, 0, sizeof(struct v4l2_ext_control));
+ memset(&ctrls, 0, sizeof(struct v4l2_ext_controls));
+
+ metadata.buffer_index = buffer_index;
+ metadata.VideoEncMetadata =
+ (v4l2_ctrl_videoenc_outputbuf_metadata *)&enc_metadata;
+
+ ctl.id = V4L2_CID_MPEG_VIDEOENC_METADATA;
+ ctl.string = (char *)&metadata;
+
+ ctrls.count = 1;
+ ctrls.controls = &ctl;
+ ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+
+ ret = v4l2_ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls);
+
+ return ret;
+}
+
+int
+nvv4l2_set_stream_control_framerate(int fd, uint32_t buf_type,
+ uint32_t framerate_num,
+ uint32_t framerate_den)
+{
+ int ret;
+ struct v4l2_streamparm parms;
+
+ memset(&parms, 0, sizeof(parms));
+
+ parms.parm.output.timeperframe.numerator = framerate_den;
+ parms.parm.output.timeperframe.denominator = framerate_num;
+ parms.type = buf_type;
+
+ ret = v4l2_ioctl(fd, VIDIOC_S_PARM, &parms);
+
+ return ret;
+}
+
+int
+nvv4l2_subscribe_event(int fd, uint32_t type, uint32_t id,
+ uint32_t flags)
+{
+ struct v4l2_event_subscription sub;
+ int ret;
+
+ memset(&sub, 0, sizeof(struct v4l2_event_subscription));
+
+ sub.type = type;
+ sub.id = id;
+ sub.flags = flags;
+
+ ret = v4l2_ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
+
+ return ret;
+}
+
+void
+nvv4l2_dbg_plane_supported_formats(nvv4l2_ctx_t *ctx,
+ uint32_t buf_type)
+{
+ struct v4l2_fmtdesc fdesc;
+ char fourcc[5] = {0};
+ int ret;
+
+ memset(&fdesc, 0, sizeof(fdesc));
+ fdesc.type = buf_type;
+
+ av_log(ctx->avctx, AV_LOG_INFO,
+ "%s plane format support:\n",
+ buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
+ "Output" : "Capture");
+
+ while (true) {
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_ENUM_FMT, &fdesc);
+ if (ret)
+ break;
+
+ memcpy(fourcc, &fdesc.pixelformat, 4);
+ av_log(ctx->avctx, AV_LOG_INFO, "%d: %s (%s)\n",
+ fdesc.index, fourcc, fdesc.description);
+ fdesc.index++;
+ }
+}
+
+NvBufferPixFmtVersion
+nvv4l2_get_pixfmt_list_version(nvv4l2_ctx_t *ctx)
+{
+ NvBufferParams params;
+ NvBufferCreateParams iParams;
+ NvBufferPixFmtVersion version;
+ int dma_fd = -1;
+ int ret;
+
+ memset(&params, 0, sizeof(params));
+ memset(&iParams, 0, sizeof(NvBufferCreateParams));
+
+ iParams.width = 1280;
+ iParams.height = 720;
+ iParams.layout = NvBufferLayout_BlockLinear;
+ iParams.payloadType = NvBufferPayload_SurfArray;
+ iParams.nvbuf_tag = NvBufferTag_NONE;
+ iParams.colorFormat = NvBufferColorFormat_NV12;
+
+ /* Create assumed NV12 buffer */
+ ret = NvBufferCreateEx(&dma_fd, &iParams);
+ if (ret || dma_fd == -1) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Error getting NvBuffer Pixel Format list version!\n");
+ return NvBufferPixFmtVersion_New; /* Fallback to new */
+ }
+
+ /* Query created buffer parameters */
+ ret = NvBufferGetParams(dma_fd, &params);
+ if (ret) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Error getting NvBuffer Pixel Format list version!\n");
+ return NvBufferPixFmtVersion_New; /* Fallback to new */
+ }
+
+ /* Check if returned parameters match NV12 in old BSP. */
+ if (params.num_planes == 2 && params.pitch[1] == iParams.width) {
+ av_log(ctx->avctx, AV_LOG_VERBOSE, "Old NvBuffer Utils version\n");
+ version = NvBufferPixFmtVersion_Legacy;
+ } else {
+ av_log(ctx->avctx, AV_LOG_VERBOSE, "New NvBuffer Utils version\n");
+ version = NvBufferPixFmtVersion_New;
+ }
+
+ NvBufferDestroy(dma_fd);
+
+ return version;
+}
diff -Naur ffmpeg-4.3.2-Matrix-19.1/libavcodec/nvv4l2_dec.c ffmpeg-4.3.2-Matrix-19.1-2/libavcodec/nvv4l2_dec.c
--- ffmpeg-4.3.2-Matrix-19.1/libavcodec/nvv4l2_dec.c 1970-01-01 01:00:00.000000000 +0100
+++ ffmpeg-4.3.2-Matrix-19.1-2/libavcodec/nvv4l2_dec.c 2022-03-20 03:28:14.608398264 +0100
@@ -0,0 +1,1196 @@
+/*
+ * Copyright (c) 2021-2022, CTCaer <ctcaer@gmail.com>
+ *
+ * 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.
+ */
+
+#include <stdatomic.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "internal.h"
+#include "libavutil/log.h"
+
+#include "nvv4l2.h"
+
+/*
+ ** Output plane format support:
+ ** S264 (H264 Encoded Slice bitstream)
+ ** VP8F (VP8 Encoded Slice bitstream)
+ ** H264 (H264 Encoded bitstream)
+ ** H265 (H265 Encoded bitstream)
+ ** VP80 (VP8 Encoded bitstream)
+ ** VP90 (VP9 Encoded bitstream)
+ ** MPG2 (MPEG2 Encoded bitstream)
+ ** MPG4 (MPEG4 Encoded bitstream)
+ ** JPEG (JPEG Encoded bitstream)
+ ** MJPG (MJPEG Encoded bitstream)
+ ** DVX4 (divx Encoded bitstream)
+ ** DVX5 (divx Encoded bitstream)
+ **
+ ** Capture plane format support:
+ ** NM12 (YUV 4:2:0)
+ */
+
+/*
+ ** Output plane memory type support:
+ ** V4L2_MEMORY_MMAP
+ ** V4L2_MEMORY_USERPTR
+ ** Capture plane memory type support:
+ ** V4L2_MEMORY_MMAP
+ ** V4L2_MEMORY_DMABUF
+ */
+
+#define DECODER_DEV "/dev/nvhost-nvdec"
+#define OP_PLANE_REQ_SIZEIMAGE 4000000
+
+typedef struct {
+ char eos_reached;
+ nvv4l2_ctx_t *ctx;
+ AVClass *av_class;
+} nvv4l2DecodeContext;
+
+static int
+set_output_plane_format(nvv4l2_ctx_t *ctx, uint32_t pixfmt,
+ uint32_t sizeimage)
+{
+ int ret;
+ struct v4l2_format format;
+
+ memset(&format, 0, sizeof(struct v4l2_format));
+ format.type = ctx->op_buf_type;
+ format.fmt.pix_mp.pixelformat = pixfmt;
+ format.fmt.pix_mp.num_planes = 1;
+ format.fmt.pix_mp.plane_fmt[0].sizeimage = sizeimage;
+
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_S_FMT, &format);
+
+ if (ret == 0) {
+ ctx->op_num_planes = format.fmt.pix_mp.num_planes;
+ for (uint32_t i = 0; i < ctx->op_num_planes; i++) {
+ ctx->op_planefmts[i].stride =
+ format.fmt.pix_mp.plane_fmt[i].bytesperline;
+ ctx->op_planefmts[i].sizeimage =
+ format.fmt.pix_mp.plane_fmt[i].sizeimage;
+ }
+ }
+
+ return ret;
+}
+
+static int
+set_capture_plane_format(AVCodecContext *avctx, nvv4l2_ctx_t *ctx,
+ uint32_t pixfmt, uint32_t width, uint32_t height)
+{
+ int ret;
+ struct v4l2_format format;
+ uint32_t num_bufferplanes;
+ NvBufferPlaneFormat planefmts[NV_MAX_PLANES];
+
+ nvv4l2_fill_buffer_plane_format(ctx, &num_bufferplanes, planefmts, width,
+ height, pixfmt);
+ ctx->cp_num_planes = num_bufferplanes;
+ for (uint32_t i = 0; i < num_bufferplanes; i++) {
+ ctx->cp_planefmts[i] = planefmts[i];
+ }
+ memset(&format, 0, sizeof(struct v4l2_format));
+ format.type = ctx->cp_buf_type;
+ format.fmt.pix_mp.width = width;
+ format.fmt.pix_mp.height = height;
+ format.fmt.pix_mp.pixelformat = pixfmt;
+ format.fmt.pix_mp.num_planes = num_bufferplanes;
+
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_S_FMT, &format);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR, "Error in VIDIOC_S_FMT!\n");
+ ctx->in_error = true;
+ } else {
+ ctx->cp_num_planes = format.fmt.pix_mp.num_planes;
+ for (uint32_t i = 0; i < ctx->cp_num_planes; i++) {
+ ctx->cp_planefmts[i].stride =
+ format.fmt.pix_mp.plane_fmt[i].bytesperline;
+ ctx->cp_planefmts[i].sizeimage =
+ format.fmt.pix_mp.plane_fmt[i].sizeimage;
+ }
+ }
+
+ return ret;
+}
+
+static void query_set_capture(AVCodecContext *avctx, nvv4l2_ctx_t *ctx)
+{
+ struct v4l2_format format;
+ struct v4l2_crop crop;
+ struct v4l2_control ctl;
+ int ret;
+ int32_t min_cap_buffers;
+ NvBufferCreateParams input_params = { 0 };
+ NvBufferCreateParams cap_params = { 0 };
+
+ if (ctx->in_error || ctx->eos)
+ return;
+
+ /* Get format on capture plane set by device.
+ ** This may change after an resolution change event.
+ */
+ format.type = ctx->cp_buf_type;
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_G_FMT, &format);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Could not get format from decoder capture plane!\n");
+ ctx->in_error = true;
+ return;
+ }
+
+ /* Query cropping size and position. */
+ crop.type = ctx->cp_buf_type;
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_G_CROP, &crop);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Could not get crop from decoder capture plane!\n");
+ ctx->in_error = true;
+ return;
+ }
+
+ av_log(avctx, AV_LOG_VERBOSE, "Resolution changed to: %dx%d\n",
+ crop.c.width, crop.c.height);
+
+ ctx->codec_width = crop.c.width;
+ ctx->codec_height = crop.c.height;
+
+ for (uint32_t i = 0; i < NV_MAX_BUFFERS; i++) {
+ if (ctx->plane_dma_fd[i] != -1) {
+ NvBufferDestroy(ctx->plane_dma_fd[i]);
+ ctx->plane_dma_fd[i] = -1;
+ }
+ }
+
+ /*
+ ** Due to VIC constrains the transformation from Block Linear to Pitch
+ ** must have aligned widths to 64B. Otherwise the frame might be produced
+ ** as scrambled.
+ */
+ ctx->plane_width_aligned = NVALIGN(crop.c.width, 64);
+ if (ctx->plane_width_aligned != crop.c.width)
+ av_log(avctx, AV_LOG_VERBOSE, "Linesize got aligned: %d -> %d\n",
+ crop.c.width, ctx->plane_width_aligned);
+ crop.c.width = ctx->plane_width_aligned;
+
+ /* Create transform/export DMA buffers. */
+ for (uint32_t i = 0; i < NV_MAX_BUFFERS; i++) {
+ input_params.width = crop.c.width;
+ input_params.height = crop.c.height;
+ input_params.layout = NvBufferLayout_Pitch;
+ input_params.payloadType = NvBufferPayload_SurfArray;
+ input_params.nvbuf_tag = NvBufferTag_VIDEO_DEC;
+
+ switch (ctx->cp_pixfmt) {
+ case V4L2_PIX_FMT_YUV420M:
+ input_params.colorFormat = NvBufferColorFormat_YUV420;
+ break;
+ case V4L2_PIX_FMT_NV12M:
+ input_params.colorFormat = NvBufferColorFormat_NV12;
+ if (ctx->pixfmt_list_ver == NvBufferPixFmtVersion_New)
+ input_params.colorFormat++;
+ break;
+ }
+
+ ret = NvBufferCreateEx(&ctx->plane_dma_fd[i], &input_params);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR, "Creation of dmabuf failed!\n");
+ ctx->in_error = true;
+ }
+ }
+
+ /* Stop streaming. */
+ pthread_mutex_lock(&ctx->queue_lock);
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_STREAMOFF, &ctx->cp_buf_type);
+ if (ret) {
+ ctx->in_error = true;
+ } else {
+ pthread_cond_broadcast(&ctx->queue_cond);
+ }
+ pthread_mutex_unlock(&ctx->queue_lock);
+
+ /* Request buffers with count 0 and destroy all
+ ** previously allocated buffers.
+ */
+ ret = nvv4l2_req_buffers_on_capture_plane(ctx,
+ ctx->cp_buf_type,
+ ctx->cp_mem_type, 0);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error in requesting 0 capture plane buffers!\n");
+ ctx->in_error = true;
+ return;
+ }
+
+ /* Destroy previous DMA buffers. */
+ for (uint32_t i = 0; i < ctx->cp_num_buffers; i++) {
+ if (ctx->dmabuff_fd[i] != -1) {
+ ret = NvBufferDestroy(ctx->dmabuff_fd[i]);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to Destroy NvBuffer!\n");
+ ctx->in_error = true;
+ }
+ ctx->dmabuff_fd[i] = -1;
+ }
+ }
+
+ /* Set capture plane format to update vars. */
+ ret = set_capture_plane_format(avctx, ctx,
+ format.fmt.pix_mp.pixelformat,
+ format.fmt.pix_mp.width,
+ format.fmt.pix_mp.height);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error in setting capture plane format!\n");
+ ctx->in_error = true;
+ return;
+ }
+
+ /* Get control value for min buffers which have to
+ ** be requested on capture plane.
+ */
+ ctl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
+
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_G_CTRL, &ctl);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR, "Error getting value of control!\n");
+ ctx->in_error = true;
+ return;
+ } else {
+ min_cap_buffers = ctl.value;
+ }
+
+ /* Set quantization type. */
+ if (format.fmt.pix_mp.quantization == V4L2_QUANTIZATION_DEFAULT) {
+ av_log(avctx, AV_LOG_VERBOSE,
+ "Colorspace ITU-R BT.601 with standard range luma (16-235)\n");
+ cap_params.colorFormat = NvBufferColorFormat_NV12;
+ } else {
+ av_log(avctx, AV_LOG_VERBOSE,
+ "Colorspace ITU-R BT.601 with extended range luma (0-255)\n");
+ cap_params.colorFormat = NvBufferColorFormat_NV12_ER;
+ }
+
+ /* Increment color format if NvBuffer is newer. */
+ if (ctx->pixfmt_list_ver == NvBufferPixFmtVersion_New)
+ cap_params.colorFormat++;
+
+ /* Request number of buffers returned by ctrl, plus 10 more. */
+ ctx->cp_num_buffers = min_cap_buffers + 10;
+
+ /* Create DMA Buffers by defining the parameters for the HW Buffer.
+ ** @payloadType defines the memory handle for the NvBuffer, here
+ ** defined for the set of planes.
+ ** @nvbuf_tag identifies the type of device or component
+ ** requesting the operation.
+ ** @layout defines memory layout for the surfaces, either Pitch/BLockLinear.
+ */
+ for (uint32_t i = 0; i < ctx->cp_num_buffers; i++) {
+ cap_params.width = crop.c.width;
+ cap_params.height = crop.c.height;
+ cap_params.layout = NvBufferLayout_BlockLinear;
+ cap_params.payloadType = NvBufferPayload_SurfArray;
+ cap_params.nvbuf_tag = NvBufferTag_VIDEO_DEC;
+ ret = NvBufferCreateEx(&ctx->dmabuff_fd[i], &cap_params);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to create buffers!\n");
+ ctx->in_error = true;
+ break;
+ }
+ }
+
+ /* Request buffers on capture plane. */
+ ret = nvv4l2_req_buffers_on_capture_plane(ctx,
+ ctx->cp_buf_type,
+ ctx->cp_mem_type,
+ ctx->cp_num_buffers);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error in requesting capture plane buffers!\n");
+ ctx->in_error = true;
+ return;
+ }
+
+ /* Enqueue all empty buffers on capture plane. */
+ for (uint32_t i = 0; i < ctx->cp_num_buffers; i++) {
+ struct v4l2_buffer v4l2_buf;
+ struct v4l2_plane planes[NV_MAX_PLANES];
+
+ memset(&v4l2_buf, 0, sizeof(v4l2_buf));
+ memset(planes, 0, sizeof(planes));
+
+ v4l2_buf.index = i;
+ v4l2_buf.m.planes = planes;
+ v4l2_buf.type = ctx->cp_buf_type;
+ v4l2_buf.memory = ctx->cp_mem_type;
+ v4l2_buf.length = ctx->cp_num_planes;
+ /* Set DMA plane handle. */
+ v4l2_buf.m.planes[0].m.fd = ctx->dmabuff_fd[i];
+ v4l2_buf.m.planes[1].m.fd = ctx->dmabuff_fd[i];
+
+ ret = nvv4l2_q_buffer(ctx, &v4l2_buf, ctx->cp_buffers[i],
+ ctx->cp_buf_type, ctx->cp_mem_type,
+ ctx->cp_num_planes);
+
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR, "Qing failed on capture plane!\n");
+ ctx->in_error = true;
+ return;
+ }
+ }
+
+ /* Set max performance mode if low latency is requested. */
+ if (ctx->low_latency) {
+ ret = nvv4l2_set_ext_controls(ctx->fd,
+ V4L2_CID_MPEG_VIDEO_MAX_PERFORMANCE, 0, 1);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set control max performance!\n");
+ ctx->in_error = true;
+ }
+ }
+
+ /* Set streaming status ON on capture plane. */
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_STREAMON, &ctx->cp_buf_type);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR, "Streaming error on capture plane!\n");
+ ctx->in_error = true;
+ }
+
+ ctx->cp_streamon = true;
+
+ av_log(avctx, AV_LOG_VERBOSE, "Query and set capture successful\n");
+
+ return;
+}
+
+static void *dec_capture_thread(void *arg)
+{
+ nvv4l2_ctx_t *ctx = (nvv4l2_ctx_t *)arg;
+ struct v4l2_event event;
+ int buf_index;
+ int ret;
+
+ av_log(ctx->avctx, AV_LOG_VERBOSE, "Starting capture thread\n");
+
+ /* Need to wait for the first Resolution change event, so that
+ ** the decoder knows the stream resolution and can allocate
+ ** appropriate buffers when REQBUFS is called.
+ */
+ do {
+ /* Dequeue the subscribed event. */
+ ret = nvv4l2_dq_event(ctx, &event, 50000);
+ if (ret) {
+ if (errno == EAGAIN) {
+ av_log(ctx->avctx, AV_LOG_VERBOSE,
+ "Timeout waiting for first resolution event!\n");
+ } else {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Error in dequeuing decoder event!\n");
+ }
+ ctx->in_error = true;
+ break;
+ }
+ }
+ while ((event.type != V4L2_EVENT_RESOLUTION_CHANGE) &&
+ !ctx->in_error && !ctx->eos);
+
+ /* Received first resolution change event
+ ** Format and buffers are now set on capture.
+ */
+ query_set_capture(ctx->avctx, ctx);
+
+ /* Check for resolution event to again
+ ** set format and buffers on capture plane.
+ */
+ while (!ctx->in_error && !ctx->eos) {
+ ret = nvv4l2_dq_event(ctx, &event, 0);
+ if (ret == 0) {
+ switch (event.type) {
+ case V4L2_EVENT_RESOLUTION_CHANGE:
+ query_set_capture(ctx->avctx, ctx);
+ continue;
+ }
+ }
+
+ /* Main Capture loop for DQ and Q. */
+ while (!ctx->eos) {
+ struct v4l2_buffer v4l2_cp_buf;
+ struct v4l2_plane capture_planes[NV_MAX_PLANES];
+ NvBufferRect src_rect, dest_rect;
+ NvBufferParams buf_params;
+ NvBufferTransformParams transform_params;
+
+ memset(&v4l2_cp_buf, 0, sizeof(v4l2_cp_buf));
+ memset(capture_planes, 0, sizeof(capture_planes));
+ v4l2_cp_buf.m.planes = capture_planes;
+
+ /* Dequeue the filled buffer. */
+ if (nvv4l2_dq_buffer(ctx, &v4l2_cp_buf, NULL,
+ ctx->cp_buf_type, ctx->cp_mem_type, 0)) {
+ if (errno == EAGAIN) {
+ usleep(1000);
+ }
+ break;
+ }
+
+ /* Transformation parameters are defined
+ ** which are passed to the NvBufferTransform
+ ** for required conversion.
+ */
+ src_rect.top = 0;
+ src_rect.left = 0;
+ src_rect.width = ctx->codec_width;
+ src_rect.height = ctx->codec_height;
+ dest_rect.top = 0;
+ dest_rect.left = 0;
+ dest_rect.width = ctx->codec_width;
+ dest_rect.height = ctx->codec_height;
+
+ /* @transform_flag defines the flags for enabling the
+ ** valid transforms. All the valid parameters are
+ ** present in the nvv4l2_ext_utils header.
+ */
+ transform_params.transform_flag = NVBUFFER_TRANSFORM_FILTER;
+ transform_params.transform_flip = NvBufferTransform_None;
+ transform_params.transform_filter =
+ NvBufferTransform_Filter_Smart;
+ transform_params.src_rect = src_rect;
+ transform_params.dst_rect = dest_rect;
+ transform_params.session = ctx->buf_session;
+
+ pthread_mutex_lock(&ctx->queue_lock);
+
+ buf_index = nvv4l2_pool_idx_next(ctx, ctx->export_pool);
+
+ /* Blocklinear to Pitch transformation is required
+ ** to dump the raw decoded buffer data.
+ */
+ if (buf_index >= 0) {
+ ret = NvBufferTransform(ctx->dmabuff_fd[v4l2_cp_buf.index],
+ ctx->plane_dma_fd[buf_index],
+ &transform_params);
+ if (ret == -1) {
+ ctx->in_error = true;
+ av_log(ctx->avctx, AV_LOG_ERROR, "Transform failed!\n");
+ pthread_mutex_unlock(&ctx->queue_lock);
+ break;
+ }
+
+ ret = NvBufferGetParams(ctx->plane_dma_fd[buf_index],
+ &buf_params);
+ if (ret) {
+ ctx->in_error = true;
+ av_log(ctx->avctx, AV_LOG_ERROR, "GetParams failed!\n");
+ pthread_mutex_unlock(&ctx->queue_lock);
+ break;
+ }
+ }
+
+ ctx->plane_width[0] = buf_params.width[0];
+ ctx->plane_height[0] = buf_params.height[0];
+ ctx->plane_width[1] = buf_params.width[1];
+ ctx->plane_height[1] = buf_params.height[1];
+ if (ctx->cp_pixfmt == V4L2_PIX_FMT_YUV420M) {
+ ctx->plane_width[2] = buf_params.width[2];
+ ctx->plane_height[2] = buf_params.height[2];
+ }
+
+ /* Set timestamp based on origin pts flags */
+ if (buf_index >= 0) {
+ if (v4l2_cp_buf.timestamp.tv_usec == 0 &&
+ v4l2_cp_buf.timestamp.tv_sec == NV_V4L2_NOPTS_VALUE) {
+ /* Origin packet had no pts and user pts values. */
+ ctx->frame_pts[buf_index] = AV_NOPTS_VALUE;
+ ctx->frame_user_pts[buf_index] = AV_NOPTS_VALUE;
+ } else if (v4l2_cp_buf.timestamp.tv_sec &
+ NV_V4L2_REORDERED_OPAQUE_FLAG) {
+ /* Origin packet had only user pts value. */
+ v4l2_cp_buf.timestamp.tv_sec &=
+ (~NV_V4L2_REORDERED_OPAQUE_FLAG);
+ ctx->frame_pts[buf_index] = AV_NOPTS_VALUE;
+ ctx->frame_user_pts[buf_index] =
+ v4l2_cp_buf.timestamp.tv_usec +
+ (v4l2_cp_buf.timestamp.tv_sec * AV_TIME_BASE);
+ } else {
+ /* Origin packet had pts value. */
+ ctx->frame_pts[buf_index] =
+ v4l2_cp_buf.timestamp.tv_usec +
+ (v4l2_cp_buf.timestamp.tv_sec * AV_TIME_BASE);
+ ctx->frame_user_pts[buf_index] = AV_NOPTS_VALUE;
+ }
+ }
+
+ nvv4l2_pool_push(ctx, ctx->export_pool);
+ pthread_mutex_unlock(&ctx->queue_lock);
+
+ if (ctx->low_latency) {
+ pthread_mutex_lock(&ctx->frame_lock);
+ pthread_cond_signal(&ctx->frame_cond);
+ pthread_mutex_unlock(&ctx->frame_lock);
+ }
+
+ /* Set DMA plane handle. */
+ v4l2_cp_buf.m.planes[0].m.fd = ctx->dmabuff_fd[v4l2_cp_buf.index];
+
+ /* Queue the buffer. */
+ ret = nvv4l2_q_buffer(ctx, &v4l2_cp_buf, NULL, ctx->cp_buf_type,
+ ctx->cp_mem_type, ctx->cp_num_planes);
+
+ if (ret) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Qing failed on capture plane!\n");
+ if (ctx->draining_event) {
+ ctx->draining_event = false;
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Draining event, rejecting error\n");
+ } else {
+ ctx->in_error = true;
+ }
+ break;
+ }
+ }
+ }
+
+ if (ctx->low_latency) {
+ pthread_mutex_lock(&ctx->frame_lock);
+ pthread_cond_broadcast(&ctx->frame_cond);
+ pthread_mutex_unlock(&ctx->frame_lock);
+ }
+
+ av_log(ctx->avctx, AV_LOG_VERBOSE,
+ "Exiting decoder capture loop thread\n");
+ return NULL;
+}
+
+int
+nvv4l2_decoder_get_frame(AVCodecContext *avctx, nvv4l2_ctx_t *ctx,
+ int *buf_index, NvFrame *frame)
+{
+ struct timespec timeout;
+ struct timeval now;
+ int _buf_index;
+ int ret = 0;
+
+ /* In low latency mode, block until a decoded frame is ready. */
+ if (ctx->low_latency) {
+ pthread_mutex_lock(&ctx->frame_lock);
+ while (atomic_load(&ctx->export_pool->capacity) == 0 &&
+ !ctx->eos && !ctx->in_error && ret != ETIMEDOUT) {
+ /* 500ms timeout */
+ gettimeofday(&now, NULL);
+ timeout.tv_nsec = (now.tv_usec + 500000L) * 1000L;
+ timeout.tv_sec = now.tv_sec + timeout.tv_nsec / 1000000000L;
+ timeout.tv_nsec = timeout.tv_nsec % 1000000000L;
+
+ ret = pthread_cond_timedwait(&ctx->frame_cond,
+ &ctx->frame_lock, &timeout);
+ }
+ pthread_mutex_unlock(&ctx->frame_lock);
+ }
+
+ if (ctx->export_pool->capacity == 0)
+ return 1;
+
+ _buf_index = nvv4l2_pool_pop(ctx, ctx->export_pool);
+
+ frame->width = ctx->codec_width;
+ frame->height = ctx->codec_height;
+ frame->pts = ctx->frame_pts[_buf_index];
+ frame->user_pts = ctx->frame_user_pts[_buf_index];
+
+ *buf_index = _buf_index;
+
+ return 0;
+
+}
+
+int
+nvv4l2_decoder_put_packet(AVCodecContext *avctx, nvv4l2_ctx_t *ctx,
+ NvPacket *packet)
+{
+ int ret;
+ /* Read the encoded data and Enqueue the output
+ ** plane buffers. Exit loop in case file read is complete.
+ */
+ struct v4l2_buffer v4l2_buf_op;
+ struct v4l2_plane queue_op_planes[NV_MAX_PLANES];
+ NvBuffer *buffer;
+ memset(&v4l2_buf_op, 0, sizeof(v4l2_buf_op));
+ memset(queue_op_planes, 0, sizeof(queue_op_planes));
+ v4l2_buf_op.m.planes = queue_op_planes;
+
+ if (ctx->num_active_op_buffers < ctx->op_num_buffers) {
+ /* Get an unused buffer to add to the queue. */
+ buffer = ctx->op_buffers[ctx->num_active_op_buffers];
+ v4l2_buf_op.index = ctx->num_active_op_buffers;
+ } else {
+ /* Dequeue a finished buffer and reuse it. */
+ ret = nvv4l2_dq_buffer(ctx, &v4l2_buf_op, &buffer,
+ ctx->op_buf_type, ctx->op_mem_type, -1);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error DQing buffer at output plane!\n");
+ ctx->in_error = true;
+ return -1;
+ }
+ }
+
+ /* Copy packet data. */
+ memcpy(buffer->planes[0].data, packet->payload, packet->payload_size);
+ buffer->planes[0].bytesused = packet->payload_size;
+
+ v4l2_buf_op.m.planes[0].bytesused = buffer->planes[0].bytesused;
+
+ /* Set timestamp based on packet flags. */
+ v4l2_buf_op.flags |= V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ if (packet->pts != AV_NOPTS_VALUE) {
+ /* Packet pts is valid */
+ v4l2_buf_op.timestamp.tv_sec = packet->pts / AV_TIME_BASE;
+ v4l2_buf_op.timestamp.tv_usec = packet->pts % AV_TIME_BASE;
+ } else if (packet->user_pts != AV_NOPTS_VALUE) {
+ /* User pts is valid */
+ v4l2_buf_op.timestamp.tv_sec = packet->user_pts / AV_TIME_BASE;
+ v4l2_buf_op.timestamp.tv_usec = packet->user_pts % AV_TIME_BASE;
+ v4l2_buf_op.timestamp.tv_sec |= NV_V4L2_REORDERED_OPAQUE_FLAG;
+ } else {
+ /* No valid pts or user pts */
+ v4l2_buf_op.timestamp.tv_sec = NV_V4L2_NOPTS_VALUE;
+ v4l2_buf_op.timestamp.tv_usec = 0;
+ }
+
+ /* Queue packet on output plane. */
+ ret = nvv4l2_q_buffer(ctx, &v4l2_buf_op, buffer,
+ ctx->op_buf_type, ctx->op_mem_type, ctx->op_num_planes);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR, "Error Qing buffer at output plane!\n");
+ ctx->in_error = true;
+ return -1;
+ }
+
+ if (ctx->num_active_op_buffers < ctx->op_num_buffers) {
+ ctx->num_active_op_buffers++;
+ }
+
+ if (v4l2_buf_op.m.planes[0].bytesused == 0) {
+ ctx->eos = true;
+ av_log(avctx, AV_LOG_VERBOSE, "Input file read complete\n");
+ }
+
+ return 0;
+}
+
+nvv4l2_ctx_t *nvv4l2_create_decoder(AVCodecContext *avctx,
+ NvCodingType nv_codec_type,
+ int pix_fmt)
+{
+ nvv4l2_ctx_t *ctx = (nvv4l2_ctx_t *)NVCALLOC(1, sizeof(nvv4l2_ctx_t));
+ int ret = 0;
+ int flags = 0;
+ ctx->avctx = avctx;
+
+ /* The call creates a new V4L2 Video Decoder object
+ ** on the device node "/dev/nvhost-nvdec"
+ ** Additional flags can also be given with which the device
+ ** should be opened.
+ ** This opens the device in Blocking mode.
+ */
+ ctx->fd = v4l2_open(DECODER_DEV, flags | O_RDWR);
+ if (ctx->fd == -1) {
+ av_log(avctx, AV_LOG_ERROR, "Could not open device!\n");
+ ctx->in_error = true;
+ return ctx;
+ }
+
+ /* Initialization. */
+ ctx->cp_pixfmt = pix_fmt;
+ ctx->op_pixfmt = nvv4l2_map_nvcodec_type(nv_codec_type);
+
+ /* Get NvBuffer pixel format list version */
+ ctx->pixfmt_list_ver = nvv4l2_get_pixfmt_list_version(ctx);
+
+ /* Get a NvBuffer session for interprocess transforms */
+ ctx->buf_session = NvBufferSessionCreate();
+
+ /* Decoder code assumes that the following do not change.
+ ** If another memory type is wanted, relevant changes should be done
+ ** to the rest of the code.
+ */
+ ctx->op_mem_type = V4L2_MEMORY_USERPTR;
+ ctx->cp_mem_type = V4L2_MEMORY_DMABUF;
+
+ ctx->op_buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ ctx->cp_buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+ for (uint32_t i = 0; i < NV_MAX_BUFFERS; i++) {
+ ctx->dmabuff_fd[i] = -1;
+ ctx->plane_dma_fd[i] = -1;
+ }
+
+ /* Allocate packet pool. */
+ ctx->export_pool = (NvQueues *)NVCALLOC(1, sizeof(NvQueues));
+
+ /* Initialize mutexes */
+ pthread_mutex_init(&ctx->queue_lock, NULL);
+ pthread_mutex_init(&ctx->frame_lock, NULL);
+ pthread_cond_init(&ctx->queue_cond, NULL);
+ pthread_cond_init(&ctx->frame_cond, NULL);
+
+ /* Subscribe to Resolution change event.
+ ** This is required to catch whenever resolution change event
+ ** is triggered to set the format on capture plane.
+ */
+ ret = nvv4l2_subscribe_event(ctx->fd,
+ V4L2_EVENT_RESOLUTION_CHANGE,
+ 0, 0);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to subscribe for resolution change!\n");
+ ctx->in_error = true;
+ }
+
+ /* Set format on output plane.
+ ** The format of the encoded bitstream is set.
+ */
+ ret = set_output_plane_format(ctx, ctx->op_pixfmt, OP_PLANE_REQ_SIZEIMAGE);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error in setting output plane format!\n");
+ ctx->in_error = true;
+ }
+
+ /* Set appropriate controls.
+ ** V4L2_CID_MPEG_VIDEO_DISABLE_COMPLETE_FRAME_INPUT control is
+ ** set to false as the application always sends NALUs.
+ ** Also, mandatory when V4L2_BUF_FLAG_TIMESTAMP_COPY is used.
+ */
+ ret =
+ nvv4l2_set_ext_controls(ctx->fd,
+ V4L2_CID_MPEG_VIDEO_DISABLE_COMPLETE_FRAME_INPUT,
+ 0, 0);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set control enable complete frame!\n");
+ ctx->in_error = true;
+ }
+
+ /* Request buffers on output plane to fill
+ ** the input bitstream.
+ */
+ ret = nvv4l2_req_buffers_on_output_plane(ctx,
+ ctx->op_buf_type,
+ ctx->op_mem_type, 10);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error in requesting buffers on output plane!\n");
+ ctx->in_error = true;
+ }
+
+ for (uint32_t i = 0; i < ctx->op_num_buffers; i++) {
+ if (nvv4l2_allocate_memory(ctx, ctx->op_buffers[i])) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Buffer mapping error on output plane!\n");
+ ctx->in_error = true;
+ }
+ }
+
+ /* Start stream processing on output plane
+ ** by setting the streaming status ON.
+ */
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_STREAMON, &ctx->op_buf_type);
+ if (ret != 0) {
+ av_log(avctx, AV_LOG_ERROR, "Streaming error on output plane!\n");
+ ctx->in_error = true;
+ }
+
+ ctx->op_streamon = true;
+
+ /* Create and start capture loop thread. */
+ pthread_create(&ctx->capture_thread, NULL, dec_capture_thread, ctx);
+
+ return ctx;
+}
+
+int nvv4l2_decoder_close(AVCodecContext *avctx, nvv4l2_ctx_t *ctx)
+{
+ int ret;
+
+ if (!ctx)
+ return 0;
+
+ pthread_mutex_lock(&ctx->queue_lock);
+ ctx->eos = true;
+ pthread_mutex_unlock(&ctx->queue_lock);
+ if (ctx->fd != -1) {
+ /* Stop streaming on both planes. */
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_STREAMOFF, &ctx->op_buf_type);
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_STREAMOFF, &ctx->cp_buf_type);
+ ctx->op_streamon = false;
+ ctx->cp_streamon = false;
+
+ /* Wait for capture thread to exit. */
+ if (ctx->capture_thread) {
+ pthread_join(ctx->capture_thread, NULL);
+ }
+
+ /* Request 0 buffers on both planes. */
+ ret = nvv4l2_req_buffers_on_output_plane(ctx,
+ ctx->op_buf_type,
+ ctx->op_mem_type, 0);
+
+ ret = nvv4l2_req_buffers_on_capture_plane(ctx,
+ ctx->cp_buf_type,
+ ctx->cp_mem_type, 0);
+
+ /* All allocated DMA buffers must be destroyed. */
+ for (uint32_t i = 0; i < ctx->cp_num_buffers; i++) {
+ if (ctx->dmabuff_fd[i] != -1) {
+ ret = NvBufferDestroy(ctx->dmabuff_fd[i]);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to destroy dma buffer!\n");
+ }
+ ctx->dmabuff_fd[i] = -1;
+ }
+ }
+
+ /* Destroy all allocated transform/export DMA buffers. */
+ for (uint32_t i = 0; i < NV_MAX_BUFFERS; i++) {
+ if (ctx->plane_dma_fd[i] != -1) {
+ ret = NvBufferDestroy(ctx->plane_dma_fd[i]);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to destroy plane buffer!\n");
+ }
+ ctx->plane_dma_fd[i] = -1;
+ }
+ }
+
+ /* Destroy NvBuffer session. */
+ if (ctx->buf_session)
+ NvBufferSessionDestroy(ctx->buf_session);
+
+ NVFREE(ctx->export_pool);
+
+ /* Close the opened V4L2 device. */
+ ret = v4l2_close(ctx->fd);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to close the device!\n");
+ }
+
+ /* Free mutexes */
+ pthread_mutex_destroy(&ctx->queue_lock);
+ pthread_mutex_destroy(&ctx->frame_lock);
+ pthread_cond_destroy(&ctx->queue_cond);
+ pthread_cond_destroy(&ctx->frame_cond);
+ }
+
+ /* Report application run status on exit. */
+ if (ctx->in_error) {
+ av_log(avctx, AV_LOG_VERBOSE, "Decoder Run failed\n");
+ } else {
+ av_log(avctx, AV_LOG_VERBOSE, "Decoder Run was successful\n");
+ }
+
+ NVFREE(ctx);
+
+ return ret;
+}
+
+static NvCodingType map_avcodec_id(enum AVCodecID id)
+{
+ switch (id) {
+ case AV_CODEC_ID_H264:
+ return NvVideoCodec_H264;
+ case AV_CODEC_ID_HEVC:
+ return NvVideoCodec_HEVC;
+ case AV_CODEC_ID_MPEG2VIDEO:
+ return NvVideoCodec_MPEG2;
+ case AV_CODEC_ID_MPEG4:
+ return NvVideoCodec_MPEG4;
+ case AV_CODEC_ID_VP8:
+ return NvVideoCodec_VP8;
+ case AV_CODEC_ID_VP9:
+ return NvVideoCodec_VP9;
+ }
+ return NvVideoCodec_UNDEFINED;
+}
+
+static int nvv4l2dec_init(AVCodecContext *avctx)
+{
+ nvv4l2DecodeContext *nvv4l2_ctx = avctx->priv_data;
+ NvCodingType nv_codec_type = map_avcodec_id(avctx->codec_id);
+ int pix_fmt;
+
+ if (nv_codec_type == NvVideoCodec_UNDEFINED) {
+ av_log(avctx, AV_LOG_ERROR, "Unsupported codec ID %d!\n",
+ avctx->codec_id);
+ return AVERROR_BUG;
+ }
+
+ switch (avctx->pix_fmt) {
+ case AV_PIX_FMT_NONE:
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+ case AV_PIX_FMT_YUV420P:
+ pix_fmt = V4L2_PIX_FMT_YUV420M;
+ break;
+ case AV_PIX_FMT_NV12:
+ pix_fmt = V4L2_PIX_FMT_NV12M;
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format %d!\n",
+ avctx->pix_fmt);
+ return AVERROR_BUG;
+ }
+
+ nvv4l2_ctx->ctx = nvv4l2_create_decoder(avctx, nv_codec_type, pix_fmt);
+
+ if (!nvv4l2_ctx->ctx || nvv4l2_ctx->ctx->in_error) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to create nvv4l2 decoder!\n");
+
+ if (nvv4l2_ctx->ctx && nvv4l2_ctx->ctx->in_error) {
+ nvv4l2_decoder_close(avctx, nvv4l2_ctx->ctx);
+ }
+
+ return AVERROR_UNKNOWN;
+ }
+
+ /*
+ ** Check if low latency is needed.
+ ** Depends on whole frames received instead of slices.
+ ** Otherwise the decoder only starts streaming after a
+ ** required amount of packets received.
+ */
+ nvv4l2_ctx->ctx->low_latency =
+ (avctx->flags & AV_CODEC_FLAG_LOW_DELAY) ? true : false;
+
+ return 0;
+}
+
+static void nvv4l2dec_flush(AVCodecContext *avctx)
+{
+ nvv4l2DecodeContext *nvv4l2_ctx = avctx->priv_data;
+ nvv4l2_ctx_t *ctx = nvv4l2_ctx->ctx;
+ int ret = 0;
+
+ pthread_mutex_lock(&ctx->queue_lock);
+ /* Flush all queued buffers from output and capture plane. */
+ if (ctx->op_streamon && ctx->cp_streamon &&
+ (ctx->num_queued_op_buffers || ctx->num_active_op_buffers)) {
+ /* Stop streaming on both planes. */
+ v4l2_ioctl(ctx->fd, VIDIOC_STREAMOFF, &ctx->op_buf_type);
+ v4l2_ioctl(ctx->fd, VIDIOC_STREAMOFF, &ctx->cp_buf_type);
+ ctx->op_streamon = false;
+ ctx->cp_streamon = false;
+
+ /* Turn on output plane streaming. */
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_STREAMON, &ctx->op_buf_type);
+ if (ret != 0) {
+ av_log(avctx, AV_LOG_ERROR, "Streaming error on output plane!\n");
+ ctx->in_error = true;
+ } else {
+ ctx->op_streamon = true;
+ }
+
+ ctx->draining_event = true;
+
+ /* Re-enqueue all now empty buffers on capture plane. */
+ for (uint32_t i = 0; i < ctx->cp_num_buffers; i++) {
+ struct v4l2_buffer v4l2_buf;
+ struct v4l2_plane planes[NV_MAX_PLANES];
+
+ memset(&v4l2_buf, 0, sizeof(v4l2_buf));
+ memset(planes, 0, sizeof(planes));
+
+ v4l2_buf.index = i;
+ v4l2_buf.m.planes = planes;
+ v4l2_buf.type = ctx->cp_buf_type;
+ v4l2_buf.memory = ctx->cp_mem_type;
+ v4l2_buf.length = ctx->cp_num_planes;
+ /* Set DMA plane handle */
+ v4l2_buf.m.planes[0].m.fd = ctx->dmabuff_fd[i];
+ v4l2_buf.m.planes[1].m.fd = ctx->dmabuff_fd[i];
+
+ pthread_mutex_unlock(&ctx->queue_lock);
+ ret = nvv4l2_q_buffer(ctx, &v4l2_buf, ctx->cp_buffers[i],
+ ctx->cp_buf_type, ctx->cp_mem_type,
+ ctx->cp_num_planes);
+ pthread_mutex_lock(&ctx->queue_lock);
+
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Qing empty failed on capture plane!\n");
+ }
+ }
+
+ ctx->num_active_op_buffers = 0;
+ ctx->num_queued_op_buffers = 0;
+ ctx->num_queued_cp_buffers = 0;
+
+ /* Turn on capture plane streaming. */
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_STREAMON, &ctx->cp_buf_type);
+ if (ret != 0) {
+ av_log(avctx, AV_LOG_ERROR, "Streaming error on capture plane!\n");
+ ctx->in_error = true;
+ } else {
+ ctx->cp_streamon = true;
+ }
+ }
+
+ /* Flush all decoded frames from frame pool */
+ while (ctx->export_pool->capacity != 0) {
+ nvv4l2_pool_pop(ctx, ctx->export_pool);
+ }
+ ctx->export_pool->front = 0;
+ ctx->export_pool->back = 0;
+ pthread_mutex_unlock(&ctx->queue_lock);
+}
+
+static int nvv4l2dec_close(AVCodecContext *avctx)
+{
+ nvv4l2DecodeContext *nvv4l2_ctx = avctx->priv_data;
+ return nvv4l2_decoder_close(avctx, nvv4l2_ctx->ctx);
+}
+
+static int
+nvv4l2dec_decode(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ nvv4l2DecodeContext *nvv4l2_ctx = avctx->priv_data;
+ nvv4l2_ctx_t *ctx = nvv4l2_ctx->ctx;
+ AVFrame *avframe = (AVFrame *)data;
+ NvFrame _nvframe = { 0 };
+ int processed_size = 0;
+ int buf_index = -1;
+
+ if (ctx->in_error) {
+ return AVERROR_UNKNOWN;
+ }
+
+ if (avpkt->size) {
+ NvPacket packet;
+ packet.payload_size = avpkt->size;
+ packet.payload = avpkt->data;
+ packet.pts = avpkt->pts;
+ packet.user_pts = avctx->reordered_opaque;
+
+ if (!nvv4l2_decoder_put_packet(avctx, ctx, &packet)) {
+ processed_size = avpkt->size;
+ } else {
+ return AVERROR_UNKNOWN;
+ }
+ }
+
+ /* Get a decoded frame if any. */
+ if (nvv4l2_decoder_get_frame(avctx, ctx, &buf_index, &_nvframe))
+ return processed_size;
+
+ /* Set coded width to aligned size to fit the transformation.
+ ** It gets restored after transformation by default.
+ */
+ avctx->coded_width = ctx->plane_width_aligned;
+
+ /* Get frame data buffers. */
+ if (ff_get_buffer(avctx, avframe, 0) < 0)
+ return AVERROR(ENOMEM);
+
+ /* Export decoded frame data. */
+ if (buf_index >= 0 && avframe->data[0]) {
+ NvBuffer2Raw(ctx->plane_dma_fd[buf_index], 0,
+ ctx->plane_width[0], ctx->plane_height[0],
+ avframe->data[0]);
+ NvBuffer2Raw(ctx->plane_dma_fd[buf_index], 1,
+ ctx->plane_width[1], ctx->plane_height[1],
+ avframe->data[1]);
+ if (ctx->cp_pixfmt == V4L2_PIX_FMT_YUV420M) {
+ NvBuffer2Raw(ctx->plane_dma_fd[buf_index], 2,
+ ctx->plane_width[2], ctx->plane_height[2],
+ avframe->data[2]);
+ }
+ }
+
+ avframe->width = _nvframe.width;
+ avframe->height = _nvframe.height;
+
+ avframe->format = avctx->pix_fmt;
+ avframe->pkt_dts = AV_NOPTS_VALUE;
+
+ /* Decide which timestamps to set. */
+ if (_nvframe.pts != AV_NOPTS_VALUE) {
+ avframe->pts = _nvframe.pts;
+ } else {
+ avframe->pts = _nvframe.pts;
+ avframe->reordered_opaque = _nvframe.user_pts;
+ }
+
+ avframe->key_frame = 0;
+
+ avctx->coded_width = _nvframe.width;
+ avctx->coded_height = _nvframe.height;
+ avctx->width = _nvframe.width;
+ avctx->height = _nvframe.height;
+
+ *got_frame = 1;
+
+ return processed_size;
+}
+
+#define NVV4L2_DEC_CLASS(NAME) \
+ static const AVClass nvv4l2_##NAME##_dec_class = { \
+ .class_name = "nvv4l2_" #NAME "_dec", \
+ .version = LIBAVUTIL_VERSION_INT, \
+ };
+
+#define NVV4L2_DEC(NAME, ID, BSFS) \
+ NVV4L2_DEC_CLASS(NAME) \
+ AVCodec ff_##NAME##_nvv4l2_decoder = { \
+ .name = #NAME "_nvv4l2", \
+ .long_name = NULL_IF_CONFIG_SMALL(#NAME " NVV4L2 HW decoder for Tegra"), \
+ .type = AVMEDIA_TYPE_VIDEO, \
+ .id = ID, \
+ .priv_data_size = sizeof(nvv4l2DecodeContext), \
+ .init = nvv4l2dec_init, \
+ .close = nvv4l2dec_close, \
+ .decode = nvv4l2dec_decode, \
+ .flush = nvv4l2dec_flush, \
+ .priv_class = &nvv4l2_##NAME##_dec_class, \
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | \
+ AV_CODEC_CAP_AVOID_PROBING, \
+ .bsfs = BSFS, \
+ .wrapper_name = "nvv4l2", \
+ .pix_fmts =(const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, \
+ AV_PIX_FMT_NV12, \
+ AV_PIX_FMT_NONE }, \
+ };
+
+NVV4L2_DEC(h264, AV_CODEC_ID_H264, "h264_mp4toannexb");
+NVV4L2_DEC(hevc, AV_CODEC_ID_HEVC, "hevc_mp4toannexb");
+NVV4L2_DEC(mpeg2, AV_CODEC_ID_MPEG2VIDEO, NULL);
+NVV4L2_DEC(mpeg4, AV_CODEC_ID_MPEG4, NULL);
+NVV4L2_DEC(vp9, AV_CODEC_ID_VP9, NULL);
+NVV4L2_DEC(vp8, AV_CODEC_ID_VP8, NULL);
diff -Naur ffmpeg-4.3.2-Matrix-19.1/libavcodec/nvv4l2_enc.c ffmpeg-4.3.2-Matrix-19.1-2/libavcodec/nvv4l2_enc.c
--- ffmpeg-4.3.2-Matrix-19.1/libavcodec/nvv4l2_enc.c 1970-01-01 01:00:00.000000000 +0100
+++ ffmpeg-4.3.2-Matrix-19.1-2/libavcodec/nvv4l2_enc.c 2022-03-20 03:26:30.814729473 +0100
@@ -0,0 +1,1440 @@
+/*
+ * Copyright (c) 2021-2022, CTCaer <ctcaer@gmail.com>
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "internal.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+
+#include "nvv4l2.h"
+
+#define ENCODER_DEV "/dev/nvhost-msenc"
+#define PACKET_DEFAULT_SIZE (2*1024*1024)
+
+/*
+ ** Output plane format support:
+ ** YM12 (YUV 4:2:0)
+ ** NM12 (YUV 4:2:0 interleaved)
+ ** YM24 (YUV 4:4:4)
+ ** PM10 (YUV 4:2:0 10-bit interleaved)
+ **
+ ** Capture plane format support:
+ ** H264 (H264 Encoded bitstream)
+ ** H265 (H265 Encoded bitstream)
+ ** VP80 (VP8 Encoded bitstream)
+ */
+
+/*
+ ** Output plane memory type support:
+ ** V4L2_MEMORY_MMAP
+ ** V4L2_MEMORY_DMABUF
+ ** Capture plane memory type support:
+ ** V4L2_MEMORY_MMAP
+ */
+
+typedef struct {
+ const AVClass *class;
+ nvv4l2_ctx_t *ctx;
+ int num_capture_buffers;
+ int profile;
+ int level;
+ int tier;
+ int rc;
+ int preset;
+ int lossless;
+ int twopass;
+} nvv4l2EncodeContext;
+
+static int
+set_output_plane_format(AVCodecContext *avctx, nvv4l2_ctx_t *ctx,
+ uint32_t pixfmt, uint32_t width, uint32_t height)
+{
+ int ret;
+ struct v4l2_format format;
+ uint32_t num_bufferplanes;
+ NvBufferPlaneFormat planefmts[NV_MAX_PLANES];
+
+ /* Get plane format */
+ ret = nvv4l2_fill_buffer_plane_format(ctx, &num_bufferplanes, planefmts,
+ width, height, pixfmt);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error getting output plane format!\n");
+ ctx->in_error = true;
+ return ret;
+ }
+ ctx->op_num_planes = num_bufferplanes;
+
+ /* Set plane format. */
+ for (uint32_t j = 0; j < num_bufferplanes; ++j) {
+ ctx->op_planefmts[j] = planefmts[j];
+ }
+ memset(&format, 0, sizeof(struct v4l2_format));
+ format.type = ctx->op_buf_type;
+ format.fmt.pix_mp.width = width;
+ format.fmt.pix_mp.height = height;
+ format.fmt.pix_mp.pixelformat = pixfmt;
+ format.fmt.pix_mp.num_planes = num_bufferplanes;
+
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_S_FMT, &format);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error in setting output plane format!\n");
+ ctx->in_error = true;
+ } else {
+ ctx->op_num_planes = format.fmt.pix_mp.num_planes;
+ for (uint32_t j = 0; j < ctx->op_num_planes; j++) {
+ ctx->op_planefmts[j].stride =
+ format.fmt.pix_mp.plane_fmt[j].bytesperline;
+ ctx->op_planefmts[j].sizeimage =
+ format.fmt.pix_mp.plane_fmt[j].sizeimage;
+ }
+ }
+
+ return ret;
+}
+
+static int
+set_capture_plane_format(AVCodecContext *avctx, nvv4l2_ctx_t *ctx,
+ uint32_t pixfmt, uint32_t width,
+ uint32_t height, uint32_t sizeimage)
+{
+ int ret;
+ struct v4l2_format format;
+
+ memset(&format, 0, sizeof(struct v4l2_format));
+ format.type = ctx->cp_buf_type;
+ format.fmt.pix_mp.pixelformat = pixfmt;
+ format.fmt.pix_mp.width = width;
+ format.fmt.pix_mp.height = height;
+ format.fmt.pix_mp.num_planes = 1;
+ format.fmt.pix_mp.plane_fmt[0].sizeimage = sizeimage;
+
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_S_FMT, &format);
+
+ if (ret == 0) {
+ ctx->cp_num_planes = format.fmt.pix_mp.num_planes;
+ for (uint32_t i = 0; i < ctx->cp_num_planes; ++i) {
+ ctx->cp_planefmts[i].stride =
+ format.fmt.pix_mp.plane_fmt[i].bytesperline;
+ ctx->cp_planefmts[i].sizeimage =
+ format.fmt.pix_mp.plane_fmt[i].sizeimage;
+ }
+ } else {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error in setting capture plane format!\n");
+ ctx->in_error = true;
+ }
+
+ return ret;
+}
+
+static void *enc_capture_thread(void *arg)
+{
+ nvv4l2_ctx_t *ctx = (nvv4l2_ctx_t *)arg;
+ uint32_t packet_size;
+ int buf_index;
+ int ret;
+
+ /* Check for EOS event in case stream finished. */
+ while (!ctx->in_error && !ctx->eos) {
+ /* Main Capture loop for DQ and Q. */
+ struct v4l2_buffer v4l2_cp_buf;
+ struct v4l2_plane capture_planes[NV_MAX_PLANES];
+ v4l2_ctrl_videoenc_outputbuf_metadata enc_metadata;
+ NvBuffer *cp_buffer = NULL;
+
+ memset(&v4l2_cp_buf, 0, sizeof(v4l2_cp_buf));
+ memset(capture_planes, 0, sizeof(capture_planes));
+ v4l2_cp_buf.m.planes = capture_planes;
+ v4l2_cp_buf.length = 1;
+
+ /* Dequeue the filled buffer. */
+ if (nvv4l2_dq_buffer(ctx, &v4l2_cp_buf, &cp_buffer,
+ ctx->cp_buf_type, ctx->cp_mem_type, 0)) {
+ if (errno == EAGAIN) {
+ usleep(1000);
+ }
+ continue;
+ }
+
+ packet_size = cp_buffer->planes[0].bytesused;
+
+ if (packet_size == 0) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Got 0 size buffer in capture!\n");
+ ctx->in_error = true;
+ break;
+ }
+
+ buf_index = nvv4l2_pool_idx_next(ctx, ctx->export_pool);
+
+ if (buf_index >= 0) {
+ /* Ensure packet buffer fits new packet */
+ if (ctx->packet_buf_size[buf_index] < packet_size) {
+ NVFREE(ctx->packet[buf_index]);
+ ctx->packet[buf_index] = (unsigned char *)NVMALLOC(packet_size);
+ ctx->packet_buf_size[buf_index] = packet_size;
+ }
+
+ ctx->packet_size[buf_index] = packet_size;
+ memcpy(ctx->packet[buf_index], cp_buffer->planes[0].data,
+ packet_size);
+
+ ctx->frame_pts[buf_index] = v4l2_cp_buf.timestamp.tv_usec +
+ (v4l2_cp_buf.timestamp.tv_sec *
+ AV_TIME_BASE);
+
+ ret = nvv4l2_get_ext_control_metadata(ctx->fd,
+ v4l2_cp_buf.index,
+ &enc_metadata);
+ if (ret) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Failed getting metadata!\n");
+ ctx->in_error = true;
+ break;
+ }
+ ctx->packet_keyflag[buf_index] =
+ enc_metadata.KeyFrame ? true : false;
+ }
+
+ nvv4l2_pool_push(ctx, ctx->export_pool);
+
+ /* Queue the buffer. */
+ ret = nvv4l2_q_buffer(ctx, &v4l2_cp_buf, cp_buffer, ctx->cp_buf_type,
+ ctx->cp_mem_type, ctx->cp_num_planes);
+
+ if (ret) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Qing failed on capture plane!\n");
+ ctx->in_error = true;
+ break;
+ }
+ }
+
+ av_log(ctx->avctx, AV_LOG_VERBOSE,
+ "Exiting encoder capture loop thread\n");
+
+ return NULL;
+}
+
+nvv4l2_ctx_t *nvv4l2_create_encoder(AVCodecContext *avctx,
+ NvEncoder *encoder,
+ NvCodingType nv_codec_type,
+ int pix_fmt)
+{
+ nvv4l2EncodeContext *nvv4l2_ctx = avctx->priv_data;
+
+ int ret;
+ int flags = 0;
+ nvv4l2_ctx_t *ctx = (nvv4l2_ctx_t *)NVCALLOC(1, sizeof(nvv4l2_ctx_t));
+ ctx->avctx = avctx;
+ ctx->enc = encoder;
+
+ /* The call creates a new V4L2 Video Decoder object
+ ** on the device node "/dev/nvhost-msenc"
+ ** Additional flags can also be given with which the device
+ ** should be opened.
+ ** This opens the device in Blocking mode.
+ */
+ ctx->fd = v4l2_open(ENCODER_DEV, flags | O_RDWR);
+ if (ctx->fd == -1) {
+ av_log(avctx, AV_LOG_ERROR, "Could not open device!\n");
+ ctx->in_error = true;
+ return ctx;
+ }
+
+ /* Initialization. */
+ ctx->codec_width = encoder->width;
+ ctx->codec_height = encoder->height;
+ ctx->low_latency = encoder->low_latency;
+ ctx->op_pixfmt = pix_fmt;
+ ctx->cp_pixfmt = nvv4l2_map_nvcodec_type(nv_codec_type);
+
+ /* Get NvBuffer pixel format list version */
+ ctx->pixfmt_list_ver = nvv4l2_get_pixfmt_list_version(ctx);
+
+ /* Encoder code assumes that the following do not change.
+ ** If another memory type is wanted, relevant changes should be done
+ ** to the rest of the code.
+ */
+ ctx->op_mem_type = V4L2_MEMORY_DMABUF;
+ ctx->cp_mem_type = V4L2_MEMORY_MMAP;
+
+ ctx->op_buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ ctx->cp_buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+ for (uint32_t i = 0; i < NV_MAX_BUFFERS; i++)
+ ctx->plane_dma_fd[i] = -1;
+
+ /* Allocate packet pool. */
+ ctx->export_pool = (NvQueues *)NVCALLOC(1, sizeof(NvQueues));
+ for(int index = 0; index < NV_MAX_BUFFERS; index++) {
+ ctx->packet[index] = (unsigned char *)NVMALLOC(PACKET_DEFAULT_SIZE);
+ ctx->packet_buf_size[index] = PACKET_DEFAULT_SIZE;
+ }
+
+ /* Initialize mutexes */
+ pthread_mutex_init(&ctx->queue_lock, NULL);
+ pthread_cond_init(&ctx->queue_cond, NULL);
+
+ /* Set format on capture plane. */
+ ret = set_capture_plane_format(avctx, ctx, ctx->cp_pixfmt,
+ ctx->codec_width, ctx->codec_height,
+ PACKET_DEFAULT_SIZE);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error in setting capture plane format!\n");
+ ctx->in_error = true;
+ }
+
+ /* Set format on output plane. */
+ ret = set_output_plane_format(avctx, ctx, ctx->op_pixfmt,
+ ctx->codec_width, ctx->codec_height);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error in setting output plane format!\n");
+ ctx->in_error = true;
+ }
+
+ /* Set max performance mode if low latency is requested. */
+ if (ctx->low_latency) {
+ ret =
+ nvv4l2_set_ext_controls(ctx->fd,
+ V4L2_CID_MPEG_VIDEO_MAX_PERFORMANCE, 0, 1);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set control max performance!\n");
+ ctx->in_error = true;
+ }
+ }
+
+ /* Set encoder bitrate. */
+ ret = nvv4l2_set_ext_controls(ctx->fd, V4L2_CID_MPEG_VIDEO_BITRATE,
+ V4L2_CTRL_CLASS_MPEG,
+ ctx->enc->bitrate);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set encoder bitrate!\n");
+ ctx->in_error = true;
+ }
+
+ /* Set encoder HW Preset Type. */
+ ret = nvv4l2_set_ext_controls(ctx->fd,
+ V4L2_CID_MPEG_VIDEOENC_HW_PRESET_TYPE_PARAM,
+ V4L2_CTRL_CLASS_MPEG,
+ ctx->enc->preset_type);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set encoder HW Preset Type!\n");
+ ctx->in_error = true;
+ }
+
+ /* Set number of reference frames. */
+ if (ctx->enc->num_ref) {
+ ret = nvv4l2_set_ext_controls(ctx->fd,
+ V4L2_CID_MPEG_VIDEOENC_NUM_REFERENCE_FRAMES,
+ V4L2_CTRL_CLASS_MPEG,
+ ctx->enc->num_ref);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set num reference frames!\n");
+ ctx->in_error = true;
+ }
+ }
+
+ /* Set number of B Frames. */
+ if (ctx->enc->num_b_frames && nv_codec_type == NvVideoCodec_H264) {
+ ret = nvv4l2_set_ext_controls(ctx->fd,
+ V4L2_CID_MPEG_VIDEOENC_NUM_BFRAMES,
+ V4L2_CTRL_CLASS_MPEG,
+ ctx->enc->num_b_frames);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set number of B Frames!\n");
+ ctx->in_error = true;
+ }
+ }
+
+ /* Set encoder profile. */
+ ret = nvv4l2_set_ext_controls(ctx->fd, nv_codec_type == NvVideoCodec_H264 ?
+ V4L2_CID_MPEG_VIDEO_H264_PROFILE :
+ V4L2_CID_MPEG_VIDEO_H265_PROFILE,
+ V4L2_CTRL_CLASS_MPEG,
+ ctx->enc->profile);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set encoder profile!\n");
+ ctx->in_error = true;
+ }
+
+ /* Set encoder level. */
+ ret = nvv4l2_set_ext_controls(ctx->fd, nv_codec_type == NvVideoCodec_H264 ?
+ V4L2_CID_MPEG_VIDEO_H264_LEVEL :
+ V4L2_CID_MPEG_VIDEOENC_H265_LEVEL,
+ V4L2_CTRL_CLASS_MPEG,
+ ctx->enc->level);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set encoder level!\n");
+ ctx->in_error = true;
+ }
+
+ if (!ctx->enc->lossless) {
+ /* Set encoder rate control mode. */
+ ret = nvv4l2_set_ext_controls(ctx->fd, V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+ V4L2_CTRL_CLASS_MPEG,
+ ctx->enc->ratecontrol);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set encoder rate control mode!\n");
+ ctx->in_error = true;
+ }
+
+ /* Set encoder max bitrate for VBR. */
+ if (ctx->enc->ratecontrol == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) {
+
+ uint32_t max_bitrate = 1.2f * ctx->enc->bitrate;
+ ret = nvv4l2_set_ext_controls(ctx->fd,
+ V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+ V4L2_CTRL_CLASS_MPEG,
+ max_bitrate);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set encoder max bitrate for VBR!\n");
+ ctx->in_error = true;
+ }
+ }
+ } else {
+ /* Set constant qp configuration for lossless encoding enabled */
+ ret = nvv4l2_set_ext_control_constant_qp(ctx->fd, 0);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set encoder qp to 0 for lossless encoding!\n");
+ ctx->in_error = true;
+ }
+ }
+
+ /* Set Two-pass CBR mode. */
+ if (ctx->enc->twopass) {
+ /* Set encoder IDR interval. */
+ ret = nvv4l2_set_ext_controls(ctx->fd,
+ V4L2_CID_MPEG_VIDEOENC_TWO_PASS_CBR,
+ V4L2_CTRL_CLASS_MPEG,
+ 1);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set encoder 2-pass cbr!\n");
+ ctx->in_error = true;
+ }
+ }
+
+ /* Set encoder IDR interval. */
+ ret = nvv4l2_set_ext_controls(ctx->fd, V4L2_CID_MPEG_VIDEO_IDR_INTERVAL,
+ V4L2_CTRL_CLASS_MPEG,
+ ctx->enc->idr_interval);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set encoder IDR interval!\n");
+ ctx->in_error = true;
+ }
+
+ /* Set encoder quantization parameters. */
+ if (ctx->enc->qmin != -1 || ctx->enc->qmax != -1) {
+ ret = nvv4l2_set_ext_control_qp_range(ctx->fd,
+ ctx->enc->qmin, ctx->enc->qmax);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set encoder quantization parameters!\n");
+ ctx->in_error = true;
+ }
+ }
+
+ /* Set encoder I-Frame interval. */
+ ret = nvv4l2_set_ext_controls(ctx->fd, V4L2_CID_MPEG_VIDEO_GOP_SIZE,
+ V4L2_CTRL_CLASS_MPEG,
+ ctx->enc->iframe_interval);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set encoder I-Frame interval!\n");
+ ctx->in_error = true;
+ }
+
+ /* Set insertSPSPPSAtIDR. */
+ if (ctx->enc->sps_pps_at_idr) {
+ ret = nvv4l2_set_ext_controls(ctx->fd,
+ V4L2_CID_MPEG_VIDEOENC_INSERT_SPS_PPS_AT_IDR,
+ V4L2_CTRL_CLASS_MPEG,
+ 1);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set insertSPSPPSAtIDR!\n");
+ ctx->in_error = true;
+ }
+ }
+
+ /* Set encoder framerate. */
+ ret = nvv4l2_set_stream_control_framerate(ctx->fd,
+ ctx->op_mem_type,
+ ctx->enc->fps_n,
+ ctx->enc->fps_d);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to set framerate!\n");
+ ctx->in_error = true;
+ }
+
+ /* Request max 10 buffers on output plane.
+ ** Number of received buffers normally is lower (6). */
+ ret = nvv4l2_req_buffers_on_output_plane(ctx,
+ ctx->op_buf_type,
+ ctx->op_mem_type,
+ 10);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error in requesting buffers on output plane!\n");
+ ctx->in_error = true;
+ }
+
+ /* Create import DMA buffers. */
+ for (uint32_t i = 0; i < ctx->op_num_buffers; i++) {
+ NvBufferCreateParams iParams;
+ memset(&iParams, 0, sizeof(NvBufferCreateParams));
+ iParams.width = ctx->codec_width;
+ iParams.height = ctx->codec_height;
+ iParams.layout = NvBufferLayout_Pitch;
+ iParams.payloadType = NvBufferPayload_SurfArray;
+ iParams.nvbuf_tag = NvBufferTag_VIDEO_ENC;
+ switch (ctx->op_pixfmt) {
+ case V4L2_PIX_FMT_YUV444M:
+ iParams.colorFormat = NvBufferColorFormat_YUV444;
+ break;
+ case V4L2_PIX_FMT_P010M:
+ iParams.layout = NvBufferLayout_BlockLinear;
+ iParams.colorFormat = NvBufferColorFormat_NV12_10LE;
+ break;
+ case V4L2_PIX_FMT_NV12M:
+ iParams.colorFormat = NvBufferColorFormat_NV12;
+ break;
+ default:
+ iParams.colorFormat = NvBufferColorFormat_YUV420;
+ break;
+ }
+
+ if (ctx->enc->profile == V4L2_MPEG_VIDEO_H265_PROFILE_MAIN10) {
+ iParams.layout = NvBufferLayout_BlockLinear;
+ iParams.colorFormat = NvBufferColorFormat_NV12_10LE;
+ }
+
+ /* Increment color format if NvBuffer is newer. */
+ if (ctx->pixfmt_list_ver == NvBufferPixFmtVersion_New &&
+ iParams.colorFormat > NvBufferColorFormat_YUV420) {
+ iParams.colorFormat++;
+ }
+
+ ret = NvBufferCreateEx(&ctx->plane_dma_fd[i], &iParams);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR, "Creation of dmabuf failed!\n");
+ ctx->in_error = true;
+ }
+ }
+
+ /* Request buffers on capture plane. */
+ ret = nvv4l2_req_buffers_on_capture_plane(ctx,
+ ctx->cp_buf_type,
+ ctx->cp_mem_type,
+ nvv4l2_ctx->num_capture_buffers);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error in requesting buffers on capture plane!\n");
+ ctx->in_error = true;
+ }
+
+ /* Map buffers on capture plane */
+ for (uint32_t i = 0; i < ctx->cp_num_buffers; i++) {
+ ret = nvv4l2_query_buffer(ctx, ctx->cp_buf_type,
+ ctx->cp_mem_type, ctx->cp_num_planes, i);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to query buffer on capture plane!\n");
+ ctx->in_error = true;
+ }
+ ret = nvv4l2_export_buffer(ctx, ctx->cp_buf_type,
+ ctx->cp_num_planes, i);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to export buffer on capture plane!\n");
+ ctx->in_error = true;
+ }
+ ret = nvv4l2_map(ctx, ctx->cp_buffers[i]);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to map buffer on capture plane!\n");
+ ctx->in_error = true;
+ }
+ }
+
+ /* Start stream processing on output plane. */
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_STREAMON, &ctx->op_buf_type);
+ if (ret != 0) {
+ av_log(avctx, AV_LOG_ERROR, "Streaming error on output plane!\n");
+ ctx->in_error = true;
+ }
+ ctx->op_streamon = true;
+
+ /* Set streaming status ON on capture plane. */
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_STREAMON, &ctx->cp_buf_type);
+ if (ret != 0) {
+ av_log(avctx, AV_LOG_ERROR, "Streaming error on capture plane!\n");
+ ctx->in_error = true;
+ }
+ ctx->cp_streamon = true;
+
+ /* Create and start capture loop thread. */
+ pthread_create(&ctx->capture_thread, NULL, enc_capture_thread, ctx);
+
+ /* Enqueue all the empty capture plane buffers. */
+ for (uint32_t i = 0; i < ctx->cp_num_buffers; i++){
+ struct v4l2_buffer v4l2_buf;
+ struct v4l2_plane planes[NV_MAX_PLANES];
+ memset(&v4l2_buf, 0, sizeof(v4l2_buf));
+ memset(planes, 0, NV_MAX_PLANES * sizeof(struct v4l2_plane));
+
+ v4l2_buf.index = i;
+ v4l2_buf.m.planes = planes;
+
+ ret = nvv4l2_q_buffer(ctx, &v4l2_buf, ctx->cp_buffers[i],
+ ctx->cp_buf_type, ctx->cp_mem_type,
+ ctx->cp_num_planes);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR, "Qing failed on capture plane!\n");
+ ctx->in_error = true;
+ }
+ }
+
+ return ctx;
+}
+
+int nvv4l2_encoder_put_frame(AVCodecContext *avctx, nvv4l2_ctx_t *ctx,
+ NvFrame *frame)
+{
+ int ret;
+ struct v4l2_buffer v4l2_buf_op;
+ struct v4l2_plane queue_op_planes[NV_MAX_PLANES];
+ NvBuffer *buffer;
+ memset(&v4l2_buf_op, 0, sizeof(v4l2_buf_op));
+ memset(queue_op_planes, 0, sizeof(queue_op_planes));
+ v4l2_buf_op.m.planes = queue_op_planes;
+
+ if (ctx->in_error)
+ return -1;
+
+ if (ctx->num_active_op_buffers < ctx->op_num_buffers) {
+ /* Get an unused buffer to add to the queue. */
+ buffer = ctx->op_buffers[ctx->num_active_op_buffers];
+ v4l2_buf_op.index = ctx->num_active_op_buffers;
+
+ /* Map new plane buffer for memory type DMABUF. */
+ v4l2_buf_op.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ v4l2_buf_op.memory = ctx->op_mem_type;
+ ret = nvv4l2_map_out(ctx, &v4l2_buf_op, ctx->op_buf_type,
+ ctx->op_mem_type,
+ ctx->plane_dma_fd[v4l2_buf_op.index]);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error while mapping buffer at output plane!\n");
+ ctx->in_error = true;
+ return -1;
+ }
+ } else {
+ /* Dequeue a finished buffer and reuse it. */
+ ret = nvv4l2_dq_buffer(ctx, &v4l2_buf_op, &buffer,
+ ctx->op_buf_type, ctx->op_mem_type, -1);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error DQing buffer at output plane!\n");
+ ctx->in_error = true;
+ return -1;
+ }
+ }
+
+ /* Import frame into output plane */
+ for (uint32_t i = 0; i < buffer->n_planes; i++) {
+ Raw2NvBuffer(frame->payload[i], i, ctx->op_planefmts[i].width,
+ ctx->op_planefmts[i].height, buffer->planes[i].fd);
+ buffer->planes[i].bytesused = ctx->op_planefmts[i].width *
+ ctx->op_planefmts[i].height *
+ ctx->op_planefmts[i].bytesperpixel;
+ v4l2_buf_op.m.planes[i].bytesused = buffer->planes[i].bytesused;
+ }
+
+ /* Set timestamp */
+ v4l2_buf_op.flags |= V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ v4l2_buf_op.timestamp.tv_usec = frame->pts % AV_TIME_BASE;
+ v4l2_buf_op.timestamp.tv_sec = frame->pts / AV_TIME_BASE;
+
+ /* Queue frame on output plane. */
+ ret = nvv4l2_q_buffer(ctx, &v4l2_buf_op, buffer,
+ ctx->op_buf_type, ctx->op_mem_type, ctx->op_num_planes);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR, "Error Qing buffer at output plane!\n");
+ ctx->in_error = true;
+ return -1;
+ }
+
+ if (ctx->num_active_op_buffers < ctx->op_num_buffers) {
+ ctx->num_active_op_buffers++;
+ }
+
+ return 0;
+}
+
+int nvv4l2_encoder_get_packet(AVCodecContext *avctx,
+ nvv4l2_ctx_t *ctx,
+ NvPacket *packet)
+{
+ int packet_index;
+
+ if (ctx->export_pool->capacity == 0)
+ return 1;
+
+ packet_index = nvv4l2_pool_pop(ctx, ctx->export_pool);
+
+ packet->payload = ctx->packet[packet_index];
+ packet->payload_size = ctx->packet_size[packet_index];
+ packet->pts = ctx->frame_pts[packet_index];
+
+ if (ctx->packet_keyflag[packet_index])
+ packet->flags |= AV_PKT_FLAG_KEY;
+
+ return 0;
+}
+
+int nvv4l2_encoder_close(AVCodecContext *avctx, nvv4l2_ctx_t *ctx)
+{
+ int ret;
+
+ if (!ctx)
+ return 0;
+
+ pthread_mutex_lock(&ctx->queue_lock);
+ ctx->eos = true;
+ pthread_mutex_unlock(&ctx->queue_lock);
+ if (ctx->fd != -1) {
+ /* Stop streaming on both planes. */
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_STREAMOFF, &ctx->op_buf_type);
+ ret = v4l2_ioctl(ctx->fd, VIDIOC_STREAMOFF, &ctx->cp_buf_type);
+
+ /* Wait for capture thread to exit. */
+ if (ctx->capture_thread) {
+ pthread_join(ctx->capture_thread, NULL);
+ }
+
+ /* Unmap MMAPed buffers. */
+ for (uint32_t i = 0; i < ctx->cp_num_buffers; ++i) {
+ nvv4l2_destroyBuffer(ctx, ctx->cp_buffers[i]);
+ }
+
+ /* Request 0 buffers on both planes. */
+ ret = nvv4l2_req_buffers_on_output_plane(ctx,
+ ctx->op_buf_type,
+ ctx->op_mem_type, 0);
+
+ ret = nvv4l2_req_buffers_on_capture_plane(ctx,
+ ctx->cp_buf_type,
+ ctx->cp_mem_type, 0);
+
+ /* Unmap and destroy all allocated DMA buffers. */
+ for (uint32_t i = 0; i < ctx->op_num_buffers; i++) {
+ if (ctx->plane_dma_fd[i] != -1) {
+ nvv4l2_unmap_out(ctx, i, ctx->op_buf_type,
+ ctx->op_mem_type, ctx->plane_dma_fd[i]);
+ ret = NvBufferDestroy(ctx->plane_dma_fd[i]);
+ ctx->plane_dma_fd[i] = -1;
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to destroy output plane dma buffer!\n");
+ }
+ }
+ }
+
+ /* Free packet pool */
+ for (int index = 0; index < NV_MAX_BUFFERS; index++) {
+ NVFREE(ctx->packet[index]);
+ }
+ NVFREE(ctx->export_pool);
+
+ /* Close the opened V4L2 device. */
+ ret = v4l2_close(ctx->fd);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to close the device!\n");
+ }
+
+ /* Free mutexes */
+ pthread_mutex_destroy(&ctx->queue_lock);
+ pthread_cond_destroy(&ctx->queue_cond);
+ }
+
+ /* Free encoder parameters */
+ NVFREE(ctx->enc);
+
+ /* Report application run status on exit. */
+ if (ctx->in_error) {
+ av_log(avctx, AV_LOG_ERROR, "Encoder Run failed\n");
+ } else {
+ av_log(avctx, AV_LOG_VERBOSE, "Encoder Run is successful\n");
+ }
+
+ NVFREE(ctx);
+
+ return ret;
+}
+
+static void
+nvv4l2_set_h264_profile_params(nvv4l2EncodeContext *nvv4l2_ctx,
+ NvEncoder *enc,
+ int *pix_fmt)
+{
+ switch (nvv4l2_ctx->profile & ~FF_PROFILE_H264_INTRA) {
+ case FF_PROFILE_H264_MAIN:
+ enc->profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
+ break;
+ case FF_PROFILE_H264_BASELINE:
+ enc->profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
+ break;
+ case FF_PROFILE_H264_HIGH:
+ enc->profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
+ break;
+ case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
+ enc->profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
+ break;
+
+ default:
+ enc->profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
+ break;
+ }
+
+ if (enc->lossless && *pix_fmt == V4L2_PIX_FMT_YUV444M)
+ enc->profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
+
+ switch (nvv4l2_ctx->level) {
+ case 9:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
+ break;
+ case 10:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
+ break;
+ case 11:
+ if (nvv4l2_ctx->profile & FF_PROFILE_H264_INTRA)
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
+ else
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
+ break;
+ case 12:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
+ break;
+ case 13:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
+ break;
+ case 20:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
+ break;
+ case 21:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
+ break;
+ case 22:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
+ break;
+ case 30:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
+ break;
+ case 31:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
+ break;
+ case 32:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
+ break;
+ case 40:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
+ break;
+ case 41:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
+ break;
+ case 42:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
+ break;
+ case 50:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
+ break;
+ case 51:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
+ break;
+ default:
+ enc->level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
+ break;
+ }
+}
+
+static void
+nvv4l2_set_hevc_profile_params(nvv4l2EncodeContext *nvv4l2_ctx,
+ NvEncoder *enc,
+ int *pix_fmt)
+{
+ switch (nvv4l2_ctx->profile & ~FF_PROFILE_H264_INTRA) {
+ case FF_PROFILE_HEVC_MAIN:
+ enc->profile = V4L2_MPEG_VIDEO_H265_PROFILE_MAIN;
+ break;
+ case FF_PROFILE_HEVC_MAIN_10:
+ enc->profile = V4L2_MPEG_VIDEO_H265_PROFILE_MAIN10;
+ *pix_fmt = V4L2_PIX_FMT_P010M;
+ break;
+
+ default:
+ enc->profile = V4L2_MPEG_VIDEO_H265_PROFILE_MAIN;
+ break;
+ }
+
+ if (*pix_fmt == V4L2_PIX_FMT_P010M)
+ enc->profile = V4L2_MPEG_VIDEO_H265_PROFILE_MAIN10;
+
+ switch (nvv4l2_ctx->tier) {
+ case 0:
+ case 1:
+ enc->tier = nvv4l2_ctx->tier;
+ break;
+
+ default:
+ enc->tier = 0;
+ break;
+ }
+
+ switch (nvv4l2_ctx->level) {
+ case 30:
+ enc->level = V4L2_MPEG_VIDEO_H265_LEVEL_1_0_MAIN_TIER;
+ break;
+ case 60:
+ enc->level = V4L2_MPEG_VIDEO_H265_LEVEL_2_0_MAIN_TIER;
+ break;
+ case 63:
+ enc->level = V4L2_MPEG_VIDEO_H265_LEVEL_2_1_MAIN_TIER;
+ break;
+ case 90:
+ enc->level = V4L2_MPEG_VIDEO_H265_LEVEL_3_0_MAIN_TIER;
+ break;
+ case 93:
+ enc->level = V4L2_MPEG_VIDEO_H265_LEVEL_3_1_MAIN_TIER;
+ break;
+ case 120:
+ enc->level = V4L2_MPEG_VIDEO_H265_LEVEL_4_0_MAIN_TIER;
+ break;
+ case 123:
+ enc->level = V4L2_MPEG_VIDEO_H265_LEVEL_4_1_MAIN_TIER;
+ break;
+ case 150:
+ enc->level = V4L2_MPEG_VIDEO_H265_LEVEL_5_0_MAIN_TIER;
+ break;
+ case 153:
+ enc->level = V4L2_MPEG_VIDEO_H265_LEVEL_5_1_MAIN_TIER;
+ break;
+ case 156:
+ enc->level = V4L2_MPEG_VIDEO_H265_LEVEL_5_2_MAIN_TIER;
+ break;
+ case 180:
+ enc->level = V4L2_MPEG_VIDEO_H265_LEVEL_6_0_MAIN_TIER;
+ break;
+ case 183:
+ enc->level = V4L2_MPEG_VIDEO_H265_LEVEL_6_1_MAIN_TIER;
+ break;
+ case 186:
+ enc->level = V4L2_MPEG_VIDEO_H265_LEVEL_6_2_MAIN_TIER;
+ break;
+ default:
+ enc->level = V4L2_MPEG_VIDEO_H265_LEVEL_6_2_MAIN_TIER;
+ break;
+ }
+
+ enc->level += enc->tier;
+}
+
+static NvEncoder *set_encoder_parameters(AVCodecContext *avctx,
+ nvv4l2EncodeContext *nvv4l2_ctx,
+ NvCodingType nv_codec_type,
+ int *pix_fmt)
+{
+ NvEncoder *enc = (NvEncoder *)NVCALLOC(1, sizeof(NvEncoder));
+
+ enc->lossless = nvv4l2_ctx->lossless;
+ enc->ratecontrol = nvv4l2_ctx->rc == 1 ?
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR :
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
+ if (nvv4l2_ctx->twopass) {
+ enc->twopass = 1;
+ enc->ratecontrol = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
+ }
+
+ enc->width = avctx->width;
+ enc->height = avctx->height;
+ enc->bitrate = avctx->bit_rate;
+
+ if (nv_codec_type == NvVideoCodec_H264) {
+ nvv4l2_set_h264_profile_params(nvv4l2_ctx, enc, pix_fmt);
+ } else if (nv_codec_type == NvVideoCodec_HEVC) {
+ nvv4l2_set_hevc_profile_params(nvv4l2_ctx, enc, pix_fmt);
+ }
+
+ switch (nvv4l2_ctx->preset) {
+ case 1:
+ enc->preset_type = V4L2_ENC_HW_PRESET_ULTRAFAST;
+ break;
+ case 2:
+ enc->preset_type = V4L2_ENC_HW_PRESET_FAST;
+ break;
+ case 3:
+ enc->preset_type = V4L2_ENC_HW_PRESET_MEDIUM;
+ break;
+ case 4:
+ enc->preset_type = V4L2_ENC_HW_PRESET_SLOW;
+ break;
+ default:
+ enc->preset_type = V4L2_ENC_HW_PRESET_MEDIUM;
+ break;
+ }
+
+ if (avctx->gop_size > 0) {
+ enc->idr_interval = avctx->gop_size;
+ enc->iframe_interval = avctx->gop_size;
+ } else {
+ enc->idr_interval = 60;
+ enc->iframe_interval = 30;
+ }
+ enc->fps_n = avctx->framerate.num;
+ enc->fps_d = avctx->framerate.den;
+
+ if (avctx->qmin >= 0 && avctx->qmax >= 0) {
+ enc->qmin = avctx->qmin;
+ enc->qmax = avctx->qmax;
+ } else {
+ enc->qmin = -1;
+ enc->qmax = -1;
+ }
+
+ if (avctx->max_b_frames >= 0 && avctx->max_b_frames < 3)
+ enc->num_b_frames = avctx->max_b_frames;
+
+ if (avctx->refs > 0)
+ enc->num_ref = avctx->refs;
+
+ enc->sps_pps_at_idr = !(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER);
+ enc->low_latency = (avctx->flags & AV_CODEC_FLAG_LOW_DELAY) ? true : false;
+
+ return enc;
+}
+
+static NvCodingType map_avcodec_id(enum AVCodecID id)
+{
+ switch (id) {
+ case AV_CODEC_ID_H264:
+ return NvVideoCodec_H264;
+ case AV_CODEC_ID_HEVC:
+ return NvVideoCodec_HEVC;
+ }
+ return NvVideoCodec_UNDEFINED;
+}
+
+static int nvv4l2enc_init(AVCodecContext *avctx)
+{
+ nvv4l2EncodeContext *nvv4l2_ctx = avctx->priv_data;
+ NvCodingType nv_codec_type;
+ NvEncoder *encoder;
+ int pix_fmt;
+
+ nv_codec_type = map_avcodec_id(avctx->codec_id);
+ if (nv_codec_type == NvVideoCodec_UNDEFINED) {
+ av_log(avctx, AV_LOG_ERROR, "Unsupported codec ID %d!\n",
+ avctx->codec_id);
+ return AVERROR_BUG;
+ }
+
+ /* Set output plane pixel format. */
+ switch (avctx->pix_fmt) {
+ case AV_PIX_FMT_YUV444P:
+ pix_fmt = V4L2_PIX_FMT_YUV444M;
+ break;
+ case AV_PIX_FMT_NV12:
+ pix_fmt = V4L2_PIX_FMT_NV12M;
+ break;
+ case AV_PIX_FMT_P010:
+ pix_fmt = V4L2_PIX_FMT_P010M;
+ break;
+ case AV_PIX_FMT_NONE:
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+ case AV_PIX_FMT_YUV420P:
+ pix_fmt = V4L2_PIX_FMT_YUV420M;
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format %d!\n",
+ avctx->pix_fmt);
+ return AVERROR_BUG;
+ }
+
+ /* Set encoder parameters. */
+ encoder = set_encoder_parameters(avctx, nvv4l2_ctx, nv_codec_type,
+ &pix_fmt);
+
+ /* Check if global SPS/PPS header is required and sample it. */
+ if (nv_codec_type == NvVideoCodec_H264 &&
+ (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
+ NvFrame _nvframe = {0};
+ NvPacket packet = {0};
+ uint8_t *dst[4];
+ int linesize[4];
+ int header_size = 0;
+ int ret = 0;
+
+ nvv4l2_ctx->ctx = nvv4l2_create_encoder(avctx, encoder,
+ NvVideoCodec_H264,
+ pix_fmt);
+ if (!nvv4l2_ctx->ctx || nvv4l2_ctx->ctx->in_error) {
+ ret = 1;
+ goto out;
+ }
+
+ /* Get a blank packet to extract metadata */
+ av_image_alloc(dst, linesize, avctx->width, avctx->height,
+ avctx->pix_fmt, 1);
+
+ while (true) {
+ _nvframe.payload[0] = dst[0];
+ _nvframe.payload[1] = dst[1];
+ _nvframe.payload[2] = dst[2];
+
+ ret = nvv4l2_encoder_put_frame(avctx, nvv4l2_ctx->ctx, &_nvframe);
+ if (ret)
+ goto out;
+
+ /* Try several times to get a packet before queuing a new one. */
+ for (uint32_t i = 0; i < 100; i++) {
+ ret = nvv4l2_encoder_get_packet(avctx, nvv4l2_ctx->ctx,
+ &packet);
+ if (!ret)
+ break;
+ usleep(1000);
+ }
+ if (ret)
+ continue;
+
+ /* Find H264_NAL_IDR_SLICE */
+ for (header_size = 0;
+ (header_size + 4) < packet.payload_size;
+ header_size++) {
+ if (packet.payload[header_size] == 0 &&
+ packet.payload[header_size + 1] == 0 &&
+ packet.payload[header_size + 2] == 0 &&
+ packet.payload[header_size + 3] == 1 &&
+ packet.payload[header_size + 4] == 0x65) {
+ break;
+ }
+ }
+
+ if (header_size >= packet.payload_size) {
+ av_log(avctx, AV_LOG_ERROR, "Header was not found!\n");
+ return AVERROR_BUG;
+ }
+
+ avctx->extradata_size = header_size;
+ avctx->extradata = av_mallocz(header_size +
+ AV_INPUT_BUFFER_PADDING_SIZE);
+ memcpy(avctx->extradata, packet.payload, header_size);
+
+ break;
+ }
+ av_free(dst[0]);
+
+out:
+ nvv4l2_encoder_close(avctx, nvv4l2_ctx->ctx);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR, "Error in initializing!\n");
+ return AVERROR_BUG;
+ }
+
+ /* Set encoder parameters again */
+ encoder = set_encoder_parameters(avctx, nvv4l2_ctx, nv_codec_type,
+ &pix_fmt);
+ }
+
+ nvv4l2_ctx->ctx = nvv4l2_create_encoder(avctx, encoder, nv_codec_type,
+ pix_fmt);
+
+ if (!nvv4l2_ctx->ctx || nvv4l2_ctx->ctx->in_error) {
+ nvv4l2_encoder_close(avctx, nvv4l2_ctx->ctx);
+ return AVERROR_BUG;
+ } else
+ return 0;
+}
+
+static int
+nvv4l2enc_encode(AVCodecContext *avctx, AVPacket *pkt,
+ const AVFrame *frame, int *got_packet)
+{
+ nvv4l2EncodeContext *nvv4l2_ctx = avctx->priv_data;
+ nvv4l2_ctx_t *ctx = nvv4l2_ctx->ctx;
+ NvFrame _nvframe = {0};
+ NvPacket packet = {0};
+
+ if (ctx->in_error) {
+ return AVERROR_UNKNOWN;
+ }
+
+ if (frame) {
+ _nvframe.payload[0] = frame->data[0];
+ _nvframe.payload[1] = frame->data[1];
+ _nvframe.payload[2] = frame->data[2];
+
+ _nvframe.pts = frame->pts;
+
+ if (nvv4l2_encoder_put_frame(avctx, ctx, &_nvframe))
+ return AVERROR_UNKNOWN;
+ }
+
+ if (nvv4l2_encoder_get_packet(avctx, ctx, &packet))
+ return 0;
+
+ ff_alloc_packet2(avctx, pkt, packet.payload_size, packet.payload_size);
+
+ memcpy(pkt->data, packet.payload, packet.payload_size);
+ pkt->dts = pkt->pts = packet.pts;
+
+ if (packet.flags & AV_PKT_FLAG_KEY)
+ pkt->flags = AV_PKT_FLAG_KEY;
+
+ *got_packet = 1;
+
+ return 0;
+}
+
+static av_cold int nvv4l2enc_close(AVCodecContext *avctx)
+{
+ nvv4l2EncodeContext *nvv4l2_ctx = avctx->priv_data;
+ nvv4l2_encoder_close(avctx, nvv4l2_ctx->ctx);
+
+ return 0;
+}
+
+static const AVCodecDefault defaults[] = {
+ { "b", "5M" },
+ { "qmin", "-1" },
+ { "qmax", "-1" },
+ { "qdiff", "-1" },
+ { "qblur", "-1" },
+ { "qcomp", "-1" },
+ { "g", "50" },
+ { "bf", "0" },
+ { "refs", "0" },
+ { NULL },
+};
+
+#define OFFSET(x) offsetof(nvv4l2EncodeContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+
+static const AVOption options_h264[] = {
+ { "num_capture_buffers", "Number of buffers in the capture context",
+ OFFSET(num_capture_buffers), AV_OPT_TYPE_INT, {.i64 = 10 }, 1, 32, VE },
+
+ { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT,
+ { .i64 = FF_PROFILE_H264_MAIN }, FF_PROFILE_H264_BASELINE,
+ FF_PROFILE_H264_HIGH_444_PREDICTIVE, VE, "profile" },
+#define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
+ { .i64 = value }, 0, 0, VE, "profile"
+ { PROFILE("baseline", FF_PROFILE_H264_BASELINE) },
+ { PROFILE("main", FF_PROFILE_H264_MAIN) },
+ { PROFILE("high", FF_PROFILE_H264_HIGH) },
+ { PROFILE("high444", FF_PROFILE_H264_HIGH_444_PREDICTIVE) },
+#undef PROFILE
+
+ { "level", "Profile Level", OFFSET(level), AV_OPT_TYPE_INT,
+ { .i64 = 51 }, 9, 51, VE, "level" },
+#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
+ { .i64 = value }, 0, 0, VE, "level"
+ { LEVEL("1.0", 10) },
+ { LEVEL("1b", 9 ) },
+ { LEVEL("1.1", 11) },
+ { LEVEL("1.2", 12) },
+ { LEVEL("1.3", 13) },
+ { LEVEL("2.0", 20) },
+ { LEVEL("2.1", 21) },
+ { LEVEL("2.2", 22) },
+ { LEVEL("3.0", 30) },
+ { LEVEL("3.1", 31) },
+ { LEVEL("3.2", 32) },
+ { LEVEL("4.0", 40) },
+ { LEVEL("4.1", 41) },
+ { LEVEL("4.2", 42) },
+ { LEVEL("5.0", 50) },
+ { LEVEL("5.1", 51) },
+#undef LEVEL
+
+ { "lossless", "Enable lossless encoding", OFFSET(lossless), AV_OPT_TYPE_INT,
+ { .i64 = 0 }, 0, 1, VE, "lossless"},
+#define LOSSLESS(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
+ { .i64 = value }, 0, 0, VE, "lossless"
+ { LOSSLESS("off", 0) },
+ { LOSSLESS("on", 1) },
+#undef LOSSLESS
+
+ { "rc", "Override the preset rate-control",
+ OFFSET(rc), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE, "rc" },
+ { "cbr", "Constant bitrate mode", 0, AV_OPT_TYPE_CONST,
+ { .i64 = 0 }, 0, 0, VE, "rc" },
+ { "vbr", "Variable bitrate mode", 0, AV_OPT_TYPE_CONST,
+ { .i64 = 1 }, 0, 0, VE, "rc" },
+
+ { "preset", "Set the encoding preset", OFFSET(preset),
+ AV_OPT_TYPE_INT, { .i64 = 3 }, 1, 4, VE, "preset" },
+ { "default", "", 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, 0, 0, VE, "preset" },
+ { "slow", "", 0, AV_OPT_TYPE_CONST, { .i64 = 4 }, 0, 0, VE, "preset" },
+ { "medium", "", 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, 0, 0, VE, "preset" },
+ { "fast", "", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, VE, "preset" },
+ { "ultrafast", "", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, VE, "preset" },
+
+ { "2pass", "Enable Two-Pass CBR. (Forces CBR).",
+ OFFSET(twopass), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, VE },
+#define TWOPASS(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
+ { .i64 = value }, 0, 0, VE, "twopass"
+ { TWOPASS("off", 0) },
+ { TWOPASS("on", 1) },
+#undef TWOPASS
+ { NULL }
+};
+
+static const AVOption options_hevc[] = {
+ { "num_capture_buffers", "Number of buffers in the capture context",
+ OFFSET(num_capture_buffers), AV_OPT_TYPE_INT, {.i64 = 10 }, 1, 32, VE },
+
+ { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT,
+ { .i64 = FF_PROFILE_HEVC_MAIN }, FF_PROFILE_HEVC_MAIN,
+ FF_PROFILE_HEVC_MAIN_10, VE, "profile" },
+#define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
+ { .i64 = value }, 0, 0, VE, "profile"
+ { PROFILE("main", FF_PROFILE_HEVC_MAIN) },
+ { PROFILE("main10", FF_PROFILE_HEVC_MAIN_10) },
+#undef PROFILE
+
+ { "tier", "Set the encoding tier", OFFSET(tier), AV_OPT_TYPE_INT,
+ { .i64 = 0 }, 0, 1, VE, "tier"},
+#define TIER(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
+ { .i64 = value }, 0, 0, VE, "tier"
+ { TIER("main", 0) },
+ { TIER("high", 1) },
+#undef TIER
+
+ { "level", "Profile Level", OFFSET(level), AV_OPT_TYPE_INT,
+ { .i64 = 186 }, 30, 186, VE, "level" },
+#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
+ { .i64 = value }, 0, 0, VE, "level"
+ { LEVEL("1", 30) },
+ { LEVEL("2", 60) },
+ { LEVEL("2.1", 63) },
+ { LEVEL("3", 90) },
+ { LEVEL("3.1", 93) },
+ { LEVEL("4", 120) },
+ { LEVEL("4.1", 123) },
+ { LEVEL("5", 150) },
+ { LEVEL("5.1", 153) },
+ { LEVEL("5.2", 156) },
+ { LEVEL("6", 180) },
+ { LEVEL("6.1", 183) },
+ { LEVEL("6.2", 186) },
+#undef LEVEL
+
+ { "lossless", "Enable lossless encoding", OFFSET(lossless), AV_OPT_TYPE_INT,
+ { .i64 = 0 }, 0, 1, VE, "lossless"},
+#define LOSSLESS(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
+ { .i64 = value }, 0, 0, VE, "lossless"
+ { LOSSLESS("off", 0) },
+ { LOSSLESS("on", 1) },
+#undef LOSSLESS
+
+ { "rc", "Override the preset rate-control", OFFSET(rc),
+ AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE, "rc" },
+ { "cbr", "Constant bitrate mode", 0, AV_OPT_TYPE_CONST,
+ { .i64 = 0 }, 0, 0, VE, "rc" },
+ { "vbr", "Variable bitrate mode", 0, AV_OPT_TYPE_CONST,
+ { .i64 = 1 }, 0, 0, VE, "rc" },
+
+ { "preset", "Set the encoding preset", OFFSET(preset),
+ AV_OPT_TYPE_INT, { .i64 = 3 }, 3, 4, VE, "preset" },
+ { "default", "", 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, 0, 0, VE, "preset" },
+ { "slow", "", 0, AV_OPT_TYPE_CONST, { .i64 = 4 }, 0, 0, VE, "preset" },
+ { "medium", "", 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, 0, 0, VE, "preset" },
+ { "fast", "", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, VE, "preset" },
+ { "ultrafast", "", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, VE, "preset" },
+
+ { "2pass", "Enable Two-Pass CBR. (Forces CBR).",
+ OFFSET(twopass), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, VE },
+#define TWOPASS(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
+ { .i64 = value }, 0, 0, VE, "twopass"
+ { TWOPASS("off", 0) },
+ { TWOPASS("on", 1) },
+#undef TWOPASS
+ { NULL }
+};
+
+#define NVV4L2_ENC_CLASS(NAME) \
+ static const AVClass nvv4l2_##NAME##_enc_class = { \
+ .class_name = "nvv4l2_" #NAME "_enc", \
+ .item_name = av_default_item_name, \
+ .option = options_##NAME, \
+ .version = LIBAVUTIL_VERSION_INT, \
+ };
+
+#define NVV4L2_ENC(NAME, ID) \
+ NVV4L2_ENC_CLASS(NAME) \
+ AVCodec ff_##NAME##_nvv4l2_encoder = { \
+ .name = #NAME "_nvv4l2" , \
+ .long_name = NULL_IF_CONFIG_SMALL(#NAME " NVV4L2 HW encoder for Tegra"), \
+ .type = AVMEDIA_TYPE_VIDEO, \
+ .id = ID, \
+ .priv_data_size = sizeof(nvv4l2EncodeContext), \
+ .init = nvv4l2enc_init, \
+ .close = nvv4l2enc_close, \
+ .encode2 = nvv4l2enc_encode, \
+ .priv_class = &nvv4l2_##NAME##_enc_class, \
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, \
+ .defaults = defaults, \
+ .wrapper_name = "nvv4l2", \
+ .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, \
+ AV_PIX_FMT_YUV444P, \
+ AV_PIX_FMT_NV12, \
+ AV_PIX_FMT_P010, \
+ AV_PIX_FMT_NONE }, \
+ };
+
+NVV4L2_ENC(h264, AV_CODEC_ID_H264);
+NVV4L2_ENC(hevc, AV_CODEC_ID_HEVC);
diff -Naur ffmpeg-4.3.2-Matrix-19.1/libavcodec/nvv4l2_ext_utils.h ffmpeg-4.3.2-Matrix-19.1-2/libavcodec/nvv4l2_ext_utils.h
--- ffmpeg-4.3.2-Matrix-19.1/libavcodec/nvv4l2_ext_utils.h 1970-01-01 01:00:00.000000000 +0100
+++ ffmpeg-4.3.2-Matrix-19.1-2/libavcodec/nvv4l2_ext_utils.h 2022-03-20 03:20:58.137382048 +0100
@@ -0,0 +1,2463 @@
+/*
+ * Copyright (c) 2016-2022, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. The names of its contributors may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* This file contains amendments to the V4L2 headers made after the
+ * supported kernel version and NVIDIA extensions.
+ */
+
+#ifndef __NVV4L2_EXT_UTILS_H__
+#define __NVV4L2_EXT_UTILS_H__
+
+#include <errno.h>
+
+/**
+ * @file
+ * <b>NVIDIA V4L2 API Extensions</b>
+ *
+ * @b Description: This file declares NVIDIA V4L2 extensions,
+ * controls and structures.
+ */
+
+/**
+ *
+ * @defgroup ee_extensions_group V4L2 NV Extensions API
+ *
+ * This file declares NVIDIA V4L2 extensions, controls, and structures.
+ *
+ */
+/**
+ * Defines V4L2 pixel format for DIVX.
+ */
+#define V4L2_PIX_FMT_DIVX4 v4l2_fourcc('D', 'V', 'X', '4')
+
+#define V4L2_PIX_FMT_DIVX5 v4l2_fourcc('D', 'V', 'X', '5')
+/**
+ * Defines V4L2 pixel format for H.265.
+ */
+#define V4L2_PIX_FMT_H265 v4l2_fourcc('H', '2', '6', '5')
+
+/**
+ * Defines the V4L2 pixel format for VP9.
+ */
+#define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0')
+
+/**
+ * Defines the V4L2 pixel format for representing single plane 10-bit Y/CbCr 4:2:0 decoder data.
+ */
+#define V4L2_PIX_FMT_P010 v4l2_fourcc('P', '0', '1', '0') /* Y/CbCr 4:2:0, 10 bits per channel */
+
+/**
+ * Defines the V4L2 pixel format for representing semi-planar 10-bit Y/CbCr 4:2:0 decoder data.
+ */
+#define V4L2_PIX_FMT_P010M v4l2_fourcc('P', 'M', '1', '0') /* Y/CbCr 4:2:0, 10 bits per channel */
+
+/**
+ * Defines the V4L2 pixel format for representing single plane 12-bit Y/CbCr 4:2:0 decoder data.
+ */
+#define V4L2_PIX_FMT_P012 v4l2_fourcc('P', '0', '1', '2') /* Y/CbCr 4:2:0, 12 bits per channel */
+
+/**
+ * Defines the V4L2 pixel format for representing semi-planar 12-bit Y/CbCr 4:2:0 decoder data.
+ */
+#define V4L2_PIX_FMT_P012M v4l2_fourcc('P', 'M', '1', '2') /* Y/CbCr 4:2:0, 12 bits per channel */
+
+/**
+ * Defines the V4L2 pixel format for representing semi-planar 8-bit Y/CbCr 4:4:4 decoder data.
+ */
+#define V4L2_PIX_FMT_NV24M v4l2_fourcc('N', 'M', '2', '4') /* Y/CbCr 4:4:4, 8 bits per channel */
+
+/**
+ * Defines the V4L2 pixel format for representing semi-planar 10-bit Y/CbCr 4:4:4 decoder data.
+ */
+#define V4L2_PIX_FMT_NV24_10LE v4l2_fourcc('N', 'V', '1', '0') /* Y/CbCr 4:4:4, 10 bits per channel */
+
+
+/** @cond UNUSED */
+/* >> The declarations from here to the next endcond statement are not
+ * >> currently implemented. DO NOT USE. */
+
+#define V4L2_PIX_FMT_YUV422RM v4l2_fourcc('4', '2', 'R', 'M')
+
+
+#define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4') /** H264 parsed slices. */
+#define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F') /** VP8 parsed frames. */
+
+#define V4L2_CTRL_FLAG_CAN_STORE 0x0200
+
+/** @endcond */
+
+/**
+ * Defines the V4L2 event type for decoder resolution event change.
+ */
+#define V4L2_EVENT_RESOLUTION_CHANGE 5
+
+/** @cond UNUSED */
+/* >> The declarations from here to the next endcond statement are not
+ * >> currently implemented. DO NOT USE. */
+
+/*---------------Below are changes from the v4l2-controls.h----------------------*/
+
+#define V4L2_CID_MPEG_VIDEO_H264_SPS (V4L2_CID_MPEG_BASE+383)
+#define V4L2_CID_MPEG_VIDEO_H264_PPS (V4L2_CID_MPEG_BASE+384)
+#define V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (V4L2_CID_MPEG_BASE+385)
+#define V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAM (V4L2_CID_MPEG_BASE+386)
+#define V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAM (V4L2_CID_MPEG_BASE+387)
+
+#define V4L2_CID_MPEG_VIDEO_VP8_FRAME_HDR (V4L2_CID_MPEG_BASE+512)
+
+/** @endcond */
+
+/**
+ * Defines the control ID to set the H.265 encoder profile.
+ *
+ * A v4l2_mpeg_video_h265_profile must be passed.
+ */
+#define V4L2_CID_MPEG_VIDEO_H265_PROFILE (V4L2_CID_MPEG_BASE+513)
+
+/**
+ * Defines the possible profiles for H.265 encoder.
+ */
+enum v4l2_mpeg_video_h265_profile {
+ /** H.265 Main profile. */
+ V4L2_MPEG_VIDEO_H265_PROFILE_MAIN = 0,
+ /** H.265 Main10 profile. */
+ V4L2_MPEG_VIDEO_H265_PROFILE_MAIN10 = 1,
+ /** H.265 MainStillPicture profile. */
+ V4L2_MPEG_VIDEO_H265_PROFILE_MAINSTILLPICTURE = 2,
+};
+
+/**
+ * Defines the control ID to set the encoder IDR frame interval.
+ * Must be used with \c VIDIOC_S_EXT_CTRLS IOCTL.
+ */
+#define V4L2_CID_MPEG_VIDEO_IDR_INTERVAL (V4L2_CID_MPEG_BASE+514)
+
+/** @cond UNUSED */
+/* >> The declarations from here to the next endcond statement are not
+ * >> currently implemented. DO NOT USE. */
+
+/* Complex controls */
+
+#define V4L2_H264_SPS_CONSTRAINT_SET0_FLAG 0x01
+#define V4L2_H264_SPS_CONSTRAINT_SET1_FLAG 0x02
+#define V4L2_H264_SPS_CONSTRAINT_SET2_FLAG 0x04
+#define V4L2_H264_SPS_CONSTRAINT_SET3_FLAG 0x08
+#define V4L2_H264_SPS_CONSTRAINT_SET4_FLAG 0x10
+#define V4L2_H264_SPS_CONSTRAINT_SET5_FLAG 0x20
+
+#define V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE 0x01
+#define V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS 0x02
+#define V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO 0x04
+#define V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED 0x08
+#define V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY 0x10
+#define V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD 0x20
+#define V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE 0x40
+struct v4l2_ctrl_h264_sps {
+ __u8 profile_idc;
+ __u8 constraint_set_flags;
+ __u8 level_idc;
+ __u8 seq_parameter_set_id;
+ __u8 chroma_format_idc;
+ __u8 bit_depth_luma_minus8;
+ __u8 bit_depth_chroma_minus8;
+ __u8 log2_max_frame_num_minus4;
+ __u8 pic_order_cnt_type;
+ __u8 log2_max_pic_order_cnt_lsb_minus4;
+ __s32 offset_for_non_ref_pic;
+ __s32 offset_for_top_to_bottom_field;
+ __u8 num_ref_frames_in_pic_order_cnt_cycle;
+ __s32 offset_for_ref_frame[255];
+ __u8 max_num_ref_frames;
+ __u16 pic_width_in_mbs_minus1;
+ __u16 pic_height_in_map_units_minus1;
+ __u8 flags;
+};
+
+#define V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE 0x0001
+#define V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT 0x0002
+#define V4L2_H264_PPS_FLAG_WEIGHTED_PRED 0x0004
+#define V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT 0x0008
+#define V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED 0x0010
+#define V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT 0x0020
+#define V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE 0x0040
+#define V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT 0x0080
+struct v4l2_ctrl_h264_pps {
+ __u8 pic_parameter_set_id;
+ __u8 seq_parameter_set_id;
+ __u8 num_slice_groups_minus1;
+ __u8 num_ref_idx_l0_default_active_minus1;
+ __u8 num_ref_idx_l1_default_active_minus1;
+ __u8 weighted_bipred_idc;
+ __s8 pic_init_qp_minus26;
+ __s8 pic_init_qs_minus26;
+ __s8 chroma_qp_index_offset;
+ __s8 second_chroma_qp_index_offset;
+ __u8 flags;
+};
+
+struct v4l2_ctrl_h264_scaling_matrix {
+ __u8 scaling_list_4x4[6][16];
+ __u8 scaling_list_8x8[6][64];
+};
+
+struct v4l2_h264_weight_factors {
+ __s8 luma_weight[32];
+ __s8 luma_offset[32];
+ __s8 chroma_weight[32][2];
+ __s8 chroma_offset[32][2];
+};
+
+struct v4l2_h264_pred_weight_table {
+ __u8 luma_log2_weight_denom;
+ __u8 chroma_log2_weight_denom;
+ struct v4l2_h264_weight_factors weight_factors[2];
+};
+
+#define V4L2_SLICE_FLAG_FIELD_PIC 0x01
+#define V4L2_SLICE_FLAG_BOTTOM_FIELD 0x02
+#define V4L2_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED 0x04
+#define V4L2_SLICE_FLAG_SP_FOR_SWITCH 0x08
+struct v4l2_ctrl_h264_slice_param {
+ /** Holds the size in bytes, including the header. */
+ __u32 size;
+ /** Holds the offset in bits to slice_data() from the beginning of this slice. */
+ __u32 header_bit_size;
+
+ __u16 first_mb_in_slice;
+ __u8 slice_type;
+ __u8 pic_parameter_set_id;
+ __u8 colour_plane_id;
+ __u16 frame_num;
+ __u16 idr_pic_id;
+ __u16 pic_order_cnt_lsb;
+ __s32 delta_pic_order_cnt_bottom;
+ __s32 delta_pic_order_cnt0;
+ __s32 delta_pic_order_cnt1;
+ __u8 redundant_pic_cnt;
+
+ struct v4l2_h264_pred_weight_table pred_weight_table;
+ /* Size in bits of dec_ref_pic_marking() syntax element. */
+ __u32 dec_ref_pic_marking_bit_size;
+ /* Size in bits of pic order count syntax. */
+ __u32 pic_order_cnt_bit_size;
+
+ __u8 cabac_init_idc;
+ __s8 slice_qp_delta;
+ __s8 slice_qs_delta;
+ __u8 disable_deblocking_filter_idc;
+ __s8 slice_alpha_c0_offset_div2;
+ __s8 slice_beta_offset_div2;
+ __u32 slice_group_change_cycle;
+
+ __u8 num_ref_idx_l0_active_minus1;
+ __u8 num_ref_idx_l1_active_minus1;
+ /* Entries on each list are indices
+ * into v4l2_ctrl_h264_decode_param.dpb[]. */
+ __u8 ref_pic_list0[32];
+ __u8 ref_pic_list1[32];
+
+ __u8 flags;
+};
+
+/** Defines whether the v4l2_h264_dpb_entry structure is used.
+If not set, this entry is unused for reference. */
+#define V4L2_H264_DPB_ENTRY_FLAG_ACTIVE 0x01
+#define V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM 0x02
+struct v4l2_h264_dpb_entry {
+ __u32 buf_index; /**< v4l2_buffer index. */
+ __u16 frame_num;
+ __u16 pic_num;
+ /** @note `v4l2_buffer.field` specifies this field. */
+ __s32 top_field_order_cnt;
+ __s32 bottom_field_order_cnt;
+ __u8 flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
+};
+
+struct v4l2_ctrl_h264_decode_param {
+ __u32 num_slices;
+ __u8 idr_pic_flag;
+ __u8 nal_ref_idc;
+ __s32 top_field_order_cnt;
+ __s32 bottom_field_order_cnt;
+ __u8 ref_pic_list_p0[32];
+ __u8 ref_pic_list_b0[32];
+ __u8 ref_pic_list_b1[32];
+ struct v4l2_h264_dpb_entry dpb[16];
+};
+
+#define V4L2_VP8_SEGMNT_HDR_FLAG_ENABLED 0x01
+#define V4L2_VP8_SEGMNT_HDR_FLAG_UPDATE_MAP 0x02
+#define V4L2_VP8_SEGMNT_HDR_FLAG_UPDATE_FEATURE_DATA 0x04
+struct v4l2_vp8_sgmnt_hdr {
+ __u8 segment_feature_mode;
+
+ __s8 quant_update[4];
+ __s8 lf_update[4];
+ __u8 segment_probs[3];
+
+ __u8 flags;
+};
+
+#define V4L2_VP8_LF_HDR_ADJ_ENABLE 0x01
+#define V4L2_VP8_LF_HDR_DELTA_UPDATE 0x02
+struct v4l2_vp8_loopfilter_hdr {
+ __u8 type;
+ __u8 level;
+ __u8 sharpness_level;
+ __s8 ref_frm_delta_magnitude[4];
+ __s8 mb_mode_delta_magnitude[4];
+
+ __u8 flags;
+};
+
+struct v4l2_vp8_quantization_hdr {
+ __u8 y_ac_qi;
+ __s8 y_dc_delta;
+ __s8 y2_dc_delta;
+ __s8 y2_ac_delta;
+ __s8 uv_dc_delta;
+ __s8 uv_ac_delta;
+ __u16 dequant_factors[4][3][2];
+};
+
+struct v4l2_vp8_entropy_hdr {
+ __u8 coeff_probs[4][8][3][11];
+ __u8 y_mode_probs[4];
+ __u8 uv_mode_probs[3];
+ __u8 mv_probs[2][19];
+};
+
+#define V4L2_VP8_FRAME_HDR_FLAG_EXPERIMENTAL 0x01
+#define V4L2_VP8_FRAME_HDR_FLAG_SHOW_FRAME 0x02
+#define V4L2_VP8_FRAME_HDR_FLAG_MB_NO_SKIP_COEFF 0x04
+struct v4l2_ctrl_vp8_frame_hdr {
+ /** 0: keyframe, 1: not a keyframe. */
+ __u8 key_frame;
+ __u8 version;
+
+ /** Populated also if not a key frame. */
+ __u16 width;
+ __u8 horizontal_scale;
+ __u16 height;
+ __u8 vertical_scale;
+
+ struct v4l2_vp8_sgmnt_hdr sgmnt_hdr;
+ struct v4l2_vp8_loopfilter_hdr lf_hdr;
+ struct v4l2_vp8_quantization_hdr quant_hdr;
+ struct v4l2_vp8_entropy_hdr entropy_hdr;
+
+ __u8 sign_bias_golden;
+ __u8 sign_bias_alternate;
+
+ __u8 prob_skip_false;
+ __u8 prob_intra;
+ __u8 prob_last;
+ __u8 prob_gf;
+
+ __u32 first_part_size;
+ /**
+ * Holds the offset in bits of the MB data in the first partition,
+ * i.e. bit offset starting from first_part_offset.
+ */
+ __u32 first_part_offset;
+ __u32 macroblock_bit_offset;
+
+ __u8 num_dct_parts;
+ __u32 dct_part_sizes[8];
+
+ __u8 bool_dec_range;
+ __u8 bool_dec_value;
+ __u8 bool_dec_count;
+
+ /** Holds the v4l2_buffer index of the last reference frame. */
+ __u32 last_frame;
+ /** Holds the v4l2_buffer index of the golden reference frame. */
+ __u32 golden_frame;
+ /** Holds the v4l2_buffer index of the alt reference frame. */
+ __u32 alt_frame;
+
+ __u8 flags;
+};
+
+/** @endcond */
+
+/*---------------Add below NVIDIA specific extensions ----------------------*/
+
+/**
+ * @defgroup V4L2Dec V4L2 Video Decoder
+ *
+ * @brief NVIDIA V4L2 Video Decoder Description and Extensions
+ *
+ * The video decoder device node is
+ *
+ * /dev/nvhost-nvdec
+ *
+ * ### Supported Pixel Formats
+ * OUTPUT PLANE | CAPTURE PLANE
+ * :----------------: | :----------------:
+ * V4L2_PIX_FMT_H264 | V4L2_PIX_FMT_NV12M
+ * V4L2_PIX_FMT_H265 | V4L2_PIX_FMT_NV12M
+ *
+ * ### Supported Memory Types
+ * MEMORY | OUTPUT PLANE | CAPTURE PLANE
+ * :------------------: | :----------: | :-----------:
+ * V4L2_MEMORY_MMAP | Y | Y
+ * V4L2_MEMORY_DMABUF | N | Y
+ * V4L2_MEMORY_USERPTR | Y | N
+ *
+ * ### Supported Controls
+ * - #V4L2_CID_MPEG_VIDEO_DISABLE_COMPLETE_FRAME_INPUT
+ * - #V4L2_CID_MPEG_VIDEO_DISABLE_DPB
+ * - #V4L2_CID_MPEG_VIDEO_ERROR_REPORTING
+ * - #V4L2_CID_MPEG_VIDEO_SKIP_FRAMES
+ * - V4L2_CID_MIN_BUFFERS_FOR_CAPTURE (Get the minimum buffers to be allocated on capture plane.
+ * Read only. Valid after #V4L2_EVENT_RESOLUTION_CHANGE)
+ * - #V4L2_CID_MPEG_VIDEODEC_INPUT_METADATA
+ * - #V4L2_CID_MPEG_VIDEODEC_METADATA
+ * - #V4L2_CID_MPEG_VIDEO_BUF_API_TYPE
+ * - #V4L2_CID_MPEG_VIDEO_CUDA_MEM_TYPE
+ * - #V4L2_CID_MPEG_VIDEO_CUDA_GPU_ID
+ * - #V4L2_CID_MPEG_VIDEODEC_DROP_FRAME_INTERVAL
+ *
+ * ### Supported Events
+ * Event | Purpose
+ * ----------------------------- | :----------------------------:
+ * #V4L2_EVENT_RESOLUTION_CHANGE | Resolution of the stream has changed.
+ *
+ * ### Handling Resolution Change Events
+ * When the decoder generates a \c V4L2_EVENT_RESOLUTION_CHANGE event, the
+ * application calls \c STREAMOFF on the capture plane to tell the decoder to
+ * deallocate the current buffers by calling REQBUF with count zero, get
+ * the new capture plane format, and then proceed with setting up the buffers
+ * for the capture plane.
+ *
+ * In case of decoder, the buffer format might differ from the display resolution.
+ * The application must use \c VIDIOC_G_CROP to get the display resolution.
+ *
+ * ### EOS Handling
+ * The following sequence must be followed for sending EOS and recieving EOS
+ * from the decoder.
+ * -# Send EOS to decoder by queueing on the output plane a buffer with
+ * bytesused = 0 for the 0th plane (`v4l2_buffer.m.planes[0].bytesused = 0`).
+ * -# Dequeues buffers on the output plane until it gets a buffer with bytesused = 0
+ * for the 0th plane (`v4l2_buffer.m.planes[0].bytesused == 0`)
+ * -# Dequeues buffers on the capture plane until it gets a buffer with bytesused = 0
+ * for the 0th plane.
+ *
+ * ### Decoder Input Frame Metadata
+ * Decoder supports reporting stream header parsing error info as input frame metadata.
+ * See \c V4L2_CID_MPEG_VIDEO_ERROR_REPORTING, \c V4L2_CID_MPEG_VIDEODEC_INPUT_METADATA
+ * and \c v4l2_ctrl_video_metadata for more information.
+ *
+ * ### Decoder Output Frame Metadata
+ * Decoder supports reporting frame related metadata, including error reports and
+ * DPB info. See \c V4L2_CID_MPEG_VIDEO_ERROR_REPORTING, \c V4L2_CID_MPEG_VIDEODEC_METADATA
+ * and \c v4l2_ctrl_video_metadata for more information.
+ *
+ * @note Currently, V4L2 plugins do not support odd resolution.
+ * @{
+ * @ingroup ee_extensions_group
+ */
+
+/**
+ * Defines the Control ID to indicate to the decoder that the input
+ * buffers do not contain complete buffers.
+ *
+ * @note This control must be set in case of frames containing multiple slices
+ * when the input buffers do not contain all the slices of the frame.
+ *
+ * A boolean value must be supplied with this control.
+ *
+ */
+#define V4L2_CID_MPEG_VIDEO_DISABLE_COMPLETE_FRAME_INPUT (V4L2_CID_MPEG_BASE+515)
+
+/**
+ * Defines the Control ID to disable decoder DPB management.
+ *
+ * @note This only works for streams having a single reference frame.
+ *
+ * A boolean value must be supplied with this control.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEO_DISABLE_DPB (V4L2_CID_MPEG_BASE+516)
+
+/**
+ * Defines the Control ID to enable decoder error and metadata reporting.
+ *
+ * A boolean value must be supplied with this control.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEO_ERROR_REPORTING (V4L2_CID_MPEG_BASE+517)
+
+/**
+ * Defines the Control ID to set the skip frames property of the decoder.
+ *
+ * Decoder must be configured to skip certain types of frames. One
+ * \c v4l2_skip_frames_type must be passed.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ * This control ID is supported only for H264.
+ */
+#define V4L2_CID_MPEG_VIDEO_SKIP_FRAMES (V4L2_CID_MPEG_BASE+518)
+
+/**
+ * Defines the Control ID to get the decoder output metadata.
+ *
+ * @note Metadata reporting must be enabled using
+ * #V4L2_CID_MPEG_VIDEO_ERROR_REPORTING IOCTL for this.
+ *
+ * A pointer to a valid \c v4l2_ctrl_video_metadata structure must be supplied
+ * with this control.
+ *
+ * @attention This control must be read after dequeueing a buffer successfully from
+ * the capture plane. The values in the structure are valid until the buffer is queued
+ * again.
+ */
+#define V4L2_CID_MPEG_VIDEODEC_METADATA (V4L2_CID_MPEG_BASE+519)
+
+/**
+ * Defines the Control ID to get the decoder input header error metadata.
+ *
+ * @note Metadata reporting must be enabled using
+ * #V4L2_CID_MPEG_VIDEO_ERROR_REPORTING IOCTL for this.
+ *
+ * A pointer to a valid \c v4l2_ctrl_video_metadata structure must be supplied
+ * with this control.
+ *
+ * @attention This control must be read after dequeueing a buffer successfully from
+ * the output plane. The values in the structure are valid until the buffer is queued
+ * again.
+ */
+#define V4L2_CID_MPEG_VIDEODEC_INPUT_METADATA (V4L2_CID_MPEG_BASE+520)
+
+/**
+ * Defines the Control ID to check if display data is present.
+ *
+ * This control returns true if HDR metadata is present in the stream.
+ *
+ */
+#define V4L2_CID_VIDEODEC_DISPLAYDATA_PRESENT (V4L2_CID_MPEG_BASE+521)
+
+/**
+ * Defines the Control ID to get display data if V4L2_CID_VIDEODEC_DISPLAYDATA_PRESENT returns true.
+ *
+ * This control returns display data such as display_primaries, white_point and
+ * display_parameter_luminance required for display module.
+ *
+ */
+#define V4L2_CID_VIDEODEC_HDR_MASTERING_DISPLAY_DATA (V4L2_CID_MPEG_BASE+522)
+
+/**
+ * Defines the Control ID to get Sample Aspect Ratio width for decoding.
+ *
+ * This control returns unsigned integer of Sample Aspect Ratio width.
+ *
+ * @attention This control must be set after receiving V4L2_EVENT_RESOLUTION_CHANGE.
+ *
+ */
+#define V4L2_CID_MPEG_VIDEODEC_SAR_WIDTH (V4L2_CID_MPEG_BASE+569)
+
+/**
+ * Defines the Control ID to get Sample Aspect Ratio height for decoding.
+ *
+ * This control returns unsigned integer of Sample Aspect Ratio height.
+ *
+ * @attention This control must be set after receiving V4L2_EVENT_RESOLUTION_CHANGE.
+ *
+ */
+#define V4L2_CID_MPEG_VIDEODEC_SAR_HEIGHT (V4L2_CID_MPEG_BASE+570)
+
+/** @} */
+
+/**
+ * @defgroup V4L2Conv V4L2 Video Converter
+ *
+ * @brief NVIDIA V4L2 Video Converter Description and Extensions
+ *
+ * Use the video converter for color space conversion, scaling, and
+ * conversion between hardware buffer memory (\c V4L2_MEMORY_MMAP/\c
+ * V4L2_MEMORY_DMABUF), software buffer memory (\c V4L2_MEMORY_USERPTR), and
+ * other operations such as cropping, flipping/rotating, and
+ * temporal noise reduction (TNR).
+ * The video converter device node is \c "/dev/nvhost-vic".
+ *
+ * ### Supported Pixelformats
+ * PIXEL FORMAT | PIXEL FORMAT
+ * :---------------------: | :--------------:
+ * V4L2_PIX_FMT_YUV444M | V4L2_PIX_FMT_YVU422M
+ * V4L2_PIX_FMT_YUV420M | V4L2_PIX_FMT_YVU420M
+ * V4L2_PIX_FMT_NV12M | V4L2_PIX_FMT_GREY
+ * V4L2_PIX_FMT_YUYV | V4L2_PIX_FMT_YVYU
+ * V4L2_PIX_FMT_UYVY | V4L2_PIX_FMT_VYUY
+ * V4L2_PIX_FMT_ABGR32 | V4L2_PIX_FMT_XBGR32
+ *
+ * ### Supported Pixel Formats for TNR
+ * PIXEL FORMAT | PIXEL FORMAT
+ * :---------------------: | :--------------:
+ * V4L2_PIX_FMT_YUV420M | V4L2_PIX_FMT_NV12M
+ * V4L2_PIX_FMT_UYVY | V4L2_PIX_FMT_YUYV
+ *
+ * ### Supported Memory Types
+ * MEMORY | OUTPUT PLANE | CAPTURE PLANE
+ * :------------------: | :----------: | :-----------:
+ * V4L2_MEMORY_MMAP | Y | Y
+ * V4L2_MEMORY_DMABUF | Y | Y
+ * V4L2_MEMORY_USERPTR | Y | Y
+ *
+ * ### Supported Controls
+ * - #V4L2_CID_VIDEO_CONVERT_OUTPUT_PLANE_LAYOUT
+ * - #V4L2_CID_VIDEO_CONVERT_CAPTURE_PLANE_LAYOUT
+ * - #V4L2_CID_VIDEO_CONVERT_FLIP_METHOD
+ * - #V4L2_CID_VIDEO_CONVERT_INTERPOLATION_METHOD
+ * - #V4L2_CID_VIDEO_CONVERT_TNR_ALGORITHM
+ * - #V4L2_CID_VIDEO_CONVERT_YUV_RESCALE_METHOD
+ *
+ * ### Cropping
+ * Video converter supports cropping using \c VIDIOC_S_SELECTION IOCTL with type
+ * \c V4L2_BUF_TYPE_VIDEO_CAPTURE and target \c V4L2_SEL_TGT_CROP. This must
+ * be set before requesting buffers on either plane.
+ *
+ * ### EOS Handling
+ * The following sequence must be followed for sending EOS and recieving EOS
+ * from the converter.
+ * -# Send EOS to converter by queueing on the output plane a buffer with
+ * bytesused = 0 for the 0th plane (`v4l2_buffer.m.planes[0].bytesused = 0`).
+ * -# Dequeues buffers on the capture plane until it gets a buffer with bytesused = 0
+ * for the 0th plane.
+ *
+ * @note Currently, V4L2 plugins do not support odd resolution.
+ * @{
+ * @ingroup ee_extensions_group
+ */
+
+/**
+ * Defines the Control ID to set converter output plane buffer layout.
+ *
+ * A value of type \c v4l2_nv_buffer_layout must be supplied with this control.
+ *
+ * @attention This control must be set before requesting buffers on the output plane.
+ */
+#define V4L2_CID_VIDEO_CONVERT_OUTPUT_PLANE_LAYOUT (V4L2_CID_MPEG_BASE+523)
+
+/**
+ * Defines the Control ID to set converter capture plane buffer layout.
+ *
+ * A value of type \c v4l2_nv_buffer_layout must be supplied with this control.
+ *
+ * @attention This control must be set before requesting buffers on the capture plane.
+ */
+#define V4L2_CID_VIDEO_CONVERT_CAPTURE_PLANE_LAYOUT (V4L2_CID_MPEG_BASE+524)
+
+/**
+ * Defines the Control ID to set the converter flip/rotation method.
+ *
+ * A value of type \c v4l2_flip_method must be supplied with this control.
+ *
+ * @attention This control must be set before requesting buffers on either plane.
+ */
+#define V4L2_CID_VIDEO_CONVERT_FLIP_METHOD (V4L2_CID_MPEG_BASE+525)
+
+/**
+ * Defines the Control ID to set the converter interpolation method.
+ *
+ * A value of type \c v4l2_interpolation_method must be supplied with this control.
+ *
+ * @attention This control must be set before requesting buffers on either plane.
+ */
+#define V4L2_CID_VIDEO_CONVERT_INTERPOLATION_METHOD (V4L2_CID_MPEG_BASE+526)
+
+/**
+ * Defines the Control ID to set the converter Temporal Noise Reduction (TNR) algorithm.
+ *
+ * A value of type \c v4l2_tnr_algorithm must be supplied with this control.
+ *
+ * @attention This control must be set before requesting buffers on either plane.
+ * @attention TNR algorithms are not supported with YUV422 and YUV444 capture
+ * plane formats.
+ */
+#define V4L2_CID_VIDEO_CONVERT_TNR_ALGORITHM (V4L2_CID_MPEG_BASE+527)
+/** @} */
+
+/**
+ * @defgroup V4L2Enc V4L2 Video Encoder
+ *
+ * @brief NVIDIA V4L2 Video Encoder Description and Extensions
+ *
+ * The video encoder device node is \c "/dev/nvhost-msenc".
+ *
+ * ### Supported Pixelformats
+ * OUTPUT PLANE | CAPTURE PLANE
+ * :---------------------: | :--------------
+ * V4L2_PIX_FMT_YUV420M | V4L2_PIX_FMT_H264
+ * - | V4L2_PIX_FMT_H265
+ *
+ * ### Supported Memory Types
+ * MEMORY | OUTPUT PLANE | CAPTURE PLANE
+ * :------------------: | :----------: | :-----------:
+ * V4L2_MEMORY_MMAP | Y | Y
+ * V4L2_MEMORY_DMABUF | Y | N
+ * V4L2_MEMORY_USERPTR | N | N
+ * \attention For the video encoder, it is necessary that the capture plane
+ * format be set before the output plane format and only then request buffers on
+ * any of the planes.
+ *
+ * ### Supported Controls
+ * The following sections describe the supported controls.
+ *
+ * #### Controls From the Open Source V4L2-Controls Header
+ * Control ID | Purpose | Runtime Configurable
+ * -------------------------------- | -------------------- | :------------------:
+ * V4L2_CID_MPEG_VIDEO_BITRATE | Bitrate | Y
+ * V4L2_CID_MPEG_VIDEO_H264_PROFILE | H.264 Encode Profile | N
+ * V4L2_CID_MPEG_VIDEO_BITRATE_MODE | Rate Control Mode | N
+ * V4L2_CID_MPEG_VIDEO_GOP_SIZE | I-frame Interval | N
+ * V4L2_CID_MPEG_VIDEO_H264_LEVEL | Encode Level | N
+ * V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE | Force I-frame on one of queued output plane buffer | Y
+ *
+ * All non-runtime configurable options must be set after setting formats on
+ * both the planes and before requesting buffers on either plane.
+ *
+ * The runtime configurable parameters can be called anytime after setting
+ * formats on both the planes.
+ *
+ * #### NVIDIA-Specific Controls
+ * - #V4L2_CID_MPEG_VIDEO_H265_PROFILE
+ * - #V4L2_CID_MPEG_VIDEO_IDR_INTERVAL
+ * - #V4L2_CID_MPEG_VIDEOENC_TEMPORAL_TRADEOFF_LEVEL
+ * - #V4L2_CID_MPEG_VIDEOENC_SLICE_LENGTH_PARAM
+ * - #V4L2_CID_MPEG_VIDEOENC_ROI_PARAMS
+ * - #V4L2_CID_MPEG_VIDEOENC_VIRTUALBUFFER_SIZE
+ * - #V4L2_CID_MPEG_VIDEOENC_NUM_REFERENCE_FRAMES
+ * - #V4L2_CID_MPEG_VIDEOENC_SLICE_INTRAREFRESH_PARAM
+ * - #V4L2_CID_MPEG_VIDEOENC_NUM_BFRAMES
+ * - #V4L2_CID_MPEG_VIDEOENC_INSERT_SPS_PPS_AT_IDR
+ * - #V4L2_CID_MPEG_VIDEOENC_METADATA
+ * - #V4L2_CID_MPEG_VIDEOENC_METADATA_MV
+ * - #V4L2_CID_MPEG_VIDEOENC_ENABLE_METADATA_MV
+ * - #V4L2_CID_MPEG_VIDEOENC_QP_RANGE
+ * - #V4L2_CID_MPEG_VIDEOENC_HW_PRESET_TYPE_PARAM
+ * - #V4L2_CID_MPEG_VIDEOENC_INPUT_METADATA
+ * - #V4L2_CID_MPEG_VIDEOENC_ENABLE_EXTERNAL_RPS_CONTROL
+ * - #V4L2_CID_MPEG_VIDEOENC_ENABLE_EXTERNAL_RATE_CONTROL
+ * - #V4L2_CID_MPEG_VIDEOENC_ENABLE_ROI_PARAM
+ * - #V4L2_CID_MPEG_VIDEOENC_ENABLE_RECONCRC_PARAM
+ * - #V4L2_CID_MPEG_VIDEOENC_INSERT_VUI
+ * - #V4L2_CID_MPEG_VIDEOENC_INSERT_AUD
+ * - #V4L2_CID_MPEG_VIDEOENC_EXTEDED_COLORFORMAT
+ * - #V4L2_CID_MPEG_VIDEOENC_ENABLE_ALLIFRAME_ENCODE
+ * - #V4L2_CID_MPEG_VIDEOENC_H265_LEVEL
+ * - #V4L2_CID_MPEG_VIDEOENC_ENABLE_SLICE_LEVEL_ENCODE
+ *
+ * #### Setting Framerate
+ * The encoder framerate can be set with \c VIDIOC_S_PARM IOCTL by setting the numerator
+ * and denominator in `v4l2_streamparm.parm.output.timeperframe`.
+ *
+ * ### Supported Encoder Profiles
+ * #### H.264
+ * - V4L2_MPEG_VIDEO_H264_PROFILE_MAIN
+ * - V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE
+ * - V4L2_MPEG_VIDEO_H264_PROFILE_HIGH
+ *
+ * #### H.265
+ * - V4L2_MPEG_VIDEO_H265_PROFILE_MAIN
+ * - V4L2_MPEG_VIDEO_H265_PROFILE_MAIN10
+ *
+ * ### Encoder Output Metadata
+ * The encoder supports reporting frame related metadata, including motion vectors
+ * for that frame. See \c V4L2_CID_MPEG_VIDEOENC_METADATA,
+ * \c V4L2_CID_MPEG_VIDEOENC_METADATA_MV and \c V4L2_CID_MPEG_VIDEOENC_ENABLE_METADATA_MV
+ * for more information.
+ *
+ * ### EOS Handling
+ * The following sequence must be followed for sending EOS and recieving EOS
+ * from the encoder.
+ * -# Send EOS to encoder by queueing on the output plane a buffer with
+ * bytesused = 0 for the 0th plane (`v4l2_buffer.m.planes[0].bytesused = 0`).
+ * -# Dequeues buffers on the capture plane until it gets a buffer with bytesused = 0
+ * for the 0th plane.
+ *
+ * @note Currently, V4L2 plugins do not support odd resolution.
+ * @{
+ * @ingroup ee_extensions_group
+ */
+
+
+/**
+ * Defines the Control ID to configure encoder to drop frames while encoding.
+ *
+ * A value of type \c v4l2_enc_temporal_tradeoff_level_type must be supplied
+ * with this control.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_TEMPORAL_TRADEOFF_LEVEL (V4L2_CID_MPEG_BASE+528)
+
+/**
+ * Defines the Control ID to configure encoder slice length either in terms of MBs or bits.
+ *
+ * A pointer to a valid \c v4l2_enc_slice_length_param structure must be supplied
+ * with this control.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_SLICE_LENGTH_PARAM (V4L2_CID_MPEG_BASE+529)
+
+/**
+ * Defines the Control ID to configure encoder to encode particular region of frame in high
+ * quality.
+ *
+ * A pointer to a valid \c v4l2_enc_frame_ROI_params structure must be supplied
+ * with this control.
+ *
+ * @attention This control must be set after requesting buffers on both the
+ * planes.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_ROI_PARAMS (V4L2_CID_MPEG_BASE+530)
+
+/**
+ * Defines the Control ID to specify virtual buffer size in bits for encoder.
+ *
+ * A pointer to a valid \c v4l2_enc_virtual_buffer_size structure must be
+ * supplied with this control.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_VIRTUALBUFFER_SIZE (V4L2_CID_MPEG_BASE+531)
+
+/**
+ * Defines the Control ID to specify maximum number of reference frames that can be used.
+ *
+ * An integer value must be supplied with this control.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_NUM_REFERENCE_FRAMES (V4L2_CID_MPEG_BASE+532)
+
+/**
+ * Defines the Control ID to specify the encoder slice intra refresh interval.
+ *
+ * A pointer to a valid \c v4l2_enc_slice_intrarefresh_param structure must be
+ * supplied with this control.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_SLICE_INTRAREFRESH_PARAM (V4L2_CID_MPEG_BASE+533)
+
+/**
+ * Defines the Control ID to set number of B frames to be encoded between two P frames.
+ *
+ * This works with H.264 encoder. This also works with H.265 encoder for Jetson Xavier and
+ * Jetson Xavier NX platforms. An integer value must be supplied with this control.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_NUM_BFRAMES (V4L2_CID_MPEG_BASE+534)
+
+/**
+ * Defines the Control ID to enable/disable inserting SPS and PPS explicitly at IDR interval.
+ *
+ * A boolean value must be supplied with this control.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_INSERT_SPS_PPS_AT_IDR (V4L2_CID_MPEG_BASE+535)
+
+/**
+ * Defines the Control ID to get encoder output metadata.
+ *
+ * A pointer to valid #v4l2_ctrl_video_metadata structure must be supplied with
+ * this control.
+ *
+ * @attention This control must be read after dequeueing a buffer successfully from
+ * the capture plane. The values in the structure are valid until the buffer is queued
+ * again.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_METADATA (V4L2_CID_MPEG_BASE+536)
+
+/**
+ * Defines the Control ID to enable/disable encoder motion vector reporting.
+ *
+ * A boolean value must be supplied with this control.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_ENABLE_METADATA_MV (V4L2_CID_MPEG_BASE+537)
+
+/**
+ * Defines the Control ID to get encoder output motion vector metadata.
+ *
+ * A pointer to valid \c v4l2_ctrl_videoenc_outputbuf_metadata_MV structure must
+ * be supplied with this control.
+ *
+ * @attention This control must be read after dequeueing a buffer successfully from
+ * the capture plane. The values in the structure are valid until the buffer is queued
+ * again.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_METADATA_MV (V4L2_CID_MPEG_BASE+538)
+
+/**
+ * Defines the Control ID to set QP range for I/P/B frames.
+ *
+ * A pointer to a valid \c v4l2_ctrl_video_qp_range structure must
+ * be supplied with this control.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_QP_RANGE (V4L2_CID_MPEG_BASE+539)
+
+/**
+ * Defines the Control ID to set encoder HW Preset type.
+ *
+ * A pointer to valid #v4l2_enc_hw_preset_type_param structure must
+ * be supplied with this control.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_HW_PRESET_TYPE_PARAM (V4L2_CID_MPEG_BASE+540)
+
+/**
+ * Defines the Control ID to provide input metadata for encoder buffer.
+ *
+ * A pointer to valid #v4l2_ctrl_videoenc_input_metadata structure must be
+ * supplied with this control.
+ *
+ * @attention This control must be called before queueing a buffer on the output
+ * plane. Use the bitwise OR of v4l2_enc_input_metadata_param in the
+ * v4l2_ctrl_videoenc_input_metadata.metadata_flag to provide different input
+ * metadata parameters in one s_ctrl call.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_INPUT_METADATA (V4L2_CID_MPEG_BASE+541)
+
+/**
+ * Defines the Control ID to configure encoder for external RPS control.
+ *
+ * A pointer to a valid #v4l2_enc_enable_ext_rps_ctr structure must be supplied
+ * with this control.
+ *
+ * @attention This control must be set after requesting buffers on both the
+ * planes. The value for V4L2_CID_MPEG_VIDEOENC_NUM_REFERENCE_FRAMES, if being entered,
+ * must be set after this control.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_ENABLE_EXTERNAL_RPS_CONTROL (V4L2_CID_MPEG_BASE+542)
+
+/**
+ * Defines the Control ID to configure encoder for external rate control.
+ *
+ * A pointer to a valid #v4l2_enc_enable_ext_rate_ctr structure must be supplied
+ * with this control.
+ *
+ * @attention This control must be set after requesting buffers on both the
+ * planes.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_ENABLE_EXTERNAL_RATE_CONTROL (V4L2_CID_MPEG_BASE+543)
+
+/**
+ * Defines the Control ID to configure ROI encoding for a session.
+ *
+ * A pointer to a valid #v4l2_enc_enable_roi_param structure must be supplied
+ * with this control.
+ *
+ * @attention This control must be set after requesting buffers on both the
+ * planes.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_ENABLE_ROI_PARAM (V4L2_CID_MPEG_BASE+544)
+
+/**
+ * Defines the Control ID to configure Reconstructed CRC for a session.
+ *
+ * A pointer to a valid #v4l2_enc_enable_reconcrc_param structure must be supplied
+ * with this control.
+ *
+ * @attention This control must be set after requesting buffers on both the
+ * planes.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_ENABLE_RECONCRC_PARAM (V4L2_CID_MPEG_BASE+545)
+
+/**
+ * Control ID to enable/disable inserting VUI in SPS.
+ *
+ * A boolean value should be supplied with this control.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_INSERT_VUI (V4L2_CID_MPEG_BASE+546)
+
+/**
+ * Control ID to enable/disable inserting AUD(Access Unit Delimiter).
+ *
+ * A boolean value should be supplied with this control.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_INSERT_AUD (V4L2_CID_MPEG_BASE+547)
+
+/**
+ * Control ID to enable/disable setting extended color format.
+ *
+ * A boolean value should be supplied with this control.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane. Also this control should be
+ * enabled/disabled only after V4L2_CID_MPEG_VIDEOENC_INSERT_VUI is set
+ */
+#define V4L2_CID_MPEG_VIDEOENC_EXTEDED_COLORFORMAT (V4L2_CID_MPEG_BASE+548)
+
+/**
+ * Control ID to select which NVDEC IP to decode.
+ *
+ * @note This functionality is currently being deprecated and no longer
+ * functional.
+ *
+ * A v4l2_decode_instance_type should be supplied with this control.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEO_DECODE_INSTANCE (V4L2_CID_MPEG_BASE+549)
+/**
+ * Control ID to issue a pseudo POLL call on the fd opened in non blocking mode.
+ *
+ * A pointer to a valid #v4l2_ctrl_video_device_poll must be supplied with this control.
+ *
+ * @attention This should only be called when the Decoder or Encoder is opened with
+ * O_NONBLOCK flag.
+ */
+#define V4L2_CID_MPEG_VIDEO_DEVICE_POLL (V4L2_CID_MPEG_BASE+550)
+
+/**
+ * Control ID to set/clear the polling interrupt mode. Useful when a POLL issued from the
+ * application but wants the wait to be interrupted.
+ *
+ * A boolean value must be supplied with this control, True indicates polling interrupt shall be
+ * enabled and it shall stay enabled (i.e calls to POLL will return immediately) until a call to
+ * same control ID is made by passing a boolean 0 value.
+ *
+ * @attention This should only be called when the Decoder or Encoder is opened with
+ * O_NONBLOCK flag.
+ */
+#define V4L2_CID_MPEG_SET_POLL_INTERRUPT (V4L2_CID_MPEG_BASE+551)
+
+/**
+ * Control ID to enable/disable setting rate control two pass CBR.
+ *
+ * A boolean value should be supplied with this control.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_TWO_PASS_CBR (V4L2_CID_MPEG_BASE+552)
+
+/**
+ * Defines the Control ID to set the converter YUV Rescale method.
+ *
+ * A value of type \c v4l2_yuv_rescale_method must be supplied with this control.
+ *
+ * @attention This control must be set before requesting buffers on either plane.
+ */
+#define V4L2_CID_VIDEO_CONVERT_YUV_RESCALE_METHOD (V4L2_CID_MPEG_BASE+553)
+
+/**
+ * Control ID to enable maximum Performance.
+ *
+ * An integer value must be supplied with this control.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEO_MAX_PERFORMANCE (V4L2_CID_MPEG_BASE+554)
+
+/**
+ * Control ID to enable/disable setting for all i-Frame encoding.
+ *
+ * A boolean value should be supplied with this control.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_ENABLE_ALLIFRAME_ENCODE (V4L2_CID_MPEG_BASE+555)
+
+/**
+ * Defines the Control ID to set buf api to be used by decoder/encoder.
+ *
+ * A boolean value should be supplied with this control, default is 0
+ * This has to be called before any other ioctls are used and cannot be changed.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ * This is internal ioctl due to be removed later.
+ */
+#define V4L2_CID_MPEG_VIDEO_BUF_API_TYPE (V4L2_CID_MPEG_BASE+556)
+
+/**
+ * Defines the Control ID to set cuda memory type to be used by decoder/encoder.
+ *
+ * This control can be used by the decoder to set the memory type for surfaces.
+ * A value of \c v4l2_cuda_mem_type needs to be set with this control.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEO_CUDA_MEM_TYPE (V4L2_CID_MPEG_BASE+557)
+
+/**
+ * Defines the Control ID to set GPU ID to be used by decoder/encoder.
+ *
+ * An integer value should be supplied with this control.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEO_CUDA_GPU_ID (V4L2_CID_MPEG_BASE+558)
+
+/**
+ * Defines the Control ID to set drop frames interval for decoder.
+ *
+ * An integer value should be supplied with this control. A value of "x"
+ * indicates every "x"th frame should be given out from the decoder, rest shall
+ * dropped after decoding.
+ *
+ * @attention This control must be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEODEC_DROP_FRAME_INTERVAL (V4L2_CID_MPEG_BASE+559)
+
+/**
+ * Control ID to enable/disable setting for attaching VP8/9 headers.
+ * Only to be used for VP8/9 pixel format not for H264/5.
+ *
+ * A boolean value should be supplied with this control.
+ * If value is false headers will be disabled and true will enable the headers.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+ #define V4L2_CID_MPEG_VIDEOENC_VPX_HEADERS_WITH_FRAME (V4L2_CID_MPEG_BASE+560)
+
+/**
+ * Defines the control ID to set the H.265 encoder level.
+ *
+ * A v4l2_mpeg_video_h265_level must be passed.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_H265_LEVEL (V4L2_CID_MPEG_BASE+561)
+
+/**
+ * Control ID to enable/disable slice level encode output.
+ *
+ * A boolean value should be supplied with this control.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_ENABLE_SLICE_LEVEL_ENCODE (V4L2_CID_MPEG_BASE+562)
+
+/* L4T BSP 32.5.x */
+/**
+ * Defines the Control ID to set Picture Order Count property in frames.
+ *
+ * This works only with H.264 encoder. An integer value must be supplied with this
+ * control.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_POC_TYPE (V4L2_CID_MPEG_BASE+563)
+
+/* L4T BSP 32.6.x */
+/**
+ * Defines the Control ID to set Sample Aspect Ratio width for H265 VUI encoding.
+ *
+ * An integer value must be supplied with this control.
+ * The VUI Sample Aspect Ratio indicator for H265 follows the standard enum defined for
+ * v4l2_mpeg_video_h264_vui_sar_idc.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_H265_VUI_EXT_SAR_WIDTH (V4L2_CID_MPEG_BASE+564)
+
+/**
+ * Defines the Control ID to set Sample Aspect Ratio height for H265 VUI encoding.
+ *
+ * An integer value must be supplied with this control.
+ * The VUI Sample Aspect Ratio indicator for H265 follows the standard enum defined
+ * for v4l2_mpeg_video_h264_vui_sar_idc.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_H265_VUI_EXT_SAR_HEIGHT (V4L2_CID_MPEG_BASE+565)
+
+/**
+ * Defines the Control ID to force INTRA frame.
+ *
+ * This control can be used by encoder to force encoding an intra frame.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_FORCE_INTRA_FRAME (V4L2_CID_MPEG_BASE+566)
+
+/**
+ * Defines the Control ID to force IDR frame.
+ *
+ * This control can be used by encoder to force encoding an idr frame.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_FORCE_IDR_FRAME (V4L2_CID_MPEG_BASE+567)
+
+ /**
+ * Defines the Control ID to set low latency to be used by decoder.
+ *
+ * This control can be used by decoder to set low latency for streams having
+ * I and IPPP frames.
+ *
+ * @attention This control must be set before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEO_CUDA_LOW_LATENCY (V4L2_CID_MPEG_BASE+568)
+
+/* L4T BSP 32.7.x */
+/**
+ * Defines the Control ID to enable lossless H.264/H.265 encoding.
+ *
+ * An boolean value must be supplied with this control. Default is 0.
+ * Lossless encoding is supported only for YUV444 8/10-bit format.
+ * @note This control must be set in case of H.264 YUV444 encoding as
+ * it does not support lossy encoding.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_ENABLE_LOSSLESS (V4L2_CID_MPEG_BASE+569)
+
+/**
+ * Defines the Control ID to set chroma_factor_idc for H.265 encoding.
+ *
+ * An integer value must be supplied with this control. Default is 1, and
+ * 3 for YUV444 8/10-bit format.
+ *
+ * @attention This control should be set after setting formats on both the planes
+ * and before requesting buffers on either plane.
+ */
+#define V4L2_CID_MPEG_VIDEOENC_H265_CHROMA_FACTOR_IDC (V4L2_CID_MPEG_BASE+570)
+/** @} */
+
+/** @addtogroup V4L2Dec */
+/** @{ */
+/**
+ * Enum v4l2_skip_frames_type, possible methods for decoder skip frames. */
+enum v4l2_skip_frames_type {
+ /** Do not skip any frame. */
+ V4L2_SKIP_FRAMES_TYPE_NONE = 0,
+ /** Skip all non-reference frames. */
+ V4L2_SKIP_FRAMES_TYPE_NONREF = 1,
+ /** Skip all frames except IDR */
+ V4L2_SKIP_FRAMES_TYPE_DECODE_IDR_ONLY = 2,
+};
+
+/**
+ * Enum v4l2_cuda_mem_type, possible methods for cuda memory tpye. */
+enum v4l2_cuda_mem_type {
+ /** Memory type device. */
+ V4L2_CUDA_MEM_TYPE_DEVICE = 0,
+ /** Memory type host. */
+ V4L2_CUDA_MEM_TYPE_PINNED = 1,
+ /** Memory type unified. */
+ V4L2_CUDA_MEM_TYPE_UNIFIED = 2,
+};
+
+/**
+ * Enum v4l2_videodec_input_error_type, possible error types for input stream. */
+enum v4l2_videodec_input_error_type {
+ /** no error. */
+ V4L2_DEC_ERROR_NONE = 0x0,
+ /** sps error. */
+ V4L2_DEC_ERROR_SPS = 0x1,
+ /** pps error. */
+ V4L2_DEC_ERROR_PPS = 0x2,
+ /** slice header error. */
+ V4L2_DEC_ERROR_SLICE_HDR = 0x4,
+ /** missing reference frame error. */
+ V4L2_DEC_ERROR_MISSING_REF_FRAME = 0x8,
+ /** VPS error. */
+ V4L2_DEC_ERROR_VPS = 0x10,
+};
+
+/**
+ * Holds the decoder error status metadata for the frame.
+ */
+typedef struct v4l2_ctrl_videodec_statusmetadata_
+{
+ /** Error types:
+ * bit 0: Fatal
+ * bit 1: MB level syntax
+ * bit 2: Missing Slice(s)
+ * bit 3: PrevFrameLostFlag */
+ __u32 DecodeError;
+ /** Number of macro blocks decoded without error. */
+ __u32 DecodedMBs;
+ /** Number of macro blocks where error was concealed. */
+ __u32 ConcealedMBs;
+ /** POC of the reference frame used for concealment. */
+ __u32 nConcealedFromPOC;
+ /** Time required to decode the frame, in microseconds. */
+ __u32 FrameDecodeTime;
+}v4l2_ctrl_videodec_statusmetadata;
+
+/**
+ * Holds the the frame specific metadata for a reference frame.
+ */
+typedef struct v4l2_ctrl_videodec_refframe_metadata_
+{
+ /** Boolean value indicating if the frame is present in DPB. */
+ __u32 bPresent;
+ /** Boolean value indicating if the frame is an IDR. */
+ __u32 bIdrFrame;
+ /** Boolean value indicating if the frame is a long term reference frame. */
+ __u32 bLTRefFrame;
+ /** Boolean value indicating if it is a predicted frame. */
+ __u32 bPredicted;
+ /** Picture order count of the frame. */
+ __u32 nPictureOrderCnt;
+ /** Frame number. Resets to zero for an IDR frame. */
+ __u32 nFrameNum;
+ /** Long Term Frame Index of the frame. */
+ __u32 nLTRFrameIdx;
+} v4l2_ctrl_videodec_refframe_metadata;
+
+/**
+ * Holds the the frame specific metadata for the current frame.
+ */
+typedef struct v4l2_ctrl_videodec_currentframe_metadata_
+{
+ /** Boolean value indicating if the current frame is a reference frame. */
+ __u32 bRefFrame;
+ /** Boolean value indicating if the current frame is an IDR. */
+ __u32 bIdrFrame;
+ /** Boolean value indicating if the current frame is a long term reference frame. */
+ __u32 bLTRefFrame;
+ /** Picture order count of the current frame. */
+ __u32 nPictureOrderCnt;
+ /** Frame number. Resets to zero for an IDR frame. */
+ __u32 nFrameNum;
+ /** Long Term Frame Index of the current frame. */
+ __u32 nLTRFrameIdx;
+} v4l2_ctrl_videodec_currentframe_metadata;
+
+/**
+ * Holds the decoder DPB info metadata.
+ */
+typedef struct v4l2_ctrl_videodec_dpbinfometadata_
+{
+ /** Metadata for the current decoded frame. */
+ v4l2_ctrl_videodec_currentframe_metadata currentFrame;
+ /** Number of active frames present in the DPB. */
+ __u32 nActiveRefFrames;
+ /** An array of metadatas for the active frames in the DPB. Only
+ * nActiveRefFrames elements in the array are valid. */
+ v4l2_ctrl_videodec_refframe_metadata RPSList[16];
+} v4l2_ctrl_videodec_dpbinfometadata;
+
+/**
+ * Holds H.264 specific decoder metadata for the frame.
+ */
+typedef struct v4l2_ctrl_h264dec_bufmetadata_
+{
+ /** Holds the number of bits in the frame. */
+ __u32 nFrameNumBits;
+ /** Type of frame:
+ * 0 = B
+ * 1 = P
+ * 2 = I */
+ __u32 FrameType;
+ /** Holds the current DPB information of the decoder. */
+ v4l2_ctrl_videodec_dpbinfometadata dpbInfo;
+}v4l2_ctrl_h264dec_bufmetadata;
+
+/**
+ * Holds H.265 specific decoder metadata for the frame.
+ */
+typedef struct v4l2_ctrl_hevcdec_bufmetadata_
+{
+ /** Holds the number of bits in the frame. */
+ __u32 nPocLsbBits;
+ /** Type of frame:
+ * 0 = B
+ * 1 = P
+ * 2 = I */
+ __u32 FrameType;
+ /** Holds the current DPB information of the decoder. */
+ v4l2_ctrl_videodec_dpbinfometadata dpbInfo;
+}v4l2_ctrl_hevcdec_bufmetadata;
+
+/**
+ * Holds the video decoder input header error metadata for a frame.
+ */
+typedef struct v4l2_ctrl_videodec_inputbuf_metadata_
+{
+ /** Bits represent types of error as defined
+ * with v4l2_videodec_input_error_type. */
+ __u32 nBitStreamError;
+} v4l2_ctrl_videodec_inputbuf_metadata;
+
+/**
+ * Holds the video decoder output metadata for a frame.
+ */
+typedef struct v4l2_ctrl_videodec_outputbuf_metadata_
+{
+ /** Color primaries. */
+ __u8 ucColorPrimaries;
+ /** Transfer characteristics. */
+ __u8 ucTransferCharacteristics;
+ /** Matrix coefficients. */
+ __u8 ucMatrixCoefficients;
+ /** Boolean value indicating if \c FrameDecStats has valid contents. */
+ __u32 bValidFrameStatus;
+ /** Frame decode statistics. */
+ v4l2_ctrl_videodec_statusmetadata FrameDecStats;
+ /** Codec specific metadata for the frame. */
+ union {
+ /** H.264 specific metadata. */
+ v4l2_ctrl_h264dec_bufmetadata H264DecParams;
+ /** H.265 specific metadata. */
+ v4l2_ctrl_hevcdec_bufmetadata HEVCDecParams;
+ }CodecParams;
+} v4l2_ctrl_videodec_outputbuf_metadata;
+/** @} */
+
+/** @addtogroup V4L2Enc */
+/** @{ */
+
+/**
+ * Specifies the types of encoder temporal tradeoff levels
+ */
+enum v4l2_enc_temporal_tradeoff_level_type {
+ /** Do not drop any buffers. */
+ V4L2_ENC_TEMPORAL_TRADEOFF_LEVEL_DROPNONE = 0,
+ /** Drop 1 in every 5 buffers. */
+ V4L2_ENC_TEMPORAL_TRADEOFF_LEVEL_DROP1IN5,
+ /** Drop 1 in every 3 buffers. */
+ V4L2_ENC_TEMPORAL_TRADEOFF_LEVEL_DROP1IN3,
+ /** Drop 1 in every 2 buffers. */
+ V4L2_ENC_TEMPORAL_TRADEOFF_LEVEL_DROP1IN2,
+ /** Drop 2 in every 3 buffers. */
+ V4L2_ENC_TEMPORAL_TRADEOFF_LEVEL_DROP2IN3,
+};
+
+/**
+ * Specifies the encoder HW Preset type.
+ */
+enum v4l2_enc_hw_preset_type {
+ /** Encoder HWPreset DISABLED. */
+ V4L2_ENC_HW_PRESET_DISABLE = 0,
+ /** Encoder HWPreset with per frame encode time UltraFast. */
+ V4L2_ENC_HW_PRESET_ULTRAFAST = 1,
+ /** Encoder HWPreset with per frame encode time Fast. */
+ V4L2_ENC_HW_PRESET_FAST,
+ /** Encoder HWPreset with per frame encode time Medium. */
+ V4L2_ENC_HW_PRESET_MEDIUM,
+ /** Encoder HWPreset with per frame encode time Slow. */
+ V4L2_ENC_HW_PRESET_SLOW,
+};
+
+/**
+ * Holds encoder HW Preset type parameters
+ * to be used with #V4L2_CID_MPEG_VIDEOENC_HW_PRESET_TYPE_PARAM IOCTL.
+ */
+typedef struct v4l2_enc_hw_preset_type_param_
+{
+ /** Type in which the encoder hw preset is specified, one of type #v4l2_enc_hw_preset_type. */
+ enum v4l2_enc_hw_preset_type hw_preset_type;
+ /** Boolean value indicating if encoder set to max clock. */
+ __u8 set_max_enc_clock;
+}v4l2_enc_hw_preset_type_param;
+
+/**
+ * Enum specifying the type of slice length.
+ */
+enum v4l2_enc_slice_length_type {
+ /** Slice size is specified in terms of number of bytes. */
+ V4L2_ENC_SLICE_LENGTH_TYPE_BITS = 0,
+ /** Slice size is specified in terms of number of macroblocks. */
+ V4L2_ENC_SLICE_LENGTH_TYPE_MBLK,
+};
+
+/**
+ * Specifies the input buffer metadata flag.
+ */
+enum v4l2_enc_input_metadata_param {
+ /** Input metadata structure contains ROI parameters. */
+ V4L2_ENC_INPUT_ROI_PARAM_FLAG = 1,
+ /** Input metadata structure contains GDR parameters. */
+ V4L2_ENC_INPUT_GDR_PARAM_FLAG = 1 << 1,
+ /** Input metadata structure contains External RPS parameters. */
+ V4L2_ENC_INPUT_RPS_PARAM_FLAG = 1 << 2,
+ /** Input metadata structure contains External RC parameters. */
+ V4L2_ENC_INPUT_RC_PARAM_FLAG = 1 << 3,
+ /** Input metadata structure contains ReconCRC parameters. */
+ V4L2_ENC_INPUT_RECONCRC_PARAM_FLAG = 1 << 4,
+};
+
+/**
+ * Defines the possible levels for H.265 encoder.
+ */
+enum v4l2_mpeg_video_h265_level {
+
+ V4L2_MPEG_VIDEO_H265_LEVEL_1_0_MAIN_TIER = 0,
+ V4L2_MPEG_VIDEO_H265_LEVEL_1_0_HIGH_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_2_0_MAIN_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_2_0_HIGH_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_2_1_MAIN_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_2_1_HIGH_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_3_0_MAIN_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_3_0_HIGH_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_3_1_MAIN_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_3_1_HIGH_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_4_0_MAIN_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_4_0_HIGH_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_4_1_MAIN_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_4_1_HIGH_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_5_0_MAIN_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_5_0_HIGH_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_5_1_MAIN_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_5_1_HIGH_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_5_2_MAIN_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_5_2_HIGH_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_6_0_MAIN_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_6_0_HIGH_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_6_1_MAIN_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_6_1_HIGH_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_6_2_MAIN_TIER,
+ V4L2_MPEG_VIDEO_H265_LEVEL_6_2_HIGH_TIER,
+};
+
+/**
+ * Holds encoder slice length parameters, to be used with
+ * \c V4L2_CID_MPEG_VIDEOENC_SLICE_LENGTH_PARAM IOCTL.
+ */
+typedef struct v4l2_enc_slice_length_param_
+{
+ /** Type in which the slice length is specified, one of type \c v4l2_enc_slice_length_type. */
+ enum v4l2_enc_slice_length_type slice_length_type;
+ /** Size of the slice in either number of bytes or number of macro blocks. */
+ __u32 slice_length;
+}v4l2_enc_slice_length_param;
+
+/**
+ * Holds encoder virtual buffer size parameters, to be used with
+ * \c V4L2_CID_MPEG_VIDEOENC_VIRTUALBUFFER_SIZE IOCTL.
+ */
+typedef struct v4l2_enc_virtual_buffer_size_
+{
+ /** Size of the virtual buffer, in bits. */
+ __u32 size;
+}v4l2_enc_virtual_buffer_size;
+
+/**
+ * Holds encoder number of reference frame parameters, to be used with
+ * \c V4L2_CID_MPEG_VIDEOENC_NUM_REFERENCE_FRAMES IOCTL.
+ *
+ * This is not supported for H.265.
+ */
+typedef struct v4l2_enc_num_ref_frames_
+{
+ /** Number of reference frames. */
+ __u32 frames;
+}v4l2_enc_num_ref_frames;
+
+/**
+ * Holds encoder slice intrareferesh parameters, to be used with
+ * \c V4L2_CID_MPEG_VIDEOENC_SLICE_INTRAREFRESH_PARAM IOCTL.
+ */
+typedef struct v4l2_enc_slice_intrarefresh_param_
+{
+ /** Slice intrarefresh interval, in number of slices. */
+ __u32 interval;
+}v4l2_enc_slice_intrarefresh_param;
+
+/**
+ * Defines the maximum number of ROI regions supported by the encoder.
+ */
+#define V4L2_MAX_ROI_REGIONS 8
+
+/**
+ * Holds the encoder quality parameters for a single ROI region.
+ */
+typedef struct v4l2_enc_ROI_param_
+{
+ /** Region of interest rectangle. */
+ struct v4l2_rect ROIRect;
+ /** QP delta for the region. */
+ __s32 QPdelta;
+} v4l2_enc_ROI_param;
+
+/**
+ * Holds the encoder frame ROI parameters
+ * to be used with #V4L2_CID_MPEG_VIDEOENC_ROI_PARAMS IOCTL.
+ */
+typedef struct v4l2_enc_frame_ROI_params_
+{
+ /** Number of regions. */
+ __u32 num_ROI_regions;
+ /** Array of indiviudal ROI parameters. */
+ v4l2_enc_ROI_param ROI_params[V4L2_MAX_ROI_REGIONS];
+ /** Config store integer to which this control is to be applied.
+ * This must be same as the value of config store of \c v4l2_buffer to which
+ * the ROI params is applied. */
+ __u32 config_store;
+}v4l2_enc_frame_ROI_params;
+
+/**
+ * Holds the motion vector parameters for a single block.
+ * For H.264, nvenc provides one motion vector per 16x16 block(Macroblock).
+ * For H.265, nvenc provides one motion vector per 32x32 block(Coded Tree Block).
+ */
+typedef struct MVInfo_ {
+ /** Number of pixels the macro block moved in horizontal direction. */
+ __s32 mv_x : 16;
+ /** Number of pixels the macro block moved in vertical direction. */
+ __s32 mv_y : 14;
+ /** Temporal hints used by hardware for Motion Estimation. */
+ __u32 weight : 2;
+} MVInfo;
+
+/**
+ * Holds the motion vector parameters for one complete frame.
+ */
+typedef struct v4l2_ctrl_videoenc_outputbuf_metadata_MV_ {
+ /** Size of the pMVInfo buffer, in bytes. */
+ __u32 bufSize;
+ /** Pointer to the buffer containing the motion vectors. */
+ MVInfo *pMVInfo;
+} v4l2_ctrl_videoenc_outputbuf_metadata_MV;
+
+/**
+ * Maximum number of reference frames supported by the encoder.
+ */
+#define V4L2_MAX_REF_FRAMES 8
+
+/**
+ * Holds the RPS List parameters of encoded frame.
+ */
+typedef struct v4l2_enc_frame_full_prop_
+{
+ /** Unique frame ID. */
+ __u32 nFrameId;
+ /** Boolean value indicating if current frame is an IDR. */
+ __u8 bIdrFrame;
+ /** Boolean value indicating if set Long Term Ref Flag. */
+ __u8 bLTRefFrame;
+ /** Picture Order Count. */
+ __u32 nPictureOrderCnt;
+ /** FrameNum. */
+ __u32 nFrameNum;
+ /** LongTermFrameIdx of a picture. */
+ __u32 nLTRFrameIdx;
+} v4l2_enc_frame_full_prop;
+
+/**
+ * Holds the encoder output metadata for a frame, to be used with
+ * \c V4L2_CID_MPEG_VIDEOENC_METADATA IOCTL.
+ */
+typedef struct v4l2_ctrl_videoenc_outputbuf_metadata_
+{
+ /** Boolean value indicating if current frame is a key frame. */
+ __u8 KeyFrame;
+ /** Boolean value indicating end of frame in case of multi slice encoding. */
+ __u8 EndofFrame;
+ /** Average QP value of the frame. */
+ __u16 AvgQP;
+ /** Boolean value indicating if current frame is a golden or alternate frame. */
+ __u8 bIsGoldenOrAlternateFrame;
+ /** CRC for Reconstructed frame. */
+ __u8 bValidReconCRC;
+ /** Recon Y-frame CRC */
+ __u32 ReconFrame_Y_CRC;
+ /** Recon U-frame CRC */
+ __u32 ReconFrame_U_CRC;
+ /** Recon V-frame CRC */
+ __u32 ReconFrame_V_CRC;
+ /** Number of bits needed to encode the frame. */
+ __u32 EncodedFrameBits;
+ /** Minumum QP value in the frame. */
+ __u32 FrameMinQP;
+ /** Maximum QP value in the frame. */
+ __u32 FrameMaxQP;
+ /** RPS Feedback. */
+ __u32 bRPSFeedback_status;
+ /** Reference frame ID used for Motion Estimation of current frame,
+ ignored for IDR */
+ __u32 nCurrentRefFrameId;
+ /** Number of active reference frames. */
+ __u32 nActiveRefFrames;
+ /** RPS List including most recent frame if it is reference frame. */
+ v4l2_enc_frame_full_prop RPSList[V4L2_MAX_REF_FRAMES];
+} v4l2_ctrl_videoenc_outputbuf_metadata;
+
+/**
+ * Holds the metadata parameters for video encoder and decoder.
+ *
+ * The metadata is valid for the buffer with index \c buffer_index after the
+ * buffer is dequeued until it is queued again.
+ */
+typedef struct v4l2_ctrl_video_metadata_
+{
+ /** A pointer to #v4l2_ctrl_videodec_inputbuf_metadata structure.
+ * This must be a valid pointer when used with #V4L2_CID_MPEG_VIDEODEC_INPUT_METADATA
+ * IOCTL. */
+ v4l2_ctrl_videodec_inputbuf_metadata *VideoDecHeaderErrorMetadata;
+ /** A pointer to #v4l2_ctrl_videodec_outputbuf_metadata structure.
+ * This must be a valid pointer when used with #V4L2_CID_MPEG_VIDEODEC_METADATA
+ * IOCTL. */
+ v4l2_ctrl_videodec_outputbuf_metadata *VideoDecMetadata;
+ /** A pointer to #v4l2_ctrl_videoenc_outputbuf_metadata structure.
+ * This must be a valid pointer when used with #V4L2_CID_MPEG_VIDEOENC_METADATA
+ * IOCTL. */
+ v4l2_ctrl_videoenc_outputbuf_metadata *VideoEncMetadata;
+ /** A pointer to #v4l2_ctrl_videoenc_outputbuf_metadata_MV structure.
+ * This must be a valid pointer when used with #V4L2_CID_MPEG_VIDEOENC_METADATA_MV
+ * IOCTL. */
+ v4l2_ctrl_videoenc_outputbuf_metadata_MV *VideoEncMetadataMV;
+ /** Index of the buffer whose metadata is required. */
+ __u32 buffer_index;
+} v4l2_ctrl_video_metadata;
+
+/**
+ * Holds the encoder GDR parameters
+ * to be used with #V4L2_CID_MPEG_VIDEOENC_INPUT_METADATA IOCTL.
+ */
+typedef struct v4l2_enc_gdr_params_
+{
+ /** Parameter for GDR (Intra Refresh) for specified number of frames. */
+ __u32 nGDRFrames;
+} v4l2_enc_gdr_params;
+
+/**
+ * Holds the params to configure encoder for external rps control
+ * to be used with #V4L2_CID_MPEG_VIDEOENC_ENABLE_EXTERNAL_RPS_CONTROL IOCTL.
+ */
+typedef struct v4l2_enc_enable_ext_rps_ctrl_
+{
+ /** Boolean value indicating if enabled External RPS control. */
+ __u8 bEnableExternalRPS;
+ /** Boolean value indicating if allowed gap in frame number. */
+ __u8 bGapsInFrameNumAllowed;
+ /* TODO : Check for field details. */
+ __u32 nH264FrameNumBits;
+ /* TODO : Check for field details. */
+ __u32 nH265PocLsbBits;
+}v4l2_enc_enable_ext_rps_ctr;
+
+
+/**
+ * Holds the encoder frame property.
+ */
+typedef struct _v4l2_enc_frame_prop
+{
+ /** unique Id. */
+ __u32 nFrameId;
+ /** Long Term Ref Flag. */
+ __u8 bLTRefFrame;
+} v4l2_enc_frame_prop;
+
+/**
+ * Holds the encoder frame external rps control parameters
+ * to be used with #V4L2_CID_MPEG_VIDEOENC_INPUT_METADATA IOCTL.
+ */
+typedef struct v4l2_enc_frame_ext_rps_ctrl_params_
+{
+ /** unique Id of current frame. */
+ __u32 nFrameId;
+ /** Boolean value indicating if current frame referenced or non-referenced. */
+ __u8 bRefFrame;
+ /** Boolean value indicating if current frame long Term Ref Flag. */
+ __u8 bLTRefFrame;
+ /** Max Number of reference frames to use for inter-motion search. */
+ __u32 nMaxRefFrames;
+ /** # of valid entries in RPS, 0 means IDR. */
+ __u32 nActiveRefFrames;;
+ /** frame id of reference frame to be used for motion search, ignored for IDR. */
+ __u32 nCurrentRefFrameId;
+ /** Array of RPS */
+ v4l2_enc_frame_prop RPSList[V4L2_MAX_REF_FRAMES];
+}v4l2_enc_frame_ext_rps_ctrl_params;
+
+
+/**
+ * Holds the params to configure encoder for external rate control mode
+ * to be used with #V4L2_CID_MPEG_VIDEOENC_ENABLE_EXTERNAL_RATE_CONTROL IOCTL.
+ */
+typedef struct v4l2_enc_enable_ext_rate_ctrl_
+{
+ /** Boolean value indicating if enabled External Picture RC. */
+ __u8 bEnableExternalPictureRC;
+ /** Max QP per session when external picture RC enabled. */
+ __u32 nsessionMaxQP;
+}v4l2_enc_enable_ext_rate_ctr;
+
+/**
+ * Holds the encoder frame external rate control parameters
+ * to be used with #V4L2_CID_MPEG_VIDEOENC_INPUT_METADATA ioctl.
+ */
+typedef struct v4l2_enc_frame_ext_rate_ctrl_params_
+{
+ /** Target frame bits. */
+ __u32 nTargetFrameBits;
+ /** Frame start QP. */
+ __u32 nFrameQP;
+ /** Frame min QP. */
+ __u32 nFrameMinQp;
+ /** Frame max QP. */
+ __u32 nFrameMaxQp;
+ /** Frame min QP deviation. */
+ __u32 nMaxQPDeviation;
+}v4l2_enc_frame_ext_rate_ctrl_params;
+
+/**
+ * Holds the params to configure encoder for ROI parameters encoding
+ *
+ * Must be used with #V4L2_CID_MPEG_VIDEOENC_ENABLE_ROI_PARAM IOCTL.
+ */
+typedef struct v4l2_enc_enable_roi_param_
+{
+ /** Boolean value to indicating ROI param encoding. */
+ __u8 bEnableROI;
+}v4l2_enc_enable_roi_param;
+
+/**
+ * Holds the params to configure encoder for Reconstructed CRC encoding
+ *
+ * Must be used with #V4L2_CID_MPEG_VIDEOENC_ENABLE_RECONCRC_PARAM IOCTL.
+ */
+typedef struct v4l2_enc_enable_reconcrc_param_
+{
+ /** Boolean value to indicating Reconstructed CRC encoding. */
+ __u8 bEnableReconCRC;
+}v4l2_enc_enable_reconcrc_param;
+
+/**
+ * Holds the encoder frame Reconstructed CRC parameters.
+ *
+ * Must be used with #V4L2_CID_MPEG_VIDEOENC_INPUT_METADATA IOCTL.
+ */
+typedef struct v4l2_enc_frame_ReconCRC_params_
+{
+ /** Rectangle to specify the co-ordinates of the input frame
+ * used to calculate reconstructed picture CRC. */
+ struct v4l2_rect ReconCRCRect;
+}v4l2_enc_frame_ReconCRC_params;
+
+/**
+ * Holds the encoder frame input metadata parameters.
+ *
+ * Must be used with #V4L2_CID_MPEG_VIDEOENC_INPUT_METADATA IOCTL.
+ */
+typedef struct v4l2_ctrl_videoenc_input_metadata_
+{
+ /** Flag to indicate which inputbuffer metadata is valid. */
+ __u32 flag;
+ /** Pointer to the ROI params structure when ROI param is in metadata_flag. */
+ v4l2_enc_frame_ROI_params *VideoEncROIParams;
+ /** Pointer to the Reconstructed CRC parameter structure when ReconCRC param is in
+ * metadata flag. */
+ v4l2_enc_frame_ReconCRC_params *VideoReconCRCParams;
+ /** Pointer to the GDR params structure when GDR param is in metadata_flag. */
+ v4l2_enc_gdr_params *VideoEncGDRParams;
+ /** Pointer to the External RPL control parameter structure when RPS param is in
+ * metadata flag. */
+ v4l2_enc_frame_ext_rps_ctrl_params *VideoEncRPSParams;
+ /** Pointer to the External Rate control parameter structure when RC param is in
+ * metadata flag. */
+ v4l2_enc_frame_ext_rate_ctrl_params *VideoEncExtRCParams;
+ /** Config store integer to which these parameters are to be applied.
+ * This must be same as the value of config store of queued v4l2_buffer
+ * for which these parameters are valid. */
+ __u32 config_store;
+} v4l2_ctrl_videoenc_input_metadata;
+
+/**
+ * Setting Qp values in #v4l2_ctrl_video_qp_range to QP_RETAIN_VAL
+ * retains default or previously set QP values.
+ */
+#define QP_RETAIN_VAL -1
+
+/**
+ * Holds the encoder frame min/max QP parameters.
+ *
+ * Must be used with #V4L2_CID_MPEG_VIDEOENC_QP_RANGE IOCTL.
+ */
+typedef struct _v4l2_ctrl_video_qp_range
+{
+ /** Minimum QP value for I frame. */
+ __u32 MinQpI;
+ /** Maximum QP value for I frame. */
+ __u32 MaxQpI;
+ /** Minimum QP value for P frame. */
+ __u32 MinQpP;
+ /** Maximum QP value for P frame. */
+ __u32 MaxQpP;
+ /** Minimum QP value for B frame. */
+ __u32 MinQpB;
+ /** Maximum QP value for B frame. */
+ __u32 MaxQpB;
+} v4l2_ctrl_video_qp_range;
+/** @} */
+
+/** @addtogroup V4L2Conv */
+/** @{ */
+
+/**
+ * Enum specifying types of buffer layouts.
+ */
+enum v4l2_nv_buffer_layout {
+ V4L2_NV_BUFFER_LAYOUT_PITCH = 0, /**< Pitch Linear Layout. */
+ V4L2_NV_BUFFER_LAYOUT_BLOCKLINEAR = 1, /**< Block Linear Layout. */
+};
+
+/**
+ * Specifies the types of rotation/flip algorithms.
+ */
+enum v4l2_flip_method {
+ V4L2_FLIP_METHOD_IDENTITY = 0, /**< Identity (no rotation). */
+ V4L2_FLIP_METHOD_90L = 1, /**< Rotate counter-clockwise 90 degrees. */
+ V4L2_FLIP_METHOD_180 = 2, /**< Rotate 180 degrees. */
+ V4L2_FLIP_METHOD_90R = 3, /**< Rotate clockwise 90 degrees. */
+ V4L2_FLIP_METHOD_HORIZ = 4, /**< Flip horizontally. */
+ V4L2_FLIP_METHOD_INVTRANS = 5, /**< Flip across upper right/lower left diagonal. */
+ V4L2_FLIP_METHOD_VERT = 6, /**< Flip vertically. */
+ V4L2_FLIP_METHOD_TRANS = 7, /**< Flip across upper left/lower right diagonal. */
+};
+
+/**
+ * Specifies the types of interpolation methods.
+ */
+enum v4l2_interpolation_method {
+ V4L2_INTERPOLATION_NEAREST = 1, /**< Nearest interpolation method */
+ V4L2_INTERPOLATION_BILINEAR = 2, /**< Bi-Linear interpolation method */
+ V4L2_INTERPOLATION_5_TAP = 3, /**< 5-Tap interpolation method */
+ V4L2_INTERPOLATION_10_TAP = 4, /**< 10-Tap interpolation method */
+ V4L2_INTERPOLATION_SMART = 5, /**< Smart interpolation method */
+ V4L2_INTERPOLATION_NICEST = 6, /**< Nicest interpolation method */
+};
+
+/**
+ * Specifies the types of TNR algorithms.
+ */
+enum v4l2_tnr_algorithm {
+ V4L2_TNR_ALGO_ORIGINAL = 0, /**< Default TNR algorithm. */
+ V4L2_TNR_ALGO_OUTDOOR_LOW_LIGHT = 1, /**< Outdoor Low Light TNR algorithm. */
+ V4L2_TNR_ALGO_OUTDOOR_MEDIUM_LIGHT = 2, /**< Outdoor Medium Light TNR algorithm. */
+ V4L2_TNR_ALGO_OUTDOOR_HIGH_LIGHT = 3, /**< Outdoor High Light TNR algorithm. */
+ V4L2_TNR_ALGO_INDOOR_LOW_LIGHT = 4, /**< Indoor Low Light TNR algorithm. */
+ V4L2_TNR_ALGO_INDOOR_MEDIUM_LIGHT = 5, /**< Indoor Medium Light TNR algorithm. */
+ V4L2_TNR_ALGO_INDOOR_HIGH_LIGHT = 6, /**< Indoor High Light TNR algorithm. */
+};
+
+/**
+ * Specifies the types of YUV rescale methods.
+ */
+enum v4l2_yuv_rescale_method {
+ /**< Disable */
+ V4L2_YUV_RESCALE_NONE = 0,
+ /**< Standard(limited range [16 235]) to extension(full range [0 255]) */
+ V4L2_YUV_RESCALE_STD_TO_EXT = 1,
+ /**< Extension(full range [0 255] to standard(limited range [16 235]) */
+ V4L2_YUV_RESCALE_EXT_TO_STD = 2,
+};
+
+typedef struct v4l2_ctrl_video_displaydata_
+{
+ __u32 masteringdisplaydatapresent;
+}v4l2_ctrl_video_displaydata;
+
+/**
+ * HDR Metadata.
+ */
+
+typedef struct _v4l2_ctrl_video_hdrmasteringdisplaydata
+{
+ // idx 0 : G, 1 : B, 2 : R
+ __u16 display_primaries_x[3]; // normalized x chromaticity cordinate. It shall be in the range of 0 to 50000
+ __u16 display_primaries_y[3]; // normalized y chromaticity cordinate. It shall be in the range of 0 to 50000
+ __u16 white_point_x; // normalized x chromaticity cordinate of white point of mastering display
+ __u16 white_point_y; // normalized y chromaticity cordinate of white point of mastering display
+ __u32 max_display_parameter_luminance; // nominal maximum display luminance in units of 0.0001 candelas per square metre
+ __u32 min_display_parameter_luminance; // nominal minimum display luminance in units of 0.0001 candelas per square metre
+} v4l2_ctrl_video_hdrmasteringdisplaydata;
+
+
+/**
+ * Poll device
+ */
+typedef struct _v4l2_ctrl_video_device_poll
+{
+ __u16 req_events; // Requested events, a bitmask of POLLIN, POLLOUT, POLLERR, POLLPRI.
+ __u16 resp_events; // Returned events a similar bitmask of above events.
+} v4l2_ctrl_video_device_poll;
+
+/** @} */
+
+
+
+/**
+ * @file
+ * <b>NVIDIA Multimedia Utilities: Buffering and Transform/Composition/Blending</b>
+ *
+ */
+
+/**
+ * Defines the maximum number of planes for a video frame.
+ */
+#define MAX_NUM_PLANES 4
+
+/**
+ * Defines NvBuffer Version.
+ */
+typedef enum
+{
+ /** L4T BSP r32.3.x - r32.4.x */
+ NvBufferPixFmtVersion_Legacy,
+ /** L4T BSP r32.5.x and newer */
+ NvBufferPixFmtVersion_New,
+} NvBufferPixFmtVersion;
+
+/**
+ * Defines Payload types for NvBuffer.
+ */
+typedef enum
+{
+ /** buffer payload with HW memory handle for set of planes. */
+ NvBufferPayload_SurfArray,
+ /** buffer payload with HW memory handle for specific memory size. */
+ NvBufferPayload_MemHandle,
+} NvBufferPayloadType;
+
+/**
+ * Defines Layout formats for NvBuffer video planes.
+ */
+typedef enum
+{
+ /** Pitch Layout. */
+ NvBufferLayout_Pitch,
+ /** BlockLinear Layout. */
+ NvBufferLayout_BlockLinear,
+} NvBufferLayout;
+
+/**
+ * Defines memory access flags for NvBuffer.
+ */
+typedef enum
+{
+ /** Memory read. */
+ NvBufferMem_Read,
+ /** Memory write. */
+ NvBufferMem_Write,
+ /** Memory read & write. */
+ NvBufferMem_Read_Write,
+} NvBufferMemFlags;
+
+/**
+ * Defines tags that identify the components requesting a memory allocation.
+ * The tags can be used later to identify the total memory allocated to
+ * particular types of components.
+ */
+typedef enum
+{
+ /** tag None. */
+ NvBufferTag_NONE = 0x0,
+ /** tag for Camera. */
+ NvBufferTag_CAMERA = 0x200,
+ /** tag for Jpeg Encoder/Decoder. */
+ NvBufferTag_JPEG = 0x1500,
+ /** tag for VPR Buffers. */
+ NvBufferTag_PROTECTED = 0x1504,
+ /** tag for H264/H265 Video Encoder. */
+ NvBufferTag_VIDEO_ENC = 0x1200,
+ /** tag for H264/H265/VP9 Video Decoder. */
+ NvBufferTag_VIDEO_DEC = 0x1400,
+ /** tag for Video Transform/Composite. */
+ NvBufferTag_VIDEO_CONVERT = 0xf01,
+} NvBufferTag;
+
+/**
+ * Defines color formats for NvBuffer.
+ */
+typedef enum
+{
+ /** BT.601 colorspace - YUV420 multi-planar. */
+ NvBufferColorFormat_YUV420 = 0,
+ /** BT.601 colorspace - YUV420 ER multi-planar. */
+ NvBufferColorFormat_YUV420_ER = 2, /* BSP 32.5.0 and up: 3 */
+ /** BT.601 colorspace - Y/CbCr 4:2:0 multi-planar. */
+ NvBufferColorFormat_NV12 = 4, /* BSP 32.5.0 and up: 5 */
+ /** BT.601 colorspace - Y/CbCr ER 4:2:0 multi-planar. */
+ NvBufferColorFormat_NV12_ER = 5, /* BSP 32.5.0 and up: 6 */
+ /** LegacyRGBA colorspace - BGRA-8-8-8-8 planar. */
+ NvBufferColorFormat_ABGR32 = 16, /* BSP 32.5.0 and up: 17 */
+ /** LegacyRGBA colorspace - XRGB-8-8-8-8 planar. */
+ NvBufferColorFormat_XRGB32 = 17, /* BSP 32.5.0 and up: 18 */
+ /** LegacyRGBA colorspace - ARGB-8-8-8-8 planar. */
+ NvBufferColorFormat_ARGB32 = 18, /* BSP 32.5.0 and up: 19 */
+ /** BT.601 colorspace - Y/CbCr 4:2:0 10-bit multi-planar. */
+ NvBufferColorFormat_NV12_10LE = 19, /* BSP 32.5.0 and up: 20 */
+ /** BT.601 colorspace - YUV444 multi-planar. */
+ NvBufferColorFormat_YUV444 = 35, /* BSP 32.5.0 and up: 36 */
+} NvBufferColorFormat;
+
+/**
+ * Defines video flip methods.
+ */
+typedef enum
+{
+ /** Video flip none. */
+ NvBufferTransform_None,
+ /** Video flip rotate 90 degree counter-clockwise. */
+ NvBufferTransform_Rotate90,
+ /** Video flip rotate 180 degree. */
+ NvBufferTransform_Rotate180,
+ /** Video flip rotate 270 degree counter-clockwise. */
+ NvBufferTransform_Rotate270,
+ /** Video flip with respect to X-axis. */
+ NvBufferTransform_FlipX,
+ /** Video flip with respect to Y-axis. */
+ NvBufferTransform_FlipY,
+ /** Video flip transpose. */
+ NvBufferTransform_Transpose,
+ /** Video flip inverse transpode. */
+ NvBufferTransform_InvTranspose,
+} NvBufferTransform_Flip;
+
+/**
+ * Defines transform video filter types.
+ */
+typedef enum
+{
+ /** transform filter nearest. */
+ NvBufferTransform_Filter_Nearest,
+ /** transform filter bilinear. */
+ NvBufferTransform_Filter_Bilinear,
+ /** transform filter 5 tap. */
+ NvBufferTransform_Filter_5_Tap,
+ /** transform filter 10 tap. */
+ NvBufferTransform_Filter_10_Tap,
+ /** transform filter smart. */
+ NvBufferTransform_Filter_Smart,
+ /** transform filter nicest. */
+ NvBufferTransform_Filter_Nicest,
+} NvBufferTransform_Filter;
+
+/**
+ * Defines flags to indicate for valid transform.
+ */
+typedef enum {
+ /** transform flag to crop source rectangle. */
+ NVBUFFER_TRANSFORM_CROP_SRC = 1,
+ /** transform flag to crop destination rectangle. */
+ NVBUFFER_TRANSFORM_CROP_DST = 1 << 1,
+ /** transform flag to set filter type. */
+ NVBUFFER_TRANSFORM_FILTER = 1 << 2,
+ /** transform flag to set flip method. */
+ NVBUFFER_TRANSFORM_FLIP = 1 << 3,
+} NvBufferTransform_Flag;
+
+/**
+ * Holds coordinates for a rectangle.
+ */
+typedef struct
+{
+ /** rectangle top. */
+ uint32_t top;
+ /** rectangle left. */
+ uint32_t left;
+ /** rectangle width. */
+ uint32_t width;
+ /** rectangle height. */
+ uint32_t height;
+}NvBufferRect;
+
+/**
+ * Holds an opaque NvBuffer session type required for parallel buffer
+ * tranformations and compositions. Operations using a single session are
+ * scheduled sequentially, after the previous operation finishes. Operations for
+ * multiple sessions are scheduled in parallel.
+ */
+typedef struct _NvBufferSession * NvBufferSession;
+
+
+/**
+ * Holds the input parameters for hardware buffer creation.
+ */
+typedef struct _NvBufferCreateParams
+{
+ /** width of the buffer. */
+ int32_t width;
+ /** height of the buffer. */
+ int32_t height;
+ /** payload type of the buffer. */
+ NvBufferPayloadType payloadType;
+ /** size of the memory.(Applicale for NvBufferPayload_MemHandle) */
+ int32_t memsize;
+ /** layout of the buffer. */
+ NvBufferLayout layout;
+ /** colorformat of the buffer. */
+ NvBufferColorFormat colorFormat;
+ /** tag to associate with the buffer. */
+ NvBufferTag nvbuf_tag;
+}NvBufferCreateParams;
+
+/**
+ * Holds parameters for a hardware buffer.
+ */
+typedef struct _NvBufferParams
+{
+ /** Holds the DMABUF FD of the hardware buffer. */
+ uint32_t dmabuf_fd;
+ /** pointer to hardware buffer memory. */
+ void *nv_buffer;
+ /** payload type of the buffer. */
+ NvBufferPayloadType payloadType;
+ /** size of the memory.(Applicale for NvBufferPayload_MemHandle) */
+ int32_t memsize;
+ /** size of hardware buffer. */
+ uint32_t nv_buffer_size;
+ /** video format type of hardware buffer. */
+ NvBufferColorFormat pixel_format;
+ /** number of planes of hardware buffer. */
+ uint32_t num_planes;
+ /** width of each planes of hardware buffer. */
+ uint32_t width[MAX_NUM_PLANES];
+ /** height of each planes of hardware buffer. */
+ uint32_t height[MAX_NUM_PLANES];
+ /** pitch of each planes of hardware buffer. */
+ uint32_t pitch[MAX_NUM_PLANES];
+ /** memory offset values of each video planes of hardware buffer. */
+ uint32_t offset[MAX_NUM_PLANES];
+ /** size of each video planes of hardware buffer. */
+ uint32_t psize[MAX_NUM_PLANES];
+ /** layout type of each planes of hardware buffer. */
+ uint32_t layout[MAX_NUM_PLANES];
+}NvBufferParams;
+
+/**
+ * Holds parameters for buffer transform functions.
+ */
+typedef struct _NvBufferTransformParams
+{
+ /** flag to indicate which of the transform parameters are valid. */
+ uint32_t transform_flag;
+ /** flip method. */
+ NvBufferTransform_Flip transform_flip;
+ /** transform filter. */
+ NvBufferTransform_Filter transform_filter;
+ /** source rectangle coordinates for crop opeartion. */
+ NvBufferRect src_rect;
+ /** destination rectangle coordinates for crop opeartion. */
+ NvBufferRect dst_rect;
+ /** NvBufferSession to be used for transform. If NULL, the default session
+ * is used. */
+ NvBufferSession session;
+}NvBufferTransformParams;
+
+/**
+ * Allocates a hardware buffer (deprecated).
+ *
+ * @deprecated Use NvBufferCreateEx() instead.
+ * @param[out] dmabuf_fd Returns the DMABUF FD of the hardware buffer.
+ * @param[in] width Buffer width, in bytes.
+ * @param[in] height Buffer height, in bytes.
+ * @param[in] layout Layout of the buffer.
+ * @param[in] colorFormat Color format of the buffer.
+ *
+ * @return 0 if successful, or -1 otherwise.
+ */
+int NvBufferCreate (int *dmabuf_fd, int width, int height,
+ NvBufferLayout layout, NvBufferColorFormat colorFormat);
+
+/**
+ * Allocates a hardware buffer.
+ *
+ * @param[out] dmabuf_fd Returns the DMABUF FD of the hardware buffer.
+ * @param[in] input_params Input parameters for hardware buffer creation.
+ *
+ * @returns 0 for success, -1 for failure
+ */
+int NvBufferCreateEx (int *dmabuf_fd, NvBufferCreateParams *input_params);
+
+/**
+ * Gets buffer parameters.
+ * @param[in] dmabuf_fd `DMABUF FD` of buffer.
+ * @param[out] params A pointer to the structure to fill with parameters.
+ *
+ * @returns 0 for success, -1 for failure.
+ */
+int NvBufferGetParams (int dmabuf_fd, NvBufferParams *params);
+
+/**
+* Destroys a HW buffer.
+* @param[in] dmabuf_fd Specifies the `dmabuf_fd` `hw_buffer` to destroy.
+*
+* @returns 0 for success, -1 for failure.
+*/
+int NvBufferDestroy (int dmabuf_fd);
+
+/**
+* Syncs the HW memory cache for the CPU.
+*
+* \sa NvBufferMemMap for the purpose of the function
+*
+* @param[in] dmabuf_fd DMABUF FD of buffer.
+* @param[in] plane video frame plane.
+* @param[in] pVirtAddr Virtual Address pointer of the memory-mapped plane.
+*
+* @returns 0 for success, -1 for failure.
+
+*/
+int NvBufferMemSyncForCpu (int dmabuf_fd, unsigned int plane, void **pVirtAddr);
+
+/**
+* Syncs the hardware memory cache for the device.
+*
+* \sa NvBufferMemMap for the purpose of the function
+*
+* @param[in] dmabuf_fd DMABUF FD of buffer.
+* @param[in] plane video frame plane.
+* @param[in] pVirtAddr Virtual Address pointer of the memory-mapped plane.
+*
+* @returns 0 for success, -1 for failure.
+*/
+int NvBufferMemSyncForDevice (int dmabuf_fd, unsigned int plane, void **pVirtAddr);
+
+/**
+* Gets the memory-mapped virtual address of the plane.
+*
+* The client must call NvBufferMemSyncForCpu() with the virtual address returned
+* by this function before accessing the mapped memory in CPU.
+*
+* After memory mapping is complete, mapped memory modification
+* must be coordinated between the CPU and hardware device as
+* follows:
+* - CPU: If the CPU modifies any mapped memory, the client must call
+* NvBufferMemSyncForDevice() before any hardware device accesses the memory.
+* - Hardware device: If the mapped memory is modified by any hardware device,
+* the client must call NvBufferMemSyncForCpu() before CPU accesses the memory.
+*
+* @param[in] dmabuf_fd DMABUF FD of buffer.
+* @param[in] plane video frame plane.(Applies to @ref NvBufferPayload_SurfArray.)
+* @param[in] memflag NvBuffer memory flag.
+* @param[out] pVirtAddr Virtual Address pointer of the memory-mapped plane.
+*
+* @returns 0 for success, -1 for failure.
+*/
+int NvBufferMemMap (int dmabuf_fd, unsigned int plane, NvBufferMemFlags memflag, void **pVirtAddr);
+
+/**
+* Unmaps the mapped virtual address of the plane.
+*
+* If the following conditions are both true, the client must call
+* NvBufferMemSyncForDevice() before unmapping the memory:
+* - Mapped memory was modified by the CPU.
+* - Mapped memory will be accessed by a hardware device.
+*
+* @param[in] dmabuf_fd DMABUF FD of the buffer.
+* @param[in] plane Video frame plane. Applies to
+* @ref NvBufferPayload_SurfArray.
+* @param[in] pVirtAddr Virtual address pointer to the memory-mapped plane.
+*
+* @returns 0 for success, -1 for failure.
+*/
+int NvBufferMemUnMap (int dmabuf_fd, unsigned int plane, void **pVirtAddr);
+
+/**
+* Copies the NvBuffer plane contents to a raw buffer plane.
+* @param[in] dmabuf_fd DMABUF FD of NvBuffer.
+* @param[in] plane video frame plane.
+* @param[in] out_width aligned width of the raw data plane.
+* @param[in] out_height aligned height of the raw data plane.
+* @param[in] ptr pointer to the output raw plane data.
+*
+* @returns 0 for success, -1 for failure.
+*/
+int NvBuffer2Raw (int dmabuf_fd, unsigned int plane, unsigned int out_width, unsigned int out_height, unsigned char *ptr);
+
+/**
+* Copies raw buffer plane contents to an NvBuffer plane.
+* @param[in] ptr pointer to the input raw plane data.
+* @param[in] plane video frame plane.
+* @param[in] in_width aligned width of the raw data plane.
+* @param[in] in_height aligned height of the raw data plane.
+* @param[in] dmabuf_fd DMABUF FD of NvBuffer.
+*
+* @returns 0 for success, -1 for failure.
+*/
+int Raw2NvBuffer (unsigned char *ptr, unsigned int plane, unsigned int in_width, unsigned int in_height, int dmabuf_fd);
+
+/**
+* Creates a new NvBufferSession for parallel scheduling of
+* buffer transformations and compositions.
+*
+* @returns A session pointer, NULL for failure.
+*/
+NvBufferSession NvBufferSessionCreate(void);
+
+/**
+* Destroys an existing \ref NvBufferSession.
+* @param[in] session An existing NvBufferSession.
+*/
+void NvBufferSessionDestroy(NvBufferSession session);
+
+/**
+ * Transforms one DMA buffer to another DMA buffer.
+ * This function can support transforms for copying, scaling, fliping, rotating, and cropping.
+ * @param[in] src_dmabuf_fd DMABUF FD of source buffer
+ * @param[in] dst_dmabuf_fd DMABUF FD of destination buffer
+ * @param[in] transform_params transform parameters
+ *
+ * @return 0 for sucess, -1 for failure.
+ */
+int NvBufferTransform (int src_dmabuf_fd, int dst_dmabuf_fd, NvBufferTransformParams *transform_params);
+
+#endif /*__NVV4L2_EXT_UTILS_H__*/
diff -Naur ffmpeg-4.3.2-Matrix-19.1/libavcodec/nvv4l2.h ffmpeg-4.3.2-Matrix-19.1-2/libavcodec/nvv4l2.h
--- ffmpeg-4.3.2-Matrix-19.1/libavcodec/nvv4l2.h 1970-01-01 01:00:00.000000000 +0100
+++ ffmpeg-4.3.2-Matrix-19.1-2/libavcodec/nvv4l2.h 2022-03-20 03:24:58.293242052 +0100
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 2021-2022, CTCaer <ctcaer@gmail.com>
+ *
+ * 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.
+ */
+
+/**
+ * Specifies the decoder device node.
+ */
+#ifndef __NVV4L2_H__
+#define __NVV4L2_H__
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <libv4l2.h>
+#include <linux/videodev2.h>
+#include "avcodec.h"
+
+#include "nvv4l2_ext_utils.h"
+
+#define NV_MAX_BUFFERS 32
+#define NV_MAX_PLANES 3
+
+/* Max timestamp accepted by NVV4L2 */
+#define NV_V4L2_TIMESTAMP_MAX_SEC ((int64_t)UINT64_C(0x1AD7F29ABCA))
+
+/* Custom values/flags to pass over info into capture plane */
+#define NV_V4L2_NOPTS_VALUE NV_V4L2_TIMESTAMP_MAX_SEC
+#define NV_V4L2_REORDERED_OPAQUE_FLAG ((int64_t)UINT64_C(0x10000000000))
+
+#define NVMIN(a,b) (((a) < (b)) ? (a) : (b))
+#define NVMAX(a, b) ((a) > (b) ? (a) : (b))
+
+/* Use app malloc/free implementation */
+#define NVMALLOC(size) (av_malloc((size)))
+#define NVCALLOC(num, size) (av_mallocz((num) * (size)))
+#define NVFREE(ptr) (av_free((ptr)))
+
+#define NVALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
+
+typedef struct _queue {
+ uint32_t capacity;
+ uint32_t front;
+ uint32_t back;
+} NvQueues;
+
+typedef enum {
+ NV_PIX_NV12,
+ NV_PIX_YUV420
+} NvPixFormat;
+
+typedef struct _NVPACKET {
+ uint32_t flags;
+ uint32_t payload_size;
+ uint8_t *payload;
+ uint32_t width;
+ uint32_t height;
+ int64_t pts;
+ int64_t user_pts;
+} NvPacket;
+
+typedef struct _NVFRAME {
+ uint32_t flags;
+ uint32_t payload_size[3];
+ uint8_t *payload[3];
+ uint32_t width;
+ uint32_t height;
+ int64_t pts;
+ int64_t user_pts;
+} NvFrame;
+
+typedef enum {
+ NvVideoCodec_H264, /**< H.264 */
+ NvVideoCodec_MPEG4, /**< MPEG-4 */
+ NvVideoCodec_MPEG2, /**< MPEG-2 */
+ NvVideoCodec_VP8, /**< VP8 */
+ NvVideoCodec_VP9, /**< VP9 */
+ NvVideoCodec_HEVC, /**< H.265/HEVC */
+ NvVideoCodec_UNDEFINED,
+} NvCodingType;
+
+typedef struct {
+ uint32_t width; /**< Holds the width of the plane in pixels. */
+ uint32_t height; /**< Holds the height of the plane in pixels. */
+
+ uint32_t bytesperpixel; /**< Holds the bytes used to represent one
+ pixel in the plane. */
+ uint32_t stride; /**< Holds the stride of the plane in bytes. */
+ uint32_t sizeimage; /**< Holds the size of the plane in bytes. */
+} NvBufferPlaneFormat;
+
+ /**
+ * Holds the buffer plane parameters.
+ */
+
+typedef struct {
+ NvBufferPlaneFormat fmt; /**< Holds the format of the plane. */
+ uint8_t *data; /**< Holds a pointer to the plane memory. */
+ uint32_t bytesused; /**< Holds the number of valid bytes in the plane. */
+ int fd; /**< Holds the file descriptor (FD) of the plane of the
+ exported buffer, in the case of V4L2 MMAP buffers. */
+ uint32_t mem_offset; /**< Holds the offset of the first valid byte
+ from the data pointer. */
+ uint32_t length; /**< Holds the size of the buffer in bytes. */
+} NvBufferPlane;
+
+typedef struct {
+ enum v4l2_buf_type buf_type; /**< Type of the buffer. */
+ enum v4l2_memory memory_type; /**< Type of memory associated with the buffer. */
+ uint32_t index; /**< Holds the buffer index. */
+ uint32_t n_planes; /**< Holds the number of planes in the buffer. */
+ NvBufferPlane planes[NV_MAX_PLANES];
+ bool mapped;
+} NvBuffer;
+
+typedef struct {
+ uint32_t width;
+ uint32_t height;
+ bool low_latency;
+ uint32_t profile;
+ uint32_t bitrate;
+ uint32_t level;
+ uint32_t tier;
+ uint32_t preset_type;
+ uint32_t lossless;
+ uint32_t twopass;
+ uint32_t iframe_interval;
+ uint32_t idr_interval;
+ uint32_t fps_n;
+ uint32_t fps_d;
+ int qmin;
+ int qmax;
+ int num_b_frames;
+ uint32_t num_ref;
+ bool sps_pps_at_idr;
+ uint32_t ratecontrol;
+} NvEncoder;
+
+/**
+ * @brief Struct defining the decoder context.
+ * The video decoder device node is `/dev/nvhost-nvdec`. The category name
+ * for the decoder is \c "NVDEC".
+ *
+ * The context stores the information for decoding.
+ * Refer to [V4L2 Video Decoder](group__V4L2Dec.html) for more information on the decoder.
+ */
+
+typedef struct {
+ uint32_t codec_width;
+ uint32_t codec_height;
+
+ NvBufferSession buf_session;
+ NvBufferPixFmtVersion pixfmt_list_ver;
+
+ uint32_t op_pixfmt;
+ uint32_t cp_pixfmt;
+ enum v4l2_memory op_mem_type;
+ enum v4l2_memory cp_mem_type;
+ enum v4l2_buf_type op_buf_type;
+ enum v4l2_buf_type cp_buf_type;
+ NvBufferPlaneFormat op_planefmts[NV_MAX_PLANES];
+ NvBufferPlaneFormat cp_planefmts[NV_MAX_PLANES];
+ uint32_t cp_num_planes;
+ uint32_t op_num_planes;
+ uint32_t cp_num_buffers;
+ uint32_t op_num_buffers;
+ NvQueues *export_pool;
+ NvBuffer **op_buffers;
+ NvBuffer **cp_buffers;
+ uint32_t num_active_op_buffers;
+ uint32_t num_queued_op_buffers;
+ uint32_t num_queued_cp_buffers;
+
+ pthread_mutex_t queue_lock;
+ pthread_cond_t queue_cond;
+ pthread_mutex_t frame_lock;
+ pthread_cond_t frame_cond;
+ pthread_t capture_thread;
+
+ bool in_error;
+ bool eos;
+ bool op_streamon;
+ bool cp_streamon;
+ bool draining_event;
+ bool low_latency;
+
+ int fd;
+ int out_dma_fd;
+ int dmabuff_fd[NV_MAX_BUFFERS];
+
+ int plane_dma_fd[NV_MAX_BUFFERS];
+ uint32_t plane_width[MAX_NUM_PLANES];
+ uint32_t plane_height[MAX_NUM_PLANES];
+ uint32_t plane_width_aligned;
+ int64_t frame_pts[NV_MAX_BUFFERS];
+ int64_t frame_user_pts[NV_MAX_BUFFERS];
+
+ uint8_t *packet[NV_MAX_BUFFERS];
+ uint32_t packet_buf_size[NV_MAX_BUFFERS];
+ uint32_t packet_size[NV_MAX_BUFFERS];
+ bool packet_keyflag[NV_MAX_BUFFERS];
+
+ NvEncoder *enc;
+ AVCodecContext *avctx;
+} nvv4l2_ctx_t;
+
+/* NVV4L2 common functions */
+uint32_t nvv4l2_map_nvcodec_type(NvCodingType nv_codec_type);
+int
+nvv4l2_pool_idx_next(nvv4l2_ctx_t *ctx, NvQueues *q);
+void
+nvv4l2_pool_push(nvv4l2_ctx_t *ctx, NvQueues *q);
+int
+nvv4l2_pool_pop(nvv4l2_ctx_t *ctx, NvQueues *q);
+int
+nvv4l2_create_bufferfmt(NvBuffer *buffer, enum v4l2_buf_type buf_type,
+ enum v4l2_memory memory_type, uint32_t n_planes,
+ NvBufferPlaneFormat *fmt, uint32_t index);
+int
+nvv4l2_map_out(nvv4l2_ctx_t *ctx, struct v4l2_buffer *v4l2_buf,
+ enum v4l2_buf_type buf_type, enum v4l2_memory mem_type,
+ int dma_fd);
+int
+nvv4l2_unmap_out(nvv4l2_ctx_t *ctx, int index, enum v4l2_buf_type buf_type,
+ enum v4l2_memory mem_type, int dma_fd);
+void
+nvv4l2_destroyBuffer(nvv4l2_ctx_t *ctx, NvBuffer *buffer);
+int
+nvv4l2_allocate_memory(nvv4l2_ctx_t *ctx, NvBuffer *buffer);
+int
+nvv4l2_map(nvv4l2_ctx_t *ctx, NvBuffer *buffer);
+void
+nvv4l2_unmap(nvv4l2_ctx_t *ctx, NvBuffer *buffer);
+int
+nvv4l2_query_buffer(nvv4l2_ctx_t *ctx, enum v4l2_buf_type buf_type,
+ enum v4l2_memory memory_type, uint32_t num_planes,
+ uint32_t index);
+int
+nvv4l2_export_buffer(nvv4l2_ctx_t *ctx, enum v4l2_buf_type buf_type,
+ uint32_t num_planes, uint32_t index);
+int
+nvv4l2_fill_buffer_plane_format(nvv4l2_ctx_t *ctx,
+ uint32_t *num_planes,
+ NvBufferPlaneFormat *planefmts,
+ uint32_t width, uint32_t height,
+ uint32_t pixfmt);
+int
+nvv4l2_dq_event(nvv4l2_ctx_t *ctx, struct v4l2_event *event,
+ uint32_t max_wait_ms);
+int
+nvv4l2_dq_buffer(nvv4l2_ctx_t *ctx, struct v4l2_buffer *v4l2_buf,
+ NvBuffer **buffer, enum v4l2_buf_type buf_type,
+ enum v4l2_memory memory_type, uint32_t num_retries);
+int
+nvv4l2_q_buffer(nvv4l2_ctx_t *ctx, struct v4l2_buffer *v4l2_buf,
+ NvBuffer *buffer, enum v4l2_buf_type buf_type,
+ enum v4l2_memory memory_type, int num_planes);
+int
+nvv4l2_req_buffers_on_capture_plane(nvv4l2_ctx_t *ctx,
+ enum v4l2_buf_type buf_type,
+ enum v4l2_memory mem_type,
+ int num_buffers);
+int
+nvv4l2_req_buffers_on_output_plane(nvv4l2_ctx_t *ctx,
+ enum v4l2_buf_type buf_type,
+ enum v4l2_memory mem_type,
+ int num_buffers);
+int
+nvv4l2_set_ext_controls(int fd, uint32_t id,
+ uint32_t class, uint32_t value);
+int
+nvv4l2_set_ext_control_qp_range(int fd, uint32_t qpmin,
+ uint32_t qpmax);
+int
+nvv4l2_set_ext_control_constant_qp(int fd, uint32_t qpval);
+int
+nvv4l2_get_ext_control_metadata(int fd, uint32_t buffer_index,
+ v4l2_ctrl_videoenc_outputbuf_metadata *enc_metadata);
+int
+nvv4l2_set_stream_control_framerate(int fd, uint32_t buf_type,
+ uint32_t framerate_num,
+ uint32_t framerate_den);
+int
+nvv4l2_subscribe_event(int fd, uint32_t type, uint32_t id,
+ uint32_t flags);
+
+NvBufferPixFmtVersion
+nvv4l2_get_pixfmt_list_version(nvv4l2_ctx_t *ctx);
+
+/* NVV4L2 debug functions */
+void
+nvv4l2_dbg_plane_supported_formats(nvv4l2_ctx_t *ctx,
+ uint32_t buf_type);
+
+/* NVV4L2 decoder functions */
+nvv4l2_ctx_t *nvv4l2_create_decoder(AVCodecContext *avctx,
+ NvCodingType nv_codec_type,
+ int pix_fmt);
+int
+nvv4l2_decoder_put_packet(AVCodecContext *avctx, nvv4l2_ctx_t *ctx,
+ NvPacket *packet);
+int
+nvv4l2_decoder_get_frame(AVCodecContext *avctx, nvv4l2_ctx_t *ctx,
+ int *buf_index, NvFrame *frame);
+int nvv4l2_decoder_close(AVCodecContext *avctx, nvv4l2_ctx_t *ctx);
+
+/* NVV4L2 encoder functions */
+nvv4l2_ctx_t *nvv4l2_create_encoder(AVCodecContext *avctx,
+ NvEncoder *enc,
+ NvCodingType codingType,
+ int pix_fmt);
+int
+nvv4l2_encoder_put_frame(AVCodecContext *avctx, nvv4l2_ctx_t *ctx,
+ NvFrame *frame);
+int
+nvv4l2_encoder_get_packet(AVCodecContext *avctx,
+ nvv4l2_ctx_t *ctx,
+ NvPacket *packet);
+int
+nvv4l2_encoder_close(AVCodecContext *avctx, nvv4l2_ctx_t *ctx);
+
+#endif