* 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
18073 lines
629 KiB
Diff
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(©, &is->video_st->attached_pic)) < 0)
|
|
+ goto fail;
|
|
+ packet_queue_put(&is->videoq, ©);
|
|
+ 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, ¶ms);
|
|
+ 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(¶ms, 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, ¶ms);
|
|
+ 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
|